/* 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 gboolean gst_y4m_dec_src_query (GstPad * pad, GstQuery * query) { GstY4mDec *y4mdec = GST_Y4M_DEC (gst_pad_get_parent (pad)); gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: { GstFormat format; GstPad *peer; GST_DEBUG ("duration query"); gst_query_parse_duration (query, &format, NULL); if (format != GST_FORMAT_TIME) { res = FALSE; GST_DEBUG_OBJECT (y4mdec, "not handling duration query in format %d", format); break; } peer = gst_pad_get_peer (y4mdec->sinkpad); if (peer) { GstQuery *peer_query = gst_query_new_duration (GST_FORMAT_BYTES); res = gst_pad_query (peer, peer_query); if (res) { gint64 duration; int n_frames; gst_query_parse_duration (peer_query, &format, &duration); n_frames = gst_y4m_dec_bytes_to_frames (y4mdec, duration); GST_DEBUG ("duration in frames %d", n_frames); duration = gst_y4m_dec_frames_to_timestamp (y4mdec, n_frames); GST_DEBUG ("duration in time %" GST_TIME_FORMAT, GST_TIME_ARGS (duration)); gst_query_set_duration (query, GST_FORMAT_TIME, duration); res = TRUE; } gst_query_unref (peer_query); gst_object_unref (peer); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (y4mdec); return res; }
static VALUE duration_initialize(VALUE self, VALUE format) { GstQuery *query; query = gst_query_new_duration(RVAL2GST_FORMAT(format)); G_INITIALIZE(self, query); return Qnil; }
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; }
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 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); }
gint main (gint argc, gchar * argv[]) { GstElement *pipeline, *filesrc, *decodebin; GstStateChangeReturn res; GstIterator *it; GstBus *bus; GValue data = { 0, }; gst_init (&argc, &argv); pipeline = gst_pipeline_new ("pipeline"); filesrc = gst_element_factory_make ("filesrc", "filesrc"); g_assert (filesrc); decodebin = gst_element_factory_make ("decodebin", "decodebin"); g_assert (decodebin); gst_bin_add_many (GST_BIN (pipeline), filesrc, decodebin, NULL); gst_element_link (filesrc, decodebin); if (argc < 2) { g_print ("usage: %s <filenames>\n", argv[0]); exit (-1); } if (!g_str_has_prefix (argv[1], "file://")) { g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL); } else { g_object_set (G_OBJECT (filesrc), "location", argv[1] + 7, NULL); } /* we've got to connect fakesinks to newly decoded pads to make sure * buffers have actually been flowing over those pads and caps have * been set on them. decodebin might insert internal queues and * without fakesinks it's pot-luck what caps we get from the pad, because * it depends on whether the queues have started pushing buffers yet or not. * With fakesinks we make sure that the pipeline doesn't go to PAUSED state * before each fakesink has a buffer queued. */ g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (new_decoded_pad_cb), pipeline); bus = gst_element_get_bus (pipeline); g_print ("pause..\n"); res = gst_element_set_state (pipeline, GST_STATE_PAUSED); if (res == GST_STATE_CHANGE_FAILURE) { show_error ("Could not go to PAUSED state", bus); exit (-1); } g_print ("waiting..\n"); res = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); if (res != GST_STATE_CHANGE_SUCCESS) { show_error ("Failed to complete state change to PAUSED", bus); exit (-1); } g_print ("stats..\n"); it = gst_element_iterate_src_pads (decodebin); while (gst_iterator_next (it, &data) == GST_ITERATOR_OK) { GstPad *pad = g_value_get_object (&data); GstCaps *caps; gchar *str; GstQuery *query; g_print ("stream %s:\n", GST_OBJECT_NAME (pad)); caps = gst_pad_query_caps (pad, NULL); str = gst_caps_to_string (caps); g_print (" caps: %s\n", str); g_free (str); gst_caps_unref (caps); query = gst_query_new_duration (GST_FORMAT_TIME); if (gst_pad_query (pad, query)) { gint64 duration; gst_query_parse_duration (query, NULL, &duration); g_print (" duration: %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (duration)); } gst_query_unref (query); g_value_reset (&data); } g_value_unset (&data); gst_iterator_free (it); return 0; }
void create_queries() { GstQuery *query; /* POSITION */ { GstFormat format; gint64 position; xmlfile = "gstquery_create_queries"; std_log(LOG_FILENAME_LINE, "Test Started create_queries"); query = gst_query_new_position (GST_FORMAT_TIME); fail_if (query == NULL); fail_unless (GST_QUERY_TYPE (query) == GST_QUERY_POSITION); gst_query_parse_position (query, &format, NULL); fail_if (format != GST_FORMAT_TIME); gst_query_set_position (query, GST_FORMAT_TIME, 0xdeadbeaf); gst_query_parse_position (query, &format, &position); fail_if (format != GST_FORMAT_TIME); fail_if (position != 0xdeadbeaf); gst_query_unref (query); } /* DURATION */ { GstFormat format; gint64 duration; query = gst_query_new_duration (GST_FORMAT_TIME); fail_if (query == NULL); fail_unless (GST_QUERY_TYPE (query) == GST_QUERY_DURATION); gst_query_parse_duration (query, &format, NULL); fail_if (format != GST_FORMAT_TIME); gst_query_set_duration (query, GST_FORMAT_TIME, 0xdeadbeaf); gst_query_parse_duration (query, &format, &duration); fail_if (format != GST_FORMAT_TIME); fail_if (duration != 0xdeadbeaf); gst_query_unref (query); } { /* FIXME make tests for: * * LATENCY * JITTER * RATE * SEEKING * SEGMENT * CONVERT */ } /* SEGMENT */ { gdouble rate; GstFormat format; gint64 start, stop; format = GST_FORMAT_BYTES; query = gst_query_new_segment (format); fail_if (query == NULL); fail_unless (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT); gst_query_parse_segment (query, &rate, &format, &start, &stop); /* see if empty gives undefined formats */ fail_if (rate != 0.0); fail_if (format != GST_FORMAT_BYTES); fail_if (start != -1); fail_if (stop != -1); /* change all values */ gst_query_set_segment (query, 2.0, GST_FORMAT_TIME, 1 * GST_SECOND, 3 * GST_SECOND); gst_query_parse_segment (query, &rate, &format, &start, &stop); /* see if the values were changed */ fail_if (rate != 2.0); fail_if (format != GST_FORMAT_TIME); fail_if (start != 1 * GST_SECOND); fail_if (stop != 3 * GST_SECOND); gst_query_unref (query); } /* FORMATS */ { guint size; GstFormat format; query = gst_query_new_formats (); fail_if (query == NULL); fail_unless (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS); /* empty */ gst_query_parse_formats_length (query, &size); fail_if (size != 0); /* see if empty gives undefined formats */ gst_query_parse_formats_nth (query, 0, &format); fail_if (format != GST_FORMAT_UNDEFINED); gst_query_parse_formats_nth (query, 1, &format); fail_if (format != GST_FORMAT_UNDEFINED); /* set 2 formats */ gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES); gst_query_parse_formats_length (query, &size); fail_if (size != 2); format = GST_FORMAT_UNDEFINED; gst_query_parse_formats_nth (query, 0, &format); fail_if (format != GST_FORMAT_TIME); gst_query_parse_formats_nth (query, 1, &format); fail_if (format != GST_FORMAT_BYTES); /* out of bounds, should return UNDEFINED */ gst_query_parse_formats_nth (query, 2, &format); fail_if (format != GST_FORMAT_UNDEFINED); /* overwrite with 3 formats */ gst_query_set_formats (query, 3, GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_PERCENT); gst_query_parse_formats_length (query, &size); fail_if (size != 3); gst_query_parse_formats_nth (query, 2, &format); fail_if (format != GST_FORMAT_PERCENT); /* create one from an array */ { static GstFormat formats[] = { GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_PERCENT }; gst_query_set_formatsv (query, 3, formats); gst_query_parse_formats_length (query, &size); fail_if (size != 3); gst_query_parse_formats_nth (query, 0, &format); fail_if (format != GST_FORMAT_TIME); gst_query_parse_formats_nth (query, 2, &format); fail_if (format != GST_FORMAT_PERCENT); } gst_query_unref (query); } std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
void test_queries() { GstBin *bin; GstElement *src, *sink; GstStateChangeReturn ret; GstPad *pad; GstQuery *dur, *pos; xmlfile = "gstquery_test_queries"; std_log(LOG_FILENAME_LINE, "Test Started test_queries"); fail_unless ((bin = (GstBin *) gst_pipeline_new (NULL)) != NULL, "Could not create pipeline"); fail_unless ((src = gst_element_factory_make ("fakesrc", NULL)) != NULL, "Could not create fakesrc"); g_object_set (src, "datarate", 200, "sizetype", 2, NULL); fail_unless ((sink = gst_element_factory_make ("fakesink", NULL)) != NULL, "Could not create fakesink"); g_object_set (sink, "sync", TRUE, NULL); fail_unless ((dur = gst_query_new_duration (GST_FORMAT_BYTES)) != NULL, "Could not prepare duration query"); fail_unless ((pos = gst_query_new_position (GST_FORMAT_BYTES)) != NULL, "Could not prepare position query"); fail_unless (gst_bin_add (bin, src), "Could not add src to bin"); fail_unless (gst_bin_add (bin, sink), "Could not add sink to bin"); fail_unless (gst_element_link (src, sink), "could not link src and sink"); ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING); fail_if (ret == GST_STATE_CHANGE_FAILURE, "Failed to set pipeline PLAYING"); if (ret == GST_STATE_CHANGE_ASYNC) gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); /* Query the bin */ fail_unless (gst_element_query (GST_ELEMENT (bin), pos), "Could not query pipeline position"); fail_unless (gst_element_query (GST_ELEMENT (bin), dur), "Could not query pipeline duration"); /* Query elements */ fail_unless (gst_element_query (GST_ELEMENT (src), pos), "Could not query position of fakesrc"); fail_unless (gst_element_query (GST_ELEMENT (src), pos), "Could not query duration of fakesrc"); fail_unless (gst_element_query (GST_ELEMENT (sink), pos), "Could not query position of fakesink"); fail_unless (gst_element_query (GST_ELEMENT (sink), pos), "Could not query duration of fakesink"); /* Query pads */ fail_unless ((pad = gst_element_get_pad (src, "src")) != NULL, "Could not get source pad of fakesrc"); fail_unless (gst_pad_query (pad, pos), "Could not query position of fakesrc src pad"); fail_unless (gst_pad_query (pad, dur), "Could not query duration of fakesrc src pad"); gst_object_unref (pad); /* We don't query the sink pad of fakesink, it doesn't * handle downstream queries atm, but it might later, who knows? */ ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL); fail_if (ret == GST_STATE_CHANGE_FAILURE, "Failed to set pipeline NULL"); if (ret == GST_STATE_CHANGE_ASYNC) gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); gst_query_unref (dur); gst_query_unref (pos); gst_object_unref (bin); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
DurationQueryPtr DurationQuery::create(Format format) { return DurationQueryPtr::wrap(gst_query_new_duration(static_cast<GstFormat>(format)), false); }
gint64 gstreamer_get_position(gboolean *error) { gint64 pos, len; if (end_of_stream) { #if GST_CHECK_VERSION(1, 0, 0) if (gst_element_query_duration(pipeline, GST_FORMAT_TIME, &len)) { #else GstFormat format = GST_FORMAT_TIME; if (gst_element_query_duration(pipeline, &format, &len)) { #endif if (error != NULL) *error = FALSE; return len; } if (error != NULL) *error = TRUE; return 0; } #if GST_CHECK_VERSION(1, 0, 0) if (gst_element_query_position(pipeline, GST_FORMAT_TIME, &pos)) { if (gst_element_query_duration (pipeline, GST_FORMAT_TIME, &len)) { #else GstFormat format = GST_FORMAT_TIME; if (gst_element_query_position(pipeline, &format, &pos)) { GstFormat format2 = GST_FORMAT_TIME; if (gst_element_query_duration(pipeline, &format2, &len)) { #endif if (error != NULL) *error = FALSE; return pos; } } // printf("gstplay: Could not succesfully query current position.\n"); if (error != NULL) *error = TRUE; return 0; } gint64 gstreamer_get_duration() { GstQuery *query; gboolean res; query = gst_query_new_duration (GST_FORMAT_TIME); res = gst_element_query (pipeline, query); gint64 duration; if (res) { gst_query_parse_duration(query, NULL, &duration); } else duration = 0; gst_query_unref (query); return duration; } const gchar *gstreamer_get_duration_str() { gint64 duration = gstreamer_get_duration(); char s[80]; sprintf(s, "%u:%02u:%02u", GST_TIME_ARGS(duration)); return strdup(s); } static gboolean seek_to_time_cb(gpointer data) { gstreamer_seek_to_time(requested_position); gstreamer_set_volume(suspended_audio_volume); return FALSE; } void gstreamer_seek_to_time(gint64 time_nanoseconds) { end_of_stream = FALSE; if (!gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, time_nanoseconds)) { printf("gstplay: Seek failed!.n"); } }