From a6b5e3c7d59c699063296611da91b2654303b3e6 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Sat, 20 Feb 2021 11:36:42 +0000 Subject: [PATCH] transcoder: Add state-changed signal Similar to GstPlayer, a new signal for state tracking is now emitted at runtime, as a commodity for applications which then don't need to monitor the pipeline GstBus for state changes anymore. Part-of: --- .../gst/transcoder/gsttranscoder-private.h | 3 +- .../transcoder/gsttranscoder-signal-adapter.c | 13 ++++ gst-libs/gst/transcoder/gsttranscoder.c | 68 +++++++++++++++++++ gst-libs/gst/transcoder/gsttranscoder.h | 27 ++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/transcoder/gsttranscoder-private.h b/gst-libs/gst/transcoder/gsttranscoder-private.h index edf8daf9ca..f0acce6ef5 100644 --- a/gst-libs/gst/transcoder/gsttranscoder-private.h +++ b/gst-libs/gst/transcoder/gsttranscoder-private.h @@ -25,6 +25,7 @@ #define GST_TRANSCODER_MESSAGE_DATA_TYPE "transcoder-message-type" #define GST_TRANSCODER_MESSAGE_DATA_POSITION "position" #define GST_TRANSCODER_MESSAGE_DATA_DURATION "duration" +#define GST_TRANSCODER_MESSAGE_DATA_STATE "state" #define GST_TRANSCODER_MESSAGE_DATA_ERROR "error" #define GST_TRANSCODER_MESSAGE_DATA_WARNING "warning" #define GST_TRANSCODER_MESSAGE_DATA_ISSUE_DETAILS "issue-details" @@ -40,4 +41,4 @@ struct _GstTranscoderSignalAdapter GstTranscoderSignalAdapter * gst_transcoder_signal_adapter_new_sync_emit (GstTranscoder * transcoder); -GstTranscoderSignalAdapter * gst_transcoder_signal_adapter_new (GstTranscoder * transcoder, GMainContext * context); \ No newline at end of file +GstTranscoderSignalAdapter * gst_transcoder_signal_adapter_new (GstTranscoder * transcoder, GMainContext * context); diff --git a/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.c b/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.c index 6d544051f9..cbbec126ee 100644 --- a/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.c +++ b/gst-libs/gst/transcoder/gsttranscoder-signal-adapter.c @@ -37,6 +37,7 @@ enum { SIGNAL_POSITION_UPDATED, SIGNAL_DURATION_CHANGED, + SIGNAL_STATE_CHANGED, SIGNAL_DONE, SIGNAL_ERROR, SIGNAL_WARNING, @@ -94,6 +95,13 @@ gst_transcoder_signal_adapter_emit (GstTranscoderSignalAdapter * self, g_signal_emit (self, signals[SIGNAL_DURATION_CHANGED], 0, duration); break; } + case GST_TRANSCODER_MESSAGE_STATE_CHANGED:{ + GstTranscoderState state; + gst_structure_get (message_data, GST_TRANSCODER_MESSAGE_DATA_STATE, + GST_TYPE_TRANSCODER_STATE, &state, NULL); + g_signal_emit (self, signals[SIGNAL_STATE_CHANGED], 0, state); + break; + } case GST_TRANSCODER_MESSAGE_DONE: g_signal_emit (self, signals[SIGNAL_DONE], 0); break; @@ -298,6 +306,11 @@ gst_transcoder_signal_adapter_class_init (GstTranscoderSignalAdapterClass * G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_ERROR, GST_TYPE_STRUCTURE); + signals[SIGNAL_STATE_CHANGED] = + g_signal_new ("state-changed", 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_TRANSCODER_STATE); + /** * GstTranscoderSignalAdapter:transcoder: * diff --git a/gst-libs/gst/transcoder/gsttranscoder.c b/gst-libs/gst/transcoder/gsttranscoder.c index 575493a251..1b933751fa 100644 --- a/gst-libs/gst/transcoder/gsttranscoder.c +++ b/gst-libs/gst/transcoder/gsttranscoder.c @@ -90,6 +90,8 @@ struct _GstTranscoder GstClockTime last_duration; + GstTranscoderState app_state; + GstBus *api_bus; GstTranscoderSignalAdapter *signal_adapter; GstTranscoderSignalAdapter *sync_signal_adapter; @@ -589,6 +591,20 @@ warning_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data) g_free (message); } +static void +notify_state_changed (GstTranscoder * self, GstTranscoderState new_state) +{ + if (new_state == self->app_state) + return; + + GST_DEBUG_OBJECT (self, "Notifying new state: %s", + gst_transcoder_state_get_name (new_state)); + self->app_state = new_state; + api_bus_post_message (self, GST_TRANSCODER_MESSAGE_STATE_CHANGED, + GST_TRANSCODER_MESSAGE_DATA_STATE, GST_TYPE_TRANSCODER_STATE, new_state, + NULL); +} + static void eos_cb (G_GNUC_UNUSED GstBus * bus, G_GNUC_UNUSED GstMessage * msg, gpointer user_data) @@ -602,6 +618,7 @@ eos_cb (G_GNUC_UNUSED GstBus * bus, G_GNUC_UNUSED GstMessage * msg, tick_cb (self); remove_tick_source (self); + notify_state_changed (self, GST_TRANSCODER_STATE_STOPPED); api_bus_post_message (self, GST_TRANSCODER_MESSAGE_DONE, NULL, NULL); self->is_eos = TRUE; } @@ -654,9 +671,16 @@ state_changed_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, self->current_state = new_state; + if (new_state == GST_STATE_PAUSED + && pending_state == GST_STATE_VOID_PENDING) { + remove_tick_source (self); + notify_state_changed (self, GST_TRANSCODER_STATE_PAUSED); + } + if (new_state == GST_STATE_PLAYING && pending_state == GST_STATE_VOID_PENDING) { add_tick_source (self); + notify_state_changed (self, GST_TRANSCODER_STATE_PLAYING); } } } @@ -797,6 +821,7 @@ gst_transcoder_main (gpointer data) self->current_state = GST_STATE_NULL; self->is_eos = FALSE; self->is_live = FALSE; + self->app_state = GST_TRANSCODER_STATE_STOPPED; GST_TRACE_OBJECT (self, "Starting main loop"); g_main_loop_run (self->loop); @@ -1410,6 +1435,23 @@ gst_transcoder_message_parse_position (GstMessage * msg, GST_TYPE_CLOCK_TIME, position); } +/** + * gst_transcoder_message_parse_state: + * @msg: A #GstMessage + * @state: (out): the resulting state + * + * Parse the given state @msg and extract the corresponding #GstTranscoderState + * + * Since: 1.20 + */ +void +gst_transcoder_message_parse_state (GstMessage * msg, + GstTranscoderState * state) +{ + PARSE_MESSAGE_FIELD (msg, GST_TRANSCODER_MESSAGE_DATA_STATE, + GST_TYPE_TRANSCODER_STATE, state); +} + /** * gst_transcoder_message_parse_error: * @msg: A #GstMessage @@ -1449,3 +1491,29 @@ gst_transcoder_message_parse_warning (GstMessage * msg, GError * error, PARSE_MESSAGE_FIELD (msg, GST_TRANSCODER_MESSAGE_DATA_ISSUE_DETAILS, GST_TYPE_STRUCTURE, details); } + +/** + * gst_transcoder_state_get_name: + * @state: a #GstTranscoderState + * + * Gets a string representing the given state. + * + * Returns: (transfer none): a string with the name of the state. + * + * Since: 1.20 + */ +const gchar * +gst_transcoder_state_get_name (GstTranscoderState state) +{ + switch (state) { + case GST_TRANSCODER_STATE_STOPPED: + return "stopped"; + case GST_TRANSCODER_STATE_PAUSED: + return "paused"; + case GST_TRANSCODER_STATE_PLAYING: + return "playing"; + } + + g_assert_not_reached (); + return NULL; +} diff --git a/gst-libs/gst/transcoder/gsttranscoder.h b/gst-libs/gst/transcoder/gsttranscoder.h index 5f890c6385..938db7e672 100644 --- a/gst-libs/gst/transcoder/gsttranscoder.h +++ b/gst-libs/gst/transcoder/gsttranscoder.h @@ -28,12 +28,35 @@ GQuark gst_transcoder_error_quark (void); GST_TRANSCODER_API const gchar * gst_transcoder_error_get_name (GstTranscoderError error); +/*********** State definition ************/ + +/** + * GstTranscoderState: + * @GST_TRANSCODER_STATE_STOPPED: the transcoder is stopped. + * @GST_TRANSCODER_STATE_PAUSED: the transcoder is paused. + * @GST_TRANSCODER_STATE_PLAYING: the transcoder is currently transcoding a + * stream. + * + * High level representation of the transcoder pipeline state. + * + * Since: 1.20 + */ +typedef enum { + GST_TRANSCODER_STATE_STOPPED, + GST_TRANSCODER_STATE_PAUSED, + GST_TRANSCODER_STATE_PLAYING +} GstTranscoderState; + +GST_TRANSCODER_API +const gchar * gst_transcoder_state_get_name (GstTranscoderState state); + /*********** Messages types definitions ************/ /** * GstTranscoderMessage: * @GST_TRANSCODER_MESSAGE_POSITION_UPDATED: Sink position changed * @GST_TRANSCODER_MESSAGE_DURATION_CHANGED: Duration of stream changed + * @GST_TRANSCODER_MESSAGE_STATE_CHANGED: Pipeline state changed * @GST_TRANSCODER_MESSAGE_DONE: Transcoding is done * @GST_TRANSCODER_MESSAGE_ERROR: Message contains an error * @GST_TRANSCODER_MESSAGE_WARNING: Message contains an error @@ -48,6 +71,7 @@ typedef enum { GST_TRANSCODER_MESSAGE_POSITION_UPDATED, GST_TRANSCODER_MESSAGE_DURATION_CHANGED, + GST_TRANSCODER_MESSAGE_STATE_CHANGED, GST_TRANSCODER_MESSAGE_DONE, GST_TRANSCODER_MESSAGE_ERROR, GST_TRANSCODER_MESSAGE_WARNING, @@ -65,6 +89,9 @@ void gst_transcoder_message_parse_position (GstMessage * msg GST_TRANSCODER_API void gst_transcoder_message_parse_duration (GstMessage * msg, GstClockTime * duration); +GST_TRANSCODER_API +void gst_transcoder_message_parse_state (GstMessage * msg, GstTranscoderState * state); + GST_TRANSCODER_API void gst_transcoder_message_parse_error (GstMessage * msg, GError * error, GstStructure ** details);