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.
|
||||
///
|
||||
/// Copyright (c) 2011 by Johns. All Rights Reserved.
|
||||
/// Copyright (c) 2011, 2012 by Johns. All Rights Reserved.
|
||||
///
|
||||
/// Contributor(s):
|
||||
///
|
||||
@ -59,6 +59,122 @@ static enum CodecID AudioCodecID; ///< current codec id
|
||||
|
||||
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.
|
||||
**
|
||||
@ -74,13 +190,10 @@ void PlayAudio(const uint8_t * data, int size, uint8_t id)
|
||||
if (BrokenThreadsAndPlugins) {
|
||||
return;
|
||||
}
|
||||
// PES header 0x00 0x00 0x01 ID
|
||||
// ID 0xBD 0xC0-0xCF
|
||||
|
||||
// channel switch: SetAudioChannelDevice: SetDigitalAudioDevice:
|
||||
|
||||
// Detect audio code
|
||||
// MPEG-PS mp2 MPEG1, MPEG2, AC3
|
||||
// PES header 0x00 0x00 0x01 ID
|
||||
// ID 0xBD 0xC0-0xCF
|
||||
|
||||
if (size < 9) {
|
||||
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"));
|
||||
return;
|
||||
}
|
||||
// Detect audio code
|
||||
// MPEG-PS mp2 MPEG1, MPEG2, AC3
|
||||
|
||||
// Syncword - 0x0B77
|
||||
if (data[0] == 0x0B && data[1] == 0x77) {
|
||||
if (!MyAudioDecoder) {
|
||||
@ -141,9 +257,23 @@ void PlayAudio(const uint8_t * data, int size, uint8_t id)
|
||||
// no start package
|
||||
// FIXME: Nick/Viva sends this shit, need to find sync in packet
|
||||
// FIXME: otherwise it takes too long until sound appears
|
||||
|
||||
if (AudioCodecID == CODEC_ID_NONE) {
|
||||
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