Subversion Repositories Kolibri OS

Rev

Rev 6117 | Rev 6121 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6117 Rev 6118
1
#include 
1
#include 
2
#include 
2
#include 
3
#include 
3
#include 
4
#include 
4
#include 
5
#include 
5
#include 
6
#include 
6
#include 
7
#include 
7
#include 
8
#include 
8
#include 
9
#include 
9
#include 
10
#include 
10
#include 
11
#include 
11
#include 
12
#include 
12
#include 
13
#include "winlib/winlib.h"
13
#include "winlib/winlib.h"
14
#include "fplay.h"
14
#include "fplay.h"
15
 
-
 
16
extern int dfx;
-
 
17
 
15
 
18
struct hw_profile
16
struct hw_profile
19
{
17
{
20
    enum AVCodecID av_codec;
18
    enum AVCodecID av_codec;
21
    int ff_profile;
19
    int ff_profile;
22
    uint64_t va_profile;
20
    uint64_t va_profile;
23
};
21
};
24
 
22
 
25
 
23
 
26
#define ENTER()   printf("enter %s\n",__FUNCTION__)
24
#define ENTER()   printf("enter %s\n",__FUNCTION__)
27
#define LEAVE()   printf("leave %s\n",__FUNCTION__)
25
#define LEAVE()   printf("leave %s\n",__FUNCTION__)
28
#define FAIL()    printf("fail %s\n",__FUNCTION__)
26
#define FAIL()    printf("fail %s\n",__FUNCTION__)
29
 
27
 
30
 
28
 
31
#if DEBUG
29
#if DEBUG
32
# define D(x) x
30
# define D(x) x
33
# define bug printf
31
# define bug printf
34
#else
32
#else
35
# define D(x)
33
# define D(x)
36
#endif
34
#endif
37
 
35
 
38
#undef  ARRAY_ELEMS
36
#undef  ARRAY_ELEMS
39
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
37
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
40
 
38
 
41
static int drm_fd = 0;
39
static int drm_fd = 0;
42
static struct vaapi_context *v_context;
40
static struct vaapi_context *v_context;
43
 
41
 
44
static VASurfaceID v_surface_id[4];
42
static VASurfaceID v_surface_id[4];
45
 
43
 
46
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
44
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
47
#define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0))
45
#define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0))
48
 
46
 
