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