<div dir="ltr"><br><div class="gmail_quote"><div dir="ltr"><div>Hi,<br></div><div>Following is my code for a very basic file player. It is using playbin.<br></div><div>Basically I am trying to understand the tric play functionalities of gstreamer pipelines.<br>

</div>
<div>I am very new to gstreamer world.<br></div><div>I noticed that every time I change the speed the pipline freezes for few seconds and then reflects the change. <br></div><div>I am using VAAPI enabled system. any way to debug specifically the cause of those frozen moments.<br>


</div><div>Thanks in advance. <br></div><div><br><br>#include <string.h><br>#include <gst/gst.h><br>#include <iostream><br>#include <stdio.h><br><br>typedef struct _CustomData {<br>    GstElement *pipeline;<br>


    GstElement *video_sink;<br>    GMainLoop *loop;<br><br>    gboolean playing;  /* Playing or Paused */<br>    gdouble rate;      /* Current playback rate (can be negative) */<br>} CustomData;<br><br>/* Send seek event to change rate */<br>


static void send_seek_event (CustomData *data) {<br>    gint64 position;<br>    GstFormat format = GST_FORMAT_TIME;<br>    GstEvent *seek_event;<br>        <br>     g_print(" SEEK EVENT RECEIVED. \n");<br><br>    /* Obtain the current position, needed for the seek event */<br>


    if (!gst_element_query_position (data->pipeline, format, &position)) {<br>        g_printerr ("Unable to retrieve current position.\n");<br>        return;<br>    }<br><br>    /* Create the seek event */<br>


    if (data->rate > 0) {<br>        seek_event = gst_event_new_seek (data->rate, GST_FORMAT_TIME, /*GST_SEEK_FLAG_FLUSH |*/ GST_SEEK_FLAG_ACCURATE,<br>                GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_NONE,0);<br>


    } else {<br>        seek_event = gst_event_new_seek (data->rate, GST_FORMAT_TIME, /*GST_SEEK_FLAG_FLUSH |*/ GST_SEEK_FLAG_ACCURATE,<br>                GST_SEEK_TYPE_SET,0, GST_SEEK_TYPE_SET, position);<br>    }<br>


<br>    if (data->video_sink == NULL) {<br>        /* If we have not done so, obtain the sink through which we will send the seek events */<br>        g_object_get (data->pipeline, "video-sink", &data->video_sink, NULL);<br>


    }<br><br>    /* Send the event */<br>    gst_element_send_event (data->video_sink, seek_event);<br><br>    g_print ("Current rate: %g\n", data->rate);<br>}<br><br>/* Process keyboard input */<br>static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) {<br>


    gchar *str = NULL;<br><br>    if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) != G_IO_STATUS_NORMAL) {<br>        return TRUE;<br>    }<br><br>    switch (g_ascii_tolower (str[0])) {<br>        case 'p':<br>


            data->playing = !data->playing;<br>            gst_element_set_state (data->pipeline, data->playing ? GST_STATE_PLAYING : GST_STATE_PAUSED);<br>            g_print ("Setting state to %s\n", data->playing ? "PLAYING" : "PAUSE");<br>


            break;<br>        case 's':<br>            if (g_ascii_isupper (str[0])) <br>                        {<br>                <br>                data->rate *= 2.0;<br>                           } <br>

             else <br>
            {<br>                data->rate /= 2.0;<br>            }<br>            send_seek_event (data);<br>            break;<br>        case 'd':<br>            data->rate *= -1.0;<br>            send_seek_event (data);<br>


            break;<br>        case 'n':<br>            if (data->video_sink == NULL) {<br>                /* If we have not done so, obtain the sink through which we will send the step events */<br>                g_object_get (data->pipeline, "video-sink", &data->video_sink, NULL);<br>


            }<br><br>            gst_element_send_event (data->video_sink,<br>                    gst_event_new_step (GST_FORMAT_BUFFERS, 1, data->rate, TRUE, FALSE));<br>            g_print ("Stepping one frame\n");<br>


            break;<br>        case 'q':<br>            g_main_loop_quit (data->loop);<br>            break;<br>        default:<br>            break;<br>    }<br><br>    g_free (str);<br><br>    return TRUE;<br>


}<br><br>int main(int argc, char *argv[]) {<br>    CustomData data;<br>    GstStateChangeReturn ret;<br>    GIOChannel *io_stdin;<br><br>    /* Initialize GStreamer */<br>    gst_init (&argc, &argv);<br><br>    /* Initialize our data structure */<br>


    memset (&data, 0, sizeof (data));<br><br>    /* Print usage map */<br>    g_print (<br>            "USAGE: Choose one of the following options, then press enter:\n"<br>            " 'P' to toggle between PAUSE and PLAY\n"<br>


            " 'S' to increase playback speed, 's' to decrease playback speed\n"<br>            " 'D' to toggle playback direction\n"<br>            " 'N' to move to next frame (in the current direction, better in PAUSE)\n"<br>


            " 'Q' to quit\n");<br><br>    /* Build the pipeline */<br>//    data.pipeline = gst_parse_launch ("playbin2 uri=<a href="http://docs.gstreamer.com/media/sintel_trailer-480p.webm" target="_blank">http://docs.gstreamer.com/media/sintel_trailer-480p.webm</a>", NULL);<br>


    data.pipeline = gst_parse_launch ("playbin uri=file:///home/ufouser/Tata_1080p24_H264.mp4", NULL);<br><br>    /* Add a keyboard watch so we get notified of keystrokes */<br>#ifdef _WIN32<br>    io_stdin = g_io_channel_win32_new_fd (fileno (stdin));<br>


#else<br>    io_stdin = g_io_channel_unix_new (fileno (stdin));<br>#endif<br>    g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data);<br><br>    /* Start playing */<br>    ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);<br>


    if (ret == GST_STATE_CHANGE_FAILURE) {<br>        g_printerr ("Unable to set the pipeline to the playing state.\n");<br>        gst_object_unref (data.pipeline);<br>        return -1;<br>    }<br>    data.playing = TRUE;<br>


    data.rate = 1.0;<br><br>    /* Create a GLib Main Loop and set it to run */<br>    data.loop = g_main_loop_new (NULL, FALSE);<br>    g_main_loop_run (data.loop);<br><br>    /* Free resources */<br>    g_main_loop_unref (data.loop);<br>


    g_io_channel_unref (io_stdin);<br>    gst_element_set_state (data.pipeline, GST_STATE_NULL);<br>    if (data.video_sink != NULL)<br>        gst_object_unref (data.video_sink);<br>    gst_object_unref (data.pipeline);<br>


    return 0;<br>}<br></div></div></div><div><br></div>-- <br>Regards<br>Subodh
</div>