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