Beispiel #1
0
/**
 * gst_bus_set_flushing:
 * @bus: a #GstBus
 * @flushing: whether or not to flush the bus
 *
 * If @flushing, flush out and unref any messages queued in the bus. Releases
 * references to the message origin objects. Will flush future messages until
 * gst_bus_set_flushing() sets @flushing to %FALSE.
 *
 * MT safe.
 */
void
gst_bus_set_flushing (GstBus * bus, gboolean flushing)
{
  GstMessage *message;
  GList *message_list = NULL;

  g_return_if_fail (GST_IS_BUS (bus));

  GST_OBJECT_LOCK (bus);

  if (flushing) {
    GST_OBJECT_FLAG_SET (bus, GST_BUS_FLUSHING);

    GST_DEBUG_OBJECT (bus, "set bus flushing");

    while ((message = gst_bus_pop (bus)))
      message_list = g_list_prepend (message_list, message);
  } else {
    GST_DEBUG_OBJECT (bus, "unset bus flushing");
    GST_OBJECT_FLAG_UNSET (bus, GST_BUS_FLUSHING);
  }

  GST_OBJECT_UNLOCK (bus);

  g_list_free_full (message_list, (GDestroyNotify) gst_message_unref);
}
void GStreamerWrapper::handleGStMessage()
{
	if ( m_GstBus != NULL )
	{
		while ( gst_bus_have_pending( m_GstBus ) )
		{
			m_GstMessage = gst_bus_pop( m_GstBus );

			if ( m_GstMessage != NULL )
			{
				// std::cout << "Message Type: " << GST_MESSAGE_TYPE_NAME( m_GstMessage ) << std::endl;

				switch ( GST_MESSAGE_TYPE( m_GstMessage ) )
				{
				case GST_MESSAGE_ERROR:
					GError* err;
					gchar* debug;
					gst_message_parse_error( m_GstMessage, &err, &debug );

					std::cout << "Embedded video playback halted: module " << gst_element_get_name( GST_MESSAGE_SRC( m_GstMessage ) ) <<
						" reported " << err->message << std::endl;

					close();

					g_error_free(err);
					g_free(debug);
					break;

				case GST_MESSAGE_EOS:
					switch ( m_LoopMode )
					{
						case NO_LOOP:
							stop();
							break;

						case LOOP:
							stop();
							play();
							break;

						case BIDIRECTIONAL_LOOP:
							m_PlayDirection = (PlayDirection)-m_PlayDirection;
							stop();
							play();
							break;

						default:
							break;
					}
					break;

				default:
					break;
				}
			}

			gst_object_unref( m_GstMessage );
		}
	}
}
Beispiel #3
0
void PlayerGst::timerUpdate()
{
	GstMessage* message;
	while(!usePlaybin && (message = gst_bus_pop(bus), message)) {
		switch (GST_MESSAGE_TYPE (message)) {
		case GST_MESSAGE_ERROR: {
			GError *err;
			gchar *debug;
			gst_message_parse_error (message, &err, &debug);
			QString str;
			str = "Error #"+QString::number(err->code)+" in module "+QString::number(err->domain)+"\n"+QString::fromUtf8(err->message);
			if(err->code == 6 && err->domain == 851) {
				str += "\nMay be you should to install gstreamer0.10-plugins-ugly or gstreamer0.10-plugins-bad";
			}
			QMessageBox::warning(0, "Gstreamer error", str);
			g_error_free (err);
			g_free (debug);
			break;
		}
		case GST_MESSAGE_EOS:
			need_finish();
			//QMessageBox::information(0, "", "EOS");
			return;
		default:
			break;
		}
	}
    if(playing()) {
		gint64 p;
		GstFormat fmt = GST_FORMAT_TIME;
		gst_element_query_position(pipeline, &fmt, &p);
		emit position((double)(p - Gstart) / Glength);
    }
}
Beispiel #4
0
static void
pull_messages (void)
{
  GstMessage *m;
  const GstStructure *s;
  guint message_ids[NUM_THREADS];
  gint i;

  for (i = 0; i < NUM_THREADS; i++)
    message_ids[i] = 0;

  while (1) {
    gint _t, _i;

    m = gst_bus_pop (test_bus);
    if (!m)
      break;
    g_return_if_fail (GST_MESSAGE_TYPE (m) == GST_MESSAGE_APPLICATION);

    s = gst_message_get_structure (m);
    if (!gst_structure_get_int (s, "thread_id", &_t))
      g_critical ("Invalid message");
    if (!gst_structure_get_int (s, "msg_id", &_i))
      g_critical ("Invalid message");

    g_return_if_fail (_t < NUM_THREADS);
    g_return_if_fail (_i == message_ids[_t]++);

    gst_message_unref (m);
  }

  for (i = 0; i < NUM_THREADS; i++)
    g_return_if_fail (message_ids[i] == NUM_MESSAGES);
}
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);
			}
