mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
audio: initial version of GstBaseAudioCodec
Moved most of the code to GstBaseAudioCodec, GstBaseAudioDecode is now really small, maybe we do not really need it (or its encoder counterpart). Added more API for subclasses and documentation.
This commit is contained in:
parent
9740eb35b8
commit
2ed1331f43
2 changed files with 104 additions and 180 deletions
|
@ -1,6 +1,6 @@
|
||||||
/* GStreamer
|
/* GStreamer
|
||||||
* Copyright (C) 2009 Igalia S.L.
|
* Copyright (C) 2009 Igalia S.L.
|
||||||
* Author: Iago Toral <itoral@igalia.com>
|
* Author: Iago Toral Quiroga <itoral@igalia.com>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -28,18 +28,19 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: is still interesting providing sink_query and src_query functions?
|
* FIXME: Do we really need decoder/encoder classes?
|
||||||
|
* FIXME: is it interesting to provide sink_query and src_query functions?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (baseaudio_debug);
|
GST_DEBUG_CATEGORY_EXTERN (baseaudiocodec_debug);
|
||||||
#define GST_CAT_DEFAULT baseaudio_debug
|
#define GST_CAT_DEFAULT baseaudiocodec_debug
|
||||||
|
|
||||||
|
/* ----- Function prototypes ----- */
|
||||||
|
|
||||||
static void gst_base_audio_decoder_finalize (GObject * object);
|
static void gst_base_audio_decoder_finalize (GObject * object);
|
||||||
|
|
||||||
static gboolean gst_base_audio_decoder_src_event (GstPad * pad,
|
static gboolean gst_base_audio_decoder_src_event (GstPad * pad,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
static GstFlowReturn gst_base_audio_decoder_chain (GstPad * pad,
|
|
||||||
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, */
|
||||||
|
@ -52,10 +53,9 @@ 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 gboolean gst_base_audio_decoder_reset (GstBaseAudioCodec *
|
static gboolean gst_base_audio_decoder_reset (GstBaseAudioCodec * codec);
|
||||||
base_audio_codec);
|
|
||||||
static void gst_base_audio_decoder_handle_discont (GstBaseAudioDecoder *
|
/* ----- GObject setup ----- */
|
||||||
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);
|
||||||
|
@ -63,7 +63,6 @@ GST_BOILERPLATE (GstBaseAudioDecoder, gst_base_audio_decoder,
|
||||||
static void
|
static void
|
||||||
gst_base_audio_decoder_base_init (gpointer g_class)
|
gst_base_audio_decoder_base_init (gpointer g_class)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -76,24 +75,20 @@ 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->reset = gst_base_audio_decoder_reset;
|
parent_class->reset = gst_base_audio_decoder_reset;
|
||||||
|
|
||||||
klass->handle_discont = gst_base_audio_decoder_handle_discont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_base_audio_decoder_init (GstBaseAudioDecoder * base_audio_decoder,
|
gst_base_audio_decoder_init (GstBaseAudioDecoder * decoder,
|
||||||
GstBaseAudioDecoderClass * klass)
|
GstBaseAudioDecoderClass * klass)
|
||||||
{
|
{
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
|
|
||||||
GST_DEBUG ("gst_base_audio_decoder_init");
|
GST_DEBUG ("gst_base_audio_decoder_init");
|
||||||
|
|
||||||
pad = GST_BASE_AUDIO_CODEC_SINK_PAD (base_audio_decoder);
|
pad = GST_BASE_AUDIO_CODEC_SINK_PAD (decoder);
|
||||||
|
|
||||||
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 (decoder);
|
||||||
|
|
||||||
gst_pad_set_event_function (pad, gst_base_audio_decoder_src_event);
|
gst_pad_set_event_function (pad, gst_base_audio_decoder_src_event);
|
||||||
gst_pad_set_query_type_function (pad, gst_base_audio_decoder_get_query_types);
|
gst_pad_set_query_type_function (pad, gst_base_audio_decoder_get_query_types);
|
||||||
|
@ -110,6 +105,8 @@ gst_base_audio_decoder_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----- Private element implementation ----- */
|
||||||
|
|
||||||
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)
|
||||||
|
@ -119,7 +116,7 @@ gst_base_audio_decoder_src_convert (GstPad * pad, GstFormat src_format,
|
||||||
gint bytes_per_sample;
|
gint bytes_per_sample;
|
||||||
gint scale = 1;
|
gint scale = 1;
|
||||||
guint byterate;
|
guint byterate;
|
||||||
|
|
||||||
if (src_format == *dest_format || src_value == -1 || src_value == 0) {
|
if (src_format == *dest_format || src_value == -1 || src_value == 0) {
|
||||||
*dest_value = src_value;
|
*dest_value = src_value;
|
||||||
}
|
}
|
||||||
|
@ -131,18 +128,18 @@ gst_base_audio_decoder_src_convert (GstPad * pad, GstFormat src_format,
|
||||||
switch (src_format) {
|
switch (src_format) {
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
switch (*dest_format) {
|
switch (*dest_format) {
|
||||||
case GST_FORMAT_DEFAULT: /* Bytes -> Samples */
|
case GST_FORMAT_DEFAULT: /* Bytes -> Samples */
|
||||||
if (bytes_per_sample == 0)
|
if (bytes_per_sample == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
*dest_value = src_value / bytes_per_sample;
|
*dest_value = src_value / bytes_per_sample;
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_TIME: /* Bytes -> Time */
|
case GST_FORMAT_TIME: /* Bytes -> Time */
|
||||||
byterate = bytes_per_sample * codec->state.rate;
|
byterate = bytes_per_sample * codec->state.rate;
|
||||||
if (byterate == 0)
|
if (byterate == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
*dest_value =
|
*dest_value =
|
||||||
gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
|
gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +149,7 @@ gst_base_audio_decoder_src_convert (GstPad * pad, GstFormat src_format,
|
||||||
case GST_FORMAT_BYTES: /* Samples -> Bytes */
|
case GST_FORMAT_BYTES: /* Samples -> Bytes */
|
||||||
*dest_value = src_value * bytes_per_sample;
|
*dest_value = src_value * bytes_per_sample;
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_TIME: /* Samples -> Time */
|
case GST_FORMAT_TIME: /* Samples -> Time */
|
||||||
if (codec->state.rate == 0)
|
if (codec->state.rate == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
*dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
|
*dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
|
||||||
|
@ -167,7 +164,7 @@ gst_base_audio_decoder_src_convert (GstPad * pad, GstFormat src_format,
|
||||||
case GST_FORMAT_BYTES: /* Time -> Bytes */
|
case GST_FORMAT_BYTES: /* Time -> Bytes */
|
||||||
scale = bytes_per_sample;
|
scale = bytes_per_sample;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case GST_FORMAT_DEFAULT: /* Time -> Samples */
|
case GST_FORMAT_DEFAULT: /* Time -> Samples */
|
||||||
*dest_value = gst_util_uint64_scale_int (src_value,
|
*dest_value = gst_util_uint64_scale_int (src_value,
|
||||||
scale * codec->state.rate, GST_SECOND);
|
scale * codec->state.rate, GST_SECOND);
|
||||||
break;
|
break;
|
||||||
|
@ -184,8 +181,8 @@ gst_base_audio_decoder_src_convert (GstPad * pad, GstFormat src_format,
|
||||||
|
|
||||||
#ifndef GST_DISABLE_INDEX
|
#ifndef GST_DISABLE_INDEX
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_base_audio_decoder_index_seek (GstBaseAudioDecoder *base_audio_decoder,
|
gst_base_audio_decoder_index_seek (GstBaseAudioDecoder * decoder,
|
||||||
GstIndex *index, GstPad * pad, GstEvent * event)
|
GstIndex * index, GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstIndexEntry *entry;
|
GstIndexEntry *entry;
|
||||||
gdouble rate;
|
gdouble rate;
|
||||||
|
@ -194,18 +191,18 @@ gst_base_audio_decoder_index_seek (GstBaseAudioDecoder *base_audio_decoder,
|
||||||
GstSeekType cur_type, stop_type;
|
GstSeekType cur_type, stop_type;
|
||||||
gint64 cur, stop;
|
gint64 cur, stop;
|
||||||
gint index_id;
|
gint index_id;
|
||||||
GstBaseAudioCodec *base_audio_codec;
|
GstBaseAudioCodec *codec;
|
||||||
|
|
||||||
base_audio_codec = GST_BASE_AUDIO_CODEC (base_audio_decoder);
|
codec = GST_BASE_AUDIO_CODEC (decoder);
|
||||||
|
|
||||||
gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
|
gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
|
||||||
&stop_type, &stop);
|
&stop_type, &stop);
|
||||||
|
|
||||||
gst_index_get_writer_id (index, GST_OBJECT (base_audio_decoder), &index_id);
|
gst_index_get_writer_id (index, GST_OBJECT (decoder), &index_id);
|
||||||
entry = gst_index_get_assoc_entry (index, index_id,
|
entry = gst_index_get_assoc_entry (index, index_id,
|
||||||
GST_INDEX_LOOKUP_BEFORE, GST_ASSOCIATION_FLAG_KEY_UNIT, format, cur);
|
GST_INDEX_LOOKUP_BEFORE, GST_ASSOCIATION_FLAG_KEY_UNIT, format, cur);
|
||||||
|
|
||||||
if (entry && gst_pad_is_linked (base_audio_codec->sinkpad)) {
|
if (entry && gst_pad_is_linked (GST_BASE_AUDIO_CODEC_SINK_PAD (codec))) {
|
||||||
const GstFormat *peer_formats, *try_formats;
|
const GstFormat *peer_formats, *try_formats;
|
||||||
|
|
||||||
/* since we know the exact byteoffset of the frame,
|
/* since we know the exact byteoffset of the frame,
|
||||||
|
@ -218,10 +215,11 @@ gst_base_audio_decoder_index_seek (GstBaseAudioDecoder *base_audio_decoder,
|
||||||
|
|
||||||
try_formats = try_all_formats;
|
try_formats = try_all_formats;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* FIXE ME */
|
/* FIXE ME */
|
||||||
peer_formats =
|
peer_formats =
|
||||||
gst_pad_get_formats (GST_PAD_PEER (base_audio_codec->sinkpad));
|
gst_pad_get_formats (GST_PAD_PEER (GST_BASE_AUDIO_CODEC_SINK_PAD
|
||||||
|
(codec)));
|
||||||
#else
|
#else
|
||||||
peer_formats = try_all_formats;
|
peer_formats = try_all_formats;
|
||||||
#endif
|
#endif
|
||||||
|
@ -232,18 +230,17 @@ gst_base_audio_decoder_index_seek (GstBaseAudioDecoder *base_audio_decoder,
|
||||||
if (gst_index_entry_assoc_map (entry, *try_formats, &value)) {
|
if (gst_index_entry_assoc_map (entry, *try_formats, &value)) {
|
||||||
GstEvent *seek_event;
|
GstEvent *seek_event;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base_audio_decoder,
|
GST_DEBUG_OBJECT (decoder,
|
||||||
"index %s %" G_GINT64_FORMAT
|
"index %s %" G_GINT64_FORMAT
|
||||||
" -> %s %" G_GINT64_FORMAT,
|
" -> %s %" G_GINT64_FORMAT,
|
||||||
gst_format_get_details (format)->nick,
|
gst_format_get_details (format)->nick,
|
||||||
cur,
|
cur, gst_format_get_details (*try_formats)->nick, value);
|
||||||
gst_format_get_details (*try_formats)->nick,
|
|
||||||
value);
|
seek_event = gst_event_new_seek (rate, *try_formats, flags,
|
||||||
|
cur_type, value, stop_type, stop);
|
||||||
seek_event = gst_event_new_seek (rate, *try_formats, flags,
|
|
||||||
cur_type, value, stop_type, stop);
|
if (gst_pad_push_event (GST_BASE_AUDIO_CODEC_SINK_PAD (codec),
|
||||||
|
seek_event)) {
|
||||||
if (gst_pad_push_event (base_audio_codec->sinkpad, seek_event)) {
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,8 +254,8 @@ gst_base_audio_decoder_index_seek (GstBaseAudioDecoder *base_audio_decoder,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_base_audio_decoder_normal_seek (GstBaseAudioDecoder *base_audio_decoder,
|
gst_base_audio_decoder_normal_seek (GstBaseAudioDecoder * decoder,
|
||||||
GstPad *pad, GstEvent *event)
|
GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
gdouble rate;
|
gdouble rate;
|
||||||
GstFormat format, conv;
|
GstFormat format, conv;
|
||||||
|
@ -269,15 +266,12 @@ gst_base_audio_decoder_normal_seek (GstBaseAudioDecoder *base_audio_decoder,
|
||||||
gint64 time_stop, bytes_stop;
|
gint64 time_stop, bytes_stop;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
GstEvent *peer_event;
|
GstEvent *peer_event;
|
||||||
GstBaseAudioDecoderClass *base_audio_decoder_class;
|
GstBaseAudioCodec *codec;
|
||||||
GstBaseAudioCodec *base_audio_codec;
|
|
||||||
|
|
||||||
base_audio_codec = GST_BASE_AUDIO_CODEC (base_audio_decoder);
|
codec = GST_BASE_AUDIO_CODEC (decoder);
|
||||||
base_audio_decoder_class =
|
|
||||||
GST_BASE_AUDIO_DECODER_GET_CLASS (base_audio_decoder);
|
|
||||||
|
|
||||||
gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
|
gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
|
||||||
&stop_type, &stop);
|
&stop_type, &stop);
|
||||||
|
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
|
|
||||||
|
@ -285,59 +279,60 @@ gst_base_audio_decoder_normal_seek (GstBaseAudioDecoder *base_audio_decoder,
|
||||||
conv = GST_FORMAT_TIME;
|
conv = GST_FORMAT_TIME;
|
||||||
if (!gst_base_audio_decoder_src_convert (pad, format, cur, &conv, &time_cur))
|
if (!gst_base_audio_decoder_src_convert (pad, format, cur, &conv, &time_cur))
|
||||||
goto convert_failed;
|
goto convert_failed;
|
||||||
if (!gst_base_audio_decoder_src_convert (pad, format, stop, &conv, &time_stop))
|
if (!gst_base_audio_decoder_src_convert (pad, format, stop, &conv,
|
||||||
|
&time_stop))
|
||||||
goto convert_failed;
|
goto convert_failed;
|
||||||
|
|
||||||
GST_DEBUG ("seek to time %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
|
GST_DEBUG ("seek to time %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (time_cur), GST_TIME_ARGS (time_stop));
|
GST_TIME_ARGS (time_cur), GST_TIME_ARGS (time_stop));
|
||||||
|
|
||||||
peer_event = gst_event_new_seek (rate, GST_FORMAT_TIME, flags,
|
peer_event = gst_event_new_seek (rate, GST_FORMAT_TIME, flags,
|
||||||
cur_type, time_cur, stop_type, time_stop);
|
cur_type, time_cur, stop_type, time_stop);
|
||||||
|
|
||||||
res = gst_pad_push_event (base_audio_codec->sinkpad, peer_event);
|
res = gst_pad_push_event (GST_BASE_AUDIO_CODEC_SINK_PAD (codec), peer_event);
|
||||||
|
|
||||||
/* 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_src_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_src_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;
|
||||||
|
|
||||||
peer_event =
|
peer_event =
|
||||||
gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, bytes_cur,
|
gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, bytes_cur,
|
||||||
stop_type, bytes_stop);
|
stop_type, bytes_stop);
|
||||||
|
|
||||||
res = gst_pad_push_event (base_audio_codec->sinkpad, peer_event);
|
res = gst_pad_push_event (GST_BASE_AUDIO_CODEC_SINK_PAD (codec),
|
||||||
|
peer_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
convert_failed:
|
convert_failed:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (base_audio_decoder, "failed to convert format %u", format);
|
GST_DEBUG_OBJECT (decoder, "failed to convert format %u", format);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_base_audio_decoder_seek (GstBaseAudioDecoder *base_audio_decoder,
|
gst_base_audio_decoder_seek (GstBaseAudioDecoder * decoder,
|
||||||
GstPad *pad, GstEvent *event)
|
GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
|
||||||
#ifndef GST_DISABLE_INDEX
|
#ifndef GST_DISABLE_INDEX
|
||||||
GstIndex *index = gst_element_get_index (GST_ELEMENT (base_audio_decoder));
|
GstIndex *index = gst_element_get_index (GST_ELEMENT (decoder));
|
||||||
if (index) {
|
if (index) {
|
||||||
res = gst_base_audio_decoder_index_seek (base_audio_decoder,
|
res = gst_base_audio_decoder_index_seek (decoder, index, pad, event);
|
||||||
index, pad, event);
|
|
||||||
gst_object_unref (index);
|
gst_object_unref (index);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
res = gst_base_audio_decoder_normal_seek (base_audio_decoder, pad, event);
|
res = gst_base_audio_decoder_normal_seek (decoder, pad, event);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -346,28 +341,25 @@ static gboolean
|
||||||
gst_base_audio_decoder_src_event (GstPad * pad, GstEvent * event)
|
gst_base_audio_decoder_src_event (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
gboolean res;
|
gboolean res;
|
||||||
GstBaseAudioDecoder *base_audio_decoder;
|
GstBaseAudioDecoder *decoder;
|
||||||
GstBaseAudioCodec *base_audio_codec;
|
GstBaseAudioCodec *codec;
|
||||||
GstBaseAudioDecoderClass *base_audio_decoder_class;
|
|
||||||
|
decoder = GST_BASE_AUDIO_DECODER (GST_PAD_PARENT (pad));
|
||||||
base_audio_decoder = GST_BASE_AUDIO_DECODER (GST_PAD_PARENT (pad));
|
codec = GST_BASE_AUDIO_CODEC (decoder);
|
||||||
base_audio_codec = GST_BASE_AUDIO_CODEC (base_audio_decoder);
|
|
||||||
base_audio_decoder_class =
|
|
||||||
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 */
|
/* 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 (GST_BASE_AUDIO_CODEC_SINK_PAD (codec), event);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
res = gst_base_audio_decoder_seek (base_audio_decoder, pad, event);
|
res = gst_base_audio_decoder_seek (decoder, pad, 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 (GST_BASE_AUDIO_CODEC_SINK_PAD (codec), event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -391,7 +383,8 @@ gst_base_audio_decoder_src_query (GstPad * pad, GstQuery * query)
|
||||||
|
|
||||||
enc = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
|
enc = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
switch GST_QUERY_TYPE (query) {
|
switch GST_QUERY_TYPE
|
||||||
|
(query) {
|
||||||
case GST_QUERY_CONVERT:
|
case GST_QUERY_CONVERT:
|
||||||
{
|
{
|
||||||
GstFormat src_fmt, dest_fmt;
|
GstFormat src_fmt, dest_fmt;
|
||||||
|
@ -408,8 +401,10 @@ 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;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -426,7 +421,7 @@ error:
|
||||||
/* return TRUE; */
|
/* return TRUE; */
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
/* FIXME: implement (is this really necessary?) */
|
/* FIXME: implement (is this really necessary?) */
|
||||||
/* static gboolean */
|
/* static gboolean */
|
||||||
/* gst_base_audio_decoder_sink_query (GstPad * pad, GstQuery * query) */
|
/* gst_base_audio_decoder_sink_query (GstPad * pad, GstQuery * query) */
|
||||||
/* { */
|
/* { */
|
||||||
|
@ -434,66 +429,8 @@ error:
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_base_audio_decoder_reset (GstBaseAudioCodec * base_audio_codec)
|
gst_base_audio_decoder_reset (GstBaseAudioCodec * codec)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("gst_base_audio_decoder_reset");
|
GST_DEBUG ("gst_base_audio_decoder_reset");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_base_audio_decoder_handle_discont (GstBaseAudioDecoder *base_audio_decoder,
|
|
||||||
GstBuffer *buffer)
|
|
||||||
{
|
|
||||||
GstBaseAudioCodec *base_audio_codec;
|
|
||||||
|
|
||||||
base_audio_codec = GST_BASE_AUDIO_CODEC (base_audio_decoder);
|
|
||||||
|
|
||||||
if (base_audio_codec->started) {
|
|
||||||
gst_base_audio_codec_reset (base_audio_codec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
gst_base_audio_decoder_chain (GstPad * pad, GstBuffer * buf)
|
|
||||||
{
|
|
||||||
GstBaseAudioDecoder *base_audio_decoder;
|
|
||||||
GstBaseAudioCodec *base_audio_codec;
|
|
||||||
GstBaseAudioDecoderClass *base_audio_decoder_class;
|
|
||||||
GstBaseAudioCodecClass *base_audio_codec_class;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
GST_DEBUG ("chain %lld", GST_BUFFER_TIMESTAMP (buf));
|
|
||||||
|
|
||||||
base_audio_decoder = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
|
|
||||||
base_audio_codec = GST_BASE_AUDIO_CODEC (base_audio_decoder);
|
|
||||||
base_audio_decoder_class = GST_BASE_AUDIO_DECODER_GET_CLASS (base_audio_decoder);
|
|
||||||
base_audio_codec_class = GST_BASE_AUDIO_CODEC_GET_CLASS (base_audio_decoder);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base_audio_decoder, "chain");
|
|
||||||
|
|
||||||
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
|
|
||||||
GST_DEBUG_OBJECT (base_audio_decoder, "received DISCONT buffer");
|
|
||||||
gst_base_audio_decoder_handle_discont (base_audio_decoder, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!base_audio_codec->started) {
|
|
||||||
base_audio_codec_class->start (base_audio_codec);
|
|
||||||
base_audio_codec->started = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
base_audio_decoder->offset += GST_BUFFER_SIZE (buf);
|
|
||||||
|
|
||||||
gst_adapter_push (base_audio_codec->input_adapter, buf);
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = base_audio_decoder_class->parse_data (base_audio_decoder);
|
|
||||||
} while (ret == GST_FLOW_OK);
|
|
||||||
|
|
||||||
if (ret == GST_BASE_AUDIO_DECODER_FLOW_NEED_DATA) {
|
|
||||||
gst_object_unref (base_audio_decoder);
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_object_unref (base_audio_decoder);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#warning "You can define GST_USE_UNSTABLE_API to avoid this warning."
|
#warning "You can define GST_USE_UNSTABLE_API to avoid this warning."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gst/audio/gstbaseaudiocodec.h>
|
#include "gstbaseaudiocodec.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -43,30 +43,17 @@ G_BEGIN_DECLS
|
||||||
#define GST_IS_BASE_AUDIO_DECODER_CLASS(obj) \
|
#define GST_IS_BASE_AUDIO_DECODER_CLASS(obj) \
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_AUDIO_DECODER))
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_AUDIO_DECODER))
|
||||||
|
|
||||||
/**
|
|
||||||
* GST_BASE_AUDIO_DECODER_FLOW_NEED_DATA:
|
|
||||||
*
|
|
||||||
* Custom GstFlowReturn value indicating that more data is needed.
|
|
||||||
*/
|
|
||||||
#define GST_BASE_AUDIO_DECODER_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
|
|
||||||
|
|
||||||
typedef struct _GstBaseAudioDecoder GstBaseAudioDecoder;
|
typedef struct _GstBaseAudioDecoder GstBaseAudioDecoder;
|
||||||
typedef struct _GstBaseAudioDecoderClass GstBaseAudioDecoderClass;
|
typedef struct _GstBaseAudioDecoderClass GstBaseAudioDecoderClass;
|
||||||
|
|
||||||
struct _GstBaseAudioDecoder
|
struct _GstBaseAudioDecoder
|
||||||
{
|
{
|
||||||
GstBaseAudioCodec base_audio_codec;
|
GstBaseAudioCodec base_audio_codec;
|
||||||
|
|
||||||
/*< private >*/
|
|
||||||
guint64 offset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstBaseAudioDecoderClass
|
struct _GstBaseAudioDecoderClass
|
||||||
{
|
{
|
||||||
GstBaseAudioCodecClass base_audio_codec_class;
|
GstBaseAudioCodecClass base_audio_codec_class;
|
||||||
|
|
||||||
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