1 /*
2 * AAC encoder wrapper
3 * Copyright (c) 2012 Martin Storsjo
4 *
5 * This file is part of FFmpeg.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include <fdk-aac/aacenc_lib.h>
21
32
33 #ifdef AACENCODER_LIB_VL0
34 #define FDKENC_VER_AT_LEAST(vl0, vl1) \
35 ((AACENCODER_LIB_VL0 > vl0) || \
36 (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1))
37 #else
38 #define FDKENC_VER_AT_LEAST(vl0, vl1) 0
39 #endif
40
60
63
66 {
"eld_sbr",
"Enable SBR for ELD (for SBR in other configurations, use the -profile parameter)", offsetof(
AACContext, eld_sbr),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1,
AV_OPT_FLAG_AUDIO_PARAM |
AV_OPT_FLAG_ENCODING_PARAM },
67 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
69 #endif
70 {
"signaling",
"SBR/PS signaling style", offsetof(
AACContext, signaling),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 2,
AV_OPT_FLAG_AUDIO_PARAM |
AV_OPT_FLAG_ENCODING_PARAM, .unit =
"signaling" },
71 {
"default",
"Choose signaling implicitly (explicit hierarchical by default, implicit if global header is disabled)", 0,
AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0,
AV_OPT_FLAG_AUDIO_PARAM |
AV_OPT_FLAG_ENCODING_PARAM, .unit =
"signaling" },
73 {
"explicit_sbr",
"Explicit SBR, implicit PS signaling", 0,
AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0,
AV_OPT_FLAG_AUDIO_PARAM |
AV_OPT_FLAG_ENCODING_PARAM, .unit =
"signaling" },
86 };
87
93 };
94
96 {
97 switch (err) {
98 case AACENC_OK:
99 return "No error";
100 case AACENC_INVALID_HANDLE:
101 return "Invalid handle";
102 case AACENC_MEMORY_ERROR:
103 return "Memory allocation error";
104 case AACENC_UNSUPPORTED_PARAMETER:
105 return "Unsupported parameter";
106 case AACENC_INVALID_CONFIG:
107 return "Invalid config";
108 case AACENC_INIT_ERROR:
109 return "Initialization error";
110 case AACENC_INIT_AAC_ERROR:
111 return "AAC library initialization error";
112 case AACENC_INIT_SBR_ERROR:
113 return "SBR library initialization error";
114 case AACENC_INIT_TP_ERROR:
115 return "Transport library initialization error";
116 case AACENC_INIT_META_ERROR:
117 return "Metadata library initialization error";
118 case AACENC_ENCODE_ERROR:
119 return "Encoding error";
120 case AACENC_ENCODE_EOF:
121 return "End of file";
122 default:
123 return "Unknown error";
124 }
125 }
126
128 {
130
132 aacEncClose(&
s->handle);
134
135 return 0;
136 }
137
139 {
141 AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
142 AACENC_InArgs in_args = { 0 };
143 AACENC_OutArgs out_args;
145 uint8_t dummy_in[1], dummy_out[1];
146 int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP };
147 int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) };
148 int in_buffer_sizes[] = { 0,
sizeof(
s->metaDataSetup) };
149 int out_buffer_identifier = OUT_BITSTREAM_DATA;
150 int out_buffer_size = sizeof(dummy_out), out_buffer_element_size = 1;
151 void* inBuffer[] = { dummy_in, &
s->metaDataSetup };
152 void *out_ptr = dummy_out;
153 AACENC_ERROR err;
154
156
157 in_buf.bufs = (void **)inBuffer;
158 in_buf.numBufs =
s->metadata_mode == 0 ? 1 : 2;
159 in_buf.bufferIdentifiers = in_buffer_identifiers;
160 in_buf.bufSizes = in_buffer_sizes;
161 in_buf.bufElSizes = in_buffer_element_sizes;
162
163 out_buf.numBufs = 1;
164 out_buf.bufs = &out_ptr;
165 out_buf.bufferIdentifiers = &out_buffer_identifier;
166 out_buf.bufSizes = &out_buffer_size;
167 out_buf.bufElSizes = &out_buffer_element_size;
168
169 err = aacEncEncode(
s->handle, &in_buf, &out_buf, &in_args, &out_args);
170 if (err != AACENC_OK) {
173 }
174 }
175
177 {
180 AACENC_InfoStruct
info = { 0 };
183 AACENC_ERROR err;
185 int sce = 0, cpe = 0;
186
191 }
192
195
196 if ((err = aacEncoder_SetParam(
s->handle, AACENC_AOT, aot)) != AACENC_OK) {
200 }
201
203 if ((err = aacEncoder_SetParam(
s->handle, AACENC_SBR_MODE,
204 1)) != AACENC_OK) {
208 }
209 }
210
211 if (
s->frame_length >= 0) {
212 if ((err = aacEncoder_SetParam(
s->handle, AACENC_GRANULE_LENGTH,
213 s->frame_length)) != AACENC_OK) {
217 }
218 }
219
220 if ((err = aacEncoder_SetParam(
s->handle, AACENC_SAMPLERATE,
225 }
226
228 case 1:
mode = MODE_1; sce = 1; cpe = 0;
break;
229 case 2:
230 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
231 // (profile + 1) to map from profile range to AOT range
233 if ((err = aacEncoder_SetParam(
s->handle, AACENC_CHANNELMODE,
234 128)) != AACENC_OK) {
238 } else {
240 sce = 1;
241 cpe = 0;
242 }
243 } else
244 #endif
245 {
247 sce = 0;
248 cpe = 1;
249 }
250 break;
251 case 3:
mode = MODE_1_2; sce = 1; cpe = 1;
break;
252 case 4:
mode = MODE_1_2_1; sce = 2; cpe = 1;
break;
253 case 5:
mode = MODE_1_2_2; sce = 1; cpe = 2;
break;
254 case 6:
mode = MODE_1_2_2_1; sce = 2; cpe = 2;
break;
255 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
256 case 7:
mode = MODE_6_1; sce = 3; cpe = 2;
break;
257 #endif
258 /* The version macro is introduced the same time as the 7.1 support, so this
259 should suffice. */
260 #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
261 case 8:
262 sce = 2;
263 cpe = 3;
265 mode = MODE_7_1_REAR_SURROUND;
266 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
268 mode = MODE_7_1_TOP_FRONT;
269 #endif
270 } else {
271 // MODE_1_2_2_2_1 and MODE_7_1_FRONT_CENTER use the same channel layout
272 mode = MODE_7_1_FRONT_CENTER;
273 }
274 break;
275 #endif
276 default:
280 }
281
282 if ((err = aacEncoder_SetParam(
s->handle, AACENC_CHANNELMODE,
283 mode)) != AACENC_OK) {
287 }
288
289 if ((err = aacEncoder_SetParam(
s->handle, AACENC_CHANNELORDER,
290 1)) != AACENC_OK) {
292 "Unable to set wav channel order %d: %s\n",
295 }
296
301 "VBR quality %d out of range, should be 1-5\n",
mode);
303 }
305 "Note, the VBR setting is unsupported and only works with "
306 "some parameter combinations\n");
307 if ((err = aacEncoder_SetParam(
s->handle, AACENC_BITRATEMODE,
308 mode)) != AACENC_OK) {
312 }
313 } else {
316 sce = 1;
317 cpe = 0;
318 }
325 }
326 if ((err = aacEncoder_SetParam(
s->handle, AACENC_BITRATE,
331 }
332 }
333
334 /* Choose bitstream format - if global header is requested, use
335 * raw access units, otherwise use ADTS. */
336 if ((err = aacEncoder_SetParam(
s->handle, AACENC_TRANSMUX,
338 s->latm ? TT_MP4_LOAS : TT_MP4_ADTS)) != AACENC_OK) {
342 }
343
344 if (
s->latm &&
s->header_period) {
345 if ((err = aacEncoder_SetParam(
s->handle, AACENC_HEADER_PERIOD,
346 s->header_period)) != AACENC_OK) {
350 }
351 }
352
353 /* If no signaling mode is chosen, use explicit hierarchical signaling
354 * if using mp4 mode (raw access units, with global header) and
355 * implicit signaling if using ADTS. */
356 if (
s->signaling < 0)
358
359 if ((err = aacEncoder_SetParam(
s->handle, AACENC_SIGNALING_MODE,
360 s->signaling)) != AACENC_OK) {
364 }
365
366 if ((err = aacEncoder_SetParam(
s->handle, AACENC_AFTERBURNER,
367 s->afterburner)) != AACENC_OK) {
371 }
372
378 }
379 if ((err = aacEncoder_SetParam(
s->handle, AACENC_BANDWIDTH,
380 avctx->
cutoff)) != AACENC_OK) {
384 }
385 }
386
387 s->metadata_mode = 0;
389 s->metadata_mode = 1;
390 s->metaDataSetup.prog_ref_level_present = 1;
391 s->metaDataSetup.prog_ref_level =
s->prog_ref << 16;
392 }
393 if (
s->drc_profile) {
394 s->metadata_mode = 1;
395 s->metaDataSetup.drc_profile =
s->drc_profile;
396 s->metaDataSetup.drc_TargetRefLevel =
s->drc_target_ref << 16;
397 if (
s->comp_profile) {
398 /* Including the comp_profile means that we need to set the mode to ETSI */
399 s->metadata_mode = 2;
400 s->metaDataSetup.comp_profile =
s->comp_profile;
401 s->metaDataSetup.comp_TargetRefLevel =
s->comp_target_ref << 16;
402 }
403 }
404
405 if ((err = aacEncoder_SetParam(
s->handle, AACENC_METADATA_MODE,
s->metadata_mode)) != AACENC_OK) {
409 }
410
415 }
416
417 if ((err = aacEncInfo(
s->handle, &
info)) != AACENC_OK) {
421 }
422
424 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
426 #else
428 #endif
430
438 }
439
441 }
442
444 if (!cpb_props)
449
450 return 0;
454 }
455
458 {
460 AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
461 AACENC_InArgs in_args = { 0 };
462 AACENC_OutArgs out_args = { 0 };
463 void* inBuffer[] = { 0, &
s->metaDataSetup };
464 int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP };
465 int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) };
466 int in_buffer_sizes[] = { 0,
sizeof(
s->metaDataSetup) };
467 int out_buffer_identifier = OUT_BITSTREAM_DATA;
468 int out_buffer_size, out_buffer_element_size;
469 void *out_ptr;
470 int ret, discard_padding;
471 uint8_t dummy_buf[1];
472 AACENC_ERROR err;
473
474 /* handle end-of-stream small frame and flushing */
476 /* Must be a non-null pointer, even if it's a dummy. We could use
477 * the address of anything else on the stack as well. */
478 inBuffer[0] = dummy_buf;
479
480 in_args.numInSamples = -1;
481 } else {
482 inBuffer[0] =
frame->data[0];
484
486
487 /* add current frame to the queue */
490 }
491
492 if (
s->metadata_mode == 0) {
493 in_buf.numBufs = 1;
494 } else {
495 in_buf.numBufs = 2;
496 }
497
498 in_buf.bufs = (void**)inBuffer;
499 in_buf.bufferIdentifiers = in_buffer_identifiers;
500 in_buf.bufSizes = in_buffer_sizes;
501 in_buf.bufElSizes = in_buffer_element_sizes;
502
503 /* The maximum packet size is 6144 bits aka 768 bytes per channel. */
507
508 out_ptr = avpkt->
data;
509 out_buffer_size = avpkt->
size;
510 out_buffer_element_size = 1;
511 out_buf.numBufs = 1;
512 out_buf.bufs = &out_ptr;
513 out_buf.bufferIdentifiers = &out_buffer_identifier;
514 out_buf.bufSizes = &out_buffer_size;
515 out_buf.bufElSizes = &out_buffer_element_size;
516
517 if ((err = aacEncEncode(
s->handle, &in_buf, &out_buf, &in_args,
518 &out_args)) != AACENC_OK) {
519 if (!
frame && err == AACENC_ENCODE_EOF)
520 return 0;
524 }
525
526 if (!out_args.numOutBytes)
527 return 0;
528
529 /* Get the next frame pts & duration */
532
534 // Check if subtraction resulted in an overflow
538 }
539 if ((!
s->delay_sent && avctx->
initial_padding > 0) || discard_padding > 0) {
540 uint8_t *side_data =
542 if (!side_data)
544 if (!
s->delay_sent) {
547 }
548 AV_WL32(side_data + 4, discard_padding);
549 }
550
551 avpkt->
size = out_args.numOutBytes;
553 *got_packet_ptr = 1;
554 return 0;
555 }
556
564 };
565
567 { "b", "0" },
569 };
570
578 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
580 #endif
581 #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
584 #endif
585 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
587 #endif
588 { 0 },
589 };
590
592 96000, 88200, 64000, 48000, 44100, 32000,
593 24000, 22050, 16000, 12000, 11025, 8000, 0
594 };
595
597 .
p.
name =
"libfdk_aac",
615 .p.wrapper_name = "libfdk",
617 };