]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/omapdrmtest.git/blob - capturevpedisplay.c
Merge pull request #1 in PSDKLA/omapdrmtest from GFXFORK/eric-omapdrmtest:bugfix...
[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;
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;
111 /**
112  *****************************************************************************
113  * @brief:  request buffer for vip
114  *
115  * @return: 0 on success 
116  *****************************************************************************
117 */
118 int vip_reqbuf(void)
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;
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)
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;
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)
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;
195 /**
196  *****************************************************************************
197  * @brief:  dequeue shared buffer from vip
198  *
199  * @return: buf.index int 
200  *****************************************************************************
201 */
202 int vip_dqbuf(struct vpe * vpe)
204         int ret;
205         struct v4l2_buffer buf;
206         
207         dprintf("vip dequeue buffer\n");
208         
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;
224 int main(int argc, char *argv[])
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");
268         
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         }
333         
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);
342         
343         return 0;