diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2015-04-10 10:25:13 +0300 |
---|---|---|
committer | Hendrik Leppkes <h.leppkes@gmail.com> | 2017-08-04 20:18:07 +0300 |
commit | 7dbc8adf2d239b96555090d355c9ba08dea7a05d (patch) | |
tree | 48bb5257a94db8c60a5f24be380b0b93a3d6e8db | |
parent | 60066475c49a3031a31b3ad8fef011339990dec0 (diff) |
matroskadec_haali: search more aggressively for a duration of incomplete files
-rw-r--r-- | libavformat/MatroskaParser.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/libavformat/MatroskaParser.c b/libavformat/MatroskaParser.c index 12ca04c483..375ef33245 100644 --- a/libavformat/MatroskaParser.c +++ b/libavformat/MatroskaParser.c @@ -70,6 +70,9 @@ #define MAXCLUSTER (256*1048576) #define MAXFRAME (4*1048576) +#define MAXDURATIONREAD (13000000LL) +#define MAXDURATIONRETRY (6) + #if defined(_WIN32) && defined(_MSC_VER) #define LL(x) x##i64 #define ULL(x) x##ui64 @@ -2747,7 +2750,7 @@ static void fixupChapter(ulonglong adj, struct Chapter *ch) { static longlong findLastTimecode(MatroskaFile *mf) { ulonglong nd = 0; - unsigned n,vtrack; + unsigned n,vtrack,retry=0; if (mf->nTracks == 0) return -1; @@ -2763,25 +2766,36 @@ ok: EmptyQueues(mf); - if (mf->nCues == 0) { - mf->readPosition = mf->pCluster + 13000000 > mf->pSegmentTop ? mf->pCluster : mf->pSegmentTop - 13000000; - mf->tcCluster = 0; - } else { - mf->readPosition = mf->Cues[mf->nCues - 1].Position + mf->pSegment; - mf->tcCluster = mf->Cues[mf->nCues - 1].Time / mf->Seg.TimecodeScale; - } mf->trackMask = ~(ULL(1) << vtrack); - do - while (mf->Queues[vtrack].head) - { - ulonglong tc = mf->Queues[vtrack].head->flags & FRAME_UNKNOWN_END ? - mf->Queues[vtrack].head->Start : mf->Queues[vtrack].head->End; - if (nd < tc) - nd = tc; - QFree(mf,QGet(&mf->Queues[vtrack])); + while (nd == 0 && retry < MAXDURATIONRETRY) { + if (mf->nCues == 0) { + mf->readPosition = mf->pCluster + (MAXDURATIONREAD << retry) > mf->pSegmentTop ? mf->pCluster : mf->pSegmentTop - (MAXDURATIONREAD << retry); + mf->tcCluster = 0; + + if (retry > 0 && (mf->pCluster + (MAXDURATIONREAD << retry) > mf->pSegmentTop) && (mf->pCluster + (MAXDURATIONREAD << (retry - 1)) > mf->pSegmentTop)) + break; + } else { + if (retry >= mf->nCues) + break; + + mf->readPosition = mf->Cues[mf->nCues - (1 + retry)].Position + mf->pSegment; + mf->tcCluster = mf->Cues[mf->nCues - (1 + retry)].Time / mf->Seg.TimecodeScale; } - while (fillQueues(mf,0) != EOF); + + do + while (mf->Queues[vtrack].head) + { + ulonglong tc = mf->Queues[vtrack].head->flags & FRAME_UNKNOWN_END ? + mf->Queues[vtrack].head->Start : mf->Queues[vtrack].head->End; + if (nd < tc) + nd = tc; + QFree(mf, QGet(&mf->Queues[vtrack])); + } + while (fillQueues(mf, 0) != EOF); + + retry++; + } mf->trackMask = 0; |