/*!
 * \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);
    }
}
Beispiel #8
0
static void internal_bus_watch_handler(struct gst_video_state *st)
{
	GstTagList *tag_list;
	gchar *title;
	GError *err;
	gchar *d;

	GstMessage *msg = gst_bus_pop(st->bus);

	if (!msg) {
		// take a nap (300ms)
		usleep(300 * 1000);
		return;
	}

	switch (GST_MESSAGE_TYPE(msg)) {

	case GST_MESSAGE_EOS:

		/* XXX decrementing repeat count? */

		/* Re-start stream */
		gst_element_set_state(st->pipeline, GST_STATE_NULL);
		gst_element_set_state(st->pipeline, GST_STATE_PLAYING);
		break;

	case GST_MESSAGE_ERROR:
		gst_message_parse_error(msg, &err, &d);

		DEBUG_WARNING("Error: %d(%m) message=%s\n", err->code,
			      err->code, err->message);
		DEBUG_WARNING("Debug: %s\n", d);

		g_free(d);
		g_error_free(err);

		st->run = FALSE;
		break;

	case GST_MESSAGE_TAG:
		gst_message_parse_tag(msg, &tag_list);

		if (gst_tag_list_get_string(tag_list, GST_TAG_TITLE, &title)) {
			DEBUG_NOTICE("Title: %s\n", title);
			g_free(title);
		}
		break;

	default:
		break;
	}

	gst_message_unref(msg);
}
// checkMsgBus
void gstCamera::checkMsgBus()
{
	while(true)
	{
		GstMessage* msg = gst_bus_pop(mBus);

		if( !msg )
			break;

		gst_message_print(mBus, msg, this);
		gst_message_unref(msg);
	}
}
//-------------------------------------------------------------------------------
// Name: __GSTLoopFunction
// Arguments: none
// Description: bus call watch
// FIXME: usage: should not be called anywhere (only for the thread)
//-------------------------------------------------------------------------------
void GSTVideoControl::GSTLoopFunction (void)
{
	while (1)
	{	
		while ((__bus_msg = gst_bus_pop (__bus))) 
		{
			// Call your bus message handler
			(*__GSTLoopFunctionPTR) (__bus, __bus_msg, NULL);
			gst_message_unref (__bus_msg);
		}
	}
	
	return;
}
Beispiel #11
0
gboolean
GstPipe::source_dispatch(GSource *source,
                         GSourceFunc callback,
                         gpointer user_data) {
    GstBusFunc handler = (GstBusFunc) callback;
    GstBusSource *bsrc = (GstBusSource *) source;
    gboolean result = FALSE;

    if (handler) {
        GstMessage *message = gst_bus_pop(bsrc->bus);
        if (message) {
            result = handler(bsrc->bus, message, user_data);
            gst_message_unref(message);
        }
    }
    return result;
}
Beispiel #12
0
void CvCapture_GStreamer::handleMessage()
{
    GstBus* bus = gst_element_get_bus(pipeline);

    while(gst_bus_have_pending(bus)) {
        GstMessage* msg = gst_bus_pop(bus);

//        printf("Got %s message\n", GST_MESSAGE_TYPE_NAME(msg));

        switch (GST_MESSAGE_TYPE (msg)) {
        case GST_MESSAGE_STATE_CHANGED:
            GstState oldstate, newstate, pendstate;
            gst_message_parse_state_changed(msg, &oldstate, &newstate, &pendstate);
//            printf("state changed from %d to %d (%d)\n", oldstate, newstate, pendstate);
            break;
        case GST_MESSAGE_ERROR: {
            GError *err;
            gchar *debug;
            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(pipeline, GST_STATE_NULL);

            break;
        }
        case GST_MESSAGE_EOS:
//            CV_WARN("NetStream has reached the end of the stream.");

            break;
        default:
//            CV_WARN("unhandled message\n");
            break;
        }

        gst_message_unref(msg);
    }

    gst_object_unref(GST_OBJECT(bus));
}
Beispiel #13
0
static gboolean
gst_bus_source_dispatch (GSource * source, GSourceFunc callback,
    gpointer user_data)
{
  GstBusFunc handler = (GstBusFunc) callback;
  GstBusSource *bsource = (GstBusSource *) source;
  GstMessage *message;
  gboolean keep;
  GstBus *bus;

  g_return_val_if_fail (bsource != NULL, FALSE);

  bus = bsource->bus;

  g_return_val_if_fail (GST_IS_BUS (bus), FALSE);

  message = gst_bus_pop (bus);

  /* The message queue might be empty if some other thread or callback set
   * the bus to flushing between check/prepare and dispatch */
  if (G_UNLIKELY (message == NULL))
    return TRUE;

  if (!handler)
    goto no_handler;

  GST_DEBUG_OBJECT (bus, "source %p calling dispatch with %" GST_PTR_FORMAT,
      source, message);

  keep = handler (bus, message, user_data);
  gst_message_unref (message);

  GST_DEBUG_OBJECT (bus, "source %p handler returns %d", source, keep);

  return keep;

no_handler:
  {
    g_warning ("GstBus watch dispatched without callback\n"
        "You must call g_source_set_callback().");
    gst_message_unref (message);
    return FALSE;
  }
}
Beispiel #14
0
static void internal_bus_watch_handler(struct videnc_state *st)
{
	GError *err;
	gchar *d;
	GstMessage *msg = gst_bus_pop(st->bus);

	if (!msg) {
		/* take a nap (300ms) */
		usleep(300 * 1000);
		return;
	}

	switch (GST_MESSAGE_TYPE(msg)) {

	case GST_MESSAGE_EOS:

		/* XXX decrementing repeat count? */

		/* Re-start stream */
		gst_element_set_state(st->pipeline, GST_STATE_NULL);
		gst_element_set_state(st->pipeline, GST_STATE_PLAYING);
		break;

	case GST_MESSAGE_ERROR:
		gst_message_parse_error(msg, &err, &d);

		warning("gst_video: Error: %d(%m) message=%s\n", err->code,
			err->code, err->message);
		warning("gst_video: Debug: %s\n", d);

		g_free(d);
		g_error_free(err);

		st->run = FALSE;
		break;

	default:
		break;
	}

	gst_message_unref(msg);
}
Beispiel #15
0
/**
 * gst_bus_set_flushing:
 * @bus: a #GstBus
 * @flushing: whether or not to flush the bus
 *
 * If @flushing, flush out and unref any messages queued in the bus. Releases
 * references to the message origin objects. Will flush future messages until
 * gst_bus_set_flushing() sets @flushing to #FALSE.
 *
 * MT safe.
 */
