mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed detecting frames on channels that broadcast with separate "fields" instead of complete frames
This commit is contained in:
parent
22f70b02e2
commit
d1dd7df17a
4
HISTORY
4
HISTORY
@ -6557,8 +6557,10 @@ Video Disk Recorder Revision History
|
||||
- The original display size of subtitles is now used to scale them properly when
|
||||
displaying them on an HD OSD.
|
||||
|
||||
2011-03-13: Version 1.7.18
|
||||
2011-03-20: Version 1.7.18
|
||||
|
||||
- Changed -O2 to -O3 in Make.config.template (reported by Matti Lehtimäki).
|
||||
- Added a missing 'default' case in cPixmapMemory::DrawEllipse().
|
||||
- Fixed some direct comparisons of double values.
|
||||
- Fixed detecting frames on channels that broadcast with separate "fields" instead
|
||||
of complete frames.
|
||||
|
40
remux.c
40
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.52 2011/03/13 13:57:09 kls Exp $
|
||||
* $Id: remux.c 2.53 2011/03/20 10:21:14 kls Exp $
|
||||
*/
|
||||
|
||||
#include "remux.h"
|
||||
@ -783,9 +783,11 @@ cFrameDetector::cFrameDetector(int Pid, int Type)
|
||||
synced = false;
|
||||
newFrame = independentFrame = false;
|
||||
numPtsValues = 0;
|
||||
numFrames = 0;
|
||||
numIFrames = 0;
|
||||
framesPerSecond = 0;
|
||||
framesInPayloadUnit = framesPerPayloadUnit = 0;
|
||||
payloadUnitOfFrame = 0;
|
||||
scanning = false;
|
||||
scanner = EMPTY_SCANNER;
|
||||
}
|
||||
@ -807,6 +809,7 @@ void cFrameDetector::SetPid(int Pid, int Type)
|
||||
void cFrameDetector::Reset(void)
|
||||
{
|
||||
newFrame = independentFrame = false;
|
||||
payloadUnitOfFrame = 0;
|
||||
scanning = false;
|
||||
scanner = EMPTY_SCANNER;
|
||||
}
|
||||
@ -844,6 +847,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
dbgframes("#");
|
||||
numPtsValues = 0;
|
||||
numIFrames = 0;
|
||||
numFrames = 0;
|
||||
}
|
||||
else
|
||||
numPtsValues++;
|
||||
@ -863,10 +867,23 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
framesPerSecond = 25.0;
|
||||
else if (Delta % 3003 == 0)
|
||||
framesPerSecond = 30.0 / 1.001;
|
||||
else if (abs(Delta - 1800) <= 1)
|
||||
framesPerSecond = 50.0;
|
||||
else if (abs(Delta - 1800) <= 1) {
|
||||
if (numFrames > 50) {
|
||||
// this is a "best guess": if there are more than 50 frames between two I-frames, we assume each "frame" actually contains a "field", so two "fields" make one "frame"
|
||||
framesPerSecond = 25.0;
|
||||
framesPerPayloadUnit = -2;
|
||||
}
|
||||
else
|
||||
framesPerSecond = 50.0;
|
||||
}
|
||||
else if (Delta == 1501)
|
||||
framesPerSecond = 60.0 / 1.001;
|
||||
if (numFrames > 50) {
|
||||
// this is a "best guess": if there are more than 50 frames between two I-frames, we assume each "frame" actually contains a "field", so two "fields" make one "frame"
|
||||
framesPerSecond = 30.0 / 1.001;
|
||||
framesPerPayloadUnit = -2;
|
||||
}
|
||||
else
|
||||
framesPerSecond = 60.0 / 1.001;
|
||||
else {
|
||||
framesPerSecond = 25.0;
|
||||
dsyslog("unknown frame delta (%d), assuming 25 fps", Delta);
|
||||
@ -874,7 +891,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
}
|
||||
else // audio
|
||||
framesPerSecond = 90000.0 / Delta; // PTS of audio frames is always increasing
|
||||
dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d\n", Delta, framesPerSecond, framesPerPayloadUnit);
|
||||
dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d NF = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numFrames);
|
||||
}
|
||||
}
|
||||
scanner = EMPTY_SCANNER;
|
||||
@ -909,6 +926,8 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
framesInPayloadUnit++;
|
||||
if (independentFrame)
|
||||
numIFrames++;
|
||||
if (numIFrames == 1)
|
||||
numFrames++;
|
||||
dbgframes("%d ", (Data[i + 2] >> 3) & 0x07);
|
||||
}
|
||||
if (synced)
|
||||
@ -923,6 +942,13 @@ 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;
|
||||
}
|
||||
@ -930,6 +956,8 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
framesInPayloadUnit++;
|
||||
if (independentFrame)
|
||||
numIFrames++;
|
||||
if (numIFrames == 1)
|
||||
numFrames++;
|
||||
dbgframes("%02X ", Data[i + 1]);
|
||||
}
|
||||
if (synced)
|
||||
@ -955,7 +983,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
||||
}
|
||||
if (!synced && framesPerSecond > 0.0 && independentFrame) {
|
||||
synced = true;
|
||||
dbgframes("*");
|
||||
dbgframes("*\n");
|
||||
Reset();
|
||||
return Processed + TS_SIZE;
|
||||
}
|
||||
|
7
remux.h
7
remux.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: remux.h 2.27 2010/11/01 11:24:20 kls Exp $
|
||||
* $Id: remux.h 2.28 2011/03/19 16:52:46 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __REMUX_H
|
||||
@ -345,12 +345,15 @@ private:
|
||||
bool independentFrame;
|
||||
uint32_t ptsValues[MaxPtsValues]; // 32 bit is enough - we only need the delta
|
||||
int numPtsValues;
|
||||
int numFrames;
|
||||
int numIFrames;
|
||||
bool isVideo;
|
||||
double framesPerSecond;
|
||||
int framesInPayloadUnit;
|
||||
int framesPerPayloadUnit; // Some broadcasters send one frame per payload unit (== 1),
|
||||
// while others put an entire GOP into one payload unit (> 1).
|
||||
// some put an entire GOP into one payload unit (> 1), and
|
||||
// some spread a single frame over several payload units (< 0).
|
||||
int payloadUnitOfFrame;
|
||||
bool scanning;
|
||||
uint32_t scanner;
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user