Fixed ELST box in mp4, and use it to fix track desync issues.
This commit is contained in:
parent
0fff6f8773
commit
e53b14365c
2 changed files with 46 additions and 19 deletions
|
@ -3763,57 +3763,57 @@ namespace MP4 {
|
||||||
|
|
||||||
void ELST::setSegmentDuration(uint32_t cnt, uint64_t newVal) {
|
void ELST::setSegmentDuration(uint32_t cnt, uint64_t newVal) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
setInt64(newVal, 28*cnt+8);
|
setInt64(newVal, 20*cnt+8);
|
||||||
} else {
|
} else {
|
||||||
setInt32(newVal, 20*cnt+8);
|
setInt32(newVal, 12*cnt+8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ELST::getSegmentDuration(uint32_t cnt) {
|
uint64_t ELST::getSegmentDuration(uint32_t cnt) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
return getInt64(28*cnt+8);
|
return getInt64(20*cnt+8);
|
||||||
} else {
|
} else {
|
||||||
return getInt32(20*cnt+8);
|
return getInt32(12*cnt+8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELST::setMediaTime(uint32_t cnt, uint64_t newVal) {
|
void ELST::setMediaTime(uint32_t cnt, uint64_t newVal) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
setInt64(newVal, 28*cnt+16);
|
setInt64(newVal, 20*cnt+16);
|
||||||
} else {
|
} else {
|
||||||
setInt32(newVal, 20*cnt+12);
|
setInt32(newVal, 12*cnt+12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ELST::getMediaTime(uint32_t cnt) {
|
uint64_t ELST::getMediaTime(uint32_t cnt) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
return getInt64(28*cnt+16);
|
return getInt64(20*cnt+16);
|
||||||
} else {
|
} else {
|
||||||
return getInt32(20*cnt+12);
|
return getInt32(12*cnt+12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELST::setMediaRateInteger(uint32_t cnt, uint16_t newVal) {
|
void ELST::setMediaRateInteger(uint32_t cnt, uint16_t newVal) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
setInt16(newVal, 28*cnt+24);
|
setInt16(newVal, 20*cnt+24);
|
||||||
} else {
|
} else {
|
||||||
setInt16(newVal, 20*cnt+16);
|
setInt16(newVal, 12*cnt+16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ELST::getMediaRateInteger(uint32_t cnt) {
|
uint16_t ELST::getMediaRateInteger(uint32_t cnt) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
return getInt16(28*cnt+24);
|
return getInt16(20*cnt+24);
|
||||||
} else {
|
} else {
|
||||||
return getInt16(20*cnt+16);
|
return getInt16(12*cnt+16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELST::setMediaRateFraction(uint32_t cnt, uint16_t newVal) {
|
void ELST::setMediaRateFraction(uint32_t cnt, uint16_t newVal) {
|
||||||
if (getVersion() == 1) {
|
if (getVersion() == 1) {
|
||||||
setInt16(newVal, 28*cnt+26);
|
setInt16(newVal, 20*cnt+26);
|
||||||
} else {
|
} else {
|
||||||
setInt16(newVal, 20*cnt+18);
|
setInt16(newVal, 12*cnt+18);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,12 @@ namespace Mist{
|
||||||
uint64_t res = 36 // FTYP Box
|
uint64_t res = 36 // FTYP Box
|
||||||
+ 8 //MOOV box
|
+ 8 //MOOV box
|
||||||
+ 108; //MVHD Box
|
+ 108; //MVHD Box
|
||||||
|
uint64_t firstms = 0xFFFFFFFFFFFFFFFFull;
|
||||||
|
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
||||||
|
if (myMeta.tracks[*it].firstms < firstms){
|
||||||
|
firstms = myMeta.tracks[*it].firstms;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
|
||||||
DTSC::Track & thisTrack = myMeta.tracks[*it];
|
DTSC::Track & thisTrack = myMeta.tracks[*it];
|
||||||
uint64_t tmpRes = 0;
|
uint64_t tmpRes = 0;
|
||||||
|
@ -59,6 +65,9 @@ namespace Mist{
|
||||||
+ 8 //MINF Box
|
+ 8 //MINF Box
|
||||||
+ 36 //DINF Box
|
+ 36 //DINF Box
|
||||||
+ 8; // STBL Box
|
+ 8; // STBL Box
|
||||||
|
if (thisTrack.firstms != firstms){
|
||||||
|
tmpRes += 12;// EDTS entry extra
|
||||||
|
}
|
||||||
|
|
||||||
//These boxes are empty when generating fragmented output
|
//These boxes are empty when generating fragmented output
|
||||||
tmpRes += 20 + (fragmented ? 0 : (partCount * 4));//STSZ
|
tmpRes += 20 + (fragmented ? 0 : (partCount * 4));//STSZ
|
||||||
|
@ -168,6 +177,7 @@ namespace Mist{
|
||||||
//Construct with duration of -1, as this is the default for fragmented
|
//Construct with duration of -1, as this is the default for fragmented
|
||||||
MP4::MVHD mvhdBox(-1);
|
MP4::MVHD mvhdBox(-1);
|
||||||
//Then override it only when we are not sending a fragmented file
|
//Then override it only when we are not sending a fragmented file
|
||||||
|
uint64_t fms;
|
||||||
if (!fragmented){
|
if (!fragmented){
|
||||||
//calculating longest duration
|
//calculating longest duration
|
||||||
uint64_t firstms = 0xFFFFFFFFFFFFFFull;
|
uint64_t firstms = 0xFFFFFFFFFFFFFFull;
|
||||||
|
@ -177,6 +187,7 @@ namespace Mist{
|
||||||
firstms = std::min(firstms, (uint64_t)myMeta.tracks[*it].firstms);
|
firstms = std::min(firstms, (uint64_t)myMeta.tracks[*it].firstms);
|
||||||
}
|
}
|
||||||
mvhdBox.setDuration(lastms - firstms);
|
mvhdBox.setDuration(lastms - firstms);
|
||||||
|
fms = firstms;
|
||||||
}
|
}
|
||||||
//Set the trackid for the first "empty" track within the file.
|
//Set the trackid for the first "empty" track within the file.
|
||||||
mvhdBox.setTrackID(selectedTracks.size() + 1);
|
mvhdBox.setTrackID(selectedTracks.size() + 1);
|
||||||
|
@ -202,11 +213,27 @@ namespace Mist{
|
||||||
MP4::ELST elstBox;
|
MP4::ELST elstBox;
|
||||||
elstBox.setVersion(0);
|
elstBox.setVersion(0);
|
||||||
elstBox.setFlags(0);
|
elstBox.setFlags(0);
|
||||||
|
if (thisTrack.firstms != fms){
|
||||||
|
elstBox.setCount(2);
|
||||||
|
|
||||||
|
elstBox.setSegmentDuration(0, fragmented ? -1 : thisTrack.firstms - fms);
|
||||||
|
elstBox.setMediaTime(0, 0xFFFFFFFFull);
|
||||||
|
elstBox.setMediaRateInteger(0, 0);
|
||||||
|
elstBox.setMediaRateFraction(0, 0);
|
||||||
|
|
||||||
|
elstBox.setSegmentDuration(1, tDuration);
|
||||||
|
elstBox.setMediaTime(1, 0);
|
||||||
|
elstBox.setMediaRateInteger(1, 1);
|
||||||
|
elstBox.setMediaRateFraction(1, 0);
|
||||||
|
}else{
|
||||||
elstBox.setCount(1);
|
elstBox.setCount(1);
|
||||||
elstBox.setSegmentDuration(0, fragmented ? -1 : tDuration);
|
|
||||||
|
elstBox.setSegmentDuration(0, tDuration);
|
||||||
elstBox.setMediaTime(0, 0);
|
elstBox.setMediaTime(0, 0);
|
||||||
elstBox.setMediaRateInteger(0, 1);
|
elstBox.setMediaRateInteger(0, 1);
|
||||||
elstBox.setMediaRateFraction(0, 0);
|
elstBox.setMediaRateFraction(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
edtsBox.setContent(elstBox, 0);
|
edtsBox.setContent(elstBox, 0);
|
||||||
trakBox.setContent(edtsBox, trakOffset++);
|
trakBox.setContent(edtsBox, trakOffset++);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue