2006-02-13 Tim-Philipp Müller <tim at centricular dot net>
+ * ext/dvdread/dvdreadsrc.c: (gst_dvd_read_src_class_init),
+ (gst_dvd_read_src_get_size), (gst_dvd_read_src_do_seek),
+ (gst_dvd_read_src_do_duration_query):
+ Don't implement GstBaseSrc::get_size or GstBaseSrc::is_seekable,
+ otherwise GstBaseSrc will think we can operate pull_range based,
+ which we don't really, and typefinding will fail miserably.
+ Also, make seeking work somewhat (only works with flumpegdemux
+ at the moment, mpegstream needs fixing for that first).
+
+2006-02-13 Tim-Philipp Müller <tim at centricular dot net>
+
* ext/dvdread/dvdreadsrc.c: (gst_dvd_read_src_read),
(gst_dvd_read_src_create), (gst_dvd_read_src_src_event):
Only allocate buffer once we know exactly how much we need,
GValue * value, GParamSpec * pspec);
static GstEvent *gst_dvd_read_src_make_clut_change_event (GstDvdReadSrc * src,
const guint * clut);
-static gboolean gst_dvd_read_src_get_size (GstBaseSrc * bsrc, guint64 * size);
-static gboolean gst_dvd_read_src_seekable (GstBaseSrc * bsrc);
+static gboolean gst_dvd_read_src_get_size (GstDvdReadSrc * src, gint64 * size);
GST_BOILERPLATE_FULL (GstDvdReadSrc, gst_dvd_read_src, GstPushSrc,
GST_TYPE_PUSH_SRC, gst_dvd_read_src_do_init)
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dvd_read_src_stop);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_dvd_read_src_src_query);
gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_dvd_read_src_src_event);
- gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_dvd_read_src_get_size);
- gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_dvd_read_src_seekable);
gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_dvd_read_src_create);
}
}
static gboolean
-gst_dvd_read_src_seekable (GstBaseSrc * basesrc)
+gst_dvd_read_src_get_size (GstDvdReadSrc * src, gint64 * size)
{
- return TRUE;
-}
-
-static gboolean
-gst_dvd_read_src_get_size (GstBaseSrc * basesrc, guint64 * size)
-{
- GstDvdReadSrc *src = GST_DVD_READ_SRC (basesrc);
gboolean ret = FALSE;
if (src->dvd_title) {
blocks = DVDFileSize (src->dvd_title);
if (blocks >= 0) {
- *size = (guint64) blocks *DVD_VIDEO_LB_LEN;
+ *size = (gint64) blocks *DVD_VIDEO_LB_LEN;
ret = TRUE;
} else {
gint64 new_off, total, cur;
GstFormat format;
GstPad *srcpad;
+ gboolean query_ok;
gdouble rate;
srcpad = GST_BASE_SRC (src)->srcpad;
}
switch (format) {
- case GST_FORMAT_BYTES:{
- new_off /= DVD_VIDEO_LB_LEN;
- format = sector_format;
+ case GST_FORMAT_BYTES:
break;
- }
default:{
if (format != chapter_format &&
format != sector_format &&
}
/* get current offset and length */
- gst_pad_query_duration (srcpad, &format, &total);
- gst_pad_query_position (srcpad, &format, &cur);
+ if (format == GST_FORMAT_BYTES) {
+ GST_OBJECT_LOCK (src);
+ query_ok = gst_dvd_read_src_get_size (src, &total);
+ cur = (gint64) src->cur_pack * DVD_VIDEO_LB_LEN;
+ GST_OBJECT_UNLOCK (src);
+ } else {
+ query_ok = gst_pad_query_duration (srcpad, &format, &total)
+ && gst_pad_query_position (srcpad, &format, &cur);
+ }
+
+ if (!query_ok) {
+ GST_DEBUG_OBJECT (src, "Failed to query duration/position");
+ return FALSE;
+ }
- GST_DEBUG_OBJECT (src, "Current %s: %" G_GINT64_FORMAT,
+ GST_DEBUG_OBJECT (src, "Current %s: %12" G_GINT64_FORMAT,
gst_format_get_name (format), cur);
- GST_DEBUG_OBJECT (src, "Total %s: %" G_GINT64_FORMAT,
+ GST_DEBUG_OBJECT (src, "Total %s: %12" G_GINT64_FORMAT,
gst_format_get_name (format), total);
- if (cur == new_off) {
- GST_DEBUG_OBJECT (src, "We're already at that position!");
- return TRUE;
- }
-
/* get absolute */
switch (cur_type) {
case GST_SEEK_TYPE_SET:
return FALSE;
}
- GST_LOG_OBJECT (src, "Seeking to unit %" G_GINT64_FORMAT, new_off);
+ if (cur == new_off) {
+ GST_DEBUG_OBJECT (src, "We're already at that position!");
+ return TRUE;
+ }
+
+ GST_LOG_OBJECT (src, "Seeking to %s: %12" G_GINT64_FORMAT,
+ gst_format_get_name (format), new_off);
GST_OBJECT_LOCK (src);
if (format == angle_format) {
src->angle = new_off;
- GST_OBJECT_UNLOCK (src);
- return TRUE;
+ goto done;
}
if (format == sector_format) {
src->cur_pack = new_off;
+ } else if (format == GST_FORMAT_BYTES) {
+ src->cur_pack = new_off / DVD_VIDEO_LB_LEN;
+ if ((src->cur_pack * DVD_VIDEO_LB_LEN) != new_off) {
+ GST_LOG_OBJECT (src, "rounded down offset %" G_GINT64_FORMAT " => %"
+ G_GINT64_FORMAT, new_off, (gint64) src->cur_pack * DVD_VIDEO_LB_LEN);
+ }
} else if (format == chapter_format) {
src->cur_pack = 0;
src->chapter = new_off;
if ((flags & GST_SEEK_FLAG_FLUSH) != 0)
src->flush_pend = TRUE;
+done:
+
GST_OBJECT_UNLOCK (src);
return TRUE;
break;
}
case GST_FORMAT_BYTES:{
- guint64 size;
-
- if (!gst_dvd_read_src_get_size (GST_BASE_SRC (src), &size))
+ if (!gst_dvd_read_src_get_size (src, &val))
return FALSE;
-
- val = (gint64) size;
break;
}
default:{