Skip to content

Commit ccee512

Browse files
tegginamanissThulinma
authored andcommitted
Bug Fix: CMAF DASH playback works
- syntax error fixed - removed unnecessary track id simplification
1 parent e9d5920 commit ccee512

File tree

2 files changed

+43
-49
lines changed

2 files changed

+43
-49
lines changed

lib/cmaf.cpp

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ namespace CMAF{
1313
return payloadSize;
1414
}
1515

16-
size_t simplifiedTrackId(const DTSC::Meta & M, size_t idx) {
17-
std::string type = M.getType(idx);
18-
if (type == "video") {return 1;}
19-
if (type == "audio") {return 2;}
20-
if (type == "meta") {return 3;}
21-
return idx;
22-
}
23-
2416
std::string trackHeader(const DTSC::Meta &M, size_t track, bool simplifyTrackIds){
2517
std::string tType = M.getType(track);
2618

@@ -43,9 +35,6 @@ namespace CMAF{
4335
MP4::TRAK trakBox;
4436

4537
MP4::TKHD tkhdBox(M, track);
46-
if (simplifyTrackIds){
47-
tkhdBox.setTrackID(simplifiedTrackId(M, track));
48-
}
4938
tkhdBox.setDuration(0);
5039
trakBox.setContent(tkhdBox, 0);
5140

@@ -87,7 +76,7 @@ namespace CMAF{
8776
btrtBox.setAverageBitrate(M.getBps(track));
8877
btrtBox.setMaxBitrate(M.getMaxBps(track));
8978

90-
sampleEntry.setBoxEntry(sampleEntry.getBoxEntryCount(),btrtBox);
79+
sampleEntry.setBoxEntry(sampleEntry.getBoxEntryCount(), btrtBox);
9180
stsdBox.setEntry(sampleEntry, 0);
9281
}else if (tType == "audio"){
9382
MP4::AudioSampleEntry sampleEntry(M, track);
@@ -96,7 +85,7 @@ namespace CMAF{
9685
btrtBox.setAverageBitrate(M.getBps(track));
9786
btrtBox.setMaxBitrate(M.getMaxBps(track));
9887

99-
sampleEntry.setBoxEntry(sampleEntry.getBoxEntryCount(),btrtBox);
88+
sampleEntry.setBoxEntry(sampleEntry.getBoxEntryCount(), btrtBox);
10089
stsdBox.setEntry(sampleEntry, 0);
10190
}else if (tType == "meta"){
10291
MP4::TextSampleEntry sampleEntry(M, track);
@@ -131,9 +120,6 @@ namespace CMAF{
131120
}
132121

133122
MP4::TREX trexBox(track + 1);
134-
if (simplifyTrackIds){
135-
trexBox.setTrackID(simplifiedTrackId(M, track));
136-
}
137123
trexBox.setDefaultSampleDuration(1000);
138124
mvexBox.setContent(trexBox, M.getVod() ? 1 : 0);
139125

@@ -148,17 +134,21 @@ namespace CMAF{
148134
MP4::SIDX sidxBox;
149135
sidxBox.setReferenceID(track + 1);
150136
sidxBox.setTimescale(1000);
151-
sidxBox.setEarliestPresentationTime(keys.getTime(0) + parts.getOffset(0) - M.getFirstms(track));
137+
sidxBox.setEarliestPresentationTime(keys.getTime(0) + parts.getOffset(0) -
138+
M.getFirstms(track));
152139

153140
for (size_t i = 0; i < fragments.getEndValid(); i++){
154141
size_t firstKey = fragments.getFirstKey(i);
155142
size_t endKey =
156143
((i + 1 < fragments.getEndValid()) ? fragments.getFirstKey(i + 1) : keys.getEndValid());
157144

158145
MP4::sidxReference refItem;
159-
refItem.referencedSize = payloadSize(M, track, keys.getTime(firstKey), keys.getTime(endKey)) + keyHeaderSize(M, track, i) + 8;
146+
refItem.referencedSize =
147+
payloadSize(M, track, keys.getTime(firstKey), keys.getTime(endKey)) +
148+
keyHeaderSize(M, track, i) + 8;
160149
refItem.subSegmentDuration =
161-
(endKey == keys.getEndValid() ? M.getLastms(track) : keys.getTime(endKey)) - keys.getTime(firstKey);
150+
(endKey == keys.getEndValid() ? M.getLastms(track) : keys.getTime(endKey)) -
151+
keys.getTime(firstKey);
162152
refItem.sapStart = true;
163153
refItem.sapType = 16;
164154
refItem.sapDeltaTime = 0;
@@ -209,7 +199,8 @@ namespace CMAF{
209199
}
210200

211201
/// Generates the 'moof' box for a DTSC::Key based CMAF fragment.
212-
std::string keyHeader(const DTSC::Meta &M, size_t track, uint64_t startTime, uint64_t endTime, uint64_t segmentNum, bool simplifyTrackIds, bool UTCTime){
202+
std::string keyHeader(const DTSC::Meta &M, size_t track, uint64_t startTime, uint64_t endTime,
203+
uint64_t segmentNum, bool simplifyTrackIds, bool UTCTime){
213204

214205
size_t firstPart = M.getPartIndex(startTime, track);
215206
size_t endPart = M.getPartIndex(endTime, track);
@@ -218,10 +209,9 @@ namespace CMAF{
218209
MP4::MFHD mfhdBox(segmentNum);
219210
moofBox.setContent(mfhdBox, 0);
220211

221-
222212
std::set<sortPart> trunOrder;
223213

224-
//We use keyHeaderSize here to determine the relative offsets of the data in the 'mdat' box.
214+
// We use keyHeaderSize here to determine the relative offsets of the data in the 'mdat' box.
225215
uint64_t relativeOffset = keyHeaderSize(M, track, startTime, endTime) + 8;
226216

227217
sortPart temp;
@@ -242,21 +232,20 @@ namespace CMAF{
242232

243233
tfhdBox.setFlags(MP4::tfhdSampleFlag | MP4::tfhdBaseIsMoof | MP4::tfhdSampleDesc);
244234
tfhdBox.setTrackID(track + 1);
245-
if (simplifyTrackIds){
246-
tfhdBox.setTrackID(simplifiedTrackId(M, track));
247-
}
248235
tfhdBox.setDefaultSampleDuration(444);
249236
tfhdBox.setDefaultSampleSize(444);
250-
tfhdBox.setDefaultSampleFlags((M.getType(track) == "video") ? (MP4::noIPicture | MP4::noKeySample)
251-
: (MP4::isIPicture | MP4::isKeySample));
237+
tfhdBox.setDefaultSampleFlags((M.getType(track) == "video")
238+
? (MP4::noIPicture | MP4::noKeySample)
239+
: (MP4::isIPicture | MP4::isKeySample));
252240
tfhdBox.setSampleDescriptionIndex(1);
253241
trafBox.setContent(tfhdBox, 0);
254242

255243
MP4::TFDT tfdtBox;
256244
if (M.getVod()){
257245
tfdtBox.setBaseMediaDecodeTime(startTime - M.getFirstms(track));
258246
}else{
259-
tfdtBox.setBaseMediaDecodeTime((UTCTime ? startTime + M.getBootMsOffset() + unixBootDiff : startTime));
247+
tfdtBox.setBaseMediaDecodeTime(
248+
(UTCTime ? startTime + M.getBootMsOffset() + unixBootDiff : startTime));
260249
}
261250
trafBox.setContent(tfdtBox, 1);
262251

@@ -277,15 +266,14 @@ namespace CMAF{
277266
MP4::trunSampleInformation sampleInfo;
278267
sampleInfo.sampleSize = parts.getSize(it->partIndex);
279268
sampleInfo.sampleDuration = parts.getDuration(it->partIndex);
280-
if (it == lastOne){
281-
sampleInfo.sampleDuration = endTime - it->time;
282-
}
269+
if (it == lastOne){sampleInfo.sampleDuration = endTime - it->time;}
283270
sampleInfo.sampleOffset = parts.getOffset(it->partIndex);
284271
trunBox.setSampleInformation(sampleInfo, trunOffset++);
285272
}
286273
}else{
287-
WARN_MSG("Empty CMAF header for track %zu: %" PRIu64 "-%" PRIu64 " contains no packets (first: %" PRIu64
288-
", last: %" PRIu64 "), firstPart=%zu, lastPart=%zu",
274+
WARN_MSG("Empty CMAF header for track %zu: %" PRIu64 "-%" PRIu64
275+
" contains no packets (first: %" PRIu64 ", last: %" PRIu64
276+
"), firstPart=%zu, lastPart=%zu",
289277
track, startTime, endTime, M.getFirstms(track), M.getLastms(track), firstPart,
290278
endPart);
291279
}

src/output/output_cmaf.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -489,32 +489,32 @@ namespace Mist{
489489
}
490490

491491
void OutCMAF::generateSegmentlist(size_t idx, std::stringstream &s,
492-
void callBack(uint64_t, uint64_t, std::stringstream &, bool)){
493-
DTSC::Fragments fragments(M.fragments(idx));
492+
void dashSegmentCallBack(uint64_t, uint64_t,
493+
std::stringstream &, bool)){
494+
// NOTE: Weirdly making the 0th track as the reference track fixed everything.
495+
// Looks like a nomenclature issue.
496+
// TODO: Investigate with spec and refactor stuff appropriately.
497+
498+
size_t mainTrack = *M.getValidTracks().begin(); // M.mainTrack();
499+
500+
if (mainTrack == INVALID_TRACK_ID){return;}
501+
DTSC::Fragments fragments(M.fragments(mainTrack));
494502
uint32_t firstFragment = fragments.getFirstValid();
495503
uint32_t lastFragment = fragments.getEndValid();
496504
bool first = true;
497505
// skip the first two fragments if live
498506
if (M.getLive() && (lastFragment - firstFragment) > 6){firstFragment += 2;}
499507

500-
if (M.getType(idx) == "audio"){
501-
uint32_t mainTrack = M.mainTrack();
502-
if (mainTrack == INVALID_TRACK_ID){return;}
503-
DTSC::Fragments f(M.fragments(mainTrack));
504-
uint64_t firstVidTime = M.getTimeForFragmentIndex(mainTrack, f.getFirstValid());
505-
firstFragment = M.getFragmentIndexForTime(idx, firstVidTime);
506-
}
507-
508-
DTSC::Keys keys(M.keys(idx));
508+
DTSC::Keys keys(M.keys(mainTrack));
509509
for (; firstFragment < lastFragment; ++firstFragment){
510510
uint32_t duration = fragments.getDuration(firstFragment);
511511
uint64_t starttime = keys.getTime(fragments.getFirstKey(firstFragment));
512512
if (!duration){
513513
if (M.getLive()){continue;}// skip last fragment when live
514-
duration = M.getLastms(idx) - starttime;
514+
duration = M.getLastms(mainTrack) - starttime;
515515
}
516-
if (M.getVod()){starttime -= M.getFirstms(idx);}
517-
callBack(starttime, duration, s, first);
516+
if (M.getVod()){starttime -= M.getFirstms(mainTrack);}
517+
dashSegmentCallBack(starttime, duration, s, first);
518518
first = false;
519519
}
520520

@@ -662,7 +662,7 @@ namespace Mist{
662662
it++){
663663
if (M.getType(it->first) == "video"){vTracks.insert(it->first);}
664664
if (M.getType(it->first) == "audio"){aTracks.insert(it->first);}
665-
if (M.getType(it->first) == "subtitle"){sTracks.insert(it->first);}
665+
if (M.getCodec(it->first) == "subtitle"){sTracks.insert(it->first);}
666666
}
667667

668668
if (!vTracks.size() && !aTracks.size()){return "";}
@@ -685,12 +685,18 @@ namespace Mist{
685685
<< "\" suggestedPresentationDelay=\"PT5.0S\" minBufferTime=\"PT2.0S\" publishTime=\""
686686
<< Util::getUTCString(Util::epoch()) << "\" ";
687687
}
688+
689+
r << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
690+
r << "xmlns:xlink=\"http://www.w3.org/1999/xlink\" ";
691+
r << "xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 "
692+
"http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/"
693+
"DASH-MPD.xsd\" ";
688694
r << "profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
689695
"xmlns=\"urn:mpeg:dash:schema:mpd:2011\" >"
690696
<< std::endl;
691697
r << "<ProgramInformation><Title>" << streamName << "</Title></ProgramInformation>"
692698
<< std::endl;
693-
r << "<Period " << (M.getLive() ? "start=\"0\"" : "") << ">" << std::endl;
699+
r << "<Period " << (M.getLive() ? "start=\"PT0.0S\"" : "") << ">" << std::endl;
694700

695701
dashAdaptation(1, vTracks, videoAligned, r);
696702
dashAdaptation(2, aTracks, audioAligned, r);

0 commit comments

Comments
 (0)