void
gst_bus_set_flushing (GstBus * bus, gboolean flushing)
{
  GstMessage *message;

  GST_OBJECT_LOCK (bus);

  if (flushing) {
    GST_OBJECT_FLAG_SET (bus, GST_BUS_FLUSHING);

    GST_DEBUG_OBJECT (bus, "set bus flushing");

    while ((message = gst_bus_pop (bus)))
      gst_message_unref (message);
  } else {
    GST_DEBUG_OBJECT (bus, "unset bus flushing");
    GST_OBJECT_FLAG_UNSET (bus, GST_BUS_FLUSHING);
  }

  GST_OBJECT_UNLOCK (bus);
}
static gboolean
check_bus_messages (GstSplitMuxPartReader * part)
{
  gboolean ret = FALSE;
  GstBus *bus;
  GstMessage *m;

  bus = gst_element_get_bus (GST_ELEMENT_CAST (part));
  while ((m = gst_bus_pop (bus)) != NULL) {
    if (GST_MESSAGE_TYPE (m) == GST_MESSAGE_ERROR) {
      GST_LOG_OBJECT (part, "Got error message while preparing. Failing.");
      gst_message_unref (m);
      goto done;
    }
    gst_message_unref (m);
  }
  ret = TRUE;
done:
  gst_object_unref (bus);
  return ret;
}
Beispiel #17
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);
		}
