mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Fix bug: wrong start of video packet.
This commit is contained in:
parent
8dd95dab5e
commit
97af9c6de2
@ -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.
|
||||||
|
91
softhddev.c
91
softhddev.c
@ -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
|
||||||
|
&& data[4] == 0x0B && data[5] == 0x77) {
|
||||||
|
if (AudioCodecID != CODEC_ID_AC3) {
|
||||||
Debug(3, "[softhddev]%s: DVD Audio %d\n", __FUNCTION__, id);
|
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user