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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2028>
#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"
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);
{
SIGNAL_POSITION_UPDATED,
SIGNAL_DURATION_CHANGED,
+ SIGNAL_STATE_CHANGED,
SIGNAL_DONE,
SIGNAL_ERROR,
SIGNAL_WARNING,
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;
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:
*
GstClockTime last_duration;
+ GstTranscoderState app_state;
+
GstBus *api_bus;
GstTranscoderSignalAdapter *signal_adapter;
GstTranscoderSignalAdapter *sync_signal_adapter;
}
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)
{
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;
}
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);
}
}
}
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);
}
/**
+ * 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
* @error: (out): the resulting 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;
+}
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
{
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,
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);
GST_TRANSCODER_API