49
#define PE(av_codec_id, ff_profile, vdp_profile)                \
47
#define PE(av_codec_id, ff_profile, vdp_profile)                \
50
    {AV_CODEC_ID_ ## av_codec_id, FF_PROFILE_ ## ff_profile,    \
48
    {AV_CODEC_ID_ ## av_codec_id, FF_PROFILE_ ## ff_profile,    \
51
     VAProfile ## vdp_profile}
49
     VAProfile ## vdp_profile}
52
 
50
 
53
static const struct hw_profile profiles[] = {
51
static const struct hw_profile profiles[] = {
54
    PE(MPEG2VIDEO,  MPEG2_MAIN,         MPEG2Main),
52
    PE(MPEG2VIDEO,  MPEG2_MAIN,         MPEG2Main),
55
    PE(MPEG2VIDEO,  MPEG2_SIMPLE,       MPEG2Simple),
53
    PE(MPEG2VIDEO,  MPEG2_SIMPLE,       MPEG2Simple),
56
    PE(MPEG4,       MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple),
54
    PE(MPEG4,       MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple),
57
    PE(MPEG4,       MPEG4_MAIN,         MPEG4Main),
55
    PE(MPEG4,       MPEG4_MAIN,         MPEG4Main),
58
    PE(MPEG4,       MPEG4_SIMPLE,       MPEG4Simple),
56
    PE(MPEG4,       MPEG4_SIMPLE,       MPEG4Simple),
59
    PE(H264,        H264_HIGH,          H264High),
57
    PE(H264,        H264_HIGH,          H264High),
60
    PE(H264,        H264_MAIN,          H264Main),
58
    PE(H264,        H264_MAIN,          H264Main),
61
    PE(H264,        H264_BASELINE,      H264Baseline),
59
    PE(H264,        H264_BASELINE,      H264Baseline),
62
    PE(VC1,         VC1_ADVANCED,       VC1Advanced),
60
    PE(VC1,         VC1_ADVANCED,       VC1Advanced),
63
    PE(VC1,         VC1_MAIN,           VC1Main),
61
    PE(VC1,         VC1_MAIN,           VC1Main),
64
    PE(VC1,         VC1_SIMPLE,         VC1Simple),
62
    PE(VC1,         VC1_SIMPLE,         VC1Simple),
65
    PE(WMV3,        VC1_ADVANCED,       VC1Advanced),
63
    PE(WMV3,        VC1_ADVANCED,       VC1Advanced),
66
    PE(WMV3,        VC1_MAIN,           VC1Main),
64
    PE(WMV3,        VC1_MAIN,           VC1Main),
67
    PE(WMV3,        VC1_SIMPLE,         VC1Simple),
65
    PE(WMV3,        VC1_SIMPLE,         VC1Simple),
68
#if HAS_HEVC
66
#if HAS_HEVC
69
    PE(HEVC,        HEVC_MAIN,          HEVCMain),
67
    PE(HEVC,        HEVC_MAIN,          HEVCMain),
70
    PE(HEVC,        HEVC_MAIN_10,       HEVCMain10),
68
    PE(HEVC,        HEVC_MAIN_10,       HEVCMain10),
71
#endif
69
#endif
72
#if HAS_VP9
70
#if HAS_VP9
73
    PE(VP9,         VP9_0,              VP9Profile0),
71
    PE(VP9,         VP9_0,              VP9Profile0),
74
#endif
72
#endif
75
    {0}
73
    {0}
76
};
74
};
77
 
75
 
78
int va_check_codec_support(enum AVCodecID id)
76
int va_check_codec_support(enum AVCodecID id)
79
{
77
{
80
    for (int n = 0; profiles[n].av_codec; n++) {
78
    for (int n = 0; profiles[n].av_codec; n++) {
81
        if (profiles[n].av_codec == id)
79
        if (profiles[n].av_codec == id)
82
            return 1;
80
            return 1;
83
    }
81
    }
84
    return 0;
82
    return 0;
85
}
83
}
86
 
84
 
87
static int vaapi_check_status(VAStatus status, const char *msg)
85
static int vaapi_check_status(VAStatus status, const char *msg)
88
{
86
{
89
    if (status != VA_STATUS_SUCCESS) {
87
    if (status != VA_STATUS_SUCCESS) {
90
        fprintf(stderr, "[%s] %s: %s\n", PACKAGE_NAME, msg, vaErrorStr(status));
88
        fprintf(stderr, "[%s] %s: %s\n", PACKAGE_NAME, msg, vaErrorStr(status));
91
        return 0;
89
        return 0;
92
    }
90
    }
93
    return 1;
91
    return 1;
94
};
92
};
95
 
93
 
96
static const char *string_of_VADisplayAttribType(VADisplayAttribType type)
94
static const char *string_of_VADisplayAttribType(VADisplayAttribType type)
97
{
95
{
98
    switch (type) {
96
    switch (type) {
99
#define TYPE(type) \
97
#define TYPE(type) \
100
        case VADisplayAttrib##type: return "VADisplayAttrib" #type
98
        case VADisplayAttrib##type: return "VADisplayAttrib" #type
101
        TYPE(Brightness);
99
        TYPE(Brightness);
102
        TYPE(Contrast);
100
        TYPE(Contrast);
103
        TYPE(Hue);
101
        TYPE(Hue);
104
        TYPE(Saturation);
102
        TYPE(Saturation);
105
        TYPE(BackgroundColor);
103
        TYPE(BackgroundColor);
106
#if !VA_CHECK_VERSION(0,34,0)
104
#if !VA_CHECK_VERSION(0,34,0)
107
        TYPE(DirectSurface);
105
        TYPE(DirectSurface);
108
#endif
106
#endif
109
#if VA_CHECK_VERSION(0,32,0)
107
#if VA_CHECK_VERSION(0,32,0)
110
        TYPE(Rotation);
108
        TYPE(Rotation);
111
#endif
109
#endif
112
#undef TYPE
110
#undef TYPE
113
    default: break;
111
    default: break;
114
    }
112
    }
115
    return "";
113
    return "";
116
}
114
}
117
 
115
 
118
static const char *string_of_VAProfile(VAProfile profile)
116
static const char *string_of_VAProfile(VAProfile profile)
119
{
117
{
120
    switch (profile) {
118
    switch (profile) {
121
#define PROFILE(profile) \
119
#define PROFILE(profile) \
122
        case VAProfile##profile: return "VAProfile" #profile
120
        case VAProfile##profile: return "VAProfile" #profile
123
        PROFILE(MPEG2Simple);
121
        PROFILE(MPEG2Simple);
124
        PROFILE(MPEG2Main);
122
        PROFILE(MPEG2Main);
125
        PROFILE(MPEG4Simple);
123
        PROFILE(MPEG4Simple);
126
        PROFILE(MPEG4AdvancedSimple);
124
        PROFILE(MPEG4AdvancedSimple);
127
        PROFILE(MPEG4Main);
125
        PROFILE(MPEG4Main);
128
#if VA_CHECK_VERSION(0,32,0)
126
#if VA_CHECK_VERSION(0,32,0)
129
        PROFILE(JPEGBaseline);
127
        PROFILE(JPEGBaseline);
130
        PROFILE(H263Baseline);
128
        PROFILE(H263Baseline);
131
        PROFILE(H264ConstrainedBaseline);
129
        PROFILE(H264ConstrainedBaseline);
132
#endif
130
#endif
133
        PROFILE(H264Baseline);
131
        PROFILE(H264Baseline);
134
        PROFILE(H264Main);
132
        PROFILE(H264Main);
135
        PROFILE(H264High);
133
        PROFILE(H264High);
136
        PROFILE(VC1Simple);
134
        PROFILE(VC1Simple);
137
        PROFILE(VC1Main);
135
        PROFILE(VC1Main);
138
        PROFILE(VC1Advanced);
136
        PROFILE(VC1Advanced);
139
#undef PROFILE
137
#undef PROFILE
140
    default: break;
138
    default: break;
141
    }
139
    }
142
    return "";
140
    return "";
143
}
141
}
144
 
142
 
145
static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint)
143
static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint)
146
{
144
{
147
    switch (entrypoint) {
145
    switch (entrypoint) {
148
#define ENTRYPOINT(entrypoint) \
146
#define ENTRYPOINT(entrypoint) \
149
        case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint
147
        case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint
150
        ENTRYPOINT(VLD);
148
        ENTRYPOINT(VLD);
151
        ENTRYPOINT(IZZ);
149
        ENTRYPOINT(IZZ);
152
        ENTRYPOINT(IDCT);
150
        ENTRYPOINT(IDCT);
153
        ENTRYPOINT(MoComp);
151
        ENTRYPOINT(MoComp);
154
        ENTRYPOINT(Deblocking);
152
        ENTRYPOINT(Deblocking);
155
#if VA_CHECK_VERSION(0,32,0)
153
#if VA_CHECK_VERSION(0,32,0)
156
        ENTRYPOINT(EncSlice);
154
        ENTRYPOINT(EncSlice);
157
        ENTRYPOINT(EncPicture);
155
        ENTRYPOINT(EncPicture);
158
#endif
156
#endif
159
#undef ENTRYPOINT
157
#undef ENTRYPOINT
160
    default: break;
158
    default: break;
161
    }
159
    }
162
    return "";
160
    return "";
163
}
161
}
164
 
