mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +00:00
Added src_queries to decoder class. Added handle_discont to decoder
class. Reworked reset. Various other minor fixes.
This commit is contained in:
parent
d05c805b16
commit
9740eb35b8
2 changed files with 112 additions and 42 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue