P_INVOKE gboolean bp_can_seek (BansheePlayer *player) { GstQuery *query; gboolean can_seek = TRUE; g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE); if (player->playbin == NULL) { return FALSE; } query = gst_query_new_seeking (GST_FORMAT_TIME); if (!gst_element_query (player->playbin, query)) { // This will probably fail, 100% of the time, because it's apparently // very unimplemented in GStreamer... when it's fixed // we will return FALSE here, and show the warning // g_warning ("Could not query pipeline for seek ability"); return bp_get_duration (player) > 0; } gst_query_parse_seeking (query, NULL, &can_seek, NULL, NULL); gst_query_unref (query); return can_seek && bp_get_duration (player) > 0; }
static gboolean play_do_seek (GstElement * pipeline, gint64 pos, gdouble rate, GstPlayTrickMode mode) { GstSeekFlags seek_flags; GstQuery *query; GstEvent *seek; gboolean seekable = FALSE; query = gst_query_new_seeking (GST_FORMAT_TIME); if (!gst_element_query (pipeline, query)) { gst_query_unref (query); return FALSE; } gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL); gst_query_unref (query); if (!seekable) return FALSE; seek_flags = GST_SEEK_FLAG_FLUSH; switch (mode) { case GST_PLAY_TRICK_MODE_DEFAULT: seek_flags |= GST_SEEK_FLAG_TRICKMODE; break; case GST_PLAY_TRICK_MODE_DEFAULT_NO_AUDIO: seek_flags |= GST_SEEK_FLAG_TRICKMODE | GST_SEEK_FLAG_TRICKMODE_NO_AUDIO; break; case GST_PLAY_TRICK_MODE_KEY_UNITS: seek_flags |= GST_SEEK_FLAG_TRICKMODE_KEY_UNITS; break; case GST_PLAY_TRICK_MODE_KEY_UNITS_NO_AUDIO: seek_flags |= GST_SEEK_FLAG_TRICKMODE_KEY_UNITS | GST_SEEK_FLAG_TRICKMODE_NO_AUDIO; break; case GST_PLAY_TRICK_MODE_NONE: default: break; } if (rate >= 0) seek = gst_event_new_seek (rate, GST_FORMAT_TIME, seek_flags | GST_SEEK_FLAG_ACCURATE, /* start */ GST_SEEK_TYPE_SET, pos, /* stop */ GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE); else seek = gst_event_new_seek (rate, GST_FORMAT_TIME, seek_flags | GST_SEEK_FLAG_ACCURATE, /* start */ GST_SEEK_TYPE_SET, 0, /* stop */ GST_SEEK_TYPE_SET, pos); if (!gst_element_send_event (pipeline, seek)) return FALSE; cur_rate = rate; trick_mode = mode; return TRUE; }
static void handle_message (CustomData *data, GstMessage *msg) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR: gst_message_parse_error (msg, &err, &debug_info); g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error (&err); g_free (debug_info); data->terminate = TRUE; break; case GST_MESSAGE_EOS: g_print ("End-Of-Stream reached.\n"); data->terminate = TRUE; break; case GST_MESSAGE_DURATION: /* The duration has changed, mark the current one as invalid */ data->duration = GST_CLOCK_TIME_NONE; break; case GST_MESSAGE_STATE_CHANGED: { GstState old_state, new_state, pending_state; gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state); if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->playbin2)) { g_print ("Pipeline state changed from %s to %s:\n", gst_element_state_get_name (old_state), gst_element_state_get_name (new_state)); /* Remember whether we are in the PLAYING state or not */ data->playing = (new_state == GST_STATE_PLAYING); if (data->playing) { /* We just moved to PLAYING. Check if seeking is possible */ GstQuery *query; gint64 start, end; query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (data->playbin2, query)) { gst_query_parse_seeking (query, NULL, &data->seek_enabled, &start, &end); if (data->seek_enabled) { g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (start), GST_TIME_ARGS (end)); } else { g_print ("Seeking is DISABLED for this stream.\n"); } } else { g_printerr ("Seeking query failed."); } gst_query_unref (query); } } } break; default: /* We should not reach here */ g_printerr ("Unexpected message received.\n"); break; } gst_message_unref (msg); }
/* generate queries to adaptive demux */ static gboolean testQueryCheckDataReceived (GstAdaptiveDemuxTestEngine * engine, GstAdaptiveDemuxTestOutputStream * stream, GstBuffer * buffer, gpointer user_data) { GList *pads; GstPad *pad; GstQuery *query; gboolean ret; gint64 duration; gboolean seekable; gint64 segment_start; gint64 segment_end; gchar *uri; gchar *redirect_uri; gboolean redirect_permanent; pads = GST_ELEMENT_PADS (stream->appsink); /* AppSink should have only 1 pad */ fail_unless (pads != NULL); fail_unless (g_list_length (pads) == 1); pad = GST_PAD (pads->data); query = gst_query_new_duration (GST_FORMAT_TIME); ret = gst_pad_peer_query (pad, query); fail_unless (ret == TRUE); gst_query_parse_duration (query, NULL, &duration); fail_unless (duration == 135743 * GST_MSECOND); gst_query_unref (query); query = gst_query_new_seeking (GST_FORMAT_TIME); ret = gst_pad_peer_query (pad, query); fail_unless (ret == TRUE); gst_query_parse_seeking (query, NULL, &seekable, &segment_start, &segment_end); fail_unless (seekable == TRUE); fail_unless (segment_start == 0); fail_unless (segment_end == duration); gst_query_unref (query); query = gst_query_new_uri (); ret = gst_pad_peer_query (pad, query); fail_unless (ret == TRUE); gst_query_parse_uri (query, &uri); gst_query_parse_uri_redirection (query, &redirect_uri); gst_query_parse_uri_redirection_permanent (query, &redirect_permanent); fail_unless (strcmp (uri, "http://unit.test/test.mpd") == 0); /* adaptive demux does not reply with redirect information */ fail_unless (redirect_uri == NULL); fail_unless (redirect_permanent == FALSE); g_free (uri); g_free (redirect_uri); gst_query_unref (query); return gst_adaptive_demux_test_check_received_data (engine, stream, buffer, user_data); }
static VALUE seeking_initialize(VALUE self, VALUE format) { GstQuery *query; query = gst_query_new_seeking(RVAL2GST_FORMAT(format)); G_INITIALIZE(self, query); return Qnil; }
static void gst_discoverer_init (GstDiscoverer * dc) { GstElement *tmp; GstFormat format = GST_FORMAT_TIME; dc->priv = G_TYPE_INSTANCE_GET_PRIVATE (dc, GST_TYPE_DISCOVERER, GstDiscovererPrivate); dc->priv->timeout = DEFAULT_PROP_TIMEOUT; dc->priv->async = FALSE; dc->priv->lock = g_mutex_new (); GST_LOG ("Creating pipeline"); dc->priv->pipeline = (GstBin *) gst_pipeline_new ("Discoverer"); GST_LOG_OBJECT (dc, "Creating uridecodebin"); dc->priv->uridecodebin = gst_element_factory_make ("uridecodebin", "discoverer-uri"); if (G_UNLIKELY (dc->priv->uridecodebin == NULL)) { GST_ERROR ("Can't create uridecodebin"); return; } GST_LOG_OBJECT (dc, "Adding uridecodebin to pipeline"); gst_bin_add (dc->priv->pipeline, dc->priv->uridecodebin); dc->priv->pad_added_id = g_signal_connect_object (dc->priv->uridecodebin, "pad-added", G_CALLBACK (uridecodebin_pad_added_cb), dc, 0); dc->priv->pad_remove_id = g_signal_connect_object (dc->priv->uridecodebin, "pad-removed", G_CALLBACK (uridecodebin_pad_removed_cb), dc, 0); GST_LOG_OBJECT (dc, "Getting pipeline bus"); dc->priv->bus = gst_pipeline_get_bus ((GstPipeline *) dc->priv->pipeline); dc->priv->bus_cb_id = g_signal_connect_object (dc->priv->bus, "message", G_CALLBACK (discoverer_bus_cb), dc, 0); GST_DEBUG_OBJECT (dc, "Done initializing Discoverer"); /* This is ugly. We get the GType of decodebin2 so we can quickly detect * when a decodebin2 is added to uridecodebin so we can set the * post-stream-topology setting to TRUE */ dc->priv->element_added_id = g_signal_connect_object (dc->priv->uridecodebin, "element-added", G_CALLBACK (uridecodebin_element_added_cb), dc, 0); tmp = gst_element_factory_make ("decodebin2", NULL); dc->priv->decodebin2_type = G_OBJECT_TYPE (tmp); gst_object_unref (tmp); /* create queries */ dc->priv->seeking_query = gst_query_new_seeking (format); }
void test_nonseeking() { GstElement *src; GstQuery *seeking_query; gint pipe_fd[2]; gchar data[4096]; gboolean seekable; xmlfile = "fdsrc_test_nonseeking"; std_log(LOG_FILENAME_LINE, "Test Started test_nonseeking"); fail_if (pipe (pipe_fd) < 0); src = setup_fdsrc (); g_object_set (G_OBJECT (src), "num-buffers", 3, NULL); g_object_set (G_OBJECT (src), "fd", pipe_fd[0], NULL); fail_unless (gst_element_set_state (src, GST_STATE_PAUSED) == GST_STATE_CHANGE_SUCCESS, "could not set to paused"); memset (data, 0, 4096); fail_if (write (pipe_fd[1], data, 256) < 0); /* Test that fdsrc is non-seekable with a pipe */ fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES)) != NULL); fail_unless (gst_element_query (src, seeking_query) == TRUE); gst_query_parse_seeking (seeking_query, NULL, &seekable, NULL, NULL); fail_unless (seekable == FALSE); gst_query_unref (seeking_query); fail_unless (gst_element_set_state (src, GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null"); /* cleanup */ cleanup_fdsrc (src); close (pipe_fd[0]); close (pipe_fd[1]); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
void test_seeking() { GstElement *src; gint in_fd; GstQuery *seeking_query; gboolean seekable; xmlfile = "fdsrc_test_seeking"; std_log(LOG_FILENAME_LINE, "Test Started test_seeking"); #ifndef TESTFILE #error TESTFILE not defined #endif in_fd = errno ; fail_if ((in_fd = open ("c:\\data\\gstreamer\\warning.wav", O_RDONLY)) < 0); src = setup_fdsrc (); g_object_set (G_OBJECT (src), "fd", in_fd, NULL); fail_unless (gst_element_set_state (src, GST_STATE_PAUSED) == GST_STATE_CHANGE_SUCCESS, "could not set to paused"); /* Test that fdsrc is seekable with a file fd */ fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES)) != NULL); fail_unless (gst_element_query (src, seeking_query) == TRUE); gst_query_parse_seeking (seeking_query, NULL, &seekable, NULL, NULL); fail_unless (seekable == TRUE); gst_query_unref (seeking_query); fail_unless (gst_element_set_state (src, GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null"); /* cleanup */ cleanup_fdsrc (src); close (in_fd); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static void pragha_backend_evaluate_if_can_seek(PraghaBackend *backend) { GstQuery *query; PraghaBackendPrivate *priv = backend->priv; query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (priv->pipeline, query)) gst_query_parse_seeking (query, NULL, &priv->can_seek, NULL, NULL); gst_query_unref (query); }
bool SourceObject::IsSeekable () const { std::shared_ptr<GstQuery> query (gst_query_new_seeking (GST_FORMAT_TIME), gst_query_unref); if (!gst_element_query (GST_ELEMENT (Dec_), query.get ())) return false; gboolean seekable = false; GstFormat format; gint64 start = 0, stop = 0; gst_query_parse_seeking (query.get (), &format, &seekable, &start, &stop); return seekable; }
static gboolean event_forward_func (GstPad * pad, EventData * evdata) { gboolean ret = TRUE; GstPad *peer = gst_pad_get_peer (pad); GstAggregatorPadPrivate *padpriv = GST_AGGREGATOR_PAD (pad)->priv; if (peer) { ret = gst_pad_send_event (peer, gst_event_ref (evdata->event)); GST_DEBUG_OBJECT (pad, "return of event push is %d", ret); gst_object_unref (peer); } if (ret == FALSE) { if (GST_EVENT_TYPE (evdata->event) == GST_EVENT_SEEK) GST_ERROR_OBJECT (pad, "Event %" GST_PTR_FORMAT " failed", evdata->event); if (GST_EVENT_TYPE (evdata->event) == GST_EVENT_SEEK) { GstQuery *seeking = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_pad_query (peer, seeking)) { gboolean seekable; gst_query_parse_seeking (seeking, NULL, &seekable, NULL, NULL); if (seekable == FALSE) { GST_INFO_OBJECT (pad, "Source not seekable, We failed but it does not matter!"); ret = TRUE; } } else { GST_ERROR_OBJECT (pad, "Query seeking FAILED"); } } if (evdata->flush) { padpriv->pending_flush_start = FALSE; padpriv->pending_flush_stop = FALSE; } } else { evdata->one_actually_seeked = TRUE; } evdata->result &= ret; /* Always send to all pads */ return FALSE; }
static void relative_seek (GstPlay * play, gdouble percent) { GstQuery *query; gboolean seekable = FALSE; gint64 dur = -1, pos = -1, step; g_return_if_fail (percent >= -1.0 && percent <= 1.0); if (!gst_element_query_position (play->playbin, GST_FORMAT_TIME, &pos)) goto seek_failed; query = gst_query_new_seeking (GST_FORMAT_TIME); if (!gst_element_query (play->playbin, query)) { gst_query_unref (query); goto seek_failed; } gst_query_parse_seeking (query, NULL, &seekable, NULL, &dur); gst_query_unref (query); if (!seekable || dur <= 0) goto seek_failed; step = dur * percent; if (ABS (step) < GST_SECOND) step = (percent < 0) ? -GST_SECOND : GST_SECOND; pos = pos + step; if (pos > dur) { if (!play_next (play)) { g_print ("\n%s\n", _("Reached end of play list.")); g_main_loop_quit (play->loop); } } else { if (pos < 0) pos = 0; play_do_seek (play, pos, play->rate, play->trick_mode); } return; seek_failed: { g_print ("\nCould not seek.\n"); } }
static void relative_seek (GstPlay * play, gdouble percent) { GstQuery *query; gboolean seekable = FALSE; gint64 dur = -1, pos = -1; g_return_if_fail (percent >= -1.0 && percent <= 1.0); if (!gst_element_query_position (play->playbin, GST_FORMAT_TIME, &pos)) goto seek_failed; query = gst_query_new_seeking (GST_FORMAT_TIME); if (!gst_element_query (play->playbin, query)) { gst_query_unref (query); goto seek_failed; } gst_query_parse_seeking (query, NULL, &seekable, NULL, &dur); gst_query_unref (query); if (!seekable || dur <= 0) goto seek_failed; pos = pos + dur * percent; if (pos > dur) { if (!play_next (play)) { g_print ("\nReached end of play list.\n"); g_main_loop_quit (play->loop); } } else { if (pos < 0) pos = 0; if (!gst_element_seek_simple (play->playbin, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, pos)) goto seek_failed; } return; seek_failed: { g_print ("\nCould not seek.\n"); } }
bool GstVideoPlayerBackend::isSeekable() const { if (!m_pipeline) return false; GstQuery *query = gst_query_new_seeking(GST_FORMAT_TIME); gboolean re = gst_element_query(m_pipeline, query); if (re) { gboolean seekable; gst_query_parse_seeking(query, 0, &seekable, 0, 0); re = seekable; } else qDebug() << "gstreamer: Failed to query seeking properties of the stream"; gst_query_unref(query); return re; }
static gboolean impl_seekable (RBPlayer *player) { RBPlayerGst *mp = RB_PLAYER_GST (player); gboolean can_seek = TRUE; GstQuery *query; if (mp->priv->playbin == NULL) return FALSE; query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (mp->priv->playbin, query)) { gst_query_parse_seeking (query, NULL, &can_seek, NULL, NULL); } else { gst_query_unref (query); query = gst_query_new_duration (GST_FORMAT_TIME); can_seek = gst_element_query (mp->priv->playbin, query); } gst_query_unref (query); return can_seek; }
// 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; }
static void handle_message(CustomData *data, GstMessage *msg) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &debug_info); g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME(msg->src), err->message); g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error(&err); g_free(debug_info); data->terminate = TRUE; break; case GST_MESSAGE_EOS: g_print("\nEnd-Of-Stream reached.\n"); data->terminate = TRUE; break; case GST_MESSAGE_DURATION_CHANGED: fprintf(stderr, "LaDurée a changé !! Ça m'énerve !!\n"); data->duration = GST_CLOCK_TIME_NONE; break; case GST_MESSAGE_STATE_CHANGED: { GstState old_state, new_state, pending_state; if (GST_MESSAGE_SRC(msg) == GST_OBJECT(data->playbin)) { gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state); g_print("Pipeline state changed from %s to %s:\n", gst_element_state_get_name(old_state), gst_element_state_get_name(new_state)); data->playing = (new_state == GST_STATE_PLAYING); if (data->playing) { GstQuery *query; gint64 start, end; query = gst_query_new_seeking(GST_FORMAT_TIME); if (gst_element_query(data->playbin, query)) { gst_query_parse_seeking(query, NULL, &data->seek_enabled, &start, &end); if (data->seek_enabled) { g_print("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n", GST_TIME_ARGS(start), GST_TIME_ARGS(end)); } else { g_print("Seeking is DISABLED for this stream.\n"); } } else { g_printerr("Seeking query failed."); } gst_query_unref(query); } } } break; default: g_printerr("Unexpected message received.\n"); break; } gst_message_unref(msg); }
void MediaImpl::_checkMessages() { if (_bus != NULL) { // Get message. GstMessage *msg = gst_bus_timed_pop_filtered( _bus, 0, (GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_ASYNC_DONE)); if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { // Error //////////////////////////////////////////////// case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &debug_info); g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error(&err); g_free(debug_info); if (!_isSharedMemorySource) { _terminate = true; } else { _attached = false; gst_element_set_state (_pipeline, GST_STATE_PAUSED); gst_element_set_state (_pipeline, GST_STATE_NULL); gst_element_set_state (_pipeline, GST_STATE_READY); } // _finish(); break; // End-of-stream //////////////////////////////////////// case GST_MESSAGE_EOS: // Automatically loop back. g_print("End-Of-Stream reached.\n"); resetMovie(); // _terminate = true; // _finish(); break; // Pipeline has prerolled/ready to play /////////////// case GST_MESSAGE_ASYNC_DONE: if (!_isMovieReady()) { // Check if seeking is allowed. gint64 start, end; GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (_pipeline, query)) { gst_query_parse_seeking (query, NULL, (gboolean*)&_seekEnabled, &start, &end); if (_seekEnabled) { g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (start), GST_TIME_ARGS (end)); } else { g_print ("Seeking is DISABLED for this stream.\n"); } } else { g_printerr ("Seeking query failed."); } gst_query_unref (query); // Movie is ready! _setMovieReady(true); } break; case GST_MESSAGE_STATE_CHANGED: // We are only interested in state-changed messages from the pipeline. if (GST_MESSAGE_SRC (msg) == GST_OBJECT (_pipeline)) { GstState oldState, newState, pendingState; gst_message_parse_state_changed(msg, &oldState, &newState, &pendingState); g_print("Pipeline state for movie %s changed from %s to %s:\n", _uri.toUtf8().constData(), gst_element_state_get_name(oldState), gst_element_state_get_name(newState)); } break; default: // We should not reach here. g_printerr("Unexpected message received.\n"); break; } gst_message_unref(msg); } } }
SeekingQueryPtr SeekingQuery::create(Format format) { return SeekingQueryPtr::wrap(gst_query_new_seeking(static_cast<GstFormat>(format)), false); }
void MediaImpl::_postRun() { // Parse message. if (_bus != NULL) { GstMessage *msg = gst_bus_timed_pop_filtered( _bus, 0, (GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS)); if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &debug_info); g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error(&err); g_free(debug_info); _terminate = true; // _finish(); break; case GST_MESSAGE_EOS: g_print("End-Of-Stream reached.\n"); // _terminate = true; // _finish(); break; case GST_MESSAGE_STATE_CHANGED: // We are only interested in state-changed messages from the pipeline. if (GST_MESSAGE_SRC (msg) == GST_OBJECT (_pipeline)) { GstState oldState, newState, pendingState; gst_message_parse_state_changed(msg, &oldState, &newState, &pendingState); g_print("Pipeline state for movie %s changed from %s to %s:\n", _currentMovie.toUtf8().constData(), gst_element_state_get_name(oldState), gst_element_state_get_name(newState)); // if (oldState == GST_STATE_PAUSED && newState == GST_STATE_READY) // gst_adapter_clear(_audioBufferAdapter); if (newState == GST_STATE_PLAYING) { // Check if seeking is allowed. gint64 start, end; GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (_pipeline, query)) { gst_query_parse_seeking (query, NULL, (gboolean*)&_seekEnabled, &start, &end); if (_seekEnabled) { g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (start), GST_TIME_ARGS (end)); } else { g_print ("Seeking is DISABLED for this stream.\n"); } } else { g_printerr ("Seeking query failed."); } gst_query_unref (query); } } break; default: // We should not reach here. g_printerr("Unexpected message received.\n"); break; } gst_message_unref(msg); } } }
void VideoImpl::_checkMessages() { if (_bus != NULL) { // Get message. GstMessage *msg = gst_bus_timed_pop_filtered( _bus, 0, (GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_ASYNC_DONE)); if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { // Error //////////////////////////////////////////////// case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &debug_info); qWarning() << "Error received from element " << GST_OBJECT_NAME (msg->src) << ": " << err->message << endl; qDebug() << "Debugging information: " << (debug_info ? debug_info : "none") << "." << endl; g_clear_error(&err); g_free(debug_info); if (!isLive()) { _terminate = true; } else { gst_element_set_state (_pipeline, GST_STATE_PAUSED); gst_element_set_state (_pipeline, GST_STATE_NULL); gst_element_set_state (_pipeline, GST_STATE_READY); } // _finish(); break; // End-of-stream //////////////////////////////////////// case GST_MESSAGE_EOS: // Automatically loop back. resetMovie(); // _terminate = true; // _finish(); break; // Pipeline has prerolled/ready to play /////////////// case GST_MESSAGE_ASYNC_DONE: if (!_isMovieReady()) { // Check if seeking is allowed. gint64 start, end; GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (_pipeline, query)) { gst_query_parse_seeking (query, NULL, (gboolean*)&_seekEnabled, &start, &end); if (_seekEnabled) { #ifdef VIDEO_IMPL_VERBOSE qDebug() << "Seeking is ENABLED from " << start << " to " << end << "." << endl; #endif } else { qDebug() << "Seeking is DISABLED for this stream." << endl; } } else { qWarning() << "Seeking query failed." << endl; } gst_query_unref (query); // Movie is ready! #ifdef VIDEO_IMPL_VERBOSE qDebug() << "Preroll done: movie is ready." << endl; #endif // ifdef _setMovieReady(true); } break; case GST_MESSAGE_STATE_CHANGED: // We are only interested in state-changed messages from the pipeline. if (GST_MESSAGE_SRC (msg) == GST_OBJECT (_pipeline)) { GstState oldState, newState, pendingState; gst_message_parse_state_changed(msg, &oldState, &newState, &pendingState); #ifdef VIDEO_IMPL_VERBOSE qDebug() << "Pipeline state for movie " << _uri << " changed from " << gst_element_state_get_name(oldState) << " to " << gst_element_state_get_name(newState) << endl; #endif } break; default: // We should not reach here. qWarning() << "Unexpected message received." << endl; break; } gst_message_unref(msg); } } }
static gboolean gst_raw_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstRawParse *rp = GST_RAW_PARSE (parent); gboolean ret = FALSE; GST_DEBUG ("src_query %s", gst_query_type_get_name (GST_QUERY_TYPE (query))); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; gint64 time, value; GST_LOG ("query position"); gst_query_parse_position (query, &format, NULL); time = rp->segment.position; ret = gst_raw_parse_convert (rp, GST_FORMAT_TIME, time, format, &value); gst_query_set_position (query, format, value); break; } case GST_QUERY_DURATION:{ gint64 duration; GstFormat format; GstQuery *bquery; GST_LOG ("query duration"); ret = gst_pad_peer_query (rp->sinkpad, query); if (ret) goto done; gst_query_parse_duration (query, &format, NULL); /* We only handle TIME and DEFAULT format */ if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT) goto error; bquery = gst_query_new_duration (GST_FORMAT_BYTES); ret = gst_pad_peer_query (rp->sinkpad, bquery); if (!ret) { gst_query_unref (bquery); goto error; } gst_query_parse_duration (bquery, NULL, &duration); gst_query_unref (bquery); ret = gst_raw_parse_convert (rp, GST_FORMAT_BYTES, duration, format, &duration); if (ret) gst_query_set_duration (query, format, duration); break; } case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; gint64 src_val, dest_val; GST_LOG ("query convert"); gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); ret = gst_raw_parse_convert (rp, src_fmt, src_val, dest_fmt, &dest_val); if (!ret) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; } case GST_QUERY_SEEKING:{ GstFormat fmt; ret = TRUE; gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); if (fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT && fmt != GST_FORMAT_BYTES) { gst_query_set_seeking (query, fmt, FALSE, -1, -1); } else if (rp->mode == GST_PAD_MODE_PUSH) { GstQuery *peerquery = gst_query_new_seeking (GST_FORMAT_BYTES); gboolean seekable; seekable = gst_pad_peer_query (rp->sinkpad, peerquery); if (seekable) gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL); gst_query_unref (peerquery); gst_query_set_seeking (query, fmt, seekable, seekable ? 0 : -1, -1); } else { gst_query_set_seeking (query, fmt, TRUE, 0, -1); } break; } default: /* else forward upstream */ ret = gst_pad_query_default (rp->sinkpad, parent, query); break; } done: return ret; /* ERRORS */ error: { GST_DEBUG_OBJECT (rp, "query failed"); goto done; } }
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; }
static void test_queries (InsanityTest * test) { GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME); if (gst_element_query (glob_pipeline, query)) { GstFormat fmt; gboolean seekable, known_seekable; gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL); if (glob_media_desc_parser == NULL) { insanity_test_validate_checklist_item (test, "seekable-detection", TRUE, "No media-descriptor file, result not verified against it"); glob_seekable = seekable; } else { known_seekable = media_descriptor_parser_get_seekable (glob_media_desc_parser); insanity_test_validate_checklist_item (test, "seekable-detection", known_seekable == seekable, NULL); glob_seekable = known_seekable; } } else { if (glob_media_desc_parser != NULL) glob_seekable = media_descriptor_parser_get_seekable (glob_media_desc_parser); LOG (test, "%s Does not handle seeking queries (seekable-detection \"SKIP\")", gst_element_factory_get_metadata (gst_element_get_factory (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME)); } gst_query_unref (query); query = gst_query_new_duration (GST_FORMAT_TIME); if (gst_element_query (glob_pipeline, query)) { GstFormat fmt; gchar *validate_msg = NULL; gint64 duration; if (glob_media_desc_parser == NULL) { gst_query_parse_duration (query, &fmt, &duration); validate_msg = g_strdup_printf ("Found duration %" GST_TIME_FORMAT " No media-descriptor file, result not verified against it", GST_TIME_ARGS (duration)); insanity_test_validate_checklist_item (test, "duration-detection", TRUE, validate_msg); g_free (validate_msg); glob_duration = duration; } else { glob_duration = media_descriptor_parser_get_duration (glob_media_desc_parser); gst_query_parse_duration (query, &fmt, &duration); if (glob_duration != duration) { validate_msg = g_strdup_printf ("Found time %" GST_TIME_FORMAT "-> %" GST_TIME_FORMAT, GST_TIME_ARGS (duration), GST_TIME_ARGS (glob_duration)); insanity_test_validate_checklist_item (test, "duration-detection", glob_duration == duration, validate_msg); g_free (validate_msg); } else { insanity_test_validate_checklist_item (test, "duration-detection", TRUE, NULL); } } } else { if (glob_media_desc_parser != NULL) glob_duration = media_descriptor_parser_get_seekable (glob_media_desc_parser); LOG (test, "%s Does not handle duration queries " "(duration-detection \"SKIP\")", gst_element_factory_get_metadata (gst_element_get_factory (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME)); } if (GST_CLOCK_TIME_IS_VALID (glob_duration) && glob_playback_duration > glob_duration) { LOG (test, "playback_duration > media duration, setting it" "to media_duration != 2"); glob_playback_duration = glob_duration / 2; } gst_query_unref (query); next_test (test); }