mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Search audio sync inside PES packets.
This commit is contained in:
parent
0d63fac2e8
commit
d2606a5d5f
144
softhddev.c
144
softhddev.c
@ -1,7 +1,7 @@
|
|||||||
///
|
///
|
||||||
/// @file softhddev.c @brief A software HD device plugin for VDR.
|
/// @file softhddev.c @brief A software HD device plugin for VDR.
|
||||||
///
|
///
|
||||||
/// Copyright (c) 2011 by Johns. All Rights Reserved.
|
/// Copyright (c) 2011, 2012 by Johns. All Rights Reserved.
|
||||||
///
|
///
|
||||||
/// Contributor(s):
|
/// Contributor(s):
|
||||||
///
|
///
|
||||||
@ -59,6 +59,122 @@ static enum CodecID AudioCodecID; ///< current codec id
|
|||||||
|
|
||||||
extern void AudioTest(void); // FIXME:
|
extern void AudioTest(void); // FIXME:
|
||||||
|
|
||||||
|
/**
|
||||||
|
** mpeg bitrate table.
|
||||||
|
**
|
||||||
|
** BitRateTable[Version][Layer][Index]
|
||||||
|
*/
|
||||||
|
static const uint16_t BitRateTable[2][4][16] = {
|
||||||
|
// MPEG Version 1
|
||||||
|
{{},
|
||||||
|
{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,
|
||||||
|
0},
|
||||||
|
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0},
|
||||||
|
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}},
|
||||||
|
// MPEG Version 2 & 2.5
|
||||||
|
{{},
|
||||||
|
{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0},
|
||||||
|
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
|
||||||
|
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
** mpeg samperate table.
|
||||||
|
*/
|
||||||
|
static const uint16_t SampleRateTable[4] = {
|
||||||
|
44100, 48000, 32000, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Find sync in audio packet.
|
||||||
|
**
|
||||||
|
** @param avpkt audio packet
|
||||||
|
**
|
||||||
|
** From: http://www.mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm
|
||||||
|
**
|
||||||
|
** AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
|
||||||
|
**
|
||||||
|
** o a 11x frame sync
|
||||||
|
** o b 2x mpeg audio version (2.5, reserved, 2, 1)
|
||||||
|
** o c 2x layer (reserved, III, II, I)
|
||||||
|
** o e 2x BitRate index
|
||||||
|
** o f 2x SampleRate index
|
||||||
|
** o g 1x Paddding bit
|
||||||
|
** o .. doesn't care
|
||||||
|
**
|
||||||
|
** frame length:
|
||||||
|
** Layer I:
|
||||||
|
** FrameLengthInBytes = (12 * BitRate / SampleRate + Padding) * 4
|
||||||
|
** Layer II & III:
|
||||||
|
** FrameLengthInBytes = 144 * BitRate / SampleRate + Padding
|
||||||
|
*/
|
||||||
|
static int FindAudioSync(const AVPacket * avpkt)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const uint8_t *data;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
data = avpkt->data;
|
||||||
|
while (i < avpkt->size - 4) {
|
||||||
|
if (data[i] == 0xFF && (data[i + 1] & 0xFC) == 0xFC) {
|
||||||
|
int mpeg2;
|
||||||
|
int mpeg25;
|
||||||
|
int layer;
|
||||||
|
int bit_rate_index;
|
||||||
|
int sample_rate_index;
|
||||||
|
int padding;
|
||||||
|
int bit_rate;
|
||||||
|
int sample_rate;
|
||||||
|
int frame_size;
|
||||||
|
|
||||||
|
mpeg2 = !(data[i + 1] & 0x08) && (data[i + 1] & 0x10);
|
||||||
|
mpeg25 = !(data[i + 1] & 0x08) && !(data[i + 1] & 0x10);
|
||||||
|
layer = 4 - ((data[i + 1] >> 1) & 0x03);
|
||||||
|
bit_rate_index = (data[i + 2] >> 4) & 0x0F;
|
||||||
|
sample_rate_index = (data[i + 2] >> 2) & 0x03;
|
||||||
|
padding = (data[i + 2] >> 1) & 0x01;
|
||||||
|
|
||||||
|
sample_rate = SampleRateTable[sample_rate_index];
|
||||||
|
if (!sample_rate) { // no valid sample rate try next
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sample_rate >>= mpeg2; // mpeg 2 half rate
|
||||||
|
sample_rate >>= mpeg25; // mpeg 2.5 quarter rate
|
||||||
|
|
||||||
|
bit_rate = BitRateTable[mpeg2 | mpeg25][layer][bit_rate_index];
|
||||||
|
bit_rate *= 1000;
|
||||||
|
switch (layer) {
|
||||||
|
case 1:
|
||||||
|
frame_size = (12 * bit_rate) / sample_rate;
|
||||||
|
frame_size = (frame_size + padding) * 4;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
frame_size = (144 * bit_rate) / sample_rate;
|
||||||
|
frame_size = frame_size + padding;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Debug(3,
|
||||||
|
"audio: mpeg%s layer%d bitrate=%d samplerate=%d %d bytes\n",
|
||||||
|
mpeg25 ? "2.5" : mpeg2 ? "2" : "1", layer, bit_rate,
|
||||||
|
sample_rate, frame_size);
|
||||||
|
if (i + frame_size < avpkt->size - 4) {
|
||||||
|
if (data[i + frame_size] == 0xFF
|
||||||
|
&& (data[i + frame_size + 1] & 0xFC) == 0xFC) {
|
||||||
|
Debug(3, "audio: mpeg1/2 found at %d\n", i);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// no valid frame size or no continuation, try next
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Play audio packet.
|
** Play audio packet.
|
||||||
**
|
**
|
||||||
@ -74,13 +190,10 @@ void PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
if (BrokenThreadsAndPlugins) {
|
if (BrokenThreadsAndPlugins) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// PES header 0x00 0x00 0x01 ID
|
|
||||||
// ID 0xBD 0xC0-0xCF
|
|
||||||
|
|
||||||
// channel switch: SetAudioChannelDevice: SetDigitalAudioDevice:
|
// channel switch: SetAudioChannelDevice: SetDigitalAudioDevice:
|
||||||
|
|
||||||
// Detect audio code
|
// PES header 0x00 0x00 0x01 ID
|
||||||
// MPEG-PS mp2 MPEG1, MPEG2, AC3
|
// ID 0xBD 0xC0-0xCF
|
||||||
|
|
||||||
if (size < 9) {
|
if (size < 9) {
|
||||||
Error(_("[softhddev] invalid audio packet\n"));
|
Error(_("[softhddev] invalid audio packet\n"));
|
||||||
@ -111,6 +224,9 @@ void PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
Error(_("[softhddev] invalid audio packet\n"));
|
Error(_("[softhddev] invalid audio packet\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Detect audio code
|
||||||
|
// MPEG-PS mp2 MPEG1, MPEG2, AC3
|
||||||
|
|
||||||
// Syncword - 0x0B77
|
// Syncword - 0x0B77
|
||||||
if (data[0] == 0x0B && data[1] == 0x77) {
|
if (data[0] == 0x0B && data[1] == 0x77) {
|
||||||
if (!MyAudioDecoder) {
|
if (!MyAudioDecoder) {
|
||||||
@ -141,9 +257,23 @@ void PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
// no start package
|
// no start package
|
||||||
// FIXME: Nick/Viva sends this shit, need to find sync in packet
|
// FIXME: Nick/Viva sends this shit, need to find sync in packet
|
||||||
// FIXME: otherwise it takes too long until sound appears
|
// FIXME: otherwise it takes too long until sound appears
|
||||||
|
|
||||||
if (AudioCodecID == CODEC_ID_NONE) {
|
if (AudioCodecID == CODEC_ID_NONE) {
|
||||||
Debug(3, "[softhddev]%s: ??? %d\n", __FUNCTION__, id);
|
Debug(3, "[softhddev]%s: ??? %d\n", __FUNCTION__, id);
|
||||||
return;
|
avpkt->data = (void *)data;
|
||||||
|
avpkt->size = size;
|
||||||
|
n = FindAudioSync(avpkt);
|
||||||
|
if (n < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!MyAudioDecoder) {
|
||||||
|
MyAudioDecoder = CodecAudioNewDecoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_MP2);
|
||||||
|
AudioCodecID = CODEC_ID_MP2;
|
||||||
|
data += n;
|
||||||
|
size -= n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user