2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2012> Collabora Ltd.
4 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
28 /* for stats file handling */
30 #include <glib/gstdio.h>
33 #include <libavcodec/avcodec.h>
38 #include "gstavcodecmap.h"
39 #include "gstavutils.h"
40 #include "gstavaudenc.h"
42 #define DEFAULT_AUDIO_BITRATE 128000
54 PROP_RTP_PAYLOAD_SIZE,
58 /* A number of function prototypes are given so we can refer to them later. */
59 static void gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass);
60 static void gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass);
61 static void gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc);
62 static void gst_ffmpegaudenc_finalize (GObject * object);
64 static gboolean gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder,
66 static GstFlowReturn gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder,
68 static gboolean gst_ffmpegaudenc_start (GstAudioEncoder * encoder);
69 static gboolean gst_ffmpegaudenc_stop (GstAudioEncoder * encoder);
70 static void gst_ffmpegaudenc_flush (GstAudioEncoder * encoder);
72 static void gst_ffmpegaudenc_set_property (GObject * object,
73 guint prop_id, const GValue * value, GParamSpec * pspec);
74 static void gst_ffmpegaudenc_get_property (GObject * object,
75 guint prop_id, GValue * value, GParamSpec * pspec);
77 #define GST_FFENC_PARAMS_QDATA g_quark_from_static_string("avenc-params")
79 static GstElementClass *parent_class = NULL;
81 /*static guint gst_ffmpegaudenc_signals[LAST_SIGNAL] = { 0 }; */
84 gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass)
86 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
88 GstPadTemplate *srctempl = NULL, *sinktempl = NULL;
89 GstCaps *srccaps = NULL, *sinkcaps = NULL;
90 gchar *longname, *description;
93 (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
94 GST_FFENC_PARAMS_QDATA);
95 g_assert (in_plugin != NULL);
97 /* construct the element details struct */
98 longname = g_strdup_printf ("libav %s encoder", in_plugin->long_name);
99 description = g_strdup_printf ("libav %s encoder", in_plugin->name);
100 gst_element_class_set_metadata (element_class, longname,
101 "Codec/Encoder/Audio", description,
102 "Wim Taymans <wim.taymans@gmail.com>, "
103 "Ronald Bultje <rbultje@ronald.bitfreak.net>");
105 g_free (description);
107 if (!(srccaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, TRUE))) {
108 GST_DEBUG ("Couldn't get source caps for encoder '%s'", in_plugin->name);
109 srccaps = gst_caps_new_empty_simple ("unknown/unknown");
112 sinkcaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
113 in_plugin->id, TRUE, in_plugin);
115 GST_DEBUG ("Couldn't get sink caps for encoder '%s'", in_plugin->name);
116 sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
120 sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
121 GST_PAD_ALWAYS, sinkcaps);
122 srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
124 gst_element_class_add_pad_template (element_class, srctempl);
125 gst_element_class_add_pad_template (element_class, sinktempl);
127 klass->in_plugin = in_plugin;
128 klass->srctempl = srctempl;
129 klass->sinktempl = sinktempl;
135 gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass)
137 GObjectClass *gobject_class;
138 GstAudioEncoderClass *gstaudioencoder_class;
140 gobject_class = (GObjectClass *) klass;
141 gstaudioencoder_class = (GstAudioEncoderClass *) klass;
143 parent_class = g_type_class_peek_parent (klass);
145 gobject_class->set_property = gst_ffmpegaudenc_set_property;
146 gobject_class->get_property = gst_ffmpegaudenc_get_property;
148 /* FIXME: could use -1 for a sensible per-codec defaults */
149 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BIT_RATE,
150 g_param_spec_int ("bitrate", "Bit Rate",
151 "Target Audio Bitrate", 0, G_MAXINT, DEFAULT_AUDIO_BITRATE,
152 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
153 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COMPLIANCE,
154 g_param_spec_enum ("compliance", "Compliance",
155 "Adherence of the encoder to the specifications",
156 GST_TYPE_FFMPEG_COMPLIANCE, FFMPEG_DEFAULT_COMPLIANCE,
157 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
159 gobject_class->finalize = gst_ffmpegaudenc_finalize;
161 gstaudioencoder_class->start = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_start);
162 gstaudioencoder_class->stop = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_stop);
163 gstaudioencoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_flush);
164 gstaudioencoder_class->set_format =
165 GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_set_format);
166 gstaudioencoder_class->handle_frame =
167 GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_handle_frame);
171 gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
173 GstFFMpegAudEncClass *klass =
174 (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
176 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (ffmpegaudenc));
179 ffmpegaudenc->context = avcodec_alloc_context3 (klass->in_plugin);
180 ffmpegaudenc->opened = FALSE;
181 ffmpegaudenc->frame = av_frame_alloc ();
183 ffmpegaudenc->compliance = FFMPEG_DEFAULT_COMPLIANCE;
185 gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (ffmpegaudenc), TRUE);
189 gst_ffmpegaudenc_finalize (GObject * object)
191 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) object;
193 /* clean up remaining allocated data */
194 av_frame_free (&ffmpegaudenc->frame);
195 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
196 av_free (ffmpegaudenc->context);
198 G_OBJECT_CLASS (parent_class)->finalize (object);
202 gst_ffmpegaudenc_start (GstAudioEncoder * encoder)
204 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
205 GstFFMpegAudEncClass *oclass =
206 (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
208 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
209 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
210 oclass->in_plugin) < 0) {
211 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
219 gst_ffmpegaudenc_stop (GstAudioEncoder * encoder)
221 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
223 /* close old session */
224 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
225 ffmpegaudenc->opened = FALSE;
231 gst_ffmpegaudenc_flush (GstAudioEncoder * encoder)
233 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
235 if (ffmpegaudenc->opened) {
236 avcodec_flush_buffers (ffmpegaudenc->context);
241 gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
243 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
245 GstCaps *allowed_caps;
248 GstFFMpegAudEncClass *oclass =
249 (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
251 /* close old session */
252 if (ffmpegaudenc->opened) {
253 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
254 ffmpegaudenc->opened = FALSE;
255 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
256 oclass->in_plugin) < 0) {
257 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
262 /* if we set it in _getcaps we should set it also in _link */
263 ffmpegaudenc->context->strict_std_compliance = ffmpegaudenc->compliance;
265 /* user defined properties */
266 if (ffmpegaudenc->bitrate > 0) {
267 GST_INFO_OBJECT (ffmpegaudenc, "Setting avcontext to bitrate %d",
268 ffmpegaudenc->bitrate);
269 ffmpegaudenc->context->bit_rate = ffmpegaudenc->bitrate;
270 ffmpegaudenc->context->bit_rate_tolerance = ffmpegaudenc->bitrate;
272 GST_INFO_OBJECT (ffmpegaudenc,
273 "Using avcontext default bitrate %" G_GINT64_FORMAT,
274 (gint64) ffmpegaudenc->context->bit_rate);
277 /* RTP payload used for GOB production (for Asterisk) */
278 if (ffmpegaudenc->rtp_payload_size) {
279 ffmpegaudenc->context->rtp_payload_size = ffmpegaudenc->rtp_payload_size;
282 /* some other defaults */
283 ffmpegaudenc->context->rc_strategy = 2;
284 ffmpegaudenc->context->b_frame_strategy = 0;
285 ffmpegaudenc->context->coder_type = 0;
286 ffmpegaudenc->context->context_model = 0;
287 ffmpegaudenc->context->scenechange_threshold = 0;
289 /* fetch pix_fmt and so on */
290 gst_ffmpeg_audioinfo_to_context (info, ffmpegaudenc->context);
291 if (!ffmpegaudenc->context->time_base.den) {
292 ffmpegaudenc->context->time_base.den = GST_AUDIO_INFO_RATE (info);
293 ffmpegaudenc->context->time_base.num = 1;
294 ffmpegaudenc->context->ticks_per_frame = 1;
297 if (ffmpegaudenc->context->channel_layout) {
298 gst_ffmpeg_channel_layout_to_gst (ffmpegaudenc->context->channel_layout,
299 ffmpegaudenc->context->channels, ffmpegaudenc->ffmpeg_layout);
300 ffmpegaudenc->needs_reorder =
301 (memcmp (ffmpegaudenc->ffmpeg_layout, info->position,
302 sizeof (GstAudioChannelPosition) *
303 ffmpegaudenc->context->channels) != 0);
306 /* some codecs support more than one format, first auto-choose one */
307 GST_DEBUG_OBJECT (ffmpegaudenc, "picking an output format ...");
308 allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
310 GST_DEBUG_OBJECT (ffmpegaudenc, "... but no peer, using template caps");
311 /* we need to copy because get_allowed_caps returns a ref, and
312 * get_pad_template_caps doesn't */
314 gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
316 GST_DEBUG_OBJECT (ffmpegaudenc, "chose caps %" GST_PTR_FORMAT, allowed_caps);
317 gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
318 oclass->in_plugin->type, allowed_caps, ffmpegaudenc->context);
321 if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) {
322 gst_caps_unref (allowed_caps);
323 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
324 GST_DEBUG_OBJECT (ffmpegaudenc, "avenc_%s: Failed to open FFMPEG codec",
325 oclass->in_plugin->name);
326 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
327 oclass->in_plugin) < 0)
328 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
330 if ((oclass->in_plugin->capabilities & CODEC_CAP_EXPERIMENTAL) &&
331 ffmpegaudenc->compliance != GST_FFMPEG_EXPERIMENTAL) {
332 GST_ELEMENT_ERROR (ffmpegaudenc, LIBRARY, SETTINGS,
333 ("Codec is experimental, but settings don't allow encoders to "
334 "produce output of experimental quality"),
335 ("This codec may not create output that is conformant to the specs "
336 "or of good quality. If you must use it anyway, set the "
337 "compliance property to experimental"));
342 /* try to set this caps on the other side */
343 other_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id,
344 ffmpegaudenc->context, TRUE);
347 gst_caps_unref (allowed_caps);
348 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
349 GST_DEBUG ("Unsupported codec - no caps found");
350 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
351 oclass->in_plugin) < 0)
352 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
356 icaps = gst_caps_intersect (allowed_caps, other_caps);
357 gst_caps_unref (allowed_caps);
358 gst_caps_unref (other_caps);
359 if (gst_caps_is_empty (icaps)) {
360 gst_caps_unref (icaps);
363 icaps = gst_caps_fixate (icaps);
365 if (!gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (ffmpegaudenc),
367 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
368 gst_caps_unref (icaps);
369 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
370 oclass->in_plugin) < 0)
371 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
374 gst_caps_unref (icaps);
376 frame_size = ffmpegaudenc->context->frame_size;
377 if (frame_size > 1) {
378 gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
380 gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
382 gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 1);
384 gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
386 gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
388 gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 0);
391 /* Store some tags */
393 GstTagList *tags = gst_tag_list_new_empty ();
396 gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_NOMINAL_BITRATE,
397 (guint) ffmpegaudenc->context->bit_rate, NULL);
400 gst_ffmpeg_get_codecid_longname (ffmpegaudenc->context->codec_id)))
401 gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_AUDIO_CODEC, codec,
404 gst_audio_encoder_merge_tags (encoder, tags, GST_TAG_MERGE_REPLACE);
405 gst_tag_list_unref (tags);
409 ffmpegaudenc->opened = TRUE;
415 gst_ffmpegaudenc_free_avpacket (gpointer pkt)
417 av_packet_unref ((AVPacket *) pkt);
418 g_slice_free (AVPacket, pkt);
426 guint8 **ext_data_array, *ext_data;
430 buffer_info_free (void *opaque, guint8 * data)
432 BufferInfo *info = opaque;
435 gst_buffer_unmap (info->buffer, &info->map);
436 gst_buffer_unref (info->buffer);
438 av_free (info->ext_data);
439 av_free (info->ext_data_array);
441 g_slice_free (BufferInfo, info);
445 gst_ffmpegaudenc_encode_audio (GstFFMpegAudEnc * ffmpegaudenc,
446 GstBuffer * buffer, gint * have_data)
448 GstAudioEncoder *enc;
454 AVFrame *frame = ffmpegaudenc->frame;
458 enc = GST_AUDIO_ENCODER (ffmpegaudenc);
460 ctx = ffmpegaudenc->context;
462 pkt = g_slice_new0 (AVPacket);
464 if (buffer != NULL) {
465 BufferInfo *buffer_info = g_slice_new0 (BufferInfo);
469 buffer_info->buffer = buffer;
470 gst_buffer_map (buffer, &buffer_info->map, GST_MAP_READ);
471 audio_in = buffer_info->map.data;
472 in_size = buffer_info->map.size;
474 GST_LOG_OBJECT (ffmpegaudenc, "encoding buffer %p size:%u", audio_in,
477 info = gst_audio_encoder_get_audio_info (enc);
478 planar = av_sample_fmt_is_planar (ffmpegaudenc->context->sample_fmt);
479 frame->format = ffmpegaudenc->context->sample_fmt;
480 frame->sample_rate = ffmpegaudenc->context->sample_rate;
481 frame->channels = ffmpegaudenc->context->channels;
482 frame->channel_layout = ffmpegaudenc->context->channel_layout;
484 if (planar && info->channels > 1) {
488 nsamples = frame->nb_samples = in_size / info->bpf;
489 channels = info->channels;
492 av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0);
494 if (info->channels > AV_NUM_DATA_POINTERS) {
495 buffer_info->ext_data_array = frame->extended_data =
496 av_malloc_array (info->channels, sizeof (uint8_t *));
498 frame->extended_data = frame->data;
501 buffer_info->ext_data = frame->extended_data[0] = av_malloc (in_size);
502 frame->linesize[0] = in_size / channels;
503 for (i = 1; i < channels; i++)
504 frame->extended_data[i] =
505 frame->extended_data[i - 1] + frame->linesize[0];
507 switch (info->finfo->width) {
509 const guint8 *idata = (const guint8 *) audio_in;
511 for (i = 0; i < nsamples; i++) {
512 for (j = 0; j < channels; j++) {
513 ((guint8 *) frame->extended_data[j])[i] = idata[j];
520 const guint16 *idata = (const guint16 *) audio_in;
522 for (i = 0; i < nsamples; i++) {
523 for (j = 0; j < channels; j++) {
524 ((guint16 *) frame->extended_data[j])[i] = idata[j];
531 const guint32 *idata = (const guint32 *) audio_in;
533 for (i = 0; i < nsamples; i++) {
534 for (j = 0; j < channels; j++) {
535 ((guint32 *) frame->extended_data[j])[i] = idata[j];
543 const guint64 *idata = (const guint64 *) audio_in;
545 for (i = 0; i < nsamples; i++) {
546 for (j = 0; j < channels; j++) {
547 ((guint64 *) frame->extended_data[j])[i] = idata[j];
555 g_assert_not_reached ();
559 gst_buffer_unmap (buffer, &buffer_info->map);
560 gst_buffer_unref (buffer);
561 buffer_info->buffer = NULL;
563 frame->data[0] = audio_in;
564 frame->extended_data = frame->data;
565 frame->linesize[0] = in_size;
566 frame->nb_samples = nsamples = in_size / info->bpf;
568 av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0);
571 /* we have a frame to feed the encoder */
572 res = avcodec_encode_audio2 (ctx, pkt, frame, have_data);
574 av_frame_unref (frame);
576 GST_LOG_OBJECT (ffmpegaudenc, "draining");
577 /* flushing the encoder */
578 res = avcodec_encode_audio2 (ctx, pkt, NULL, have_data);
582 char error_str[128] = { 0, };
584 g_slice_free (AVPacket, pkt);
585 av_strerror (res, error_str, sizeof (error_str));
586 GST_ERROR_OBJECT (enc, "Failed to encode buffer: %d - %s", res, error_str);
589 GST_LOG_OBJECT (ffmpegaudenc, "got output size %d", res);
593 const AVCodec *codec;
595 GST_LOG_OBJECT (ffmpegaudenc, "pushing size %d", pkt->size);
598 gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, pkt->data,
599 pkt->size, 0, pkt->size, pkt, gst_ffmpegaudenc_free_avpacket);
601 codec = ffmpegaudenc->context->codec;
602 if ((codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) || !buffer) {
603 /* FIXME: Not really correct, as -1 means "all the samples we got
604 given so far", which may not be true depending on the codec,
605 but we have no way to know AFAICT */
606 ret = gst_audio_encoder_finish_frame (enc, outbuf, -1);
608 ret = gst_audio_encoder_finish_frame (enc, outbuf, nsamples);
611 GST_LOG_OBJECT (ffmpegaudenc, "no output produced");
612 g_slice_free (AVPacket, pkt);
620 gst_ffmpegaudenc_drain (GstFFMpegAudEnc * ffmpegaudenc)
622 GstFFMpegAudEncClass *oclass;
624 oclass = (GstFFMpegAudEncClass *) (G_OBJECT_GET_CLASS (ffmpegaudenc));
626 if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
627 gint have_data, try = 0;
629 GST_LOG_OBJECT (ffmpegaudenc,
630 "codec has delay capabilities, calling until libav has drained everything");
635 ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, NULL, &have_data);
636 if (ret != GST_FLOW_OK || have_data == 0)
638 } while (try++ < 10);
643 gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
645 GstFFMpegAudEnc *ffmpegaudenc;
649 ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
651 if (G_UNLIKELY (!ffmpegaudenc->opened))
655 gst_ffmpegaudenc_drain (ffmpegaudenc);
659 inbuf = gst_buffer_ref (inbuf);
661 GST_DEBUG_OBJECT (ffmpegaudenc,
662 "Received time %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
663 ", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
664 GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)), gst_buffer_get_size (inbuf));
666 /* Reorder channels to the GStreamer channel order */
667 if (ffmpegaudenc->needs_reorder) {
668 GstAudioInfo *info = gst_audio_encoder_get_audio_info (encoder);
670 inbuf = gst_buffer_make_writable (inbuf);
671 gst_audio_buffer_reorder_channels (inbuf, info->finfo->format,
672 info->channels, info->position, ffmpegaudenc->ffmpeg_layout);
675 ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, inbuf, &have_data);
677 if (ret != GST_FLOW_OK)
685 GST_ELEMENT_ERROR (ffmpegaudenc, CORE, NEGOTIATION, (NULL),
686 ("not configured to input format before data start"));
687 gst_buffer_unref (inbuf);
688 return GST_FLOW_NOT_NEGOTIATED;
692 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to push buffer %d (%s)", ret,
693 gst_flow_get_name (ret));
699 gst_ffmpegaudenc_set_property (GObject * object,
700 guint prop_id, const GValue * value, GParamSpec * pspec)
702 GstFFMpegAudEnc *ffmpegaudenc;
704 /* Get a pointer of the right type. */
705 ffmpegaudenc = (GstFFMpegAudEnc *) (object);
707 if (ffmpegaudenc->opened) {
708 GST_WARNING_OBJECT (ffmpegaudenc,
709 "Can't change properties once decoder is setup !");
713 /* Check the argument id to see which argument we're setting. */
716 ffmpegaudenc->bitrate = g_value_get_int (value);
718 case PROP_RTP_PAYLOAD_SIZE:
719 ffmpegaudenc->rtp_payload_size = g_value_get_int (value);
721 case PROP_COMPLIANCE:
722 ffmpegaudenc->compliance = g_value_get_enum (value);
725 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
730 /* The set function is simply the inverse of the get fuction. */
732 gst_ffmpegaudenc_get_property (GObject * object,
733 guint prop_id, GValue * value, GParamSpec * pspec)
735 GstFFMpegAudEnc *ffmpegaudenc;
737 /* It's not null if we got it, but it might not be ours */
738 ffmpegaudenc = (GstFFMpegAudEnc *) (object);
742 g_value_set_int (value, ffmpegaudenc->bitrate);
745 case PROP_RTP_PAYLOAD_SIZE:
746 g_value_set_int (value, ffmpegaudenc->rtp_payload_size);
748 case PROP_COMPLIANCE:
749 g_value_set_enum (value, ffmpegaudenc->compliance);
752 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
758 gst_ffmpegaudenc_register (GstPlugin * plugin)
760 GTypeInfo typeinfo = {
761 sizeof (GstFFMpegAudEncClass),
762 (GBaseInitFunc) gst_ffmpegaudenc_base_init,
764 (GClassInitFunc) gst_ffmpegaudenc_class_init,
767 sizeof (GstFFMpegAudEnc),
769 (GInstanceInitFunc) gst_ffmpegaudenc_init,
775 GST_LOG ("Registering encoders");
777 in_plugin = av_codec_next (NULL);
782 /* Skip non-AV codecs */
783 if (in_plugin->type != AVMEDIA_TYPE_AUDIO)
786 /* no quasi codecs, please */
787 if (in_plugin->id == AV_CODEC_ID_PCM_S16LE_PLANAR ||
788 (in_plugin->id >= AV_CODEC_ID_PCM_S16LE &&
789 in_plugin->id <= AV_CODEC_ID_PCM_BLURAY) ||
790 (in_plugin->id >= AV_CODEC_ID_PCM_S8_PLANAR &&
791 in_plugin->id <= AV_CODEC_ID_PCM_S64BE)) {
795 /* No encoders depending on external libraries (we don't build them, but
796 * people who build against an external ffmpeg might have them.
797 * We have native gstreamer plugins for all of those libraries anyway. */
798 if (!strncmp (in_plugin->name, "lib", 3)) {
800 ("Not using external library encoder %s. Use the gstreamer-native ones instead.",
806 if (!av_codec_is_encoder (in_plugin)) {
810 /* FIXME : We should have a method to know cheaply whether we have a mapping
811 * for the given plugin or not */
813 GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
815 /* no codecs for which we're GUARANTEED to have better alternatives */
816 if (!strcmp (in_plugin->name, "vorbis")
817 || !strcmp (in_plugin->name, "flac")) {
818 GST_LOG ("Ignoring encoder %s", in_plugin->name);
822 /* construct the type */
823 type_name = g_strdup_printf ("avenc_%s", in_plugin->name);
825 type = g_type_from_name (type_name);
829 /* create the glib type now */
831 g_type_register_static (GST_TYPE_AUDIO_ENCODER, type_name, &typeinfo,
833 g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) in_plugin);
836 static const GInterfaceInfo preset_info = {
841 g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_info);
845 switch (in_plugin->id) {
846 /* avenc_aac: see https://bugzilla.gnome.org/show_bug.cgi?id=691617 */
847 case AV_CODEC_ID_AAC:
848 rank = GST_RANK_NONE;
851 rank = GST_RANK_SECONDARY;
855 if (!gst_element_register (plugin, type_name, rank, type)) {
863 in_plugin = av_codec_next (in_plugin);
866 GST_LOG ("Finished registering encoders");