-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathaac.c
105 lines (83 loc) · 2.89 KB
/
aac.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
* aac.c: Frontend Status Monitor plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#include "tools.h"
#include "aac.h"
#define IS_HEAAC_AUDIO(buf) (((buf)[0] == 0xFF) && (((buf)[1] & 0xF6) == 0xF0))
int cFemonAAC::sampleRateS[16] =
{
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, -1, -1, -1, -1
};
cFemonAAC::cFemonAAC(cFemonAudioIf *audioHandlerP)
: audioHandlerM(audioHandlerP)
{
}
cFemonAAC::~cFemonAAC()
{
}
bool cFemonAAC::processAudio(const uint8_t *bufP, int lenP)
{
cFemonBitStream bs(bufP, lenP * 8);
if (!audioHandlerM)
return false;
/* ADTS Fixed Header:
* syncword 12b always: '111111111111'
* id 1b 0: MPEG-4, 1: MPEG-2
* layer 2b always: '00'
* protection_absent 1b
* profile 2b 0: Main profile AAC MAIN 1: Low Complexity profile (LC) AAC LC 2: Scalable Sample Rate profile (SSR) AAC SSR 3: (reserved) AAC LTP
* sampling_frequency_index 4b
* private_bit 1b
* channel_configuration 3b
* original/copy 1b
* home 1b
* emphasis 2b only if ID == 0 (ie MPEG-4)
*/
// skip PES header
if (!PesLongEnough(lenP))
return false;
bs.SkipBits(8 * PesPayloadOffset(bufP));
// HE-AAC audio detection
if (bs.GetBits(12) != 0xFFF) // syncword
return false;
bs.SkipBit(); // id
// layer must be 0
if (bs.GetBits(2)) // layer
return false;
bs.SkipBit(); // protection_absent
bs.SkipBits(2); // profile
int sampling_frequency_index = bs.GetBits(4); // sampling_frequency_index
bs.SkipBit(); // private pid
int channel_configuration = bs.GetBits(3); // channel_configuration
audioHandlerM->SetAudioCodec(AUDIO_CODEC_HEAAC);
audioHandlerM->SetAudioBitrate(AUDIO_BITRATE_RESERVED);
switch (channel_configuration) {
case 0:
audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_STEREO);
break;
case 1:
audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_JOINT_STEREO);
break;
case 2:
audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_DUAL);
break;
case 3:
audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_SINGLE);
break;
default:
audioHandlerM->SetAudioChannel(AUDIO_CHANNEL_MODE_INVALID);
break;
}
switch (sampling_frequency_index) {
case 0xC ... 0xF:
audioHandlerM->SetAudioSamplingFrequency(AUDIO_SAMPLING_FREQUENCY_RESERVED);
break;
default:
audioHandlerM->SetAudioSamplingFrequency(sampleRateS[sampling_frequency_index]);
break;
}
return true;
}