capturevpedisplay: Request interlaced capture and pass field ids
[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;
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;
116 /**
117  *****************************************************************************
118  * @brief:  request buffer for vip
119  *
120  * @return: 0 on success 
121  *****************************************************************************
122 */
123 int vip_reqbuf()
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;
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)
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;
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)
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;
200 /**
201  *****************************************************************************
202  * @brief:  dequeue shared buffer from vip
203  *
204  * @return: buf.index int 
205  *****************************************************************************
206 */
207 int vip_dqbuf(struct vpe * vpe)
209         int ret;
210         struct v4l2_buffer buf;
211         
212         dprintf("vip dequeue buffer\n");
213         
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;
229 int main(int argc, char *argv[])
231         int i, ret = 0, 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");
270         
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         }
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;