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