/*!
 * \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;
}
示例#6
0
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);
}
示例#7
0
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;
}
示例#8
0
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;
  }
}
示例#11
0
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);
}
示例#12
0
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;
}
示例#13
0
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);
}
示例#14
0
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;
}
示例#15
0
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);
		}