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