mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
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:
parent
4c62946ee9
commit
1db592839e
2 changed files with 45 additions and 16 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue