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.
This commit is contained in:
Tim-Philipp Müller 2009-06-16 01:40:42 +01:00
parent 4c62946ee9
commit 1db592839e
2 changed files with 45 additions and 16 deletions

View file

@ -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 static GstFlowReturn
gst_mp3parse_chain (GstPad * pad, GstBuffer * buf) 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 */ /* Check the first frame for a Xing header to get our total length */
if (mp3parse->frame_count == 0) { if (mp3parse->frame_count == 0) {
GstQuery *query;
/* For the first frame in the file, look for a Xing frame after /* For the first frame in the file, look for a Xing frame after
* the header, and output a codec tag */ * the header, and output a codec tag */
gst_mp3parse_handle_first_frame (mp3parse); gst_mp3parse_handle_first_frame (mp3parse);
/* Check if we're seekable */ /* Check if we're seekable */
query = gst_query_new_seeking (GST_FORMAT_BYTES); gst_mp3parse_check_seekability (mp3parse);
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);
} }
/* Update VBR stats */ /* Update VBR stats */

View file

@ -120,11 +120,12 @@ struct _GstMPEGAudioParse {
GSList *pending_accurate_seeks; GSList *pending_accurate_seeks;
gboolean exact_position; gboolean exact_position;
/* Track whether we're seekable. The seek table for accurate seeking is /* Track whether we're seekable (in BYTES format, if upstream operates in
* not maintained if we're not seekable */ * 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; gboolean seekable;
/* pending segment */ /* pending segment */
GstEvent *pending_segment; GstEvent *pending_segment;
/* pending events */ /* pending events */