mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-29 23:32:33 +00:00
baseparse: Don't truncate the duration to milliseconds in gst_base_parse_convert_default().
There's no need to do this, and it can make seeking far less accurate. For a specific use case: I am working with a long (45-minute) MPEG-1 layer 3 file, which has a constant bit rate but no seeking tables. Trying to seek the pipeline immediately after pausing it, without the ACCURATE flag, to a location 41 minutes in, yields a location that is potentially over ten seconds ahead of where it should be. This patch improves that drastically. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/374>
This commit is contained in:
parent
334c347de2
commit
cc835c0722
2 changed files with 44 additions and 4 deletions
|
@ -1782,7 +1782,7 @@ gst_base_parse_convert_default (GstBaseParse * parse,
|
||||||
if (!parse->priv->framecount)
|
if (!parse->priv->framecount)
|
||||||
goto no_framecount;
|
goto no_framecount;
|
||||||
|
|
||||||
duration = parse->priv->acc_duration / GST_MSECOND;
|
duration = parse->priv->acc_duration;
|
||||||
bytes = parse->priv->bytecount;
|
bytes = parse->priv->bytecount;
|
||||||
|
|
||||||
if (G_UNLIKELY (!duration || !bytes))
|
if (G_UNLIKELY (!duration || !bytes))
|
||||||
|
@ -1793,7 +1793,6 @@ gst_base_parse_convert_default (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, duration, bytes);
|
*dest_value = gst_util_uint64_scale (src_value, duration, bytes);
|
||||||
*dest_value *= GST_MSECOND;
|
|
||||||
GST_DEBUG_OBJECT (parse,
|
GST_DEBUG_OBJECT (parse,
|
||||||
"converted %" G_GINT64_FORMAT " bytes to %" GST_TIME_FORMAT,
|
"converted %" G_GINT64_FORMAT " bytes to %" GST_TIME_FORMAT,
|
||||||
src_value, GST_TIME_ARGS (*dest_value));
|
src_value, GST_TIME_ARGS (*dest_value));
|
||||||
|
@ -1804,8 +1803,7 @@ gst_base_parse_convert_default (GstBaseParse * parse,
|
||||||
} else if (src_format == GST_FORMAT_TIME) {
|
} else if (src_format == GST_FORMAT_TIME) {
|
||||||
if (dest_format == GST_FORMAT_BYTES) {
|
if (dest_format == GST_FORMAT_BYTES) {
|
||||||
GST_DEBUG_OBJECT (parse, "converting time -> bytes");
|
GST_DEBUG_OBJECT (parse, "converting time -> bytes");
|
||||||
*dest_value = gst_util_uint64_scale (src_value / GST_MSECOND, bytes,
|
*dest_value = gst_util_uint64_scale (src_value, bytes, duration);
|
||||||
duration);
|
|
||||||
GST_DEBUG_OBJECT (parse,
|
GST_DEBUG_OBJECT (parse,
|
||||||
"converted %" GST_TIME_FORMAT " to %" G_GINT64_FORMAT " bytes",
|
"converted %" GST_TIME_FORMAT " to %" G_GINT64_FORMAT " bytes",
|
||||||
GST_TIME_ARGS (src_value), *dest_value);
|
GST_TIME_ARGS (src_value), *dest_value);
|
||||||
|
|
|
@ -722,6 +722,47 @@ GST_START_TEST (parser_initial_gap_prefer_upstream_caps)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (parser_convert_duration)
|
||||||
|
{
|
||||||
|
static const gint64 seconds = 45 * 60;
|
||||||
|
gint64 value, expect;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
have_eos = FALSE;
|
||||||
|
have_data = FALSE;
|
||||||
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
setup_parsertester ();
|
||||||
|
gst_pad_set_getrange_function (mysrcpad, _src_getrange);
|
||||||
|
gst_pad_set_query_function (mysrcpad, _src_query);
|
||||||
|
gst_pad_set_chain_function (mysinkpad, _sink_chain);
|
||||||
|
gst_pad_set_event_function (mysinkpad, _sink_event);
|
||||||
|
|
||||||
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
|
gst_element_set_state (parsetest, GST_STATE_PLAYING);
|
||||||
|
gst_pad_set_active (mysinkpad, TRUE);
|
||||||
|
|
||||||
|
g_main_loop_run (loop);
|
||||||
|
fail_unless (have_eos == TRUE);
|
||||||
|
fail_unless (have_data == TRUE);
|
||||||
|
|
||||||
|
ret = gst_base_parse_convert_default (GST_BASE_PARSE (parsetest),
|
||||||
|
GST_FORMAT_TIME, seconds * GST_SECOND, GST_FORMAT_BYTES, &value);
|
||||||
|
fail_unless (ret == TRUE);
|
||||||
|
expect = gst_util_uint64_scale_round (seconds * sizeof (guint64),
|
||||||
|
TEST_VIDEO_FPS_N, TEST_VIDEO_FPS_D);
|
||||||
|
fail_unless_equals_int (value, expect);
|
||||||
|
gst_element_set_state (parsetest, GST_STATE_NULL);
|
||||||
|
|
||||||
|
check_no_error_received ();
|
||||||
|
cleanup_parsertest ();
|
||||||
|
|
||||||
|
g_main_loop_unref (loop);
|
||||||
|
loop = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
baseparse_setup (void)
|
baseparse_setup (void)
|
||||||
|
@ -755,6 +796,7 @@ gst_baseparse_suite (void)
|
||||||
tcase_add_test (tc, parser_pull_short_read);
|
tcase_add_test (tc, parser_pull_short_read);
|
||||||
tcase_add_test (tc, parser_pull_frame_growth);
|
tcase_add_test (tc, parser_pull_frame_growth);
|
||||||
tcase_add_test (tc, parser_initial_gap_prefer_upstream_caps);
|
tcase_add_test (tc, parser_initial_gap_prefer_upstream_caps);
|
||||||
|
tcase_add_test (tc, parser_convert_duration);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue