-base: use caps event
[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-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 #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 = 1;
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, 0,
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   guint32 fourcc;
848
849   GST_DEBUG_OBJECT (dec, "fps %d/%d, PAR %d/%d",
850       dec->info.fps_numerator, dec->info.fps_denominator,
851       dec->info.aspect_numerator, dec->info.aspect_denominator);
852
853   /* calculate par
854    * the info.aspect_* values reflect PAR;
855    * 0:x and x:0 are allowed and can be interpreted as 1:1.
856    */
857   if (dec->have_par) {
858     /* we had a par on the sink caps, override the encoded par */
859     GST_DEBUG_OBJECT (dec, "overriding with input PAR");
860     par_num = dec->par_num;
861     par_den = dec->par_den;
862   } else {
863     /* take encoded par */
864     par_num = dec->info.aspect_numerator;
865     par_den = dec->info.aspect_denominator;
866   }
867   if (par_num == 0 || par_den == 0) {
868     par_num = par_den = 1;
869   }
870   /* theora has:
871    *
872    *  width/height : dimension of the encoded frame 
873    *  pic_width/pic_height : dimension of the visible part
874    *  pic_x/pic_y : offset in encoded frame where visible part starts
875    */
876   GST_DEBUG_OBJECT (dec, "dimension %dx%d, PAR %d/%d", dec->info.pic_width,
877       dec->info.pic_height, par_num, par_den);
878   GST_DEBUG_OBJECT (dec, "frame dimension %dx%d, offset %d:%d",
879       dec->info.pic_width, dec->info.pic_height,
880       dec->info.pic_x, dec->info.pic_y);
881
882   switch (dec->info.pixel_fmt) {
883     case TH_PF_444:
884       dec->output_bpp = 24;
885       dec->format = GST_VIDEO_FORMAT_Y444;
886       fourcc = GST_MAKE_FOURCC ('Y', '4', '4', '4');
887       break;
888     case TH_PF_420:
889       dec->output_bpp = 12;     /* Average bits per pixel. */
890       dec->format = GST_VIDEO_FORMAT_I420;
891       fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
892       break;
893     case TH_PF_422:
894       dec->output_bpp = 16;
895       dec->format = GST_VIDEO_FORMAT_Y42B;
896       fourcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
897       break;
898     default:
899       goto invalid_format;
900   }
901
902   if (dec->crop) {
903     dec->width = dec->info.pic_width;
904     dec->height = dec->info.pic_height;
905     dec->offset_x = dec->info.pic_x;
906     dec->offset_y = dec->info.pic_y;
907     /* Ensure correct offsets in chroma for formats that need it
908      * by rounding the offset. libtheora will add proper pixels,
909      * so no need to handle them ourselves. */
910     if (dec->offset_x & 1 && dec->info.pixel_fmt != TH_PF_444) {
911       dec->offset_x--;
912       dec->width++;
913     }
914     if (dec->offset_y & 1 && dec->info.pixel_fmt == TH_PF_420) {
915       dec->offset_y--;
916       dec->height++;
917     }
918   } else {
919     /* no cropping, use the encoded dimensions */
920     dec->width = dec->info.frame_width;
921     dec->height = dec->info.frame_height;
922     dec->offset_x = 0;
923     dec->offset_y = 0;
924   }
925
926   GST_DEBUG_OBJECT (dec, "after fixup frame dimension %dx%d, offset %d:%d",
927       dec->width, dec->height, dec->offset_x, dec->offset_y);
928
929   /* done */
930   dec->decoder = th_decode_alloc (&dec->info, dec->setup);
931
932   if (th_decode_ctl (dec->decoder, TH_DECCTL_SET_TELEMETRY_MV,
933           &dec->telemetry_mv, sizeof (dec->telemetry_mv)) != TH_EIMPL) {
934     GST_WARNING_OBJECT (dec, "Could not enable MV visualisation");
935   }
936   if (th_decode_ctl (dec->decoder, TH_DECCTL_SET_TELEMETRY_MBMODE,
937           &dec->telemetry_mbmode, sizeof (dec->telemetry_mbmode)) != TH_EIMPL) {
938     GST_WARNING_OBJECT (dec, "Could not enable MB mode visualisation");
939   }
940   if (th_decode_ctl (dec->decoder, TH_DECCTL_SET_TELEMETRY_QI,
941           &dec->telemetry_qi, sizeof (dec->telemetry_qi)) != TH_EIMPL) {
942     GST_WARNING_OBJECT (dec, "Could not enable QI mode visualisation");
943   }
944   if (th_decode_ctl (dec->decoder, TH_DECCTL_SET_TELEMETRY_BITS,
945           &dec->telemetry_bits, sizeof (dec->telemetry_bits)) != TH_EIMPL) {
946     GST_WARNING_OBJECT (dec, "Could not enable BITS mode visualisation");
947   }
948
949   caps = gst_caps_new_simple ("video/x-raw-yuv",
950       "format", GST_TYPE_FOURCC, fourcc,
951       "framerate", GST_TYPE_FRACTION,
952       dec->info.fps_numerator, dec->info.fps_denominator,
953       "pixel-aspect-ratio", GST_TYPE_FRACTION, par_num, par_den,
954       "width", G_TYPE_INT, dec->width, "height", G_TYPE_INT, dec->height,
955       "color-matrix", G_TYPE_STRING, "sdtv",
956       "chroma-site", G_TYPE_STRING, "jpeg", NULL);
957   gst_pad_set_caps (dec->srcpad, caps);
958   gst_caps_unref (caps);
959
960   /* negotiate a bufferpool */
961   if ((ret = theora_negotiate_pool (dec, caps)) != GST_FLOW_OK)
962     goto no_bufferpool;
963
964   dec->have_header = TRUE;
965
966   if (dec->pendingevents) {
967     for (walk = dec->pendingevents; walk; walk = g_list_next (walk))
968       gst_pad_push_event (dec->srcpad, GST_EVENT_CAST (walk->data));
969     g_list_free (dec->pendingevents);
970     dec->pendingevents = NULL;
971   }
972
973   if (dec->tags) {
974     gst_element_found_tags_for_pad (GST_ELEMENT_CAST (dec), dec->srcpad,
975         dec->tags);
976     dec->tags = NULL;
977   }
978
979   return ret;
980
981   /* ERRORS */
982 invalid_format:
983   {
984     GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt);
985     return GST_FLOW_ERROR;
986   }
987 no_bufferpool:
988   {
989     return ret;
990   }
991 }
992
993 static GstFlowReturn
994 theora_handle_header_packet (GstTheoraDec * dec, ogg_packet * packet)
995 {
996   GstFlowReturn res;
997   int ret;
998
999   GST_DEBUG_OBJECT (dec, "parsing header packet");
1000
1001   ret = th_decode_headerin (&dec->info, &dec->comment, &dec->setup, packet);
1002   if (ret < 0)
1003     goto header_read_error;
1004
1005   switch (packet->packet[0]) {
1006     case 0x81:
1007       res = theora_handle_comment_packet (dec, packet);
1008       break;
1009     case 0x82:
1010       res = theora_handle_type_packet (dec, packet);
1011       break;
1012     default:
1013       /* ignore */
1014       g_warning ("unknown theora header packet found");
1015     case 0x80:
1016       /* nothing special, this is the identification header */
1017       res = GST_FLOW_OK;
1018       break;
1019   }
1020   return res;
1021
1022   /* ERRORS */
1023 header_read_error:
1024   {
1025     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1026         (NULL), ("couldn't read header packet"));
1027     return GST_FLOW_ERROR;
1028   }
1029 }
1030
1031 /* returns TRUE if buffer is within segment, else FALSE.
1032  * if Buffer is on segment border, it's timestamp and duration will be clipped */
1033 static gboolean
1034 clip_buffer (GstTheoraDec * dec, GstBuffer * buf)
1035 {
1036   gboolean res = TRUE;
1037   GstClockTime in_ts, in_dur, stop;
1038   guint64 cstart, cstop;
1039
1040   in_ts = GST_BUFFER_TIMESTAMP (buf);
1041   in_dur = GST_BUFFER_DURATION (buf);
1042
1043   GST_LOG_OBJECT (dec,
1044       "timestamp:%" GST_TIME_FORMAT " , duration:%" GST_TIME_FORMAT,
1045       GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur));
1046
1047   /* can't clip without TIME segment */
1048   if (dec->segment.format != GST_FORMAT_TIME)
1049     goto beach;
1050
1051   /* we need a start time */
1052   if (!GST_CLOCK_TIME_IS_VALID (in_ts))
1053     goto beach;
1054
1055   /* generate valid stop, if duration unknown, we have unknown stop */
1056   stop =
1057       GST_CLOCK_TIME_IS_VALID (in_dur) ? (in_ts + in_dur) : GST_CLOCK_TIME_NONE;
1058
1059   /* now clip */
1060   if (!(res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1061               in_ts, stop, &cstart, &cstop)))
1062     goto beach;
1063
1064   /* update timestamp and possibly duration if the clipped stop time is
1065    * valid */
1066   GST_BUFFER_TIMESTAMP (buf) = cstart;
1067   if (GST_CLOCK_TIME_IS_VALID (cstop))
1068     GST_BUFFER_DURATION (buf) = cstop - cstart;
1069
1070 beach:
1071   GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : ""));
1072   return res;
1073 }
1074
1075 static GstFlowReturn
1076 theora_dec_push_forward (GstTheoraDec * dec, GstBuffer * buf)
1077 {
1078   GstFlowReturn result = GST_FLOW_OK;
1079
1080   if (clip_buffer (dec, buf)) {
1081     if (dec->discont) {
1082       GST_LOG_OBJECT (dec, "setting DISCONT");
1083       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
1084       dec->discont = FALSE;
1085     }
1086     result = gst_pad_push (dec->srcpad, buf);
1087   } else {
1088     gst_buffer_unref (buf);
1089   }
1090
1091   return result;
1092 }
1093
1094 static GstFlowReturn
1095 theora_dec_push_reverse (GstTheoraDec * dec, GstBuffer * buf)
1096 {
1097   GstFlowReturn result = GST_FLOW_OK;
1098
1099   dec->queued = g_list_prepend (dec->queued, buf);
1100
1101   return result;
1102 }
1103
1104 /* Allocate buffer and copy image data into Y444 format */
1105 static GstFlowReturn
1106 theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, GstBuffer ** out)
1107 {
1108   gint width, height, stride;
1109   GstFlowReturn result;
1110   int i, plane;
1111   guint8 *dest, *src;
1112   gsize size;
1113   guint8 *data;
1114   gboolean reconfigure;
1115
1116   GST_OBJECT_LOCK (dec->srcpad);
1117   reconfigure = GST_PAD_NEEDS_RECONFIGURE (dec->srcpad);
1118   GST_OBJECT_FLAG_UNSET (dec->srcpad, GST_PAD_NEED_RECONFIGURE);
1119   GST_OBJECT_UNLOCK (dec->srcpad);
1120
1121   if (reconfigure) {
1122     GstCaps *caps;
1123
1124     caps = gst_pad_get_current_caps (dec->srcpad);
1125     theora_negotiate_pool (dec, caps);
1126     gst_caps_unref (caps);
1127   }
1128
1129   result = gst_buffer_pool_acquire_buffer (dec->pool, out, NULL);
1130   if (G_UNLIKELY (result != GST_FLOW_OK))
1131     goto no_buffer;
1132
1133   data = gst_buffer_map (*out, &size, NULL, GST_MAP_WRITE);
1134
1135   /* FIXME, we can do things slightly more efficient when we know that
1136    * downstream understands clipping and video metadata */
1137
1138   for (plane = 0; plane < 3; plane++) {
1139     width =
1140         gst_video_format_get_component_width (dec->format, plane, dec->width);
1141     height =
1142         gst_video_format_get_component_height (dec->format, plane, dec->height);
1143     stride = gst_video_format_get_row_stride (dec->format, plane, dec->width);
1144
1145     dest = data + gst_video_format_get_component_offset (dec->format,
1146         plane, dec->width, dec->height);
1147     src = buf[plane].data;
1148     src += ((height == dec->height) ? dec->offset_y : dec->offset_y / 2)
1149         * buf[plane].stride;
1150     src += (width == dec->width) ? dec->offset_x : dec->offset_x / 2;
1151
1152     for (i = 0; i < height; i++) {
1153       memcpy (dest, src, width);
1154
1155       dest += stride;
1156       src += buf[plane].stride;
1157     }
1158   }
1159   gst_buffer_unmap (*out, data, size);
1160
1161   return GST_FLOW_OK;
1162
1163   /* ERRORS */
1164 no_buffer:
1165   {
1166     GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s",
1167         gst_flow_get_name (result));
1168     return result;
1169   }
1170 }
1171
1172 static GstFlowReturn
1173 theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
1174     GstClockTime outtime, GstClockTime outdur)
1175 {
1176   /* normal data packet */
1177   th_ycbcr_buffer buf;
1178   GstBuffer *out;
1179   gboolean keyframe;
1180   GstFlowReturn result;
1181   ogg_int64_t gp;
1182
1183   if (G_UNLIKELY (!dec->have_header))
1184     goto not_initialized;
1185
1186   /* get timestamp and durations */
1187   if (outtime == -1)
1188     outtime = dec->last_timestamp;
1189   if (outdur == -1)
1190     outdur = gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator,
1191         dec->info.fps_numerator);
1192
1193   /* calculate expected next timestamp */
1194   if (outtime != -1 && outdur != -1)
1195     dec->last_timestamp = outtime + outdur;
1196
1197   /* the second most significant bit of the first data byte is cleared 
1198    * for keyframes. We can only check it if it's not a zero-length packet. */
1199   keyframe = packet->bytes && ((packet->packet[0] & 0x40) == 0);
1200   if (G_UNLIKELY (keyframe)) {
1201     GST_DEBUG_OBJECT (dec, "we have a keyframe");
1202     dec->need_keyframe = FALSE;
1203   } else if (G_UNLIKELY (dec->need_keyframe)) {
1204     goto dropping;
1205   }
1206
1207   GST_DEBUG_OBJECT (dec, "parsing data packet");
1208
1209   /* this does the decoding */
1210   if (G_UNLIKELY (th_decode_packetin (dec->decoder, packet, &gp) < 0))
1211     goto decode_error;
1212
1213   if (outtime != -1) {
1214     gboolean need_skip;
1215     GstClockTime running_time;
1216     GstClockTime earliest_time;
1217     gdouble proportion;
1218
1219     /* qos needs to be done on running time */
1220     running_time = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1221         outtime);
1222
1223     GST_OBJECT_LOCK (dec);
1224     proportion = dec->proportion;
1225     earliest_time = dec->earliest_time;
1226     /* check for QoS, don't perform the last steps of getting and
1227      * pushing the buffers that are known to be late. */
1228     need_skip = earliest_time != -1 && running_time <= earliest_time;
1229     GST_OBJECT_UNLOCK (dec);
1230
1231     if (need_skip) {
1232       GstMessage *qos_msg;
1233       guint64 stream_time;
1234       gint64 jitter;
1235
1236       GST_DEBUG_OBJECT (dec, "skipping decoding: qostime %"
1237           GST_TIME_FORMAT " <= %" GST_TIME_FORMAT,
1238           GST_TIME_ARGS (running_time), GST_TIME_ARGS (earliest_time));
1239
1240       dec->dropped++;
1241
1242       stream_time =
1243           gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, outtime);
1244       jitter = GST_CLOCK_DIFF (running_time, earliest_time);
1245
1246       qos_msg =
1247           gst_message_new_qos (GST_OBJECT_CAST (dec), FALSE, running_time,
1248           stream_time, outtime, outdur);
1249       gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
1250       gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
1251           dec->processed, dec->dropped);
1252       gst_element_post_message (GST_ELEMENT_CAST (dec), qos_msg);
1253
1254       goto dropping_qos;
1255     }
1256   }
1257
1258   /* this does postprocessing and set up the decoded frame
1259    * pointers in our yuv variable */
1260   if (G_UNLIKELY (th_decode_ycbcr_out (dec->decoder, buf) < 0))
1261     goto no_yuv;
1262
1263   if (G_UNLIKELY ((buf[0].width != dec->info.frame_width)
1264           || (buf[0].height != dec->info.frame_height)))
1265     goto wrong_dimensions;
1266
1267   result = theora_handle_image (dec, buf, &out);
1268   if (result != GST_FLOW_OK)
1269     return result;
1270
1271   GST_BUFFER_OFFSET (out) = dec->frame_nr;
1272   if (dec->frame_nr != -1)
1273     dec->frame_nr++;
1274   GST_BUFFER_OFFSET_END (out) = dec->frame_nr;
1275
1276   GST_BUFFER_TIMESTAMP (out) = outtime;
1277   GST_BUFFER_DURATION (out) = outdur;
1278
1279   dec->processed++;
1280
1281   if (dec->segment.rate >= 0.0)
1282     result = theora_dec_push_forward (dec, out);
1283   else
1284     result = theora_dec_push_reverse (dec, out);
1285
1286   return result;
1287
1288   /* ERRORS */
1289 not_initialized:
1290   {
1291     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1292         (NULL), ("no header sent yet"));
1293     return GST_FLOW_ERROR;
1294   }
1295 dropping:
1296   {
1297     GST_WARNING_OBJECT (dec, "dropping frame because we need a keyframe");
1298     dec->discont = TRUE;
1299     return GST_FLOW_OK;
1300   }
1301 dropping_qos:
1302   {
1303     if (dec->frame_nr != -1)
1304       dec->frame_nr++;
1305     dec->discont = TRUE;
1306     GST_WARNING_OBJECT (dec, "dropping frame because of QoS");
1307     return GST_FLOW_OK;
1308   }
1309 decode_error:
1310   {
1311     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1312         (NULL), ("theora decoder did not decode data packet"));
1313     return GST_FLOW_ERROR;
1314   }
1315 no_yuv:
1316   {
1317     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1318         (NULL), ("couldn't read out YUV image"));
1319     return GST_FLOW_ERROR;
1320   }
1321 wrong_dimensions:
1322   {
1323     GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, FORMAT,
1324         (NULL), ("dimensions of image do not match header"));
1325     return GST_FLOW_ERROR;
1326   }
1327 }
1328
1329 static GstFlowReturn
1330 theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf)
1331 {
1332   ogg_packet packet;
1333   GstFlowReturn result = GST_FLOW_OK;
1334   GstClockTime timestamp, duration;
1335   gsize size;
1336
1337   /* make ogg_packet out of the buffer */
1338   packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
1339   packet.bytes = size;
1340   packet.granulepos = -1;
1341   packet.packetno = 0;          /* we don't really care */
1342   packet.b_o_s = dec->have_header ? 0 : 1;
1343   /* EOS does not matter for the decoder */
1344   packet.e_o_s = 0;
1345
1346   GST_LOG_OBJECT (dec, "decode buffer of size %ld", packet.bytes);
1347
1348   /* save last seem timestamp for interpolating the next timestamps using the
1349    * framerate when we need to */
1350   timestamp = GST_BUFFER_TIMESTAMP (buf);
1351   duration = GST_BUFFER_DURATION (buf);
1352
1353   GST_DEBUG_OBJECT (dec, "header=%02x, outtime=%" GST_TIME_FORMAT,
1354       packet.bytes ? packet.packet[0] : -1, GST_TIME_ARGS (timestamp));
1355
1356   /* switch depending on packet type. A zero byte packet is always a data
1357    * packet; we don't dereference it in that case. */
1358   if (packet.bytes && packet.packet[0] & 0x80) {
1359     if (dec->have_header) {
1360       GST_WARNING_OBJECT (GST_OBJECT (dec), "Ignoring header");
1361       goto done;
1362     }
1363     result = theora_handle_header_packet (dec, &packet);
1364   } else {
1365     result = theora_handle_data_packet (dec, &packet, timestamp, duration);
1366   }
1367 done:
1368   gst_buffer_unmap (buf, packet.packet, size);
1369
1370   return result;
1371 }
1372
1373 /* For reverse playback we use a technique that can be used for
1374  * any keyframe based video codec.
1375  *
1376  * Input:
1377  *  Buffer decoding order:  7  8  9  4  5  6  1  2  3  EOS
1378  *  Keyframe flag:                      K        K
1379  *  Discont flag:           D        D        D
1380  *
1381  * - Each Discont marks a discont in the decoding order.
1382  * - The keyframes mark where we can start decoding.
1383  *
1384  * First we prepend incomming buffers to the gather queue, whenever we receive
1385  * a discont, we flush out the gather queue.
1386  *
1387  * The above data will be accumulated in the gather queue like this:
1388  *
1389  *   gather queue:  9  8  7
1390  *                        D
1391  *
1392  * Whe buffer 4 is received (with a DISCONT), we flush the gather queue like
1393  * this:
1394  *
1395  *   while (gather)
1396  *     take head of queue and prepend to decode queue.
1397  *     if we copied a keyframe, decode the decode queue.
1398  *
1399  * After we flushed the gather queue, we add 4 to the (now empty) gather queue.
1400  * We get the following situation:
1401  *
1402  *  gather queue:    4
1403  *  decode queue:    7  8  9
1404  *
1405  * After we received 5 (Keyframe) and 6:
1406  *
1407  *  gather queue:    6  5  4
1408  *  decode queue:    7  8  9
1409  *
1410  * When we receive 1 (DISCONT) which triggers a flush of the gather queue:
1411  *
1412  *   Copy head of the gather queue (6) to decode queue:
1413  *
1414  *    gather queue:    5  4
1415  *    decode queue:    6  7  8  9
1416  *
1417  *   Copy head of the gather queue (5) to decode queue. This is a keyframe so we
1418  *   can start decoding.
1419  *
1420  *    gather queue:    4
1421  *    decode queue:    5  6  7  8  9
1422  *
1423  *   Decode frames in decode queue, store raw decoded data in output queue, we
1424  *   can take the head of the decode queue and prepend the decoded result in the
1425  *   output queue:
1426  *
1427  *    gather queue:    4
1428  *    decode queue:    
1429  *    output queue:    9  8  7  6  5
1430  *
1431  *   Now output all the frames in the output queue, picking a frame from the
1432  *   head of the queue.
1433  *
1434  *   Copy head of the gather queue (4) to decode queue, we flushed the gather
1435  *   queue and can now store input buffer in the gather queue:
1436  *
1437  *    gather queue:    1
1438  *    decode queue:    4
1439  *
1440  *  When we receive EOS, the queue looks like:
1441  *
1442  *    gather queue:    3  2  1
1443  *    decode queue:    4
1444  *
1445  *  Fill decode queue, first keyframe we copy is 2:
1446  *
1447  *    gather queue:    1
1448  *    decode queue:    2  3  4
1449  *
1450  *  Decoded output:
1451  *
1452  *    gather queue:    1
1453  *    decode queue:    
1454  *    output queue:    4  3  2
1455  *
1456  *  Leftover buffer 1 cannot be decoded and must be discarded.
1457  */
1458 static GstFlowReturn
1459 theora_dec_flush_decode (GstTheoraDec * dec)
1460 {
1461   GstFlowReturn res = GST_FLOW_OK;
1462
1463   while (dec->decode) {
1464     GstBuffer *buf = GST_BUFFER_CAST (dec->decode->data);
1465
1466     GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
1467         buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1468
1469     /* decode buffer, prepend to output queue */
1470     res = theora_dec_decode_buffer (dec, buf);
1471
1472     /* don't need it anymore now */
1473     gst_buffer_unref (buf);
1474
1475     dec->decode = g_list_delete_link (dec->decode, dec->decode);
1476   }
1477   while (dec->queued) {
1478     GstBuffer *buf = GST_BUFFER_CAST (dec->queued->data);
1479
1480     /* iterate ouput queue an push downstream */
1481     res = gst_pad_push (dec->srcpad, buf);
1482
1483     dec->queued = g_list_delete_link (dec->queued, dec->queued);
1484   }
1485
1486   return res;
1487 }
1488
1489 static GstFlowReturn
1490 theora_dec_chain_reverse (GstTheoraDec * dec, gboolean discont, GstBuffer * buf)
1491 {
1492   GstFlowReturn res = GST_FLOW_OK;
1493
1494   /* if we have a discont, move buffers to the decode list */
1495   if (G_UNLIKELY (discont)) {
1496     GST_DEBUG_OBJECT (dec, "received discont,gathering buffers");
1497     while (dec->gather) {
1498       GstBuffer *gbuf;
1499       guint8 data[1];
1500
1501       gbuf = GST_BUFFER_CAST (dec->gather->data);
1502       /* remove from the gather list */
1503       dec->gather = g_list_delete_link (dec->gather, dec->gather);
1504       /* copy to decode queue */
1505       dec->decode = g_list_prepend (dec->decode, gbuf);
1506
1507       /* if we copied a keyframe, flush and decode the decode queue */
1508       gst_buffer_extract (gbuf, 0, data, 1);
1509       if ((data[0] & 0x40) == 0) {
1510         GST_DEBUG_OBJECT (dec, "copied keyframe");
1511         res = theora_dec_flush_decode (dec);
1512       }
1513     }
1514   }
1515
1516   /* add buffer to gather queue */
1517   GST_DEBUG_OBJECT (dec, "gathering buffer %p, size %u", buf,
1518       gst_buffer_get_size (buf));
1519   dec->gather = g_list_prepend (dec->gather, buf);
1520
1521   return res;
1522 }
1523
1524 static GstFlowReturn
1525 theora_dec_chain_forward (GstTheoraDec * dec, gboolean discont,
1526     GstBuffer * buffer)
1527 {
1528   GstFlowReturn result;
1529
1530   result = theora_dec_decode_buffer (dec, buffer);
1531
1532   gst_buffer_unref (buffer);
1533
1534   return result;
1535 }
1536
1537 static GstFlowReturn
1538 theora_dec_chain (GstPad * pad, GstBuffer * buf)
1539 {
1540   GstTheoraDec *dec;
1541   GstFlowReturn res;
1542   gboolean discont;
1543
1544   dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
1545
1546   /* peel of DISCONT flag */
1547   discont = GST_BUFFER_IS_DISCONT (buf);
1548
1549   /* resync on DISCONT */
1550   if (G_UNLIKELY (discont)) {
1551     GST_DEBUG_OBJECT (dec, "received DISCONT buffer");
1552     dec->need_keyframe = TRUE;
1553     dec->last_timestamp = -1;
1554     dec->discont = TRUE;
1555   }
1556
1557   if (dec->segment.rate > 0.0)
1558     res = theora_dec_chain_forward (dec, discont, buf);
1559   else
1560     res = theora_dec_chain_reverse (dec, discont, buf);
1561
1562   gst_object_unref (dec);
1563
1564   return res;
1565 }
1566
1567 static GstStateChangeReturn
1568 theora_dec_change_state (GstElement * element, GstStateChange transition)
1569 {
1570   GstTheoraDec *dec = GST_THEORA_DEC (element);
1571   GstStateChangeReturn ret;
1572
1573   switch (transition) {
1574     case GST_STATE_CHANGE_NULL_TO_READY:
1575       break;
1576     case GST_STATE_CHANGE_READY_TO_PAUSED:
1577       th_info_clear (&dec->info);
1578       th_comment_clear (&dec->comment);
1579       GST_DEBUG_OBJECT (dec, "Setting have_header to FALSE in READY->PAUSED");
1580       dec->have_header = FALSE;
1581       dec->have_par = FALSE;
1582       gst_theora_dec_reset (dec);
1583       break;
1584     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1585       break;
1586     default:
1587       break;
1588   }
1589
1590   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1591
1592   switch (transition) {
1593     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1594       break;
1595     case GST_STATE_CHANGE_PAUSED_TO_READY:
1596       th_info_clear (&dec->info);
1597       th_comment_clear (&dec->comment);
1598       th_setup_free (dec->setup);
1599       dec->setup = NULL;
1600       th_decode_free (dec->decoder);
1601       dec->decoder = NULL;
1602       gst_theora_dec_reset (dec);
1603       if (dec->pool) {
1604         gst_buffer_pool_set_active (dec->pool, FALSE);
1605         gst_object_unref (dec->pool);
1606         dec->pool = NULL;
1607       }
1608       break;
1609     case GST_STATE_CHANGE_READY_TO_NULL:
1610       break;
1611     default:
1612       break;
1613   }
1614
1615   return ret;
1616 }
1617
1618 static void
1619 theora_dec_set_property (GObject * object, guint prop_id,
1620     const GValue * value, GParamSpec * pspec)
1621 {
1622   GstTheoraDec *dec = GST_THEORA_DEC (object);
1623
1624   switch (prop_id) {
1625     case PROP_CROP:
1626       dec->crop = g_value_get_boolean (value);
1627       break;
1628     case PROP_TELEMETRY_MV:
1629       dec->telemetry_mv = g_value_get_int (value);
1630       break;
1631     case PROP_TELEMETRY_MBMODE:
1632       dec->telemetry_mbmode = g_value_get_int (value);
1633       break;
1634     case PROP_TELEMETRY_QI:
1635       dec->telemetry_qi = g_value_get_int (value);
1636       break;
1637     case PROP_TELEMETRY_BITS:
1638       dec->telemetry_bits = g_value_get_int (value);
1639       break;
1640     default:
1641       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1642       break;
1643   }
1644 }
1645
1646 static void
1647 theora_dec_get_property (GObject * object, guint prop_id,
1648     GValue * value, GParamSpec * pspec)
1649 {
1650   GstTheoraDec *dec = GST_THEORA_DEC (object);
1651
1652   switch (prop_id) {
1653     case PROP_CROP:
1654       g_value_set_boolean (value, dec->crop);
1655       break;
1656     case PROP_TELEMETRY_MV:
1657       g_value_set_int (value, dec->telemetry_mv);
1658       break;
1659     case PROP_TELEMETRY_MBMODE:
1660       g_value_set_int (value, dec->telemetry_mbmode);
1661       break;
1662     case PROP_TELEMETRY_QI:
1663       g_value_set_int (value, dec->telemetry_qi);
1664       break;
1665     case PROP_TELEMETRY_BITS:
1666       g_value_set_int (value, dec->telemetry_bits);
1667       break;
1668     default:
1669       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1670       break;
1671   }
1672 }