fix sub timing in mkv files with video delay

Some matroska files have audio start at timestamp 0 and video later.
In this case mkvtoolnix seems to use the first block of the first
cluster to the audio track (I would assume this is only an
implementation detail and not really from the matroska specs. And also
could happen in other cases without the video being delayed, but that's
not the point). Aegisub used to read this first block and use its
timestamp as the starting point of the video track.

With this commit, Aegisub tries to read all the blocks until it can read
the first timestamp of the video track and use it for the subtitles'
timestamps. Audio tracks don't seem to be impacted by these changes.
This commit is contained in:
odrling 2020-11-17 17:15:46 +01:00
parent b3461a52ae
commit ac2c466038
No known key found for this signature in database
GPG Key ID: A56620C3E2B7EB46
1 changed files with 30 additions and 11 deletions

View File

@ -1088,8 +1088,9 @@ static void parseSegmentInfo(MatroskaFile *mf,uint64_t toplen) {
static void parseFirstCluster(MatroskaFile *mf,uint64_t toplen) {
uint64_t end = filepos(mf) + toplen;
int tracknum = -1;
int i = 0;
mf->seen.Cluster = 1;
mf->firstTimecode = 0;
FOREACH(mf,toplen)
@ -1097,22 +1098,40 @@ static void parseFirstCluster(MatroskaFile *mf,uint64_t toplen) {
mf->firstTimecode += readUInt(mf,(unsigned)len);
break;
case 0xa3: // BlockEx
readVLUInt(mf); // track number
mf->firstTimecode += readSInt(mf, 2);
start = filepos(mf);
tracknum = readVLUInt(mf); // track number
skipbytes(mf,end - filepos(mf));
return;
for (i = 0; i < mf->nTracks; ++i) {
if (mf->Tracks[i]->Number == tracknum && mf->Tracks[i]->Type == TT_VIDEO) {
mf->firstTimecode += readSInt(mf, 2);
mf->seen.Cluster = 1;
skipbytes(mf,end - filepos(mf));
return;
}
}
skipbytes(mf, len - (filepos(mf) - start));
break;
case 0xa0: // BlockGroup
FOREACH(mf,len)
case 0xa1: // Block
readVLUInt(mf); // track number
mf->firstTimecode += readSInt(mf,2);
case 0xa1: // Block
start = filepos(mf);
tracknum = readVLUInt(mf); // track number
skipbytes(mf,end - filepos(mf));
return;
for (i = 0; i < mf->nTracks; ++i) {
if (mf->Tracks[i]->Number == tracknum && mf->Tracks[i]->Type == TT_VIDEO) {
mf->firstTimecode += readSInt(mf, 2);
mf->seen.Cluster = 1;
skipbytes(mf,end - filepos(mf));
return;
}
}
skipbytes(mf, len - (filepos(mf) - start));
break;
ENDFOR(mf);
break;
ENDFOR(mf);
}
static void parseVideoInfo(MatroskaFile *mf,uint64_t toplen,struct TrackInfo *ti) {