162
 
165
VADisplay va_open_display(void)
163
VADisplay va_open_display(void)
166
{
164
{
167
    VADisplay va_dpy;
165
    VADisplay va_dpy;
168
 
166
 
169
    drm_fd = get_service("DISPLAY");
167
    drm_fd = get_service("DISPLAY");
170
    if (drm_fd == 0)
168
    if (drm_fd == 0)
171
        return NULL;
169
        return NULL;
172
 
170
 
173
    va_dpy = vaGetDisplayDRM(drm_fd);
171
    va_dpy = vaGetDisplayDRM(drm_fd);
174
    if (va_dpy)
172
    if (va_dpy)
175
        return va_dpy;
173
        return va_dpy;
176
 
174
 
177
    drm_fd = 0;
175
    drm_fd = 0;
178
    return NULL;
176
    return NULL;
179
};
177
};
180
 
178
 
181
int vaapi_init(VADisplay display)
179
int vaapi_init(VADisplay display)
182
{
180
{
183
    struct vaapi_context *vaapi;
181
    struct vaapi_context *vaapi;
184
    int major_version, minor_version;
182
    int major_version, minor_version;
185
    int i, num_display_attrs, max_display_attrs;
183
    int i, num_display_attrs, max_display_attrs;
186
    VADisplayAttribute *display_attrs = NULL;
184
    VADisplayAttribute *display_attrs = NULL;
187
    VAStatus status;
185
    VAStatus status;
188
 
186
 
189
    if (v_context)
187
    if (v_context)
190
        return 0;
188
        return 0;
191
 
189
 
192
    if (!display)
190
    if (!display)
193
        goto error;
191
        goto error;
194
    D(bug("VA display %p\n", display));
192
    D(bug("VA display %p\n", display));
195
 
193
 
196
    status = vaInitialize(display, &major_version, &minor_version);
194
    status = vaInitialize(display, &major_version, &minor_version);
197
    if (!vaapi_check_status(status, "vaInitialize()"))
195
    if (!vaapi_check_status(status, "vaInitialize()"))
198
        goto error;
196
        goto error;
199
    D(bug("VA API version %d.%d\n", major_version, minor_version));
197
    D(bug("VA API version %d.%d\n", major_version, minor_version));
200
 
198
 
201
    max_display_attrs = vaMaxNumDisplayAttributes(display);
199
    max_display_attrs = vaMaxNumDisplayAttributes(display);
202
    display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0]));
200
    display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0]));
203
    if (!display_attrs)
201
    if (!display_attrs)
204
        goto error;
202
        goto error;
205
 
203
 
206
    num_display_attrs = 0; /* XXX: workaround old GMA500 bug */
204
    num_display_attrs = 0; /* XXX: workaround old GMA500 bug */
207
    status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs);
205
    status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs);
208
    if (!vaapi_check_status(status, "vaQueryDisplayAttributes()"))
206
    if (!vaapi_check_status(status, "vaQueryDisplayAttributes()"))
209
        goto error;
207
        goto error;
210
    D(bug("%d display attributes available\n", num_display_attrs));
208
    D(bug("%d display attributes available\n", num_display_attrs));
