2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
27 #include <libavcodec/avcodec.h>
28 #include <libavutil/stereo3d.h>
29 #include <libavutil/mastering_display_metadata.h>
32 #include "gstavcodecmap.h"
33 #include "gstavutils.h"
34 #include "gstavviddec.h"
36 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
38 #define GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED (1<<15)
40 #define MAX_TS_MASK 0xff
42 #define DEFAULT_LOWRES 0
43 #define DEFAULT_SKIPFRAME 0
44 #define DEFAULT_DIRECT_RENDERING TRUE
45 #define DEFAULT_MAX_THREADS 0
46 #define DEFAULT_OUTPUT_CORRUPT TRUE
47 #define REQUIRED_POOL_MAX_BUFFERS 32
48 #define DEFAULT_STRIDE_ALIGN 31
49 #define DEFAULT_ALLOC_PARAM { 0, DEFAULT_STRIDE_ALIGN, 0, 0, }
50 #define DEFAULT_THREAD_TYPE 0
51 #define DEFAULT_STD_COMPLIANCE GST_AV_CODEC_COMPLIANCE_AUTO
58 PROP_DIRECT_RENDERING,
67 /* A number of function prototypes are given so we can refer to them later. */
68 static void gst_ffmpegviddec_finalize (GObject * object);
70 static gboolean gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
71 GstVideoCodecState * state);
72 static GstFlowReturn gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
73 GstVideoCodecFrame * frame);
74 static gboolean gst_ffmpegviddec_start (GstVideoDecoder * decoder);
75 static gboolean gst_ffmpegviddec_stop (GstVideoDecoder * decoder);
76 static gboolean gst_ffmpegviddec_flush (GstVideoDecoder * decoder);
77 static gboolean gst_ffmpegviddec_decide_allocation (GstVideoDecoder * decoder,
79 static gboolean gst_ffmpegviddec_propose_allocation (GstVideoDecoder * decoder,
82 static void gst_ffmpegviddec_set_property (GObject * object,
83 guint prop_id, const GValue * value, GParamSpec * pspec);
84 static void gst_ffmpegviddec_get_property (GObject * object,
85 guint prop_id, GValue * value, GParamSpec * pspec);
87 static gboolean gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec,
88 AVCodecContext * context, AVFrame * picture, GstBufferFlags flags);
90 /* some sort of bufferpool handling, but different */
91 static int gst_ffmpegviddec_get_buffer2 (AVCodecContext * context,
92 AVFrame * picture, int flags);
93 static gboolean gst_ffmpegviddec_can_direct_render (GstFFMpegVidDec *
96 static GstFlowReturn gst_ffmpegviddec_finish (GstVideoDecoder * decoder);
97 static GstFlowReturn gst_ffmpegviddec_drain (GstVideoDecoder * decoder);
99 static gboolean picture_changed (GstFFMpegVidDec * ffmpegdec,
100 AVFrame * picture, gboolean one_field);
101 static gboolean context_changed (GstFFMpegVidDec * ffmpegdec,
102 AVCodecContext * context);
104 G_DEFINE_ABSTRACT_TYPE (GstFFMpegVidDec, gst_ffmpegviddec,
105 GST_TYPE_VIDEO_DECODER);
107 #define parent_class gst_ffmpegviddec_parent_class
109 #define GST_FFMPEGVIDDEC_TYPE_LOWRES (gst_ffmpegviddec_lowres_get_type())
111 gst_ffmpegviddec_lowres_get_type (void)
113 static GType ffmpegdec_lowres_type = 0;
115 if (!ffmpegdec_lowres_type) {
116 static const GEnumValue ffmpegdec_lowres[] = {
118 {1, "1", "1/2-size"},
119 {2, "2", "1/4-size"},
123 ffmpegdec_lowres_type =
124 g_enum_register_static ("GstLibAVVidDecLowres", ffmpegdec_lowres);
127 return ffmpegdec_lowres_type;
130 #define GST_FFMPEGVIDDEC_TYPE_SKIPFRAME (gst_ffmpegviddec_skipframe_get_type())
132 gst_ffmpegviddec_skipframe_get_type (void)
134 static GType ffmpegdec_skipframe_type = 0;
136 if (!ffmpegdec_skipframe_type) {
137 static const GEnumValue ffmpegdec_skipframe[] = {
138 {0, "0", "Skip nothing"},
139 {1, "1", "Skip B-frames"},
140 {2, "2", "Skip IDCT/Dequantization"},
141 {5, "5", "Skip everything"},
145 ffmpegdec_skipframe_type =
146 g_enum_register_static ("GstLibAVVidDecSkipFrame", ffmpegdec_skipframe);
149 return ffmpegdec_skipframe_type;
152 static const GFlagsValue ffmpegdec_thread_types[] = {
153 {0x0, "Auto", "auto"},
154 {0x1, "Frame", "frame"},
155 {0x2, "Slice", "slice"},
159 #define GST_FFMPEGVIDDEC_TYPE_THREAD_TYPE (gst_ffmpegviddec_thread_type_get_type())
161 gst_ffmpegviddec_thread_type_get_type (void)
163 static GType ffmpegdec_thread_type_type = 0;
165 if (!ffmpegdec_thread_type_type) {
166 ffmpegdec_thread_type_type =
167 g_flags_register_static ("GstLibAVVidDecThreadType",
168 ffmpegdec_thread_types);
170 return ffmpegdec_thread_type_type;
174 dup_caps_with_alternate (GstCaps * caps)
176 GstCaps *with_alternate;
177 GstCapsFeatures *features;
179 with_alternate = gst_caps_copy (caps);
180 features = gst_caps_features_new (GST_CAPS_FEATURE_FORMAT_INTERLACED, NULL);
181 gst_caps_set_features_simple (with_alternate, features);
183 gst_caps_set_simple (with_alternate, "interlace-mode", G_TYPE_STRING,
186 return with_alternate;
190 gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
192 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
194 gobject_class->set_property = gst_ffmpegviddec_set_property;
195 gobject_class->get_property = gst_ffmpegviddec_get_property;
198 * GstFFMpegVidDec:std-compliance:
200 * Specifies standard compliance mode to use
204 g_object_class_install_property (gobject_class, PROP_STD_COMPLIANCE,
205 g_param_spec_enum ("std-compliance", "Standard Compliance",
206 "Standard compliance mode to use", GST_TYPE_AV_CODEC_COMPLIANCE,
207 DEFAULT_STD_COMPLIANCE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
211 gst_ffmpegviddec_subclass_init (GstFFMpegVidDecClass * klass,
212 gconstpointer class_data)
214 GstVideoDecoderClass *viddec_class = GST_VIDEO_DECODER_CLASS (klass);
215 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
216 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
217 GstPadTemplate *sinktempl, *srctempl;
218 GstCaps *sinkcaps, *srccaps;
219 const AVCodec *in_plugin;
220 gchar *longname, *description;
223 in_plugin = class_data;
224 g_assert (in_plugin != NULL);
226 /* construct the element details struct */
227 longname = g_strdup_printf ("libav %s decoder", in_plugin->long_name);
228 description = g_strdup_printf ("libav %s decoder", in_plugin->name);
229 gst_element_class_set_metadata (element_class, longname,
230 "Codec/Decoder/Video", description,
231 "Wim Taymans <wim.taymans@gmail.com>, "
232 "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
233 "Edward Hervey <bilboed@bilboed.com>");
235 g_free (description);
238 sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
240 GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
241 sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
243 srccaps = gst_ffmpeg_codectype_to_video_caps (NULL,
244 in_plugin->id, FALSE, in_plugin);
246 GST_DEBUG ("Couldn't get source caps for decoder '%s'", in_plugin->name);
247 srccaps = gst_caps_from_string ("video/x-raw");
249 gst_caps_append (srccaps, dup_caps_with_alternate (srccaps));
252 sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
253 GST_PAD_ALWAYS, sinkcaps);
254 srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
256 gst_element_class_add_pad_template (element_class, srctempl);
257 gst_element_class_add_pad_template (element_class, sinktempl);
259 gst_caps_unref (sinkcaps);
260 gst_caps_unref (srccaps);
262 klass->in_plugin = in_plugin;
264 gobject_class->finalize = gst_ffmpegviddec_finalize;
266 gobject_class->set_property = gst_ffmpegviddec_set_property;
267 gobject_class->get_property = gst_ffmpegviddec_get_property;
269 g_object_class_install_property (gobject_class, PROP_SKIPFRAME,
270 g_param_spec_enum ("skip-frame", "Skip frames",
271 "Which types of frames to skip during decoding",
272 GST_FFMPEGVIDDEC_TYPE_SKIPFRAME, 0,
273 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
274 g_object_class_install_property (gobject_class, PROP_LOWRES,
275 g_param_spec_enum ("lowres", "Low resolution",
276 "At which resolution to decode images",
277 GST_FFMPEGVIDDEC_TYPE_LOWRES, 0,
278 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
279 g_object_class_install_property (gobject_class, PROP_DIRECT_RENDERING,
280 g_param_spec_boolean ("direct-rendering", "Direct Rendering",
281 "Enable direct rendering", DEFAULT_DIRECT_RENDERING,
282 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
283 #ifndef GST_REMOVE_DEPRECATED
284 g_object_class_install_property (gobject_class, PROP_DEBUG_MV,
285 g_param_spec_boolean ("debug-mv", "Debug motion vectors",
286 "Whether to print motion vectors on top of the image "
287 "(deprecated, non-functional)", FALSE,
288 G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
290 g_object_class_install_property (gobject_class, PROP_OUTPUT_CORRUPT,
291 g_param_spec_boolean ("output-corrupt", "Output corrupt buffers",
292 "Whether libav should output frames even if corrupted",
293 DEFAULT_OUTPUT_CORRUPT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
295 caps = klass->in_plugin->capabilities;
296 if (caps & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)) {
297 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MAX_THREADS,
298 g_param_spec_int ("max-threads", "Maximum decode threads",
299 "Maximum number of worker threads to spawn. (0 = auto)",
300 0, G_MAXINT, DEFAULT_MAX_THREADS,
301 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
302 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_THREAD_TYPE,
303 g_param_spec_flags ("thread-type", "Thread type",
304 "Multithreading methods to use",
305 GST_FFMPEGVIDDEC_TYPE_THREAD_TYPE,
306 DEFAULT_THREAD_TYPE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
309 viddec_class->set_format = gst_ffmpegviddec_set_format;
310 viddec_class->handle_frame = gst_ffmpegviddec_handle_frame;
311 viddec_class->start = gst_ffmpegviddec_start;
312 viddec_class->stop = gst_ffmpegviddec_stop;
313 viddec_class->flush = gst_ffmpegviddec_flush;
314 viddec_class->finish = gst_ffmpegviddec_finish;
315 viddec_class->drain = gst_ffmpegviddec_drain;
316 viddec_class->decide_allocation = gst_ffmpegviddec_decide_allocation;
317 viddec_class->propose_allocation = gst_ffmpegviddec_propose_allocation;
319 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
321 gst_type_mark_as_plugin_api (GST_FFMPEGVIDDEC_TYPE_LOWRES, 0);
322 gst_type_mark_as_plugin_api (GST_FFMPEGVIDDEC_TYPE_SKIPFRAME, 0);
323 gst_type_mark_as_plugin_api (GST_FFMPEGVIDDEC_TYPE_THREAD_TYPE, 0);
324 gst_type_mark_as_plugin_api (GST_TYPE_AV_CODEC_COMPLIANCE, 0);
325 gst_type_mark_as_plugin_api (GST_TYPE_FFMPEGVIDDEC, 0);
329 gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec)
334 gst_ffmpegviddec_subinit (GstFFMpegVidDec * ffmpegdec)
336 GstFFMpegVidDecClass *klass =
337 (GstFFMpegVidDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
339 /* some ffmpeg data */
340 ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
341 ffmpegdec->context->opaque = ffmpegdec;
342 ffmpegdec->picture = av_frame_alloc ();
343 ffmpegdec->opened = FALSE;
344 ffmpegdec->skip_frame = ffmpegdec->lowres = 0;
345 ffmpegdec->direct_rendering = DEFAULT_DIRECT_RENDERING;
346 ffmpegdec->max_threads = DEFAULT_MAX_THREADS;
347 ffmpegdec->output_corrupt = DEFAULT_OUTPUT_CORRUPT;
348 ffmpegdec->thread_type = DEFAULT_THREAD_TYPE;
349 ffmpegdec->std_compliance = DEFAULT_STD_COMPLIANCE;
351 GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (ffmpegdec));
352 gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST
355 gst_video_decoder_set_needs_format (GST_VIDEO_DECODER (ffmpegdec), TRUE);
359 gst_ffmpegviddec_finalize (GObject * object)
361 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (object);
363 av_frame_free (&ffmpegdec->picture);
364 avcodec_free_context (&ffmpegdec->context);
366 G_OBJECT_CLASS (parent_class)->finalize (object);
370 gst_ffmpegviddec_context_set_flags (AVCodecContext * context, guint flags,
373 g_return_if_fail (context != NULL);
376 context->flags |= flags;
378 context->flags &= ~flags;
382 gst_ffmpegviddec_context_set_flags2 (AVCodecContext * context, guint flags,
385 g_return_if_fail (context != NULL);
388 context->flags2 |= flags;
390 context->flags2 &= ~flags;
395 gst_ffmpegviddec_close (GstFFMpegVidDec * ffmpegdec, gboolean reset)
397 GstFFMpegVidDecClass *oclass;
400 oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
402 GST_LOG_OBJECT (ffmpegdec, "closing ffmpeg codec");
404 gst_caps_replace (&ffmpegdec->last_caps, NULL);
406 gst_ffmpeg_avcodec_close (ffmpegdec->context);
407 ffmpegdec->opened = FALSE;
409 for (i = 0; i < G_N_ELEMENTS (ffmpegdec->stride); i++)
410 ffmpegdec->stride[i] = -1;
412 gst_buffer_replace (&ffmpegdec->palette, NULL);
414 av_freep (&ffmpegdec->context->extradata);
416 avcodec_free_context (&ffmpegdec->context);
417 ffmpegdec->context = avcodec_alloc_context3 (oclass->in_plugin);
418 if (ffmpegdec->context == NULL) {
419 GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
422 ffmpegdec->context->opaque = ffmpegdec;
429 gst_ffmpegviddec_open (GstFFMpegVidDec * ffmpegdec)
431 GstFFMpegVidDecClass *oclass;
434 oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
436 if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
439 for (i = 0; i < G_N_ELEMENTS (ffmpegdec->stride); i++)
440 ffmpegdec->stride[i] = -1;
442 ffmpegdec->opened = TRUE;
444 GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
445 oclass->in_plugin->name, oclass->in_plugin->id);
447 gst_ffmpegviddec_context_set_flags (ffmpegdec->context,
448 AV_CODEC_FLAG_OUTPUT_CORRUPT, ffmpegdec->output_corrupt);
455 gst_ffmpegviddec_close (ffmpegdec, TRUE);
456 GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
457 oclass->in_plugin->name);
463 gst_ffmpegviddec_get_palette (GstFFMpegVidDec * ffmpegdec,
464 GstVideoCodecState * state)
466 GstStructure *str = gst_caps_get_structure (state->caps, 0);
467 const GValue *palette_v;
470 /* do we have a palette? */
471 if ((palette_v = gst_structure_get_value (str, "palette_data"))) {
472 palette = gst_value_get_buffer (palette_v);
473 GST_DEBUG ("got palette data %p", palette);
474 if (gst_buffer_get_size (palette) >= AVPALETTE_SIZE) {
475 gst_buffer_replace (&ffmpegdec->palette, palette);
481 gst_ffmpegviddec_needs_reset (GstFFMpegVidDec * ffmpegdec,
482 GstVideoCodecState * state)
484 GstCaps *last_caps, *new_caps;
485 gboolean needs_reset;
487 if (ffmpegdec->last_caps == NULL)
490 last_caps = gst_caps_copy (ffmpegdec->last_caps);
491 new_caps = gst_caps_copy (state->caps);
493 /* Simply ignore framerate for now, this could easily be evolved per CODEC if
494 * future issue are found.*/
495 gst_structure_remove_field (gst_caps_get_structure (last_caps, 0),
497 gst_structure_remove_field (gst_caps_get_structure (new_caps, 0),
500 needs_reset = !gst_caps_is_equal (last_caps, new_caps);
502 gst_caps_unref (last_caps);
503 gst_caps_unref (new_caps);
509 gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
510 GstVideoCodecState * state)
512 GstFFMpegVidDec *ffmpegdec;
513 GstFFMpegVidDecClass *oclass;
514 GstClockTime latency = GST_CLOCK_TIME_NONE;
515 gboolean ret = FALSE;
519 ffmpegdec = GST_FFMPEGVIDDEC (decoder);
520 oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
522 GST_DEBUG_OBJECT (ffmpegdec, "setcaps called");
524 GST_OBJECT_LOCK (ffmpegdec);
526 if (!gst_ffmpegviddec_needs_reset (ffmpegdec, state)) {
527 gst_caps_replace (&ffmpegdec->last_caps, state->caps);
531 /* close old session */
532 if (ffmpegdec->opened) {
533 GST_OBJECT_UNLOCK (ffmpegdec);
534 gst_ffmpegviddec_finish (decoder);
535 GST_OBJECT_LOCK (ffmpegdec);
536 if (!gst_ffmpegviddec_close (ffmpegdec, TRUE)) {
537 GST_OBJECT_UNLOCK (ffmpegdec);
540 ffmpegdec->pic_pix_fmt = 0;
541 ffmpegdec->pic_width = 0;
542 ffmpegdec->pic_height = 0;
543 ffmpegdec->pic_par_n = 0;
544 ffmpegdec->pic_par_d = 0;
545 ffmpegdec->pic_interlaced = 0;
546 ffmpegdec->pic_field_order = 0;
547 ffmpegdec->pic_field_order_changed = FALSE;
548 ffmpegdec->ctx_ticks = 0;
549 ffmpegdec->ctx_time_n = 0;
550 ffmpegdec->ctx_time_d = 0;
551 ffmpegdec->cur_multiview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
552 ffmpegdec->cur_multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
555 gst_caps_replace (&ffmpegdec->last_caps, state->caps);
557 /* set buffer functions */
558 ffmpegdec->context->get_buffer2 = gst_ffmpegviddec_get_buffer2;
559 ffmpegdec->context->draw_horiz_band = NULL;
561 /* reset coded_width/_height to prevent it being reused from last time when
562 * the codec is opened again, causing a mismatch and possible
563 * segfault/corruption. (Common scenario when renegotiating caps) */
564 ffmpegdec->context->coded_width = 0;
565 ffmpegdec->context->coded_height = 0;
567 GST_LOG_OBJECT (ffmpegdec, "size %dx%d", ffmpegdec->context->width,
568 ffmpegdec->context->height);
570 /* FIXME : Create a method that takes GstVideoCodecState instead */
571 /* get size and so */
572 gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
573 oclass->in_plugin->type, state->caps, ffmpegdec->context);
575 GST_LOG_OBJECT (ffmpegdec, "size after %dx%d", ffmpegdec->context->width,
576 ffmpegdec->context->height);
578 gst_ffmpegviddec_get_palette (ffmpegdec, state);
580 if (!ffmpegdec->context->time_base.den || !ffmpegdec->context->time_base.num) {
581 GST_DEBUG_OBJECT (ffmpegdec, "forcing 25/1 framerate");
582 ffmpegdec->context->time_base.num = 1;
583 ffmpegdec->context->time_base.den = 25;
586 /* workaround encoder bugs */
587 ffmpegdec->context->workaround_bugs |= FF_BUG_AUTODETECT;
588 ffmpegdec->context->err_recognition = 1;
591 ffmpegdec->context->lowres = ffmpegdec->lowres;
592 ffmpegdec->context->skip_frame = ffmpegdec->skip_frame;
595 query = gst_query_new_latency ();
597 /* Check if upstream is live. If it isn't we can enable frame based
598 * threading, which is adding latency */
599 if (gst_pad_peer_query (GST_VIDEO_DECODER_SINK_PAD (ffmpegdec), query)) {
600 gst_query_parse_latency (query, &is_live, NULL, NULL);
602 gst_query_unref (query);
604 if (ffmpegdec->thread_type) {
605 GST_DEBUG_OBJECT (ffmpegdec, "Use requested thread type 0x%x",
606 ffmpegdec->thread_type);
607 ffmpegdec->context->thread_type = ffmpegdec->thread_type;
610 ffmpegdec->context->thread_type = FF_THREAD_SLICE;
612 ffmpegdec->context->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
615 if (ffmpegdec->max_threads == 0) {
616 /* When thread type is FF_THREAD_FRAME, extra latency is introduced equal
617 * to one frame per thread. We thus need to calculate the thread count ourselves */
618 if ((!(oclass->in_plugin->capabilities & AV_CODEC_CAP_AUTO_THREADS)) ||
619 (ffmpegdec->context->thread_type & FF_THREAD_FRAME))
620 ffmpegdec->context->thread_count =
621 MIN (gst_ffmpeg_auto_max_threads (), 16);
623 ffmpegdec->context->thread_count = 0;
625 ffmpegdec->context->thread_count = ffmpegdec->max_threads;
627 if (ffmpegdec->std_compliance == GST_AV_CODEC_COMPLIANCE_AUTO) {
628 /* Normal yields lower latency, but fails some compliance check */
629 if (is_live || ffmpegdec->context->thread_type == FF_THREAD_SLICE) {
630 ffmpegdec->context->strict_std_compliance =
631 GST_AV_CODEC_COMPLIANCE_NORMAL;
633 ffmpegdec->context->strict_std_compliance =
634 GST_AV_CODEC_COMPLIANCE_STRICT;
637 ffmpegdec->context->strict_std_compliance = ffmpegdec->std_compliance;
640 if (oclass->in_plugin->id == AV_CODEC_ID_H264) {
641 GstStructure *s = gst_caps_get_structure (state->caps, 0);
642 const char *alignment;
643 gboolean nal_aligned;
645 alignment = gst_structure_get_string (s, "alignment");
646 nal_aligned = !g_strcmp0 (alignment, "nal");
648 if (ffmpegdec->context->thread_type == FF_THREAD_FRAME)
650 ffmpegdec->context->thread_type = FF_THREAD_SLICE;
653 gst_ffmpegviddec_context_set_flags2 (ffmpegdec->context,
654 AV_CODEC_FLAG2_CHUNKS, nal_aligned);
655 gst_video_decoder_set_subframe_mode (decoder, nal_aligned);
658 /* open codec - we don't select an output pix_fmt yet,
659 * simply because we don't know! We only get it
660 * during playback... */
661 if (!gst_ffmpegviddec_open (ffmpegdec))
665 if (ffmpegdec->input_state)
666 gst_video_codec_state_unref (ffmpegdec->input_state);
667 ffmpegdec->input_state = gst_video_codec_state_ref (state);
669 if (ffmpegdec->input_state->info.fps_n) {
670 GstVideoInfo *info = &ffmpegdec->input_state->info;
671 latency = gst_util_uint64_scale_ceil (
672 (ffmpegdec->context->has_b_frames) * GST_SECOND, info->fps_d,
675 if (ffmpegdec->context->thread_type & FF_THREAD_FRAME) {
677 gst_util_uint64_scale_ceil (ffmpegdec->context->thread_count *
678 GST_SECOND, info->fps_d, info->fps_n);
685 GST_OBJECT_UNLOCK (ffmpegdec);
687 if (GST_CLOCK_TIME_IS_VALID (latency))
688 gst_video_decoder_set_latency (decoder, latency, latency);
695 GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
700 GST_ERROR_OBJECT (ffmpegdec,
701 "Can't do NAL aligned H.264 with frame threading.");
708 GstFFMpegVidDec *ffmpegdec;
709 GstVideoCodecFrame *frame;
711 GstVideoFrame vframe;
713 AVBufferRef *avbuffer;
714 } GstFFMpegVidDecVideoFrame;
716 static GstFFMpegVidDecVideoFrame *
717 gst_ffmpegviddec_video_frame_new (GstFFMpegVidDec * ffmpegdec,
718 GstVideoCodecFrame * frame)
720 GstFFMpegVidDecVideoFrame *dframe;
722 dframe = g_slice_new0 (GstFFMpegVidDecVideoFrame);
723 dframe->ffmpegdec = ffmpegdec;
724 dframe->frame = frame;
726 GST_DEBUG_OBJECT (ffmpegdec, "new video frame %p", dframe);
732 gst_ffmpegviddec_video_frame_free (GstFFMpegVidDec * ffmpegdec,
733 GstFFMpegVidDecVideoFrame * frame)
735 GST_DEBUG_OBJECT (ffmpegdec, "free video frame %p", frame);
738 gst_video_frame_unmap (&frame->vframe);
739 GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame->frame,
740 GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED);
741 gst_video_decoder_release_frame (GST_VIDEO_DECODER (ffmpegdec), frame->frame);
742 gst_buffer_replace (&frame->buffer, NULL);
743 if (frame->avbuffer) {
744 av_buffer_unref (&frame->avbuffer);
746 g_slice_free (GstFFMpegVidDecVideoFrame, frame);
750 dummy_free_buffer (void *opaque, uint8_t * data)
752 GstFFMpegVidDecVideoFrame *frame = opaque;
754 gst_ffmpegviddec_video_frame_free (frame->ffmpegdec, frame);
757 /* This function prepares the pool configuration for direct rendering. To use
758 * this method, the codec should support direct rendering and the pool should
759 * support video meta and video alignment */
761 gst_ffmpegvideodec_prepare_dr_pool (GstFFMpegVidDec * ffmpegdec,
762 GstBufferPool * pool, GstVideoInfo * info, GstStructure * config)
764 GstAllocationParams params;
765 GstVideoAlignment align;
766 GstAllocator *allocator = NULL;
768 gint linesize_align[AV_NUM_DATA_POINTERS];
772 width = GST_VIDEO_INFO_WIDTH (info);
773 height = MAX (GST_VIDEO_INFO_HEIGHT (info), ffmpegdec->context->coded_height);
775 /* let ffmpeg find the alignment and padding */
776 avcodec_align_dimensions2 (ffmpegdec->context, &width, &height,
779 align.padding_top = 0;
780 align.padding_left = 0;
781 align.padding_right = width - GST_VIDEO_INFO_WIDTH (info);
782 align.padding_bottom = height - GST_VIDEO_INFO_HEIGHT (info);
784 /* add extra padding to match libav buffer allocation sizes */
785 align.padding_bottom++;
787 gst_buffer_pool_config_get_allocator (config, &allocator, ¶ms);
789 max_align = DEFAULT_STRIDE_ALIGN;
790 max_align |= params.align;
792 for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
793 if (linesize_align[i] > 0)
794 max_align |= linesize_align[i] - 1;
797 for (i = 0; i < GST_VIDEO_MAX_PLANES; i++)
798 align.stride_align[i] = max_align;
800 params.align = max_align;
802 gst_buffer_pool_config_set_allocator (config, allocator, ¶ms);
804 GST_DEBUG_OBJECT (ffmpegdec, "aligned dimension %dx%d -> %dx%d "
805 "padding t:%u l:%u r:%u b:%u, stride_align %d:%d:%d:%d",
806 GST_VIDEO_INFO_WIDTH (info),
807 GST_VIDEO_INFO_HEIGHT (info), width, height, align.padding_top,
808 align.padding_left, align.padding_right, align.padding_bottom,
809 align.stride_align[0], align.stride_align[1], align.stride_align[2],
810 align.stride_align[3]);
812 gst_buffer_pool_config_add_option (config,
813 GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
814 gst_buffer_pool_config_set_video_alignment (config, &align);
818 gst_ffmpegviddec_ensure_internal_pool (GstFFMpegVidDec * ffmpegdec,
819 AVFrame * picture, GstVideoInterlaceMode interlace_mode)
821 GstAllocationParams params = DEFAULT_ALLOC_PARAM;
823 GstVideoFormat format;
825 GstStructure *config;
828 format = gst_ffmpeg_pixfmt_to_videoformat (picture->format);
830 if (ffmpegdec->internal_pool != NULL &&
831 GST_VIDEO_INFO_FORMAT (&ffmpegdec->pool_info) == format &&
832 ffmpegdec->pool_width == picture->width &&
833 ffmpegdec->pool_height == picture->height &&
834 ffmpegdec->pool_format == picture->format)
837 GST_DEBUG_OBJECT (ffmpegdec, "Updating internal pool (%i, %i)",
838 picture->width, picture->height);
840 /* if we are negotiating from get_buffer, then renegotiate later in order
841 * to potentially use a downstream pool */
842 if (gst_ffmpegviddec_can_direct_render (ffmpegdec))
843 gst_pad_mark_reconfigure (GST_VIDEO_DECODER_SRC_PAD (ffmpegdec));
845 format = gst_ffmpeg_pixfmt_to_videoformat (picture->format);
847 if (interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) {
848 gst_video_info_set_interlaced_format (&info, format, interlace_mode,
849 picture->width, 2 * picture->height);
851 gst_video_info_set_format (&info, format, picture->width, picture->height);
854 /* If we have not yet been negotiated, a NONE format here would
855 * result in invalid initial dimension alignments, and potential
856 * out of bounds writes.
858 ffmpegdec->context->pix_fmt = picture->format;
860 for (i = 0; i < G_N_ELEMENTS (ffmpegdec->stride); i++)
861 ffmpegdec->stride[i] = -1;
863 if (ffmpegdec->internal_pool)
864 gst_object_unref (ffmpegdec->internal_pool);
866 ffmpegdec->internal_pool = gst_video_buffer_pool_new ();
867 config = gst_buffer_pool_get_config (ffmpegdec->internal_pool);
869 caps = gst_video_info_to_caps (&info);
870 gst_buffer_pool_config_set_params (config, caps, info.size, 2, 0);
871 gst_buffer_pool_config_set_allocator (config, NULL, ¶ms);
872 gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
874 gst_ffmpegvideodec_prepare_dr_pool (ffmpegdec,
875 ffmpegdec->internal_pool, &info, config);
876 /* generic video pool never fails */
877 gst_buffer_pool_set_config (ffmpegdec->internal_pool, config);
878 gst_caps_unref (caps);
880 gst_buffer_pool_set_active (ffmpegdec->internal_pool, TRUE);
882 /* Remember pool size so we can detect changes */
883 ffmpegdec->pool_width = picture->width;
884 ffmpegdec->pool_height =
885 MAX (picture->height, ffmpegdec->context->coded_height);
886 ffmpegdec->pool_format = picture->format;
887 ffmpegdec->pool_info = info;
891 gst_ffmpegviddec_can_direct_render (GstFFMpegVidDec * ffmpegdec)
893 GstFFMpegVidDecClass *oclass;
895 if (!ffmpegdec->direct_rendering)
898 oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
899 return ((oclass->in_plugin->capabilities & AV_CODEC_CAP_DR1) ==
903 /* called when ffmpeg wants us to allocate a buffer to write the decoded frame
904 * into. We try to give it memory from our pool */
906 gst_ffmpegviddec_get_buffer2 (AVCodecContext * context, AVFrame * picture,
909 GstVideoCodecFrame *frame;
910 GstFFMpegVidDecVideoFrame *dframe;
911 GstFFMpegVidDec *ffmpegdec;
914 int create_buffer_flags = 0;
916 ffmpegdec = GST_FFMPEGVIDDEC (context->opaque);
918 GST_DEBUG_OBJECT (ffmpegdec, "getting buffer picture %p", picture);
920 /* apply the last info we have seen to this picture, when we get the
921 * picture back from ffmpeg we can use this to correctly timestamp the output
923 GST_DEBUG_OBJECT (ffmpegdec, "opaque value SN %d",
924 (gint32) picture->reordered_opaque);
927 gst_video_decoder_get_frame (GST_VIDEO_DECODER (ffmpegdec),
928 picture->reordered_opaque);
929 if (G_UNLIKELY (frame == NULL))
932 /* now it has a buffer allocated, so it is real and will also
934 GST_VIDEO_CODEC_FRAME_FLAG_SET (frame,
935 GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED);
936 GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame,
937 GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
939 if (G_UNLIKELY (frame->output_buffer != NULL))
940 goto duplicate_frame;
942 /* GstFFMpegVidDecVideoFrame receives the frame ref */
943 if (picture->opaque) {
944 dframe = picture->opaque;
945 dframe->frame = frame;
947 picture->opaque = dframe =
948 gst_ffmpegviddec_video_frame_new (ffmpegdec, frame);
951 GST_DEBUG_OBJECT (ffmpegdec, "storing opaque %p", dframe);
953 if (!gst_ffmpegviddec_can_direct_render (ffmpegdec))
956 gst_ffmpegviddec_ensure_internal_pool (ffmpegdec, picture,
957 GST_BUFFER_FLAG_IS_SET (frame->input_buffer,
958 GST_VIDEO_BUFFER_FLAG_ONEFIELD) ? GST_VIDEO_INTERLACE_MODE_ALTERNATE :
959 GST_VIDEO_INTERLACE_MODE_PROGRESSIVE);
961 ret = gst_buffer_pool_acquire_buffer (ffmpegdec->internal_pool,
962 &frame->output_buffer, NULL);
963 if (ret != GST_FLOW_OK)
966 /* piggy-backed alloc'ed on the frame,
967 * and there was much rejoicing and we are grateful.
968 * Now take away buffer from frame, we will give it back later when decoded.
969 * This allows multiple request for a buffer per frame; unusual but possible. */
970 gst_buffer_replace (&dframe->buffer, frame->output_buffer);
971 gst_buffer_replace (&frame->output_buffer, NULL);
974 if (!gst_video_frame_map (&dframe->vframe, &ffmpegdec->pool_info,
975 dframe->buffer, GST_MAP_READWRITE))
977 dframe->mapped = TRUE;
979 for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
980 if (c < GST_VIDEO_INFO_N_PLANES (&ffmpegdec->pool_info)) {
981 picture->data[c] = GST_VIDEO_FRAME_PLANE_DATA (&dframe->vframe, c);
982 picture->linesize[c] = GST_VIDEO_FRAME_PLANE_STRIDE (&dframe->vframe, c);
984 if (ffmpegdec->stride[c] == -1)
985 ffmpegdec->stride[c] = picture->linesize[c];
987 /* libav does not allow stride changes, decide allocation should check
988 * before replacing the internal pool with a downstream pool.
989 * https://bugzilla.gnome.org/show_bug.cgi?id=704769
990 * https://bugzilla.libav.org/show_bug.cgi?id=556
992 g_assert (picture->linesize[c] == ffmpegdec->stride[c]);
994 picture->data[c] = NULL;
995 picture->linesize[c] = 0;
997 GST_LOG_OBJECT (ffmpegdec, "linesize %d, data %p", picture->linesize[c],
1001 if ((flags & AV_GET_BUFFER_FLAG_REF) == AV_GET_BUFFER_FLAG_REF) {
1002 /* decoder might reuse this AVFrame and it would result to no more
1003 * get_buffer() call if the AVFrame's AVBuffer is writable
1004 * (meaning that the refcount of AVBuffer == 1).
1005 * To enforce get_buffer() for the every output frame, set read-only flag here
1007 create_buffer_flags = AV_BUFFER_FLAG_READONLY;
1009 picture->buf[0] = av_buffer_create (NULL,
1010 0, dummy_free_buffer, dframe, create_buffer_flags);
1012 GST_LOG_OBJECT (ffmpegdec, "returned frame %p", dframe->buffer);
1019 int ret = avcodec_default_get_buffer2 (context, picture, flags);
1021 GST_LOG_OBJECT (ffmpegdec, "direct rendering disabled, fallback alloc");
1023 for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
1024 ffmpegdec->stride[c] = picture->linesize[c];
1026 /* Wrap our buffer around the default one to be able to have a callback
1027 * when our data can be freed. Just putting our data into the first free
1028 * buffer might not work if there are too many allocated already
1030 if (picture->buf[0]) {
1031 dframe->avbuffer = picture->buf[0];
1033 av_buffer_create (picture->buf[0]->data, picture->buf[0]->size,
1034 dummy_free_buffer, dframe, 0);
1037 av_buffer_create (NULL, 0, dummy_free_buffer, dframe, 0);
1044 GST_ELEMENT_ERROR (ffmpegdec, RESOURCE, FAILED,
1045 ("Unable to allocate memory"),
1046 ("The downstream pool failed to allocated buffer."));
1051 GST_ELEMENT_ERROR (ffmpegdec, RESOURCE, OPEN_READ_WRITE,
1052 ("Cannot access memory for read and write operation."),
1053 ("The video memory allocated from downstream pool could not mapped for"
1054 "read and write."));
1059 GST_WARNING_OBJECT (ffmpegdec, "already alloc'ed output buffer for frame");
1060 gst_video_codec_frame_unref (frame);
1065 GST_WARNING_OBJECT (ffmpegdec, "Couldn't get codec frame !");
1071 picture_changed (GstFFMpegVidDec * ffmpegdec, AVFrame * picture,
1074 gint pic_field_order = 0;
1077 pic_field_order = ffmpegdec->pic_field_order;
1078 } else if (picture->interlaced_frame) {
1079 if (picture->repeat_pict)
1080 pic_field_order |= GST_VIDEO_BUFFER_FLAG_RFF;
1081 if (picture->top_field_first)
1082 pic_field_order |= GST_VIDEO_BUFFER_FLAG_TFF;
1085 return !(ffmpegdec->pic_width == picture->width
1086 && ffmpegdec->pic_height == picture->height
1087 && ffmpegdec->pic_pix_fmt == picture->format
1088 && ffmpegdec->pic_par_n == picture->sample_aspect_ratio.num
1089 && ffmpegdec->pic_par_d == picture->sample_aspect_ratio.den
1090 && ffmpegdec->pic_interlaced == picture->interlaced_frame
1091 && ffmpegdec->pic_field_order == pic_field_order
1092 && ffmpegdec->cur_multiview_mode == ffmpegdec->picture_multiview_mode
1093 && ffmpegdec->cur_multiview_flags == ffmpegdec->picture_multiview_flags);
1097 context_changed (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context)
1099 return !(ffmpegdec->ctx_ticks == context->ticks_per_frame
1100 && ffmpegdec->ctx_time_n == context->time_base.num
1101 && ffmpegdec->ctx_time_d == context->time_base.den);
1105 update_video_context (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context,
1106 AVFrame * picture, gboolean one_field)
1108 gint pic_field_order = 0;
1110 if (picture->interlaced_frame) {
1111 if (picture->repeat_pict)
1112 pic_field_order |= GST_VIDEO_BUFFER_FLAG_RFF;
1113 if (picture->top_field_first)
1114 pic_field_order |= GST_VIDEO_BUFFER_FLAG_TFF;
1117 if (!picture_changed (ffmpegdec, picture, one_field)
1118 && !context_changed (ffmpegdec, context))
1121 GST_DEBUG_OBJECT (ffmpegdec,
1122 "Renegotiating video from %dx%d@ %d:%d PAR %d/%d fps pixfmt %d to %dx%d@ %d:%d PAR %d/%d fps pixfmt %d",
1123 ffmpegdec->pic_width, ffmpegdec->pic_height,
1124 ffmpegdec->pic_par_n, ffmpegdec->pic_par_d,
1125 ffmpegdec->ctx_time_n, ffmpegdec->ctx_time_d,
1126 ffmpegdec->pic_pix_fmt,
1127 picture->width, picture->height,
1128 picture->sample_aspect_ratio.num,
1129 picture->sample_aspect_ratio.den,
1130 context->time_base.num, context->time_base.den, picture->format);
1132 ffmpegdec->pic_pix_fmt = picture->format;
1133 ffmpegdec->pic_width = picture->width;
1134 ffmpegdec->pic_height = picture->height;
1135 ffmpegdec->pic_par_n = picture->sample_aspect_ratio.num;
1136 ffmpegdec->pic_par_d = picture->sample_aspect_ratio.den;
1137 ffmpegdec->cur_multiview_mode = ffmpegdec->picture_multiview_mode;
1138 ffmpegdec->cur_multiview_flags = ffmpegdec->picture_multiview_flags;
1140 /* Remember if we have interlaced content and the field order changed
1141 * at least once. If that happens, we must be interlace-mode=mixed
1143 if (ffmpegdec->pic_field_order_changed ||
1144 (ffmpegdec->pic_field_order != pic_field_order &&
1145 ffmpegdec->pic_interlaced))
1146 ffmpegdec->pic_field_order_changed = TRUE;
1148 ffmpegdec->pic_field_order = pic_field_order;
1149 ffmpegdec->pic_interlaced = picture->interlaced_frame;
1151 if (!ffmpegdec->pic_interlaced)
1152 ffmpegdec->pic_field_order_changed = FALSE;
1154 ffmpegdec->ctx_ticks = context->ticks_per_frame;
1155 ffmpegdec->ctx_time_n = context->time_base.num;
1156 ffmpegdec->ctx_time_d = context->time_base.den;
1162 gst_ffmpegviddec_update_par (GstFFMpegVidDec * ffmpegdec,
1163 GstVideoInfo * in_info, GstVideoInfo * out_info)
1165 gboolean demuxer_par_set = FALSE;
1166 gboolean decoder_par_set = FALSE;
1167 gint demuxer_num = 1, demuxer_denom = 1;
1168 gint decoder_num = 1, decoder_denom = 1;
1169 GstVideoCodecFrame *out_frame;
1170 GstFFMpegVidDecVideoFrame *out_dframe;
1172 if (in_info->par_n && in_info->par_d) {
1173 demuxer_num = in_info->par_n;
1174 demuxer_denom = in_info->par_d;
1175 demuxer_par_set = TRUE;
1176 GST_DEBUG_OBJECT (ffmpegdec, "Demuxer PAR: %d:%d", demuxer_num,
1180 if (ffmpegdec->pic_par_n && ffmpegdec->pic_par_d) {
1181 decoder_num = ffmpegdec->pic_par_n;
1182 decoder_denom = ffmpegdec->pic_par_d;
1183 decoder_par_set = TRUE;
1184 GST_DEBUG_OBJECT (ffmpegdec, "Decoder PAR: %d:%d", decoder_num,
1188 if (!demuxer_par_set && !decoder_par_set)
1191 if (demuxer_par_set && !decoder_par_set)
1192 goto use_demuxer_par;
1194 if (decoder_par_set && !demuxer_par_set)
1195 goto use_decoder_par;
1197 /* Special case for some encoders which provide an 1:2 pixel aspect ratio
1198 * for HEVC interlaced content, possibly to work around decoders that don't
1199 * support field-based interlacing. Add some defensive checks to check for
1200 * a "common" aspect ratio. */
1201 out_dframe = ffmpegdec->picture->opaque;
1202 out_frame = out_dframe->frame;
1204 if (demuxer_num == 1 && demuxer_denom == 1 &&
1205 decoder_num == 1 && decoder_denom == 2 &&
1206 GST_BUFFER_FLAG_IS_SET (out_frame->input_buffer,
1207 GST_VIDEO_BUFFER_FLAG_ONEFIELD) &&
1208 gst_video_is_common_aspect_ratio (ffmpegdec->pic_width,
1209 ffmpegdec->pic_height, 1, 2) &&
1210 !gst_video_is_common_aspect_ratio (ffmpegdec->pic_width,
1211 ffmpegdec->pic_height, 1, 1)) {
1212 GST_WARNING_OBJECT (ffmpegdec,
1213 "PAR 1/2 makes the aspect ratio of "
1214 "a %d x %d frame uncommon. Switching to 1/1",
1215 ffmpegdec->pic_width, ffmpegdec->pic_height);
1216 goto use_demuxer_par;
1219 /* Both the demuxer and the decoder provide a PAR. If one of
1220 * the two PARs is 1:1 and the other one is not, use the one
1221 * that is not 1:1. */
1222 if (demuxer_num == demuxer_denom && decoder_num != decoder_denom) {
1223 goto use_decoder_par;
1226 if (decoder_num == decoder_denom && demuxer_num != demuxer_denom) {
1227 goto use_demuxer_par;
1230 /* Both PARs are non-1:1, so use the PAR provided by the demuxer */
1231 goto use_demuxer_par;
1235 GST_DEBUG_OBJECT (ffmpegdec,
1236 "Setting decoder provided pixel-aspect-ratio of %u:%u", decoder_num,
1238 out_info->par_n = decoder_num;
1239 out_info->par_d = decoder_denom;
1244 GST_DEBUG_OBJECT (ffmpegdec,
1245 "Setting demuxer provided pixel-aspect-ratio of %u:%u", demuxer_num,
1247 out_info->par_n = demuxer_num;
1248 out_info->par_d = demuxer_denom;
1253 GST_DEBUG_OBJECT (ffmpegdec,
1254 "Neither demuxer nor codec provide a pixel-aspect-ratio");
1255 out_info->par_n = 1;
1256 out_info->par_d = 1;
1261 static GstVideoMultiviewMode
1262 stereo_av_to_gst (enum AVStereo3DType type)
1265 case AV_STEREO3D_SIDEBYSIDE:
1266 return GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
1267 case AV_STEREO3D_TOPBOTTOM:
1268 return GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
1269 case AV_STEREO3D_FRAMESEQUENCE:
1270 return GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
1271 case AV_STEREO3D_CHECKERBOARD:
1272 return GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
1273 case AV_STEREO3D_SIDEBYSIDE_QUINCUNX:
1274 return GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX;
1275 case AV_STEREO3D_LINES:
1276 return GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED;
1277 case AV_STEREO3D_COLUMNS:
1278 return GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED;
1283 return GST_VIDEO_MULTIVIEW_MODE_NONE;
1287 mastering_display_metadata_av_to_gst (AVMasteringDisplayMetadata * av,
1288 GstVideoMasteringDisplayInfo * gst)
1290 const guint64 chroma_scale = 50000;
1291 const guint64 luma_scale = 10000;
1294 /* Use only complete mastering meta */
1295 if (!av->has_primaries || !av->has_luminance)
1298 for (i = 0; i < G_N_ELEMENTS (gst->display_primaries); i++) {
1299 gst->display_primaries[i].x = (guint16) gst_util_uint64_scale (chroma_scale,
1300 av->display_primaries[i][0].num, av->display_primaries[i][0].den);
1301 gst->display_primaries[i].y = (guint16) gst_util_uint64_scale (chroma_scale,
1302 av->display_primaries[i][1].num, av->display_primaries[i][1].den);
1305 gst->white_point.x = (guint16) gst_util_uint64_scale (chroma_scale,
1306 av->white_point[0].num, av->white_point[0].den);
1307 gst->white_point.y = (guint16) gst_util_uint64_scale (chroma_scale,
1308 av->white_point[1].num, av->white_point[1].den);
1311 gst->max_display_mastering_luminance =
1312 (guint32) gst_util_uint64_scale (luma_scale,
1313 av->max_luminance.num, av->max_luminance.den);
1314 gst->min_display_mastering_luminance =
1315 (guint32) gst_util_uint64_scale (luma_scale,
1316 av->min_luminance.num, av->min_luminance.den);
1322 content_light_metadata_av_to_gst (AVContentLightMetadata * av,
1323 GstVideoContentLightLevel * gst)
1325 gst->max_content_light_level = av->MaxCLL;
1326 gst->max_frame_average_light_level = av->MaxFALL;
1332 gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec,
1333 AVCodecContext * context, AVFrame * picture, GstBufferFlags flags)
1336 GstVideoInfo *in_info, *out_info;
1337 GstVideoCodecState *output_state;
1339 GstClockTime latency;
1341 GstVideoInterlaceMode interlace_mode;
1343 gboolean one_field = ! !(flags & GST_VIDEO_BUFFER_FLAG_ONEFIELD);
1345 if (!update_video_context (ffmpegdec, context, picture, one_field))
1348 caps_height = ffmpegdec->pic_height;
1350 fmt = gst_ffmpeg_pixfmt_to_videoformat (ffmpegdec->pic_pix_fmt);
1351 if (G_UNLIKELY (fmt == GST_VIDEO_FORMAT_UNKNOWN))
1352 goto unknown_format;
1354 /* set the interlaced flag */
1355 in_s = gst_caps_get_structure (ffmpegdec->input_state->caps, 0);
1356 if (flags & GST_VIDEO_BUFFER_FLAG_ONEFIELD) {
1357 /* TODO: we don't get that information from ffmpeg, so copy it from
1359 interlace_mode = GST_VIDEO_INTERLACE_MODE_ALTERNATE;
1360 caps_height = 2 * caps_height;
1361 } else if (!gst_structure_has_field (in_s, "interlace-mode")) {
1362 if (ffmpegdec->pic_interlaced) {
1363 if (ffmpegdec->pic_field_order_changed ||
1364 (ffmpegdec->pic_field_order & GST_VIDEO_BUFFER_FLAG_RFF)) {
1365 interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
1367 interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
1370 interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
1375 gst_video_info_from_caps (&info, ffmpegdec->input_state->caps);
1376 interlace_mode = info.interlace_mode;
1379 if (interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE)
1381 gst_video_decoder_set_interlaced_output_state (GST_VIDEO_DECODER
1382 (ffmpegdec), fmt, interlace_mode, ffmpegdec->pic_width, caps_height,
1383 ffmpegdec->input_state);
1386 gst_video_decoder_set_output_state (GST_VIDEO_DECODER
1387 (ffmpegdec), fmt, ffmpegdec->pic_width, caps_height,
1388 ffmpegdec->input_state);
1389 if (ffmpegdec->output_state)
1390 gst_video_codec_state_unref (ffmpegdec->output_state);
1391 ffmpegdec->output_state = output_state;
1393 in_info = &ffmpegdec->input_state->info;
1394 out_info = &ffmpegdec->output_state->info;
1396 out_info->interlace_mode = interlace_mode;
1397 if (!gst_structure_has_field (in_s, "interlace-mode")
1398 && interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED) {
1399 if ((ffmpegdec->pic_field_order & GST_VIDEO_BUFFER_FLAG_TFF))
1400 GST_VIDEO_INFO_FIELD_ORDER (out_info) =
1401 GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST;
1403 GST_VIDEO_INFO_FIELD_ORDER (out_info) =
1404 GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST;
1407 if (!gst_structure_has_field (in_s, "chroma-site")) {
1408 switch (context->chroma_sample_location) {
1409 case AVCHROMA_LOC_LEFT:
1410 out_info->chroma_site = GST_VIDEO_CHROMA_SITE_MPEG2;
1412 case AVCHROMA_LOC_CENTER:
1413 out_info->chroma_site = GST_VIDEO_CHROMA_SITE_JPEG;
1415 case AVCHROMA_LOC_TOPLEFT:
1416 out_info->chroma_site = GST_VIDEO_CHROMA_SITE_DV;
1418 case AVCHROMA_LOC_TOP:
1419 out_info->chroma_site = GST_VIDEO_CHROMA_SITE_V_COSITED;
1426 if (!gst_structure_has_field (in_s, "colorimetry")
1427 || in_info->colorimetry.primaries == GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
1428 out_info->colorimetry.primaries =
1429 gst_video_color_primaries_from_iso (context->color_primaries);
1432 if (!gst_structure_has_field (in_s, "colorimetry")
1433 || in_info->colorimetry.transfer == GST_VIDEO_TRANSFER_UNKNOWN) {
1434 out_info->colorimetry.transfer =
1435 gst_video_transfer_function_from_iso (context->color_trc);
1438 if (!gst_structure_has_field (in_s, "colorimetry")
1439 || in_info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_UNKNOWN) {
1440 out_info->colorimetry.matrix =
1441 gst_video_color_matrix_from_iso (context->colorspace);
1444 if (!gst_structure_has_field (in_s, "colorimetry")
1445 || in_info->colorimetry.range == GST_VIDEO_COLOR_RANGE_UNKNOWN) {
1446 if (context->color_range == AVCOL_RANGE_JPEG) {
1447 out_info->colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
1448 } else if (context->color_range == AVCOL_RANGE_MPEG) {
1449 out_info->colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
1451 out_info->colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
1455 /* try to find a good framerate */
1456 if ((in_info->fps_d && in_info->fps_n) ||
1457 GST_VIDEO_INFO_FLAG_IS_SET (in_info, GST_VIDEO_FLAG_VARIABLE_FPS)) {
1458 /* take framerate from input when it was specified (#313970) */
1459 fps_n = in_info->fps_n;
1460 fps_d = in_info->fps_d;
1462 fps_n = ffmpegdec->ctx_time_d / ffmpegdec->ctx_ticks;
1463 fps_d = ffmpegdec->ctx_time_n;
1466 GST_LOG_OBJECT (ffmpegdec, "invalid framerate: %d/0, -> %d/1", fps_n,
1470 if (gst_util_fraction_compare (fps_n, fps_d, 1000, 1) > 0) {
1471 GST_LOG_OBJECT (ffmpegdec, "excessive framerate: %d/%d, -> 0/1", fps_n,
1478 GST_LOG_OBJECT (ffmpegdec, "setting framerate: %d/%d", fps_n, fps_d);
1479 out_info->fps_n = fps_n;
1480 out_info->fps_d = fps_d;
1482 /* calculate and update par now */
1483 gst_ffmpegviddec_update_par (ffmpegdec, in_info, out_info);
1485 GST_VIDEO_INFO_MULTIVIEW_MODE (out_info) = ffmpegdec->cur_multiview_mode;
1486 GST_VIDEO_INFO_MULTIVIEW_FLAGS (out_info) = ffmpegdec->cur_multiview_flags;
1488 /* To passing HDR information to caps directly */
1489 if (output_state->caps == NULL) {
1490 output_state->caps = gst_video_info_to_caps (out_info);
1492 output_state->caps = gst_caps_make_writable (output_state->caps);
1495 if (flags & GST_VIDEO_BUFFER_FLAG_ONEFIELD) {
1496 /* TODO: we don't get that information from ffmpeg, so copy it from
1498 gst_caps_features_add (gst_caps_get_features (ffmpegdec->output_state->caps,
1499 0), GST_CAPS_FEATURE_FORMAT_INTERLACED);
1502 if (!gst_structure_has_field (in_s, "mastering-display-info")) {
1503 AVFrameSideData *sd = av_frame_get_side_data (picture,
1504 AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
1505 GstVideoMasteringDisplayInfo minfo;
1508 && mastering_display_metadata_av_to_gst ((AVMasteringDisplayMetadata *)
1509 sd->data, &minfo)) {
1510 GST_LOG_OBJECT (ffmpegdec, "update mastering display info: "
1515 "max_luminance(%u) "
1516 "min_luminance(%u) ",
1517 minfo.display_primaries[0].x, minfo.display_primaries[0].y,
1518 minfo.display_primaries[1].x, minfo.display_primaries[1].y,
1519 minfo.display_primaries[2].x, minfo.display_primaries[2].y,
1520 minfo.white_point.x, minfo.white_point.y,
1521 minfo.max_display_mastering_luminance,
1522 minfo.min_display_mastering_luminance);
1524 if (!gst_video_mastering_display_info_add_to_caps (&minfo,
1525 output_state->caps)) {
1526 GST_WARNING_OBJECT (ffmpegdec,
1527 "Couldn't set mastering display info to caps");
1532 if (!gst_structure_has_field (in_s, "content-light-level")) {
1533 AVFrameSideData *sd = av_frame_get_side_data (picture,
1534 AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
1535 GstVideoContentLightLevel cll;
1537 if (sd && content_light_metadata_av_to_gst ((AVContentLightMetadata *)
1539 GST_LOG_OBJECT (ffmpegdec, "update content light level: "
1540 "maxCLL:(%u), maxFALL:(%u)", cll.max_content_light_level,
1541 cll.max_frame_average_light_level);
1543 if (!gst_video_content_light_level_add_to_caps (&cll, output_state->caps)) {
1544 GST_WARNING_OBJECT (ffmpegdec,
1545 "Couldn't set content light level to caps");
1550 if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (ffmpegdec)))
1551 goto negotiate_failed;
1553 /* The decoder is configured, we now know the true latency */
1556 gst_util_uint64_scale_ceil (ffmpegdec->context->has_b_frames *
1557 GST_SECOND, fps_d, fps_n);
1558 if (ffmpegdec->context->thread_type & FF_THREAD_FRAME) {
1560 gst_util_uint64_scale_ceil (ffmpegdec->context->thread_count *
1561 GST_SECOND, fps_d, fps_n);
1563 gst_video_decoder_set_latency (GST_VIDEO_DECODER (ffmpegdec), latency,
1572 GST_ERROR_OBJECT (ffmpegdec,
1573 "decoder requires a video format unsupported by GStreamer");
1578 /* Reset so we try again next time even if force==FALSE */
1579 ffmpegdec->pic_pix_fmt = 0;
1580 ffmpegdec->pic_width = 0;
1581 ffmpegdec->pic_height = 0;
1582 ffmpegdec->pic_par_n = 0;
1583 ffmpegdec->pic_par_d = 0;
1584 ffmpegdec->pic_interlaced = 0;
1585 ffmpegdec->pic_field_order = 0;
1586 ffmpegdec->pic_field_order_changed = FALSE;
1587 ffmpegdec->ctx_ticks = 0;
1588 ffmpegdec->ctx_time_n = 0;
1589 ffmpegdec->ctx_time_d = 0;
1591 GST_ERROR_OBJECT (ffmpegdec, "negotiation failed");
1596 /* perform qos calculations before decoding the next frame.
1598 * Sets the skip_frame flag and if things are really bad, skips to the next
1603 gst_ffmpegviddec_do_qos (GstFFMpegVidDec * ffmpegdec,
1604 GstVideoCodecFrame * frame, gboolean * mode_switch)
1606 GstClockTimeDiff diff;
1607 GstSegmentFlags skip_flags =
1608 GST_VIDEO_DECODER_INPUT_SEGMENT (ffmpegdec).flags;
1610 *mode_switch = FALSE;
1615 if (skip_flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
1616 ffmpegdec->context->skip_frame = AVDISCARD_NONKEY;
1617 *mode_switch = TRUE;
1618 } else if (skip_flags & GST_SEGMENT_FLAG_TRICKMODE) {
1619 ffmpegdec->context->skip_frame = AVDISCARD_NONREF;
1620 *mode_switch = TRUE;
1623 if (*mode_switch == TRUE) {
1624 /* We've already switched mode, we can return straight away
1625 * without any further calculation */
1630 gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (ffmpegdec),
1633 /* if we don't have timing info, then we don't do QoS */
1634 if (G_UNLIKELY (diff == G_MAXINT64)) {
1635 /* Ensure the skipping strategy is the default one */
1636 ffmpegdec->context->skip_frame = ffmpegdec->skip_frame;
1640 GST_DEBUG_OBJECT (ffmpegdec, "decoding time %" G_GINT64_FORMAT, diff);
1642 if (diff > 0 && ffmpegdec->context->skip_frame != AVDISCARD_DEFAULT) {
1643 ffmpegdec->context->skip_frame = AVDISCARD_DEFAULT;
1644 *mode_switch = TRUE;
1645 GST_DEBUG_OBJECT (ffmpegdec, "QOS: normal mode");
1648 else if (diff <= 0 && ffmpegdec->context->skip_frame != AVDISCARD_NONREF) {
1649 ffmpegdec->context->skip_frame = AVDISCARD_NONREF;
1650 *mode_switch = TRUE;
1651 GST_DEBUG_OBJECT (ffmpegdec,
1652 "QOS: hurry up, diff %" G_GINT64_FORMAT " >= 0", diff);
1656 /* get an outbuf buffer with the current picture */
1657 static GstFlowReturn
1658 get_output_buffer (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame)
1660 GstFlowReturn ret = GST_FLOW_OK;
1661 AVFrame pic, *outpic;
1662 GstVideoFrame vframe;
1666 GST_LOG_OBJECT (ffmpegdec, "get output buffer");
1668 if (!ffmpegdec->output_state)
1669 goto not_negotiated;
1672 gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (ffmpegdec),
1674 if (G_UNLIKELY (ret != GST_FLOW_OK))
1677 /* original ffmpeg code does not handle odd sizes correctly.
1678 * This patched up version does */
1679 /* Fill avpicture */
1680 info = &ffmpegdec->output_state->info;
1681 if (!gst_video_frame_map (&vframe, info, frame->output_buffer,
1682 GST_MAP_READ | GST_MAP_WRITE))
1685 memset (&pic, 0, sizeof (pic));
1686 pic.format = ffmpegdec->pic_pix_fmt;
1687 pic.width = GST_VIDEO_FRAME_WIDTH (&vframe);
1688 pic.height = GST_VIDEO_FRAME_HEIGHT (&vframe);
1689 for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
1690 if (c < GST_VIDEO_INFO_N_PLANES (info)) {
1691 pic.data[c] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, c);
1692 pic.linesize[c] = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, c);
1693 GST_LOG_OBJECT (ffmpegdec, "[%i] linesize %d, data %p", c,
1694 pic.linesize[c], pic.data[c]);
1697 pic.linesize[c] = 0;
1701 outpic = ffmpegdec->picture;
1703 if (av_frame_copy (&pic, outpic) != 0) {
1704 GST_ERROR_OBJECT (ffmpegdec, "Failed to copy output frame");
1705 ret = GST_FLOW_ERROR;
1708 gst_video_frame_unmap (&vframe);
1710 ffmpegdec->picture->reordered_opaque = -1;
1717 GST_ELEMENT_ERROR (ffmpegdec, RESOURCE, FAILED,
1718 ("Unable to allocate memory"),
1719 ("The downstream pool failed to allocated buffer."));
1724 GST_ELEMENT_ERROR (ffmpegdec, RESOURCE, OPEN_READ_WRITE,
1725 ("Cannot access memory for read and write operation."),
1726 ("The video memory allocated from downstream pool could not mapped for"
1727 "read and write."));
1732 GST_DEBUG_OBJECT (ffmpegdec, "not negotiated");
1733 return GST_FLOW_NOT_NEGOTIATED;
1738 gst_avpacket_init (AVPacket * packet, guint8 * data, guint size)
1740 memset (packet, 0, sizeof (AVPacket));
1741 packet->data = data;
1742 packet->size = size;
1746 * Returns: whether a frame was decoded
1749 gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
1750 GstVideoCodecFrame * frame, GstFlowReturn * ret)
1753 gboolean got_frame = FALSE;
1754 gboolean mode_switch;
1755 GstVideoCodecFrame *out_frame;
1756 GstFFMpegVidDecVideoFrame *out_dframe;
1757 GstBufferPool *pool;
1761 /* in case we skip frames */
1762 ffmpegdec->picture->pict_type = -1;
1764 /* run QoS code, we don't stop decoding the frame when we are late because
1765 * else we might skip a reference frame */
1766 gst_ffmpegviddec_do_qos (ffmpegdec, frame, &mode_switch);
1768 res = avcodec_receive_frame (ffmpegdec->context, ffmpegdec->picture);
1770 /* No frames available at this time */
1771 if (res == AVERROR (EAGAIN))
1773 else if (res == AVERROR_EOF) {
1774 *ret = GST_FLOW_EOS;
1775 GST_DEBUG_OBJECT (ffmpegdec, "Context was entirely flushed");
1777 } else if (res < 0) {
1779 GST_WARNING_OBJECT (ffmpegdec, "Legitimate decoding error");
1785 /* get the output picture timing info again */
1786 out_dframe = ffmpegdec->picture->opaque;
1787 out_frame = gst_video_codec_frame_ref (out_dframe->frame);
1789 /* also give back a buffer allocated by the frame, if any */
1790 gst_buffer_replace (&out_frame->output_buffer, out_dframe->buffer);
1791 gst_buffer_replace (&out_dframe->buffer, NULL);
1793 /* Extract auxilliary info not stored in the main AVframe */
1795 GstVideoInfo *in_info = &ffmpegdec->input_state->info;
1796 /* Take multiview mode from upstream if present */
1797 ffmpegdec->picture_multiview_mode = GST_VIDEO_INFO_MULTIVIEW_MODE (in_info);
1798 ffmpegdec->picture_multiview_flags =
1799 GST_VIDEO_INFO_MULTIVIEW_FLAGS (in_info);
1801 /* Otherwise, see if there's info in the frame */
1802 if (ffmpegdec->picture_multiview_mode == GST_VIDEO_MULTIVIEW_MODE_NONE) {
1803 AVFrameSideData *side_data =
1804 av_frame_get_side_data (ffmpegdec->picture, AV_FRAME_DATA_STEREO3D);
1806 AVStereo3D *stereo = (AVStereo3D *) side_data->data;
1807 ffmpegdec->picture_multiview_mode = stereo_av_to_gst (stereo->type);
1808 if (stereo->flags & AV_STEREO3D_FLAG_INVERT) {
1809 ffmpegdec->picture_multiview_flags =
1810 GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1812 ffmpegdec->picture_multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
1818 GST_DEBUG_OBJECT (ffmpegdec,
1819 "pts %" G_GUINT64_FORMAT " duration %" G_GUINT64_FORMAT,
1820 out_frame->pts, out_frame->duration);
1821 GST_DEBUG_OBJECT (ffmpegdec, "picture: pts %" G_GUINT64_FORMAT,
1822 (guint64) ffmpegdec->picture->pts);
1823 GST_DEBUG_OBJECT (ffmpegdec, "picture: num %d",
1824 ffmpegdec->picture->coded_picture_number);
1825 GST_DEBUG_OBJECT (ffmpegdec, "picture: display %d",
1826 ffmpegdec->picture->display_picture_number);
1827 GST_DEBUG_OBJECT (ffmpegdec, "picture: opaque %p",
1828 ffmpegdec->picture->opaque);
1829 GST_DEBUG_OBJECT (ffmpegdec, "picture: reordered opaque %" G_GUINT64_FORMAT,
1830 (guint64) ffmpegdec->picture->reordered_opaque);
1831 GST_DEBUG_OBJECT (ffmpegdec, "repeat_pict:%d",
1832 ffmpegdec->picture->repeat_pict);
1833 GST_DEBUG_OBJECT (ffmpegdec, "corrupted frame: %d",
1834 ! !(ffmpegdec->picture->flags & AV_FRAME_FLAG_CORRUPT));
1836 if (!gst_ffmpegviddec_negotiate (ffmpegdec, ffmpegdec->context,
1837 ffmpegdec->picture, GST_BUFFER_FLAGS (out_frame->input_buffer)))
1838 goto negotiation_error;
1840 pool = gst_video_decoder_get_buffer_pool (GST_VIDEO_DECODER (ffmpegdec));
1841 if (G_UNLIKELY (out_frame->output_buffer == NULL)) {
1842 *ret = get_output_buffer (ffmpegdec, out_frame);
1843 } else if (G_UNLIKELY (out_frame->output_buffer->pool != pool)) {
1844 GstBuffer *tmp = out_frame->output_buffer;
1845 out_frame->output_buffer = NULL;
1846 *ret = get_output_buffer (ffmpegdec, out_frame);
1847 gst_buffer_unref (tmp);
1849 #ifndef G_DISABLE_ASSERT
1851 GstVideoMeta *vmeta = gst_buffer_get_video_meta (out_frame->output_buffer);
1853 GstVideoInfo *info = &ffmpegdec->output_state->info;
1854 g_assert ((gint) vmeta->width == GST_VIDEO_INFO_WIDTH (info));
1855 g_assert ((gint) vmeta->height == GST_VIDEO_INFO_HEIGHT (info));
1859 gst_object_unref (pool);
1861 if (G_UNLIKELY (*ret != GST_FLOW_OK))
1864 /* Mark corrupted frames as corrupted */
1865 if (ffmpegdec->picture->flags & AV_FRAME_FLAG_CORRUPT)
1866 GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_BUFFER_FLAG_CORRUPTED);
1868 if (ffmpegdec->pic_interlaced) {
1869 /* set interlaced flags */
1870 if (ffmpegdec->picture->repeat_pict)
1871 GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_RFF);
1872 if (ffmpegdec->picture->top_field_first)
1873 GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
1874 if (ffmpegdec->picture->interlaced_frame)
1875 GST_BUFFER_FLAG_SET (out_frame->output_buffer,
1876 GST_VIDEO_BUFFER_FLAG_INTERLACED);
1880 AVFrameSideData *side_data =
1881 av_frame_get_side_data (ffmpegdec->picture, AV_FRAME_DATA_A53_CC);
1883 GST_LOG_OBJECT (ffmpegdec,
1884 "Found CC side data of type AV_FRAME_DATA_A53_CC, size %d",
1885 (int) side_data->size);
1886 GST_MEMDUMP ("A53 CC", side_data->data, side_data->size);
1888 /* do not add closed caption meta if it already exists */
1889 if (!gst_buffer_get_meta (out_frame->input_buffer,
1890 GST_VIDEO_CAPTION_META_API_TYPE)) {
1891 out_frame->output_buffer =
1892 gst_buffer_make_writable (out_frame->output_buffer);
1893 gst_buffer_add_video_caption_meta (out_frame->output_buffer,
1894 GST_VIDEO_CAPTION_TYPE_CEA708_RAW, side_data->data,
1897 GST_LOG_OBJECT (ffmpegdec,
1898 "Closed caption meta already exists: will not add new caption meta");
1904 /* so we decoded this frame, frames preceding it in decoding order
1905 * that still do not have a buffer allocated seem rather useless,
1906 * and can be discarded, due to e.g. misparsed bogus frame
1907 * or non-keyframe in skipped decoding, ...
1908 * In any case, not likely to be seen again, so discard those,
1909 * before they pile up and/or mess with timestamping */
1912 GstVideoDecoder *dec = GST_VIDEO_DECODER (ffmpegdec);
1913 gboolean old = TRUE;
1915 ol = l = gst_video_decoder_get_frames (dec);
1917 GstVideoCodecFrame *tmp = l->data;
1922 if (old && GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (tmp)) {
1923 GST_LOG_OBJECT (dec,
1924 "discarding ghost frame %p (#%d) PTS:%" GST_TIME_FORMAT " DTS:%"
1925 GST_TIME_FORMAT, tmp, tmp->system_frame_number,
1926 GST_TIME_ARGS (tmp->pts), GST_TIME_ARGS (tmp->dts));
1927 /* drop extra ref and remove from frame list */
1928 GST_VIDEO_CODEC_FRAME_FLAG_UNSET (tmp,
1929 GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED);
1930 gst_video_decoder_release_frame (dec, tmp);
1932 /* drop extra ref we got */
1933 gst_video_codec_frame_unref (tmp);
1940 av_frame_unref (ffmpegdec->picture);
1943 GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame,
1944 GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED);
1946 if (gst_video_decoder_get_subframe_mode (GST_VIDEO_DECODER (ffmpegdec)))
1947 gst_video_decoder_have_last_subframe (GST_VIDEO_DECODER (ffmpegdec),
1950 /* FIXME: Ideally we would remap the buffer read-only now before pushing but
1951 * libav might still have a reference to it!
1953 if (GST_BUFFER_FLAG_IS_SET (out_frame->input_buffer,
1954 GST_VIDEO_BUFFER_FLAG_ONEFIELD)) {
1955 GST_BUFFER_FLAG_SET (out_frame->output_buffer,
1956 GST_VIDEO_BUFFER_FLAG_ONEFIELD);
1957 if (GST_BUFFER_FLAG_IS_SET (out_frame->input_buffer,
1958 GST_VIDEO_BUFFER_FLAG_TFF)) {
1959 GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
1963 gst_video_decoder_finish_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
1966 GST_DEBUG_OBJECT (ffmpegdec, "return flow %s, got frame: %d",
1967 gst_flow_get_name (*ret), got_frame);
1973 GST_DEBUG_OBJECT (ffmpegdec, "no output buffer");
1974 GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame,
1975 GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED);
1976 gst_video_decoder_drop_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
1982 gst_video_decoder_drop_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
1983 if (GST_PAD_IS_FLUSHING (GST_VIDEO_DECODER_SRC_PAD (ffmpegdec))) {
1984 *ret = GST_FLOW_FLUSHING;
1987 GST_WARNING_OBJECT (ffmpegdec, "Error negotiating format");
1988 *ret = GST_FLOW_NOT_NEGOTIATED;
1994 /* Returns: Whether a frame was decoded */
1996 gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame,
1997 GstFlowReturn * ret)
1999 gboolean got_frame = FALSE;
2001 if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
2005 ffmpegdec->context->frame_number++;
2007 got_frame = gst_ffmpegviddec_video_frame (ffmpegdec, frame, ret);
2014 GST_ERROR_OBJECT (ffmpegdec, "no codec context");
2015 *ret = GST_FLOW_NOT_NEGOTIATED;
2020 static GstFlowReturn
2021 gst_ffmpegviddec_drain (GstVideoDecoder * decoder)
2023 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
2024 GstFlowReturn ret = GST_FLOW_OK;
2025 gboolean got_frame = FALSE;
2027 if (!ffmpegdec->opened)
2030 if (avcodec_send_packet (ffmpegdec->context, NULL))
2031 goto send_packet_failed;
2034 got_frame = gst_ffmpegviddec_frame (ffmpegdec, NULL, &ret);
2035 } while (got_frame && ret == GST_FLOW_OK);
2036 avcodec_flush_buffers (ffmpegdec->context);
2038 /* FFMpeg will return AVERROR_EOF if it's internal was fully drained
2039 * then we are translating it to GST_FLOW_EOS. However, because this behavior
2040 * is fully internal stuff of this implementation and gstvideodecoder
2041 * baseclass doesn't convert this GST_FLOW_EOS to GST_FLOW_OK,
2042 * convert this flow returned here */
2043 if (ret == GST_FLOW_EOS)
2050 GST_WARNING_OBJECT (ffmpegdec, "send packet failed, could not drain decoder");
2054 static GstFlowReturn
2055 gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
2056 GstVideoCodecFrame * frame)
2058 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
2063 GstFlowReturn ret = GST_FLOW_OK;
2066 GST_LOG_OBJECT (ffmpegdec,
2067 "Received new data of size %" G_GSIZE_FORMAT ", dts %" GST_TIME_FORMAT
2068 ", pts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
2069 gst_buffer_get_size (frame->input_buffer), GST_TIME_ARGS (frame->dts),
2070 GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->duration));
2072 if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
2073 GST_ELEMENT_ERROR (ffmpegdec, STREAM, DECODE, ("Decoding problem"),
2074 ("Failed to map buffer for reading"));
2075 return GST_FLOW_ERROR;
2078 /* treat frame as void until a buffer is requested for it */
2079 if (!GST_VIDEO_CODEC_FRAME_FLAG_IS_SET (frame,
2080 GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED))
2081 GST_VIDEO_CODEC_FRAME_FLAG_SET (frame,
2082 GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
2087 if (size > 0 && (!GST_MEMORY_IS_ZERO_PADDED (minfo.memory)
2088 || (minfo.maxsize - minfo.size) < AV_INPUT_BUFFER_PADDING_SIZE)) {
2090 if (ffmpegdec->padded_size < size + AV_INPUT_BUFFER_PADDING_SIZE) {
2091 ffmpegdec->padded_size = size + AV_INPUT_BUFFER_PADDING_SIZE;
2092 ffmpegdec->padded = g_realloc (ffmpegdec->padded, ffmpegdec->padded_size);
2093 GST_LOG_OBJECT (ffmpegdec, "resized padding buffer to %d",
2094 ffmpegdec->padded_size);
2096 GST_CAT_TRACE_OBJECT (GST_CAT_PERFORMANCE, ffmpegdec,
2097 "Copy input to add padding");
2098 memcpy (ffmpegdec->padded, data, size);
2099 memset (ffmpegdec->padded + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2101 data = ffmpegdec->padded;
2104 /* now decode the frame */
2105 gst_avpacket_init (&packet, data, size);
2107 if (ffmpegdec->palette) {
2110 pal = av_packet_new_side_data (&packet, AV_PKT_DATA_PALETTE,
2112 gst_buffer_extract (ffmpegdec->palette, 0, pal, AVPALETTE_SIZE);
2113 GST_DEBUG_OBJECT (ffmpegdec, "copy pal %p %p", &packet, pal);
2119 /* save reference to the timing info */
2120 ffmpegdec->context->reordered_opaque = (gint64) frame->system_frame_number;
2121 ffmpegdec->picture->reordered_opaque = (gint64) frame->system_frame_number;
2123 GST_DEBUG_OBJECT (ffmpegdec, "stored opaque values idx %d",
2124 frame->system_frame_number);
2126 /* This might call into get_buffer() from another thread,
2127 * which would cause a deadlock. Release the lock here
2128 * and taking it again later seems safe
2129 * See https://bugzilla.gnome.org/show_bug.cgi?id=726020
2131 GST_VIDEO_DECODER_STREAM_UNLOCK (ffmpegdec);
2132 if (avcodec_send_packet (ffmpegdec->context, &packet) < 0) {
2133 GST_VIDEO_DECODER_STREAM_LOCK (ffmpegdec);
2134 goto send_packet_failed;
2136 GST_VIDEO_DECODER_STREAM_LOCK (ffmpegdec);
2139 /* decode a frame of audio/video now */
2140 got_frame = gst_ffmpegviddec_frame (ffmpegdec, frame, &ret);
2142 if (ret != GST_FLOW_OK) {
2143 GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
2144 gst_flow_get_name (ret));
2147 } while (got_frame);
2150 gst_buffer_unmap (frame->input_buffer, &minfo);
2151 gst_video_codec_frame_unref (frame);
2157 GST_WARNING_OBJECT (ffmpegdec, "Failed to send data for decoding");
2163 gst_ffmpegviddec_start (GstVideoDecoder * decoder)
2165 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
2166 GstFFMpegVidDecClass *oclass;
2168 oclass = GST_FFMPEGVIDDEC_GET_CLASS (ffmpegdec);
2170 GST_OBJECT_LOCK (ffmpegdec);
2171 avcodec_free_context (&ffmpegdec->context);
2172 ffmpegdec->context = avcodec_alloc_context3 (oclass->in_plugin);
2173 if (ffmpegdec->context == NULL) {
2174 GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
2175 GST_OBJECT_UNLOCK (ffmpegdec);
2178 ffmpegdec->context->opaque = ffmpegdec;
2179 GST_OBJECT_UNLOCK (ffmpegdec);
2185 gst_ffmpegviddec_stop (GstVideoDecoder * decoder)
2187 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
2189 GST_OBJECT_LOCK (ffmpegdec);
2190 gst_ffmpegviddec_close (ffmpegdec, FALSE);
2191 GST_OBJECT_UNLOCK (ffmpegdec);
2192 g_free (ffmpegdec->padded);
2193 ffmpegdec->padded = NULL;
2194 ffmpegdec->padded_size = 0;
2195 if (ffmpegdec->input_state)
2196 gst_video_codec_state_unref (ffmpegdec->input_state);
2197 ffmpegdec->input_state = NULL;
2198 if (ffmpegdec->output_state)
2199 gst_video_codec_state_unref (ffmpegdec->output_state);
2200 ffmpegdec->output_state = NULL;
2202 if (ffmpegdec->internal_pool)
2203 gst_object_unref (ffmpegdec->internal_pool);
2204 ffmpegdec->internal_pool = NULL;
2206 ffmpegdec->pic_pix_fmt = 0;
2207 ffmpegdec->pic_width = 0;
2208 ffmpegdec->pic_height = 0;
2209 ffmpegdec->pic_par_n = 0;
2210 ffmpegdec->pic_par_d = 0;
2211 ffmpegdec->pic_interlaced = 0;
2212 ffmpegdec->pic_field_order = 0;
2213 ffmpegdec->pic_field_order_changed = FALSE;
2214 ffmpegdec->ctx_ticks = 0;
2215 ffmpegdec->ctx_time_n = 0;
2216 ffmpegdec->ctx_time_d = 0;
2218 ffmpegdec->pool_width = 0;
2219 ffmpegdec->pool_height = 0;
2220 ffmpegdec->pool_format = 0;
2225 static GstFlowReturn
2226 gst_ffmpegviddec_finish (GstVideoDecoder * decoder)
2228 GstFlowReturn flow_ret;
2230 flow_ret = gst_ffmpegviddec_drain (decoder);
2232 /* note that finish can and should clean up more drastically,
2233 * but drain is also invoked on e.g. packet loss in GAP handling */
2234 gst_ffmpegviddec_flush (decoder);
2240 gst_ffmpegviddec_flush (GstVideoDecoder * decoder)
2242 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
2244 if (ffmpegdec->opened) {
2245 GST_LOG_OBJECT (decoder, "flushing buffers");
2246 avcodec_flush_buffers (ffmpegdec->context);
2253 gst_ffmpegviddec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
2255 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (decoder);
2256 GstVideoCodecState *state;
2257 GstBufferPool *pool;
2258 guint size, min, max;
2259 GstStructure *config;
2260 gboolean have_pool, have_videometa, have_alignment, update_pool = FALSE;
2261 GstAllocator *allocator = NULL;
2262 GstAllocationParams params = DEFAULT_ALLOC_PARAM;
2264 have_pool = (gst_query_get_n_allocation_pools (query) != 0);
2266 if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder,
2270 state = gst_video_decoder_get_output_state (decoder);
2272 if (gst_query_get_n_allocation_params (query) > 0) {
2273 gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
2274 params.align = MAX (params.align, DEFAULT_STRIDE_ALIGN);
2276 gst_query_add_allocation_param (query, allocator, ¶ms);
2279 gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
2281 /* Don't use pool that can't grow, as we don't know how many buffer we'll
2282 * need, otherwise we may stall */
2283 if (max != 0 && max < REQUIRED_POOL_MAX_BUFFERS) {
2284 gst_object_unref (pool);
2285 pool = gst_video_buffer_pool_new ();
2290 /* if there is an allocator, also drop it, as it might be the reason we
2291 * have this limit. Default will be used */
2293 gst_object_unref (allocator);
2298 config = gst_buffer_pool_get_config (pool);
2299 gst_buffer_pool_config_set_params (config, state->caps, size, min, max);
2300 gst_buffer_pool_config_set_allocator (config, allocator, ¶ms);
2303 gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
2306 gst_buffer_pool_config_add_option (config,
2307 GST_BUFFER_POOL_OPTION_VIDEO_META);
2310 gst_buffer_pool_has_option (pool, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
2312 /* If we have videometa, we never have to copy */
2313 if (have_videometa && have_pool && have_alignment &&
2314 gst_ffmpegviddec_can_direct_render (ffmpegdec)) {
2315 GstStructure *config_copy = gst_structure_copy (config);
2317 gst_ffmpegvideodec_prepare_dr_pool (ffmpegdec, pool, &state->info,
2320 /* FIXME validate and retry */
2321 if (gst_buffer_pool_set_config (pool, config_copy)) {
2325 gst_buffer_pool_set_active (pool, TRUE);
2326 ret = gst_buffer_pool_acquire_buffer (pool, &tmp, NULL);
2327 if (ret == GST_FLOW_OK) {
2328 GstVideoMeta *vmeta = gst_buffer_get_video_meta (tmp);
2329 gboolean same_stride = TRUE;
2332 for (i = 0; i < vmeta->n_planes; i++) {
2333 if (vmeta->stride[i] != ffmpegdec->stride[i]) {
2334 same_stride = FALSE;
2339 gst_buffer_unref (tmp);
2342 if (ffmpegdec->internal_pool)
2343 gst_object_unref (ffmpegdec->internal_pool);
2344 ffmpegdec->internal_pool = gst_object_ref (pool);
2345 ffmpegdec->pool_width = GST_VIDEO_INFO_WIDTH (&state->info);
2346 ffmpegdec->pool_height =
2347 MAX (GST_VIDEO_INFO_HEIGHT (&state->info),
2348 ffmpegdec->context->coded_height);
2349 ffmpegdec->pool_info = state->info;
2350 gst_structure_free (config);
2357 if (have_videometa && ffmpegdec->internal_pool
2358 && gst_ffmpeg_pixfmt_to_videoformat (ffmpegdec->pool_format) ==
2359 GST_VIDEO_INFO_FORMAT (&state->info)
2360 && ffmpegdec->pool_width == state->info.width
2361 && ffmpegdec->pool_height == state->info.height) {
2363 gst_object_unref (pool);
2364 pool = gst_object_ref (ffmpegdec->internal_pool);
2365 gst_structure_free (config);
2370 if (!gst_buffer_pool_set_config (pool, config)) {
2371 gboolean working_pool = FALSE;
2372 config = gst_buffer_pool_get_config (pool);
2374 if (gst_buffer_pool_config_validate_params (config, state->caps, size, min,
2376 working_pool = gst_buffer_pool_set_config (pool, config);
2378 gst_structure_free (config);
2381 if (!working_pool) {
2382 gst_object_unref (pool);
2383 pool = gst_video_buffer_pool_new ();
2384 config = gst_buffer_pool_get_config (pool);
2385 gst_buffer_pool_config_set_params (config, state->caps, size, min, max);
2386 gst_buffer_pool_config_set_allocator (config, NULL, ¶ms);
2387 gst_buffer_pool_set_config (pool, config);
2395 gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
2397 gst_object_unref (pool);
2399 gst_object_unref (allocator);
2400 gst_video_codec_state_unref (state);
2406 gst_ffmpegviddec_propose_allocation (GstVideoDecoder * decoder,
2409 GstAllocationParams params;
2411 gst_allocation_params_init (¶ms);
2412 params.flags = GST_MEMORY_FLAG_ZERO_PADDED;
2413 params.align = DEFAULT_STRIDE_ALIGN;
2414 params.padding = AV_INPUT_BUFFER_PADDING_SIZE;
2415 /* we would like to have some padding so that we don't have to
2416 * memcpy. We don't suggest an allocator. */
2417 gst_query_add_allocation_param (query, NULL, ¶ms);
2419 return GST_VIDEO_DECODER_CLASS (parent_class)->propose_allocation (decoder,
2424 gst_ffmpegviddec_set_property (GObject * object,
2425 guint prop_id, const GValue * value, GParamSpec * pspec)
2427 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (object);
2431 ffmpegdec->lowres = ffmpegdec->context->lowres = g_value_get_enum (value);
2433 case PROP_SKIPFRAME:
2434 ffmpegdec->skip_frame = ffmpegdec->context->skip_frame =
2435 g_value_get_enum (value);
2437 case PROP_DIRECT_RENDERING:
2438 ffmpegdec->direct_rendering = g_value_get_boolean (value);
2440 #ifndef GST_REMOVE_DEPRECATED
2442 /* non-functional */
2445 case PROP_MAX_THREADS:
2446 ffmpegdec->max_threads = g_value_get_int (value);
2448 case PROP_OUTPUT_CORRUPT:
2449 ffmpegdec->output_corrupt = g_value_get_boolean (value);
2451 case PROP_THREAD_TYPE:
2452 ffmpegdec->thread_type = g_value_get_flags (value);
2454 case PROP_STD_COMPLIANCE:
2455 ffmpegdec->std_compliance = g_value_get_enum (value);
2458 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2464 gst_ffmpegviddec_get_property (GObject * object,
2465 guint prop_id, GValue * value, GParamSpec * pspec)
2467 GstFFMpegVidDec *ffmpegdec = GST_FFMPEGVIDDEC (object);
2471 g_value_set_enum (value, ffmpegdec->lowres);
2473 case PROP_SKIPFRAME:
2474 g_value_set_enum (value, ffmpegdec->skip_frame);
2476 case PROP_DIRECT_RENDERING:
2477 g_value_set_boolean (value, ffmpegdec->direct_rendering);
2479 #ifndef GST_REMOVE_DEPRECATED
2481 g_value_set_boolean (value, FALSE);
2484 case PROP_MAX_THREADS:
2485 g_value_set_int (value, ffmpegdec->max_threads);
2487 case PROP_OUTPUT_CORRUPT:
2488 g_value_set_boolean (value, ffmpegdec->output_corrupt);
2490 case PROP_THREAD_TYPE:
2491 g_value_set_flags (value, ffmpegdec->thread_type);
2493 case PROP_STD_COMPLIANCE:
2494 g_value_set_enum (value, ffmpegdec->std_compliance);
2497 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2503 gst_ffmpegviddec_register (GstPlugin * plugin)
2505 GTypeInfo typeinfo = {
2506 sizeof (GstFFMpegVidDecClass),
2509 (GClassInitFunc) gst_ffmpegviddec_subclass_init,
2512 sizeof (GstFFMpegVidDec),
2514 (GInstanceInitFunc) gst_ffmpegviddec_subinit,
2521 GST_LOG ("Registering decoders");
2523 while ((in_plugin = (AVCodec *) av_codec_iterate (&i))) {
2527 /* only video decoders */
2528 if (!av_codec_is_decoder (in_plugin)
2529 || in_plugin->type != AVMEDIA_TYPE_VIDEO)
2532 /* no quasi codecs, please */
2533 if (in_plugin->id == AV_CODEC_ID_RAWVIDEO ||
2534 in_plugin->id == AV_CODEC_ID_V210 ||
2535 in_plugin->id == AV_CODEC_ID_V210X ||
2536 in_plugin->id == AV_CODEC_ID_V308 ||
2537 in_plugin->id == AV_CODEC_ID_V408 ||
2538 in_plugin->id == AV_CODEC_ID_V410 ||
2539 in_plugin->id == AV_CODEC_ID_R210
2540 || in_plugin->id == AV_CODEC_ID_AYUV
2541 || in_plugin->id == AV_CODEC_ID_Y41P
2542 || in_plugin->id == AV_CODEC_ID_012V
2543 || in_plugin->id == AV_CODEC_ID_YUV4
2544 #if AV_VERSION_INT (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) >= \
2545 AV_VERSION_INT (57,4,0)
2546 || in_plugin->id == AV_CODEC_ID_WRAPPED_AVFRAME
2548 || in_plugin->id == AV_CODEC_ID_ZLIB) {
2552 /* No decoders depending on external libraries (we don't build them, but
2553 * people who build against an external ffmpeg might have them.
2554 * We have native gstreamer plugins for all of those libraries anyway. */
2555 if (!strncmp (in_plugin->name, "lib", 3)) {
2557 ("Not using external library decoder %s. Use the gstreamer-native ones instead.",
2562 /* Skip hardware or hybrid (hardware with software fallback) */
2563 if ((in_plugin->capabilities & AV_CODEC_CAP_HARDWARE) ==
2564 AV_CODEC_CAP_HARDWARE) {
2566 ("Ignoring hardware decoder %s. We can't handle this outside of ffmpeg",
2571 if ((in_plugin->capabilities & AV_CODEC_CAP_HYBRID) == AV_CODEC_CAP_HYBRID) {
2573 ("Ignoring hybrid decoder %s. We can't handle this outside of ffmpeg",
2578 /* No vdpau plugins until we can figure out how to properly use them
2579 * outside of ffmpeg. */
2580 if (g_str_has_suffix (in_plugin->name, "_vdpau")) {
2582 ("Ignoring VDPAU decoder %s. We can't handle this outside of ffmpeg",
2587 if (g_str_has_suffix (in_plugin->name, "_xvmc")) {
2589 ("Ignoring XVMC decoder %s. We can't handle this outside of ffmpeg",
2594 if (strstr (in_plugin->name, "vaapi")) {
2596 ("Ignoring VAAPI decoder %s. We can't handle this outside of ffmpeg",
2601 if (g_str_has_suffix (in_plugin->name, "_qsv")) {
2603 ("Ignoring qsv decoder %s. We can't handle this outside of ffmpeg",
2608 GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
2610 /* no codecs for which we're GUARANTEED to have better alternatives */
2611 /* MPEG1VIDEO : the mpeg2video decoder is preferred */
2612 /* MP1 : Use MP3 for decoding */
2613 /* MP2 : Use MP3 for decoding */
2614 /* Theora: Use libtheora based theoradec */
2615 /* CDG: use cdgdec */
2616 if (!strcmp (in_plugin->name, "theora") ||
2617 !strcmp (in_plugin->name, "mpeg1video") ||
2618 strstr (in_plugin->name, "crystalhd") != NULL ||
2619 !strcmp (in_plugin->name, "ass") ||
2620 !strcmp (in_plugin->name, "srt") ||
2621 !strcmp (in_plugin->name, "pgssub") ||
2622 !strcmp (in_plugin->name, "dvdsub") ||
2623 !strcmp (in_plugin->name, "dvbsub") ||
2624 !strcmp (in_plugin->name, "cdgraphics")) {
2625 GST_LOG ("Ignoring decoder %s", in_plugin->name);
2629 /* construct the type */
2630 if (!strcmp (in_plugin->name, "hevc")) {
2631 plugin_name = g_strdup ("h265");
2633 plugin_name = g_strdup ((gchar *) in_plugin->name);
2635 g_strdelimit (plugin_name, NULL, '_');
2636 type_name = g_strdup_printf ("avdec_%s", plugin_name);
2637 g_free (plugin_name);
2639 type = g_type_from_name (type_name);
2642 /* create the gtype now */
2643 typeinfo.class_data = in_plugin;
2645 g_type_register_static (GST_TYPE_FFMPEGVIDDEC, type_name, &typeinfo,
2649 /* (Ronald) MPEG-4 gets a higher priority because it has been well-
2650 * tested and by far outperforms divxdec/xviddec - so we prefer it.
2651 * msmpeg4v3 same, as it outperforms divxdec for divx3 playback. */
2652 switch (in_plugin->id) {
2653 case AV_CODEC_ID_MPEG1VIDEO:
2654 case AV_CODEC_ID_MPEG2VIDEO:
2655 case AV_CODEC_ID_MPEG4:
2656 case AV_CODEC_ID_MSMPEG4V3:
2657 case AV_CODEC_ID_H264:
2658 case AV_CODEC_ID_HEVC:
2659 case AV_CODEC_ID_RV10:
2660 case AV_CODEC_ID_RV20:
2661 case AV_CODEC_ID_RV30:
2662 case AV_CODEC_ID_RV40:
2663 rank = GST_RANK_PRIMARY;
2665 /* DVVIDEO: we have a good dv decoder, fast on both ppc as well as x86.
2666 * They say libdv's quality is better though. leave as secondary.
2667 * note: if you change this, see the code in gstdv.c in good/ext/dv.
2669 case AV_CODEC_ID_DVVIDEO:
2670 rank = GST_RANK_SECONDARY;
2673 rank = GST_RANK_MARGINAL;
2676 if (!gst_element_register (plugin, type_name, rank, type)) {
2677 g_warning ("Failed to register %s", type_name);
2685 GST_LOG ("Finished Registering decoders");