avvidec: Expose Closed Caption as GstVideoCaptionMeta
[platform/upstream/gstreamer.git] / ext / libav / gstavviddec.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <assert.h>
25 #include <string.h>
26
27 #include <libavcodec/avcodec.h>
28 #include <libavutil/stereo3d.h>
29
30 #include <gst/gst.h>
31 #include <gst/video/video.h>
32 #include <gst/video/gstvideodecoder.h>
33 #include <gst/video/gstvideometa.h>
34 #include <gst/video/gstvideopool.h>
35 #include <gst/video/video-anc.h>
36
37 #include "gstav.h"
38 #include "gstavcodecmap.h"
39 #include "gstavutils.h"
40 #include "gstavviddec.h"
41
42 #define MAX_TS_MASK 0xff
43
44 #define DEFAULT_LOWRES                  0
45 #define DEFAULT_SKIPFRAME               0
46 #define DEFAULT_DIRECT_RENDERING        TRUE
47 #define DEFAULT_DEBUG_MV                FALSE
48 #define DEFAULT_MAX_THREADS             0
49 #define DEFAULT_OUTPUT_CORRUPT          TRUE
50 #define REQUIRED_POOL_MAX_BUFFERS       32
51 #define DEFAULT_STRIDE_ALIGN            31
52 #define DEFAULT_ALLOC_PARAM             { 0, DEFAULT_STRIDE_ALIGN, 0, 0, }
53
54 enum
55 {
56   PROP_0,
57   PROP_LOWRES,
58   PROP_SKIPFRAME,
59   PROP_DIRECT_RENDERING,
60   PROP_DEBUG_MV,
61   PROP_MAX_THREADS,
62   PROP_OUTPUT_CORRUPT,
63   PROP_LAST
64 };
65
66 /* A number of function prototypes are given so we can refer to them later. */
67 static void gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass);
68 static void gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass);
69 static void gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec);
70 static void gst_ffmpegviddec_finalize (GObject * object);
71
72 static gboolean gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
73     GstVideoCodecState * state);
74 static GstFlowReturn gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
75     GstVideoCodecFrame * frame);
76 static gboolean gst_ffmpegviddec_start (GstVideoDecoder * decoder);
77 static gboolean gst_ffmpegviddec_stop (GstVideoDecoder * decoder);
78 static gboolean gst_ffmpegviddec_flush (GstVideoDecoder * decoder);
79 static gboolean gst_ffmpegviddec_decide_allocation (GstVideoDecoder * decoder,
80     GstQuery * query);
81 static gboolean gst_ffmpegviddec_propose_allocation (GstVideoDecoder * decoder,
82     GstQuery * query);
83
84 static void gst_ffmpegviddec_set_property (GObject * object,
85     guint prop_id, const GValue * value, GParamSpec * pspec);
86 static void gst_ffmpegviddec_get_property (GObject * object,
87     guint prop_id, GValue * value, GParamSpec * pspec);
88
89 static gboolean gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec,
90     AVCodecContext * context, AVFrame * picture);
91
92 /* some sort of bufferpool handling, but different */
93 static int gst_ffmpegviddec_get_buffer2 (AVCodecContext * context,
94     AVFrame * picture, int flags);
95
96 static GstFlowReturn gst_ffmpegviddec_finish (GstVideoDecoder * decoder);
97 static GstFlowReturn gst_ffmpegviddec_drain (GstVideoDecoder * decoder);
98
99 static gboolean picture_changed (GstFFMpegVidDec * ffmpegdec,
100     AVFrame * picture);
101 static gboolean context_changed (GstFFMpegVidDec * ffmpegdec,
102     AVCodecContext * context);
103
104 #define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
105
106 static GstElementClass *parent_class = NULL;
107
108 #define GST_FFMPEGVIDDEC_TYPE_LOWRES (gst_ffmpegviddec_lowres_get_type())
109 static GType
110 gst_ffmpegviddec_lowres_get_type (void)
111 {
112   static GType ffmpegdec_lowres_type = 0;
113
114   if (!ffmpegdec_lowres_type) {
115     static const GEnumValue ffmpegdec_lowres[] = {
116       {0, "0", "full"},
117       {1, "1", "1/2-size"},
118       {2, "2", "1/4-size"},
119       {0, NULL, NULL},
120     };
121
122     ffmpegdec_lowres_type =
123         g_enum_register_static ("GstLibAVVidDecLowres", ffmpegdec_lowres);
124   }
125
126   return ffmpegdec_lowres_type;
127 }
128
129 #define GST_FFMPEGVIDDEC_TYPE_SKIPFRAME (gst_ffmpegviddec_skipframe_get_type())
130 static GType
131 gst_ffmpegviddec_skipframe_get_type (void)
132 {
133   static GType ffmpegdec_skipframe_type = 0;
134
135   if (!ffmpegdec_skipframe_type) {
136     static const GEnumValue ffmpegdec_skipframe[] = {
137       {0, "0", "Skip nothing"},
138       {1, "1", "Skip B-frames"},
139       {2, "2", "Skip IDCT/Dequantization"},
140       {5, "5", "Skip everything"},
141       {0, NULL, NULL},
142     };
143
144     ffmpegdec_skipframe_type =
145         g_enum_register_static ("GstLibAVVidDecSkipFrame", ffmpegdec_skipframe);
146   }
147
148   return ffmpegdec_skipframe_type;
149 }
150
151 static void
152 gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass)
153 {
154   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
155   GstPadTemplate *sinktempl, *srctempl;
156   GstCaps *sinkcaps, *srccaps;
157   AVCodec *in_plugin;
158   gchar *longname, *description;
159
160   in_plugin =
161       (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
162       GST_FFDEC_PARAMS_QDATA);
163   g_assert (in_plugin != NULL);
164
165   /* construct the element details struct */
166   longname = g_strdup_printf ("libav %s decoder", in_plugin->long_name);
167   description = g_strdup_printf ("libav %s decoder", in_plugin->name);
168   gst_element_class_set_metadata (element_class, longname,
169       "Codec/Decoder/Video", description,
170       "Wim Taymans <wim.taymans@gmail.com>, "
171       "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
172       "Edward Hervey <bilboed@bilboed.com>");
173   g_free (longname);
174   g_free (description);
175
176   /* get the caps */
177   sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
178   if (!sinkcaps) {
179     GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
180     sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
181   }
182   srccaps = gst_ffmpeg_codectype_to_video_caps (NULL,
183       in_plugin->id, FALSE, in_plugin);
184   if (!srccaps) {
185     GST_DEBUG ("Couldn't get source caps for decoder '%s'", in_plugin->name);
186     srccaps = gst_caps_from_string ("video/x-raw");
187   }
188
189   /* pad templates */
190   sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
191       GST_PAD_ALWAYS, sinkcaps);
192   srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
193
194   gst_element_class_add_pad_template (element_class, srctempl);
195   gst_element_class_add_pad_template (element_class, sinktempl);
196
197   gst_caps_unref (sinkcaps);
198   gst_caps_unref (srccaps);
199
200   klass->in_plugin = in_plugin;
201 }
202
203 static void
204 gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
205 {
206   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
207   GstVideoDecoderClass *viddec_class = GST_VIDEO_DECODER_CLASS (klass);
208   int caps;
209
210   parent_class = g_type_class_peek_parent (klass);
211
212   gobject_class->finalize = gst_ffmpegviddec_finalize;
213
214   gobject_class->set_property = gst_ffmpegviddec_set_property;
215   gobject_class->get_property = gst_ffmpegviddec_get_property;
216
217   g_object_class_install_property (gobject_class, PROP_SKIPFRAME,
218       g_param_spec_enum ("skip-frame", "Skip frames",
219           "Which types of frames to skip during decoding",
220           GST_FFMPEGVIDDEC_TYPE_SKIPFRAME, 0,
221           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
222   g_object_class_install_property (gobject_class, PROP_LOWRES,
223       g_param_spec_enum ("lowres", "Low resolution",
224           "At which resolution to decode images",
225           GST_FFMPEGVIDDEC_TYPE_LOWRES, 0,
226           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
227   g_object_class_install_property (gobject_class, PROP_DIRECT_RENDERING,
228       g_param_spec_boolean ("direct-rendering", "Direct Rendering",
229           "Enable direct rendering", DEFAULT_DIRECT_RENDERING,
230           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
231   g_object_class_install_property (gobject_class, PROP_DEBUG_MV,
232       g_param_spec_boolean ("debug-mv", "Debug motion vectors",
233           "Whether libav should print motion vectors on top of the image",
234           DEFAULT_DEBUG_MV, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
235   g_object_class_install_property (gobject_class, PROP_OUTPUT_CORRUPT,
236       g_param_spec_boolean ("output-corrupt", "Output corrupt buffers",
237           "Whether libav should output frames even if corrupted",
238           DEFAULT_OUTPUT_CORRUPT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
239
240   caps = klass->in_plugin->capabilities;
241   if (caps & (CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS)) {
242     g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MAX_THREADS,
243         g_param_spec_int ("max-threads", "Maximum decode threads",
244             "Maximum number of worker threads to spawn. (0 = auto)",
245             0, G_MAXINT, DEFAULT_MAX_THREADS,
246             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
247   }
248
249   viddec_class->set_format = gst_ffmpegviddec_set_format;
250   viddec_class->handle_frame = gst_ffmpegviddec_handle_frame;
251   viddec_class->start = gst_ffmpegviddec_start;
252   viddec_class->stop = gst_ffmpegviddec_stop;
253   viddec_class->flush = gst_ffmpegviddec_flush;
254   viddec_class->finish = gst_ffmpegviddec_finish;
255   viddec_class->drain = gst_ffmpegviddec_drain;
256   viddec_class->decide_allocation = gst_ffmpegviddec_decide_allocation;
257   viddec_class->propose_allocation = gst_ffmpegviddec_propose_allocation;
258 }
259
260 static void
261 gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec)
262 {
263   GstFFMpegVidDecClass *klass =
264       (GstFFMpegVidDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
265
266   /* some ffmpeg data */
267   ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
268   ffmpegdec->context->opaque = ffmpegdec;
269   ffmpegdec->picture = av_frame_alloc ();
270   ffmpegdec->opened = FALSE;
271   ffmpegdec->skip_frame = ffmpegdec->lowres = 0;
272   ffmpegdec->direct_rendering = DEFAULT_DIRECT_RENDERING;
273   ffmpegdec->debug_mv = DEFAULT_DEBUG_MV;
274   ffmpegdec->max_threads = DEFAULT_MAX_THREADS;
275   ffmpegdec->output_corrupt = DEFAULT_OUTPUT_CORRUPT;
276
277   GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (ffmpegdec));
278   gst_video_decoder_set_use_default_pad_acceptcaps (GST_VIDEO_DECODER_CAST
279       (ffmpegdec), TRUE);
280
281   gst_video_decoder_set_needs_format (GST_VIDEO_DECODER (ffmpegdec), TRUE);
282 }
283
284 static void
285 gst_ffmpegviddec_finalize (GObject * object)
286 {
287   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) object;
288
289   av_frame_free (&ffmpegdec->picture);
290
291   if (ffmpegdec->context != NULL) {
292     gst_ffmpeg_avcodec_close (ffmpegdec->context);
293     av_free (ffmpegdec->context);
294     ffmpegdec->context = NULL;
295   }
296
297   G_OBJECT_CLASS (parent_class)->finalize (object);
298 }
299
300 static void
301 gst_ffmpegviddec_context_set_flags (AVCodecContext * context, guint flags,
302     gboolean enable)
303 {
304   g_return_if_fail (context != NULL);
305
306   if (enable)
307     context->flags |= flags;
308   else
309     context->flags &= ~flags;
310 }
311
312 /* with LOCK */
313 static gboolean
314 gst_ffmpegviddec_close (GstFFMpegVidDec * ffmpegdec, gboolean reset)
315 {
316   GstFFMpegVidDecClass *oclass;
317   gint i;
318
319   oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
320
321   GST_LOG_OBJECT (ffmpegdec, "closing ffmpeg codec");
322
323   gst_caps_replace (&ffmpegdec->last_caps, NULL);
324
325   gst_ffmpeg_avcodec_close (ffmpegdec->context);
326   ffmpegdec->opened = FALSE;
327
328   for (i = 0; i < G_N_ELEMENTS (ffmpegdec->stride); i++)
329     ffmpegdec->stride[i] = -1;
330
331   gst_buffer_replace (&ffmpegdec->palette, NULL);
332
333   if (ffmpegdec->context->extradata) {
334     av_free (ffmpegdec->context->extradata);
335     ffmpegdec->context->extradata = NULL;
336   }
337   if (reset) {
338     if (avcodec_get_context_defaults3 (ffmpegdec->context,
339             oclass->in_plugin) < 0) {
340       GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
341       return FALSE;
342     }
343     ffmpegdec->context->opaque = ffmpegdec;
344   }
345   return TRUE;
346 }
347
348 /* with LOCK */
349 static gboolean
350 gst_ffmpegviddec_open (GstFFMpegVidDec * ffmpegdec)
351 {
352   GstFFMpegVidDecClass *oclass;
353   gint i;
354
355   oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
356
357   if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
358     goto could_not_open;
359
360   for (i = 0; i < G_N_ELEMENTS (ffmpegdec->stride); i++)
361     ffmpegdec->stride[i] = -1;
362
363   ffmpegdec->opened = TRUE;
364
365   GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
366       oclass->in_plugin->name, oclass->in_plugin->id);
367
368   gst_ffmpegviddec_context_set_flags (ffmpegdec->context,
369       CODEC_FLAG_OUTPUT_CORRUPT, ffmpegdec->output_corrupt);
370
371   return TRUE;
372
373   /* ERRORS */
374 could_not_open:
375   {
376     gst_ffmpegviddec_close (ffmpegdec, TRUE);
377     GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
378         oclass->in_plugin->name);
379     return FALSE;
380   }
381 }
382
383 static void
384 gst_ffmpegviddec_get_palette (GstFFMpegVidDec * ffmpegdec,
385     GstVideoCodecState * state)
386 {
387   GstStructure *str = gst_caps_get_structure (state->caps, 0);
388   const GValue *palette_v;
389   GstBuffer *palette;
390
391   /* do we have a palette? */
392   if ((palette_v = gst_structure_get_value (str, "palette_data"))) {
393     palette = gst_value_get_buffer (palette_v);
394     GST_DEBUG ("got palette data %p", palette);
395     if (gst_buffer_get_size (palette) >= AVPALETTE_SIZE) {
396       gst_buffer_replace (&ffmpegdec->palette, palette);
397     }
398   }
399 }
400
401
402 static gboolean
403 gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
404     GstVideoCodecState * state)
405 {
406   GstFFMpegVidDec *ffmpegdec;
407   GstFFMpegVidDecClass *oclass;
408   GstClockTime latency = GST_CLOCK_TIME_NONE;
409   gboolean ret = FALSE;
410
411   ffmpegdec = (GstFFMpegVidDec *) decoder;
412   oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
413
414   if (ffmpegdec->last_caps != NULL &&
415       gst_caps_is_equal (ffmpegdec->last_caps, state->caps)) {
416     return TRUE;
417   }
418
419   GST_DEBUG_OBJECT (ffmpegdec, "setcaps called");
420
421   GST_OBJECT_LOCK (ffmpegdec);
422   /* stupid check for VC1 */
423   if ((oclass->in_plugin->id == AV_CODEC_ID_WMV3) ||
424       (oclass->in_plugin->id == AV_CODEC_ID_VC1))
425     oclass->in_plugin->id = gst_ffmpeg_caps_to_codecid (state->caps, NULL);
426
427   /* close old session */
428   if (ffmpegdec->opened) {
429     GST_OBJECT_UNLOCK (ffmpegdec);
430     gst_ffmpegviddec_finish (decoder);
431     GST_OBJECT_LOCK (ffmpegdec);
432     if (!gst_ffmpegviddec_close (ffmpegdec, TRUE)) {
433       GST_OBJECT_UNLOCK (ffmpegdec);
434       return FALSE;
435     }
436     ffmpegdec->pic_pix_fmt = 0;
437     ffmpegdec->pic_width = 0;
438     ffmpegdec->pic_height = 0;
439     ffmpegdec->pic_par_n = 0;
440     ffmpegdec->pic_par_d = 0;
441     ffmpegdec->pic_interlaced = 0;
442     ffmpegdec->pic_field_order = 0;
443     ffmpegdec->pic_field_order_changed = FALSE;
444     ffmpegdec->ctx_ticks = 0;
445     ffmpegdec->ctx_time_n = 0;
446     ffmpegdec->ctx_time_d = 0;
447     ffmpegdec->cur_multiview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
448     ffmpegdec->cur_multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
449   }
450
451   gst_caps_replace (&ffmpegdec->last_caps, state->caps);
452
453   /* set buffer functions */
454   ffmpegdec->context->get_buffer2 = gst_ffmpegviddec_get_buffer2;
455   ffmpegdec->context->draw_horiz_band = NULL;
456
457   /* reset coded_width/_height to prevent it being reused from last time when
458    * the codec is opened again, causing a mismatch and possible
459    * segfault/corruption. (Common scenario when renegotiating caps) */
460   ffmpegdec->context->coded_width = 0;
461   ffmpegdec->context->coded_height = 0;
462
463   GST_LOG_OBJECT (ffmpegdec, "size %dx%d", ffmpegdec->context->width,
464       ffmpegdec->context->height);
465
466   /* FIXME : Create a method that takes GstVideoCodecState instead */
467   /* get size and so */
468   gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
469       oclass->in_plugin->type, state->caps, ffmpegdec->context);
470
471   GST_LOG_OBJECT (ffmpegdec, "size after %dx%d", ffmpegdec->context->width,
472       ffmpegdec->context->height);
473
474   gst_ffmpegviddec_get_palette (ffmpegdec, state);
475
476   if (!ffmpegdec->context->time_base.den || !ffmpegdec->context->time_base.num) {
477     GST_DEBUG_OBJECT (ffmpegdec, "forcing 25/1 framerate");
478     ffmpegdec->context->time_base.num = 1;
479     ffmpegdec->context->time_base.den = 25;
480   }
481
482   /* workaround encoder bugs */
483   ffmpegdec->context->workaround_bugs |= FF_BUG_AUTODETECT;
484   ffmpegdec->context->err_recognition = 1;
485
486   /* for slow cpus */
487   ffmpegdec->context->lowres = ffmpegdec->lowres;
488   ffmpegdec->context->skip_frame = ffmpegdec->skip_frame;
489
490   /* ffmpeg can draw motion vectors on top of the image (not every decoder
491    * supports it) */
492   ffmpegdec->context->debug_mv = ffmpegdec->debug_mv;
493
494   {
495     GstQuery *query;
496     gboolean is_live;
497
498     if (ffmpegdec->max_threads == 0) {
499       if (!(oclass->in_plugin->capabilities & CODEC_CAP_AUTO_THREADS))
500         ffmpegdec->context->thread_count = gst_ffmpeg_auto_max_threads ();
501       else
502         ffmpegdec->context->thread_count = 0;
503     } else
504       ffmpegdec->context->thread_count = ffmpegdec->max_threads;
505
506     query = gst_query_new_latency ();
507     is_live = FALSE;
508     /* Check if upstream is live. If it isn't we can enable frame based
509      * threading, which is adding latency */
510     if (gst_pad_peer_query (GST_VIDEO_DECODER_SINK_PAD (ffmpegdec), query)) {
511       gst_query_parse_latency (query, &is_live, NULL, NULL);
512     }
513     gst_query_unref (query);
514
515     if (is_live)
516       ffmpegdec->context->thread_type = FF_THREAD_SLICE;
517     else
518       ffmpegdec->context->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
519   }
520
521   /* open codec - we don't select an output pix_fmt yet,
522    * simply because we don't know! We only get it
523    * during playback... */
524   if (!gst_ffmpegviddec_open (ffmpegdec))
525     goto open_failed;
526
527   if (ffmpegdec->input_state)
528     gst_video_codec_state_unref (ffmpegdec->input_state);
529   ffmpegdec->input_state = gst_video_codec_state_ref (state);
530
531   if (ffmpegdec->input_state->info.fps_n) {
532     GstVideoInfo *info = &ffmpegdec->input_state->info;
533     latency = gst_util_uint64_scale_ceil (
534         (ffmpegdec->context->has_b_frames) * GST_SECOND, info->fps_d,
535         info->fps_n);
536   }
537
538   ret = TRUE;
539
540 done:
541   GST_OBJECT_UNLOCK (ffmpegdec);
542
543   if (GST_CLOCK_TIME_IS_VALID (latency))
544     gst_video_decoder_set_latency (decoder, latency, latency);
545
546   return ret;
547
548   /* ERRORS */
549 open_failed:
550   {
551     GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
552     goto done;
553   }
554 }
555
556 typedef struct
557 {
558   GstFFMpegVidDec *ffmpegdec;
559   GstVideoCodecFrame *frame;
560   gboolean mapped;
561   GstVideoFrame vframe;
562   GstBuffer *buffer;
563   AVBufferRef *avbuffer;
564 } GstFFMpegVidDecVideoFrame;
565
566 static GstFFMpegVidDecVideoFrame *
567 gst_ffmpegviddec_video_frame_new (GstFFMpegVidDec * ffmpegdec,
568     GstVideoCodecFrame * frame)
569 {
570   GstFFMpegVidDecVideoFrame *dframe;
571
572   dframe = g_slice_new0 (GstFFMpegVidDecVideoFrame);
573   dframe->ffmpegdec = ffmpegdec;
574   dframe->frame = frame;
575
576   GST_DEBUG_OBJECT (ffmpegdec, "new video frame %p", dframe);
577
578   return dframe;
579 }
580
581 static void
582 gst_ffmpegviddec_video_frame_free (GstFFMpegVidDec * ffmpegdec,
583     GstFFMpegVidDecVideoFrame * frame)
584 {
585   GST_DEBUG_OBJECT (ffmpegdec, "free video frame %p", frame);
586
587   if (frame->mapped)
588     gst_video_frame_unmap (&frame->vframe);
589   gst_video_decoder_release_frame (GST_VIDEO_DECODER (ffmpegdec), frame->frame);
590   gst_buffer_replace (&frame->buffer, NULL);
591   if (frame->avbuffer) {
592     av_buffer_unref (&frame->avbuffer);
593   }
594   g_slice_free (GstFFMpegVidDecVideoFrame, frame);
595 }
596
597 static void
598 dummy_free_buffer (void *opaque, uint8_t * data)
599 {
600   GstFFMpegVidDecVideoFrame *frame = opaque;
601
602   gst_ffmpegviddec_video_frame_free (frame->ffmpegdec, frame);
603 }
604
605 /* This function prepares the pool configuration for direct rendering. To use
606  * this method, the codec should support direct rendering and the pool should
607  * support video meta and video alignment */
608 static void
609 gst_ffmpegvideodec_prepare_dr_pool (GstFFMpegVidDec * ffmpegdec,
610     GstBufferPool * pool, GstVideoInfo * info, GstStructure * config)
611 {
612   GstAllocationParams params;
613   GstVideoAlignment align;
614   GstAllocator *allocator = NULL;
615   gint width, height;
616   gint linesize_align[4];
617   gint i;
618   guint edge;
619   gsize max_align;
620
621   width = GST_VIDEO_INFO_WIDTH (info);
622   height = GST_VIDEO_INFO_HEIGHT (info);
623
624   /* let ffmpeg find the alignment and padding */
625   avcodec_align_dimensions2 (ffmpegdec->context, &width, &height,
626       linesize_align);
627
628   if (ffmpegdec->context->flags & CODEC_FLAG_EMU_EDGE)
629     edge = 0;
630   else
631     edge = avcodec_get_edge_width ();
632
633   /* increase the size for the padding */
634   width += edge << 1;
635   height += edge << 1;
636
637   align.padding_top = edge;
638   align.padding_left = edge;
639   align.padding_right = width - GST_VIDEO_INFO_WIDTH (info) - edge;
640   align.padding_bottom = height - GST_VIDEO_INFO_HEIGHT (info) - edge;
641
642   /* add extra padding to match libav buffer allocation sizes */
643   align.padding_bottom++;
644
645   gst_buffer_pool_config_get_allocator (config, &allocator, &params);
646
647   max_align = DEFAULT_STRIDE_ALIGN;
648   max_align |= params.align;
649
650   for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
651     if (linesize_align[i] > 0)
652       max_align |= linesize_align[i] - 1;
653   }
654
655   for (i = 0; i < GST_VIDEO_MAX_PLANES; i++)
656     align.stride_align[i] = max_align;
657
658   params.align = max_align;
659
660   gst_buffer_pool_config_set_allocator (config, allocator, &params);
661
662   GST_DEBUG_OBJECT (ffmpegdec, "aligned dimension %dx%d -> %dx%d "
663       "padding t:%u l:%u r:%u b:%u, stride_align %d:%d:%d:%d",
664       GST_VIDEO_INFO_WIDTH (info),
665       GST_VIDEO_INFO_HEIGHT (info), width, height, align.padding_top,
666       align.padding_left, align.padding_right, align.padding_bottom,
667       align.stride_align[0], align.stride_align[1], align.stride_align[2],
668       align.stride_align[3]);
669
670   gst_buffer_pool_config_add_option (config,
671       GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
672   gst_buffer_pool_config_set_video_alignment (config, &align);
673 }
674
675 static void
676 gst_ffmpegviddec_ensure_internal_pool (GstFFMpegVidDec * ffmpegdec,
677     AVFrame * picture)
678 {
679   GstAllocationParams params = DEFAULT_ALLOC_PARAM;
680   GstVideoInfo info;
681   GstVideoFormat format;
682   GstCaps *caps;
683   GstStructure *config;
684   gint i;
685
686   if (ffmpegdec->internal_pool != NULL &&
687       ffmpegdec->pool_width == picture->width &&
688       ffmpegdec->pool_height == picture->height &&
689       ffmpegdec->pool_format == picture->format)
690     return;
691
692   GST_DEBUG_OBJECT (ffmpegdec, "Updating internal pool (%i, %i)",
693       picture->width, picture->height);
694
695   format = gst_ffmpeg_pixfmt_to_videoformat (picture->format);
696   gst_video_info_set_format (&info, format, picture->width, picture->height);
697
698   for (i = 0; i < G_N_ELEMENTS (ffmpegdec->stride); i++)
699     ffmpegdec->stride[i] = -1;
700
701   if (ffmpegdec->internal_pool)
702     gst_object_unref (ffmpegdec->internal_pool);
703
704   ffmpegdec->internal_pool = gst_video_buffer_pool_new ();
705   config = gst_buffer_pool_get_config (ffmpegdec->internal_pool);
706
707   caps = gst_video_info_to_caps (&info);
708   gst_buffer_pool_config_set_params (config, caps, info.size, 2, 0);
709   gst_buffer_pool_config_set_allocator (config, NULL, &params);
710   gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
711
712   gst_ffmpegvideodec_prepare_dr_pool (ffmpegdec,
713       ffmpegdec->internal_pool, &info, config);
714   /* generic video pool never fails */
715   gst_buffer_pool_set_config (ffmpegdec->internal_pool, config);
716   gst_caps_unref (caps);
717
718   gst_buffer_pool_set_active (ffmpegdec->internal_pool, TRUE);
719
720   /* Remember pool size so we can detect changes */
721   ffmpegdec->pool_width = picture->width;
722   ffmpegdec->pool_height = picture->height;
723   ffmpegdec->pool_format = picture->format;
724   ffmpegdec->pool_info = info;
725 }
726
727 static gboolean
728 gst_ffmpegviddec_can_direct_render (GstFFMpegVidDec * ffmpegdec)
729 {
730   GstFFMpegVidDecClass *oclass;
731
732   if (!ffmpegdec->direct_rendering)
733     return FALSE;
734
735   oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
736   return ((oclass->in_plugin->capabilities & CODEC_CAP_DR1) == CODEC_CAP_DR1);
737 }
738
739 /* called when ffmpeg wants us to allocate a buffer to write the decoded frame
740  * into. We try to give it memory from our pool */
741 static int
742 gst_ffmpegviddec_get_buffer2 (AVCodecContext * context, AVFrame * picture,
743     int flags)
744 {
745   GstVideoCodecFrame *frame;
746   GstFFMpegVidDecVideoFrame *dframe;
747   GstFFMpegVidDec *ffmpegdec;
748   gint c;
749   GstFlowReturn ret;
750
751   ffmpegdec = (GstFFMpegVidDec *) context->opaque;
752
753   GST_DEBUG_OBJECT (ffmpegdec, "getting buffer picture %p", picture);
754
755   /* apply the last info we have seen to this picture, when we get the
756    * picture back from ffmpeg we can use this to correctly timestamp the output
757    * buffer */
758   GST_DEBUG_OBJECT (ffmpegdec, "opaque value SN %d",
759       (gint32) picture->reordered_opaque);
760
761   frame =
762       gst_video_decoder_get_frame (GST_VIDEO_DECODER (ffmpegdec),
763       picture->reordered_opaque);
764   if (G_UNLIKELY (frame == NULL))
765     goto no_frame;
766
767   /* now it has a buffer allocated, so it is real and will also
768    * be _released */
769   GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame,
770       GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
771
772   if (G_UNLIKELY (frame->output_buffer != NULL))
773     goto duplicate_frame;
774
775   /* GstFFMpegVidDecVideoFrame receives the frame ref */
776   if (picture->opaque) {
777     dframe = picture->opaque;
778     dframe->frame = frame;
779   } else {
780     picture->opaque = dframe =
781         gst_ffmpegviddec_video_frame_new (ffmpegdec, frame);
782   }
783
784   GST_DEBUG_OBJECT (ffmpegdec, "storing opaque %p", dframe);
785
786   if (!gst_ffmpegviddec_can_direct_render (ffmpegdec))
787     goto no_dr;
788
789   gst_ffmpegviddec_ensure_internal_pool (ffmpegdec, picture);
790
791   ret = gst_buffer_pool_acquire_buffer (ffmpegdec->internal_pool,
792       &frame->output_buffer, NULL);
793   if (ret != GST_FLOW_OK)
794     goto alloc_failed;
795
796   /* piggy-backed alloc'ed on the frame,
797    * and there was much rejoicing and we are grateful.
798    * Now take away buffer from frame, we will give it back later when decoded.
799    * This allows multiple request for a buffer per frame; unusual but possible. */
800   gst_buffer_replace (&dframe->buffer, frame->output_buffer);
801   gst_buffer_replace (&frame->output_buffer, NULL);
802
803   /* Fill avpicture */
804   if (!gst_video_frame_map (&dframe->vframe, &ffmpegdec->pool_info,
805           dframe->buffer, GST_MAP_READWRITE))
806     goto map_failed;
807   dframe->mapped = TRUE;
808
809   for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
810     if (c < GST_VIDEO_INFO_N_PLANES (&ffmpegdec->pool_info)) {
811       picture->data[c] = GST_VIDEO_FRAME_PLANE_DATA (&dframe->vframe, c);
812       picture->linesize[c] = GST_VIDEO_FRAME_PLANE_STRIDE (&dframe->vframe, c);
813
814       if (ffmpegdec->stride[c] == -1)
815         ffmpegdec->stride[c] = picture->linesize[c];
816
817       /* libav does not allow stride changes, decide allocation should check
818        * before replacing the internal pool with a downstream pool.
819        * https://bugzilla.gnome.org/show_bug.cgi?id=704769
820        * https://bugzilla.libav.org/show_bug.cgi?id=556
821        */
822       g_assert (picture->linesize[c] == ffmpegdec->stride[c]);
823     } else {
824       picture->data[c] = NULL;
825       picture->linesize[c] = 0;
826     }
827     GST_LOG_OBJECT (ffmpegdec, "linesize %d, data %p", picture->linesize[c],
828         picture->data[c]);
829   }
830
831   picture->buf[0] = av_buffer_create (NULL, 0, dummy_free_buffer, dframe, 0);
832
833   GST_LOG_OBJECT (ffmpegdec, "returned frame %p", dframe->buffer);
834
835   return 0;
836
837 no_dr:
838   {
839     int c;
840     int ret = avcodec_default_get_buffer2 (context, picture, flags);
841
842     GST_LOG_OBJECT (ffmpegdec, "direct rendering disabled, fallback alloc");
843
844     for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
845       ffmpegdec->stride[c] = picture->linesize[c];
846     }
847     /* Wrap our buffer around the default one to be able to have a callback
848      * when our data can be freed. Just putting our data into the first free
849      * buffer might not work if there are too many allocated already
850      */
851     if (picture->buf[0]) {
852       dframe->avbuffer = picture->buf[0];
853       picture->buf[0] =
854           av_buffer_create (picture->buf[0]->data, picture->buf[0]->size,
855           dummy_free_buffer, dframe, 0);
856     } else {
857       picture->buf[0] =
858           av_buffer_create (NULL, 0, dummy_free_buffer, dframe, 0);
859     }
860
861     return ret;
862   }
863 alloc_failed:
864   {
865     GST_ELEMENT_ERROR (ffmpegdec, RESOURCE, FAILED,
866         ("Unable to allocate memory"),
867         ("The downstream pool failed to allocated buffer."));
868     return -1;
869   }
870 map_failed:
871   {
872     GST_ELEMENT_ERROR (ffmpegdec, RESOURCE, OPEN_READ_WRITE,
873         ("Cannot access memory for read and write operation."),
874         ("The video memory allocated from downstream pool could not mapped for"
875             "read and write."));
876     return -1;
877   }
878 duplicate_frame:
879   {
880     GST_WARNING_OBJECT (ffmpegdec, "already alloc'ed output buffer for frame");
881     gst_video_codec_frame_unref (frame);
882     return -1;
883   }
884 no_frame:
885   {
886     GST_WARNING_OBJECT (ffmpegdec, "Couldn't get codec frame !");
887     return -1;
888   }
889 }
890
891 static gboolean
892 picture_changed (GstFFMpegVidDec * ffmpegdec, AVFrame * picture)
893 {
894   gint pic_field_order = 0;
895
896   if (picture->interlaced_frame) {
897     if (picture->repeat_pict)
898       pic_field_order |= GST_VIDEO_BUFFER_FLAG_RFF;
899     if (picture->top_field_first)
900       pic_field_order |= GST_VIDEO_BUFFER_FLAG_TFF;
901   }
902
903   return !(ffmpegdec->pic_width == picture->width
904       && ffmpegdec->pic_height == picture->height
905       && ffmpegdec->pic_pix_fmt == picture->format
906       && ffmpegdec->pic_par_n == picture->sample_aspect_ratio.num
907       && ffmpegdec->pic_par_d == picture->sample_aspect_ratio.den
908       && ffmpegdec->pic_interlaced == picture->interlaced_frame
909       && ffmpegdec->pic_field_order == pic_field_order
910       && ffmpegdec->cur_multiview_mode == ffmpegdec->picture_multiview_mode
911       && ffmpegdec->cur_multiview_flags == ffmpegdec->picture_multiview_flags);
912 }
913
914 static gboolean
915 context_changed (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context)
916 {
917   return !(ffmpegdec->ctx_ticks == context->ticks_per_frame
918       && ffmpegdec->ctx_time_n == context->time_base.num
919       && ffmpegdec->ctx_time_d == context->time_base.den);
920 }
921
922 static gboolean
923 update_video_context (GstFFMpegVidDec * ffmpegdec, AVCodecContext * context,
924     AVFrame * picture)
925 {
926   gint pic_field_order = 0;
927
928   if (picture->interlaced_frame) {
929     if (picture->repeat_pict)
930       pic_field_order |= GST_VIDEO_BUFFER_FLAG_RFF;
931     if (picture->top_field_first)
932       pic_field_order |= GST_VIDEO_BUFFER_FLAG_TFF;
933   }
934
935   if (!picture_changed (ffmpegdec, picture)
936       && !context_changed (ffmpegdec, context))
937     return FALSE;
938
939   GST_DEBUG_OBJECT (ffmpegdec,
940       "Renegotiating video from %dx%d@ %d:%d PAR %d/%d fps pixfmt %d to %dx%d@ %d:%d PAR %d/%d fps pixfmt %d",
941       ffmpegdec->pic_width, ffmpegdec->pic_height,
942       ffmpegdec->pic_par_n, ffmpegdec->pic_par_d,
943       ffmpegdec->ctx_time_n, ffmpegdec->ctx_time_d,
944       ffmpegdec->pic_pix_fmt,
945       picture->width, picture->height,
946       picture->sample_aspect_ratio.num,
947       picture->sample_aspect_ratio.den,
948       context->time_base.num, context->time_base.den, picture->format);
949
950   ffmpegdec->pic_pix_fmt = picture->format;
951   ffmpegdec->pic_width = picture->width;
952   ffmpegdec->pic_height = picture->height;
953   ffmpegdec->pic_par_n = picture->sample_aspect_ratio.num;
954   ffmpegdec->pic_par_d = picture->sample_aspect_ratio.den;
955   ffmpegdec->cur_multiview_mode = ffmpegdec->picture_multiview_mode;
956   ffmpegdec->cur_multiview_flags = ffmpegdec->picture_multiview_flags;
957
958   /* Remember if we have interlaced content and the field order changed
959    * at least once. If that happens, we must be interlace-mode=mixed
960    */
961   if (ffmpegdec->pic_field_order_changed ||
962       (ffmpegdec->pic_field_order != pic_field_order &&
963           ffmpegdec->pic_interlaced))
964     ffmpegdec->pic_field_order_changed = TRUE;
965
966   ffmpegdec->pic_field_order = pic_field_order;
967   ffmpegdec->pic_interlaced = picture->interlaced_frame;
968
969   if (!ffmpegdec->pic_interlaced)
970     ffmpegdec->pic_field_order_changed = FALSE;
971
972   ffmpegdec->ctx_ticks = context->ticks_per_frame;
973   ffmpegdec->ctx_time_n = context->time_base.num;
974   ffmpegdec->ctx_time_d = context->time_base.den;
975
976   return TRUE;
977 }
978
979 static void
980 gst_ffmpegviddec_update_par (GstFFMpegVidDec * ffmpegdec,
981     GstVideoInfo * in_info, GstVideoInfo * out_info)
982 {
983   gboolean demuxer_par_set = FALSE;
984   gboolean decoder_par_set = FALSE;
985   gint demuxer_num = 1, demuxer_denom = 1;
986   gint decoder_num = 1, decoder_denom = 1;
987
988   if (in_info->par_n && in_info->par_d) {
989     demuxer_num = in_info->par_n;
990     demuxer_denom = in_info->par_d;
991     demuxer_par_set = TRUE;
992     GST_DEBUG_OBJECT (ffmpegdec, "Demuxer PAR: %d:%d", demuxer_num,
993         demuxer_denom);
994   }
995
996   if (ffmpegdec->pic_par_n && ffmpegdec->pic_par_d) {
997     decoder_num = ffmpegdec->pic_par_n;
998     decoder_denom = ffmpegdec->pic_par_d;
999     decoder_par_set = TRUE;
1000     GST_DEBUG_OBJECT (ffmpegdec, "Decoder PAR: %d:%d", decoder_num,
1001         decoder_denom);
1002   }
1003
1004   if (!demuxer_par_set && !decoder_par_set)
1005     goto no_par;
1006
1007   if (demuxer_par_set && !decoder_par_set)
1008     goto use_demuxer_par;
1009
1010   if (decoder_par_set && !demuxer_par_set)
1011     goto use_decoder_par;
1012
1013   /* Both the demuxer and the decoder provide a PAR. If one of
1014    * the two PARs is 1:1 and the other one is not, use the one
1015    * that is not 1:1. */
1016   if (demuxer_num == demuxer_denom && decoder_num != decoder_denom)
1017     goto use_decoder_par;
1018
1019   if (decoder_num == decoder_denom && demuxer_num != demuxer_denom)
1020     goto use_demuxer_par;
1021
1022   /* Both PARs are non-1:1, so use the PAR provided by the demuxer */
1023   goto use_demuxer_par;
1024
1025 use_decoder_par:
1026   {
1027     GST_DEBUG_OBJECT (ffmpegdec,
1028         "Setting decoder provided pixel-aspect-ratio of %u:%u", decoder_num,
1029         decoder_denom);
1030     out_info->par_n = decoder_num;
1031     out_info->par_d = decoder_denom;
1032     return;
1033   }
1034 use_demuxer_par:
1035   {
1036     GST_DEBUG_OBJECT (ffmpegdec,
1037         "Setting demuxer provided pixel-aspect-ratio of %u:%u", demuxer_num,
1038         demuxer_denom);
1039     out_info->par_n = demuxer_num;
1040     out_info->par_d = demuxer_denom;
1041     return;
1042   }
1043 no_par:
1044   {
1045     GST_DEBUG_OBJECT (ffmpegdec,
1046         "Neither demuxer nor codec provide a pixel-aspect-ratio");
1047     out_info->par_n = 1;
1048     out_info->par_d = 1;
1049     return;
1050   }
1051 }
1052
1053 static GstVideoMultiviewMode
1054 stereo_av_to_gst (enum AVStereo3DType type)
1055 {
1056   switch (type) {
1057     case AV_STEREO3D_SIDEBYSIDE:
1058       return GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
1059     case AV_STEREO3D_TOPBOTTOM:
1060       return GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
1061     case AV_STEREO3D_FRAMESEQUENCE:
1062       return GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
1063     case AV_STEREO3D_CHECKERBOARD:
1064       return GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
1065     case AV_STEREO3D_SIDEBYSIDE_QUINCUNX:
1066       return GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX;
1067     case AV_STEREO3D_LINES:
1068       return GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED;
1069     case AV_STEREO3D_COLUMNS:
1070       return GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED;
1071     default:
1072       break;
1073   }
1074
1075   return GST_VIDEO_MULTIVIEW_MODE_NONE;
1076 }
1077
1078 static gboolean
1079 gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec,
1080     AVCodecContext * context, AVFrame * picture)
1081 {
1082   GstVideoFormat fmt;
1083   GstVideoInfo *in_info, *out_info;
1084   GstVideoCodecState *output_state;
1085   gint fps_n, fps_d;
1086   GstClockTime latency;
1087   GstStructure *in_s;
1088
1089   if (!update_video_context (ffmpegdec, context, picture))
1090     return TRUE;
1091
1092   fmt = gst_ffmpeg_pixfmt_to_videoformat (ffmpegdec->pic_pix_fmt);
1093   if (G_UNLIKELY (fmt == GST_VIDEO_FORMAT_UNKNOWN))
1094     goto unknown_format;
1095
1096   output_state =
1097       gst_video_decoder_set_output_state (GST_VIDEO_DECODER (ffmpegdec), fmt,
1098       ffmpegdec->pic_width, ffmpegdec->pic_height, ffmpegdec->input_state);
1099   if (ffmpegdec->output_state)
1100     gst_video_codec_state_unref (ffmpegdec->output_state);
1101   ffmpegdec->output_state = output_state;
1102
1103   in_info = &ffmpegdec->input_state->info;
1104   out_info = &ffmpegdec->output_state->info;
1105
1106   /* set the interlaced flag */
1107   in_s = gst_caps_get_structure (ffmpegdec->input_state->caps, 0);
1108
1109   if (!gst_structure_has_field (in_s, "interlace-mode")) {
1110     if (ffmpegdec->pic_interlaced) {
1111       if (ffmpegdec->pic_field_order_changed ||
1112           (ffmpegdec->pic_field_order & GST_VIDEO_BUFFER_FLAG_RFF)) {
1113         out_info->interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
1114       } else {
1115         out_info->interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
1116         if ((ffmpegdec->pic_field_order & GST_VIDEO_BUFFER_FLAG_TFF))
1117           GST_VIDEO_INFO_FIELD_ORDER (out_info) =
1118               GST_VIDEO_FIELD_ORDER_TOP_FIELD_FIRST;
1119         else
1120           GST_VIDEO_INFO_FIELD_ORDER (out_info) =
1121               GST_VIDEO_FIELD_ORDER_BOTTOM_FIELD_FIRST;
1122       }
1123     } else {
1124       out_info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
1125     }
1126   }
1127
1128   if (!gst_structure_has_field (in_s, "chroma-site")) {
1129     switch (context->chroma_sample_location) {
1130       case AVCHROMA_LOC_LEFT:
1131         out_info->chroma_site = GST_VIDEO_CHROMA_SITE_MPEG2;
1132         break;
1133       case AVCHROMA_LOC_CENTER:
1134         out_info->chroma_site = GST_VIDEO_CHROMA_SITE_JPEG;
1135         break;
1136       case AVCHROMA_LOC_TOPLEFT:
1137         out_info->chroma_site = GST_VIDEO_CHROMA_SITE_DV;
1138         break;
1139       case AVCHROMA_LOC_TOP:
1140         out_info->chroma_site = GST_VIDEO_CHROMA_SITE_V_COSITED;
1141         break;
1142       default:
1143         break;
1144     }
1145   }
1146
1147   if (!gst_structure_has_field (in_s, "colorimetry")
1148       || in_info->colorimetry.primaries == GST_VIDEO_COLOR_PRIMARIES_UNKNOWN) {
1149     switch (context->color_primaries) {
1150       case AVCOL_PRI_BT709:
1151         out_info->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
1152         break;
1153       case AVCOL_PRI_BT470M:
1154         out_info->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M;
1155         break;
1156       case AVCOL_PRI_BT470BG:
1157         out_info->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
1158         break;
1159       case AVCOL_PRI_SMPTE170M:
1160         out_info->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
1161         break;
1162       case AVCOL_PRI_SMPTE240M:
1163         out_info->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
1164         break;
1165       case AVCOL_PRI_FILM:
1166         out_info->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_FILM;
1167         break;
1168       case AVCOL_PRI_BT2020:
1169         out_info->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
1170         break;
1171       default:
1172         break;
1173     }
1174   }
1175
1176   if (!gst_structure_has_field (in_s, "colorimetry")
1177       || in_info->colorimetry.transfer == GST_VIDEO_TRANSFER_UNKNOWN) {
1178     switch (context->color_trc) {
1179       case AVCOL_TRC_BT2020_10:
1180       case AVCOL_TRC_BT709:
1181       case AVCOL_TRC_SMPTE170M:
1182         out_info->colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
1183         break;
1184       case AVCOL_TRC_GAMMA22:
1185         out_info->colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA22;
1186         break;
1187       case AVCOL_TRC_GAMMA28:
1188         out_info->colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA28;
1189         break;
1190       case AVCOL_TRC_SMPTE240M:
1191         out_info->colorimetry.transfer = GST_VIDEO_TRANSFER_SMPTE240M;
1192         break;
1193       case AVCOL_TRC_LINEAR:
1194         out_info->colorimetry.transfer = GST_VIDEO_TRANSFER_GAMMA10;
1195         break;
1196       case AVCOL_TRC_LOG:
1197         out_info->colorimetry.transfer = GST_VIDEO_TRANSFER_LOG100;
1198         break;
1199       case AVCOL_TRC_LOG_SQRT:
1200         out_info->colorimetry.transfer = GST_VIDEO_TRANSFER_LOG316;
1201         break;
1202       case AVCOL_TRC_BT2020_12:
1203         out_info->colorimetry.transfer = GST_VIDEO_TRANSFER_BT2020_12;
1204         break;
1205       default:
1206         break;
1207     }
1208   }
1209
1210   if (!gst_structure_has_field (in_s, "colorimetry")
1211       || in_info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_UNKNOWN) {
1212     switch (context->colorspace) {
1213       case AVCOL_SPC_RGB:
1214         out_info->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
1215         break;
1216       case AVCOL_SPC_BT709:
1217         out_info->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
1218         break;
1219       case AVCOL_SPC_FCC:
1220         out_info->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_FCC;
1221         break;
1222       case AVCOL_SPC_BT470BG:
1223       case AVCOL_SPC_SMPTE170M:
1224         out_info->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
1225         break;
1226       case AVCOL_SPC_SMPTE240M:
1227         out_info->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
1228         break;
1229       case AVCOL_SPC_BT2020_NCL:
1230         out_info->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
1231         break;
1232       default:
1233         break;
1234     }
1235   }
1236
1237   if (!gst_structure_has_field (in_s, "colorimetry")
1238       || in_info->colorimetry.range == GST_VIDEO_COLOR_RANGE_UNKNOWN) {
1239     if (context->color_range == AVCOL_RANGE_JPEG) {
1240       out_info->colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255;
1241     } else {
1242       out_info->colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
1243     }
1244   }
1245
1246   /* try to find a good framerate */
1247   if ((in_info->fps_d && in_info->fps_n) ||
1248       GST_VIDEO_INFO_FLAG_IS_SET (in_info, GST_VIDEO_FLAG_VARIABLE_FPS)) {
1249     /* take framerate from input when it was specified (#313970) */
1250     fps_n = in_info->fps_n;
1251     fps_d = in_info->fps_d;
1252   } else {
1253     fps_n = ffmpegdec->ctx_time_d / ffmpegdec->ctx_ticks;
1254     fps_d = ffmpegdec->ctx_time_n;
1255
1256     if (!fps_d) {
1257       GST_LOG_OBJECT (ffmpegdec, "invalid framerate: %d/0, -> %d/1", fps_n,
1258           fps_n);
1259       fps_d = 1;
1260     }
1261     if (gst_util_fraction_compare (fps_n, fps_d, 1000, 1) > 0) {
1262       GST_LOG_OBJECT (ffmpegdec, "excessive framerate: %d/%d, -> 0/1", fps_n,
1263           fps_d);
1264       fps_n = 0;
1265       fps_d = 1;
1266     }
1267   }
1268
1269   GST_LOG_OBJECT (ffmpegdec, "setting framerate: %d/%d", fps_n, fps_d);
1270   out_info->fps_n = fps_n;
1271   out_info->fps_d = fps_d;
1272
1273   /* calculate and update par now */
1274   gst_ffmpegviddec_update_par (ffmpegdec, in_info, out_info);
1275
1276   GST_VIDEO_INFO_MULTIVIEW_MODE (out_info) = ffmpegdec->cur_multiview_mode;
1277   GST_VIDEO_INFO_MULTIVIEW_FLAGS (out_info) = ffmpegdec->cur_multiview_flags;
1278
1279   if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (ffmpegdec)))
1280     goto negotiate_failed;
1281
1282   /* The decoder is configured, we now know the true latency */
1283   if (fps_n) {
1284     latency =
1285         gst_util_uint64_scale_ceil (ffmpegdec->context->has_b_frames *
1286         GST_SECOND, fps_d, fps_n);
1287     gst_video_decoder_set_latency (GST_VIDEO_DECODER (ffmpegdec), latency,
1288         latency);
1289   }
1290
1291   return TRUE;
1292
1293   /* ERRORS */
1294 unknown_format:
1295   {
1296     GST_ERROR_OBJECT (ffmpegdec,
1297         "decoder requires a video format unsupported by GStreamer");
1298     return FALSE;
1299   }
1300 negotiate_failed:
1301   {
1302     /* Reset so we try again next time even if force==FALSE */
1303     ffmpegdec->pic_pix_fmt = 0;
1304     ffmpegdec->pic_width = 0;
1305     ffmpegdec->pic_height = 0;
1306     ffmpegdec->pic_par_n = 0;
1307     ffmpegdec->pic_par_d = 0;
1308     ffmpegdec->pic_interlaced = 0;
1309     ffmpegdec->pic_field_order = 0;
1310     ffmpegdec->pic_field_order_changed = FALSE;
1311     ffmpegdec->ctx_ticks = 0;
1312     ffmpegdec->ctx_time_n = 0;
1313     ffmpegdec->ctx_time_d = 0;
1314
1315     GST_ERROR_OBJECT (ffmpegdec, "negotiation failed");
1316     return FALSE;
1317   }
1318 }
1319
1320 /* perform qos calculations before decoding the next frame.
1321  *
1322  * Sets the skip_frame flag and if things are really bad, skips to the next
1323  * keyframe.
1324  *
1325  */
1326 static void
1327 gst_ffmpegviddec_do_qos (GstFFMpegVidDec * ffmpegdec,
1328     GstVideoCodecFrame * frame, gboolean * mode_switch)
1329 {
1330   GstClockTimeDiff diff;
1331   GstSegmentFlags skip_flags =
1332       GST_VIDEO_DECODER_INPUT_SEGMENT (ffmpegdec).flags;
1333
1334   *mode_switch = FALSE;
1335
1336   if (frame == NULL)
1337     return;
1338
1339   if (skip_flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) {
1340     ffmpegdec->context->skip_frame = AVDISCARD_NONKEY;
1341     *mode_switch = TRUE;
1342   } else if (skip_flags & GST_SEGMENT_FLAG_TRICKMODE) {
1343     ffmpegdec->context->skip_frame = AVDISCARD_NONREF;
1344     *mode_switch = TRUE;
1345   }
1346
1347   if (*mode_switch == TRUE) {
1348     /* We've already switched mode, we can return straight away
1349      * without any further calculation */
1350     return;
1351   }
1352
1353   diff =
1354       gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (ffmpegdec),
1355       frame);
1356
1357   /* if we don't have timing info, then we don't do QoS */
1358   if (G_UNLIKELY (diff == G_MAXINT64)) {
1359     /* Ensure the skipping strategy is the default one */
1360     ffmpegdec->context->skip_frame = ffmpegdec->skip_frame;
1361     return;
1362   }
1363
1364   GST_DEBUG_OBJECT (ffmpegdec, "decoding time %" G_GINT64_FORMAT, diff);
1365
1366   if (diff > 0 && ffmpegdec->context->skip_frame != AVDISCARD_DEFAULT) {
1367     ffmpegdec->context->skip_frame = AVDISCARD_DEFAULT;
1368     *mode_switch = TRUE;
1369     GST_DEBUG_OBJECT (ffmpegdec, "QOS: normal mode");
1370   }
1371
1372   else if (diff <= 0 && ffmpegdec->context->skip_frame != AVDISCARD_NONREF) {
1373     ffmpegdec->context->skip_frame = AVDISCARD_NONREF;
1374     *mode_switch = TRUE;
1375     GST_DEBUG_OBJECT (ffmpegdec,
1376         "QOS: hurry up, diff %" G_GINT64_FORMAT " >= 0", diff);
1377   }
1378 }
1379
1380 /* get an outbuf buffer with the current picture */
1381 static GstFlowReturn
1382 get_output_buffer (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame)
1383 {
1384   GstFlowReturn ret = GST_FLOW_OK;
1385   AVFrame pic, *outpic;
1386   GstVideoFrame vframe;
1387   GstVideoInfo *info;
1388   gint c;
1389
1390   GST_LOG_OBJECT (ffmpegdec, "get output buffer");
1391
1392   if (!ffmpegdec->output_state)
1393     goto not_negotiated;
1394
1395   ret =
1396       gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (ffmpegdec),
1397       frame);
1398   if (G_UNLIKELY (ret != GST_FLOW_OK))
1399     goto alloc_failed;
1400
1401   /* original ffmpeg code does not handle odd sizes correctly.
1402    * This patched up version does */
1403   /* Fill avpicture */
1404   info = &ffmpegdec->output_state->info;
1405   if (!gst_video_frame_map (&vframe, info, frame->output_buffer,
1406           GST_MAP_READ | GST_MAP_WRITE))
1407     goto map_failed;
1408
1409   memset (&pic, 0, sizeof (pic));
1410   pic.format = ffmpegdec->pic_pix_fmt;
1411   pic.width = GST_VIDEO_FRAME_WIDTH (&vframe);
1412   pic.height = GST_VIDEO_FRAME_HEIGHT (&vframe);
1413   for (c = 0; c < AV_NUM_DATA_POINTERS; c++) {
1414     if (c < GST_VIDEO_INFO_N_PLANES (info)) {
1415       pic.data[c] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, c);
1416       pic.linesize[c] = GST_VIDEO_FRAME_PLANE_STRIDE (&vframe, c);
1417       GST_LOG_OBJECT (ffmpegdec, "[%i] linesize %d, data %p", c,
1418           pic.linesize[c], pic.data[c]);
1419     } else {
1420       pic.data[c] = NULL;
1421       pic.linesize[c] = 0;
1422     }
1423   }
1424
1425   outpic = ffmpegdec->picture;
1426
1427   if (av_frame_copy (&pic, outpic) != 0) {
1428     GST_ERROR_OBJECT (ffmpegdec, "Failed to copy output frame");
1429     ret = GST_FLOW_ERROR;
1430   }
1431
1432   gst_video_frame_unmap (&vframe);
1433
1434   ffmpegdec->picture->reordered_opaque = -1;
1435
1436   return ret;
1437
1438   /* special cases */
1439 alloc_failed:
1440   {
1441     GST_ELEMENT_ERROR (ffmpegdec, RESOURCE, FAILED,
1442         ("Unable to allocate memory"),
1443         ("The downstream pool failed to allocated buffer."));
1444     return ret;
1445   }
1446 map_failed:
1447   {
1448     GST_ELEMENT_ERROR (ffmpegdec, RESOURCE, OPEN_READ_WRITE,
1449         ("Cannot access memory for read and write operation."),
1450         ("The video memory allocated from downstream pool could not mapped for"
1451             "read and write."));
1452     return ret;
1453   }
1454 not_negotiated:
1455   {
1456     GST_DEBUG_OBJECT (ffmpegdec, "not negotiated");
1457     return GST_FLOW_NOT_NEGOTIATED;
1458   }
1459 }
1460
1461 static void
1462 gst_avpacket_init (AVPacket * packet, guint8 * data, guint size)
1463 {
1464   memset (packet, 0, sizeof (AVPacket));
1465   packet->data = data;
1466   packet->size = size;
1467 }
1468
1469 /* gst_ffmpegviddec_[video|audio]_frame:
1470  * ffmpegdec:
1471  * data: pointer to the data to decode
1472  * size: size of data in bytes
1473  * in_timestamp: incoming timestamp.
1474  * in_duration: incoming duration.
1475  * in_offset: incoming offset (frame number).
1476  * ret: Return flow.
1477  *
1478  * Returns: number of bytes used in decoding. The check for successful decode is
1479  *   outbuf being non-NULL.
1480  */
1481 static gint
1482 gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
1483     guint8 * data, guint size, gint * have_data, GstVideoCodecFrame * frame,
1484     GstFlowReturn * ret)
1485 {
1486   gint len = -1;
1487   gboolean mode_switch;
1488   GstVideoCodecFrame *out_frame;
1489   GstFFMpegVidDecVideoFrame *out_dframe;
1490   AVPacket packet;
1491   GstBufferPool *pool;
1492
1493   *ret = GST_FLOW_OK;
1494
1495   /* in case we skip frames */
1496   ffmpegdec->picture->pict_type = -1;
1497
1498   /* run QoS code, we don't stop decoding the frame when we are late because
1499    * else we might skip a reference frame */
1500   gst_ffmpegviddec_do_qos (ffmpegdec, frame, &mode_switch);
1501
1502   if (frame) {
1503     /* save reference to the timing info */
1504     ffmpegdec->context->reordered_opaque = (gint64) frame->system_frame_number;
1505     ffmpegdec->picture->reordered_opaque = (gint64) frame->system_frame_number;
1506
1507     GST_DEBUG_OBJECT (ffmpegdec, "stored opaque values idx %d",
1508         frame->system_frame_number);
1509   }
1510
1511   /* now decode the frame */
1512   gst_avpacket_init (&packet, data, size);
1513
1514   if (ffmpegdec->palette) {
1515     guint8 *pal;
1516
1517     pal = av_packet_new_side_data (&packet, AV_PKT_DATA_PALETTE,
1518         AVPALETTE_SIZE);
1519     gst_buffer_extract (ffmpegdec->palette, 0, pal, AVPALETTE_SIZE);
1520     GST_DEBUG_OBJECT (ffmpegdec, "copy pal %p %p", &packet, pal);
1521   }
1522
1523   /* This might call into get_buffer() from another thread,
1524    * which would cause a deadlock. Release the lock here
1525    * and taking it again later seems safe
1526    * See https://bugzilla.gnome.org/show_bug.cgi?id=726020
1527    */
1528   GST_VIDEO_DECODER_STREAM_UNLOCK (ffmpegdec);
1529   len = avcodec_decode_video2 (ffmpegdec->context,
1530       ffmpegdec->picture, have_data, &packet);
1531   GST_VIDEO_DECODER_STREAM_LOCK (ffmpegdec);
1532
1533   GST_DEBUG_OBJECT (ffmpegdec, "after decode: len %d, have_data %d",
1534       len, *have_data);
1535
1536   /* when we are in skip_frame mode, don't complain when ffmpeg returned
1537    * no data because we told it to skip stuff. */
1538   if (len < 0 && (mode_switch || ffmpegdec->context->skip_frame))
1539     len = 0;
1540
1541   /* no data, we're done */
1542   if (len < 0 || *have_data == 0)
1543     goto beach;
1544
1545   /* get the output picture timing info again */
1546   out_dframe = ffmpegdec->picture->opaque;
1547   out_frame = gst_video_codec_frame_ref (out_dframe->frame);
1548
1549   /* also give back a buffer allocated by the frame, if any */
1550   gst_buffer_replace (&out_frame->output_buffer, out_dframe->buffer);
1551   gst_buffer_replace (&out_dframe->buffer, NULL);
1552
1553   /* Extract auxilliary info not stored in the main AVframe */
1554   {
1555     GstVideoInfo *in_info = &ffmpegdec->input_state->info;
1556     /* Take multiview mode from upstream if present */
1557     ffmpegdec->picture_multiview_mode = GST_VIDEO_INFO_MULTIVIEW_MODE (in_info);
1558     ffmpegdec->picture_multiview_flags =
1559         GST_VIDEO_INFO_MULTIVIEW_FLAGS (in_info);
1560
1561     /* Otherwise, see if there's info in the frame */
1562     if (ffmpegdec->picture_multiview_mode == GST_VIDEO_MULTIVIEW_MODE_NONE) {
1563       AVFrameSideData *side_data =
1564           av_frame_get_side_data (ffmpegdec->picture, AV_FRAME_DATA_STEREO3D);
1565       if (side_data) {
1566         AVStereo3D *stereo = (AVStereo3D *) side_data->data;
1567         ffmpegdec->picture_multiview_mode = stereo_av_to_gst (stereo->type);
1568         if (stereo->flags & AV_STEREO3D_FLAG_INVERT) {
1569           ffmpegdec->picture_multiview_flags =
1570               GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
1571         } else {
1572           ffmpegdec->picture_multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
1573         }
1574       }
1575     }
1576   }
1577
1578   GST_DEBUG_OBJECT (ffmpegdec,
1579       "pts %" G_GUINT64_FORMAT " duration %" G_GUINT64_FORMAT,
1580       out_frame->pts, out_frame->duration);
1581   GST_DEBUG_OBJECT (ffmpegdec, "picture: pts %" G_GUINT64_FORMAT,
1582       (guint64) ffmpegdec->picture->pts);
1583   GST_DEBUG_OBJECT (ffmpegdec, "picture: num %d",
1584       ffmpegdec->picture->coded_picture_number);
1585   GST_DEBUG_OBJECT (ffmpegdec, "picture: display %d",
1586       ffmpegdec->picture->display_picture_number);
1587   GST_DEBUG_OBJECT (ffmpegdec, "picture: opaque %p",
1588       ffmpegdec->picture->opaque);
1589   GST_DEBUG_OBJECT (ffmpegdec, "picture: reordered opaque %" G_GUINT64_FORMAT,
1590       (guint64) ffmpegdec->picture->reordered_opaque);
1591   GST_DEBUG_OBJECT (ffmpegdec, "repeat_pict:%d",
1592       ffmpegdec->picture->repeat_pict);
1593   GST_DEBUG_OBJECT (ffmpegdec, "corrupted frame: %d",
1594       ! !(ffmpegdec->picture->flags & AV_FRAME_FLAG_CORRUPT));
1595
1596   if (!gst_ffmpegviddec_negotiate (ffmpegdec, ffmpegdec->context,
1597           ffmpegdec->picture))
1598     goto negotiation_error;
1599
1600   pool = gst_video_decoder_get_buffer_pool (GST_VIDEO_DECODER (ffmpegdec));
1601   if (G_UNLIKELY (out_frame->output_buffer == NULL)) {
1602     *ret = get_output_buffer (ffmpegdec, out_frame);
1603   } else if (G_UNLIKELY (out_frame->output_buffer->pool != pool)) {
1604     GstBuffer *tmp = out_frame->output_buffer;
1605     out_frame->output_buffer = NULL;
1606     *ret = get_output_buffer (ffmpegdec, out_frame);
1607     gst_buffer_unref (tmp);
1608   }
1609 #ifndef G_DISABLE_ASSERT
1610   else {
1611     GstVideoMeta *vmeta = gst_buffer_get_video_meta (out_frame->output_buffer);
1612     if (vmeta) {
1613       GstVideoInfo *info = &ffmpegdec->output_state->info;
1614       g_assert (vmeta->width == GST_VIDEO_INFO_WIDTH (info));
1615       g_assert (vmeta->height == GST_VIDEO_INFO_HEIGHT (info));
1616     }
1617   }
1618 #endif
1619   gst_object_unref (pool);
1620
1621   if (G_UNLIKELY (*ret != GST_FLOW_OK))
1622     goto no_output;
1623
1624   /* Mark corrupted frames as corrupted */
1625   if (ffmpegdec->picture->flags & AV_FRAME_FLAG_CORRUPT)
1626     GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_BUFFER_FLAG_CORRUPTED);
1627
1628   if (ffmpegdec->pic_interlaced) {
1629     /* set interlaced flags */
1630     if (ffmpegdec->picture->repeat_pict)
1631       GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_RFF);
1632     if (ffmpegdec->picture->top_field_first)
1633       GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
1634     if (ffmpegdec->picture->interlaced_frame)
1635       GST_BUFFER_FLAG_SET (out_frame->output_buffer,
1636           GST_VIDEO_BUFFER_FLAG_INTERLACED);
1637   }
1638
1639   {
1640     AVFrameSideData *side_data =
1641         av_frame_get_side_data (ffmpegdec->picture, AV_FRAME_DATA_A53_CC);
1642     if (side_data) {
1643       GST_LOG_OBJECT (ffmpegdec, "Found CC of size %d", side_data->size);
1644       GST_MEMDUMP ("A53 CC", side_data->data, side_data->size);
1645       out_frame->output_buffer =
1646           gst_buffer_make_writable (out_frame->output_buffer);
1647       gst_buffer_add_video_caption_meta (out_frame->output_buffer,
1648           GST_VIDEO_CAPTION_TYPE_CEA708_RAW, side_data->data, side_data->size);
1649     }
1650   }
1651
1652   /* cleaning time */
1653   /* so we decoded this frame, frames preceding it in decoding order
1654    * that still do not have a buffer allocated seem rather useless,
1655    * and can be discarded, due to e.g. misparsed bogus frame
1656    * or non-keyframe in skipped decoding, ...
1657    * In any case, not likely to be seen again, so discard those,
1658    * before they pile up and/or mess with timestamping */
1659   {
1660     GList *l, *ol;
1661     GstVideoDecoder *dec = GST_VIDEO_DECODER (ffmpegdec);
1662     gboolean old = TRUE;
1663
1664     ol = l = gst_video_decoder_get_frames (dec);
1665     while (l) {
1666       GstVideoCodecFrame *tmp = l->data;
1667
1668       if (tmp == frame)
1669         old = FALSE;
1670
1671       if (old && GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (tmp)) {
1672         GST_LOG_OBJECT (dec,
1673             "discarding ghost frame %p (#%d) PTS:%" GST_TIME_FORMAT " DTS:%"
1674             GST_TIME_FORMAT, tmp, tmp->system_frame_number,
1675             GST_TIME_ARGS (tmp->pts), GST_TIME_ARGS (tmp->dts));
1676         /* drop extra ref and remove from frame list */
1677         gst_video_decoder_release_frame (dec, tmp);
1678       } else {
1679         /* drop extra ref we got */
1680         gst_video_codec_frame_unref (tmp);
1681       }
1682       l = l->next;
1683     }
1684     g_list_free (ol);
1685   }
1686
1687   av_frame_unref (ffmpegdec->picture);
1688
1689   /* FIXME: Ideally we would remap the buffer read-only now before pushing but
1690    * libav might still have a reference to it!
1691    */
1692   *ret =
1693       gst_video_decoder_finish_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
1694
1695 beach:
1696   GST_DEBUG_OBJECT (ffmpegdec, "return flow %s, len %d",
1697       gst_flow_get_name (*ret), len);
1698   return len;
1699
1700   /* special cases */
1701 no_output:
1702   {
1703     GST_DEBUG_OBJECT (ffmpegdec, "no output buffer");
1704     gst_video_decoder_drop_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
1705     len = -1;
1706     goto beach;
1707   }
1708
1709 negotiation_error:
1710   {
1711     if (GST_PAD_IS_FLUSHING (GST_VIDEO_DECODER_SRC_PAD (ffmpegdec))) {
1712       *ret = GST_FLOW_FLUSHING;
1713       goto beach;
1714     }
1715     GST_WARNING_OBJECT (ffmpegdec, "Error negotiating format");
1716     *ret = GST_FLOW_NOT_NEGOTIATED;
1717     goto beach;
1718   }
1719 }
1720
1721
1722 /* gst_ffmpegviddec_frame:
1723  * ffmpegdec:
1724  * data: pointer to the data to decode
1725  * size: size of data in bytes
1726  * got_data: 0 if no data was decoded, != 0 otherwise.
1727  * in_time: timestamp of data
1728  * in_duration: duration of data
1729  * ret: GstFlowReturn to return in the chain function
1730  *
1731  * Decode the given frame and pushes it downstream.
1732  *
1733  * Returns: Number of bytes used in decoding, -1 on error/failure.
1734  */
1735
1736 static gint
1737 gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec,
1738     guint8 * data, guint size, gint * have_data, GstVideoCodecFrame * frame,
1739     GstFlowReturn * ret)
1740 {
1741   GstFFMpegVidDecClass *oclass;
1742   gint len = 0;
1743
1744   if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
1745     goto no_codec;
1746
1747   GST_LOG_OBJECT (ffmpegdec, "data:%p, size:%d", data, size);
1748
1749   *ret = GST_FLOW_OK;
1750   ffmpegdec->context->frame_number++;
1751
1752   oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1753
1754   len =
1755       gst_ffmpegviddec_video_frame (ffmpegdec, data, size, have_data, frame,
1756       ret);
1757
1758   if (len < 0) {
1759     GST_WARNING_OBJECT (ffmpegdec,
1760         "avdec_%s: decoding error (len: %d, have_data: %d)",
1761         oclass->in_plugin->name, len, *have_data);
1762   }
1763
1764   return len;
1765
1766   /* ERRORS */
1767 no_codec:
1768   {
1769     GST_ERROR_OBJECT (ffmpegdec, "no codec context");
1770     *ret = GST_FLOW_NOT_NEGOTIATED;
1771     return -1;
1772   }
1773 }
1774
1775 static GstFlowReturn
1776 gst_ffmpegviddec_drain (GstVideoDecoder * decoder)
1777 {
1778   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
1779   GstFFMpegVidDecClass *oclass;
1780
1781   if (!ffmpegdec->opened)
1782     return GST_FLOW_OK;
1783
1784   oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1785
1786   if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
1787     gint have_data, len;
1788     GstFlowReturn ret;
1789
1790     GST_LOG_OBJECT (ffmpegdec,
1791         "codec has delay capabilities, calling until ffmpeg has drained everything");
1792
1793     do {
1794       len = gst_ffmpegviddec_frame (ffmpegdec, NULL, 0, &have_data, NULL, &ret);
1795     } while (len >= 0 && have_data == 1 && ret == GST_FLOW_OK);
1796   }
1797
1798   return GST_FLOW_OK;
1799 }
1800
1801 static GstFlowReturn
1802 gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
1803     GstVideoCodecFrame * frame)
1804 {
1805   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
1806   guint8 *data, *bdata;
1807   gint size, len, have_data, bsize;
1808   GstMapInfo minfo;
1809   GstFlowReturn ret = GST_FLOW_OK;
1810   gboolean do_padding;
1811
1812   GST_LOG_OBJECT (ffmpegdec,
1813       "Received new data of size %" G_GSIZE_FORMAT ", dts %" GST_TIME_FORMAT
1814       ", pts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
1815       gst_buffer_get_size (frame->input_buffer), GST_TIME_ARGS (frame->dts),
1816       GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->duration));
1817
1818   if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
1819     GST_ELEMENT_ERROR (ffmpegdec, STREAM, DECODE, ("Decoding problem"),
1820         ("Failed to map buffer for reading"));
1821     return GST_FLOW_ERROR;
1822   }
1823
1824   /* treat frame as void until a buffer is requested for it */
1825   GST_VIDEO_CODEC_FRAME_FLAG_SET (frame,
1826       GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
1827
1828   bdata = minfo.data;
1829   bsize = minfo.size;
1830
1831   if (bsize > 0 && (!GST_MEMORY_IS_ZERO_PADDED (minfo.memory)
1832           || (minfo.maxsize - minfo.size) < FF_INPUT_BUFFER_PADDING_SIZE)) {
1833     /* add padding */
1834     if (ffmpegdec->padded_size < bsize + FF_INPUT_BUFFER_PADDING_SIZE) {
1835       ffmpegdec->padded_size = bsize + FF_INPUT_BUFFER_PADDING_SIZE;
1836       ffmpegdec->padded = g_realloc (ffmpegdec->padded, ffmpegdec->padded_size);
1837       GST_LOG_OBJECT (ffmpegdec, "resized padding buffer to %d",
1838           ffmpegdec->padded_size);
1839     }
1840     GST_CAT_TRACE_OBJECT (CAT_PERFORMANCE, ffmpegdec,
1841         "Copy input to add padding");
1842     memcpy (ffmpegdec->padded, bdata, bsize);
1843     memset (ffmpegdec->padded + bsize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
1844
1845     bdata = ffmpegdec->padded;
1846     do_padding = TRUE;
1847   } else {
1848     do_padding = FALSE;
1849   }
1850
1851   do {
1852     guint8 tmp_padding[FF_INPUT_BUFFER_PADDING_SIZE];
1853
1854     /* parse, if at all possible */
1855     data = bdata;
1856     size = bsize;
1857
1858     if (do_padding) {
1859       /* add temporary padding */
1860       GST_CAT_TRACE_OBJECT (CAT_PERFORMANCE, ffmpegdec,
1861           "Add temporary input padding");
1862       memcpy (tmp_padding, data + size, FF_INPUT_BUFFER_PADDING_SIZE);
1863       memset (data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
1864     }
1865
1866     /* decode a frame of audio/video now */
1867     len =
1868         gst_ffmpegviddec_frame (ffmpegdec, data, size, &have_data, frame, &ret);
1869
1870     if (ret != GST_FLOW_OK) {
1871       GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
1872           gst_flow_get_name (ret));
1873       /* bad flow return, make sure we discard all data and exit */
1874       bsize = 0;
1875       break;
1876     }
1877
1878     if (do_padding) {
1879       memcpy (data + size, tmp_padding, FF_INPUT_BUFFER_PADDING_SIZE);
1880     }
1881
1882     if (len == 0 && have_data == 0) {
1883       /* nothing was decoded, this could be because no data was available or
1884        * because we were skipping frames.
1885        * If we have no context we must exit and wait for more data, we keep the
1886        * data we tried. */
1887       GST_LOG_OBJECT (ffmpegdec, "Decoding didn't return any data, breaking");
1888       break;
1889     }
1890
1891     if (len < 0) {
1892       /* a decoding error happened, we must break and try again with next data. */
1893       GST_LOG_OBJECT (ffmpegdec, "Decoding error, breaking");
1894       bsize = 0;
1895       break;
1896     }
1897
1898     /* prepare for the next round, for codecs with a context we did this
1899      * already when using the parser. */
1900     bsize -= len;
1901     bdata += len;
1902
1903     do_padding = TRUE;
1904
1905     GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0).  bsize:%d , bdata:%p",
1906         bsize, bdata);
1907   } while (bsize > 0);
1908
1909   if (bsize > 0)
1910     GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize);
1911
1912   gst_buffer_unmap (frame->input_buffer, &minfo);
1913   gst_video_codec_frame_unref (frame);
1914
1915   return ret;
1916 }
1917
1918 static gboolean
1919 gst_ffmpegviddec_start (GstVideoDecoder * decoder)
1920 {
1921   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
1922   GstFFMpegVidDecClass *oclass;
1923
1924   oclass = (GstFFMpegVidDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1925
1926   GST_OBJECT_LOCK (ffmpegdec);
1927   gst_ffmpeg_avcodec_close (ffmpegdec->context);
1928   if (avcodec_get_context_defaults3 (ffmpegdec->context, oclass->in_plugin) < 0) {
1929     GST_DEBUG_OBJECT (ffmpegdec, "Failed to set context defaults");
1930     GST_OBJECT_UNLOCK (ffmpegdec);
1931     return FALSE;
1932   }
1933   ffmpegdec->context->opaque = ffmpegdec;
1934   GST_OBJECT_UNLOCK (ffmpegdec);
1935
1936   return TRUE;
1937 }
1938
1939 static gboolean
1940 gst_ffmpegviddec_stop (GstVideoDecoder * decoder)
1941 {
1942   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
1943
1944   GST_OBJECT_LOCK (ffmpegdec);
1945   gst_ffmpegviddec_close (ffmpegdec, FALSE);
1946   GST_OBJECT_UNLOCK (ffmpegdec);
1947   g_free (ffmpegdec->padded);
1948   ffmpegdec->padded = NULL;
1949   ffmpegdec->padded_size = 0;
1950   if (ffmpegdec->input_state)
1951     gst_video_codec_state_unref (ffmpegdec->input_state);
1952   ffmpegdec->input_state = NULL;
1953   if (ffmpegdec->output_state)
1954     gst_video_codec_state_unref (ffmpegdec->output_state);
1955   ffmpegdec->output_state = NULL;
1956
1957   if (ffmpegdec->internal_pool)
1958     gst_object_unref (ffmpegdec->internal_pool);
1959   ffmpegdec->internal_pool = NULL;
1960
1961   ffmpegdec->pic_pix_fmt = 0;
1962   ffmpegdec->pic_width = 0;
1963   ffmpegdec->pic_height = 0;
1964   ffmpegdec->pic_par_n = 0;
1965   ffmpegdec->pic_par_d = 0;
1966   ffmpegdec->pic_interlaced = 0;
1967   ffmpegdec->pic_field_order = 0;
1968   ffmpegdec->pic_field_order_changed = FALSE;
1969   ffmpegdec->ctx_ticks = 0;
1970   ffmpegdec->ctx_time_n = 0;
1971   ffmpegdec->ctx_time_d = 0;
1972
1973   ffmpegdec->pool_width = 0;
1974   ffmpegdec->pool_height = 0;
1975   ffmpegdec->pool_format = 0;
1976
1977   return TRUE;
1978 }
1979
1980 static GstFlowReturn
1981 gst_ffmpegviddec_finish (GstVideoDecoder * decoder)
1982 {
1983   gst_ffmpegviddec_drain (decoder);
1984   /* note that finish can and should clean up more drastically,
1985    * but drain is also invoked on e.g. packet loss in GAP handling */
1986   gst_ffmpegviddec_flush (decoder);
1987
1988   return GST_FLOW_OK;
1989 }
1990
1991 static gboolean
1992 gst_ffmpegviddec_flush (GstVideoDecoder * decoder)
1993 {
1994   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
1995
1996   if (ffmpegdec->opened) {
1997     GST_LOG_OBJECT (decoder, "flushing buffers");
1998     avcodec_flush_buffers (ffmpegdec->context);
1999   }
2000
2001   return TRUE;
2002 }
2003
2004 static gboolean
2005 gst_ffmpegviddec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
2006 {
2007   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) decoder;
2008   GstVideoCodecState *state;
2009   GstBufferPool *pool;
2010   guint size, min, max;
2011   GstStructure *config;
2012   gboolean have_pool, have_videometa, have_alignment, update_pool = FALSE;
2013   GstAllocator *allocator = NULL;
2014   GstAllocationParams params = DEFAULT_ALLOC_PARAM;
2015
2016   have_pool = (gst_query_get_n_allocation_pools (query) != 0);
2017
2018   if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder,
2019           query))
2020     return FALSE;
2021
2022   state = gst_video_decoder_get_output_state (decoder);
2023
2024   if (gst_query_get_n_allocation_params (query) > 0) {
2025     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
2026     params.align = MAX (params.align, DEFAULT_STRIDE_ALIGN);
2027   } else {
2028     gst_query_add_allocation_param (query, allocator, &params);
2029   }
2030
2031   gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
2032
2033   /* Don't use pool that can't grow, as we don't know how many buffer we'll
2034    * need, otherwise we may stall */
2035   if (max != 0 && max < REQUIRED_POOL_MAX_BUFFERS) {
2036     gst_object_unref (pool);
2037     pool = gst_video_buffer_pool_new ();
2038     max = 0;
2039     update_pool = TRUE;
2040     have_pool = FALSE;
2041
2042     /* if there is an allocator, also drop it, as it might be the reason we
2043      * have this limit. Default will be used */
2044     if (allocator) {
2045       gst_object_unref (allocator);
2046       allocator = NULL;
2047     }
2048   }
2049
2050   config = gst_buffer_pool_get_config (pool);
2051   gst_buffer_pool_config_set_params (config, state->caps, size, min, max);
2052   gst_buffer_pool_config_set_allocator (config, allocator, &params);
2053
2054   have_videometa =
2055       gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
2056
2057   if (have_videometa)
2058     gst_buffer_pool_config_add_option (config,
2059         GST_BUFFER_POOL_OPTION_VIDEO_META);
2060
2061   have_alignment =
2062       gst_buffer_pool_has_option (pool, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
2063
2064   /* If we have videometa, we never have to copy */
2065   if (have_videometa && have_pool && have_alignment &&
2066       gst_ffmpegviddec_can_direct_render (ffmpegdec)) {
2067     GstStructure *config_copy = gst_structure_copy (config);
2068
2069     gst_ffmpegvideodec_prepare_dr_pool (ffmpegdec, pool, &state->info,
2070         config_copy);
2071
2072     /* FIXME validate and retry */
2073     if (gst_buffer_pool_set_config (pool, config_copy)) {
2074       GstFlowReturn ret;
2075       GstBuffer *tmp;
2076
2077       gst_buffer_pool_set_active (pool, TRUE);
2078       ret = gst_buffer_pool_acquire_buffer (pool, &tmp, NULL);
2079       if (ret == GST_FLOW_OK) {
2080         GstVideoMeta *vmeta = gst_buffer_get_video_meta (tmp);
2081         gboolean same_stride = TRUE;
2082         gint i;
2083
2084         for (i = 0; i < vmeta->n_planes; i++) {
2085           if (vmeta->stride[i] != ffmpegdec->stride[i]) {
2086             same_stride = FALSE;
2087             break;
2088           }
2089         }
2090
2091         gst_buffer_unref (tmp);
2092
2093         if (same_stride) {
2094           if (ffmpegdec->internal_pool)
2095             gst_object_unref (ffmpegdec->internal_pool);
2096           ffmpegdec->internal_pool = gst_object_ref (pool);
2097           ffmpegdec->pool_info = state->info;
2098           gst_structure_free (config);
2099           goto done;
2100         }
2101       }
2102     }
2103   }
2104
2105   if (have_videometa && ffmpegdec->internal_pool
2106       && ffmpegdec->pool_width == state->info.width
2107       && ffmpegdec->pool_height == state->info.height) {
2108     update_pool = TRUE;
2109     gst_object_unref (pool);
2110     pool = gst_object_ref (ffmpegdec->internal_pool);
2111     gst_structure_free (config);
2112     goto done;
2113   }
2114
2115   /* configure */
2116   if (!gst_buffer_pool_set_config (pool, config)) {
2117     gboolean working_pool = FALSE;
2118     config = gst_buffer_pool_get_config (pool);
2119
2120     if (gst_buffer_pool_config_validate_params (config, state->caps, size, min,
2121             max)) {
2122       working_pool = gst_buffer_pool_set_config (pool, config);
2123     } else {
2124       gst_structure_free (config);
2125     }
2126
2127     if (!working_pool) {
2128       gst_object_unref (pool);
2129       pool = gst_video_buffer_pool_new ();
2130       config = gst_buffer_pool_get_config (pool);
2131       gst_buffer_pool_config_set_params (config, state->caps, size, min, max);
2132       gst_buffer_pool_config_set_allocator (config, NULL, &params);
2133       gst_buffer_pool_set_config (pool, config);
2134       update_pool = TRUE;
2135     }
2136   }
2137
2138 done:
2139   /* and store */
2140   if (update_pool)
2141     gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
2142
2143   gst_object_unref (pool);
2144   if (allocator)
2145     gst_object_unref (allocator);
2146   gst_video_codec_state_unref (state);
2147
2148   return TRUE;
2149 }
2150
2151 static gboolean
2152 gst_ffmpegviddec_propose_allocation (GstVideoDecoder * decoder,
2153     GstQuery * query)
2154 {
2155   GstAllocationParams params;
2156
2157   gst_allocation_params_init (&params);
2158   params.flags = GST_MEMORY_FLAG_ZERO_PADDED;
2159   params.align = DEFAULT_STRIDE_ALIGN;
2160   params.padding = FF_INPUT_BUFFER_PADDING_SIZE;
2161   /* we would like to have some padding so that we don't have to
2162    * memcpy. We don't suggest an allocator. */
2163   gst_query_add_allocation_param (query, NULL, &params);
2164
2165   return GST_VIDEO_DECODER_CLASS (parent_class)->propose_allocation (decoder,
2166       query);
2167 }
2168
2169 static void
2170 gst_ffmpegviddec_set_property (GObject * object,
2171     guint prop_id, const GValue * value, GParamSpec * pspec)
2172 {
2173   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) object;
2174
2175   switch (prop_id) {
2176     case PROP_LOWRES:
2177       ffmpegdec->lowres = ffmpegdec->context->lowres = g_value_get_enum (value);
2178       break;
2179     case PROP_SKIPFRAME:
2180       ffmpegdec->skip_frame = ffmpegdec->context->skip_frame =
2181           g_value_get_enum (value);
2182       break;
2183     case PROP_DIRECT_RENDERING:
2184       ffmpegdec->direct_rendering = g_value_get_boolean (value);
2185       break;
2186     case PROP_DEBUG_MV:
2187       ffmpegdec->debug_mv = ffmpegdec->context->debug_mv =
2188           g_value_get_boolean (value);
2189       break;
2190     case PROP_MAX_THREADS:
2191       ffmpegdec->max_threads = g_value_get_int (value);
2192       break;
2193     case PROP_OUTPUT_CORRUPT:
2194       ffmpegdec->output_corrupt = g_value_get_boolean (value);
2195       break;
2196     default:
2197       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2198       break;
2199   }
2200 }
2201
2202 static void
2203 gst_ffmpegviddec_get_property (GObject * object,
2204     guint prop_id, GValue * value, GParamSpec * pspec)
2205 {
2206   GstFFMpegVidDec *ffmpegdec = (GstFFMpegVidDec *) object;
2207
2208   switch (prop_id) {
2209     case PROP_LOWRES:
2210       g_value_set_enum (value, ffmpegdec->context->lowres);
2211       break;
2212     case PROP_SKIPFRAME:
2213       g_value_set_enum (value, ffmpegdec->context->skip_frame);
2214       break;
2215     case PROP_DIRECT_RENDERING:
2216       g_value_set_boolean (value, ffmpegdec->direct_rendering);
2217       break;
2218     case PROP_DEBUG_MV:
2219       g_value_set_boolean (value, ffmpegdec->context->debug_mv);
2220       break;
2221     case PROP_MAX_THREADS:
2222       g_value_set_int (value, ffmpegdec->max_threads);
2223       break;
2224     case PROP_OUTPUT_CORRUPT:
2225       g_value_set_boolean (value, ffmpegdec->output_corrupt);
2226       break;
2227     default:
2228       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2229       break;
2230   }
2231 }
2232
2233 gboolean
2234 gst_ffmpegviddec_register (GstPlugin * plugin)
2235 {
2236   GTypeInfo typeinfo = {
2237     sizeof (GstFFMpegVidDecClass),
2238     (GBaseInitFunc) gst_ffmpegviddec_base_init,
2239     NULL,
2240     (GClassInitFunc) gst_ffmpegviddec_class_init,
2241     NULL,
2242     NULL,
2243     sizeof (GstFFMpegVidDec),
2244     0,
2245     (GInstanceInitFunc) gst_ffmpegviddec_init,
2246   };
2247   GType type;
2248   AVCodec *in_plugin;
2249   gint rank;
2250
2251   in_plugin = av_codec_next (NULL);
2252
2253   GST_LOG ("Registering decoders");
2254
2255   while (in_plugin) {
2256     gchar *type_name;
2257     gchar *plugin_name;
2258
2259     /* only video decoders */
2260     if (!av_codec_is_decoder (in_plugin)
2261         || in_plugin->type != AVMEDIA_TYPE_VIDEO)
2262       goto next;
2263
2264     /* no quasi codecs, please */
2265     if (in_plugin->id == AV_CODEC_ID_RAWVIDEO ||
2266         in_plugin->id == AV_CODEC_ID_V210 ||
2267         in_plugin->id == AV_CODEC_ID_V210X ||
2268         in_plugin->id == AV_CODEC_ID_V308 ||
2269         in_plugin->id == AV_CODEC_ID_V408 ||
2270         in_plugin->id == AV_CODEC_ID_V410 ||
2271         in_plugin->id == AV_CODEC_ID_R210
2272         || in_plugin->id == AV_CODEC_ID_AYUV
2273         || in_plugin->id == AV_CODEC_ID_Y41P
2274         || in_plugin->id == AV_CODEC_ID_012V
2275         || in_plugin->id == AV_CODEC_ID_YUV4
2276 #if AV_VERSION_INT (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) >= \
2277         AV_VERSION_INT (57,4,0)
2278         || in_plugin->id == AV_CODEC_ID_WRAPPED_AVFRAME
2279 #endif
2280         || in_plugin->id == AV_CODEC_ID_ZLIB) {
2281       goto next;
2282     }
2283
2284     /* No decoders depending on external libraries (we don't build them, but
2285      * people who build against an external ffmpeg might have them.
2286      * We have native gstreamer plugins for all of those libraries anyway. */
2287     if (!strncmp (in_plugin->name, "lib", 3)) {
2288       GST_DEBUG
2289           ("Not using external library decoder %s. Use the gstreamer-native ones instead.",
2290           in_plugin->name);
2291       goto next;
2292     }
2293
2294     /* No vdpau plugins until we can figure out how to properly use them
2295      * outside of ffmpeg. */
2296     if (g_str_has_suffix (in_plugin->name, "_vdpau")) {
2297       GST_DEBUG
2298           ("Ignoring VDPAU decoder %s. We can't handle this outside of ffmpeg",
2299           in_plugin->name);
2300       goto next;
2301     }
2302
2303     if (g_str_has_suffix (in_plugin->name, "_xvmc")) {
2304       GST_DEBUG
2305           ("Ignoring XVMC decoder %s. We can't handle this outside of ffmpeg",
2306           in_plugin->name);
2307       goto next;
2308     }
2309
2310     if (strstr (in_plugin->name, "vaapi")) {
2311       GST_DEBUG
2312           ("Ignoring VAAPI decoder %s. We can't handle this outside of ffmpeg",
2313           in_plugin->name);
2314       goto next;
2315     }
2316
2317     if (g_str_has_suffix (in_plugin->name, "_qsv")) {
2318       GST_DEBUG
2319           ("Ignoring qsv decoder %s. We can't handle this outside of ffmpeg",
2320           in_plugin->name);
2321       goto next;
2322     }
2323
2324     if (g_str_has_suffix (in_plugin->name, "_cuvid")) {
2325       GST_DEBUG
2326           ("Ignoring CUVID decoder %s. We can't handle this outside of ffmpeg",
2327           in_plugin->name);
2328       goto next;
2329     }
2330
2331     if (g_str_has_suffix (in_plugin->name, "_v4l2m2m")) {
2332       GST_DEBUG
2333           ("Ignoring V4L2 mem-to-mem decoder %s. We can't handle this outside of ffmpeg",
2334           in_plugin->name);
2335       goto next;
2336     }
2337
2338     GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
2339
2340     /* no codecs for which we're GUARANTEED to have better alternatives */
2341     /* MPEG1VIDEO : the mpeg2video decoder is preferred */
2342     /* MP1 : Use MP3 for decoding */
2343     /* MP2 : Use MP3 for decoding */
2344     /* Theora: Use libtheora based theoradec */
2345     if (!strcmp (in_plugin->name, "theora") ||
2346         !strcmp (in_plugin->name, "mpeg1video") ||
2347         strstr (in_plugin->name, "crystalhd") != NULL ||
2348         !strcmp (in_plugin->name, "ass") ||
2349         !strcmp (in_plugin->name, "srt") ||
2350         !strcmp (in_plugin->name, "pgssub") ||
2351         !strcmp (in_plugin->name, "dvdsub") ||
2352         !strcmp (in_plugin->name, "dvbsub")) {
2353       GST_LOG ("Ignoring decoder %s", in_plugin->name);
2354       goto next;
2355     }
2356
2357     /* construct the type */
2358     if (!strcmp (in_plugin->name, "hevc")) {
2359       plugin_name = g_strdup ("h265");
2360     } else {
2361       plugin_name = g_strdup ((gchar *) in_plugin->name);
2362     }
2363     g_strdelimit (plugin_name, NULL, '_');
2364     type_name = g_strdup_printf ("avdec_%s", plugin_name);
2365     g_free (plugin_name);
2366
2367     type = g_type_from_name (type_name);
2368
2369     if (!type) {
2370       /* create the gtype now */
2371       type =
2372           g_type_register_static (GST_TYPE_VIDEO_DECODER, type_name, &typeinfo,
2373           0);
2374       g_type_set_qdata (type, GST_FFDEC_PARAMS_QDATA, (gpointer) in_plugin);
2375     }
2376
2377     /* (Ronald) MPEG-4 gets a higher priority because it has been well-
2378      * tested and by far outperforms divxdec/xviddec - so we prefer it.
2379      * msmpeg4v3 same, as it outperforms divxdec for divx3 playback.
2380      * VC1/WMV3 are not working and thus unpreferred for now. */
2381     switch (in_plugin->id) {
2382       case AV_CODEC_ID_MPEG1VIDEO:
2383       case AV_CODEC_ID_MPEG2VIDEO:
2384       case AV_CODEC_ID_MPEG4:
2385       case AV_CODEC_ID_MSMPEG4V3:
2386       case AV_CODEC_ID_H264:
2387       case AV_CODEC_ID_HEVC:
2388       case AV_CODEC_ID_RV10:
2389       case AV_CODEC_ID_RV20:
2390       case AV_CODEC_ID_RV30:
2391       case AV_CODEC_ID_RV40:
2392         rank = GST_RANK_PRIMARY;
2393         break;
2394         /* DVVIDEO: we have a good dv decoder, fast on both ppc as well as x86.
2395          * They say libdv's quality is better though. leave as secondary.
2396          * note: if you change this, see the code in gstdv.c in good/ext/dv.
2397          */
2398       case AV_CODEC_ID_DVVIDEO:
2399         rank = GST_RANK_SECONDARY;
2400         break;
2401       default:
2402         rank = GST_RANK_MARGINAL;
2403         break;
2404     }
2405     if (!gst_element_register (plugin, type_name, rank, type)) {
2406       g_warning ("Failed to register %s", type_name);
2407       g_free (type_name);
2408       return FALSE;
2409     }
2410
2411     g_free (type_name);
2412
2413   next:
2414     in_plugin = av_codec_next (in_plugin);
2415   }
2416
2417   GST_LOG ("Finished Registering decoders");
2418
2419   return TRUE;
2420 }