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 struct thr_data {
28 struct display *disp;
29 struct v4l2 *v4l2;
30 uint32_t fourcc, width, height;
31 };
33 static void
34 usage(char *name)
35 {
36 MSG("Usage: %s [OPTION]...", name);
37 MSG("Test of buffer passing between v4l2 camera and display.");
38 MSG("");
39 MSG("viddec3test options:");
40 MSG("\t-h, --help: Print this help and exit.");
41 MSG("\t--multi <num>: Capture from <num> different devices.");
42 MSG("\t\t\tEach device name and format would be parsed in the cmdline");
43 MSG("");
44 disp_usage();
45 v4l2_usage();
46 }
48 void *
49 capture_loop(void *arg)
50 {
51 struct thr_data *data = (struct thr_data *)arg;
52 struct display *disp = data->disp;
53 struct v4l2 *v4l2 = data->v4l2;
54 uint32_t fourcc = data->fourcc;
55 uint32_t width = data->width, height = data->height;
57 struct buffer **buffers, *capt;
58 int ret, i;
60 buffers = disp_get_vid_buffers(disp, NBUF, fourcc, width, height);
61 if (!buffers) {
62 return NULL;
63 }
65 ret = v4l2_reqbufs(v4l2, buffers, NBUF);
66 if (ret) {
67 return NULL;
68 }
70 for (i = 0; i < NBUF; i++) {
71 v4l2_qbuf(v4l2, buffers[i]);
72 }
74 ret = v4l2_streamon(v4l2);
75 if (ret) {
76 return NULL;
77 }
79 for (i = 1; i < CNT; i++) {
81 capt = v4l2_dqbuf(v4l2);
82 ret = disp_post_vid_buffer(disp, capt,
83 0, 0, width, height);
84 if (ret) {
85 ERROR("Post buffer failed");
86 return NULL;
87 }
88 v4l2_qbuf(v4l2, capt);
89 }
90 v4l2_streamoff(v4l2);
92 MSG("Ok!");
93 return disp;
94 }
96 int
97 main(int argc, char **argv)
98 {
99 struct display *disp;
100 struct v4l2 *v4l2;
101 pthread_t threads[MAX_CAP];
102 struct thr_data tdata[MAX_CAP];
103 void *result = NULL;
104 int ret = 0, i, multi = 1, idx = 0;
105 char c;
107 MSG("Opening Display..");
108 disp = disp_open(argc, argv);
109 if (!disp) {
110 usage(argv[0]);
111 return 1;
112 }
114 disp->multiplanar = false;
116 for (i = 1; i < argc; i++) {
117 if (!argv[i])
118 continue;
120 if (!strcmp("--multi", argv[i])) {
121 argv[i++] = NULL;
122 sscanf(argv[i], "%d", &multi);
123 argv[i] = NULL;
124 if(multi < 1 || multi > MAX_CAP) {
125 usage(argv[i]);
126 return 1;
127 }
128 }
129 }
131 for (i = 0; i < multi; i++) {
132 MSG("Opening V4L2..");
133 v4l2 = v4l2_open(argc, argv, &tdata[i].fourcc,
134 &tdata[i].width, &tdata[i].height);
135 if (!v4l2) {
136 usage(argv[0]);
137 return 1;
138 }
139 tdata[i].disp = disp;
140 tdata[i].v4l2 = v4l2;
141 }
143 if (check_args(argc, argv)) {
144 /* remaining args.. print usage msg */
145 usage(argv[0]);
146 return 0;
147 }
149 for (i = 0; i < multi; i++) {
150 ret = pthread_create(&threads[i], NULL, capture_loop, &tdata[i]);
151 if(ret) {
152 MSG("Failed creating thread");
153 }
154 }
156 for (i = 0; i < multi; i++) {
157 pthread_join(threads[i], &result);
158 }
160 disp_close(disp);
162 return ret;
163 }