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 /** Input file descriptor */
68 static int fin = -1;
70 /** OMAPDRM buffer objects */
71 static struct omap_bo *bo_y[6];
72 static struct omap_bo *bo_uv[6];
74 /**
75 *****************************************************************************
76 * @brief: free allocated input buffers
77 *
78 * @param: coplanar int
79 *
80 *****************************************************************************
81 */
82 void release_input_buffers(int coplanar)
83 {
84 int i;
86 for (i = 0; i < NUMBUF; i++) {
87 omap_bo_del(bo_y[i]);
88 if (coplanar)
89 omap_bo_del(bo_uv[i]);
90 }
91 }
93 /**
94 *****************************************************************************
95 * @brief: read image from file & fill it in input buffer
96 *
97 * @param: str char pointer
98 * @param: fd int
99 * @param: addr void pointer
100 * @param: size int
101 *
102 * @return: >0 number of bytes read
103 * @return: 0 end of file
104 *****************************************************************************
105 */
106 int do_read (char *str, int fd, void *addr, int size) {
107 int nbytes = size, ret = 0, val;
108 do {
109 nbytes = size - ret;
110 addr = addr + ret;
111 if (nbytes == 0) {
112 break;
113 }
114 ret = read(fd, addr, nbytes);
115 } while(ret > 0);
117 if (ret < 0) {
118 val = errno;
119 printf ("Read failed %s: %d %s\n", str, ret, strerror(val));
120 exit (1);
121 } else {
122 dprintf ("Total bytes read %s = %d\n", str, size);
123 }
125 return ret;
126 }
128 /**
129 *****************************************************************************
130 * @brief: allocates input buffer for vpe process
131 *
132 * @param: vpe struct vpe pointer
133 * @param: base void pointer
134 * @param: base_uv void pointer
135 *
136 * @return: 0 on success
137 *****************************************************************************
138 */
139 int allocate_input_buffers(struct vpe *vpe, void *base[], void *base_uv[])
140 {
141 int i;
142 uint32_t bo_flags = OMAP_BO_WC;
144 for (i = 0; i < NUMBUF; i++) {
145 bo_y[i] = omap_bo_new(vpe->disp->dev, vpe->src.size,
146 bo_flags);
148 /** Get DMABUF fd for corresponding buffer object */
149 vpe->input_buf_dmafd[i] = omap_bo_dmabuf(bo_y[i]);
151 /** Get virtual address for Y buffers */
152 base[i] = omap_bo_map(bo_y[i]);
153 dprintf("base[i] = 0x%x\n", i, base[i]);
155 if(vpe->src.coplanar) {
156 bo_uv[i] = omap_bo_new(vpe->disp->dev, vpe->src.size_uv,
157 bo_flags);
159 /** Get DMABUF fd for corresponding buffer object */
160 vpe->input_buf_dmafd_uv[i] = omap_bo_dmabuf(bo_uv[i]);
162 /** Get virtual address for UV buffers */
163 base_uv[i] = omap_bo_map(bo_uv[i]);
164 dprintf("base_uv[i] = 0x%x\n", i, base_uv[i]);
165 }
167 }
169 return 0;
170 }
172 int main (int argc, char *argv[])
173 {
174 int i, ret = 0, index = -1;
176 void *srcBuffers[NUMBUF];
177 void *srcBuffers_uv[NUMBUF];
178 int num_frames = 0;
180 struct vpe *vpe;
182 if (argc != 16) {
183 printf (
184 "USAGE : <SRCfilename> <SRCWidth> <SRCHeight> <SRCFormat> "
185 "<DSTWidth> <DSTHeight> <DSTformat> "
186 "<CropTop> <CropLeft> <CropWidth> <CropHeight> "
187 "<interlace> <translen> -s <connector_id>:<mode>\n"
188 "Note:\n<interlace>\n1 - Deinterlace Alternate frame type\n"
189 "2 - Deinterlace Sequence TB frame type\n");
191 return 1;
192 }
194 /** Open the device */
195 vpe = vpe_open();
197 /** Open input file in read only mode */
198 fin = open (argv[1], O_RDONLY);
199 vpe->src.width = atoi (argv[2]);
200 vpe->src.height = atoi (argv[3]);
201 describeFormat (argv[4], &vpe->src);
203 vpe->dst.width = atoi (argv[5]);
204 vpe->dst.height = atoi (argv[6]);
205 describeFormat (argv[7], &vpe->dst);
207 vpe->crop.c.top = atoi (argv[8]);
208 vpe->crop.c.left = atoi (argv[9]);
209 vpe->crop.c.width = atoi (argv[10]);
210 vpe->crop.c.height = atoi (argv[11]);
211 vpe->crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
213 vpe->deint = atoi (argv[12]);
214 vpe->translen = atoi (argv[13]);
216 dprintf ("Input @ %d = %d x %d , %d\nOutput = %d x %d , %d\n",
217 fin, vpe->src.width, vpe->src.height, vpe->src.fourcc,
218 vpe->dst.width, vpe->dst.height, vpe->dst.fourcc);
220 if (fin < 0 || vpe->src.height < 0 || vpe->src.width < 0 || \
221 vpe->src.fourcc < 0 || vpe->dst.height < 0 || \
222 vpe->dst.width < 0 || vpe->dst.fourcc < 0 || \
223 vpe->crop.c.top < 0 || vpe->crop.c.left < 0 || \
224 vpe->crop.c.width < 0 || vpe->crop.c.height < 0) {
225 pexit("Invalid parameters\n");
226 }
228 vpe->disp = disp_open(argc, argv);
229 if(!vpe->disp)
230 pexit("Can't open display\n");
232 dprintf("display open success!!!\n");
234 vpe_input_init(vpe);
236 allocate_input_buffers(vpe, srcBuffers, srcBuffers_uv);
238 vpe_output_init(vpe);
240 for (i = 0; i < NUMBUF; i++)
241 vpe_output_qbuf(vpe, i);
243 dprintf ("Input Buffers = %d @ size %d\nOutput Buffers = %d @ size %d\n",
244 vpe->src.numbuf, vpe->src.size, vpe->dst.numbuf,
245 vpe->dst.size);
247 /*************************************
248 Driver is ready Now
249 *************************************/
251 /** Read into the OUTPUT buffers from fin file */
253 switch (vpe->deint) {
254 case 1:
255 vpe->field = V4L2_FIELD_TOP;
256 break;
257 case 2:
258 vpe->field = V4L2_FIELD_SEQ_TB;
259 break;
260 case 0:
261 default:
262 vpe->field = V4L2_FIELD_ANY;
263 break;
264 }
266 for (i = 0; i < NUMBUF; i++) {
267 do_read("Y plane", fin, srcBuffers[i], vpe->src.size);
268 if (vpe->src.coplanar)
269 do_read("UV plane", fin, srcBuffers_uv[i],
270 vpe->src.size_uv);
272 vpe_input_qbuf(vpe, i);
274 if (vpe->deint == 1) {
275 if (vpe->field == V4L2_FIELD_TOP)
276 vpe->field = V4L2_FIELD_BOTTOM;
277 else
278 vpe->field = V4L2_FIELD_TOP;
279 }
280 }
282 /*************************************
283 Data is ready Now
284 *************************************/
286 stream_ON(vpe->fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
287 stream_ON(vpe->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
289 while (1) {
291 index = vpe_input_dqbuf(vpe);
293 if (do_read ("Y plane", fin, srcBuffers[index],
294 vpe->src.size) <= 0)
295 break;
296 if (vpe->src.coplanar)
297 if(do_read ("UV plane", fin, srcBuffers_uv[index],
298 vpe->src.size_uv) <= 0)
299 break;
301 vpe_input_qbuf(vpe, index);
302 if (vpe->deint == 1) {
303 if (vpe->field == V4L2_FIELD_TOP)
304 vpe->field = V4L2_FIELD_BOTTOM;
305 else
306 vpe->field = V4L2_FIELD_TOP;
307 }
309 index = vpe_output_dqbuf(vpe);
310 display_buffer(vpe, index);
311 vpe_output_qbuf(vpe, index);
312 num_frames++;
314 printf("frames completed %d\n\n", num_frames);
316 if (vpe->deint == 2) {
317 index = vpe_output_dqbuf(vpe);
318 display_buffer(vpe, index);
319 vpe_output_qbuf(vpe, index);
320 num_frames++;
322 printf("frames completed %d\n\n", num_frames);
323 }
324 }
326 printf("Done!!!\n");
328 /** Driver cleanup */
329 stream_OFF(vpe->fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
330 stream_OFF(vpe->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
332 release_input_buffers(vpe->src.coplanar);
334 disp_close(vpe->disp);
335 vpe_close(vpe);
336 close(fin);
338 return 0;
339 }