2 * Copyright (C) 2013 nu774
3 * For conditions of distribution and use, see copyright notice in COPYING
16 int aacenc_is_sbr_active(const aacenc_param_t
*params
)
18 switch (params
->profile
) {
19 case AOT_SBR
: case AOT_PS
: case AOT_MP2_SBR
: case AOT_MP2_PS
:
20 case AOT_DABPLUS_SBR
: case AOT_DABPLUS_PS
:
21 case AOT_DRM_SBR
: case AOT_DRM_MPEG_PS
:
24 if (params
->profile
== AOT_ER_AAC_ELD
&& params
->lowdelay_sbr
)
29 static const unsigned aacenc_sampling_freq_tab
[] = {
30 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
31 16000, 12000, 11025, 8000, 7350, 0, 0, 0
35 unsigned sampling_freq_index(unsigned rate
)
38 for (i
= 0; aacenc_sampling_freq_tab
[i
]; ++i
)
39 if (aacenc_sampling_freq_tab
[i
] == rate
)
45 * Append backward compatible SBR/PS signaling to implicit signaling ASC,
46 * if SBR/PS is present.
48 int aacenc_mp4asc(const aacenc_param_t
*params
,
49 const uint8_t *asc
, uint32_t ascsize
,
50 uint8_t *outasc
, uint32_t *outsize
)
52 unsigned asc_sfreq
= aacenc_sampling_freq_tab
[(asc
[0]&0x7)<<1 |asc
[1]>>7];
54 switch (params
->profile
) {
57 if (*outsize
< ascsize
+ 3)
59 memcpy(outasc
, asc
, ascsize
);
60 /* syncExtensionType:11 (value:0x2b7) */
61 outasc
[ascsize
+0] = 0x2b << 1;
62 outasc
[ascsize
+1] = 0x7 << 5;
63 /* extensionAudioObjectType:5 (value:5)*/
64 outasc
[ascsize
+1] |= 5;
65 /* sbrPresentFlag:1 (value:1) */
66 outasc
[ascsize
+2] = 0x80;
67 /* extensionSamplingFrequencyIndex:4 */
68 outasc
[ascsize
+2] |= sampling_freq_index(asc_sfreq
<< 1) << 3;
69 if (params
->profile
== AOT_SBR
) {
70 *outsize
= ascsize
+ 3;
73 if (*outsize
< ascsize
+ 5)
75 /* syncExtensionType:11 (value:0x548) */
76 outasc
[ascsize
+2] |= 0x5;
77 outasc
[ascsize
+3] = 0x48;
78 /* psPresentFlag:1 (value:1) */
79 outasc
[ascsize
+4] = 0x80;
80 *outsize
= ascsize
+ 5;
83 if (*outsize
< ascsize
)
85 memcpy(outasc
, asc
, ascsize
);
92 int aacenc_channel_mode(const pcm_sample_description_t
*format
)
94 uint32_t chanmask
= format
->channel_mask
;
96 if (format
->channels_per_frame
> 6)
99 static uint32_t defaults
[] = { 0x4, 0x3, 0x7, 0, 0x37, 0x3f };
100 chanmask
= defaults
[format
->channels_per_frame
- 1];
103 case 0x3: return MODE_2
;
104 case 0x4: return MODE_1
;
105 case 0x7: return MODE_1_2
;
106 case 0x37: return MODE_1_2_2
;
107 case 0x3f: return MODE_1_2_2_1
;
108 case 0x107: return MODE_1_2_1
;
109 case 0x607: return MODE_1_2_2
;
110 case 0x60f: return MODE_1_2_2_1
;
115 int aacenc_init(HANDLE_AACENCODER
*encoder
, const aacenc_param_t
*params
,
116 const pcm_sample_description_t
*format
,
117 AACENC_InfoStruct
*info
)
123 if ((channel_mode
= aacenc_channel_mode(format
)) == 0) {
124 fprintf(stderr
, "ERROR: unsupported channel layout\n");
127 if (aacEncOpen(encoder
, 0, 0) != AACENC_OK
) {
128 fprintf(stderr
, "ERROR: aacEncOpen() failed\n");
131 aot
= (params
->profile
? params
->profile
: AOT_AAC_LC
);
132 if (aacEncoder_SetParam(*encoder
, AACENC_AOT
, aot
) != AACENC_OK
) {
133 fprintf(stderr
, "ERROR: unsupported profile\n");
136 if (params
->bitrate_mode
== 0)
137 aacEncoder_SetParam(*encoder
, AACENC_BITRATE
, params
->bitrate
);
138 else if (aacEncoder_SetParam(*encoder
, AACENC_BITRATEMODE
,
139 params
->bitrate_mode
) != AACENC_OK
) {
140 fprintf(stderr
, "ERROR: unsupported bitrate mode\n");
143 if (aacEncoder_SetParam(*encoder
, AACENC_SAMPLERATE
,
144 format
->sample_rate
) != AACENC_OK
) {
145 fprintf(stderr
, "ERROR: unsupported sample rate\n");
148 aacEncoder_SetParam(*encoder
, AACENC_CHANNELMODE
, channel_mode
);
149 aacEncoder_SetParam(*encoder
, AACENC_BANDWIDTH
, params
->bandwidth
);
150 aacEncoder_SetParam(*encoder
, AACENC_CHANNELORDER
, 1);
151 aacEncoder_SetParam(*encoder
, AACENC_AFTERBURNER
, !!params
->afterburner
);
153 if (aot
== AOT_ER_AAC_ELD
&& params
->lowdelay_sbr
)
154 aacEncoder_SetParam(*encoder
, AACENC_SBR_MODE
, 1);
156 if (aacEncoder_SetParam(*encoder
, AACENC_TRANSMUX
,
157 params
->transport_format
) != AACENC_OK
) {
158 fprintf(stderr
, "ERROR: unsupported transport format\n");
161 if (aacEncoder_SetParam(*encoder
, AACENC_SIGNALING_MODE
,
162 params
->sbr_signaling
) != AACENC_OK
) {
163 fprintf(stderr
, "ERROR: failed to set SBR signaling mode\n");
166 if (params
->adts_crc_check
)
167 aacEncoder_SetParam(*encoder
, AACENC_PROTECTION
, 1);
168 if (params
->header_period
)
169 aacEncoder_SetParam(*encoder
, AACENC_HEADER_PERIOD
,
170 params
->header_period
);
172 if (aacEncEncode(*encoder
, 0, 0, 0, 0) != AACENC_OK
) {
173 fprintf(stderr
, "ERROR: encoder initialization failed\n");
176 if (aacEncInfo(*encoder
, info
) != AACENC_OK
) {
177 fprintf(stderr
, "ERROR: cannot retrieve encoder info\n");
183 aacEncClose(encoder
);
187 int aac_encode_frame(HANDLE_AACENCODER encoder
,
188 const pcm_sample_description_t
*format
,
189 const int16_t *input
, unsigned iframes
,
190 uint8_t **output
, uint32_t *olen
, uint32_t *osize
)
192 uint32_t ilen
= iframes
* format
->channels_per_frame
;
193 AACENC_BufDesc ibdesc
= { 0 }, obdesc
= { 0 };
194 AACENC_InArgs iargs
= { 0 };
195 AACENC_OutArgs oargs
= { 0 };
196 void *ibufs
[] = { (void*)input
};
198 INT ibuf_ids
[] = { IN_AUDIO_DATA
};
199 INT obuf_ids
[] = { OUT_BITSTREAM_DATA
};
200 INT ibuf_sizes
[] = { ilen
* sizeof(int16_t) };
202 INT ibuf_el_sizes
[] = { sizeof(int16_t) };
203 INT obuf_el_sizes
[] = { 1 };
205 unsigned channel_mode
, obytes
;
207 channel_mode
= aacEncoder_GetParam(encoder
, AACENC_CHANNELMODE
);
208 obytes
= 6144 / 8 * channel_mode
+ 7;
209 if (!*output
|| *osize
< obytes
) {
211 *output
= realloc(*output
, obytes
);
214 obuf_sizes
[0] = obytes
;
216 iargs
.numInSamples
= ilen
? ilen
: -1; /* -1 for signaling EOF */
219 ibdesc
.bufferIdentifiers
= ibuf_ids
;
220 ibdesc
.bufSizes
= ibuf_sizes
;
221 ibdesc
.bufElSizes
= ibuf_el_sizes
;
224 obdesc
.bufferIdentifiers
= obuf_ids
;
225 obdesc
.bufSizes
= obuf_sizes
;
226 obdesc
.bufElSizes
= obuf_el_sizes
;
228 err
= aacEncEncode(encoder
, &ibdesc
, &obdesc
, &iargs
, &oargs
);
229 if (err
!= AACENC_ENCODE_EOF
&& err
!= AACENC_OK
) {
230 fprintf(stderr
, "ERROR: aacEncEncode() failed\n");
233 *olen
= oargs
.numOutBytes
;
234 return oargs
.numInSamples
;