void ofGstUtils::gstHandleMessage(){
	GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(gstPipeline));
	while(gst_bus_have_pending(bus)) {
		GstMessage* msg = gst_bus_pop(bus);
		if(appsink && appsink->on_message(msg)) continue;

	//	ofLogVerbose() << "GStreamer: Got " << GST_MESSAGE_TYPE_NAME(msg) << " message from " << GST_MESSAGE_SRC_NAME(msg);

		switch (GST_MESSAGE_TYPE (msg)) {

			case GST_MESSAGE_BUFFERING:
				gint pctBuffered;
				gst_message_parse_buffering(msg,&pctBuffered);
				//ofLog(OF_LOG_VERBOSE,"GStreamer: buffering %i\%", pctBuffered);
				/*if(pctBuffered<100){
					gst_element_set_state (gstPipeline, GST_STATE_PAUSED);
				}else if(!bPaused){
					gst_element_set_state (gstPipeline, GST_STATE_PLAYING);
				}*/
			break;

#if GST_VERSION_MAJOR==0
			case GST_MESSAGE_DURATION:{
				GstFormat format=GST_FORMAT_TIME;
				gst_element_query_duration(gstPipeline,&format,&durationNanos);
			}break;
#else
			case GST_MESSAGE_DURATION_CHANGED:
				gst_element_query_duration(gstPipeline,GST_FORMAT_TIME,&durationNanos);
				break;

#endif

			case GST_MESSAGE_STATE_CHANGED:{
				GstState oldstate, newstate, pendstate;
				gst_message_parse_state_changed(msg, &oldstate, &newstate, &pendstate);
				if(isStream && newstate==GST_STATE_PAUSED && !bPlaying ){
					bLoaded = true;
					bPlaying = true;
					if(!bPaused){
//						cout << "setting stream pipeline to play " << endl;
						play();
					}
				}
			//	ofLogVerbose() << "GStreamer: " << GST_MESSAGE_SRC_NAME(msg) << " state changed from " << getName(oldstate) + " to " + getName(newstate) + " (" + getName(pendstate) + ")";
			}break;

			case GST_MESSAGE_ASYNC_DONE:
				gLogManager.log("GStreamer: async done",ELL_INFO);
			break;

			case GST_MESSAGE_ERROR: {
				GError *err;
				gchar *debug;
				gst_message_parse_error(msg, &err, &debug);
				/*
				ofLog(OF_LOG_ERROR, "GStreamer Plugin: Embedded video playback halted; module %s reported: %s",
					  gst_element_get_name(GST_MESSAGE_SRC (msg)), err->message);
					  */
				g_error_free(err);
				g_free(debug);

				gst_element_set_state(GST_ELEMENT(gstPipeline), GST_STATE_NULL);

			}break;

			case GST_MESSAGE_EOS:
			//	ofLog(OF_LOG_VERBOSE,"GStreamer: end of the stream.");
				bIsMovieDone = true;
				
				if(appsink && !isAppSink) appsink->on_eos();

				switch(loopMode){
					/*
					case OF_LOOP_NORMAL:{
						GstFormat format = GST_FORMAT_TIME;
						GstSeekFlags flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH |GST_SEEK_FLAG_KEY_UNIT);
						gint64 pos;
#if GST_VERSION_MAJOR==0
						gst_element_query_position(GST_ELEMENT(gstPipeline),&format,&pos);
#else
						gst_element_query_position(GST_ELEMENT(gstPipeline),format,&pos);
#endif
						if(!gst_element_seek(GST_ELEMENT(gstPipeline),
											speed,
											format,
											flags,
											GST_SEEK_TYPE_SET,
											0,
											GST_SEEK_TYPE_SET,
											durationNanos)) {
							gLogManager.log("GStreamer: unable to seek");
						}
					}break;

					case OF_LOOP_PALINDROME:{
						GstFormat format = GST_FORMAT_TIME;
						GstSeekFlags flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH |GST_SEEK_FLAG_KEY_UNIT);
						gint64 pos;
#if GST_VERSION_MAJOR==0
						gst_element_query_position(GST_ELEMENT(gstPipeline),&format,&pos);
#else
						gst_element_query_position(GST_ELEMENT(gstPipeline),format,&pos);
#endif
						float loopSpeed;
						if(pos>0)
							loopSpeed=-speed;
						else
							loopSpeed=speed;
						if(!gst_element_seek(GST_ELEMENT(gstPipeline),
											loopSpeed,
											GST_FORMAT_UNDEFINED,
											flags,
											GST_SEEK_TYPE_NONE,
											0,
											GST_SEEK_TYPE_NONE,
											0)) {
							gLogManager.log("GStreamer: unable to seek");
						}
					}break;
					*/
					default:
					break;
				}

			break;

			default:
		//		ofLogVerbose() << "GStreamer: unhandled message from " << GST_MESSAGE_SRC_NAME(msg);
			break;
		}
		gst_message_unref(msg);
	}

	gst_object_unref(GST_OBJECT(bus));
}
Beispiel #19
0
void ofGstUtils::gstHandleMessage(){
	GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(gstPipeline));
	while(gst_bus_have_pending(bus)) {
		GstMessage* msg = gst_bus_pop(bus);
		if(appsink && appsink->on_message(msg)) continue;

		ofLog(OF_LOG_VERBOSE,"GStreamer: Got %s message", GST_MESSAGE_TYPE_NAME(msg));

		switch (GST_MESSAGE_TYPE (msg)) {

			case GST_MESSAGE_BUFFERING:
				gint pctBuffered;
				gst_message_parse_buffering(msg,&pctBuffered);
				ofLog(OF_LOG_VERBOSE,"GStreamer: buffering %i\%", pctBuffered);
				if(isStream && !bLoaded && appsink){
					appsink->on_stream_prepared();
				}
				if(pctBuffered<100){
					gst_element_set_state (gstPipeline, GST_STATE_PAUSED);
				}else if(!bPaused){
					gst_element_set_state (gstPipeline, GST_STATE_PLAYING);
				}
			break;

			case GST_MESSAGE_DURATION:{
				GstFormat format=GST_FORMAT_TIME;
				gst_element_query_duration(gstPipeline,&format,&durationNanos);
			}break;

			case GST_MESSAGE_STATE_CHANGED:{
				GstState oldstate, newstate, pendstate;
				gst_message_parse_state_changed(msg, &oldstate, &newstate, &pendstate);
				if(isStream && !bLoaded && appsink){
					appsink->on_stream_prepared();
				}
				/*seek_lock();
				if(posChangingPaused && newstate==GST_STATE_PLAYING){
					gst_element_set_state (gstPipeline, GST_STATE_PAUSED);
					posChangingPaused=false;
				}
				seek_unlock();*/

				ofLog(OF_LOG_VERBOSE,"GStreamer: state changed from " + getName(oldstate) + " to " + getName(newstate) + " (" + getName(pendstate) + ")");
			}break;

			case GST_MESSAGE_ASYNC_DONE:
				ofLog(OF_LOG_VERBOSE,"GStreamer: async done");
			break;

			case GST_MESSAGE_ERROR: {
				GError *err;
				gchar *debug;
				gst_message_parse_error(msg, &err, &debug);

				ofLog(OF_LOG_ERROR, "GStreamer Plugin: Embedded video playback halted; module %s reported: %s",
					  gst_element_get_name(GST_MESSAGE_SRC (msg)), err->message);

				g_error_free(err);
				g_free(debug);

				gst_element_set_state(GST_ELEMENT(gstPipeline), GST_STATE_NULL);

			}break;

			case GST_MESSAGE_EOS:
				ofLog(OF_LOG_VERBOSE,"GStreamer: end of the stream.");
				bIsMovieDone = true;

				switch(loopMode){

					case OF_LOOP_NORMAL:{
						GstFormat format = GST_FORMAT_TIME;
						GstSeekFlags flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH |GST_SEEK_FLAG_KEY_UNIT);
						gint64 pos;
						gst_element_query_position(GST_ELEMENT(gstPipeline),&format,&pos);

						float loopSpeed;
						if(pos>0)
							loopSpeed=-speed;
						else
							loopSpeed=speed;
						if(!gst_element_seek(GST_ELEMENT(gstPipeline),
											speed,
											format,
											flags,
											GST_SEEK_TYPE_SET,
											0,
											GST_SEEK_TYPE_SET,
											durationNanos)) {
							ofLog(OF_LOG_WARNING,"GStreamer: unable to seek");
						}
					}break;

					case OF_LOOP_PALINDROME:{
						GstFormat format = GST_FORMAT_TIME;
						GstSeekFlags flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH |GST_SEEK_FLAG_KEY_UNIT);
						gint64 pos;
						gst_element_query_position(GST_ELEMENT(gstPipeline),&format,&pos);
						float loopSpeed;
						if(pos>0)
							loopSpeed=-speed;
						else
							loopSpeed=speed;
						if(!gst_element_seek(GST_ELEMENT(gstPipeline),
											loopSpeed,
											GST_FORMAT_UNDEFINED,
											flags,
											GST_SEEK_TYPE_NONE,
											0,
											GST_SEEK_TYPE_NONE,
											0)) {
							ofLog(OF_LOG_WARNING,"GStreamer: unable to seek");
						}
					}break;

					default:
					break;
				}

			break;

			default:
				ofLog(OF_LOG_VERBOSE,"GStreamer: unhandled message");
			break;
		}
		gst_message_unref(msg);
	}

	gst_object_unref(GST_OBJECT(bus));
}
Beispiel #20
0
	void SourceObject::HandleErrorMsg (GstMessage *msg)
	{
		GError *gerror = nullptr;
		gchar *debug = nullptr;
		gst_message_parse_error (msg, &gerror, &debug);

		const auto& msgStr = QString::fromUtf8 (gerror->message);
		const auto& debugStr = QString::fromUtf8 (debug);

		const auto code = gerror->code;
		const auto domain = gerror->domain;

		g_error_free (gerror);
		g_free (debug);

		// GStreamer is utter crap
		if (domain == GST_RESOURCE_ERROR &&
				code == GST_RESOURCE_ERROR_NOT_FOUND &&
				msgStr == "Cancelled")
			return;

		qWarning () << Q_FUNC_INFO
				<< GetCurrentSource ().ToUrl ()
				<< domain
				<< code
				<< msgStr
				<< debugStr;

		const std::map<decltype (domain), std::map<decltype (code), SourceError>> errMap
		{
			{
				GST_CORE_ERROR,
				{
					{
						GST_CORE_ERROR_MISSING_PLUGIN,
						SourceError::MissingPlugin
					}
				}
			},
			{
				GST_RESOURCE_ERROR,
				{
					{
						GST_RESOURCE_ERROR_NOT_FOUND,
						SourceError::SourceNotFound
					}
				}
			},
			{
				GST_STREAM_ERROR,
				{
					{
						GST_STREAM_ERROR_TYPE_NOT_FOUND,
						SourceError::InvalidSource
					}
				}
			}
		};

		const auto errCode = [&] () -> SourceError
			{
				try
				{
					return errMap.at (domain).at (code);
				}
				catch (const std::out_of_range&)
				{
					return SourceError::Other;
				}
			} ();

		if (!IsDrainingMsgs_)
		{
			qDebug () << Q_FUNC_INFO << "draining bus";
			IsDrainingMsgs_ = true;

			while (const auto newMsg = gst_bus_pop (gst_pipeline_get_bus (GST_PIPELINE (Dec_))))
				handleMessage (std::shared_ptr<GstMessage> (newMsg, gst_message_unref));

			IsDrainingMsgs_ = false;
			BusDrainWC_.wakeAll ();
		}

		if (!IsDrainingMsgs_)
			emit error (msgStr, errCode);
	}
