Quantcast

Can't query to get Position and Duration GStreamer

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Can't query to get Position and Duration GStreamer

hungbattran
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;
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Can't query to get Position and Duration GStreamer

Thiago Sousa Santos-2


On Wed, Mar 22, 2017 at 10:02 AM, hungbattran <[hidden email]> wrote:
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.

See my suggestion below.

 
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);his 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.

  /* 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;


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 */
  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;
}



--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Can-t-query-to-get-Position-and-Duration-GStreamer-tp4682359.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel



--
Thiago Sousa Santos

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Can't query to get Position and Duration GStreamer

Tim Müller
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Can't query to get Position and Duration GStreamer

Tim Müller
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Can't query to get Position and Duration GStreamer

hungbattran
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
Loading...