gboolean expose_allstreams; /* Whether to expose unknow type streams or not */
- gboolean upstream_seekable; /* if upstream is seekable */
-
GList *filtered; /* elements for which error messages are filtered */
};
GstCaps * caps, GstDecodeBin * decode_bin);
static void decodebin_set_queue_size (GstDecodeBin * dbin,
- GstElement * multiqueue, gboolean preroll);
+ GstElement * multiqueue, gboolean preroll, gboolean seekable);
static gboolean gst_decode_bin_autoplug_continue (GstElement * element,
GstPad * pad, GstCaps * caps);
GstStateChange transition);
static void gst_decode_bin_handle_message (GstBin * bin, GstMessage * message);
+static gboolean check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad);
+
#define EXPOSE_LOCK(dbin) G_STMT_START { \
GST_LOG_OBJECT (dbin, \
"expose locking from thread %p", \
*
* Check if upstream is seekable.
*/
-static void
+static gboolean
check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad)
{
GstQuery *query;
gint64 start = -1, stop = -1;
-
- dbin->upstream_seekable = FALSE;
+ gboolean seekable = FALSE;
query = gst_query_new_seeking (GST_FORMAT_BYTES);
if (!gst_pad_peer_query (pad, query)) {
GST_DEBUG_OBJECT (dbin, "seeking query failed");
gst_query_unref (query);
- return;
+ return FALSE;
}
- gst_query_parse_seeking (query, NULL, &dbin->upstream_seekable,
- &start, &stop);
+ gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
gst_query_unref (query);
/* try harder to query upstream size if we didn't get it the first time */
- if (dbin->upstream_seekable && stop == -1) {
+ if (seekable && stop == -1) {
GstFormat fmt = GST_FORMAT_BYTES;
GST_DEBUG_OBJECT (dbin, "doing duration query to fix up unset 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 (dbin->upstream_seekable && (start != 0 || stop <= start)) {
+ if (seekable && (start != 0 || stop <= start)) {
GST_DEBUG_OBJECT (dbin, "seekable but unknown start/stop -> disable");
- dbin->upstream_seekable = FALSE;
+ return FALSE;
}
- GST_DEBUG_OBJECT (dbin, "upstream seekable: %d", dbin->upstream_seekable);
+ GST_DEBUG_OBJECT (dbin, "upstream seekable: %d", seekable);
+ return seekable;
}
static void
pad = gst_element_get_static_pad (typefind, "src");
sink_pad = gst_element_get_static_pad (typefind, "sink");
- /* if upstream is seekable we can safely set a limit in time to the queues so
- * that streams at low bitrates can preroll */
- check_upstream_seekable (decode_bin, sink_pad);
-
/* need some lock here to prevent race with shutdown state change
* which might yank away e.g. decode_chain while building stuff here.
* In typical cases, STREAM_LOCK is held and handles that, it need not
* we can probably set its buffering state to playing now */
GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to "
"'playing' buffering mode", group);
- decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE);
+ decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE, TRUE);
CHAIN_MUTEX_UNLOCK (chain);
EXPOSE_LOCK (chain->dbin);
* playing or prerolling. */
static void
decodebin_set_queue_size (GstDecodeBin * dbin, GstElement * multiqueue,
- gboolean preroll)
+ gboolean preroll, gboolean seekable)
{
guint max_bytes, max_buffers;
guint64 max_time;
if ((max_buffers = dbin->max_size_buffers) == 0)
max_buffers = AUTO_PREROLL_SIZE_BUFFERS;
if ((max_time = dbin->max_size_time) == 0)
- max_time = dbin->upstream_seekable ? AUTO_PREROLL_SEEKABLE_SIZE_TIME :
+ max_time = seekable ? AUTO_PREROLL_SEEKABLE_SIZE_TIME :
AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME;
} else {
/* update runtime limits. At runtime, we try to keep the amount of buffers
{
GstDecodeGroup *group = g_slice_new0 (GstDecodeGroup);
GstElement *mq;
+ gboolean seekable;
GST_DEBUG_OBJECT (dbin, "Creating new group %p with parent chain %p", group,
parent);
}
/* configure queue sizes for preroll */
- decodebin_set_queue_size (dbin, mq, TRUE);
+ seekable = FALSE;
+ if (parent && parent->demuxer) {
+ GstElement *element =
+ ((GstDecodeElement *) parent->elements->data)->element;
+ GstPad *pad = gst_element_get_static_pad (element, "sink");
+ if (pad) {
+ seekable = check_upstream_seekable (dbin, pad);
+ gst_object_unref (pad);
+ }
+ }
+ decodebin_set_queue_size (dbin, mq, TRUE, seekable);
group->overrunsig = g_signal_connect (G_OBJECT (mq), "overrun",
G_CALLBACK (multi_queue_overrun_cb), group);
dbin = group->dbin;
/* configure queues for playback */
- decodebin_set_queue_size (dbin, group->multiqueue, FALSE);
+ decodebin_set_queue_size (dbin, group->multiqueue, FALSE, TRUE);
/* we can now disconnect any overrun signal, which is used to expose the
* group. */