[gthumb] media player: wait for the playbin state to change
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] media player: wait for the playbin state to change
- Date: Thu, 8 Feb 2018 08:55:20 +0000 (UTC)
commit b0c1d5dc174af4f60bb11a429c7144fc5d066dae
Author: Paolo Bacchilega <paobac src gnome org>
Date: Thu Feb 8 09:53:02 2018 +0100
media player: wait for the playbin state to change
This should fix a possible lock as describe in bug #760214.
extensions/gstreamer_tools/gth-media-viewer-page.c | 424 ++++++++++----------
1 files changed, 214 insertions(+), 210 deletions(-)
---
diff --git a/extensions/gstreamer_tools/gth-media-viewer-page.c
b/extensions/gstreamer_tools/gth-media-viewer-page.c
index eb4f9cd..c5edc08 100644
--- a/extensions/gstreamer_tools/gth-media-viewer-page.c
+++ b/extensions/gstreamer_tools/gth-media-viewer-page.c
@@ -610,182 +610,25 @@ update_play_button (GthMediaViewerPage *self,
}
-static void
-gth_media_viewer_page_real_activate (GthViewerPage *base,
- GthBrowser *browser)
-{
- GthMediaViewerPage *self;
-
- if (! gstreamer_init ())
- return;
-
- self = (GthMediaViewerPage*) base;
-
- self->priv->browser = browser;
- g_action_map_add_action_entries (G_ACTION_MAP (browser),
- actions,
- G_N_ELEMENTS (actions),
- browser);
- self->priv->screenshot_button =
- gth_browser_add_header_bar_button (browser,
- GTH_BROWSER_HEADER_SECTION_VIEWER_VIEW,
- "camera-photo-symbolic",
- _("Take a screenshot"),
- "win.video-screenshot",
- NULL);
-
- /* audio area */
-
- self->priv->audio_area = gtk_drawing_area_new ();
- gtk_style_context_add_class (gtk_widget_get_style_context (self->priv->audio_area), "video-player");
- gtk_widget_add_events (self->priv->audio_area, (gtk_widget_get_events (self->priv->audio_area)
- | GDK_EXPOSURE_MASK
- | GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_POINTER_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON_MOTION_MASK
- | GDK_SCROLL_MASK));
- gtk_widget_set_can_focus (self->priv->audio_area, TRUE);
- gtk_widget_show (self->priv->audio_area);
-
- g_signal_connect (G_OBJECT (self->priv->audio_area),
- "draw",
- G_CALLBACK (video_area_draw_cb),
- self);
- g_signal_connect (G_OBJECT (self->priv->audio_area),
- "button_press_event",
- G_CALLBACK (video_area_button_press_cb),
- self);
- g_signal_connect (G_OBJECT (self->priv->audio_area),
- "popup-menu",
- G_CALLBACK (video_area_popup_menu_cb),
- self);
- g_signal_connect (G_OBJECT (self->priv->audio_area),
- "scroll_event",
- G_CALLBACK (video_area_scroll_event_cb),
- self);
-
- /* mediabar */
-
- self->priv->builder = _gtk_builder_new_from_file ("mediabar.ui", "gstreamer_tools");
- self->priv->mediabar = GET_WIDGET ("mediabar");
- gtk_widget_set_halign (self->priv->mediabar, GTK_ALIGN_FILL);
- gtk_widget_set_valign (self->priv->mediabar, GTK_ALIGN_END);
-
- gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("play_slower_image")),
- "media-seek-backward-symbolic",
- GTK_ICON_SIZE_MENU);
- gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("play_faster_image")),
- "media-seek-forward-symbolic",
- GTK_ICON_SIZE_MENU);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("loop_button")), self->priv->loop);
-
- g_signal_connect (GET_WIDGET ("volume_adjustment"),
- "value-changed",
- G_CALLBACK (volume_value_changed_cb),
- self);
- g_signal_connect (GET_WIDGET ("position_adjustment"),
- "value-changed",
- G_CALLBACK (position_value_changed_cb),
- self);
- g_signal_connect (GET_WIDGET ("play_button"),
- "clicked",
- G_CALLBACK (play_button_clicked_cb),
- self);
- g_signal_connect (GET_WIDGET ("play_slower_button"),
- "clicked",
- G_CALLBACK (play_slower_button_clicked_cb),
- self);
- g_signal_connect (GET_WIDGET ("play_faster_button"),
- "clicked",
- G_CALLBACK (play_faster_button_clicked_cb),
- self);
- g_signal_connect (GET_WIDGET ("loop_button"),
- "clicked",
- G_CALLBACK (loop_button_clicked_cb),
- self);
-
- self->priv->mediabar_revealer = gtk_revealer_new ();
- gtk_revealer_set_transition_type (GTK_REVEALER (self->priv->mediabar_revealer),
GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
- gtk_widget_set_halign (self->priv->mediabar_revealer, GTK_ALIGN_FILL);
- gtk_widget_set_valign (self->priv->mediabar_revealer, GTK_ALIGN_END);
- gtk_widget_show (self->priv->mediabar_revealer);
- gtk_container_add (GTK_CONTAINER (self->priv->mediabar_revealer), self->priv->mediabar);
-
- self->priv->area_box = gtk_stack_new ();
- gtk_stack_add_named (GTK_STACK (self->priv->area_box), self->priv->audio_area, "audio-area");
- gtk_widget_show (self->priv->area_box);
-
- self->priv->area_overlay = gtk_overlay_new ();
- gtk_container_add (GTK_CONTAINER (self->priv->area_overlay), self->priv->area_box);
- gtk_overlay_add_overlay (GTK_OVERLAY (self->priv->area_overlay), self->priv->mediabar_revealer);
- gtk_widget_show (self->priv->area_overlay);
-
- gth_browser_set_viewer_widget (browser, self->priv->area_overlay);
-
- gtk_widget_realize (self->priv->audio_area);
- gth_browser_register_viewer_control (self->priv->browser, self->priv->mediabar_revealer);
- gth_browser_register_viewer_control (self->priv->browser, gtk_scale_button_get_popup
(GTK_SCALE_BUTTON (GET_WIDGET ("volumebutton"))));
-
- gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
-}
-
-
-static void
-save_volume (GthMediaViewerPage *self)
-{
- GSettings *settings;
- double volume;
-
- settings = g_settings_new (GTHUMB_GSTREAMER_TOOLS_SCHEMA);
- g_object_get (self->priv->playbin, "volume", &volume, NULL);
- g_settings_set_int (settings, PREF_GSTREAMER_TOOLS_VOLUME, (int) (volume * 100.0));
-
- g_object_unref (settings);
-}
-
-
-static void
-gth_media_viewer_page_real_deactivate (GthViewerPage *base)
+/*
+static char *
+state_description (GstState state)
{
- GthMediaViewerPage *self;
-
- self = (GthMediaViewerPage*) base;
-
- gth_browser_unregister_viewer_control (self->priv->browser, gtk_scale_button_get_popup
(GTK_SCALE_BUTTON (GET_WIDGET ("volumebutton"))));
- gth_browser_unregister_viewer_control (self->priv->browser, self->priv->mediabar_revealer);
-
- if (self->priv->builder != NULL) {
- g_object_unref (self->priv->builder);
- self->priv->builder = NULL;
- }
-
- if (self->priv->update_progress_id != 0) {
- g_source_remove (self->priv->update_progress_id);
- self->priv->update_progress_id = 0;
- }
-
- if (self->priv->update_volume_id != 0) {
- g_source_remove (self->priv->update_volume_id);
- self->priv->update_volume_id = 0;
- }
-
- if (self->priv->playbin != NULL) {
- save_volume (self);
- gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
- gst_object_unref (GST_OBJECT (self->priv->playbin));
- self->priv->playbin = NULL;
- self->priv->video_area = NULL;
- self->priv->audio_area = NULL;
+ switch (state) {
+ case GST_STATE_VOID_PENDING:
+ return "void pending";
+ case GST_STATE_NULL:
+ return "null";
+ case GST_STATE_READY:
+ return "ready";
+ case GST_STATE_PAUSED:
+ return "paused";
+ case GST_STATE_PLAYING:
+ return "playing";
}
-
- gtk_widget_destroy (self->priv->screenshot_button);
- self->priv->screenshot_button = NULL;
-
- gth_browser_set_viewer_widget (self->priv->browser, NULL);
+ return "error";
}
+*/
static void
@@ -856,27 +699,6 @@ update_stream_info (GthMediaViewerPage *self)
}
-/*
-static char *
-state_description (GstState state)
-{
- switch (state) {
- case GST_STATE_VOID_PENDING:
- return "void pending";
- case GST_STATE_NULL:
- return "null";
- case GST_STATE_READY:
- return "ready";
- case GST_STATE_PAUSED:
- return "paused";
- case GST_STATE_PLAYING:
- return "playing";
- }
- return "error";
-}
-*/
-
-
static void
bus_message_cb (GstBus *bus,
GstMessage *message,
@@ -1047,6 +869,201 @@ create_playbin (GthMediaViewerPage *self)
static void
+gth_media_viewer_page_real_activate (GthViewerPage *base,
+ GthBrowser *browser)
+{
+ GthMediaViewerPage *self;
+
+ if (! gstreamer_init ())
+ return;
+
+ self = (GthMediaViewerPage*) base;
+
+ self->priv->browser = browser;
+ g_action_map_add_action_entries (G_ACTION_MAP (browser),
+ actions,
+ G_N_ELEMENTS (actions),
+ browser);
+ self->priv->screenshot_button =
+ gth_browser_add_header_bar_button (browser,
+ GTH_BROWSER_HEADER_SECTION_VIEWER_VIEW,
+ "camera-photo-symbolic",
+ _("Take a screenshot"),
+ "win.video-screenshot",
+ NULL);
+
+ /* audio area */
+
+ self->priv->audio_area = gtk_drawing_area_new ();
+ gtk_style_context_add_class (gtk_widget_get_style_context (self->priv->audio_area), "video-player");
+ gtk_widget_add_events (self->priv->audio_area, (gtk_widget_get_events (self->priv->audio_area)
+ | GDK_EXPOSURE_MASK
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_POINTER_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON_MOTION_MASK
+ | GDK_SCROLL_MASK));
+ gtk_widget_set_can_focus (self->priv->audio_area, TRUE);
+ gtk_widget_show (self->priv->audio_area);
+
+ g_signal_connect (G_OBJECT (self->priv->audio_area),
+ "draw",
+ G_CALLBACK (video_area_draw_cb),
+ self);
+ g_signal_connect (G_OBJECT (self->priv->audio_area),
+ "button_press_event",
+ G_CALLBACK (video_area_button_press_cb),
+ self);
+ g_signal_connect (G_OBJECT (self->priv->audio_area),
+ "popup-menu",
+ G_CALLBACK (video_area_popup_menu_cb),
+ self);
+ g_signal_connect (G_OBJECT (self->priv->audio_area),
+ "scroll_event",
+ G_CALLBACK (video_area_scroll_event_cb),
+ self);
+
+ /* mediabar */
+
+ self->priv->builder = _gtk_builder_new_from_file ("mediabar.ui", "gstreamer_tools");
+ self->priv->mediabar = GET_WIDGET ("mediabar");
+ gtk_widget_set_halign (self->priv->mediabar, GTK_ALIGN_FILL);
+ gtk_widget_set_valign (self->priv->mediabar, GTK_ALIGN_END);
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("play_slower_image")),
+ "media-seek-backward-symbolic",
+ GTK_ICON_SIZE_MENU);
+ gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("play_faster_image")),
+ "media-seek-forward-symbolic",
+ GTK_ICON_SIZE_MENU);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("loop_button")), self->priv->loop);
+
+ g_signal_connect (GET_WIDGET ("volume_adjustment"),
+ "value-changed",
+ G_CALLBACK (volume_value_changed_cb),
+ self);
+ g_signal_connect (GET_WIDGET ("position_adjustment"),
+ "value-changed",
+ G_CALLBACK (position_value_changed_cb),
+ self);
+ g_signal_connect (GET_WIDGET ("play_button"),
+ "clicked",
+ G_CALLBACK (play_button_clicked_cb),
+ self);
+ g_signal_connect (GET_WIDGET ("play_slower_button"),
+ "clicked",
+ G_CALLBACK (play_slower_button_clicked_cb),
+ self);
+ g_signal_connect (GET_WIDGET ("play_faster_button"),
+ "clicked",
+ G_CALLBACK (play_faster_button_clicked_cb),
+ self);
+ g_signal_connect (GET_WIDGET ("loop_button"),
+ "clicked",
+ G_CALLBACK (loop_button_clicked_cb),
+ self);
+
+ self->priv->mediabar_revealer = gtk_revealer_new ();
+ gtk_revealer_set_transition_type (GTK_REVEALER (self->priv->mediabar_revealer),
GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
+ gtk_widget_set_halign (self->priv->mediabar_revealer, GTK_ALIGN_FILL);
+ gtk_widget_set_valign (self->priv->mediabar_revealer, GTK_ALIGN_END);
+ gtk_widget_show (self->priv->mediabar_revealer);
+ gtk_container_add (GTK_CONTAINER (self->priv->mediabar_revealer), self->priv->mediabar);
+
+ self->priv->area_box = gtk_stack_new ();
+ gtk_stack_add_named (GTK_STACK (self->priv->area_box), self->priv->audio_area, "audio-area");
+ gtk_widget_show (self->priv->area_box);
+
+ self->priv->area_overlay = gtk_overlay_new ();
+ gtk_container_add (GTK_CONTAINER (self->priv->area_overlay), self->priv->area_box);
+ gtk_overlay_add_overlay (GTK_OVERLAY (self->priv->area_overlay), self->priv->mediabar_revealer);
+ gtk_widget_show (self->priv->area_overlay);
+
+ gth_browser_set_viewer_widget (browser, self->priv->area_overlay);
+
+ gtk_widget_realize (self->priv->audio_area);
+ gth_browser_register_viewer_control (self->priv->browser, self->priv->mediabar_revealer);
+ gth_browser_register_viewer_control (self->priv->browser, gtk_scale_button_get_popup
(GTK_SCALE_BUTTON (GET_WIDGET ("volumebutton"))));
+
+ gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
+
+ create_playbin (self);
+}
+
+
+static void
+save_volume (GthMediaViewerPage *self)
+{
+ GSettings *settings;
+ double volume;
+
+ settings = g_settings_new (GTHUMB_GSTREAMER_TOOLS_SCHEMA);
+ g_object_get (self->priv->playbin, "volume", &volume, NULL);
+ g_settings_set_int (settings, PREF_GSTREAMER_TOOLS_VOLUME, (int) (volume * 100.0));
+
+ g_object_unref (settings);
+}
+
+
+static void
+wait_playbin_state_change_to_complete (GthMediaViewerPage *self)
+{
+ (void) gst_element_get_state (self->priv->playbin,
+ NULL,
+ NULL,
+ GST_SECOND * 10);
+}
+
+
+static void
+gth_media_viewer_page_real_deactivate (GthViewerPage *base)
+{
+ GthMediaViewerPage *self;
+
+ self = (GthMediaViewerPage*) base;
+
+ gth_browser_unregister_viewer_control (self->priv->browser, gtk_scale_button_get_popup
(GTK_SCALE_BUTTON (GET_WIDGET ("volumebutton"))));
+ gth_browser_unregister_viewer_control (self->priv->browser, self->priv->mediabar_revealer);
+
+ if (self->priv->builder != NULL) {
+ g_object_unref (self->priv->builder);
+ self->priv->builder = NULL;
+ }
+
+ if (self->priv->update_progress_id != 0) {
+ g_source_remove (self->priv->update_progress_id);
+ self->priv->update_progress_id = 0;
+ }
+
+ if (self->priv->update_volume_id != 0) {
+ g_source_remove (self->priv->update_volume_id);
+ self->priv->update_volume_id = 0;
+ }
+
+ if (self->priv->playbin != NULL) {
+ save_volume (self);
+
+ g_signal_handlers_disconnect_by_data (self->priv->playbin, self);
+ g_signal_handlers_disconnect_by_data (self->priv->video_area, self);
+
+ gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
+ wait_playbin_state_change_to_complete (self);
+ gst_object_unref (GST_OBJECT (self->priv->playbin));
+ self->priv->playbin = NULL;
+ self->priv->video_area = NULL;
+ self->priv->audio_area = NULL;
+ }
+
+ gtk_widget_destroy (self->priv->screenshot_button);
+ self->priv->screenshot_button = NULL;
+
+ gth_browser_set_viewer_widget (self->priv->browser, NULL);
+}
+
+
+static void
_gth_media_viewer_page_set_uri (GthMediaViewerPage *self,
const char *uri,
GstState state)
@@ -1057,7 +1074,7 @@ _gth_media_viewer_page_set_uri (GthMediaViewerPage *self,
g_object_set (G_OBJECT (self->priv->playbin), "uri", uri, NULL);
gst_element_set_state (self->priv->playbin, state);
- /*gst_element_get_state (self->priv->playbin, NULL, NULL, GST_CLOCK_TIME_NONE);*/
+ wait_playbin_state_change_to_complete (self);
}
@@ -1070,7 +1087,6 @@ gth_media_viewer_page_real_show (GthViewerPage *base)
self->priv->background_painted = FALSE;
gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
- create_playbin (self);
if (self->priv->file_data != NULL) {
char *uri;
@@ -1114,9 +1130,7 @@ gth_media_viewer_page_real_view (GthViewerPage *base,
self = (GthMediaViewerPage*) base;
g_return_if_fail (file_data != NULL);
-
- if (! gstreamer_init ())
- return;
+ g_return_if_fail (self->priv->playbin != NULL);
gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
@@ -1151,10 +1165,6 @@ gth_media_viewer_page_real_view (GthViewerPage *base,
g_signal_handlers_unblock_by_func(GET_WIDGET ("position_adjustment"), position_value_changed_cb,
self);
reset_player_state (self);
- create_playbin (self);
- if (self->priv->playbin == NULL)
- return;
-
uri = g_file_get_uri (self->priv->file_data->file);
_gth_media_viewer_page_set_uri (self, uri, self->priv->visible ? GST_STATE_PLAYING :
GST_STATE_PAUSED);
@@ -1285,13 +1295,7 @@ gth_media_viewer_page_finalize (GObject *obj)
self->priv->update_volume_id = 0;
}
- if (self->priv->playbin != NULL) {
- save_volume (self);
- gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
- gst_object_unref (GST_OBJECT (self->priv->playbin));
- self->priv->playbin = NULL;
- }
- _g_object_unref (self->priv->icon);
+ _g_object_unref (self->priv->icon);
_g_object_unref (self->priv->file_data);
_g_object_unref (self->priv->updated_info);
if (self->priv->screensaver != NULL) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]