Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5362 | serge | 1 | /* |
2 | * Copyright (c) 2009 Intel Corporation. All Rights Reserved. |
||
3 | * |
||
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: |
||
11 | * |
||
12 | * The above copyright notice and this permission notice (including the |
||
13 | * next paragraph) shall be included in all copies or substantial portions |
||
14 | * of the Software. |
||
15 | * |
||
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. |
||
23 | */ |
||
24 | |||
25 | #define _GNU_SOURCE 1 |
||
26 | #include "va.h" |
||
27 | #include "va_backend.h" |
||
28 | #include "va_trace.h" |
||
29 | #include "va_fool.h" |
||
30 | |||
31 | #include |
||
32 | #include |
||
33 | #include |
||
34 | #include |
||
35 | #include |
||
36 | #include |
||
37 | #include |
||
38 | #include |
||
39 | #include |
||
40 | #include |
||
41 | #include |
||
42 | #include |
||
43 | |||
44 | /* |
||
45 | * Do dummy decode/encode, ignore the input data |
||
46 | * In order to debug memory leak or low performance issues, we need to isolate driver problems |
||
47 | * We export env "VA_FOOL", with which, we can do fake decode/encode: |
||
48 | * |
||
49 | * LIBVA_FOOL_DECODE: |
||
50 | * . if set, decode does nothing |
||
51 | * LIBVA_FOOL_ENCODE= |
||
52 | * . if set, encode does nothing, but fill in the coded buffer from the content of files with |
||
53 | * name framename.0,framename.1,..., framename.N, framename.0,..., framename.N,...repeatly |
||
54 | * Use file name to determine h264 or vp8 |
||
55 | * LIBVA_FOOL_JPEG= |
||
56 | * LIBVA_FOOL_POSTP: |
||
57 | * . if set, do nothing for vaPutSurface |
||
58 | */ |
||
59 | |||
60 | |||
61 | /* global settings */ |
||
62 | int fool_codec = 0; |
||
63 | int fool_postp = 0; |
||
64 | |||
65 | #define FOOL_BUFID_MAGIC 0x12345600 |
||
66 | #define FOOL_BUFID_MASK 0xffffff00 |
||
67 | |||
68 | struct fool_context { |
||
69 | int enabled; /* fool_codec is global, and it is for concurent encode/decode */ |
||
70 | char *fn_enc;/* file pattern with codedbuf content for encode */ |
||
71 | char *segbuf_enc; /* the segment buffer of coded buffer, load frome fn_enc */ |
||
72 | int file_count; |
||
73 | |||
74 | char *fn_jpg;/* file name of JPEG fool with codedbuf content */ |
||
75 | char *segbuf_jpg; /* the segment buffer of coded buffer, load frome fn_jpg */ |
||
76 | |||
77 | VAEntrypoint entrypoint; /* current entrypoint */ |
||
78 | |||
79 | /* all buffers with same type share one malloc-ed memory |
||
80 | * bufferID = (buffer numbers with the same type << 8) || type |
||
81 | * the malloc-ed memory can be find by fool_buf[bufferID & 0xff] |
||
82 | * the size is ignored here |
||
83 | */ |
||
84 | char *fool_buf[VABufferTypeMax]; /* memory of fool buffers */ |
||
85 | unsigned int fool_buf_size[VABufferTypeMax]; /* size of memory of fool buffers */ |
||
86 | unsigned int fool_buf_element[VABufferTypeMax]; /* element count of created buffers */ |
||
87 | unsigned int fool_buf_count[VABufferTypeMax]; /* count of created buffers */ |
||
88 | VAContextID context; |
||
89 | }; |
||
90 | |||
91 | #define FOOL_CTX(dpy) ((struct fool_context *)((VADisplayContextP)dpy)->vafool) |
||
92 | |||
93 | #define DPY2FOOLCTX(dpy) \ |
||
94 | struct fool_context *fool_ctx = FOOL_CTX(dpy); \ |
||
95 | if (fool_ctx == NULL) \ |
||
96 | return 0; /* no fool for the context */ \ |
||
97 | |||
98 | #define DPY2FOOLCTX_CHK(dpy) \ |
||
99 | struct fool_context *fool_ctx = FOOL_CTX(dpy); \ |
||
100 | if ((fool_ctx == NULL) || (fool_ctx->enabled == 0)) \ |
||
101 | return 0; /* no fool for the context */ \ |
||
102 | |||
103 | /* Prototype declarations (functions defined in va.c) */ |
||
104 | |||
105 | void va_errorMessage(const char *msg, ...); |
||
106 | void va_infoMessage(const char *msg, ...); |
||
107 | |||
108 | int va_parseConfig(char *env, char *env_value); |
||
109 | |||
110 | void va_FoolInit(VADisplay dpy) |
||
111 | { |
||
112 | char env_value[1024]; |
||
113 | |||
114 | struct fool_context *fool_ctx = calloc(sizeof(struct fool_context), 1); |
||
115 | |||
116 | if (fool_ctx == NULL) |
||
117 | return; |
||
118 | |||
119 | if (va_parseConfig("LIBVA_FOOL_POSTP", NULL) == 0) { |
||
120 | fool_postp = 1; |
||
121 | va_infoMessage("LIBVA_FOOL_POSTP is on, dummy vaPutSurface\n"); |
||
122 | } |
||
123 | |||
124 | if (va_parseConfig("LIBVA_FOOL_DECODE", NULL) == 0) { |
||
125 | fool_codec |= VA_FOOL_FLAG_DECODE; |
||
126 | va_infoMessage("LIBVA_FOOL_DECODE is on, dummy decode\n"); |
||
127 | } |
||
128 | if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) { |
||
129 | fool_codec |= VA_FOOL_FLAG_ENCODE; |
||
130 | fool_ctx->fn_enc = strdup(env_value); |
||
131 | va_infoMessage("LIBVA_FOOL_ENCODE is on, load encode data from file with patten %s\n", |
||
132 | fool_ctx->fn_enc); |
||
133 | } |
||
134 | if (va_parseConfig("LIBVA_FOOL_JPEG", &env_value[0]) == 0) { |
||
135 | fool_codec |= VA_FOOL_FLAG_JPEG; |
||
136 | fool_ctx->fn_jpg = strdup(env_value); |
||
137 | va_infoMessage("LIBVA_FOOL_JPEG is on, load encode data from file with patten %s\n", |
||
138 | fool_ctx->fn_jpg); |
||
139 | } |
||
140 | |||
141 | ((VADisplayContextP)dpy)->vafool = fool_ctx; |
||
142 | } |
||
143 | |||
144 | |||
145 | int va_FoolEnd(VADisplay dpy) |
||
146 | { |
||
147 | int i; |
||
148 | DPY2FOOLCTX(dpy); |
||
149 | |||
150 | for (i = 0; i < VABufferTypeMax; i++) {/* free memory */ |
||
151 | if (fool_ctx->fool_buf[i]) |
||
152 | free(fool_ctx->fool_buf[i]); |
||
153 | } |
||
154 | if (fool_ctx->segbuf_enc) |
||
155 | free(fool_ctx->segbuf_enc); |
||
156 | if (fool_ctx->segbuf_jpg) |
||
157 | free(fool_ctx->segbuf_jpg); |
||
158 | if (fool_ctx->fn_enc) |
||
159 | free(fool_ctx->fn_enc); |
||
160 | if (fool_ctx->fn_jpg) |
||
161 | free(fool_ctx->fn_jpg); |
||
162 | |||
163 | free(fool_ctx); |
||
164 | ((VADisplayContextP)dpy)->vafool = NULL; |
||
165 | |||
166 | return 0; |
||
167 | } |
||
168 | |||
169 | int va_FoolCreateConfig( |
||
170 | VADisplay dpy, |
||
171 | VAProfile profile, |
||
172 | VAEntrypoint entrypoint, |
||
173 | VAConfigAttrib *attrib_list, |
||
174 | int num_attribs, |
||
175 | VAConfigID *config_id /* out */ |
||
176 | ) |
||
177 | { |
||
178 | DPY2FOOLCTX(dpy); |
||
179 | |||
180 | fool_ctx->entrypoint = entrypoint; |
||
181 | |||
182 | /* |
||
183 | * check fool_codec to align with current context |
||
184 | * e.g. fool_codec = decode then for encode, the |
||
185 | * vaBegin/vaRender/vaEnd also run into fool path |
||
186 | * which is not desired |
||
187 | */ |
||
188 | if (((fool_codec & VA_FOOL_FLAG_DECODE) && (entrypoint == VAEntrypointVLD)) || |
||
189 | ((fool_codec & VA_FOOL_FLAG_JPEG) && (entrypoint == VAEntrypointEncPicture))) |
||
190 | fool_ctx->enabled = 1; |
||
191 | else if ((fool_codec & VA_FOOL_FLAG_ENCODE) && (entrypoint == VAEntrypointEncSlice)) { |
||
192 | /* H264 is desired */ |
||
193 | if (((profile == VAProfileH264Baseline || |
||
194 | profile == VAProfileH264Main || |
||
195 | profile == VAProfileH264High || |
||
196 | profile == VAProfileH264ConstrainedBaseline)) && |
||
197 | strstr(fool_ctx->fn_enc, "h264")) |
||
198 | fool_ctx->enabled = 1; |
||
199 | |||
200 | /* vp8 is desired */ |
||
201 | if ((profile == VAProfileVP8Version0_3) && |
||
202 | strstr(fool_ctx->fn_enc, "vp8")) |
||
203 | fool_ctx->enabled = 1; |
||
204 | } |
||
205 | if (fool_ctx->enabled) |
||
206 | va_infoMessage("FOOL is enabled for this context\n"); |
||
207 | else |
||
208 | va_infoMessage("FOOL is not enabled for this context\n"); |
||
209 | |||
210 | |||
211 | return 0; /* continue */ |
||
212 | } |
||
213 | |||
214 | |||
215 | VAStatus va_FoolCreateBuffer( |
||
216 | VADisplay dpy, |
||
217 | VAContextID context, /* in */ |
||
218 | VABufferType type, /* in */ |
||
219 | unsigned int size, /* in */ |
||
220 | unsigned int num_elements, /* in */ |
||
221 | void *data, /* in */ |
||
222 | VABufferID *buf_id /* out */ |
||
223 | ) |
||
224 | { |
||
225 | unsigned int new_size = size * num_elements; |
||
226 | unsigned int old_size; |
||
227 | DPY2FOOLCTX_CHK(dpy); |
||
228 | |||
229 | old_size = fool_ctx->fool_buf_size[type] * fool_ctx->fool_buf_element[type]; |
||
230 | |||
231 | if (old_size < new_size) |
||
232 | fool_ctx->fool_buf[type] = realloc(fool_ctx->fool_buf[type], new_size); |
||
233 | |||
234 | fool_ctx->fool_buf_size[type] = size; |
||
235 | fool_ctx->fool_buf_element[type] = num_elements; |
||
236 | fool_ctx->fool_buf_count[type]++; |
||
237 | /* because we ignore the vaRenderPicture, |
||
238 | * all buffers with same type share same real memory |
||
239 | * bufferID = (magic number) | type |
||
240 | */ |
||
241 | *buf_id = FOOL_BUFID_MAGIC | type; |
||
242 | |||
243 | return 1; /* don't call into driver */ |
||
244 | } |
||
245 | |||
246 | VAStatus va_FoolBufferInfo( |
||
247 | VADisplay dpy, |
||
248 | VABufferID buf_id, /* in */ |
||
249 | VABufferType *type, /* out */ |
||
250 | unsigned int *size, /* out */ |
||
251 | unsigned int *num_elements /* out */ |
||
252 | ) |
||
253 | { |
||
254 | unsigned int magic; |
||
255 | |||
256 | DPY2FOOLCTX_CHK(dpy); |
||
257 | |||
258 | magic = buf_id & FOOL_BUFID_MASK; |
||
259 | if (magic != FOOL_BUFID_MAGIC) |
||
260 | return 0; /* could be VAImageBufferType from vaDeriveImage */ |
||
261 | |||
262 | *type = buf_id & 0xff; |
||
263 | *size = fool_ctx->fool_buf_size[*type]; |
||
264 | *num_elements = fool_ctx->fool_buf_element[*type];; |
||
265 | |||
266 | return 1; /* fool is valid */ |
||
267 | } |
||
268 | |||
269 | static int va_FoolFillCodedBufEnc(struct fool_context *fool_ctx) |
||
270 | { |
||
271 | char file_name[1024]; |
||
272 | struct stat file_stat = {0}; |
||
273 | VACodedBufferSegment *codedbuf; |
||
274 | int i, fd = -1; |
||
275 | |||
276 | /* try file_name.file_count, if fail, try file_name.file_count-- */ |
||
277 | for (i=0; i<=1; i++) { |
||
278 | snprintf(file_name, 1024, "%s.%d", |
||
279 | fool_ctx->fn_enc, |
||
280 | fool_ctx->file_count); |
||
281 | |||
282 | if ((fd = open(file_name, O_RDONLY)) != -1) { |
||
283 | fstat(fd, &file_stat); |
||
284 | fool_ctx->file_count++; /* open next file */ |
||
285 | break; |
||
286 | } else /* fall back to the first file file */ |
||
287 | fool_ctx->file_count = 0; |
||
288 | } |
||
289 | if (fd != -1) { |
||
290 | fool_ctx->segbuf_enc = realloc(fool_ctx->segbuf_enc, file_stat.st_size); |
||
291 | read(fd, fool_ctx->segbuf_enc, file_stat.st_size); |
||
292 | close(fd); |
||
293 | } else |
||
294 | va_errorMessage("Open file %s failed:%s\n", file_name, strerror(errno)); |
||
295 | |||
296 | codedbuf = (VACodedBufferSegment *)fool_ctx->fool_buf[VAEncCodedBufferType]; |
||
297 | codedbuf->size = file_stat.st_size; |
||
298 | codedbuf->bit_offset = 0; |
||
299 | codedbuf->status = 0; |
||
300 | codedbuf->reserved = 0; |
||
301 | codedbuf->buf = fool_ctx->segbuf_enc; |
||
302 | codedbuf->next = NULL; |
||
303 | |||
304 | return 0; |
||
305 | } |
||
306 | |||
307 | static int va_FoolFillCodedBufJPG(struct fool_context *fool_ctx) |
||
308 | { |
||
309 | struct stat file_stat = {0}; |
||
310 | VACodedBufferSegment *codedbuf; |
||
311 | int fd = -1; |
||
312 | |||
313 | if ((fd = open(fool_ctx->fn_jpg, O_RDONLY)) != -1) { |
||
314 | fstat(fd, &file_stat); |
||
315 | fool_ctx->segbuf_jpg = realloc(fool_ctx->segbuf_jpg, file_stat.st_size); |
||
316 | read(fd, fool_ctx->segbuf_jpg, file_stat.st_size); |
||
317 | close(fd); |
||
318 | } else |
||
319 | va_errorMessage("Open file %s failed:%s\n", fool_ctx->fn_jpg, strerror(errno)); |
||
320 | |||
321 | codedbuf = (VACodedBufferSegment *)fool_ctx->fool_buf[VAEncCodedBufferType]; |
||
322 | codedbuf->size = file_stat.st_size; |
||
323 | codedbuf->bit_offset = 0; |
||
324 | codedbuf->status = 0; |
||
325 | codedbuf->reserved = 0; |
||
326 | codedbuf->buf = fool_ctx->segbuf_jpg; |
||
327 | codedbuf->next = NULL; |
||
328 | |||
329 | return 0; |
||
330 | } |
||
331 | |||
332 | |||
333 | static int va_FoolFillCodedBuf(struct fool_context *fool_ctx) |
||
334 | { |
||
335 | if (fool_ctx->entrypoint == VAEntrypointEncSlice) |
||
336 | va_FoolFillCodedBufEnc(fool_ctx); |
||
337 | else if (fool_ctx->entrypoint == VAEntrypointEncPicture) |
||
338 | va_FoolFillCodedBufJPG(fool_ctx); |
||
339 | |||
340 | return 0; |
||
341 | } |
||
342 | |||
343 | |||
344 | VAStatus va_FoolMapBuffer( |
||
345 | VADisplay dpy, |
||
346 | VABufferID buf_id, /* in */ |
||
347 | void **pbuf /* out */ |
||
348 | ) |
||
349 | { |
||
350 | unsigned int magic, buftype; |
||
351 | DPY2FOOLCTX_CHK(dpy); |
||
352 | |||
353 | magic = buf_id & FOOL_BUFID_MASK; |
||
354 | if (magic != FOOL_BUFID_MAGIC) |
||
355 | return 0; /* could be VAImageBufferType from vaDeriveImage */ |
||
356 | |||
357 | buftype = buf_id & 0xff; |
||
358 | *pbuf = fool_ctx->fool_buf[buftype]; |
||
359 | |||
360 | /* it is coded buffer, fill coded segment from file */ |
||
361 | if (*pbuf && (buftype == VAEncCodedBufferType)) |
||
362 | va_FoolFillCodedBuf(fool_ctx); |
||
363 | |||
364 | return 1; /* fool is valid */ |
||
365 | } |
||
366 | |||
367 | VAStatus va_FoolCheckContinuity(VADisplay dpy) |
||
368 | { |
||
369 | DPY2FOOLCTX_CHK(dpy); |
||
370 | |||
371 | return 1; /* fool is valid */ |
||
372 | }=1;>>>><> |
||
373 |