6ee59fd700037cd95ef359abcf1597215f4dfe76
[glsdk/omapdrmtest.git] / viddec3test.c
1 /*
2  * Copyright (C) 2012 Texas Instruments
3  * Author: Rob Clark <rob.clark@linaro.org>
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  */
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
22 #include <dce.h>
23 #include <xdc/std.h>
24 #include <ti/xdais/xdas.h>
25 #include <ti/sdo/ce/Engine.h>
26 #include <ti/sdo/ce/video3/viddec3.h>
28 #include "util.h"
29 #include "demux.h"
31 /* Padding for width as per Codec Requirement (for h264) */
32 #define PADX  32
33 /* Padding for height as per Codec requirement (for h264)*/
34 #define PADY  24
36 static void
37 usage(char *name)
38 {
39         MSG("Usage: %s [OPTIONS] INFILE", name);
40         MSG("Test of viddec3 decoder.");
41         MSG("");
42         disp_usage();
43 }
45 int
46 main(int argc, char **argv)
47 {
48         struct display *disp;
49         struct demux *demux;
50         struct buffer *framebuf;
51         char *infile = NULL;
52         char *input = NULL;
53         struct omap_bo *input_bo = NULL;
54         int ret = 1, i, input_sz, num_buffers;
55         int width, height, padded_width, padded_height;
56         Engine_Error ec;
57         XDAS_Int32 err;
58         Engine_Handle engine;
59         VIDDEC3_Handle codec;
60         VIDDEC3_Params *params;
61         VIDDEC3_DynamicParams *dynParams;
62         VIDDEC3_Status *status;
63         XDM2_BufDesc *inBufs;
64         XDM2_BufDesc *outBufs;
65         VIDDEC3_InArgs *inArgs;
66         VIDDEC3_OutArgs *outArgs;
68         MSG("Opening Display..");
69         disp = disp_open(argc, argv);
70         if (!disp) {
71                 usage(argv[0]);
72                 return 1;
73         }
75         /* loop thru args, find input file.. */
76         for (i = 1; i < argc; i++) {
77                 int fd;
78                 if (!argv[i]) {
79                         continue;
80                 }
81                 fd = open(argv[i], 0);
82                 if (fd > 0) {
83                         infile = argv[i];
84                         argv[i] = NULL;
85                         close(fd);
86                         break;
87                 }
88                 break;
89         }
91         if (check_args(argc, argv) || !infile) {
92                 ERROR("invalid args");
93                 goto usage;
94         }
96         MSG("Opening Demuxer..");
97         demux = demux_init(infile, &width, &height);
98         if (!demux) {
99                 goto usage;
100         }
102         MSG("infile=%s, width=%d, height=%d", infile, width, height);
104         /* calculate output buffer parameters: */
105         width  = ALIGN2 (width, 4);        /* round up to macroblocks */
106         height = ALIGN2 (height, 4);       /* round up to macroblocks */
107         padded_width  = ALIGN2 (width + (2*PADX), 7);
108         padded_height = height + 4*PADY;
109         num_buffers   = MIN(16, 32768 / ((width/16) * (height/16))) + 3;
111         MSG("padded_width=%d, padded_height=%d, num_buffers=%d",
112                         padded_width, padded_height, num_buffers);
114         input_sz = width * height;
115         input_bo = omap_bo_new(disp->dev, input_sz, OMAP_BO_WC);
116         input = omap_bo_map(input_bo);
118         framebuf = disp_get_fb(disp);
120         if (! disp_get_vid_buffers(disp, num_buffers, FOURCC_STR("NV12"),
121                         padded_width, padded_height)) {
122                 goto out;
123         }
125         MSG("Opening Engine..");
126         dce_set_fd(disp->fd);
127         engine = Engine_open("ivahd_vidsvr", NULL, &ec);
128         if (!engine) {
129                 ERROR("fail");
130                 goto out;
131         }
133         params = dce_alloc(sizeof(IVIDDEC3_Params));
134         params->size = sizeof(IVIDDEC3_Params);
136         params->maxWidth         = width;
137         params->maxHeight        = height;
138         params->maxFrameRate     = 30000;
139         params->maxBitRate       = 10000000;
140         params->dataEndianness   = XDM_BYTE;
141         params->forceChromaFormat= XDM_YUV_420SP;
142         params->operatingMode    = IVIDEO_DECODE_ONLY;
143         params->displayDelay     = IVIDDEC3_DISPLAY_DELAY_AUTO;
144         params->displayBufsMode  = IVIDDEC3_DISPLAYBUFS_EMBEDDED;
145         params->inputDataMode    = IVIDEO_ENTIREFRAME;
146         params->metadataType[0]  = IVIDEO_METADATAPLANE_NONE;
147         params->metadataType[1]  = IVIDEO_METADATAPLANE_NONE;
148         params->metadataType[2]  = IVIDEO_METADATAPLANE_NONE;
149         params->numInputDataUnits= 0;
150         params->outputDataMode   = IVIDEO_ENTIREFRAME;
151         params->numOutputDataUnits = 0;
152         params->errorInfoMode    = IVIDEO_ERRORINFO_OFF;
154         codec = VIDDEC3_create(engine, "ivahd_h264dec", params);
155         if (!codec) {
156                 ERROR("fail");
157                 goto out;
158         }
160         dynParams = dce_alloc(sizeof(IVIDDEC3_DynamicParams));
161         dynParams->size = sizeof(IVIDDEC3_DynamicParams);
163         dynParams->decodeHeader  = XDM_DECODE_AU;
165         /*Not Supported: Set default*/
166         dynParams->displayWidth  = 0;
167         dynParams->frameSkipMode = IVIDEO_NO_SKIP;
168         dynParams->newFrameFlag  = XDAS_TRUE;
170         status = dce_alloc(sizeof(IVIDDEC3_Status));
171         status->size = sizeof(IVIDDEC3_Status);
173         err = VIDDEC3_control(codec, XDM_SETPARAMS, dynParams, status);
174         if (err) {
175                 ERROR("fail: %d", err);
176                 goto out;
177         }
179         /* not entirely sure why we need to call this here.. just copying omx.. */
180         err = VIDDEC3_control(codec, XDM_GETBUFINFO, dynParams, status);
181         if (err) {
182                 ERROR("fail: %d", err);
183                 goto out;
184         }
186         inBufs = malloc(sizeof(XDM2_BufDesc));
187         inBufs->numBufs = 1;
188         inBufs->descs[0].buf = (XDAS_Int8 *)omap_bo_handle(input_bo);
189         inBufs->descs[0].memType = XDM_MEMTYPE_BO;
191         outBufs = malloc(sizeof(XDM2_BufDesc));
192         outBufs->numBufs = 2;
193         outBufs->descs[0].memType = XDM_MEMTYPE_BO;
194         outBufs->descs[1].memType = XDM_MEMTYPE_BO;
196         inArgs = dce_alloc(sizeof(IVIDDEC3_InArgs));
197         inArgs->size = sizeof(IVIDDEC3_InArgs);
199         outArgs = dce_alloc(sizeof(IVIDDEC3_OutArgs));
200         outArgs->size = sizeof(IVIDDEC3_OutArgs);
202         while (inBufs->numBufs && outBufs->numBufs) {
203                 struct buffer *buf;
204                 int n;
205                 suseconds_t t;
207                 buf = disp_get_vid_buffer(disp);
208                 if (!buf) {
209                         ERROR("fail: out of buffers");
210                         goto shutdown;
211                 }
213                 n = demux_read(demux, input, input_sz);
214                 if (n) {
215                         inBufs->descs[0].bufSize.bytes = n;
216                         inArgs->numBytes = n;
217                         MSG("push: %d bytes (%p)", n, buf);
218                 } else {
219                         /* end of input.. do we need to flush? */
220                         MSG("end of input");
221                         inBufs->numBufs = 0;
222                         inArgs->inputID = 0;
223                 }
225                 inArgs->inputID = (XDAS_Int32)buf;
226                 outBufs->descs[0].buf = (XDAS_Int8 *)omap_bo_handle(buf->bo[0]);
227                 outBufs->descs[1].buf = (XDAS_Int8 *)omap_bo_handle(buf->bo[1]);
229                 t = mark(NULL);
230                 err = VIDDEC3_process(codec, inBufs, outBufs, inArgs, outArgs);
231                 MSG("processed returned in: %ldus", (long int)mark(&t));
232                 if (err) {
233                         ERROR("process returned error: %d", err);
234                         ERROR("extendedError: %08x", outArgs->extendedError);
235                         if (XDM_ISFATALERROR(outArgs->extendedError))
236                                 goto shutdown;
237                 }
239                 for (i = 0; outArgs->outputID[i]; i++) {
240                         /* calculate offset to region of interest */
241                         XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
243                         /* get the output buffer and write it to file */
244                         buf = (struct buffer *)outArgs->outputID[i];
245                         MSG("post buffer: %p %d,%d %d,%d", buf,
246                                         r->topLeft.x, r->topLeft.y,
247                                         r->bottomRight.x, r->bottomRight.y);
248                         disp_post_vid_buffer(disp, buf, r->topLeft.x, r->topLeft.y,
249                                         r->bottomRight.x - r->topLeft.x,
250                                         r->bottomRight.y - r->topLeft.y);
251                 }
253                 for (i = 0; outArgs->freeBufID[i]; i++) {
254                         buf = (struct buffer *)outArgs->freeBufID[i];
255                         disp_put_vid_buffer(disp, buf);
256                 }
258                 if (outArgs->outBufsInUseFlag) {
259                         MSG("TODO... outBufsInUseFlag"); // XXX
260                 }
261         }
263         MSG("Ok!");
264         ret = 0;
266 shutdown:
267         VIDDEC3_delete(codec);
269 out:
270         if (engine)         Engine_close(engine);
271         if (params)         dce_free(params);
272         if (dynParams)      dce_free(dynParams);
273         if (status)         dce_free(status);
274         if (inBufs)         free(inBufs);
275         if (outBufs)        free(outBufs);
276         if (inArgs)         dce_free(inArgs);
277         if (outArgs)        dce_free(outArgs);
278         if (input_bo)       omap_bo_del(input_bo);
279         if (demux)          demux_deinit(demux);
281         return ret;
283 usage:
284         usage(argv[0]);
285         return ret;