mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed frame detection when regenerating the index
This commit is contained in:
parent
f98ae169e1
commit
3ad369d249
94
remux.c
94
remux.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remux.c 2.68 2012/11/02 14:35:57 kls Exp $
|
* $Id: remux.c 2.69 2012/11/06 10:59:39 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remux.h"
|
#include "remux.h"
|
||||||
@ -991,8 +991,6 @@ cMpeg2Parser::cMpeg2Parser(void)
|
|||||||
int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
|
int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
|
||||||
{
|
{
|
||||||
newFrame = independentFrame = false;
|
newFrame = independentFrame = false;
|
||||||
if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE)
|
|
||||||
return 0; // need more data
|
|
||||||
cTsPayload tsPayload(const_cast<uchar *>(Data), Length, Pid);
|
cTsPayload tsPayload(const_cast<uchar *>(Data), Length, Pid);
|
||||||
if (TsPayloadStart(Data)) {
|
if (TsPayloadStart(Data)) {
|
||||||
tsPayload.SkipPesHeader();
|
tsPayload.SkipPesHeader();
|
||||||
@ -1000,23 +998,27 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
|
|||||||
if (debug && seenIndependentFrame)
|
if (debug && seenIndependentFrame)
|
||||||
dbgframes("/");
|
dbgframes("/");
|
||||||
}
|
}
|
||||||
do {
|
for (;;) {
|
||||||
scanner = (scanner << 8) | tsPayload.GetByte();
|
scanner = (scanner << 8) | tsPayload.GetByte();
|
||||||
if (scanner == 0x00000100) { // Picture Start Code
|
if (scanner == 0x00000100) { // Picture Start Code
|
||||||
newFrame = true;
|
newFrame = true;
|
||||||
tsPayload.GetByte();
|
tsPayload.GetByte();
|
||||||
uchar FrameType = (tsPayload.GetByte() >> 3) & 0x07;
|
uchar FrameType = (tsPayload.GetByte() >> 3) & 0x07;
|
||||||
independentFrame = FrameType == 1; // I-Frame
|
independentFrame = FrameType == 1; // I-Frame
|
||||||
if (debug) {
|
if (debug) {
|
||||||
seenIndependentFrame |= independentFrame;
|
seenIndependentFrame |= independentFrame;
|
||||||
if (seenIndependentFrame) {
|
if (seenIndependentFrame) {
|
||||||
static const char FrameTypes[] = "?IPBD???";
|
static const char FrameTypes[] = "?IPBD???";
|
||||||
dbgframes("%c", FrameTypes[FrameType]);
|
dbgframes("%c", FrameTypes[FrameType]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (tsPayload.Available() > (MIN_TS_PACKETS_FOR_FRAME_DETECTOR - 1) * TS_SIZE);
|
if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
|
||||||
|
|| (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit...
|
||||||
|
&& (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
|
||||||
|
break;
|
||||||
|
}
|
||||||
return tsPayload.Used();
|
return tsPayload.Used();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1133,8 +1135,6 @@ int32_t cMpeg4Parser::GetGolombSe(void)
|
|||||||
int cMpeg4Parser::Parse(const uchar *Data, int Length, int Pid)
|
int cMpeg4Parser::Parse(const uchar *Data, int Length, int Pid)
|
||||||
{
|
{
|
||||||
newFrame = independentFrame = false;
|
newFrame = independentFrame = false;
|
||||||
if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE)
|
|
||||||
return 0; // need more data
|
|
||||||
tsPayload.Setup(const_cast<uchar *>(Data), Length, Pid);
|
tsPayload.Setup(const_cast<uchar *>(Data), Length, Pid);
|
||||||
if (TsPayloadStart(Data)) {
|
if (TsPayloadStart(Data)) {
|
||||||
tsPayload.SkipPesHeader();
|
tsPayload.SkipPesHeader();
|
||||||
@ -1143,28 +1143,32 @@ int cMpeg4Parser::Parse(const uchar *Data, int Length, int Pid)
|
|||||||
dbgframes("/");
|
dbgframes("/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
do {
|
for (;;) {
|
||||||
scanner = (scanner << 8) | GetByte(true);
|
scanner = (scanner << 8) | GetByte(true);
|
||||||
if ((scanner & 0xFFFFFF00) == 0x00000100) { // NAL unit start
|
if ((scanner & 0xFFFFFF00) == 0x00000100) { // NAL unit start
|
||||||
uchar NalUnitType = scanner & 0x1F;
|
uchar NalUnitType = scanner & 0x1F;
|
||||||
switch (NalUnitType) {
|
switch (NalUnitType) {
|
||||||
case nutAccessUnitDelimiter: ParseAccessUnitDelimiter();
|
case nutAccessUnitDelimiter: ParseAccessUnitDelimiter();
|
||||||
gotAccessUnitDelimiter = true;
|
gotAccessUnitDelimiter = true;
|
||||||
break;
|
break;
|
||||||
case nutSequenceParameterSet: ParseSequenceParameterSet();
|
case nutSequenceParameterSet: ParseSequenceParameterSet();
|
||||||
gotSequenceParameterSet = true;
|
gotSequenceParameterSet = true;
|
||||||
break;
|
break;
|
||||||
case nutCodedSliceNonIdr:
|
case nutCodedSliceNonIdr:
|
||||||
case nutCodedSliceIdr: if (gotAccessUnitDelimiter && gotSequenceParameterSet) {
|
case nutCodedSliceIdr: if (gotAccessUnitDelimiter && gotSequenceParameterSet) {
|
||||||
ParseSliceHeader();
|
ParseSliceHeader();
|
||||||
gotAccessUnitDelimiter = false;
|
gotAccessUnitDelimiter = false;
|
||||||
return tsPayload.Used();
|
return tsPayload.Used();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (tsPayload.Available() > (MIN_TS_PACKETS_FOR_FRAME_DETECTOR - 1) * TS_SIZE);
|
if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
|
||||||
|
|| (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit...
|
||||||
|
&& (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
|
||||||
|
break;
|
||||||
|
}
|
||||||
return tsPayload.Used();
|
return tsPayload.Used();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1324,8 +1328,6 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
|||||||
int n = parser->Parse(Data, Length, pid);
|
int n = parser->Parse(Data, Length, pid);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
if (parser->NewFrame()) {
|
if (parser->NewFrame()) {
|
||||||
if (Processed)
|
|
||||||
return Processed; // flush everything before this new frame
|
|
||||||
newFrame = true;
|
newFrame = true;
|
||||||
independentFrame = parser->IndependentFrame();
|
independentFrame = parser->IndependentFrame();
|
||||||
if (synced) {
|
if (synced) {
|
||||||
|
10
remux.h
10
remux.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remux.h 2.33 2012/11/02 14:33:11 kls Exp $
|
* $Id: remux.h 2.34 2012/11/06 11:03:06 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REMUX_H
|
#ifndef __REMUX_H
|
||||||
@ -158,7 +158,7 @@ private:
|
|||||||
uchar *data;
|
uchar *data;
|
||||||
int length;
|
int length;
|
||||||
int pid;
|
int pid;
|
||||||
int index; // points to the next byte to process
|
int index; // points to the next byte to process
|
||||||
public:
|
public:
|
||||||
cTsPayload(void);
|
cTsPayload(void);
|
||||||
cTsPayload(uchar *Data, int Length, int Pid = -1);
|
cTsPayload(uchar *Data, int Length, int Pid = -1);
|
||||||
@ -171,6 +171,12 @@ public:
|
|||||||
///< Otherwise the PID of the first TS packet defines which payload will be
|
///< Otherwise the PID of the first TS packet defines which payload will be
|
||||||
///< delivered.
|
///< delivered.
|
||||||
///< Any intermediate TS packets with different PIDs will be skipped.
|
///< Any intermediate TS packets with different PIDs will be skipped.
|
||||||
|
bool AtTsStart(void) { return index < length && (index % TS_SIZE) == 0; }
|
||||||
|
///< Returns true if this payload handler is currently pointing to first byte
|
||||||
|
///< of a TS packet.
|
||||||
|
bool AtPayloadStart(void) { return AtTsStart() && TsPayloadStart(data + index); }
|
||||||
|
///< Returns true if this payload handler is currently pointing to the first byte
|
||||||
|
///< of a TS packet that starts a new payload.
|
||||||
int Available(void) { return length - index; }
|
int Available(void) { return length - index; }
|
||||||
///< Returns the number of raw bytes (including any TS headers) still available
|
///< Returns the number of raw bytes (including any TS headers) still available
|
||||||
///< in the TS payload handler.
|
///< in the TS payload handler.
|
||||||
|
Loading…
Reference in New Issue
Block a user