/*! * \brief handleMessage * Handles gstreamer bus messages. Mainly for debugging purposes and ensuring clean shutdown on error */ void handleMessage(GstElement * pipeline) { GError *err = NULL; gchar *debug = NULL; GstBus* bus = NULL; GstStreamStatusType tp; GstElement * elem = NULL; GstMessage* msg = NULL; bus = gst_element_get_bus(pipeline); while(gst_bus_have_pending(bus)) { msg = gst_bus_pop(bus); //printf("Got %s message\n", GST_MESSAGE_TYPE_NAME(msg)); if(gst_is_missing_plugin_message(msg)) { //ERROR(1, "GStreamer: your gstreamer installation is missing a required plugin\n"); fprintf(stderr, "GStreamer: your gstreamer installation is missing a required plugin\n"); } else { switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_STATE_CHANGED: GstState oldstate, newstate, pendstate; gst_message_parse_state_changed(msg, &oldstate, &newstate, &pendstate); //fprintf(stderr, "state changed from %s to %s (pending: %s)\n", gst_element_state_get_name(oldstate), // gst_element_state_get_name(newstate), gst_element_state_get_name(pendstate)); break; case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &debug); //fprintf(stderr, "GStreamer Plugin: Embedded video playback halted; module %s reported: %s\n", // gst_element_get_name(GST_MESSAGE_SRC (msg)), err->message); g_error_free(err); g_free(debug); gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL); break; case GST_MESSAGE_EOS: //fprintf(stderr, "reached the end of the stream."); break; case GST_MESSAGE_STREAM_STATUS: gst_message_parse_stream_status(msg,&tp,&elem); //fprintf(stderr, "stream status: elem %s, %i\n", GST_ELEMENT_NAME(elem), tp); break; default: //fprintf(stderr, "unhandled message\n"); break; } } gst_message_unref(msg); } gst_object_unref(GST_OBJECT(bus)); }
void GStreamerBaseFrameSourceImpl::handleGStreamerMessages() { GstMessage* msg = NULL; GError *err = NULL; gchar *debug = NULL; GstStreamStatusType tp; GstElement * elem = NULL; if (!bus) return; while (gst_bus_have_pending(bus)) { msg = gst_bus_pop(bus); if (gst_is_missing_plugin_message(msg)) { printf("GStreamer: your gstreamer installation is missing a required plugin!\n"); end = true; } else { switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_STATE_CHANGED: GstState oldstate, newstate, pendstate; gst_message_parse_state_changed(msg, &oldstate, &newstate, &pendstate); break; case GST_MESSAGE_ERROR: { gst_message_parse_error(msg, &err, &debug); std::unique_ptr<char[], GlibDeleter> name(gst_element_get_name(GST_MESSAGE_SRC (msg))); printf("GStreamer Plugin: Embedded video playback halted; module %s reported: %s\n", name.get(), err->message); g_error_free(err); g_free(debug); end = true; break; } case GST_MESSAGE_EOS: end = true; break; case GST_MESSAGE_STREAM_STATUS: gst_message_parse_stream_status(msg,&tp,&elem); break; default: break; } } gst_message_unref(msg); } }
gboolean rb_gst_check_missing_plugins (GstEncodingProfile *profile, char ***details, char ***descriptions) { GstElement *encodebin; GstBus *bus; GstPad *pad; gboolean ret; ret = FALSE; encodebin = gst_element_factory_make ("encodebin", NULL); if (encodebin == NULL) { g_warning ("Unable to create encodebin"); return TRUE; } bus = gst_bus_new (); gst_element_set_bus (encodebin, bus); gst_bus_set_flushing (bus, FALSE); /* necessary? */ g_object_set (encodebin, "profile", profile, NULL); pad = gst_element_get_static_pad (encodebin, "audio_0"); if (pad == NULL) { GstMessage *message; GList *messages = NULL; GList *m; int i; message = gst_bus_pop (bus); while (message != NULL) { if (gst_is_missing_plugin_message (message)) { messages = g_list_append (messages, message); } else { gst_message_unref (message); } message = gst_bus_pop (bus); } if (messages != NULL) { if (details != NULL) { *details = g_new0(char *, g_list_length (messages)+1); } if (descriptions != NULL) { *descriptions = g_new0(char *, g_list_length (messages)+1); }
void _bp_missing_elements_process_message (BansheePlayer *player, GstMessage *message) { g_return_if_fail (IS_BANSHEE_PLAYER (player)); g_return_if_fail (message != NULL); if (gst_is_missing_plugin_message (message)) { gchar *detail = gst_missing_plugin_message_get_installer_detail (message); GSList *node = player->missing_element_details_handled; player->handle_missing_elements = TRUE; // Only save the error if we've never encounted it before for (; node != NULL; node = node->next) { if (g_ascii_strcasecmp (node->data, detail) == 0) { bp_debug2 ("Ignoring missing element details, already prompted ('%s')", detail); return; } } bp_debug2 ("Saving missing element details ('%s')", detail); player->missing_element_details = g_slist_append (player->missing_element_details, detail); } }
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 VALUE instance2robj(gpointer instance) { VALUE klass; GstMessage *message; message = instance; switch (GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_UNKNOWN: klass = rb_cGstMessageUnknown; break; case GST_MESSAGE_EOS: klass = rb_cGstMessageEos; break; case GST_MESSAGE_ERROR: klass = rb_cGstMessageError; break; case GST_MESSAGE_WARNING: klass = rb_cGstMessageWarning; break; case GST_MESSAGE_INFO: klass = rb_cGstMessageInfo; break; case GST_MESSAGE_TAG: klass = rb_cGstMessageTag; break; case GST_MESSAGE_BUFFERING: klass = rb_cGstMessageBuffering; break; case GST_MESSAGE_STATE_CHANGED: klass = rb_cGstMessageStateChanged; break; case GST_MESSAGE_STATE_DIRTY: klass = rb_cGstMessageStateDirty; break; case GST_MESSAGE_STEP_DONE: klass = rb_cGstMessageStepDone; break; case GST_MESSAGE_CLOCK_PROVIDE: klass = rb_cGstMessageClockProvide; break; case GST_MESSAGE_CLOCK_LOST: klass = rb_cGstMessageClockLost; break; case GST_MESSAGE_NEW_CLOCK: klass = rb_cGstMessageNewClock; break; case GST_MESSAGE_STRUCTURE_CHANGE: klass = rb_cGstMessageStructureChange; break; case GST_MESSAGE_STREAM_STATUS: klass = rb_cGstMessageStreamStatus; break; case GST_MESSAGE_APPLICATION: klass = rb_cGstMessageApplication; break; case GST_MESSAGE_ELEMENT: if (gst_is_missing_plugin_message(message)) { klass = rb_cGstMissingMessage; } else { klass = rb_cGstMessageElement; } break; case GST_MESSAGE_SEGMENT_START: klass = rb_cGstMessageSegmentStart; break; case GST_MESSAGE_SEGMENT_DONE: klass = rb_cGstMessageSegmentDone; break; case GST_MESSAGE_DURATION: klass = rb_cGstMessageDuration; break; case GST_MESSAGE_LATENCY: klass = rb_cGstMessageLatency; break; case GST_MESSAGE_ASYNC_START: klass = rb_cGstMessageAsyncStart; break; case GST_MESSAGE_ASYNC_DONE: klass = rb_cGstMessageAsyncDone; break; case GST_MESSAGE_ANY: klass = rb_cGstMessageAny; break; default: klass = rb_cGstMessage; break; } gst_mini_object_ref(instance); return Data_Wrap_Struct(klass, NULL, _rbgst_mini_object_free, instance); }
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; }
G_MODULE_EXPORT gboolean live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data) { signal_user_data_t *ud = (signal_user_data_t*)data; switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_UNKNOWN: { //printf("unknown"); } break; case GST_MESSAGE_EOS: { // Done //printf("eos\n"); live_preview_stop(ud); gst_element_seek(ud->preview->play, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); } break; case GST_MESSAGE_ERROR: { //printf("error\n"); GError *err; gchar *debug; gst_message_parse_error(msg, &err, &debug); g_warning("Gstreamer Error: %s", err->message); g_error_free(err); g_free(debug); } break; case GST_MESSAGE_WARNING: case GST_MESSAGE_INFO: case GST_MESSAGE_TAG: case GST_MESSAGE_BUFFERING: case GST_MESSAGE_STATE_CHANGED: { //printf("state change %x\n", state); GstState state, pending; gst_element_get_state(ud->preview->play, &state, &pending, 0); if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING) { update_stream_info(ud); } } break; case GST_MESSAGE_STATE_DIRTY: { //printf("state dirty\n"); } break; case GST_MESSAGE_STEP_DONE: { //printf("step done\n"); } break; case GST_MESSAGE_CLOCK_PROVIDE: { //printf("clock provide\n"); } break; case GST_MESSAGE_CLOCK_LOST: { //printf("clock lost\n"); } break; case GST_MESSAGE_NEW_CLOCK: { //printf("new clock\n"); } break; case GST_MESSAGE_STRUCTURE_CHANGE: { //printf("structure change\n"); } break; case GST_MESSAGE_STREAM_STATUS: { //printf("stream status\n"); } break; case GST_MESSAGE_APPLICATION: { //printf("application\n"); } break; case GST_MESSAGE_ELEMENT: { //printf("element\n"); if (gst_is_missing_plugin_message(msg)) { GtkWindow *hb_window; hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window")); gst_element_set_state(ud->preview->play, GST_STATE_PAUSED); gchar *message, *desc; desc = gst_missing_plugin_message_get_description(msg); message = g_strdup_printf( _("Missing GStreamer plugin\n" "Audio or Video may not play as expected\n\n%s"), desc); ghb_message_dialog(hb_window, GTK_MESSAGE_WARNING, message, "Ok", NULL); g_free(message); gst_element_set_state(ud->preview->play, GST_STATE_PLAYING); } else if (msg->src == GST_OBJECT_CAST(ud->preview->vsink)) { const GstStructure *gstStruct; const GValue *val; gstStruct = gst_message_get_structure(msg); if (gstStruct != NULL && (gst_structure_has_name(gstStruct, "preroll-pixbuf") || gst_structure_has_name(gstStruct, "pixbuf"))) { val = gst_structure_get_value(gstStruct, "pixbuf"); if (val != NULL) { GdkPixbuf * pix; GtkWidget *widget; int width, height; if (ud->preview->pix != NULL) g_object_unref(ud->preview->pix); if (ud->preview->scaled_pix != NULL) g_object_unref(ud->preview->scaled_pix); pix = GDK_PIXBUF(g_value_dup_object(val)); width = gdk_pixbuf_get_width(pix); height = gdk_pixbuf_get_height(pix); if (width != ud->preview->width || height != ud->preview->height || width != ud->preview->render_width || height != ud->preview->render_height) { double xscale, yscale; xscale = (double)ud->preview->render_width / ud->preview->width; yscale = (double)ud->preview->render_height / ud->preview->height; if (xscale <= yscale) { width = ud->preview->render_width; height = ud->preview->height * xscale; } else { width = ud->preview->width * yscale; height = ud->preview->render_height; } ud->preview->scaled_pix = gdk_pixbuf_scale_simple(pix, width, height, GDK_INTERP_BILINEAR); g_object_ref(pix); } else { ud->preview->scaled_pix = pix; } ud->preview->pix = ud->preview->scaled_pix; g_object_ref(ud->preview->pix); widget = GHB_WIDGET (ud->builder, "preview_image"); gtk_widget_queue_draw(widget); } } } } break; case GST_MESSAGE_SEGMENT_START: { //printf("segment start\n"); } break; case GST_MESSAGE_SEGMENT_DONE: { //printf("segment done\n"); } break; case GST_MESSAGE_DURATION_CHANGED: { //printf("duration change\n"); }; case GST_MESSAGE_LATENCY: { //printf("latency\n"); }; case GST_MESSAGE_ASYNC_START: { //printf("async start\n"); } break; case GST_MESSAGE_ASYNC_DONE: { //printf("async done\n"); } break; case GST_MESSAGE_REQUEST_STATE: { //printf("request state\n"); } break; case GST_MESSAGE_STEP_START: { //printf("step start\n"); } break; case GST_MESSAGE_QOS: { //printf("qos\n"); } break; case GST_MESSAGE_PROGRESS: { //printf("progress\n"); } break; case GST_MESSAGE_TOC: { //printf("toc\n"); } break; case GST_MESSAGE_RESET_TIME: { //printf("reset time\n"); } break; case GST_MESSAGE_STREAM_START: { //printf("stream start\n"); }; case GST_MESSAGE_ANY: { //printf("any\n"); } break; default: { // Ignore //printf("?msg? %x\n", GST_MESSAGE_TYPE(msg)); } } return TRUE; }
/** * gst_missing_plugin_message_get_description: * @msg: a missing-plugin #GstMessage of type #GST_MESSAGE_ELEMENT * * Returns a localised string describing the missing feature, for use in * error dialogs and the like. Should never return NULL unless @msg is not * a valid missing-plugin message. * * This function is mainly for applications that need a human-readable string * describing a missing plugin, given a previously collected missing-plugin * message * * Returns: a newly-allocated description string, or NULL on error. Free * string with g_free() when not needed any longer. */ gchar * gst_missing_plugin_message_get_description (GstMessage * msg) { GstMissingType missing_type; const gchar *desc; gchar *ret = NULL; g_return_val_if_fail (gst_is_missing_plugin_message (msg), NULL); GST_LOG ("Parsing missing-plugin message: %" GST_PTR_FORMAT, msg->structure); desc = gst_structure_get_string (msg->structure, "name"); if (desc != NULL && *desc != '\0') { ret = g_strdup (desc); goto done; } /* fallback #1 */ missing_type = missing_structure_get_type (msg->structure); switch (missing_type) { case GST_MISSING_TYPE_URISOURCE: case GST_MISSING_TYPE_URISINK: case GST_MISSING_TYPE_ELEMENT:{ gchar *detail = NULL; if (missing_structure_get_string_detail (msg->structure, &detail)) { if (missing_type == GST_MISSING_TYPE_URISOURCE) ret = gst_pb_utils_get_source_description (detail); else if (missing_type == GST_MISSING_TYPE_URISINK) ret = gst_pb_utils_get_sink_description (detail); else ret = gst_pb_utils_get_sink_description (detail); g_free (detail); } break; } case GST_MISSING_TYPE_DECODER: case GST_MISSING_TYPE_ENCODER:{ GstCaps *caps = NULL; if (missing_structure_get_caps_detail (msg->structure, &caps)) { if (missing_type == GST_MISSING_TYPE_DECODER) ret = gst_pb_utils_get_decoder_description (caps); else ret = gst_pb_utils_get_encoder_description (caps); gst_caps_unref (caps); } break; } default: break; } if (ret) goto done; /* fallback #2 */ switch (missing_type) { case GST_MISSING_TYPE_URISOURCE: desc = _("Unknown source element"); break; case GST_MISSING_TYPE_URISINK: desc = _("Unknown sink element"); break; case GST_MISSING_TYPE_ELEMENT: desc = _("Unknown element"); break; case GST_MISSING_TYPE_DECODER: desc = _("Unknown decoder element"); break; case GST_MISSING_TYPE_ENCODER: desc = _("Unknown encoder element"); break; default: /* we should really never get here, but we better still return * something if we do */ desc = _("Plugin or element of unknown type"); break; } ret = g_strdup (desc); done: GST_LOG ("returning '%s'", ret); return ret; }
/** * gst_missing_plugin_message_get_installer_detail: * @msg: a missing-plugin #GstMessage of type #GST_MESSAGE_ELEMENT * * Returns an opaque string containing all the details about the missing * element to be passed to an external installer called via * gst_install_plugins_async() or gst_install_plugins_sync(). * * This function is mainly for applications that call external plugin * installation mechanisms using one of the two above-mentioned functions. * * Returns: a newly-allocated detail string, or NULL on error. Free string * with g_free() when not needed any longer. */ gchar * gst_missing_plugin_message_get_installer_detail (GstMessage * msg) { GstMissingType missing_type; const gchar *progname; const gchar *type; GString *str = NULL; gchar *detail = NULL; gchar *desc; g_return_val_if_fail (gst_is_missing_plugin_message (msg), NULL); GST_LOG ("Parsing missing-plugin message: %" GST_PTR_FORMAT, msg->structure); missing_type = missing_structure_get_type (msg->structure); if (missing_type == GST_MISSING_TYPE_UNKNOWN) { GST_WARNING ("couldn't parse 'type' field"); goto error; } type = gst_structure_get_string (msg->structure, "type"); g_assert (type != NULL); /* validity already checked above */ /* FIXME: use gst_installer_detail_new() here too */ str = g_string_new (GST_DETAIL_STRING_MARKER "|"); g_string_append_printf (str, "%u.%u|", GST_VERSION_MAJOR, GST_VERSION_MINOR); progname = (const gchar *) g_get_prgname (); if (progname) { g_string_append_printf (str, "%s|", progname); } else { g_string_append_printf (str, "pid/%lu|", (gulong) getpid ()); } desc = gst_missing_plugin_message_get_description (msg); if (desc) { g_strdelimit (desc, "|", '#'); g_string_append_printf (str, "%s|", desc); g_free (desc); } else { g_string_append (str, "|"); } switch (missing_type) { case GST_MISSING_TYPE_URISOURCE: case GST_MISSING_TYPE_URISINK: case GST_MISSING_TYPE_ELEMENT: if (!missing_structure_get_string_detail (msg->structure, &detail)) goto error; break; case GST_MISSING_TYPE_DECODER: case GST_MISSING_TYPE_ENCODER:{ GstCaps *caps = NULL; if (!missing_structure_get_caps_detail (msg->structure, &caps)) goto error; detail = gst_caps_to_string (caps); gst_caps_unref (caps); break; } default: g_return_val_if_reached (NULL); } g_string_append_printf (str, "%s-%s", type, detail); g_free (detail); return g_string_free (str, FALSE); /* ERRORS */ error: { GST_WARNING ("Failed to parse missing-plugin msg: %" GST_PTR_FORMAT, msg); if (str) g_string_free (str, TRUE); return NULL; } }
void eServiceMP3Record::gstBusCall(GstMessage *msg) { if (!msg) return; ePtr<iRecordableService> ptr = this; gchar *sourceName; GstObject *source; source = GST_MESSAGE_SRC(msg); if (!GST_IS_OBJECT(source)) return; sourceName = gst_object_get_name(source); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: eDebug("[eMP3ServiceRecord] gstBusCall eos event"); // Stream end -> stop recording m_event((iRecordableService*)this, evGstRecordEnded); break; case GST_MESSAGE_STATE_CHANGED: { if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_recording_pipeline)) break; GstState old_state, new_state; gst_message_parse_state_changed(msg, &old_state, &new_state, NULL); if(old_state == new_state) break; GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state); eDebug("[eMP3ServiceRecord] gstBusCall state transition %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state)); switch(transition) { case GST_STATE_CHANGE_PAUSED_TO_PLAYING: { if (m_streamingsrc_timeout) m_streamingsrc_timeout->stop(); break; } default: break; } break; } case GST_MESSAGE_ERROR: { gchar *debug; GError *err; gst_message_parse_error(msg, &err, &debug); g_free(debug); if (err->code != GST_STREAM_ERROR_CODEC_NOT_FOUND) eWarning("[eServiceMP3Record] gstBusCall Gstreamer error: %s (%i) from %s", err->message, err->code, sourceName); g_error_free(err); break; } case GST_MESSAGE_ELEMENT: { const GstStructure *msgstruct = gst_message_get_structure(msg); if (msgstruct) { if (gst_is_missing_plugin_message(msg)) { GstCaps *caps = NULL; gst_structure_get (msgstruct, "detail", GST_TYPE_CAPS, &caps, NULL); if (caps) { std::string codec = (const char*) gst_caps_to_string(caps); eDebug("[eServiceMP3Record] gstBusCall cannot record because of incompatible codecs %s", codec.c_str()); gst_caps_unref(caps); } } else { const gchar *eventname = gst_structure_get_name(msgstruct); if (eventname) { if (!strcmp(eventname, "redirect")) { const char *uri = gst_structure_get_string(msgstruct, "new-location"); eDebug("[eServiceMP3Record] gstBusCall redirect to %s", uri); gst_element_set_state (m_recording_pipeline, GST_STATE_NULL); g_object_set(G_OBJECT (m_source), "uri", uri, NULL); gst_element_set_state (m_recording_pipeline, GST_STATE_PLAYING); } } } } break; } case GST_MESSAGE_STREAM_STATUS: { GstStreamStatusType type; GstElement *owner; gst_message_parse_stream_status (msg, &type, &owner); if (type == GST_STREAM_STATUS_TYPE_CREATE) { if (GST_IS_PAD(source)) owner = gst_pad_get_parent_element(GST_PAD(source)); else if (GST_IS_ELEMENT(source)) owner = GST_ELEMENT(source); else owner = 0; if (owner) { GstState state; gst_element_get_state(m_recording_pipeline, &state, NULL, 0LL); GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner)); const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory)); if (!strcmp(name, "souphttpsrc") && (state == GST_STATE_READY) && !m_streamingsrc_timeout->isActive()) { m_streamingsrc_timeout->start(HTTP_TIMEOUT*1000, true); g_object_set (G_OBJECT (owner), "timeout", HTTP_TIMEOUT, NULL); eDebug("[eServiceMP3Record] gstBusCall setting timeout on %s to %is", name, HTTP_TIMEOUT); } } if (GST_IS_PAD(source)) gst_object_unref(owner); } break; } default: break; } g_free(sourceName); }
static gboolean bus_cb (GstBus *bus, GstMessage *message, RBPlayerGst *mp) { const GstStructure *structure; g_return_val_if_fail (mp != NULL, FALSE); switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: { char *debug; GError *error = NULL; GError *sig_error = NULL; int code; gboolean emit = TRUE; gst_message_parse_error (message, &error, &debug); /* If we've already got an error, ignore 'internal data flow error' * type messages, as they're too generic to be helpful. */ if (mp->priv->emitted_error && error->domain == GST_STREAM_ERROR && error->code == GST_STREAM_ERROR_FAILED) { rb_debug ("Ignoring generic error \"%s\"", error->message); emit = FALSE; } code = rb_gst_error_get_error_code (error); if (emit) { if (message_from_sink (mp->priv->audio_sink, message)) { rb_debug ("got error from sink: %s (%s)", error->message, debug); /* Translators: the parameter here is an error message */ g_set_error (&sig_error, RB_PLAYER_ERROR, code, _("Failed to open output device: %s"), error->message); } else { rb_debug ("got error from stream: %s (%s)", error->message, debug); g_set_error (&sig_error, RB_PLAYER_ERROR, code, "%s", error->message); } state_change_finished (mp, sig_error); mp->priv->emitted_error = TRUE; _rb_player_emit_error (RB_PLAYER (mp), mp->priv->stream_data, sig_error); } /* close if not already closing */ if (mp->priv->uri != NULL) rb_player_close (RB_PLAYER (mp), NULL, NULL); g_error_free (error); g_free (debug); break; } case GST_MESSAGE_EOS: _rb_player_emit_eos (RB_PLAYER (mp), mp->priv->stream_data, FALSE); break; case GST_MESSAGE_STATE_CHANGED: { GstState oldstate; GstState newstate; GstState pending; gst_message_parse_state_changed (message, &oldstate, &newstate, &pending); if (GST_MESSAGE_SRC (message) == GST_OBJECT (mp->priv->playbin)) { rb_debug ("playbin reached state %s", gst_element_state_get_name (newstate)); if (pending == GST_STATE_VOID_PENDING) { state_change_finished (mp, NULL); } } break; } case GST_MESSAGE_TAG: { GstTagList *tags; gst_message_parse_tag (message, &tags); if (mp->priv->stream_change_pending || mp->priv->playbin_stream_changing) { mp->priv->stream_tags = g_list_append (mp->priv->stream_tags, tags); } else { gst_tag_list_foreach (tags, (GstTagForeachFunc) process_tag, mp); gst_tag_list_free (tags); } break; } case GST_MESSAGE_BUFFERING: { gint progress; structure = gst_message_get_structure (message); if (!gst_structure_get_int (structure, "buffer-percent", &progress)) { g_warning ("Could not get value from BUFFERING message"); break; } if (progress >= 100) { mp->priv->buffering = FALSE; if (mp->priv->playing) { rb_debug ("buffering done, setting pipeline back to PLAYING"); gst_element_set_state (mp->priv->playbin, GST_STATE_PLAYING); } else { rb_debug ("buffering done, leaving pipeline PAUSED"); } } else if (mp->priv->buffering == FALSE && mp->priv->playing) { GstState cur_state; gst_element_get_state (mp->priv->playbin, &cur_state, NULL, 0); if (cur_state == GST_STATE_PLAYING) { rb_debug ("buffering - temporarily pausing playback"); gst_element_set_state (mp->priv->playbin, GST_STATE_PAUSED); } else { rb_debug ("buffering - during preroll; doing nothing"); } mp->priv->buffering = TRUE; } _rb_player_emit_buffering (RB_PLAYER (mp), mp->priv->stream_data, progress); break; } case GST_MESSAGE_APPLICATION: structure = gst_message_get_structure (message); _rb_player_emit_event (RB_PLAYER (mp), mp->priv->stream_data, gst_structure_get_name (structure), NULL); break; case GST_MESSAGE_ELEMENT: structure = gst_message_get_structure (message); if (gst_is_missing_plugin_message (message)) { handle_missing_plugin_message (mp, message); } else if (mp->priv->playbin_stream_changing && gst_structure_has_name (structure, "playbin2-stream-changed")) { rb_debug ("got playbin2-stream-changed message"); mp->priv->playbin_stream_changing = FALSE; emit_playing_stream_and_tags (mp, TRUE); } else if (gst_structure_has_name (structure, "redirect")) { const char *uri = gst_structure_get_string (structure, "new-location"); _rb_player_emit_redirect (RB_PLAYER (mp), mp->priv->stream_data, uri); } break; default: break; } /* emit message signals too, so plugins can process messages */ gst_bus_async_signal_func (bus, message, NULL); return TRUE; }
void eServiceMP3::gstBusCall(GstMessage *msg) { if (!msg) return; gchar *sourceName; GstObject *source; source = GST_MESSAGE_SRC(msg); if (!GST_IS_OBJECT(source)) return; sourceName = gst_object_get_name(source); #if 0 gchar *string; if (gst_message_get_structure(msg)) string = gst_structure_to_string(gst_message_get_structure(msg)); else string = g_strdup(GST_MESSAGE_TYPE_NAME(msg)); eDebug("eTsRemoteSource::gst_message from %s: %s", sourceName, string); g_free(string); #endif switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: m_event((iPlayableService*)this, evEOF); break; case GST_MESSAGE_STATE_CHANGED: { if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin)) break; GstState old_state, new_state; gst_message_parse_state_changed(msg, &old_state, &new_state, NULL); if(old_state == new_state) break; eDebug("eServiceMP3::state transition %s -> %s", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state)); GstStateChange transition = (GstStateChange)GST_STATE_TRANSITION(old_state, new_state); switch(transition) { case GST_STATE_CHANGE_NULL_TO_READY: { } break; case GST_STATE_CHANGE_READY_TO_PAUSED: { GstElement *subsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin), "subtitle_sink"); if (subsink) { #ifdef GSTREAMER_SUBTITLE_SYNC_MODE_BUG /* * HACK: disable sync mode for now, gstreamer suffers from a bug causing sparse streams to loose sync, after pause/resume / skip * see: https://bugzilla.gnome.org/show_bug.cgi?id=619434 * Sideeffect of using sync=false is that we receive subtitle buffers (far) ahead of their * display time. * Not too far ahead for subtitles contained in the media container. * But for external srt files, we could receive all subtitles at once. * And not just once, but after each pause/resume / skip. * So as soon as gstreamer has been fixed to keep sync in sparse streams, sync needs to be re-enabled. */ g_object_set (G_OBJECT (subsink), "sync", FALSE, NULL); #endif #if 0 /* we should not use ts-offset to sync with the decoder time, we have to do our own decoder timekeeping */ g_object_set (G_OBJECT (subsink), "ts-offset", -2L * GST_SECOND, NULL); /* late buffers probably will not occur very often */ g_object_set (G_OBJECT (subsink), "max-lateness", 0L, NULL); /* avoid prerolling (it might not be a good idea to preroll a sparse stream) */ g_object_set (G_OBJECT (subsink), "async", TRUE, NULL); #endif eDebug("eServiceMP3::subsink properties set!"); gst_object_unref(subsink); } setAC3Delay(ac3_delay); setPCMDelay(pcm_delay); } break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: { if ( m_sourceinfo.is_streaming && m_streamingsrc_timeout ) m_streamingsrc_timeout->stop(); } break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: { } break; case GST_STATE_CHANGE_PAUSED_TO_READY: { } break; case GST_STATE_CHANGE_READY_TO_NULL: { } break; } break; } case GST_MESSAGE_ERROR: { gchar *debug; GError *err; gst_message_parse_error (msg, &err, &debug); g_free (debug); eWarning("Gstreamer error: %s (%i) from %s", err->message, err->code, sourceName ); if ( err->domain == GST_STREAM_ERROR ) { if ( err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND ) { if ( g_strrstr(sourceName, "videosink") ) m_event((iPlayableService*)this, evUser+11); else if ( g_strrstr(sourceName, "audiosink") ) m_event((iPlayableService*)this, evUser+10); } } g_error_free(err); break; } case GST_MESSAGE_INFO: { gchar *debug; GError *inf; gst_message_parse_info (msg, &inf, &debug); g_free (debug); if ( inf->domain == GST_STREAM_ERROR && inf->code == GST_STREAM_ERROR_DECODE ) { if ( g_strrstr(sourceName, "videosink") ) m_event((iPlayableService*)this, evUser+14); } g_error_free(inf); break; } case GST_MESSAGE_TAG: { GstTagList *tags, *result; gst_message_parse_tag(msg, &tags); result = gst_tag_list_merge(m_stream_tags, tags, GST_TAG_MERGE_REPLACE); if (result) { if (m_stream_tags) gst_tag_list_free(m_stream_tags); m_stream_tags = result; } const GValue *gv_image = gst_tag_list_get_value_index(tags, GST_TAG_IMAGE, 0); if ( gv_image ) { GstBuffer *buf_image; buf_image = gst_value_get_buffer (gv_image); int fd = open("/tmp/.id3coverart", O_CREAT|O_WRONLY|O_TRUNC, 0644); int ret = write(fd, GST_BUFFER_DATA(buf_image), GST_BUFFER_SIZE(buf_image)); close(fd); eDebug("eServiceMP3::/tmp/.id3coverart %d bytes written ", ret); m_event((iPlayableService*)this, evUser+13); } gst_tag_list_free(tags); m_event((iPlayableService*)this, evUpdatedInfo); break; } case GST_MESSAGE_ASYNC_DONE: { if(GST_MESSAGE_SRC(msg) != GST_OBJECT(m_gst_playbin)) break; GstTagList *tags; gint i, active_idx, n_video = 0, n_audio = 0, n_text = 0; g_object_get (m_gst_playbin, "n-video", &n_video, NULL); g_object_get (m_gst_playbin, "n-audio", &n_audio, NULL); g_object_get (m_gst_playbin, "n-text", &n_text, NULL); eDebug("eServiceMP3::async-done - %d video, %d audio, %d subtitle", n_video, n_audio, n_text); if ( n_video + n_audio <= 0 ) stop(); active_idx = 0; m_audioStreams.clear(); m_subtitleStreams.clear(); for (i = 0; i < n_audio; i++) { audioStream audio; gchar *g_codec, *g_lang; GstPad* pad = 0; g_signal_emit_by_name (m_gst_playbin, "get-audio-pad", i, &pad); GstCaps* caps = gst_pad_get_negotiated_caps(pad); if (!caps) continue; GstStructure* str = gst_caps_get_structure(caps, 0); const gchar *g_type = gst_structure_get_name(str); eDebug("AUDIO STRUCT=%s", g_type); audio.type = gstCheckAudioPad(str); g_codec = g_strdup(g_type); g_lang = g_strdup_printf ("und"); g_signal_emit_by_name (m_gst_playbin, "get-audio-tags", i, &tags); if ( tags && gst_is_tag_list(tags) ) { gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_codec); gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang); gst_tag_list_free(tags); } audio.language_code = std::string(g_lang); audio.codec = std::string(g_codec); eDebug("eServiceMP3::audio stream=%i codec=%s language=%s", i, g_codec, g_lang); m_audioStreams.push_back(audio); g_free (g_lang); g_free (g_codec); gst_caps_unref(caps); } for (i = 0; i < n_text; i++) { gchar *g_codec = NULL, *g_lang = NULL; g_signal_emit_by_name (m_gst_playbin, "get-text-tags", i, &tags); subtitleStream subs; g_lang = g_strdup_printf ("und"); if ( tags && gst_is_tag_list(tags) ) { gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang); gst_tag_list_get_string(tags, GST_TAG_SUBTITLE_CODEC, &g_codec); gst_tag_list_free(tags); } subs.language_code = std::string(g_lang); eDebug("eServiceMP3::subtitle stream=%i language=%s codec=%s", i, g_lang, g_codec); GstPad* pad = 0; g_signal_emit_by_name (m_gst_playbin, "get-text-pad", i, &pad); if ( pad ) g_signal_connect (G_OBJECT (pad), "notify::caps", G_CALLBACK (gstTextpadHasCAPS), this); subs.type = getSubtitleType(pad, g_codec); m_subtitleStreams.push_back(subs); g_free (g_lang); } m_event((iPlayableService*)this, evUpdatedInfo); if ( m_errorInfo.missing_codec != "" ) { if ( m_errorInfo.missing_codec.find("video/") == 0 || ( m_errorInfo.missing_codec.find("audio/") == 0 && getNumberOfTracks() == 0 ) ) m_event((iPlayableService*)this, evUser+12); } break; } case GST_MESSAGE_ELEMENT: { if (const GstStructure *msgstruct = gst_message_get_structure(msg)) { if ( gst_is_missing_plugin_message(msg) ) { GstCaps *caps; gst_structure_get (msgstruct, "detail", GST_TYPE_CAPS, &caps, NULL); std::string codec = (const char*) gst_caps_to_string(caps); gchar *description = gst_missing_plugin_message_get_description(msg); if ( description ) { eDebug("eServiceMP3::m_errorInfo.missing_codec = %s", codec.c_str()); m_errorInfo.error_message = "GStreamer plugin " + (std::string)description + " not available!\n"; m_errorInfo.missing_codec = codec.substr(0,(codec.find_first_of(','))); g_free(description); } gst_caps_unref(caps); } else { const gchar *eventname = gst_structure_get_name(msgstruct); if ( eventname ) { if (!strcmp(eventname, "eventSizeChanged") || !strcmp(eventname, "eventSizeAvail")) { gst_structure_get_int (msgstruct, "aspect_ratio", &m_aspect); gst_structure_get_int (msgstruct, "width", &m_width); gst_structure_get_int (msgstruct, "height", &m_height); if (strstr(eventname, "Changed")) m_event((iPlayableService*)this, evVideoSizeChanged); } else if (!strcmp(eventname, "eventFrameRateChanged") || !strcmp(eventname, "eventFrameRateAvail")) { gst_structure_get_int (msgstruct, "frame_rate", &m_framerate); if (strstr(eventname, "Changed")) m_event((iPlayableService*)this, evVideoFramerateChanged); } else if (!strcmp(eventname, "eventProgressiveChanged") || !strcmp(eventname, "eventProgressiveAvail")) { gst_structure_get_int (msgstruct, "progressive", &m_progressive); if (strstr(eventname, "Changed")) m_event((iPlayableService*)this, evVideoProgressiveChanged); } } } } break; } case GST_MESSAGE_BUFFERING: { GstBufferingMode mode; gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent)); gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft)); m_event((iPlayableService*)this, evBuffering); break; } case GST_MESSAGE_STREAM_STATUS: { GstStreamStatusType type; GstElement *owner; gst_message_parse_stream_status (msg, &type, &owner); if ( type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming ) { if ( GST_IS_PAD(source) ) owner = gst_pad_get_parent_element(GST_PAD(source)); else if ( GST_IS_ELEMENT(source) ) owner = GST_ELEMENT(source); else owner = 0; if ( owner ) { GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner)); const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory)); if (!strcmp(name, "souphttpsrc")) { m_streamingsrc_timeout->start(HTTP_TIMEOUT*1000, true); g_object_set (G_OBJECT (owner), "timeout", HTTP_TIMEOUT, NULL); eDebug("eServiceMP3::GST_STREAM_STATUS_TYPE_CREATE -> setting timeout on %s to %is", name, HTTP_TIMEOUT); } } if ( GST_IS_PAD(source) ) gst_object_unref(owner); } break; } default: break; } g_free (sourceName); }
G_MODULE_EXPORT gboolean live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data) { signal_user_data_t *ud = (signal_user_data_t*)data; switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_UNKNOWN: { //printf("unknown"); } break; case GST_MESSAGE_EOS: { // Done GtkImage *img; //printf("eos"); img = GTK_IMAGE(GHB_WIDGET(ud->builder, "live_preview_play_image")); gtk_image_set_from_icon_name(img, GHB_PLAY_ICON, GTK_ICON_SIZE_BUTTON); gst_element_set_state(ud->preview->play, GST_STATE_PAUSED); ud->preview->pause = TRUE; gst_element_seek(ud->preview->play, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); } break; case GST_MESSAGE_ERROR: { //printf("error\n"); GError *err; gchar *debug; gst_message_parse_error(msg, &err, &debug); g_warning("Gstreamer Error: %s", err->message); g_error_free(err); g_free(debug); } break; case GST_MESSAGE_WARNING: case GST_MESSAGE_INFO: case GST_MESSAGE_TAG: case GST_MESSAGE_BUFFERING: case GST_MESSAGE_STATE_CHANGED: { GstState state, pending; gst_element_get_state(ud->preview->play, &state, &pending, 0); //printf("state change %x\n", state); if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING) { update_stream_info(ud); } } break; case GST_MESSAGE_STATE_DIRTY: { //printf("state dirty\n"); } break; case GST_MESSAGE_STEP_DONE: { //printf("step done\n"); } break; case GST_MESSAGE_CLOCK_PROVIDE: { //printf("clock provide\n"); } break; case GST_MESSAGE_CLOCK_LOST: { //printf("clock lost\n"); } break; case GST_MESSAGE_NEW_CLOCK: { //printf("new clock\n"); } break; case GST_MESSAGE_STRUCTURE_CHANGE: { //printf("structure change\n"); } break; case GST_MESSAGE_STREAM_STATUS: { //printf("stream status\n"); } break; case GST_MESSAGE_APPLICATION: { //printf("application\n"); } break; case GST_MESSAGE_ELEMENT: { //printf("element\n"); if (gst_is_missing_plugin_message(msg)) { GtkWindow *hb_window; hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window")); gst_element_set_state(ud->preview->play, GST_STATE_PAUSED); gchar *message, *desc; desc = gst_missing_plugin_message_get_description(msg); message = g_strdup_printf( _("Missing GStreamer plugin\n" "Audio or Video may not play as expected\n\n%s"), desc); ghb_message_dialog(hb_window, GTK_MESSAGE_WARNING, message, "Ok", NULL); g_free(message); gst_element_set_state(ud->preview->play, GST_STATE_PLAYING); } } break; case GST_MESSAGE_SEGMENT_START: { //printf("segment start\n"); } break; case GST_MESSAGE_SEGMENT_DONE: { //printf("segment done\n"); } break; #if GST_CHECK_VERSION(1, 0, 0) case GST_MESSAGE_DURATION_CHANGED: { //printf("duration change\n"); }; #endif case GST_MESSAGE_LATENCY: { //printf("latency\n"); }; case GST_MESSAGE_ASYNC_START: { //printf("async start\n"); } break; case GST_MESSAGE_ASYNC_DONE: { //printf("async done\n"); } break; case GST_MESSAGE_REQUEST_STATE: { //printf("request state\n"); } break; case GST_MESSAGE_STEP_START: { //printf("step start\n"); } break; case GST_MESSAGE_QOS: { //printf("qos\n"); } break; #if GST_CHECK_VERSION(1, 0, 0) case GST_MESSAGE_PROGRESS: { //printf("progress\n"); } break; case GST_MESSAGE_TOC: { //printf("toc\n"); } break; case GST_MESSAGE_RESET_TIME: { //printf("reset time\n"); } break; case GST_MESSAGE_STREAM_START: { //printf("stream start\n"); }; #endif case GST_MESSAGE_ANY: { //printf("any\n"); } break; default: { // Ignore //printf("?msg? %x\n", GST_MESSAGE_TYPE(msg)); } } return TRUE; }
gboolean check_missing_plugins(GstEncodingProfile *profile, char ***details, char ***descriptions) { GstElement *encodebin; GstBus *bus; GstPad *pad; gboolean ret; ret = FALSE; encodebin = gst_element_factory_make("encodebin", NULL); if (encodebin == NULL) { g_warning("Unable to create encodebin"); return TRUE; } bus = gst_bus_new(); gst_element_set_bus(encodebin, bus); gst_bus_set_flushing(bus, FALSE); /* necessary? */ g_object_set(encodebin, "profile", profile, NULL); pad = gst_element_get_static_pad(encodebin, "audio_0"); if (pad == NULL) { GstMessage *message; GList *messages = NULL; GList *m; message = gst_bus_pop(bus); while (message != NULL) { if (gst_is_missing_plugin_message(message)) messages = g_list_append(messages, message); else gst_message_unref(message); message = gst_bus_pop(bus); } if (messages != NULL) { int i; if (details != NULL) *details = g_new0(char *, g_list_length(messages)+1); if (descriptions != NULL) *descriptions = g_new0(char *, g_list_length(messages)+1); i = 0; for (m = messages; m != NULL; m = m->next) { char *str; if (details != NULL) { str = gst_missing_plugin_message_get_installer_detail(m->data); (*details)[i] = str; } if (descriptions != NULL) { str = gst_missing_plugin_message_get_description(m->data); (*descriptions)[i] = str; } i++; } ret = TRUE; g_list_foreach(messages,(GFunc)gst_message_unref, NULL); g_list_free(messages); }