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 <stdlib.h>
21 #include <string.h>
22 #include <stdio.h>
24 #include <libdce.h>
25 #include <xf86drm.h>
26 #include <omap_drm.h>
27 #include <omap_drmif.h>
28 #include "util.h"
30 #define MAX_IO_BUFS 16
32 /* omap drm device handle */
33 struct omap_device *dev = NULL;
35 extern void *dsp_dce_alloc(int sz);
36 extern void dsp_dce_free(void *ptr);
38 struct decoder {
39 Engine_Handle engine;
40 VIDDEC2_Handle codec;
41 VIDDEC2_Params *params;
42 VIDDEC2_DynamicParams *dynParams;
43 VIDDEC2_Status *status;
44 XDM1_BufDesc *inBufs;
45 XDM_BufDesc *outBufs;
46 VIDDEC2_InArgs *inArgs;
47 VIDDEC2_OutArgs *outArgs;
48 char *input;
49 char *output;
50 struct omap_bo *input_bo;
51 struct omap_bo *output_bo;
52 int input_sz, output_sz;
53 XDAS_Int8 **outBuffer;
54 XDAS_Int32 *outBufSizes;
55 };
57 static void
58 decoder_close(struct decoder *decoder)
59 {
60 if(!decoder) goto bailout;
61 if (decoder->params) dsp_dce_free(decoder->params);
62 if (decoder->dynParams) dsp_dce_free(decoder->dynParams);
63 if (decoder->status) dsp_dce_free(decoder->status);
64 if (decoder->inBufs)
65 {
66 dsp_dce_buf_unlock(1, &(decoder->inBufs->descs[0].buf));
67 close(decoder->inBufs->descs[0].buf);
68 dsp_dce_free(decoder->inBufs);
69 }
70 if (decoder->outBufs) dsp_dce_free(decoder->outBufs);
71 if (decoder->inArgs) dsp_dce_free(decoder->inArgs);
72 if (decoder->outArgs) dsp_dce_free(decoder->outArgs);
73 if (decoder->input_bo) omap_bo_del(decoder->input_bo);
74 if (decoder->output_bo) omap_bo_del(decoder->output_bo);
76 if (decoder->outBuffer)
77 {
78 close(decoder->outBuffer[0]);
79 dsp_dce_free(decoder->outBuffer);
80 }
81 if (decoder->outBufSizes) dsp_dce_free(decoder->outBufSizes);
82 if (decoder->codec) VIDDEC2_delete(decoder->codec);
83 if (decoder->engine) Engine_close(decoder->engine);
85 free(decoder);
86 bailout:
87 if (dev) dce_deinit(dev);
88 }
90 static struct decoder *
91 decoder_open(int pattern)
92 {
93 struct decoder *decoder;
94 int i;
95 int width = 176, height = 144;
96 Engine_Error ec;
97 XDAS_Int32 err;
99 decoder = calloc(1, sizeof(*decoder));
100 if (!decoder)
101 return NULL;
103 MSG("%p: Opening Engine..", decoder);
104 dev = dce_init();
105 if(dev == NULL) {
106 ERROR("%p: dce init failed", dev);
107 goto fail;
108 }
109 decoder->engine = Engine_open("dsp_vidsvr", NULL, &ec);
110 if (!decoder->engine) {
111 ERROR("%p: could not open engine", decoder);
112 goto fail;
113 }
114 decoder->input_sz = width * height;
115 decoder->input_bo = omap_bo_new(dev, decoder->input_sz, OMAP_BO_WC);
116 decoder->input = omap_bo_map(decoder->input_bo);
118 decoder->output_sz = width * height;
119 decoder->output_bo = omap_bo_new(dev, decoder->output_sz, OMAP_BO_WC);
120 decoder->output = omap_bo_map(decoder->output_bo);
122 decoder->params = dsp_dce_alloc(sizeof(IVIDDEC2_Params));
123 decoder->params->size = sizeof(IVIDDEC2_Params);
125 decoder->codec = VIDDEC2_create(decoder->engine,
126 "dsp_universalCopy", decoder->params);
128 if (!decoder->codec) {
129 ERROR("%p: could not create codec", decoder);
130 goto fail;
131 }
132 MSG("Created dsp_universalCopy \n");
133 decoder->dynParams = dsp_dce_alloc(sizeof(IVIDDEC2_DynamicParams));
134 decoder->dynParams->size = sizeof(IVIDDEC2_DynamicParams);
136 decoder->status = dsp_dce_alloc(sizeof(IVIDDEC2_Status));
137 decoder->status->size = sizeof(IVIDDEC2_Status);
139 err = VIDDEC2_control(decoder->codec, XDM_SETPARAMS,
140 decoder->dynParams, decoder->status);
141 if (err) {
142 ERROR("%p: fail: %d", decoder, err);
143 goto fail;
144 }
145 /* not entirely sure why we need to call this here.. just copying omx.. */
146 err = VIDDEC2_control(decoder->codec, XDM_GETBUFINFO,
147 decoder->dynParams, decoder->status);
148 if (err) {
149 ERROR("%p: fail: %d", decoder, err);
150 goto fail;
151 }
152 decoder->outBuffer = dsp_dce_alloc(sizeof(XDAS_Int8*) * MAX_IO_BUFS);
153 decoder->outBufSizes = dsp_dce_alloc(sizeof(XDAS_Int32)* MAX_IO_BUFS);
154 decoder->inBufs = dsp_dce_alloc(sizeof(XDM1_BufDesc));
155 decoder->inBufs->numBufs = 1;
156 decoder->inBufs->descs[0].buf = (XDAS_Int8 *)omap_bo_dmabuf((struct omap_bo*) decoder->input_bo);
157 decoder->inBufs->descs[0].bufSize = width * height;
158 dsp_dce_buf_lock(1, &(decoder->inBufs->descs[0].buf));
160 decoder->outBuffer[0] = (XDAS_Int8*)omap_bo_dmabuf((struct omap_bo*) decoder->output_bo);
161 decoder->outBuffer[1] = decoder->outBuffer[0];
162 decoder->outBufSizes[0] = width * height;
163 decoder->outBufSizes[1] = decoder->outBufSizes[0];
164 decoder->outBufs = dsp_dce_alloc(sizeof(XDM_BufDesc));
165 decoder->outBufs->numBufs = 2;
166 decoder->outBufs->bufs = (XDAS_Int8**)decoder->outBuffer;
167 decoder->outBufs->bufSizes = &decoder->outBufSizes[0];
168 dsp_dce_buf_lock(1, &decoder->outBuffer[0]);
170 decoder->inArgs = dsp_dce_alloc(sizeof(IVIDDEC2_InArgs));
171 decoder->inArgs->size = sizeof(IVIDDEC2_InArgs);
173 decoder->outArgs = dsp_dce_alloc(sizeof(IVIDDEC2_OutArgs));
174 decoder->outArgs->size = sizeof(IVIDDEC2_OutArgs);
176 // Fill input buffer with a pattern for testing */
177 MSG("Fill input buffer with pattern %d\n", pattern);
178 for(i = 0; i < decoder->input_sz ; i++)
179 decoder->input[i] = pattern;
181 return decoder;
184 usage:
185 MSG("Fail\n");
186 fail:
187 if (decoder)
188 decoder_close(decoder);
189 return NULL;
190 }
192 static int
193 decoder_process(struct decoder *decoder)
194 {
195 XDM1_BufDesc *inBufs = decoder->inBufs;
196 XDM_BufDesc *outBufs = decoder->outBufs;
197 VIDDEC2_InArgs *inArgs = decoder->inArgs;
198 VIDDEC2_OutArgs *outArgs = decoder->outArgs;
199 XDAS_Int32 err = XDM_EOK, j,success = XDAS_TRUE;
200 char *src,*dst;
202 err = VIDDEC2_process(decoder->codec, inBufs, outBufs, inArgs, outArgs);
203 if (err) {
204 ERROR("%p: process returned error: %d", decoder, err);
205 return -1;
206 }
208 dsp_dce_buf_unlock(1, &decoder->outBuffer[0]);
210 MSG("Verifing the UniversalCopy algorithm\n");
212 src = (char*)decoder->input;
213 dst = (char*)decoder->output;
214 for(j= 0 ; j < decoder->input_sz ; j++){
215 if(*src != *dst){
216 MSG("copycodectest failed at %d, 0x%x, 0x%x\n", j, *src, *dst);
217 success = XDAS_FALSE;
218 break;
219 }
220 src++;
221 dst++;
222 }
223 if(success ==XDAS_TRUE)
224 MSG("copycodectest executed successfully\n");
226 return 0;
227 }
229 int
230 main(int argc, char **argv)
231 {
232 struct decoder *decoder = NULL;
233 int pattern;
234 if(argc != 2){
235 MSG("Usage: copycodectest pattern(0 to 255) \t");
236 MSG("Example: copycodectest 100\n");
237 exit(0);
238 }
239 pattern = atoi(argv[1]);
240 decoder = decoder_open(pattern);
242 if(decoder)
243 decoder_process(decoder);
245 if(decoder)
246 decoder_close(decoder);
248 return 0;
249 }