Ported to 0.9. Some issues to be solved yet: 1- set correct timestamps 2- seg fault when eos 3- seek is now disabled
Original commit message from CVS: Ported to 0.9. Some issues to be solved yet: 1- set correct timestamps 2- seg fault when eos 3- seek is now disabled
This commit is contained in:
parent
7a50084e34
commit
5df1c827fb
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
|||||||
|
2005-11-08 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
|
|
||||||
|
configure.ac:
|
||||||
|
PORTED_09:
|
||||||
|
ext/Makefile.am:
|
||||||
|
ext/ivorbis/vorbis.c:
|
||||||
|
ext/ivorbis/vorbisfile.c:
|
||||||
|
Ported to 0.9. Some issues to be solved yet:
|
||||||
|
1- set correct timestamps
|
||||||
|
2- seg fault when eos
|
||||||
|
3- seek is now disabled
|
||||||
|
|
||||||
2005-11-06 Julien MOUTTE <julien@moutte.net>
|
2005-11-06 Julien MOUTTE <julien@moutte.net>
|
||||||
|
|
||||||
* examples/Makefile.am: Cleanup non existing
|
* examples/Makefile.am: Cleanup non existing
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
When porting a plugin start with 0.8 CVS head, not the old code in this module. There are many bugfixes which have gone into 0.8 which you want to keep.
|
When porting a plugin start with 0.8 CVS head, not the old code in this module. There are many bugfixes which have gone into 0.8 which you want to keep.
|
||||||
|
|
||||||
List of ported plugins (update when you commit a ported plugin):
|
List of ported plugins (update when you commit a ported plugin):
|
||||||
|
ivorbis (alima)
|
||||||
gsmdec (alima)
|
gsmdec (alima)
|
||||||
sdl (alima)
|
sdl (alima)
|
||||||
speed (fcarvalho)
|
speed (fcarvalho)
|
||||||
|
14
configure.ac
14
configure.ac
@ -409,6 +409,19 @@ GST_CHECK_FEATURE(SDL, [SDL plug-in], sdlvideosink, [
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl *** ivorbis ***
|
||||||
|
dnl AM_PATH_IVORBIS only takes two options
|
||||||
|
translit(dnm, m, l) AM_CONDITIONAL(USE_IVORBIS, true)
|
||||||
|
GST_CHECK_FEATURE(IVORBIS, [integer vorbis plug-in], ivorbisdec, [
|
||||||
|
IVORBIS_LIBS=
|
||||||
|
IVORBIS_CFLAGS=
|
||||||
|
AC_CHECK_LIB(vorbisidec, vorbis_block_init,
|
||||||
|
[IVORBIS_LIBS=-lvorbisidec
|
||||||
|
HAVE_IVORBIS=yes],
|
||||||
|
HAVE_IVORBIS=no)
|
||||||
|
AC_SUBST(IVORBIS_LIBS)
|
||||||
|
AC_SUBST(IVORBIS_CFLAGS)
|
||||||
|
])
|
||||||
|
|
||||||
dnl *** gsm ***
|
dnl *** gsm ***
|
||||||
translit(dnm, m, l) AM_CONDITIONAL(USE_GSM, true)
|
translit(dnm, m, l) AM_CONDITIONAL(USE_GSM, true)
|
||||||
@ -496,6 +509,7 @@ ext/Makefile
|
|||||||
ext/directfb/Makefile
|
ext/directfb/Makefile
|
||||||
ext/faac/Makefile
|
ext/faac/Makefile
|
||||||
ext/faad/Makefile
|
ext/faad/Makefile
|
||||||
|
ext/ivorbis/Makefile
|
||||||
ext/gsm/Makefile
|
ext/gsm/Makefile
|
||||||
ext/sdl/Makefile
|
ext/sdl/Makefile
|
||||||
docs/Makefile
|
docs/Makefile
|
||||||
|
@ -76,11 +76,11 @@ endif
|
|||||||
HERMES_DIR=
|
HERMES_DIR=
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if USE_IVORBIS
|
if USE_IVORBIS
|
||||||
# IVORBIS_DIR=ivorbis
|
IVORBIS_DIR=ivorbis
|
||||||
# else
|
else
|
||||||
IVORBIS_DIR=
|
IVORBIS_DIR=
|
||||||
# endif
|
endif
|
||||||
|
|
||||||
# if USE_JACK
|
# if USE_JACK
|
||||||
# JACK_DIR=jack
|
# JACK_DIR=jack
|
||||||
|
@ -30,9 +30,6 @@ extern GType ivorbisfile_get_type (void);
|
|||||||
static gboolean
|
static gboolean
|
||||||
plugin_init (GstPlugin * plugin)
|
plugin_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
if (!gst_library_load ("gstbytestream"))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!gst_element_register (plugin, "tremor", GST_RANK_PRIMARY,
|
if (!gst_element_register (plugin, "tremor", GST_RANK_PRIMARY,
|
||||||
ivorbisfile_get_type ()))
|
ivorbisfile_get_type ()))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <tremor/ivorbiscodec.h>
|
#include <tremor/ivorbiscodec.h>
|
||||||
#include <tremor/ivorbisfile.h>
|
#include <tremor/ivorbisfile.h>
|
||||||
#include <gst/bytestream/bytestream.h>
|
#include <gst/base/gstadapter.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (ivorbisfile_debug);
|
GST_DEBUG_CATEGORY_STATIC (ivorbisfile_debug);
|
||||||
#define GST_CAT_DEFAULT ivorbisfile_debug
|
#define GST_CAT_DEFAULT ivorbisfile_debug
|
||||||
@ -48,7 +48,8 @@ struct _Ivorbisfile
|
|||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
GstPad *sinkpad, *srcpad;
|
GstPad *sinkpad, *srcpad;
|
||||||
GstByteStream *bs;
|
GstAdapter *adapter;
|
||||||
|
guint64 adapterOffset;
|
||||||
|
|
||||||
OggVorbis_File vf;
|
OggVorbis_File vf;
|
||||||
gint current_link;
|
gint current_link;
|
||||||
@ -65,6 +66,10 @@ struct _Ivorbisfile
|
|||||||
guint64 total_bytes;
|
guint64 total_bytes;
|
||||||
guint64 offset;
|
guint64 offset;
|
||||||
|
|
||||||
|
gint rate;
|
||||||
|
gint channels;
|
||||||
|
gint width;
|
||||||
|
|
||||||
GstCaps *metadata;
|
GstCaps *metadata;
|
||||||
GstCaps *streaminfo;
|
GstCaps *streaminfo;
|
||||||
};
|
};
|
||||||
@ -109,31 +114,38 @@ static void gst_ivorbisfile_init (Ivorbisfile * ivorbisfile);
|
|||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_ivorbisfile_change_state (GstElement * element, GstStateChange transition);
|
gst_ivorbisfile_change_state (GstElement * element, GstStateChange transition);
|
||||||
|
|
||||||
static const GstFormat *gst_ivorbisfile_get_formats (GstPad * pad);
|
|
||||||
static gboolean gst_ivorbisfile_src_convert (GstPad * pad,
|
static gboolean gst_ivorbisfile_src_convert (GstPad * pad,
|
||||||
GstFormat src_format,
|
GstFormat src_format,
|
||||||
gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
|
gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
|
||||||
static gboolean gst_ivorbisfile_sink_convert (GstPad * pad,
|
static gboolean gst_ivorbisfile_sink_convert (GstPad * pad,
|
||||||
GstFormat src_format,
|
GstFormat src_format,
|
||||||
gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
|
gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
|
||||||
static const GstQueryType *gst_ivorbisfile_get_query_types (GstPad * pad);
|
static const GstQueryType *gst_ivorbisfile_get_src_query_types (GstPad * pad);
|
||||||
|
|
||||||
|
static gboolean gst_ivorbisfile_src_query (GstPad * pad, GstQuery * query);
|
||||||
|
|
||||||
static gboolean gst_ivorbisfile_src_query (GstPad * pad,
|
|
||||||
GstQueryType type, GstFormat * format, gint64 * value);
|
|
||||||
static const GstEventMask *gst_ivorbisfile_get_event_masks (GstPad * pad);
|
|
||||||
static gboolean gst_ivorbisfile_src_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_ivorbisfile_src_event (GstPad * pad, GstEvent * event);
|
||||||
|
|
||||||
|
static gboolean gst_ivorbisfile_sink_event (GstPad * pad, GstEvent * event);
|
||||||
|
|
||||||
|
static const GstQueryType *gst_ivorbisfile_get_sink_query_types (GstPad * pad);
|
||||||
|
|
||||||
|
static gboolean gst_ivorbisfile_sink_query (GstPad * pad, GstQuery * query);
|
||||||
|
|
||||||
static void gst_ivorbisfile_get_property (GObject * object,
|
static void gst_ivorbisfile_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
static void gst_ivorbisfile_set_property (GObject * object,
|
static void gst_ivorbisfile_set_property (GObject * object,
|
||||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static void gst_ivorbisfile_loop (GstElement * element);
|
static gboolean gst_ivorbisfile_sink_activate (GstPad * sinkpad);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_ivorbisfile_sink_activate_pull (GstPad * sinkpad, gboolean active);
|
||||||
|
|
||||||
|
static void gst_ivorbisfile_loop (GstPad * pad);
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
//static guint gst_ivorbisfile_signals[LAST_SIGNAL] = { 0 };
|
|
||||||
|
|
||||||
static GstFormat logical_stream_format;
|
static GstFormat logical_stream_format;
|
||||||
|
|
||||||
GType
|
GType
|
||||||
@ -230,6 +242,9 @@ gst_ivorbisfile_class_init (IvorbisfileClass * klass)
|
|||||||
|
|
||||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
gobject_class->get_property = gst_ivorbisfile_get_property;
|
||||||
|
gobject_class->set_property = gst_ivorbisfile_set_property;
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, ARG_METADATA,
|
g_object_class_install_property (gobject_class, ARG_METADATA,
|
||||||
g_param_spec_boxed ("metadata", "Metadata", "(logical) Stream metadata",
|
g_param_spec_boxed ("metadata", "Metadata", "(logical) Stream metadata",
|
||||||
GST_TYPE_CAPS, G_PARAM_READABLE));
|
GST_TYPE_CAPS, G_PARAM_READABLE));
|
||||||
@ -237,8 +252,6 @@ gst_ivorbisfile_class_init (IvorbisfileClass * klass)
|
|||||||
g_param_spec_boxed ("streaminfo", "stream",
|
g_param_spec_boxed ("streaminfo", "stream",
|
||||||
"(logical) Stream information", GST_TYPE_CAPS, G_PARAM_READABLE));
|
"(logical) Stream information", GST_TYPE_CAPS, G_PARAM_READABLE));
|
||||||
|
|
||||||
gobject_class->get_property = gst_ivorbisfile_get_property;
|
|
||||||
gobject_class->set_property = gst_ivorbisfile_set_property;
|
|
||||||
|
|
||||||
gstelement_class->change_state = gst_ivorbisfile_change_state;
|
gstelement_class->change_state = gst_ivorbisfile_change_state;
|
||||||
}
|
}
|
||||||
@ -249,26 +262,27 @@ gst_ivorbisfile_init (Ivorbisfile * ivorbisfile)
|
|||||||
ivorbisfile->sinkpad = gst_pad_new_from_template (gst_vorbisdec_sink_template,
|
ivorbisfile->sinkpad = gst_pad_new_from_template (gst_vorbisdec_sink_template,
|
||||||
"sink");
|
"sink");
|
||||||
gst_element_add_pad (GST_ELEMENT (ivorbisfile), ivorbisfile->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (ivorbisfile), ivorbisfile->sinkpad);
|
||||||
gst_pad_set_formats_function (ivorbisfile->sinkpad,
|
|
||||||
gst_ivorbisfile_get_formats);
|
|
||||||
gst_pad_set_convert_function (ivorbisfile->sinkpad,
|
|
||||||
gst_ivorbisfile_sink_convert);
|
|
||||||
|
|
||||||
gst_element_set_loop_function (GST_ELEMENT (ivorbisfile),
|
gst_pad_set_query_type_function (ivorbisfile->sinkpad,
|
||||||
gst_ivorbisfile_loop);
|
gst_ivorbisfile_get_sink_query_types);
|
||||||
|
gst_pad_set_query_function (ivorbisfile->sinkpad, gst_ivorbisfile_sink_query);
|
||||||
|
|
||||||
|
gst_pad_set_activate_function (ivorbisfile->sinkpad,
|
||||||
|
gst_ivorbisfile_sink_activate);
|
||||||
|
gst_pad_set_activatepull_function (ivorbisfile->sinkpad,
|
||||||
|
gst_ivorbisfile_sink_activate_pull);
|
||||||
|
|
||||||
|
gst_pad_set_event_function (ivorbisfile->sinkpad, gst_ivorbisfile_sink_event);
|
||||||
|
|
||||||
ivorbisfile->srcpad =
|
ivorbisfile->srcpad =
|
||||||
gst_pad_new_from_template (gst_vorbisdec_src_template, "src");
|
gst_pad_new_from_template (gst_vorbisdec_src_template, "src");
|
||||||
gst_element_add_pad (GST_ELEMENT (ivorbisfile), ivorbisfile->srcpad);
|
gst_element_add_pad (GST_ELEMENT (ivorbisfile), ivorbisfile->srcpad);
|
||||||
gst_pad_set_formats_function (ivorbisfile->srcpad,
|
|
||||||
gst_ivorbisfile_get_formats);
|
|
||||||
gst_pad_set_query_type_function (ivorbisfile->srcpad,
|
gst_pad_set_query_type_function (ivorbisfile->srcpad,
|
||||||
gst_ivorbisfile_get_query_types);
|
gst_ivorbisfile_get_src_query_types);
|
||||||
gst_pad_set_query_function (ivorbisfile->srcpad, gst_ivorbisfile_src_query);
|
gst_pad_set_query_function (ivorbisfile->srcpad, gst_ivorbisfile_src_query);
|
||||||
gst_pad_set_event_mask_function (ivorbisfile->srcpad,
|
|
||||||
gst_ivorbisfile_get_event_masks);
|
|
||||||
gst_pad_set_event_function (ivorbisfile->srcpad, gst_ivorbisfile_src_event);
|
gst_pad_set_event_function (ivorbisfile->srcpad, gst_ivorbisfile_src_event);
|
||||||
gst_pad_set_convert_function (ivorbisfile->srcpad,
|
|
||||||
gst_ivorbisfile_src_convert);
|
|
||||||
|
|
||||||
ivorbisfile->total_bytes = 0;
|
ivorbisfile->total_bytes = 0;
|
||||||
ivorbisfile->offset = 0;
|
ivorbisfile->offset = 0;
|
||||||
@ -277,6 +291,11 @@ gst_ivorbisfile_init (Ivorbisfile * ivorbisfile)
|
|||||||
ivorbisfile->metadata = NULL;
|
ivorbisfile->metadata = NULL;
|
||||||
ivorbisfile->streaminfo = NULL;
|
ivorbisfile->streaminfo = NULL;
|
||||||
ivorbisfile->current_link = -1;
|
ivorbisfile->current_link = -1;
|
||||||
|
|
||||||
|
ivorbisfile->rate = -1;
|
||||||
|
ivorbisfile->channels = -1;
|
||||||
|
ivorbisfile->width = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the next four functions are the ov callbacks we provide to ivorbisfile
|
/* the next four functions are the ov callbacks we provide to ivorbisfile
|
||||||
@ -285,15 +304,15 @@ gst_ivorbisfile_init (Ivorbisfile * ivorbisfile)
|
|||||||
static size_t
|
static size_t
|
||||||
gst_ivorbisfile_read (void *ptr, size_t size, size_t nmemb, void *datasource)
|
gst_ivorbisfile_read (void *ptr, size_t size, size_t nmemb, void *datasource)
|
||||||
{
|
{
|
||||||
guint32 got_bytes = 0;
|
|
||||||
guint8 *data;
|
|
||||||
size_t read_size = size * nmemb;
|
size_t read_size = size * nmemb;
|
||||||
|
GstBuffer *buf = NULL;
|
||||||
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (datasource);
|
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (datasource);
|
||||||
|
size_t ret;
|
||||||
|
|
||||||
GST_DEBUG ("read %d", read_size);
|
GST_DEBUG ("read %d", read_size);
|
||||||
|
|
||||||
/* make sure we don't go to EOS */
|
/* make sure we don't go to EOS */
|
||||||
|
|
||||||
if (!ivorbisfile->may_eos && ivorbisfile->total_bytes &&
|
if (!ivorbisfile->may_eos && ivorbisfile->total_bytes &&
|
||||||
ivorbisfile->offset + read_size > ivorbisfile->total_bytes) {
|
ivorbisfile->offset + read_size > ivorbisfile->total_bytes) {
|
||||||
read_size = ivorbisfile->total_bytes - ivorbisfile->offset;
|
read_size = ivorbisfile->total_bytes - ivorbisfile->offset;
|
||||||
@ -302,50 +321,25 @@ gst_ivorbisfile_read (void *ptr, size_t size, size_t nmemb, void *datasource)
|
|||||||
if (read_size == 0 || ivorbisfile->eos)
|
if (read_size == 0 || ivorbisfile->eos)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (got_bytes == 0) {
|
if (GST_FLOW_OK != gst_pad_pull_range (ivorbisfile->sinkpad,
|
||||||
got_bytes = gst_bytestream_peek_bytes (ivorbisfile->bs, &data, read_size);
|
ivorbisfile->offset, read_size, &buf)) {
|
||||||
if (got_bytes < read_size) {
|
|
||||||
GstEvent *event;
|
|
||||||
guint32 avail;
|
|
||||||
|
|
||||||
gst_bytestream_get_status (ivorbisfile->bs, &avail, &event);
|
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
|
||||||
case GST_EVENT_EOS:
|
|
||||||
GST_DEBUG ("eos");
|
|
||||||
ivorbisfile->eos = TRUE;
|
|
||||||
if (avail == 0) {
|
|
||||||
gst_event_unref (event);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case GST_EVENT_DISCONTINUOUS:
|
|
||||||
GST_DEBUG ("discont");
|
|
||||||
ivorbisfile->need_discont = TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gst_event_unref (event);
|
|
||||||
if (avail > 0)
|
|
||||||
got_bytes = gst_bytestream_peek_bytes (ivorbisfile->bs, &data, avail);
|
|
||||||
else
|
|
||||||
got_bytes = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (ptr, data, got_bytes);
|
memcpy (ptr, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
||||||
gst_bytestream_flush_fast (ivorbisfile->bs, got_bytes);
|
|
||||||
|
|
||||||
ivorbisfile->offset += got_bytes;
|
ivorbisfile->offset += GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
return got_bytes / size;
|
ret = GST_BUFFER_SIZE (buf) / size;
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gst_ivorbisfile_seek (void *datasource, int64_t offset, int whence)
|
gst_ivorbisfile_seek (void *datasource, int64_t offset, int whence)
|
||||||
{
|
{
|
||||||
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (datasource);
|
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (datasource);
|
||||||
GstSeekType method;
|
|
||||||
guint64 pending_offset = ivorbisfile->offset;
|
guint64 pending_offset = ivorbisfile->offset;
|
||||||
gboolean need_total = FALSE;
|
gboolean need_total = FALSE;
|
||||||
|
|
||||||
@ -357,24 +351,22 @@ gst_ivorbisfile_seek (void *datasource, int64_t offset, int whence)
|
|||||||
GST_DEBUG ("seek %" G_GINT64_FORMAT " %d", offset, whence);
|
GST_DEBUG ("seek %" G_GINT64_FORMAT " %d", offset, whence);
|
||||||
|
|
||||||
if (whence == SEEK_SET) {
|
if (whence == SEEK_SET) {
|
||||||
method = GST_SEEK_METHOD_SET;
|
|
||||||
pending_offset = offset;
|
pending_offset = offset;
|
||||||
|
ivorbisfile->adapterOffset = offset;
|
||||||
} else if (whence == SEEK_CUR) {
|
} else if (whence == SEEK_CUR) {
|
||||||
method = GST_SEEK_METHOD_CUR;
|
|
||||||
pending_offset += offset;
|
pending_offset += offset;
|
||||||
|
ivorbisfile->adapterOffset += offset;
|
||||||
} else if (whence == SEEK_END) {
|
} else if (whence == SEEK_END) {
|
||||||
method = GST_SEEK_METHOD_END;
|
|
||||||
need_total = TRUE;
|
need_total = TRUE;
|
||||||
pending_offset = ivorbisfile->total_bytes - offset;
|
pending_offset = ivorbisfile->total_bytes - offset;
|
||||||
|
ivorbisfile->adapterOffset = ivorbisfile->total_bytes - offset;
|
||||||
} else
|
} else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!gst_bytestream_seek (ivorbisfile->bs, offset, method))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ivorbisfile->offset = pending_offset;
|
ivorbisfile->offset = pending_offset;
|
||||||
if (need_total)
|
if (need_total)
|
||||||
ivorbisfile->total_bytes = gst_bytestream_tell (ivorbisfile->bs) + offset;
|
ivorbisfile->total_bytes = ivorbisfile->adapterOffset + offset;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -392,7 +384,7 @@ gst_ivorbisfile_tell (void *datasource)
|
|||||||
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (datasource);
|
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (datasource);
|
||||||
long result;
|
long result;
|
||||||
|
|
||||||
result = gst_bytestream_tell (ivorbisfile->bs);
|
result = ivorbisfile->adapterOffset;
|
||||||
|
|
||||||
GST_DEBUG ("tell %ld", result);
|
GST_DEBUG ("tell %ld", result);
|
||||||
|
|
||||||
@ -513,40 +505,89 @@ gst_ivorbisfile_new_link (Ivorbisfile * ivorbisfile, gint link)
|
|||||||
"depth", G_TYPE_INT, 16,
|
"depth", G_TYPE_INT, 16,
|
||||||
"rate", G_TYPE_INT, vi->rate, "channels", G_TYPE_INT, vi->channels, NULL);
|
"rate", G_TYPE_INT, vi->rate, "channels", G_TYPE_INT, vi->channels, NULL);
|
||||||
|
|
||||||
if (gst_pad_try_set_caps (ivorbisfile->srcpad, caps) <= 0) {
|
ivorbisfile->rate = vi->rate;
|
||||||
|
ivorbisfile->channels = vi->channels;
|
||||||
|
ivorbisfile->width = 16;
|
||||||
|
|
||||||
|
if (gst_pad_set_caps (ivorbisfile->srcpad, caps) <= 0) {
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_caps_free (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_ivorbisfile_loop (GstElement * element)
|
static gboolean
|
||||||
|
gst_ivorbisfile_sink_activate (GstPad * sinkpad)
|
||||||
{
|
{
|
||||||
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (element);
|
|
||||||
|
Ivorbisfile *ivorbisfile;
|
||||||
|
|
||||||
|
ivorbisfile = GST_IVORBISFILE (GST_PAD_PARENT (sinkpad));
|
||||||
|
|
||||||
|
if (gst_pad_check_pull_range (sinkpad)) {
|
||||||
|
/* FIX ME */
|
||||||
|
/* ivorbisfile->vf.seekable = TRUE; */
|
||||||
|
ivorbisfile->vf.seekable = FALSE;
|
||||||
|
return gst_pad_activate_pull (sinkpad, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ivorbisfile->vf.seekable = FALSE;
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_ivorbisfile_sink_activate_pull (GstPad * sinkpad, gboolean active)
|
||||||
|
{
|
||||||
|
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
/* if we have a scheduler we can start the task */
|
||||||
|
result = gst_pad_start_task (sinkpad,
|
||||||
|
(GstTaskFunction) gst_ivorbisfile_loop, sinkpad);
|
||||||
|
} else {
|
||||||
|
result = gst_pad_stop_task (sinkpad);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ivorbisfile_loop (GstPad * pad)
|
||||||
|
{
|
||||||
|
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (GST_PAD_PARENT (pad));
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
long ret;
|
long ret;
|
||||||
GstClockTime time;
|
GstClockTime time;
|
||||||
gint64 samples;
|
gint64 samples;
|
||||||
gint link;
|
gint link;
|
||||||
|
|
||||||
|
if (ivorbisfile->eos)
|
||||||
|
return;
|
||||||
|
|
||||||
/* this function needs to go first since you don't want to be messing
|
/* this function needs to go first since you don't want to be messing
|
||||||
* with an unset vf ;) */
|
* with an unset vf ;) */
|
||||||
if (ivorbisfile->restart) {
|
if (ivorbisfile->restart) {
|
||||||
|
|
||||||
ivorbisfile->offset = 0;
|
ivorbisfile->offset = 0;
|
||||||
ivorbisfile->total_bytes = 0;
|
ivorbisfile->total_bytes = 0;
|
||||||
ivorbisfile->may_eos = FALSE;
|
ivorbisfile->may_eos = FALSE;
|
||||||
ivorbisfile->vf.seekable = gst_bytestream_seek (ivorbisfile->bs, 0,
|
ivorbisfile->adapterOffset = 0;
|
||||||
GST_SEEK_METHOD_SET);
|
|
||||||
GST_DEBUG ("ivorbisfile: seekable: %s\n",
|
GST_DEBUG ("ivorbisfile: seekable: %s\n",
|
||||||
ivorbisfile->vf.seekable ? "yes" : "no");
|
ivorbisfile->vf.seekable ? "yes" : "no");
|
||||||
|
|
||||||
/* open our custom ivorbisfile data object with the callbacks we provide */
|
/* open our custom ivorbisfile data object with the callbacks we provide */
|
||||||
if (ov_open_callbacks (ivorbisfile, &ivorbisfile->vf, NULL, 0,
|
if (ov_open_callbacks (ivorbisfile, &ivorbisfile->vf, NULL, 0,
|
||||||
ivorbisfile_ov_callbacks) < 0) {
|
ivorbisfile_ov_callbacks) < 0) {
|
||||||
GST_ELEMENT_ERROR (element, STREAM, DECODE, (NULL), (NULL));
|
GST_ELEMENT_ERROR (ivorbisfile, STREAM, DECODE, (NULL), (NULL));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ivorbisfile->need_discont = TRUE;
|
ivorbisfile->need_discont = TRUE;
|
||||||
@ -615,24 +656,21 @@ gst_ivorbisfile_loop (GstElement * element)
|
|||||||
GST_BUFFER_DATA (outbuf) = g_malloc (4096);
|
GST_BUFFER_DATA (outbuf) = g_malloc (4096);
|
||||||
GST_BUFFER_SIZE (outbuf) = 4096;
|
GST_BUFFER_SIZE (outbuf) = 4096;
|
||||||
|
|
||||||
|
ret = ov_read (&ivorbisfile->vf,
|
||||||
|
(char *) GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf), &link);
|
||||||
|
|
||||||
/* get current time for discont and buffer timestamp */
|
/* get current time for discont and buffer timestamp */
|
||||||
time = (GstClockTime) (ov_time_tell (&ivorbisfile->vf) * GST_SECOND);
|
time = (GstClockTime) (ov_time_tell (&ivorbisfile->vf) * GST_SECOND);
|
||||||
|
|
||||||
ret = ov_read (&ivorbisfile->vf,
|
|
||||||
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf), &link);
|
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
GST_DEBUG ("eos");
|
GST_DEBUG ("eos");
|
||||||
/* send EOS event */
|
/* send EOS event */
|
||||||
/*ov_clear (&ivorbisfile->vf); */
|
|
||||||
ivorbisfile->restart = TRUE;
|
ivorbisfile->restart = TRUE;
|
||||||
gst_buffer_unref (outbuf);
|
gst_buffer_unref (outbuf);
|
||||||
/* if the pad is not usable, don't push it out */
|
/* if the pad is not usable, don't push it out */
|
||||||
if (GST_PAD_IS_USABLE (ivorbisfile->srcpad)) {
|
gst_pad_push_event (ivorbisfile->srcpad, gst_event_new_eos ());
|
||||||
gst_pad_push (ivorbisfile->srcpad,
|
|
||||||
GST_DATA (gst_event_new (GST_EVENT_EOS)));
|
|
||||||
}
|
|
||||||
gst_element_set_eos (element);
|
|
||||||
return;
|
return;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
g_warning ("ivorbisfile: decoding error");
|
g_warning ("ivorbisfile: decoding error");
|
||||||
@ -640,24 +678,30 @@ gst_ivorbisfile_loop (GstElement * element)
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (ivorbisfile->need_discont) {
|
if (ivorbisfile->need_discont) {
|
||||||
GstEvent *discont;
|
GstEvent *event;
|
||||||
|
|
||||||
ivorbisfile->need_discont = FALSE;
|
ivorbisfile->need_discont = FALSE;
|
||||||
|
|
||||||
/* if the pad is not usable, don't push it out */
|
|
||||||
if (GST_PAD_IS_USABLE (ivorbisfile->srcpad)) {
|
|
||||||
/* get stream stats */
|
/* get stream stats */
|
||||||
samples = (gint64) (ov_pcm_tell (&ivorbisfile->vf));
|
samples = (gint64) (ov_pcm_tell (&ivorbisfile->vf));
|
||||||
|
|
||||||
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time,
|
event =
|
||||||
GST_FORMAT_DEFAULT, samples, NULL);
|
gst_event_new_newsegment (FALSE, 1.0, GST_FORMAT_TIME, time,
|
||||||
|
GST_CLOCK_TIME_NONE, 0);
|
||||||
|
|
||||||
|
gst_pad_push_event (ivorbisfile->srcpad, event);
|
||||||
|
|
||||||
gst_pad_push (ivorbisfile->srcpad, GST_DATA (discont));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (ivorbisfile->srcpad));
|
||||||
|
|
||||||
GST_BUFFER_SIZE (outbuf) = ret;
|
GST_BUFFER_SIZE (outbuf) = ret;
|
||||||
|
/* FIX ME TO SET RIGHT TIMESTAMP
|
||||||
|
gint bufsize = ret / (ivorbisfile->width / 8);
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = time;
|
GST_BUFFER_TIMESTAMP (outbuf) = time;
|
||||||
|
GST_BUFFER_DURATION (outbuf) = GST_SECOND * bufsize / (ivorbisfile->rate * ivorbisfile->channels);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
ivorbisfile->may_eos = TRUE;
|
ivorbisfile->may_eos = TRUE;
|
||||||
|
|
||||||
@ -665,34 +709,10 @@ gst_ivorbisfile_loop (GstElement * element)
|
|||||||
ivorbisfile->total_bytes += GST_BUFFER_SIZE (outbuf);
|
ivorbisfile->total_bytes += GST_BUFFER_SIZE (outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_PAD_IS_USABLE (ivorbisfile->srcpad))
|
gst_pad_push (ivorbisfile->srcpad, outbuf);
|
||||||
gst_pad_push (ivorbisfile->srcpad, GST_DATA (outbuf));
|
|
||||||
else
|
|
||||||
gst_buffer_unref (outbuf);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static const GstFormat *
|
|
||||||
gst_ivorbisfile_get_formats (GstPad * pad)
|
|
||||||
{
|
|
||||||
static GstFormat src_formats[] = {
|
|
||||||
GST_FORMAT_TIME,
|
|
||||||
GST_FORMAT_BYTES,
|
|
||||||
GST_FORMAT_DEFAULT,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
static GstFormat sink_formats[] = {
|
|
||||||
GST_FORMAT_TIME,
|
|
||||||
GST_FORMAT_BYTES,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
src_formats[3] = logical_stream_format;
|
|
||||||
sink_formats[2] = logical_stream_format;
|
|
||||||
|
|
||||||
return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -706,7 +726,7 @@ gst_ivorbisfile_src_convert (GstPad * pad,
|
|||||||
Ivorbisfile *ivorbisfile;
|
Ivorbisfile *ivorbisfile;
|
||||||
vorbis_info *vi;
|
vorbis_info *vi;
|
||||||
|
|
||||||
ivorbisfile = GST_IVORBISFILE (gst_pad_get_parent (pad));
|
ivorbisfile = GST_IVORBISFILE (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
vi = ov_info (&ivorbisfile->vf, -1);
|
vi = ov_info (&ivorbisfile->vf, -1);
|
||||||
bytes_per_sample = vi->channels * 2;
|
bytes_per_sample = vi->channels * 2;
|
||||||
@ -803,6 +823,32 @@ gst_ivorbisfile_src_convert (GstPad * pad,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_ivorbisfile_sink_query (GstPad * pad, GstQuery * query)
|
||||||
|
{
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
|
case GST_QUERY_CONVERT:
|
||||||
|
{
|
||||||
|
GstFormat src_fmt, dest_fmt;
|
||||||
|
gint64 src_val, dest_val;
|
||||||
|
|
||||||
|
/* peel off input */
|
||||||
|
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
|
||||||
|
if ((res = gst_ivorbisfile_sink_convert (pad, src_fmt, src_val,
|
||||||
|
&dest_fmt, &dest_val))) {
|
||||||
|
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ivorbisfile_sink_convert (GstPad * pad,
|
gst_ivorbisfile_sink_convert (GstPad * pad,
|
||||||
GstFormat src_format, gint64 src_value,
|
GstFormat src_format, gint64 src_value,
|
||||||
@ -811,7 +857,7 @@ gst_ivorbisfile_sink_convert (GstPad * pad,
|
|||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
Ivorbisfile *ivorbisfile;
|
Ivorbisfile *ivorbisfile;
|
||||||
|
|
||||||
ivorbisfile = GST_IVORBISFILE (gst_pad_get_parent (pad));
|
ivorbisfile = GST_IVORBISFILE (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
switch (src_format) {
|
switch (src_format) {
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
@ -851,11 +897,23 @@ gst_ivorbisfile_sink_convert (GstPad * pad,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const GstQueryType *
|
static const GstQueryType *
|
||||||
gst_ivorbisfile_get_query_types (GstPad * pad)
|
gst_ivorbisfile_get_sink_query_types (GstPad * pad)
|
||||||
|
{
|
||||||
|
static const GstQueryType types[] = {
|
||||||
|
GST_QUERY_CONVERT,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GstQueryType *
|
||||||
|
gst_ivorbisfile_get_src_query_types (GstPad * pad)
|
||||||
{
|
{
|
||||||
static const GstQueryType types[] = {
|
static const GstQueryType types[] = {
|
||||||
GST_QUERY_TOTAL,
|
|
||||||
GST_QUERY_POSITION,
|
GST_QUERY_POSITION,
|
||||||
|
GST_QUERY_DURATION,
|
||||||
|
GST_QUERY_CONVERT,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -864,103 +922,194 @@ gst_ivorbisfile_get_query_types (GstPad * pad)
|
|||||||
|
|
||||||
/* handles queries for location in the stream in the requested format */
|
/* handles queries for location in the stream in the requested format */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ivorbisfile_src_query (GstPad * pad, GstQueryType type,
|
gst_ivorbisfile_src_query (GstPad * pad, GstQuery * query)
|
||||||
GstFormat * format, gint64 * value)
|
|
||||||
{
|
{
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
Ivorbisfile *ivorbisfile;
|
Ivorbisfile *ivorbisfile;
|
||||||
vorbis_info *vi;
|
vorbis_info *vi;
|
||||||
|
|
||||||
ivorbisfile = GST_IVORBISFILE (gst_pad_get_parent (pad));
|
ivorbisfile = GST_IVORBISFILE (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
vi = ov_info (&ivorbisfile->vf, -1);
|
vi = ov_info (&ivorbisfile->vf, -1);
|
||||||
|
|
||||||
switch (type) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
case GST_QUERY_TOTAL:
|
case GST_QUERY_POSITION:
|
||||||
{
|
{
|
||||||
switch (*format) {
|
|
||||||
|
GstFormat format;
|
||||||
|
GstFormat rformat = GST_FORMAT_TIME;
|
||||||
|
gint64 cur;
|
||||||
|
GstPad *peer;
|
||||||
|
|
||||||
|
/* save requested format */
|
||||||
|
gst_query_parse_position (query, &format, NULL);
|
||||||
|
|
||||||
|
/* query peer for current position in time */
|
||||||
|
gst_query_set_position (query, GST_FORMAT_TIME, -1);
|
||||||
|
|
||||||
|
if ((peer = gst_pad_get_peer (ivorbisfile->sinkpad)) == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!gst_pad_query_position (peer, &rformat, &cur)) {
|
||||||
|
GST_LOG_OBJECT (ivorbisfile, "query on peer pad failed");
|
||||||
|
gst_object_unref (peer);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
gst_object_unref (peer);
|
||||||
|
|
||||||
|
if (format != rformat) {
|
||||||
|
gst_ivorbisfile_src_convert (pad, rformat, cur, &format, &cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
if (ivorbisfile->vf.seekable)
|
if (ivorbisfile->vf.seekable)
|
||||||
*value = ov_pcm_total (&ivorbisfile->vf, -1);
|
cur = ov_pcm_tell (&ivorbisfile->vf);
|
||||||
else
|
else
|
||||||
return FALSE;
|
cur = ivorbisfile->total_bytes / (vi->channels * 2);
|
||||||
break;
|
|
||||||
case GST_FORMAT_BYTES:
|
|
||||||
if (ivorbisfile->vf.seekable)
|
|
||||||
*value = ov_pcm_total (&ivorbisfile->vf, -1) * vi->channels * 2;
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
if (ivorbisfile->vf.seekable)
|
if (ivorbisfile->vf.seekable)
|
||||||
*value =
|
cur = (gint64) (ov_time_tell (&ivorbisfile->vf) * GST_SECOND);
|
||||||
(gint64) (ov_time_total (&ivorbisfile->vf, -1) * GST_SECOND);
|
|
||||||
else
|
else
|
||||||
return FALSE;
|
cur = ivorbisfile->total_bytes * GST_SECOND
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (*format == logical_stream_format) {
|
|
||||||
if (ivorbisfile->vf.seekable)
|
|
||||||
*value = ivorbisfile->vf.links;
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
} else
|
|
||||||
res = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GST_QUERY_POSITION:
|
|
||||||
switch (*format) {
|
|
||||||
case GST_FORMAT_TIME:
|
|
||||||
if (ivorbisfile->vf.seekable)
|
|
||||||
*value = (gint64) (ov_time_tell (&ivorbisfile->vf) * GST_SECOND);
|
|
||||||
else
|
|
||||||
*value = ivorbisfile->total_bytes * GST_SECOND
|
|
||||||
/ (vi->rate * vi->channels * 2);
|
/ (vi->rate * vi->channels * 2);
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
if (ivorbisfile->vf.seekable)
|
if (ivorbisfile->vf.seekable)
|
||||||
*value = ov_pcm_tell (&ivorbisfile->vf) * vi->channels * 2;
|
cur = ov_pcm_tell (&ivorbisfile->vf) * vi->channels * 2;
|
||||||
else
|
else
|
||||||
*value = ivorbisfile->total_bytes;
|
cur = ivorbisfile->total_bytes;
|
||||||
break;
|
|
||||||
case GST_FORMAT_DEFAULT:
|
|
||||||
if (ivorbisfile->vf.seekable)
|
|
||||||
*value = ov_pcm_tell (&ivorbisfile->vf);
|
|
||||||
else
|
|
||||||
*value = ivorbisfile->total_bytes / (vi->channels * 2);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (*format == logical_stream_format) {
|
if (format == logical_stream_format) {
|
||||||
if (ivorbisfile->vf.seekable)
|
if (ivorbisfile->vf.seekable)
|
||||||
*value = ivorbisfile->current_link;
|
cur = ivorbisfile->current_link;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else
|
} else
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_query_set_position (query, format, cur);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case GST_QUERY_DURATION:
|
||||||
|
{
|
||||||
|
|
||||||
|
GstFormat format;
|
||||||
|
GstFormat rformat = GST_FORMAT_TIME;
|
||||||
|
gint64 cur;
|
||||||
|
GstPad *peer;
|
||||||
|
|
||||||
|
/* save requested format */
|
||||||
|
gst_query_parse_position (query, &format, NULL);
|
||||||
|
|
||||||
|
/* query peer for current position in time */
|
||||||
|
gst_query_set_position (query, GST_FORMAT_TIME, -1);
|
||||||
|
|
||||||
|
if ((peer = gst_pad_get_peer (ivorbisfile->sinkpad)) == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!gst_pad_query_position (peer, &rformat, &cur)) {
|
||||||
|
GST_LOG_OBJECT (ivorbisfile, "query on peer pad failed");
|
||||||
|
gst_object_unref (peer);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
gst_object_unref (peer);
|
||||||
|
|
||||||
|
if (format != rformat) {
|
||||||
|
gst_ivorbisfile_src_convert (pad, rformat, cur, &format, &cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case GST_FORMAT_DEFAULT:
|
||||||
|
if (ivorbisfile->vf.seekable)
|
||||||
|
cur = ov_pcm_total (&ivorbisfile->vf, -1);
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
case GST_FORMAT_BYTES:
|
||||||
|
if (ivorbisfile->vf.seekable)
|
||||||
|
cur = ov_pcm_total (&ivorbisfile->vf, -1) * vi->channels * 2;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
case GST_FORMAT_TIME:
|
||||||
|
if (ivorbisfile->vf.seekable)
|
||||||
|
cur = (gint64) (ov_time_total (&ivorbisfile->vf, -1) * GST_SECOND);
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (format == logical_stream_format) {
|
||||||
|
if (ivorbisfile->vf.seekable)
|
||||||
|
cur = ivorbisfile->vf.links;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
} else
|
||||||
|
res = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_query_set_position (query, format, cur);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GST_QUERY_CONVERT:
|
||||||
|
{
|
||||||
|
GstFormat src_fmt, dest_fmt;
|
||||||
|
gint64 src_val, dest_val;
|
||||||
|
|
||||||
|
/* peel off input */
|
||||||
|
gst_query_parse_convert (query, &src_fmt, &src_val, NULL, NULL);
|
||||||
|
if ((res = gst_ivorbisfile_src_convert (pad, src_fmt, src_val,
|
||||||
|
&dest_fmt, &dest_val))) {
|
||||||
|
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
error:
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GstEventMask *
|
|
||||||
gst_ivorbisfile_get_event_masks (GstPad * pad)
|
static gboolean
|
||||||
|
gst_ivorbisfile_sink_event (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
static const GstEventMask masks[] = {
|
|
||||||
{GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_FLAG_ACCURATE},
|
|
||||||
{0,}
|
|
||||||
};
|
|
||||||
|
|
||||||
return masks;
|
Ivorbisfile *ivorbisfile;
|
||||||
|
|
||||||
|
ivorbisfile = GST_IVORBISFILE (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_EOS:
|
||||||
|
GST_DEBUG ("eos");
|
||||||
|
ov_clear (&ivorbisfile->vf);
|
||||||
|
ivorbisfile->eos = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_EVENT_NEWSEGMENT:
|
||||||
|
GST_DEBUG ("discont");
|
||||||
|
ivorbisfile->need_discont = TRUE;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gst_pad_event_default (pad, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* handle events on src pad */
|
/* handle events on src pad */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ivorbisfile_src_event (GstPad * pad, GstEvent * event)
|
gst_ivorbisfile_src_event (GstPad * pad, GstEvent * event)
|
||||||
@ -976,6 +1125,7 @@ gst_ivorbisfile_src_event (GstPad * pad, GstEvent * event)
|
|||||||
gint64 offset;
|
gint64 offset;
|
||||||
vorbis_info *vi;
|
vorbis_info *vi;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
|
GstSeekFlags flags;
|
||||||
|
|
||||||
GST_DEBUG ("ivorbisfile: handling seek event on pad %s:%s",
|
GST_DEBUG ("ivorbisfile: handling seek event on pad %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (pad));
|
GST_DEBUG_PAD_NAME (pad));
|
||||||
@ -985,16 +1135,15 @@ gst_ivorbisfile_src_event (GstPad * pad, GstEvent * event)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = GST_EVENT_SEEK_OFFSET (event);
|
gst_event_parse_seek (event, NULL, &format, &flags, NULL, &offset, NULL,
|
||||||
format = GST_EVENT_SEEK_FORMAT (event);
|
NULL);
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
ivorbisfile->seek_pending = TRUE;
|
ivorbisfile->seek_pending = TRUE;
|
||||||
ivorbisfile->seek_value = offset;
|
ivorbisfile->seek_value = offset;
|
||||||
ivorbisfile->seek_format = format;
|
ivorbisfile->seek_format = format;
|
||||||
ivorbisfile->seek_accurate = GST_EVENT_SEEK_FLAGS (event)
|
ivorbisfile->seek_accurate = flags & GST_SEEK_FLAG_ACCURATE;
|
||||||
& GST_SEEK_FLAG_ACCURATE;
|
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
vi = ov_info (&ivorbisfile->vf, -1);
|
vi = ov_info (&ivorbisfile->vf, -1);
|
||||||
@ -1009,16 +1158,14 @@ gst_ivorbisfile_src_event (GstPad * pad, GstEvent * event)
|
|||||||
ivorbisfile->seek_pending = TRUE;
|
ivorbisfile->seek_pending = TRUE;
|
||||||
ivorbisfile->seek_value = offset;
|
ivorbisfile->seek_value = offset;
|
||||||
ivorbisfile->seek_format = format;
|
ivorbisfile->seek_format = format;
|
||||||
ivorbisfile->seek_accurate = GST_EVENT_SEEK_FLAGS (event)
|
ivorbisfile->seek_accurate = flags & GST_SEEK_FLAG_ACCURATE;
|
||||||
& GST_SEEK_FLAG_ACCURATE;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (format == logical_stream_format) {
|
if (format == logical_stream_format) {
|
||||||
ivorbisfile->seek_pending = TRUE;
|
ivorbisfile->seek_pending = TRUE;
|
||||||
ivorbisfile->seek_value = offset;
|
ivorbisfile->seek_value = offset;
|
||||||
ivorbisfile->seek_format = format;
|
ivorbisfile->seek_format = format;
|
||||||
ivorbisfile->seek_accurate = GST_EVENT_SEEK_FLAGS (event)
|
ivorbisfile->seek_accurate = flags & GST_SEEK_FLAG_ACCURATE;
|
||||||
& GST_SEEK_FLAG_ACCURATE;
|
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("unhandled seek format");
|
GST_DEBUG ("unhandled seek format");
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
@ -1040,31 +1187,39 @@ done:
|
|||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_ivorbisfile_change_state (GstElement * element, GstStateChange transition)
|
gst_ivorbisfile_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (element);
|
Ivorbisfile *ivorbisfile = GST_IVORBISFILE (element);
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
|
/* fall through */
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
ivorbisfile->restart = TRUE;
|
ivorbisfile->restart = TRUE;
|
||||||
ivorbisfile->bs = gst_bytestream_new (ivorbisfile->sinkpad);
|
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||||
ivorbisfile->eos = FALSE;
|
ivorbisfile->eos = FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
||||||
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
|
|
||||||
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
ov_clear (&ivorbisfile->vf);
|
ov_clear (&ivorbisfile->vf);
|
||||||
gst_bytestream_destroy (ivorbisfile->bs);
|
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
|
||||||
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
|
||||||
|
|
||||||
return GST_STATE_CHANGE_SUCCESS;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user