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 (¶ms);
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, ¶ms);
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