Advertisement
Guest User

Untitled

a guest
May 7th, 2014
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.09 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <unistd.h>
  3.  
  4. #include <assert.h>
  5. #include <gst/gst.h>
  6. #include <glib.h>
  7. #include <string.h>
  8.  
  9. typedef struct _CustomData {
  10.     GstElement *pipeline;
  11.     GstElement *video_sink;
  12.     GMainLoop *loop;
  13.  
  14.     gboolean playing; /* Playing or Paused */
  15.     gdouble rate; /* Current playback rate (can be negative) */
  16.  
  17.     int count;
  18.     int uri_count;
  19.     char **uris;
  20. } CustomData;
  21.  
  22. /* Send seek event to change rate */
  23. static void send_seek_event(CustomData *data) {
  24.     gint64 position;
  25.     GstEvent *seek_event;
  26.  
  27.     /* Obtain the current position, needed for the seek event */
  28.     if (!gst_element_query_position(data->pipeline, GST_FORMAT_TIME, &position)) {
  29.         g_printerr("Unable to retrieve current position.\n");
  30.         return;
  31.     }
  32.  
  33.     seek_event = gst_event_new_seek(data->rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
  34.             GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_SET, -1);
  35.  
  36.     /* Send the event */
  37.     gst_element_send_event(data->pipeline, seek_event);
  38.  
  39.     g_print("Current rate: %g\n", data->rate);
  40. }
  41.  
  42. static void prepare_next_stream(GstElement *obj, gpointer userdata) {
  43.     CustomData *data = (CustomData*) userdata;
  44.     const char* next_uri = data->uris[(data->count + 1) % data->uri_count];
  45.     g_print("about-to-finish %4d; setting next to %s\n",
  46.             data->count, next_uri);
  47.     g_object_set(G_OBJECT(data->pipeline), "uri", next_uri, NULL);
  48.  
  49.     data->count++;
  50. }
  51.  
  52. /* Process keyboard input */
  53. static gboolean handle_keyboard(GIOChannel *source, GIOCondition cond, CustomData *data) {
  54.     gchar *str = NULL;
  55.  
  56.     if (g_io_channel_read_line(source, &str, NULL, NULL, NULL) != G_IO_STATUS_NORMAL) {
  57.         return TRUE;
  58.     }
  59.  
  60.     switch (g_ascii_tolower(str[0])) {
  61.         case 'p':
  62.             data->playing = !data->playing;
  63.             gst_element_set_state(data->pipeline, data->playing ? GST_STATE_PLAYING : GST_STATE_PAUSED);
  64.             g_print("Setting state to %s\n", data->playing ? "PLAYING" : "PAUSE");
  65.             break;
  66.         case 's':
  67.             if (g_ascii_isupper(str[0])) {
  68.                 data->rate *= 1.1;
  69.             } else {
  70.                 data->rate /= 1.1;
  71.             }
  72.             send_seek_event(data);
  73.             break;
  74.         case 'd':
  75.             data->rate *= -1.0;
  76.             send_seek_event(data);
  77.             break;
  78.         case 'n':
  79.             if (data->video_sink == NULL) {
  80.                 /* If we have not done so, obtain the sink through which we will send the step events */
  81.                 g_object_get(data->pipeline, "video-sink", &data->video_sink, NULL);
  82.             }
  83.  
  84.             gst_element_send_event(data->video_sink,
  85.                     gst_event_new_step(GST_FORMAT_BUFFERS, 1, data->rate, TRUE, FALSE));
  86.             g_print("Stepping one frame\n");
  87.             break;
  88.         case 'q':
  89.             g_main_loop_quit(data->loop);
  90.             break;
  91.         default:
  92.             break;
  93.     }
  94.  
  95.     g_free(str);
  96.  
  97.     return TRUE;
  98. }
  99.  
  100.  
  101. int main(int argc, char *argv[]) {
  102.     CustomData data;
  103.     GIOChannel *io_stdin;
  104.  
  105.     /* Initialisation */
  106.     gst_init(&argc, &argv);
  107.     /* Initialize our data structure */
  108.     memset(&data, 0, sizeof (data));
  109.  
  110.     data.loop = g_main_loop_new(NULL, FALSE);
  111.  
  112.     /* Check input arguments */
  113.     if (argc < 2) {
  114.         g_printerr("Usage: %s <list of space-delimited filenames or URLs>\n",
  115.                 argv[0]);
  116.         return -1;
  117.     }
  118.  
  119.  
  120.     /* Print usage map */
  121.     g_print(
  122.             "USAGE: Choose one of the following options, then press enter:\n"
  123.             " 'P' to toggle between PAUSE and PLAY\n"
  124.             " 'S' to increase playback speed, 's' to decrease playback speed\n"
  125.             " 'D' to toggle playback direction\n"
  126.             " 'N' to move to next frame (in the current direction, better in PAUSE)\n"
  127.             " 'Q' to quit\n");
  128.  
  129.  
  130.     data.pipeline = gst_element_factory_make("playbin", "play");
  131.     assert(data.pipeline != NULL);
  132.  
  133.  
  134.     // Add watch for keyboard input
  135.     io_stdin = g_io_channel_unix_new(fileno(stdin));
  136.     g_io_add_watch(io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, &data);
  137.  
  138.     /* Register about-to-finish callback to re-set the URI */
  139.     data.count = 0;
  140.     data.uris = &(argv[1]);
  141.     data.uri_count = argc - 1;
  142.     g_signal_connect(data.pipeline, "about-to-finish",
  143.             G_CALLBACK(prepare_next_stream), &data);
  144.    
  145.     /* Set initial URI */
  146.     g_object_set(G_OBJECT(data.pipeline), "uri", argv[1], NULL);
  147.     g_print("Now playing: %s\n", argv[1]);
  148.     gst_element_set_state(data.pipeline, GST_STATE_PLAYING);
  149.     data.playing = TRUE;
  150.     data.rate = 1.0;
  151.  
  152.     /* Iterate */
  153.     g_print("Running...\n");
  154.     g_main_loop_run(data.loop);
  155.  
  156.     /* since we loop endlessly, the follwing is never reached */
  157.  
  158.     /* Out of the main loop, clean up nicely */
  159.     g_print("Returned, stopping playback\n");
  160.     gst_element_set_state(data.pipeline, GST_STATE_NULL);
  161.  
  162.     g_print("Deleting pipeline\n");
  163.     gst_object_unref(GST_OBJECT(data.pipeline));
  164.     g_main_loop_unref(data.loop);
  165.  
  166.  
  167.     return 0;
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement