From: Zebediah Figura Date: Tue, 18 Feb 2020 03:50:54 +0000 (-0600) Subject: baseparse: Don't truncate the duration to milliseconds in gst_base_parse_convert_defa... X-Git-Tag: 1.22.0~2509 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cc835c0722cd76d1746c3e3dce461c3f4c7052db;p=platform%2Fupstream%2Fgstreamer.git 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: --- diff --git a/subprojects/gstreamer/libs/gst/base/gstbaseparse.c b/subprojects/gstreamer/libs/gst/base/gstbaseparse.c index 9e5a652..660439b 100644 --- a/subprojects/gstreamer/libs/gst/base/gstbaseparse.c +++ b/subprojects/gstreamer/libs/gst/base/gstbaseparse.c @@ -1782,7 +1782,7 @@ gst_base_parse_convert_default (GstBaseParse * parse, if (!parse->priv->framecount) goto no_framecount; - duration = parse->priv->acc_duration / GST_MSECOND; + duration = parse->priv->acc_duration; bytes = parse->priv->bytecount; if (G_UNLIKELY (!duration || !bytes)) @@ -1793,7 +1793,6 @@ gst_base_parse_convert_default (GstBaseParse * parse, /* BYTES -> TIME conversion */ GST_DEBUG_OBJECT (parse, "converting bytes -> time"); *dest_value = gst_util_uint64_scale (src_value, duration, bytes); - *dest_value *= GST_MSECOND; GST_DEBUG_OBJECT (parse, "converted %" G_GINT64_FORMAT " bytes to %" GST_TIME_FORMAT, 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) { if (dest_format == GST_FORMAT_BYTES) { GST_DEBUG_OBJECT (parse, "converting time -> bytes"); - *dest_value = gst_util_uint64_scale (src_value / GST_MSECOND, bytes, - duration); + *dest_value = gst_util_uint64_scale (src_value, bytes, duration); GST_DEBUG_OBJECT (parse, "converted %" GST_TIME_FORMAT " to %" G_GINT64_FORMAT " bytes", GST_TIME_ARGS (src_value), *dest_value); diff --git a/subprojects/gstreamer/tests/check/libs/baseparse.c b/subprojects/gstreamer/tests/check/libs/baseparse.c index a53fdfe..d92b19f 100644 --- a/subprojects/gstreamer/tests/check/libs/baseparse.c +++ b/subprojects/gstreamer/tests/check/libs/baseparse.c @@ -722,6 +722,47 @@ GST_START_TEST (parser_initial_gap_prefer_upstream_caps) 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 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_frame_growth); tcase_add_test (tc, parser_initial_gap_prefer_upstream_caps); + tcase_add_test (tc, parser_convert_duration); return s; }