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
31
32 #ifdef AACENCODER_LIB_VL0
33 #define FDKENC_VER_AT_LEAST(vl0, vl1) \
34 ((AACENCODER_LIB_VL0 > vl0) || \
35 (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1))
36 #else
37 #define FDKENC_VER_AT_LEAST(vl0, vl1) 0
38 #endif
39
59
62
65 {
"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 },
66 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
68 #endif
69 {
"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" },
70 {
"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" },
72 {
"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" },
85 };
86
92 };
93
95 {
96 switch (err) {
97 case AACENC_OK:
98 return "No error";
99 case AACENC_INVALID_HANDLE:
100 return "Invalid handle";
101 case AACENC_MEMORY_ERROR:
102 return "Memory allocation error";
103 case AACENC_UNSUPPORTED_PARAMETER:
104 return "Unsupported parameter";
105 case AACENC_INVALID_CONFIG:
106 return "Invalid config";
107 case AACENC_INIT_ERROR:
108 return "Initialization error";
109 case AACENC_INIT_AAC_ERROR:
110 return "AAC library initialization error";
111 case AACENC_INIT_SBR_ERROR:
112 return "SBR library initialization error";
113 case AACENC_INIT_TP_ERROR:
114 return "Transport library initialization error";
115 case AACENC_INIT_META_ERROR:
116 return "Metadata library initialization error";
117 case AACENC_ENCODE_ERROR:
118 return "Encoding error";
119 case AACENC_ENCODE_EOF:
120 return "End of file";
121 default:
122 return "Unknown error";
123 }
124 }
125
127 {
129
131 aacEncClose(&
s->handle);
133
134 return 0;
135 }
136
138 {
140 AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
141 AACENC_InArgs in_args = { 0 };
142 AACENC_OutArgs out_args;
144 uint8_t dummy_in[1], dummy_out[1];
145 int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP };
146 int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) };
147 int in_buffer_sizes[] = { 0,
sizeof(
s->metaDataSetup) };
148 int out_buffer_identifier = OUT_BITSTREAM_DATA;
149 int out_buffer_size = sizeof(dummy_out), out_buffer_element_size = 1;
150 void* inBuffer[] = { dummy_in, &
s->metaDataSetup };
151 void *out_ptr = dummy_out;
152 AACENC_ERROR err;
153
155
156 in_buf.bufs = (void **)inBuffer;
157 in_buf.numBufs =
s->metadata_mode == 0 ? 1 : 2;
158 in_buf.bufferIdentifiers = in_buffer_identifiers;
159 in_buf.bufSizes = in_buffer_sizes;
160 in_buf.bufElSizes = in_buffer_element_sizes;
161
162 out_buf.numBufs = 1;
163 out_buf.bufs = &out_ptr;
164 out_buf.bufferIdentifiers = &out_buffer_identifier;
165 out_buf.bufSizes = &out_buffer_size;
166 out_buf.bufElSizes = &out_buffer_element_size;
167
168 err = aacEncEncode(
s->handle, &in_buf, &out_buf, &in_args, &out_args);
169 if (err != AACENC_OK) {
172 }
173 }
174
176 {
179 AACENC_InfoStruct
info = { 0 };
181 AACENC_ERROR err;
183 int sce = 0, cpe = 0;
184
189 }
190
193
194 if ((err = aacEncoder_SetParam(
s->handle, AACENC_AOT, aot)) != AACENC_OK) {
198 }
199
201 if ((err = aacEncoder_SetParam(
s->handle, AACENC_SBR_MODE,
202 1)) != AACENC_OK) {
206 }
207 }
208
209 if (
s->frame_length >= 0) {
210 if ((err = aacEncoder_SetParam(
s->handle, AACENC_GRANULE_LENGTH,
211 s->frame_length)) != AACENC_OK) {
215 }
216 }
217
218 if ((err = aacEncoder_SetParam(
s->handle, AACENC_SAMPLERATE,
223 }
224
226 case 1:
mode = MODE_1; sce = 1; cpe = 0;
break;
227 case 2:
228 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
229 // (profile + 1) to map from profile range to AOT range
231 if ((err = aacEncoder_SetParam(
s->handle, AACENC_CHANNELMODE,
232 128)) != AACENC_OK) {
236 } else {
238 sce = 1;
239 cpe = 0;
240 }
241 } else
242 #endif
243 {
245 sce = 0;
246 cpe = 1;
247 }
248 break;
249 case 3:
mode = MODE_1_2; sce = 1; cpe = 1;
break;
250 case 4:
mode = MODE_1_2_1; sce = 2; cpe = 1;
break;
251 case 5:
mode = MODE_1_2_2; sce = 1; cpe = 2;
break;
252 case 6:
mode = MODE_1_2_2_1; sce = 2; cpe = 2;
break;
253 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
254 case 7:
mode = MODE_6_1; sce = 3; cpe = 2;
break;
255 #endif
256 /* The version macro is introduced the same time as the 7.1 support, so this
257 should suffice. */
258 #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
259 case 8:
260 sce = 2;
261 cpe = 3;
263 mode = MODE_7_1_REAR_SURROUND;
264 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
266 mode = MODE_7_1_TOP_FRONT;
267 #endif
268 } else {
269 // MODE_1_2_2_2_1 and MODE_7_1_FRONT_CENTER use the same channel layout
270 mode = MODE_7_1_FRONT_CENTER;
271 }
272 break;
273 #endif
274 default:
278 }
279
280 if ((err = aacEncoder_SetParam(
s->handle, AACENC_CHANNELMODE,
281 mode)) != AACENC_OK) {
285 }
286
287 if ((err = aacEncoder_SetParam(
s->handle, AACENC_CHANNELORDER,
288 1)) != AACENC_OK) {
290 "Unable to set wav channel order %d: %s\n",
293 }
294
299 "VBR quality %d out of range, should be 1-5\n",
mode);
301 }
303 "Note, the VBR setting is unsupported and only works with "
304 "some parameter combinations\n");
305 if ((err = aacEncoder_SetParam(
s->handle, AACENC_BITRATEMODE,
306 mode)) != AACENC_OK) {
310 }
311 } else {
314 sce = 1;
315 cpe = 0;
316 }
323 }
324 if ((err = aacEncoder_SetParam(
s->handle, AACENC_BITRATE,
329 }
330 }
331
332 /* Choose bitstream format - if global header is requested, use
333 * raw access units, otherwise use ADTS. */
334 if ((err = aacEncoder_SetParam(
s->handle, AACENC_TRANSMUX,
336 s->latm ? TT_MP4_LOAS : TT_MP4_ADTS)) != AACENC_OK) {
340 }
341
342 if (
s->latm &&
s->header_period) {
343 if ((err = aacEncoder_SetParam(
s->handle, AACENC_HEADER_PERIOD,
344 s->header_period)) != AACENC_OK) {
348 }
349 }
350
351 /* If no signaling mode is chosen, use explicit hierarchical signaling
352 * if using mp4 mode (raw access units, with global header) and
353 * implicit signaling if using ADTS. */
354 if (
s->signaling < 0)
356
357 if ((err = aacEncoder_SetParam(
s->handle, AACENC_SIGNALING_MODE,
358 s->signaling)) != AACENC_OK) {
362 }
363
364 if ((err = aacEncoder_SetParam(
s->handle, AACENC_AFTERBURNER,
365 s->afterburner)) != AACENC_OK) {
369 }
370
376 }
377 if ((err = aacEncoder_SetParam(
s->handle, AACENC_BANDWIDTH,
378 avctx->
cutoff)) != AACENC_OK) {
382 }
383 }
384
385 s->metadata_mode = 0;
387 s->metadata_mode = 1;
388 s->metaDataSetup.prog_ref_level_present = 1;
389 s->metaDataSetup.prog_ref_level =
s->prog_ref << 16;
390 }
391 if (
s->drc_profile) {
392 s->metadata_mode = 1;
393 s->metaDataSetup.drc_profile =
s->drc_profile;
394 s->metaDataSetup.drc_TargetRefLevel =
s->drc_target_ref << 16;
395 if (
s->comp_profile) {
396 /* Including the comp_profile means that we need to set the mode to ETSI */
397 s->metadata_mode = 2;
398 s->metaDataSetup.comp_profile =
s->comp_profile;
399 s->metaDataSetup.comp_TargetRefLevel =
s->comp_target_ref << 16;
400 }
401 }
402
403 if ((err = aacEncoder_SetParam(
s->handle, AACENC_METADATA_MODE,
s->metadata_mode)) != AACENC_OK) {
407 }
408
413 }
414
415 if ((err = aacEncInfo(
s->handle, &
info)) != AACENC_OK) {
419 }
420
422 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
424 #else
426 #endif
428
436 }
437
439 }
440 return 0;
444 }
445
448 {
450 AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
451 AACENC_InArgs in_args = { 0 };
452 AACENC_OutArgs out_args = { 0 };
453 void* inBuffer[] = { 0, &
s->metaDataSetup };
454 int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP };
455 int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) };
456 int in_buffer_sizes[] = { 0,
sizeof(
s->metaDataSetup) };
457 int out_buffer_identifier = OUT_BITSTREAM_DATA;
458 int out_buffer_size, out_buffer_element_size;
459 void *out_ptr;
460 int ret, discard_padding;
461 uint8_t dummy_buf[1];
462 AACENC_ERROR err;
463
464 /* handle end-of-stream small frame and flushing */
466 /* Must be a non-null pointer, even if it's a dummy. We could use
467 * the address of anything else on the stack as well. */
468 inBuffer[0] = dummy_buf;
469
470 in_args.numInSamples = -1;
471 } else {
474
476
477 /* add current frame to the queue */
480 }
481
482 if (
s->metadata_mode == 0) {
483 in_buf.numBufs = 1;
484 } else {
485 in_buf.numBufs = 2;
486 }
487
488 in_buf.bufs = (void**)inBuffer;
489 in_buf.bufferIdentifiers = in_buffer_identifiers;
490 in_buf.bufSizes = in_buffer_sizes;
491 in_buf.bufElSizes = in_buffer_element_sizes;
492
493 /* The maximum packet size is 6144 bits aka 768 bytes per channel. */
497
498 out_ptr = avpkt->
data;
499 out_buffer_size = avpkt->
size;
500 out_buffer_element_size = 1;
501 out_buf.numBufs = 1;
502 out_buf.bufs = &out_ptr;
503 out_buf.bufferIdentifiers = &out_buffer_identifier;
504 out_buf.bufSizes = &out_buffer_size;
505 out_buf.bufElSizes = &out_buffer_element_size;
506
507 if ((err = aacEncEncode(
s->handle, &in_buf, &out_buf, &in_args,
508 &out_args)) != AACENC_OK) {
509 if (!
frame && err == AACENC_ENCODE_EOF)
510 return 0;
514 }
515
516 if (!out_args.numOutBytes)
517 return 0;
518
519 /* Get the next frame pts & duration */
522
524 // Check if subtraction resulted in an overflow
528 }
529 if ((!
s->delay_sent && avctx->
initial_padding > 0) || discard_padding > 0) {
530 uint8_t *side_data =
532 if (!side_data)
534 if (!
s->delay_sent) {
537 }
538 AV_WL32(side_data + 4, discard_padding);
539 }
540
541 avpkt->
size = out_args.numOutBytes;
542 *got_packet_ptr = 1;
543 return 0;
544 }
545
553 };
554
556 { "b", "0" },
558 };
559
567 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
569 #endif
570 #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
573 #endif
574 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
576 #endif
577 { 0 },
578 };
579
581 96000, 88200, 64000, 48000, 44100, 32000,
582 24000, 22050, 16000, 12000, 11025, 8000, 0
583 };
584
586 .
p.
name =
"libfdk_aac",
605 .p.wrapper_name = "libfdk",
607 };