ffmpegdec: Fix debug statements
[gstreamer-omap:gst-ffmpeg.git] / ext / ffmpeg / gstffmpegdec.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., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, 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 #ifdef HAVE_FFMPEG_UNINSTALLED
28 #include <avcodec.h>
29 #else
30 #include <libavcodec/avcodec.h>
31 #endif
32
33 #include <gst/gst.h>
34 #include <gst/video/video.h>
35
36 #include "gstffmpeg.h"
37 #include "gstffmpegcodecmap.h"
38 #include "gstffmpegutils.h"
39
40 /* define to enable alternative buffer refcounting algorithm */
41 #undef EXTRA_REF
42
43 typedef struct _GstFFMpegDec GstFFMpegDec;
44
45 #define MAX_TS_MASK 0xff
46
47 /* for each incomming buffer we keep all timing info in a structure like this.
48  * We keep a circular array of these structures around to store the timing info.
49  * The index in the array is what we pass as opaque data (to pictures) and
50  * pts (to parsers) so that ffmpeg can remember them for us. */
51 typedef struct
52 {
53   gint idx;
54   GstClockTime timestamp;
55   GstClockTime duration;
56   gint64 offset;
57 } GstTSInfo;
58
59 struct _GstFFMpegDec
60 {
61   GstElement element;
62
63   /* We need to keep track of our pads, so we do so here. */
64   GstPad *srcpad;
65   GstPad *sinkpad;
66
67   /* decoding */
68   AVCodecContext *context;
69   AVFrame *picture;
70   gboolean opened;
71   union
72   {
73     struct
74     {
75       gint width, height;
76       gint clip_width, clip_height;
77       gint par_n, par_d;
78       gint fps_n, fps_d;
79       gint old_fps_n, old_fps_d;
80       gboolean interlaced;
81
82       enum PixelFormat pix_fmt;
83     } video;
84     struct
85     {
86       gint channels;
87       gint samplerate;
88       gint depth;
89     } audio;
90   } format;
91   gboolean waiting_for_key;
92   gboolean discont;
93   gboolean clear_ts;
94
95   /* for tracking DTS/PTS */
96   gboolean has_b_frames;
97   gboolean reordered_in;
98   GstClockTime last_in;
99   GstClockTime next_in;
100   gboolean reordered_out;
101   GstClockTime last_out;
102   GstClockTime next_out;
103
104   /* parsing */
105   gboolean turnoff_parser;      /* used for turning off aac raw parsing
106                                  * See bug #566250 */
107   AVCodecParserContext *pctx;
108   GstBuffer *pcache;
109   guint8 *padded;
110   guint padded_size;
111
112   GValue *par;                  /* pixel aspect ratio of incoming data */
113   gboolean current_dr;          /* if direct rendering is enabled */
114   gboolean extra_ref;           /* keep extra ref around in get/release */
115
116   /* some properties */
117   gint hurry_up;
118   gint lowres;
119   gboolean direct_rendering;
120   gboolean do_padding;
121   gboolean debug_mv;
122   gboolean crop;
123
124   /* QoS stuff *//* with LOCK */
125   gdouble proportion;
126   GstClockTime earliest_time;
127
128   /* clipping segment */
129   GstSegment segment;
130
131   gboolean is_realvideo;
132
133   GstTSInfo ts_info[MAX_TS_MASK + 1];
134   gint ts_idx;
135
136   /* reverse playback queue */
137   GList *queued;
138
139   /* Can downstream allocate 16bytes aligned data. */
140   gboolean can_allocate_aligned;
141 };
142
143 typedef struct _GstFFMpegDecClass GstFFMpegDecClass;
144
145 struct _GstFFMpegDecClass
146 {
147   GstElementClass parent_class;
148
149   AVCodec *in_plugin;
150   GstPadTemplate *srctempl, *sinktempl;
151 };
152
153 #define GST_TS_INFO_NONE &ts_info_none
154 static const GstTSInfo ts_info_none = { -1, -1, -1, -1 };
155
156 static const GstTSInfo *
157 gst_ts_info_store (GstFFMpegDec * dec, GstClockTime timestamp,
158     GstClockTime duration, gint64 offset)
159 {
160   gint idx = dec->ts_idx;
161   dec->ts_info[idx].idx = idx;
162   dec->ts_info[idx].timestamp = timestamp;
163   dec->ts_info[idx].duration = duration;
164   dec->ts_info[idx].offset = offset;
165   dec->ts_idx = (idx + 1) & MAX_TS_MASK;
166
167   return &dec->ts_info[idx];
168 }
169
170 static const GstTSInfo *
171 gst_ts_info_get (GstFFMpegDec * dec, gint idx)
172 {
173   if (G_UNLIKELY (idx < 0 || idx > MAX_TS_MASK))
174     return GST_TS_INFO_NONE;
175
176   return &dec->ts_info[idx];
177 }
178
179 #define GST_TYPE_FFMPEGDEC \
180   (gst_ffmpegdec_get_type())
181 #define GST_FFMPEGDEC(obj) \
182   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEC,GstFFMpegDec))
183 #define GST_FFMPEGDEC_CLASS(klass) \
184   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEC,GstFFMpegDecClass))
185 #define GST_IS_FFMPEGDEC(obj) \
186   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEC))
187 #define GST_IS_FFMPEGDEC_CLASS(klass) \
188   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEC))
189
190 #define DEFAULT_LOWRES                  0
191 #define DEFAULT_SKIPFRAME               0
192 #define DEFAULT_DIRECT_RENDERING        TRUE
193 #define DEFAULT_DO_PADDING              TRUE
194 #define DEFAULT_DEBUG_MV                FALSE
195 #define DEFAULT_CROP                    TRUE
196
197 enum
198 {
199   PROP_0,
200   PROP_LOWRES,
201   PROP_SKIPFRAME,
202   PROP_DIRECT_RENDERING,
203   PROP_DO_PADDING,
204   PROP_DEBUG_MV,
205   PROP_CROP,
206   PROP_LAST
207 };
208
209 /* A number of function prototypes are given so we can refer to them later. */
210 static void gst_ffmpegdec_base_init (GstFFMpegDecClass * klass);
211 static void gst_ffmpegdec_class_init (GstFFMpegDecClass * klass);
212 static void gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec);
213 static void gst_ffmpegdec_finalize (GObject * object);
214
215 static gboolean gst_ffmpegdec_query (GstPad * pad, GstQuery * query);
216 static gboolean gst_ffmpegdec_src_event (GstPad * pad, GstEvent * event);
217
218 static gboolean gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps);
219 static gboolean gst_ffmpegdec_sink_event (GstPad * pad, GstEvent * event);
220 static GstFlowReturn gst_ffmpegdec_chain (GstPad * pad, GstBuffer * buf);
221
222 static GstStateChangeReturn gst_ffmpegdec_change_state (GstElement * element,
223     GstStateChange transition);
224
225 static void gst_ffmpegdec_set_property (GObject * object,
226     guint prop_id, const GValue * value, GParamSpec * pspec);
227 static void gst_ffmpegdec_get_property (GObject * object,
228     guint prop_id, GValue * value, GParamSpec * pspec);
229
230 static gboolean gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec,
231     gboolean force);
232
233 /* some sort of bufferpool handling, but different */
234 static int gst_ffmpegdec_get_buffer (AVCodecContext * context,
235     AVFrame * picture);
236 static void gst_ffmpegdec_release_buffer (AVCodecContext * context,
237     AVFrame * picture);
238
239 static void gst_ffmpegdec_drain (GstFFMpegDec * ffmpegdec);
240
241 #define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("ffdec-params")
242
243 static GstElementClass *parent_class = NULL;
244
245 #define GST_FFMPEGDEC_TYPE_LOWRES (gst_ffmpegdec_lowres_get_type())
246 static GType
247 gst_ffmpegdec_lowres_get_type (void)
248 {
249   static GType ffmpegdec_lowres_type = 0;
250
251   if (!ffmpegdec_lowres_type) {
252     static const GEnumValue ffmpegdec_lowres[] = {
253       {0, "0", "full"},
254       {1, "1", "1/2-size"},
255       {2, "2", "1/4-size"},
256       {0, NULL, NULL},
257     };
258
259     ffmpegdec_lowres_type =
260         g_enum_register_static ("GstFFMpegDecLowres", ffmpegdec_lowres);
261   }
262
263   return ffmpegdec_lowres_type;
264 }
265
266 #define GST_FFMPEGDEC_TYPE_SKIPFRAME (gst_ffmpegdec_skipframe_get_type())
267 static GType
268 gst_ffmpegdec_skipframe_get_type (void)
269 {
270   static GType ffmpegdec_skipframe_type = 0;
271
272   if (!ffmpegdec_skipframe_type) {
273     static const GEnumValue ffmpegdec_skipframe[] = {
274       {0, "0", "Skip nothing"},
275       {1, "1", "Skip B-frames"},
276       {2, "2", "Skip IDCT/Dequantization"},
277       {5, "5", "Skip everything"},
278       {0, NULL, NULL},
279     };
280
281     ffmpegdec_skipframe_type =
282         g_enum_register_static ("GstFFMpegDecSkipFrame", ffmpegdec_skipframe);
283   }
284
285   return ffmpegdec_skipframe_type;
286 }
287
288 static void
289 gst_ffmpegdec_base_init (GstFFMpegDecClass * klass)
290 {
291   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
292   GstPadTemplate *sinktempl, *srctempl;
293   GstCaps *sinkcaps, *srccaps;
294   AVCodec *in_plugin;
295   gchar *longname, *classification, *description;
296
297   in_plugin =
298       (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
299       GST_FFDEC_PARAMS_QDATA);
300   g_assert (in_plugin != NULL);
301
302   /* construct the element details struct */
303   longname = g_strdup_printf ("FFmpeg %s decoder", in_plugin->long_name);
304   classification = g_strdup_printf ("Codec/Decoder/%s",
305       (in_plugin->type == CODEC_TYPE_VIDEO) ? "Video" : "Audio");
306   description = g_strdup_printf ("FFmpeg %s decoder", in_plugin->name);
307   gst_element_class_set_details_simple (element_class, longname, classification,
308       description,
309       "Wim Taymans <wim.taymans@gmail.com>, "
310       "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
311       "Edward Hervey <bilboed@bilboed.com>");
312   g_free (longname);
313   g_free (classification);
314   g_free (description);
315
316   /* get the caps */
317   sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
318   if (!sinkcaps) {
319     GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
320     sinkcaps = gst_caps_from_string ("unknown/unknown");
321   }
322   if (in_plugin->type == CODEC_TYPE_VIDEO) {
323     srccaps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv");
324   } else {
325     srccaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
326         in_plugin->id, FALSE, in_plugin);
327   }
328   if (!srccaps) {
329     GST_DEBUG ("Couldn't get source caps for decoder '%s'", in_plugin->name);
330     srccaps = gst_caps_from_string ("unknown/unknown");
331   }
332
333   /* pad templates */
334   sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
335       GST_PAD_ALWAYS, sinkcaps);
336   srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
337
338   gst_element_class_add_pad_template (element_class, srctempl);
339   gst_element_class_add_pad_template (element_class, sinktempl);
340
341   klass->in_plugin = in_plugin;
342   klass->srctempl = srctempl;
343   klass->sinktempl = sinktempl;
344 }
345
346 static void
347 gst_ffmpegdec_class_init (GstFFMpegDecClass * klass)
348 {
349   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
350   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
351
352   parent_class = g_type_class_peek_parent (klass);
353
354   gobject_class->finalize = gst_ffmpegdec_finalize;
355
356   gobject_class->set_property = gst_ffmpegdec_set_property;
357   gobject_class->get_property = gst_ffmpegdec_get_property;
358
359   if (klass->in_plugin->type == CODEC_TYPE_VIDEO) {
360     g_object_class_install_property (gobject_class, PROP_SKIPFRAME,
361         g_param_spec_enum ("skip-frame", "Skip frames",
362             "Which types of frames to skip during decoding",
363             GST_FFMPEGDEC_TYPE_SKIPFRAME, 0,
364             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
365     g_object_class_install_property (gobject_class, PROP_LOWRES,
366         g_param_spec_enum ("lowres", "Low resolution",
367             "At which resolution to decode images", GST_FFMPEGDEC_TYPE_LOWRES,
368             0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
369     g_object_class_install_property (gobject_class, PROP_DIRECT_RENDERING,
370         g_param_spec_boolean ("direct-rendering", "Direct Rendering",
371             "Enable direct rendering", DEFAULT_DIRECT_RENDERING,
372             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
373     g_object_class_install_property (gobject_class, PROP_DO_PADDING,
374         g_param_spec_boolean ("do-padding", "Do Padding",
375             "Add 0 padding before decoding data", DEFAULT_DO_PADDING,
376             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
377     g_object_class_install_property (gobject_class, PROP_DEBUG_MV,
378         g_param_spec_boolean ("debug-mv", "Debug motion vectors",
379             "Whether ffmpeg should print motion vectors on top of the image",
380             DEFAULT_DEBUG_MV, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
381 #if 0
382     g_object_class_install_property (gobject_class, PROP_CROP,
383         g_param_spec_boolean ("crop", "Crop",
384             "Crop images to the display region",
385             DEFAULT_CROP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
386 #endif
387   }
388
389   gstelement_class->change_state = gst_ffmpegdec_change_state;
390 }
391
392 static void
393 gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec)
394 {
395   GstFFMpegDecClass *oclass;
396
397   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
398
399   /* setup pads */
400   ffmpegdec->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink");
401   gst_pad_set_setcaps_function (ffmpegdec->sinkpad,
402       GST_DEBUG_FUNCPTR (gst_ffmpegdec_setcaps));
403   gst_pad_set_event_function (ffmpegdec->sinkpad,
404       GST_DEBUG_FUNCPTR (gst_ffmpegdec_sink_event));
405   gst_pad_set_chain_function (ffmpegdec->sinkpad,
406       GST_DEBUG_FUNCPTR (gst_ffmpegdec_chain));
407   gst_element_add_pad (GST_ELEMENT (ffmpegdec), ffmpegdec->sinkpad);
408
409   ffmpegdec->srcpad = gst_pad_new_from_template (oclass->srctempl, "src");
410   gst_pad_use_fixed_caps (ffmpegdec->srcpad);
411   gst_pad_set_event_function (ffmpegdec->srcpad,
412       GST_DEBUG_FUNCPTR (gst_ffmpegdec_src_event));
413   gst_pad_set_query_function (ffmpegdec->srcpad,
414       GST_DEBUG_FUNCPTR (gst_ffmpegdec_query));
415   gst_element_add_pad (GST_ELEMENT (ffmpegdec), ffmpegdec->srcpad);
416
417   /* some ffmpeg data */
418   ffmpegdec->context = avcodec_alloc_context ();
419   ffmpegdec->picture = avcodec_alloc_frame ();
420   ffmpegdec->pctx = NULL;
421   ffmpegdec->pcache = NULL;
422   ffmpegdec->par = NULL;
423   ffmpegdec->opened = FALSE;
424   ffmpegdec->waiting_for_key = TRUE;
425   ffmpegdec->hurry_up = ffmpegdec->lowres = 0;
426   ffmpegdec->direct_rendering = DEFAULT_DIRECT_RENDERING;
427   ffmpegdec->do_padding = DEFAULT_DO_PADDING;
428   ffmpegdec->debug_mv = DEFAULT_DEBUG_MV;
429   ffmpegdec->crop = DEFAULT_CROP;
430
431   ffmpegdec->format.video.par_n = -1;
432   ffmpegdec->format.video.fps_n = -1;
433   ffmpegdec->format.video.old_fps_n = -1;
434   gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
435
436   /* We initially assume downstream can allocate 16 bytes aligned buffers */
437   ffmpegdec->can_allocate_aligned = TRUE;
438 }
439
440 static void
441 gst_ffmpegdec_finalize (GObject * object)
442 {
443   GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) object;
444
445   if (ffmpegdec->context != NULL) {
446     av_free (ffmpegdec->context);
447     ffmpegdec->context = NULL;
448   }
449
450   if (ffmpegdec->picture != NULL) {
451     av_free (ffmpegdec->picture);
452     ffmpegdec->picture = NULL;
453   }
454
455   G_OBJECT_CLASS (parent_class)->finalize (object);
456 }
457
458 static gboolean
459 gst_ffmpegdec_query (GstPad * pad, GstQuery * query)
460 {
461   GstFFMpegDec *ffmpegdec;
462   GstPad *peer;
463   gboolean res;
464
465   ffmpegdec = (GstFFMpegDec *) gst_pad_get_parent (pad);
466
467   res = FALSE;
468
469   if ((peer = gst_pad_get_peer (ffmpegdec->sinkpad))) {
470     /* just forward to peer */
471     res = gst_pad_query (peer, query);
472     gst_object_unref (peer);
473   }
474 #if 0
475   {
476     GstFormat bfmt;
477
478     bfmt = GST_FORMAT_BYTES;
479
480     /* ok, do bitrate calc... */
481     if ((type != GST_QUERY_POSITION && type != GST_QUERY_TOTAL) ||
482         *fmt != GST_FORMAT_TIME || ffmpegdec->context->bit_rate == 0 ||
483         !gst_pad_query (peer, type, &bfmt, value))
484       return FALSE;
485
486     if (ffmpegdec->pcache && type == GST_QUERY_POSITION)
487       *value -= GST_BUFFER_SIZE (ffmpegdec->pcache);
488     *value *= GST_SECOND / ffmpegdec->context->bit_rate;
489   }
490 #endif
491
492   gst_object_unref (ffmpegdec);
493
494   return res;
495 }
496
497 static void
498 gst_ffmpegdec_reset_ts (GstFFMpegDec * ffmpegdec)
499 {
500   ffmpegdec->last_in = GST_CLOCK_TIME_NONE;
501   ffmpegdec->next_in = GST_CLOCK_TIME_NONE;
502   ffmpegdec->last_out = GST_CLOCK_TIME_NONE;
503   ffmpegdec->next_out = GST_CLOCK_TIME_NONE;
504   ffmpegdec->reordered_in = FALSE;
505   ffmpegdec->reordered_out = FALSE;
506 }
507
508 static void
509 gst_ffmpegdec_update_qos (GstFFMpegDec * ffmpegdec, gdouble proportion,
510     GstClockTime timestamp)
511 {
512   GST_LOG_OBJECT (ffmpegdec, "update QOS: %f, %" GST_TIME_FORMAT,
513       proportion, GST_TIME_ARGS (timestamp));
514
515   GST_OBJECT_LOCK (ffmpegdec);
516   ffmpegdec->proportion = proportion;
517   ffmpegdec->earliest_time = timestamp;
518   GST_OBJECT_UNLOCK (ffmpegdec);
519 }
520
521 static void
522 gst_ffmpegdec_reset_qos (GstFFMpegDec * ffmpegdec)
523 {
524   gst_ffmpegdec_update_qos (ffmpegdec, 0.5, GST_CLOCK_TIME_NONE);
525 }
526
527 static void
528 gst_ffmpegdec_read_qos (GstFFMpegDec * ffmpegdec, gdouble * proportion,
529     GstClockTime * timestamp)
530 {
531   GST_OBJECT_LOCK (ffmpegdec);
532   *proportion = ffmpegdec->proportion;
533   *timestamp = ffmpegdec->earliest_time;
534   GST_OBJECT_UNLOCK (ffmpegdec);
535 }
536
537 static gboolean
538 gst_ffmpegdec_src_event (GstPad * pad, GstEvent * event)
539 {
540   GstFFMpegDec *ffmpegdec;
541   gboolean res;
542
543   ffmpegdec = (GstFFMpegDec *) gst_pad_get_parent (pad);
544
545   switch (GST_EVENT_TYPE (event)) {
546     case GST_EVENT_QOS:
547     {
548       gdouble proportion;
549       GstClockTimeDiff diff;
550       GstClockTime timestamp;
551
552       gst_event_parse_qos (event, &proportion, &diff, &timestamp);
553
554       /* update our QoS values */
555       gst_ffmpegdec_update_qos (ffmpegdec, proportion, timestamp + diff);
556
557       /* forward upstream */
558       res = gst_pad_push_event (ffmpegdec->sinkpad, event);
559       break;
560     }
561     default:
562       /* forward upstream */
563       res = gst_pad_push_event (ffmpegdec->sinkpad, event);
564       break;
565   }
566
567   gst_object_unref (ffmpegdec);
568
569   return res;
570 }
571
572 /* with LOCK */
573 static void
574 gst_ffmpegdec_close (GstFFMpegDec * ffmpegdec)
575 {
576   if (!ffmpegdec->opened)
577     return;
578
579   GST_LOG_OBJECT (ffmpegdec, "closing ffmpeg codec");
580
581   if (ffmpegdec->par) {
582     g_free (ffmpegdec->par);
583     ffmpegdec->par = NULL;
584   }
585
586   if (ffmpegdec->context->priv_data)
587     gst_ffmpeg_avcodec_close (ffmpegdec->context);
588   ffmpegdec->opened = FALSE;
589
590   if (ffmpegdec->context->palctrl) {
591     av_free (ffmpegdec->context->palctrl);
592     ffmpegdec->context->palctrl = NULL;
593   }
594
595   if (ffmpegdec->context->extradata) {
596     av_free (ffmpegdec->context->extradata);
597     ffmpegdec->context->extradata = NULL;
598   }
599
600   if (ffmpegdec->pctx) {
601     if (ffmpegdec->pcache) {
602       gst_buffer_unref (ffmpegdec->pcache);
603       ffmpegdec->pcache = NULL;
604     }
605     av_parser_close (ffmpegdec->pctx);
606     ffmpegdec->pctx = NULL;
607   }
608
609   ffmpegdec->format.video.par_n = -1;
610   ffmpegdec->format.video.fps_n = -1;
611   ffmpegdec->format.video.old_fps_n = -1;
612   ffmpegdec->format.video.interlaced = FALSE;
613 }
614
615 /* with LOCK */
616 static gboolean
617 gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec)
618 {
619   GstFFMpegDecClass *oclass;
620
621   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
622
623   if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
624     goto could_not_open;
625
626   ffmpegdec->opened = TRUE;
627   ffmpegdec->is_realvideo = FALSE;
628
629   GST_LOG_OBJECT (ffmpegdec, "Opened ffmpeg codec %s, id %d",
630       oclass->in_plugin->name, oclass->in_plugin->id);
631
632   /* open a parser if we can */
633   switch (oclass->in_plugin->id) {
634     case CODEC_ID_MPEG4:
635     case CODEC_ID_MJPEG:
636     case CODEC_ID_VC1:
637       GST_LOG_OBJECT (ffmpegdec, "not using parser, blacklisted codec");
638       ffmpegdec->pctx = NULL;
639       break;
640     case CODEC_ID_H264:
641       /* For H264, only use a parser if there is no context data, if there is, 
642        * we're talking AVC */
643       if (ffmpegdec->context->extradata_size == 0) {
644         GST_LOG_OBJECT (ffmpegdec, "H264 with no extradata, creating parser");
645         ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
646       } else {
647         GST_LOG_OBJECT (ffmpegdec,
648             "H264 with extradata implies framed data - not using parser");
649         ffmpegdec->pctx = NULL;
650       }
651       break;
652     case CODEC_ID_RV10:
653     case CODEC_ID_RV30:
654     case CODEC_ID_RV20:
655     case CODEC_ID_RV40:
656       ffmpegdec->is_realvideo = TRUE;
657       break;
658     default:
659       if (!ffmpegdec->turnoff_parser) {
660         ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
661         if (ffmpegdec->pctx)
662           GST_LOG_OBJECT (ffmpegdec, "Using parser %p", ffmpegdec->pctx);
663         else
664           GST_LOG_OBJECT (ffmpegdec, "No parser for codec");
665       } else {
666         GST_LOG_OBJECT (ffmpegdec, "Parser deactivated for format");
667       }
668       break;
669   }
670
671   switch (oclass->in_plugin->type) {
672     case CODEC_TYPE_VIDEO:
673       ffmpegdec->format.video.width = 0;
674       ffmpegdec->format.video.height = 0;
675       ffmpegdec->format.video.clip_width = -1;
676       ffmpegdec->format.video.clip_height = -1;
677       ffmpegdec->format.video.pix_fmt = PIX_FMT_NB;
678       ffmpegdec->format.video.interlaced = FALSE;
679       break;
680     case CODEC_TYPE_AUDIO:
681       ffmpegdec->format.audio.samplerate = 0;
682       ffmpegdec->format.audio.channels = 0;
683       ffmpegdec->format.audio.depth = 0;
684       break;
685     default:
686       break;
687   }
688
689   gst_ffmpegdec_reset_ts (ffmpegdec);
690   /* FIXME, reset_qos holds the LOCK */
691   ffmpegdec->proportion = 0.0;
692   ffmpegdec->earliest_time = -1;
693
694   return TRUE;
695
696   /* ERRORS */
697 could_not_open:
698   {
699     gst_ffmpegdec_close (ffmpegdec);
700     GST_DEBUG_OBJECT (ffmpegdec, "ffdec_%s: Failed to open FFMPEG codec",
701         oclass->in_plugin->name);
702     return FALSE;
703   }
704 }
705
706 static gboolean
707 gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps)
708 {
709   GstFFMpegDec *ffmpegdec;
710   GstFFMpegDecClass *oclass;
711   GstStructure *structure;
712   const GValue *par;
713   const GValue *fps;
714   gboolean ret = TRUE;
715
716   ffmpegdec = (GstFFMpegDec *) (gst_pad_get_parent (pad));
717   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
718
719   GST_DEBUG_OBJECT (pad, "setcaps called");
720
721   GST_OBJECT_LOCK (ffmpegdec);
722
723   /* stupid check for VC1 */
724   if ((oclass->in_plugin->id == CODEC_ID_WMV3) ||
725       (oclass->in_plugin->id == CODEC_ID_VC1))
726     oclass->in_plugin->id = gst_ffmpeg_caps_to_codecid (caps, NULL);
727
728   /* close old session */
729   if (ffmpegdec->opened) {
730     GST_OBJECT_UNLOCK (ffmpegdec);
731     gst_ffmpegdec_drain (ffmpegdec);
732     GST_OBJECT_LOCK (ffmpegdec);
733     gst_ffmpegdec_close (ffmpegdec);
734
735     /* and reset the defaults that were set when a context is created */
736     avcodec_get_context_defaults (ffmpegdec->context);
737   }
738
739   /* set buffer functions */
740   ffmpegdec->context->get_buffer = gst_ffmpegdec_get_buffer;
741   ffmpegdec->context->release_buffer = gst_ffmpegdec_release_buffer;
742   ffmpegdec->context->draw_horiz_band = NULL;
743
744   /* default is to let format decide if it needs a parser */
745   ffmpegdec->turnoff_parser = FALSE;
746
747   ffmpegdec->has_b_frames = FALSE;
748
749   GST_LOG_OBJECT (ffmpegdec, "size %dx%d", ffmpegdec->context->width,
750       ffmpegdec->context->height);
751
752   /* get size and so */
753   gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
754       oclass->in_plugin->type, caps, ffmpegdec->context);
755
756   GST_LOG_OBJECT (ffmpegdec, "size after %dx%d", ffmpegdec->context->width,
757       ffmpegdec->context->height);
758
759   if (!ffmpegdec->context->time_base.den || !ffmpegdec->context->time_base.num) {
760     GST_DEBUG_OBJECT (ffmpegdec, "forcing 25/1 framerate");
761     ffmpegdec->context->time_base.num = 1;
762     ffmpegdec->context->time_base.den = 25;
763   }
764
765   /* get pixel aspect ratio if it's set */
766   structure = gst_caps_get_structure (caps, 0);
767
768   par = gst_structure_get_value (structure, "pixel-aspect-ratio");
769   if (par) {
770     GST_DEBUG_OBJECT (ffmpegdec, "sink caps have pixel-aspect-ratio of %d:%d",
771         gst_value_get_fraction_numerator (par),
772         gst_value_get_fraction_denominator (par));
773     /* should be NULL */
774     if (ffmpegdec->par)
775       g_free (ffmpegdec->par);
776     ffmpegdec->par = g_new0 (GValue, 1);
777     gst_value_init_and_copy (ffmpegdec->par, par);
778   }
779
780   /* get the framerate from incoming caps. fps_n is set to -1 when
781    * there is no valid framerate */
782   fps = gst_structure_get_value (structure, "framerate");
783   if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
784     ffmpegdec->format.video.fps_n = gst_value_get_fraction_numerator (fps);
785     ffmpegdec->format.video.fps_d = gst_value_get_fraction_denominator (fps);
786     GST_DEBUG_OBJECT (ffmpegdec, "Using framerate %d/%d from incoming caps",
787         ffmpegdec->format.video.fps_n, ffmpegdec->format.video.fps_d);
788   } else {
789     ffmpegdec->format.video.fps_n = -1;
790     GST_DEBUG_OBJECT (ffmpegdec, "Using framerate from codec");
791   }
792
793   /* figure out if we can use direct rendering */
794   ffmpegdec->current_dr = FALSE;
795   ffmpegdec->extra_ref = FALSE;
796   if (ffmpegdec->direct_rendering) {
797     GST_DEBUG_OBJECT (ffmpegdec, "trying to enable direct rendering");
798     if (oclass->in_plugin->capabilities & CODEC_CAP_DR1) {
799       if (oclass->in_plugin->id == CODEC_ID_H264) {
800         GST_DEBUG_OBJECT (ffmpegdec, "disable direct rendering setup for H264");
801         /* does not work, many stuff reads outside of the planes */
802         ffmpegdec->current_dr = FALSE;
803         ffmpegdec->extra_ref = TRUE;
804       } else if ((oclass->in_plugin->id == CODEC_ID_SVQ1) ||
805           (oclass->in_plugin->id == CODEC_ID_VP5) ||
806           (oclass->in_plugin->id == CODEC_ID_VP6) ||
807           (oclass->in_plugin->id == CODEC_ID_VP6F) ||
808           (oclass->in_plugin->id == CODEC_ID_VP6A)) {
809         GST_DEBUG_OBJECT (ffmpegdec,
810             "disable direct rendering setup for broken stride support");
811         /* does not work, uses a incompatible stride. See #610613 */
812         ffmpegdec->current_dr = FALSE;
813         ffmpegdec->extra_ref = TRUE;
814       } else {
815         GST_DEBUG_OBJECT (ffmpegdec, "enabled direct rendering");
816         ffmpegdec->current_dr = TRUE;
817       }
818     } else {
819       GST_DEBUG_OBJECT (ffmpegdec, "direct rendering not supported");
820     }
821   }
822   if (ffmpegdec->current_dr) {
823     /* do *not* draw edges when in direct rendering, for some reason it draws
824      * outside of the memory. */
825     ffmpegdec->context->flags |= CODEC_FLAG_EMU_EDGE;
826   }
827
828   /* for AAC we only use av_parse if not on raw caps */
829   if (oclass->in_plugin->id == CODEC_ID_AAC) {
830     const gchar *format = gst_structure_get_string (structure, "stream-format");
831
832     if (format == NULL || strcmp (format, "raw") == 0) {
833       ffmpegdec->turnoff_parser = TRUE;
834     }
835   }
836
837   /* workaround encoder bugs */
838   ffmpegdec->context->workaround_bugs |= FF_BUG_AUTODETECT;
839   ffmpegdec->context->error_recognition = 1;
840
841   /* for slow cpus */
842   ffmpegdec->context->lowres = ffmpegdec->lowres;
843   ffmpegdec->context->hurry_up = ffmpegdec->hurry_up;
844
845   /* ffmpeg can draw motion vectors on top of the image (not every decoder
846    * supports it) */
847   ffmpegdec->context->debug_mv = ffmpegdec->debug_mv;
848
849   /* open codec - we don't select an output pix_fmt yet,
850    * simply because we don't know! We only get it
851    * during playback... */
852   if (!gst_ffmpegdec_open (ffmpegdec))
853     goto open_failed;
854
855   /* clipping region */
856   gst_structure_get_int (structure, "width",
857       &ffmpegdec->format.video.clip_width);
858   gst_structure_get_int (structure, "height",
859       &ffmpegdec->format.video.clip_height);
860
861   GST_DEBUG_OBJECT (pad, "clipping to %dx%d",
862       ffmpegdec->format.video.clip_width, ffmpegdec->format.video.clip_height);
863
864   /* take into account the lowres property */
865   if (ffmpegdec->format.video.clip_width != -1)
866     ffmpegdec->format.video.clip_width >>= ffmpegdec->lowres;
867   if (ffmpegdec->format.video.clip_height != -1)
868     ffmpegdec->format.video.clip_height >>= ffmpegdec->lowres;
869
870   GST_DEBUG_OBJECT (pad, "final clipping to %dx%d",
871       ffmpegdec->format.video.clip_width, ffmpegdec->format.video.clip_height);
872
873 done:
874   GST_OBJECT_UNLOCK (ffmpegdec);
875
876   gst_object_unref (ffmpegdec);
877
878   return ret;
879
880   /* ERRORS */
881 open_failed:
882   {
883     GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
884     if (ffmpegdec->par) {
885       g_free (ffmpegdec->par);
886       ffmpegdec->par = NULL;
887     }
888     ret = FALSE;
889     goto done;
890   }
891 }
892
893 static GstFlowReturn
894 alloc_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf,
895     gint width, gint height)
896 {
897   GstFlowReturn ret;
898   gint fsize;
899
900   ret = GST_FLOW_ERROR;
901   *outbuf = NULL;
902
903   GST_LOG_OBJECT (ffmpegdec, "alloc output buffer");
904
905   /* see if we need renegotiation */
906   if (G_UNLIKELY (!gst_ffmpegdec_negotiate (ffmpegdec, FALSE)))
907     goto negotiate_failed;
908
909   /* get the size of the gstreamer output buffer given a
910    * width/height/format */
911   fsize = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
912       width, height);
913
914   if (!ffmpegdec->context->palctrl && ffmpegdec->can_allocate_aligned) {
915     GST_LOG_OBJECT (ffmpegdec, "calling pad_alloc");
916     /* no pallete, we can use the buffer size to alloc */
917     ret = gst_pad_alloc_buffer_and_set_caps (ffmpegdec->srcpad,
918         GST_BUFFER_OFFSET_NONE, fsize,
919         GST_PAD_CAPS (ffmpegdec->srcpad), outbuf);
920     if (G_UNLIKELY (ret != GST_FLOW_OK))
921       goto alloc_failed;
922
923     /* If buffer isn't 128-bit aligned, create a memaligned one ourselves */
924     if (((uintptr_t) GST_BUFFER_DATA (*outbuf)) % 16) {
925       GST_DEBUG_OBJECT (ffmpegdec,
926           "Downstream can't allocate aligned buffers.");
927       ffmpegdec->can_allocate_aligned = FALSE;
928       gst_buffer_unref (*outbuf);
929       *outbuf = new_aligned_buffer (fsize, GST_PAD_CAPS (ffmpegdec->srcpad));
930     }
931   } else {
932     GST_LOG_OBJECT (ffmpegdec,
933         "not calling pad_alloc, we have a pallete or downstream can't give 16 byte aligned buffers.");
934     /* for paletted data we can't use pad_alloc_buffer(), because
935      * fsize contains the size of the palette, so the overall size
936      * is bigger than ffmpegcolorspace's unit size, which will
937      * prompt GstBaseTransform to complain endlessly ... */
938     *outbuf = new_aligned_buffer (fsize, GST_PAD_CAPS (ffmpegdec->srcpad));
939     ret = GST_FLOW_OK;
940   }
941   return ret;
942
943   /* special cases */
944 negotiate_failed:
945   {
946     GST_DEBUG_OBJECT (ffmpegdec, "negotiate failed");
947     return GST_FLOW_NOT_NEGOTIATED;
948   }
949 alloc_failed:
950   {
951     GST_DEBUG_OBJECT (ffmpegdec, "pad_alloc failed %d (%s)", ret,
952         gst_flow_get_name (ret));
953     return ret;
954   }
955 }
956
957 static int
958 gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
959 {
960   GstBuffer *buf = NULL;
961   GstFFMpegDec *ffmpegdec;
962   gint width, height;
963   gint coded_width, coded_height;
964   gint res;
965
966   ffmpegdec = (GstFFMpegDec *) context->opaque;
967
968   GST_DEBUG_OBJECT (ffmpegdec, "getting buffer");
969
970   /* apply the last info we have seen to this picture, when we get the
971    * picture back from ffmpeg we can use this to correctly timestamp the output
972    * buffer */
973   picture->reordered_opaque = context->reordered_opaque;
974   /* make sure we don't free the buffer when it's not ours */
975   picture->opaque = NULL;
976
977   /* take width and height before clipping */
978   width = context->width;
979   height = context->height;
980   coded_width = context->coded_width;
981   coded_height = context->coded_height;
982
983   GST_LOG_OBJECT (ffmpegdec, "dimension %dx%d, coded %dx%d", width, height,
984       coded_width, coded_height);
985   if (!ffmpegdec->current_dr) {
986     GST_LOG_OBJECT (ffmpegdec, "direct rendering disabled, fallback alloc");
987     res = avcodec_default_get_buffer (context, picture);
988
989     GST_LOG_OBJECT (ffmpegdec, "linsize %d %d %d", picture->linesize[0],
990         picture->linesize[1], picture->linesize[2]);
991     GST_LOG_OBJECT (ffmpegdec, "data %u %u %u", 0,
992         (guint) (picture->data[1] - picture->data[0]),
993         (guint) (picture->data[2] - picture->data[0]));
994     return res;
995   }
996
997   switch (context->codec_type) {
998     case CODEC_TYPE_VIDEO:
999       /* some ffmpeg video plugins don't see the point in setting codec_type ... */
1000     case CODEC_TYPE_UNKNOWN:
1001     {
1002       GstFlowReturn ret;
1003       gint clip_width, clip_height;
1004
1005       /* take final clipped output size */
1006       if ((clip_width = ffmpegdec->format.video.clip_width) == -1)
1007         clip_width = width;
1008       if ((clip_height = ffmpegdec->format.video.clip_height) == -1)
1009         clip_height = height;
1010
1011       GST_LOG_OBJECT (ffmpegdec, "raw outsize %d/%d", width, height);
1012
1013       /* this is the size ffmpeg needs for the buffer */
1014       avcodec_align_dimensions (context, &width, &height);
1015
1016       GST_LOG_OBJECT (ffmpegdec, "aligned outsize %d/%d, clip %d/%d",
1017           width, height, clip_width, clip_height);
1018
1019       if (width != clip_width || height != clip_height) {
1020         /* We can't alloc if we need to clip the output buffer later */
1021         GST_LOG_OBJECT (ffmpegdec, "we need clipping, fallback alloc");
1022         return avcodec_default_get_buffer (context, picture);
1023       }
1024
1025       /* alloc with aligned dimensions for ffmpeg */
1026       ret = alloc_output_buffer (ffmpegdec, &buf, width, height);
1027       if (G_UNLIKELY (ret != GST_FLOW_OK)) {
1028         /* alloc default buffer when we can't get one from downstream */
1029         GST_LOG_OBJECT (ffmpegdec, "alloc failed, fallback alloc");
1030         return avcodec_default_get_buffer (context, picture);
1031       }
1032
1033       /* copy the right pointers and strides in the picture object */
1034       gst_ffmpeg_avpicture_fill ((AVPicture *) picture,
1035           GST_BUFFER_DATA (buf), context->pix_fmt, width, height);
1036       break;
1037     }
1038     case CODEC_TYPE_AUDIO:
1039     default:
1040       GST_ERROR_OBJECT (ffmpegdec,
1041           "_get_buffer() should never get called for non-video buffers !");
1042       g_assert_not_reached ();
1043       break;
1044   }
1045
1046   /* tell ffmpeg we own this buffer, tranfer the ref we have on the buffer to
1047    * the opaque data. */
1048   picture->type = FF_BUFFER_TYPE_USER;
1049   picture->age = 256 * 256 * 256 * 64;
1050   picture->opaque = buf;
1051
1052 #ifdef EXTRA_REF
1053   if (picture->reference != 0 || ffmpegdec->extra_ref) {
1054     GST_DEBUG_OBJECT (ffmpegdec, "adding extra ref");
1055     gst_buffer_ref (buf);
1056   }
1057 #endif
1058
1059   GST_LOG_OBJECT (ffmpegdec, "returned buffer %p", buf);
1060
1061   return 0;
1062 }
1063
1064 static void
1065 gst_ffmpegdec_release_buffer (AVCodecContext * context, AVFrame * picture)
1066 {
1067   gint i;
1068   GstBuffer *buf;
1069   GstFFMpegDec *ffmpegdec;
1070
1071   ffmpegdec = (GstFFMpegDec *) context->opaque;
1072
1073   /* check if it was our buffer */
1074   if (picture->opaque == NULL) {
1075     GST_DEBUG_OBJECT (ffmpegdec, "default release buffer");
1076     avcodec_default_release_buffer (context, picture);
1077     return;
1078   }
1079
1080   /* we remove the opaque data now */
1081   buf = GST_BUFFER_CAST (picture->opaque);
1082   GST_DEBUG_OBJECT (ffmpegdec, "release buffer %p", buf);
1083   picture->opaque = NULL;
1084
1085 #ifdef EXTRA_REF
1086   if (picture->reference != 0 || ffmpegdec->extra_ref) {
1087     GST_DEBUG_OBJECT (ffmpegdec, "remove extra ref");
1088     gst_buffer_unref (buf);
1089   }
1090 #else
1091   gst_buffer_unref (buf);
1092 #endif
1093
1094   /* zero out the reference in ffmpeg */
1095   for (i = 0; i < 4; i++) {
1096     picture->data[i] = NULL;
1097     picture->linesize[i] = 0;
1098   }
1099 }
1100
1101 static void
1102 gst_ffmpegdec_add_pixel_aspect_ratio (GstFFMpegDec * ffmpegdec,
1103     GstStructure * s)
1104 {
1105   gboolean demuxer_par_set = FALSE;
1106   gboolean decoder_par_set = FALSE;
1107   gint demuxer_num = 1, demuxer_denom = 1;
1108   gint decoder_num = 1, decoder_denom = 1;
1109
1110   GST_OBJECT_LOCK (ffmpegdec);
1111
1112   if (ffmpegdec->par) {
1113     demuxer_num = gst_value_get_fraction_numerator (ffmpegdec->par);
1114     demuxer_denom = gst_value_get_fraction_denominator (ffmpegdec->par);
1115     demuxer_par_set = TRUE;
1116     GST_DEBUG_OBJECT (ffmpegdec, "Demuxer PAR: %d:%d", demuxer_num,
1117         demuxer_denom);
1118   }
1119
1120   if (ffmpegdec->context->sample_aspect_ratio.num &&
1121       ffmpegdec->context->sample_aspect_ratio.den) {
1122     decoder_num = ffmpegdec->context->sample_aspect_ratio.num;
1123     decoder_denom = ffmpegdec->context->sample_aspect_ratio.den;
1124     decoder_par_set = TRUE;
1125     GST_DEBUG_OBJECT (ffmpegdec, "Decoder PAR: %d:%d", decoder_num,
1126         decoder_denom);
1127   }
1128
1129   GST_OBJECT_UNLOCK (ffmpegdec);
1130
1131   if (!demuxer_par_set && !decoder_par_set)
1132     goto no_par;
1133
1134   if (demuxer_par_set && !decoder_par_set)
1135     goto use_demuxer_par;
1136
1137   if (decoder_par_set && !demuxer_par_set)
1138     goto use_decoder_par;
1139
1140   /* Both the demuxer and the decoder provide a PAR. If one of
1141    * the two PARs is 1:1 and the other one is not, use the one
1142    * that is not 1:1. */
1143   if (demuxer_num == demuxer_denom && decoder_num != decoder_denom)
1144     goto use_decoder_par;
1145
1146   if (decoder_num == decoder_denom && demuxer_num != demuxer_denom)
1147     goto use_demuxer_par;
1148
1149   /* Both PARs are non-1:1, so use the PAR provided by the demuxer */
1150   goto use_demuxer_par;
1151
1152 use_decoder_par:
1153   {
1154     GST_DEBUG_OBJECT (ffmpegdec,
1155         "Setting decoder provided pixel-aspect-ratio of %u:%u", decoder_num,
1156         decoder_denom);
1157     gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, decoder_num,
1158         decoder_denom, NULL);
1159     return;
1160   }
1161
1162 use_demuxer_par:
1163   {
1164     GST_DEBUG_OBJECT (ffmpegdec,
1165         "Setting demuxer provided pixel-aspect-ratio of %u:%u", demuxer_num,
1166         demuxer_denom);
1167     gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, demuxer_num,
1168         demuxer_denom, NULL);
1169     return;
1170   }
1171 no_par:
1172   {
1173     GST_DEBUG_OBJECT (ffmpegdec,
1174         "Neither demuxer nor codec provide a pixel-aspect-ratio");
1175     return;
1176   }
1177 }
1178
1179 static gboolean
1180 gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec, gboolean force)
1181 {
1182   GstFFMpegDecClass *oclass;
1183   GstCaps *caps;
1184
1185   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1186
1187   switch (oclass->in_plugin->type) {
1188     case CODEC_TYPE_VIDEO:
1189       if (!force && ffmpegdec->format.video.width == ffmpegdec->context->width
1190           && ffmpegdec->format.video.height == ffmpegdec->context->height
1191           && ffmpegdec->format.video.fps_n == ffmpegdec->format.video.old_fps_n
1192           && ffmpegdec->format.video.fps_d == ffmpegdec->format.video.old_fps_d
1193           && ffmpegdec->format.video.pix_fmt == ffmpegdec->context->pix_fmt
1194           && ffmpegdec->format.video.par_n ==
1195           ffmpegdec->context->sample_aspect_ratio.num
1196           && ffmpegdec->format.video.par_d ==
1197           ffmpegdec->context->sample_aspect_ratio.den)
1198         return TRUE;
1199       GST_DEBUG_OBJECT (ffmpegdec,
1200           "Renegotiating video from %dx%d@ %d:%d PAR %d/%d fps to %dx%d@ %d:%d PAR %d/%d fps",
1201           ffmpegdec->format.video.width, ffmpegdec->format.video.height,
1202           ffmpegdec->format.video.par_n, ffmpegdec->format.video.par_d,
1203           ffmpegdec->format.video.old_fps_n, ffmpegdec->format.video.old_fps_n,
1204           ffmpegdec->context->width, ffmpegdec->context->height,
1205           ffmpegdec->context->sample_aspect_ratio.num,
1206           ffmpegdec->context->sample_aspect_ratio.den,
1207           ffmpegdec->format.video.fps_n, ffmpegdec->format.video.fps_d);
1208       ffmpegdec->format.video.width = ffmpegdec->context->width;
1209       ffmpegdec->format.video.height = ffmpegdec->context->height;
1210       ffmpegdec->format.video.old_fps_n = ffmpegdec->format.video.fps_n;
1211       ffmpegdec->format.video.old_fps_d = ffmpegdec->format.video.fps_d;
1212       ffmpegdec->format.video.pix_fmt = ffmpegdec->context->pix_fmt;
1213       ffmpegdec->format.video.par_n =
1214           ffmpegdec->context->sample_aspect_ratio.num;
1215       ffmpegdec->format.video.par_d =
1216           ffmpegdec->context->sample_aspect_ratio.den;
1217       break;
1218     case CODEC_TYPE_AUDIO:
1219     {
1220       gint depth = av_smp_format_depth (ffmpegdec->context->sample_fmt);
1221       if (!force && ffmpegdec->format.audio.samplerate ==
1222           ffmpegdec->context->sample_rate &&
1223           ffmpegdec->format.audio.channels == ffmpegdec->context->channels &&
1224           ffmpegdec->format.audio.depth == depth)
1225         return TRUE;
1226       GST_DEBUG_OBJECT (ffmpegdec,
1227           "Renegotiating audio from %dHz@%dchannels (%d) to %dHz@%dchannels (%d)",
1228           ffmpegdec->format.audio.samplerate, ffmpegdec->format.audio.channels,
1229           ffmpegdec->format.audio.depth,
1230           ffmpegdec->context->sample_rate, ffmpegdec->context->channels, depth);
1231       ffmpegdec->format.audio.samplerate = ffmpegdec->context->sample_rate;
1232       ffmpegdec->format.audio.channels = ffmpegdec->context->channels;
1233       ffmpegdec->format.audio.depth = depth;
1234     }
1235       break;
1236     default:
1237       break;
1238   }
1239
1240   caps = gst_ffmpeg_codectype_to_caps (oclass->in_plugin->type,
1241       ffmpegdec->context, oclass->in_plugin->id, FALSE);
1242
1243   if (caps == NULL)
1244     goto no_caps;
1245
1246   switch (oclass->in_plugin->type) {
1247     case CODEC_TYPE_VIDEO:
1248     {
1249       gint width, height;
1250       gboolean interlaced;
1251
1252       width = ffmpegdec->format.video.clip_width;
1253       height = ffmpegdec->format.video.clip_height;
1254       interlaced = ffmpegdec->format.video.interlaced;
1255
1256       if (width != -1 && height != -1) {
1257         /* overwrite the output size with the dimension of the
1258          * clipping region but only if they are smaller. */
1259         if (width < ffmpegdec->context->width)
1260           gst_caps_set_simple (caps, "width", G_TYPE_INT, width, NULL);
1261         if (height < ffmpegdec->context->height)
1262           gst_caps_set_simple (caps, "height", G_TYPE_INT, height, NULL);
1263       }
1264       gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, interlaced,
1265           NULL);
1266
1267       /* If a demuxer provided a framerate then use it (#313970) */
1268       if (ffmpegdec->format.video.fps_n != -1) {
1269         gst_caps_set_simple (caps, "framerate",
1270             GST_TYPE_FRACTION, ffmpegdec->format.video.fps_n,
1271             ffmpegdec->format.video.fps_d, NULL);
1272       }
1273       gst_ffmpegdec_add_pixel_aspect_ratio (ffmpegdec,
1274           gst_caps_get_structure (caps, 0));
1275       break;
1276     }
1277     case CODEC_TYPE_AUDIO:
1278     {
1279       break;
1280     }
1281     default:
1282       break;
1283   }
1284
1285   if (!gst_pad_set_caps (ffmpegdec->srcpad, caps))
1286     goto caps_failed;
1287
1288   gst_caps_unref (caps);
1289
1290   return TRUE;
1291
1292   /* ERRORS */
1293 no_caps:
1294   {
1295     GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
1296         ("could not find caps for codec (%s), unknown type",
1297             oclass->in_plugin->name));
1298     return FALSE;
1299   }
1300 caps_failed:
1301   {
1302     GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
1303         ("Could not set caps for ffmpeg decoder (%s), not fixed?",
1304             oclass->in_plugin->name));
1305     gst_caps_unref (caps);
1306
1307     return FALSE;
1308   }
1309 }
1310
1311 /* perform qos calculations before decoding the next frame.
1312  *
1313  * Sets the hurry_up flag and if things are really bad, skips to the next
1314  * keyframe.
1315  * 
1316  * Returns TRUE if the frame should be decoded, FALSE if the frame can be dropped
1317  * entirely.
1318  */
1319 static gboolean
1320 gst_ffmpegdec_do_qos (GstFFMpegDec * ffmpegdec, GstClockTime timestamp,
1321     gboolean * mode_switch)
1322 {
1323   GstClockTimeDiff diff;
1324   gdouble proportion;
1325   GstClockTime qostime, earliest_time;
1326
1327   *mode_switch = FALSE;
1328
1329   /* no timestamp, can't do QoS */
1330   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp)))
1331     goto no_qos;
1332
1333   /* get latest QoS observation values */
1334   gst_ffmpegdec_read_qos (ffmpegdec, &proportion, &earliest_time);
1335
1336   /* skip qos if we have no observation (yet) */
1337   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
1338     /* no hurry_up initialy */
1339     ffmpegdec->context->hurry_up = 0;
1340     goto no_qos;
1341   }
1342
1343   /* qos is done on running time of the timestamp */
1344   qostime = gst_segment_to_running_time (&ffmpegdec->segment, GST_FORMAT_TIME,
1345       timestamp);
1346
1347   /* timestamp can be out of segment, then we don't do QoS */
1348   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (qostime)))
1349     goto no_qos;
1350
1351   /* see how our next timestamp relates to the latest qos timestamp. negative
1352    * values mean we are early, positive values mean we are too late. */
1353   diff = GST_CLOCK_DIFF (qostime, earliest_time);
1354
1355   GST_DEBUG_OBJECT (ffmpegdec, "QOS: qostime %" GST_TIME_FORMAT
1356       ", earliest %" GST_TIME_FORMAT, GST_TIME_ARGS (qostime),
1357       GST_TIME_ARGS (earliest_time));
1358
1359   /* if we using less than 40% of the available time, we can try to
1360    * speed up again when we were slow. */
1361   if (proportion < 0.4 && diff < 0) {
1362     goto normal_mode;
1363   } else {
1364     /* if we're more than two seconds late, switch to the next keyframe */
1365     /* FIXME, let the demuxer decide what's the best since we might be dropping
1366      * a lot of frames when the keyframe is far away or we even might not get a new
1367      * keyframe at all.. */
1368     if (diff > ((GstClockTimeDiff) GST_SECOND * 2)
1369         && !ffmpegdec->waiting_for_key) {
1370       goto skip_to_keyframe;
1371     } else if (diff >= 0) {
1372       /* we're too slow, try to speed up */
1373       if (ffmpegdec->waiting_for_key) {
1374         /* we were waiting for a keyframe, that's ok */
1375         goto skipping;
1376       }
1377       /* switch to hurry_up mode */
1378       goto hurry_up;
1379     }
1380   }
1381
1382 no_qos:
1383   return TRUE;
1384
1385 skipping:
1386   {
1387     return FALSE;
1388   }
1389 normal_mode:
1390   {
1391     if (ffmpegdec->context->hurry_up != 0) {
1392       ffmpegdec->context->hurry_up = 0;
1393       *mode_switch = TRUE;
1394       GST_DEBUG_OBJECT (ffmpegdec, "QOS: normal mode %g < 0.4", proportion);
1395     }
1396     return TRUE;
1397   }
1398 skip_to_keyframe:
1399   {
1400     ffmpegdec->context->hurry_up = 1;
1401     ffmpegdec->waiting_for_key = TRUE;
1402     *mode_switch = TRUE;
1403     GST_DEBUG_OBJECT (ffmpegdec,
1404         "QOS: keyframe, %" G_GINT64_FORMAT " > GST_SECOND/2", diff);
1405     /* we can skip the current frame */
1406     return FALSE;
1407   }
1408 hurry_up:
1409   {
1410     if (ffmpegdec->context->hurry_up != 1) {
1411       ffmpegdec->context->hurry_up = 1;
1412       *mode_switch = TRUE;
1413       GST_DEBUG_OBJECT (ffmpegdec,
1414           "QOS: hurry up, diff %" G_GINT64_FORMAT " >= 0", diff);
1415     }
1416     return TRUE;
1417   }
1418 }
1419
1420 /* returns TRUE if buffer is within segment, else FALSE.
1421  * if Buffer is on segment border, it's timestamp and duration will be clipped */
1422 static gboolean
1423 clip_video_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
1424     GstClockTime in_dur)
1425 {
1426   gboolean res = TRUE;
1427   gint64 cstart, cstop;
1428   GstClockTime stop;
1429
1430   GST_LOG_OBJECT (dec,
1431       "timestamp:%" GST_TIME_FORMAT " , duration:%" GST_TIME_FORMAT,
1432       GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur));
1433
1434   /* can't clip without TIME segment */
1435   if (G_UNLIKELY (dec->segment.format != GST_FORMAT_TIME))
1436     goto beach;
1437
1438   /* we need a start time */
1439   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (in_ts)))
1440     goto beach;
1441
1442   /* generate valid stop, if duration unknown, we have unknown stop */
1443   stop =
1444       GST_CLOCK_TIME_IS_VALID (in_dur) ? (in_ts + in_dur) : GST_CLOCK_TIME_NONE;
1445
1446   /* now clip */
1447   res =
1448       gst_segment_clip (&dec->segment, GST_FORMAT_TIME, in_ts, stop, &cstart,
1449       &cstop);
1450   if (G_UNLIKELY (!res))
1451     goto beach;
1452
1453   /* we're pretty sure the duration of this buffer is not till the end of this
1454    * segment (which _clip will assume when the stop is -1) */
1455   if (stop == GST_CLOCK_TIME_NONE)
1456     cstop = GST_CLOCK_TIME_NONE;
1457
1458   /* update timestamp and possibly duration if the clipped stop time is
1459    * valid */
1460   GST_BUFFER_TIMESTAMP (buf) = cstart;
1461   if (GST_CLOCK_TIME_IS_VALID (cstop))
1462     GST_BUFFER_DURATION (buf) = cstop - cstart;
1463
1464   GST_LOG_OBJECT (dec,
1465       "clipped timestamp:%" GST_TIME_FORMAT " , duration:%" GST_TIME_FORMAT,
1466       GST_TIME_ARGS (cstart), GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1467
1468 beach:
1469   GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : ""));
1470   return res;
1471 }
1472
1473
1474 /* figure out if the current picture is a keyframe, return TRUE if that is
1475  * the case. */
1476 static gboolean
1477 check_keyframe (GstFFMpegDec * ffmpegdec)
1478 {
1479   GstFFMpegDecClass *oclass;
1480   gboolean is_itype = FALSE;
1481   gboolean is_reference = FALSE;
1482   gboolean iskeyframe;
1483
1484   /* figure out if we are dealing with a keyframe */
1485   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
1486
1487   /* remember that we have B frames, we need this for the DTS -> PTS conversion
1488    * code */
1489   if (!ffmpegdec->has_b_frames && ffmpegdec->picture->pict_type == FF_B_TYPE) {
1490     GST_DEBUG_OBJECT (ffmpegdec, "we have B frames");
1491     ffmpegdec->has_b_frames = TRUE;
1492   }
1493
1494   is_itype = (ffmpegdec->picture->pict_type == FF_I_TYPE);
1495   is_reference = (ffmpegdec->picture->reference == 1);
1496
1497   iskeyframe = (is_itype || is_reference || ffmpegdec->picture->key_frame)
1498       || (oclass->in_plugin->id == CODEC_ID_INDEO3)
1499       || (oclass->in_plugin->id == CODEC_ID_MSZH)
1500       || (oclass->in_plugin->id == CODEC_ID_ZLIB)
1501       || (oclass->in_plugin->id == CODEC_ID_VP3)
1502       || (oclass->in_plugin->id == CODEC_ID_HUFFYUV);
1503
1504   GST_LOG_OBJECT (ffmpegdec,
1505       "current picture: type: %d, is_keyframe:%d, is_itype:%d, is_reference:%d",
1506       ffmpegdec->picture->pict_type, iskeyframe, is_itype, is_reference);
1507
1508   return iskeyframe;
1509 }
1510
1511 /* get an outbuf buffer with the current picture */
1512 static GstFlowReturn
1513 get_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf)
1514 {
1515   GstFlowReturn ret;
1516
1517   ret = GST_FLOW_OK;
1518   *outbuf = NULL;
1519
1520   if (ffmpegdec->picture->opaque != NULL) {
1521     /* we allocated a picture already for ffmpeg to decode into, let's pick it
1522      * up and use it now. */
1523     *outbuf = (GstBuffer *) ffmpegdec->picture->opaque;
1524     GST_LOG_OBJECT (ffmpegdec, "using opaque buffer %p", *outbuf);
1525 #ifndef EXTRA_REF
1526     gst_buffer_ref (*outbuf);
1527 #endif
1528   } else {
1529     AVPicture pic, *outpic;
1530     gint width, height;
1531
1532     GST_LOG_OBJECT (ffmpegdec, "get output buffer");
1533
1534     /* figure out size of output buffer, this is the clipped output size because
1535      * we will copy the picture into it but only when the clipping region is
1536      * smaller than the actual picture size. */
1537     if ((width = ffmpegdec->format.video.clip_width) == -1)
1538       width = ffmpegdec->context->width;
1539     else if (width > ffmpegdec->context->width)
1540       width = ffmpegdec->context->width;
1541
1542     if ((height = ffmpegdec->format.video.clip_height) == -1)
1543       height = ffmpegdec->context->height;
1544     else if (height > ffmpegdec->context->height)
1545       height = ffmpegdec->context->height;
1546
1547     GST_LOG_OBJECT (ffmpegdec, "clip width %d/height %d", width, height);
1548
1549     ret = alloc_output_buffer (ffmpegdec, outbuf, width, height);
1550     if (G_UNLIKELY (ret != GST_FLOW_OK))
1551       goto alloc_failed;
1552
1553     /* original ffmpeg code does not handle odd sizes correctly.
1554      * This patched up version does */
1555     gst_ffmpeg_avpicture_fill (&pic, GST_BUFFER_DATA (*outbuf),
1556         ffmpegdec->context->pix_fmt, width, height);
1557
1558     outpic = (AVPicture *) ffmpegdec->picture;
1559
1560     GST_LOG_OBJECT (ffmpegdec, "linsize %d %d %d", outpic->linesize[0],
1561         outpic->linesize[1], outpic->linesize[2]);
1562     GST_LOG_OBJECT (ffmpegdec, "data %u %u %u", 0,
1563         (guint) (outpic->data[1] - outpic->data[0]),
1564         (guint) (outpic->data[2] - outpic->data[0]));
1565
1566     av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt, width, height);
1567   }
1568   ffmpegdec->picture->reordered_opaque = -1;
1569
1570   return ret;
1571
1572   /* special cases */
1573 alloc_failed:
1574   {
1575     GST_DEBUG_OBJECT (ffmpegdec, "pad_alloc failed");
1576     return ret;
1577   }
1578 }
1579
1580 static void
1581 clear_queued (GstFFMpegDec * ffmpegdec)
1582 {
1583   g_list_foreach (ffmpegdec->queued, (GFunc) gst_mini_object_unref, NULL);
1584   g_list_free (ffmpegdec->queued);
1585   ffmpegdec->queued = NULL;
1586 }
1587
1588 static GstFlowReturn
1589 flush_queued (GstFFMpegDec * ffmpegdec)
1590 {
1591   GstFlowReturn res = GST_FLOW_OK;
1592
1593   while (ffmpegdec->queued) {
1594     GstBuffer *buf = GST_BUFFER_CAST (ffmpegdec->queued->data);
1595
1596     GST_LOG_OBJECT (ffmpegdec, "pushing buffer %p, offset %"
1597         G_GUINT64_FORMAT ", timestamp %"
1598         GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT, buf,
1599         GST_BUFFER_OFFSET (buf),
1600         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1601         GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
1602
1603     /* iterate ouput queue an push downstream */
1604     res = gst_pad_push (ffmpegdec->srcpad, buf);
1605
1606     ffmpegdec->queued =
1607         g_list_delete_link (ffmpegdec->queued, ffmpegdec->queued);
1608   }
1609   return res;
1610 }
1611
1612 /* gst_ffmpegdec_[video|audio]_frame:
1613  * ffmpegdec:
1614  * data: pointer to the data to decode
1615  * size: size of data in bytes
1616  * in_timestamp: incoming timestamp.
1617  * in_duration: incoming duration.
1618  * in_offset: incoming offset (frame number).
1619  * outbuf: outgoing buffer. Different from NULL ONLY if it contains decoded data.
1620  * ret: Return flow.
1621  *
1622  * Returns: number of bytes used in decoding. The check for successful decode is
1623  *   outbuf being non-NULL.
1624  */
1625 static gint
1626 gst_ffmpegdec_video_frame (GstFFMpegDec * ffmpegdec,
1627     guint8 * data, guint size,
1628     const GstTSInfo * dec_info, GstBuffer ** outbuf, GstFlowReturn * ret)
1629 {
1630   gint len = -1;
1631   gint have_data;
1632   gboolean iskeyframe;
1633   gboolean mode_switch;
1634   gboolean decode;
1635   gint hurry_up = 0;
1636   GstClockTime out_timestamp, out_duration, out_pts;
1637   gint64 out_offset;
1638   const GstTSInfo *out_info;
1639
1640   *ret = GST_FLOW_OK;
1641   *outbuf = NULL;
1642
1643   ffmpegdec->context->opaque = ffmpegdec;
1644
1645   /* in case we skip frames */
1646   ffmpegdec->picture->pict_type = -1;
1647
1648   /* run QoS code, we don't stop decoding the frame when we are late because
1649    * else we might skip a reference frame */
1650   decode = gst_ffmpegdec_do_qos (ffmpegdec, dec_info->timestamp, &mode_switch);
1651
1652   if (ffmpegdec->is_realvideo && data != NULL) {
1653     gint slice_count;
1654     gint i;
1655
1656     /* setup the slice table for realvideo */
1657     if (ffmpegdec->context->slice_offset == NULL)
1658       ffmpegdec->context->slice_offset = g_malloc (sizeof (guint32) * 1000);
1659
1660     slice_count = (*data++) + 1;
1661     ffmpegdec->context->slice_count = slice_count;
1662
1663     for (i = 0; i < slice_count; i++) {
1664       data += 4;
1665       ffmpegdec->context->slice_offset[i] = GST_READ_UINT32_LE (data);
1666       data += 4;
1667     }
1668   }
1669
1670   if (!decode) {
1671     /* no decoding needed, save previous hurry_up value and brutely skip
1672      * decoding everything */
1673     hurry_up = ffmpegdec->context->hurry_up;
1674     ffmpegdec->context->hurry_up = 2;
1675   }
1676
1677   /* save reference to the timing info */
1678   ffmpegdec->context->reordered_opaque = (gint64) dec_info->idx;
1679   ffmpegdec->picture->reordered_opaque = (gint64) dec_info->idx;
1680
1681   GST_DEBUG_OBJECT (ffmpegdec, "stored opaque values idx %d", dec_info->idx);
1682
1683   /* now decode the frame */
1684   len = avcodec_decode_video (ffmpegdec->context,
1685       ffmpegdec->picture, &have_data, data, size);
1686
1687   /* restore previous state */
1688   if (!decode)
1689     ffmpegdec->context->hurry_up = hurry_up;
1690
1691   GST_DEBUG_OBJECT (ffmpegdec, "after decode: len %d, have_data %d",
1692       len, have_data);
1693
1694   /* when we are in hurry_up mode, don't complain when ffmpeg returned
1695    * no data because we told it to skip stuff. */
1696   if (len < 0 && (mode_switch || ffmpegdec->context->hurry_up))
1697     len = 0;
1698
1699   if (len > 0 && have_data <= 0 && (mode_switch
1700           || ffmpegdec->context->hurry_up)) {
1701     /* we consumed some bytes but nothing decoded and we are skipping frames,
1702      * disable the interpollation of DTS timestamps */
1703     ffmpegdec->last_out = -1;
1704   }
1705
1706   /* no data, we're done */
1707   if (len < 0 || have_data <= 0)
1708     goto beach;
1709
1710   /* get the output picture timing info again */
1711   out_info = gst_ts_info_get (ffmpegdec, ffmpegdec->picture->reordered_opaque);
1712   out_pts = out_info->timestamp;
1713   out_duration = out_info->duration;
1714   out_offset = out_info->offset;
1715
1716   GST_DEBUG_OBJECT (ffmpegdec,
1717       "pts %" G_GUINT64_FORMAT " duration %" G_GUINT64_FORMAT " offset %"
1718       G_GINT64_FORMAT, out_pts, out_duration, out_offset);
1719   GST_DEBUG_OBJECT (ffmpegdec, "picture: pts %" G_GUINT64_FORMAT,
1720       (guint64) ffmpegdec->picture->pts);
1721   GST_DEBUG_OBJECT (ffmpegdec, "picture: num %d",
1722       ffmpegdec->picture->coded_picture_number);
1723   GST_DEBUG_OBJECT (ffmpegdec, "picture: ref %d",
1724       ffmpegdec->picture->reference);
1725   GST_DEBUG_OBJECT (ffmpegdec, "picture: display %d",
1726       ffmpegdec->picture->display_picture_number);
1727   GST_DEBUG_OBJECT (ffmpegdec, "picture: opaque %p",
1728       ffmpegdec->picture->opaque);
1729   GST_DEBUG_OBJECT (ffmpegdec, "picture: reordered opaque %" G_GUINT64_FORMAT,
1730       (guint64) ffmpegdec->picture->reordered_opaque);
1731   GST_DEBUG_OBJECT (ffmpegdec, "repeat_pict:%d",
1732       ffmpegdec->picture->repeat_pict);
1733   GST_DEBUG_OBJECT (ffmpegdec, "interlaced_frame:%d",
1734       ffmpegdec->picture->interlaced_frame);
1735
1736   if (G_UNLIKELY (ffmpegdec->picture->interlaced_frame !=
1737           ffmpegdec->format.video.interlaced)) {
1738     GST_WARNING ("Change in interlacing ! picture:%d, recorded:%d",
1739         ffmpegdec->picture->interlaced_frame,
1740         ffmpegdec->format.video.interlaced);
1741     ffmpegdec->format.video.interlaced = ffmpegdec->picture->interlaced_frame;
1742     gst_ffmpegdec_negotiate (ffmpegdec, TRUE);
1743   }
1744
1745   /* check if we are dealing with a keyframe here, this will also check if we
1746    * are dealing with B frames. */
1747   iskeyframe = check_keyframe (ffmpegdec);
1748
1749   /* check that the timestamps go upwards */
1750   if (ffmpegdec->last_out != -1 && ffmpegdec->last_out > out_pts) {
1751     /* timestamps go backwards, this means frames were reordered and we must
1752      * be dealing with DTS as the buffer timestamps */
1753     if (!ffmpegdec->reordered_out) {
1754       GST_DEBUG_OBJECT (ffmpegdec, "detected reordered out timestamps");
1755       ffmpegdec->reordered_out = TRUE;
1756     }
1757     if (ffmpegdec->reordered_in) {
1758       /* we reset the input reordering here because we want to recover from an
1759        * occasionally wrong reordered input timestamp */
1760       GST_DEBUG_OBJECT (ffmpegdec, "assuming DTS input timestamps");
1761       ffmpegdec->reordered_in = FALSE;
1762     }
1763   }
1764
1765   if (out_pts == 0 && out_pts == ffmpegdec->last_out) {
1766     GST_LOG_OBJECT (ffmpegdec, "ffmpeg returns 0 timestamps, ignoring");
1767     /* some codecs only output 0 timestamps, when that happens, make us select an
1768      * output timestamp based on the input timestamp. We do this by making the
1769      * ffmpeg timestamp and the interpollated next timestamp invalid. */
1770     out_pts = -1;
1771     ffmpegdec->next_out = -1;
1772   } else
1773     ffmpegdec->last_out = out_pts;
1774
1775   /* we assume DTS as input timestamps unless we see reordered input
1776    * timestamps */
1777   if (!ffmpegdec->reordered_in) {
1778     /* PTS and DTS are the same for keyframes */
1779     if (!iskeyframe && ffmpegdec->next_out != -1) {
1780       /* interpolate all timestamps except for keyframes, FIXME, this is
1781        * wrong when QoS is active. */
1782       GST_DEBUG_OBJECT (ffmpegdec, "interpolate timestamps");
1783       out_pts = -1;
1784       out_offset = -1;
1785     }
1786   }
1787
1788   /* when we're waiting for a keyframe, see if we have one or drop the current
1789    * non-keyframe */
1790   if (G_UNLIKELY (ffmpegdec->waiting_for_key)) {
1791     if (G_LIKELY (!iskeyframe))
1792       goto drop_non_keyframe;
1793
1794     /* we have a keyframe, we can stop waiting for one */
1795     ffmpegdec->waiting_for_key = FALSE;
1796   }
1797
1798   /* get a handle to the output buffer */
1799   *ret = get_output_buffer (ffmpegdec, outbuf);
1800   if (G_UNLIKELY (*ret != GST_FLOW_OK))
1801     goto no_output;
1802
1803   /*
1804    * Timestamps:
1805    *
1806    *  1) Copy picture timestamp if valid
1807    *  2) else interpolate from previous output timestamp
1808    *  3) else copy input timestamp
1809    */
1810   out_timestamp = -1;
1811   if (out_pts != -1) {
1812     /* Get (interpolated) timestamp from FFMPEG */
1813     out_timestamp = (GstClockTime) out_pts;
1814     GST_LOG_OBJECT (ffmpegdec, "using timestamp %" GST_TIME_FORMAT
1815         " returned by ffmpeg", GST_TIME_ARGS (out_timestamp));
1816   }
1817   if (!GST_CLOCK_TIME_IS_VALID (out_timestamp) && ffmpegdec->next_out != -1) {
1818     out_timestamp = ffmpegdec->next_out;
1819     GST_LOG_OBJECT (ffmpegdec, "using next timestamp %" GST_TIME_FORMAT,
1820         GST_TIME_ARGS (out_timestamp));
1821   }
1822   if (!GST_CLOCK_TIME_IS_VALID (out_timestamp)) {
1823     out_timestamp = dec_info->timestamp;
1824     GST_LOG_OBJECT (ffmpegdec, "using in timestamp %" GST_TIME_FORMAT,
1825         GST_TIME_ARGS (out_timestamp));
1826   }
1827   GST_BUFFER_TIMESTAMP (*outbuf) = out_timestamp;
1828
1829   /*
1830    * Offset:
1831    *  0) Use stored input offset (from opaque)
1832    *  1) Use value converted from timestamp if valid
1833    *  2) Use input offset if valid
1834    */
1835   if (out_offset != GST_BUFFER_OFFSET_NONE) {
1836     /* out_offset already contains the offset from ts_info */
1837     GST_LOG_OBJECT (ffmpegdec, "Using offset returned by ffmpeg");
1838   } else if (out_timestamp != GST_CLOCK_TIME_NONE) {
1839     GstFormat out_fmt = GST_FORMAT_DEFAULT;
1840     GST_LOG_OBJECT (ffmpegdec, "Using offset converted from timestamp");
1841     /* FIXME, we should really remove this as it's not nice at all to do
1842      * upstream queries for each frame to get the frame offset. We also can't
1843      * really remove this because it is the only way of setting frame offsets
1844      * on outgoing buffers. We should have metadata so that the upstream peer
1845      * can set a frame number on the encoded data. */
1846     gst_pad_query_peer_convert (ffmpegdec->sinkpad,
1847         GST_FORMAT_TIME, out_timestamp, &out_fmt, &out_offset);
1848   } else if (dec_info->offset != GST_BUFFER_OFFSET_NONE) {
1849     /* FIXME, the input offset is input media specific and might not
1850      * be the same for the output media. (byte offset as input, frame number
1851      * as output, for example) */
1852     GST_LOG_OBJECT (ffmpegdec, "using in_offset %" G_GINT64_FORMAT,
1853         dec_info->offset);
1854     out_offset = dec_info->offset;
1855   } else {
1856     GST_LOG_OBJECT (ffmpegdec, "no valid offset found");
1857     out_offset = GST_BUFFER_OFFSET_NONE;
1858   }
1859   GST_BUFFER_OFFSET (*outbuf) = out_offset;
1860
1861   /*
1862    * Duration:
1863    *
1864    *  1) Use reordered input duration if valid
1865    *  2) Else use input duration
1866    *  3) else use input framerate
1867    *  4) else use ffmpeg framerate
1868    */
1869   if (GST_CLOCK_TIME_IS_VALID (out_duration)) {
1870     /* We have a valid (reordered) duration */
1871     GST_LOG_OBJECT (ffmpegdec, "Using duration returned by ffmpeg");
1872   } else if (GST_CLOCK_TIME_IS_VALID (dec_info->duration)) {
1873     GST_LOG_OBJECT (ffmpegdec, "using in_duration");
1874     out_duration = dec_info->duration;
1875   } else {
1876     /* if we have an input framerate, use that */
1877     if (ffmpegdec->format.video.fps_n != -1 &&
1878         (ffmpegdec->format.video.fps_n != 1000 &&
1879             ffmpegdec->format.video.fps_d != 1)) {
1880       GST_LOG_OBJECT (ffmpegdec, "using input framerate for duration");
1881       out_duration = gst_util_uint64_scale_int (GST_SECOND,
1882           ffmpegdec->format.video.fps_d, ffmpegdec->format.video.fps_n);
1883     } else {
1884       /* don't try to use the decoder's framerate when it seems a bit abnormal,
1885        * which we assume when den >= 1000... */
1886       if (ffmpegdec->context->time_base.num != 0 &&
1887           (ffmpegdec->context->time_base.den > 0 &&
1888               ffmpegdec->context->time_base.den < 1000)) {
1889         GST_LOG_OBJECT (ffmpegdec, "using decoder's framerate for duration");
1890         out_duration = gst_util_uint64_scale_int (GST_SECOND,
1891             ffmpegdec->context->time_base.num *
1892             ffmpegdec->context->ticks_per_frame,
1893             ffmpegdec->context->time_base.den);
1894       } else {
1895         GST_LOG_OBJECT (ffmpegdec, "no valid duration found");
1896       }
1897     }
1898   }
1899
1900   /* Take repeat_pict into account */
1901   if (GST_CLOCK_TIME_IS_VALID (out_duration)) {
1902     out_duration += out_duration * ffmpegdec->picture->repeat_pict / 2;
1903   }
1904   GST_BUFFER_DURATION (*outbuf) = out_duration;
1905
1906   if (out_timestamp != -1 && out_duration != -1)
1907     ffmpegdec->next_out = out_timestamp + out_duration;
1908
1909   /* palette is not part of raw video frame in gst and the size
1910    * of the outgoing buffer needs to be adjusted accordingly */
1911   if (ffmpegdec->context->palctrl != NULL)
1912     GST_BUFFER_SIZE (*outbuf) -= AVPALETTE_SIZE;
1913
1914   /* now see if we need to clip the buffer against the segment boundaries. */
1915   if (G_UNLIKELY (!clip_video_buffer (ffmpegdec, *outbuf, out_timestamp,
1916               out_duration)))
1917     goto clipped;
1918
1919   /* mark as keyframe or delta unit */
1920   if (!iskeyframe)
1921     GST_BUFFER_FLAG_SET (*outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1922
1923   if (ffmpegdec->picture->top_field_first)
1924     GST_BUFFER_FLAG_SET (*outbuf, GST_VIDEO_BUFFER_TFF);
1925
1926
1927 beach:
1928   GST_DEBUG_OBJECT (ffmpegdec, "return flow %d, out %p, len %d",
1929       *ret, *outbuf, len);
1930   return len;
1931
1932   /* special cases */
1933 drop_non_keyframe:
1934   {
1935     GST_WARNING_OBJECT (ffmpegdec, "Dropping non-keyframe (seek/init)");
1936     goto beach;
1937   }
1938 no_output:
1939   {
1940     GST_DEBUG_OBJECT (ffmpegdec, "no output buffer");
1941     len = -1;
1942     goto beach;
1943   }
1944 clipped:
1945   {
1946     GST_DEBUG_OBJECT (ffmpegdec, "buffer clipped");
1947     gst_buffer_unref (*outbuf);
1948     *outbuf = NULL;
1949     goto beach;
1950   }
1951 }
1952
1953 /* returns TRUE if buffer is within segment, else FALSE.
1954  * if Buffer is on segment border, it's timestamp and duration will be clipped */
1955 static gboolean
1956 clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
1957     GstClockTime in_dur)
1958 {
1959   GstClockTime stop;
1960   gint64 diff, ctime, cstop;
1961   gboolean res = TRUE;
1962
1963   GST_LOG_OBJECT (dec,
1964       "timestamp:%" GST_TIME_FORMAT ", duration:%" GST_TIME_FORMAT
1965       ", size %u", GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur),
1966       GST_BUFFER_SIZE (buf));
1967
1968   /* can't clip without TIME segment */
1969   if (G_UNLIKELY (dec->segment.format != GST_FORMAT_TIME))
1970     goto beach;
1971
1972   /* we need a start time */
1973   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (in_ts)))
1974     goto beach;
1975
1976   /* trust duration */
1977   stop = in_ts + in_dur;
1978
1979   res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME, in_ts, stop, &ctime,
1980       &cstop);
1981   if (G_UNLIKELY (!res))
1982     goto out_of_segment;
1983
1984   /* see if some clipping happened */
1985   if (G_UNLIKELY ((diff = ctime - in_ts) > 0)) {
1986     /* bring clipped time to bytes */
1987     diff =
1988         gst_util_uint64_scale_int (diff, dec->format.audio.samplerate,
1989         GST_SECOND) * (dec->format.audio.depth * dec->format.audio.channels);
1990
1991     GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %"
1992         G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff);
1993
1994     GST_BUFFER_SIZE (buf) -= diff;
1995     GST_BUFFER_DATA (buf) += diff;
1996   }
1997   if (G_UNLIKELY ((diff = stop - cstop) > 0)) {
1998     /* bring clipped time to bytes */
1999     diff =
2000         gst_util_uint64_scale_int (diff, dec->format.audio.samplerate,
2001         GST_SECOND) * (dec->format.audio.depth * dec->format.audio.channels);
2002
2003     GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %"
2004         G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
2005
2006     GST_BUFFER_SIZE (buf) -= diff;
2007   }
2008   GST_BUFFER_TIMESTAMP (buf) = ctime;
2009   GST_BUFFER_DURATION (buf) = cstop - ctime;
2010
2011 beach:
2012   GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : ""));
2013   return res;
2014
2015   /* ERRORS */
2016 out_of_segment:
2017   {
2018     GST_LOG_OBJECT (dec, "out of segment");
2019     goto beach;
2020   }
2021 }
2022
2023 static gint
2024 gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
2025     AVCodec * in_plugin, guint8 * data, guint size,
2026     const GstTSInfo * dec_info, GstBuffer ** outbuf, GstFlowReturn * ret)
2027 {
2028   gint len = -1;
2029   gint have_data = AVCODEC_MAX_AUDIO_FRAME_SIZE;
2030   GstClockTime out_timestamp, out_duration;
2031   gint64 out_offset;
2032
2033   GST_DEBUG_OBJECT (ffmpegdec,
2034       "size:%d, offset:%" G_GINT64_FORMAT ", ts:%" GST_TIME_FORMAT ", dur:%"
2035       GST_TIME_FORMAT ", ffmpegdec->next_out:%" GST_TIME_FORMAT, size,
2036       dec_info->offset, GST_TIME_ARGS (dec_info->timestamp),
2037       GST_TIME_ARGS (dec_info->duration), GST_TIME_ARGS (ffmpegdec->next_out));
2038
2039   *outbuf =
2040       new_aligned_buffer (AVCODEC_MAX_AUDIO_FRAME_SIZE,
2041       GST_PAD_CAPS (ffmpegdec->srcpad));
2042
2043   len = avcodec_decode_audio2 (ffmpegdec->context,
2044       (int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size);
2045   GST_DEBUG_OBJECT (ffmpegdec,
2046       "Decode audio: len=%d, have_data=%d", len, have_data);
2047
2048   if (len >= 0 && have_data > 0) {
2049     GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
2050     if (!gst_ffmpegdec_negotiate (ffmpegdec, FALSE)) {
2051       gst_buffer_unref (*outbuf);
2052       *outbuf = NULL;
2053       len = -1;
2054       goto beach;
2055     }
2056
2057     /* Buffer size */
2058     GST_BUFFER_SIZE (*outbuf) = have_data;
2059
2060     /*
2061      * Timestamps:
2062      *
2063      *  1) Copy input timestamp if valid
2064      *  2) else interpolate from previous input timestamp
2065      */
2066     /* always take timestamps from the input buffer if any */
2067     if (GST_CLOCK_TIME_IS_VALID (dec_info->timestamp)) {
2068       out_timestamp = dec_info->timestamp;
2069     } else {
2070       out_timestamp = ffmpegdec->next_out;
2071     }
2072
2073     /*
2074      * Duration:
2075      *
2076      *  1) calculate based on number of samples
2077      */
2078     out_duration = gst_util_uint64_scale (have_data, GST_SECOND,
2079         ffmpegdec->format.audio.depth * ffmpegdec->format.audio.channels *
2080         ffmpegdec->format.audio.samplerate);
2081
2082     /* offset:
2083      *
2084      * Just copy
2085      */
2086     out_offset = dec_info->offset;
2087
2088     GST_DEBUG_OBJECT (ffmpegdec,
2089         "Buffer created. Size:%d , timestamp:%" GST_TIME_FORMAT " , duration:%"
2090         GST_TIME_FORMAT, have_data,
2091         GST_TIME_ARGS (out_timestamp), GST_TIME_ARGS (out_duration));
2092
2093     GST_BUFFER_TIMESTAMP (*outbuf) = out_timestamp;
2094     GST_BUFFER_DURATION (*outbuf) = out_duration;
2095     GST_BUFFER_OFFSET (*outbuf) = out_offset;
2096
2097     /* the next timestamp we'll use when interpolating */
2098     ffmpegdec->next_out = out_timestamp + out_duration;
2099
2100     /* now see if we need to clip the buffer against the segment boundaries. */
2101     if (G_UNLIKELY (!clip_audio_buffer (ffmpegdec, *outbuf, out_timestamp,
2102                 out_duration)))
2103       goto clipped;
2104
2105   } else {
2106     gst_buffer_unref (*outbuf);
2107     *outbuf = NULL;
2108   }
2109
2110   /* If we don't error out after the first failed read with the AAC decoder,
2111    * we must *not* carry on pushing data, else we'll cause segfaults... */
2112   if (len == -1 && in_plugin->id == CODEC_ID_AAC) {
2113     GST_ELEMENT_ERROR (ffmpegdec, STREAM, DECODE, (NULL),
2114         ("Decoding of AAC stream by FFMPEG failed."));
2115     *ret = GST_FLOW_ERROR;
2116   }
2117
2118 beach:
2119   GST_DEBUG_OBJECT (ffmpegdec, "return flow %d, out %p, len %d",
2120       *ret, *outbuf, len);
2121   return len;
2122
2123   /* ERRORS */
2124 clipped:
2125   {
2126     GST_DEBUG_OBJECT (ffmpegdec, "buffer clipped");
2127     gst_buffer_unref (*outbuf);
2128     *outbuf = NULL;
2129     goto beach;
2130   }
2131 }
2132
2133 /* gst_ffmpegdec_frame:
2134  * ffmpegdec:
2135  * data: pointer to the data to decode
2136  * size: size of data in bytes
2137  * got_data: 0 if no data was decoded, != 0 otherwise.
2138  * in_time: timestamp of data
2139  * in_duration: duration of data
2140  * ret: GstFlowReturn to return in the chain function
2141  *
2142  * Decode the given frame and pushes it downstream.
2143  *
2144  * Returns: Number of bytes used in decoding, -1 on error/failure.
2145  */
2146
2147 static gint
2148 gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
2149     guint8 * data, guint size, gint * got_data, const GstTSInfo * dec_info,
2150     GstFlowReturn * ret)
2151 {
2152   GstFFMpegDecClass *oclass;
2153   GstBuffer *outbuf = NULL;
2154   gint have_data = 0, len = 0;
2155
2156   if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
2157     goto no_codec;
2158
2159   GST_LOG_OBJECT (ffmpegdec, "data:%p, size:%d, id:%d", data, size,
2160       dec_info->idx);
2161
2162   *ret = GST_FLOW_OK;
2163   ffmpegdec->context->frame_number++;
2164
2165   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
2166
2167   switch (oclass->in_plugin->type) {
2168     case CODEC_TYPE_VIDEO:
2169       len =
2170           gst_ffmpegdec_video_frame (ffmpegdec, data, size, dec_info, &outbuf,
2171           ret);
2172       break;
2173     case CODEC_TYPE_AUDIO:
2174       len =
2175           gst_ffmpegdec_audio_frame (ffmpegdec, oclass->in_plugin, data, size,
2176           dec_info, &outbuf, ret);
2177
2178       /* if we did not get an output buffer and we have a pending discont, don't
2179        * clear the input timestamps, we will put them on the next buffer because
2180        * else we might create the first buffer with a very big timestamp gap. */
2181       if (outbuf == NULL && ffmpegdec->discont) {
2182         GST_DEBUG_OBJECT (ffmpegdec, "no buffer but keeping timestamp");
2183         ffmpegdec->clear_ts = FALSE;
2184       }
2185       break;
2186     default:
2187       GST_ERROR_OBJECT (ffmpegdec, "Asked to decode non-audio/video frame !");
2188       g_assert_not_reached ();
2189       break;
2190   }
2191
2192   if (outbuf)
2193     have_data = 1;
2194
2195   if (len < 0 || have_data < 0) {
2196     GST_WARNING_OBJECT (ffmpegdec,
2197         "ffdec_%s: decoding error (len: %d, have_data: %d)",
2198         oclass->in_plugin->name, len, have_data);
2199     *got_data = 0;
2200     goto beach;
2201   } else if (len == 0 && have_data == 0) {
2202     *got_data = 0;
2203     goto beach;
2204   } else {
2205     /* this is where I lost my last clue on ffmpeg... */
2206     *got_data = 1;
2207   }
2208
2209   if (outbuf) {
2210     GST_LOG_OBJECT (ffmpegdec,
2211         "Decoded data, now pushing buffer %p with offset %" G_GINT64_FORMAT
2212         ", timestamp %" GST_TIME_FORMAT " and duration %" GST_TIME_FORMAT,
2213         outbuf, GST_BUFFER_OFFSET (outbuf),
2214         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
2215         GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
2216
2217     /* mark pending discont */
2218     if (ffmpegdec->discont) {
2219       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
2220       ffmpegdec->discont = FALSE;
2221     }
2222     /* set caps */
2223     outbuf = gst_buffer_make_metadata_writable (outbuf);
2224     gst_buffer_set_caps (outbuf, GST_PAD_CAPS (ffmpegdec->srcpad));
2225
2226     if (ffmpegdec->segment.rate > 0.0) {
2227       /* and off we go */
2228       *ret = gst_pad_push (ffmpegdec->srcpad, outbuf);
2229     } else {
2230       /* reverse playback, queue frame till later when we get a discont. */
2231       GST_DEBUG_OBJECT (ffmpegdec, "queued frame");
2232       ffmpegdec->queued = g_list_prepend (ffmpegdec->queued, outbuf);
2233       *ret = GST_FLOW_OK;
2234     }
2235   } else {
2236     GST_DEBUG_OBJECT (ffmpegdec, "We didn't get a decoded buffer");
2237   }
2238
2239 beach:
2240   return len;
2241
2242   /* ERRORS */
2243 no_codec:
2244   {
2245     GST_ERROR_OBJECT (ffmpegdec, "no codec context");
2246     return -1;
2247   }
2248 }
2249
2250 static void
2251 gst_ffmpegdec_drain (GstFFMpegDec * ffmpegdec)
2252 {
2253   GstFFMpegDecClass *oclass;
2254
2255   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
2256
2257   if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
2258     gint have_data, len, try = 0;
2259
2260     GST_LOG_OBJECT (ffmpegdec,
2261         "codec has delay capabilities, calling until ffmpeg has drained everything");
2262
2263     do {
2264       GstFlowReturn ret;
2265
2266       len =
2267           gst_ffmpegdec_frame (ffmpegdec, NULL, 0, &have_data, &ts_info_none,
2268           &ret);
2269       if (len < 0 || have_data == 0)
2270         break;
2271     } while (try++ < 10);
2272   }
2273   if (ffmpegdec->segment.rate < 0.0) {
2274     /* if we have some queued frames for reverse playback, flush them now */
2275     flush_queued (ffmpegdec);
2276   }
2277 }
2278
2279 static void
2280 gst_ffmpegdec_flush_pcache (GstFFMpegDec * ffmpegdec)
2281 {
2282   if (ffmpegdec->pcache) {
2283     gst_buffer_unref (ffmpegdec->pcache);
2284     ffmpegdec->pcache = NULL;
2285   }
2286   if (ffmpegdec->pctx) {
2287     GstFFMpegDecClass *oclass;
2288
2289     oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
2290
2291     av_parser_close (ffmpegdec->pctx);
2292     ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
2293   }
2294 }
2295
2296 static gboolean
2297 gst_ffmpegdec_sink_event (GstPad * pad, GstEvent * event)
2298 {
2299   GstFFMpegDec *ffmpegdec;
2300   GstFFMpegDecClass *oclass;
2301   gboolean ret = FALSE;
2302
2303   ffmpegdec = (GstFFMpegDec *) gst_pad_get_parent (pad);
2304   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
2305
2306   GST_DEBUG_OBJECT (ffmpegdec, "Handling %s event",
2307       GST_EVENT_TYPE_NAME (event));
2308
2309   switch (GST_EVENT_TYPE (event)) {
2310     case GST_EVENT_EOS:
2311     {
2312       gst_ffmpegdec_drain (ffmpegdec);
2313       break;
2314     }
2315     case GST_EVENT_FLUSH_STOP:
2316     {
2317       if (ffmpegdec->opened) {
2318         avcodec_flush_buffers (ffmpegdec->context);
2319       }
2320       gst_ffmpegdec_reset_ts (ffmpegdec);
2321       gst_ffmpegdec_reset_qos (ffmpegdec);
2322       gst_ffmpegdec_flush_pcache (ffmpegdec);
2323       ffmpegdec->waiting_for_key = TRUE;
2324       gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
2325       clear_queued (ffmpegdec);
2326       break;
2327     }
2328     case GST_EVENT_NEWSEGMENT:
2329     {
2330       gboolean update;
2331       GstFormat fmt;
2332       gint64 start, stop, time;
2333       gdouble rate, arate;
2334
2335       gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
2336           &start, &stop, &time);
2337
2338       switch (fmt) {
2339         case GST_FORMAT_TIME:
2340           /* fine, our native segment format */
2341           break;
2342         case GST_FORMAT_BYTES:
2343         {
2344           gint bit_rate;
2345
2346           bit_rate = ffmpegdec->context->bit_rate;
2347
2348           /* convert to time or fail */
2349           if (!bit_rate)
2350             goto no_bitrate;
2351
2352           GST_DEBUG_OBJECT (ffmpegdec, "bitrate: %d", bit_rate);
2353
2354           /* convert values to TIME */
2355           if (start != -1)
2356             start = gst_util_uint64_scale_int (start, GST_SECOND, bit_rate);
2357           if (stop != -1)
2358             stop = gst_util_uint64_scale_int (stop, GST_SECOND, bit_rate);
2359           if (time != -1)
2360             time = gst_util_uint64_scale_int (time, GST_SECOND, bit_rate);
2361
2362           /* unref old event */
2363           gst_event_unref (event);
2364
2365           /* create new converted time segment */
2366           fmt = GST_FORMAT_TIME;
2367           /* FIXME, bitrate is not good enough too find a good stop, let's
2368            * hope start and time were 0... meh. */
2369           stop = -1;
2370           event = gst_event_new_new_segment (update, rate, fmt,
2371               start, stop, time);
2372           break;
2373         }
2374         default:
2375           /* invalid format */
2376           goto invalid_format;
2377       }
2378
2379       /* drain pending frames before trying to use the new segment, queued
2380        * buffers belonged to the previous segment. */
2381       if (ffmpegdec->context->codec)
2382         gst_ffmpegdec_drain (ffmpegdec);
2383
2384       GST_DEBUG_OBJECT (ffmpegdec,
2385           "NEWSEGMENT in time start %" GST_TIME_FORMAT " -- stop %"
2386           GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
2387
2388       /* and store the values */
2389       gst_segment_set_newsegment_full (&ffmpegdec->segment, update,
2390           rate, arate, fmt, start, stop, time);
2391       break;
2392     }
2393     default:
2394       break;
2395   }
2396
2397   /* and push segment downstream */
2398   ret = gst_pad_push_event (ffmpegdec->srcpad, event);
2399
2400 done:
2401   gst_object_unref (ffmpegdec);
2402
2403   return ret;
2404
2405   /* ERRORS */
2406 no_bitrate:
2407   {
2408     GST_WARNING_OBJECT (ffmpegdec, "no bitrate to convert BYTES to TIME");
2409     gst_event_unref (event);
2410     goto done;
2411   }
2412 invalid_format:
2413   {
2414     GST_WARNING_OBJECT (ffmpegdec, "unknown format received in NEWSEGMENT");
2415     gst_event_unref (event);
2416     goto done;
2417   }
2418 }
2419
2420 static GstFlowReturn
2421 gst_ffmpegdec_chain (GstPad * pad, GstBuffer * inbuf)
2422 {
2423   GstFFMpegDec *ffmpegdec;
2424   GstFFMpegDecClass *oclass;
2425   guint8 *data, *bdata, *pdata;
2426   gint size, bsize, len, have_data;
2427   GstFlowReturn ret = GST_FLOW_OK;
2428   GstClockTime in_timestamp;
2429   GstClockTime in_duration;
2430   gboolean discont;
2431   gint64 in_offset;
2432   const GstTSInfo *in_info;
2433   const GstTSInfo *dec_info;
2434
2435   ffmpegdec = (GstFFMpegDec *) (GST_PAD_PARENT (pad));
2436
2437   if (G_UNLIKELY (!ffmpegdec->opened))
2438     goto not_negotiated;
2439
2440   discont = GST_BUFFER_IS_DISCONT (inbuf);
2441
2442   /* The discont flags marks a buffer that is not continuous with the previous
2443    * buffer. This means we need to clear whatever data we currently have. We
2444    * currently also wait for a new keyframe, which might be suboptimal in the
2445    * case of a network error, better show the errors than to drop all data.. */
2446   if (G_UNLIKELY (discont)) {
2447     GST_DEBUG_OBJECT (ffmpegdec, "received DISCONT");
2448     /* drain what we have queued */
2449     gst_ffmpegdec_drain (ffmpegdec);
2450     gst_ffmpegdec_flush_pcache (ffmpegdec);
2451     avcodec_flush_buffers (ffmpegdec->context);
2452     ffmpegdec->discont = TRUE;
2453     gst_ffmpegdec_reset_ts (ffmpegdec);
2454   }
2455   /* by default we clear the input timestamp after decoding each frame so that
2456    * interpollation can work. */
2457   ffmpegdec->clear_ts = TRUE;
2458
2459   oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
2460
2461   /* do early keyframe check pretty bad to rely on the keyframe flag in the
2462    * source for this as it might not even be parsed (UDP/file/..).  */
2463   if (G_UNLIKELY (ffmpegdec->waiting_for_key)) {
2464     GST_DEBUG_OBJECT (ffmpegdec, "waiting for keyframe");
2465     if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DELTA_UNIT) &&
2466         oclass->in_plugin->type != CODEC_TYPE_AUDIO)
2467       goto skip_keyframe;
2468
2469     GST_DEBUG_OBJECT (ffmpegdec, "got keyframe");
2470     ffmpegdec->waiting_for_key = FALSE;
2471   }
2472   /* parse cache joining. If there is cached data */
2473   if (ffmpegdec->pcache) {
2474     /* join with previous data */
2475     GST_LOG_OBJECT (ffmpegdec, "join parse cache");
2476     inbuf = gst_buffer_join (ffmpegdec->pcache, inbuf);
2477     /* no more cached data, we assume we can consume the complete cache */
2478     ffmpegdec->pcache = NULL;
2479   }
2480
2481   in_timestamp = GST_BUFFER_TIMESTAMP (inbuf);
2482   in_duration = GST_BUFFER_DURATION (inbuf);
2483   in_offset = GST_BUFFER_OFFSET (inbuf);
2484
2485   /* get handle to timestamp info, we can pass this around to ffmpeg */
2486   in_info = gst_ts_info_store (ffmpegdec, in_timestamp, in_duration, in_offset);
2487
2488   if (in_timestamp != -1) {
2489     /* check for increasing timestamps if they are jumping backwards, we
2490      * probably are dealing with PTS as timestamps */
2491     if (!ffmpegdec->reordered_in && ffmpegdec->last_in != -1
2492         && in_timestamp < ffmpegdec->last_in) {
2493       GST_LOG_OBJECT (ffmpegdec, "detected reordered input timestamps");
2494       ffmpegdec->reordered_in = TRUE;
2495     }
2496     ffmpegdec->last_in = in_timestamp;
2497   }
2498
2499   GST_LOG_OBJECT (ffmpegdec,
2500       "Received new data of size %u, offset:%" G_GUINT64_FORMAT ", ts:%"
2501       GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT ", info %d",
2502       GST_BUFFER_SIZE (inbuf), GST_BUFFER_OFFSET (inbuf),
2503       GST_TIME_ARGS (in_timestamp), GST_TIME_ARGS (in_duration), in_info->idx);
2504
2505   /* workarounds, functions write to buffers:
2506    *  libavcodec/svq1.c:svq1_decode_frame writes to the given buffer.
2507    *  libavcodec/svq3.c:svq3_decode_slice_header too.
2508    * ffmpeg devs know about it and will fix it (they said). */
2509   if (oclass->in_plugin->id == CODEC_ID_SVQ1 ||
2510       oclass->in_plugin->id == CODEC_ID_SVQ3) {
2511     inbuf = gst_buffer_make_writable (inbuf);
2512   }
2513
2514   bdata = GST_BUFFER_DATA (inbuf);
2515   bsize = GST_BUFFER_SIZE (inbuf);
2516
2517   do {
2518     /* parse, if at all possible */
2519     if (ffmpegdec->pctx) {
2520       gint res;
2521
2522       GST_LOG_OBJECT (ffmpegdec,
2523           "Calling av_parser_parse with offset %" G_GINT64_FORMAT ", ts:%"
2524           GST_TIME_FORMAT, in_offset, GST_TIME_ARGS (in_timestamp));
2525
2526       /* feed the parser. We pass the timestamp info so that we can recover all
2527        * info again later */
2528       res = av_parser_parse (ffmpegdec->pctx, ffmpegdec->context,
2529           &data, &size, bdata, bsize, in_info->idx, in_info->idx);
2530
2531       GST_LOG_OBJECT (ffmpegdec,
2532           "parser returned res %d and size %d", res, size);
2533
2534       /* store pts for decoding */
2535       dec_info = gst_ts_info_get (ffmpegdec, ffmpegdec->pctx->pts);
2536
2537       GST_LOG_OBJECT (ffmpegdec, "consuming %d bytes. id %d", size,
2538           dec_info->idx);
2539
2540       if (res) {
2541         /* there is output, set pointers for next round. */
2542         bsize -= res;
2543         bdata += res;
2544       } else {
2545         /* Parser did not consume any data, make sure we don't clear the
2546          * timestamp for the next round */
2547         ffmpegdec->clear_ts = FALSE;
2548       }
2549
2550       /* if there is no output, we must break and wait for more data. also the
2551        * timestamp in the context is not updated. */
2552       if (size == 0) {
2553         if (bsize > 0)
2554           continue;
2555         else
2556           break;
2557       }
2558     } else {
2559       data = bdata;
2560       size = bsize;
2561
2562       dec_info = in_info;
2563     }
2564
2565     if (ffmpegdec->do_padding) {
2566       /* add padding */
2567       if (ffmpegdec->padded_size < size + FF_INPUT_BUFFER_PADDING_SIZE) {
2568         ffmpegdec->padded_size = size + FF_INPUT_BUFFER_PADDING_SIZE;
2569         ffmpegdec->padded =
2570             g_realloc (ffmpegdec->padded, ffmpegdec->padded_size);
2571         GST_LOG_OBJECT (ffmpegdec, "resized padding buffer to %d",
2572             ffmpegdec->padded_size);
2573       }
2574       memcpy (ffmpegdec->padded, data, size);
2575       memset (ffmpegdec->padded + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
2576
2577       pdata = ffmpegdec->padded;
2578     } else {
2579       pdata = data;
2580     }
2581
2582     /* decode a frame of audio/video now */
2583     len =
2584         gst_ffmpegdec_frame (ffmpegdec, pdata, size, &have_data, dec_info,
2585         &ret);
2586
2587     if (ret != GST_FLOW_OK) {
2588       GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
2589           gst_flow_get_name (ret));
2590       /* bad flow retun, make sure we discard all data and exit */
2591       bsize = 0;
2592       break;
2593     }
2594     if (!ffmpegdec->pctx) {
2595       if (len == 0 && !have_data) {
2596         /* nothing was decoded, this could be because no data was available or
2597          * because we were skipping frames.
2598          * If we have no context we must exit and wait for more data, we keep the
2599          * data we tried. */
2600         GST_LOG_OBJECT (ffmpegdec, "Decoding didn't return any data, breaking");
2601         break;
2602       } else if (len < 0) {
2603         /* a decoding error happened, we must break and try again with next data. */
2604         GST_LOG_OBJECT (ffmpegdec, "Decoding error, breaking");
2605         bsize = 0;
2606         break;
2607       }
2608       /* prepare for the next round, for codecs with a context we did this
2609        * already when using the parser. */
2610       bsize -= len;
2611       bdata += len;
2612     } else {
2613       if (len == 0) {
2614         /* nothing was decoded, this could be because no data was available or
2615          * because we were skipping frames. Since we have a parser we can
2616          * continue with the next frame */
2617         GST_LOG_OBJECT (ffmpegdec,
2618             "Decoding didn't return any data, trying next");
2619       } else if (len < 0) {
2620         /* we have a context that will bring us to the next frame */
2621         GST_LOG_OBJECT (ffmpegdec, "Decoding error, trying next");
2622       }
2623     }
2624
2625     /* make sure we don't use the same old timestamp for the next frame and let
2626      * the interpollation take care of it. */
2627     if (ffmpegdec->clear_ts) {
2628       in_timestamp = GST_CLOCK_TIME_NONE;
2629       in_duration = GST_CLOCK_TIME_NONE;
2630       in_offset = GST_BUFFER_OFFSET_NONE;
2631       in_info = GST_TS_INFO_NONE;
2632     } else {
2633       ffmpegdec->clear_ts = TRUE;
2634     }
2635
2636     GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0).  bsize:%d , bdata:%p",
2637         bsize, bdata);
2638   } while (bsize > 0);
2639
2640   /* keep left-over */
2641   if (ffmpegdec->pctx && bsize > 0) {
2642     in_timestamp = GST_BUFFER_TIMESTAMP (inbuf);
2643     in_offset = GST_BUFFER_OFFSET (inbuf);
2644
2645     GST_LOG_OBJECT (ffmpegdec,
2646         "Keeping %d bytes of data with offset %" G_GINT64_FORMAT ", timestamp %"
2647         GST_TIME_FORMAT, bsize, in_offset, GST_TIME_ARGS (in_timestamp));
2648
2649     ffmpegdec->pcache = gst_buffer_create_sub (inbuf,
2650         GST_BUFFER_SIZE (inbuf) - bsize, bsize);
2651     /* we keep timestamp, even though all we really know is that the correct
2652      * timestamp is not below the one from inbuf */
2653     GST_BUFFER_TIMESTAMP (ffmpegdec->pcache) = in_timestamp;
2654     GST_BUFFER_OFFSET (ffmpegdec->pcache) = in_offset;
2655   } else if (bsize > 0) {
2656     GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize);
2657   }
2658   gst_buffer_unref (inbuf);
2659
2660   return ret;
2661
2662   /* ERRORS */
2663 not_negotiated:
2664   {
2665     oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
2666     GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
2667         ("ffdec_%s: input format was not set before data start",
2668             oclass->in_plugin->name));
2669     gst_buffer_unref (inbuf);
2670     return GST_FLOW_NOT_NEGOTIATED;
2671   }
2672 skip_keyframe:
2673   {
2674     GST_DEBUG_OBJECT (ffmpegdec, "skipping non keyframe");
2675     gst_buffer_unref (inbuf);
2676     return GST_FLOW_OK;
2677   }
2678 }
2679
2680 static GstStateChangeReturn
2681 gst_ffmpegdec_change_state (GstElement * element, GstStateChange transition)
2682 {
2683   GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) element;
2684   GstStateChangeReturn ret;
2685
2686   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2687
2688   switch (transition) {
2689     case GST_STATE_CHANGE_PAUSED_TO_READY:
2690       GST_OBJECT_LOCK (ffmpegdec);
2691       gst_ffmpegdec_close (ffmpegdec);
2692       GST_OBJECT_UNLOCK (ffmpegdec);
2693       clear_queued (ffmpegdec);
2694       g_free (ffmpegdec->padded);
2695       ffmpegdec->padded = NULL;
2696       ffmpegdec->padded_size = 0;
2697       ffmpegdec->can_allocate_aligned = TRUE;
2698       break;
2699     default:
2700       break;
2701   }
2702
2703   return ret;
2704 }
2705
2706 static void
2707 gst_ffmpegdec_set_property (GObject * object,
2708     guint prop_id, const GValue * value, GParamSpec * pspec)
2709 {
2710   GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) object;
2711
2712   switch (prop_id) {
2713     case PROP_LOWRES:
2714       ffmpegdec->lowres = ffmpegdec->context->lowres = g_value_get_enum (value);
2715       break;
2716     case PROP_SKIPFRAME:
2717       ffmpegdec->hurry_up = ffmpegdec->context->hurry_up =
2718           g_value_get_enum (value);
2719       break;
2720     case PROP_DIRECT_RENDERING:
2721       ffmpegdec->direct_rendering = g_value_get_boolean (value);
2722       break;
2723     case PROP_DO_PADDING:
2724       ffmpegdec->do_padding = g_value_get_boolean (value);
2725       break;
2726     case PROP_DEBUG_MV:
2727       ffmpegdec->debug_mv = ffmpegdec->context->debug_mv =
2728           g_value_get_boolean (value);
2729       break;
2730     case PROP_CROP:
2731       ffmpegdec->crop = g_value_get_boolean (value);
2732       break;
2733     default:
2734       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2735       break;
2736   }
2737 }
2738
2739 static void
2740 gst_ffmpegdec_get_property (GObject * object,
2741     guint prop_id, GValue * value, GParamSpec * pspec)
2742 {
2743   GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) object;
2744
2745   switch (prop_id) {
2746     case PROP_LOWRES:
2747       g_value_set_enum (value, ffmpegdec->context->lowres);
2748       break;
2749     case PROP_SKIPFRAME:
2750       g_value_set_enum (value, ffmpegdec->context->hurry_up);
2751       break;
2752     case PROP_DIRECT_RENDERING:
2753       g_value_set_boolean (value, ffmpegdec->direct_rendering);
2754       break;
2755     case PROP_DO_PADDING:
2756       g_value_set_boolean (value, ffmpegdec->do_padding);
2757       break;
2758     case PROP_DEBUG_MV:
2759       g_value_set_boolean (value, ffmpegdec->context->debug_mv);
2760       break;
2761     case PROP_CROP:
2762       g_value_set_boolean (value, ffmpegdec->crop);
2763       break;
2764     default:
2765       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2766       break;
2767   }
2768 }
2769
2770 gboolean
2771 gst_ffmpegdec_register (GstPlugin * plugin)
2772 {
2773   GTypeInfo typeinfo = {
2774     sizeof (GstFFMpegDecClass),
2775     (GBaseInitFunc) gst_ffmpegdec_base_init,
2776     NULL,
2777     (GClassInitFunc) gst_ffmpegdec_class_init,
2778     NULL,
2779     NULL,
2780     sizeof (GstFFMpegDec),
2781     0,
2782     (GInstanceInitFunc) gst_ffmpegdec_init,
2783   };
2784   GType type;
2785   AVCodec *in_plugin;
2786   gint rank;
2787
2788   in_plugin = av_codec_next (NULL);
2789
2790   GST_LOG ("Registering decoders");
2791
2792   while (in_plugin) {
2793     gchar *type_name;
2794     gchar *plugin_name;
2795
2796     /* only decoders */
2797     if (!in_plugin->decode) {
2798       goto next;
2799     }
2800
2801     /* no quasi-codecs, please */
2802     if (in_plugin->id == CODEC_ID_RAWVIDEO ||
2803         in_plugin->id == CODEC_ID_V210 ||
2804         in_plugin->id == CODEC_ID_V210X ||
2805         in_plugin->id == CODEC_ID_R210 ||
2806         (in_plugin->id >= CODEC_ID_PCM_S16LE &&
2807             in_plugin->id <= CODEC_ID_PCM_BLURAY)) {
2808       goto next;
2809     }
2810
2811     /* No decoders depending on external libraries (we don't build them, but
2812      * people who build against an external ffmpeg might have them.
2813      * We have native gstreamer plugins for all of those libraries anyway. */
2814     if (!strncmp (in_plugin->name, "lib", 3)) {
2815       GST_DEBUG
2816           ("Not using external library decoder %s. Use the gstreamer-native ones instead.",
2817           in_plugin->name);
2818       goto next;
2819     }
2820
2821     /* No vdpau plugins until we can figure out how to properly use them
2822      * outside of ffmpeg. */
2823     if (g_str_has_suffix (in_plugin->name, "_vdpau")) {
2824       GST_DEBUG
2825           ("Ignoring VDPAU decoder %s. We can't handle this outside of ffmpeg",
2826           in_plugin->name);
2827       goto next;
2828     }
2829
2830     if (g_str_has_suffix (in_plugin->name, "_xvmc")) {
2831       GST_DEBUG
2832           ("Ignoring XVMC decoder %s. We can't handle this outside of ffmpeg",
2833           in_plugin->name);
2834       goto next;
2835     }
2836
2837     GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
2838
2839     /* no codecs for which we're GUARANTEED to have better alternatives */
2840     /* MPEG1VIDEO : the mpeg2video decoder is preferred */
2841     /* MP1 : Use MP3 for decoding */
2842     /* MP2 : Use MP3 for decoding */
2843     /* Theora: Use libtheora based theoradec */
2844     if (!strcmp (in_plugin->name, "gif") ||
2845         !strcmp (in_plugin->name, "vorbis") ||
2846         !strcmp (in_plugin->name, "theora") ||
2847         !strcmp (in_plugin->name, "mpeg1video") ||
2848         !strcmp (in_plugin->name, "wavpack") ||
2849         !strcmp (in_plugin->name, "mp1") ||
2850         !strcmp (in_plugin->name, "mp2") ||
2851         !strcmp (in_plugin->name, "libfaad") ||
2852         !strcmp (in_plugin->name, "mpeg4aac")) {