a8329eb723e7330b0381d23f4d9c37f7f2e895e6
[glsdk/omapdrmtest.git] / dmabuftest.c
1 /*
2  * Copyright (C) 2011 Texas Instruments
3  * Author: Rob Clark <rob.clark@linaro.org>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 as published by
7  * the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
19 #include <pthread.h>
20 #include "util.h"
22 #define NBUF 3
23 #define CNT  500
25 enum display_area {
26         FULL,
27         OVERLAY
28 };
30 struct thr_data {
31         struct display *disp;
32         struct v4l2 *v4l2;
33         uint32_t fourcc, width, height;
34         enum display_area area;
35 };
37 static void
38 usage(char *name)
39 {
40         MSG("Usage: %s [OPTION]...", name);
41         MSG("Test of buffer passing between v4l2 camera and display.");
42         MSG("");
43         disp_usage();
44         v4l2_usage();
45 }
47 void *
48 capture_loop(void *arg)
49 {
50         struct thr_data *data = (struct thr_data *)arg;
51         struct display *disp = data->disp;
52         struct v4l2 *v4l2 = data->v4l2;
53         uint32_t fourcc = data->fourcc;
54         uint32_t width = data->width, height = data->height;
56         struct buffer **buffers;
57         int ret, i;
59         buffers = disp_get_vid_buffers(disp, NBUF, fourcc, width, height);
60         if (!buffers) {
61                 return NULL;
62         }
64         ret = v4l2_reqbufs(v4l2, buffers, NBUF);
65         if (ret) {
66                 return NULL;
67         }
69         if(data->area == OVERLAY) {
70                 for (i = 0; i < NBUF; i++) {
71                         buffers[i]->noScale = true;
72                         get_overlay_plane(disp, buffers[i]);
73                 }
74         }
75         v4l2_qbuf(v4l2, buffers[0]);
76         v4l2_streamon(v4l2);
77         for (i = 1; i < CNT; i++) {
78                 v4l2_qbuf(v4l2, buffers[i % NBUF]);
80                 switch(data->area) {
81                 case FULL:
82                         ret = disp_post_vid_buffer(disp, v4l2_dqbuf(v4l2),
83                                 0, 0, width, height);
84                 break;
85                 case OVERLAY:
86                         ret = disp_post_vid_buffer(disp, v4l2_dqbuf(v4l2),
87                                 0, 0, width, height);
88                 break;
89                 }
90                 if (ret) {
91                         return NULL;
92                 }
93         }
94         v4l2_streamoff(v4l2);
96         MSG("Ok!");
97         return disp;
98 }
100 int
101 main(int argc, char **argv)
103         struct display *disp;
104         struct v4l2 *v4l2;
105         pthread_t threads[2];
106         struct thr_data tdata[2];
107         void *result = NULL;
108         int ret = 0, i, dual = 0;
110         MSG("Opening Display..");
111         disp = disp_open(argc, argv);
112         if (!disp) {
113                 usage(argv[0]);
114                 return 1;
115         }
117         for (i = 1; i < argc; i++) {
118                 if (!argv[i])
119                         continue;
121                 if (!strcmp("--dual", argv[i])) {
122                         dual = 1;
123                         argv[i] = NULL;
124                 }
125         }
127         MSG("Opening V4L2..");
128         v4l2 = v4l2_open(argc, argv, &tdata[0].fourcc,
129                 &tdata[0].width, &tdata[0].height);
130         if (!v4l2) {
131                 usage(argv[0]);
132                 return 1;
133         }
134         tdata[0].disp = disp;
135         tdata[0].v4l2 = v4l2;
136         tdata[0].area = FULL;
138         if(dual) {
139                 MSG("Opening second V4L2..");
140                 v4l2 = v4l2_open(argc, argv, &tdata[1].fourcc,
141                         &tdata[1].width, &tdata[1].height);
142                 if (!v4l2) {
143                         usage(argv[0]);
144                         return 1;
145                 }
146                 tdata[1].disp = disp;
147                 tdata[1].v4l2 = v4l2;
148                 tdata[1].area = OVERLAY;
149         }
151         if (check_args(argc, argv)) {
152                 /* remaining args.. print usage msg */
153                 usage(argv[0]);
154                 return 0;
155         }
157         if(dual) {
158                 ret = pthread_create(&threads[0], NULL, capture_loop, &tdata[0]);
159                 if(ret) {
160                         MSG("Failed creating thread");
161                 }
162                 ret = pthread_create(&threads[1], NULL, capture_loop, &tdata[1]);
163                 if(ret) {
164                         MSG("Failed creating thread");
165                 }
166         } else {
167                 capture_loop(&tdata[0]);
168         }
170         pthread_join(threads[0], &result);
171         pthread_join(threads[1], &result);
173         disp_close(disp);
175         return ret;