mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +00:00
basesink: implement percentage position and duration queries
If upstream does not handle them, then implement those ourself.
This commit is contained in:
parent
c29e34113f
commit
c96dec2a06
1 changed files with 78 additions and 27 deletions
|
@ -4512,6 +4512,39 @@ convert_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_base_sink_get_duration (GstBaseSink * basesink, GstFormat format,
|
||||||
|
gint64 * dur, gboolean * upstream)
|
||||||
|
{
|
||||||
|
gboolean res = FALSE;
|
||||||
|
|
||||||
|
if (basesink->pad_mode == GST_ACTIVATE_PULL) {
|
||||||
|
GstFormat uformat = GST_FORMAT_BYTES;
|
||||||
|
gint64 uduration;
|
||||||
|
|
||||||
|
/* get the duration in bytes, in pull mode that's all we are sure to
|
||||||
|
* know. We have to explicitly get this value from upstream instead of
|
||||||
|
* using our cached value because it might change. Duration caching
|
||||||
|
* should be done at a higher level. */
|
||||||
|
res = gst_pad_query_peer_duration (basesink->sinkpad, &uformat, &uduration);
|
||||||
|
if (res) {
|
||||||
|
gst_segment_set_duration (&basesink->segment, uformat, uduration);
|
||||||
|
if (format != uformat) {
|
||||||
|
/* convert to the requested format */
|
||||||
|
res = gst_pad_query_convert (basesink->sinkpad, uformat, uduration,
|
||||||
|
&format, dur);
|
||||||
|
} else {
|
||||||
|
*dur = uduration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*upstream = FALSE;
|
||||||
|
} else {
|
||||||
|
*upstream = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_base_sink_query (GstElement * element, GstQuery * query)
|
gst_base_sink_query (GstElement * element, GstQuery * query)
|
||||||
{
|
{
|
||||||
|
@ -4539,45 +4572,63 @@ gst_base_sink_query (GstElement * element, GstQuery * query)
|
||||||
/* fallback to peer query */
|
/* fallback to peer query */
|
||||||
res = gst_pad_peer_query (basesink->sinkpad, query);
|
res = gst_pad_peer_query (basesink->sinkpad, query);
|
||||||
}
|
}
|
||||||
|
if (!res) {
|
||||||
|
/* we can handle a few things if upstream failed */
|
||||||
|
if (format == GST_FORMAT_PERCENT) {
|
||||||
|
gint64 dur = 0;
|
||||||
|
GstFormat uformat = GST_FORMAT_TIME;
|
||||||
|
|
||||||
|
res = gst_base_sink_get_position (basesink, GST_FORMAT_TIME, &cur,
|
||||||
|
&upstream);
|
||||||
|
if (!res && upstream) {
|
||||||
|
res = gst_pad_query_peer_position (basesink->sinkpad, &uformat,
|
||||||
|
&cur);
|
||||||
|
}
|
||||||
|
if (res) {
|
||||||
|
res = gst_base_sink_get_duration (basesink, GST_FORMAT_TIME, &dur,
|
||||||
|
&upstream);
|
||||||
|
if (!res && upstream) {
|
||||||
|
res = gst_pad_query_peer_duration (basesink->sinkpad, &uformat,
|
||||||
|
&dur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res) {
|
||||||
|
gint64 pos;
|
||||||
|
|
||||||
|
pos = gst_util_uint64_scale (100 * GST_FORMAT_PERCENT_SCALE, cur,
|
||||||
|
dur);
|
||||||
|
gst_query_set_position (query, GST_FORMAT_PERCENT, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_QUERY_DURATION:
|
case GST_QUERY_DURATION:
|
||||||
{
|
{
|
||||||
GstFormat format, uformat;
|
gint64 dur = 0;
|
||||||
gint64 duration, uduration;
|
GstFormat format;
|
||||||
|
gboolean upstream = FALSE;
|
||||||
|
|
||||||
gst_query_parse_duration (query, &format, NULL);
|
gst_query_parse_duration (query, &format, NULL);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (basesink, "duration query in format %s",
|
GST_DEBUG_OBJECT (basesink, "duration query in format %s",
|
||||||
gst_format_get_name (format));
|
gst_format_get_name (format));
|
||||||
|
|
||||||
if (basesink->pad_mode == GST_ACTIVATE_PULL) {
|
if ((res =
|
||||||
uformat = GST_FORMAT_BYTES;
|
gst_base_sink_get_duration (basesink, format, &dur, &upstream))) {
|
||||||
|
gst_query_set_duration (query, format, dur);
|
||||||
/* get the duration in bytes, in pull mode that's all we are sure to
|
} else if (upstream) {
|
||||||
* know. We have to explicitly get this value from upstream instead of
|
/* fallback to peer query */
|
||||||
* using our cached value because it might change. Duration caching
|
|
||||||
* should be done at a higher level. */
|
|
||||||
res = gst_pad_query_peer_duration (basesink->sinkpad, &uformat,
|
|
||||||
&uduration);
|
|
||||||
if (res) {
|
|
||||||
gst_segment_set_duration (&basesink->segment, uformat, uduration);
|
|
||||||
if (format != uformat) {
|
|
||||||
/* convert to the requested format */
|
|
||||||
res = gst_pad_query_convert (basesink->sinkpad, uformat, uduration,
|
|
||||||
&format, &duration);
|
|
||||||
} else {
|
|
||||||
duration = uduration;
|
|
||||||
}
|
|
||||||
if (res) {
|
|
||||||
/* set the result */
|
|
||||||
gst_query_set_duration (query, format, duration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* in push mode we simply forward upstream */
|
|
||||||
res = gst_pad_peer_query (basesink->sinkpad, query);
|
res = gst_pad_peer_query (basesink->sinkpad, query);
|
||||||
}
|
}
|
||||||
|
if (!res) {
|
||||||
|
/* we can handle a few things if upstream failed */
|
||||||
|
if (format == GST_FORMAT_PERCENT) {
|
||||||
|
gst_query_set_duration (query, GST_FORMAT_PERCENT,
|
||||||
|
GST_FORMAT_PERCENT_MAX);
|
||||||
|
res = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_QUERY_LATENCY:
|
case GST_QUERY_LATENCY:
|
||||||
|
|
Loading…
Reference in a new issue