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;
91 fmt.fmt.pix.width = width;
92 fmt.fmt.pix.height = height;
93 fmt.fmt.pix.pixelformat = fourcc;
94 fmt.fmt.pix.field = V4L2_FIELD_ALTERNATE;
96 ret = ioctl(vipfd, VIDIOC_S_FMT, &fmt);
97 if (ret < 0)
98 pexit( "vip: S_FMT failed: %s\n", strerror(errno));
100 ret = ioctl(vipfd, VIDIOC_G_FMT, &fmt);
101 if (ret < 0)
102 pexit( "vip: G_FMT after set format failed: %s\n", strerror(errno));
104 printf("vip: G_FMT(start): width = %u, height = %u, 4cc = %.4s\n",
105 fmt.fmt.pix.width, fmt.fmt.pix.height,
106 (char*)&fmt.fmt.pix.pixelformat);
108 return 0;
109 }
111 /**
112 *****************************************************************************
113 * @brief: request buffer for vip
114 *
115 * @return: 0 on success
116 *****************************************************************************
117 */
118 int vip_reqbuf(void)
119 {
120 int ret;
121 struct v4l2_requestbuffers rqbufs;
123 memset(&rqbufs, 0, sizeof(rqbufs));
124 rqbufs.count = NUMBUF;
125 rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
126 rqbufs.memory = V4L2_MEMORY_DMABUF;
128 ret = ioctl(vipfd, VIDIOC_REQBUFS, &rqbufs);
129 if (ret < 0)
130 pexit( "vip: REQBUFS failed: %s\n", strerror(errno));
132 dprintf("vip: allocated buffers = %d\n", rqbufs.count);
134 return 0;
135 }
137 /**
138 *****************************************************************************
139 * @brief: allocates shared buffer for vip and vpe
140 *
141 * @param: vpe struct vpe pointer
142 *
143 * @return: 0 on success
144 *****************************************************************************
145 */
146 int allocate_shared_buffers(struct vpe *vpe)
147 {
148 int i;
150 shared_bufs = disp_get_vid_buffers(vpe->disp, NUMBUF, vpe->src.fourcc,
151 vpe->src.width, vpe->src.height);
152 if (!shared_bufs)
153 pexit("allocating shared buffer failed\n");
155 for (i = 0; i < NUMBUF; i++) {
156 /** Get DMABUF fd for corresponding buffer object */
157 vpe->input_buf_dmafd[i] = omap_bo_dmabuf(shared_bufs[i]->bo[0]);
158 shared_bufs[i]->fd[0] = vpe->input_buf_dmafd[i];
159 dprintf("vpe->input_buf_dmafd[%d] = %d\n", i, vpe->input_buf_dmafd[i]);
160 }
162 return 0;
163 }
165 /**
166 *****************************************************************************
167 * @brief: queue shared buffer to vip
168 *
169 * @param: vpe struct vpe pointer
170 * @param: index int
171 *
172 * @return: 0 on success
173 *****************************************************************************
174 */
175 int vip_qbuf(struct vpe *vpe, int index)
176 {
177 int ret;
178 struct v4l2_buffer buf;
180 dprintf("vip buffer queue\n");
182 memset(&buf, 0, sizeof buf);
183 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
184 buf.memory = V4L2_MEMORY_DMABUF;
185 buf.index = index;
186 buf.m.fd = vpe->input_buf_dmafd[index];
188 ret = ioctl(vipfd, VIDIOC_QBUF, &buf);
189 if (ret < 0)
190 pexit( "vip: QBUF failed: %s, index = %d\n", strerror(errno), index);
192 return 0;
193 }
195 /**
196 *****************************************************************************
197 * @brief: dequeue shared buffer from vip
198 *
199 * @return: buf.index int
200 *****************************************************************************
201 */
202 int vip_dqbuf(struct vpe * vpe)
203 {
204 int ret;
205 struct v4l2_buffer buf;
207 dprintf("vip dequeue buffer\n");
209 memset(&buf, 0, sizeof buf);
211 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
212 buf.memory = V4L2_MEMORY_DMABUF;
213 ret = ioctl(vipfd, VIDIOC_DQBUF, &buf);
214 if (ret < 0)
215 pexit("vip: DQBUF failed: %s\n", strerror(errno));
217 dprintf("vip: DQBUF idx = %d, field = %s\n", buf.index,
218 buf.field == V4L2_FIELD_TOP? "Top" : "Bottom");
219 vpe->field = buf.field;
221 return buf.index;
222 }
224 int main(int argc, char *argv[])
225 {
226 int i, index = -1, count = 0 ;
228 struct vpe *vpe;
230 if (argc != 11) {
231 printf (
232 "USAGE : <SRCWidth> <SRCHeight> <SRCFormat> "
233 "<DSTWidth> <DSTHeight> <DSTformat> "
234 "<interlace> <translen> -s <connector_id>:<mode>\n");
236 return 1;
237 }
239 /** Open the device */
240 vpe = vpe_open();
242 vpe->src.width = atoi (argv[1]);
243 vpe->src.height = atoi (argv[2]);
244 describeFormat (argv[3], &vpe->src);
246 /* Force input format to be single plane */
247 vpe->src.coplanar = 0;
249 vpe->dst.width = atoi (argv[4]);
250 vpe->dst.height = atoi (argv[5]);
251 describeFormat (argv[6], &vpe->dst);
253 vpe->deint = atoi (argv[7]);
254 vpe->translen = atoi (argv[8]);
256 dprintf ("Input @ %d = %d x %d , %d\nOutput = %d x %d , %d\n",
257 fin, vpe->src.width, vpe->src.height, vpe->src.fourcc,
258 vpe->dst.width, vpe->dst.height, vpe->dst.fourcc);
260 if ( vpe->src.height < 0 || vpe->src.width < 0 || vpe->src.fourcc < 0 || \
261 vpe->dst.height < 0 || vpe->dst.width < 0 || vpe->dst.fourcc < 0) {
262 pexit("Invalid parameters\n");
263 }
265 vipfd = open ("/dev/video1",O_RDWR);
266 if (vipfd < 0)
267 pexit("Can't open camera: /dev/video1\n");
269 printf("vip open success!!!\n");
271 vpe->disp = disp_open(argc, argv);
272 if(!vpe->disp)
273 pexit("Can't open display\n");
275 vpe->disp->multiplanar = false;
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 }