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 gst_caps_unref (sinkcaps);
128 gst_caps_unref (srccaps);
130 klass->in_plugin = in_plugin;
131 klass->srctempl = srctempl;
132 klass->sinktempl = sinktempl;
138 gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass)
140 GObjectClass *gobject_class;
141 GstAudioEncoderClass *gstaudioencoder_class;
143 gobject_class = (GObjectClass *) klass;
144 gstaudioencoder_class = (GstAudioEncoderClass *) klass;
146 parent_class = g_type_class_peek_parent (klass);
148 gobject_class->set_property = gst_ffmpegaudenc_set_property;
149 gobject_class->get_property = gst_ffmpegaudenc_get_property;
151 /* FIXME: could use -1 for a sensible per-codec defaults */
152 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BIT_RATE,
153 g_param_spec_int ("bitrate", "Bit Rate",
154 "Target Audio Bitrate", 0, G_MAXINT, DEFAULT_AUDIO_BITRATE,
155 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COMPLIANCE,
157 g_param_spec_enum ("compliance", "Compliance",
158 "Adherence of the encoder to the specifications",
159 GST_TYPE_FFMPEG_COMPLIANCE, FFMPEG_DEFAULT_COMPLIANCE,
160 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
162 gobject_class->finalize = gst_ffmpegaudenc_finalize;
164 gstaudioencoder_class->start = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_start);
165 gstaudioencoder_class->stop = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_stop);
166 gstaudioencoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_flush);
167 gstaudioencoder_class->set_format =
168 GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_set_format);
169 gstaudioencoder_class->handle_frame =
170 GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_handle_frame);
174 gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
176 GstFFMpegAudEncClass *klass =
177 (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
179 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (ffmpegaudenc));
182 ffmpegaudenc->context = avcodec_alloc_context3 (klass->in_plugin);
183 ffmpegaudenc->opened = FALSE;
184 ffmpegaudenc->frame = av_frame_alloc ();
186 ffmpegaudenc->compliance = FFMPEG_DEFAULT_COMPLIANCE;
188 gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (ffmpegaudenc), TRUE);
192 gst_ffmpegaudenc_finalize (GObject * object)
194 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) object;
196 /* clean up remaining allocated data */
197 av_frame_free (&ffmpegaudenc->frame);
198 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
199 av_free (ffmpegaudenc->context);
201 G_OBJECT_CLASS (parent_class)->finalize (object);
205 gst_ffmpegaudenc_start (GstAudioEncoder * encoder)
207 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
208 GstFFMpegAudEncClass *oclass =
209 (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
211 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
212 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
213 oclass->in_plugin) < 0) {
214 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
222 gst_ffmpegaudenc_stop (GstAudioEncoder * encoder)
224 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
226 /* close old session */
227 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
228 ffmpegaudenc->opened = FALSE;
234 gst_ffmpegaudenc_flush (GstAudioEncoder * encoder)
236 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
238 if (ffmpegaudenc->opened) {
239 avcodec_flush_buffers (ffmpegaudenc->context);
244 gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
246 GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
248 GstCaps *allowed_caps;
251 GstFFMpegAudEncClass *oclass =
252 (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
254 /* close old session */
255 if (ffmpegaudenc->opened) {
256 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
257 ffmpegaudenc->opened = FALSE;
258 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
259 oclass->in_plugin) < 0) {
260 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
265 /* if we set it in _getcaps we should set it also in _link */
266 ffmpegaudenc->context->strict_std_compliance = ffmpegaudenc->compliance;
268 /* user defined properties */
269 if (ffmpegaudenc->bitrate > 0) {
270 GST_INFO_OBJECT (ffmpegaudenc, "Setting avcontext to bitrate %d",
271 ffmpegaudenc->bitrate);
272 ffmpegaudenc->context->bit_rate = ffmpegaudenc->bitrate;
273 ffmpegaudenc->context->bit_rate_tolerance = ffmpegaudenc->bitrate;
275 GST_INFO_OBJECT (ffmpegaudenc,
276 "Using avcontext default bitrate %" G_GINT64_FORMAT,
277 (gint64) ffmpegaudenc->context->bit_rate);
280 /* RTP payload used for GOB production (for Asterisk) */
281 if (ffmpegaudenc->rtp_payload_size) {
282 ffmpegaudenc->context->rtp_payload_size = ffmpegaudenc->rtp_payload_size;
285 /* some other defaults */
286 ffmpegaudenc->context->rc_strategy = 2;
287 ffmpegaudenc->context->b_frame_strategy = 0;
288 ffmpegaudenc->context->coder_type = 0;
289 ffmpegaudenc->context->context_model = 0;
290 ffmpegaudenc->context->scenechange_threshold = 0;
292 /* fetch pix_fmt and so on */
293 gst_ffmpeg_audioinfo_to_context (info, ffmpegaudenc->context);
294 if (!ffmpegaudenc->context->time_base.den) {
295 ffmpegaudenc->context->time_base.den = GST_AUDIO_INFO_RATE (info);
296 ffmpegaudenc->context->time_base.num = 1;
297 ffmpegaudenc->context->ticks_per_frame = 1;
300 if (ffmpegaudenc->context->channel_layout) {
301 gst_ffmpeg_channel_layout_to_gst (ffmpegaudenc->context->channel_layout,
302 ffmpegaudenc->context->channels, ffmpegaudenc->ffmpeg_layout);
303 ffmpegaudenc->needs_reorder =
304 (memcmp (ffmpegaudenc->ffmpeg_layout, info->position,
305 sizeof (GstAudioChannelPosition) *
306 ffmpegaudenc->context->channels) != 0);
309 /* some codecs support more than one format, first auto-choose one */
310 GST_DEBUG_OBJECT (ffmpegaudenc, "picking an output format ...");
311 allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
313 GST_DEBUG_OBJECT (ffmpegaudenc, "... but no peer, using template caps");
314 /* we need to copy because get_allowed_caps returns a ref, and
315 * get_pad_template_caps doesn't */
317 gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
319 GST_DEBUG_OBJECT (ffmpegaudenc, "chose caps %" GST_PTR_FORMAT, allowed_caps);
320 gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
321 oclass->in_plugin->type, allowed_caps, ffmpegaudenc->context);
324 if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) {
325 gst_caps_unref (allowed_caps);
326 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
327 GST_DEBUG_OBJECT (ffmpegaudenc, "avenc_%s: Failed to open FFMPEG codec",
328 oclass->in_plugin->name);
329 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
330 oclass->in_plugin) < 0)
331 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
333 if ((oclass->in_plugin->capabilities & CODEC_CAP_EXPERIMENTAL) &&
334 ffmpegaudenc->compliance != GST_FFMPEG_EXPERIMENTAL) {
335 GST_ELEMENT_ERROR (ffmpegaudenc, LIBRARY, SETTINGS,
336 ("Codec is experimental, but settings don't allow encoders to "
337 "produce output of experimental quality"),
338 ("This codec may not create output that is conformant to the specs "
339 "or of good quality. If you must use it anyway, set the "
340 "compliance property to experimental"));
345 /* try to set this caps on the other side */
346 other_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id,
347 ffmpegaudenc->context, TRUE);
350 gst_caps_unref (allowed_caps);
351 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
352 GST_DEBUG ("Unsupported codec - no caps found");
353 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
354 oclass->in_plugin) < 0)
355 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
359 icaps = gst_caps_intersect (allowed_caps, other_caps);
360 gst_caps_unref (allowed_caps);
361 gst_caps_unref (other_caps);
362 if (gst_caps_is_empty (icaps)) {
363 gst_caps_unref (icaps);
366 icaps = gst_caps_fixate (icaps);
368 if (!gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (ffmpegaudenc),
370 gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
371 gst_caps_unref (icaps);
372 if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
373 oclass->in_plugin) < 0)
374 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
377 gst_caps_unref (icaps);
379 frame_size = ffmpegaudenc->context->frame_size;
380 if (frame_size > 1) {
381 gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
383 gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
385 gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 1);
387 gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
389 gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
391 gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 0);
394 /* Store some tags */
396 GstTagList *tags = gst_tag_list_new_empty ();
399 gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_NOMINAL_BITRATE,
400 (guint) ffmpegaudenc->context->bit_rate, NULL);
403 gst_ffmpeg_get_codecid_longname (ffmpegaudenc->context->codec_id)))
404 gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_AUDIO_CODEC, codec,
407 gst_audio_encoder_merge_tags (encoder, tags, GST_TAG_MERGE_REPLACE);
408 gst_tag_list_unref (tags);
412 ffmpegaudenc->opened = TRUE;
418 gst_ffmpegaudenc_free_avpacket (gpointer pkt)
420 av_packet_unref ((AVPacket *) pkt);
421 g_slice_free (AVPacket, pkt);
429 guint8 **ext_data_array, *ext_data;
433 buffer_info_free (void *opaque, guint8 * data)
435 BufferInfo *info = opaque;
438 gst_buffer_unmap (info->buffer, &info->map);
439 gst_buffer_unref (info->buffer);
441 av_free (info->ext_data);
442 av_free (info->ext_data_array);
444 g_slice_free (BufferInfo, info);
448 gst_ffmpegaudenc_encode_audio (GstFFMpegAudEnc * ffmpegaudenc,
449 GstBuffer * buffer, gint * have_data)
451 GstAudioEncoder *enc;
457 AVFrame *frame = ffmpegaudenc->frame;
461 enc = GST_AUDIO_ENCODER (ffmpegaudenc);
463 ctx = ffmpegaudenc->context;
465 pkt = g_slice_new0 (AVPacket);
467 if (buffer != NULL) {
468 BufferInfo *buffer_info = g_slice_new0 (BufferInfo);
472 buffer_info->buffer = buffer;
473 gst_buffer_map (buffer, &buffer_info->map, GST_MAP_READ);
474 audio_in = buffer_info->map.data;
475 in_size = buffer_info->map.size;
477 GST_LOG_OBJECT (ffmpegaudenc, "encoding buffer %p size:%u", audio_in,
480 info = gst_audio_encoder_get_audio_info (enc);
481 planar = av_sample_fmt_is_planar (ffmpegaudenc->context->sample_fmt);
482 frame->format = ffmpegaudenc->context->sample_fmt;
483 frame->sample_rate = ffmpegaudenc->context->sample_rate;
484 frame->channels = ffmpegaudenc->context->channels;
485 frame->channel_layout = ffmpegaudenc->context->channel_layout;
487 if (planar && info->channels > 1) {
491 nsamples = frame->nb_samples = in_size / info->bpf;
492 channels = info->channels;
495 av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0);
497 if (info->channels > AV_NUM_DATA_POINTERS) {
498 buffer_info->ext_data_array = frame->extended_data =
499 av_malloc_array (info->channels, sizeof (uint8_t *));
501 frame->extended_data = frame->data;
504 buffer_info->ext_data = frame->extended_data[0] = av_malloc (in_size);
505 frame->linesize[0] = in_size / channels;
506 for (i = 1; i < channels; i++)
507 frame->extended_data[i] =
508 frame->extended_data[i - 1] + frame->linesize[0];
510 switch (info->finfo->width) {
512 const guint8 *idata = (const guint8 *) audio_in;
514 for (i = 0; i < nsamples; i++) {
515 for (j = 0; j < channels; j++) {
516 ((guint8 *) frame->extended_data[j])[i] = idata[j];
523 const guint16 *idata = (const guint16 *) audio_in;
525 for (i = 0; i < nsamples; i++) {
526 for (j = 0; j < channels; j++) {
527 ((guint16 *) frame->extended_data[j])[i] = idata[j];
534 const guint32 *idata = (const guint32 *) audio_in;
536 for (i = 0; i < nsamples; i++) {
537 for (j = 0; j < channels; j++) {
538 ((guint32 *) frame->extended_data[j])[i] = idata[j];
546 const guint64 *idata = (const guint64 *) audio_in;
548 for (i = 0; i < nsamples; i++) {
549 for (j = 0; j < channels; j++) {
550 ((guint64 *) frame->extended_data[j])[i] = idata[j];
558 g_assert_not_reached ();
562 gst_buffer_unmap (buffer, &buffer_info->map);
563 gst_buffer_unref (buffer);
564 buffer_info->buffer = NULL;
566 frame->data[0] = audio_in;
567 frame->extended_data = frame->data;
568 frame->linesize[0] = in_size;
569 frame->nb_samples = nsamples = in_size / info->bpf;
571 av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0);
574 /* we have a frame to feed the encoder */
575 res = avcodec_encode_audio2 (ctx, pkt, frame, have_data);
577 av_frame_unref (frame);
579 GST_LOG_OBJECT (ffmpegaudenc, "draining");
580 /* flushing the encoder */
581 res = avcodec_encode_audio2 (ctx, pkt, NULL, have_data);
585 char error_str[128] = { 0, };
587 g_slice_free (AVPacket, pkt);
588 av_strerror (res, error_str, sizeof (error_str));
589 GST_ERROR_OBJECT (enc, "Failed to encode buffer: %d - %s", res, error_str);
592 GST_LOG_OBJECT (ffmpegaudenc, "got output size %d", res);
596 const AVCodec *codec;
598 GST_LOG_OBJECT (ffmpegaudenc, "pushing size %d", pkt->size);
601 gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, pkt->data,
602 pkt->size, 0, pkt->size, pkt, gst_ffmpegaudenc_free_avpacket);
604 codec = ffmpegaudenc->context->codec;
605 if ((codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) || !buffer) {
606 /* FIXME: Not really correct, as -1 means "all the samples we got
607 given so far", which may not be true depending on the codec,
608 but we have no way to know AFAICT */
609 ret = gst_audio_encoder_finish_frame (enc, outbuf, -1);
611 ret = gst_audio_encoder_finish_frame (enc, outbuf, nsamples);
614 GST_LOG_OBJECT (ffmpegaudenc, "no output produced");
615 g_slice_free (AVPacket, pkt);
623 gst_ffmpegaudenc_drain (GstFFMpegAudEnc * ffmpegaudenc)
625 GstFFMpegAudEncClass *oclass;
627 oclass = (GstFFMpegAudEncClass *) (G_OBJECT_GET_CLASS (ffmpegaudenc));
629 if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
630 gint have_data, try = 0;
632 GST_LOG_OBJECT (ffmpegaudenc,
633 "codec has delay capabilities, calling until libav has drained everything");
638 ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, NULL, &have_data);
639 if (ret != GST_FLOW_OK || have_data == 0)
641 } while (try++ < 10);
646 gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
648 GstFFMpegAudEnc *ffmpegaudenc;
652 ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
654 if (G_UNLIKELY (!ffmpegaudenc->opened))
658 gst_ffmpegaudenc_drain (ffmpegaudenc);
662 inbuf = gst_buffer_ref (inbuf);
664 GST_DEBUG_OBJECT (ffmpegaudenc,
665 "Received time %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
666 ", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
667 GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)), gst_buffer_get_size (inbuf));
669 /* Reorder channels to the GStreamer channel order */
670 if (ffmpegaudenc->needs_reorder) {
671 GstAudioInfo *info = gst_audio_encoder_get_audio_info (encoder);
673 inbuf = gst_buffer_make_writable (inbuf);
674 gst_audio_buffer_reorder_channels (inbuf, info->finfo->format,
675 info->channels, info->position, ffmpegaudenc->ffmpeg_layout);
678 ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, inbuf, &have_data);
680 if (ret != GST_FLOW_OK)
688 GST_ELEMENT_ERROR (ffmpegaudenc, CORE, NEGOTIATION, (NULL),
689 ("not configured to input format before data start"));
690 gst_buffer_unref (inbuf);
691 return GST_FLOW_NOT_NEGOTIATED;
695 GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to push buffer %d (%s)", ret,
696 gst_flow_get_name (ret));
702 gst_ffmpegaudenc_set_property (GObject * object,
703 guint prop_id, const GValue * value, GParamSpec * pspec)
705 GstFFMpegAudEnc *ffmpegaudenc;
707 /* Get a pointer of the right type. */
708 ffmpegaudenc = (GstFFMpegAudEnc *) (object);
710 if (ffmpegaudenc->opened) {
711 GST_WARNING_OBJECT (ffmpegaudenc,
712 "Can't change properties once decoder is setup !");
716 /* Check the argument id to see which argument we're setting. */
719 ffmpegaudenc->bitrate = g_value_get_int (value);
721 case PROP_RTP_PAYLOAD_SIZE:
722 ffmpegaudenc->rtp_payload_size = g_value_get_int (value);
724 case PROP_COMPLIANCE:
725 ffmpegaudenc->compliance = g_value_get_enum (value);
728 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
733 /* The set function is simply the inverse of the get fuction. */
735 gst_ffmpegaudenc_get_property (GObject * object,
736 guint prop_id, GValue * value, GParamSpec * pspec)
738 GstFFMpegAudEnc *ffmpegaudenc;
740 /* It's not null if we got it, but it might not be ours */
741 ffmpegaudenc = (GstFFMpegAudEnc *) (object);
745 g_value_set_int (value, ffmpegaudenc->bitrate);
748 case PROP_RTP_PAYLOAD_SIZE:
749 g_value_set_int (value, ffmpegaudenc->rtp_payload_size);
751 case PROP_COMPLIANCE:
752 g_value_set_enum (value, ffmpegaudenc->compliance);
755 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
761 gst_ffmpegaudenc_register (GstPlugin * plugin)
763 GTypeInfo typeinfo = {
764 sizeof (GstFFMpegAudEncClass),
765 (GBaseInitFunc) gst_ffmpegaudenc_base_init,
767 (GClassInitFunc) gst_ffmpegaudenc_class_init,
770 sizeof (GstFFMpegAudEnc),
772 (GInstanceInitFunc) gst_ffmpegaudenc_init,
778 GST_LOG ("Registering encoders");
780 in_plugin = av_codec_next (NULL);
785 /* Skip non-AV codecs */
786 if (in_plugin->type != AVMEDIA_TYPE_AUDIO)
789 /* no quasi codecs, please */
790 if (in_plugin->id == AV_CODEC_ID_PCM_S16LE_PLANAR ||
791 (in_plugin->id >= AV_CODEC_ID_PCM_S16LE &&
792 in_plugin->id <= AV_CODEC_ID_PCM_BLURAY) ||
793 (in_plugin->id >= AV_CODEC_ID_PCM_S8_PLANAR &&
794 #if AV_VERSION_INT (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) >= AV_VERSION_INT (57,69,0)
795 in_plugin->id <= AV_CODEC_ID_PCM_F24LE)) {
796 #elif AV_VERSION_INT (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) >= AV_VERSION_INT (57,54,0)
797 in_plugin->id <= AV_CODEC_ID_PCM_S64BE)) {
799 in_plugin->id <= AV_CODEC_ID_PCM_S16BE_PLANAR)) {
804 /* No encoders depending on external libraries (we don't build them, but
805 * people who build against an external ffmpeg might have them.
806 * We have native gstreamer plugins for all of those libraries anyway. */
807 if (!strncmp (in_plugin->name, "lib", 3)) {
809 ("Not using external library encoder %s. Use the gstreamer-native ones instead.",
815 if (!av_codec_is_encoder (in_plugin)) {
819 /* FIXME : We should have a method to know cheaply whether we have a mapping
820 * for the given plugin or not */
822 GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
824 /* no codecs for which we're GUARANTEED to have better alternatives */
825 if (!strcmp (in_plugin->name, "vorbis")
826 || !strcmp (in_plugin->name, "flac")) {
827 GST_LOG ("Ignoring encoder %s", in_plugin->name);
831 /* construct the type */
832 type_name = g_strdup_printf ("avenc_%s", in_plugin->name);
834 type = g_type_from_name (type_name);
838 /* create the glib type now */
840 g_type_register_static (GST_TYPE_AUDIO_ENCODER, type_name, &typeinfo,
842 g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) in_plugin);
845 static const GInterfaceInfo preset_info = {
850 g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_info);
854 switch (in_plugin->id) {
855 /* avenc_aac: see https://bugzilla.gnome.org/show_bug.cgi?id=691617 */
856 case AV_CODEC_ID_AAC:
857 rank = GST_RANK_NONE;
860 rank = GST_RANK_SECONDARY;
864 if (!gst_element_register (plugin, type_name, rank, type)) {
872 in_plugin = av_codec_next (in_plugin);
875 GST_LOG ("Finished registering encoders");