static GstStateChangeReturn gst_ducati_viddec_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstDucatiVidDec *self = GST_DUCATIVIDDEC (element); GST_INFO_OBJECT (self, "begin: changing state %s -> %s", gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)), gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition))); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!engine_open (self)) { GST_ERROR_OBJECT (self, "could not open"); return GST_STATE_CHANGE_FAILURE; } break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (ret == GST_STATE_CHANGE_FAILURE) goto leave; switch (transition) { case GST_STATE_CHANGE_READY_TO_NULL: codec_delete (self); engine_close (self); break; default: break; } leave: GST_LOG_OBJECT (self, "end"); return ret; }
gboolean check_run_main_loop_until_msg_or_error (BtSong * song, const gchar * msg) { GstStateChangeReturn sret; GstState state, pending; GMainLoop *main_loop = g_main_loop_new (NULL, FALSE); GstElement *bin = (GstElement *) check_gobject_get_object_property (song, "bin"); GstBus *bus = gst_element_get_bus (bin); gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); g_signal_connect (bus, "message::error", G_CALLBACK (_check_message_received), (gpointer) main_loop); g_signal_connect (bus, msg, G_CALLBACK (_check_message_received), (gpointer) main_loop); _check_run_main_loop_error = FALSE; sret = gst_element_get_state (bin, &state, &pending, G_GUINT64_CONSTANT (0)); // be careful to not run this when the song already finished if (sret != GST_STATE_CHANGE_FAILURE) { GST_INFO_OBJECT (song, "running main_loop: sret=%s, state=%s/%s", gst_element_state_change_return_get_name (sret), gst_element_state_get_name (state), gst_element_state_get_name (pending)); g_main_loop_run (main_loop); } else { GST_INFO_OBJECT (song, "skipping main_loop: sret=%s, state=%s/%s", gst_element_state_change_return_get_name (sret), gst_element_state_get_name (state), gst_element_state_get_name (pending)); } gst_bus_remove_signal_watch (bus); g_signal_handlers_disconnect_matched (bus, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, (gpointer) main_loop); gst_object_unref (bus); gst_object_unref (bin); g_main_loop_unref (main_loop); GST_INFO_OBJECT (song, "finished main_loop"); return sret == GST_STATE_CHANGE_FAILURE ? FALSE : !_check_run_main_loop_error; }
static gboolean mybusfunc(GstBus *bus, GstMessage *message, gpointer user_data) { GMainLoop *loop = (GMainLoop *) user_data; GstState prev_state, curr_state; GError *err = NULL; gchar *debug_info = NULL; g_print("Got %s\n", GST_MESSAGE_TYPE_NAME(message)); switch (GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_EOS: g_print("End of stream\n"); g_main_loop_quit(loop); break; case GST_MESSAGE_ERROR: gst_message_parse_error(message, &err, &debug_info); g_printerr("Error from element %s: %s\n", GST_OBJECT_NAME(message->src), err->message); g_printerr("Debugging info: %s\n", (debug_info) ? debug_info : "none"); g_error_free(err); g_free(debug_info); g_main_loop_quit(loop); break; case GST_MESSAGE_STATE_CHANGED: gst_message_parse_state_changed(message, &prev_state, &curr_state, NULL); g_print("Element %s changed from %s to %s\n", GST_OBJECT_NAME(message->src), gst_element_state_get_name(prev_state), gst_element_state_get_name(curr_state)); break; default: g_print("Unhandled messages"); break; } g_print("\n"); return TRUE; }
static gboolean bus_callback (GstBus * bus, GstMessage * message, gpointer data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR:{ GError *err; gchar *debug; gst_message_parse_error (message, &err, &debug); g_print ("Error: %s\n", err->message); g_error_free (err); g_free (debug); /* Write debug graph to file */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (camera_bin), GST_DEBUG_GRAPH_SHOW_ALL, "camerabin.error"); g_main_loop_quit (loop); break; } case GST_MESSAGE_STATE_CHANGED: if (GST_IS_BIN (GST_MESSAGE_SRC (message))) { GstState oldstate, newstate; gst_message_parse_state_changed (message, &oldstate, &newstate, NULL); GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "state-changed: %s -> %s", gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate)); } break; case GST_MESSAGE_EOS: /* end-of-stream */ GST_INFO ("got eos() - should not happen"); g_main_loop_quit (loop); break; default: /* unhandled message */ break; } return TRUE; }
/* This function is called when the pipeline changes states. We use it to * keep track of the current state. */ static void state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) { GstState old_state, new_state, pending_state; gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state); if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->playbin)) { data->state = new_state; g_print ("State set to %s\n", gst_element_state_get_name (new_state)); if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) { /* For extra responsiveness, we refresh the GUI as soon as we reach the PAUSED state */ refresh_ui (data); } } }
void GstUtils::wait_state_changed(GstElement *bin) { if (!GST_IS_BIN(bin)) { g_warning("GstUtils::wait_state_changed not a bin"); return; } GValue val = G_VALUE_INIT; g_value_init(&val, G_TYPE_BOOLEAN); g_object_get_property(G_OBJECT(bin), "async-handling", &val); if (g_value_get_boolean(&val) == FALSE) while (GST_STATE(bin) != GST_STATE_TARGET(bin)) { g_debug("GstUtils::wait_state_changed, from %s to %s", gst_element_state_get_name(GST_STATE(bin)), gst_element_state_get_name(GST_STATE_TARGET(bin))); // warning this may be blocking gst_element_get_state(bin, nullptr, nullptr, GST_CLOCK_TIME_NONE); } g_value_unset(&val); return; }
gboolean on_pipeline_msg(GstBus * bus, GstMessage * msg, gpointer loop) { gchar * debug; GError * error;; switch(GST_MESSAGE_TYPE(msg)) { // Mensaje de finalización del stream case GST_MESSAGE_EOS: fprintf(stderr, "End of stream\n"); kill(getpid(), SIGUSR1); break; // Mensaje que indica que se ha producido un error case GST_MESSAGE_ERROR: gst_message_parse_error(msg, & error, & debug); g_free(debug); g_printerr("Error: %s\n", error->message); g_error_free(error); kill(getpid(), SIGUSR1); break; case GST_MESSAGE_STATE_CHANGED: { GstState old_state, new_state; gst_message_parse_state_changed(msg, &old_state, &new_state, NULL); g_print("Element %s changed state from %s to %s.\n", GST_OBJECT_NAME(msg->src), gst_element_state_get_name(old_state), gst_element_state_get_name(new_state)); break; } default: break; } return TRUE; }
static void state_changed_cb (GstBus * bus, GstMessage * msg, APP_STATE_T * state) { GstState old_state, new_state, pending_state; if (GST_MESSAGE_SRC (msg) == GST_OBJECT (state->pipeline)) { gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state); g_print ("State changed to %s\n", gst_element_state_get_name (new_state)); if (old_state == GST_STATE_PAUSED && new_state == GST_STATE_READY) { g_main_loop_quit (state->main_loop); } } }
static void start_state_change (RBPlayerGst *mp, GstState state, enum StateChangeAction action) { GstStateChangeReturn scr; rb_debug ("changing state to %s", gst_element_state_get_name (state)); mp->priv->state_change_action = action; scr = gst_element_set_state (mp->priv->playbin, state); if (scr == GST_STATE_CHANGE_SUCCESS) { rb_debug ("state change succeeded synchronously"); state_change_finished (mp, NULL); } }
static gboolean thumb_app_start (ThumbApp *app) { GstBus *bus; GstMessageType events; gboolean terminate = FALSE; gboolean async_received = FALSE; gst_element_set_state (app->play, GST_STATE_PAUSED); bus = gst_element_get_bus (app->play); events = GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR; while (terminate == FALSE) { GstMessage *message; GstElement *src; message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, events); src = (GstElement*)GST_MESSAGE_SRC (message); switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ASYNC_DONE: if (src == app->play) { async_received = TRUE; terminate = TRUE; } break; case GST_MESSAGE_ERROR: xplayer_gst_message_print (message, app->play, "xplayer-video-thumbnailer-error"); terminate = TRUE; break; default: /* Ignore */ ;; } gst_message_unref (message); } gst_object_unref (bus); if (async_received) { /* state change succeeded */ GST_DEBUG ("state change to %s succeeded", gst_element_state_get_name (GST_STATE_PAUSED)); } return async_received; }
static gboolean bus_call (GstBus * bus, GstMessage * msg, gpointer data) { switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS:{ gst_element_set_state (gst_data.playbin, GST_STATE_NULL); gst_element_set_state (gst_data.playbin, GST_STATE_PLAYING); g_print ("End-of-stream\n"); break; } case GST_MESSAGE_STATE_CHANGED: { GstState old_state, new_state; gst_message_parse_state_changed (msg, &old_state, &new_state, NULL); g_print ("Element %s changed state from %s to %s.\n", GST_OBJECT_NAME (msg->src), gst_element_state_get_name (old_state), gst_element_state_get_name (new_state)); break; } case GST_MESSAGE_ERROR:{ gchar *debug; GError *err; gst_element_set_state (gst_data.playbin, GST_STATE_NULL); gst_message_parse_error (msg, &err, &debug); g_print ("Debugging info: %s\n", (debug) ? debug : "none"); g_free (debug); g_print ("Error: %s\n", err->message); g_error_free (err); break; } default: break; } return TRUE; }
static void assert_state_change (GstElement * element, GstState new_state, GstStateChangeReturn result, GstState result_state) { GstStateChangeReturn ret = gst_element_set_state (element, new_state); if (ret != result) { g_printerr ("%s: change state to %s returned %s instead of %s", GST_OBJECT_NAME (element), gst_element_state_get_name (new_state), RETURN_NAME (ret), RETURN_NAME (result)); g_assert_not_reached (); } assert_state (element, result_state); }
static gboolean jack_handle_transport_change (GstJackAudioClient * client, GstState state) { GstObject *obj = GST_OBJECT_PARENT (client->user_data); guint mode; g_object_get (obj, "transport", &mode, NULL); if ((mode & GST_JACK_TRANSPORT_SLAVE) && (GST_STATE (obj) != state)) { GST_INFO_OBJECT (obj, "requesting state change: %s", gst_element_state_get_name (state)); gst_element_post_message (GST_ELEMENT (obj), gst_message_new_request_state (obj, state)); return TRUE; } return FALSE; }
static gboolean stop_data(GstElement *source) { if (gst_element_is_locked_state(source) == FALSE) { if (gst_element_set_locked_state(source, TRUE) == TRUE) { std::clog << "##### LOCK OK" << std::endl; std::clog << "##### LOCK NOW" << std::endl; GstState rtspstate; gst_element_get_state(source, &rtspstate, NULL, GST_CLOCK_TIME_NONE); switch (rtspstate) { case GST_STATE_PLAYING: gst_element_set_state(source, GST_STATE_PAUSED); gst_element_set_locked_state(source, FALSE); break; case GST_STATE_PAUSED: gst_element_set_state(source, GST_STATE_READY); gst_element_set_locked_state(source, FALSE); break; case GST_STATE_READY: gst_element_set_state(source, GST_STATE_NULL); gst_element_set_locked_state(source, FALSE); break; case GST_STATE_NULL: gst_object_unref(GST_OBJECT(source)); g_idle_remove_by_data(source); break; } std::clog << "########## State: " << gst_element_state_get_name( rtspstate) << std::endl; // gst_object_unref(GST_OBJECT(source)); } } }
/* This function is called when the pipeline changes states. We use it to * keep track of the current state. */ static void state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) { GstState old_state, new_state, pending_state; gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state); if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->pipeline)) { data->state = new_state; g_print ("State set to %s\n", gst_element_state_get_name (new_state)); /* update playPauseImage */ if (data->state == GST_STATE_PAUSED || data->state == GST_STATE_READY) { _set_playPauseImage(data, GTK_STOCK_MEDIA_PLAY); } else { _set_playPauseImage(data, GTK_STOCK_MEDIA_PAUSE); } if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) { /* For extra responsiveness, we refresh the GUI as soon as we reach the PAUSED state */ refresh_ui (data); } } }
/* Notify UI about pipeline state changes */ static void state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) { GstState old_state, new_state, pending_state; gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state); /* Only pay attention to messages coming from the pipeline, not its children */ if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->pipeline)) { data->state = new_state; gchar *message = g_strdup_printf("State changed to %s", gst_element_state_get_name(new_state)); set_ui_message(message, data); g_free (message); /* The Ready to Paused state change is particularly interesting: */ if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) { /* By now the sink already knows the media size */ check_media_size(data); /* If there was a scheduled seek, perform it now that we have moved to the Paused state */ if (GST_CLOCK_TIME_IS_VALID (data->desired_position)) execute_seek (data->desired_position, data); } } }
gboolean gst_element_sync_state_with_parent_target_state (GstElement * element) { GstElement *parent; GstState target; GstStateChangeReturn ret; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); parent = GST_ELEMENT_CAST (gst_element_get_parent (element)); if (parent == NULL) { GST_DEBUG_OBJECT (element, "element has no parent"); return FALSE; } GST_OBJECT_LOCK (parent); target = GST_STATE_TARGET (parent); GST_OBJECT_UNLOCK (parent); GST_DEBUG_OBJECT (element, "setting parent (%s) target state %s", GST_ELEMENT_NAME (parent), gst_element_state_get_name (target)); gst_object_unref (parent); ret = gst_element_set_state (element, target); if (ret == GST_STATE_CHANGE_FAILURE) { GST_DEBUG_OBJECT (element, "setting target state failed (%s)", gst_element_state_change_return_get_name (ret)); return FALSE; } return TRUE; }
static gboolean play_bus_msg (GstBus * bus, GstMessage * msg, gpointer user_data) { GstPlay *play = user_data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ASYNC_DONE: /* dump graph on preroll */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (play->playbin), GST_DEBUG_GRAPH_SHOW_ALL, "gst-play.async-done"); g_print ("Prerolled.\r"); if (play->missing != NULL && play_install_missing_plugins (play)) { g_print ("New plugins installed, trying again...\n"); --play->cur_idx; play_next (play); } break; case GST_MESSAGE_BUFFERING:{ gint percent; if (!play->buffering) g_print ("\n"); gst_message_parse_buffering (msg, &percent); g_print ("%s %d%% \r", _("Buffering..."), percent); if (percent == 100) { /* a 100% message means buffering is done */ if (play->buffering) { play->buffering = FALSE; /* no state management needed for live pipelines */ if (!play->is_live) gst_element_set_state (play->playbin, play->desired_state); } } else { /* buffering... */ if (!play->buffering) { if (!play->is_live) gst_element_set_state (play->playbin, GST_STATE_PAUSED); play->buffering = TRUE; } } break; } case GST_MESSAGE_CLOCK_LOST:{ g_print (_("Clock lost, selecting a new one\n")); gst_element_set_state (play->playbin, GST_STATE_PAUSED); gst_element_set_state (play->playbin, GST_STATE_PLAYING); break; } case GST_MESSAGE_LATENCY: g_print ("Redistribute latency...\n"); gst_bin_recalculate_latency (GST_BIN (play->playbin)); break; case GST_MESSAGE_REQUEST_STATE:{ GstState state; gchar *name; name = gst_object_get_path_string (GST_MESSAGE_SRC (msg)); gst_message_parse_request_state (msg, &state); g_print ("Setting state to %s as requested by %s...\n", gst_element_state_get_name (state), name); gst_element_set_state (play->playbin, state); g_free (name); break; } case GST_MESSAGE_EOS: /* print final position at end */ play_timeout (play); g_print ("\n"); /* and switch to next item in list */ if (!play_next (play)) { g_print ("Reached end of play list.\n"); g_main_loop_quit (play->loop); } break; case GST_MESSAGE_WARNING:{ GError *err; gchar *dbg = NULL; /* dump graph on warning */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (play->playbin), GST_DEBUG_GRAPH_SHOW_ALL, "gst-play.warning"); gst_message_parse_warning (msg, &err, &dbg); g_printerr ("WARNING %s\n", err->message); if (dbg != NULL) g_printerr ("WARNING debug information: %s\n", dbg); g_error_free (err); g_free (dbg); break; } case GST_MESSAGE_ERROR:{ GError *err; gchar *dbg; /* dump graph on error */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (play->playbin), GST_DEBUG_GRAPH_SHOW_ALL, "gst-play.error"); gst_message_parse_error (msg, &err, &dbg); g_printerr ("ERROR %s for %s\n", err->message, play->uris[play->cur_idx]); if (dbg != NULL) g_printerr ("ERROR debug information: %s\n", dbg); g_error_free (err); g_free (dbg); /* flush any other error messages from the bus and clean up */ gst_element_set_state (play->playbin, GST_STATE_NULL); if (play->missing != NULL && play_install_missing_plugins (play)) { g_print ("New plugins installed, trying again...\n"); --play->cur_idx; play_next (play); break; } /* try next item in list then */ if (!play_next (play)) { g_print ("Reached end of play list.\n"); g_main_loop_quit (play->loop); } break; } default: if (gst_is_missing_plugin_message (msg)) { gchar *desc; desc = gst_missing_plugin_message_get_description (msg); g_print ("Missing plugin: %s\n", desc); g_free (desc); play->missing = g_list_append (play->missing, gst_message_ref (msg)); } break; } return TRUE; }
/* returns TRUE if there was an error or we caught a keyboard interrupt. */ static gboolean event_loop (GstElement * pipeline, gboolean blocking, GstState target_state) { GstBus *bus; GstMessage *message = NULL; gboolean res = FALSE; gboolean buffering = FALSE; bus = gst_element_get_bus (GST_ELEMENT (pipeline)); #ifndef DISABLE_FAULT_HANDLER g_timeout_add (50, (GSourceFunc) check_intr, pipeline); #endif while (TRUE) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, blocking ? -1 : 0); /* if the poll timed out, only when !blocking */ if (message == NULL) goto exit; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_NEW_CLOCK: { GstClock *clock; gst_message_parse_new_clock (message, &clock); g_print ("New clock: %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL")); break; } case GST_MESSAGE_EOS: g_print ("Got EOS from element \"%s\".\n", GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)))); goto exit; case GST_MESSAGE_TAG: if (tags) { GstTagList *tags; gst_message_parse_tag (message, &tags); g_print ("FOUND TAG : found by element \"%s\".\n", GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)))); gst_tag_list_foreach (tags, print_tag, NULL); gst_tag_list_free (tags); } break; case GST_MESSAGE_INFO:{ GError *gerror; gchar *debug; gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message)); gst_message_parse_info (message, &gerror, &debug); if (debug) { g_print ("INFO:\n%s\n", debug); } g_error_free (gerror); g_free (debug); g_free (name); break; } case GST_MESSAGE_WARNING:{ GError *gerror; gchar *debug; gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message)); /* dump graph on warning */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.warning"); gst_message_parse_warning (message, &gerror, &debug); g_print ("WARNING: from element %s: %s\n", name, gerror->message); if (debug) { g_print ("Additional debug info:\n%s\n", debug); } g_error_free (gerror); g_free (debug); g_free (name); break; } case GST_MESSAGE_ERROR:{ GError *gerror; gchar *debug; /* dump graph on error */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.error"); gst_message_parse_error (message, &gerror, &debug); gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); g_error_free (gerror); g_free (debug); /* we have an error */ res = TRUE; goto exit; } case GST_MESSAGE_STATE_CHANGED:{ GstState old, newX, pending; gst_message_parse_state_changed (message, &old, &newX, &pending); /* we only care about pipeline state change messages */ if (GST_MESSAGE_SRC (message) != GST_OBJECT_CAST (pipeline)) break; /* dump graph for pipeline state changes */ { gchar *dump_name = g_strdup_printf ("gst-launch.%s_%s", gst_element_state_get_name (old), gst_element_state_get_name (newX)); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, dump_name); g_free (dump_name); } /* ignore when we are buffering since then we mess with the states * ourselves. */ if (buffering) { fprintf (stderr, "Prerolled, waiting for buffering to finish...\n"); break; } /* if we reached the final target state, exit */ if (target_state == GST_STATE_PAUSED && newX == target_state) goto exit; /* else not an interesting message */ break; } case GST_MESSAGE_BUFFERING:{ gint percent; gst_message_parse_buffering (message, &percent); fprintf (stderr, "%s %d%% \r", "buffering...", percent); /* no state management needed for live pipelines */ if (is_live) break; if (percent == 100) { /* a 100% message means buffering is done */ buffering = FALSE; /* if the desired state is playing, go back */ if (target_state == GST_STATE_PLAYING) { fprintf (stderr, "Done buffering, setting pipeline to PLAYING ...\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); } else goto exit; } else { /* buffering busy */ if (buffering == FALSE && target_state == GST_STATE_PLAYING) { /* we were not buffering but PLAYING, PAUSE the pipeline. */ fprintf (stderr, "Buffering, setting pipeline to PAUSED ...\n"); gst_element_set_state (pipeline, GST_STATE_PAUSED); } buffering = TRUE; } break; } case GST_MESSAGE_LATENCY: { fprintf (stderr, "Redistribute latency...\n"); gst_bin_recalculate_latency (GST_BIN (pipeline)); break; } case GST_MESSAGE_APPLICATION:{ const GstStructure *s; s = gst_message_get_structure (message); if (gst_structure_has_name (s, "GstLaunchInterrupt")) { /* this application message is posted when we caught an interrupt and * we need to stop the pipeline. */ fprintf (stderr, "Interrupt: Stopping pipeline ...\n"); /* return TRUE when we caught an interrupt */ res = TRUE; goto exit; } } default: /* just be quiet by default */ break; } if (message) gst_message_unref (message); } g_assert_not_reached (); exit: { if (message) gst_message_unref (message); gst_object_unref (bus); return res; } }
static gboolean bus_message(GstBus *bus, GstMessage *message, void *pv) { switch (GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_ERROR: { GError *err = NULL; gchar *dbg_info = NULL; gst_message_parse_error(message, &err, &dbg_info); AVB_LOGF_ERROR("GStreamer ERROR message from element %s: %s", GST_OBJECT_NAME(message->src), err->message); AVB_LOGF_ERROR("Additional info: %s\n", (dbg_info) ? dbg_info : "none"); g_error_free(err); g_free(dbg_info); break; } case GST_MESSAGE_WARNING: { GError *err = NULL; gchar *dbg_info = NULL; gst_message_parse_warning(message, &err, &dbg_info); AVB_LOGF_WARNING("GStreamer WARNING message from element %s: %s", GST_OBJECT_NAME(message->src), err->message); AVB_LOGF_WARNING("Additional info: %s\n", (dbg_info) ? dbg_info : "none"); g_error_free(err); g_free(dbg_info); break; } case GST_MESSAGE_INFO: { GError *err = NULL; gchar *dbg_info = NULL; gst_message_parse_info(message, &err, &dbg_info); AVB_LOGF_ERROR("GStreamer INFO message from element %s: %s", GST_OBJECT_NAME(message->src), err->message); AVB_LOGF_ERROR("Additional info: %s\n", (dbg_info) ? dbg_info : "none"); g_error_free(err); g_free(dbg_info); break; } case GST_MESSAGE_STATE_CHANGED: { GstState old_state, new_state; gst_message_parse_state_changed(message, &old_state, &new_state, NULL); AVB_LOGF_DEBUG("Element %s changed state from %s to %s", GST_OBJECT_NAME(message->src), gst_element_state_get_name(old_state), gst_element_state_get_name(new_state)); break; } case GST_MESSAGE_STREAM_STATUS: { // not so valuable break; } case GST_MESSAGE_EOS: AVB_LOG_INFO("EOS received"); break; default: AVB_LOGF_INFO("GStreamer '%s' message from element %s", gst_message_type_get_name(GST_MESSAGE_TYPE(message)), GST_OBJECT_NAME(message->src)); break; } return TRUE; }
static void gve_bus_message_cb (GstBus * bus, GstMessage * message, gpointer data) { GstVideoEditor *gve = (GstVideoEditor *) data; GstMessageType msg_type; g_return_if_fail (gve != NULL); g_return_if_fail (GST_IS_VIDEO_EDITOR (gve)); msg_type = GST_MESSAGE_TYPE (message); switch (msg_type) { case GST_MESSAGE_ERROR: gve_error_msg (gve, message); if (gve->priv->main_pipeline) gst_element_set_state (gve->priv->main_pipeline, GST_STATE_NULL); break; case GST_MESSAGE_WARNING: GST_WARNING ("Warning message: %" GST_PTR_FORMAT, message); break; case GST_MESSAGE_STATE_CHANGED: { GstState old_state, new_state; gchar *src_name; gst_message_parse_state_changed (message, &old_state, &new_state, NULL); if (old_state == new_state) break; /* we only care about playbin (pipeline) state changes */ if (GST_MESSAGE_SRC (message) != GST_OBJECT (gve->priv->main_pipeline)) break; src_name = gst_object_get_name (message->src); GST_INFO ("%s changed state from %s to %s", src_name, gst_element_state_get_name (old_state), gst_element_state_get_name (new_state)); g_free (src_name); if (new_state == GST_STATE_PLAYING) gve_set_tick_timeout (gve, TIMEOUT); if (old_state == GST_STATE_PAUSED && new_state == GST_STATE_READY) { if (gve->priv->update_id > 0) { g_source_remove (gve->priv->update_id); gve->priv->update_id = 0; } } if (old_state == GST_STATE_NULL && new_state == GST_STATE_READY) GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (gve->priv->main_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "longomatch-editor-null-to-ready"); if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (gve->priv->main_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "longomatch-editor-ready-to-paused"); break; } case GST_MESSAGE_EOS: if (gve->priv->update_id > 0) { g_source_remove (gve->priv->update_id); gve->priv->update_id = 0; } gst_element_set_state (gve->priv->main_pipeline, GST_STATE_NULL); g_signal_emit (gve, gve_signals[SIGNAL_PERCENT_COMPLETED], 0, (gfloat) 1); /* Close file sink properly */ g_object_set (G_OBJECT (gve->priv->file_sink), "location", "", NULL); break; default: GST_LOG ("Unhandled message: %" GST_PTR_FORMAT, message); break; } }
gboolean CGstDecoder::BusCallback(GstBus *bus, GstMessage *msg, gpointer data) { CGstDecoder *decoder = (CGstDecoder *)data; gchar *str; switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: g_print ("GStreamer: End of stream\n"); g_main_loop_quit(decoder->m_loop); break; case GST_MESSAGE_ERROR: GError *error; gst_message_parse_error (msg, &error, &str); g_free (str); g_printerr ("GStreamer: Error - %s %s\n", str, error->message); g_error_free (error); g_main_loop_quit(decoder->m_loop); break; case GST_MESSAGE_WARNING: GError *warning; gst_message_parse_error (msg, &warning, &str); g_free (str); g_printerr ("GStreamer: Warning - %s %s\n", str, warning->message); g_error_free (warning); break; case GST_MESSAGE_INFO: GError *info; gst_message_parse_error (msg, &info, &str); g_free (str); g_printerr ("GStreamer: Info - %s %s\n", str, info->message); g_error_free (info); break; case GST_MESSAGE_TAG: printf("GStreamer: Message TAG\n"); break; case GST_MESSAGE_BUFFERING: printf("GStreamer: Message BUFFERING\n"); break; case GST_MESSAGE_STATE_CHANGED: printf("GStreamer: Message STATE_CHANGED\n"); GstState old_state, new_state; gst_message_parse_state_changed (msg, &old_state, &new_state, NULL); printf("GStreamer: Element %s changed state from %s to %s.\n", GST_OBJECT_NAME (msg->src), gst_element_state_get_name (old_state), gst_element_state_get_name (new_state)); break; case GST_MESSAGE_STATE_DIRTY: printf("GStreamer: Message STATE_DIRTY\n"); break; case GST_MESSAGE_STEP_DONE: printf("GStreamer: Message STEP_DONE\n"); break; case GST_MESSAGE_CLOCK_PROVIDE: printf("GStreamer: Message CLOCK_PROVIDE\n"); break; case GST_MESSAGE_CLOCK_LOST: printf("GStreamer: Message CLOCK_LOST\n"); break; case GST_MESSAGE_NEW_CLOCK: printf("GStreamer: Message NEW_CLOCK\n"); break; case GST_MESSAGE_STRUCTURE_CHANGE: printf("GStreamer: Message STRUCTURE_CHANGE\n"); break; case GST_MESSAGE_STREAM_STATUS: printf("GStreamer: Message STREAM_STATUS\n"); break; case GST_MESSAGE_APPLICATION: printf("GStreamer: Message APPLICATION\n"); break; case GST_MESSAGE_ELEMENT: printf("GStreamer: Message ELEMENT\n"); break; case GST_MESSAGE_SEGMENT_START: printf("GStreamer: Message SEGMENT_START\n"); break; case GST_MESSAGE_SEGMENT_DONE: printf("GStreamer: Message SEGMENT_DONE\n"); break; case GST_MESSAGE_DURATION: printf("GStreamer: Message DURATION\n"); break; case GST_MESSAGE_LATENCY: printf("GStreamer: Message LATENCY\n"); break; case GST_MESSAGE_ASYNC_START: printf("GStreamer: Message ASYNC_START\n"); break; case GST_MESSAGE_ASYNC_DONE: printf("GStreamer: Message ASYNC_DONE\n"); break; case GST_MESSAGE_REQUEST_STATE: printf("GStreamer: Message REQUEST_STATE\n"); break; case GST_MESSAGE_STEP_START: printf("GStreamer: Message STEP_START\n"); break; #if 0 /* Breaks build for now */ case GST_MESSAGE_QOS: printf("GStreamer: Message QOS\n"); break; #endif default: printf("GStreamer: Unknown message %i\n", GST_MESSAGE_TYPE(msg)); break; } return TRUE; }
static GstStateChangeReturn change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstOmxBaseSink *self; self = GST_OMX_BASE_SINK (element); GST_LOG_OBJECT (self, "begin"); GST_INFO_OBJECT (self, "changing state %s - %s", gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)), gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition))); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!self->initialized) { if (!omx_init (self)) return GST_PAD_LINK_REFUSED; self->initialized = TRUE; } g_omx_core_prepare (self->gomx); break; case GST_STATE_CHANGE_READY_TO_PAUSED: g_omx_core_start (self->gomx); break; case GST_STATE_CHANGE_PAUSED_TO_READY: g_omx_port_finish (self->in_port); break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (ret == GST_STATE_CHANGE_FAILURE) goto leave; switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: g_omx_port_pause (self->in_port); break; case GST_STATE_CHANGE_PAUSED_TO_READY: g_omx_core_stop (self->gomx); break; case GST_STATE_CHANGE_READY_TO_NULL: g_omx_core_unload (self->gomx); break; default: break; } leave: GST_LOG_OBJECT (self, "end"); return ret; }
void MediaImpl::_checkMessages() { if (_bus != NULL) { // Get message. GstMessage *msg = gst_bus_timed_pop_filtered( _bus, 0, (GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_ASYNC_DONE)); if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { // Error //////////////////////////////////////////////// case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &debug_info); g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error(&err); g_free(debug_info); if (!_isSharedMemorySource) { _terminate = true; } else { _attached = false; gst_element_set_state (_pipeline, GST_STATE_PAUSED); gst_element_set_state (_pipeline, GST_STATE_NULL); gst_element_set_state (_pipeline, GST_STATE_READY); } // _finish(); break; // End-of-stream //////////////////////////////////////// case GST_MESSAGE_EOS: // Automatically loop back. g_print("End-Of-Stream reached.\n"); resetMovie(); // _terminate = true; // _finish(); break; // Pipeline has prerolled/ready to play /////////////// case GST_MESSAGE_ASYNC_DONE: if (!_isMovieReady()) { // Check if seeking is allowed. gint64 start, end; GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (_pipeline, query)) { gst_query_parse_seeking (query, NULL, (gboolean*)&_seekEnabled, &start, &end); if (_seekEnabled) { g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (start), GST_TIME_ARGS (end)); } else { g_print ("Seeking is DISABLED for this stream.\n"); } } else { g_printerr ("Seeking query failed."); } gst_query_unref (query); // Movie is ready! _setMovieReady(true); } break; case GST_MESSAGE_STATE_CHANGED: // We are only interested in state-changed messages from the pipeline. if (GST_MESSAGE_SRC (msg) == GST_OBJECT (_pipeline)) { GstState oldState, newState, pendingState; gst_message_parse_state_changed(msg, &oldState, &newState, &pendingState); g_print("Pipeline state for movie %s changed from %s to %s:\n", _uri.toUtf8().constData(), gst_element_state_get_name(oldState), gst_element_state_get_name(newState)); } break; default: // We should not reach here. g_printerr("Unexpected message received.\n"); break; } gst_message_unref(msg); } } }
/* * Get Caps * * As can be seen this method violates the API between the GST element * and the Android device. Should be fixed... (FIXME) * */ static GstCaps * gst_android_video_source_get_caps(GstBaseSrc * p_basesrc, GstCaps * p_filter) { int i; int minFps; int maxFps; int fmtPos; int minWidth, minHeight; int maxWidth, maxHeight; GstCaps *caps; GstCaps *capsVec = NULL; GA_LOGTRACE("ENTER %s --xx--> thread(%ld)", __FUNCTION__, pthread_self()); GstAndroidVideoSource *p_src = GST_ANDROIDVIDEOSOURCE(p_basesrc); if (GST_STATE(p_src) == GST_STATE_NULL || GST_STATE(p_src) <= GST_STATE_NULL) { GA_LOGINFO("%s: Called in state %s. Don't know device support yet. Will return NULL caps.", __FUNCTION__, gst_element_state_get_name(GST_STATE(p_src))); return NULL; } if (VCD_GetWidestFpsRange(p_src->m_devHandle, &minFps, &maxFps) != VCD_NO_ERROR) { return NULL; } if (VCD_NO_ERROR != VCD_GetMinResolution(p_src->m_devHandle, &minWidth, &minHeight)) { return NULL; } if (VCD_NO_ERROR != VCD_GetMaxResolution(p_src->m_devHandle, &maxWidth, &maxHeight)) { return NULL; } capsVec = gst_caps_new_empty(); for (fmtPos = 0; fmtPos < VCD_getMediaSupportFmtLen(p_src->m_devHandle); fmtPos++) { int fmt = VCD_getMediaSupportFmt(p_src->m_devHandle)[fmtPos]; GstVideoFormat gstVideoFmt = vcd_int_to_gst_video_format(fmt); if (gstVideoFmt != GST_VIDEO_FORMAT_UNKNOWN) { caps = gst_caps_new_simple( "video/x-raw", "format", G_TYPE_STRING, gst_video_format_to_string(gstVideoFmt), "width", GST_TYPE_INT_RANGE, minWidth, maxWidth, "height", GST_TYPE_INT_RANGE, minHeight, maxHeight, #ifdef ACCEPT_FPS_CAPS_DOWN_TO_1FPS "framerate", GST_TYPE_FRACTION_RANGE, 1000, ANDROID_FPS_DENOMINATOR, maxFps, ANDROID_FPS_DENOMINATOR, #else "framerate", GST_TYPE_FRACTION_RANGE, minFps, ANDROID_FPS_DENOMINATOR, maxFps, ANDROID_FPS_DENOMINATOR, #endif "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); gst_caps_append(capsVec, caps); } } // Some Android devices report one or more supported formats (or other stuff) // more than once, which gives caps duplicates. Those are removed by doing // gst_caps_do_simplify()... capsVec = gst_caps_simplify(capsVec); GA_LOGINFO("%s: By Android video device supported CAPS:", __FUNCTION__); GA_LOGINFO("%s:-----------------------------------------------------------", __FUNCTION__); for (i = 0; i < gst_caps_get_size(capsVec); i++) { // Android log cannot print that long messages so we need to take one caps at a time GstCaps *capsCopy = gst_caps_copy_nth(capsVec, i); GA_LOGINFO("CAPS%d: %s", i+1, gst_caps_to_string(capsCopy)); gst_caps_unref(capsCopy); } GA_LOGINFO("%s:-----------------------------------------------------------", __FUNCTION__); GA_LOGTRACE("EXIT %s", __FUNCTION__); return capsVec; }
static gboolean play_bus_msg (GstBus * bus, GstMessage * msg, gpointer user_data) { GstPlay *play = user_data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ASYNC_DONE: /* dump graph on preroll */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (play->playbin), GST_DEBUG_GRAPH_SHOW_ALL, "gst-play.async-done"); g_print ("Prerolled.\r"); if (play->missing != NULL && play_install_missing_plugins (play)) { g_print ("New plugins installed, trying again...\n"); --play->cur_idx; play_next (play); } break; case GST_MESSAGE_BUFFERING:{ gint percent; if (!play->buffering) g_print ("\n"); gst_message_parse_buffering (msg, &percent); g_print ("%s %d%% \r", _("Buffering..."), percent); if (percent == 100) { /* a 100% message means buffering is done */ if (play->buffering) { play->buffering = FALSE; /* no state management needed for live pipelines */ if (!play->is_live) gst_element_set_state (play->playbin, play->desired_state); } } else { /* buffering... */ if (!play->buffering) { if (!play->is_live) gst_element_set_state (play->playbin, GST_STATE_PAUSED); play->buffering = TRUE; } } break; } case GST_MESSAGE_CLOCK_LOST:{ g_print (_("Clock lost, selecting a new one\n")); gst_element_set_state (play->playbin, GST_STATE_PAUSED); gst_element_set_state (play->playbin, GST_STATE_PLAYING); break; } case GST_MESSAGE_LATENCY: g_print ("Redistribute latency...\n"); gst_bin_recalculate_latency (GST_BIN (play->playbin)); break; case GST_MESSAGE_REQUEST_STATE:{ GstState state; gchar *name; name = gst_object_get_path_string (GST_MESSAGE_SRC (msg)); gst_message_parse_request_state (msg, &state); g_print ("Setting state to %s as requested by %s...\n", gst_element_state_get_name (state), name); gst_element_set_state (play->playbin, state); g_free (name); break; } case GST_MESSAGE_EOS: /* print final position at end */ play_timeout (play); g_print ("\n"); /* and switch to next item in list */ if (!play_next (play)) { g_print ("%s\n", _("Reached end of play list.")); g_main_loop_quit (play->loop); } break; case GST_MESSAGE_WARNING:{ GError *err; gchar *dbg = NULL; /* dump graph on warning */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (play->playbin), GST_DEBUG_GRAPH_SHOW_ALL, "gst-play.warning"); gst_message_parse_warning (msg, &err, &dbg); g_printerr ("WARNING %s\n", err->message); if (dbg != NULL) g_printerr ("WARNING debug information: %s\n", dbg); g_clear_error (&err); g_free (dbg); break; } case GST_MESSAGE_ERROR:{ GError *err; gchar *dbg; /* dump graph on error */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (play->playbin), GST_DEBUG_GRAPH_SHOW_ALL, "gst-play.error"); gst_message_parse_error (msg, &err, &dbg); g_printerr ("ERROR %s for %s\n", err->message, play->uris[play->cur_idx]); if (dbg != NULL) g_printerr ("ERROR debug information: %s\n", dbg); g_clear_error (&err); g_free (dbg); /* flush any other error messages from the bus and clean up */ gst_element_set_state (play->playbin, GST_STATE_NULL); if (play->missing != NULL && play_install_missing_plugins (play)) { g_print ("New plugins installed, trying again...\n"); --play->cur_idx; play_next (play); break; } /* try next item in list then */ if (!play_next (play)) { g_print ("%s\n", _("Reached end of play list.")); g_main_loop_quit (play->loop); } break; } case GST_MESSAGE_ELEMENT: { GstNavigationMessageType mtype = gst_navigation_message_get_type (msg); if (mtype == GST_NAVIGATION_MESSAGE_EVENT) { GstEvent *ev = NULL; if (gst_navigation_message_parse_event (msg, &ev)) { GstNavigationEventType e_type = gst_navigation_event_get_type (ev); switch (e_type) { case GST_NAVIGATION_EVENT_KEY_PRESS: { const gchar *key; if (gst_navigation_event_parse_key_event (ev, &key)) { GST_INFO ("Key press: %s", key); if (strcmp (key, "Left") == 0) key = GST_PLAY_KB_ARROW_LEFT; else if (strcmp (key, "Right") == 0) key = GST_PLAY_KB_ARROW_RIGHT; else if (strcmp (key, "Up") == 0) key = GST_PLAY_KB_ARROW_UP; else if (strcmp (key, "Down") == 0) key = GST_PLAY_KB_ARROW_DOWN; else if (strcmp (key, "space") == 0) key = " "; else if (strlen (key) > 1) break; keyboard_cb (key, user_data); } break; } case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS: { gint button; if (gst_navigation_event_parse_mouse_button_event (ev, &button, NULL, NULL)) { if (button == 4) { /* wheel up */ relative_seek (play, +0.08); } else if (button == 5) { /* wheel down */ relative_seek (play, -0.01); } } break; } default: break; } } if (ev) gst_event_unref (ev); } break; } default: if (gst_is_missing_plugin_message (msg)) { gchar *desc; desc = gst_missing_plugin_message_get_description (msg); g_print ("Missing plugin: %s\n", desc); g_free (desc); play->missing = g_list_append (play->missing, gst_message_ref (msg)); } break; } return TRUE; }
static void event_loop (GstElement * bin, GstClockTime start) { GstBus *bus; GstMessage *msg = NULL; gboolean running = TRUE; bus = gst_element_get_bus (bin); while (running) { msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_WARNING, -1); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_STATE_CHANGED: if (GST_MESSAGE_SRC (msg) == (GstObject *) bin) { GstState old_state, new_state; GstClockTime end; gst_message_parse_state_changed (msg, &old_state, &new_state, NULL); end = gst_util_get_timestamp (); g_print ("%" GST_TIME_FORMAT " state change on the bin: %s -> %s\n", GST_TIME_ARGS (end - start), gst_element_state_get_name (old_state), gst_element_state_get_name (new_state)); if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) { running = FALSE; } } break; case GST_MESSAGE_WARNING:{ GError *err = NULL; gchar *dbg = NULL; gst_message_parse_warning (msg, &err, &dbg); GST_WARNING_OBJECT (GST_MESSAGE_SRC (msg), "%s (%s)", err->message, (dbg ? dbg : "no details")); g_error_free (err); g_free (dbg); break; } case GST_MESSAGE_ERROR:{ GError *err = NULL; gchar *dbg = NULL; gst_message_parse_error (msg, &err, &dbg); GST_ERROR_OBJECT (GST_MESSAGE_SRC (msg), "%s (%s)", err->message, (dbg ? dbg : "no details")); g_error_free (err); g_free (dbg); running = FALSE; break; } default: break; } gst_message_unref (msg); } gst_object_unref (bus); }
static gboolean message_loop_to_state_change (MetadataExtractor *extractor, GstState state) { GstBus *bus; GstMessageType events; g_return_val_if_fail (extractor, FALSE); g_return_val_if_fail (extractor->playbin, FALSE); bus = gst_element_get_bus (extractor->playbin); events = (GST_MESSAGE_TAG | GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS); for (;;) { GstMessage *message; message = gst_bus_timed_pop_filtered (bus, GST_SECOND * 5, events); if (message == NULL) goto timed_out; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_STATE_CHANGED: { GstState old_state; GstState new_state; old_state = new_state = GST_STATE_NULL; gst_message_parse_state_changed (message, &old_state, &new_state, NULL); if (old_state == new_state) break; /* we only care about playbin (pipeline) state changes */ if (GST_MESSAGE_SRC (message) != GST_OBJECT (extractor->playbin)) break; if ((old_state == GST_STATE_READY) && (new_state == GST_STATE_PAUSED)) update_stream_info (extractor); else if ((old_state == GST_STATE_PAUSED) && (new_state == GST_STATE_READY)) reset_extractor_data (extractor); if (new_state == state) { gst_message_unref (message); goto success; } break; } case GST_MESSAGE_TAG: { GstTagList *tag_list; GstTagList *result; tag_list = NULL; gst_message_parse_tag (message, &tag_list); result = gst_tag_list_merge (extractor->tagcache, tag_list, GST_TAG_MERGE_KEEP); if (extractor->tagcache != NULL) gst_tag_list_free (extractor->tagcache); extractor->tagcache = result; gst_tag_list_free (tag_list); break; } case GST_MESSAGE_ERROR: { gchar *debug = NULL; GError *gsterror = NULL; gst_message_parse_error (message, &gsterror, &debug); /*g_warning ("Error: %s (%s)", gsterror->message, debug);*/ g_error_free (gsterror); gst_message_unref (message); g_free (debug); goto error; } break; case GST_MESSAGE_EOS: { g_warning ("Media file could not be played."); gst_message_unref (message); goto error; } break; default: g_assert_not_reached (); break; } gst_message_unref (message); } g_assert_not_reached (); success: /* state change succeeded */ GST_DEBUG ("state change to %s succeeded", gst_element_state_get_name (state)); return TRUE; timed_out: /* it's taking a long time to open */ GST_DEBUG ("state change to %s timed out, returning success", gst_element_state_get_name (state)); return TRUE; error: GST_DEBUG ("error while waiting for state change to %s", gst_element_state_get_name (state)); /* already set *error */ return FALSE; }
static gboolean gst_switchui_handle_message (GstBus * bus, GstMessage * message, gpointer data) { GstSwitchUI *switchui = (GstSwitchUI *) data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: gst_switchui_handle_eos (switchui); break; case GST_MESSAGE_ERROR: { GError *error = NULL; gchar *debug; gst_message_parse_error (message, &error, &debug); gst_switchui_handle_error (switchui, error, debug); } break; case GST_MESSAGE_WARNING: { GError *error = NULL; gchar *debug; gst_message_parse_warning (message, &error, &debug); gst_switchui_handle_warning (switchui, error, debug); } break; case GST_MESSAGE_INFO: { GError *error = NULL; gchar *debug; gst_message_parse_info (message, &error, &debug); gst_switchui_handle_info (switchui, error, debug); } break; case GST_MESSAGE_TAG: { GstTagList *tag_list; gst_message_parse_tag (message, &tag_list); if (verbose) g_print ("tag\n"); } break; case GST_MESSAGE_STATE_CHANGED: { GstState oldstate, newstate, pending; gst_message_parse_state_changed (message, &oldstate, &newstate, &pending); if (GST_ELEMENT (message->src) == switchui->pipeline) { if (verbose) g_print ("state change from %s to %s\n", gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate)); switch (GST_STATE_TRANSITION (oldstate, newstate)) { case GST_STATE_CHANGE_NULL_TO_READY: gst_switchui_handle_null_to_ready (switchui); break; case GST_STATE_CHANGE_READY_TO_PAUSED: gst_switchui_handle_ready_to_paused (switchui); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: gst_switchui_handle_paused_to_playing (switchui); break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: gst_switchui_handle_playing_to_paused (switchui); break; case GST_STATE_CHANGE_PAUSED_TO_READY: gst_switchui_handle_paused_to_ready (switchui); break; case GST_STATE_CHANGE_READY_TO_NULL: gst_switchui_handle_ready_to_null (switchui); break; default: if (verbose) g_print ("unknown state change from %s to %s\n", gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate)); } } } break; case GST_MESSAGE_BUFFERING: { int percent; gst_message_parse_buffering (message, &percent); //g_print("buffering %d\n", percent); if (!switchui->paused_for_buffering && percent < 100) { g_print ("pausing for buffing\n"); switchui->paused_for_buffering = TRUE; gst_element_set_state (switchui->pipeline, GST_STATE_PAUSED); } else if (switchui->paused_for_buffering && percent == 100) { g_print ("unpausing for buffing\n"); switchui->paused_for_buffering = FALSE; gst_element_set_state (switchui->pipeline, GST_STATE_PLAYING); } } break; case GST_MESSAGE_STATE_DIRTY: case GST_MESSAGE_CLOCK_PROVIDE: case GST_MESSAGE_CLOCK_LOST: case GST_MESSAGE_NEW_CLOCK: case GST_MESSAGE_STRUCTURE_CHANGE: case GST_MESSAGE_STREAM_STATUS: break; case GST_MESSAGE_STEP_DONE: case GST_MESSAGE_APPLICATION: case GST_MESSAGE_ELEMENT: case GST_MESSAGE_SEGMENT_START: case GST_MESSAGE_SEGMENT_DONE: //case GST_MESSAGE_DURATION: case GST_MESSAGE_LATENCY: case GST_MESSAGE_ASYNC_START: case GST_MESSAGE_ASYNC_DONE: case GST_MESSAGE_REQUEST_STATE: case GST_MESSAGE_STEP_START: case GST_MESSAGE_QOS: default: if (verbose) { g_print ("message: %s\n", GST_MESSAGE_TYPE_NAME (message)); } break; } return TRUE; }
void MediaPlayerPrivate::updateStates() { // There is no (known) way to get such level of information about // the state of GStreamer, therefore, when in PAUSED state, // we are sure we can display the first frame and go to play MediaPlayer::NetworkState oldNetworkState = m_networkState; MediaPlayer::ReadyState oldReadyState = m_readyState; GstState state; GstState pending; if (!m_playBin) return; GstStateChangeReturn ret = gst_element_get_state (m_playBin, &state, &pending, 250 * GST_NSECOND); switch(ret) { case GST_STATE_CHANGE_SUCCESS: LOG_VERBOSE(Media, "State: %s, pending: %s", gst_element_state_get_name(state), gst_element_state_get_name(pending)); if (state == GST_STATE_READY) { m_readyState = MediaPlayer::HaveEnoughData; } else if (state == GST_STATE_PAUSED) { m_readyState = MediaPlayer::HaveEnoughData; } m_networkState = MediaPlayer::Loaded; g_object_get(m_playBin, "source", &m_source, NULL); if (!m_source) LOG_VERBOSE(Media, "m_source is NULL"); break; case GST_STATE_CHANGE_ASYNC: LOG_VERBOSE(Media, "Async: State: %s, pending: %s", gst_element_state_get_name(state), gst_element_state_get_name(pending)); // Change in progress return; break; case GST_STATE_CHANGE_NO_PREROLL: LOG_VERBOSE(Media, "No preroll: State: %s, pending: %s", gst_element_state_get_name(state), gst_element_state_get_name(pending)); if (state == GST_STATE_READY) { m_readyState = MediaPlayer::HaveFutureData; } else if (state == GST_STATE_PAUSED) { m_readyState = MediaPlayer::HaveCurrentData; } m_networkState = MediaPlayer::Loading; break; default: LOG_VERBOSE(Media, "Else : %d", ret); break; } if (seeking()) m_readyState = MediaPlayer::HaveNothing; if (m_networkState != oldNetworkState) { LOG_VERBOSE(Media, "Network State Changed from %u to %u", oldNetworkState, m_networkState); m_player->networkStateChanged(); } if (m_readyState != oldReadyState) { LOG_VERBOSE(Media, "Ready State Changed from %u to %u", oldReadyState, m_readyState); m_player->readyStateChanged(); } }