Added src_queries to decoder class. Added handle_discont to decoder

class. Reworked reset. Various other minor fixes.
This commit is contained in:
Iago Toral 2009-08-14 09:45:52 +02:00 committed by Tim-Philipp Müller
parent d05c805b16
commit 9740eb35b8
2 changed files with 112 additions and 42 deletions

View file

@ -24,8 +24,13 @@
#include "gstbaseaudiodecoder.h" #include "gstbaseaudiodecoder.h"
#include <gst/gstutils.h>
#include <string.h> #include <string.h>
/*
* FIXME: is still interesting providing sink_query and src_query functions?
*/
GST_DEBUG_CATEGORY_EXTERN (baseaudio_debug); GST_DEBUG_CATEGORY_EXTERN (baseaudio_debug);
#define GST_CAT_DEFAULT baseaudio_debug #define GST_CAT_DEFAULT baseaudio_debug
@ -35,11 +40,11 @@ static gboolean gst_base_audio_decoder_src_event (GstPad * pad,
GstEvent * event); GstEvent * event);
static GstFlowReturn gst_base_audio_decoder_chain (GstPad * pad, static GstFlowReturn gst_base_audio_decoder_chain (GstPad * pad,
GstBuffer * buf); GstBuffer * buf);
static gboolean gst_base_audio_decoder_sink_query (GstPad * pad, /* static gboolean gst_base_audio_decoder_sink_query (GstPad * pad, */
GstQuery * query); /* GstQuery * query); */
static gboolean gst_base_audio_decoder_sink_convert (GstPad * pad, /* static gboolean gst_base_audio_decoder_sink_convert (GstPad * pad, */
GstFormat src_format, gint64 src_value, GstFormat * dest_format, /* GstFormat src_format, gint64 src_value, GstFormat * dest_format, */
gint64 * dest_value); /* gint64 * dest_value); */
static const GstQueryType *gst_base_audio_decoder_get_query_types (GstPad * static const GstQueryType *gst_base_audio_decoder_get_query_types (GstPad *
pad); pad);
static gboolean gst_base_audio_decoder_src_query (GstPad * pad, static gboolean gst_base_audio_decoder_src_query (GstPad * pad,
@ -47,8 +52,10 @@ static gboolean gst_base_audio_decoder_src_query (GstPad * pad,
static gboolean gst_base_audio_decoder_src_convert (GstPad * pad, static gboolean gst_base_audio_decoder_src_convert (GstPad * pad,
GstFormat src_format, gint64 src_value, GstFormat * dest_format, GstFormat src_format, gint64 src_value, GstFormat * dest_format,
gint64 * dest_value); gint64 * dest_value);
static void gst_base_audio_decoder_reset (GstBaseAudioDecoder * static gboolean gst_base_audio_decoder_reset (GstBaseAudioCodec *
base_audio_decoder); base_audio_codec);
static void gst_base_audio_decoder_handle_discont (GstBaseAudioDecoder *
base_audio_decoder, GstBuffer * buffer);
GST_BOILERPLATE (GstBaseAudioDecoder, gst_base_audio_decoder, GST_BOILERPLATE (GstBaseAudioDecoder, gst_base_audio_decoder,
GstBaseAudioCodec, GST_TYPE_BASE_AUDIO_CODEC); GstBaseAudioCodec, GST_TYPE_BASE_AUDIO_CODEC);
@ -68,7 +75,9 @@ gst_base_audio_decoder_class_init (GstBaseAudioDecoderClass * klass)
gobject_class->finalize = gst_base_audio_decoder_finalize; gobject_class->finalize = gst_base_audio_decoder_finalize;
parent_class = g_type_class_peek_parent (klass); parent_class->reset = gst_base_audio_decoder_reset;
klass->handle_discont = gst_base_audio_decoder_handle_discont;
} }
static void static void
@ -82,7 +91,7 @@ gst_base_audio_decoder_init (GstBaseAudioDecoder * base_audio_decoder,
pad = GST_BASE_AUDIO_CODEC_SINK_PAD (base_audio_decoder); pad = GST_BASE_AUDIO_CODEC_SINK_PAD (base_audio_decoder);
gst_pad_set_chain_function (pad, gst_base_audio_decoder_chain); gst_pad_set_chain_function (pad, gst_base_audio_decoder_chain);
gst_pad_set_query_function (pad, gst_base_audio_decoder_sink_query); /* gst_pad_set_query_function (pad, gst_base_audio_decoder_sink_query); */
pad = GST_BASE_AUDIO_CODEC_SRC_PAD (base_audio_decoder); pad = GST_BASE_AUDIO_CODEC_SRC_PAD (base_audio_decoder);
@ -94,25 +103,83 @@ gst_base_audio_decoder_init (GstBaseAudioDecoder * base_audio_decoder,
static void static void
gst_base_audio_decoder_finalize (GObject * object) gst_base_audio_decoder_finalize (GObject * object)
{ {
GstBaseAudioDecoder *base_audio_decoder;
g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (object)); g_return_if_fail (GST_IS_BASE_AUDIO_DECODER (object));
GST_DEBUG_OBJECT (object, "finalize"); GST_DEBUG_OBJECT (object, "gst_base_audio_decoder_finalize");
base_audio_decoder = GST_BASE_AUDIO_DECODER (object);
gst_base_audio_decoder_reset (base_audio_decoder);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
/* FIXME: implement */
static gboolean static gboolean
gst_base_audio_decoder_src_convert (GstPad * pad, GstFormat src_format, gst_base_audio_decoder_src_convert (GstPad * pad, GstFormat src_format,
gint64 src_value, GstFormat * dest_format, gint64 * dest_value) gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
{ {
return TRUE; gboolean res = TRUE;
GstBaseAudioCodec *codec;
gint bytes_per_sample;
gint scale = 1;
guint byterate;
if (src_format == *dest_format || src_value == -1 || src_value == 0) {
*dest_value = src_value;
}
codec = GST_BASE_AUDIO_CODEC (GST_PAD_PARENT (pad));
bytes_per_sample = codec->state.channels * codec->state.bytes_per_sample;
switch (src_format) {
case GST_FORMAT_BYTES:
switch (*dest_format) {
case GST_FORMAT_DEFAULT: /* Bytes -> Samples */
if (bytes_per_sample == 0)
return FALSE;
*dest_value = src_value / bytes_per_sample;
break;
case GST_FORMAT_TIME: /* Bytes -> Time */
byterate = bytes_per_sample * codec->state.rate;
if (byterate == 0)
return FALSE;
*dest_value =
gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
break;
default:
res = FALSE;
}
break;
case GST_FORMAT_DEFAULT:
switch (*dest_format) {
case GST_FORMAT_BYTES: /* Samples -> Bytes */
*dest_value = src_value * bytes_per_sample;
break;
case GST_FORMAT_TIME: /* Samples -> Time */
if (codec->state.rate == 0)
return FALSE;
*dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
codec->state.rate);
break;
default:
res = FALSE;
}
break;
case GST_FORMAT_TIME:
switch (*dest_format) {
case GST_FORMAT_BYTES: /* Time -> Bytes */
scale = bytes_per_sample;
/* fallthrough */
case GST_FORMAT_DEFAULT: /* Time -> Samples */
*dest_value = gst_util_uint64_scale_int (src_value,
scale * codec->state.rate, GST_SECOND);
break;
default:
res = FALSE;
}
break;
default:
res = FALSE;
}
return res;
} }
#ifndef GST_DISABLE_INDEX #ifndef GST_DISABLE_INDEX
@ -232,10 +299,10 @@ gst_base_audio_decoder_normal_seek (GstBaseAudioDecoder *base_audio_decoder,
/* Try seek in bytes if seek in time failed */ /* Try seek in bytes if seek in time failed */
if (!res) { if (!res) {
conv = GST_FORMAT_BYTES; conv = GST_FORMAT_BYTES;
if (!gst_base_audio_decoder_sink_convert (pad, GST_FORMAT_TIME, time_cur, if (!gst_base_audio_decoder_src_convert (pad, GST_FORMAT_TIME, time_cur,
&conv, &bytes_cur)) &conv, &bytes_cur))
goto convert_failed; goto convert_failed;
if (!gst_base_audio_decoder_sink_convert (pad, GST_FORMAT_TIME, time_stop, if (!gst_base_audio_decoder_src_convert (pad, GST_FORMAT_TIME, time_stop,
&conv, &bytes_stop)) &conv, &bytes_stop))
goto convert_failed; goto convert_failed;
@ -289,7 +356,8 @@ gst_base_audio_decoder_src_event (GstPad * pad, GstEvent * event)
GST_BASE_AUDIO_DECODER_GET_CLASS (base_audio_decoder); GST_BASE_AUDIO_DECODER_GET_CLASS (base_audio_decoder);
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:{ case GST_EVENT_SEEK:
/* Try the demuxer first */
gst_event_ref (event); gst_event_ref (event);
res = gst_pad_push_event (base_audio_codec->sinkpad, event); res = gst_pad_push_event (base_audio_codec->sinkpad, event);
if (!res) { if (!res) {
@ -297,7 +365,6 @@ gst_base_audio_decoder_src_event (GstPad * pad, GstEvent * event)
} }
gst_event_unref (event); gst_event_unref (event);
break; break;
}
default: default:
res = gst_pad_push_event (base_audio_codec->sinkpad, event); res = gst_pad_push_event (base_audio_codec->sinkpad, event);
break; break;
@ -341,7 +408,7 @@ gst_base_audio_decoder_src_query (GstPad * pad, GstQuery * query)
} }
default: default:
res = gst_pad_query_default (pad, query); res = gst_pad_query_default (pad, query);
} }
gst_object_unref (enc); gst_object_unref (enc);
return res; return res;
@ -351,34 +418,38 @@ error:
return res; return res;
} }
/* FIXME: implement */ /* FIXME: implement (is this really necessary?) */
static gboolean /* static gboolean */
gst_base_audio_decoder_sink_convert (GstPad * pad, GstFormat src_format, /* gst_base_audio_decoder_sink_convert (GstPad * pad, GstFormat src_format, */
gint64 src_value, GstFormat * dest_format, gint64 * dest_value) /* gint64 src_value, GstFormat * dest_format, gint64 * dest_value) */
{ /* { */
return TRUE; /* return TRUE; */
} /* } */
/* FIXME: implement (is this really necessary?) */
/* static gboolean */
/* gst_base_audio_decoder_sink_query (GstPad * pad, GstQuery * query) */
/* { */
/* return TRUE; */
/* } */
/* FIXME: implement */
static gboolean static gboolean
gst_base_audio_decoder_sink_query (GstPad * pad, GstQuery * query) gst_base_audio_decoder_reset (GstBaseAudioCodec * base_audio_codec)
{ {
GST_DEBUG ("gst_base_audio_decoder_reset");
return TRUE; return TRUE;
} }
static void static void
gst_base_audio_decoder_reset (GstBaseAudioDecoder * base_audio_decoder) gst_base_audio_decoder_handle_discont (GstBaseAudioDecoder *base_audio_decoder,
GstBuffer *buffer)
{ {
GstBaseAudioCodecClass *base_audio_codec_class;
GstBaseAudioCodec *base_audio_codec; GstBaseAudioCodec *base_audio_codec;
base_audio_codec = GST_BASE_AUDIO_CODEC (base_audio_decoder); base_audio_codec = GST_BASE_AUDIO_CODEC (base_audio_decoder);
base_audio_codec_class = GST_BASE_AUDIO_CODEC_GET_CLASS (base_audio_codec);
GST_DEBUG ("reset"); if (base_audio_codec->started) {
gst_base_audio_codec_reset (base_audio_codec);
if (base_audio_codec_class->reset) {
base_audio_codec_class->reset (base_audio_codec);
} }
} }
@ -402,9 +473,7 @@ gst_base_audio_decoder_chain (GstPad * pad, GstBuffer * buf)
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) { if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
GST_DEBUG_OBJECT (base_audio_decoder, "received DISCONT buffer"); GST_DEBUG_OBJECT (base_audio_decoder, "received DISCONT buffer");
if (base_audio_codec->started) { gst_base_audio_decoder_handle_discont (base_audio_decoder, buf);
gst_base_audio_decoder_reset (base_audio_decoder);
}
} }
if (!base_audio_codec->started) { if (!base_audio_codec->started) {

View file

@ -66,6 +66,7 @@ struct _GstBaseAudioDecoderClass
GstBaseAudioCodecClass base_audio_codec_class; GstBaseAudioCodecClass base_audio_codec_class;
GstFlowReturn (*parse_data) (GstBaseAudioDecoder *decoder); GstFlowReturn (*parse_data) (GstBaseAudioDecoder *decoder);
void (*handle_discont) (GstBaseAudioDecoder *decoder, GstBuffer *buffer);
}; };
GType gst_base_audio_decoder_get_type (void); GType gst_base_audio_decoder_get_type (void);