"TheoraDec",
"Codec/Decoder/Video",
"decode raw theora streams to raw YUV video",
- "Benjamin Otte <in7y118@public.uni-hamburg.de>",
+ "Benjamin Otte <in7y118@public.uni-hamburg.de>, "
+ "Wim Taymans <wim@fluendo.com>",
};
static GstStaticPadTemplate theora_dec_src_factory =
static gboolean theora_dec_src_event (GstPad * pad, GstEvent * event);
static gboolean theora_dec_src_query (GstPad * pad,
GstQueryType query, GstFormat * format, gint64 * value);
+static gboolean theora_dec_src_convert (GstPad * pad,
+ GstFormat src_format, gint64 src_value,
+ GstFormat * dest_format, gint64 * dest_value);
+static gboolean theora_dec_sink_convert (GstPad * pad,
+ GstFormat src_format, gint64 src_value,
+ GstFormat * dest_format, gint64 * dest_value);
+static const GstFormat *theora_get_formats (GstPad * pad);
+static const GstEventMask *theora_get_event_masks (GstPad * pad);
+static const GstQueryType *theora_get_query_types (GstPad * pad);
static void
dec->sinkpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&theora_dec_sink_factory), "sink");
+ gst_pad_set_formats_function (dec->sinkpad, theora_get_formats);
+ gst_pad_set_convert_function (dec->sinkpad, theora_dec_sink_convert);
gst_pad_set_chain_function (dec->sinkpad, theora_dec_chain);
gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
gst_pad_new_from_template (gst_static_pad_template_get
(&theora_dec_src_factory), "src");
gst_pad_use_explicit_caps (dec->srcpad);
+ gst_pad_set_event_mask_function (dec->srcpad, theora_get_event_masks);
gst_pad_set_event_function (dec->srcpad, theora_dec_src_event);
+ gst_pad_set_query_type_function (dec->srcpad, theora_get_query_types);
gst_pad_set_query_function (dec->srcpad, theora_dec_src_query);
+ gst_pad_set_formats_function (dec->srcpad, theora_get_formats);
+ gst_pad_set_convert_function (dec->srcpad, theora_dec_src_convert);
+
gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
GST_FLAG_SET (dec, GST_ELEMENT_EVENT_AWARE);
return (ret);
}
+static const GstFormat *
+theora_get_formats (GstPad * pad)
+{
+ static GstFormat src_formats[] = {
+ GST_FORMAT_DEFAULT, /* frames in this case */
+ GST_FORMAT_TIME,
+ GST_FORMAT_BYTES,
+ 0
+ };
+ static GstFormat sink_formats[] = {
+ GST_FORMAT_DEFAULT,
+ GST_FORMAT_TIME,
+ 0
+ };
+
+ return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
+}
+
+static const GstEventMask *
+theora_get_event_masks (GstPad * pad)
+{
+ static const GstEventMask theora_src_event_masks[] = {
+ {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
+ {0,}
+ };
+
+ return theora_src_event_masks;
+}
+
+static const GstQueryType *
+theora_get_query_types (GstPad * pad)
+{
+ static const GstQueryType theora_src_query_types[] = {
+ GST_QUERY_TOTAL,
+ GST_QUERY_POSITION,
+ 0
+ };
+
+ return theora_src_query_types;
+}
+
+
static gboolean
-theora_dec_from_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from,
- guint64 * to)
+theora_dec_src_convert (GstPad * pad,
+ GstFormat src_format, gint64 src_value,
+ GstFormat * dest_format, gint64 * dest_value)
{
- guint64 framecount;
- guint ilog = _theora_ilog (dec->info.keyframe_frequency_force - 1);
+ gboolean res = TRUE;
+ GstTheoraDec *dec;
+ guint64 scale = 1;
+
+ dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
+ /* we need the info part before we can done something */
if (dec->packetno < 1)
return FALSE;
- /* granulepos is last ilog bits for counting pframes since last iframe and
- * bits in front of that for the framenumber of the last iframe. */
- framecount = from >> ilog;
- framecount += from - (framecount << ilog);
-
- switch (format) {
+ switch (src_format) {
+ case GST_FORMAT_BYTES:
+ switch (*dest_format) {
+ case GST_FORMAT_DEFAULT:
+ *dest_value =
+ src_value * 2 / (dec->info.height * dec->info.width * 3);
+ break;
+ case GST_FORMAT_TIME:
+ /* seems like a rather silly conversion, implement me if you like */
+ default:
+ res = FALSE;
+ }
+ break;
case GST_FORMAT_TIME:
- *to = framecount * (GST_SECOND * dec->info.fps_denominator /
- dec->info.fps_numerator);
+ switch (*dest_format) {
+ case GST_FORMAT_BYTES:
+ scale = 4 * (dec->info.width * dec->info.height) / 3;
+ case GST_FORMAT_DEFAULT:
+ *dest_value = src_value * scale * dec->info.fps_numerator /
+ (dec->info.fps_denominator * GST_SECOND);
+ break;
+ default:
+ res = FALSE;
+ }
break;
case GST_FORMAT_DEFAULT:
- *to = framecount;
- break;
- case GST_FORMAT_BYTES:
- *to = framecount * dec->info.height * dec->info.width * 3 / 2;
+ switch (*dest_format) {
+ case GST_FORMAT_TIME:
+ *dest_value = src_value * (GST_SECOND * dec->info.fps_denominator /
+ dec->info.fps_numerator);
+ break;
+ case GST_FORMAT_BYTES:
+ *dest_value =
+ src_value * 3 * (dec->info.width * dec->info.height) / 2;
+ break;
+ default:
+ res = FALSE;
+ }
break;
default:
- return FALSE;
+ res = FALSE;
}
- return TRUE;
+
+ return res;
}
-/* FIXME: we can only seek to keyframes... */
static gboolean
-theora_dec_to_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from,
- guint64 * to)
+theora_dec_sink_convert (GstPad * pad,
+ GstFormat src_format, gint64 src_value,
+ GstFormat * dest_format, gint64 * dest_value)
{
- guint64 framecount;
+ gboolean res = TRUE;
+ GstTheoraDec *dec;
+ dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
+
+ /* we need the info part before we can done something */
if (dec->packetno < 1)
return FALSE;
- switch (format) {
- case GST_FORMAT_TIME:
- framecount =
- from * dec->info.fps_numerator / (GST_SECOND *
- dec->info.fps_denominator);
- break;
+ switch (src_format) {
case GST_FORMAT_DEFAULT:
- framecount = from;
- break;
- case GST_FORMAT_BYTES:
- framecount = from * 8 / (dec->info.height * dec->info.width * 12);
+ {
+ guint64 framecount;
+ guint ilog;
+
+ ilog = _theora_ilog (dec->info.keyframe_frequency_force - 1);
+
+ /* granulepos is last ilog bits for counting pframes since last iframe and
+ * bits in front of that for the framenumber of the last iframe. */
+ framecount = src_value >> ilog;
+ framecount += src_value - (framecount << ilog);
+
+ switch (*dest_format) {
+ case GST_FORMAT_TIME:
+ *dest_value = framecount * (GST_SECOND * dec->info.fps_denominator /
+ dec->info.fps_numerator);
+ break;
+ default:
+ res = FALSE;
+ }
break;
+ }
default:
- return FALSE;
+ res = FALSE;
}
- *to = framecount << _theora_ilog (dec->info.keyframe_frequency_force - 1);
- return TRUE;
+
+ return res;
}
static gboolean
gint64 granulepos;
GstTheoraDec *dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
GstFormat my_format = GST_FORMAT_DEFAULT;
+ guint64 time;
if (query == GST_QUERY_POSITION) {
+ /* this is easy, we can convert a granule position to everything */
granulepos = dec->granulepos;
} else {
+ /* for the total, we just forward the query to the peer */
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format,
&granulepos))
return FALSE;
}
- if (!theora_dec_from_granulepos (dec, *format, granulepos, value))
+ /* and convert to the final format in two steps with time as the
+ * intermediate step */
+ my_format = GST_FORMAT_TIME;
+ if (!theora_dec_sink_convert (dec->sinkpad, granulepos, GST_FORMAT_DEFAULT,
+ &my_format, &time))
+ return FALSE;
+ if (!theora_dec_src_convert (pad, my_format, time, format, value))
return FALSE;
GST_LOG_OBJECT (dec,
{
gboolean res = TRUE;
GstTheoraDec *dec;
+ GstFormat format;
dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
case GST_EVENT_SEEK:{
guint64 value;
- res = theora_dec_to_granulepos (dec, GST_EVENT_SEEK_FORMAT (event),
- GST_EVENT_SEEK_OFFSET (event), &value);
+ /* convert to granulepos, this will fail as we cannot generate
+ * a granulepos, only convert an existing one to something else,
+ * which basically means that seeking doesn't work this way */
+ format = GST_FORMAT_DEFAULT;
+ res = theora_dec_sink_convert (pad, GST_EVENT_SEEK_FORMAT (event),
+ GST_EVENT_SEEK_OFFSET (event), &format, &value);
if (res) {
GstEvent *real_seek = gst_event_new_seek (
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) |
GST_FORMAT_DEFAULT,
value);
- /* sync to keyframe */
- dec->need_keyframe = TRUE;
res = gst_pad_send_event (GST_PAD_PEER (dec->sinkpad), real_seek);
+ if (res) {
+ /* sync to keyframe */
+ dec->need_keyframe = TRUE;
+ }
}
gst_event_unref (event);
break;
GST_FORMAT_TIME, (guint64) 0, GST_FORMAT_DEFAULT,
(guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
} else {
- dec->packetno = 3;
+ GstFormat time_format, default_format, bytes_format;
+
+ time_format = GST_FORMAT_TIME;
+ default_format = GST_FORMAT_DEFAULT;
+ bytes_format = GST_FORMAT_BYTES;
+
/* if one of them works, all of them work */
- if (theora_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos,
- &time)
- && theora_dec_from_granulepos (dec, GST_FORMAT_DEFAULT,
- dec->granulepos, &value)
- && theora_dec_from_granulepos (dec, GST_FORMAT_BYTES,
- dec->granulepos, &bytes)) {
+ if (theora_dec_sink_convert (dec->sinkpad, GST_FORMAT_DEFAULT,
+ dec->granulepos, &time_format, &time)
+ && theora_dec_src_convert (dec->srcpad, GST_FORMAT_TIME, time,
+ &default_format, &value)
+ && theora_dec_src_convert (dec->srcpad, GST_FORMAT_TIME, time,
+ &bytes_format, &bytes)) {
gst_pad_push (dec->srcpad,
GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
time, GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes,
0)));
+ /* store new framenumber */
+ dec->packetno = value + 3;
} else {
GST_ERROR_OBJECT (dec,
"failed to parse data for DISCONT event, not sending any");
}
+ /* sync to keyframe */
+ dec->need_keyframe = TRUE;
}
break;
default:
GstTheoraDec *dec;
ogg_packet packet;
guint64 offset_end;
+ GstClockTime outtime;
dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
if (GST_IS_EVENT (data)) {
buf = GST_BUFFER (data);
- offset_end = GST_BUFFER_OFFSET_END (buf);
- if (offset_end != -1) {
- dec->granulepos = offset_end;
+ if (dec->packetno >= 3) {
+ offset_end = GST_BUFFER_OFFSET_END (buf);
+ if (offset_end != -1) {
+ dec->granulepos = offset_end;
+ /* granulepos to time */
+ outtime = GST_SECOND * theora_granule_time (&dec->state, dec->granulepos);
+ } else {
+ GstFormat time_format = GST_FORMAT_TIME;
+
+ /* framenumber to time */
+ theora_dec_src_convert (dec->srcpad, GST_FORMAT_DEFAULT,
+ dec->packetno - 3, &time_format, &outtime);
+ }
+ } else {
+ /* we don't know yet */
+ outtime = -1;
}
/* make ogg_packet out of the buffer */
gst_data_unref (data);
return;
}
-#if 0
- {
- GTimeVal tv;
- guint64 time;
-
- g_get_current_time (&tv);
- time = GST_TIMEVAL_TO_TIME (tv);
-#endif
- if (theora_decode_packetin (&dec->state, &packet)) {
- GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
- (NULL), ("theora decoder did not read data packet"));
- gst_data_unref (data);
- return;
- }
- if (theora_decode_YUVout (&dec->state, &yuv) < 0) {
- GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
- (NULL), ("couldn't read out YUV image"));
- gst_data_unref (data);
- return;
- }
- g_return_if_fail (yuv.y_width == dec->info.width);
- g_return_if_fail (yuv.y_height == dec->info.height);
- out = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE,
- yuv.y_width * yuv.y_height * 12 / 8);
- y = GST_BUFFER_DATA (out);
- u = y + yuv.y_width * yuv.y_height;
- v = u + yuv.y_width * yuv.y_height / 4;
- for (i = 0; i < yuv.y_height; i++) {
- memcpy (y + i * yuv.y_width, yuv.y + i * yuv.y_stride, yuv.y_width);
- }
- for (i = 0; i < yuv.y_height / 2; i++) {
- memcpy (u + i * yuv.uv_width, yuv.u + i * yuv.uv_stride, yuv.uv_width);
- memcpy (v + i * yuv.uv_width, yuv.v + i * yuv.uv_stride, yuv.uv_width);
- }
- GST_BUFFER_OFFSET (out) = dec->packetno - 4;
- GST_BUFFER_OFFSET_END (out) = dec->packetno - 3;
- GST_BUFFER_DURATION (out) =
- GST_SECOND * ((gdouble) dec->info.fps_denominator) /
- dec->info.fps_numerator;
- GST_BUFFER_TIMESTAMP (out) =
- GST_BUFFER_OFFSET (out) * GST_BUFFER_DURATION (out);
-#if 0
- g_get_current_time (&tv);
- time = GST_TIMEVAL_TO_TIME (tv) - time;
- if (time > 10000000)
- g_print ("w00t, you're sl0000w!! - %llu\n", time);
+ if (theora_decode_packetin (&dec->state, &packet)) {
+ GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
+ (NULL), ("theora decoder did not read data packet"));
+ gst_data_unref (data);
+ return;
}
-#endif
+ if (theora_decode_YUVout (&dec->state, &yuv) < 0) {
+ GST_ELEMENT_ERROR (GST_ELEMENT (dec), STREAM, DECODE,
+ (NULL), ("couldn't read out YUV image"));
+ gst_data_unref (data);
+ return;
+ }
+ g_return_if_fail (yuv.y_width == dec->info.width);
+ g_return_if_fail (yuv.y_height == dec->info.height);
+ out = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET_NONE,
+ yuv.y_width * yuv.y_height * 3 / 2);
+ y = GST_BUFFER_DATA (out);
+ u = y + yuv.y_width * yuv.y_height;
+ v = u + yuv.y_width * yuv.y_height / 4;
+ for (i = 0; i < yuv.y_height; i++) {
+ memcpy (y + i * yuv.y_width, yuv.y + i * yuv.y_stride, yuv.y_width);
+ }
+ for (i = 0; i < yuv.y_height / 2; i++) {
+ memcpy (u + i * yuv.uv_width, yuv.u + i * yuv.uv_stride, yuv.uv_width);
+ memcpy (v + i * yuv.uv_width, yuv.v + i * yuv.uv_stride, yuv.uv_width);
+ }
+ GST_BUFFER_OFFSET (out) = dec->packetno - 4;
+ GST_BUFFER_OFFSET_END (out) = dec->packetno - 3;
+ GST_BUFFER_DURATION (out) =
+ GST_SECOND * ((gdouble) dec->info.fps_denominator) /
+ dec->info.fps_numerator;
+ GST_BUFFER_TIMESTAMP (out) = outtime;
+
gst_pad_push (dec->srcpad, GST_DATA (out));
}
gst_data_unref (data);
static gboolean vorbis_dec_src_event (GstPad * pad, GstEvent * event);
static gboolean vorbis_dec_src_query (GstPad * pad,
GstQueryType query, GstFormat * format, gint64 * value);
+static gboolean vorbis_dec_convert (GstPad * pad,
+ GstFormat src_format, gint64 src_value,
+ GstFormat * dest_format, gint64 * dest_value);
static void
static const GstFormat *
vorbis_dec_get_formats (GstPad * pad)
{
- static const GstFormat src_formats[] = {
+ static GstFormat src_formats[] = {
GST_FORMAT_BYTES,
- GST_FORMAT_DEFAULT,
+ GST_FORMAT_DEFAULT, /* samples in the audio case */
GST_FORMAT_TIME,
0
};
- static const GstFormat sink_formats[] = {
+ static GstFormat sink_formats[] = {
GST_FORMAT_BYTES,
GST_FORMAT_TIME,
+ GST_FORMAT_DEFAULT, /* granulepos or samples */
0
};
return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
}
+static const GstEventMask *
+vorbis_get_event_masks (GstPad * pad)
+{
+ static const GstEventMask vorbis_dec_src_event_masks[] = {
+ {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_FLUSH},
+ {0,}
+ };
+
+ return vorbis_dec_src_event_masks;
+}
+
+static const GstQueryType *
+vorbis_get_query_types (GstPad * pad)
+{
+ static const GstQueryType vorbis_dec_src_query_types[] = {
+ GST_QUERY_TOTAL,
+ GST_QUERY_POSITION,
+ 0
+ };
+
+ return vorbis_dec_src_query_types;
+}
+
static void
gst_vorbis_dec_init (GstVorbisDec * dec)
{
gst_pad_new_from_template (gst_static_pad_template_get
(&vorbis_dec_src_factory), "src");
gst_pad_use_explicit_caps (dec->srcpad);
+ gst_pad_set_event_mask_function (dec->srcpad, vorbis_get_event_masks);
gst_pad_set_event_function (dec->srcpad, vorbis_dec_src_event);
+ gst_pad_set_query_type_function (dec->srcpad, vorbis_get_query_types);
gst_pad_set_query_function (dec->srcpad, vorbis_dec_src_query);
gst_pad_set_formats_function (dec->srcpad, vorbis_dec_get_formats);
+ gst_pad_set_convert_function (dec->srcpad, vorbis_dec_convert);
gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
GST_FLAG_SET (dec, GST_ELEMENT_EVENT_AWARE);
}
-/* FIXME: plug this to the pad convert function */
static gboolean
-vorbis_dec_to_granulepos (GstVorbisDec * dec, GstFormat format, guint64 from,
- guint64 * to)
+vorbis_dec_convert (GstPad * pad,
+ GstFormat src_format, gint64 src_value,
+ GstFormat * dest_format, gint64 * dest_value)
{
- if (dec->packetno < 1)
- return FALSE;
+ gboolean res = TRUE;
+ GstVorbisDec *dec;
+ guint64 scale = 1;
- switch (format) {
- case GST_FORMAT_TIME:
- *to = from * dec->vi.rate / GST_SECOND;
- return TRUE;
- case GST_FORMAT_DEFAULT:
- *to = from;
- return TRUE;
- case GST_FORMAT_BYTES:
- *to = from / sizeof (float) / dec->vi.channels;
- return TRUE;
- default:
- return FALSE;
- }
-}
+ dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
-static gboolean
-vorbis_dec_from_granulepos (GstVorbisDec * dec, GstFormat format, guint64 from,
- guint64 * to)
-{
if (dec->packetno < 1)
return FALSE;
- switch (format) {
+ switch (src_format) {
case GST_FORMAT_TIME:
- *to = from * GST_SECOND / dec->vi.rate;
- return TRUE;
+ switch (*dest_format) {
+ case GST_FORMAT_BYTES:
+ scale = sizeof (float) * dec->vi.channels;
+ case GST_FORMAT_DEFAULT:
+ *dest_value = scale * (src_value * dec->vi.rate / GST_SECOND);
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
case GST_FORMAT_DEFAULT:
- *to = from;
- return TRUE;
+ switch (*dest_format) {
+ case GST_FORMAT_BYTES:
+ *dest_value = src_value * sizeof (float) * dec->vi.channels;
+ break;
+ case GST_FORMAT_TIME:
+ *dest_value = src_value * GST_SECOND / dec->vi.rate;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
case GST_FORMAT_BYTES:
- *to = from * sizeof (float) * dec->vi.channels;
- return TRUE;
+ switch (*dest_format) {
+ case GST_FORMAT_DEFAULT:
+ *dest_value = src_value / (sizeof (float) * dec->vi.channels);
+ break;
+ case GST_FORMAT_TIME:
+ *dest_value = src_value * GST_SECOND /
+ (dec->vi.rate * sizeof (float) * dec->vi.channels);
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
default:
- return FALSE;
+ res = FALSE;
}
-}
+ return res;
+}
static gboolean
vorbis_dec_src_query (GstPad * pad, GstQueryType query, GstFormat * format,
gint64 * value)
{
- gint64 granulepos;
+ gint64 granulepos = 0;
GstVorbisDec *dec = GST_VORBIS_DEC (gst_pad_get_parent (pad));
GstFormat my_format = GST_FORMAT_DEFAULT;
- if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format,
- &granulepos))
- return FALSE;
+ if (query == GST_QUERY_POSITION) {
+ granulepos = dec->granulepos;
+ } else {
+ /* query peer in default format */
+ if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format,
+ &granulepos))
+ return FALSE;
+ }
- if (!vorbis_dec_from_granulepos (dec, *format, granulepos, (guint64 *) value))
+ /* and convert to the final format */
+ if (!vorbis_dec_convert (pad, GST_FORMAT_DEFAULT, granulepos, format, value))
return FALSE;
GST_LOG_OBJECT (dec,
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:{
guint64 value;
+ GstFormat my_format = GST_FORMAT_DEFAULT;
- res = vorbis_dec_to_granulepos (dec, GST_EVENT_SEEK_FORMAT (event),
- GST_EVENT_SEEK_OFFSET (event), &value);
+ /* convert to granulepos */
+ res = vorbis_dec_convert (pad, GST_EVENT_SEEK_FORMAT (event),
+ GST_EVENT_SEEK_OFFSET (event), &my_format, &value);
if (res) {
GstEvent *real_seek = gst_event_new_seek (
(GST_EVENT_SEEK_TYPE (event) & ~GST_SEEK_FORMAT_MASK) |
return res;
}
+
static void
vorbis_dec_event (GstVorbisDec * dec, GstEvent * event)
{
GST_FORMAT_TIME, (guint64) 0, GST_FORMAT_DEFAULT,
(guint64) 0, GST_FORMAT_BYTES, (guint64) 0, 0)));
} else {
+ GstFormat time_format, default_format, bytes_format;
+
+ time_format = GST_FORMAT_TIME;
+ default_format = GST_FORMAT_DEFAULT;
+ bytes_format = GST_FORMAT_BYTES;
+
dec->packetno = 3;
/* if one of them works, all of them work */
- if (vorbis_dec_from_granulepos (dec, GST_FORMAT_TIME, dec->granulepos,
- &time)
- && vorbis_dec_from_granulepos (dec, GST_FORMAT_DEFAULT,
- dec->granulepos, &value)
- && vorbis_dec_from_granulepos (dec, GST_FORMAT_BYTES,
- dec->granulepos, &bytes)) {
+ if (vorbis_dec_convert (dec->srcpad, GST_FORMAT_DEFAULT,
+ dec->granulepos, &time_format, &time)
+ && vorbis_dec_convert (dec->srcpad, GST_FORMAT_DEFAULT,
+ dec->granulepos, &bytes_format, &bytes)) {
gst_pad_push (dec->srcpad,
GST_DATA (gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME,
- time, GST_FORMAT_DEFAULT, value, GST_FORMAT_BYTES, bytes,
- 0)));
+ time, GST_FORMAT_DEFAULT, dec->granulepos,
+ GST_FORMAT_BYTES, bytes, 0)));
} else {
GST_ERROR_OBJECT (dec,
"failed to parse data for DISCONT event, not sending any");