2 * Copyright (c) 2009 Intel Corporation. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include "va_backend.h"
39 #include <sys/types.h>
46 * Do dummy decode/encode, ignore the input data
47 * In order to debug memory leak or low performance issues, we need to isolate driver problems
48 * We export env "VA_FOOL", with which, we can do fake decode/encode:
51 * . if set, decode does nothing
52 * LIBVA_FOOL_ENCODE=<framename>:
53 * . if set, encode does nothing, but fill in the coded buffer from the content of files with
54 * name framename.0,framename.1,..., framename.N, framename.0,..., framename.N,...repeatly
55 * LIBVA_FOOL_JPEG=<framename>:fill the content of filename to codedbuf for jpeg encoding
57 * . if set, do nothing for vaPutSurface
65 #define FOOL_BUFID_MAGIC 0x12345600
66 #define FOOL_BUFID_MASK 0xffffff00
69 char *fn_enc;/* file pattern with codedbuf content for encode */
70 char *segbuf_enc; /* the segment buffer of coded buffer, load frome fn_enc */
73 char *fn_jpg;/* file name of JPEG fool with codedbuf content */
74 char *segbuf_jpg; /* the segment buffer of coded buffer, load frome fn_jpg */
76 VAEntrypoint entrypoint; /* current entrypoint */
78 /* all buffers with same type share one malloc-ed memory
79 * bufferID = (buffer numbers with the same type << 8) || type
80 * the malloc-ed memory can be find by fool_buf[bufferID & 0xff]
81 * the size is ignored here
83 char *fool_buf[VABufferTypeMax]; /* memory of fool buffers */
84 unsigned int fool_buf_size[VABufferTypeMax]; /* size of memory of fool buffers */
85 unsigned int fool_buf_element[VABufferTypeMax]; /* element count of created buffers */
86 unsigned int fool_buf_count[VABufferTypeMax]; /* count of created buffers */
90 #define FOOL_CTX(dpy) ((struct fool_context *)((VADisplayContextP)dpy)->vafool)
91 #define DPY2FOOLCTX(dpy) \
92 struct fool_context *fool_ctx = FOOL_CTX(dpy); \
94 if (fool_ctx == NULL) \
95 return 0; /* let driver go */ \
97 /* Prototype declarations (functions defined in va.c) */
99 void va_errorMessage(const char *msg, ...);
100 void va_infoMessage(const char *msg, ...);
102 int va_parseConfig(char *env, char *env_value);
104 void va_FoolInit(VADisplay dpy)
106 char env_value[1024];
109 struct fool_context *fool_ctx = calloc(sizeof(struct fool_context), 1);
111 if (fool_ctx == NULL)
114 if (va_parseConfig("LIBVA_FOOL_POSTP", NULL) == 0) {
116 va_infoMessage("LIBVA_FOOL_POSTP is on, dummy vaPutSurface\n");
119 if (va_parseConfig("LIBVA_FOOL_DECODE", NULL) == 0) {
120 fool_codec |= VA_FOOL_FLAG_DECODE;
121 va_infoMessage("LIBVA_FOOL_DECODE is on, dummy decode\n");
123 if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) {
124 fool_codec |= VA_FOOL_FLAG_ENCODE;
125 fool_ctx->fn_enc = strdup(env_value);
126 va_infoMessage("LIBVA_FOOL_ENCODE is on, load encode data from file with patten %s\n",
129 if (va_parseConfig("LIBVA_FOOL_JPEG", &env_value[0]) == 0) {
130 fool_codec |= VA_FOOL_FLAG_JPEG;
131 fool_ctx->fn_jpg = strdup(env_value);
132 va_infoMessage("LIBVA_FOOL_JPEG is on, load encode data from file with patten %s\n",
136 ((VADisplayContextP)dpy)->vafool = fool_ctx;
140 int va_FoolEnd(VADisplay dpy)
145 for (i = 0; i < VABufferTypeMax; i++) {/* free memory */
146 if (fool_ctx->fool_buf[i])
147 free(fool_ctx->fool_buf[i]);
149 if (fool_ctx->segbuf_enc)
150 free(fool_ctx->segbuf_enc);
151 if (fool_ctx->segbuf_jpg)
152 free(fool_ctx->segbuf_jpg);
153 if (fool_ctx->fn_enc)
154 free(fool_ctx->fn_enc);
155 if (fool_ctx->fn_jpg)
156 free(fool_ctx->fn_jpg);
159 ((VADisplayContextP)dpy)->vafool = NULL;
165 int va_FoolCreateConfig(
168 VAEntrypoint entrypoint,
169 VAConfigAttrib *attrib_list,
171 VAConfigID *config_id /* out */
176 fool_ctx->entrypoint = entrypoint;
179 * check fool_codec to align with current context
180 * e.g. fool_codec = decode then for encode, the
181 * vaBegin/vaRender/vaEnd also run into fool path
182 * which is not desired
184 if (((fool_codec & VA_FOOL_FLAG_DECODE) && (entrypoint == VAEntrypointVLD)) ||
185 ((fool_codec & VA_FOOL_FLAG_ENCODE) && (entrypoint == VAEntrypointEncSlice)) ||
186 ((fool_codec & VA_FOOL_FLAG_JPEG) && (entrypoint == VAEntrypointEncPicture)))
187 ; /* the fool_codec is meaningful */
191 return 0; /* driver continue */
195 VAStatus va_FoolCreateBuffer(
197 VAContextID context, /* in */
198 VABufferType type, /* in */
199 unsigned int size, /* in */
200 unsigned int num_elements, /* in */
202 VABufferID *buf_id /* out */
205 unsigned int new_size = size * num_elements;
206 unsigned int old_size;
209 old_size = fool_ctx->fool_buf_size[type] * fool_ctx->fool_buf_element[type];
211 if (old_size < new_size)
212 fool_ctx->fool_buf[type] = realloc(fool_ctx->fool_buf[type], new_size);
214 fool_ctx->fool_buf_size[type] = size;
215 fool_ctx->fool_buf_element[type] = num_elements;
216 fool_ctx->fool_buf_count[type]++;
217 /* because we ignore the vaRenderPicture,
218 * all buffers with same type share same real memory
219 * bufferID = (magic number) | type
221 *buf_id = FOOL_BUFID_MAGIC | type;
223 return 1; /* don't call into driver */
226 VAStatus va_FoolBufferInfo(
228 VABufferID buf_id, /* in */
229 VABufferType *type, /* out */
230 unsigned int *size, /* out */
231 unsigned int *num_elements /* out */
234 unsigned int magic = buf_id & FOOL_BUFID_MASK;
237 if (magic != FOOL_BUFID_MAGIC)
240 *type = buf_id & 0xff;
241 *size = fool_ctx->fool_buf_size[*type];
242 *num_elements = fool_ctx->fool_buf_element[*type];;
244 return 1; /* don't call into driver */
247 static int va_FoolFillCodedBufEnc(struct fool_context *fool_ctx)
249 char file_name[1024];
250 struct stat file_stat = {0};
251 VACodedBufferSegment *codedbuf;
254 /* try file_name.file_count, if fail, try file_name.file_count-- */
255 for (i=0; i<=1; i++) {
256 snprintf(file_name, 1024, "%s.%d",
258 fool_ctx->file_count);
260 if ((fd = open(file_name, O_RDONLY)) != -1) {
261 fstat(fd, &file_stat);
262 fool_ctx->file_count++; /* open next file */
264 } else /* fall back to the first file file */
265 fool_ctx->file_count = 0;
268 fool_ctx->segbuf_enc = realloc(fool_ctx->segbuf_enc, file_stat.st_size);
269 read(fd, fool_ctx->segbuf_enc, file_stat.st_size);
272 va_errorMessage("Open file %s failed:%s\n", file_name, strerror(errno));
274 codedbuf = (VACodedBufferSegment *)fool_ctx->fool_buf[VAEncCodedBufferType];
275 codedbuf->size = file_stat.st_size;
276 codedbuf->bit_offset = 0;
277 codedbuf->status = 0;
278 codedbuf->reserved = 0;
279 codedbuf->buf = fool_ctx->segbuf_enc;
280 codedbuf->next = NULL;
286 static int va_FoolFillCodedBufJPG(struct fool_context *fool_ctx)
288 struct stat file_stat = {0};
289 VACodedBufferSegment *codedbuf;
292 if ((fd = open(fool_ctx->fn_jpg, O_RDONLY)) != -1) {
293 fstat(fd, &file_stat);
294 fool_ctx->segbuf_jpg = realloc(fool_ctx->segbuf_jpg, file_stat.st_size);
295 read(fd, fool_ctx->segbuf_jpg, file_stat.st_size);
298 va_errorMessage("Open file %s failed:%s\n", fool_ctx->fn_jpg, strerror(errno));
300 codedbuf = (VACodedBufferSegment *)fool_ctx->fool_buf[VAEncCodedBufferType];
301 codedbuf->size = file_stat.st_size;
302 codedbuf->bit_offset = 0;
303 codedbuf->status = 0;
304 codedbuf->reserved = 0;
305 codedbuf->buf = fool_ctx->segbuf_jpg;
306 codedbuf->next = NULL;
312 static int va_FoolFillCodedBuf(struct fool_context *fool_ctx)
314 if (fool_ctx->entrypoint == VAEntrypointEncSlice)
315 va_FoolFillCodedBufEnc(fool_ctx);
316 else if (fool_ctx->entrypoint == VAEntrypointEncPicture)
317 va_FoolFillCodedBufJPG(fool_ctx);
323 VAStatus va_FoolMapBuffer(
325 VABufferID buf_id, /* in */
326 void **pbuf /* out */
329 unsigned int buftype = buf_id & 0xff;
330 unsigned int magic = buf_id & FOOL_BUFID_MASK;
333 if (magic != FOOL_BUFID_MAGIC || buftype >= VABufferTypeMax || !pbuf)
336 /* buf_id is the buffer type */
337 *pbuf = fool_ctx->fool_buf[buftype];
339 /* it is coded buffer, fill the fake segment buf from file */
340 if (*pbuf && (buftype == VAEncCodedBufferType))
341 va_FoolFillCodedBuf(fool_ctx);
343 return 1; /* don't call into driver */
346 VAStatus va_FoolUnmapBuffer(
348 VABufferID buf_id /* in */
351 unsigned int magic = buf_id & FOOL_BUFID_MASK;
353 if (magic != FOOL_BUFID_MAGIC)