211
    for (i = 0; i < num_display_attrs; i++) {
209
    for (i = 0; i < num_display_attrs; i++) {
212
        VADisplayAttribute * const display_attr = &display_attrs[i];
210
        VADisplayAttribute * const display_attr = &display_attrs[i];
213
        D(bug("  %-32s (%s/%s) min %d max %d value 0x%x\n",
211
        D(bug("  %-32s (%s/%s) min %d max %d value 0x%x\n",
214
              string_of_VADisplayAttribType(display_attr->type),
212
              string_of_VADisplayAttribType(display_attr->type),
215
              (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---",
213
              (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---",
216
              (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---",
214
              (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---",
217
              display_attr->min_value,
215
              display_attr->min_value,
218
              display_attr->max_value,
216
              display_attr->max_value,
219
              display_attr->value));
217
              display_attr->value));
220
    }
218
    }
221
 
219
 
222
    if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL)
220
    if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL)
223
        goto error;
221
        goto error;
224
    vaapi->display               = display;
222
    vaapi->display               = display;
225
    vaapi->config_id             = VA_INVALID_ID;
223
    vaapi->config_id             = VA_INVALID_ID;
226
    vaapi->context_id            = VA_INVALID_ID;
224
    vaapi->context_id            = VA_INVALID_ID;
227
//    vaapi->pic_param_buf_id      = VA_INVALID_ID;
-
 
228
//    vaapi->iq_matrix_buf_id      = VA_INVALID_ID;
-
 
229
//    vaapi->bitplane_buf_id       = VA_INVALID_ID;
-
 
230
 
225
 
231
    v_context = vaapi;
226
    v_context = vaapi;
232
 
227
 
233
    return 0;
228
    return 0;
234
 
229
 
235
error:
230
error:
236
    free(display_attrs);
231
    free(display_attrs);
237
    return -1;
232
    return -1;
238
}
233
}
239
 
234
 
240
 
235
 
241
static int has_profile(struct vaapi_context *vaapi, VAProfile profile)
236
static int has_profile(struct vaapi_context *vaapi, VAProfile profile)
242
{
237
{
243
    VAProfile *profiles;
238
    VAProfile *profiles;
244
    int        n_profiles;
239
    int        n_profiles;
245
    VAStatus   status;
240
    VAStatus   status;
246
    int i;
241
    int i;
247
 
242
 
248
    profiles = calloc(vaMaxNumProfiles(vaapi->display), sizeof(profiles[0]));
243
    profiles = calloc(vaMaxNumProfiles(vaapi->display), sizeof(profiles[0]));
249
 
244
 
250
    status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles);
245
    status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles);
251
 
246
 
252
    if (!vaapi_check_status(status, "vaQueryConfigProfiles()"))
247
    if (!vaapi_check_status(status, "vaQueryConfigProfiles()"))
253
        return 0;
248
        return 0;
254
 
249
 
255
    D(bug("%d profiles available\n", n_profiles));
250
    D(bug("%d profiles available\n", n_profiles));
256
 
251
 
257
    for (i = 0; i < n_profiles; i++)
252
    for (i = 0; i < n_profiles; i++)
258
    {
253
    {
259
        if (profiles[i] == profile)
254
        if (profiles[i] == profile)
260
            return 1;
255
            return 1;
261
    }
256
    }
262
    return 0;
257
    return 0;
263
}
258
}
264
 
259
 
265
static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint)
260
static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint)
266
{
261
{
267
    VAEntrypoint *entrypoints;
262
    VAEntrypoint *entrypoints;
268
    int           n_entrypoints;
263
    int           n_entrypoints;
269
    VAStatus      status;
264
    VAStatus      status;
270
    int i;
265
    int i;
271
 
266
 
272
    entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(entrypoints[0]));
267
    entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(entrypoints[0]));
273
 
268
 
274
    status = vaQueryConfigEntrypoints(vaapi->display, profile,
269
    status = vaQueryConfigEntrypoints(vaapi->display, profile,
275
                                      entrypoints, &n_entrypoints);
270
                                      entrypoints, &n_entrypoints);
276
    if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()"))
271
    if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()"))
277
        return 0;
272
        return 0;
278
 
273
 
279
    D(bug("%d entrypoints available for %s\n", n_entrypoints,
274
    D(bug("%d entrypoints available for %s\n", n_entrypoints,
280
          string_of_VAProfile(profile)));
275
          string_of_VAProfile(profile)));
281
 
276
 
282
    for (i = 0; i < n_entrypoints; i++)
277
    for (i = 0; i < n_entrypoints; i++)
283
    {
278
    {
284
        if (entrypoints[i] == entrypoint)
279
        if (entrypoints[i] == entrypoint)
285
            return 1;
280
            return 1;
286
    }
281
    }
287
    return 0;
282
    return 0;
288
}
283
}
289
 
284
 
290
static int vaapi_init_decoder(VAProfile    profile,
285
static int vaapi_init_decoder(VAProfile    profile,
291
                       VAEntrypoint entrypoint,
286
                       VAEntrypoint entrypoint,
292
                       unsigned int picture_width,
287
                       unsigned int picture_width,
293
                       unsigned int picture_height)
288
                       unsigned int picture_height)
