static GstStateChangeReturn gst_audio_decoder_change_state (GstElement *
element, GstStateChange transition);
-static gboolean gst_audio_decoder_sink_event (GstPad * pad, GstEvent * event);
-static gboolean gst_audio_decoder_src_event (GstPad * pad, GstEvent * event);
-static gboolean gst_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps);
-static gboolean gst_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_audio_decoder_chain (GstPad * pad, GstBuffer * buf);
-static gboolean gst_audio_decoder_src_query (GstPad * pad, GstQuery * query);
-static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstQuery * query);
-static const GstQueryType *gst_audio_decoder_get_query_types (GstPad * pad);
+static gboolean gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
+static gboolean gst_audio_decoder_src_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
+static gboolean gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec,
+ GstCaps * caps);
+gboolean gst_audio_decoder_src_setcaps (GstAudioDecoder * dec, GstCaps * caps);
+static GstFlowReturn gst_audio_decoder_chain (GstPad * pad, GstObject * parent,
+ GstBuffer * buf);
+static gboolean gst_audio_decoder_src_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
+static gboolean gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
static void gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full);
+static GstElementClass *parent_class = NULL;
-GST_BOILERPLATE (GstAudioDecoder, gst_audio_decoder, GstElement,
- GST_TYPE_ELEMENT);
+static void gst_audio_decoder_class_init (GstAudioDecoderClass * klass);
+static void gst_audio_decoder_init (GstAudioDecoder * dec,
+ GstAudioDecoderClass * klass);
-static void
-gst_audio_decoder_base_init (gpointer g_class)
+GType
+gst_audio_decoder_get_type (void)
{
+ static volatile gsize audio_decoder_type = 0;
+
+ if (g_once_init_enter (&audio_decoder_type)) {
+ GType _type;
+ static const GTypeInfo audio_decoder_info = {
+ sizeof (GstAudioDecoderClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gst_audio_decoder_class_init,
+ NULL,
+ NULL,
+ sizeof (GstAudioDecoder),
+ 0,
+ (GInstanceInitFunc) gst_audio_decoder_init,
+ };
+
+ _type = g_type_register_static (GST_TYPE_ELEMENT,
+ "GstAudioDecoder", &audio_decoder_info, G_TYPE_FLAG_ABSTRACT);
+ g_once_init_leave (&audio_decoder_type, _type);
+ }
+ return audio_decoder_type;
}
+
static void
gst_audio_decoder_class_init (GstAudioDecoderClass * klass)
{
dec->sinkpad = gst_pad_new_from_template (pad_template, "sink");
gst_pad_set_event_function (dec->sinkpad,
GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_event));
- gst_pad_set_setcaps_function (dec->sinkpad,
- GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_setcaps));
gst_pad_set_chain_function (dec->sinkpad,
GST_DEBUG_FUNCPTR (gst_audio_decoder_chain));
gst_pad_set_query_function (dec->sinkpad,
g_return_if_fail (pad_template != NULL);
dec->srcpad = gst_pad_new_from_template (pad_template, "src");
- gst_pad_set_setcaps_function (dec->srcpad,
- GST_DEBUG_FUNCPTR (gst_audio_decoder_src_setcaps));
gst_pad_set_event_function (dec->srcpad,
GST_DEBUG_FUNCPTR (gst_audio_decoder_src_event));
gst_pad_set_query_function (dec->srcpad,
GST_DEBUG_FUNCPTR (gst_audio_decoder_src_query));
- gst_pad_set_query_type_function (dec->srcpad,
- GST_DEBUG_FUNCPTR (gst_audio_decoder_get_query_types));
gst_pad_use_fixed_caps (dec->srcpad);
gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
GST_DEBUG_OBJECT (dec, "srcpad created");
dec->priv->error_count = 0;
gst_audio_decoder_clear_queues (dec);
- gst_audio_info_clear (&dec->priv->ctx.info);
+ gst_audio_info_init (&dec->priv->ctx.info);
memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
if (dec->priv->taglist) {
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-/* automagically perform sanity checking of src caps;
- * also extracts output data format */
-static gboolean
-gst_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps)
+/**
+ * gst_audio_decoder_set_outcaps:
+ * @dec: a #GstAudioDecoder
+ * @caps: #GstCaps
+ *
+ * Configure output @caps on the srcpad of @dec. Also perform
+ * sanity checking of @caps and extracts output data format
+ *
+ * Returns: %TRUE on success.
+ * */
+gboolean
+gst_audio_decoder_set_outcaps (GstAudioDecoder * dec, GstCaps * caps)
{
- GstAudioDecoder *dec;
gboolean res = TRUE;
guint old_rate;
- dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
-
GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
GST_AUDIO_DECODER_STREAM_LOCK (dec);
done:
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
- gst_object_unref (dec);
+ res = gst_pad_set_caps (dec->srcpad, caps);
+
return res;
/* ERRORS */
}
static gboolean
-gst_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps)
+gst_audio_decoder_sink_setcaps (GstAudioDecoder * dec, GstCaps * caps)
{
- GstAudioDecoder *dec;
GstAudioDecoderClass *klass;
gboolean res = TRUE;
- dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
klass = GST_AUDIO_DECODER_GET_CLASS (dec);
GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);
GST_AUDIO_DECODER_STREAM_LOCK (dec);
/* NOTE pbutils only needed here */
/* TODO maybe (only) upstream demuxer/parser etc should handle this ? */
+#if 0
if (dec->priv->taglist)
gst_tag_list_free (dec->priv->taglist);
dec->priv->taglist = gst_tag_list_new ();
gst_pb_utils_add_codec_description_to_tag_list (dec->priv->taglist,
GST_TAG_AUDIO_CODEC, caps);
+#endif
if (klass->set_format)
res = klass->set_format (dec, caps);
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
- g_object_unref (dec);
return res;
}
return GST_FLOW_OK;
}
- GST_LOG_OBJECT (dec, "clipping buffer of size %d with ts %" GST_TIME_FORMAT
- ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
+ GST_LOG_OBJECT (dec,
+ "clipping buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
+ ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
}
/* decorate */
- gst_buffer_set_caps (buf, GST_PAD_CAPS (dec->srcpad));
-
if (G_UNLIKELY (priv->discont)) {
GST_LOG_OBJECT (dec, "marking discont");
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
/* duration should always be valid for raw audio */
g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
- dec->segment.last_stop =
+ dec->segment.position =
GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
}
}
}
- GST_LOG_OBJECT (dec, "pushing buffer of size %d with ts %" GST_TIME_FORMAT
- ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
+ GST_LOG_OBJECT (dec,
+ "pushing buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
+ ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
gst_audio_decoder_setup (dec);
if (G_LIKELY (buf)) {
- GST_LOG_OBJECT (dec, "output buffer of size %d with ts %" GST_TIME_FORMAT
- ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
+ GST_LOG_OBJECT (dec,
+ "output buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
+ ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
}
}
gst_adapter_push (priv->adapter_out, buf);
priv->out_dur += GST_BUFFER_DURATION (buf);
- av += GST_BUFFER_SIZE (buf);
+ av += gst_buffer_get_size (buf);
buf = NULL;
}
if (priv->out_dur > dec->priv->latency)
GstAudioDecoderContext *ctx;
gint samples = 0;
GstClockTime ts, next_ts;
+ gsize size;
GstFlowReturn ret = GST_FLOW_OK;
/* subclass should know what it is producing by now */
- g_return_val_if_fail (buf == NULL || GST_PAD_CAPS (dec->srcpad) != NULL,
+ g_return_val_if_fail (buf == NULL || gst_pad_has_current_caps (dec->srcpad),
GST_FLOW_ERROR);
/* subclass should not hand us no data */
- g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0,
+ g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
GST_FLOW_ERROR);
/* no dummy calls please */
g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);
priv = dec->priv;
ctx = &dec->priv->ctx;
+ size = buf ? gst_buffer_get_size (buf) : 0;
/* must know the output format by now */
g_return_val_if_fail (buf == NULL || GST_AUDIO_INFO_IS_VALID (&ctx->info),
GST_FLOW_ERROR);
- GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames",
- buf ? GST_BUFFER_SIZE (buf) : -1,
- buf ? GST_BUFFER_SIZE (buf) / ctx->info.bpf : -1, frames);
+ GST_LOG_OBJECT (dec,
+ "accepting %" G_GSIZE_FORMAT " bytes == %" G_GSIZE_FORMAT
+ " samples for %d frames", buf ? size : -1,
+ buf ? size / ctx->info.bpf : -1, frames);
GST_AUDIO_DECODER_STREAM_LOCK (dec);
/* output shoud be whole number of sample frames */
if (G_LIKELY (buf && ctx->info.bpf)) {
- if (GST_BUFFER_SIZE (buf) % ctx->info.bpf)
+ if (size % ctx->info.bpf)
goto wrong_buffer;
/* per channel least */
- samples = GST_BUFFER_SIZE (buf) / ctx->info.bpf;
+ samples = size / ctx->info.bpf;
}
/* frame and ts book-keeping */
if (gst_tag_list_is_empty (priv->taglist)) {
gst_tag_list_free (priv->taglist);
} else {
- gst_element_found_tags (GST_ELEMENT (dec), priv->taglist);
+ gst_pad_push_event (dec->srcpad, gst_event_new_tag (priv->taglist));
}
priv->taglist = NULL;
}
- buf = gst_buffer_make_metadata_writable (buf);
+ buf = gst_buffer_make_writable (buf);
if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
GST_BUFFER_TIMESTAMP (buf) =
priv->base_ts +
wrong_buffer:
{
GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL),
- ("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buf),
+ ("buffer size %" G_GSIZE_FORMAT " not a multiple of %d", size,
ctx->info.bpf));
gst_buffer_unref (buf);
ret = GST_FLOW_ERROR;
GstAudioDecoderClass * klass, GstBuffer * buffer)
{
if (G_LIKELY (buffer)) {
+ gsize size = gst_buffer_get_size (buffer);
/* keep around for admin */
- GST_LOG_OBJECT (dec, "tracking frame size %d, ts %" GST_TIME_FORMAT,
- GST_BUFFER_SIZE (buffer),
+ GST_LOG_OBJECT (dec,
+ "tracking frame size %" G_GSIZE_FORMAT ", ts %" GST_TIME_FORMAT, size,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
g_queue_push_tail (&dec->priv->frames, buffer);
dec->priv->ctx.delay = dec->priv->frames.length;
- dec->priv->bytes_in += GST_BUFFER_SIZE (buffer);
+ dec->priv->bytes_in += size;
} else {
GST_LOG_OBJECT (dec, "providing subclass with NULL frame");
}
goto parse_failed;
}
- if (ret == GST_FLOW_UNEXPECTED) {
+ if (ret == GST_FLOW_EOS) {
GST_LOG_OBJECT (dec, "no frame yet");
ret = GST_FLOW_OK;
break;
priv->prev_ts = ts;
}
buffer = gst_adapter_take_buffer (priv->adapter, len);
- buffer = gst_buffer_make_metadata_writable (buffer);
+ buffer = gst_buffer_make_writable (buffer);
GST_BUFFER_TIMESTAMP (buffer) = ts;
flush += len;
} else {
GstFlowReturn ret = GST_FLOW_OK;
/* discard silly case, though maybe ts may be of value ?? */
- if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) == 0)) {
+ if (G_UNLIKELY (gst_buffer_get_size (buffer) == 0)) {
GST_DEBUG_OBJECT (dec, "discarding empty buffer");
gst_buffer_unref (buffer);
goto exit;
}
if (G_LIKELY (res == GST_FLOW_OK)) {
- GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %u, "
+ GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %" G_GSIZE_FORMAT ", "
"time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
- GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
+ gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
/* should be already, but let's be sure */
- buf = gst_buffer_make_metadata_writable (buf);
+ buf = gst_buffer_make_writable (buf);
/* avoid stray DISCONT from forward processing,
* which have no meaning in reverse pushing */
GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
}
if (G_LIKELY (buf)) {
- GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %u, "
+ GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %" G_GSIZE_FORMAT ", "
"time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
- GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
+ gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
/* add buffer to gather queue */
}
static GstFlowReturn
-gst_audio_decoder_chain (GstPad * pad, GstBuffer * buffer)
+gst_audio_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
GstAudioDecoder *dec;
GstFlowReturn ret;
- dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad));
+ dec = GST_AUDIO_DECODER (parent);
GST_LOG_OBJECT (dec,
- "received buffer of size %d with ts %" GST_TIME_FORMAT
- ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer),
+ "received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
+ ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
gboolean handled = FALSE;
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
{
- GstFormat format;
- gdouble rate, arate;
- gint64 start, stop, time;
- gboolean update;
+ GstSegment seg;
GST_AUDIO_DECODER_STREAM_LOCK (dec);
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
+ gst_event_copy_segment (event, &seg);
- if (format == GST_FORMAT_TIME) {
- GST_DEBUG_OBJECT (dec, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT
- " -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
- ", rate %g, applied_rate %g",
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time),
- rate, arate);
+ if (seg.format == GST_FORMAT_TIME) {
+ GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_SEGMENT_FORMAT,
+ &seg);
} else {
- GstFormat dformat = GST_FORMAT_TIME;
-
- GST_DEBUG_OBJECT (dec, "received NEW_SEGMENT %" G_GINT64_FORMAT
- " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
- ", rate %g, applied_rate %g", start, stop, time, rate, arate);
+ gint64 nstart;
+ GST_DEBUG_OBJECT (dec, "received SEGMENT %" GST_SEGMENT_FORMAT, &seg);
/* handle newsegment resulting from legacy simple seeking */
/* note that we need to convert this whether or not enough data
* to handle initial newsegment */
if (dec->priv->ctx.do_byte_time &&
- gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, start,
- &dformat, &start)) {
+ gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, seg.start,
+ GST_FORMAT_TIME, &nstart)) {
/* best attempt convert */
/* as these are only estimates, stop is kept open-ended to avoid
* premature cutting */
GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT,
- GST_TIME_ARGS (start));
- format = GST_FORMAT_TIME;
- time = start;
- stop = GST_CLOCK_TIME_NONE;
+ GST_TIME_ARGS (nstart));
+ seg.format = GST_FORMAT_TIME;
+ seg.start = nstart;
+ seg.time = nstart;
+ seg.stop = GST_CLOCK_TIME_NONE;
/* replace event */
gst_event_unref (event);
- event = gst_event_new_new_segment_full (update, rate, arate,
- GST_FORMAT_TIME, start, stop, time);
+ event = gst_event_new_segment (&seg);
} else {
GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
/* finish current segment */
gst_audio_decoder_drain (dec);
+#if 0
if (update) {
/* time progressed without data, see if we can fill the gap with
* some concealment data */
GST_DEBUG_OBJECT (dec,
- "segment update: plc %d, do_plc %d, last_stop %" GST_TIME_FORMAT,
+ "segment update: plc %d, do_plc %d, position %" GST_TIME_FORMAT,
dec->priv->plc, dec->priv->ctx.do_plc,
- GST_TIME_ARGS (dec->segment.last_stop));
+ GST_TIME_ARGS (dec->segment.position));
if (dec->priv->plc && dec->priv->ctx.do_plc &&
- dec->segment.rate > 0.0 && dec->segment.last_stop < start) {
+ dec->segment.rate > 0.0 && dec->segment.position < start) {
GstAudioDecoderClass *klass;
GstBuffer *buf;
klass = GST_AUDIO_DECODER_GET_CLASS (dec);
/* hand subclass empty frame with duration that needs covering */
buf = gst_buffer_new ();
- GST_BUFFER_DURATION (buf) = start - dec->segment.last_stop;
+ GST_BUFFER_DURATION (buf) = start - dec->segment.position;
/* best effort, not much error handling */
gst_audio_decoder_handle_frame (dec, klass, buf);
}
- } else {
+ } else
+#endif
+ {
/* prepare for next one */
gst_audio_decoder_flush (dec, FALSE);
/* and that's where we time from,
* in case upstream does not come up with anything better
* (e.g. upstream BYTE) */
- if (format != GST_FORMAT_TIME) {
- dec->priv->base_ts = start;
+ if (seg.format != GST_FORMAT_TIME) {
+ dec->priv->base_ts = seg.start;
dec->priv->samples = 0;
}
}
/* and follow along with segment */
- gst_segment_set_newsegment_full (&dec->segment, update, rate, arate,
- format, start, stop, time);
-
+ dec->segment = seg;
dec->priv->pending_events =
g_list_append (dec->priv->pending_events, event);
handled = TRUE;
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
break;
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ gst_audio_decoder_sink_setcaps (dec, caps);
+ gst_event_unref (event);
+ handled = TRUE;
+ break;
+ }
default:
break;
}
}
static gboolean
-gst_audio_decoder_sink_event (GstPad * pad, GstEvent * event)
+gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
GstAudioDecoder *dec;
GstAudioDecoderClass *klass;
gboolean handled = FALSE;
gboolean ret = TRUE;
- dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
+ dec = GST_AUDIO_DECODER (parent);
klass = GST_AUDIO_DECODER_GET_CLASS (dec);
GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
if (!GST_EVENT_IS_SERIALIZED (event)
|| GST_EVENT_TYPE (event) == GST_EVENT_EOS
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
- ret = gst_pad_event_default (pad, event);
+ ret = gst_pad_event_default (pad, parent, event);
} else {
GST_AUDIO_DECODER_STREAM_LOCK (dec);
dec->priv->pending_events =
GST_DEBUG_OBJECT (dec, "event handled");
- gst_object_unref (dec);
return ret;
}
}
memcpy (&seek_segment, &dec->segment, sizeof (seek_segment));
- gst_segment_set_seek (&seek_segment, rate, format, flags, start_type,
+ gst_segment_do_seek (&seek_segment, rate, format, flags, start_type,
start_time, end_type, end_time, NULL);
- start_time = seek_segment.last_stop;
+ start_time = seek_segment.position;
- format = GST_FORMAT_BYTES;
if (!gst_pad_query_convert (dec->sinkpad, GST_FORMAT_TIME, start_time,
- &format, &start)) {
+ GST_FORMAT_BYTES, &start)) {
GST_DEBUG_OBJECT (dec, "conversion failed");
return FALSE;
}
}
static gboolean
-gst_audio_decoder_src_event (GstPad * pad, GstEvent * event)
+gst_audio_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstAudioDecoder *dec;
gboolean res = FALSE;
- dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
- if (G_UNLIKELY (dec == NULL)) {
- gst_event_unref (event);
- return FALSE;
- }
+ dec = GST_AUDIO_DECODER (parent);
GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
{
- GstFormat format, tformat;
+ GstFormat format;
gdouble rate;
GstSeekFlags flags;
GstSeekType cur_type, stop_type;
/* ... though a non-time seek can be aided as well */
/* First bring the requested format to time */
- tformat = GST_FORMAT_TIME;
- if (!(res = gst_pad_query_convert (pad, format, cur, &tformat, &tcur)))
+ if (!(res =
+ gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &tcur)))
goto convert_error;
- if (!(res = gst_pad_query_convert (pad, format, stop, &tformat, &tstop)))
+ if (!(res =
+ gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME,
+ &tstop)))
goto convert_error;
/* then seek with time on the peer */
break;
}
done:
- gst_object_unref (dec);
-
return res;
/* ERRORS */
}
static gboolean
-gst_audio_decoder_sink_query (GstPad * pad, GstQuery * query)
+gst_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
+ GstQuery * query)
{
- gboolean res = TRUE;
+ gboolean res = FALSE;
GstAudioDecoder *dec;
- dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
+ dec = GST_AUDIO_DECODER (parent);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_FORMATS:
break;
}
default:
- res = gst_pad_query_default (pad, query);
+ res = gst_pad_query_default (pad, parent, query);
break;
}
error:
- gst_object_unref (dec);
return res;
}
-static const GstQueryType *
-gst_audio_decoder_get_query_types (GstPad * pad)
-{
- static const GstQueryType gst_audio_decoder_src_query_types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_DURATION,
- GST_QUERY_CONVERT,
- GST_QUERY_LATENCY,
- 0
- };
-
- return gst_audio_decoder_src_query_types;
-}
-
/* FIXME ? are any of these queries (other than latency) a decoder's business ??
* also, the conversion stuff might seem to make sense, but seems to not mind
* segment stuff etc at all
* Supposedly that's backward compatibility ... */
static gboolean
-gst_audio_decoder_src_query (GstPad * pad, GstQuery * query)
+gst_audio_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
GstAudioDecoder *dec;
- GstPad *peerpad;
gboolean res = FALSE;
- dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad));
- if (G_UNLIKELY (dec == NULL))
- return FALSE;
-
- peerpad = gst_pad_get_peer (GST_PAD (dec->sinkpad));
+ dec = GST_AUDIO_DECODER (parent);
GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);
GstFormat format;
/* upstream in any case */
- if ((res = gst_pad_query_default (pad, query)))
+ if ((res = gst_pad_query_default (pad, parent, query)))
break;
gst_query_parse_duration (query, &format, NULL);
if (format == GST_FORMAT_TIME && gst_audio_decoder_do_byte (dec)) {
gint64 value;
- format = GST_FORMAT_BYTES;
- if (gst_pad_query_peer_duration (dec->sinkpad, &format, &value)) {
+ if (gst_pad_peer_query_duration (dec->sinkpad, GST_FORMAT_BYTES,
+ &value)) {
GST_LOG_OBJECT (dec, "upstream size %" G_GINT64_FORMAT, value);
- format = GST_FORMAT_TIME;
if (gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, value,
- &format, &value)) {
+ GST_FORMAT_TIME, &value)) {
gst_query_set_duration (query, GST_FORMAT_TIME, value);
res = TRUE;
}
}
/* we start from the last seen time */
- time = dec->segment.last_stop;
+ time = dec->segment.position;
/* correct for the segment values */
time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time);
/* and convert to the final format */
gst_query_parse_position (query, &format, NULL);
if (!(res = gst_pad_query_convert (pad, GST_FORMAT_TIME, time,
- &format, &value)))
+ format, &value)))
break;
gst_query_set_position (query, format, value);
break;
}
default:
- res = gst_pad_query_default (pad, query);
+ res = gst_pad_query_default (pad, parent, query);
break;
}
- gst_object_unref (peerpad);
return res;
}
break;
}
- ret = parent_class->change_state (element, transition);
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
switch (transition) {
case GST_STATE_CHANGE_PLAYING_TO_PAUSED: