Ejemplo n.º 1
0
void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message)
{
    GstMessage* gm = message.rawMessage();

    if (gm == 0) {
        // Null message, query current position
        quint32 newPos = position();

        if (newPos/1000 != m_lastPosition) {
            m_lastPosition = newPos/1000;
            emit positionChanged(newPos);
        }

    } else {
        //tag message comes from elements inside playbin, not from playbin itself
        if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) {
            //qDebug() << "tag message";
            GstTagList *tag_list;
            gst_message_parse_tag(gm, &tag_list);
            gst_tag_list_foreach(tag_list, addTagToMap, &m_tags);

            //qDebug() << m_tags;

            emit tagsChanged();
        }

        if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) {
            switch (GST_MESSAGE_TYPE(gm))  {
            case GST_MESSAGE_STATE_CHANGED:
                {
                    GstState    oldState;
                    GstState    newState;
                    GstState    pending;

                    gst_message_parse_state_changed(gm, &oldState, &newState, &pending);

#ifdef DEBUG_PLAYBIN_STATES
                    QStringList states;
                    states << "GST_STATE_VOID_PENDING" <<  "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING";

                    qDebug() << QString("state changed: old: %1  new: %2  pending: %3") \
                            .arg(states[oldState]) \
                            .arg(states[newState]) \
                            .arg(states[pending]);
#endif

                    switch (newState) {
                    case GST_STATE_VOID_PENDING:
                    case GST_STATE_NULL:
                        setSeekable(false);
                        if (m_state != QMediaPlayer::StoppedState)
                            emit stateChanged(m_state = QMediaPlayer::StoppedState);
                        break;
                    case GST_STATE_READY:
                        setSeekable(false);
                        if (m_state != QMediaPlayer::StoppedState)
                            emit stateChanged(m_state = QMediaPlayer::StoppedState);
                        break;
                    case GST_STATE_PAUSED:
                        if (m_state != QMediaPlayer::PausedState)
                            emit stateChanged(m_state = QMediaPlayer::PausedState);

                        //check for seekable
                        if (oldState == GST_STATE_READY) {
                            /*
                                //gst_element_seek_simple doesn't work reliably here, have to find a better solution

                                GstFormat   format = GST_FORMAT_TIME;
                                gint64      position = 0;
                                bool seekable = false;
                                if (gst_element_query_position(m_playbin, &format, &position)) {
                                    seekable = gst_element_seek_simple(m_playbin, format, GST_SEEK_FLAG_NONE, position);
                                }

                                setSeekable(seekable);
                                */

                            setSeekable(true);

                            if (!qFuzzyCompare(m_playbackRate, qreal(1.0))) {
                                qreal rate = m_playbackRate;
                                m_playbackRate = 1.0;
                                setPlaybackRate(rate);
                            }

                            if (m_renderer)
                                m_renderer->precessNewStream();

                        }


                        break;
                    case GST_STATE_PLAYING:
                        if (oldState == GST_STATE_PAUSED)
                            getStreamsInfo();

                        if (m_state != QMediaPlayer::PlayingState)
                            emit stateChanged(m_state = QMediaPlayer::PlayingState);

                        break;
                    }
                }
                break;

            case GST_MESSAGE_EOS:
                emit playbackFinished();
                break;

            case GST_MESSAGE_TAG:
            case GST_MESSAGE_STREAM_STATUS:
            case GST_MESSAGE_UNKNOWN:
                break;
            case GST_MESSAGE_ERROR:
                {
                    GError *err;
                    gchar *debug;
                    gst_message_parse_error (gm, &err, &debug);
                    emit error(int(QMediaPlayer::ResourceError), QString::fromUtf8(err->message));
                    qWarning() << "Error:" << QString::fromUtf8(err->message);
                    g_error_free (err);
                    g_free (debug);
                }
                break;
            case GST_MESSAGE_WARNING:
            case GST_MESSAGE_INFO:
                break;
            case GST_MESSAGE_BUFFERING:
                {
                    int progress = 0;
                    gst_message_parse_buffering(gm, &progress);
                    emit bufferingProgressChanged(progress);
                }
                break;
            case GST_MESSAGE_STATE_DIRTY:
            case GST_MESSAGE_STEP_DONE:
            case GST_MESSAGE_CLOCK_PROVIDE:
            case GST_MESSAGE_CLOCK_LOST:
            case GST_MESSAGE_NEW_CLOCK:
            case GST_MESSAGE_STRUCTURE_CHANGE:
            case GST_MESSAGE_APPLICATION:
            case GST_MESSAGE_ELEMENT:
                break;
            case GST_MESSAGE_SEGMENT_START:
                {
                    const GstStructure *structure = gst_message_get_structure(gm);
                    qint64 position = g_value_get_int64(gst_structure_get_value(structure, "position"));
                    position /= 1000000;
                    m_lastPosition = position;
                    emit positionChanged(position);
                }
                break;
            case GST_MESSAGE_SEGMENT_DONE:
                break;
            case GST_MESSAGE_DURATION:
                {
                    GstFormat   format = GST_FORMAT_TIME;
                    gint64      duration = 0;

                    if (gst_element_query_duration(m_playbin, &format, &duration)) {
                        int newDuration = duration / 1000000;
                        if (m_duration != newDuration) {
                            m_duration = newDuration;
                            emit durationChanged(m_duration);
                        }
                    }
                }
                break;
            case GST_MESSAGE_LATENCY:
#if (GST_VERSION_MAJOR >= 0) &&  (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 13)
            case GST_MESSAGE_ASYNC_START:
            case GST_MESSAGE_ASYNC_DONE:
#if GST_VERSION_MICRO >= 23
            case GST_MESSAGE_REQUEST_STATE:
#endif
#endif
            case GST_MESSAGE_ANY:
                break;
            }
        }
    }
}
static gboolean
hls_test_bus_message (InsanityGstPipelineTest * ptest, GstMessage * msg)
{
  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_BUFFERING:
    {
      gint per;

      gst_message_parse_buffering (msg, &per);

      /* First buffering happend properly, this is requiered to be able to
       * start seeking */
      if (G_UNLIKELY (glob_buffered == FALSE)) {
        if (per == 100) {
          insanity_test_validate_checklist_item (INSANITY_TEST (ptest),
              "done-buffering", TRUE, NULL);
          glob_buffered = TRUE;

          if (glob_buffering_timeout != 0) {
            g_source_remove (glob_buffering_timeout);
            glob_buffering_timeout = 0;
          }
        } else {
          glob_buffering_timeout = g_timeout_add (250,
              (GSourceFunc) buffering_timeout, INSANITY_TEST (ptest));
        }
      }

      break;
    }
    case GST_MESSAGE_STATE_CHANGED:
      if (GST_MESSAGE_SRC (msg) == GST_OBJECT (glob_pipeline)) {
        const char *validate_checklist_item = glob_validate_on_playing;
        GstState oldstate, newstate, pending;

        gst_message_parse_state_changed (msg, &oldstate, &newstate, &pending);
        if (newstate == GST_STATE_PAUSED && oldstate == GST_STATE_READY) {
          GstIterator *it;
          GValue v = { 0, };
          gboolean queried;
          InsanityTest *test = INSANITY_TEST (ptest);
          GstQuery *query = gst_query_new_latency ();
          const gchar *step_message = "Could not query seeking\n";

          if ((queried = gst_element_query (glob_pipeline, query))) {
            gst_query_parse_latency (query, &glob_is_live, NULL, NULL);
            step_message = NULL;
          } else
            insanity_test_printf (test, "Could not query\n");

          insanity_gst_pipeline_test_set_live (ptest, glob_is_live);
          insanity_test_validate_checklist_item (test, "queried-live", queried,
              step_message);
          gst_query_unref (query);

          step_message = "Could not query seekable\n";
          query = gst_query_new_seeking (GST_FORMAT_TIME);
          if ((queried = gst_element_query (glob_pipeline, query))) {
            gst_query_parse_seeking (query, NULL, &glob_is_seekable, NULL,
                NULL);
            step_message = NULL;
          } else
            insanity_test_printf (test, "Could not query\n");

          insanity_test_validate_checklist_item (test, "queried-seekable",
              queried, step_message);
          gst_query_unref (query);

          /* Iterate over the bins to find a hlsdemux */
          it = gst_bin_iterate_recurse (GST_BIN (glob_pipeline));
          if (gst_iterator_find_custom (it, (GCompareFunc) find_hlsdemux, &v,
                  NULL)) {
            glob_hlsdemux = g_value_dup_object (&v);
          }
          g_value_unset (&v);
          gst_iterator_free (it);

          if (glob_hlsdemux != NULL) {
            insanity_test_validate_checklist_item (test, "protocol-is-hls",
                TRUE, "HLS protocol in use");

            gst_object_unref (glob_hlsdemux);
          } else {
            insanity_test_validate_checklist_item (test, "protocol-is-hls",
                FALSE, "HLS protocol in use");
            insanity_test_done (test);
          }

          /* Watch pipeline only if seekable */
          if (glob_is_seekable)
            watch_pipeline (ptest);

        } else if (newstate == GST_STATE_PLAYING
            && pending == GST_STATE_VOID_PENDING && validate_checklist_item) {
          glob_validate_on_playing = NULL;
          insanity_test_validate_checklist_item (INSANITY_TEST (ptest),
              validate_checklist_item, TRUE, NULL);
          /* let it run a couple seconds */
          glob_wait_time = hls_test_get_wait_time (INSANITY_TEST (ptest));
          glob_timer_id =
              g_timeout_add (250, (GSourceFunc) & wait_and_end_step,
              INSANITY_TEST (ptest));
        }
      }
      break;
    case GST_MESSAGE_EOS:
      return FALSE;
    default:
      break;
  }

  return TRUE;

}
Ejemplo n.º 3
0
bool ofGstUtils::gstHandleMessage(GstBus * bus, GstMessage * msg){
	if(appsink && appsink->on_message(msg)) return true;

		/*ofLogVerbose("ofGstUtils") << "gstHandleMessage(): 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);
			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): buffering " << 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){
					//ofLogVerbose("ofGstUtils") << "gstHandleMessage(): setting stream pipeline to play";
					play();
				}
			}

			/*ofLogVerbose("ofGstUtils") << "gstHandleMessage(): " << GST_MESSAGE_SRC_NAME(msg) << " state changed from "
					<< getName(oldstate) << " to " << getName(newstate) << " (" + getName(pendstate) << ")";*/
		}break;

		case GST_MESSAGE_ASYNC_DONE:
			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): async done";
		break;

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

			ofLogError("ofGstUtils") << "gstHandleMessage(): embedded video playback halted for plugin, module "
				<< name << "  reported: " << err->message;

			g_free(name);
			g_error_free(err);
			g_free(debug);

			gst_element_set_state(GST_ELEMENT(gstPipeline), GST_STATE_NULL);

		}break;

		case GST_MESSAGE_EOS:{
			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): end of the stream";
			bool isClosing = closing;
			eos_cb();

			if(isClosing){
				busWatchID = 0;
				return false;
			}

			switch(loopMode){

				case OF_LOOP_NORMAL:{
					GstFormat format = GST_FORMAT_TIME;
					GstSeekFlags flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT);
					if(speed>0){
						if(!gst_element_seek(GST_ELEMENT(gstPipeline),
											speed,
											format,
											flags,
											GST_SEEK_TYPE_SET,
											0,
											GST_SEEK_TYPE_SET,
											-1)) {
							ofLogWarning("ofGstUtils") << "gstHandleMessage(): unable to seek";
						}
					}else if(speed<0){
						if(!gst_element_seek(GST_ELEMENT(gstPipeline),speed, 	format,
								flags,
								GST_SEEK_TYPE_SET,
								0,
								GST_SEEK_TYPE_SET,
								durationNanos-1000000)) {
							ofLogWarning("ofGstUtils") << "gstHandleMessage(): 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)) {
						ofLogWarning("ofGstUtils") << "gstHandleMessage(): unable to seek";
					}
				}break;

				default:
				break;
			}

		}break;
		case GST_MESSAGE_LATENCY:
			gst_bin_recalculate_latency (GST_BIN (getPipeline()));
			break;
		case GST_MESSAGE_REQUEST_STATE:	{
			GstState state;
			gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (msg));

			gst_message_parse_request_state (msg, &state);
			gst_element_set_state (getPipeline(), state);

			g_free (name);
			break;
		}
		case GST_MESSAGE_HAVE_CONTEXT:{
			GstContext *context;
			const gchar *context_type;
			gchar *context_str;

			gst_message_parse_have_context (msg, &context);

			context_type = gst_context_get_context_type (context);
			context_str = gst_structure_to_string (gst_context_get_structure (context));
			ofLogNotice("ofGstUtils","Got context from element '%s': %s=%s\n",
				GST_ELEMENT_NAME (GST_MESSAGE_SRC (msg)), context_type,
				context_str);
			g_free (context_str);
			gst_context_unref (context);
			break;
		}
		default:
			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): unhandled message from " << GST_MESSAGE_SRC_NAME(msg);
		break;
	}

	return true;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
