mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Fixed detecting frames on channels that broadcast with 50 or 60 fps
This commit is contained in:
47
remux.c
47
remux.c
@@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: remux.c 2.47 2010/06/05 13:32:15 kls Exp $
|
||||
* $Id: remux.c 2.48 2010/11/01 12:29:17 kls Exp $
|
||||
*/
|
||||
|
||||
#include "remux.h"
|
||||
@@ -780,9 +780,8 @@ cFrameDetector::cFrameDetector(int Pid, int Type)
|
||||
newFrame = independentFrame = false;
|
||||
numPtsValues = 0;
|
||||
numIFrames = 0;
|
||||
frameDuration = 0;
|
||||
framesPerSecond = 0;
|
||||
framesInPayloadUnit = framesPerPayloadUnit = 0;
|
||||
payloadUnitOfFrame = 0;
|
||||
scanning = false;
|
||||
scanner = EMPTY_SCANNER;
|
||||
}
|
||||
@@ -804,7 +803,6 @@ void cFrameDetector::SetPid(int Pid, int Type)
|
||||
void cFrameDetector::Reset(void)
|
||||
{
|
||||
newFrame = independentFrame = false;
|
||||
payloadUnitOfFrame = 0;
|
||||
scanning = false;
|
||||
scanner = EMPTY_SCANNER;
|
||||
}
|
||||
@@ -831,8 +829,8 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
return Processed;
|
||||
if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE)
|
||||
return Processed; // need more data, in case the frame type is not stored in the first TS packet
|
||||
if (!frameDuration) {
|
||||
// frame duration unknown, so collect a sequence of PTS values:
|
||||
if (!framesPerSecond) {
|
||||
// frame rate unknown, so collect a sequence of PTS values:
|
||||
if (numPtsValues < MaxPtsValues && numIFrames < 2) { // collect a sequence containing at least two I-frames
|
||||
const uchar *Pes = Data + TsPayloadOffset(Data);
|
||||
if (PesHasPts(Pes)) {
|
||||
@@ -857,28 +855,22 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
uint32_t Delta = ptsValues[0];
|
||||
// determine frame info:
|
||||
if (isVideo) {
|
||||
if (Delta % 3600 == 0)
|
||||
frameDuration = 3600; // PAL, 25 fps, exact timing
|
||||
else if (abs(Delta % 3600) == 3599 || abs(Delta % 3600) == 1)
|
||||
frameDuration = 3600; // PAL, 25 fps, timing with jitter
|
||||
if (abs(Delta - 3600) <= 1)
|
||||
framesPerSecond = 25.0;
|
||||
else if (Delta % 3003 == 0)
|
||||
frameDuration = 3003; // NTSC, 29.97 fps
|
||||
else if (abs(Delta - 1800) <= 1) {
|
||||
frameDuration = 3600; // PAL, 25 fps
|
||||
framesPerPayloadUnit = -2;
|
||||
}
|
||||
else if (Delta == 1501) {
|
||||
frameDuration = 3003; // NTSC, 29.97 fps
|
||||
framesPerPayloadUnit = -2;
|
||||
}
|
||||
framesPerSecond = 30.0 / 1.001;
|
||||
else if (abs(Delta - 1800) <= 1)
|
||||
framesPerSecond = 50.0;
|
||||
else if (Delta == 1501)
|
||||
framesPerSecond = 60.0 / 1.001;
|
||||
else {
|
||||
frameDuration = 3600; // unknown, assuming 25 fps
|
||||
dsyslog("unknown frame duration (%d), assuming 25 fps", Delta);
|
||||
framesPerSecond = 25.0;
|
||||
dsyslog("unknown frame delta (%d), assuming 25 fps", Delta);
|
||||
}
|
||||
}
|
||||
else // audio
|
||||
frameDuration = Delta; // PTS of audio frames is always increasing
|
||||
dbgframes("\nframe duration = %d FPS = %5.2f FPPU = %d\n", frameDuration, 90000.0 / frameDuration, framesPerPayloadUnit);
|
||||
framesPerSecond = 90000.0 / Delta; // PTS of audio frames is always increasing
|
||||
dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d\n", Delta, framesPerSecond, framesPerPayloadUnit);
|
||||
}
|
||||
}
|
||||
scanner = EMPTY_SCANNER;
|
||||
@@ -927,13 +919,6 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
newFrame = true;
|
||||
independentFrame = Data[i + 1] == 0x10;
|
||||
if (synced) {
|
||||
if (framesPerPayloadUnit < 0) {
|
||||
payloadUnitOfFrame = (payloadUnitOfFrame + 1) % -framesPerPayloadUnit;
|
||||
if (payloadUnitOfFrame != 0 && independentFrame)
|
||||
payloadUnitOfFrame = 0;
|
||||
if (payloadUnitOfFrame)
|
||||
newFrame = false;
|
||||
}
|
||||
if (framesPerPayloadUnit <= 1)
|
||||
scanning = false;
|
||||
}
|
||||
@@ -964,7 +949,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
pid = 0; // let's just ignore any further data
|
||||
}
|
||||
}
|
||||
if (!synced && frameDuration && independentFrame) {
|
||||
if (!synced && framesPerSecond && independentFrame) {
|
||||
synced = true;
|
||||
dbgframes("*");
|
||||
Reset();
|
||||
|
Reference in New Issue
Block a user