From 30a7229b338ffcb04bbc0b7344e3148860bf7d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Tue, 6 Apr 2021 18:49:08 +0200 Subject: [PATCH] API: add media info updated signal Emit media info updated signal only when media info is initially created and when number/format of tracks changes later. This is needed for GUI to detect resolution change (adaptive streaming) or when user adds external subtitles to current video. --- lib/gst/clapper/gstclapper.c | 61 +++++++++++++++++++++++++++++++++++- src/widget.js | 24 ++------------ 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/lib/gst/clapper/gstclapper.c b/lib/gst/clapper/gstclapper.c index e09c46ce..46cd7765 100644 --- a/lib/gst/clapper/gstclapper.c +++ b/lib/gst/clapper/gstclapper.c @@ -106,6 +106,7 @@ enum SIGNAL_ERROR, SIGNAL_WARNING, SIGNAL_VIDEO_DIMENSIONS_CHANGED, + SIGNAL_MEDIA_INFO_UPDATED, SIGNAL_MUTE_CHANGED, SIGNAL_LAST }; @@ -421,6 +422,11 @@ gst_clapper_class_init (GstClapperClass * klass) G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_ERROR); + signals[SIGNAL_MEDIA_INFO_UPDATED] = + g_signal_new ("media-info-updated", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL, + NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_CLAPPER_MEDIA_INFO); + signals[SIGNAL_VIDEO_DIMENSIONS_CHANGED] = g_signal_new ("video-dimensions-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL, @@ -838,6 +844,48 @@ main_loop_running_cb (gpointer user_data) return G_SOURCE_REMOVE; } +typedef struct +{ + GstClapper *clapper; + GstClapperMediaInfo *info; +} MediaInfoUpdatedSignalData; + +static void +media_info_updated_dispatch (gpointer user_data) +{ + MediaInfoUpdatedSignalData *data = user_data; + + if (data->clapper->inhibit_sigs) + return; + + if (data->clapper->target_state >= GST_STATE_PAUSED) { + g_signal_emit (data->clapper, signals[SIGNAL_MEDIA_INFO_UPDATED], 0, + data->info); + } +} + +static void +free_media_info_updated_signal_data (MediaInfoUpdatedSignalData * data) +{ + g_object_unref (data->clapper); + g_object_unref (data->info); + g_free (data); +} + +static void +emit_media_info_updated (GstClapper * self) +{ + MediaInfoUpdatedSignalData *data = g_new (MediaInfoUpdatedSignalData, 1); + data->clapper = g_object_ref (self); + g_mutex_lock (&self->lock); + data->info = gst_clapper_media_info_copy (self->media_info); + g_mutex_unlock (&self->lock); + + gst_clapper_signal_dispatcher_dispatch (self->signal_dispatcher, self, + media_info_updated_dispatch, data, + (GDestroyNotify) free_media_info_updated_signal_data); +} + typedef struct { GstClapper *clapper; @@ -1468,7 +1516,17 @@ notify_caps_cb (G_GNUC_UNUSED GObject * object, { GstClapper *self = GST_CLAPPER (user_data); - check_video_dimensions_changed (self); + if (self->target_state >= GST_STATE_PAUSED) { + gboolean has_media_info = FALSE; + + check_video_dimensions_changed (self); + g_mutex_lock (&self->lock); + has_media_info = (self->media_info != NULL); + g_mutex_unlock (&self->lock); + + if (has_media_info) + emit_media_info_updated (self); + } } typedef struct @@ -1568,6 +1626,7 @@ state_changed_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, } else { self->cached_duration = GST_CLOCK_TIME_NONE; } + emit_media_info_updated (self); } if (new_state == GST_STATE_PAUSED diff --git a/src/widget.js b/src/widget.js index 9c42af70..53cb9b0f 100644 --- a/src/widget.js +++ b/src/widget.js @@ -40,7 +40,6 @@ class ClapperWidget extends Gtk.Grid this._hideControlsTimeout = null; this._updateTimeTimeout = null; - this.needsTracksUpdate = true; this.needsCursorRestore = false; this.overlay = new Gtk.Overlay(); @@ -75,6 +74,7 @@ class ClapperWidget extends Gtk.Grid ); this.player.connect('position-updated', this._onPlayerPositionUpdated.bind(this)); this.player.connect('duration-changed', this._onPlayerDurationChanged.bind(this)); + this.player.connect('media-info-updated', this._onMediaInfoUpdated.bind(this)); this.overlay.set_child(playerWidget); this.overlay.add_overlay(this.revealerTop); @@ -197,12 +197,8 @@ class ClapperWidget extends Gtk.Grid this.controlsBox.set_visible(!isOnTop); } - _updateMediaInfo() + _onMediaInfoUpdated(player, mediaInfo) { - const mediaInfo = this.player.get_media_info(); - if(!mediaInfo) - return GLib.SOURCE_REMOVE; - /* Set titlebar media title */ this.updateTitle(mediaInfo); @@ -212,8 +208,7 @@ class ClapperWidget extends Gtk.Grid this.controls.setLiveMode(isLive, this.isSeekable); if(this.player.needsTocUpdate) { - /* FIXME: Remove `get_toc` check after required GstPlay(er) ver bump */ - if(!isLive && mediaInfo.get_toc) + if(!isLive) this.updateChapters(mediaInfo.get_toc()); this.player.needsTocUpdate = false; @@ -309,8 +304,6 @@ class ClapperWidget extends Gtk.Grid anyButtonShown = true; } this.controls.revealTracksRevealer.set_visible(anyButtonShown); - - return GLib.SOURCE_REMOVE; } updateTitle(mediaInfo) @@ -449,16 +442,12 @@ class ClapperWidget extends Gtk.Grid this.controls.positionScale.clear_marks(); this.controls.chapters = null; } - if(!player.playlistWidget.getActiveIsLocalFile()) { - this.needsTracksUpdate = true; - } break; case GstClapper.ClapperState.STOPPED: debug('player state changed to: STOPPED'); this.controls.currentPosition = 0; this.controls.positionScale.set_value(0); this.controls.togglePlayButton.setPrimaryIcon(); - this.needsTracksUpdate = true; break; case GstClapper.ClapperState.PAUSED: debug('player state changed to: PAUSED'); @@ -467,13 +456,6 @@ class ClapperWidget extends Gtk.Grid case GstClapper.ClapperState.PLAYING: debug('player state changed to: PLAYING'); this.controls.togglePlayButton.setSecondaryIcon(); - if(this.needsTracksUpdate) { - this.needsTracksUpdate = false; - GLib.idle_add( - GLib.PRIORITY_DEFAULT_IDLE, - this._updateMediaInfo.bind(this) - ); - } break; default: break;