baseparse: use only upstream duration if it provides one

This commit is contained in:
Mark Nauwelaerts 2010-10-29 14:08:58 +02:00 committed by Tim-Philipp Müller
parent 78ef0387e7
commit 0f9435888a

View file

@ -258,6 +258,7 @@ struct _GstBaseParsePrivate
gboolean own_index;
/* seek table entries only maintained if upstream is BYTE seekable */
gboolean upstream_seekable;
gboolean upstream_has_duration;
/* minimum distance between two index entries */
GstClockTimeDiff idx_interval;
/* ts and offset of last entry added */
@ -529,6 +530,7 @@ gst_base_parse_reset (GstBaseParse * parse)
parse->priv->index_last_ts = 0;
parse->priv->index_last_offset = 0;
parse->priv->upstream_seekable = FALSE;
parse->priv->upstream_has_duration = FALSE;
parse->priv->idx_interval = 0;
parse->priv->exact_position = TRUE;
@ -1298,6 +1300,24 @@ done:
parse->priv->idx_interval = idx_interval * GST_MSECOND;
}
/* some misc checks on upstream */
static void
gst_base_parse_check_upstream (GstBaseParse * parse)
{
GstFormat fmt = GST_FORMAT_TIME;
gint64 stop;
if (gst_pad_query_peer_duration (parse->sinkpad, &fmt, &stop))
if (GST_CLOCK_TIME_IS_VALID (stop) && stop) {
/* upstream has one, accept it also, and no further updates */
gst_base_parse_set_duration (parse, GST_FORMAT_TIME, stop, 0);
parse->priv->upstream_has_duration = TRUE;
}
GST_DEBUG_OBJECT (parse, "upstream_has_duration: %d",
parse->priv->upstream_has_duration);
}
/**
* gst_base_parse_handle_and_push_buffer:
* @parse: #GstBaseParse.
@ -1323,6 +1343,12 @@ gst_base_parse_handle_and_push_buffer (GstBaseParse * parse,
parse->priv->discont = FALSE;
}
/* some one-time start-up */
if (G_UNLIKELY (!parse->priv->framecount)) {
gst_base_parse_check_seekability (parse);
gst_base_parse_check_upstream (parse);
}
GST_LOG_OBJECT (parse,
"parsing frame at offset %" G_GUINT64_FORMAT
" (%#" G_GINT64_MODIFIER "x) of size %d",
@ -1383,11 +1409,6 @@ gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
/* some one-time start-up */
if (G_UNLIKELY (!parse->priv->framecount)) {
gst_base_parse_check_seekability (parse);
}
/* update stats */
parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BASE_PARSE_BUFFER_FLAG_NO_FRAME)) {
@ -2386,6 +2407,11 @@ gst_base_parse_set_duration (GstBaseParse * parse,
g_return_if_fail (parse != NULL);
GST_BASE_PARSE_LOCK (parse);
if (parse->priv->upstream_has_duration) {
GST_DEBUG_OBJECT (parse, "using upstream duration; discarding update");
goto exit;
}
if (duration != parse->priv->duration) {
GstMessage *m;
@ -2405,6 +2431,7 @@ gst_base_parse_set_duration (GstBaseParse * parse,
}
GST_DEBUG_OBJECT (parse, "set update interval: %d", interval);
parse->priv->update_interval = interval;
exit:
GST_BASE_PARSE_UNLOCK (parse);
}