static gboolean
gst_PlayRegion_handle_message (GstBus * bus, GstMessage * message, gpointer data)
{
  GstPlayRegion *PlayRegion = (GstPlayRegion *) data;

  switch (GST_MESSAGE_TYPE (message)) {

    case GST_MESSAGE_APPLICATION:
      if (gst_message_has_name (message, "ExPrerolled")) {
        /* it's our message */
        g_print ("we are all prerolled, do seek\n");
        gst_element_seek (PlayRegion->pipeline,
          1.0, GST_FORMAT_TIME,
          GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
          GST_SEEK_TYPE_SET, 2 * GST_SECOND,
          GST_SEEK_TYPE_SET, 5 * GST_SECOND);

        gst_element_set_state (PlayRegion->pipeline, GST_STATE_PLAYING);
      }
      break;

    case GST_MESSAGE_EOS:
      gst_PlayRegion_handle_eos (PlayRegion);
      break;
    case GST_MESSAGE_ERROR:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_error (message, &error, &debug);
      gst_PlayRegion_handle_error (PlayRegion, error, debug);
    }
      break;
    case GST_MESSAGE_WARNING:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_warning (message, &error, &debug);
      gst_PlayRegion_handle_warning (PlayRegion, error, debug);
    }
      break;
    case GST_MESSAGE_INFO:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_info (message, &error, &debug);
      gst_PlayRegion_handle_info (PlayRegion, error, debug);
    }
      break;
    case GST_MESSAGE_TAG:
    {
      GstTagList *tag_list;

      gst_message_parse_tag (message, &tag_list);
      if (verbose)
        g_print ("tag\n");
    }
      break;
    case GST_MESSAGE_STATE_CHANGED:
    {
      GstState oldstate, newstate, pending;

      gst_message_parse_state_changed (message, &oldstate, &newstate, &pending);
      if (GST_ELEMENT (message->src) == PlayRegion->pipeline) {
        if (verbose)
          g_print ("state change from %s to %s\n",
              gst_element_state_get_name (oldstate),
              gst_element_state_get_name (newstate));
        switch (GST_STATE_TRANSITION (oldstate, newstate)) {
          case GST_STATE_CHANGE_NULL_TO_READY:
            gst_PlayRegion_handle_null_to_ready (PlayRegion);
            break;
          case GST_STATE_CHANGE_READY_TO_PAUSED:
            gst_PlayRegion_handle_ready_to_paused (PlayRegion);
            break;
          case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
            gst_PlayRegion_handle_paused_to_playing (PlayRegion);
            break;
          case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
            gst_PlayRegion_handle_playing_to_paused (PlayRegion);
            break;
          case GST_STATE_CHANGE_PAUSED_TO_READY:
            gst_PlayRegion_handle_paused_to_ready (PlayRegion);
            break;
          case GST_STATE_CHANGE_READY_TO_NULL:
            gst_PlayRegion_handle_ready_to_null (PlayRegion);
            break;
          default:
            if (verbose)
              g_print ("unknown state change from %s to %s\n",
                  gst_element_state_get_name (oldstate),
                  gst_element_state_get_name (newstate));
        }
      }
    }
      break;
    case GST_MESSAGE_BUFFERING:
    {
      int percent;
      gst_message_parse_buffering (message, &percent);
      //g_print("buffering %d\n", percent);
      if (!PlayRegion->paused_for_buffering && percent < 100) {
        g_print ("pausing for buffing\n");
        PlayRegion->paused_for_buffering = TRUE;
        gst_element_set_state (PlayRegion->pipeline, GST_STATE_PAUSED);
      } else if (PlayRegion->paused_for_buffering && percent == 100) {
        g_print ("unpausing for buffing\n");
        PlayRegion->paused_for_buffering = FALSE;
        gst_element_set_state (PlayRegion->pipeline, GST_STATE_PLAYING);
      }
    }
      break;
    case GST_MESSAGE_STATE_DIRTY:
    case GST_MESSAGE_CLOCK_PROVIDE:
    case GST_MESSAGE_CLOCK_LOST:
    case GST_MESSAGE_NEW_CLOCK:
    case GST_MESSAGE_STRUCTURE_CHANGE:
    case GST_MESSAGE_STREAM_STATUS:
      break;
    case GST_MESSAGE_STEP_DONE:
    case GST_MESSAGE_ELEMENT:
    case GST_MESSAGE_SEGMENT_START:
    case GST_MESSAGE_SEGMENT_DONE:
    case GST_MESSAGE_DURATION:
    case GST_MESSAGE_LATENCY:
    case GST_MESSAGE_ASYNC_START:
    case GST_MESSAGE_ASYNC_DONE:
    case GST_MESSAGE_REQUEST_STATE:
    case GST_MESSAGE_STEP_START:
    case GST_MESSAGE_QOS:
    default:
      if (verbose) {
        g_print ("message: %s\n", GST_MESSAGE_TYPE_NAME (message));
      }
      break;
  }

  return TRUE;
}
Ejemplo n.º 6
0
static void
bus_message_cb (GstBus     *bus,
                GstMessage *message,
                gpointer    user_data)
{
	GthMediaViewerPage *self = user_data;

	if (GST_MESSAGE_SRC (message) != GST_OBJECT (self->priv->playbin))
		return;

	switch (GST_MESSAGE_TYPE (message)) {
	case GST_MESSAGE_STATE_CHANGED: {
		GstState old_state;
		GstState new_state;
		GstState pending_state;

		old_state = new_state = GST_STATE_NULL;
		gst_message_parse_state_changed (message, &old_state, &new_state, &pending_state);
		if (old_state == new_state)
			break;

		self->priv->paused = (new_state == GST_STATE_PAUSED);
		update_current_position_bar (self);

		if ((old_state == GST_STATE_NULL) && (new_state == GST_STATE_READY) && (pending_state != GST_STATE_PAUSED)) {
			update_stream_info (self);
			gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (self));
			gth_viewer_page_file_loaded (GTH_VIEWER_PAGE (self), self->priv->file_data, TRUE);
		}
		if ((old_state == GST_STATE_READY) && (new_state == GST_STATE_PAUSED)) {
			update_stream_info (self);
			gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (self));
			gth_viewer_page_file_loaded (GTH_VIEWER_PAGE (self), self->priv->file_data, TRUE);
		}
		if ((old_state == GST_STATE_READY) || (new_state == GST_STATE_PAUSED))
			update_volume_from_playbin (self);
		if ((old_state == GST_STATE_PLAYING) || (new_state == GST_STATE_PLAYING))
			update_play_button (self, new_state);
		break;
	}

	case GST_MESSAGE_DURATION_CHANGED:
		self->priv->duration = 0;
		update_current_position_bar (self);
		break;

	case GST_MESSAGE_EOS:
		reset_player_state (self);
		break;

	case GST_MESSAGE_BUFFERING: {
		int percent = 0;
		gst_message_parse_buffering (message, &percent);
		gst_element_set_state (self->priv->playbin, (percent == 100) ? GST_STATE_PLAYING : GST_STATE_PAUSED);
		break;
	}

	case GST_MESSAGE_ERROR:
		gth_viewer_page_file_loaded (GTH_VIEWER_PAGE (self), self->priv->file_data, FALSE);
		break;

	default:
		break;
	}
}
Ejemplo n.º 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 ("%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;
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
0
static gboolean
master_bus_msg (GstBus * bus, GstMessage * msg, gpointer data)
{
  GstPipeline *pipeline = data;

  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_ERROR:{
      GError *err;
      gchar *dbg;

      gst_message_parse_error (msg, &err, &dbg);
      g_printerr ("MASTER: ERROR: %s\n", err->message);
      if (dbg != NULL)
        g_printerr ("MASTER: ERROR debug information: %s\n", dbg);
      g_error_free (err);
      g_free (dbg);

      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
          GST_DEBUG_GRAPH_SHOW_ALL, "ipc.master.error");

      g_main_loop_quit (loop);
      break;
    }
    case GST_MESSAGE_WARNING:{
      GError *err;
      gchar *dbg;

      gst_message_parse_warning (msg, &err, &dbg);
      g_printerr ("MASTER: WARNING: %s\n", err->message);
      if (dbg != NULL)
        g_printerr ("MASTER: WARNING debug information: %s\n", dbg);
      g_error_free (err);
      g_free (dbg);

      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
          GST_DEBUG_GRAPH_SHOW_ALL, "ipc.master.warning");
      break;
    }
    case GST_MESSAGE_ASYNC_DONE:
      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
          GST_DEBUG_GRAPH_SHOW_ALL, "ipc.master.async-done");
      break;
    case GST_MESSAGE_EOS:
      g_print ("EOS on master\n");
      gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
      g_main_loop_quit (loop);
      break;
    case GST_MESSAGE_BUFFERING:{
      gint percent;
      GstBufferingMode bufmode;

      if (!buffering)
        g_print ("\n");

      gst_message_parse_buffering (msg, &percent);
      g_print ("%s %d%%  \r", "Buffering...", percent);

      gst_message_parse_buffering_stats (msg, &bufmode, NULL, NULL, NULL);

      /* no state management needed for live pipelines */
      if (bufmode != GST_BUFFERING_LIVE) {
        if (percent == 100) {
          /* a 100% message means buffering is done */
          if (buffering) {
            buffering = FALSE;
            gst_element_set_state (GST_ELEMENT (pipeline), desired_state);
            g_print ("\n%s\n", gst_element_state_get_name (desired_state));
          }
        } else {
          /* buffering... */
          if (!buffering) {
            gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
            buffering = TRUE;
          }
        }
      }
      break;
    }
    case GST_MESSAGE_CLOCK_LOST:{
      g_print ("Clock lost, selecting a new one\n");
      gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
      gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
      break;
    }
    case GST_MESSAGE_LATENCY:
    {
      gst_bin_recalculate_latency (GST_BIN (pipeline));
      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);

      GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
          GST_DEBUG_GRAPH_SHOW_VERBOSE, "ipc.slave.reqstate");

      g_print ("Setting state to %s as requested by %s...\n",
          gst_element_state_get_name (state), name);

      gst_element_set_state (GST_ELEMENT (pipeline), state);
      g_free (name);
      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, GST_ELEMENT (pipeline));
              }
              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 (GST_ELEMENT (pipeline), +0.08);
                } else if (button == 5) {
                  /* wheel down */
                  relative_seek (GST_ELEMENT (pipeline), -0.01);
                }
              }
              break;
            }
            default:
              break;
          }
        }
        if (ev)
          gst_event_unref (ev);
      }
      break;
    }
    default:
      break;
  }
  return TRUE;
}
Ejemplo n.º 10
0
// A C-style callback used to receive messages from GStreamer:
static gboolean linGstBusCallback(
  GstBus *bus,
  GstMessage *msg,
  gpointer linGstObjectPtr)
{
  Q_UNUSED(bus);

  switch (GST_MESSAGE_TYPE(msg))
  {
  case GST_MESSAGE_TAG:
    {
      GstTagList *tags = NULL;

      gst_message_parse_tag(msg, &tags);

      gst_tag_list_foreach(tags, linHandleTag, linGstObjectPtr);

      if (tags) gst_tag_list_free(tags);
    }
    break;

  case GST_MESSAGE_STATE_CHANGED:
    // The stream has entered a new state; perform any necessary cleanup:
    {
      LinVideoDisplayForm *myForm =
        static_cast<LinVideoDisplayForm *>(linGstObjectPtr);

      // Check to see if the stream allows seeking:
      if ( myForm->seekingUnknown()
        && myForm->gstObjectMatches(GST_MESSAGE_SRC(msg)))
      {
        GstState oldState, newState, pendingState;

        gst_message_parse_state_changed(
          msg, &oldState, &newState, &pendingState);

        if (newState == GST_STATE_PLAYING)
        {
          // First, initialize the data dialog:
          myForm->setupDataDialog();

          // Now, check for seeking:
          gboolean seekEnabled;
          gint64 start, end;
          GstQuery *query;
          query = gst_query_new_seeking(GST_FORMAT_TIME);
          if (myForm->gstElementQuery(query))
          {
            gst_query_parse_seeking(query, NULL, &seekEnabled, &start, &end);

/*
            if (seekEnabled)
            {
              qDebug() << "Seek from " << start << " to " << end;
            }
*/

            myForm->setSeeking(seekEnabled == true);
          }

          gst_query_unref(query);
        }
      }
    }
    break;

  case GST_MESSAGE_BUFFERING:
    {
      LinVideoDisplayForm *myForm =
        static_cast<LinVideoDisplayForm *>(linGstObjectPtr);

      gint percent = 0;
      gst_message_parse_buffering (msg, &percent);
//qDebug() << "Buffering percentage at " << percent;
      if (percent < 100)
      {
        myForm->waitForBuffer();
      }
      else
      {
        myForm->finishedBuffer();
      }
    }
    break;

  case GST_MESSAGE_EOS:
    {
      LinVideoDisplayForm *myForm =
        static_cast<LinVideoDisplayForm *>(linGstObjectPtr);

      myForm->stopPlaying();
    }
    break;

  case GST_MESSAGE_ERROR:
    {
      gchar *debug;
      GError *err;

      gst_message_parse_error(msg, &err, &debug);
      QString errString = "[";
      errString += GST_OBJECT_NAME(msg->src);
      errString += "]: ";
      errString += err->message;
      errString += " ";
      errString += debug;
      // Display the error message!
qDebug() << errString;

      LinVideoDisplayForm *myForm =
        static_cast<LinVideoDisplayForm *>(linGstObjectPtr);

      myForm->stopPlaying();
      
      g_free (debug);
      g_error_free (err);
    }
    break;

  default:
    break;
  }

  return true;
}
Ejemplo n.º 11
0
static gboolean
gst_inter_test_handle_message (GstBus * bus, GstMessage * message,
    gpointer data)
{
  GstInterTest *intertest = (GstInterTest *) data;

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_EOS:
      gst_inter_test_handle_eos (intertest);
      break;
    case GST_MESSAGE_ERROR:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_error (message, &error, &debug);
      gst_inter_test_handle_error (intertest, error, debug);
    }
      break;
    case GST_MESSAGE_WARNING:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_warning (message, &error, &debug);
      gst_inter_test_handle_warning (intertest, error, debug);
    }
      break;
    case GST_MESSAGE_INFO:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_info (message, &error, &debug);
      gst_inter_test_handle_info (intertest, error, debug);
    }
      break;
    case GST_MESSAGE_TAG:
    {
      GstTagList *tag_list;

      gst_message_parse_tag (message, &tag_list);
      if (verbose)
        g_print ("tag\n");
    }
      break;
    case GST_MESSAGE_STATE_CHANGED:
    {
      GstState oldstate, newstate, pending;

      gst_message_parse_state_changed (message, &oldstate, &newstate, &pending);
      if (GST_ELEMENT (message->src) == intertest->pipeline) {
        if (verbose)
          g_print ("state change from %s to %s\n",
              gst_element_state_get_name (oldstate),
              gst_element_state_get_name (newstate));
        switch (GST_STATE_TRANSITION (oldstate, newstate)) {
          case GST_STATE_CHANGE_NULL_TO_READY:
            gst_inter_test_handle_null_to_ready (intertest);
            break;
          case GST_STATE_CHANGE_READY_TO_PAUSED:
            gst_inter_test_handle_ready_to_paused (intertest);
            break;
          case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
            gst_inter_test_handle_paused_to_playing (intertest);
            break;
          case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
            gst_inter_test_handle_playing_to_paused (intertest);
            break;
          case GST_STATE_CHANGE_PAUSED_TO_READY:
            gst_inter_test_handle_paused_to_ready (intertest);
            break;
          case GST_STATE_CHANGE_READY_TO_NULL:
            gst_inter_test_handle_ready_to_null (intertest);
            break;
          default:
            if (verbose)
              g_print ("unknown state change from %s to %s\n",
                  gst_element_state_get_name (oldstate),
                  gst_element_state_get_name (newstate));
        }
      }
    }
      break;
    case GST_MESSAGE_BUFFERING:
    {
      int percent;
      gst_message_parse_buffering (message, &percent);
      //g_print("buffering %d\n", percent);
      if (!intertest->paused_for_buffering && percent < 100) {
        g_print ("pausing for buffing\n");
        intertest->paused_for_buffering = TRUE;
        gst_element_set_state (intertest->pipeline, GST_STATE_PAUSED);
      } else if (intertest->paused_for_buffering && percent == 100) {
        g_print ("unpausing for buffing\n");
        intertest->paused_for_buffering = FALSE;
        gst_element_set_state (intertest->pipeline, GST_STATE_PLAYING);
      }
    }
      break;
    case GST_MESSAGE_STATE_DIRTY:
    case GST_MESSAGE_CLOCK_PROVIDE:
    case GST_MESSAGE_CLOCK_LOST:
    case GST_MESSAGE_NEW_CLOCK:
    case GST_MESSAGE_STRUCTURE_CHANGE:
    case GST_MESSAGE_STREAM_STATUS:
      break;
    case GST_MESSAGE_STEP_DONE:
    case GST_MESSAGE_APPLICATION:
    case GST_MESSAGE_ELEMENT:
    case GST_MESSAGE_SEGMENT_START:
    case GST_MESSAGE_SEGMENT_DONE:
    case GST_MESSAGE_DURATION:
    case GST_MESSAGE_LATENCY:
    case GST_MESSAGE_ASYNC_START:
    case GST_MESSAGE_ASYNC_DONE:
    case GST_MESSAGE_REQUEST_STATE:
    case GST_MESSAGE_STEP_START:
    default:
      if (verbose) {
        g_print ("message: %s\n", GST_MESSAGE_TYPE_NAME (message));
      }
      break;
    case GST_MESSAGE_QOS:
      break;
  }

  return TRUE;
}
Ejemplo n.º 12
0
static gboolean bus_callback(GstBus *bus, GstMessage *msg, gpointer data) {
	GMainLoop *loop = (GMainLoop *)data;

	switch (GST_MESSAGE_TYPE (msg)) {
	case GST_MESSAGE_EOS:
		if (config_quit_on_stream_end() || !main_have_gui()) {
			gstreamer_destroy_pipeline();
			g_main_loop_quit(loop);
		}
		gstreamer_pause();
		end_of_stream = TRUE;
		break;
	case GST_MESSAGE_ERROR: {
		gchar  *debug;
		GError *error;

		gst_message_parse_error(msg, &error, &debug);
		g_free(debug);

		gstreamer_destroy_pipeline();

		main_show_error_message(
			"Processing error (unrecognized format or other error).",
			error->message);
		g_error_free (error);
		break;
		}
	case GST_MESSAGE_QOS: {
		GstFormat format;
		guint64 processed;
		guint64 dropped;
		gst_message_parse_qos_stats(msg, &format, &processed, &dropped);
		if (format == GST_FORMAT_BUFFERS)  {
			GstElement *src = GST_MESSAGE_SRC(msg);
			char *name = gst_element_get_name(src);
			stats_report_dropped_frames_cb(src, name, processed, dropped);
//			printf("gstplay: %s reports %lu out of %lu frames (%d%%) dropped.\n",
//				name,
//				dropped, processed + dropped,
//				(int)(dropped * 100 / (processed + dropped)));
			g_free(name);
		}
		break;
	}
	case GST_MESSAGE_STATE_CHANGED:
		if (bus_quit_on_playing) {
			// When doing the initial run to determine video parameters,
			// stop immediately when play starts.
			if (GST_STATE(playbin_pipeline) == GST_STATE_PLAYING)
				g_main_loop_quit(loop);
		}
		if (!state_change_to_playing_already_occurred &&
		GST_STATE(pipeline) == GST_STATE_PLAYING) {
			gstreamer_set_default_settings();
#if !GST_CHECK_VERSION(1, 0, 0)
			// GStreamer 0.10's xvimagesink does not force aspect ratio by default.
			GstElement *xvimagesink = find_xvimagesink();
			if (xvimagesink)
				g_object_set(G_OBJECT(xvimagesink),
					"force-aspect-ratio", TRUE, NULL);
#endif
			// Trigger a callback for the GUI to update the status bar etc.
			gui_play_start_cb();
			state_change_to_playing_already_occurred = TRUE;
		}
		if (GST_STATE(pipeline) == GST_STATE_PLAYING)
			gui_state_change_to_playing_cb();
		if (GST_STATE(pipeline) == GST_STATE_PLAYING && pause_on_state_change_to_playing) {
			pause_on_state_change_to_playing = FALSE;
			gstreamer_pause();
		}
		break;
	case GST_MESSAGE_BUFFERING:
		if (bus_quit_on_playing)
			break;
		gint percent = 0;
		gst_message_parse_buffering(msg, &percent);
		if (percent < 100) {
			if (GST_STATE(pipeline) != GST_STATE_PAUSED)
				gst_element_set_state(pipeline, GST_STATE_PAUSED);
//			printf("Buffering (%u percent done)\n", percent);
		}
		else {
			if (GST_STATE(pipeline) != GST_STATE_PLAYING)
				gst_element_set_state(pipeline, GST_STATE_PLAYING);
		}
		break;
	case GST_MESSAGE_APPLICATION: {
	        const GstStructure *s;
	        s = gst_message_get_structure (msg);
	        if (gst_structure_has_name (s, "GstLaunchInterrupt")) {
			/* This application message is posted when we caught an interrupt and
			 * we need to stop the pipeline. */
			printf("gstplay: Interrupt: Stopping pipeline ...\n");
			fflush(stdout);
			fflush(stderr);
			gstreamer_destroy_pipeline();
	          	g_main_loop_quit(loop);
		}
		break;
        }
	default:
		break;
	}

	return TRUE;
}
static void
_bus_handler (GstBus * bus, GstMessage * message,
    GstValidatePipelineMonitor * monitor)
{
  GError *err = NULL;
  gchar *debug = NULL;

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR:
      gst_message_parse_error (message, &err, &debug);

      if (g_error_matches (err, GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN)) {
        GST_VALIDATE_REPORT (monitor, MISSING_PLUGIN,
            "Error: %s -- Debug message: %s", err->message, debug);
      } else {
        GST_VALIDATE_REPORT (monitor, ERROR_ON_BUS,
            "Got error: %s -- Debug message: %s", err->message, debug);
      }
      GST_VALIDATE_MONITOR_LOCK (monitor);
      monitor->got_error = TRUE;
      GST_VALIDATE_MONITOR_UNLOCK (monitor);
      g_error_free (err);
      g_free (debug);
      break;
    case GST_MESSAGE_WARNING:
      gst_message_parse_warning (message, &err, &debug);
      GST_VALIDATE_REPORT (monitor, WARNING_ON_BUS,
          "Got warning: %s -- Debug message: %s", err->message, debug);
      g_error_free (err);
      g_free (debug);
      break;
    case GST_MESSAGE_STATE_CHANGED:
    {
      if (GST_MESSAGE_SRC (message) == GST_VALIDATE_MONITOR (monitor)->target) {
        GstState oldstate, newstate, pending;

        gst_message_parse_state_changed (message, &oldstate, &newstate,
            &pending);

        if (oldstate == GST_STATE_READY && newstate == GST_STATE_PAUSED) {
          monitor->print_pos_srcid =
              g_timeout_add (PRINT_POSITION_TIMEOUT,
              (GSourceFunc) print_position, monitor);
        } else if (oldstate >= GST_STATE_PAUSED && newstate <= GST_STATE_READY) {
          if (monitor->print_pos_srcid
              && g_source_remove (monitor->print_pos_srcid))
            monitor->print_pos_srcid = 0;
          monitor->got_error = FALSE;
        }
      }

      break;
    }
    case GST_MESSAGE_BUFFERING:
    {
      GstBufferingMode mode;
      gint percent;

      gst_message_parse_buffering (message, &percent);
      gst_message_parse_buffering_stats (message, &mode, NULL, NULL, NULL);

      if (percent == 100) {
        /* a 100% message means buffering is done */
        if (monitor->buffering) {
          monitor->print_pos_srcid =
              g_timeout_add (PRINT_POSITION_TIMEOUT,
              (GSourceFunc) print_position, monitor);
          monitor->buffering = FALSE;
        }
      } else {
        /* buffering... */
        if (!monitor->buffering) {
          monitor->buffering = TRUE;
          if (monitor->print_pos_srcid
              && g_source_remove (monitor->print_pos_srcid))
            monitor->print_pos_srcid = 0;
        }
      }
      break;
    }
    default:
      break;
  }
}
Ejemplo n.º 14
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;

	//	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));
}
Ejemplo n.º 15
0
bool ofGstUtils::gstHandleMessage(GstBus * bus, GstMessage * msg){
	if(appsink && appsink->on_message(msg)) return true;

		ofLogVerbose("ofGstUtils") << "gstHandleMessage(): 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);
			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): buffering " << 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){
					ofLogVerbose("ofGstUtils") << "gstHandleMessage(): setting stream pipeline to play";
					play();
				}
			}

			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): " << GST_MESSAGE_SRC_NAME(msg) << " state changed from "
					<< getName(oldstate) << " to " << getName(newstate) << " (" + getName(pendstate) << ")";
		}break;

		case GST_MESSAGE_ASYNC_DONE:
			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): async done";
		break;

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

			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): embedded video playback halted for plugin, module "
				<< gst_element_get_name(GST_MESSAGE_SRC (msg)) << "  reported: " << err->message;

			g_error_free(err);
			g_free(debug);

			gst_element_set_state(GST_ELEMENT(gstPipeline), GST_STATE_NULL);

		}break;

			case GST_MESSAGE_EOS:
				ofLogVerbose("ofGstUtils") << "gstHandleMessage(): 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)) {
						ofLogWarning("ofGstUtils") << "gstHandleMessage(): 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)) {
						ofLogWarning("ofGstUtils") << "gstHandleMessage(): unable to seek";
					}
				}break;

				default:
				break;
			}

		break;

		default:
			ofLogVerbose("ofGstUtils") << "gstHandleMessage(): unhandled message from " << GST_MESSAGE_SRC_NAME(msg);
		break;
	}
	return true;
}
Ejemplo n.º 16
0
static gboolean
bus_cb(GstBus *bus, GstMessage *message, XmrPlayer *player)
{
	XmrPlayerPrivate *priv;

	g_return_val_if_fail (player != NULL, FALSE);
	priv = player->priv;

	switch (GST_MESSAGE_TYPE (message))
	{
	case GST_MESSAGE_ERROR:
		{
			gchar *debug;
			GError *error;

			gst_message_parse_error(message, &error, &debug);

			g_signal_emit(player, signals[ERROR], 0, error);

			g_free(debug);
			g_error_free(error);
		}
		break;

	case GST_MESSAGE_EOS:
		g_signal_emit(player, signals[EOS], 0, FALSE);
		break;

	case GST_MESSAGE_BUFFERING:
	{
		gint progress;
		gst_message_parse_buffering(message, &progress);
		if (progress >= 100)
		{
			priv->buffering = FALSE;
			if (priv->playing)
			{
				xmr_debug("buffering done, setting pipeline back to PLAYING");
				gst_element_set_state (priv->playbin, GST_STATE_PLAYING);
			}
			else
			{
				xmr_debug("buffering done, leaving pipeline PAUSED");
			}
		}
		else if (priv->buffering == FALSE && priv->playing)
		{
			xmr_debug ("buffering - temporarily pausing playback");
			gst_element_set_state (priv->playbin, GST_STATE_PAUSED);
			priv->buffering = TRUE;
		}
		g_signal_emit(player, signals[BUFFERING], 0, progress);
		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(priv->playbin))
			{
				if (pending == GST_STATE_VOID_PENDING)
				{
					xmr_debug("playbin reached state %s", gst_element_state_get_name(newstate));
					state_change_finished(player, NULL);
				}
				g_signal_emit(player, signals[STATE_CHANGED], 0, oldstate, newstate);
			}
			break;
		}

	default:
		break;
	}

	return TRUE;
}
Ejemplo n.º 17
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));
}
gboolean
MediaPluginGStreamer010::processGSTEvents(GstBus     *bus,
					  GstMessage *message)
{
	if (!message) 
		return TRUE; // shield against GStreamer bug

	if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
	    GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
	{
		DEBUGMSG("Got GST message type: %s",
			GST_MESSAGE_TYPE_NAME (message));
	}
	else
	{
		// TODO: grok 'duration' message type
		DEBUGMSG("Got GST message type: %s",
			 GST_MESSAGE_TYPE_NAME (message));
	}

	switch (GST_MESSAGE_TYPE (message))
	{
		case GST_MESSAGE_BUFFERING:
		{
			// NEEDS GST 0.10.11+ and America discovered by C.Columbus
			gint percent = 0;
			gst_message_parse_buffering(message, &percent);
			DEBUGMSG("GST buffering: %d%%", percent);

			break;
		}
		case GST_MESSAGE_STATE_CHANGED: {
			GstState old_state;
			GstState new_state;
			GstState pending_state;
			gst_message_parse_state_changed(message,
							&old_state,
							&new_state,
							&pending_state);
			#ifdef LL_GST_REPORT_STATE_CHANGES
			// not generally very useful, and rather spammy.
			DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s",
				get_gst_state_name(old_state),
				get_gst_state_name(new_state),
				get_gst_state_name(pending_state));
			#endif // LL_GST_REPORT_STATE_CHANGES

			switch (new_state) 
			{
				case GST_STATE_VOID_PENDING:
					break;
				case GST_STATE_NULL:
					break;
				case GST_STATE_READY:
					setStatus(STATUS_LOADED);
					break;
				case GST_STATE_PAUSED:
					setStatus(STATUS_PAUSED);
					break;
				case GST_STATE_PLAYING:
					setStatus(STATUS_PLAYING);
					break;
			}
			break;
		}
		case GST_MESSAGE_ERROR:
		{
			GError *err = NULL;
			gchar *debug = NULL;
	
			gst_message_parse_error (message, &err, &debug);
			WARNMSG("GST error: %s", err?err->message:"(unknown)");
			if (err)
				g_error_free (err);
			g_free (debug);
	
			mCommand = COMMAND_STOP;
	
			setStatus(STATUS_ERROR);
	
			break;
		}
		case GST_MESSAGE_INFO:
		{
			GError *err = NULL;
			gchar *debug = NULL;
			
			gst_message_parse_info (message, &err, &debug);
			INFOMSG("GST info: %s", err?err->message:"(unknown)");
			if (err)
				g_error_free (err);
			g_free (debug);

			break;
		}
		case GST_MESSAGE_WARNING:
		{
			GError *err = NULL;
			gchar *debug = NULL;
	
			gst_message_parse_warning (message, &err, &debug);
			WARNMSG("GST warning: %s", err?err->message:"(unknown)");
			if (err)
				g_error_free (err);
			g_free (debug);
	
			break;
		}
		case GST_MESSAGE_TAG: 
		{
			GstTagList *new_tags;

			gst_message_parse_tag( message, &new_tags );

			gchar *title = NULL;

			if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) )
			{
				//WARMING("Title: %s", title);
				std::string newtitle(title);
				gst_tag_list_free(new_tags);

				if ( newtitle != mLastTitle && !newtitle.empty() )
				{
					LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
					message.setValue("name", newtitle );
					sendMessage( message );
					mLastTitle = newtitle;
				}
				g_free(title);
			}

			break;
		}
		case GST_MESSAGE_EOS:
		{
			/* end-of-stream */
			DEBUGMSG("GST end-of-stream.");
			if (mIsLooping)
			{
				DEBUGMSG("looping media...");
				double eos_pos_sec = 0.0F;
				bool got_eos_position = getTimePos(eos_pos_sec);
	
				if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC)
				{
					// if we know that the movie is really short, don't
					// loop it else it can easily become a time-hog
					// because of GStreamer spin-up overhead
					DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec);
					// inject a COMMAND_PAUSE
					mCommand = COMMAND_PAUSE;
				}
				else
				{
					#undef LLGST_LOOP_BY_SEEKING
					// loop with a stop-start instead of a seek, because it actually seems rather
					// faster than seeking on remote streams.
					#ifdef LLGST_LOOP_BY_SEEKING
					// first, try looping by an explicit rewind
					bool seeksuccess = seek(0.0);
					if (seeksuccess)
					{
						play(1.0);
					}
					else
					#endif // LLGST_LOOP_BY_SEEKING
					{  // use clumsy stop-start to loop
						DEBUGMSG("didn't loop by rewinding - stopping and starting instead...");
						stop();
						play(1.0);
					}
				}
			}
			else // not a looping media
			{
				// inject a COMMAND_STOP
				mCommand = COMMAND_STOP;
			}
		} break;

		default:
			/* unhandled message */
			break;
	}

	/* we want to be notified again the next time there is a message
	 * on the bus, so return true (false means we want to stop watching
	 * for messages on the bus and our callback should not be called again)
	 */
	return TRUE;
}
Ejemplo n.º 19
0
/* Caution: This function is executed on all sorts of strange threads, which should
 * not be excessively delayed, deadlocked, or used for anything GUI-related. Primarily,
 * we want to emit signals (which will result in queued slot calls) or do queued method
 * invocation to handle GUI updates. */
