Use AV_ namespace for all CODEC_ macro
[platform/upstream/gstreamer.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   gst_caps_unref (sinkcaps);
128   gst_caps_unref (srccaps);
129
130   klass->in_plugin = in_plugin;
131   klass->srctempl = srctempl;
132   klass->sinktempl = sinktempl;
133
134   return;
135 }
136
137 static void
138 gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass)
139 {
140   GObjectClass *gobject_class;
141   GstAudioEncoderClass *gstaudioencoder_class;
142
143   gobject_class = (GObjectClass *) klass;
144   gstaudioencoder_class = (GstAudioEncoderClass *) klass;
145
146   parent_class = g_type_class_peek_parent (klass);
147
148   gobject_class->set_property = gst_ffmpegaudenc_set_property;
149   gobject_class->get_property = gst_ffmpegaudenc_get_property;
150
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));
161
162   gobject_class->finalize = gst_ffmpegaudenc_finalize;
163
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);
171 }
172
173 static void
174 gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
175 {
176   GstFFMpegAudEncClass *klass =
177       (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
178
179   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (ffmpegaudenc));
180
181   /* ffmpeg objects */
182   ffmpegaudenc->context = avcodec_alloc_context3 (klass->in_plugin);
183   ffmpegaudenc->opened = FALSE;
184   ffmpegaudenc->frame = av_frame_alloc ();
185
186   ffmpegaudenc->compliance = FFMPEG_DEFAULT_COMPLIANCE;
187
188   gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (ffmpegaudenc), TRUE);
189 }
190
191 static void
192 gst_ffmpegaudenc_finalize (GObject * object)
193 {
194   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) object;
195
196   /* clean up remaining allocated data */
197   av_frame_free (&ffmpegaudenc->frame);
198   gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
199   av_free (ffmpegaudenc->context);
200
201   G_OBJECT_CLASS (parent_class)->finalize (object);
202 }
203
204 static gboolean
205 gst_ffmpegaudenc_start (GstAudioEncoder * encoder)
206 {
207   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
208   GstFFMpegAudEncClass *oclass =
209       (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
210
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");
215     return FALSE;
216   }
217
218   return TRUE;
219 }
220
221 static gboolean
222 gst_ffmpegaudenc_stop (GstAudioEncoder * encoder)
223 {
224   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
225
226   /* close old session */
227   gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
228   ffmpegaudenc->opened = FALSE;
229
230   return TRUE;
231 }
232
233 static void
234 gst_ffmpegaudenc_flush (GstAudioEncoder * encoder)
235 {
236   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
237
238   if (ffmpegaudenc->opened) {
239     avcodec_flush_buffers (ffmpegaudenc->context);
240   }
241 }
242
243 static gboolean
244 gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
245 {
246   GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
247   GstCaps *other_caps;
248   GstCaps *allowed_caps;
249   GstCaps *icaps;
250   gsize frame_size;
251   GstFFMpegAudEncClass *oclass =
252       (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
253
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");
261       return FALSE;
262     }
263   }
264
265   /* if we set it in _getcaps we should set it also in _link */
266   ffmpegaudenc->context->strict_std_compliance = ffmpegaudenc->compliance;
267
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;
274   } else {
275     GST_INFO_OBJECT (ffmpegaudenc,
276         "Using avcontext default bitrate %" G_GINT64_FORMAT,
277         (gint64) ffmpegaudenc->context->bit_rate);
278   }
279
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;
283   }
284
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;
291
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;
298   }
299
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);
307   }
308
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));
312   if (!allowed_caps) {
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 */
316     allowed_caps =
317         gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
318   }
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);
322
323   /* open codec */
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");
332
333     if ((oclass->in_plugin->capabilities & AV_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"));
341     }
342     return FALSE;
343   }
344
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);
348
349   if (!other_caps) {
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");
356     return FALSE;
357   }
358
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);
364     return FALSE;
365   }
366   icaps = gst_caps_fixate (icaps);
367
368   if (!gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (ffmpegaudenc),
369           icaps)) {
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");
375     return FALSE;
376   }
377   gst_caps_unref (icaps);
378
379   frame_size = ffmpegaudenc->context->frame_size;
380   if (frame_size > 1) {
381     gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
382         frame_size);
383     gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
384         frame_size);
385     gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 1);
386   } else {
387     gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
388         0);
389     gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
390         0);
391     gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 0);
392   }
393
394   /* Store some tags */
395   {
396     GstTagList *tags = gst_tag_list_new_empty ();
397     const gchar *codec;
398
399     gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_NOMINAL_BITRATE,
400         (guint) ffmpegaudenc->context->bit_rate, NULL);
401
402     if ((codec =
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,
405           NULL);
406
407     gst_audio_encoder_merge_tags (encoder, tags, GST_TAG_MERGE_REPLACE);
408     gst_tag_list_unref (tags);
409   }
410
411   /* success! */
412   ffmpegaudenc->opened = TRUE;
413
414   return TRUE;
415 }
416
417 static void
418 gst_ffmpegaudenc_free_avpacket (gpointer pkt)
419 {
420   av_packet_unref ((AVPacket *) pkt);
421   g_slice_free (AVPacket, pkt);
422 }
423
424 typedef struct
425 {
426   GstBuffer *buffer;
427   GstMapInfo map;
428
429   guint8 **ext_data_array, *ext_data;
430 } BufferInfo;
431
432 static void
433 buffer_info_free (void *opaque, guint8 * data)
434 {
435   BufferInfo *info = opaque;
436
437   if (info->buffer) {
438     gst_buffer_unmap (info->buffer, &info->map);
439     gst_buffer_unref (info->buffer);
440   } else {
441     av_free (info->ext_data);
442     av_free (info->ext_data_array);
443   }
444   g_slice_free (BufferInfo, info);
445 }
446
447 static GstFlowReturn
448 gst_ffmpegaudenc_encode_audio (GstFFMpegAudEnc * ffmpegaudenc,
449     GstBuffer * buffer, gint * have_data)
450 {
451   GstAudioEncoder *enc;
452   AVCodecContext *ctx;
453   gint res;
454   GstFlowReturn ret;
455   GstAudioInfo *info;
456   AVPacket *pkt;
457   AVFrame *frame = ffmpegaudenc->frame;
458   gboolean planar;
459   gint nsamples = -1;
460
461   enc = GST_AUDIO_ENCODER (ffmpegaudenc);
462
463   ctx = ffmpegaudenc->context;
464
465   pkt = g_slice_new0 (AVPacket);
466
467   if (buffer != NULL) {
468     BufferInfo *buffer_info = g_slice_new0 (BufferInfo);
469     guint8 *audio_in;
470     guint in_size;
471
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;
476
477     GST_LOG_OBJECT (ffmpegaudenc, "encoding buffer %p size:%u", audio_in,
478         in_size);
479
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;
486
487     if (planar && info->channels > 1) {
488       gint channels;
489       gint i, j;
490
491       nsamples = frame->nb_samples = in_size / info->bpf;
492       channels = info->channels;
493
494       frame->buf[0] =
495           av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0);
496
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 *));
500       } else {
501         frame->extended_data = frame->data;
502       }
503
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];
509
510       switch (info->finfo->width) {
511         case 8:{
512           const guint8 *idata = (const guint8 *) audio_in;
513
514           for (i = 0; i < nsamples; i++) {
515             for (j = 0; j < channels; j++) {
516               ((guint8 *) frame->extended_data[j])[i] = idata[j];
517             }
518             idata += channels;
519           }
520           break;
521         }
522         case 16:{
523           const guint16 *idata = (const guint16 *) audio_in;
524
525           for (i = 0; i < nsamples; i++) {
526             for (j = 0; j < channels; j++) {
527               ((guint16 *) frame->extended_data[j])[i] = idata[j];
528             }
529             idata += channels;
530           }
531           break;
532         }
533         case 32:{
534           const guint32 *idata = (const guint32 *) audio_in;
535
536           for (i = 0; i < nsamples; i++) {
537             for (j = 0; j < channels; j++) {
538               ((guint32 *) frame->extended_data[j])[i] = idata[j];
539             }
540             idata += channels;
541           }
542
543           break;
544         }
545         case 64:{
546           const guint64 *idata = (const guint64 *) audio_in;
547
548           for (i = 0; i < nsamples; i++) {
549             for (j = 0; j < channels; j++) {
550               ((guint64 *) frame->extended_data[j])[i] = idata[j];
551             }
552             idata += channels;
553           }
554
555           break;
556         }
557         default:
558           g_assert_not_reached ();
559           break;
560       }
561
562       gst_buffer_unmap (buffer, &buffer_info->map);
563       gst_buffer_unref (buffer);
564       buffer_info->buffer = NULL;
565     } else {
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;
570       frame->buf[0] =
571           av_buffer_create (NULL, 0, buffer_info_free, buffer_info, 0);
572     }
573
574     /* we have a frame to feed the encoder */
575     res = avcodec_encode_audio2 (ctx, pkt, frame, have_data);
576
577     av_frame_unref (frame);
578   } else {
579     GST_LOG_OBJECT (ffmpegaudenc, "draining");
580     /* flushing the encoder */
581     res = avcodec_encode_audio2 (ctx, pkt, NULL, have_data);
582   }
583
584   if (res < 0) {
585     char error_str[128] = { 0, };
586
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);
590     return GST_FLOW_OK;
591   }
592   GST_LOG_OBJECT (ffmpegaudenc, "got output size %d", res);
593
594   if (*have_data) {
595     GstBuffer *outbuf;
596     const AVCodec *codec;
597
598     GST_LOG_OBJECT (ffmpegaudenc, "pushing size %d", pkt->size);
599
600     outbuf =
601         gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, pkt->data,
602         pkt->size, 0, pkt->size, pkt, gst_ffmpegaudenc_free_avpacket);
603
604     codec = ffmpegaudenc->context->codec;
605     if ((codec->capabilities & AV_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);
610     } else {
611       ret = gst_audio_encoder_finish_frame (enc, outbuf, nsamples);
612     }
613   } else {
614     GST_LOG_OBJECT (ffmpegaudenc, "no output produced");
615     g_slice_free (AVPacket, pkt);
616     ret = GST_FLOW_OK;
617   }
618
619   return ret;
620 }
621
622 static void
623 gst_ffmpegaudenc_drain (GstFFMpegAudEnc * ffmpegaudenc)
624 {
625   GstFFMpegAudEncClass *oclass;
626
627   oclass = (GstFFMpegAudEncClass *) (G_OBJECT_GET_CLASS (ffmpegaudenc));
628
629   if (oclass->in_plugin->capabilities & AV_CODEC_CAP_DELAY) {
630     gint have_data, try = 0;
631
632     GST_LOG_OBJECT (ffmpegaudenc,
633         "codec has delay capabilities, calling until libav has drained everything");
634
635     do {
636       GstFlowReturn ret;
637
638       ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, NULL, &have_data);
639       if (ret != GST_FLOW_OK || have_data == 0)
640         break;
641     } while (try++ < 10);
642   }
643 }
644
645 static GstFlowReturn
646 gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
647 {
648   GstFFMpegAudEnc *ffmpegaudenc;
649   GstFlowReturn ret;
650   gint have_data;
651
652   ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
653
654   if (G_UNLIKELY (!ffmpegaudenc->opened))
655     goto not_negotiated;
656
657   if (!inbuf) {
658     gst_ffmpegaudenc_drain (ffmpegaudenc);
659     return GST_FLOW_OK;
660   }
661
662   inbuf = gst_buffer_ref (inbuf);
663
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));
668
669   /* Reorder channels to the GStreamer channel order */
670   if (ffmpegaudenc->needs_reorder) {
671     GstAudioInfo *info = gst_audio_encoder_get_audio_info (encoder);
672
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);
676   }
677
678   ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, inbuf, &have_data);
679
680   if (ret != GST_FLOW_OK)
681     goto push_failed;
682
683   return GST_FLOW_OK;
684
685   /* ERRORS */
686 not_negotiated:
687   {
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;
692   }
693 push_failed:
694   {
695     GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to push buffer %d (%s)", ret,
696         gst_flow_get_name (ret));
697     return ret;
698   }
699 }
700
701 static void
702 gst_ffmpegaudenc_set_property (GObject * object,
703     guint prop_id, const GValue * value, GParamSpec * pspec)
704 {
705   GstFFMpegAudEnc *ffmpegaudenc;
706
707   /* Get a pointer of the right type. */
708   ffmpegaudenc = (GstFFMpegAudEnc *) (object);
709
710   if (ffmpegaudenc->opened) {
711     GST_WARNING_OBJECT (ffmpegaudenc,
712         "Can't change properties once decoder is setup !");
713     return;
714   }
715
716   /* Check the argument id to see which argument we're setting. */
717   switch (prop_id) {
718     case PROP_BIT_RATE:
719       ffmpegaudenc->bitrate = g_value_get_int (value);
720       break;
721     case PROP_RTP_PAYLOAD_SIZE:
722       ffmpegaudenc->rtp_payload_size = g_value_get_int (value);
723       break;
724     case PROP_COMPLIANCE:
725       ffmpegaudenc->compliance = g_value_get_enum (value);
726       break;
727     default:
728       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
729       break;
730   }
731 }
732
733 /* The set function is simply the inverse of the get fuction. */
734 static void
735 gst_ffmpegaudenc_get_property (GObject * object,
736     guint prop_id, GValue * value, GParamSpec * pspec)
737 {
738   GstFFMpegAudEnc *ffmpegaudenc;
739
740   /* It's not null if we got it, but it might not be ours */
741   ffmpegaudenc = (GstFFMpegAudEnc *) (object);
742
743   switch (prop_id) {
744     case PROP_BIT_RATE:
745       g_value_set_int (value, ffmpegaudenc->bitrate);
746       break;
747       break;
748     case PROP_RTP_PAYLOAD_SIZE:
749       g_value_set_int (value, ffmpegaudenc->rtp_payload_size);
750       break;
751     case PROP_COMPLIANCE:
752       g_value_set_enum (value, ffmpegaudenc->compliance);
753       break;
754     default:
755       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
756       break;
757   }
758 }
759
760 gboolean
761 gst_ffmpegaudenc_register (GstPlugin * plugin)
762 {
763   GTypeInfo typeinfo = {
764     sizeof (GstFFMpegAudEncClass),
765     (GBaseInitFunc) gst_ffmpegaudenc_base_init,
766     NULL,
767     (GClassInitFunc) gst_ffmpegaudenc_class_init,
768     NULL,
769     NULL,
770     sizeof (GstFFMpegAudEnc),
771     0,
772     (GInstanceInitFunc) gst_ffmpegaudenc_init,
773   };
774   GType type;
775   AVCodec *in_plugin;
776
777
778   GST_LOG ("Registering encoders");
779
780   in_plugin = av_codec_next (NULL);
781   while (in_plugin) {
782     gchar *type_name;
783     guint rank;
784
785     /* Skip non-AV codecs */
786     if (in_plugin->type != AVMEDIA_TYPE_AUDIO)
787       goto next;
788
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)) {
798 #else
799             in_plugin->id <= AV_CODEC_ID_PCM_S16BE_PLANAR)) {
800 #endif
801       goto next;
802     }
803
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)) {
808       GST_DEBUG
809           ("Not using external library encoder %s. Use the gstreamer-native ones instead.",
810           in_plugin->name);
811       goto next;
812     }
813
814     /* only encoders */
815     if (!av_codec_is_encoder (in_plugin)) {
816       goto next;
817     }
818
819     /* FIXME : We should have a method to know cheaply whether we have a mapping
820      * for the given plugin or not */
821
822     GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
823
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);
828       goto next;
829     }
830
831     /* construct the type */
832     type_name = g_strdup_printf ("avenc_%s", in_plugin->name);
833
834     type = g_type_from_name (type_name);
835
836     if (!type) {
837
838       /* create the glib type now */
839       type =
840           g_type_register_static (GST_TYPE_AUDIO_ENCODER, type_name, &typeinfo,
841           0);
842       g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) in_plugin);
843
844       {
845         static const GInterfaceInfo preset_info = {
846           NULL,
847           NULL,
848           NULL
849         };
850         g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_info);
851       }
852     }
853
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;
858         break;
859       default:
860         rank = GST_RANK_SECONDARY;
861         break;
862     }
863
864     if (!gst_element_register (plugin, type_name, rank, type)) {
865       g_free (type_name);
866       return FALSE;
867     }
868
869     g_free (type_name);
870
871   next:
872     in_plugin = av_codec_next (in_plugin);
873   }
874
875   GST_LOG ("Finished registering encoders");
876
877   return TRUE;
878 }