avaudenc/dec: Ignore S64BE/LE pseudo-codecs
[platform/upstream/gst-libav.git] / ext / libav / gstavaudenc.c
1 /* GStreamer
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>
5  *
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.
10  *
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.
15  *
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.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <assert.h>
27 #include <string.h>
28 /* for stats file handling */
29 #include <stdio.h>
30 #include <glib/gstdio.h>
31 #include <errno.h>
32
33 #include <libavcodec/avcodec.h>
34
35 #include <gst/gst.h>
36
37 #include "gstav.h"
38 #include "gstavcodecmap.h"
39 #include "gstavutils.h"
40 #include "gstavaudenc.h"
41
42 #define DEFAULT_AUDIO_BITRATE 128000
43
44 enum
45 {
46   /* FILL ME */
47   LAST_SIGNAL
48 };
49
50 enum
51 {
52   PROP_0,
53   PROP_BIT_RATE,
54   PROP_RTP_PAYLOAD_SIZE,
55   PROP_COMPLIANCE,
56 };
57
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);
63
64 static gboolean gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder,
65     GstAudioInfo * info);
66 static GstFlowReturn gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder,
67     GstBuffer * inbuf);
68 static gboolean gst_ffmpegaudenc_start (GstAudioEncoder * encoder);
69 static gboolean gst_ffmpegaudenc_stop (GstAudioEncoder * encoder);
70 static void gst_ffmpegaudenc_flush (GstAudioEncoder * encoder);
71
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);
76
77 #define GST_FFENC_PARAMS_QDATA g_quark_from_static_string("avenc-params")
78
79 static GstElementClass *parent_class = NULL;
80
81 /*static guint gst_ffmpegaudenc_signals[LAST_SIGNAL] = { 0 }; */
82
83 static void
84 gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass)
85 {
86   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
87   AVCodec *in_plugin;
88   GstPadTemplate *srctempl = NULL, *sinktempl = NULL;
89   GstCaps *srccaps = NULL, *sinkcaps = NULL;
90   gchar *longname, *description;
91
92   in_plugin =
93       (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
94       GST_FFENC_PARAMS_QDATA);
95   g_assert (in_plugin != NULL);
96
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>");
104   g_free (longname);
105   g_free (description);
106
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");
110   }
111
112   sinkcaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
113       in_plugin->id, TRUE, in_plugin);
114   if (!sinkcaps) {
115     GST_DEBUG ("Couldn't get sink caps for encoder '%s'", in_plugin->name);
116     sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
117   }
118
119   /* pad templates */
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);
123
124   gst_element_class_add_pad_template (element_class, srctempl);
125   gst_element_class_add_pad_template (element_class, sinktempl);
126
127   klass->in_plugin = in_plugin;
128   klass->srctempl = srctempl;
129   klass->sinktempl = sinktempl;
130
131   return;
132 }
133
134 static void
135 gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass)
136 {
137   GObjectClass *gobject_class;
138   GstAudioEncoderClass *gstaudioencoder_class;
139
140   gobject_class = (GObjectClass *) klass;
141   gstaudioencoder_class = (GstAudioEncoderClass *) klass;
142
143   parent_class = g_type_class_peek_parent (klass);
144
145   gobject_class->set_property = gst_ffmpegaudenc_set_property;
146   gobject_class->get_property = gst_ffmpegaudenc_get_property;
147
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));
158
159   gobject_class->finalize = gst_ffmpegaudenc_finalize;
160
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);
168 }
169
170 static void
171 gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
172 {
173   GstFFMpegAudEncClass *klass =
174       (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
175
176   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (ffmpegaudenc));
177
178   /* ffmpeg objects */
179   ffmpegaudenc->context = avcodec_alloc_context3 (klass->in_plugin);
180   ffmpegaudenc->opened = FALSE;
181   ffmpegaudenc->frame = av_frame_alloc ();
182
183   ffmpegaudenc->compliance = FFMPEG_DEFAULT_COMPLIANCE;
184
185   gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (ffmpegaudenc), TRUE);
186 }
187
188 static void
189 gst_ffmpegaudenc_finalize (GObject * object)
190 {
191   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) object;
192
193   /* clean up remaining allocated data */
194   av_frame_free (&ffmpegaudenc->frame);
195   gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
196   av_free (ffmpegaudenc->context);
197
198   G_OBJECT_CLASS (parent_class)->finalize (object);
199 }
200
201 static gboolean
202 gst_ffmpegaudenc_start (GstAudioEncoder * encoder)
203 {
204   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
205   GstFFMpegAudEncClass *oclass =
206       (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
207
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");
212     return FALSE;
213   }
214
215   return TRUE;
216 }
217
218 static gboolean
219 gst_ffmpegaudenc_stop (GstAudioEncoder * encoder)
220 {
221   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
222
223   /* close old session */
224   gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
225   ffmpegaudenc->opened = FALSE;
226
227   return TRUE;
228 }
229
230 static void
231 gst_ffmpegaudenc_flush (GstAudioEncoder * encoder)
232 {
233   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
234
235   if (ffmpegaudenc->opened) {
236     avcodec_flush_buffers (ffmpegaudenc->context);
237   }
238 }
239
240 static gboolean
241 gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
242 {
243   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
244   GstCaps *other_caps;
245   GstCaps *allowed_caps;
246   GstCaps *icaps;
247   gsize frame_size;
248   GstFFMpegAudEncClass *oclass =
249       (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
250
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");
258       return FALSE;
259     }
260   }
261
262   /* if we set it in _getcaps we should set it also in _link */
263   ffmpegaudenc->context->strict_std_compliance = ffmpegaudenc->compliance;
264
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;
271   } else {
272     GST_INFO_OBJECT (ffmpegaudenc,
273         "Using avcontext default bitrate %" G_GINT64_FORMAT,
274         (gint64) ffmpegaudenc->context->bit_rate);
275   }
276
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;
280   }
281
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;
288
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;
295   }
296
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);
304   }
305
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));
309   if (!allowed_caps) {
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 */
313     allowed_caps =
314         gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
315   }
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);
319
320   /* open codec */
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");
329
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"));
338     }
339     return FALSE;
340   }
341
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);
345
346   if (!other_caps) {
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");
353     return FALSE;
354   }
355
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);
361     return FALSE;
362   }
363   icaps = gst_caps_fixate (icaps);
364
365   if (!gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (ffmpegaudenc),
366           icaps)) {
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");
372     return FALSE;
373   }
374   gst_caps_unref (icaps);
375
376   frame_size = ffmpegaudenc->context->frame_size;
377   if (frame_size > 1) {
378     gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
379         frame_size);
380     gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
381         frame_size);
382     gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 1);
383   } else {
384     gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
385         0);
386     gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
387         0);
388     gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 0);
389   }
390
391   /* Store some tags */
392   {
393     GstTagList *tags = gst_tag_list_new_empty ();
394     const gchar *codec;
395
396     gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_NOMINAL_BITRATE,
397         (guint) ffmpegaudenc->context->bit_rate, NULL);
398
399     if ((codec =
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,
402           NULL);
403
404     gst_audio_encoder_merge_tags (encoder, tags, GST_TAG_MERGE_REPLACE);
405     gst_tag_list_unref (tags);
406   }
407
408   /* success! */
409   ffmpegaudenc->opened = TRUE;
410
411   return TRUE;
412 }
413
414 static void
415 gst_ffmpegaudenc_free_avpacket (gpointer pkt)
416 {
417   av_packet_unref ((AVPacket *) pkt);
418   g_slice_free (AVPacket, pkt);
419 }
420
421 typedef struct
422 {
423   GstBuffer *buffer;
424   GstMapInfo map;
425
426   guint8 **ext_data_array, *ext_data;
427 } BufferInfo;
428
429 static void
430 buffer_info_free (void *opaque, guint8 * data)
431 {
432   BufferInfo *info = opaque;
433
434   if (info->buffer) {
435     gst_buffer_unmap (info->buffer, &info->map);
436     gst_buffer_unref (info->buffer);
437   } else {
438     av_free (info->ext_data);
439     av_free (info->ext_data_array);
440   }
441   g_slice_free (BufferInfo, info);
442 }
443
444 static GstFlowReturn
445 gst_ffmpegaudenc_encode_audio (GstFFMpegAudEnc * ffmpegaudenc,
446     GstBuffer * buffer, gint * have_data)
447 {
448   GstAudioEncoder *enc;
449   AVCodecContext *ctx;
450   gint res;
451   GstFlowReturn ret;
452   GstAudioInfo *info;
453   AVPacket *pkt;
454   AVFrame *frame = ffmpegaudenc->frame;
455   gboolean planar;
456   gint nsamples = -1;
457
458   enc = GST_AUDIO_ENCODER (ffmpegaudenc);
459
460   ctx = ffmpegaudenc->context;
461
462   pkt = g_slice_new0 (AVPacket);
463
464   if (buffer != NULL) {
465     BufferInfo *buffer_info = g_slice_new0 (BufferInfo);
466     guint8 *audio_in;
467     guint in_size;
468
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;
473
474     GST_LOG_OBJECT (ffmpegaudenc, "encoding buffer %p size:%u", audio_in,
475         in_size);
476
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;
483
484     if (planar && info->channels > 1) {
485       gint channels;
486       gint i, j;
487
488       nsamples = frame->nb_samples = in_size / info->bpf;
489       channels = info->channels;
490
491       frame->buf[0] =
492           av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0);
493
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 *));
497       } else {
498         frame->extended_data = frame->data;
499       }
500
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];
506
507       switch (info->finfo->width) {
508         case 8:{
509           const guint8 *idata = (const guint8 *) audio_in;
510
511           for (i = 0; i < nsamples; i++) {
512             for (j = 0; j < channels; j++) {
513               ((guint8 *) frame->extended_data[j])[i] = idata[j];
514             }
515             idata += channels;
516           }
517           break;
518         }
519         case 16:{
520           const guint16 *idata = (const guint16 *) audio_in;
521
522           for (i = 0; i < nsamples; i++) {
523             for (j = 0; j < channels; j++) {
524               ((guint16 *) frame->extended_data[j])[i] = idata[j];
525             }
526             idata += channels;
527           }
528           break;
529         }
530         case 32:{
531           const guint32 *idata = (const guint32 *) audio_in;
532
533           for (i = 0; i < nsamples; i++) {
534             for (j = 0; j < channels; j++) {
535               ((guint32 *) frame->extended_data[j])[i] = idata[j];
536             }
537             idata += channels;
538           }
539
540           break;
541         }
542         case 64:{
543           const guint64 *idata = (const guint64 *) audio_in;
544
545           for (i = 0; i < nsamples; i++) {
546             for (j = 0; j < channels; j++) {
547               ((guint64 *) frame->extended_data[j])[i] = idata[j];
548             }
549             idata += channels;
550           }
551
552           break;
553         }
554         default:
555           g_assert_not_reached ();
556           break;
557       }
558
559       gst_buffer_unmap (buffer, &buffer_info->map);
560       gst_buffer_unref (buffer);
561       buffer_info->buffer = NULL;
562     } else {
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;
567       frame->buf[0] =
568           av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0);
569     }
570
571     /* we have a frame to feed the encoder */
572     res = avcodec_encode_audio2 (ctx, pkt, frame, have_data);
573
574     av_frame_unref (frame);
575   } else {
576     GST_LOG_OBJECT (ffmpegaudenc, "draining");
577     /* flushing the encoder */
578     res = avcodec_encode_audio2 (ctx, pkt, NULL, have_data);
579   }
580
581   if (res < 0) {
582     char error_str[128] = { 0, };
583
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);
587     return GST_FLOW_OK;
588   }
589   GST_LOG_OBJECT (ffmpegaudenc, "got output size %d", res);
590
591   if (*have_data) {
592     GstBuffer *outbuf;
593     const AVCodec *codec;
594
595     GST_LOG_OBJECT (ffmpegaudenc, "pushing size %d", pkt->size);
596
597     outbuf =
598         gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, pkt->data,
599         pkt->size, 0, pkt->size, pkt, gst_ffmpegaudenc_free_avpacket);
600
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);
607     } else {
608       ret = gst_audio_encoder_finish_frame (enc, outbuf, nsamples);
609     }
610   } else {
611     GST_LOG_OBJECT (ffmpegaudenc, "no output produced");
612     g_slice_free (AVPacket, pkt);
613     ret = GST_FLOW_OK;
614   }
615
616   return ret;
617 }
618
619 static void
620 gst_ffmpegaudenc_drain (GstFFMpegAudEnc * ffmpegaudenc)
621 {
622   GstFFMpegAudEncClass *oclass;
623
624   oclass = (GstFFMpegAudEncClass *) (G_OBJECT_GET_CLASS (ffmpegaudenc));
625
626   if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
627     gint have_data, try = 0;
628
629     GST_LOG_OBJECT (ffmpegaudenc,
630         "codec has delay capabilities, calling until libav has drained everything");
631
632     do {
633       GstFlowReturn ret;
634
635       ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, NULL, &have_data);
636       if (ret != GST_FLOW_OK || have_data == 0)
637         break;
638     } while (try++ < 10);
639   }
640 }
641
642 static GstFlowReturn
643 gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
644 {
645   GstFFMpegAudEnc *ffmpegaudenc;
646   GstFlowReturn ret;
647   gint have_data;
648
649   ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
650
651   if (G_UNLIKELY (!ffmpegaudenc->opened))
652     goto not_negotiated;
653
654   if (!inbuf) {
655     gst_ffmpegaudenc_drain (ffmpegaudenc);
656     return GST_FLOW_OK;
657   }
658
659   inbuf = gst_buffer_ref (inbuf);
660
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));
665
666   /* Reorder channels to the GStreamer channel order */
667   if (ffmpegaudenc->needs_reorder) {
668     GstAudioInfo *info = gst_audio_encoder_get_audio_info (encoder);
669
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);
673   }
674
675   ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, inbuf, &have_data);
676
677   if (ret != GST_FLOW_OK)
678     goto push_failed;
679
680   return GST_FLOW_OK;
681
682   /* ERRORS */
683 not_negotiated:
684   {
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;
689   }
690 push_failed:
691   {
692     GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to push buffer %d (%s)", ret,
693         gst_flow_get_name (ret));
694     return ret;
695   }
696 }
697
698 static void
699 gst_ffmpegaudenc_set_property (GObject * object,
700     guint prop_id, const GValue * value, GParamSpec * pspec)
701 {
702   GstFFMpegAudEnc *ffmpegaudenc;
703
704   /* Get a pointer of the right type. */
705   ffmpegaudenc = (GstFFMpegAudEnc *) (object);
706
707   if (ffmpegaudenc->opened) {
708     GST_WARNING_OBJECT (ffmpegaudenc,
709         "Can't change properties once decoder is setup !");
710     return;
711   }
712
713   /* Check the argument id to see which argument we're setting. */
714   switch (prop_id) {
715     case PROP_BIT_RATE:
716       ffmpegaudenc->bitrate = g_value_get_int (value);
717       break;
718     case PROP_RTP_PAYLOAD_SIZE:
719       ffmpegaudenc->rtp_payload_size = g_value_get_int (value);
720       break;
721     case PROP_COMPLIANCE:
722       ffmpegaudenc->compliance = g_value_get_enum (value);
723       break;
724     default:
725       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
726       break;
727   }
728 }
729
730 /* The set function is simply the inverse of the get fuction. */
731 static void
732 gst_ffmpegaudenc_get_property (GObject * object,
733     guint prop_id, GValue * value, GParamSpec * pspec)
734 {
735   GstFFMpegAudEnc *ffmpegaudenc;
736
737   /* It's not null if we got it, but it might not be ours */
738   ffmpegaudenc = (GstFFMpegAudEnc *) (object);
739
740   switch (prop_id) {
741     case PROP_BIT_RATE:
742       g_value_set_int (value, ffmpegaudenc->bitrate);
743       break;
744       break;
745     case PROP_RTP_PAYLOAD_SIZE:
746       g_value_set_int (value, ffmpegaudenc->rtp_payload_size);
747       break;
748     case PROP_COMPLIANCE:
749       g_value_set_enum (value, ffmpegaudenc->compliance);
750       break;
751     default:
752       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
753       break;
754   }
755 }
756
757 gboolean
758 gst_ffmpegaudenc_register (GstPlugin * plugin)
759 {
760   GTypeInfo typeinfo = {
761     sizeof (GstFFMpegAudEncClass),
762     (GBaseInitFunc) gst_ffmpegaudenc_base_init,
763     NULL,
764     (GClassInitFunc) gst_ffmpegaudenc_class_init,
765     NULL,
766     NULL,
767     sizeof (GstFFMpegAudEnc),
768     0,
769     (GInstanceInitFunc) gst_ffmpegaudenc_init,
770   };
771   GType type;
772   AVCodec *in_plugin;
773
774
775   GST_LOG ("Registering encoders");
776
777   in_plugin = av_codec_next (NULL);
778   while (in_plugin) {
779     gchar *type_name;
780     guint rank;
781
782     /* Skip non-AV codecs */
783     if (in_plugin->type != AVMEDIA_TYPE_AUDIO)
784       goto next;
785
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)) {
792       goto next;
793     }
794
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)) {
799       GST_DEBUG
800           ("Not using external library encoder %s. Use the gstreamer-native ones instead.",
801           in_plugin->name);
802       goto next;
803     }
804
805     /* only encoders */
806     if (!av_codec_is_encoder (in_plugin)) {
807       goto next;
808     }
809
810     /* FIXME : We should have a method to know cheaply whether we have a mapping
811      * for the given plugin or not */
812
813     GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
814
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);
819       goto next;
820     }
821
822     /* construct the type */
823     type_name = g_strdup_printf ("avenc_%s", in_plugin->name);
824
825     type = g_type_from_name (type_name);
826
827     if (!type) {
828
829       /* create the glib type now */
830       type =
831           g_type_register_static (GST_TYPE_AUDIO_ENCODER, type_name, &typeinfo,
832           0);
833       g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) in_plugin);
834
835       {
836         static const GInterfaceInfo preset_info = {
837           NULL,
838           NULL,
839           NULL
840         };
841         g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_info);
842       }
843     }
844
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;
849         break;
850       default:
851         rank = GST_RANK_SECONDARY;
852         break;
853     }
854
855     if (!gst_element_register (plugin, type_name, rank, type)) {
856       g_free (type_name);
857       return FALSE;
858     }
859
860     g_free (type_name);
861
862   next:
863     in_plugin = av_codec_next (in_plugin);
864   }
865
866   GST_LOG ("Finished registering encoders");
867
868   return TRUE;
869 }