Dear all,
This is my code that I try to get position and duration of video. This code can play video but it can't query to get position and duration of video. Please check for me. I'm a newbee of gstreamer and this code I modify from example 13. Thank so much. #include <string.h> #include <stdio.h> #include <gst/gst.h> typedef struct _CustomData { GstElement *pipeline; GstElement *video_sink; GMainLoop *loop; gint64 position; GstEvent *seek_event; gboolean playing; /* Playing or Paused */ gdouble rate; /* Current playback rate (can be negative) */ } CustomData; int main(int argc, char *argv[]) { CustomData data; GstStateChangeReturn ret; GIOChannel *io_stdin; GstFormat format = GST_FORMAT_TIME; GstEvent *seek_event; gint64 position; gint64 duration; /* Initialize GStreamer */ gst_init (&argc, &argv); /* Initialize our data structure */ memset (&data, 0, sizeof (data)); /* Print usage map */ /* Build the pipeline */ data.pipeline = gst_parse_launch ("playbin uri=file:///home/hungtran/Desktop/sintel_trailer-480p.webm", NULL); /* Start playing */ ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr ("Unable to set the pipeline to the playing state.\n"); gst_object_unref (data.pipeline); return -1; } data.playing = TRUE; data.rate = 1.0; /* Obtain the current position, needed for the seek event */ if (!gst_element_query_position (data.pipeline, GST_FORMAT_TIME, &position)) { g_printerr ("Unable to retrieve current position.\n"); return; } if (!gst_element_query_duration (data.pipeline, GST_FORMAT_TIME, &duration)) { g_printerr ("Unable to retrieve current position.\n"); return; } printf("[right] previous=%"GST_TIME_FORMAT"\n", GST_TIME_ARGS(position)); printf("[right] previous=%"GST_TIME_FORMAT"\n", GST_TIME_ARGS(duration)); /* Create a GLib Main Loop and set it to run */ data.loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (data.loop); /* Free resources */ g_main_loop_unref (data.loop); g_io_channel_unref (io_stdin); gst_element_set_state (data.pipeline, GST_STATE_NULL); if (data.video_sink != NULL) gst_object_unref (data.video_sink); gst_object_unref (data.pipeline); return 0; } |
On Wed, Mar 22, 2017 at 10:02 AM, hungbattran <[hidden email]> wrote: Dear all, See my suggestion below. Thank so much. The pipeline will change state asynchronously to PAUSED/PLAYING and there is no guarantee that it will be ready to reply to your queries at this point in the code. You should set up a bus messages listener and wait for a State Changed message from your pipeline to make sure it is at least in PAUSED to be able to query it for position and duration. The Message handling will also be useful to detect the end of stream and errors, so you will need it anyway. /* Obtain the current position, needed for the seek event */ -- Thiago Sousa Santos
_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by hungbattran
On Wed, 2017-03-22 at 10:02 -0700, hungbattran wrote:
Hi, > /* Build the pipeline */ > data.pipeline = gst_parse_launch ("playbin uri=...", NULL); > /* Start playing */ > ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); > (...) > > /* Obtain the current position, needed for the seek event */ > if (!gst_element_query_position (data.pipeline, GST_FORMAT_TIME, > &position)) { > g_printerr ("Unable to retrieve current position.\n"); > return; > } The problem here is that you will only be able to query the position and/or duration once the pipeline is prerolled (PAUSED or PLAYING state). set_state(PLAYING) will just make GStreamer start things in the background asynchronously in other threads. When this call returns and moves on to the following lines like the query_position/duration(), GStreamer may not have yet started up the pipeline in the background threads. To fix this you'll have to wait for the pipeline to be prerolled. You can do that with: get_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); (this will block) or msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipeline), GST_CLOCK_TIME_NONE, GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR); .. check if it's an error message .. gst_message_unref(msg); (this will also block). Ideally you would add a bus watch and then query position/duration in the callback when you get an ASYNC_DONE message. Cheers -Tim -- Tim Müller, Centricular Ltd - http://www.centricular.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Sorry, completely missed Thiago's previous response :)
-- Tim Müller, Centricular Ltd - http://www.centricular.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by Tim Müller
Hi ,
I'm a newbie so I just understand a little bit. Could you explain clearly or have any example that I can refer to execute query on pipeline GStreamer? One more thing, When I query after set playing state, it's not work. However, I put this query on loop do-while(count <1000), It can return value of duration. I don't know how it work. Thank |
Free forum by Nabble | Edit this page |