294
{
289
{
295
    struct vaapi_context* const vaapi = v_context;
290
    struct vaapi_context* const vaapi = v_context;
296
    VAConfigAttrib attrib;
291
    VAConfigAttrib attrib;
297
    VAConfigID  config_id = VA_INVALID_ID;
292
    VAConfigID  config_id = VA_INVALID_ID;
298
    VAContextID context_id = VA_INVALID_ID;
293
    VAContextID context_id = VA_INVALID_ID;
299
    VAStatus status;
294
    VAStatus status;
300
 
295
 
301
ENTER();
296
ENTER();
302
    if (!vaapi)
297
    if (!vaapi)
303
    {
298
    {
304
        FAIL();
299
        FAIL();
305
        return -1;
300
        return -1;
306
    };
301
    };
307
 
302
 
308
    if (!has_profile(vaapi, profile))
303
    if (!has_profile(vaapi, profile))
309
    {
304
    {
310
        FAIL();
305
        FAIL();
311
        return -1;
306
        return -1;
312
    };
307
    };
313
 
308
 
314
    if (!has_entrypoint(vaapi, profile, entrypoint))
309
    if (!has_entrypoint(vaapi, profile, entrypoint))
315
    {
310
    {
316
        FAIL();
311
        FAIL();
317
        return -1;
312
        return -1;
318
    };
313
    };
319
 
314
 
320
    if (vaapi->config_id != VA_INVALID_ID)
315
    if (vaapi->config_id != VA_INVALID_ID)
321
        vaDestroyConfig(vaapi->display, vaapi->config_id);
316
        vaDestroyConfig(vaapi->display, vaapi->config_id);
322
 
317
 
323
    attrib.type = VAConfigAttribRTFormat;
318
    attrib.type = VAConfigAttribRTFormat;
324
 
319
 
325
    printf("vaGetConfigAttributes\n");
320
    printf("vaGetConfigAttributes\n");
326
    status = vaGetConfigAttributes(vaapi->display, profile, entrypoint,
321
    status = vaGetConfigAttributes(vaapi->display, profile, entrypoint,
327
                                   &attrib, 1);
322
                                   &attrib, 1);
328
    if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
323
    if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
329
    {
324
    {
330
        FAIL();
325
        FAIL();
331
        return -1;
326
        return -1;
332
    }
327
    }
333
 
328
 
334
    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
329
    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
335
    {
330
    {
336
        printf("Chroma format not supported.\n");
331
        printf("Chroma format not supported.\n");
337
        FAIL();
332
        FAIL();
338
        return -1;
333
        return -1;
339
    };
334
    };
340
 
335
 
341
    printf("vaCreateConfig\n");
336
    printf("vaCreateConfig\n");
342
    status = vaCreateConfig(vaapi->display, profile, entrypoint,
337
    status = vaCreateConfig(vaapi->display, profile, entrypoint,
343
                            &attrib, 1, &config_id);
338
                            &attrib, 1, &config_id);
344
    if (!vaapi_check_status(status, "vaCreateConfig()"))
339
    if (!vaapi_check_status(status, "vaCreateConfig()"))
345
    {
340
    {
346
        FAIL();
341
        FAIL();
347
        return -1;
342
        return -1;
348
    }
343
    }
349
 
344
 
350
    printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
345
    printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
351
    status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
346
    status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
352
                              v_surface_id,4,NULL,0);
347
                              v_surface_id,4,NULL,0);
353
    printf("v_surface_id_3 %x\n", v_surface_id[3]);
348
    printf("v_surface_id_3 %x\n", v_surface_id[3]);
354
    if (!vaapi_check_status(status, "vaCreateSurfaces()"))
349
    if (!vaapi_check_status(status, "vaCreateSurfaces()"))
355
    {
350
    {
356
        FAIL();
351
        FAIL();
357
        return -1;
352
        return -1;
358
    };
353
    };
359
    {
354
    {
360
        VAImage vaimage;
355
        VAImage vaimage;
361
        VABufferInfo info = {0};
356
        VABufferInfo info = {0};
362
 
357
 
363
        vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage);
358
        vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage);
364
        printf("vaDeriveImage: %x  fourcc: %x\n"
359
        printf("vaDeriveImage: %x  fourcc: %x\n"
365
               "offset0: %d pitch0: %d\n"
360
               "offset0: %d pitch0: %d\n"
366
               "offset1: %d pitch1: %d\n"
361
               "offset1: %d pitch1: %d\n"
367
               "offset2: %d pitch2: %d\n",
362
               "offset2: %d pitch2: %d\n",
368
                vaimage.buf, vaimage.format.fourcc,
363
                vaimage.buf, vaimage.format.fourcc,
369
                vaimage.offsets[0],vaimage.pitches[0],
364
                vaimage.offsets[0],vaimage.pitches[0],
370
                vaimage.offsets[1],vaimage.pitches[1],
365
                vaimage.offsets[1],vaimage.pitches[1],
371
                vaimage.offsets[2],vaimage.pitches[2]);
366
                vaimage.offsets[2],vaimage.pitches[2]);
372
 
367
 
373
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
368
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
374
        vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
369
        vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
375
        printf("vaAcquireBufferHandle: %x type: %x\n"
370
        printf("vaAcquireBufferHandle: %x type: %x\n"
376
                "mem type: %x mem size: %x\n",
371
                "mem type: %x mem size: %x\n",
377
                info.handle, info.type, info.mem_type, info.mem_size);
372
                info.handle, info.type, info.mem_type, info.mem_size);
378
 
373
 
379
        vaReleaseBufferHandle(vaapi->display, vaimage.buf);
374
        vaReleaseBufferHandle(vaapi->display, vaimage.buf);
380
 
375
 
381
        vaDestroyImage(vaapi->display,vaimage.image_id);
376
        vaDestroyImage(vaapi->display,vaimage.image_id);
382
    };
377
    };
383
 
378
 
