Stronger H264/Mpeg detection tests.

This commit is contained in:
Johns 2013-01-12 19:13:43 +01:00
parent 308742a927
commit 849ca7cfd6

View File

@ -1439,6 +1439,8 @@ static void VideoNextPacket(VideoStream * stream, int codec_id)
VideoResetPacket(stream); VideoResetPacket(stream);
} }
#ifdef USE_PIP
/** /**
** Place mpeg video data in packet ringbuffer. ** Place mpeg video data in packet ringbuffer.
** **
@ -1476,43 +1478,59 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
switch (stream->StartCodeState) { // prefix starting in last packet switch (stream->StartCodeState) { // prefix starting in last packet
case 3: // 0x00 0x00 0x01 seen case 3: // 0x00 0x00 0x01 seen
#ifdef DEBUG
fprintf(stderr, "last: %d\n", stream->StartCodeState); fprintf(stderr, "last: %d\n", stream->StartCodeState);
if (!p[0]) { #endif
if (!p[0] || p[0] == 0xb3) {
#ifdef DEBUG
fprintf(stderr, "last: %d start\n", stream->StartCodeState); fprintf(stderr, "last: %d start\n", stream->StartCodeState);
#endif
stream->PacketRb[stream->PacketWrite].stream_index -= 3; stream->PacketRb[stream->PacketWrite].stream_index -= 3;
VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO); VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
VideoEnqueue(stream, pts, startcode, 3); VideoEnqueue(stream, pts, startcode, 3);
first = p[0] == 0xb3;
p++; p++;
n--; n--;
pts = AV_NOPTS_VALUE;
} }
break; break;
case 2: // 0x00 0x00 seen case 2: // 0x00 0x00 seen
#ifdef DEBUG
fprintf(stderr, "last: %d\n", stream->StartCodeState); fprintf(stderr, "last: %d\n", stream->StartCodeState);
if (p[0] == 0x01 && !p[1]) { #endif
if (p[0] == 0x01 && (!p[1] || p[1] == 0xb3)) {
#ifdef DEBUG
fprintf(stderr, "last: %d start\n", stream->StartCodeState); fprintf(stderr, "last: %d start\n", stream->StartCodeState);
#endif
stream->PacketRb[stream->PacketWrite].stream_index -= 2; stream->PacketRb[stream->PacketWrite].stream_index -= 2;
VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO); VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
VideoEnqueue(stream, pts, startcode, 2); VideoEnqueue(stream, pts, startcode, 2);
first = p[1] == 0xb3;
p += 2; p += 2;
n -= 2; n -= 2;
pts = AV_NOPTS_VALUE;
} }
break; break;
case 1: // 0x00 seen case 1: // 0x00 seen
#ifdef DEBUG
fprintf(stderr, "last: %d\n", stream->StartCodeState); fprintf(stderr, "last: %d\n", stream->StartCodeState);
if (!p[0] && p[1] == 0x01 && !p[2]) { #endif
if (!p[0] && p[1] == 0x01 && (!p[2] || p[2] == 0xb3)) {
#ifdef DEBUG
fprintf(stderr, "last: %d start\n", stream->StartCodeState); fprintf(stderr, "last: %d start\n", stream->StartCodeState);
#endif
stream->PacketRb[stream->PacketWrite].stream_index -= 1; stream->PacketRb[stream->PacketWrite].stream_index -= 1;
VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO); VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
VideoEnqueue(stream, pts, startcode, 1); VideoEnqueue(stream, pts, startcode, 1);
first = p[2] == 0xb3;
p += 3; p += 3;
n -= 3; n -= 3;
pts = AV_NOPTS_VALUE;
} }
case 0: case 0:
break; break;
} }
//fprintf(stderr, "fix(%d): ", n);
// b3 b4 b8 00 b5 ... 00 b5 ... // b3 b4 b8 00 b5 ... 00 b5 ...
while (n > 3) { while (n > 3) {
@ -1520,6 +1538,7 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
fprintf(stderr, " %02x", p[3]); fprintf(stderr, " %02x", p[3]);
} }
// scan for picture header 0x00000100 // scan for picture header 0x00000100
// FIXME: not perfect, must split at 0xb3 also
if (!p[0] && !p[1] && p[2] == 0x01 && !p[3]) { if (!p[0] && !p[1] && p[2] == 0x01 && !p[3]) {
if (first) { if (first) {
first = 0; first = 0;
@ -1535,7 +1554,9 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
// first packet goes only upto picture header // first packet goes only upto picture header
VideoEnqueue(stream, pts, data, p - data); VideoEnqueue(stream, pts, data, p - data);
VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO); VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
#ifdef DEBUG
fprintf(stderr, "fix\r"); fprintf(stderr, "fix\r");
#endif
data = p; data = p;
size = n; size = n;
@ -1549,7 +1570,6 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
++p; ++p;
} }
//fprintf(stderr, ".\n");
stream->StartCodeState = 0; stream->StartCodeState = 0;
switch (n) { // handle packet border start code switch (n) { // handle packet border start code
case 3: case 3:
@ -1573,7 +1593,7 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
VideoEnqueue(stream, pts, data, size); VideoEnqueue(stream, pts, data, size);
} }
#ifndef USE_PIP #else
/** /**
** Fix packet for FFMpeg. ** Fix packet for FFMpeg.
@ -2065,9 +2085,10 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
} }
// H264 NAL AUD Access Unit Delimiter (0x00) 0x00 0x00 0x01 0x09 // H264 NAL AUD Access Unit Delimiter (0x00) 0x00 0x00 0x01 0x09
// and next start code
if ((data[6] & 0xC0) == 0x80 && z >= 2 && check[0] == 0x01 if ((data[6] & 0xC0) == 0x80 && z >= 2 && check[0] == 0x01
&& check[1] == 0x09) { && check[1] == 0x09 && !check[3] && !check[4]) {
// old PES HDTV recording z == 2 // old PES HDTV recording z == 2 -> stronger check!
if (stream->CodecID == CODEC_ID_H264) { if (stream->CodecID == CODEC_ID_H264) {
#if 0 #if 0
// this should improve ffwd+frew, but produce crash in ffmpeg // this should improve ffwd+frew, but produce crash in ffmpeg
@ -2095,8 +2116,8 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
VideoEnqueue(stream, pts, check - 2, l + 2); VideoEnqueue(stream, pts, check - 2, l + 2);
return size; return size;
} }
// PES start code 0x00 0x00 0x01 // PES start code 0x00 0x00 0x01 0x00|0xb3
if (z > 1 && check[0] == 0x01) { if (z > 1 && check[0] == 0x01 && (!check[1] || check[1] == 0xb3)) {
if (stream->CodecID == CODEC_ID_MPEG2VIDEO) { if (stream->CodecID == CODEC_ID_MPEG2VIDEO) {
VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO); VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
} else { } else {
@ -2109,7 +2130,11 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
} }
#endif #endif
// SKIP PES header, begin of start code // SKIP PES header, begin of start code
VideoMpegEnqueue(stream, pts, check - z, l + z); #ifdef USE_PIP
VideoMpegEnqueue(stream, pts, check - 2, l + 2);
#else
VideoEnqueue(stream, pts, check - 2, l + 2);
#endif
return size; return size;
} }
// this happens when vdr sends incomplete packets // this happens when vdr sends incomplete packets