Subversion Repositories Kolibri OS

Rev

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=:fill the content of filename to codedbuf for jpeg encoding
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
}
373