15a308887b874ac963046d5090a52b9833e06c43
[glsdk/omapdrmtest.git] / capturevpedisplay.c
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;
100         ret = ioctl(vipfd, VIDIOC_S_FMT, &fmt);
101         if (ret < 0)
102                 pexit( "vip: S_FMT failed: %s\n", strerror(errno));
104         ret = ioctl(vipfd, VIDIOC_G_FMT, &fmt);
105         if (ret < 0)
106                 pexit( "vip: G_FMT after set format failed: %s\n", strerror(errno));
108         printf("vip: G_FMT(start): width = %u, height = %u, 4cc = %.4s\n",
109                         fmt.fmt.pix.width, fmt.fmt.pix.height,
110                         (char*)&fmt.fmt.pix.pixelformat);
112         return 0;
115 /**
116  *****************************************************************************
117  * @brief:  request buffer for vip
118  *
119  * @return: 0 on success 
120  *****************************************************************************
121 */
122 int vip_reqbuf()
124         int ret;
125         struct v4l2_requestbuffers rqbufs;
127         memset(&rqbufs, 0, sizeof(rqbufs));
128         rqbufs.count = NUMBUF;
129         rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
130         rqbufs.memory = V4L2_MEMORY_DMABUF;
132         ret = ioctl(vipfd, VIDIOC_REQBUFS, &rqbufs);
133         if (ret < 0)
134                 pexit( "vip: REQBUFS failed: %s\n", strerror(errno));
136         dprintf("vip: allocated buffers = %d\n", rqbufs.count);
138         return 0;
141 /**
142  *****************************************************************************
143  * @brief:  allocates shared buffer for vip and vpe
144  *
145  * @param:  vpe struct vpe pointer
146  *
147  * @return: 0 on success 
148  *****************************************************************************
149 */
150 int allocate_shared_buffers(struct vpe *vpe)
152         int i;
154         shared_bufs = disp_get_vid_buffers(vpe->disp, NUMBUF, vpe->src.fourcc,
155                                            vpe->src.width, vpe->src.height);
156         if (!shared_bufs)
157                 pexit("allocating shared buffer failed\n");
159         for (i = 0; i < NUMBUF; i++) {
160                 /** Get DMABUF fd for corresponding buffer object */
161                 vpe->input_buf_dmafd[i] = omap_bo_dmabuf(shared_bufs[i]->bo[0]);
162                 shared_bufs[i]->fd[0] = vpe->input_buf_dmafd[i];
163                 dprintf("vpe->input_buf_dmafd[%d] = %d\n", i, vpe->input_buf_dmafd[i]);
164         }
166         return 0;
169 /**
170  *****************************************************************************
171  * @brief:  queue shared buffer to vip
172  *
173  * @param:  vpe struct vpe pointer
174  * @param:  index int
175  *
176  * @return: 0 on success 
177  *****************************************************************************
178 */
179 int vip_qbuf(struct vpe *vpe, int index)
181         int ret;
182         struct v4l2_buffer buf;
184         dprintf("vip buffer queue\n");
186         memset(&buf, 0, sizeof buf);
187         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
188         buf.memory = V4L2_MEMORY_DMABUF;
189         buf.index = index;
190         buf.m.fd = vpe->input_buf_dmafd[index];
192         ret = ioctl(vipfd, VIDIOC_QBUF, &buf);
193         if (ret < 0)
194                 pexit( "vip: QBUF failed: %s, index = %d\n", strerror(errno), index);
196         return 0;
199 /**
200  *****************************************************************************
201  * @brief:  dequeue shared buffer from vip
202  *
203  * @return: buf.index int 
204  *****************************************************************************
205 */
206 int vip_dqbuf()
208         int ret;
209         struct v4l2_buffer buf;
210         
211         dprintf("vip dequeue buffer\n");
212         
213         memset(&buf, 0, sizeof buf);
215         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
216         buf.memory = V4L2_MEMORY_DMABUF;
217         ret = ioctl(vipfd, VIDIOC_DQBUF, &buf);
218         if (ret < 0)
219                 pexit("vip: DQBUF failed: %s\n", strerror(errno));
221         dprintf("vip: DQBUF index = %d\n", buf.index);
223         return buf.index;
226 int main(int argc, char *argv[])
228         int i, ret = 0, index = -1, count = 0 ;
230         struct  vpe *vpe;
232         if (argc != 11) {
233                 printf (
234                 "USAGE : <SRCWidth> <SRCHeight> <SRCFormat> "
235                         "<DSTWidth> <DSTHeight> <DSTformat> "
236                         "<interlace> <translen> -s <connector_id>:<mode>\n");
238                 return 1;
239         }
241         /** Open the device */
242         vpe = vpe_open();
244         vpe->src.width  = atoi (argv[1]);
245         vpe->src.height = atoi (argv[2]);
246         describeFormat (argv[3], &vpe->src);
248         vpe->dst.width  = atoi (argv[4]);
249         vpe->dst.height = atoi (argv[5]);
250         describeFormat (argv[6], &vpe->dst);
252         vpe->deint = atoi (argv[7]);
253         vpe->translen = atoi (argv[8]);
255         dprintf ("Input  @ %d = %d x %d , %d\nOutput = %d x %d , %d\n",
256                 fin,  vpe->src.width, vpe->src.height, vpe->src.fourcc,
257                 vpe->dst.width, vpe->dst.height, vpe->dst.fourcc);
259         if (    vpe->src.height < 0 || vpe->src.width < 0 || vpe->src.fourcc < 0 || \
260                 vpe->dst.height < 0 || vpe->dst.width < 0 || vpe->dst.fourcc < 0) {
261                 pexit("Invalid parameters\n");
262         }
264         vipfd = open ("/dev/video1",O_RDWR);
265         if (vipfd < 0)
266                 pexit("Can't open camera: /dev/video1\n");
267         
268         printf("vip open success!!!\n");
270         vpe->disp = disp_open(argc, argv);
271         if(!vpe->disp)
272                 pexit("Can't open display\n");
274         dprintf("display open success!!!\n");
276         vip_set_format(vpe->src.width, vpe->src.height, vpe->src.fourcc);
278         vip_reqbuf();
280         vpe_input_init(vpe);
282         allocate_shared_buffers(vpe);
284         vpe_output_init(vpe);
286         for (i = 0; i < NUMBUF; i++)
287                 vip_qbuf(vpe, i);
289         for (i = 0; i < NUMBUF; i++)
290                 vpe_output_qbuf(vpe, i);
292         /*************************************
293                 Data is ready Now
294         *************************************/
296         stream_ON(vipfd, V4L2_BUF_TYPE_VIDEO_CAPTURE);
297         stream_ON(vpe->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
299         vpe->field = V4L2_FIELD_ANY;
300         while (1)
301         {
302                 index = vip_dqbuf();
304                 vpe_input_qbuf(vpe, index);
306                 if (!doOnce) {
307                         count ++;
308                         for (i = 1; i <= NUMBUF; i++) {
309                                 /** To star deinterlace, minimum 3 frames needed */
310                                 if (vpe->deint && count != 3) {
311                                         index = vip_dqbuf();
312                                         vpe_input_qbuf(vpe, index);
313                                 } else {
314                                         stream_ON(vpe->fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
315                                         doOnce = 1;
316                                         printf("streaming started...\n");
317                                         break;
318                                 }
319                                 count ++;
320                         }
321                 }
323                 index = vpe_output_dqbuf(vpe);
324                 display_buffer(vpe, index);
325                 vpe_output_qbuf(vpe, index);
327                 index = vpe_input_dqbuf(vpe);
328                 vip_qbuf(vpe, index);
329         }
330         
331         /** Driver cleanup */
332         stream_OFF(vipfd, V4L2_BUF_TYPE_VIDEO_CAPTURE);
333         stream_OFF(vpe->fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
334         stream_OFF(vpe->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
336         disp_close(vpe->disp);
337         vpe_close(vpe);
338         close(vipfd);
339         
340         return 0;