static void
helper (gboolean flush)
{
    GstElement *filter;
    GstBus *bus;
    GstPad *mysrcpad;
    GstPad *mysinkpad;

    /* init */
    filter = gst_check_setup_element ("omx_dummy");
    mysrcpad = gst_check_setup_src_pad (filter, &srctemplate, NULL);
    mysinkpad = gst_check_setup_sink_pad (filter, &sinktemplate, NULL);

    gst_pad_set_active (mysrcpad, TRUE);
    gst_pad_set_active (mysinkpad, TRUE);

    /* need to know when we are eos */
    gst_pad_set_event_function (mysinkpad, test_sink_event);

    /* and notify the test run */
    eos_mutex = g_mutex_new ();
    eos_cond = g_cond_new ();
    eos_arrived = FALSE;

    g_object_set (G_OBJECT (filter), "library-name", "libomxil-foo.so", NULL);

    /* start */

    fail_unless_equals_int (gst_element_set_state (filter, GST_STATE_PLAYING),
                            GST_STATE_CHANGE_SUCCESS);

    bus = gst_bus_new ();

    gst_element_set_bus (filter, bus);

    /* send buffers in order*/
    {
        guint i;
        for (i = 0; i < BUFFER_COUNT; i++)
        {
            GstBuffer *inbuffer;
            inbuffer = gst_buffer_new_and_alloc (BUFFER_SIZE);
            GST_BUFFER_DATA(inbuffer)[0] = i;
            ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);

            fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);

            if (flush && i % FLUSH_AT == 0)
            {
                gst_pad_push_event (mysrcpad, gst_event_new_flush_start ());
                gst_pad_push_event (mysrcpad, gst_event_new_flush_stop ());
                i += FLUSH_AT;
            }
        }
    }

    {
        GstMessage *message;
        fail_if ((message = gst_bus_pop (bus)) != NULL);

        /* make sure there's no error on the bus */
        message = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
        fail_if (message);
    }

    gst_pad_push_event (mysrcpad, gst_event_new_eos ());
    /* need to wait a bit to make sure src pad task digested all and sent eos */
    g_mutex_lock (eos_mutex);
    while (!eos_arrived)
        g_cond_wait (eos_cond, eos_mutex);
    g_mutex_unlock (eos_mutex);

    /* check the order of the buffers*/
    if (!flush)
    {
        GList *cur;
        guint i;
        for (cur = buffers, i = 0; cur; cur = g_list_next (cur), i++)
        {
            GstBuffer *buffer;
            buffer = cur->data;
            fail_unless (GST_BUFFER_DATA(buffer)[0] == i);
        }
        fail_unless (i == BUFFER_COUNT);
    }

    /* cleanup */
    gst_bus_set_flushing (bus, TRUE);
    gst_element_set_bus (filter, NULL);
    gst_object_unref (GST_OBJECT (bus));
    gst_check_drop_buffers ();

    /* deinit */
    gst_element_set_state (filter, GST_STATE_NULL);

    gst_pad_set_active (mysrcpad, FALSE);
    gst_pad_set_active (mysinkpad, FALSE);
    gst_check_teardown_src_pad (filter);
    gst_check_teardown_sink_pad (filter);
    gst_check_teardown_element (filter);

    g_mutex_free (eos_mutex);
    g_cond_free (eos_cond);
}