Bug 797526 - some assertions in nsDOMClassInfo should be fatal in debug builds -...
[gecko.git] / media / webrtc / trunk / test / linux / v4l2_file_player / v4l2_file_player.c
blob630e38e4dc4e6ae0b0b5dd683feb7bc4393e62dd
1 /**
2 * WebRTC Internal Tooling - Looping V4L2 player
3 * Author: Patrik Höglund (phoglund@webrtc.org)
5 * This file implements a basic raw video file player which loops its input
6 * file indefinitely. It is intended to be used with the v4l2loopback driver in
7 * order to play the contents of a file as if it were a webcam. Therefore, this
8 * program will write to a v4l2loopback device, say /dev/video1, and the driver
9 * will then reflect the data unmodified to any reading processes.
11 * This program basically does the same thing as
12 * gst-launch-0.10 -v filesrc location=resources/foreman_cif.yuv ! \
13 * videoparse width=352 height=288 ! v4l2sink device=/dev/video1
15 * , but with looping. Looping is unfortunately impossible to do with a regular
16 * gstreamer pipeline, hence the existence of this program.
18 * It can be run something like this:
19 * v4l2_file_player foreman_cif_short.yuv 352 288 /dev/video1 >& /dev/null
21 * The program might print warnings about failed ioctls (for instance for
22 * VIDIOC_G_FMT), but that doesn't seem to be a problem.
24 * To test, you can run for instance mplayer tv:// -tv device=/dev/video1 and
25 * verify that you see your video playing repeatedly.
27 * This code is based off the hello world example in the gstreamer manual.
28 * You can find the original code in chapter 10, "Your First Application":
29 * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/
32 #include <gst/gst.h>
33 #include <glib.h>
35 typedef struct {
36 GMainLoop* main_loop;
37 GstElement* pipeline;
38 } main_loop_and_pipeline_t;
40 static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) {
41 main_loop_and_pipeline_t *main_loop_and_pipeline =
42 (main_loop_and_pipeline_t*)data;
44 GMainLoop *loop = main_loop_and_pipeline->main_loop;
45 GstElement *pipeline = main_loop_and_pipeline->pipeline;
47 switch (GST_MESSAGE_TYPE (msg)) {
48 case GST_MESSAGE_EOS:
49 /* Reached end of input video - restart */
50 gst_element_set_state(pipeline, GST_STATE_READY);
51 gst_element_set_state(pipeline, GST_STATE_PLAYING);
52 break;
54 case GST_MESSAGE_ERROR: {
55 gchar *debug;
56 GError *error;
58 gst_message_parse_error(msg, &error, &debug);
59 g_free(debug);
61 g_printerr("Error: %s\n", error->message);
62 g_error_free(error);
64 g_main_loop_quit(loop);
65 break;
67 default:
68 break;
71 return TRUE;
74 int main(int argc, char *argv[]) {
75 gst_init(&argc, &argv);
77 GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
79 /* Check input arguments */
80 if (argc != 5 || atoi(argv[2]) == 0 || atoi(argv[3]) == 0) {
81 g_printerr("Usage: %s <filename> <width> <height> <device>\n\n", argv[0]);
82 g_printerr("Arguments:\n");
83 g_printerr(" filename: Path to the video file.\n");
84 g_printerr(" width: Video width.\n");
85 g_printerr(" height: Video height.\n");
86 g_printerr(" device: Device to write to (like /dev/video1).\n");
87 return -1;
90 /* Create gstreamer pipeline elements. */
91 GstElement *pipeline = gst_pipeline_new("looping-video-player");
92 GstElement *source = gst_element_factory_make("filesrc", "file-source");
93 GstElement *parse = gst_element_factory_make("videoparse", "video-parse");
94 GstElement *v4l2_sink = gst_element_factory_make("v4l2sink", "v4l2-sink");
96 if (!pipeline || !source || !parse || !v4l2_sink) {
97 g_printerr("One GST element could not be created. Exiting.\n");
98 return -1;
101 /* Set up input parameters. */
102 g_object_set(G_OBJECT (source), "location", argv[1], NULL);
103 g_object_set(G_OBJECT (parse), "width", atoi(argv[2]), NULL);
104 g_object_set(G_OBJECT (parse), "height", atoi(argv[3]), NULL);
105 g_object_set(G_OBJECT (v4l2_sink), "device", argv[4], NULL);
107 /* Add a callback to we can react to end-of-stream and errors. */
108 main_loop_and_pipeline_t main_loop_and_pipeline;
109 main_loop_and_pipeline.main_loop = main_loop;
110 main_loop_and_pipeline.pipeline = pipeline;
112 GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline));
113 gst_bus_add_watch(bus, bus_call, &main_loop_and_pipeline);
114 gst_object_unref(bus);
116 /* Assemble the pipeline. */
117 gst_bin_add_many(GST_BIN (pipeline), source, parse, v4l2_sink, NULL);
118 gst_element_link(source, parse);
119 gst_element_link(parse, v4l2_sink);
121 /* Start playing. */
122 gst_element_set_state(pipeline, GST_STATE_PLAYING);
123 g_main_loop_run(main_loop);
125 /* Never reached. */
126 return 0;