mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 04:00:37 +00:00
baseparse: provide default conversion using bps if no fps available
Also store estimated duration as such, rather than pretending otherwise (e.g. set by subclass).
This commit is contained in:
parent
b648638401
commit
a3f7b8527e
1 changed files with 54 additions and 29 deletions
|
@ -155,10 +155,13 @@
|
||||||
* which can be provided to GstBaseParse to enable it to cater for
|
* which can be provided to GstBaseParse to enable it to cater for
|
||||||
* buffer time metadata (which will be taken from upstream as much as possible).
|
* buffer time metadata (which will be taken from upstream as much as possible).
|
||||||
* Internally keeping track of frames and respective
|
* Internally keeping track of frames and respective
|
||||||
* sizes that have been pushed provides GstBaseParse which a bytes per frame
|
* sizes that have been pushed provides GstBaseParse with a bytes per frame
|
||||||
* rate. A default @convert (used if not overriden) will then use these
|
* rate. A default @convert (used if not overriden) will then use these
|
||||||
* rates to perform obvious conversions. These rates are also used to update
|
* rates to perform obvious conversions. These rates are also used to update
|
||||||
* (estimated) duration at regular frame intervals.
|
* (estimated) duration at regular frame intervals.
|
||||||
|
* If no (fixed) frames per second rate applies, default conversion will be
|
||||||
|
* based on (estimated) bytes per second (but no default buffer metadata
|
||||||
|
* can be provided in this case).
|
||||||
* </para></listitem>
|
* </para></listitem>
|
||||||
* </itemizedlist>
|
* </itemizedlist>
|
||||||
*
|
*
|
||||||
|
@ -207,6 +210,7 @@ struct _GstBaseParsePrivate
|
||||||
|
|
||||||
gint64 duration;
|
gint64 duration;
|
||||||
GstFormat duration_fmt;
|
GstFormat duration_fmt;
|
||||||
|
gint64 estimated_duration;
|
||||||
|
|
||||||
guint min_frame_size;
|
guint min_frame_size;
|
||||||
gboolean passthrough;
|
gboolean passthrough;
|
||||||
|
@ -224,6 +228,7 @@ struct _GstBaseParsePrivate
|
||||||
|
|
||||||
guint64 framecount;
|
guint64 framecount;
|
||||||
guint64 bytecount;
|
guint64 bytecount;
|
||||||
|
guint64 acc_duration;
|
||||||
|
|
||||||
GList *pending_events;
|
GList *pending_events;
|
||||||
|
|
||||||
|
@ -767,14 +772,32 @@ gst_base_parse_convert (GstBaseParse * parse,
|
||||||
gint64 src_value, GstFormat dest_format, gint64 * dest_value)
|
gint64 src_value, GstFormat dest_format, gint64 * dest_value)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
guint64 bytes, duration;
|
||||||
|
|
||||||
if (src_format == dest_format) {
|
if (G_UNLIKELY (src_format == dest_format)) {
|
||||||
*dest_value = src_value;
|
*dest_value = src_value;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* need data and frame info (having num means den also ok) */
|
if (G_UNLIKELY (src_value == -1)) {
|
||||||
if (!parse->priv->framecount || !parse->priv->fps_num)
|
*dest_value = -1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* need at least some frames */
|
||||||
|
if (!parse->priv->framecount)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* either frame info (having num means den also ok) or use average bitrate */
|
||||||
|
if (parse->priv->fps_num) {
|
||||||
|
duration = parse->priv->framecount * parse->priv->fps_den * 1000;
|
||||||
|
bytes = parse->priv->bytecount * parse->priv->fps_num;
|
||||||
|
} else {
|
||||||
|
duration = parse->priv->acc_duration / GST_MSECOND;
|
||||||
|
bytes = parse->priv->bytecount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!duration || !bytes))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (src_format == GST_FORMAT_BYTES) {
|
if (src_format == GST_FORMAT_BYTES) {
|
||||||
|
@ -782,9 +805,7 @@ gst_base_parse_convert (GstBaseParse * parse,
|
||||||
/* BYTES -> TIME conversion */
|
/* BYTES -> TIME conversion */
|
||||||
GST_DEBUG_OBJECT (parse, "converting bytes -> time");
|
GST_DEBUG_OBJECT (parse, "converting bytes -> time");
|
||||||
|
|
||||||
*dest_value = gst_util_uint64_scale (src_value,
|
*dest_value = gst_util_uint64_scale (src_value, duration, bytes);
|
||||||
parse->priv->framecount * parse->priv->fps_den * 1000,
|
|
||||||
parse->priv->bytecount * parse->priv->fps_num);
|
|
||||||
*dest_value *= GST_MSECOND;
|
*dest_value *= GST_MSECOND;
|
||||||
GST_DEBUG_OBJECT (parse, "conversion result: %" G_GINT64_FORMAT " ms",
|
GST_DEBUG_OBJECT (parse, "conversion result: %" G_GINT64_FORMAT " ms",
|
||||||
*dest_value / GST_MSECOND);
|
*dest_value / GST_MSECOND);
|
||||||
|
@ -793,20 +814,21 @@ gst_base_parse_convert (GstBaseParse * parse,
|
||||||
} else if (src_format == GST_FORMAT_TIME) {
|
} else if (src_format == GST_FORMAT_TIME) {
|
||||||
GST_DEBUG_OBJECT (parse, "converting time -> bytes");
|
GST_DEBUG_OBJECT (parse, "converting time -> bytes");
|
||||||
if (dest_format == GST_FORMAT_BYTES) {
|
if (dest_format == GST_FORMAT_BYTES) {
|
||||||
*dest_value = gst_util_uint64_scale (src_value / GST_MSECOND,
|
*dest_value = gst_util_uint64_scale (src_value / GST_MSECOND, bytes,
|
||||||
parse->priv->fps_num * parse->priv->bytecount,
|
duration);
|
||||||
parse->priv->fps_den * 1000 * parse->priv->framecount);
|
|
||||||
GST_DEBUG_OBJECT (parse,
|
GST_DEBUG_OBJECT (parse,
|
||||||
"time %" G_GINT64_FORMAT " ms in bytes = %" G_GINT64_FORMAT,
|
"time %" G_GINT64_FORMAT " ms in bytes = %" G_GINT64_FORMAT,
|
||||||
src_value / GST_MSECOND, *dest_value);
|
src_value / GST_MSECOND, *dest_value);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
} else if (src_format == GST_FORMAT_DEFAULT) {
|
} else if (src_format == GST_FORMAT_DEFAULT) {
|
||||||
|
/* DEFAULT == frame-based */
|
||||||
if (dest_format == GST_FORMAT_TIME) {
|
if (dest_format == GST_FORMAT_TIME) {
|
||||||
/* DEFAULT == frame-based */
|
if (parse->priv->fps_den) {
|
||||||
*dest_value = gst_util_uint64_scale (src_value,
|
*dest_value = gst_util_uint64_scale (src_value,
|
||||||
GST_SECOND * parse->priv->fps_den, parse->priv->fps_num);
|
GST_SECOND * parse->priv->fps_den, parse->priv->fps_num);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
}
|
||||||
} else if (dest_format == GST_FORMAT_BYTES) {
|
} else if (dest_format == GST_FORMAT_BYTES) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -824,32 +846,26 @@ gst_base_parse_update_duration (GstBaseParse * aacparse)
|
||||||
{
|
{
|
||||||
GstPad *peer;
|
GstPad *peer;
|
||||||
GstBaseParse *parse;
|
GstBaseParse *parse;
|
||||||
|
GstBaseParseClass *klass;
|
||||||
|
|
||||||
parse = GST_BASE_PARSE (aacparse);
|
parse = GST_BASE_PARSE (aacparse);
|
||||||
|
klass = GST_BASE_PARSE_GET_CLASS (parse);
|
||||||
|
|
||||||
/* need frame info */
|
/* must be able to convert */
|
||||||
if (!parse->priv->fps_den || !parse->priv->fps_num) {
|
if (!klass->convert)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Cannot estimate duration. No data has been passed to us yet */
|
|
||||||
if (!parse->priv->framecount || !parse->priv->bytecount) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
peer = gst_pad_get_peer (parse->sinkpad);
|
peer = gst_pad_get_peer (parse->sinkpad);
|
||||||
if (peer) {
|
if (peer) {
|
||||||
GstFormat pformat = GST_FORMAT_BYTES;
|
GstFormat pformat = GST_FORMAT_BYTES;
|
||||||
gboolean qres = FALSE;
|
gboolean qres = FALSE;
|
||||||
gint64 ptot;
|
gint64 ptot, dest_value;
|
||||||
|
|
||||||
qres = gst_pad_query_duration (peer, &pformat, &ptot);
|
qres = gst_pad_query_duration (peer, &pformat, &ptot);
|
||||||
gst_object_unref (GST_OBJECT (peer));
|
gst_object_unref (GST_OBJECT (peer));
|
||||||
if (qres) {
|
if (qres) {
|
||||||
gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
|
if (klass->convert (parse, pformat, ptot, GST_FORMAT_TIME, &dest_value))
|
||||||
gst_util_uint64_scale (ptot,
|
parse->priv->estimated_duration = dest_value;
|
||||||
parse->priv->framecount * parse->priv->fps_den * GST_SECOND,
|
|
||||||
parse->priv->bytecount * parse->priv->fps_num));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -942,8 +958,12 @@ gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
|
||||||
|
|
||||||
/* update stats */
|
/* update stats */
|
||||||
parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
|
parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
|
||||||
parse->priv->framecount +=
|
if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BASE_PARSE_BUFFER_FLAG_NO_FRAME)) {
|
||||||
!GST_BUFFER_FLAG_IS_SET (buffer, GST_BASE_PARSE_BUFFER_FLAG_NO_FRAME);
|
parse->priv->framecount++;
|
||||||
|
if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
|
||||||
|
parse->priv->acc_duration += GST_BUFFER_DURATION (buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
GST_BUFFER_FLAG_UNSET (buffer, GST_BASE_PARSE_BUFFER_FLAG_NO_FRAME);
|
GST_BUFFER_FLAG_UNSET (buffer, GST_BASE_PARSE_BUFFER_FLAG_NO_FRAME);
|
||||||
if (parse->priv->update_interval &&
|
if (parse->priv->update_interval &&
|
||||||
(parse->priv->framecount % parse->priv->update_interval) == 0)
|
(parse->priv->framecount % parse->priv->update_interval) == 0)
|
||||||
|
@ -1451,6 +1471,8 @@ gst_base_parse_activate (GstBaseParse * parse, gboolean active)
|
||||||
parse->priv->frame_duration = GST_CLOCK_TIME_NONE;
|
parse->priv->frame_duration = GST_CLOCK_TIME_NONE;
|
||||||
parse->priv->framecount = 0;
|
parse->priv->framecount = 0;
|
||||||
parse->priv->bytecount = 0;
|
parse->priv->bytecount = 0;
|
||||||
|
parse->priv->acc_duration = 0;
|
||||||
|
parse->priv->estimated_duration = -1;
|
||||||
parse->priv->next_ts = 0;
|
parse->priv->next_ts = 0;
|
||||||
parse->priv->passthrough = FALSE;
|
parse->priv->passthrough = FALSE;
|
||||||
|
|
||||||
|
@ -1812,6 +1834,9 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
|
||||||
} else if (parse->priv->duration != -1) {
|
} else if (parse->priv->duration != -1) {
|
||||||
res = klass->convert (parse, parse->priv->duration_fmt,
|
res = klass->convert (parse, parse->priv->duration_fmt,
|
||||||
parse->priv->duration, format, &dest_value);
|
parse->priv->duration, format, &dest_value);
|
||||||
|
} else if (parse->priv->estimated_duration != -1) {
|
||||||
|
dest_value = parse->priv->estimated_duration;
|
||||||
|
res = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_mutex_unlock (parse->parse_lock);
|
g_mutex_unlock (parse->parse_lock);
|
||||||
|
|
Loading…
Reference in a new issue