ff6b98fd061e4ff720b688cbe8a0e9f1404f6ad5
1 /*
2 * Copyright (C) 2011 Texas Instruments
3 * Author: Rob Clark <rob.clark@linaro.org>
4 * Adopted for testing VIP capture by: Nikhil Devshatwar <nikhil.nd@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
20 #include <pthread.h>
21 #include "util.h"
23 #define NBUF 6
24 #define CNT 500000
25 #define MAX_CAP 6
27 pthread_t active_thread;
29 enum display_area {
30 FULL,
31 OVERLAY
32 };
34 struct thr_data {
35 struct display *disp;
36 struct v4l2 *v4l2;
37 uint32_t fourcc, width, height;
38 enum display_area area;
39 };
41 static void
42 usage(char *name)
43 {
44 MSG("Usage: %s [OPTION]...", name);
45 MSG("Test of buffer passing between v4l2 camera and display.");
46 MSG("");
47 MSG("viddec3test options:");
48 MSG("\t-h, --help: Print this help and exit.");
49 MSG("\t--multi <num>: Capture from <num> different devices.");
50 MSG("\t\t\tEach device name and format would be parsed in the cmdline");
51 MSG("");
52 disp_usage();
53 v4l2_usage();
54 }
56 void *
57 capture_loop(void *arg)
58 {
59 struct thr_data *data = (struct thr_data *)arg;
60 struct display *disp = data->disp;
61 struct v4l2 *v4l2 = data->v4l2;
62 uint32_t fourcc = data->fourcc;
63 uint32_t width = data->width, height = data->height;
65 struct buffer **buffers, *capt;
66 pthread_t tid;
67 int ret, i;
69 tid = pthread_self();
71 buffers = disp_get_vid_buffers(disp, NBUF, fourcc, width, height);
72 if (!buffers) {
73 return NULL;
74 }
76 ret = v4l2_reqbufs(v4l2, buffers, NBUF);
77 if (ret) {
78 return NULL;
79 }
81 if(data->area == OVERLAY) {
82 for (i = 0; i < NBUF; i++) {
83 buffers[i]->noScale = true;
84 get_overlay_plane(disp, buffers[i]);
85 }
86 }
88 for (i = 0; i < NBUF; i++) {
89 v4l2_qbuf(v4l2, buffers[i]);
90 }
92 v4l2_streamon(v4l2);
93 for (i = 1; i < CNT; i++) {
95 capt = v4l2_dqbuf(v4l2);
96 if(active_thread == tid) {
97 switch(data->area) {
98 case FULL:
99 ret = disp_post_vid_buffer(disp, capt,
100 0, 0, width, height);
101 break;
102 case OVERLAY:
103 ret = disp_post_vid_buffer(disp, capt,
104 0, 0, width, height);
105 break;
106 }
107 if (ret) {
108 MSG("Quitting");
109 return NULL;
110 }
111 }
112 v4l2_qbuf(v4l2, capt);
113 }
114 v4l2_streamoff(v4l2);
116 MSG("Ok!");
117 return disp;
118 }
120 int
121 main(int argc, char **argv)
122 {
123 struct display *disp;
124 struct v4l2 *v4l2;
125 pthread_t threads[MAX_CAP];
126 struct thr_data tdata[MAX_CAP];
127 void *result = NULL;
128 int ret = 0, i, multi = 1, idx = 0;
129 char c;
131 MSG("Opening Display..");
132 disp = disp_open(argc, argv);
133 if (!disp) {
134 usage(argv[0]);
135 return 1;
136 }
138 for (i = 1; i < argc; i++) {
139 if (!argv[i])
140 continue;
142 if (!strcmp("--multi", argv[i])) {
143 argv[i++] = NULL;
144 sscanf(argv[i], "%d", &multi);
145 argv[i] = NULL;
146 if(multi < 1 || multi > MAX_CAP) {
147 usage(argv[i]);
148 return 1;
149 }
150 }
151 }
153 for (i = 0; i < multi; i++) {
154 MSG("Opening V4L2..");
155 v4l2 = v4l2_open(argc, argv, &tdata[i].fourcc,
156 &tdata[i].width, &tdata[i].height);
157 if (!v4l2) {
158 usage(argv[0]);
159 return 1;
160 }
161 tdata[i].disp = disp;
162 tdata[i].v4l2 = v4l2;
163 tdata[i].area = FULL;
164 }
166 if (check_args(argc, argv)) {
167 /* remaining args.. print usage msg */
168 usage(argv[0]);
169 return 0;
170 }
172 for (i = 0; i < multi; i++) {
173 ret = pthread_create(&threads[i], NULL, capture_loop, &tdata[i]);
174 if(ret) {
175 MSG("Failed creating thread");
176 }
177 }
178 active_thread = threads[0];
180 while(1) {
181 c = getchar();
182 if(c == 's') {
183 idx = (idx + 1) % multi;
184 active_thread = threads[idx];
185 }
186 }
188 for (i = 0; i < multi; i++) {
189 pthread_join(threads[i], &result);
190 }
192 disp_close(disp);
194 return ret;
195 }