Ticket #30: dts-calc4.diff
| File dts-calc4.diff, 6.2 kB (added by dconrad, 2 years ago) |
|---|
-
MatroskaImportPrivate.cpp
old new 872 872 seenFirstBlock = true; 873 873 } 874 874 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(); 878 893 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; 882 898 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 } 886 906 } 887 lastFrames.clear();888 907 889 908 for (int i = 0; i < block.NumberFrames(); i++) { 890 909 MatroskaFrame newFrame; 891 newFrame.timecode = block.GlobalTimecode() / timecodeScale; 910 newFrame.pts = block.GlobalTimecode() / timecodeScale; 911 newFrame.dts = newFrame.pts; 892 912 if (duration > 0) 893 913 newFrame.duration = duration; 894 914 else … … 901 921 newFrame.buffer = &block.GetBuffer(i); 902 922 AddFrame(newFrame); 903 923 } 904 else 924 else { 905 925 lastFrames.push_back(newFrame); 926 if (!usesLacing && type == track_video) 927 ptsReorder.push_back(newFrame.pts); 928 } 906 929 907 930 newFrame.buffer = NULL; 908 931 } … … 915 938 TimeValue sampleTime; 916 939 917 940 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); 919 942 const char *packet=NULL; size_t size=0; unsigned start=0, end=0; 920 943 packet = subtitleSerializer->popPacket(&size, &start, &end); 921 944 if (packet) { … … 927 950 return; 928 951 } 929 952 DisposeHandle(sampleH); 930 frame. timecode= start;953 frame.pts = start; 931 954 frame.duration = end - start; 932 955 sampleNum = sampleTime; 933 956 } else return; 934 957 } else if (sampleTable) { 958 TimeValue64 displayOffset = frame.pts - frame.dts; 959 935 960 err = QTSampleTableAddSampleReferences(sampleTable, frame.offset, frame.size, frame.duration, 936 0, 1, frame.flags, qtSampleDesc, &sampleNum);961 displayOffset, 1, frame.flags, qtSampleDesc, &sampleNum); 937 962 if (err) { 938 963 Codecprintf(NULL, "MKV: error adding sample reference to table %d\n", err); 939 964 return; … … 964 989 Codecprintf(NULL, "MKV: subtitle track has a sample table\n", err); 965 990 return; 966 991 } 967 err = InsertMediaIntoTrack(theTrack, frame. timecode, sampleTime, frame.duration, fixed1);992 err = InsertMediaIntoTrack(theTrack, frame.pts, sampleTime, frame.duration, fixed1); 968 993 if (err) { 969 994 Codecprintf(NULL, "MKV: error adding subtitle media into track %d\n", err); 970 995 return; … … 986 1011 if (type != track_subtitle) { 987 1012 if (sampleTable) { 988 1013 TimeValue64 sampleTime64; 989 TimeValue mediaDuration = GetMediaD uration(theMedia);1014 TimeValue mediaDuration = GetMediaDisplayDuration(theMedia); 990 1015 991 1016 err = AddSampleTableToMedia(theMedia, sampleTable, firstSample, amountToAdd, &sampleTime64); 992 1017 if (err) 993 1018 Codecprintf(NULL, "MKV: error adding sample table to media %d (type %x #%d)\n", err); 994 1019 995 1020 firstSample = sampleTime64; 996 amountToAdd = GetMediaDuration(theMedia) - mediaDuration; 1021 // XXX - almost certainly not right 1022 amountToAdd = GetMediaDisplayDuration(theMedia) - mediaDuration - 1; 997 1023 } 998 1024 err = InsertMediaIntoTrack(theTrack, -1, firstSample, amountToAdd, fixed1); 999 1025 if (err) -
MatroskaImport.h
old new 26 26 #define __MATROSKAIMPORT_H__ 27 27 28 28 #include <vector> 29 #include <list> 30 29 31 #include <QuickTime/QuickTime.h> 30 32 #include "DataHandlerCallback.h" 31 33 #include "SubImport.h" … … 42 44 using namespace std; 43 45 44 46 47 #define MAX_DECODE_DELAY 16 48 45 49 struct MatroskaFrame { 46 TimeValue64 timecode;47 // TimeValue64 duration; 48 UInt32 duration; // hack so that H.264 tracks kinda work50 TimeValue64 dts; // decode timestamp 51 TimeValue64 pts; // presentation/display timestamp 52 TimeValue duration; 49 53 SInt64 offset; 50 54 SInt64 size; 51 55 short flags; … … 126 130 // from one block group until the next block group is found to set the duration of the 127 131 // previous ones to be the difference in timestamps. 128 132 vector<MatroskaFrame> lastFrames; 133 134 // insert pts values, sort, then smallest value is current dts if size > decode delay 135 list<TimeValue64> ptsReorder; 129 136 bool seenFirstBlock; 130 137 131 138 // this is the first sample number (if sample table) or sample time that we haven't
