tizen 2.3 release
[framework/multimedia/gst-plugins-base0.10.git] / ext / theora / gsttheoradec.c
1 /* GStreamer
2  * Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
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 /**
21  * SECTION:element-theoradec
22  * @see_also: theoraenc, oggdemux
23  *
24  * This element decodes theora streams into raw video
25  * <ulink url="http://www.theora.org/">Theora</ulink> is a royalty-free
26  * video codec maintained by the <ulink url="http://www.xiph.org/">Xiph.org
27  * Foundation</ulink>, based on the VP3 codec.
28  *
29  * <refsect2>
30  * <title>Example pipeline</title>
31  * |[
32  * gst-launch -v filesrc location=videotestsrc.ogg ! oggdemux ! theoradec ! xvimagesink
33  * ]| This example pipeline will decode an ogg stream and decodes the theora video. Refer to
34  * the theoraenc example to create the ogg file.
35  * </refsect2>
36  *
37  * Last reviewed on 2006-03-01 (0.10.4)
38  */
39
40 #ifdef HAVE_CONFIG_H
41 #  include "config.h"
42 #endif
43
44 #include "gsttheoradec.h"
45 #include <gst/tag/tag.h>
46 #include <gst/video/video.h>
47
48 #define GST_CAT_DEFAULT theoradec_debug
49 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
50
51 #define THEORA_DEF_CROP         TRUE
52 #define THEORA_DEF_TELEMETRY_MV 0
53 #define THEORA_DEF_TELEMETRY_MBMODE 0
54 #define THEORA_DEF_TELEMETRY_QI 0
55 #define THEORA_DEF_TELEMETRY_BITS 0
56
57 enum
58 {
59   PROP_0,
60   PROP_CROP,
61   PROP_TELEMETRY_MV,
62   PROP_TELEMETRY_MBMODE,
63   PROP_TELEMETRY_QI,
64   PROP_TELEMETRY_BITS
65 };
66
67 static GstStaticPadTemplate theora_dec_src_factory =
68 GST_STATIC_PAD_TEMPLATE ("src",
69     GST_PAD_SRC,
70     GST_PAD_ALWAYS,
71     GST_STATIC_CAPS ("video/x-raw-yuv, "
72         "format = (fourcc) { I420, Y42B, Y444 }, "
73         "framerate = (fraction) [0/1, MAX], "
74         "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
75     );
76
77 static GstStaticPadTemplate theora_dec_sink_factory =
78 GST_STATIC_PAD_TEMPLATE ("sink",
79     GST_PAD_SINK,
80     GST_PAD_ALWAYS,
81     GST_STATIC_CAPS ("video/x-theora")
82     );
83
84 GST_BOILERPLATE (GstTheoraDec, gst_theora_dec, GstElement, GST_TYPE_ELEMENT);
85
86 static void theora_dec_get_property (GObject * object, guint prop_id,
87     GValue * value, GParamSpec * pspec);
88 static void theora_dec_set_property (GObject * object, guint prop_id,
89     const GValue * value, GParamSpec * pspec);
90
91 static gboolean theora_dec_sink_event (GstPad * pad, GstEvent * event);
92 static gboolean theora_dec_setcaps (GstPad * pad, GstCaps * caps);
93 static GstFlowReturn theora_dec_chain (GstPad * pad, GstBuffer * buffer);
94 static GstStateChangeReturn theora_dec_change_state (GstElement * element,
95     GstStateChange transition);
96 static gboolean theora_dec_src_event (GstPad * pad, GstEvent * event);
97 static gboolean theora_dec_src_query (GstPad * pad, GstQuery * query);
98 static gboolean theora_dec_src_convert (GstPad * pad,
99     GstFormat src_format, gint64 src_value,
100     GstFormat * dest_format, gint64 * dest_value);
101
102 #if 0
103 static const GstFormat *theora_get_formats (GstPad * pad);
104 #endif
105 #if 0
106 static const GstEventMask *theora_get_event_masks (GstPad * pad);
107 #endif
108 static const GstQueryType *theora_get_query_types (GstPad * pad);
109
110
111 static void
112 gst_theora_dec_base_init (gpointer g_class)
113 {
114   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
115
116   gst_element_class_add_static_pad_template (element_class,
117       &theora_dec_src_factory);
118   gst_element_class_add_static_pad_template (element_class,
119       &theora_dec_sink_factory);
120   gst_element_class_set_details_simple (element_class,
121       "Theora video decoder", "Codec/Decoder/Video",
122       "decode raw theora streams to raw YUV video",
123       "Benjamin Otte <otte@gnome.org>, Wim Taymans <wim@fluendo.com>");
124 }
125
126 static gboolean
127 gst_theora_dec_ctl_is_supported (int req)
128 {
129   /* should return TH_EFAULT or TH_EINVAL if supported, and TH_EIMPL if not */
130   return (th_decode_ctl (NULL, req, NULL, 0) != TH_EIMPL);
131 }
132
133 static void
134 gst_theora_dec_class_init (GstTheoraDecClass * klass)
135 {
136   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
137   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
138
139   gobject_class->set_property = theora_dec_set_property;
140   gobject_class->get_property = theora_dec_get_property;
141
142   g_object_class_install_property (gobject_class, PROP_CROP,
143       g_param_spec_boolean ("crop", "Crop",
144           "Crop the image to the visible region", THEORA_DEF_CROP,
145           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146
147   if (gst_theora_dec_ctl_is_supported (TH_DECCTL_SET_TELEMETRY_MV)) {
148     g_object_class_install_property (gobject_class, PROP_TELEMETRY_MV,
149         g_param_spec_int ("visualize-motion-vectors",
150             "Visualize motion vectors",
151             "Show motion vector selection overlaid on image. "
152             "Value gives a mask for motion vector (MV) modes to show",
153             0, 0xffff, THEORA_DEF_TELEMETRY_MV,
154             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
155   }
156
157   if (gst_theora_dec_ctl_is_supported (TH_DECCTL_SET_TELEMETRY_MBMODE)) {
158     g_object_class_install_property (gobject_class, PROP_TELEMETRY_MBMODE,
159         g_param_spec_int ("visualize-macroblock-modes",
160             "Visualize macroblock modes",
161             "Show macroblock mode selection overlaid on image. "
162             "Value gives a mask for macroblock (MB) modes to show",
163             0, 0xffff, THEORA_DEF_TELEMETRY_MBMODE,
164             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
165   }
166
167   if (gst_theora_dec_ctl_is_supported (TH_DECCTL_SET_TELEMETRY_QI)) {
168     g_object_class_install_property (gobject_class, PROP_TELEMETRY_QI,
169         g_param_spec_int ("visualize-quantization-modes",
170             "Visualize adaptive quantization modes",
171             "Show adaptive quantization mode selection overlaid on image. "
172             "Value gives a mask for quantization (QI) modes to show",
173             0, 0xffff, THEORA_DEF_TELEMETRY_QI,
174             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
175   }
176
177   if (gst_theora_dec_ctl_is_supported (TH_DECCTL_SET_TELEMETRY_BITS)) {
178     /* FIXME: make this a boolean instead? The value scales the bars so
179      * they're less wide. Default is to use full width, and anything else
180      * doesn't seem particularly useful, since the smaller bars just disappear
181      * then (they almost disappear for a value of 2 already). */
182     g_object_class_install_property (gobject_class, PROP_TELEMETRY_BITS,
183         g_param_spec_int ("visualize-bit-usage",
184             "Visualize bitstream usage breakdown",
185             "Sets the bitstream breakdown visualization mode. "
186             "Values influence the width of the bit usage bars to show",
187             0, 0xff, THEORA_DEF_TELEMETRY_BITS,
188             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
189   }
190
191   gstelement_class->change_state = theora_dec_change_state;
192
193   GST_DEBUG_CATEGORY_INIT (theoradec_debug, "theoradec", 0, "Theora decoder");
194 }
195
196 static void
197 gst_theora_dec_init (GstTheoraDec * dec, GstTheoraDecClass * g_class)
198 {
199   dec->sinkpad =
200       gst_pad_new_from_static_template (&theora_dec_sink_factory, "sink");
201   gst_pad_set_event_function (dec->sinkpad, theora_dec_sink_event);
202   gst_pad_set_setcaps_function (dec->sinkpad, theora_dec_setcaps);
203   gst_pad_set_chain_function (dec->sinkpad, theora_dec_chain);
204   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
205
206   dec->srcpad =
207       gst_pad_new_from_static_template (&theora_dec_src_factory, "src");
208   gst_pad_set_event_function (dec->srcpad, theora_dec_src_event);
209   gst_pad_set_query_type_function (dec->srcpad, theora_get_query_types);
210   gst_pad_set_query_function (dec->srcpad, theora_dec_src_query);
211   gst_pad_use_fixed_caps (dec->srcpad);
212
213   gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
214
215   dec->crop = THEORA_DEF_CROP;
216   dec->telemetry_mv = THEORA_DEF_TELEMETRY_MV;
217   dec->telemetry_mbmode = THEORA_DEF_TELEMETRY_MBMODE;
218   dec->telemetry_qi = THEORA_DEF_TELEMETRY_QI;
219   dec->telemetry_bits = THEORA_DEF_TELEMETRY_BITS;
220   dec->gather = NULL;
221   dec->decode = NULL;
222   dec->queued = NULL;
223   dec->pendingevents = NULL;
224 }
225
226 static void
227 gst_theora_dec_reset (GstTheoraDec * dec)
228 {
229   dec->need_keyframe = TRUE;
230   dec->last_timestamp = -1;
231   dec->discont = TRUE;
232   dec->frame_nr = -1;
233   dec->seqnum = gst_util_seqnum_next ();
234   dec->dropped = 0;
235   dec->processed = 0;
236   gst_segment_init (&dec->segment, GST_FORMAT_TIME);
237
238   GST_OBJECT_LOCK (dec);
239   dec->proportion = 1.0;
240   dec->earliest_time = -1;
241   GST_OBJECT_UNLOCK (dec);
242
243   g_list_foreach (dec->queued, (GFunc) gst_mini_object_unref, NULL);
244   g_list_free (dec->queued);
245   dec->queued = NULL;
246   g_list_foreach (dec->gather, (GFunc) gst_mini_object_unref, NULL);
247   g_list_free (dec->gather);
248   dec->gather = NULL;
249   g_list_foreach (dec->decode, (GFunc) gst_mini_object_unref, NULL);
250   g_list_free (dec->decode);
251   dec->decode = NULL;
252   g_list_foreach (dec->pendingevents, (GFunc) gst_mini_object_unref, NULL);
253   g_list_free (dec->pendingevents);
254   dec->pendingevents = NULL;
255
256   if (dec->tags) {
257     gst_tag_list_free (dec->tags);
258     dec->tags = NULL;
259   }
260 }
261
262 #if 0
263 static const GstFormat *
264 theora_get_formats (GstPad * pad)
265 {
266   static GstFormat src_formats[] = {
267     GST_FORMAT_DEFAULT,         /* frames in this case */
268     GST_FORMAT_TIME,
269     GST_FORMAT_BYTES,
270     0
271   };
272   static GstFormat sink_formats[] = {
273     GST_FORMAT_DEFAULT,
274     GST_FORMAT_TIME,
275     0
276   };
277
278   return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
279 }
280 #endif
281
282 #if 0
283 static const GstEventMask *
284 theora_get_event_masks (GstPad * pad)
285 {
286   static const GstEventMask theora_src_event_masks[] = {
287     {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
288     {0,}
289   };
290
291   return theora_src_event_masks;
292 }
293 #endif
294
295 static const GstQueryType *
296 theora_get_query_types (GstPad * pad)
297 {
298   static const GstQueryType theora_src_query_types[] = {
299     GST_QUERY_POSITION,
300     GST_QUERY_DURATION,
301     GST_QUERY_CONVERT,
302     0
303   };
304
305   return theora_src_query_types;
306 }
307
308
309 static gboolean
310 theora_dec_src_convert (GstPad * pad,
311     GstFormat src_format, gint64 src_value,
312     GstFormat * dest_format, gint64 * dest_value)
313 {
314   gboolean res = TRUE;
315   GstTheoraDec *dec;
316   guint64 scale = 1;
317
318   if (src_format == *dest_format) {
319     *dest_value = src_value;
320     return TRUE;
321   }
322
323   dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
324
325   /* we need the info part before we can done something */
326   if (!dec->have_header)
327     goto no_header;
328
329   switch (src_format) {
330     case GST_FORMAT_BYTES:
331       switch (*dest_format) {
332         case GST_FORMAT_DEFAULT:
333           *dest_value = gst_util_uint64_scale_int (src_value, 8,
334               dec->info.pic_height * dec->info.pic_width * dec->output_bpp);
335           break;
336         case GST_FORMAT_TIME:
337           /* seems like a rather silly conversion, implement me if you like */
338         default:
339           res = FALSE;
340       }
341       break;
342     case GST_FORMAT_TIME:
343       switch (*dest_format) {
344         case GST_FORMAT_BYTES:
345           scale =
346               dec->output_bpp * (dec->info.pic_width * dec->info.pic_height) /
347               8;
348         case GST_FORMAT_DEFAULT:
349           *dest_value = scale * gst_util_uint64_scale (src_value,
350               dec->info.fps_numerator, dec->info.fps_denominator * GST_SECOND);
351           break;
352         default:
353           res = FALSE;
354       }
355       break;
356     case GST_FORMAT_DEFAULT:
357       switch (*dest_format) {
358         case GST_FORMAT_TIME:
359           *dest_value = gst_util_uint64_scale (src_value,
360               GST_SECOND * dec->info.fps_denominator, dec->info.fps_numerator);
361           break;
362         case GST_FORMAT_BYTES:
363           *dest_value = gst_util_uint64_scale_int (src_value,
364               dec->output_bpp * dec->info.pic_width * dec->info.pic_height, 8);
365           break;
366         default:
367           res = FALSE;
368       }
369       break;
370     default:
371       res = FALSE;
372   }
373 done:
374   gst_object_unref (dec);
375   return res;
376
377   /* ERRORS */
378 no_header:
379   {
380     GST_DEBUG_OBJECT (dec, "no header yet, cannot convert");
381     res = FALSE;
382     goto done;
383   }
384 }
385
386 #if 0
387 static gboolean
388 theora_dec_sink_convert (GstPad * pad,
389     GstFormat src_format, gint64 src_value,
390     GstFormat * dest_format, gint64 * dest_value)
391 {
392   gboolean res = TRUE;
393   GstTheoraDec *dec;
394
395   if (src_format == *dest_format) {
396     *dest_value = src_value;
397     return TRUE;
398   }
399
400   dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
401
402   /* we need the info part before we can done something */
403   if (!dec->have_header)
404     goto no_header;
405
406   switch (src_format) {
407     case GST_FORMAT_DEFAULT:
408       switch (*dest_format) {
409         case GST_FORMAT_TIME:
410           *dest_value = _theora_granule_start_time (dec, src_value);
411           break;
412         default:
413           res = FALSE;
414       }
415       break;
416     case GST_FORMAT_TIME:
417       switch (*dest_format) {
418         case GST_FORMAT_DEFAULT:
419         {
420           guint rest;
421
422           /* framecount */
423           *dest_value = gst_util_uint64_scale (src_value,
424               dec->info.fps_numerator, GST_SECOND * dec->info.fps_denominator);
425
426           /* funny way of calculating granulepos in theora */
427           rest = *dest_value / dec->info.keyframe_granule_shift;
428           *dest_value -= rest;
429           *dest_value <<= dec->granule_shift;
430           *dest_value += rest;
431           break;
432         }
433         default:
434           res = FALSE;
435           break;
436       }
437       break;
438     default:
439       res = FALSE;
440   }
441 done:
442   gst_object_unref (dec);
443   return res;
444
445   /* ERRORS */
446 no_header:
447   {
448     GST_DEBUG_OBJECT (dec, "no header yet, cannot convert");
449     res = FALSE;
450     goto done;
451   }
452 }
453 #endif
454
455 static gboolean
456 theora_dec_src_query (GstPad * pad, GstQuery * query)
457 {
458   GstTheoraDec *dec;
459
460   gboolean res = FALSE;
461
462   dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
463
464   switch (GST_QUERY_TYPE (query)) {
465     case GST_QUERY_POSITION:
466     {
467       gint64 value;
468       GstFormat format;
469       gint64 time;
470
471       /* parse format */
472       gst_query_parse_position (query, &format, NULL);
473
474       time = dec->last_timestamp;
475       time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time);
476
477       GST_LOG_OBJECT (dec,
478           "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time));
479
480       if (!(res =
481               theora_dec_src_convert (pad, GST_FORMAT_TIME, time, &format,
482                   &value)))
483         goto error;
484
485       gst_query_set_position (query, format, value);
486
487       GST_LOG_OBJECT (dec,
488           "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
489           format);
490       break;
491     }
492     case GST_QUERY_DURATION:
493     {
494       /* forward to peer for total */
495       res = gst_pad_peer_query (dec->sinkpad, query);
496       if (!res)
497         goto error;
498
499       break;
500     }
501     case GST_QUERY_CONVERT:
502     {
503       GstFormat src_fmt, dest_fmt;
504       gint64 src_val, dest_val;
505
506       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
507       if (!(res =
508               theora_dec_src_convert (pad, src_fmt, src_val, &dest_fmt,
509                   &dest_val)))
510         goto error;
511
512       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
513       break;
514     }
515     default:
516       res = gst_pad_query_default (pad, query);
517       break;
518   }
519 done:
520   gst_object_unref (dec);
521
522   return res;
523
524   /* ERRORS */
525 error:
526   {
527     GST_DEBUG_OBJECT (dec, "query failed");
528     goto done;
529   }
530 }
531
532 static gboolean
533 theora_dec_src_event (GstPad * pad, GstEvent * event)
534 {
535   gboolean res = TRUE;
536   GstTheoraDec *dec;
537
538   dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
539
540   switch (GST_EVENT_TYPE (event)) {
541     case GST_EVENT_SEEK:
542     {
543       GstFormat format, tformat;
544       gdouble rate;
545       GstEvent *real_seek;
546       GstSeekFlags flags;
547       GstSeekType cur_type, stop_type;
548       gint64 cur, stop;
549       gint64 tcur, tstop;
550       guint32 seqnum;
551
552       gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
553           &stop_type, &stop);
554       seqnum = gst_event_get_seqnum (event);
555       gst_event_unref (event);
556
557       /* we have to ask our peer to seek to time here as we know
558        * nothing about how to generate a granulepos from the src
559        * formats or anything.
560        * 
561        * First bring the requested format to time 
562        */
563       tformat = GST_FORMAT_TIME;
564       if (!(res = theora_dec_src_convert (pad, format, cur, &tformat, &tcur)))
565         goto convert_error;
566       if (!(res = theora_dec_src_convert (pad, format, stop, &tformat, &tstop)))
567         goto convert_error;
568
569       /* then seek with time on the peer */
570       real_seek = gst_event_new_seek (rate, GST_FORMAT_TIME,
571           flags, cur_type, tcur, stop_type, tstop);
572       gst_event_set_seqnum (real_seek, seqnum);
573
574       res = gst_pad_push_event (dec->sinkpad, real_seek);
575       break;
576     }
577     case GST_EVENT_QOS:
578     {
579       gdouble proportion;
580       GstClockTimeDiff diff;
581       GstClockTime timestamp;
582
583       gst_event_parse_qos (event, &proportion, &diff, &timestamp);
584
585       /* we cannot randomly skip frame decoding since we don't have
586        * B frames. we can however use the timestamp and diff to not
587        * push late frames. This would at least save us the time to
588        * crop/memcpy the data. */
589       GST_OBJECT_LOCK (dec);
590       dec->proportion = proportion;
591       dec->earliest_time = timestamp + diff;
592       GST_OBJECT_UNLOCK (dec);
593
594       GST_DEBUG_OBJECT (dec, "got QoS %" GST_TIME_FORMAT ", %" G_GINT64_FORMAT,
595           GST_TIME_ARGS (timestamp), diff);
596
597       res = gst_pad_push_event (dec->sinkpad, event);
598       break;
599     }
600     default:
601       res = gst_pad_push_event (dec->sinkpad, event);
602       break;
603   }
604 done:
605   gst_object_unref (dec);
606
607   return res;
608
609   /* ERRORS */
610 convert_error:
611   {
612     GST_DEBUG_OBJECT (dec, "could not convert format");
613     goto done;
614   }
615 }
616
617 static gboolean
618 theora_dec_sink_event (GstPad * pad, GstEvent * event)
619 {
620   gboolean ret = FALSE;
621   GstTheoraDec *dec;
622
623   dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
624
625   GST_LOG_OBJECT (dec, "handling event");
626   switch (GST_EVENT_TYPE (event)) {
627     case GST_EVENT_FLUSH_START:
628       ret = gst_pad_push_event (dec->srcpad, event);
629       break;
630     case GST_EVENT_FLUSH_STOP:
631       gst_theora_dec_reset (dec);
632       ret = gst_pad_push_event (dec->srcpad, event);
633       break;
634     case GST_EVENT_EOS:
635       ret = gst_pad_push_event (dec->srcpad, event);
636       break;
637     case GST_EVENT_NEWSEGMENT:
638     {
639       gboolean update;
640       GstFormat format;
641       gdouble rate, arate;
642       gint64 start, stop, time;
643
644       gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
645           &start, &stop, &time);
646
647       /* we need TIME format */
648       if (format != GST_FORMAT_TIME)
649         goto newseg_wrong_format;
650
651       GST_DEBUG_OBJECT (dec,
652           "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
653           ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
654           update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
655           GST_TIME_ARGS (time));
656
657       /* now configure the values */
658       gst_segment_set_newsegment_full (&dec->segment, update,
659           rate, arate, format, start, stop, time);
660       dec->seqnum = gst_event_get_seqnum (event);
661
662       /* We don't forward this unless/until the decoder is initialised */
663       if (dec->have_header) {
664         ret = gst_pad_push_event (dec->srcpad, event);
665       } else {
666         dec->pendingevents = g_list_append (dec->pendingevents, event);
667         ret = TRUE;
668       }
669       break;
670     }
671     case GST_EVENT_TAG:
672     {
673       if (dec->have_header)
674         /* and forward */
675         ret = gst_pad_push_event (dec->srcpad, event);
676       else {
677         /* store it to send once we're initialized */
678         dec->pendingevents = g_list_append (dec->pendingevents, event);
679         ret = TRUE;
680       }
681       break;
682     }
683     default:
684       ret = gst_pad_push_event (dec->srcpad, event);
685       break;
686   }
687 done:
688   gst_object_unref (dec);
689
690   return ret;
691
692   /* ERRORS */
693 newseg_wrong_format:
694   {
695     GST_DEBUG_OBJECT (dec, "received non TIME newsegment");
696     gst_event_unref (event);
697     goto done;
698   }
699 }
700
701 static gboolean
702 theora_dec_setcaps (GstPad * pad, GstCaps * caps)
703 {
704   GstTheoraDec *dec;
705   GstStructure *s;
706   const GValue *codec_data;
707
708   dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
709
710   s = gst_caps_get_structure (caps, 0);
711
712   /* parse the par, this overrides the encoded par */
713   dec->have_par = gst_structure_get_fraction (s, "pixel-aspect-ratio",
714       &dec->par_num, &dec->par_den);
715
716   if ((codec_data = gst_structure_get_value (s, "codec_data"))) {
717     if (G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) {
718       GstBuffer *buffer;
719       guint8 *data;
720       guint size;
721       guint offset;
722
723       buffer = gst_value_get_buffer (codec_data);
724
725       offset = 0;
726       size = GST_BUFFER_SIZE (buffer);
727       data = GST_BUFFER_DATA (buffer);
728
729       while (size > 2) {
730         guint psize;
731         GstBuffer *buf;
732
733         psize = (data[0] << 8) | data[1];
734         /* skip header */
735         data += 2;
736         size -= 2;
737         offset += 2;
738
739         /* make sure we don't read too much */
740         psize = MIN (psize, size);
741
742         buf = gst_buffer_create_sub (buffer, offset, psize);
743
744         /* first buffer is a discont buffer */
745         if (offset == 2)
746           GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
747
748         /* now feed it to the decoder we can ignore the error */
749         theora_dec_chain (pad, buf);
750
751         /* skip the data */
752         size -= psize;
753         data += psize;
754         offset += psize;
755       }
756     }
757   }
758
759   gst_object_unref (dec);
760
761   return TRUE;
762 }
763
764 static GstFlowReturn
765 theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet)
766 {
767   gchar *encoder = NULL;
768   GstBuffer *buf;
769   GstTagList *list;
770
771   GST_DEBUG_OBJECT (dec, "parsing comment packet");
772
773   buf = gst_buffer_new ();
774   GST_BUFFER_SIZE (buf) = packet->bytes;
775   GST_BUFFER_DATA (buf) = packet->packet;
776
777   list =
778       gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\201theora", 7,
779       &encoder);
780
781   gst_buffer_unref (buf);
782
783   if (!list) {
784     GST_ERROR_OBJECT (dec, "couldn't decode comments");
785     list = gst_tag_list_new ();
786   }
787   if (encoder) {
788     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
789         GST_TAG_ENCODER, encoder, NULL);
790     g_free (encoder);
791   }
792   gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
793       GST_TAG_ENCODER_VERSION, dec->info.version_major,
794       GST_TAG_VIDEO_CODEC, "Theora", NULL);
795
796   if (dec->info.target_bitrate > 0) {
797     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
798         GST_TAG_BITRATE, dec->info.target_bitrate,
799         GST_TAG_NOMINAL_BITRATE, dec->info.target_bitrate, NULL);
800   }
801
802   dec->tags = list;
803
804   return GST_FLOW_OK;
805 }
806
807 static GstFlowReturn
808 theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
809 {
810   GstCaps *caps;
811   gint par_num, par_den;
812   GstFlowReturn ret = GST_FLOW_OK;
813   GList *walk;
814   guint32 fourcc;
815
816   GST_DEBUG_OBJECT (dec, "fps %d/%d, PAR %d/%d",
817       dec->info.fps_numerator, dec->info.fps_denominator,
818       dec->info.aspect_numerator, dec->info.aspect_denominator);
819
820   /* calculate par
821    * the info.aspect_* values reflect PAR;
822    * 0:x and x:0 are allowed and can be interpreted as 1:1.
823    */
824   if (dec->have_par) {
825     /* we had a par on the sink caps, override the encoded par */
826     GST_DEBUG_OBJECT (dec, "overriding with input PAR");
827     par_num = dec->par_num;
828     par_den = dec->par_den;
829   } else {
830     /* take encoded par */
831     par_num = dec->info.aspect_numerator;
832     par_den = dec->info.aspect_denominator;
833   }
834   if (par_num == 0 || par_den == 0) {
835     par_num = par_den = 1;
836   }
837   /* theora has:
838    *
839    *  width/height : dimension of the encoded frame 
840    *  pic_width/pic_height : dimension of the visible part
841    *  pic_x/pic_y : offset in encoded frame where visible part starts
842    */
843   GST_DEBUG_OBJECT (dec, "dimension %dx%d, PAR %d/%d", dec->info.pic_width,
844       dec->info.pic_height, par_num, par_den);
845   GST_DEBUG_OBJECT (dec, "frame dimension %dx%d, offset %d:%d",
846       dec->info.pic_width, dec->info.pic_height,
847       dec->info.pic_x, dec->info.pic_y);
848
849   if (dec->info.pixel_fmt == TH_PF_420) {
850     dec->output_bpp = 12;       /* Average bits per pixel. */
851     fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
852   } else if (dec->info.pixel_fmt == TH_PF_422) {
853     dec->output_bpp = 16;
854     fourcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
855   } else if (dec->info.pixel_fmt == TH_PF_444) {
856     dec->output_bpp = 24;
857     fourcc = GST_MAKE_FOURCC ('Y', '4', '4', '4');
858   } else {
859     GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt);
860     return GST_FLOW_ERROR;
861   }
862
863   if (dec->crop) {
864     dec->width = dec->info.pic_width;
865     dec->height = dec->info.pic_height;
866     dec->offset_x = dec->info.pic_x;
867     dec->offset_y = dec->info.pic_y;
868     /* Ensure correct offsets in chroma for formats that need it
869      * by rounding the offset. libtheora will add proper pixels,
870      * so no need to handle them ourselves. */
871     if (dec->offset_x & 1 && dec->info.pixel_fmt != TH_PF_444) {
872       dec->offset_x--;
873       dec->width++;
874     }
875     if (dec->offset_y & 1 && dec->info.pixel_fmt == TH_PF_420) {
876       dec->offset_y--;
877       dec->height++;
878     }
879   } else {
880     /* no cropping, use the encoded dimensions */
881     dec->width = dec->info.frame_width;
882     dec->height = dec->info.frame_height;
883     dec->offset_x = 0;
884     dec->offset_y = 0;
885   }
886
887   GST_DEBUG_OBJECT (dec, "after fixup frame dimension %dx%d, offset %d:%d",
888       dec->width, dec->height, dec->offset_x, dec->offset_y);
889
890   /* done */
891   dec->decoder = th_decode_alloc (&dec->info, dec->setup);
892
893   if (th_decode_ctl (dec->decoder, TH_DECCTL_SET_TELEMETRY_MV,
894           &dec->telemetry_mv, sizeof (dec->telemetry_mv)) != TH_EIMPL) {
895     GST_WARNING_OBJECT (dec, "Could not enable MV visualisation");
896   }
897   if (th_decode_ctl (dec->decoder, TH_DECCTL_SET_TELEMETRY_MBMODE,
898           &dec->telemetry_mbmode, sizeof (dec->telemetry_mbmode)) != TH_EIMPL) {
899     GST_WARNING_OBJECT (dec, "Could not enable MB mode visualisation");
900   }
901   if (th_decode_ctl (dec->decoder, TH_DECCTL_SET_TELEMETRY_QI,
902           &dec->telemetry_qi, sizeof (dec->telemetry_qi)) != TH_EIMPL) {
903     GST_WARNING_OBJECT (dec, "Could not enable QI mode visualisation");
904   }
905   if (th_decode_ctl (dec->decoder, TH_DECCTL_SET_TELEMETRY_BITS,
906           &dec->telemetry_bits, sizeof (dec->telemetry_bits)) != TH_EIMPL) {
907     GST_WARNING_OBJECT (dec, "Could not enable BITS mode visualisation");
908   }
909
910   caps = gst_caps_new_simple ("video/x-raw-yuv",
911       "format", GST_TYPE_FOURCC, fourcc,
912       "framerate", GST_TYPE_FRACTION,
913       dec->info.fps_numerator, dec->info.fps_denominator,
914       "pixel-aspect-ratio", GST_TYPE_FRACTION, par_num, par_den,
915       "width", G_TYPE_INT, dec->width, "height", G_TYPE_INT, dec->height,
916       "color-matrix", G_TYPE_STRING, "sdtv",
917       "chroma-site", G_TYPE_STRING, "jpeg", NULL);
918   gst_pad_set_caps (dec->srcpad, caps);
919   gst_caps_unref (caps);
920
921   dec->have_header = TRUE;
922
923   if (dec->pendingevents) {
924     for (walk = dec->pendingevents; walk; walk = g_list_next (walk))
925       gst_pad_push_event (dec->srcpad, GST_EVENT_CAST (walk->data));
926     g_list_free (dec->pendingevents);
927     dec->pendingevents = NULL;
928   }
929
930   if (dec->tags) {
931     gst_element_found_tags_for_pad (GST_ELEMENT_CAST (dec), dec->srcpad,
932         dec->tags);
933     dec->tags = NULL;
934   }
935
936   return ret;
937 }
938
939 static GstFlowReturn
940 theora_handle_header_packet (GstTheoraDec * dec, ogg_packet * packet)
941 {
942   GstFlowReturn res;
943   int ret;
944
945   GST_DEBUG_OBJECT (dec, "parsing header packet");
946
947   ret = th_decode_headerin (&dec->info, &dec->comment, &dec->setup, packet);
948   if (ret < 0)
949     goto header_read_error;
950
951   switch (packet->packet[0]) {
952     case 0x81:
953       res = theora_handle_comment_packet (dec, packet);
954       break;
955     case 0x82:
956       res = theora_handle_type_packet (dec, packet);
957       break;
958     default:
959       /* ignore */
960       g_warning ("unknown theora header packet found");
961     case 0x80:
962       /* nothing special, this is the identification header */
963       res = GST_FLOW_OK;
964       break;
965   }
966   return res;
967
968   /* ERRORS */
969 header_read_error:
970   {
971     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
972         (NULL), ("couldn't read header packet"));
973     return GST_FLOW_ERROR;
974   }
975 }
976
977 /* returns TRUE if buffer is within segment, else FALSE.
978  * if Buffer is on segment border, it's timestamp and duration will be clipped */
979 static gboolean
980 clip_buffer (GstTheoraDec * dec, GstBuffer * buf)
981 {
982   gboolean res = TRUE;
983   GstClockTime in_ts, in_dur, stop;
984   gint64 cstart, cstop;
985
986   in_ts = GST_BUFFER_TIMESTAMP (buf);
987   in_dur = GST_BUFFER_DURATION (buf);
988
989   GST_LOG_OBJECT (dec,
990       "timestamp:%" GST_TIME_FORMAT " , duration:%" GST_TIME_FORMAT,
991       GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur));
992
993   /* can't clip without TIME segment */
994   if (dec->segment.format != GST_FORMAT_TIME)
995     goto beach;
996
997   /* we need a start time */
998   if (!GST_CLOCK_TIME_IS_VALID (in_ts))
999     goto beach;
1000
1001   /* generate valid stop, if duration unknown, we have unknown stop */
1002   stop =
1003       GST_CLOCK_TIME_IS_VALID (in_dur) ? (in_ts + in_dur) : GST_CLOCK_TIME_NONE;
1004
1005   /* now clip */
1006   if (!(res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1007               in_ts, stop, &cstart, &cstop)))
1008     goto beach;
1009
1010   /* update timestamp and possibly duration if the clipped stop time is
1011    * valid */
1012   GST_BUFFER_TIMESTAMP (buf) = cstart;
1013   if (GST_CLOCK_TIME_IS_VALID (cstop))
1014     GST_BUFFER_DURATION (buf) = cstop - cstart;
1015
1016 beach:
1017   GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : ""));
1018   return res;
1019 }
1020
1021 static GstFlowReturn
1022 theora_dec_push_forward (GstTheoraDec * dec, GstBuffer * buf)
1023 {
1024   GstFlowReturn result = GST_FLOW_OK;
1025
1026   if (clip_buffer (dec, buf)) {
1027     if (dec->discont) {
1028       GST_LOG_OBJECT (dec, "setting DISCONT");
1029       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
1030       dec->discont = FALSE;
1031     }
1032     result = gst_pad_push (dec->srcpad, buf);
1033   } else {
1034     gst_buffer_unref (buf);
1035   }
1036
1037   return result;
1038 }
1039
1040 static GstFlowReturn
1041 theora_dec_push_reverse (GstTheoraDec * dec, GstBuffer * buf)
1042 {
1043   GstFlowReturn result = GST_FLOW_OK;
1044
1045   dec->queued = g_list_prepend (dec->queued, buf);
1046
1047   return result;
1048 }
1049
1050 /* Allocate buffer and copy image data into Y444 format */
1051 static GstFlowReturn
1052 theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, GstBuffer ** out)
1053 {
1054   gint width, height, stride;
1055   GstFlowReturn result;
1056   int i, plane;
1057   GstVideoFormat format;
1058   guint8 *dest, *src;
1059
1060   switch (dec->info.pixel_fmt) {
1061     case TH_PF_444:
1062       format = GST_VIDEO_FORMAT_Y444;
1063       break;
1064     case TH_PF_420:
1065       format = GST_VIDEO_FORMAT_I420;
1066       break;
1067     case TH_PF_422:
1068       format = GST_VIDEO_FORMAT_Y42B;
1069       break;
1070     default:
1071       g_assert_not_reached ();
1072   }
1073
1074   result =
1075       gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
1076       gst_video_format_get_size (format, dec->width, dec->height),
1077       GST_PAD_CAPS (dec->srcpad), out);
1078   if (G_UNLIKELY (result != GST_FLOW_OK)) {
1079     GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s",
1080         gst_flow_get_name (result));
1081     return result;
1082   }
1083
1084   for (plane = 0; plane < 3; plane++) {
1085     width = gst_video_format_get_component_width (format, plane, dec->width);
1086     height = gst_video_format_get_component_height (format, plane, dec->height);
1087     stride = gst_video_format_get_row_stride (format, plane, dec->width);
1088
1089     dest =
1090         GST_BUFFER_DATA (*out) + gst_video_format_get_component_offset (format,
1091         plane, dec->width, dec->height);
1092     src = buf[plane].data;
1093     src += ((height == dec->height) ? dec->offset_y : dec->offset_y / 2)
1094         * buf[plane].stride;
1095     src += (width == dec->width) ? dec->offset_x : dec->offset_x / 2;
1096
1097     for (i = 0; i < height; i++) {
1098       memcpy (dest, src, width);
1099
1100       dest += stride;
1101       src += buf[plane].stride;
1102     }
1103   }
1104
1105   return GST_FLOW_OK;
1106 }
1107
1108 static GstFlowReturn
1109 theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
1110     GstClockTime outtime, GstClockTime outdur)
1111 {
1112   /* normal data packet */
1113   th_ycbcr_buffer buf;
1114   GstBuffer *out;
1115   gboolean keyframe;
1116   GstFlowReturn result;
1117   ogg_int64_t gp;
1118
1119   if (G_UNLIKELY (!dec->have_header))
1120     goto not_initialized;
1121
1122   /* get timestamp and durations */
1123   if (outtime == -1)
1124     outtime = dec->last_timestamp;
1125   if (outdur == -1)
1126     outdur = gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator,
1127         dec->info.fps_numerator);
1128
1129   /* calculate expected next timestamp */
1130   if (outtime != -1 && outdur != -1)
1131     dec->last_timestamp = outtime + outdur;
1132
1133   /* the second most significant bit of the first data byte is cleared 
1134    * for keyframes. We can only check it if it's not a zero-length packet. */
1135   keyframe = packet->bytes && ((packet->packet[0] & 0x40) == 0);
1136   if (G_UNLIKELY (keyframe)) {
1137     GST_DEBUG_OBJECT (dec, "we have a keyframe");
1138     dec->need_keyframe = FALSE;
1139   } else if (G_UNLIKELY (dec->need_keyframe)) {
1140     goto dropping;
1141   }
1142
1143   GST_DEBUG_OBJECT (dec, "parsing data packet");
1144
1145   /* this does the decoding */
1146   if (G_UNLIKELY (th_decode_packetin (dec->decoder, packet, &gp) < 0))
1147     goto decode_error;
1148
1149   if (outtime != -1) {
1150     gboolean need_skip;
1151     GstClockTime running_time;
1152     GstClockTime earliest_time;
1153     gdouble proportion;
1154
1155     /* qos needs to be done on running time */
1156     running_time = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1157         outtime);
1158
1159     GST_OBJECT_LOCK (dec);
1160     proportion = dec->proportion;
1161     earliest_time = dec->earliest_time;
1162     /* check for QoS, don't perform the last steps of getting and
1163      * pushing the buffers that are known to be late. */
1164     need_skip = earliest_time != -1 && running_time <= earliest_time;
1165     GST_OBJECT_UNLOCK (dec);
1166
1167     if (need_skip) {
1168       GstMessage *qos_msg;
1169       guint64 stream_time;
1170       gint64 jitter;
1171
1172       GST_DEBUG_OBJECT (dec, "skipping decoding: qostime %"
1173           GST_TIME_FORMAT " <= %" GST_TIME_FORMAT,
1174           GST_TIME_ARGS (running_time), GST_TIME_ARGS (earliest_time));
1175
1176       dec->dropped++;
1177
1178       stream_time =
1179           gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, outtime);
1180       jitter = GST_CLOCK_DIFF (running_time, earliest_time);
1181
1182       qos_msg =
1183           gst_message_new_qos (GST_OBJECT_CAST (dec), FALSE, running_time,
1184           stream_time, outtime, outdur);
1185       gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
1186       gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
1187           dec->processed, dec->dropped);
1188       gst_element_post_message (GST_ELEMENT_CAST (dec), qos_msg);
1189
1190       goto dropping_qos;
1191     }
1192   }
1193
1194   /* this does postprocessing and set up the decoded frame
1195    * pointers in our yuv variable */
1196   if (G_UNLIKELY (th_decode_ycbcr_out (dec->decoder, buf) < 0))
1197     goto no_yuv;
1198
1199   if (G_UNLIKELY ((buf[0].width != dec->info.frame_width)
1200           || (buf[0].height != dec->info.frame_height)))
1201     goto wrong_dimensions;
1202
1203   result = theora_handle_image (dec, buf, &out);
1204   if (result != GST_FLOW_OK)
1205     return result;
1206
1207   GST_BUFFER_OFFSET (out) = dec->frame_nr;
1208   if (dec->frame_nr != -1)
1209     dec->frame_nr++;
1210   GST_BUFFER_OFFSET_END (out) = dec->frame_nr;
1211
1212   GST_BUFFER_TIMESTAMP (out) = outtime;
1213   GST_BUFFER_DURATION (out) = outdur;
1214
1215   dec->processed++;
1216
1217   if (dec->segment.rate >= 0.0)
1218     result = theora_dec_push_forward (dec, out);
1219   else
1220     result = theora_dec_push_reverse (dec, out);
1221
1222   return result;
1223
1224   /* ERRORS */
1225 not_initialized:
1226   {
1227     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1228         (NULL), ("no header sent yet"));
1229     return GST_FLOW_ERROR;
1230   }
1231 dropping:
1232   {
1233     GST_WARNING_OBJECT (dec, "dropping frame because we need a keyframe");
1234     dec->discont = TRUE;
1235     return GST_FLOW_OK;
1236   }
1237 dropping_qos:
1238   {
1239     if (dec->frame_nr != -1)
1240       dec->frame_nr++;
1241     dec->discont = TRUE;
1242     GST_WARNING_OBJECT (dec, "dropping frame because of QoS");
1243     return GST_FLOW_OK;
1244   }
1245 decode_error:
1246   {
1247     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1248         (NULL), ("theora decoder did not decode data packet"));
1249     return GST_FLOW_ERROR;
1250   }
1251 no_yuv:
1252   {
1253     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1254         (NULL), ("couldn't read out YUV image"));
1255     return GST_FLOW_ERROR;
1256   }
1257 wrong_dimensions:
1258   {
1259     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, FORMAT,
1260         (NULL), ("dimensions of image do not match header"));
1261     return GST_FLOW_ERROR;
1262   }
1263 }
1264
1265 static GstFlowReturn
1266 theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf)
1267 {
1268   ogg_packet packet;
1269   GstFlowReturn result = GST_FLOW_OK;
1270   GstClockTime timestamp, duration;
1271
1272   /* make ogg_packet out of the buffer */
1273   packet.packet = GST_BUFFER_DATA (buf);
1274   packet.bytes = GST_BUFFER_SIZE (buf);
1275   packet.granulepos = -1;
1276   packet.packetno = 0;          /* we don't really care */
1277   packet.b_o_s = dec->have_header ? 0 : 1;
1278   /* EOS does not matter for the decoder */
1279   packet.e_o_s = 0;
1280
1281   GST_LOG_OBJECT (dec, "decode buffer of size %ld", packet.bytes);
1282
1283   /* save last seem timestamp for interpolating the next timestamps using the
1284    * framerate when we need to */
1285   timestamp = GST_BUFFER_TIMESTAMP (buf);
1286   duration = GST_BUFFER_DURATION (buf);
1287
1288   GST_DEBUG_OBJECT (dec, "header=%02x, outtime=%" GST_TIME_FORMAT,
1289       packet.bytes ? packet.packet[0] : -1, GST_TIME_ARGS (timestamp));
1290
1291   /* switch depending on packet type. A zero byte packet is always a data
1292    * packet; we don't dereference it in that case. */
1293   if (packet.bytes && packet.packet[0] & 0x80) {
1294     if (dec->have_header) {
1295       GST_WARNING_OBJECT (GST_OBJECT (dec), "Ignoring header");
1296       goto done;
1297     }
1298     result = theora_handle_header_packet (dec, &packet);
1299   } else {
1300     result = theora_handle_data_packet (dec, &packet, timestamp, duration);
1301   }
1302
1303 done:
1304   return result;
1305 }
1306
1307 /* For reverse playback we use a technique that can be used for
1308  * any keyframe based video codec.
1309  *
1310  * Input:
1311  *  Buffer decoding order:  7  8  9  4  5  6  1  2  3  EOS
1312  *  Keyframe flag:                      K        K
1313  *  Discont flag:           D        D        D
1314  *
1315  * - Each Discont marks a discont in the decoding order.
1316  * - The keyframes mark where we can start decoding.
1317  *
1318  * First we prepend incomming buffers to the gather queue, whenever we receive
1319  * a discont, we flush out the gather queue.
1320  *
1321  * The above data will be accumulated in the gather queue like this:
1322  *
1323  *   gather queue:  9  8  7
1324  *                        D
1325  *
1326  * Whe buffer 4 is received (with a DISCONT), we flush the gather queue like
1327  * this:
1328  *
1329  *   while (gather)
1330  *     take head of queue and prepend to decode queue.
1331  *     if we copied a keyframe, decode the decode queue.
1332  *
1333  * After we flushed the gather queue, we add 4 to the (now empty) gather queue.
1334  * We get the following situation:
1335  *
1336  *  gather queue:    4
1337  *  decode queue:    7  8  9
1338  *
1339  * After we received 5 (Keyframe) and 6:
1340  *
1341  *  gather queue:    6  5  4
1342  *  decode queue:    7  8  9
1343  *
1344  * When we receive 1 (DISCONT) which triggers a flush of the gather queue:
1345  *
1346  *   Copy head of the gather queue (6) to decode queue:
1347  *
1348  *    gather queue:    5  4
1349  *    decode queue:    6  7  8  9
1350  *
1351  *   Copy head of the gather queue (5) to decode queue. This is a keyframe so we
1352  *   can start decoding.
1353  *
1354  *    gather queue:    4
1355  *    decode queue:    5  6  7  8  9
1356  *
1357  *   Decode frames in decode queue, store raw decoded data in output queue, we
1358  *   can take the head of the decode queue and prepend the decoded result in the
1359  *   output queue:
1360  *
1361  *    gather queue:    4
1362  *    decode queue:    
1363  *    output queue:    9  8  7  6  5
1364  *
1365  *   Now output all the frames in the output queue, picking a frame from the
1366  *   head of the queue.
1367  *
1368  *   Copy head of the gather queue (4) to decode queue, we flushed the gather
1369  *   queue and can now store input buffer in the gather queue:
1370  *
1371  *    gather queue:    1
1372  *    decode queue:    4
1373  *
1374  *  When we receive EOS, the queue looks like:
1375  *
1376  *    gather queue:    3  2  1
1377  *    decode queue:    4
1378  *
1379  *  Fill decode queue, first keyframe we copy is 2:
1380  *
1381  *    gather queue:    1
1382  *    decode queue:    2  3  4
1383  *
1384  *  Decoded output:
1385  *
1386  *    gather queue:    1
1387  *    decode queue:    
1388  *    output queue:    4  3  2
1389  *
1390  *  Leftover buffer 1 cannot be decoded and must be discarded.
1391  */
1392 static GstFlowReturn
1393 theora_dec_flush_decode (GstTheoraDec * dec)
1394 {
1395   GstFlowReturn res = GST_FLOW_OK;
1396
1397   while (dec->decode) {
1398     GstBuffer *buf = GST_BUFFER_CAST (dec->decode->data);
1399
1400     GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
1401         buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1402
1403     /* decode buffer, prepend to output queue */
1404     res = theora_dec_decode_buffer (dec, buf);
1405
1406     /* don't need it anymore now */
1407     gst_buffer_unref (buf);
1408
1409     dec->decode = g_list_delete_link (dec->decode, dec->decode);
1410   }
1411   while (dec->queued) {
1412     GstBuffer *buf = GST_BUFFER_CAST (dec->queued->data);
1413
1414     /* iterate output queue an push downstream */
1415     res = gst_pad_push (dec->srcpad, buf);
1416
1417     dec->queued = g_list_delete_link (dec->queued, dec->queued);
1418   }
1419
1420   return res;
1421 }
1422
1423 static GstFlowReturn
1424 theora_dec_chain_reverse (GstTheoraDec * dec, gboolean discont, GstBuffer * buf)
1425 {
1426   GstFlowReturn res = GST_FLOW_OK;
1427
1428   /* if we have a discont, move buffers to the decode list */
1429   if (G_UNLIKELY (discont)) {
1430     GST_DEBUG_OBJECT (dec, "received discont,gathering buffers");
1431     while (dec->gather) {
1432       GstBuffer *gbuf;
1433       guint8 *data;
1434
1435       gbuf = GST_BUFFER_CAST (dec->gather->data);
1436       /* remove from the gather list */
1437       dec->gather = g_list_delete_link (dec->gather, dec->gather);
1438       /* copy to decode queue */
1439       dec->decode = g_list_prepend (dec->decode, gbuf);
1440
1441       /* if we copied a keyframe, flush and decode the decode queue */
1442       data = GST_BUFFER_DATA (gbuf);
1443       if (data && (data[0] & 0x40) == 0) {
1444         GST_DEBUG_OBJECT (dec, "copied keyframe");
1445         res = theora_dec_flush_decode (dec);
1446       }
1447     }
1448   }
1449
1450   /* add buffer to gather queue */
1451   GST_DEBUG_OBJECT (dec, "gathering buffer %p, size %u", buf,
1452       GST_BUFFER_SIZE (buf));
1453   dec->gather = g_list_prepend (dec->gather, buf);
1454
1455   return res;
1456 }
1457
1458 static GstFlowReturn
1459 theora_dec_chain_forward (GstTheoraDec * dec, gboolean discont,
1460     GstBuffer * buffer)
1461 {
1462   GstFlowReturn result;
1463
1464   result = theora_dec_decode_buffer (dec, buffer);
1465
1466   gst_buffer_unref (buffer);
1467
1468   return result;
1469 }
1470
1471 static GstFlowReturn
1472 theora_dec_chain (GstPad * pad, GstBuffer * buf)
1473 {
1474   GstTheoraDec *dec;
1475   GstFlowReturn res;
1476   gboolean discont;
1477
1478   dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
1479
1480   /* peel of DISCONT flag */
1481   discont = GST_BUFFER_IS_DISCONT (buf);
1482
1483   /* resync on DISCONT */
1484   if (G_UNLIKELY (discont)) {
1485     GST_DEBUG_OBJECT (dec, "received DISCONT buffer");
1486     dec->need_keyframe = TRUE;
1487     dec->last_timestamp = -1;
1488     dec->discont = TRUE;
1489   }
1490
1491   if (dec->segment.rate > 0.0)
1492     res = theora_dec_chain_forward (dec, discont, buf);
1493   else
1494     res = theora_dec_chain_reverse (dec, discont, buf);
1495
1496   gst_object_unref (dec);
1497
1498   return res;
1499 }
1500
1501 static GstStateChangeReturn
1502 theora_dec_change_state (GstElement * element, GstStateChange transition)
1503 {
1504   GstTheoraDec *dec = GST_THEORA_DEC (element);
1505   GstStateChangeReturn ret;
1506
1507   switch (transition) {
1508     case GST_STATE_CHANGE_NULL_TO_READY:
1509       break;
1510     case GST_STATE_CHANGE_READY_TO_PAUSED:
1511       th_info_clear (&dec->info);
1512       th_comment_clear (&dec->comment);
1513       GST_DEBUG_OBJECT (dec, "Setting have_header to FALSE in READY->PAUSED");
1514       dec->have_header = FALSE;
1515       dec->have_par = FALSE;
1516       gst_theora_dec_reset (dec);
1517       break;
1518     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1519       break;
1520     default:
1521       break;
1522   }
1523
1524   ret = parent_class->change_state (element, transition);
1525
1526   switch (transition) {
1527     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1528       break;
1529     case GST_STATE_CHANGE_PAUSED_TO_READY:
1530       th_info_clear (&dec->info);
1531       th_comment_clear (&dec->comment);
1532       th_setup_free (dec->setup);
1533       dec->setup = NULL;
1534       th_decode_free (dec->decoder);
1535       dec->decoder = NULL;
1536       gst_theora_dec_reset (dec);
1537       break;
1538     case GST_STATE_CHANGE_READY_TO_NULL:
1539       break;
1540     default:
1541       break;
1542   }
1543
1544   return ret;
1545 }
1546
1547 static void
1548 theora_dec_set_property (GObject * object, guint prop_id,
1549     const GValue * value, GParamSpec * pspec)
1550 {
1551   GstTheoraDec *dec = GST_THEORA_DEC (object);
1552
1553   switch (prop_id) {
1554     case PROP_CROP:
1555       dec->crop = g_value_get_boolean (value);
1556       break;
1557     case PROP_TELEMETRY_MV:
1558       dec->telemetry_mv = g_value_get_int (value);
1559       break;
1560     case PROP_TELEMETRY_MBMODE:
1561       dec->telemetry_mbmode = g_value_get_int (value);
1562       break;
1563     case PROP_TELEMETRY_QI:
1564       dec->telemetry_qi = g_value_get_int (value);
1565       break;
1566     case PROP_TELEMETRY_BITS:
1567       dec->telemetry_bits = g_value_get_int (value);
1568       break;
1569     default:
1570       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1571       break;
1572   }
1573 }
1574
1575 static void
1576 theora_dec_get_property (GObject * object, guint prop_id,
1577     GValue * value, GParamSpec * pspec)
1578 {
1579   GstTheoraDec *dec = GST_THEORA_DEC (object);
1580
1581   switch (prop_id) {
1582     case PROP_CROP:
1583       g_value_set_boolean (value, dec->crop);
1584       break;
1585     case PROP_TELEMETRY_MV:
1586       g_value_set_int (value, dec->telemetry_mv);
1587       break;
1588     case PROP_TELEMETRY_MBMODE:
1589       g_value_set_int (value, dec->telemetry_mbmode);
1590       break;
1591     case PROP_TELEMETRY_QI:
1592       g_value_set_int (value, dec->telemetry_qi);
1593       break;
1594     case PROP_TELEMETRY_BITS:
1595       g_value_set_int (value, dec->telemetry_bits);
1596       break;
1597     default:
1598       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1599       break;
1600   }
1601 }