1
0
mirror of https://github.com/rofafor/vdr-plugin-femon.git synced 2023-10-10 13:36:53 +02:00
vdr-plugin-femon/femonlatm.c

113 lines
3.0 KiB
C
Raw Permalink Normal View History

2010-06-23 11:16:17 +02:00
/*
* Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#include "femontools.h"
#include "femonlatm.h"
int cFemonLATM::s_Bitrates[3][16] =
2010-06-23 11:16:17 +02:00
{
{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1}, // MPEG-2 Layer I
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, // MPEG-2 Layer II/III
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1} // MPEG-2 Layer II/III
};
int cFemonLATM::s_Samplerates[4] =
2010-06-23 11:16:17 +02:00
{
22050, 24000, 16000, -1
};
cFemonLATM::cFemonLATM(cFemonAudioIf *audiohandler)
: m_AudioHandler(audiohandler)
{
}
cFemonLATM::~cFemonLATM()
{
}
bool cFemonLATM::processAudio(const uint8_t *buf, int len)
{
2011-11-19 15:02:16 +01:00
cFemonBitStream bs(buf, len * 8);
2010-06-23 11:16:17 +02:00
if (!m_AudioHandler)
return false;
// skip PES header
if (!PesLongEnough(len))
return false;
2011-11-19 15:02:16 +01:00
bs.SkipBits(8 * PesPayloadOffset(buf));
2010-06-23 11:16:17 +02:00
// MPEG audio detection
2011-11-19 15:02:16 +01:00
if (bs.GetBits(12) != 0x56E) // syncword
2010-06-23 11:16:17 +02:00
return false;
2010-06-23 19:12:35 +02:00
m_AudioHandler->SetAudioCodec(AUDIO_CODEC_LATM);
2011-11-19 15:02:16 +01:00
if (bs.GetBit() == 0) // id: MPEG-1=1, extension to lower sampling frequencies=0
2010-06-23 19:12:35 +02:00
return true; // @todo: lower sampling frequencies support
2011-11-19 15:02:16 +01:00
int layer = 3 - bs.GetBits(2); // layer: I=11, II=10, III=01
bs.SkipBit(); // protection bit
int bit_rate_index = bs.GetBits(4); // bitrate index
int sampling_frequency = bs.GetBits(2); // sampling frequency
bs.SkipBit(); // padding bit
bs.SkipBit(); // private pid
int mode = bs.GetBits(2); // mode
2010-06-23 11:16:17 +02:00
switch (mode) {
case 0:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO);
break;
case 1:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO);
break;
case 2:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL);
break;
case 3:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE);
break;
default:
m_AudioHandler->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID);
break;
}
if (layer == 3) {
m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_FREE);
}
else {
switch (bit_rate_index) {
case 0:
m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_FREE);
break;
case 0xF:
m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_RESERVED);
break;
default:
m_AudioHandler->SetAudioBitrate(1000 * s_Bitrates[layer][bit_rate_index]);
break;
}
}
switch (sampling_frequency) {
case 3:
m_AudioHandler->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED);
break;
default:
m_AudioHandler->SetAudioSamplingFrequency(s_Samplerates[sampling_frequency]);
break;
}
return true;
}