GstBusSyncReply GstVideoPlayerBackend::busHandler(GstBus *bus, GstMessage *msg)
{
    Q_UNUSED(bus);

    switch (GST_MESSAGE_TYPE(msg))
    {
    case GST_MESSAGE_BUFFERING:
        {
            gint percent = 0;
            gst_message_parse_buffering(msg, &percent);
            qDebug() << "gstreamer: buffering" << percent << "%";
            emit bufferingStatus(percent);
        }
        break;

    case GST_MESSAGE_STATE_CHANGED:
        {
            if (m_state == PermanentError)
                break;

            GstState oldState, newState;
            gst_message_parse_state_changed(msg, &oldState, &newState, 0);
            VideoState vpState = m_state;

            switch (newState)
            {
            case GST_STATE_VOID_PENDING:
            case GST_STATE_NULL:
                if (m_state == Error)
                    break;
            case GST_STATE_READY:
                vpState = Stopped;
                break;
            case GST_STATE_PAUSED:
                vpState = Paused;
                emit durationChanged(duration());
                break;
            case GST_STATE_PLAYING:
                vpState = Playing;
                emit durationChanged(duration());
                setSpeed(m_lastspeed);
                break;
            }

            if (vpState != m_state)
            {
                VideoState old = m_state;
                m_state = vpState;
                emit stateChanged(m_state, old);
            }
        }
        break;

    case GST_MESSAGE_DURATION:
        emit durationChanged(duration());
        break;

    case GST_MESSAGE_EOS:
        {
            qDebug("gstreamer: end of stream");
            VideoState old = m_state;
            m_state = Done;
            emit stateChanged(m_state, old);
            emit endOfStream();
        }
        break;

    case GST_MESSAGE_ERROR:
        {
            gchar *debug;
            GError *error;

            gst_message_parse_error(msg, &error, &debug);
            qDebug() << "gstreamer: Error:" << error->message;
            qDebug() << "gstreamer: Debug:" << debug;

            /* Set the error message, but don't move to the error state, because that will stop playback,
             * possibly incorrectly. */
            m_errorMessage = QString::fromLatin1(error->message);

            g_free(debug);
            g_error_free(error);
        }
        break;

    case GST_MESSAGE_WARNING:
        {
            gchar *debug;
            GError *error;

            gst_message_parse_warning(msg, &error, &debug);
            qDebug() << "gstreamer: Warning:" << error->message;
            qDebug() << "gstreamer:   Debug:" << debug;

            g_free(debug);
            g_error_free(error);
        }
        break;

    default:
        break;
    }

    return GST_BUS_PASS;
}
Ejemplo n.º 20
0
int BufferingMessage::percent() const
{
    gint p;
    gst_message_parse_buffering(object<GstMessage>(), &p);
    return p;
}
Ejemplo n.º 21
0
/* returns TRUE if there was an error or we caught a keyboard interrupt. */
static gboolean
event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
{
  GstBus *bus;
  GstMessage *message = NULL;
  gboolean res = FALSE;
  gboolean buffering = FALSE;

  bus = gst_element_get_bus (GST_ELEMENT (pipeline));

#ifndef DISABLE_FAULT_HANDLER
  g_timeout_add (50, (GSourceFunc) check_intr, pipeline);
#endif

  while (TRUE) {
    message = gst_bus_poll (bus, GST_MESSAGE_ANY, blocking ? -1 : 0);

    /* if the poll timed out, only when !blocking */
    if (message == NULL)
      goto exit;

    switch (GST_MESSAGE_TYPE (message)) {
      case GST_MESSAGE_NEW_CLOCK:
      {
        GstClock *clock;

        gst_message_parse_new_clock (message, &clock);

        g_print ("New clock: %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
        break;
      }
      case GST_MESSAGE_EOS:
        g_print ("Got EOS from element \"%s\".\n",
            GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))));
        goto exit;
      case GST_MESSAGE_TAG:
        if (tags) {
          GstTagList *tags;

          gst_message_parse_tag (message, &tags);
          g_print ("FOUND TAG      : found by element \"%s\".\n",
              GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))));
          gst_tag_list_foreach (tags, print_tag, NULL);
          gst_tag_list_free (tags);
        }
        break;
      case GST_MESSAGE_INFO:{
        GError *gerror;
        gchar *debug;
        gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));

        gst_message_parse_info (message, &gerror, &debug);
        if (debug) {
          g_print ("INFO:\n%s\n", debug);
        }
        g_error_free (gerror);
        g_free (debug);
        g_free (name);
        break;
      }
      case GST_MESSAGE_WARNING:{
        GError *gerror;
        gchar *debug;
        gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));

        /* dump graph on warning */
        GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
            GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.warning");

        gst_message_parse_warning (message, &gerror, &debug);
        g_print ("WARNING: from element %s: %s\n", name, gerror->message);
        if (debug) {
          g_print ("Additional debug info:\n%s\n", debug);
        }
        g_error_free (gerror);
        g_free (debug);
        g_free (name);
        break;
      }
      case GST_MESSAGE_ERROR:{
        GError *gerror;
        gchar *debug;

        /* dump graph on error */
        GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
            GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.error");

        gst_message_parse_error (message, &gerror, &debug);
        gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
        g_error_free (gerror);
        g_free (debug);
        /* we have an error */
        res = TRUE;
        goto exit;
      }
      case GST_MESSAGE_STATE_CHANGED:{
        GstState old, newX, pending;

        gst_message_parse_state_changed (message, &old, &newX, &pending);

        /* we only care about pipeline state change messages */
        if (GST_MESSAGE_SRC (message) != GST_OBJECT_CAST (pipeline))
          break;

        /* dump graph for pipeline state changes */
        {
          gchar *dump_name = g_strdup_printf ("gst-launch.%s_%s",
              gst_element_state_get_name (old),
              gst_element_state_get_name (newX));
          GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
              GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
          g_free (dump_name);
        }

        /* ignore when we are buffering since then we mess with the states
         * ourselves. */
        if (buffering) {
          fprintf (stderr,
              "Prerolled, waiting for buffering to finish...\n");
          break;
        }

        /* if we reached the final target state, exit */
        if (target_state == GST_STATE_PAUSED && newX == target_state)
          goto exit;

        /* else not an interesting message */
        break;
      }
      case GST_MESSAGE_BUFFERING:{
        gint percent;

        gst_message_parse_buffering (message, &percent);
        fprintf (stderr, "%s %d%%  \r", "buffering...", percent);

        /* no state management needed for live pipelines */
        if (is_live)
          break;

        if (percent == 100) {
          /* a 100% message means buffering is done */
          buffering = FALSE;
          /* if the desired state is playing, go back */
          if (target_state == GST_STATE_PLAYING) {
            fprintf (stderr,
                "Done buffering, setting pipeline to PLAYING ...\n");
            gst_element_set_state (pipeline, GST_STATE_PLAYING);
          } else
            goto exit;
        } else {
          /* buffering busy */
          if (buffering == FALSE && target_state == GST_STATE_PLAYING) {
            /* we were not buffering but PLAYING, PAUSE  the pipeline. */
            fprintf (stderr, "Buffering, setting pipeline to PAUSED ...\n");
            gst_element_set_state (pipeline, GST_STATE_PAUSED);
          }
          buffering = TRUE;
        }
        break;
      }
      case GST_MESSAGE_LATENCY:
      {
        fprintf (stderr, "Redistribute latency...\n");
        gst_bin_recalculate_latency (GST_BIN (pipeline));
        break;
      }
      case GST_MESSAGE_APPLICATION:{
        const GstStructure *s;

        s = gst_message_get_structure (message);

        if (gst_structure_has_name (s, "GstLaunchInterrupt")) {
          /* this application message is posted when we caught an interrupt and
           * we need to stop the pipeline. */
          fprintf (stderr, "Interrupt: Stopping pipeline ...\n");
          /* return TRUE when we caught an interrupt */
          res = TRUE;
          goto exit;
        }
      }
      default:
        /* just be quiet by default */
        break;
    }
    if (message)
      gst_message_unref (message);
  }
  g_assert_not_reached ();

