WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / libhb / encavcodecaudio.c
blob2f302b3488e0ebe2284acc52771251033c838a9a
1 /* encavcodecaudio.c
3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
8 */
10 #include "hb.h"
11 #include "hbffmpeg.h"
13 struct hb_work_private_s
15 hb_job_t * job;
16 AVCodecContext * context;
18 int out_discrete_channels;
19 int samples_per_frame;
20 unsigned long max_output_bytes;
21 unsigned long input_samples;
22 uint8_t * output_buf;
23 uint8_t * input_buf;
24 hb_list_t * list;
26 AVAudioResampleContext *avresample;
29 static int encavcodecaInit( hb_work_object_t *, hb_job_t * );
30 static int encavcodecaWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
31 static void encavcodecaClose( hb_work_object_t * );
33 hb_work_object_t hb_encavcodeca =
35 WORK_ENCAVCODEC_AUDIO,
36 "AVCodec Audio encoder (libavcodec)",
37 encavcodecaInit,
38 encavcodecaWork,
39 encavcodecaClose
42 static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
44 AVCodec *codec;
45 AVCodecContext *context;
46 hb_audio_t *audio = w->audio;
48 hb_work_private_t *pv = calloc(1, sizeof(hb_work_private_t));
49 w->private_data = pv;
50 pv->job = job;
51 pv->list = hb_list_init();
53 // channel count, layout and matrix encoding
54 int matrix_encoding;
55 uint64_t channel_layout = hb_ff_mixdown_xlat(audio->config.out.mixdown,
56 &matrix_encoding);
57 pv->out_discrete_channels =
58 hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
60 // default settings and options
61 AVDictionary *av_opts = NULL;
62 const char *codec_name = NULL;
63 enum AVCodecID codec_id = AV_CODEC_ID_NONE;
64 enum AVSampleFormat sample_fmt = AV_SAMPLE_FMT_FLTP;
65 int bits_per_raw_sample = 0;
66 int profile = FF_PROFILE_UNKNOWN;
68 // override with encoder-specific values
69 switch (audio->config.out.codec)
71 case HB_ACODEC_AC3:
72 codec_id = AV_CODEC_ID_AC3;
73 if (matrix_encoding != AV_MATRIX_ENCODING_NONE)
74 av_dict_set(&av_opts, "dsur_mode", "on", 0);
75 break;
77 case HB_ACODEC_FFEAC3:
78 codec_id = AV_CODEC_ID_EAC3;
79 if (matrix_encoding != AV_MATRIX_ENCODING_NONE)
80 av_dict_set(&av_opts, "dsur_mode", "on", 0);
81 break;
83 case HB_ACODEC_FDK_AAC:
84 case HB_ACODEC_FDK_HAAC:
85 codec_name = "libfdk_aac";
86 sample_fmt = AV_SAMPLE_FMT_S16;
87 bits_per_raw_sample = 16;
88 switch (audio->config.out.codec)
90 case HB_ACODEC_FDK_HAAC:
91 profile = FF_PROFILE_AAC_HE;
92 break;
93 default:
94 profile = FF_PROFILE_AAC_LOW;
95 break;
97 // Libav's libfdk-aac wrapper expects back channels for 5.1
98 // audio, and will error out unless we translate the layout
99 if (channel_layout == AV_CH_LAYOUT_5POINT1)
100 channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
101 break;
103 case HB_ACODEC_FFAAC:
104 codec_name = "aac";
105 av_dict_set(&av_opts, "stereo_mode", "ms_off", 0);
106 break;
108 case HB_ACODEC_FFFLAC:
109 case HB_ACODEC_FFFLAC24:
110 codec_id = AV_CODEC_ID_FLAC;
111 switch (audio->config.out.codec)
113 case HB_ACODEC_FFFLAC24:
114 sample_fmt = AV_SAMPLE_FMT_S32;
115 bits_per_raw_sample = 24;
116 break;
117 default:
118 sample_fmt = AV_SAMPLE_FMT_S16;
119 bits_per_raw_sample = 16;
120 break;
122 break;
124 default:
125 hb_error("encavcodecaInit: unsupported codec (0x%x)",
126 audio->config.out.codec);
127 return 1;
129 if (codec_name != NULL)
131 codec = avcodec_find_encoder_by_name(codec_name);
132 if (codec == NULL)
134 hb_error("encavcodecaInit: avcodec_find_encoder_by_name(%s) failed",
135 codec_name);
136 return 1;
139 else
141 codec = avcodec_find_encoder(codec_id);
142 if (codec == NULL)
144 hb_error("encavcodecaInit: avcodec_find_encoder(%d) failed",
145 codec_id);
146 return 1;
149 // allocate the context and apply the settings
150 context = avcodec_alloc_context3(codec);
151 hb_ff_set_sample_fmt(context, codec, sample_fmt);
152 context->bits_per_raw_sample = bits_per_raw_sample;
153 context->profile = profile;
154 context->channel_layout = channel_layout;
155 context->channels = pv->out_discrete_channels;
156 context->sample_rate = audio->config.out.samplerate;
158 if (audio->config.out.bitrate > 0)
160 context->bit_rate = audio->config.out.bitrate * 1000;
162 else if (audio->config.out.quality >= 0)
164 context->global_quality = audio->config.out.quality * FF_QP2LAMBDA;
165 context->flags |= CODEC_FLAG_QSCALE;
166 if (audio->config.out.codec == HB_ACODEC_FDK_AAC ||
167 audio->config.out.codec == HB_ACODEC_FDK_HAAC)
169 char vbr[2];
170 snprintf(vbr, 2, "%.1g", audio->config.out.quality);
171 av_dict_set(&av_opts, "vbr", vbr, 0);
175 if (audio->config.out.compression_level >= 0)
177 context->compression_level = audio->config.out.compression_level;
180 // For some codecs, libav requires the following flag to be set
181 // so that it fills extradata with global header information.
182 // If this flag is not set, it inserts the data into each
183 // packet instead.
184 context->flags |= CODEC_FLAG_GLOBAL_HEADER;
186 if (hb_avcodec_open(context, codec, &av_opts, 0))
188 hb_error("encavcodecaInit: hb_avcodec_open() failed");
189 return 1;
191 // avcodec_open populates the opts dictionary with the
192 // things it didn't recognize.
193 AVDictionaryEntry *t = NULL;
194 while ((t = av_dict_get(av_opts, "", t, AV_DICT_IGNORE_SUFFIX)))
196 hb_log("encavcodecaInit: Unknown avcodec option %s", t->key);
198 av_dict_free(&av_opts);
200 pv->context = context;
201 audio->config.out.samples_per_frame =
202 pv->samples_per_frame = context->frame_size;
203 pv->input_samples = context->frame_size * context->channels;
204 pv->input_buf = malloc(pv->input_samples * sizeof(float));
205 // Some encoders in libav (e.g. fdk-aac) fail if the output buffer
206 // size is not some minumum value. 8K seems to be enough :(
207 pv->max_output_bytes = MAX(FF_MIN_BUFFER_SIZE,
208 (pv->input_samples *
209 av_get_bytes_per_sample(context->sample_fmt)));
211 // sample_fmt conversion
212 if (context->sample_fmt != AV_SAMPLE_FMT_FLT)
214 pv->output_buf = malloc(pv->max_output_bytes);
215 pv->avresample = avresample_alloc_context();
216 if (pv->avresample == NULL)
218 hb_error("encavcodecaInit: avresample_alloc_context() failed");
219 return 1;
221 av_opt_set_int(pv->avresample, "in_sample_fmt",
222 AV_SAMPLE_FMT_FLT, 0);
223 av_opt_set_int(pv->avresample, "out_sample_fmt",
224 context->sample_fmt, 0);
225 av_opt_set_int(pv->avresample, "in_channel_layout",
226 context->channel_layout, 0);
227 av_opt_set_int(pv->avresample, "out_channel_layout",
228 context->channel_layout, 0);
229 if (hb_audio_dither_is_supported(audio->config.out.codec))
231 // dithering needs the sample rate
232 av_opt_set_int(pv->avresample, "in_sample_rate",
233 context->sample_rate, 0);
234 av_opt_set_int(pv->avresample, "out_sample_rate",
235 context->sample_rate, 0);
236 av_opt_set_int(pv->avresample, "dither_method",
237 audio->config.out.dither_method, 0);
239 if (avresample_open(pv->avresample))
241 hb_error("encavcodecaInit: avresample_open() failed");
242 avresample_free(&pv->avresample);
243 return 1;
246 else
248 pv->avresample = NULL;
249 pv->output_buf = pv->input_buf;
252 if (context->extradata != NULL)
254 memcpy(w->config->extradata.bytes, context->extradata,
255 context->extradata_size);
256 w->config->extradata.length = context->extradata_size;
259 audio->config.out.delay = av_rescale_q(context->delay, context->time_base,
260 (AVRational){1, 90000});
262 return 0;
265 /***********************************************************************
266 * Close
267 ***********************************************************************
269 **********************************************************************/
270 // Some encoders (e.g. flac) require a final NULL encode in order to
271 // finalize things.
272 static void Finalize(hb_work_object_t *w)
274 hb_work_private_t *pv = w->private_data;
276 // Finalize with NULL input needed by FLAC to generate md5sum
277 // in context extradata
279 // Prepare output packet
280 AVPacket pkt;
281 int got_packet;
282 hb_buffer_t *buf = hb_buffer_init(pv->max_output_bytes);
283 av_init_packet(&pkt);
284 pkt.data = buf->data;
285 pkt.size = buf->alloc;
287 avcodec_encode_audio2(pv->context, &pkt, NULL, &got_packet);
288 hb_buffer_close(&buf);
290 // Then we need to recopy the header since it was modified
291 if (pv->context->extradata != NULL)
293 memcpy(w->config->extradata.bytes, pv->context->extradata,
294 pv->context->extradata_size);
295 w->config->extradata.length = pv->context->extradata_size;
299 static void encavcodecaClose(hb_work_object_t * w)
301 hb_work_private_t * pv = w->private_data;
303 if (pv != NULL)
305 if (pv->context != NULL)
307 Finalize(w);
308 hb_deep_log(2, "encavcodeca: closing libavcodec");
309 if (pv->context->codec != NULL)
310 avcodec_flush_buffers(pv->context);
311 hb_avcodec_close(pv->context);
312 av_free( pv->context );
315 if (pv->output_buf != NULL)
317 free(pv->output_buf);
319 if (pv->input_buf != NULL && pv->input_buf != pv->output_buf)
321 free(pv->input_buf);
323 pv->output_buf = pv->input_buf = NULL;
325 if (pv->list != NULL)
327 hb_list_empty(&pv->list);
330 if (pv->avresample != NULL)
332 avresample_free(&pv->avresample);
335 free(pv);
336 w->private_data = NULL;
340 static hb_buffer_t* Encode(hb_work_object_t *w)
342 hb_work_private_t *pv = w->private_data;
343 hb_audio_t *audio = w->audio;
344 uint64_t pts, pos;
346 if (hb_list_bytes(pv->list) < pv->input_samples * sizeof(float))
348 return NULL;
351 hb_list_getbytes(pv->list, pv->input_buf, pv->input_samples * sizeof(float),
352 &pts, &pos);
354 // Prepare input frame
355 int out_linesize;
356 int out_size = av_samples_get_buffer_size(&out_linesize,
357 pv->context->channels,
358 pv->samples_per_frame,
359 pv->context->sample_fmt, 1);
360 AVFrame frame = { .nb_samples = pv->samples_per_frame, };
361 avcodec_fill_audio_frame(&frame,
362 pv->context->channels, pv->context->sample_fmt,
363 pv->output_buf, out_size, 1);
364 if (pv->avresample != NULL)
366 int in_linesize;
367 av_samples_get_buffer_size(&in_linesize, pv->context->channels,
368 frame.nb_samples, AV_SAMPLE_FMT_FLT, 1);
369 int out_samples = avresample_convert(pv->avresample,
370 frame.extended_data, out_linesize,
371 frame.nb_samples,
372 &pv->input_buf, in_linesize,
373 frame.nb_samples);
374 if (out_samples != pv->samples_per_frame)
376 // we're not doing sample rate conversion, so this shouldn't happen
377 hb_log("encavcodecaWork: avresample_convert() failed");
378 return NULL;
382 // Libav requires that timebase of audio frames be in sample_rate units
383 frame.pts = pts + (90000 * pos / (sizeof(float) *
384 pv->out_discrete_channels *
385 audio->config.out.samplerate));
386 frame.pts = av_rescale(frame.pts, pv->context->sample_rate, 90000);
388 // Prepare output packet
389 AVPacket pkt;
390 int got_packet;
391 hb_buffer_t *out = hb_buffer_init(pv->max_output_bytes);
392 av_init_packet(&pkt);
393 pkt.data = out->data;
394 pkt.size = out->alloc;
396 // Encode
397 int ret = avcodec_encode_audio2(pv->context, &pkt, &frame, &got_packet);
398 if (ret < 0)
400 hb_log("encavcodeca: avcodec_encode_audio failed");
401 hb_buffer_close(&out);
402 return NULL;
405 if (got_packet && pkt.size)
407 out->size = pkt.size;
408 // The output pts from libav is in context->time_base. Convert it back
409 // to our timebase.
410 out->s.start = av_rescale_q(pkt.pts, pv->context->time_base,
411 (AVRational){1, 90000});
412 out->s.duration = (double)90000 * pv->samples_per_frame /
413 audio->config.out.samplerate;
414 out->s.stop = out->s.start + out->s.duration;
415 out->s.type = AUDIO_BUF;
416 out->s.frametype = HB_FRAME_AUDIO;
418 else
420 hb_buffer_close(&out);
421 return Encode(w);
424 return out;
427 static hb_buffer_t * Flush( hb_work_object_t * w )
429 hb_buffer_t *first, *buf, *last;
431 first = last = buf = Encode( w );
432 while( buf )
434 last = buf;
435 buf->next = Encode( w );
436 buf = buf->next;
439 if( last )
441 last->next = hb_buffer_eof_init();
443 else
445 first = hb_buffer_eof_init();
448 return first;
451 /***********************************************************************
452 * Work
453 ***********************************************************************
455 **********************************************************************/
456 static int encavcodecaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
457 hb_buffer_t ** buf_out )
459 hb_work_private_t * pv = w->private_data;
460 hb_buffer_t * in = *buf_in, * buf;
462 if (in->s.flags & HB_BUF_FLAG_EOF)
464 /* EOF on input - send it downstream & say we're done */
465 *buf_out = Flush( w );
466 return HB_WORK_DONE;
469 if ( pv->context == NULL || pv->context->codec == NULL )
471 // No encoder context. Nothing we can do.
472 return HB_WORK_OK;
475 hb_list_add( pv->list, in );
476 *buf_in = NULL;
478 *buf_out = buf = Encode( w );
480 while ( buf )
482 buf->next = Encode( w );
483 buf = buf->next;
486 return HB_WORK_OK;