384
    printf("vaCreateContext %dx%d\n",picture_width,picture_height);
379
    printf("vaCreateContext %dx%d\n",picture_width,picture_height);
385
    status = vaCreateContext(vaapi->display, config_id,
380
    status = vaCreateContext(vaapi->display, config_id,
386
                             picture_width, picture_height,
381
                             picture_width, picture_height,
387
                             VA_PROGRESSIVE,
382
                             VA_PROGRESSIVE,
388
                             v_surface_id, 4,
383
                             v_surface_id, 4,
389
                             &context_id);
384
                             &context_id);
390
    if (!vaapi_check_status(status, "vaCreateContext()"))
385
    if (!vaapi_check_status(status, "vaCreateContext()"))
391
    {
386
    {
392
        FAIL();
387
        FAIL();
393
        return -1;
388
        return -1;
394
    };
389
    };
395
 
390
 
396
    vaapi->config_id      = config_id;
391
    vaapi->config_id      = config_id;
397
    vaapi->context_id     = context_id;
392
    vaapi->context_id     = context_id;
398
    LEAVE();
393
    LEAVE();
399
    return 0;
394
    return 0;
400
}
395
}
401
 
396
 
402
 
397
 
403
static enum PixelFormat get_format(struct AVCodecContext *avctx,
398
static enum PixelFormat get_format(struct AVCodecContext *avctx,
404
                                   const enum AVPixelFormat *fmt)
399
                                   const enum AVPixelFormat *fmt)
