Added buf_lock and buf_unlock APIs in copycodec and yuvcopy test cases.
[glsdk/omapdrmtest.git] / yuvcopytest.c
1 /*
2  * Copyright (C) 2012 Texas Instruments
3  * Author: Ramprasad <x0038811@ti.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 as published by
7  * the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <libdce.h>
21 #include <xf86drm.h>
22 #include <omap_drm.h>
23 #include <omap_drmif.h>
25 #include "util.h"
27 #define MAX_IO_BUFS 8
28 /* Used for mpeg4 esds data copy */
30 /* omap drm device handle */
31 struct omap_device *dev = NULL;
33 struct decoder {
34         struct display *disp;
35         struct buffer *framebuf;
36         Engine_Handle engine;
37         VIDDEC2_Handle codec;
38         VIDDEC2_Params *params;
39         VIDDEC2_DynamicParams *dynParams;
40         VIDDEC2_Status *status;
41         XDM1_BufDesc *inBufs;
42         XDM_BufDesc *outBufs;
43         VIDDEC2_InArgs *inArgs;
44         VIDDEC2_OutArgs *outArgs;
45         XDAS_Int8 **outBuffer;
46         XDAS_Int32 *outBufSizes;
47         char *input;
48         struct omap_bo *input_bo;
49         int input_sz, uv_offset;
50         int padded_width;
51         int padded_height;
52         int num_outBuf;
54 };
56 static void
57 usage(char *name)
58 {
59         MSG("Usage: %s -s <connector_id>:<mode> INFILE -w width -h height", name);
60         MSG("example: %s -s 4:800x480 file.yuv -w 176 -h 144", name);
61         MSG("Test of universalCopy .");
62         MSG("");
63         MSG("yuvcopytest options:");
64         MSG("\t --help: Print this help and exit.");
65         MSG("");
66         disp_usage();
67 }
69 static void
70 decoder_close(struct decoder *decoder)
71 {
72     if(!decoder) goto bailout;
73         /* free output buffers allocated by display */
74         disp_free_buffers(decoder->disp,decoder->num_outBuf);
76         if (decoder->params)         dsp_dce_free(decoder->params);
77         if (decoder->dynParams)      dsp_dce_free(decoder->dynParams);
78         if (decoder->status)         dsp_dce_free(decoder->status);
79         if (decoder->inBufs)
80     {
81         dsp_dce_buf_unlock(1, &(decoder->inBufs->descs[0].buf));
82         close(decoder->inBufs->descs[0].buf);
83         dsp_dce_free(decoder->inBufs);
84     }
85         if (decoder->outBufs)        dsp_dce_free(decoder->outBufs);
86         if (decoder->inArgs)         dsp_dce_free(decoder->inArgs);
87         if (decoder->outArgs)        dsp_dce_free(decoder->outArgs);
88         if (decoder->outBuffer)      dsp_dce_free(decoder->outBuffer);
89     if (decoder->outBufSizes)    dsp_dce_free(decoder->outBufSizes);
90         if (decoder->input_bo)       omap_bo_del(decoder->input_bo);
91         if (decoder->codec)          VIDDEC2_delete(decoder->codec);
92         if (decoder->engine)         Engine_close(decoder->engine);
93         if (decoder->disp)           disp_close(decoder->disp);
94         free(decoder);
95 bailout:
96         if (dev)                             dce_deinit(dev);
98 }
100 static struct decoder *
101 decoder_open(int argc, char** argv)
103         struct decoder *decoder;
104         char *infile = NULL;
105         int i;
106         int width , height ,padded_width, padded_height;
107         Engine_Error ec;
108         XDAS_Int32 err;
110         decoder = calloc(1, sizeof(*decoder));
111         if (!decoder)
112                 return NULL;
114         MSG("%p: Opening Display..", decoder);
115         decoder->disp = disp_open(argc, argv);
116         if (!decoder->disp)
117                 goto usage;
119         /* loop thru args, find input file.. */
120         for (i = 1; i < argc; i++) {
121            int fd;
122            if (!argv[i]) {
123                 continue;
124             }
125             fd = open(argv[i], 0);
126             if (fd > 0) {
127                infile = argv[i];
128                argv[i] = NULL;
129                close(fd);
130                break;
131             }
132                break;
133         }
134         for(i = 1; i < argc; i++){
135             if(!argv[i])
136                continue;
138             if(!strcmp(argv[i],"-w")){
139                 argv[i] = NULL;
140                 width = atoi(argv[i+1]);
141                 argv[i+1] = NULL;
142                 continue;
143             }
144             if(!strcmp(argv[i], "-h")){
145                 argv[i] = NULL;
146                 height = atoi(argv[i+1]);
147                 argv[i+1] = NULL;
148             }
149         }
151         MSG("width = %d, height = %d\n", width, height);
152         if (check_args(argc, argv) || !infile)
153                 goto usage;
155         /* calculate output buffer parameters: */
156         width  = ALIGN2 (width, 4);        /* round up to macroblocks */
157         height = ALIGN2 (height, 4);       /* round up to macroblocks */
159         padded_width = width;
160         padded_height= height;
162         decoder->num_outBuf   = 2;
163         decoder->padded_width = padded_width;
164         decoder->padded_height = padded_height;
166         decoder->input_sz = width * height;
167         decoder->input_bo = omap_bo_new(decoder->disp->dev,
168                                 decoder->input_sz, OMAP_BO_WC);
169         decoder->input = omap_bo_map(decoder->input_bo);
170         decoder->framebuf = disp_get_fb(decoder->disp);
172         MSG("Fill input buffer with yuv luma data\n");
173         {
174             FILE *fd;
175             fd = fopen(infile, "rb");
176             fread(decoder->input, width*height, sizeof(char), fd);
177             fclose(fd);
178         }
180         if (! disp_get_vid_buffers(decoder->disp, decoder->num_outBuf,
181                         FOURCC_STR("NV12"), padded_width, padded_height)) {
182                 ERROR("%p: could not allocate buffers", decoder);
183                 goto fail;
184         }
186        MSG("%p: Opening Engine..", decoder);
187        dce_set_fd(decoder->disp->fd);
188        dev = dce_init();
189        if(dev == NULL) {
190            ERROR("%p: dce init failed", dev);
191            goto fail;
192        }
193        decoder->engine = Engine_open("dsp_vidsvr", NULL, &ec);
194        if (!decoder->engine) {
195           ERROR("%p: could not open engine", decoder);
196           goto fail;
197       }
199       decoder->params = dsp_dce_alloc(sizeof(IVIDDEC2_Params));
200       decoder->params->size = sizeof(IVIDDEC2_Params);
202       decoder->codec = VIDDEC2_create(decoder->engine,
203                                         "dsp_universalCopy", decoder->params);
204       if (!decoder->codec) {
205          ERROR("%p: could not create codec", decoder);
206          goto fail;
207       }
209       decoder->dynParams = dsp_dce_alloc(sizeof(IVIDDEC2_DynamicParams));
210       decoder->dynParams->size = sizeof(IVIDDEC2_DynamicParams);
212       decoder->status = dsp_dce_alloc(sizeof(IVIDDEC2_Status));
213       decoder->status->size = sizeof(IVIDDEC2_Status);
215       err = VIDDEC2_control(decoder->codec, XDM_SETPARAMS,
216                  decoder->dynParams, decoder->status);
217       if (err) {
218           ERROR("%p: fail: %d", decoder, err);
219           goto fail;
220       }
222         /* not entirely sure why we need to call this here.. just copying omx.. */
223       err = VIDDEC2_control(decoder->codec, XDM_GETBUFINFO,
224                 decoder->dynParams, decoder->status);
225       if (err) {
226          ERROR("%p: fail: %d", decoder, err);
227          goto fail;
228       }
230       decoder->outBuffer = dsp_dce_alloc(sizeof(XDAS_Int8*) * MAX_IO_BUFS);
231       decoder->outBufSizes = dsp_dce_alloc(sizeof(XDAS_Int32)* MAX_IO_BUFS);
233       decoder->inBufs = dsp_dce_alloc(sizeof(XDM1_BufDesc));
234       decoder->inBufs->numBufs = 1;
235       decoder->inBufs->descs[0].buf =   (XDAS_Int8 *)omap_bo_dmabuf(decoder->input_bo);
236       decoder->inBufs->descs[0].bufSize = omap_bo_size(decoder->input_bo);
237       dsp_dce_buf_lock(1, &(decoder->inBufs->descs[0].buf));
239       decoder->outBufs = dsp_dce_alloc(sizeof(XDM_BufDesc));
240       decoder->outBufs->numBufs = 2;
241       decoder->outBufs->bufs = (XDAS_Int8**)decoder->outBuffer;
242       decoder->outBufs->bufSizes = &decoder->outBufSizes[0];
244       decoder->inArgs = dsp_dce_alloc(sizeof(IVIDDEC2_InArgs));
245       decoder->inArgs->size = sizeof(IVIDDEC2_InArgs);
247       decoder->outArgs = dsp_dce_alloc(sizeof(IVIDDEC2_OutArgs));
248       decoder->outArgs->size = sizeof(IVIDDEC2_OutArgs);
250       return decoder;
252 usage:
253    usage(argv[0]);
254 fail:
255   if (decoder)
256    decoder_close(decoder);
257    return NULL;
258   }
260 static int
261 decoder_process(struct decoder *decoder)
263         XDM1_BufDesc *inBufs = decoder->inBufs;
264         XDM_BufDesc *outBufs = decoder->outBufs;
265         VIDDEC2_InArgs *inArgs = decoder->inArgs;
266         VIDDEC2_OutArgs *outArgs = decoder->outArgs;
267         struct buffer *buf;
268         XDAS_Int32 width = decoder->padded_width;
269         XDAS_Int32 height = decoder->padded_height;
270         XDAS_Int32 err;
271         char *src,*dst;
272         XDAS_Int32 i, success = XDAS_TRUE;
274         buf = disp_get_vid_buffer(decoder->disp);
275         if (!buf) {
276            ERROR("%p: fail: out of buffers", decoder);
277            return -1;
278         }
280         decoder->outBuffer[0] = buf->fd[0];
281         decoder->outBuffer[1] = (buf->multiplanar) ? buf->fd[1]:(XDAS_Int8 *)((decoder->outBuffer[0]));
282     dsp_dce_buf_lock(2,&decoder->outBuffer[0]);
284         decoder->outBufSizes[0] = decoder->padded_width * decoder->padded_height;
285         decoder->outBufSizes[1] = decoder->padded_width * (decoder->padded_height/2);
287         err = VIDDEC2_process(decoder->codec, inBufs, outBufs, inArgs, outArgs);
289         if (err) {
290                 ERROR("%p: process returned error: %d", decoder, err);
291                 return -1;
292         }
293     dsp_dce_buf_unlock(2, &decoder->outBuffer[0]);
295         disp_post_vid_buffer(decoder->disp, buf, 0, 0, width, height);
296         /* Display the output buffer for 10 seconds */
297         sleep(10);
299         disp_put_vid_buffer(decoder->disp, buf);
301         src = (char*)decoder->input;
302         dst = (char*)omap_bo_map(buf->bo[0]);
304         MSG("Comparing output buffer with input buffer\n");
306         for(i = 0; i < decoder->input_sz; i++){
307             if(*src != *dst){
308                 MSG("yuvcopytest failed at %d, 0x%x, 0x%x\n", i, *src, *dst);
309                 success = XDAS_FALSE;
310                 break;
311           }
312           src++;
313           dst++;
314        }
316        if(success ==XDAS_TRUE)
317            MSG("yuvcopytest executed successfully\n");
319         return 0;
322 int
323 main(int argc, char **argv)
325     struct decoder *decoder = NULL;
326     int i;
327     for (i = 1; i < argc; i++)
328         if ( !strcmp(argv[i], "--help")) {
329             usage(argv[0]);
330             exit(0);
331     }
332     decoder = decoder_open(argc,argv);
334     if(decoder)
335            decoder_process(decoder);
337     if(decoder)
338        decoder_close(decoder);
340     decoder = NULL;
342    return 0;