Fix bug: wrong start of video packet.

This commit is contained in:
Johns 2012-02-15 22:19:50 +01:00
parent 8dd95dab5e
commit 97af9c6de2
2 changed files with 45 additions and 49 deletions

View File

@ -1,5 +1,6 @@
User johns User johns
Fix bug: wrong start of video packet.
VDPAU: Enables inverse telecine configuration. VDPAU: Enables inverse telecine configuration.
Find AC3 (Dolby Digital) inside PES packet. Find AC3 (Dolby Digital) inside PES packet.
Fix bug: audio increments invalid audio PTS. Fix bug: audio increments invalid audio PTS.

View File

@ -71,6 +71,7 @@ static volatile char StreamFreezed; ///< stream freezed
static volatile char NewAudioStream; ///< new audio stream static volatile char NewAudioStream; ///< new audio stream
static volatile char SkipAudio; ///< skip audio stream static volatile char SkipAudio; ///< skip audio stream
static char AudioRawAc3; ///< flag raw ac3 stream
static AudioDecoder *MyAudioDecoder; ///< audio decoder static AudioDecoder *MyAudioDecoder; ///< audio decoder
static enum CodecID AudioCodecID; ///< current codec id static enum CodecID AudioCodecID; ///< current codec id
static int AudioChannelID; ///< current audio channel id static int AudioChannelID; ///< current audio channel id
@ -199,44 +200,16 @@ static int FindAudioSync(const AVPacket * avpkt)
** from ATSC A/52 table 5.18 frame size code table. ** from ATSC A/52 table 5.18 frame size code table.
*/ */
const uint16_t Ac3FrameSizeTable[38][3] = { const uint16_t Ac3FrameSizeTable[38][3] = {
{64, 69, 96}, {64, 69, 96}, {64, 70, 96}, {80, 87, 120}, {80, 88, 120},
{64, 70, 96}, {96, 104, 144}, {96, 105, 144}, {112, 121, 168}, {112, 122, 168},
{80, 87, 120}, {128, 139, 192}, {128, 140, 192}, {160, 174, 240}, {160, 175, 240},
{80, 88, 120}, {192, 208, 288}, {192, 209, 288}, {224, 243, 336}, {224, 244, 336},
{96, 104, 144}, {256, 278, 384}, {256, 279, 384}, {320, 348, 480}, {320, 349, 480},
{96, 105, 144}, {384, 417, 576}, {384, 418, 576}, {448, 487, 672}, {448, 488, 672},
{112, 121, 168}, {512, 557, 768}, {512, 558, 768}, {640, 696, 960}, {640, 697, 960},
{112, 122, 168}, {768, 835, 1152}, {768, 836, 1152}, {896, 975, 1344}, {896, 976, 1344},
{128, 139, 192}, {1024, 1114, 1536}, {1024, 1115, 1536}, {1152, 1253, 1728},
{128, 140, 192}, {1152, 1254, 1728}, {1280, 1393, 1920}, {1280, 1394, 1920},
{160, 174, 240},
{160, 175, 240},
{192, 208, 288},
{192, 209, 288},
{224, 243, 336},
{224, 244, 336},
{256, 278, 384},
{256, 279, 384},
{320, 348, 480},
{320, 349, 480},
{384, 417, 576},
{384, 418, 576},
{448, 487, 672},
{448, 488, 672},
{512, 557, 768},
{512, 558, 768},
{640, 696, 960},
{640, 697, 960},
{768, 835, 1152},
{768, 836, 1152},
{896, 975, 1344},
{896, 976, 1344},
{1024, 1114, 1536},
{1024, 1115, 1536},
{1152, 1253, 1728},
{1152, 1254, 1728},
{1280, 1393, 1920},
{1280, 1394, 1920},
}; };
/** /**
@ -354,6 +327,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_AC3); CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_AC3);
AudioCodecID = CODEC_ID_AC3; AudioCodecID = CODEC_ID_AC3;
} }
AudioRawAc3 = 1;
// Syncword - 0xFFFC - 0xFFFF // Syncword - 0xFFFC - 0xFFFF
} else if (data[0] == 0xFF && (data[1] & 0xFC) == 0xFC) { } else if (data[0] == 0xFF && (data[1] & 0xFC) == 0xFC) {
if (AudioCodecID != CODEC_ID_MP2) { if (AudioCodecID != CODEC_ID_MP2) {
@ -379,9 +353,16 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_AAC_LATM); CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_AAC_LATM);
AudioCodecID = CODEC_ID_AAC_LATM; AudioCodecID = CODEC_ID_AAC_LATM;
} }
// Private stream + LPCM ID // Private stream + DVD Track ID Syncword - 0x0B77
} else if (data[-n - 9 + 3] == 0xBD && data[0] == 0x80) { } else if (data[-n - 9 + 3] == 0xBD && (data[0] & 0xF0) == 0x80
Debug(3, "[softhddev]%s: DVD Audio %d\n", __FUNCTION__, id); && data[4] == 0x0B && data[5] == 0x77) {
if (AudioCodecID != CODEC_ID_AC3) {
Debug(3, "[softhddev]%s: DVD Audio %d\n", __FUNCTION__, id);
CodecAudioClose(MyAudioDecoder);
CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_AC3);
AudioCodecID = CODEC_ID_AC3;
}
AudioRawAc3 = 0;
// Private stream + LPCM ID // Private stream + LPCM ID
} else if (data[-n - 9 + 3] == 0xBD && data[0] == 0xA0) { } else if (data[-n - 9 + 3] == 0xBD && data[0] == 0xA0) {
if (AudioCodecID != CODEC_ID_PCM_DVD) { if (AudioCodecID != CODEC_ID_PCM_DVD) {
@ -432,9 +413,12 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
if (AudioChannelID == 0xBD) { if (AudioChannelID == 0xBD) {
n = FindDolbySync(avpkt); n = FindDolbySync(avpkt);
codec_id = CODEC_ID_AC3; codec_id = CODEC_ID_AC3;
} else { AudioRawAc3 = 1;
} else if (0xC0 <= AudioChannelID && AudioChannelID <= 0xDF) {
n = FindAudioSync(avpkt); n = FindAudioSync(avpkt);
codec_id = CODEC_ID_MP2; codec_id = CODEC_ID_MP2;
} else {
n = -1;
} }
if (n < 0) { if (n < 0) {
return osize; return osize;
@ -452,11 +436,23 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
return osize; return osize;
} }
} }
// convert data, if needed for ffmpeg
if (AudioCodecID == CODEC_ID_PCM_DVD) { if (AudioCodecID == CODEC_ID_AC3 && !AudioRawAc3
&& (data[0] & 0xF0) == 0x80) {
avpkt->data = (void *)data + 4; // skip track header
avpkt->size = size - 4;
if (avpkt->pts != (int64_t) AV_NOPTS_VALUE) {
avpkt->pts += 200 * 90; // FIXME: needs bigger buffer
}
CodecAudioDecode(MyAudioDecoder, avpkt);
} else if (AudioCodecID == CODEC_ID_PCM_DVD) {
if (size > 7) { if (size > 7) {
char *buf; char *buf;
if (avpkt->pts != (int64_t) AV_NOPTS_VALUE) {
// FIXME: needs bigger buffer
AudioSetClock(avpkt->pts + 200 * 90);
}
if (!(buf = malloc(size - 7))) { if (!(buf = malloc(size - 7))) {
Error(_("softhddev: out of memory\n")); Error(_("softhddev: out of memory\n"));
} else { } else {
@ -1020,7 +1016,7 @@ int PlayVideo(const uint8_t * data, int size)
VideoCodecID = CODEC_ID_H264; VideoCodecID = CODEC_ID_H264;
} }
// SKIP PES header // SKIP PES header
VideoEnqueue(pts, check - 5, l + 5); VideoEnqueue(pts, check - 3, l + 3);
return size; return size;
} }
// PES start code 0x00 0x00 0x01 // PES start code 0x00 0x00 0x01
@ -1037,7 +1033,7 @@ int PlayVideo(const uint8_t * data, int size)
} }
#endif #endif
// SKIP PES header // SKIP PES header
VideoEnqueue(pts, check - 3, l + 3); VideoEnqueue(pts, check - 2, l + 2);
return size; return size;
} }
// this happens when vdr sends incomplete packets // this happens when vdr sends incomplete packets
@ -1056,7 +1052,6 @@ int PlayVideo(const uint8_t * data, int size)
// mpeg codec supports incomplete packets // mpeg codec supports incomplete packets
// waiting for a full complete packages, increases needed delays // waiting for a full complete packages, increases needed delays
VideoNextPacket(CODEC_ID_MPEG2VIDEO); VideoNextPacket(CODEC_ID_MPEG2VIDEO);
return size;
} }
return size; return size;
@ -1243,6 +1238,7 @@ void Clear(void)
VideoResetPacket(); // terminate work VideoResetPacket(); // terminate work
VideoClearBuffers = 1; VideoClearBuffers = 1;
AudioFlushBuffers(); AudioFlushBuffers();
//NewAudioStream = 1;
// FIXME: audio avcodec_flush_buffers, video is done by VideoClearBuffers // FIXME: audio avcodec_flush_buffers, video is done by VideoClearBuffers
for (i = 0; VideoClearBuffers && i < 20; ++i) { for (i = 0; VideoClearBuffers && i < 20; ++i) {
@ -1347,8 +1343,7 @@ int Poll(int timeout)
{ {
// buffers are too full // buffers are too full
if (atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX / 2) { if (atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX / 2) {
if (timeout) { if (timeout) { // let display thread work
// let display thread work
usleep(timeout * 1000); usleep(timeout * 1000);
} }
return atomic_read(&VideoPacketsFilled) < VIDEO_PACKET_MAX / 2; return atomic_read(&VideoPacketsFilled) < VIDEO_PACKET_MAX / 2;