405
{
400
{
406
    int i, profile;
401
    int i, profile;
407
 
402
 
408
    ENTER();
403
    ENTER();
409
 
404
 
410
//    for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++)
405
//    for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++)
411
//        printf(" %s", av_get_pix_fmt_name(fmt[i]));
406
//        printf(" %s", av_get_pix_fmt_name(fmt[i]));
412
 
407
 
413
    for (i = 0; fmt[i] != PIX_FMT_NONE; i++) {
408
    for (i = 0; fmt[i] != PIX_FMT_NONE; i++) {
414
        printf("pixformat %x\n", fmt[i]);
409
        printf("pixformat %x\n", fmt[i]);
415
        if (fmt[i] != AV_PIX_FMT_VAAPI_VLD)
410
        if (fmt[i] != AV_PIX_FMT_VAAPI_VLD)
416
            continue;
411
            continue;
417
 
412
 
418
        switch (avctx->codec_id)
413
        switch (avctx->codec_id)
419
        {
414
        {
420
        case CODEC_ID_MPEG2VIDEO:
415
        case CODEC_ID_MPEG2VIDEO:
421
            profile = VAProfileMPEG2Main;
416
            profile = VAProfileMPEG2Main;
422
            break;
417
            break;
423
        case CODEC_ID_MPEG4:
418
        case CODEC_ID_MPEG4:
424
        case CODEC_ID_H263:
419
        case CODEC_ID_H263:
425
            profile = VAProfileMPEG4AdvancedSimple;
420
            profile = VAProfileMPEG4AdvancedSimple;
426
            break;
421
            break;
427
        case CODEC_ID_H264:
422
        case CODEC_ID_H264:
428
            profile = VAProfileH264High;
423
            profile = VAProfileH264High;
429
            break;
424
            break;
430
        case CODEC_ID_WMV3:
425
        case CODEC_ID_WMV3:
431
            profile = VAProfileVC1Main;
426
            profile = VAProfileVC1Main;
432
            break;
427
            break;
433
        case CODEC_ID_VC1:
428
        case CODEC_ID_VC1:
434
            profile = VAProfileVC1Advanced;
429
            profile = VAProfileVC1Advanced;
435
            break;
430
            break;
436
        default:
431
        default:
437
            profile = -1;
432
            profile = -1;
438
            break;
433
            break;
439
        }
434
        }
440
        if (profile >= 0) {
435
        if (profile >= 0) {
441
            if (vaapi_init_decoder(profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
436
            if (vaapi_init_decoder(profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
442
            {
437
            {
443
                avctx->hwaccel_context = v_context;
438
                avctx->hwaccel_context = v_context;
444
                LEAVE();
439
                LEAVE();
445
                return fmt[i]; ;
440
                return fmt[i]; ;
446
            }
441
            }
447
        }
442
        }
448
    }
443
    }
449
    FAIL();
444
    FAIL();
450
    return PIX_FMT_NONE;
445
    return PIX_FMT_NONE;
451
}
446
}
452
 
447
 
453
struct av_surface
448
struct av_surface
454
{
449
{
455
    int         w;
450
    int         w;
456
    int         h;
451
    int         h;
457
    VASurfaceID id;
452
    VASurfaceID id;
458
};
453
};
459
 
454
 
460
static void av_release_buffer(void *opaque, uint8_t *data)
455
static void av_release_buffer(void *opaque, uint8_t *data)
461
{
456
{
462
    struct av_surface surface = *(struct av_surface*)data;
457
    struct av_surface surface = *(struct av_surface*)data;
463
//    VDPAUContext *ctx = opaque;
458
//    VDPAUContext *ctx = opaque;
464
 
459
 
465
//    ctx->video_surface_destroy(surface);
460
//    ctx->video_surface_destroy(surface);
466
    av_freep(&data);
461
    av_freep(&data);
467
}
462
}
468
 
-
 
469
 
463
 
470
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
464
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
-
 
465
{
471
{
466
    vst_t *vst = (vst_t*)avctx->opaque;
472
    void *surface = (void *)(uintptr_t)v_surface_id[dfx];
-
 
473
 
-
 
474
//    printf("%s surface %x\n", __FUNCTION__, surface);
-
 
475
 
467
    void *surface = (void *)(uintptr_t)v_surface_id[vst->dfx];
476
//    pic->type= FF_BUFFER_TYPE_USER;
468
 
477
    pic->data[3] = surface;
469
    pic->data[3] = surface;
478
 
470
 
479
    struct av_surface *avsurface;
471
    struct av_surface *avsurface;
480
    surface = av_malloc(sizeof(*avsurface));
472
    surface = av_malloc(sizeof(*avsurface));
481
    if (!surface)
473
    if (!surface)
482
        return AVERROR(ENOMEM);
474
        return AVERROR(ENOMEM);
483
 
475
 
484
    pic->buf[0] = av_buffer_create((uint8_t*)avsurface, sizeof(*avsurface),
476
    pic->buf[0] = av_buffer_create((uint8_t*)avsurface, sizeof(*avsurface),
485
                                     av_release_buffer, avctx,
477
                                     av_release_buffer, avctx,
486
                                     AV_BUFFER_FLAG_READONLY);
478
                                     AV_BUFFER_FLAG_READONLY);
487
    return 0;
479
    return 0;
488
}
480
}
489
 
481
 
490
struct vaapi_context va_context_storage;
482
struct vaapi_context va_context_storage;
491
 
483
 
492
int fplay_init_context(AVCodecContext *avctx)
484
int fplay_init_context(vst_t *vst)
493
{
485
{
-
 
486
    AVCodecContext *vCtx = vst->vCtx;
494
    ENTER();
487
 
495
 
488
    vCtx->opaque       = vst;
496
    avctx->thread_count    = 1;
489
    vCtx->thread_count = 1;
497
    avctx->get_format      = get_format;
-
 
498
    avctx->get_buffer2      = get_buffer2;
490
    vCtx->get_format   = get_format;
499
 
491
    vCtx->get_buffer2  = get_buffer2;
500
    LEAVE();
492
 
501
    return 0;
493
    return 0;
502
}
494
}
503
 
495
 
504
int fplay_vaapi_init(void)
496
int fplay_vaapi_init(void)
505
{
497
{
506
    VADisplay dpy;
498
    VADisplay dpy;
507
 
499
 
508
    dpy = va_open_display();
500
    dpy = va_open_display();
509
 
501
 
510
    if (vaapi_init(dpy) < 0)
502
    if (vaapi_init(dpy) < 0)
511
        return -1;
503
        return -1;
512
 
504
 
513
    return 0;
505
    return 0;
514
}
506
}
515
 
507
 
516
struct SwsContext *vacvt_ctx;
508
struct SwsContext *vacvt_ctx;
517
 
-
 
518
 
-
 
519
void va_sync()
-
 
520
{
-
 
521
    struct vaapi_context* const vaapi = v_context;
-
 
522
 
-
 
523
    vaSyncSurface(vaapi->display,v_surface_id[dfx]);
-
 
524
};
-
 
525
 
-
 
526
 
509
 
527
void va_convert_picture(int width, int height, AVPicture *pic)
510
void va_convert_picture(vst_t *vst, int width, int height, AVPicture *pic)
528
{
511
{
529
    uint8_t  *src_data[4];
512
    uint8_t  *src_data[4];
530
    int       src_linesize[4];
513
    int       src_linesize[4];
531
    VAImage vaimage;
514
    VAImage vaimage;
532
    VAStatus status;
515
    VAStatus status;
533
    uint8_t *vdata;
516
    uint8_t *vdata;
534
    struct vaapi_context* const vaapi = v_context;
517
    struct vaapi_context* const vaapi = v_context;
-
 
518
 
535
 
-
 
536
 
-
 
537
    va_sync();
519
    vaSyncSurface(vaapi->display,v_surface_id[vst->dfx]);
538
 
520
 
539
    status = vaDeriveImage(vaapi->display,v_surface_id[dfx],&vaimage);
521
    status = vaDeriveImage(vaapi->display,v_surface_id[vst->dfx],&vaimage);
540
    if (!vaapi_check_status(status, "vaDeriveImage()"))
522
    if (!vaapi_check_status(status, "vaDeriveImage()"))
541
    {
523
    {
542
        FAIL();
524
        FAIL();
543
        return;
525
        return;
544
    };
526
    };
545
 
527
 
546
    static int once = 2;
528
    static int once = 2;
547
 
529
 
548
    if(once && dfx == 0)
530
    if(once && vst->dfx == 0)
549
    {
531
    {
550
        VABufferInfo info = {0};
532
        VABufferInfo info = {0};
551
 
533
 
552
        printf("vaDeriveImage: %x  fourcc: %x\n"
534
        printf("vaDeriveImage: %x  fourcc: %x\n"
553
               "offset0: %d pitch0: %d\n"
535
               "offset0: %d pitch0: %d\n"
554
               "offset1: %d pitch1: %d\n"
536
               "offset1: %d pitch1: %d\n"
555
               "offset2: %d pitch2: %d\n",
537
               "offset2: %d pitch2: %d\n",
556
                vaimage.buf, vaimage.format.fourcc,
538
                vaimage.buf, vaimage.format.fourcc,
557
                vaimage.offsets[0],vaimage.pitches[0],
539
                vaimage.offsets[0],vaimage.pitches[0],
558
                vaimage.offsets[1],vaimage.pitches[1],
540
                vaimage.offsets[1],vaimage.pitches[1],
559
                vaimage.offsets[2],vaimage.pitches[2]);
541
                vaimage.offsets[2],vaimage.pitches[2]);
560
 
542
 
561
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
543
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
562
        status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
544
        status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
563
        if (vaapi_check_status(status, "vaAcquireBufferHandle()"))
545
        if (vaapi_check_status(status, "vaAcquireBufferHandle()"))
564
        {
546
        {
565
            printf("vaAcquireBufferHandle: %x type: %x\n"
547
            printf("vaAcquireBufferHandle: %x type: %x\n"
566
                    "mem type: %x mem size: %d\n",
548
                    "mem type: %x mem size: %d\n",
567
                    info.handle, info.type, info.mem_type, info.mem_size);
549
                    info.handle, info.type, info.mem_type, info.mem_size);
568
 
550
 
569
            vaReleaseBufferHandle(vaapi->display, vaimage.buf);
551
            vaReleaseBufferHandle(vaapi->display, vaimage.buf);
570
        }
552
        }
571
        once--;
553
        once--;
572
    };
554
    };
573
 
555
 
574
    src_linesize[0] = vaimage.pitches[0];
556
    src_linesize[0] = vaimage.pitches[0];
575
    src_linesize[1] = vaimage.pitches[1];
557
    src_linesize[1] = vaimage.pitches[1];
576
    src_linesize[2] = vaimage.pitches[2];
558
    src_linesize[2] = vaimage.pitches[2];
577
    src_linesize[3] = 0;
559
    src_linesize[3] = 0;
578
 
560
 
579
    status = vaMapBuffer(vaapi->display,vaimage.buf,(void **)&vdata);
561
    status = vaMapBuffer(vaapi->display,vaimage.buf,(void **)&vdata);
580
    if (!vaapi_check_status(status, "vaMapBuffer()"))
562
    if (!vaapi_check_status(status, "vaMapBuffer()"))
581
    {
563
    {
582
        FAIL();
564
        FAIL();
583
        return;
565
        return;
584
    };
566
    };
585
 
567
 
586
//    printf("vdata: %x offset0: %d offset1: %d offset2: %d\n", vdata,
568
//    printf("vdata: %x offset0: %d offset1: %d offset2: %d\n", vdata,
587
//            vaimage.offsets[0],
569
//            vaimage.offsets[0],
588
//            vaimage.offsets[1],
570
//            vaimage.offsets[1],
589
//            vaimage.offsets[2]);
571
//            vaimage.offsets[2]);
590
 
572
 
591
    src_data[0] = vdata + vaimage.offsets[0];
573
    src_data[0] = vdata + vaimage.offsets[0];
592
    src_data[1] = vdata + vaimage.offsets[1];
574
    src_data[1] = vdata + vaimage.offsets[1];
593
    src_data[2] = vdata + vaimage.offsets[2];
575
    src_data[2] = vdata + vaimage.offsets[2];
594
    src_data[3] = 0;
576
    src_data[3] = 0;
595
 
577
 
596
    vacvt_ctx = sws_getCachedContext(vacvt_ctx, width, height, AV_PIX_FMT_NV12,
578
    vacvt_ctx = sws_getCachedContext(vacvt_ctx, width, height, AV_PIX_FMT_NV12,
597
              width, height, AV_PIX_FMT_BGRA,
579
              width, height, AV_PIX_FMT_BGRA,
598
              SWS_FAST_BILINEAR, NULL, NULL, NULL);
580
              SWS_FAST_BILINEAR, NULL, NULL, NULL);
599
    if(vacvt_ctx == NULL)
581
    if(vacvt_ctx == NULL)
600
    {
582
    {
601
        printf("Cannot initialize the conversion context!\n");
583
        printf("Cannot initialize the conversion context!\n");
602
        return ;
584
        return ;
603
    };
585
    };
604
 
586
 
605
 
587
 
606
//    __asm__ volatile ("int3");
588
//    __asm__ volatile ("int3");
607
 
589
 
608
    sws_scale(vacvt_ctx, (const uint8_t* const *)src_data, src_linesize, 0, height, pic->data, pic->linesize);
590
    sws_scale(vacvt_ctx, (const uint8_t* const *)src_data, src_linesize, 0, height, pic->data, pic->linesize);
609
 
591
 
610
    vaUnmapBuffer (vaapi->display, vaimage.buf);
592
    vaUnmapBuffer (vaapi->display, vaimage.buf);
611
    vaDestroyImage(vaapi->display, vaimage.image_id);
593
    vaDestroyImage(vaapi->display, vaimage.image_id);
612
}
594
}