mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed adjusting the DTS values in the cutter, to compensate for dropped B-frames
This commit is contained in:
parent
2eadd7d4dd
commit
b73c83e2a1
@ -2975,6 +2975,8 @@ S
|
||||
for pointing out that the name H264 should be used instead of MPEG4
|
||||
for pointing out that the cutter should only increment the TS continuity counter for
|
||||
packets that have a payload
|
||||
for pointing out that when adjusting the DTS values in the cutter, it hase to compensate
|
||||
for dropped B-frames
|
||||
|
||||
Peter Münster <pmlists@free.fr>
|
||||
for fixing 'make install' to not overwrite existing configuration files
|
||||
|
4
HISTORY
4
HISTORY
@ -7339,7 +7339,7 @@ Video Disk Recorder Revision History
|
||||
- Modified editing marks are now written to disk whenever the replay progress display
|
||||
gets hidden (thanks to Christoph Haubrich).
|
||||
|
||||
2012-11-27: Version 1.7.33
|
||||
2012-11-29: Version 1.7.33
|
||||
|
||||
- In order to be able to play TS recordings from other sources, in which there is
|
||||
more than one PMT PID in the PAT, 'int cPatPmtParser::PatPmt(void)' has been changed
|
||||
@ -7353,3 +7353,5 @@ Video Disk Recorder Revision History
|
||||
end mark.
|
||||
- The cutter now only increments the TS continuity counter for packets that have a
|
||||
payload (pointed out by Sören Moch).
|
||||
- Fixed adjusting the DTS values in the cutter, to compensate for dropped B-frames
|
||||
(pointed out by Sören Moch).
|
||||
|
53
cutter.c
53
cutter.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: cutter.c 2.19 2012/11/26 17:21:14 kls Exp $
|
||||
* $Id: cutter.c 2.20 2012/11/29 15:30:01 kls Exp $
|
||||
*/
|
||||
|
||||
#include "cutter.h"
|
||||
@ -154,8 +154,10 @@ bool cDanglingPacketStripper::Process(uchar *Data, int Length, int64_t FirstPts)
|
||||
class cPtsFixer {
|
||||
private:
|
||||
int delta; // time between two frames
|
||||
int64_t last; // the last (i.e. highest) video PTS value seen
|
||||
int64_t offset; // offset to add to PTS values
|
||||
int64_t deltaDts; // the difference between two consecutive DTS values (may differ from 'delta' in case of multiple fields per frame)
|
||||
int64_t lastPts; // the video PTS of the last frame (in display order)
|
||||
int64_t lastDts; // the last video DTS value seen
|
||||
int64_t offset; // offset to add to all timestamps
|
||||
bool fixCounters; // controls fixing the TS continuity counters (only from the second CutIn up)
|
||||
uchar counter[MAXPID]; // the TS continuity counter for each PID
|
||||
cPatPmtParser patPmtParser;
|
||||
@ -168,7 +170,9 @@ public:
|
||||
cPtsFixer::cPtsFixer(void)
|
||||
{
|
||||
delta = 0;
|
||||
last = -1;
|
||||
deltaDts = 0;
|
||||
lastPts = -1;
|
||||
lastDts = -1;
|
||||
offset = -1;
|
||||
fixCounters = false;
|
||||
memset(counter, 0x00, sizeof(counter));
|
||||
@ -186,11 +190,11 @@ void cPtsFixer::Fix(uchar *Data, int Length, bool CutIn)
|
||||
return;
|
||||
}
|
||||
// Determine the PTS offset at the beginning of each sequence (except the first one):
|
||||
if (CutIn && last >= 0) {
|
||||
if (CutIn && lastPts >= 0) {
|
||||
int64_t Pts = TsGetPts(Data, Length);
|
||||
if (Pts >= 0) {
|
||||
// offset is calculated so that Pts + offset results in last + delta:
|
||||
offset = Pts - PtsAdd(last, delta);
|
||||
// offset is calculated so that Pts + offset results in lastPts + delta:
|
||||
offset = Pts - PtsAdd(lastPts, delta);
|
||||
if (offset <= 0)
|
||||
offset = -offset;
|
||||
else
|
||||
@ -199,14 +203,32 @@ void cPtsFixer::Fix(uchar *Data, int Length, bool CutIn)
|
||||
fixCounters = true;
|
||||
}
|
||||
// Keep track of the highest video PTS:
|
||||
bool GotPts = false;
|
||||
int64_t PrevDts = lastDts;
|
||||
uchar *p = Data;
|
||||
int len = Length;
|
||||
while (len >= TS_SIZE && *p == TS_SYNC_BYTE) {
|
||||
int Pid = TsPid(p);
|
||||
if (Pid == patPmtParser.Vpid()) {
|
||||
int64_t Pts = PtsAdd(TsGetPts(p, TS_SIZE), offset); // offset is taken into account here, to make last have the "new" value already!
|
||||
if (Pts >= 0 && (last < 0 || PtsDiff(last, Pts) > 0))
|
||||
last = Pts;
|
||||
if (!GotPts) { // in case of multiple fields per frame, the offset is calculated only with the first one
|
||||
int64_t Pts = TsGetPts(p, TS_SIZE);
|
||||
if (Pts >= 0) {
|
||||
if (offset >= 0)
|
||||
Pts = PtsAdd(Pts, offset); // offset is taken into account here, to make lastPts have the "new" value already!
|
||||
if (lastPts < 0 || PtsDiff(lastPts, Pts) > 0)
|
||||
lastPts = Pts;
|
||||
}
|
||||
GotPts = true;
|
||||
}
|
||||
if (!CutIn) {
|
||||
int64_t Dts = TsGetDts(p, TS_SIZE);
|
||||
if (Dts >= 0) {
|
||||
if (offset >= 0)
|
||||
Dts = PtsAdd(Dts, offset); // offset is taken into account here, to make lastDts have the "new" value already!
|
||||
deltaDts = PtsDiff(PrevDts, Dts);
|
||||
PrevDts = Dts;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Adjust the TS continuity counter:
|
||||
if (fixCounters) {
|
||||
@ -229,8 +251,14 @@ void cPtsFixer::Fix(uchar *Data, int Length, bool CutIn)
|
||||
if (Pts >= 0)
|
||||
TsSetPts(p, TS_SIZE, PtsAdd(Pts, offset));
|
||||
int64_t Dts = TsGetDts(p, TS_SIZE);
|
||||
if (Dts >= 0)
|
||||
TsSetDts(p, TS_SIZE, PtsAdd(Dts, offset));
|
||||
if (Dts >= 0) {
|
||||
if (CutIn) {
|
||||
lastDts = PtsAdd(lastDts, deltaDts);
|
||||
TsSetDts(p, TS_SIZE, lastDts);
|
||||
}
|
||||
else
|
||||
TsSetDts(p, TS_SIZE, PtsAdd(Dts, offset));
|
||||
}
|
||||
int64_t Pcr = TsGetPcr(p);
|
||||
if (Pcr >= 0) {
|
||||
int64_t NewPcr = Pcr + offset * PCRFACTOR;
|
||||
@ -242,6 +270,7 @@ void cPtsFixer::Fix(uchar *Data, int Length, bool CutIn)
|
||||
len -= TS_SIZE;
|
||||
}
|
||||
}
|
||||
lastDts = PrevDts;
|
||||
}
|
||||
|
||||
// --- cCuttingThread --------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user