1 /*
2 * Copyright (c) 2013-2014, Texas Instruments Incorporated
3 * Author: alaganraj <alaganraj.s@ti.com>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Contact information for paper mail:
33 * Texas Instruments
34 * Post Office Box 655303
35 * Dallas, Texas 75265
36 * Contact information:
37 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
38 * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
39 * ============================================================================
40 *
41 */
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <fcntl.h>
46 #include <unistd.h>
47 #include <stdint.h>
48 #include <string.h>
49 #include <errno.h>
51 #include <linux/videodev2.h>
52 #include <linux/v4l2-controls.h>
54 #include <sys/mman.h>
55 #include <sys/ioctl.h>
57 #include <xf86drm.h>
58 #include <omap_drm.h>
59 #include <omap_drmif.h>
61 #include "util.h"
63 #include "vpe-common.c"
65 #define NUMBUF 6 //to be removed
67 /** VIP file descriptor */
68 static int vipfd = -1;
69 static int doOnce = 0;
71 struct buffer **shared_bufs;
73 /**
74 *****************************************************************************
75 * @brief: set format for vip
76 *
77 * @param: width int
78 * @param: height int
79 * @param: fourcc int
80 *
81 * @return: 0 on success
82 *****************************************************************************
83 */
84 int vip_set_format(int width, int height, int fourcc)
85 {
86 int ret;
87 struct v4l2_format fmt;
89 memset(&fmt, 0, sizeof fmt);
90 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
92 ret = ioctl(vipfd, VIDIOC_G_FMT, &fmt);
93 if (ret < 0)
94 pexit( "vip: G_FMT failed: %s\n", strerror(errno));
96 fmt.fmt.pix.width = width;
97 fmt.fmt.pix.height = height;
98 fmt.fmt.pix.pixelformat = fourcc;
99 fmt.fmt.pix.field = V4L2_FIELD_ALTERNATE;
101 ret = ioctl(vipfd, VIDIOC_S_FMT, &fmt);
102 if (ret < 0)
103 pexit( "vip: S_FMT failed: %s\n", strerror(errno));
105 ret = ioctl(vipfd, VIDIOC_G_FMT, &fmt);
106 if (ret < 0)
107 pexit( "vip: G_FMT after set format failed: %s\n", strerror(errno));
109 printf("vip: G_FMT(start): width = %u, height = %u, 4cc = %.4s\n",
110 fmt.fmt.pix.width, fmt.fmt.pix.height,
111 (char*)&fmt.fmt.pix.pixelformat);
113 return 0;
114 }
116 /**
117 *****************************************************************************
118 * @brief: request buffer for vip
119 *
120 * @return: 0 on success
121 *****************************************************************************
122 */
123 int vip_reqbuf(void)
124 {
125 int ret;
126 struct v4l2_requestbuffers rqbufs;
128 memset(&rqbufs, 0, sizeof(rqbufs));
129 rqbufs.count = NUMBUF;
130 rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
131 rqbufs.memory = V4L2_MEMORY_DMABUF;
133 ret = ioctl(vipfd, VIDIOC_REQBUFS, &rqbufs);
134 if (ret < 0)
135 pexit( "vip: REQBUFS failed: %s\n", strerror(errno));
137 dprintf("vip: allocated buffers = %d\n", rqbufs.count);
139 return 0;
140 }
142 /**
143 *****************************************************************************
144 * @brief: allocates shared buffer for vip and vpe
145 *
146 * @param: vpe struct vpe pointer
147 *
148 * @return: 0 on success
149 *****************************************************************************
150 */
151 int allocate_shared_buffers(struct vpe *vpe)
152 {
153 int i;
155 shared_bufs = disp_get_vid_buffers(vpe->disp, NUMBUF, vpe->src.fourcc,
156 vpe->src.width, vpe->src.height);
157 if (!shared_bufs)
158 pexit("allocating shared buffer failed\n");
160 for (i = 0; i < NUMBUF; i++) {
161 /** Get DMABUF fd for corresponding buffer object */
162 vpe->input_buf_dmafd[i] = omap_bo_dmabuf(shared_bufs[i]->bo[0]);
163 shared_bufs[i]->fd[0] = vpe->input_buf_dmafd[i];
164 dprintf("vpe->input_buf_dmafd[%d] = %d\n", i, vpe->input_buf_dmafd[i]);
165 }
167 return 0;
168 }
170 /**
171 *****************************************************************************
172 * @brief: queue shared buffer to vip
173 *
174 * @param: vpe struct vpe pointer
175 * @param: index int
176 *
177 * @return: 0 on success
178 *****************************************************************************
179 */
180 int vip_qbuf(struct vpe *vpe, int index)
181 {
182 int ret;
183 struct v4l2_buffer buf;
185 dprintf("vip buffer queue\n");
187 memset(&buf, 0, sizeof buf);
188 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
189 buf.memory = V4L2_MEMORY_DMABUF;
190 buf.index = index;
191 buf.m.fd = vpe->input_buf_dmafd[index];
193 ret = ioctl(vipfd, VIDIOC_QBUF, &buf);
194 if (ret < 0)
195 pexit( "vip: QBUF failed: %s, index = %d\n", strerror(errno), index);
197 return 0;
198 }
200 /**
201 *****************************************************************************
202 * @brief: dequeue shared buffer from vip
203 *
204 * @return: buf.index int
205 *****************************************************************************
206 */
207 int vip_dqbuf(struct vpe * vpe)
208 {
209 int ret;
210 struct v4l2_buffer buf;
212 dprintf("vip dequeue buffer\n");
214 memset(&buf, 0, sizeof buf);
216 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
217 buf.memory = V4L2_MEMORY_DMABUF;
218 ret = ioctl(vipfd, VIDIOC_DQBUF, &buf);
219 if (ret < 0)
220 pexit("vip: DQBUF failed: %s\n", strerror(errno));
222 dprintf("vip: DQBUF idx = %d, field = %s\n", buf.index,
223 buf.field == V4L2_FIELD_TOP? "Top" : "Bottom");
224 vpe->field = buf.field;
226 return buf.index;
227 }
229 int main(int argc, char *argv[])
230 {
231 int i, index = -1, count = 0 ;
233 struct vpe *vpe;
235 if (argc != 11) {
236 printf (
237 "USAGE : <SRCWidth> <SRCHeight> <SRCFormat> "
238 "<DSTWidth> <DSTHeight> <DSTformat> "
239 "<interlace> <translen> -s <connector_id>:<mode>\n");
241 return 1;
242 }
244 /** Open the device */
245 vpe = vpe_open();
247 vpe->src.width = atoi (argv[1]);
248 vpe->src.height = atoi (argv[2]);
249 describeFormat (argv[3], &vpe->src);
251 vpe->dst.width = atoi (argv[4]);
252 vpe->dst.height = atoi (argv[5]);
253 describeFormat (argv[6], &vpe->dst);
255 vpe->deint = atoi (argv[7]);
256 vpe->translen = atoi (argv[8]);
258 dprintf ("Input @ %d = %d x %d , %d\nOutput = %d x %d , %d\n",
259 fin, vpe->src.width, vpe->src.height, vpe->src.fourcc,
260 vpe->dst.width, vpe->dst.height, vpe->dst.fourcc);
262 if ( vpe->src.height < 0 || vpe->src.width < 0 || vpe->src.fourcc < 0 || \
263 vpe->dst.height < 0 || vpe->dst.width < 0 || vpe->dst.fourcc < 0) {
264 pexit("Invalid parameters\n");
265 }
267 vipfd = open ("/dev/video1",O_RDWR);
268 if (vipfd < 0)
269 pexit("Can't open camera: /dev/video1\n");
271 printf("vip open success!!!\n");
273 vpe->disp = disp_open(argc, argv);
274 if(!vpe->disp)
275 pexit("Can't open display\n");
277 dprintf("display open success!!!\n");
279 vip_set_format(vpe->src.width, vpe->src.height, vpe->src.fourcc);
281 vip_reqbuf();
283 vpe_input_init(vpe);
285 allocate_shared_buffers(vpe);
287 vpe_output_init(vpe);
289 for (i = 0; i < NUMBUF; i++)
290 vip_qbuf(vpe, i);
292 for (i = 0; i < NUMBUF; i++)
293 vpe_output_qbuf(vpe, i);
295 /*************************************
296 Data is ready Now
297 *************************************/
299 stream_ON(vipfd, V4L2_BUF_TYPE_VIDEO_CAPTURE);
300 stream_ON(vpe->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
302 vpe->field = V4L2_FIELD_ANY;
303 while (1)
304 {
305 index = vip_dqbuf(vpe);
307 vpe_input_qbuf(vpe, index);
309 if (!doOnce) {
310 count ++;
311 for (i = 1; i <= NUMBUF; i++) {
312 /** To star deinterlace, minimum 3 frames needed */
313 if (vpe->deint && count != 3) {
314 index = vip_dqbuf(vpe);
315 vpe_input_qbuf(vpe, index);
316 } else {
317 stream_ON(vpe->fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
318 doOnce = 1;
319 printf("streaming started...\n");
320 break;
321 }
322 count ++;
323 }
324 }
326 index = vpe_output_dqbuf(vpe);
327 display_buffer(vpe, index);
328 vpe_output_qbuf(vpe, index);
330 index = vpe_input_dqbuf(vpe);
331 vip_qbuf(vpe, index);
332 }
334 /** Driver cleanup */
335 stream_OFF(vipfd, V4L2_BUF_TYPE_VIDEO_CAPTURE);
336 stream_OFF(vpe->fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
337 stream_OFF(vpe->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
339 disp_close(vpe->disp);
340 vpe_close(vpe);
341 close(vipfd);
343 return 0;
344 }