Commit 6d49ee54 authored by Alexandru Băluț's avatar Alexandru Băluț

viewer: Fix preview flicker when trimming clip

When we show the video widget of the asset backing the trimmed clip,
the first frame of the asset is shown for a brief moment until the
initial seek is performed and the desired frame is shown. This causes an
unwanted flicker.

We have to prepare the trim preview video widget and switch the project
video widget with it only when it's ready.
parent 03e15b44
......@@ -294,6 +294,14 @@ class ViewerContainer(Gtk.Box, Loggable):
_("Detach the viewer\nYou can re-attach it by closing the newly created window."))
bbox.pack_start(self.undock_button, False, False, 0)
self.show_all()
# Create a hidden container for the clip trim preview video widget.
self.hidden_chest = Gtk.Frame()
# It has to be added to the window, otherwise when we add
# a video widget to it, it will create a new window!
self.pack_end(self.hidden_chest, False, False, 0)
self._haveUI = True
# Identify widgets for AT-SPI, making our test suite easier to develop
......@@ -307,7 +315,6 @@ class ViewerContainer(Gtk.Box, Loggable):
self.undock_button.get_accessible().set_name("undock_button")
self.buttons_container = bbox
self.show_all()
self.external_vbox.show_all()
def __corner_draw_cb(self, unused_widget, cr, lines, space, margin):
......@@ -513,12 +520,39 @@ class ViewerContainer(Gtk.Box, Loggable):
if not self.trim_pipeline:
self.debug("Creating temporary pipeline for clip %s", clip.props.uri)
self.trim_pipeline = AssetPipeline(clip)
video_sink, sink_widget = self.trim_pipeline.create_sink()
self.target.switch_widget(sink_widget)
unused_video_sink, sink_widget = self.trim_pipeline.create_sink()
# Add the widget to a hidden container and make it appear later
# when it's ready. If we show it before the initial seek completion,
# there is a flicker when the first frame of the asset is shown for
# a brief moment until the initial seek to the frame we actually
# want to show is performed.
# First make sure the container itself is ready.
widget = self.hidden_chest.get_child()
if widget:
self.warning("The previous trim preview video widget should have been removed already")
self.hidden_chest.remove(widget)
self.hidden_chest.add(sink_widget)
sink_widget.show()
self.trim_pipeline.connect("state-change", self._state_change_cb)
self.trim_pipeline.setState(Gst.State.PAUSED)
self._last_trim_ns = 0
self.trim_pipeline.simple_seek(position)
def _state_change_cb(self, trim_pipeline, state, prev_state):
if self.trim_pipeline is not trim_pipeline:
self.warning("State change reported for previous trim preview pipeline")
trim_pipeline.disconnect_by_func(self._state_change_cb)
return
# First the pipeline goes from READY to PAUSED, and then it goes
# from PAUSED to PAUSED, and this is a good moment.
if prev_state == Gst.State.PAUSED and state == Gst.State.PAUSED:
sink_widget = self.hidden_chest.get_child()
if sink_widget:
self.hidden_chest.remove(sink_widget)
self.target.switch_widget(sink_widget)
trim_pipeline.disconnect_by_func(self._state_change_cb)
def clipTrimPreviewFinished(self):
"""Switches back to the project pipeline following a clip trimming."""
if not self.trim_pipeline:
......@@ -581,7 +615,6 @@ class ViewerWidget(Gtk.AspectFrame, Loggable):
child = self.get_child()
if child:
self.remove(child)
widget.show_all()
self.add(widget)
def update_aspect_ratio(self, project):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment