2 * Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
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.
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.
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.
21 * SECTION:element-theoradec
22 * @see_also: theoraenc, oggdemux
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.
30 * <title>Example pipeline</title>
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.
37 * Last reviewed on 2006-03-01 (0.10.4)
44 #include "gsttheoradec.h"
45 #include <gst/tag/tag.h>
46 #include <gst/video/video.h>
48 #define GST_CAT_DEFAULT theoradec_debug
49 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
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
62 PROP_TELEMETRY_MBMODE,
67 static GstStaticPadTemplate theora_dec_src_factory =
68 GST_STATIC_PAD_TEMPLATE ("src",
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 ]")
77 static GstStaticPadTemplate theora_dec_sink_factory =
78 GST_STATIC_PAD_TEMPLATE ("sink",
81 GST_STATIC_CAPS ("video/x-theora")
84 #define gst_theora_dec_parent_class parent_class
85 G_DEFINE_TYPE (GstTheoraDec, gst_theora_dec, GST_TYPE_ELEMENT);
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);
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);
104 static const GstFormat *theora_get_formats (GstPad * pad);
107 static const GstEventMask *theora_get_event_masks (GstPad * pad);
109 static const GstQueryType *theora_get_query_types (GstPad * pad);
112 gst_theora_dec_ctl_is_supported (int req)
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);
119 gst_theora_dec_class_init (GstTheoraDecClass * klass)
121 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
122 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
124 gobject_class->set_property = theora_dec_set_property;
125 gobject_class->get_property = theora_dec_get_property;
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));
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));
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));
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));
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));
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>");
185 gstelement_class->change_state = theora_dec_change_state;
187 GST_DEBUG_CATEGORY_INIT (theoradec_debug, "theoradec", 0, "Theora decoder");
191 gst_theora_dec_init (GstTheoraDec * dec)
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);
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);
206 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
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;
216 dec->pendingevents = NULL;
220 gst_theora_dec_reset (GstTheoraDec * dec)
222 dec->need_keyframe = TRUE;
223 dec->last_timestamp = -1;
226 dec->seqnum = gst_util_seqnum_next ();
229 gst_segment_init (&dec->segment, GST_FORMAT_TIME);
231 GST_OBJECT_LOCK (dec);
232 dec->proportion = 1.0;
233 dec->earliest_time = -1;
234 GST_OBJECT_UNLOCK (dec);
236 g_list_foreach (dec->queued, (GFunc) gst_mini_object_unref, NULL);
237 g_list_free (dec->queued);
239 g_list_foreach (dec->gather, (GFunc) gst_mini_object_unref, NULL);
240 g_list_free (dec->gather);
242 g_list_foreach (dec->decode, (GFunc) gst_mini_object_unref, NULL);
243 g_list_free (dec->decode);
245 g_list_foreach (dec->pendingevents, (GFunc) gst_mini_object_unref, NULL);
246 g_list_free (dec->pendingevents);
247 dec->pendingevents = NULL;
250 gst_tag_list_free (dec->tags);
256 static const GstFormat *
257 theora_get_formats (GstPad * pad)
259 static GstFormat src_formats[] = {
260 GST_FORMAT_DEFAULT, /* frames in this case */
265 static GstFormat sink_formats[] = {
271 return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
276 static const GstEventMask *
277 theora_get_event_masks (GstPad * pad)
279 static const GstEventMask theora_src_event_masks[] = {
280 {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
284 return theora_src_event_masks;
288 static const GstQueryType *
289 theora_get_query_types (GstPad * pad)
291 static const GstQueryType theora_src_query_types[] = {
298 return theora_src_query_types;
303 theora_dec_src_convert (GstPad * pad,
304 GstFormat src_format, gint64 src_value,
305 GstFormat * dest_format, gint64 * dest_value)
311 if (src_format == *dest_format) {
312 *dest_value = src_value;
316 dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
318 /* we need the info part before we can done something */
319 if (!dec->have_header)
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);
329 case GST_FORMAT_TIME:
330 /* seems like a rather silly conversion, implement me if you like */
335 case GST_FORMAT_TIME:
336 switch (*dest_format) {
337 case GST_FORMAT_BYTES:
339 dec->output_bpp * (dec->info.pic_width * dec->info.pic_height) /
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);
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);
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);
367 gst_object_unref (dec);
373 GST_DEBUG_OBJECT (dec, "no header yet, cannot convert");
381 theora_dec_sink_convert (GstPad * pad,
382 GstFormat src_format, gint64 src_value,
383 GstFormat * dest_format, gint64 * dest_value)
388 if (src_format == *dest_format) {
389 *dest_value = src_value;
393 dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
395 /* we need the info part before we can done something */
396 if (!dec->have_header)
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);
409 case GST_FORMAT_TIME:
410 switch (*dest_format) {
411 case GST_FORMAT_DEFAULT:
416 *dest_value = gst_util_uint64_scale (src_value,
417 dec->info.fps_numerator, GST_SECOND * dec->info.fps_denominator);
419 /* funny way of calculating granulepos in theora */
420 rest = *dest_value / dec->info.keyframe_granule_shift;
422 *dest_value <<= dec->granule_shift;
435 gst_object_unref (dec);
441 GST_DEBUG_OBJECT (dec, "no header yet, cannot convert");
449 theora_dec_src_query (GstPad * pad, GstQuery * query)
453 gboolean res = FALSE;
455 dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
457 switch (GST_QUERY_TYPE (query)) {
458 case GST_QUERY_POSITION:
465 gst_query_parse_position (query, &format, NULL);
467 time = dec->last_timestamp;
468 time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time);
471 "query %p: our time: %" GST_TIME_FORMAT, query, GST_TIME_ARGS (time));
474 theora_dec_src_convert (pad, GST_FORMAT_TIME, time, &format,
478 gst_query_set_position (query, format, value);
481 "query %p: we return %" G_GINT64_FORMAT " (format %u)", query, value,
485 case GST_QUERY_DURATION:
487 /* forward to peer for total */
488 res = gst_pad_peer_query (dec->sinkpad, query);
494 case GST_QUERY_CONVERT:
496 GstFormat src_fmt, dest_fmt;
497 gint64 src_val, dest_val;
499 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
501 theora_dec_src_convert (pad, src_fmt, src_val, &dest_fmt,
505 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
509 res = gst_pad_query_default (pad, query);
513 gst_object_unref (dec);
520 GST_DEBUG_OBJECT (dec, "query failed");
526 theora_dec_src_event (GstPad * pad, GstEvent * event)
531 dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
533 switch (GST_EVENT_TYPE (event)) {
536 GstFormat format, tformat;
540 GstSeekType cur_type, stop_type;
545 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
547 seqnum = gst_event_get_seqnum (event);
548 gst_event_unref (event);
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.
554 * First bring the requested format to time
556 tformat = GST_FORMAT_TIME;
557 if (!(res = theora_dec_src_convert (pad, format, cur, &tformat, &tcur)))
559 if (!(res = theora_dec_src_convert (pad, format, stop, &tformat, &tstop)))
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);
567 res = gst_pad_push_event (dec->sinkpad, real_seek);
573 GstClockTimeDiff diff;
574 GstClockTime timestamp;
576 gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
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);
587 GST_DEBUG_OBJECT (dec, "got QoS %" GST_TIME_FORMAT ", %" G_GINT64_FORMAT,
588 GST_TIME_ARGS (timestamp), diff);
590 res = gst_pad_push_event (dec->sinkpad, event);
594 res = gst_pad_push_event (dec->sinkpad, event);
598 gst_object_unref (dec);
605 GST_DEBUG_OBJECT (dec, "could not convert format");
611 theora_dec_sink_event (GstPad * pad, GstEvent * event)
613 gboolean ret = FALSE;
616 dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
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);
623 case GST_EVENT_FLUSH_STOP:
624 gst_theora_dec_reset (dec);
625 ret = gst_pad_push_event (dec->srcpad, event);
628 ret = gst_pad_push_event (dec->srcpad, event);
630 case GST_EVENT_SEGMENT:
632 const GstSegment *segment;
634 gst_event_parse_segment (event, &segment);
636 /* we need TIME format */
637 if (segment->format != GST_FORMAT_TIME)
638 goto newseg_wrong_format;
640 GST_DEBUG_OBJECT (dec, "segment: %" GST_SEGMENT_FORMAT, segment);
642 /* now configure the values */
643 gst_segment_copy_into (segment, &dec->segment);
644 dec->seqnum = gst_event_get_seqnum (event);
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);
650 dec->pendingevents = g_list_append (dec->pendingevents, event);
659 gst_event_parse_caps (event, &caps);
660 ret = theora_dec_setcaps (dec, caps);
661 gst_event_unref (event);
666 if (dec->have_header)
668 ret = gst_pad_push_event (dec->srcpad, event);
670 /* store it to send once we're initialized */
671 dec->pendingevents = g_list_append (dec->pendingevents, event);
677 ret = gst_pad_event_default (pad, event);
681 gst_object_unref (dec);
688 GST_DEBUG_OBJECT (dec, "received non TIME newsegment");
689 gst_event_unref (event);
695 theora_dec_setcaps (GstTheoraDec * dec, GstCaps * caps)
698 const GValue *codec_data;
700 s = gst_caps_get_structure (caps, 0);
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);
706 if ((codec_data = gst_structure_get_value (s, "codec_data"))) {
707 if (G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) {
713 buffer = gst_value_get_buffer (codec_data);
716 data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
725 psize = (ptr[0] << 8) | ptr[1];
731 /* make sure we don't read too much */
732 psize = MIN (psize, left);
735 gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, psize);
737 /* first buffer is a discont buffer */
739 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
741 /* now feed it to the decoder we can ignore the error */
742 theora_dec_chain (dec->sinkpad, buf);
749 gst_buffer_unmap (buffer, data, size);
757 theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet)
759 gchar *encoder = NULL;
762 GST_DEBUG_OBJECT (dec, "parsing comment packet");
765 gst_tag_list_from_vorbiscomment (packet->packet, packet->bytes,
766 (guint8 *) "\201theora", 7, &encoder);
769 GST_ERROR_OBJECT (dec, "couldn't decode comments");
770 list = gst_tag_list_new ();
773 gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
774 GST_TAG_ENCODER, encoder, NULL);
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);
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);
793 theora_negotiate_pool (GstTheoraDec * dec, GstCaps * caps)
796 GstBufferPool *pool = NULL;
797 guint size, min, max, prefix, alignment;
799 /* find a pool for the negotiated caps now */
800 query = gst_query_new_allocation (caps, TRUE);
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,
808 GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints");
809 size = gst_video_format_get_size (dec->format, dec->width, dec->height);
816 GstStructure *config;
818 /* we did not get a pool, make one ourselves then */
819 pool = gst_buffer_pool_new ();
821 config = gst_buffer_pool_get_config (pool);
822 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
824 gst_buffer_pool_set_config (pool, config);
828 gst_object_unref (dec->pool);
831 /* FIXME, we can check if downstream supports clipping and/or video
835 gst_buffer_pool_set_active (pool, TRUE);
841 theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
844 gint par_num, par_den;
845 GstFlowReturn ret = GST_FLOW_OK;
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);
854 * the info.aspect_* values reflect PAR;
855 * 0:x and x:0 are allowed and can be interpreted as 1:1.
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;
863 /* take encoded par */
864 par_num = dec->info.aspect_numerator;
865 par_den = dec->info.aspect_denominator;
867 if (par_num == 0 || par_den == 0) {
868 par_num = par_den = 1;
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
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);
882 switch (dec->info.pixel_fmt) {
884 dec->output_bpp = 24;
885 dec->format = GST_VIDEO_FORMAT_Y444;
886 fourcc = GST_MAKE_FOURCC ('Y', '4', '4', '4');
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');
894 dec->output_bpp = 16;
895 dec->format = GST_VIDEO_FORMAT_Y42B;
896 fourcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
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) {
914 if (dec->offset_y & 1 && dec->info.pixel_fmt == TH_PF_420) {
919 /* no cropping, use the encoded dimensions */
920 dec->width = dec->info.frame_width;
921 dec->height = dec->info.frame_height;
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);
930 dec->decoder = th_decode_alloc (&dec->info, dec->setup);
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");
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");
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");
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");
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);
960 /* negotiate a bufferpool */
961 if ((ret = theora_negotiate_pool (dec, caps)) != GST_FLOW_OK)
964 dec->have_header = TRUE;
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;
974 gst_element_found_tags_for_pad (GST_ELEMENT_CAST (dec), dec->srcpad,
984 GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt);
985 return GST_FLOW_ERROR;
994 theora_handle_header_packet (GstTheoraDec * dec, ogg_packet * packet)
999 GST_DEBUG_OBJECT (dec, "parsing header packet");
1001 ret = th_decode_headerin (&dec->info, &dec->comment, &dec->setup, packet);
1003 goto header_read_error;
1005 switch (packet->packet[0]) {
1007 res = theora_handle_comment_packet (dec, packet);
1010 res = theora_handle_type_packet (dec, packet);
1014 g_warning ("unknown theora header packet found");
1016 /* nothing special, this is the identification header */
1025 GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1026 (NULL), ("couldn't read header packet"));
1027 return GST_FLOW_ERROR;
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 */
1034 clip_buffer (GstTheoraDec * dec, GstBuffer * buf)
1036 gboolean res = TRUE;
1037 GstClockTime in_ts, in_dur, stop;
1038 guint64 cstart, cstop;
1040 in_ts = GST_BUFFER_TIMESTAMP (buf);
1041 in_dur = GST_BUFFER_DURATION (buf);
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));
1047 /* can't clip without TIME segment */
1048 if (dec->segment.format != GST_FORMAT_TIME)
1051 /* we need a start time */
1052 if (!GST_CLOCK_TIME_IS_VALID (in_ts))
1055 /* generate valid stop, if duration unknown, we have unknown stop */
1057 GST_CLOCK_TIME_IS_VALID (in_dur) ? (in_ts + in_dur) : GST_CLOCK_TIME_NONE;
1060 if (!(res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1061 in_ts, stop, &cstart, &cstop)))
1064 /* update timestamp and possibly duration if the clipped stop time is
1066 GST_BUFFER_TIMESTAMP (buf) = cstart;
1067 if (GST_CLOCK_TIME_IS_VALID (cstop))
1068 GST_BUFFER_DURATION (buf) = cstop - cstart;
1071 GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : ""));
1075 static GstFlowReturn
1076 theora_dec_push_forward (GstTheoraDec * dec, GstBuffer * buf)
1078 GstFlowReturn result = GST_FLOW_OK;
1080 if (clip_buffer (dec, buf)) {
1082 GST_LOG_OBJECT (dec, "setting DISCONT");
1083 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
1084 dec->discont = FALSE;
1086 result = gst_pad_push (dec->srcpad, buf);
1088 gst_buffer_unref (buf);
1094 static GstFlowReturn
1095 theora_dec_push_reverse (GstTheoraDec * dec, GstBuffer * buf)
1097 GstFlowReturn result = GST_FLOW_OK;
1099 dec->queued = g_list_prepend (dec->queued, buf);
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)
1108 gint width, height, stride;
1109 GstFlowReturn result;
1115 if (gst_pad_check_reconfigure (dec->srcpad)) {
1118 caps = gst_pad_get_current_caps (dec->srcpad);
1119 theora_negotiate_pool (dec, caps);
1120 gst_caps_unref (caps);
1123 result = gst_buffer_pool_acquire_buffer (dec->pool, out, NULL);
1124 if (G_UNLIKELY (result != GST_FLOW_OK))
1127 data = gst_buffer_map (*out, &size, NULL, GST_MAP_WRITE);
1129 /* FIXME, we can do things slightly more efficient when we know that
1130 * downstream understands clipping and video metadata */
1132 for (plane = 0; plane < 3; plane++) {
1134 gst_video_format_get_component_width (dec->format, plane, dec->width);
1136 gst_video_format_get_component_height (dec->format, plane, dec->height);
1137 stride = gst_video_format_get_row_stride (dec->format, plane, dec->width);
1139 dest = data + gst_video_format_get_component_offset (dec->format,
1140 plane, dec->width, dec->height);
1141 src = buf[plane].data;
1142 src += ((height == dec->height) ? dec->offset_y : dec->offset_y / 2)
1143 * buf[plane].stride;
1144 src += (width == dec->width) ? dec->offset_x : dec->offset_x / 2;
1146 for (i = 0; i < height; i++) {
1147 memcpy (dest, src, width);
1150 src += buf[plane].stride;
1153 gst_buffer_unmap (*out, data, size);
1160 GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s",
1161 gst_flow_get_name (result));
1166 static GstFlowReturn
1167 theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
1168 GstClockTime outtime, GstClockTime outdur)
1170 /* normal data packet */
1171 th_ycbcr_buffer buf;
1174 GstFlowReturn result;
1177 if (G_UNLIKELY (!dec->have_header))
1178 goto not_initialized;
1180 /* get timestamp and durations */
1182 outtime = dec->last_timestamp;
1184 outdur = gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator,
1185 dec->info.fps_numerator);
1187 /* calculate expected next timestamp */
1188 if (outtime != -1 && outdur != -1)
1189 dec->last_timestamp = outtime + outdur;
1191 /* the second most significant bit of the first data byte is cleared
1192 * for keyframes. We can only check it if it's not a zero-length packet. */
1193 keyframe = packet->bytes && ((packet->packet[0] & 0x40) == 0);
1194 if (G_UNLIKELY (keyframe)) {
1195 GST_DEBUG_OBJECT (dec, "we have a keyframe");
1196 dec->need_keyframe = FALSE;
1197 } else if (G_UNLIKELY (dec->need_keyframe)) {
1201 GST_DEBUG_OBJECT (dec, "parsing data packet");
1203 /* this does the decoding */
1204 if (G_UNLIKELY (th_decode_packetin (dec->decoder, packet, &gp) < 0))
1207 if (outtime != -1) {
1209 GstClockTime running_time;
1210 GstClockTime earliest_time;
1213 /* qos needs to be done on running time */
1214 running_time = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1217 GST_OBJECT_LOCK (dec);
1218 proportion = dec->proportion;
1219 earliest_time = dec->earliest_time;
1220 /* check for QoS, don't perform the last steps of getting and
1221 * pushing the buffers that are known to be late. */
1222 need_skip = earliest_time != -1 && running_time <= earliest_time;
1223 GST_OBJECT_UNLOCK (dec);
1226 GstMessage *qos_msg;
1227 guint64 stream_time;
1230 GST_DEBUG_OBJECT (dec, "skipping decoding: qostime %"
1231 GST_TIME_FORMAT " <= %" GST_TIME_FORMAT,
1232 GST_TIME_ARGS (running_time), GST_TIME_ARGS (earliest_time));
1237 gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, outtime);
1238 jitter = GST_CLOCK_DIFF (running_time, earliest_time);
1241 gst_message_new_qos (GST_OBJECT_CAST (dec), FALSE, running_time,
1242 stream_time, outtime, outdur);
1243 gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
1244 gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
1245 dec->processed, dec->dropped);
1246 gst_element_post_message (GST_ELEMENT_CAST (dec), qos_msg);
1252 /* this does postprocessing and set up the decoded frame
1253 * pointers in our yuv variable */
1254 if (G_UNLIKELY (th_decode_ycbcr_out (dec->decoder, buf) < 0))
1257 if (G_UNLIKELY ((buf[0].width != dec->info.frame_width)
1258 || (buf[0].height != dec->info.frame_height)))
1259 goto wrong_dimensions;
1261 result = theora_handle_image (dec, buf, &out);
1262 if (result != GST_FLOW_OK)
1265 GST_BUFFER_OFFSET (out) = dec->frame_nr;
1266 if (dec->frame_nr != -1)
1268 GST_BUFFER_OFFSET_END (out) = dec->frame_nr;
1270 GST_BUFFER_TIMESTAMP (out) = outtime;
1271 GST_BUFFER_DURATION (out) = outdur;
1275 if (dec->segment.rate >= 0.0)
1276 result = theora_dec_push_forward (dec, out);
1278 result = theora_dec_push_reverse (dec, out);
1285 GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1286 (NULL), ("no header sent yet"));
1287 return GST_FLOW_ERROR;
1291 GST_WARNING_OBJECT (dec, "dropping frame because we need a keyframe");
1292 dec->discont = TRUE;
1297 if (dec->frame_nr != -1)
1299 dec->discont = TRUE;
1300 GST_WARNING_OBJECT (dec, "dropping frame because of QoS");
1305 GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1306 (NULL), ("theora decoder did not decode data packet"));
1307 return GST_FLOW_ERROR;
1311 GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
1312 (NULL), ("couldn't read out YUV image"));
1313 return GST_FLOW_ERROR;
1317 GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, FORMAT,
1318 (NULL), ("dimensions of image do not match header"));
1319 return GST_FLOW_ERROR;
1323 static GstFlowReturn
1324 theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf)
1327 GstFlowReturn result = GST_FLOW_OK;
1328 GstClockTime timestamp, duration;
1331 /* make ogg_packet out of the buffer */
1332 packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
1333 packet.bytes = size;
1334 packet.granulepos = -1;
1335 packet.packetno = 0; /* we don't really care */
1336 packet.b_o_s = dec->have_header ? 0 : 1;
1337 /* EOS does not matter for the decoder */
1340 GST_LOG_OBJECT (dec, "decode buffer of size %ld", packet.bytes);
1342 /* save last seem timestamp for interpolating the next timestamps using the
1343 * framerate when we need to */
1344 timestamp = GST_BUFFER_TIMESTAMP (buf);
1345 duration = GST_BUFFER_DURATION (buf);
1347 GST_DEBUG_OBJECT (dec, "header=%02x, outtime=%" GST_TIME_FORMAT,
1348 packet.bytes ? packet.packet[0] : -1, GST_TIME_ARGS (timestamp));
1350 /* switch depending on packet type. A zero byte packet is always a data
1351 * packet; we don't dereference it in that case. */
1352 if (packet.bytes && packet.packet[0] & 0x80) {
1353 if (dec->have_header) {
1354 GST_WARNING_OBJECT (GST_OBJECT (dec), "Ignoring header");
1357 result = theora_handle_header_packet (dec, &packet);
1359 result = theora_handle_data_packet (dec, &packet, timestamp, duration);
1362 gst_buffer_unmap (buf, packet.packet, size);
1367 /* For reverse playback we use a technique that can be used for
1368 * any keyframe based video codec.
1371 * Buffer decoding order: 7 8 9 4 5 6 1 2 3 EOS
1372 * Keyframe flag: K K
1373 * Discont flag: D D D
1375 * - Each Discont marks a discont in the decoding order.
1376 * - The keyframes mark where we can start decoding.
1378 * First we prepend incomming buffers to the gather queue, whenever we receive
1379 * a discont, we flush out the gather queue.
1381 * The above data will be accumulated in the gather queue like this:
1383 * gather queue: 9 8 7
1386 * Whe buffer 4 is received (with a DISCONT), we flush the gather queue like
1390 * take head of queue and prepend to decode queue.
1391 * if we copied a keyframe, decode the decode queue.
1393 * After we flushed the gather queue, we add 4 to the (now empty) gather queue.
1394 * We get the following situation:
1397 * decode queue: 7 8 9
1399 * After we received 5 (Keyframe) and 6:
1401 * gather queue: 6 5 4
1402 * decode queue: 7 8 9
1404 * When we receive 1 (DISCONT) which triggers a flush of the gather queue:
1406 * Copy head of the gather queue (6) to decode queue:
1409 * decode queue: 6 7 8 9
1411 * Copy head of the gather queue (5) to decode queue. This is a keyframe so we
1412 * can start decoding.
1415 * decode queue: 5 6 7 8 9
1417 * Decode frames in decode queue, store raw decoded data in output queue, we
1418 * can take the head of the decode queue and prepend the decoded result in the
1423 * output queue: 9 8 7 6 5
1425 * Now output all the frames in the output queue, picking a frame from the
1426 * head of the queue.
1428 * Copy head of the gather queue (4) to decode queue, we flushed the gather
1429 * queue and can now store input buffer in the gather queue:
1434 * When we receive EOS, the queue looks like:
1436 * gather queue: 3 2 1
1439 * Fill decode queue, first keyframe we copy is 2:
1442 * decode queue: 2 3 4
1448 * output queue: 4 3 2
1450 * Leftover buffer 1 cannot be decoded and must be discarded.
1452 static GstFlowReturn
1453 theora_dec_flush_decode (GstTheoraDec * dec)
1455 GstFlowReturn res = GST_FLOW_OK;
1457 while (dec->decode) {
1458 GstBuffer *buf = GST_BUFFER_CAST (dec->decode->data);
1460 GST_DEBUG_OBJECT (dec, "decoding buffer %p, ts %" GST_TIME_FORMAT,
1461 buf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1463 /* decode buffer, prepend to output queue */
1464 res = theora_dec_decode_buffer (dec, buf);
1466 /* don't need it anymore now */
1467 gst_buffer_unref (buf);
1469 dec->decode = g_list_delete_link (dec->decode, dec->decode);
1471 while (dec->queued) {
1472 GstBuffer *buf = GST_BUFFER_CAST (dec->queued->data);
1474 /* iterate ouput queue an push downstream */
1475 res = gst_pad_push (dec->srcpad, buf);
1477 dec->queued = g_list_delete_link (dec->queued, dec->queued);
1483 static GstFlowReturn
1484 theora_dec_chain_reverse (GstTheoraDec * dec, gboolean discont, GstBuffer * buf)
1486 GstFlowReturn res = GST_FLOW_OK;
1488 /* if we have a discont, move buffers to the decode list */
1489 if (G_UNLIKELY (discont)) {
1490 GST_DEBUG_OBJECT (dec, "received discont,gathering buffers");
1491 while (dec->gather) {
1495 gbuf = GST_BUFFER_CAST (dec->gather->data);
1496 /* remove from the gather list */
1497 dec->gather = g_list_delete_link (dec->gather, dec->gather);
1498 /* copy to decode queue */
1499 dec->decode = g_list_prepend (dec->decode, gbuf);
1501 /* if we copied a keyframe, flush and decode the decode queue */
1502 gst_buffer_extract (gbuf, 0, data, 1);
1503 if ((data[0] & 0x40) == 0) {
1504 GST_DEBUG_OBJECT (dec, "copied keyframe");
1505 res = theora_dec_flush_decode (dec);
1510 /* add buffer to gather queue */
1511 GST_DEBUG_OBJECT (dec, "gathering buffer %p, size %u", buf,
1512 gst_buffer_get_size (buf));
1513 dec->gather = g_list_prepend (dec->gather, buf);
1518 static GstFlowReturn
1519 theora_dec_chain_forward (GstTheoraDec * dec, gboolean discont,
1522 GstFlowReturn result;
1524 result = theora_dec_decode_buffer (dec, buffer);
1526 gst_buffer_unref (buffer);
1531 static GstFlowReturn
1532 theora_dec_chain (GstPad * pad, GstBuffer * buf)
1538 dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
1540 /* peel of DISCONT flag */
1541 discont = GST_BUFFER_IS_DISCONT (buf);
1543 /* resync on DISCONT */
1544 if (G_UNLIKELY (discont)) {
1545 GST_DEBUG_OBJECT (dec, "received DISCONT buffer");
1546 dec->need_keyframe = TRUE;
1547 dec->last_timestamp = -1;
1548 dec->discont = TRUE;
1551 if (dec->segment.rate > 0.0)
1552 res = theora_dec_chain_forward (dec, discont, buf);
1554 res = theora_dec_chain_reverse (dec, discont, buf);
1556 gst_object_unref (dec);
1561 static GstStateChangeReturn
1562 theora_dec_change_state (GstElement * element, GstStateChange transition)
1564 GstTheoraDec *dec = GST_THEORA_DEC (element);
1565 GstStateChangeReturn ret;
1567 switch (transition) {
1568 case GST_STATE_CHANGE_NULL_TO_READY:
1570 case GST_STATE_CHANGE_READY_TO_PAUSED:
1571 th_info_clear (&dec->info);
1572 th_comment_clear (&dec->comment);
1573 GST_DEBUG_OBJECT (dec, "Setting have_header to FALSE in READY->PAUSED");
1574 dec->have_header = FALSE;
1575 dec->have_par = FALSE;
1576 gst_theora_dec_reset (dec);
1578 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1584 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1586 switch (transition) {
1587 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1589 case GST_STATE_CHANGE_PAUSED_TO_READY:
1590 th_info_clear (&dec->info);
1591 th_comment_clear (&dec->comment);
1592 th_setup_free (dec->setup);
1594 th_decode_free (dec->decoder);
1595 dec->decoder = NULL;
1596 gst_theora_dec_reset (dec);
1598 gst_buffer_pool_set_active (dec->pool, FALSE);
1599 gst_object_unref (dec->pool);
1603 case GST_STATE_CHANGE_READY_TO_NULL:
1613 theora_dec_set_property (GObject * object, guint prop_id,
1614 const GValue * value, GParamSpec * pspec)
1616 GstTheoraDec *dec = GST_THEORA_DEC (object);
1620 dec->crop = g_value_get_boolean (value);
1622 case PROP_TELEMETRY_MV:
1623 dec->telemetry_mv = g_value_get_int (value);
1625 case PROP_TELEMETRY_MBMODE:
1626 dec->telemetry_mbmode = g_value_get_int (value);
1628 case PROP_TELEMETRY_QI:
1629 dec->telemetry_qi = g_value_get_int (value);
1631 case PROP_TELEMETRY_BITS:
1632 dec->telemetry_bits = g_value_get_int (value);
1635 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1641 theora_dec_get_property (GObject * object, guint prop_id,
1642 GValue * value, GParamSpec * pspec)
1644 GstTheoraDec *dec = GST_THEORA_DEC (object);
1648 g_value_set_boolean (value, dec->crop);
1650 case PROP_TELEMETRY_MV:
1651 g_value_set_int (value, dec->telemetry_mv);
1653 case PROP_TELEMETRY_MBMODE:
1654 g_value_set_int (value, dec->telemetry_mbmode);
1656 case PROP_TELEMETRY_QI:
1657 g_value_set_int (value, dec->telemetry_qi);
1659 case PROP_TELEMETRY_BITS:
1660 g_value_set_int (value, dec->telemetry_bits);
1663 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);