Ticket #30: dts-calc4.diff

File dts-calc4.diff, 6.2 kB (added by dconrad, 2 years ago)

Patch (still incorrect) updated to apply on SVN again.

  • MatroskaImportPrivate.cpp

    old new  
    872872                seenFirstBlock = true; 
    873873        } 
    874874         
    875         for (int i = 0; i < lastFrames.size(); i++) { 
    876                 // all the frames in the vector should have the same timecode at the moment 
    877                 TimeValue64 duration = block.GlobalTimecode() / timecodeScale - lastFrames[i].timecode; 
     875        // tracks w/ lacing can't have b-frames, and neither can any known audio codec 
     876        if (usesLacing || type != track_video) { 
     877                for (int i = 0; i < lastFrames.size(); i++) { 
     878                        // all the frames in the vector should have the same timecode at the moment 
     879                        TimeValue64 duration = block.GlobalTimecode() / timecodeScale - lastFrames[i].pts; 
     880                         
     881                        // since there can be multiple frames in one block, split the duration evenly between them 
     882                        // giving the remainder to the latter blocks 
     883                        int remainder = duration % lastFrames.size() >= lastFrames.size() - i ? 1 : 0; 
     884                         
     885                        lastFrames[i].duration = duration / lastFrames.size() + remainder; 
     886                         
     887                        AddFrame(lastFrames[i]); 
     888                } 
     889                lastFrames.clear(); 
     890        } else if (ptsReorder.size() > 1) { 
     891                ptsReorder.sort(); 
     892                list<TimeValue64>::iterator actualDTS = ++ptsReorder.begin(); 
    878893                 
    879                 // since there can be multiple frames in one block, split the duration evenly between them 
    880                 // giving the remainder to the latter blocks 
    881                 int remainder = duration % lastFrames.size() >= lastFrames.size() - i ? 1 : 0; 
     894                // first frame has correct dts (we start at a keyframe thus pts = dts and don't 
     895                // remove that frame until it has correct duration, for which the next frame must 
     896                // have correct dts.) So, we're looking for a pts of no more than dts + duration + 1 
     897                TimeValue64 expectedDTS = lastFrames[0].dts + lastFrames[0].duration + 1; 
    882898                 
    883                 lastFrames[i].duration = duration / lastFrames.size() + remainder; 
    884                  
    885                 AddFrame(lastFrames[i]); 
     899                if (*actualDTS <= expectedDTS || ptsReorder.size() > MAX_DECODE_DELAY) { 
     900                        lastFrames[1].dts = *actualDTS; 
     901                        lastFrames[0].duration = lastFrames[1].dts - lastFrames[0].dts; 
     902                        AddFrame(lastFrames[0]); 
     903                        lastFrames.erase(lastFrames.begin()); 
     904                        ptsReorder.pop_front(); 
     905                } 
    886906        } 
    887         lastFrames.clear(); 
    888907         
    889908        for (int i = 0; i < block.NumberFrames(); i++) { 
    890909                MatroskaFrame newFrame; 
    891                 newFrame.timecode = block.GlobalTimecode() / timecodeScale; 
     910                newFrame.pts = block.GlobalTimecode() / timecodeScale; 
     911                newFrame.dts = newFrame.pts; 
    892912                if (duration > 0) 
    893913                        newFrame.duration = duration; 
    894914                else 
     
    901921                        newFrame.buffer = &block.GetBuffer(i); 
    902922                        AddFrame(newFrame); 
    903923                } 
    904                 else 
     924                else { 
    905925                        lastFrames.push_back(newFrame); 
     926                        if (!usesLacing && type == track_video) 
     927                                ptsReorder.push_back(newFrame.pts); 
     928                } 
    906929                 
    907930                newFrame.buffer = NULL; 
    908931        } 
     
    915938        TimeValue sampleTime; 
    916939         
    917940        if (type == track_subtitle && !is_vobsub) { 
    918                 if (frame.size > 0) subtitleSerializer->pushLine((const char*)frame.buffer->Buffer(), frame.buffer->Size(), frame.timecode, frame.timecode + frame.duration); 
     941                if (frame.size > 0) subtitleSerializer->pushLine((const char*)frame.buffer->Buffer(), frame.buffer->Size(), frame.pts, frame.pts + frame.duration); 
    919942                const char *packet=NULL; size_t size=0; unsigned start=0, end=0; 
    920943                packet = subtitleSerializer->popPacket(&size, &start, &end); 
    921944                if (packet) { 
     
    927950                                return; 
    928951                        } 
    929952                        DisposeHandle(sampleH); 
    930                         frame.timecode = start; 
     953                        frame.pts = start; 
    931954                        frame.duration = end - start; 
    932955                        sampleNum = sampleTime; 
    933956                } else return; 
    934957        } else if (sampleTable) { 
     958                TimeValue64 displayOffset = frame.pts - frame.dts; 
     959                 
    935960                err = QTSampleTableAddSampleReferences(sampleTable, frame.offset, frame.size, frame.duration,  
    936                                                                                            0, 1, frame.flags, qtSampleDesc, &sampleNum); 
     961                                                                                           displayOffset, 1, frame.flags, qtSampleDesc, &sampleNum); 
    937962                if (err) { 
    938963                        Codecprintf(NULL, "MKV: error adding sample reference to table %d\n", err); 
    939964                        return; 
     
    964989                        Codecprintf(NULL, "MKV: subtitle track has a sample table\n", err); 
    965990                        return; 
    966991                } 
    967                 err = InsertMediaIntoTrack(theTrack, frame.timecode, sampleTime, frame.duration, fixed1); 
     992                err = InsertMediaIntoTrack(theTrack, frame.pts, sampleTime, frame.duration, fixed1); 
    968993                if (err) { 
    969994                        Codecprintf(NULL, "MKV: error adding subtitle media into track %d\n", err); 
    970995                        return; 
     
    9861011        if (type != track_subtitle) { 
    9871012                if (sampleTable) { 
    9881013                        TimeValue64 sampleTime64; 
    989                         TimeValue mediaDuration = GetMediaDuration(theMedia); 
     1014                        TimeValue mediaDuration = GetMediaDisplayDuration(theMedia); 
    9901015                         
    9911016                        err = AddSampleTableToMedia(theMedia, sampleTable, firstSample, amountToAdd, &sampleTime64); 
    9921017                        if (err) 
    9931018                                Codecprintf(NULL, "MKV: error adding sample table to media %d (type %x #%d)\n", err); 
    9941019                         
    9951020                        firstSample = sampleTime64; 
    996                         amountToAdd = GetMediaDuration(theMedia) - mediaDuration; 
     1021                        // XXX - almost certainly not right 
     1022                        amountToAdd = GetMediaDisplayDuration(theMedia) - mediaDuration - 1; 
    9971023                } 
    9981024                err = InsertMediaIntoTrack(theTrack, -1, firstSample, amountToAdd, fixed1); 
    9991025                if (err) 
  • MatroskaImport.h

    old new  
    2626#define __MATROSKAIMPORT_H__ 
    2727 
    2828#include <vector> 
     29#include <list> 
     30 
    2931#include <QuickTime/QuickTime.h> 
    3032#include "DataHandlerCallback.h" 
    3133#include "SubImport.h" 
     
    4244using namespace std; 
    4345 
    4446 
     47#define MAX_DECODE_DELAY 16 
     48 
    4549struct MatroskaFrame { 
    46         TimeValue64             timecode; 
    47 //      TimeValue64             duration; 
    48         UInt32                 duration;               // hack so that H.264 tracks kinda work 
     50        TimeValue64             dts;                   // decode timestamp 
     51        TimeValue64             pts;                    // presentation/display timestamp 
     52        TimeValue              duration; 
    4953        SInt64                  offset; 
    5054        SInt64                  size; 
    5155        short                   flags; 
     
    126130        // from one block group until the next block group is found to set the duration of the 
    127131        // previous ones to be the difference in timestamps. 
    128132        vector<MatroskaFrame>   lastFrames; 
     133         
     134        // insert pts values, sort, then smallest value is current dts if size > decode delay 
     135        list<TimeValue64>               ptsReorder; 
    129136        bool                                    seenFirstBlock; 
    130137         
    131138        // this is the first sample number (if sample table) or sample time that we haven't