From 1db592839e1cb07fca7bbd3f2878e76bfb154ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 16 Jun 2009 01:40:42 +0100 Subject: [PATCH] mp3parse: assume seekability only if we know the upstream size While technically upstream may be seekable even if it doesn't know the exact size, I can't think of a use case where this distincation is relevant in practice, so for now just assume we're not seekable if upstream doesn't provide us with a size. Makes sure we don't build a seek index when streaming internet radio with sources that pretend to be seekable until you try to actually seek. --- gst/mpegaudioparse/gstmpegaudioparse.c | 54 +++++++++++++++++++------- gst/mpegaudioparse/gstmpegaudioparse.h | 7 ++-- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/gst/mpegaudioparse/gstmpegaudioparse.c b/gst/mpegaudioparse/gstmpegaudioparse.c index 75ccf62cd5..17be4832e5 100644 --- a/gst/mpegaudioparse/gstmpegaudioparse.c +++ b/gst/mpegaudioparse/gstmpegaudioparse.c @@ -1162,6 +1162,46 @@ gst_mp3parse_handle_first_frame (GstMPEGAudioParse * mp3parse) } } +static void +gst_mp3parse_check_seekability (GstMPEGAudioParse * mp3parse) +{ + GstQuery *query; + gboolean seekable = FALSE; + gint64 start = -1, stop = -1; + + query = gst_query_new_seeking (GST_FORMAT_BYTES); + if (!gst_pad_peer_query (mp3parse->sinkpad, query)) { + GST_DEBUG_OBJECT (mp3parse, "seeking query failed"); + goto done; + } + + gst_query_parse_seeking (query, NULL, &seekable, &start, &stop); + + /* try harder to query upstream size if we didn't get it the first time */ + if (seekable && stop == -1) { + GstFormat fmt = GST_FORMAT_BYTES; + + GST_DEBUG_OBJECT (mp3parse, "doing duration query to fix up unset stop"); + gst_pad_query_peer_duration (mp3parse->sinkpad, &fmt, &stop); + } + + /* if upstream doesn't know the size, it's likely that it's not seekable in + * practice even if it technically may be seekable */ + if (seekable && (start != 0 || stop <= start)) { + GST_DEBUG_OBJECT (mp3parse, "seekable but unknown start/stop -> disable"); + seekable = FALSE; + } + +done: + + GST_INFO_OBJECT (mp3parse, "seekable: %d (%" G_GUINT64_FORMAT " - %" + G_GUINT64_FORMAT ")", seekable, start, stop); + + mp3parse->seekable = seekable; + + gst_query_unref (query); +} + static GstFlowReturn gst_mp3parse_chain (GstPad * pad, GstBuffer * buf) { @@ -1335,24 +1375,12 @@ gst_mp3parse_chain (GstPad * pad, GstBuffer * buf) /* Check the first frame for a Xing header to get our total length */ if (mp3parse->frame_count == 0) { - GstQuery *query; /* For the first frame in the file, look for a Xing frame after * the header, and output a codec tag */ gst_mp3parse_handle_first_frame (mp3parse); /* Check if we're seekable */ - query = gst_query_new_seeking (GST_FORMAT_BYTES); - if (!gst_pad_peer_query (mp3parse->sinkpad, query)) { - mp3parse->seekable = FALSE; - } else { - gboolean seekable; - GstFormat format; - - gst_query_parse_seeking (query, &format, &seekable, NULL, NULL); - mp3parse->seekable = seekable; - } - gst_query_unref (query); - + gst_mp3parse_check_seekability (mp3parse); } /* Update VBR stats */ diff --git a/gst/mpegaudioparse/gstmpegaudioparse.h b/gst/mpegaudioparse/gstmpegaudioparse.h index 7dc2e7be38..9ee8f5d212 100644 --- a/gst/mpegaudioparse/gstmpegaudioparse.h +++ b/gst/mpegaudioparse/gstmpegaudioparse.h @@ -120,11 +120,12 @@ struct _GstMPEGAudioParse { GSList *pending_accurate_seeks; gboolean exact_position; - /* Track whether we're seekable. The seek table for accurate seeking is - * not maintained if we're not seekable */ + /* Track whether we're seekable (in BYTES format, if upstream operates in + * TIME format, we don't care about seekability and assume upstream handles + * it). The seek table for accurate seeking is not maintained if we're not + * seekable. */ gboolean seekable; - /* pending segment */ GstEvent *pending_segment; /* pending events */