• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 #include <libavcodec/avcodec.h>
30 #include <libavutil/channel_layout.h>
31 
32 #include <gst/gst.h>
33 
34 #include "gstav.h"
35 #include "gstavcodecmap.h"
36 #include "gstavutils.h"
37 #include "gstavauddec.h"
38 
39 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
40 
41 /* A number of function prototypes are given so we can refer to them later. */
42 static void gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass);
43 static void gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass);
44 static void gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec);
45 static void gst_ffmpegauddec_finalize (GObject * object);
46 static gboolean gst_ffmpegauddec_propose_allocation (GstAudioDecoder * decoder,
47     GstQuery * query);
48 
49 static gboolean gst_ffmpegauddec_start (GstAudioDecoder * decoder);
50 static gboolean gst_ffmpegauddec_stop (GstAudioDecoder * decoder);
51 static void gst_ffmpegauddec_flush (GstAudioDecoder * decoder, gboolean hard);
52 static gboolean gst_ffmpegauddec_set_format (GstAudioDecoder * decoder,
53     GstCaps * caps);
54 static GstFlowReturn gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder,
55     GstBuffer * inbuf);
56 
57 static gboolean gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec,
58     AVCodecContext * context, AVFrame * frame, gboolean force);
59 
60 static void gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec);
61 
62 #define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
63 
64 static GstElementClass *parent_class = NULL;
65 
66 static void
gst_ffmpegauddec_base_init(GstFFMpegAudDecClass * klass)67 gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass)
68 {
69   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
70   GstPadTemplate *sinktempl, *srctempl;
71   GstCaps *sinkcaps, *srccaps;
72   AVCodec *in_plugin;
73   gchar *longname, *description;
74 
75   in_plugin =
76       (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
77       GST_FFDEC_PARAMS_QDATA);
78   g_assert (in_plugin != NULL);
79 
80   /* construct the element details struct */
81   longname = g_strdup_printf ("libav %s decoder", in_plugin->long_name);
82   description = g_strdup_printf ("libav %s decoder", in_plugin->name);
83   gst_element_class_set_metadata (element_class, longname,
84       "Codec/Decoder/Audio", description,
85       "Wim Taymans <wim.taymans@gmail.com>, "
86       "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
87       "Edward Hervey <bilboed@bilboed.com>");
88   g_free (longname);
89   g_free (description);
90 
91   /* get the caps */
92   sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
93   if (!sinkcaps) {
94     GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
95     sinkcaps = gst_caps_from_string ("unknown/unknown");
96   }
97   srccaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
98       in_plugin->id, FALSE, in_plugin);
99   if (!srccaps) {
100     GST_DEBUG ("Couldn't get source caps for decoder '%s'", in_plugin->name);
101     srccaps = gst_caps_from_string ("audio/x-raw");
102   }
103 
104   /* pad templates */
105   sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
106       GST_PAD_ALWAYS, sinkcaps);
107   srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
108 
109   gst_element_class_add_pad_template (element_class, srctempl);
110   gst_element_class_add_pad_template (element_class, sinktempl);
111 
112   gst_caps_unref (sinkcaps);
113   gst_caps_unref (srccaps);
114 
115   klass->in_plugin = in_plugin;
116   klass->srctempl = srctempl;
117   klass->sinktempl = sinktempl;
118 }
119 
120 static void
gst_ffmpegauddec_class_init(GstFFMpegAudDecClass * klass)121 gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass)
122 {
123   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
124   GstAudioDecoderClass *gstaudiodecoder_class = GST_AUDIO_DECODER_CLASS (klass);
125 
126   parent_class = g_type_class_peek_parent (klass);
127 
128   gobject_class->finalize = gst_ffmpegauddec_finalize;
129 
130   gstaudiodecoder_class->start = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_start);
131   gstaudiodecoder_class->stop = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_stop);
132   gstaudiodecoder_class->set_format =
133       GST_DEBUG_FUNCPTR (gst_ffmpegauddec_set_format);
134   gstaudiodecoder_class->handle_frame =
135       GST_DEBUG_FUNCPTR (gst_ffmpegauddec_handle_frame);
136   gstaudiodecoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_flush);
137   gstaudiodecoder_class->propose_allocation =
138       GST_DEBUG_FUNCPTR (gst_ffmpegauddec_propose_allocation);
139 
140   GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
141 }
142 
143 static void
gst_ffmpegauddec_init(GstFFMpegAudDec * ffmpegdec)144 gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec)
145 {
146   GstFFMpegAudDecClass *klass =
147       (GstFFMpegAudDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
148 
149   /* some ffmpeg data */
150   ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
151   ffmpegdec->context->opaque = ffmpegdec;
152   ffmpegdec->opened = FALSE;
153 
154   ffmpegdec->frame = av_frame_alloc ();
155 
156   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (ffmpegdec));
157   gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
158       (ffmpegdec), TRUE);
159 
160   gst_audio_decoder_set_drainable (GST_AUDIO_DECODER (ffmpegdec), TRUE);
161   gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (ffmpegdec), TRUE);
162 }
163 
164 static void
gst_ffmpegauddec_finalize(GObject * object)165 gst_ffmpegauddec_finalize (GObject * object)
166 {
167   GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) object;
168 
169   av_frame_free (&ffmpegdec->frame);
170 
171   if (ffmpegdec->context != NULL) {
172     gst_ffmpeg_avcodec_close (ffmpegdec->context);
173     av_free (ffmpegdec->context);
174     ffmpegdec->context = NULL;
175   }
176 
177   G_OBJECT_CLASS (parent_class)->finalize (object);
178 }
179 
180 /* With LOCK */
181 static gboolean
gst_ffmpegauddec_close(GstFFMpegAudDec * ffmpegdec,gboolean reset)182 gst_ffmpegauddec_close (GstFFMpegAudDec * ffmpegdec, gboolean reset)
183 {
184   GstFFMpegAudDecClass *oclass;
185 
186   oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
187 
188   GST_LOG_OBJECT (ffmpegdec, "closing libav codec");
189 
190   gst_caps_replace (&ffmpegdec->last_caps, NULL);
191 
192   gst_ffmpeg_avcodec_close (ffmpegdec->context);
193   ffmpegdec->opened = FALSE;
194 
195   if (ffmpegdec->context->extradata) {
196     av_free (ffmpegdec->context->extradata);
197     ffmpegdec->context->extradata = NULL;
198   }
199 
200   if (reset) {
201     if (avcodec_get_context_defaults3 (ffmpegdec->context,
202             oclass->in_plugin) < 0) {
203       GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
204       return FALSE;
205     }
206     ffmpegdec->context->opaque = ffmpegdec;
207   }
208 
209   return TRUE;
210 }
211 
212 static gboolean
gst_ffmpegauddec_start(GstAudioDecoder * decoder)213 gst_ffmpegauddec_start (GstAudioDecoder * decoder)
214 {
215   GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
216   GstFFMpegAudDecClass *oclass;
217 
218   oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
219 
220   GST_OBJECT_LOCK (ffmpegdec);
221   gst_ffmpeg_avcodec_close (ffmpegdec->context);
222   if (avcodec_get_context_defaults3 (ffmpegdec->context, oclass->in_plugin) < 0) {
223     GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
224     GST_OBJECT_UNLOCK (ffmpegdec);
225     return FALSE;
226   }
227   ffmpegdec->context->opaque = ffmpegdec;
228   GST_OBJECT_UNLOCK (ffmpegdec);
229 
230   return TRUE;
231 }
232 
233 static gboolean
gst_ffmpegauddec_stop(GstAudioDecoder * decoder)234 gst_ffmpegauddec_stop (GstAudioDecoder * decoder)
235 {
236   GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
237 
238   GST_OBJECT_LOCK (ffmpegdec);
239   gst_ffmpegauddec_close (ffmpegdec, FALSE);
240   g_free (ffmpegdec->padded);
241   ffmpegdec->padded = NULL;
242   ffmpegdec->padded_size = 0;
243   GST_OBJECT_UNLOCK (ffmpegdec);
244   gst_audio_info_init (&ffmpegdec->info);
245   gst_caps_replace (&ffmpegdec->last_caps, NULL);
246 
247   return TRUE;
248 }
249 
250 /* with LOCK */
251 static gboolean
gst_ffmpegauddec_open(GstFFMpegAudDec * ffmpegdec)252 gst_ffmpegauddec_open (GstFFMpegAudDec * ffmpegdec)
253 {
254   GstFFMpegAudDecClass *oclass;
255 
256   oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
257 
258   if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
259     goto could_not_open;
260 
261   ffmpegdec->opened = TRUE;
262 
263   GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
264       oclass->in_plugin->name, oclass->in_plugin->id);
265 
266   gst_audio_info_init (&ffmpegdec->info);
267 
268   return TRUE;
269 
270   /* ERRORS */
271 could_not_open:
272   {
273     gst_ffmpegauddec_close (ffmpegdec, TRUE);
274     GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
275         oclass->in_plugin->name);
276     return FALSE;
277   }
278 }
279 
280 static gboolean
gst_ffmpegauddec_propose_allocation(GstAudioDecoder * decoder,GstQuery * query)281 gst_ffmpegauddec_propose_allocation (GstAudioDecoder * decoder,
282     GstQuery * query)
283 {
284   GstAllocationParams params;
285 
286   gst_allocation_params_init (&params);
287   params.flags = GST_MEMORY_FLAG_ZERO_PADDED;
288   params.align = 15;
289   params.padding = AV_INPUT_BUFFER_PADDING_SIZE;
290   /* we would like to have some padding so that we don't have to
291    * memcpy. We don't suggest an allocator. */
292   gst_query_add_allocation_param (query, NULL, &params);
293 
294   return GST_AUDIO_DECODER_CLASS (parent_class)->propose_allocation (decoder,
295       query);
296 }
297 
298 static gboolean
gst_ffmpegauddec_set_format(GstAudioDecoder * decoder,GstCaps * caps)299 gst_ffmpegauddec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
300 {
301   GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
302   GstFFMpegAudDecClass *oclass;
303   gboolean ret = TRUE;
304 
305   oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
306 
307   GST_DEBUG_OBJECT (ffmpegdec, "setcaps called");
308 
309   GST_OBJECT_LOCK (ffmpegdec);
310 
311   if (ffmpegdec->last_caps && gst_caps_is_equal (ffmpegdec->last_caps, caps)) {
312     GST_DEBUG_OBJECT (ffmpegdec, "same caps");
313     GST_OBJECT_UNLOCK (ffmpegdec);
314     return TRUE;
315   }
316 
317   gst_caps_replace (&ffmpegdec->last_caps, caps);
318 
319   /* close old session */
320   if (ffmpegdec->opened) {
321     GST_OBJECT_UNLOCK (ffmpegdec);
322     gst_ffmpegauddec_drain (ffmpegdec);
323     GST_OBJECT_LOCK (ffmpegdec);
324     if (!gst_ffmpegauddec_close (ffmpegdec, TRUE)) {
325       GST_OBJECT_UNLOCK (ffmpegdec);
326       return FALSE;
327     }
328   }
329 
330   /* get size and so */
331   gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
332       oclass->in_plugin->type, caps, ffmpegdec->context);
333 
334   /* workaround encoder bugs */
335   ffmpegdec->context->workaround_bugs |= FF_BUG_AUTODETECT;
336   ffmpegdec->context->err_recognition = 1;
337 
338   /* open codec - we don't select an output pix_fmt yet,
339    * simply because we don't know! We only get it
340    * during playback... */
341   if (!gst_ffmpegauddec_open (ffmpegdec))
342     goto open_failed;
343 
344 done:
345   GST_OBJECT_UNLOCK (ffmpegdec);
346 
347   return ret;
348 
349   /* ERRORS */
350 open_failed:
351   {
352     GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
353     ret = FALSE;
354     goto done;
355   }
356 }
357 
358 static gboolean
settings_changed(GstFFMpegAudDec * ffmpegdec,AVFrame * frame)359 settings_changed (GstFFMpegAudDec * ffmpegdec, AVFrame * frame)
360 {
361   GstAudioFormat format;
362   GstAudioLayout layout;
363   gint channels = av_get_channel_layout_nb_channels (frame->channel_layout);
364 
365   format = gst_ffmpeg_smpfmt_to_audioformat (frame->format, &layout);
366   if (format == GST_AUDIO_FORMAT_UNKNOWN)
367     return TRUE;
368 
369   return !(ffmpegdec->info.rate == frame->sample_rate &&
370       ffmpegdec->info.channels == channels &&
371       ffmpegdec->info.finfo->format == format &&
372       ffmpegdec->info.layout == layout);
373 }
374 
375 static gboolean
gst_ffmpegauddec_negotiate(GstFFMpegAudDec * ffmpegdec,AVCodecContext * context,AVFrame * frame,gboolean force)376 gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec,
377     AVCodecContext * context, AVFrame * frame, gboolean force)
378 {
379   GstFFMpegAudDecClass *oclass;
380   GstAudioFormat format;
381   GstAudioLayout layout;
382   gint channels;
383   GstAudioChannelPosition pos[64] = { 0, };
384 
385   oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
386 
387   format = gst_ffmpeg_smpfmt_to_audioformat (frame->format, &layout);
388   if (format == GST_AUDIO_FORMAT_UNKNOWN)
389     goto no_caps;
390   channels = av_get_channel_layout_nb_channels (frame->channel_layout);
391   if (channels == 0)
392     channels = frame->channels;
393   if (channels == 0)
394     goto no_caps;
395 
396   if (!force && !settings_changed (ffmpegdec, frame))
397     return TRUE;
398 
399   GST_DEBUG_OBJECT (ffmpegdec,
400       "Renegotiating audio from %dHz@%dchannels (%d, interleaved=%d) "
401       "to %dHz@%dchannels (%d, interleaved=%d)",
402       ffmpegdec->info.rate, ffmpegdec->info.channels,
403       ffmpegdec->info.finfo->format,
404       ffmpegdec->info.layout == GST_AUDIO_LAYOUT_INTERLEAVED,
405       frame->sample_rate, channels, format,
406       layout == GST_AUDIO_LAYOUT_INTERLEAVED);
407 
408   gst_ffmpeg_channel_layout_to_gst (frame->channel_layout, channels, pos);
409   memcpy (ffmpegdec->ffmpeg_layout, pos,
410       sizeof (GstAudioChannelPosition) * channels);
411 
412   /* Get GStreamer channel layout */
413   gst_audio_channel_positions_to_valid_order (pos, channels);
414   ffmpegdec->needs_reorder =
415       memcmp (pos, ffmpegdec->ffmpeg_layout, sizeof (pos[0]) * channels) != 0;
416   gst_audio_info_set_format (&ffmpegdec->info, format,
417       frame->sample_rate, channels, pos);
418   ffmpegdec->info.layout = layout;
419 
420   if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (ffmpegdec),
421           &ffmpegdec->info))
422     goto caps_failed;
423 
424   return TRUE;
425 
426   /* ERRORS */
427 no_caps:
428   {
429 #ifdef HAVE_LIBAV_UNINSTALLED
430     /* using internal ffmpeg snapshot */
431     GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION,
432         ("Could not find GStreamer caps mapping for libav codec '%s'.",
433             oclass->in_plugin->name), (NULL));
434 #else
435     /* using external ffmpeg */
436     GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION,
437         ("Could not find GStreamer caps mapping for libav codec '%s', and "
438             "you are using an external libavcodec. This is most likely due to "
439             "a packaging problem and/or libavcodec having been upgraded to a "
440             "version that is not compatible with this version of "
441             "gstreamer-libav. Make sure your gstreamer-libav and libavcodec "
442             "packages come from the same source/repository.",
443             oclass->in_plugin->name), (NULL));
444 #endif
445     return FALSE;
446   }
447 caps_failed:
448   {
449     GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
450         ("Could not set caps for libav decoder (%s), not fixed?",
451             oclass->in_plugin->name));
452     memset (&ffmpegdec->info, 0, sizeof (ffmpegdec->info));
453 
454     return FALSE;
455   }
456 }
457 
458 static void
gst_avpacket_init(AVPacket * packet,guint8 * data,guint size)459 gst_avpacket_init (AVPacket * packet, guint8 * data, guint size)
460 {
461   memset (packet, 0, sizeof (AVPacket));
462   packet->data = data;
463   packet->size = size;
464 }
465 
466 /*
467  * Returns: whether a frame was decoded
468  */
469 static gboolean
gst_ffmpegauddec_audio_frame(GstFFMpegAudDec * ffmpegdec,AVCodec * in_plugin,GstBuffer ** outbuf,GstFlowReturn * ret)470 gst_ffmpegauddec_audio_frame (GstFFMpegAudDec * ffmpegdec,
471     AVCodec * in_plugin, GstBuffer ** outbuf, GstFlowReturn * ret)
472 {
473   gboolean got_frame = FALSE;
474   gint res;
475 
476   res = avcodec_receive_frame (ffmpegdec->context, ffmpegdec->frame);
477 
478   if (res >= 0) {
479     gint nsamples, channels, byte_per_sample;
480     gsize output_size;
481     gboolean planar;
482 
483     if (!gst_ffmpegauddec_negotiate (ffmpegdec, ffmpegdec->context,
484             ffmpegdec->frame, FALSE)) {
485       *outbuf = NULL;
486       *ret = GST_FLOW_NOT_NEGOTIATED;
487       goto beach;
488     }
489 
490     got_frame = TRUE;
491 
492     channels = ffmpegdec->info.channels;
493     nsamples = ffmpegdec->frame->nb_samples;
494     byte_per_sample = ffmpegdec->info.finfo->width / 8;
495     planar = av_sample_fmt_is_planar (ffmpegdec->context->sample_fmt);
496 
497     g_return_val_if_fail (ffmpegdec->info.layout == (planar ?
498             GST_AUDIO_LAYOUT_NON_INTERLEAVED : GST_AUDIO_LAYOUT_INTERLEAVED),
499         GST_FLOW_NOT_NEGOTIATED);
500 
501     GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
502 
503     /* ffmpegdec->frame->linesize[0] might contain padding, allocate only what's needed */
504     output_size = nsamples * byte_per_sample * channels;
505 
506     *outbuf =
507         gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER
508         (ffmpegdec), output_size);
509 
510     if (planar) {
511       gint i;
512       GstAudioMeta *meta;
513 
514       meta = gst_buffer_add_audio_meta (*outbuf, &ffmpegdec->info, nsamples,
515           NULL);
516 
517       for (i = 0; i < channels; i++) {
518         gst_buffer_fill (*outbuf, meta->offsets[i],
519             ffmpegdec->frame->extended_data[i], nsamples * byte_per_sample);
520       }
521     } else {
522       gst_buffer_fill (*outbuf, 0, ffmpegdec->frame->data[0], output_size);
523     }
524 
525     GST_DEBUG_OBJECT (ffmpegdec, "Buffer created. Size: %" G_GSIZE_FORMAT,
526         output_size);
527 
528     /* Reorder channels to the GStreamer channel order */
529     if (ffmpegdec->needs_reorder) {
530       *outbuf = gst_buffer_make_writable (*outbuf);
531       gst_audio_buffer_reorder_channels (*outbuf, ffmpegdec->info.finfo->format,
532           ffmpegdec->info.channels, ffmpegdec->ffmpeg_layout,
533           ffmpegdec->info.position);
534     }
535 
536     /* Mark corrupted frames as corrupted */
537     if (ffmpegdec->frame->flags & AV_FRAME_FLAG_CORRUPT)
538       GST_BUFFER_FLAG_SET (*outbuf, GST_BUFFER_FLAG_CORRUPTED);
539   } else if (res == AVERROR (EAGAIN)) {
540     *outbuf = NULL;
541   } else if (res == AVERROR_EOF) {
542     *ret = GST_FLOW_EOS;
543     GST_DEBUG_OBJECT (ffmpegdec, "Context was entirely flushed");
544   } else if (res < 0) {
545     *ret = GST_FLOW_OK;
546     GST_WARNING_OBJECT (ffmpegdec, "Legitimate decoding error");
547   }
548 
549 beach:
550   av_frame_unref (ffmpegdec->frame);
551   GST_DEBUG_OBJECT (ffmpegdec, "return flow %d, out %p, got_frame %d",
552       *ret, *outbuf, got_frame);
553   return got_frame;
554 }
555 
556 /*
557  * Returns: whether a frame was decoded
558  */
559 static gboolean
gst_ffmpegauddec_frame(GstFFMpegAudDec * ffmpegdec,GstFlowReturn * ret)560 gst_ffmpegauddec_frame (GstFFMpegAudDec * ffmpegdec, GstFlowReturn * ret)
561 {
562   GstFFMpegAudDecClass *oclass;
563   GstBuffer *outbuf = NULL;
564   gboolean got_frame = FALSE;
565 
566   if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
567     goto no_codec;
568 
569   *ret = GST_FLOW_OK;
570   ffmpegdec->context->frame_number++;
571 
572   oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
573 
574   got_frame =
575       gst_ffmpegauddec_audio_frame (ffmpegdec, oclass->in_plugin, &outbuf, ret);
576 
577   if (outbuf) {
578     GST_LOG_OBJECT (ffmpegdec, "Decoded data, buffer %" GST_PTR_FORMAT, outbuf);
579     *ret =
580         gst_audio_decoder_finish_subframe (GST_AUDIO_DECODER_CAST (ffmpegdec),
581         outbuf);
582   } else {
583     GST_DEBUG_OBJECT (ffmpegdec, "We didn't get a decoded buffer");
584   }
585 
586 beach:
587   return got_frame;
588 
589   /* ERRORS */
590 no_codec:
591   {
592     GST_ERROR_OBJECT (ffmpegdec, "no codec context");
593     goto beach;
594   }
595 }
596 
597 static void
gst_ffmpegauddec_drain(GstFFMpegAudDec * ffmpegdec)598 gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec)
599 {
600   GstFFMpegAudDecClass *oclass;
601   gboolean got_any_frames = FALSE;
602 
603   oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
604 
605   if (oclass->in_plugin->capabilities & AV_CODEC_CAP_DELAY) {
606     gboolean got_frame;
607 
608     GST_LOG_OBJECT (ffmpegdec,
609         "codec has delay capabilities, calling until libav has drained everything");
610 
611     if (avcodec_send_packet (ffmpegdec->context, NULL))
612       goto send_packet_failed;
613 
614     do {
615       GstFlowReturn ret;
616 
617       got_frame = gst_ffmpegauddec_frame (ffmpegdec, &ret);
618       if (got_frame)
619         got_any_frames = TRUE;
620     } while (got_frame);
621     avcodec_flush_buffers (ffmpegdec->context);
622   }
623 
624   if (got_any_frames)
625     gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec), NULL, 1);
626 
627 send_packet_failed:
628   GST_WARNING_OBJECT (ffmpegdec, "send packet failed, could not drain decoder");
629 }
630 
631 static void
gst_ffmpegauddec_flush(GstAudioDecoder * decoder,gboolean hard)632 gst_ffmpegauddec_flush (GstAudioDecoder * decoder, gboolean hard)
633 {
634   GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
635 
636   if (ffmpegdec->opened) {
637     avcodec_flush_buffers (ffmpegdec->context);
638   }
639 }
640 
641 static GstFlowReturn
gst_ffmpegauddec_handle_frame(GstAudioDecoder * decoder,GstBuffer * inbuf)642 gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
643 {
644   GstFFMpegAudDec *ffmpegdec;
645   GstFFMpegAudDecClass *oclass;
646   guint8 *data;
647   GstMapInfo map;
648   gint size;
649   gboolean got_any_frames = FALSE;
650   gboolean got_frame;
651   GstFlowReturn ret = GST_FLOW_OK;
652   gboolean is_header;
653   AVPacket packet;
654 
655   ffmpegdec = (GstFFMpegAudDec *) decoder;
656 
657   if (G_UNLIKELY (!ffmpegdec->opened))
658     goto not_negotiated;
659 
660   if (inbuf == NULL) {
661     gst_ffmpegauddec_drain (ffmpegdec);
662     return GST_FLOW_OK;
663   }
664 
665   inbuf = gst_buffer_ref (inbuf);
666   is_header = GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_HEADER);
667 
668   oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
669 
670   GST_LOG_OBJECT (ffmpegdec,
671       "Received new data of size %" G_GSIZE_FORMAT ", offset:%" G_GUINT64_FORMAT
672       ", ts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
673       gst_buffer_get_size (inbuf), GST_BUFFER_OFFSET (inbuf),
674       GST_TIME_ARGS (GST_BUFFER_PTS (inbuf)),
675       GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)));
676 
677   /* workarounds, functions write to buffers:
678    *  libavcodec/svq1.c:svq1_decode_frame writes to the given buffer.
679    *  libavcodec/svq3.c:svq3_decode_slice_header too.
680    * ffmpeg devs know about it and will fix it (they said). */
681   if (oclass->in_plugin->id == AV_CODEC_ID_SVQ1 ||
682       oclass->in_plugin->id == AV_CODEC_ID_SVQ3) {
683     inbuf = gst_buffer_make_writable (inbuf);
684   }
685 
686   gst_buffer_map (inbuf, &map, GST_MAP_READ);
687 
688   data = map.data;
689   size = map.size;
690 
691   if (size > 0 && (!GST_MEMORY_IS_ZERO_PADDED (map.memory)
692           || (map.maxsize - map.size) < AV_INPUT_BUFFER_PADDING_SIZE)) {
693     /* add padding */
694     if (ffmpegdec->padded_size < size + AV_INPUT_BUFFER_PADDING_SIZE) {
695       ffmpegdec->padded_size = size + AV_INPUT_BUFFER_PADDING_SIZE;
696       ffmpegdec->padded = g_realloc (ffmpegdec->padded, ffmpegdec->padded_size);
697       GST_LOG_OBJECT (ffmpegdec, "resized padding buffer to %d",
698           ffmpegdec->padded_size);
699     }
700     GST_CAT_TRACE_OBJECT (GST_CAT_PERFORMANCE, ffmpegdec,
701         "Copy input to add padding");
702     memcpy (ffmpegdec->padded, data, size);
703     memset (ffmpegdec->padded + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
704 
705     data = ffmpegdec->padded;
706   }
707 
708   gst_avpacket_init (&packet, data, size);
709 
710   if (!packet.size)
711     goto done;
712 
713   if (avcodec_send_packet (ffmpegdec->context, &packet) < 0) {
714     goto send_packet_failed;
715   }
716 
717   do {
718     /* decode a frame of audio now */
719     got_frame = gst_ffmpegauddec_frame (ffmpegdec, &ret);
720 
721     if (got_frame)
722       got_any_frames = TRUE;
723 
724     if (ret != GST_FLOW_OK) {
725       GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
726           gst_flow_get_name (ret));
727       /* bad flow return, make sure we discard all data and exit */
728       break;
729     }
730   } while (got_frame);
731 
732   gst_buffer_unmap (inbuf, &map);
733   gst_buffer_unref (inbuf);
734 
735   if (is_header || got_any_frames) {
736     ret =
737         gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec), NULL, 1);
738   }
739 
740 done:
741   return ret;
742 
743   /* ERRORS */
744 not_negotiated:
745   {
746     oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
747     GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
748         ("avdec_%s: input format was not set before data start",
749             oclass->in_plugin->name));
750     ret = GST_FLOW_NOT_NEGOTIATED;
751     goto done;
752   }
753 
754 send_packet_failed:
755   {
756     GST_WARNING_OBJECT (ffmpegdec, "decoding error");
757     goto done;
758   }
759 }
760 
761 gboolean
gst_ffmpegauddec_register(GstPlugin * plugin)762 gst_ffmpegauddec_register (GstPlugin * plugin)
763 {
764   GTypeInfo typeinfo = {
765     sizeof (GstFFMpegAudDecClass),
766     (GBaseInitFunc) gst_ffmpegauddec_base_init,
767     NULL,
768     (GClassInitFunc) gst_ffmpegauddec_class_init,
769     NULL,
770     NULL,
771     sizeof (GstFFMpegAudDec),
772     0,
773     (GInstanceInitFunc) gst_ffmpegauddec_init,
774   };
775   GType type;
776   AVCodec *in_plugin;
777   void *i = 0;
778   gint rank;
779 
780   GST_LOG ("Registering decoders");
781 
782   while ((in_plugin = (AVCodec *) av_codec_iterate (&i))) {
783     gchar *type_name;
784 
785     /* only decoders */
786     if (!av_codec_is_decoder (in_plugin)
787         || in_plugin->type != AVMEDIA_TYPE_AUDIO) {
788       continue;
789     }
790 
791     /* no quasi codecs, please */
792     if (in_plugin->id == AV_CODEC_ID_PCM_S16LE_PLANAR ||
793         (in_plugin->id >= AV_CODEC_ID_PCM_S16LE &&
794             in_plugin->id <= AV_CODEC_ID_PCM_BLURAY) ||
795         (in_plugin->id >= AV_CODEC_ID_PCM_S8_PLANAR &&
796             in_plugin->id <= AV_CODEC_ID_PCM_F24LE))
797       continue;
798 
799     /* No decoders depending on external libraries (we don't build them, but
800      * people who build against an external ffmpeg might have them.
801      * We have native gstreamer plugins for all of those libraries anyway. */
802     if (!strncmp (in_plugin->name, "lib", 3)) {
803       GST_DEBUG
804           ("Not using external library decoder %s. Use the gstreamer-native ones instead.",
805           in_plugin->name);
806       continue;
807     }
808 
809     GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
810 
811     /* no codecs for which we're GUARANTEED to have better alternatives */
812     /* MP1 : Use MP3 for decoding */
813     /* MP2 : Use MP3 for decoding */
814     /* Theora: Use libtheora based theoradec */
815 #ifdef OHOS_OPT_COMPAT
816     /* enable to use avdec_vorbis */
817     if (!strcmp (in_plugin->name, "wavpack") ||
818 #else
819     if (!strcmp (in_plugin->name, "vorbis") ||
820         !strcmp (in_plugin->name, "wavpack") ||
821 #endif
822         !strcmp (in_plugin->name, "mp1") ||
823         !strcmp (in_plugin->name, "mp2") ||
824         !strcmp (in_plugin->name, "libfaad") ||
825         !strcmp (in_plugin->name, "mpeg4aac") ||
826         !strcmp (in_plugin->name, "ass") ||
827         !strcmp (in_plugin->name, "srt") ||
828         !strcmp (in_plugin->name, "pgssub") ||
829         !strcmp (in_plugin->name, "dvdsub") ||
830         !strcmp (in_plugin->name, "dvbsub")) {
831       GST_LOG ("Ignoring decoder %s", in_plugin->name);
832       continue;
833     }
834 
835     /* construct the type */
836     type_name = g_strdup_printf ("avdec_%s", in_plugin->name);
837     g_strdelimit (type_name, ".,|-<> ", '_');
838 
839     type = g_type_from_name (type_name);
840 
841     if (!type) {
842       /* create the gtype now */
843       type =
844           g_type_register_static (GST_TYPE_AUDIO_DECODER, type_name, &typeinfo,
845           0);
846       g_type_set_qdata (type, GST_FFDEC_PARAMS_QDATA, (gpointer) in_plugin);
847     }
848 
849     /* (Ronald) MPEG-4 gets a higher priority because it has been well-
850      * tested and by far outperforms divxdec/xviddec - so we prefer it.
851      * msmpeg4v3 same, as it outperforms divxdec for divx3 playback.
852      * VC1/WMV3 are not working and thus unpreferred for now. */
853     switch (in_plugin->id) {
854       case AV_CODEC_ID_RA_144:
855       case AV_CODEC_ID_RA_288:
856       case AV_CODEC_ID_COOK:
857       case AV_CODEC_ID_AAC:
858         rank = GST_RANK_PRIMARY;
859         break;
860         /* SIPR: decoder should have a higher rank than realaudiodec.
861          */
862       case AV_CODEC_ID_SIPR:
863         rank = GST_RANK_SECONDARY;
864         break;
865       default:
866         rank = GST_RANK_MARGINAL;
867         break;
868     }
869     if (!gst_element_register (plugin, type_name, rank, type)) {
870       g_warning ("Failed to register %s", type_name);
871       g_free (type_name);
872       return FALSE;
873     }
874 
875     g_free (type_name);
876   }
877 
878   GST_LOG ("Finished Registering decoders");
879 
880   return TRUE;
881 }
882