GNOME Bugzilla – Bug 543444
gst_base_sink_get_position can return 0 unexpectedly
Last modified: 2008-08-19 16:47:36 UTC
Not sure if this is a bug, but it's certainly unexpected. Let's say I'm sending 50 flushing seeks per second to a pipeline while scrubbing. I make sure that the pipeline is prerolled before I seek, so I don't overload it with flushing seeks. Let's say at the same time, I'm querying the pipeline's position 100 times a second. I disregard failed queries, taking the last value that I saw. The problem is that e.g. when scrubbing around second 200 of a MOV file, that basesink sometimes returns 0. I haven't investigated too much, but things like this creep me out, in gstbasesink.c:3243: /* collect all data we need holding the lock */ if (GST_CLOCK_TIME_IS_VALID (basesink->segment.time)) time = basesink->segment.time; else time = 0; and in gstbasesink.c:2546: case GST_EVENT_FLUSH_STOP: ... /* we need new segment info after the flush. */ gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED); gst_segment_init (basesink->abidata.ABI.clip_segment, GST_FORMAT_UNDEFINED); basesink->have_newsegment = FALSE; So in this case after getting the flush_stop but before getting the first buffer, get_position will report 0. (gst_segment_init() sets segment.time to 0.) But we actually don't know the position then. I guess the right thing to do is to protect have_newsegment with the object lock (currently it's just the stream lock), and to make get_position return -1 or fail when we don't actually have the new segment. Or does this diagnostic look wrong?
* libs/gst/base/gstbasesink.c: (gst_base_sink_render_object), (gst_base_sink_event), (gst_base_sink_chain_unlocked), (gst_base_sink_negotiate_pull), (gst_base_sink_pad_activate_pull), (gst_base_sink_get_position), (gst_base_sink_change_state): Improve position reporting in the flushing state. Also report the position when we are not yet prerolled but we have a newsegment event. Fixes #543444. Improve the pull-based negotiation code. * tests/check/elements/fakesink.c: (GST_START_TEST), (fakesink_suite): Add testcase for position reporting while flushing in PAUSED and PLAYING. * tests/check/generic/sinks.c: (GST_START_TEST): Update unit-test, we can now query the position as soon as we receive a NEWSEGMENT event.