FFmpeg
Loading...
Searching...
No Matches
libfdk-xhe-aacenc.c
Go to the documentation of this file.
1/*
2 * FDK-XHE-AAC encoder wrapper
3 * Copyright (c) 2026 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
21#include "libavutil/common.h"
22#include "libavutil/mem.h"
23#include "libavutil/opt.h"
24#include "avcodec.h"
25#include "audio_frame_queue.h"
26#include "codec_internal.h"
27#include "encode.h"
28#include "profiles.h"
29
30#include <fdk-xhe-aac/xHEAACEnc.h>
31
32typedef struct XHEAACContext {
33 const AVClass *class;
34 IIS_XHEAACENC_INSTANCE_HANDLE handle;
35
36 int vbr;
40
42
44
49
50static const AVOption xhe_aac_enc_options[] = {
51 { "vbr", "VBR mode (0-6)", offsetof(XHEAACContext, vbr), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
52 { "live_loudness_level", "target loudness level in live encoding mode [LUFS]", offsetof(XHEAACContext, live_loudness_level), AV_OPT_TYPE_FLOAT, { .dbl = -24 }, -31.0, -10.0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
53 { "rap_interval", "Random Access Point interval", offsetof(XHEAACContext, rap_interval), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT64_MAX, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
54 { "stream_id", "unique ID of this stream within one adaptation set", offsetof(XHEAACContext, stream_id), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 65535, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
56 { NULL }
57};
58
59static const AVClass xhe_aac_enc_class = {
60 .class_name = "libfdk_xhe_aac",
61 .item_name = av_default_item_name,
62 .option = xhe_aac_enc_options,
63 .version = LIBAVUTIL_VERSION_INT,
64};
65
66static const char *xhe_aac_get_error(IIS_XHEAACENC_RETURN_CODE err)
67{
68 switch (err) {
69 case IIS_XHEAACENC_NO_ERROR:
70 return "No error";
71 case IIS_XHEAACENC_ERROR_PARAM_BITRATE:
72 return "Invalid or missing parameter for bitrate";
73 case IIS_XHEAACENC_ERROR_TOO_MANY_INPUT_SAMPLES:
74 return "Too many input samples";
75 case IIS_XHEAACENC_ERROR_PARAMCOMB_BASE:
76 return "Invalid parameter combination of AOT, operating mode, bitrate, bitrate mode, channel config or transport format";
77 case IIS_XHEAACENC_ERROR_INSAMPLERATE_UNSUPPORTED:
78 return "Unsupported input sample rate";
79 case IIS_XHEAACENC_ERROR_COMB_INSAMPLERATE_UNSUPPORTED:
80 return "Unsupported input sample rate for a specific configuration";
81 case IIS_XHEAACENC_ERROR_PARAMCOMB_STREAMID_SWITCHABLE_AOT:
82 return "Operating mode switchable requires a stream ID";
83 case IIS_XHEAACENC_ERROR_PARAMCOMB_RAP_INTERVAL_RAP_MIN_INTERVAL:
84 return "The RAP interval is below the allowed minimum";
85 default:
86 return "Unknown error";
87 }
88}
89
91{
92 XHEAACContext *s = avctx->priv_data;
93 IIS_XHEAACENC_RETURN_CODE err;
94
95 if (s->handle) {
96 err = IIS_xHEAACEnc_Delete(s->handle);
97 if (err != IIS_XHEAACENC_NO_ERROR)
98 av_log(avctx, AV_LOG_ERROR, "Unexpected error on close: %s (%d)\n",
99 xhe_aac_get_error(err), err);
100 s->handle = NULL;
101 }
102 ff_af_queue_close(&s->afq);
103 av_freep(&s->sample_queue);
104
105 return 0;
106}
107
109{
110 XHEAACContext *s = avctx->priv_data;
111 int ret = AVERROR(EINVAL);
112 AVCPBProperties *cpb_props;
113 IIS_XHEAACENC_CONFIG_INSTANCE_HANDLE config_handle = NULL;
114 IIS_XHEAACENC_CHANNELCONFIG channel_config;
115 IIS_XHEAACENC_BITRATEMODE bitrate_mode;
116 IIS_XHEAACENC_RETURN_CODE err;
117 int out_framesize, out_max_bitrate, out_avg_bitrate;
118
119 if (avctx->profile != AV_PROFILE_UNKNOWN && avctx->profile != AV_PROFILE_AAC_USAC) {
120 av_log(avctx, AV_LOG_ERROR, "This encoder can only encode xHE-AAC (AOT 42).\n");
121 goto error;
122 }
124
125 switch (avctx->ch_layout.nb_channels) {
126 case 1: channel_config = IIS_XHEAACENC_CHANNELCONFIG_MONO; break;
127 case 2: channel_config = IIS_XHEAACENC_CHANNELCONFIG_STEREO; break;
128 default:
129 av_log(avctx, AV_LOG_ERROR,
130 "Unsupported number of channels %d\n", avctx->ch_layout.nb_channels);
131 goto error;
132 }
133
134 err = IIS_xHEAACEnc_Config_Open(&config_handle, avctx->sample_rate, channel_config);
135 if (err != IIS_XHEAACENC_NO_ERROR) {
136 av_log(avctx, AV_LOG_ERROR, "Unable to open config: %s (%d)\n",
137 xhe_aac_get_error(err), err);
138 goto error;
139 }
140
141 if (s->vbr >= 0) {
142 switch (s->vbr) {
143 case 0: bitrate_mode = IIS_XHEAACENC_BITRATEMODE_AAC_VBR0; break;
144 case 1: bitrate_mode = IIS_XHEAACENC_BITRATEMODE_AAC_VBR1; break;
145 case 2: bitrate_mode = IIS_XHEAACENC_BITRATEMODE_AAC_VBR2; break;
146 case 3: bitrate_mode = IIS_XHEAACENC_BITRATEMODE_AAC_VBR3; break;
147 case 4: bitrate_mode = IIS_XHEAACENC_BITRATEMODE_AAC_VBR4; break;
148 case 5: bitrate_mode = IIS_XHEAACENC_BITRATEMODE_AAC_VBR5; break;
149 case 6: bitrate_mode = IIS_XHEAACENC_BITRATEMODE_AAC_VBR6; break;
150 }
151 } else {
152 bitrate_mode = IIS_XHEAACENC_BITRATEMODE_CBR;
153
154 int orig_bit_rate = avctx->bit_rate;
155 if (avctx->bit_rate <= 0) {
156 avctx->bit_rate = (32 + 32*avctx->ch_layout.nb_channels) * avctx->sample_rate / 44;
157 /* The encoder fails with bitrates below 12 kbps. */
158 avctx->bit_rate = FFMAX(avctx->bit_rate, 12000);
159 }
160
161 /* The bitrate needs to be a multiple of 2000 */
162 avctx->bit_rate = (avctx->bit_rate / 2000) * 2000;
163
164 if (orig_bit_rate > 0 && orig_bit_rate != avctx->bit_rate)
165 av_log(avctx, AV_LOG_WARNING,
166 "Bitrate %d is not a multiple of 2000, using %"PRId64"\n",
167 orig_bit_rate, avctx->bit_rate);
168
169 err = IIS_xHEAACEnc_Config_AddParamValueInt(config_handle,
170 IIS_XHEAACENC_PARAMETER_BITRATE, avctx->bit_rate);
171 if (err != IIS_XHEAACENC_NO_ERROR) {
172 av_log(avctx, AV_LOG_ERROR, "Unable to set bitrate: %s (%d)\n",
173 xhe_aac_get_error(err), err);
174 goto error;
175 }
176 }
177 err = IIS_xHEAACEnc_Config_AddParamValueInt(config_handle,
178 IIS_XHEAACENC_PARAMETER_BITRATEMODE, bitrate_mode);
179 if (err != IIS_XHEAACENC_NO_ERROR) {
180 av_log(avctx, AV_LOG_ERROR, "Unable to set bitrate mode: %s (%d)\n",
181 xhe_aac_get_error(err), err);
182 goto error;
183 }
184
185 /* We always output a raw bitstream, with an ASC in extradata, regardless
186 * of the AV_CODEC_FLAG_GLOBAL_HEADER flag. xHE-AAC can't be muxed in
187 * ADTS. It can be muxed in LATM/LOAS, but in libavcodec, that uses a
188 * different codec ID - so we can't conditionally switch to that here.
189 * Therefore, always output the raw/ASC form. */
190 err = IIS_xHEAACEnc_Config_AddParamValueInt(config_handle,
191 IIS_XHEAACENC_PARAMETER_TRANSPORTFORMAT,
192 IIS_XHEAACENC_TRANSPORTFORMAT_RAW);
193 if (err != IIS_XHEAACENC_NO_ERROR) {
194 av_log(avctx, AV_LOG_ERROR, "Unable to set transport format: %s (%d)\n",
195 xhe_aac_get_error(err), err);
196 goto error;
197 }
198
199 err = IIS_xHEAACEnc_Config_AddParamValueInt(config_handle,
200 IIS_XHEAACENC_PARAMETER_AOT, IIS_XHEAACENC_AOT_USAC);
201 if (err != IIS_XHEAACENC_NO_ERROR) {
202 av_log(avctx, AV_LOG_ERROR, "Unable to set AOT: %s (%d)\n",
203 xhe_aac_get_error(err), err);
204 goto error;
205 }
206
207 if (s->stream_id < 0) {
208 /* The encoder requires us to provide a stream ID. Within an
209 * adaptation set, the stream ID needs to be unique. If the user didn't
210 * specify one, try to make one up that probably is unique. */
211 if (s->vbr >= 0)
212 s->stream_id = s->vbr;
213 else
214 s->stream_id = avctx->bit_rate / 1000;
215 }
216 err = IIS_xHEAACEnc_Config_AddParamValueInt(config_handle,
217 IIS_XHEAACENC_PARAMETER_STREAMID, s->stream_id);
218 if (err != IIS_XHEAACENC_NO_ERROR) {
219 av_log(avctx, AV_LOG_ERROR, "Unable to set stream ID: %s (%d)\n",
220 xhe_aac_get_error(err), err);
221 goto error;
222 }
223 err = IIS_xHEAACEnc_Config_AddParamValueInt(config_handle,
224 IIS_XHEAACENC_PARAMETER_RAP_OCCURRENCE,
225 IIS_XHEAACENC_RAP_OCCURRENCE_CONSTANT_INTERVAL);
226 if (err != IIS_XHEAACENC_NO_ERROR) {
227 av_log(avctx, AV_LOG_ERROR, "Unable to set RAP occurrence: %s (%d)\n",
228 xhe_aac_get_error(err), err);
229 goto error;
230 }
231 if (s->rap_interval > 0) {
232 err = IIS_xHEAACEnc_Config_AddParamValueInt(config_handle,
233 IIS_XHEAACENC_PARAMETER_RAP_INTERVAL_MS, s->rap_interval / 1000);
234 if (err != IIS_XHEAACENC_NO_ERROR) {
235 av_log(avctx, AV_LOG_ERROR, "Unable to set RAP interval: %s (%d)\n",
236 xhe_aac_get_error(err), err);
237 goto error;
238 }
239 }
240 err = IIS_xHEAACEnc_Config_AddParamValueFloat(config_handle,
241 IIS_XHEAACENC_PARAMETER_LIVE_LOUDNESS_LEVEL, s->live_loudness_level);
242 if (err != IIS_XHEAACENC_NO_ERROR) {
243 av_log(avctx, AV_LOG_ERROR, "Unable to set live loudness level: %s (%d)\n",
244 xhe_aac_get_error(err), err);
245 goto error;
246 }
247
248 err = IIS_xHEAACEnc_Config_Finalize(config_handle);
249 if (err != IIS_XHEAACENC_NO_ERROR) {
250 av_log(avctx, AV_LOG_ERROR, "Unable to finalize config: %s (%d)\n",
251 xhe_aac_get_error(err), err);
252 goto error;
253 }
254
255 err = IIS_xHEAACEnc_Open(&s->handle, config_handle);
256 if (err != IIS_XHEAACENC_NO_ERROR) {
257 av_log(avctx, AV_LOG_ERROR, "Unable to open encoder: %s (%d)\n",
258 xhe_aac_get_error(err), err);
259 goto error;
260 }
261
262 err = IIS_xHEAACEnc_Config_Delete(config_handle);
263 if (err != IIS_XHEAACENC_NO_ERROR) {
264 av_log(avctx, AV_LOG_ERROR, "Unable to delete config: %s (%d)\n",
265 xhe_aac_get_error(err), err);
266 goto error;
267 }
268 config_handle = NULL;
269
270 err = IIS_xHEAACEnc_GetParam(s->handle, IIS_XHEAACENC_PARAMETER_OUTSAMPLERATE,
271 IIS_XHEAACENC_PARAM_INT,
272 &s->sample_rate, sizeof(s->sample_rate));
273 if (err != IIS_XHEAACENC_NO_ERROR) {
274 av_log(avctx, AV_LOG_ERROR, "Unable to get sample rate: %s (%d)\n",
275 xhe_aac_get_error(err), err);
276 goto error;
277 }
278 if (s->sample_rate != avctx->sample_rate) {
279 av_log(avctx, AV_LOG_ERROR, "Encoder resamples %d into %d - not supported\n",
280 avctx->sample_rate, s->sample_rate);
281 goto error;
282 }
283
284 err = IIS_xHEAACEnc_GetParam(s->handle, IIS_XHEAACENC_PARAMETER_FRAMESAMPLES,
285 IIS_XHEAACENC_PARAM_INT,
286 &out_framesize, sizeof(out_framesize));
287 if (err != IIS_XHEAACENC_NO_ERROR) {
288 av_log(avctx, AV_LOG_ERROR, "Unable to get frame size: %s (%d)\n",
289 xhe_aac_get_error(err), err);
290 goto error;
291 }
292 avctx->frame_size = out_framesize;
293
294 /* Note - this encoder doesn't incur any extra avctx->initial_padding
295 * that needs to be signaled and removed after decoding. (There exists
296 * a parameter IIS_XHEAACENC_PARAMETER_PRIMING we could query, but
297 * it returns zero.) */
298
299 ff_af_queue_init(avctx, &s->afq);
300
301 IIS_XHEAACENC_ASCINFO asc_info;
302 err = IIS_xHEAACEnc_GetAscInfo(s->handle, &asc_info);
303 if (err != IIS_XHEAACENC_NO_ERROR) {
304 av_log(avctx, AV_LOG_ERROR, "Unable to get ASC info: %s (%d)\n",
305 xhe_aac_get_error(err), err);
306 goto error;
307 }
308
309 avctx->extradata_size = (asc_info.ascSizeBits + 7) / 8;
310 avctx->extradata = av_mallocz(avctx->extradata_size +
312 if (!avctx->extradata) {
313 ret = AVERROR(ENOMEM);
314 goto error;
315 }
316 memcpy(avctx->extradata, asc_info.ascBuffer, avctx->extradata_size);
317
318 cpb_props = ff_encode_add_cpb_side_data(avctx);
319 if (!cpb_props) {
320 ret = AVERROR(ENOMEM);
321 goto error;
322 }
323
324 err = IIS_xHEAACEnc_GetParam(s->handle, IIS_XHEAACENC_PARAMETER_BITRATELIMIT,
325 IIS_XHEAACENC_PARAM_INT,
326 &out_max_bitrate, sizeof(out_max_bitrate));
327 if (err != IIS_XHEAACENC_NO_ERROR) {
328 av_log(avctx, AV_LOG_ERROR, "Unable to get max bitrate: %s (%d)\n",
329 xhe_aac_get_error(err), err);
330 goto error;
331 }
332
333 err = IIS_xHEAACEnc_GetParam(s->handle, IIS_XHEAACENC_PARAMETER_BITRATE,
334 IIS_XHEAACENC_PARAM_INT,
335 &out_avg_bitrate, sizeof(out_avg_bitrate));
336 if (err != IIS_XHEAACENC_NO_ERROR) {
337 av_log(avctx, AV_LOG_ERROR, "Unable to get avg bitrate: %s (%d)\n",
338 xhe_aac_get_error(err), err);
339 goto error;
340 }
341 cpb_props->max_bitrate = out_max_bitrate;
342 cpb_props->avg_bitrate = out_avg_bitrate;
343 if (avctx->bit_rate <= 0)
344 avctx->bit_rate = out_avg_bitrate;
345
346 s->sample_queue_size = 4096*20;
347 s->sample_queue = av_malloc(s->sample_queue_size * sizeof(*s->sample_queue));
348 if (!s->sample_queue) {
349 ret = AVERROR(ENOMEM);
350 goto error;
351 }
352
353 return 0;
354error:
355 if (config_handle) {
356 err = IIS_xHEAACEnc_Config_Delete(config_handle);
357 if (err != IIS_XHEAACENC_NO_ERROR)
358 av_log(avctx, AV_LOG_ERROR, "Unable to delete config: %s (%d)\n",
359 xhe_aac_get_error(err), err);
360 }
361 return ret;
362}
363
365 const AVFrame *frame, int *got_packet_ptr)
366{
367 XHEAACContext *s = avctx->priv_data;
368 IIS_XHEAACENC_RETURN_CODE err;
369 int samples_next;
370 int ret;
371
372 if (frame) {
373 int nb_new_samples = frame->nb_samples * avctx->ch_layout.nb_channels;
374
375 if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
376 return ret;
377
378 if (s->nb_sample_queue + nb_new_samples > s->sample_queue_size) {
379 int size = s->nb_sample_queue + nb_new_samples + 4096;
380 float *ptr = av_realloc(s->sample_queue, size * sizeof(*s->sample_queue));
381 if (!ptr)
382 return AVERROR(ENOMEM);
383 s->sample_queue = ptr;
384 s->sample_queue_size = size;
385 }
386
387 /* As long as we don't have enough samples, we could also feed them
388 * straight into the encoder - it does accept getting too few samples.
389 *
390 * But we can't feed it too many samples, and samples_next doesn't
391 * align with the frame size, so we need to buffer the remainder in any
392 * case. Thus for simplicity, just buffer up all samples in the wrapper.
393 *
394 * (The encoder has got a parameter IIS_XHEAACENC_PARAMETER_SAMPLES_MAX
395 * which is said to possibly be larger than IIS_XHEAACENC_PARAMETER_SAMPLES_NEXT,
396 * but currently, at least at start, one can't pass more than
397 * samples_next.)
398 */
399 memcpy(s->sample_queue + s->nb_sample_queue, frame->data[0],
400 nb_new_samples * sizeof(*s->sample_queue));
401 s->nb_sample_queue += nb_new_samples;
402 }
403
404 err = IIS_xHEAACEnc_GetParam(s->handle, IIS_XHEAACENC_PARAMETER_SAMPLES_NEXT,
405 IIS_XHEAACENC_PARAM_INT,
406 &samples_next, sizeof(samples_next));
407 if (err != IIS_XHEAACENC_NO_ERROR) {
408 av_log(avctx, AV_LOG_ERROR, "Unable to get number of required samples: %s (%d)\n",
409 xhe_aac_get_error(err), err);
410 return AVERROR(EINVAL);
411 }
412
413 if (s->nb_sample_queue < samples_next && frame) {
414 /* Not enough samples yet, and not end of stream - don't push it
415 * yet. */
416 return 0;
417 }
418
419 int min_outbuf_size;
420 err = IIS_xHEAACEnc_GetParam(s->handle, IIS_XHEAACENC_PARAMETER_MIN_OUTBUF_SIZE,
421 IIS_XHEAACENC_PARAM_INT,
422 &min_outbuf_size, sizeof(min_outbuf_size));
423 if (err != IIS_XHEAACENC_NO_ERROR) {
424 av_log(avctx, AV_LOG_ERROR, "Unable to get minimum output buffer size: %s (%d)\n",
425 xhe_aac_get_error(err), err);
426 return AVERROR(EINVAL);
427 }
428 ret = ff_alloc_packet(avctx, avpkt, min_outbuf_size);
429 if (ret < 0)
430 return ret;
431
432 int nb_samples = FFMIN(s->nb_sample_queue, samples_next);
433 int out_bytes;
434 IIS_XHEAACENC_AUINFO au_info;
435
436 err = IIS_xHEAACEnc_EncodeFrame(s->handle, s->sample_queue, nb_samples,
437 (unsigned char *)avpkt->data, &out_bytes,
438 avpkt->size, &au_info);
439 if (err != IIS_XHEAACENC_NO_ERROR) {
440 av_log(avctx, AV_LOG_ERROR, "Unable to encode frame: %s (%d)\n",
441 xhe_aac_get_error(err), err);
442 return AVERROR(EINVAL);
443 }
444 s->nb_sample_queue -= nb_samples;
445 memmove(s->sample_queue, s->sample_queue + nb_samples,
446 s->nb_sample_queue * sizeof(*s->sample_queue));
447
448 IIS_XHEAACENC_ENCODER_STATE state;
449 err = IIS_xHEAACEnc_GetEncoderState(s->handle, &state);
450 if (err != IIS_XHEAACENC_NO_ERROR) {
451 av_log(avctx, AV_LOG_ERROR, "Unable to get encoder state: %s (%d)\n",
452 xhe_aac_get_error(err), err);
453 return AVERROR(EINVAL);
454 }
455
456 /* If no output packet was generated and the encoder isn't ready to
457 * close yet, force the encoder into flushing mode. */
458 if (out_bytes <= 0 && !frame && state != IIS_XHEAACENC_ENCODER_STATE_READY_TO_CLOSE) {
459 while (state != IIS_XHEAACENC_ENCODER_STATE_FLUSHING &&
460 state != IIS_XHEAACENC_ENCODER_STATE_READY_TO_CLOSE) {
461 err = IIS_xHEAACEnc_EncodeFrame(s->handle, NULL, 0,
462 (unsigned char *)avpkt->data,
463 &out_bytes, avpkt->size, &au_info);
464 if (err != IIS_XHEAACENC_NO_ERROR) {
465 av_log(avctx, AV_LOG_ERROR, "Unable to flush encoder: %s (%d)\n",
466 xhe_aac_get_error(err), err);
467 return AVERROR(EINVAL);
468 }
469
470 err = IIS_xHEAACEnc_GetEncoderState(s->handle, &state);
471 if (err != IIS_XHEAACENC_NO_ERROR) {
472 av_log(avctx, AV_LOG_ERROR, "Unable to get encoder state: %s (%d)\n",
473 xhe_aac_get_error(err), err);
474 return AVERROR(EINVAL);
475 }
476 }
477 }
478
479 avpkt->size = out_bytes;
480 if (out_bytes > 0) {
481 *got_packet_ptr = 1;
482
483 if (au_info.auOffset != 0) {
484 av_log(avctx, AV_LOG_ERROR,
485 "Encoder reports auOffset of %d. This is currently not implemented.\n",
486 au_info.auOffset);
487 return AVERROR(EINVAL);
488 }
489
490 switch (au_info.isSyncFrame) {
491 case IIS_XHEAACENC_SYNCFRAME_NO:
492 case IIS_XHEAACENC_SYNCFRAME_INDEPENDENT_FRAME:
493 case IIS_XHEAACENC_SYNCFRAME_STREAM_MUX_CONFIG_IF:
494 break;
495 case IIS_XHEAACENC_SYNCFRAME_IMMEDIATE_PLAY_OUT_FRAME:
496 case IIS_XHEAACENC_SYNCFRAME_STREAM_MUX_CONFIG_IPF:
497 avpkt->flags |= AV_PKT_FLAG_KEY;
498 break;
499 case IIS_XHEAACENC_SYNCFRAME_INVALID:
500 default:
501 av_log(avctx, AV_LOG_ERROR, "Unexpected isSyncFrame status %d\n",
502 au_info.isSyncFrame);
503 return AVERROR(EINVAL);
504 }
505
506 ff_af_queue_remove(&s->afq, au_info.auSamplesValid, avpkt);
507 } else {
508 avpkt->size = 0;
509 }
510
511 return 0;
512}
513
514static const AVProfile profiles[] = {
515 { AV_PROFILE_AAC_USAC, "xHE-AAC" },
517};
518
520 { "b", "0" },
521 { NULL }
522};
523
529
530static const int xhe_aac_sample_rates[] = {
531 48000, 44100, 0
532};
533
535 .p.name = "libfdk_xhe_aac",
536 CODEC_LONG_NAME("Fraunhofer FDK xHE-AAC"),
537 .p.type = AVMEDIA_TYPE_AUDIO,
538 .p.id = AV_CODEC_ID_AAC,
539 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
541 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
543 .priv_data_size = sizeof(XHEAACContext),
546 .close = xhe_aac_encode_close,
548 .p.priv_class = &xhe_aac_enc_class,
549 .defaults = xhe_aac_encode_defaults,
550 .p.profiles = profiles,
552 .p.wrapper_name = "libfdk-xhe-aac",
554};
const FFCodec ff_libfdk_xhe_aac_encoder
av_cold void ff_af_queue_close(AudioFrameQueue *afq)
Close AudioFrameQueue.
av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
Initialize AudioFrameQueue.
int ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, AVPacket *pkt)
Remove frame(s) from the queue.
int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
Add a frame to the queue.
Libavcodec external API header.
static int FUNC au_info(CodedBitstreamContext *ctx, RWContext *rw, APVRawAUInfo *current)
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
#define CODEC_SAMPLERATES_ARRAY(array)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define CODEC_SAMPLEFMTS(...)
#define CODEC_CH_LAYOUTS_ARRAY(array)
common internal and external API header
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
#define AV_PROFILE_AAC_USAC
Definition defs.h:76
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition encode.c:62
AVCPBProperties * ff_encode_add_cpb_side_data(AVCodecContext *avctx)
Add a CPB properties side data to an encoding context.
Definition encode.c:1039
static struct @346255127015250356166251341105367306144006377143 state
#define AV_OPT_FLAG_AUDIO_PARAM
Definition opt.h:356
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition opt.h:351
@ AV_OPT_TYPE_DURATION
Underlying C type is int64_t.
Definition opt.h:318
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition opt.h:270
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition codec.h:79
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_SMALL_LAST_FRAME
Codec can be fed a final frame with a smaller size.
Definition codec.h:84
@ AV_CODEC_ID_AAC
Definition codec_id.h:459
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:657
#define AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_MONO
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_FLT
float
Definition samplefmt.h:60
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define av_cold
Definition attributes.h:117
static const AVProfile profiles[]
static av_cold int xhe_aac_encode_close(AVCodecContext *avctx)
static const int xhe_aac_sample_rates[]
static const AVOption xhe_aac_enc_options[]
static int xhe_aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
static const AVChannelLayout xhe_aac_ch_layouts[]
static const char * xhe_aac_get_error(IIS_XHEAACENC_RETURN_CODE err)
static av_cold int xhe_aac_encode_init(AVCodecContext *avctx)
static const AVClass xhe_aac_enc_class
static const FFCodecDefault xhe_aac_encode_defaults[]
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
Memory handling functions.
#define av_realloc(p, s)
Definition ops_static.c:54
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
#define FF_AAC_PROFILE_OPTS
Definition profiles.h:29
This structure describes the bitrate properties of an encoded bitstream.
Definition defs.h:296
int64_t avg_bitrate
Average bitrate of the stream, in bits per second.
Definition defs.h:311
int64_t max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition defs.h:301
An AVChannelLayout holds information about the channel layout of audio data.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
AVChannelLayout ch_layout
Audio channel layout.
Definition avcodec.h:1055
int64_t bit_rate
the average bitrate
Definition avcodec.h:493
int profile
profile
Definition avcodec.h:1641
int sample_rate
samples per second
Definition avcodec.h:1040
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int extradata_size
Definition avcodec.h:527
int frame_size
Number of samples per channel in an audio frame.
Definition avcodec.h:1068
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:587
int flags
A combination of AV_PKT_FLAG values.
Definition packet.h:616
int size
Definition packet.h:611
uint8_t * data
Definition packet.h:610
AVProfile.
Definition codec.h:167
IIS_XHEAACENC_INSTANCE_HANDLE handle
AudioFrameQueue afq
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static void error(const char *err)
int size