exit:
  {
    if (message)
      gst_message_unref (message);
    gst_object_unref (bus);
    return res;
  }
}
Ejemplo n.º 22
0
//static
gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gpointer data)
{
#ifdef LL_GST_REPORT_STATE_CHANGES
	LL_DEBUGS("MediaCallback") << "Got GST message type: " << GST_MESSAGE_TYPE_NAME (message) << LL_ENDL;
#endif

	LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data;

	switch (GST_MESSAGE_TYPE (message)) 
	{
		case GST_MESSAGE_BUFFERING: 
		{
			gint percent = 0;
			gst_message_parse_buffering(message, &percent);
#ifdef LL_GST_REPORT_STATE_CHANGES
			LL_DEBUGS("MediaBuffering") << "GST buffering: " << percent << "%%" << LL_ENDL;
#endif
			LLMediaEvent event( impl, percent );
			impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event );
		}
			break;
		case GST_MESSAGE_STATE_CHANGED: 
		{
			GstState old_state;
			GstState new_state;
			GstState pending_state;
			gst_message_parse_state_changed(message,
						&old_state,
						&new_state,
						&pending_state);
#ifdef LL_GST_REPORT_STATE_CHANGES
		// not generally very useful, and rather spammy.
		LL_DEBUGS("MediaState") << "GST state change (old,<new>,pending): "<< get_gst_state_name(old_state) << ",<" << get_gst_state_name(new_state) << ">," << get_gst_state_name(pending_state) << LL_ENDL;
#endif // LL_GST_REPORT_STATE_CHANGES

			switch (new_state) 
			{
			case GST_STATE_VOID_PENDING:
				break;
			case GST_STATE_NULL:
#ifdef LL_GST_REPORT_STATE_CHANGES
				LL_DEBUGS("MediaImpl") << "State changed to NULL" << LL_ENDL;
#endif
				if (impl->getState() == GST_STATE_PLAYING) 
				{ 
					// Stream was probably dropped, trying to restart
				    impl->play();
#ifdef LL_GST_REPORT_STATE_CHANGES
				    LL_DEBUGS("MediaImpl") << "Trying to restart." << LL_ENDL;
#endif
				}
				break;
			case GST_STATE_READY:
				break;
			case GST_STATE_PAUSED:
				break;
			case GST_STATE_PLAYING:
				//impl->mLastTitle = "";

				LLMediaEvent event( impl, 100 );
				impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event );
				// emit an event to say that a media source was loaded
				LLMediaEvent event2( impl );
				impl->getEventEmitter().update( &LLMediaObserver::onMediaLoaded, event2 );
				break;
			}
			break;
		}
		case GST_MESSAGE_ERROR: 
		{
			GError *err = NULL;
			gchar *debug = NULL;

			gst_message_parse_error (message, &err, &debug);
			LL_WARNS("MediaImpl") << "GST Error: " << err->message << LL_ENDL;
			g_error_free (err);
			g_free (debug);

			impl->addCommand(LLMediaBase::COMMAND_STOP);
			//impl->addCommand(LLMediaBase::COMMAND_START);

			break;
		}
		case GST_MESSAGE_INFO: 
		{
			GError *err = NULL;
			gchar *debug = NULL;
			
			gst_message_parse_info (message, &err, &debug);
			LL_INFOS("MediaImpl") << "GST info: " << err->message
														<< LL_ENDL;
			g_error_free (err);
			g_free (debug);
			break;
		}
		case GST_MESSAGE_WARNING: 
		{
			GError *err = NULL;
			gchar *debug = NULL;

			gst_message_parse_warning (message, &err, &debug);
			LL_WARNS("MediaImpl") << "GST warning: " <<  err->message
		    << LL_ENDL;
			g_error_free (err);
			g_free (debug);

			break;
		}
		case GST_MESSAGE_TAG: 
		{
			GstTagList *new_tags;

			gst_message_parse_tag( message, &new_tags );

			gchar *title;

			if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) )
			{
				LL_INFOS("MediaInfo") << "Title: " << title << LL_ENDL;
				std::string newtitle(title);
				gst_tag_list_free(new_tags);

				if ( newtitle != impl->mLastTitle && newtitle != "" )
				{
					impl->mLastTitle = newtitle;
					LLMediaEvent event( impl, impl->mLastTitle );
					impl->getEventEmitter().update( &LLMediaObserver::onMediaTitleChange, event );
				}

				g_free(title);
			}

			break;
		}
		case GST_MESSAGE_EOS:
		{
			/* end-of-stream */
			LL_DEBUGS("MediaImpl") << "GST end-of-stream." << LL_ENDL;
			if (impl->isLooping())
			{
				LL_DEBUGS("MediaImpl") << "looping media..." << LL_ENDL;
				impl->stop();
				impl->play();
			}
			else
			{
				// inject a COMMAND_STOP
				impl->addCommand(LLMediaBase::COMMAND_STOP);
			}
			break;
		}
		default:
			/* unhandled message */
			break;
	}
	/* we want to be notified again the next time there is a message
	 * on the bus, so return true (false means we want to stop watching
	 * for messages on the bus and our callback should not be called again)
	 */
	return TRUE;
}
static gboolean
handle_message (InsanityGstPipelineTest * ptest, GstMessage * message)
{
  gboolean ret = FALSE, done = FALSE;

  /* Allow the test code to handle the message instead */
  g_signal_emit (ptest, bus_message_signal, 0, message, &ret);
  if (!ret)
    return FALSE;

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR:{
      GError *error = NULL;
      char *debug = NULL;

      gst_message_parse_error (message, &error, &debug);
      send_error (ptest, error, debug);
      insanity_test_printf (INSANITY_TEST (ptest), "Error (%s, %s), quitting\n",
          error->message, debug);
      g_error_free (error);
      g_free (debug);
      done = TRUE;
      break;
    }
    case GST_MESSAGE_STATE_CHANGED:
      if (GST_MESSAGE_SRC (message) == GST_OBJECT (ptest->priv->pipeline)) {
        GstState oldstate, newstate, pending;
        gst_message_parse_state_changed (message, &oldstate, &newstate,
            &pending);

        if (newstate >= GST_STATE_PAUSED) {
          gint i;

          for (i = 0; i < G_N_ELEMENTS (duration_query_formats); i++)
            insanity_gst_pipeline_test_query_duration (ptest,
                duration_query_formats[i], NULL);
        }

        if (newstate == ptest->priv->initial_state
            && pending == GST_STATE_VOID_PENDING
            && !ptest->priv->reached_initial_state) {
          gboolean ret = TRUE;

          ptest->priv->reached_initial_state = TRUE;
          insanity_test_validate_checklist_item (INSANITY_TEST (ptest),
              "reached-initial-state", TRUE, NULL);

          /* Tell the test we reached our initial state */
          g_signal_emit (ptest, reached_initial_state_signal, 0, &ret);
          if (!ret) {
            insanity_test_printf (INSANITY_TEST (ptest),
                "Reached initial state, and asked to quit, quitting\n");
            done = TRUE;
          }
        }
      }
      break;
    case GST_MESSAGE_TAG:{
      GstTagList *tags;
      gst_message_parse_tag (message, &tags);
      gst_tag_list_foreach (tags, &send_tag, (gpointer) ptest);
      gst_tag_list_unref (tags);
      break;
    }
    case GST_MESSAGE_DURATION_CHANGED:{
      gint i;

      for (i = 0; i < G_N_ELEMENTS (duration_query_formats); i++)
        insanity_gst_pipeline_test_query_duration (ptest,
            duration_query_formats[i], NULL);
      break;
    }
    case GST_MESSAGE_EOS:
      if (GST_MESSAGE_SRC (message) == GST_OBJECT (ptest->priv->pipeline)) {
        /* Warning from the original Python source:
           # it's not 100% sure we want to stop here, because of the
           # race between the final state-change message and the eos message
           # arriving on the bus.
         */
        if (ptest->priv->reached_initial_state) {
          insanity_test_printf (INSANITY_TEST (ptest),
              "Got EOS from pipeline, and we reached initial state, quitting\n");
          done = TRUE;
        } else {
          /* If we've not seen the state change to initial state yet, we give
             an extra 3 seconds for it to complete */
          insanity_test_printf (INSANITY_TEST (ptest),
              "Got EOS from pipeline, and we did not reach initial state, delaying quit\n");
          ptest->priv->wait_timeout_id =
              g_timeout_add (3000, (GSourceFunc) & waiting_for_state_change,
              ptest);
        }
      }
      break;
    case GST_MESSAGE_BUFFERING:{
      gint percent;

      gst_message_parse_buffering (message, &percent);

      /* no state management needed for live pipelines */
      if (ptest->priv->is_live || !ptest->priv->enable_buffering)
        break;

      if (percent == 100) {
        /* a 100% message means buffering is done */
        ptest->priv->buffering = FALSE;
        /* if the desired state is playing, go back */
        if (ptest->priv->initial_state == GST_STATE_PLAYING) {
          gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline),
              GST_STATE_PLAYING);
        }
      } else {
        /* buffering busy */
        if (ptest->priv->buffering == FALSE
            && ptest->priv->initial_state == GST_STATE_PLAYING) {
          /* we were not buffering but PLAYING, PAUSE  the pipeline. */
          gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline),
              GST_STATE_PAUSED);
        }
        ptest->priv->buffering = TRUE;
      }
      break;
    case GST_MESSAGE_CLOCK_LOST:
      gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline),
          GST_STATE_PAUSED);
      gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline),
          GST_STATE_PLAYING);
      break;
    }
    default:
      break;
  }

  return done;
}
void __mm_player_streaming_buffering(mm_player_streaming_t* streamer, GstMessage *buffering_msg)
{
	GstBufferingMode mode = GST_BUFFERING_STREAM;
	gint byte_in_rate = 0;
	gint byte_out_rate = 0;
	gint64 buffering_left = -1;
	gdouble buffering_time = DEFAULT_BUFFERING_TIME;
	gdouble low_percent = 0.0;
	gdouble high_percent = 0.0;
	guint high_percent_byte = 0;
	gint buffer_percent = 0;
	guint buffer_criteria = 0;

	return_if_fail ( streamer );
	return_if_fail ( buffering_msg );
	return_if_fail ( GST_IS_MESSAGE ( buffering_msg ) );
	return_if_fail ( GST_MESSAGE_TYPE ( buffering_msg ) == GST_MESSAGE_BUFFERING );

	/* update when buffering has started. */
	if ( !streamer->is_buffering )
	{
		debug_log ( "buffering has started.\n" );

		streamer->is_buffering = TRUE;
		streamer->buffering_percent = -1;
		streamer->need_update = TRUE;
	}

	/* update buffer percent */
	gst_message_parse_buffering ( buffering_msg, &buffer_percent );

	if ( streamer->buffering_percent < buffer_percent )
	{
		debug_log ( "buffering %d%%....\n", buffer_percent );
		streamer->buffering_percent = buffer_percent;
	}

	if ( streamer->buffering_percent == MAX_BUFFER_PERCENT )
	{
		debug_log ( "buffering had done.\n" );
		streamer->is_buffering = FALSE;
	}

	if (!streamer->need_update)
	{
		debug_log ( "don't need to update buffering stats during buffering.\n" );
		return;
	}

        /* Note : Parse the buffering message to get the in/out throughput.
         *     avg_in is the network throughput and avg_out is the consumed throughtput by the linkded element.
         */
	gst_message_parse_buffering_stats ( buffering_msg, &mode, &byte_in_rate, &byte_out_rate, &buffering_left );

	if (streamer->buffer_max_bitrate > 0)
	{
		buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate);
		byte_out_rate = GET_BYTE_FROM_BIT(streamer->buffer_max_bitrate /3);
	}
	else if (streamer->buffer_avg_bitrate > 0)
	{
		buffer_criteria = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate * 3);
		byte_out_rate = GET_BYTE_FROM_BIT(streamer->buffer_avg_bitrate);
	}

	debug_log ( "in rate is %d, out rate is %d (bytes/sec).\n", byte_in_rate, byte_out_rate );

	if ( byte_in_rate > 0  &&  byte_out_rate > 0)
		buffering_time =  byte_out_rate / byte_in_rate;
	else if (byte_in_rate <= 0 && byte_out_rate > 0)
		buffering_time = MAX_BUFFERING_TIME;
	else
		buffering_time = DEFAULT_BUFFERING_TIME;

	streaming_set_buffering_time(streamer, buffering_time);

	/* calculate buffer low/high percent */
	low_percent = DEFAULT_BUFFER_LOW_PERCENT;

	if ( buffer_criteria > 0 )
	{
		high_percent_byte = buffer_criteria * streamer->buffering_time;
		high_percent = ( (gdouble)high_percent_byte * 100.0 )  / (gdouble)streamer->buffer_size;
	}
	else
	{
		high_percent_byte = streamer->buffer_high_percent * streamer->buffer_size / 100;
		high_percent= streamer->buffer_high_percent;
	}

	if ( streamer->buffer_size < high_percent_byte )
	{
		debug_log ( "buffer size[%d bytes] is smaller than high threshold[%d bytes]. update it. \n",
			streamer->buffer_size, high_percent_byte );

		streaming_set_buffer_size(streamer, high_percent_byte * 1.1);
	}

	streaming_set_buffer_percent(streamer, low_percent, high_percent);

	streamer->need_update = FALSE;

	return;
}