Subversion Repositories Kolibri OS

Rev

Rev 6438 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6438 Rev 6658
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 
13
#include 
14
#include "winlib/winlib.h"
14
#include "winlib/winlib.h"
15
#include "fplay.h"
15
#include "fplay.h"
16
 
16
 
17
struct hw_profile
17
struct hw_profile
18
{
18
{
19
    enum AVCodecID av_codec;
19
    enum AVCodecID av_codec;
20
    int ff_profile;
20
    int ff_profile;
21
    VAProfile va_profile;
21
    VAProfile va_profile;
22
};
22
};
23
 
23
 
24
 
24
 
25
#define ENTER()   printf("enter %s\n",__FUNCTION__)
25
#define ENTER()   printf("enter %s\n",__FUNCTION__)
26
#define LEAVE()   printf("leave %s\n",__FUNCTION__)
26
#define LEAVE()   printf("leave %s\n",__FUNCTION__)
27
#define FAIL()    printf("fail %s\n",__FUNCTION__)
27
#define FAIL()    printf("fail %s\n",__FUNCTION__)
28
 
28
 
29
 
29
 
30
#if DEBUG
30
#if DEBUG
31
# define D(x) x
31
# define D(x) x
32
# define bug printf
32
# define bug printf
33
#else
33
#else
34
# define D(x)
34
# define D(x)
35
#endif
35
#endif
36
 
36
 
37
#undef  ARRAY_ELEMS
37
#undef  ARRAY_ELEMS
38
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
38
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
-
 
39
 
-
 
40
struct va_decoder
-
 
41
{
-
 
42
    struct decoder decoder;
-
 
43
    VADisplay      dpy;
-
 
44
    void          *hwctx;
-
 
45
    VASurfaceID    v_surface_id[16];
-
 
46
};
-
 
47
 
-
 
48
static struct va_decoder va_decoder;
39
 
49
 
40
static int drm_fd = 0;
50
static int drm_fd = 0;
41
static struct vaapi_context *v_context;
51
static struct vaapi_context *v_context;
42
 
-
 
43
static VASurfaceID v_surface_id[16];
-
 
44
 
52
 
45
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
53
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
46
#define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0))
54
#define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0))
47
 
55
 
48
#define PE(av_codec_id, ff_profile, vdp_profile)                \
56
#define PE(av_codec_id, ff_profile, vdp_profile)                \
49
    {AV_CODEC_ID_ ## av_codec_id, FF_PROFILE_ ## ff_profile,    \
57
    {AV_CODEC_ID_ ## av_codec_id, FF_PROFILE_ ## ff_profile,    \
50
     VAProfile ## vdp_profile}
58
     VAProfile ## vdp_profile}
51
 
59
 
52
static const struct hw_profile hw_profiles[] = {
60
static const struct hw_profile hw_profiles[] = {
53
    PE(MPEG2VIDEO,  MPEG2_MAIN,         MPEG2Main),
61
    PE(MPEG2VIDEO,  MPEG2_MAIN,         MPEG2Main),
54
    PE(MPEG2VIDEO,  MPEG2_SIMPLE,       MPEG2Simple),
62
    PE(MPEG2VIDEO,  MPEG2_SIMPLE,       MPEG2Simple),
55
    PE(MPEG4,       MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple),
63
    PE(MPEG4,       MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple),
56
    PE(MPEG4,       MPEG4_MAIN,         MPEG4Main),
64
    PE(MPEG4,       MPEG4_MAIN,         MPEG4Main),
57
    PE(MPEG4,       MPEG4_SIMPLE,       MPEG4Simple),
65
    PE(MPEG4,       MPEG4_SIMPLE,       MPEG4Simple),
58
    PE(H264,        H264_HIGH,          H264High),
66
    PE(H264,        H264_HIGH,          H264High),
59
    PE(H264,        H264_MAIN,          H264Main),
67
    PE(H264,        H264_MAIN,          H264Main),
60
    PE(H264,        H264_CONSTRAINED_BASELINE, H264ConstrainedBaseline),
68
    PE(H264,        H264_CONSTRAINED_BASELINE, H264ConstrainedBaseline),
61
    PE(VC1,         VC1_ADVANCED,       VC1Advanced),
69
    PE(VC1,         VC1_ADVANCED,       VC1Advanced),
62
    PE(VC1,         VC1_MAIN,           VC1Main),
70
    PE(VC1,         VC1_MAIN,           VC1Main),
63
    PE(VC1,         VC1_SIMPLE,         VC1Simple),
71
    PE(VC1,         VC1_SIMPLE,         VC1Simple),
64
    PE(WMV3,        VC1_ADVANCED,       VC1Advanced),
72
    PE(WMV3,        VC1_ADVANCED,       VC1Advanced),
65
    PE(WMV3,        VC1_MAIN,           VC1Main),
73
    PE(WMV3,        VC1_MAIN,           VC1Main),
66
    PE(WMV3,        VC1_SIMPLE,         VC1Simple),
74
    PE(WMV3,        VC1_SIMPLE,         VC1Simple),
67
#if HAS_HEVC
75
#if HAS_HEVC
68
    PE(HEVC,        HEVC_MAIN,          HEVCMain),
76
    PE(HEVC,        HEVC_MAIN,          HEVCMain),
69
    PE(HEVC,        HEVC_MAIN_10,       HEVCMain10),
77
    PE(HEVC,        HEVC_MAIN_10,       HEVCMain10),
70
#endif
78
#endif
71
#if HAS_VP9
79
#if HAS_VP9
72
    PE(VP9,         VP9_0,              VP9Profile0),
80
    PE(VP9,         VP9_0,              VP9Profile0),
73
#endif
81
#endif
74
    {0}
82
    {0}
75
};
83
};
76
 
84
 
77
int va_check_codec_support(enum AVCodecID id)
85
int va_check_codec_support(enum AVCodecID id)
78
{
86
{
79
    for (int n = 0; hw_profiles[n].av_codec; n++) {
87
    for (int n = 0; hw_profiles[n].av_codec; n++) {
80
        if (hw_profiles[n].av_codec == id)
88
        if (hw_profiles[n].av_codec == id)
81
            return 1;
89
            return 1;
82
    }
90
    }
83
    return 0;
91
    return 0;
84
}
92
}
85
 
93
 
86
static int vaapi_check_status(VAStatus status, const char *msg)
94
static int vaapi_check_status(VAStatus status, const char *msg)
87
{
95
{
88
    if (status != VA_STATUS_SUCCESS) {
96
    if (status != VA_STATUS_SUCCESS) {
89
        fprintf(stderr, "[%s] %s: %s\n", PACKAGE_NAME, msg, vaErrorStr(status));
97
        fprintf(stderr, "[%s] %s: %s\n", PACKAGE_NAME, msg, vaErrorStr(status));
90
        return 0;
98
        return 0;
91
    }
99
    }
92
    return 1;
100
    return 1;
93
};
101
};
94
 
102
 
95
static const char *string_of_VADisplayAttribType(VADisplayAttribType type)
103
static const char *string_of_VADisplayAttribType(VADisplayAttribType type)
96
{
104
{
97
    switch (type) {
105
    switch (type) {
98
#define TYPE(type) \
106
#define TYPE(type) \
99
        case VADisplayAttrib##type: return "VADisplayAttrib" #type
107
        case VADisplayAttrib##type: return "VADisplayAttrib" #type
100
        TYPE(Brightness);
108
        TYPE(Brightness);
101
        TYPE(Contrast);
109
        TYPE(Contrast);
102
        TYPE(Hue);
110
        TYPE(Hue);
103
        TYPE(Saturation);
111
        TYPE(Saturation);
104
        TYPE(BackgroundColor);
112
        TYPE(BackgroundColor);
105
#if !VA_CHECK_VERSION(0,34,0)
113
#if !VA_CHECK_VERSION(0,34,0)
106
        TYPE(DirectSurface);
114
        TYPE(DirectSurface);
107
#endif
115
#endif
108
#if VA_CHECK_VERSION(0,32,0)
116
#if VA_CHECK_VERSION(0,32,0)
109
        TYPE(Rotation);
117
        TYPE(Rotation);
110
#endif
118
#endif
111
#undef TYPE
119
#undef TYPE
112
    default: break;
120
    default: break;
113
    }
121
    }
114
    return "";
122
    return "";
115
}
123
}
116
 
124
 
117
static const char *string_of_VAProfile(VAProfile profile)
125
static const char *string_of_VAProfile(VAProfile profile)
118
{
126
{
119
    switch (profile) {
127
    switch (profile) {
120
#define PROFILE(profile) \
128
#define PROFILE(profile) \
121
        case VAProfile##profile: return "VAProfile" #profile
129
        case VAProfile##profile: return "VAProfile" #profile
122
        PROFILE(MPEG2Simple);
130
        PROFILE(MPEG2Simple);
123
        PROFILE(MPEG2Main);
131
        PROFILE(MPEG2Main);
124
        PROFILE(MPEG4Simple);
132
        PROFILE(MPEG4Simple);
125
        PROFILE(MPEG4AdvancedSimple);
133
        PROFILE(MPEG4AdvancedSimple);
126
        PROFILE(MPEG4Main);
134
        PROFILE(MPEG4Main);
127
#if VA_CHECK_VERSION(0,32,0)
135
#if VA_CHECK_VERSION(0,32,0)
128
        PROFILE(JPEGBaseline);
136
        PROFILE(JPEGBaseline);
129
        PROFILE(H263Baseline);
137
        PROFILE(H263Baseline);
130
        PROFILE(H264ConstrainedBaseline);
138
        PROFILE(H264ConstrainedBaseline);
131
#endif
139
#endif
132
        PROFILE(H264Baseline);
140
        PROFILE(H264Baseline);
133
        PROFILE(H264Main);
141
        PROFILE(H264Main);
134
        PROFILE(H264High);
142
        PROFILE(H264High);
135
        PROFILE(VC1Simple);
143
        PROFILE(VC1Simple);
136
        PROFILE(VC1Main);
144
        PROFILE(VC1Main);
137
        PROFILE(VC1Advanced);
145
        PROFILE(VC1Advanced);
138
#undef PROFILE
146
#undef PROFILE
139
    default: break;
147
    default: break;
140
    }
148
    }
141
    return "";
149
    return "";
142
}
150
}
143
 
151
 
144
static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint)
152
static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint)
145
{
153
{
146
    switch (entrypoint) {
154
    switch (entrypoint) {
147
#define ENTRYPOINT(entrypoint) \
155
#define ENTRYPOINT(entrypoint) \
148
        case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint
156
        case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint
149
        ENTRYPOINT(VLD);
157
        ENTRYPOINT(VLD);
150
        ENTRYPOINT(IZZ);
158
        ENTRYPOINT(IZZ);
151
        ENTRYPOINT(IDCT);
159
        ENTRYPOINT(IDCT);
152
        ENTRYPOINT(MoComp);
160
        ENTRYPOINT(MoComp);
153
        ENTRYPOINT(Deblocking);
161
        ENTRYPOINT(Deblocking);
154
#if VA_CHECK_VERSION(0,32,0)
162
#if VA_CHECK_VERSION(0,32,0)
155
        ENTRYPOINT(EncSlice);
163
        ENTRYPOINT(EncSlice);
156
        ENTRYPOINT(EncPicture);
164
        ENTRYPOINT(EncPicture);
157
#endif
165
#endif
158
#undef ENTRYPOINT
166
#undef ENTRYPOINT
159
    default: break;
167
    default: break;
160
    }
168
    }
161
    return "";
169
    return "";
162
}
170
}
163
 
171
 
164
 
172
 
165
void *vaapi_init(VADisplay display)
173
void *vaapi_init(VADisplay display)
166
{
174
{
167
    struct vaapi_context *vaapi;
175
    struct vaapi_context *vaapi;
168
    int major_version, minor_version;
176
    int major_version, minor_version;
169
    int i, num_display_attrs, max_display_attrs;
177
    int i, num_display_attrs, max_display_attrs;
170
    VADisplayAttribute *display_attrs = NULL;
178
    VADisplayAttribute *display_attrs = NULL;
171
    VAStatus status;
179
    VAStatus status;
172
 
180
 
173
    if (v_context)
181
    if (v_context)
174
        return 0;
182
        return 0;
175
 
183
 
176
    if (!display)
184
    if (!display)
177
        goto error;
185
        goto error;
178
    D(bug("VA display %p\n", display));
186
    D(bug("VA display %p\n", display));
179
 
187
 
180
    status = vaInitialize(display, &major_version, &minor_version);
188
    status = vaInitialize(display, &major_version, &minor_version);
181
    if (!vaapi_check_status(status, "vaInitialize()"))
189
    if (!vaapi_check_status(status, "vaInitialize()"))
182
        goto error;
190
        goto error;
183
    D(bug("VA API version %d.%d\n", major_version, minor_version));
191
    D(bug("VA API version %d.%d\n", major_version, minor_version));
184
 
192
 
185
    max_display_attrs = vaMaxNumDisplayAttributes(display);
193
    max_display_attrs = vaMaxNumDisplayAttributes(display);
186
    display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0]));
194
    display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0]));
187
    if (!display_attrs)
195
    if (!display_attrs)
188
        goto error;
196
        goto error;
189
 
197
 
190
    num_display_attrs = 0; /* XXX: workaround old GMA500 bug */
198
    num_display_attrs = 0; /* XXX: workaround old GMA500 bug */
191
    status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs);
199
    status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs);
192
    if (!vaapi_check_status(status, "vaQueryDisplayAttributes()"))
200
    if (!vaapi_check_status(status, "vaQueryDisplayAttributes()"))
193
        goto error;
201
        goto error;
194
    D(bug("%d display attributes available\n", num_display_attrs));
202
    D(bug("%d display attributes available\n", num_display_attrs));
195
    for (i = 0; i < num_display_attrs; i++) {
203
    for (i = 0; i < num_display_attrs; i++) {
196
        VADisplayAttribute * const display_attr = &display_attrs[i];
204
        VADisplayAttribute * const display_attr = &display_attrs[i];
197
        D(bug("  %-32s (%s/%s) min %d max %d value 0x%x\n",
205
        D(bug("  %-32s (%s/%s) min %d max %d value 0x%x\n",
198
              string_of_VADisplayAttribType(display_attr->type),
206
              string_of_VADisplayAttribType(display_attr->type),
199
              (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---",
207
              (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---",
200
              (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---",
208
              (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---",
201
              display_attr->min_value,
209
              display_attr->min_value,
202
              display_attr->max_value,
210
              display_attr->max_value,
203
              display_attr->value));
211
              display_attr->value));
204
    }
212
    }
205
 
213
 
206
    if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL)
214
    if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL)
207
        goto error;
215
        goto error;
208
    vaapi->display    = display;
216
    vaapi->display    = display;
209
    vaapi->config_id  = VA_INVALID_ID;
217
    vaapi->config_id  = VA_INVALID_ID;
210
    vaapi->context_id = VA_INVALID_ID;
218
    vaapi->context_id = VA_INVALID_ID;
211
 
219
 
212
    v_context = vaapi;
220
    v_context = vaapi;
213
 
221
 
214
    return vaapi;
222
    return vaapi;
215
 
223
 
216
error:
224
error:
217
    free(display_attrs);
225
    free(display_attrs);
218
    return NULL;
226
    return NULL;
219
}
227
}
220
 
228
 
221
static int has_profile(struct vaapi_context *vaapi, VAProfile profile)
229
static int has_profile(struct vaapi_context *vaapi, VAProfile profile)
222
{
230
{
223
    VAProfile *profiles;
231
    VAProfile *profiles;
224
    int        n_profiles;
232
    int        n_profiles;
225
    size_t size;
233
    size_t size;
226
    VAStatus   status;
234
    VAStatus   status;
227
    int i;
235
    int i;
228
 
236
 
229
    size = vaMaxNumProfiles(vaapi->display) * sizeof(VAProfile);
237
    size = vaMaxNumProfiles(vaapi->display) * sizeof(VAProfile);
230
 
238
 
231
    profiles = alloca(size);
239
    profiles = alloca(size);
232
    memset(profiles, 0, size);
240
    memset(profiles, 0, size);
233
 
241
 
234
    status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles);
242
    status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles);
235
 
243
 
236
    if (!vaapi_check_status(status, "vaQueryConfigProfiles()"))
244
    if (!vaapi_check_status(status, "vaQueryConfigProfiles()"))
237
        return 0;
245
        return 0;
238
 
246
 
239
    D(bug("%d profiles available\n", n_profiles));
247
    D(bug("%d profiles available\n", n_profiles));
240
 
248
 
241
    for (i = 0; i < n_profiles; i++)
249
    for (i = 0; i < n_profiles; i++)
242
    {
250
    {
243
        if (profiles[i] == profile)
251
        if (profiles[i] == profile)
244
            return 1;
252
            return 1;
245
    }
253
    }
246
    return 0;
254
    return 0;
247
}
255
}
248
 
256
 
249
static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint)
257
static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint)
250
{
258
{
251
    VAEntrypoint *entrypoints;
259
    VAEntrypoint *entrypoints;
252
    int           n_entrypoints;
260
    int           n_entrypoints;
253
    size_t size;
261
    size_t size;
254
    VAStatus      status;
262
    VAStatus      status;
255
    int i;
263
    int i;
256
 
264
 
257
    size = vaMaxNumEntrypoints(vaapi->display) * sizeof(VAEntrypoint);
265
    size = vaMaxNumEntrypoints(vaapi->display) * sizeof(VAEntrypoint);
258
 
266
 
259
    entrypoints = alloca(size);
267
    entrypoints = alloca(size);
260
    memset(entrypoints, 0, size);
268
    memset(entrypoints, 0, size);
261
 
269
 
262
    status = vaQueryConfigEntrypoints(vaapi->display, profile,
270
    status = vaQueryConfigEntrypoints(vaapi->display, profile,
263
                                      entrypoints, &n_entrypoints);
271
                                      entrypoints, &n_entrypoints);
264
    if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()"))
272
    if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()"))
265
        return 0;
273
        return 0;
266
 
274
 
267
    D(bug("%d entrypoints available for %s\n", n_entrypoints,
275
    D(bug("%d entrypoints available for %s\n", n_entrypoints,
268
          string_of_VAProfile(profile)));
276
          string_of_VAProfile(profile)));
269
 
277
 
270
    for (i = 0; i < n_entrypoints; i++)
278
    for (i = 0; i < n_entrypoints; i++)
271
    {
279
    {
272
        if (entrypoints[i] == entrypoint)
280
        if (entrypoints[i] == entrypoint)
273
            return 1;
281
            return 1;
274
    }
282
    }
275
    return 0;
283
    return 0;
276
}
284
}
277
 
285
 
278
static int vaapi_init_decoder(vst_t *vst,VAProfile profile,
286
static int vaapi_init_decoder(vst_t *vst,VAProfile profile,
279
                              VAEntrypoint entrypoint,
287
                              VAEntrypoint entrypoint,
280
                              unsigned int picture_width,
288
                              unsigned int picture_width,
281
                              unsigned int picture_height)
289
                              unsigned int picture_height)
282
{
290
{
283
    struct vaapi_context* const vaapi = v_context;
291
    struct vaapi_context* const vaapi = v_context;
-
 
292
    struct va_decoder *hw_decoder = (struct va_decoder*)vst->decoder;
284
    VAConfigAttrib attrib;
293
    VAConfigAttrib attrib;
285
    VAConfigID  config_id = VA_INVALID_ID;
294
    VAConfigID  config_id = VA_INVALID_ID;
286
    VAContextID context_id = VA_INVALID_ID;
295
    VAContextID context_id = VA_INVALID_ID;
287
    VAStatus status;
296
    VAStatus status;
288
 
297
 
289
ENTER();
298
ENTER();
290
 
299
 
291
    printf("%s profile %x width:%d height:%d\n",
300
    printf("%s profile %x width:%d height:%d\n",
292
            __FUNCTION__, profile, picture_width, picture_height);
301
            __FUNCTION__, profile, picture_width, picture_height);
293
 
302
 
294
    if (!vaapi)
303
    if (!vaapi)
295
    {
304
    {
296
        FAIL();
305
        FAIL();
297
        return -1;
306
        return -1;
298
    };
307
    };
299
 
308
 
300
    if (!has_profile(vaapi, profile))
309
    if (!has_profile(vaapi, profile))
301
    {
310
    {
302
        FAIL();
311
        FAIL();
303
        return -1;
312
        return -1;
304
    };
313
    };
305
 
314
 
306
    if (!has_entrypoint(vaapi, profile, entrypoint))
315
    if (!has_entrypoint(vaapi, profile, entrypoint))
307
    {
316
    {
308
        FAIL();
317
        FAIL();
309
        return -1;
318
        return -1;
310
    };
319
    };
-
 
320
 
-
 
321
    if (vaapi->context_id != VA_INVALID_ID)
-
 
322
        vaDestroyContext(vaapi->display, vaapi->context_id);
-
 
323
 
-
 
324
    if (hw_decoder->decoder.has_surfaces)
-
 
325
    {
-
 
326
        vaDestroySurfaces(vaapi->display,hw_decoder->v_surface_id,hw_decoder->decoder.nframes);
-
 
327
        hw_decoder->decoder.has_surfaces = 0;
-
 
328
    }
311
 
329
 
312
    if (vaapi->config_id != VA_INVALID_ID)
330
    if (vaapi->config_id != VA_INVALID_ID)
313
        vaDestroyConfig(vaapi->display, vaapi->config_id);
331
        vaDestroyConfig(vaapi->display, vaapi->config_id);
-
 
332
 
314
 
333
 
315
    attrib.type = VAConfigAttribRTFormat;
334
    attrib.type = VAConfigAttribRTFormat;
316
 
335
 
317
    printf("vaGetConfigAttributes\n");
336
    printf("vaGetConfigAttributes\n");
318
    status = vaGetConfigAttributes(vaapi->display, profile, entrypoint,
337
    status = vaGetConfigAttributes(vaapi->display, profile, entrypoint,
319
                                   &attrib, 1);
338
                                   &attrib, 1);
320
    if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
339
    if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
321
    {
340
    {
322
        FAIL();
341
        FAIL();
323
        return -1;
342
        return -1;
324
    }
343
    }
325
 
344
 
326
    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
345
    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
327
    {
346
    {
328
        printf("Chroma format not supported.\n");
347
        printf("Chroma format not supported.\n");
329
        FAIL();
348
        FAIL();
330
        return -1;
349
        return -1;
331
    };
350
    };
332
 
351
 
333
    printf("vaCreateConfig\n");
352
    printf("vaCreateConfig\n");
334
    status = vaCreateConfig(vaapi->display, profile, entrypoint,
353
    status = vaCreateConfig(vaapi->display, profile, entrypoint,
335
                            &attrib, 1, &config_id);
354
                            &attrib, 1, &config_id);
336
    if (!vaapi_check_status(status, "vaCreateConfig()"))
355
    if (!vaapi_check_status(status, "vaCreateConfig()"))
337
    {
356
    {
338
        FAIL();
357
        FAIL();
339
        return -1;
358
        return -1;
340
    }
359
    }
341
 
360
 
342
    printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
361
    printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
343
    status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
362
    status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
344
                              v_surface_id,vst->decoder->nframes,NULL,0);
363
                              hw_decoder->v_surface_id,hw_decoder->decoder.nframes,NULL,0);
345
    if (!vaapi_check_status(status, "vaCreateSurfaces()"))
364
    if (!vaapi_check_status(status, "vaCreateSurfaces()"))
346
    {
365
    {
347
        FAIL();
366
        FAIL();
348
        return -1;
367
        return -1;
349
    };
368
    };
-
 
369
 
-
 
370
    hw_decoder->decoder.has_surfaces = 1;
-
 
371
 
350
    {
372
    {
351
        VAImage vaimage;
373
        VAImage vaimage;
352
        VABufferInfo info = {0};
374
        VABufferInfo info = {0};
353
 
375
 
354
        vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage);
376
        vaDeriveImage(vaapi->display,hw_decoder->v_surface_id[0],&vaimage);
355
        printf("vaDeriveImage: %x  fourcc: %x\n"
377
        printf("vaDeriveImage: %x  fourcc: %x\n"
356
               "offset0: %d pitch0: %d\n"
378
               "offset0: %d pitch0: %d\n"
357
               "offset1: %d pitch1: %d\n"
379
               "offset1: %d pitch1: %d\n"
358
               "offset2: %d pitch2: %d\n",
380
               "offset2: %d pitch2: %d\n",
359
                vaimage.buf, vaimage.format.fourcc,
381
                vaimage.buf, vaimage.format.fourcc,
360
                vaimage.offsets[0],vaimage.pitches[0],
382
                vaimage.offsets[0],vaimage.pitches[0],
361
                vaimage.offsets[1],vaimage.pitches[1],
383
                vaimage.offsets[1],vaimage.pitches[1],
362
                vaimage.offsets[2],vaimage.pitches[2]);
384
                vaimage.offsets[2],vaimage.pitches[2]);
363
 
385
 
364
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
386
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
365
        vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
387
        vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
366
        printf("vaAcquireBufferHandle: %x type: %x\n"
388
        printf("vaAcquireBufferHandle: %x type: %x\n"
367
                "mem type: %x mem size: %x\n",
389
                "mem type: %x mem size: %x\n",
368
                info.handle, info.type, info.mem_type, info.mem_size);
390
                info.handle, info.type, info.mem_type, info.mem_size);
369
 
391
 
370
        vaReleaseBufferHandle(vaapi->display, vaimage.buf);
392
        vaReleaseBufferHandle(vaapi->display, vaimage.buf);
371
 
393
 
372
        vaDestroyImage(vaapi->display,vaimage.image_id);
394
        vaDestroyImage(vaapi->display,vaimage.image_id);
373
    };
395
    };
374
 
396
 
375
    printf("vaCreateContext %dx%d\n",picture_width,picture_height);
397
    printf("vaCreateContext %dx%d\n",picture_width,picture_height);
376
    status = vaCreateContext(vaapi->display, config_id,
398
    status = vaCreateContext(vaapi->display, config_id,
377
                             picture_width, picture_height,
399
                             picture_width, picture_height,
378
                             VA_PROGRESSIVE,
400
                             VA_PROGRESSIVE,
379
                             v_surface_id, vst->decoder->nframes,
401
                             hw_decoder->v_surface_id, vst->decoder->nframes,
380
                             &context_id);
402
                             &context_id);
381
    if (!vaapi_check_status(status, "vaCreateContext()"))
403
    if (!vaapi_check_status(status, "vaCreateContext()"))
382
    {
404
    {
383
        FAIL();
405
        FAIL();
384
        return -1;
406
        return -1;
385
    };
407
    };
386
 
408
 
387
    vaapi->config_id  = config_id;
409
    vaapi->config_id  = config_id;
388
    vaapi->context_id = context_id;
410
    vaapi->context_id = context_id;
389
    LEAVE();
411
    LEAVE();
390
    return 0;
412
    return 0;
391
}
413
}
392
 
414
 
393
 
415
 
394
static enum PixelFormat get_format(struct AVCodecContext *avctx,
416
static enum PixelFormat get_format(struct AVCodecContext *avctx,
395
                                   const enum AVPixelFormat *fmt)
417
                                   const enum AVPixelFormat *fmt)
396
{
418
{
397
    vst_t *vst = (vst_t*)avctx->opaque;
419
    vst_t *vst = (vst_t*)avctx->opaque;
-
 
420
    struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder;
-
 
421
    struct decoder* decoder = &hw_decoder->decoder;
398
    VAProfile profile = avctx->profile;
422
    VAProfile profile = avctx->profile;
399
    enum AVCodecID codec = avctx->codec_id;
423
    enum AVCodecID codec = avctx->codec_id;
400
 
424
 
401
    if (codec == AV_CODEC_ID_H264)
425
    if(avctx->hwaccel_context != NULL)
402
    {
-
 
403
        if(profile == FF_PROFILE_H264_BASELINE)
-
 
404
            profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
-
 
405
    };
-
 
406
 
-
 
407
    if(avctx->hwaccel_context != NULL &&
426
    {
408
       (vst->codec_id != codec ||
427
        if(decoder->codec_id != avctx->codec_id ||
409
       vst->codec_profile != profile))
428
           decoder->profile  != avctx->profile)
410
    {
-
 
411
        struct decoder* decoder = vst->decoder;
-
 
412
 
429
    {
413
        printf("\n%s codec changed!!!\n"
430
        printf("\n%s codec changed!!!\n"
414
               "old id %d profile %x new id %d profile %x\n",
431
               "old id %d profile %x new id %d profile %x\n",
415
                __FUNCTION__, vst->codec_id, vst->codec_profile,
432
                    __FUNCTION__, decoder->codec_id, decoder->profile,
416
                codec, profile);
433
                codec, profile);
417
 
434
 
418
        for(int i = 0; i < decoder->nframes; i++)
435
        for(int i = 0; i < decoder->nframes; i++)
419
        {
436
        {
420
            vframe_t *vframe = &decoder->vframes[i];
437
            vframe_t *vframe = &decoder->vframes[i];
421
            vframe->format   = AV_PIX_FMT_NONE;
438
            vframe->format   = AV_PIX_FMT_NONE;
422
        };
439
        };
423
    }
440
    }
-
 
441
        else
-
 
442
            return AV_PIX_FMT_VAAPI_VLD;
-
 
443
    }
-
 
444
 
-
 
445
    if (codec == AV_CODEC_ID_H264)
-
 
446
    {
-
 
447
        if(profile == FF_PROFILE_H264_BASELINE)
-
 
448
            profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
-
 
449
    };
424
 
450
 
425
    printf("\n%s codec %d profile %x\n", __FUNCTION__,avctx->codec_id, avctx->profile);
451
    printf("\n%s codec %d profile %x\n", __FUNCTION__,avctx->codec_id, avctx->profile);
426
 
452
 
427
    for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
453
    for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
428
    {
454
    {
429
        if (fmt[i] != AV_PIX_FMT_VAAPI_VLD)
455
        if (fmt[i] != AV_PIX_FMT_VAAPI_VLD)
430
            continue;
456
            continue;
431
 
457
 
432
        for (int n = 0; hw_profiles[n].av_codec; n++)
458
        for (int n = 0; hw_profiles[n].av_codec; n++)
433
        {
459
        {
434
            if (hw_profiles[n].av_codec   == codec &&
460
            if (hw_profiles[n].av_codec   == codec &&
435
                hw_profiles[n].ff_profile == profile)
461
                hw_profiles[n].ff_profile == profile)
436
            {
462
            {
437
                profile = hw_profiles[n].va_profile;
463
                profile = hw_profiles[n].va_profile;
438
                if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
464
                if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
439
                {
465
                {
440
                    avctx->hwaccel_context = v_context;
466
                    avctx->hwaccel_context = v_context;
441
                    vst->codec_id = codec;
-
 
442
                    vst->codec_profile = profile;
-
 
443
                    printf("%s format: %x\n",__FUNCTION__, fmt[i]);
467
                    printf("%s format: %x\n",__FUNCTION__, fmt[i]);
444
                    return fmt[i];
468
                    return fmt[i];
445
                }
469
                }
446
            }
470
            }
447
        }
471
        }
448
 
472
 
449
    }
473
    }
450
    printf("%s format PIX_FMT_NONE\n",__FUNCTION__);
474
    printf("%s format PIX_FMT_NONE\n",__FUNCTION__);
451
    return PIX_FMT_NONE;
475
    return PIX_FMT_NONE;
452
}
476
}
453
 
477
 
454
struct av_surface
478
struct av_surface
455
{
479
{
456
    int         w;
480
    int         w;
457
    int         h;
481
    int         h;
458
    VASurfaceID id;
482
    VASurfaceID id;
459
};
483
};
460
 
484
 
461
static void av_release_buffer(void *opaque, uint8_t *data)
485
static void av_release_buffer(void *opaque, uint8_t *data)
462
{
486
{
463
}
487
}
464
 
488
 
465
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
489
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
466
{
490
{
467
    static struct av_surface avsurface;
491
    static struct av_surface avsurface;
468
    vst_t *vst = (vst_t*)avctx->opaque;
492
    vst_t *vst = (vst_t*)avctx->opaque;
-
 
493
    struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder;
469
    void *surface;
494
    void *surface;
470
 
495
 
471
    surface = (void *)(uintptr_t)v_surface_id[vst->decoder->active_frame->index];
496
    surface = (void *)(uintptr_t)hw_decoder->v_surface_id[vst->decoder->active_frame->index];
472
 
497
 
473
    pic->data[3] = surface;
498
    pic->data[3] = surface;
474
 
499
 
475
    pic->buf[0] = av_buffer_create((uint8_t*)&avsurface, sizeof(avsurface),
500
    pic->buf[0] = av_buffer_create((uint8_t*)&avsurface, sizeof(avsurface),
476
                                    av_release_buffer, avctx,
501
                                    av_release_buffer, avctx,
477
                                    AV_BUFFER_FLAG_READONLY);
502
                                    AV_BUFFER_FLAG_READONLY);
478
    return 0;
503
    return 0;
479
}
504
}
480
 
505
 
481
 
506
 
482
#define EGL_TEXTURE_Y_U_V_WL            0x31D7
507
#define EGL_TEXTURE_Y_U_V_WL            0x31D7
483
#define EGL_TEXTURE_Y_UV_WL             0x31D8
508
#define EGL_TEXTURE_Y_UV_WL             0x31D8
484
#define EGL_TEXTURE_Y_XUXV_WL           0x31D9
509
#define EGL_TEXTURE_Y_XUXV_WL           0x31D9
485
 
510
 
486
enum wl_drm_format {
511
enum wl_drm_format {
487
    WL_DRM_FORMAT_C8 = 0x20203843,
512
    WL_DRM_FORMAT_C8 = 0x20203843,
488
    WL_DRM_FORMAT_RGB332 = 0x38424752,
513
    WL_DRM_FORMAT_RGB332 = 0x38424752,
489
    WL_DRM_FORMAT_BGR233 = 0x38524742,
514
    WL_DRM_FORMAT_BGR233 = 0x38524742,
490
    WL_DRM_FORMAT_XRGB4444 = 0x32315258,
515
    WL_DRM_FORMAT_XRGB4444 = 0x32315258,
491
    WL_DRM_FORMAT_XBGR4444 = 0x32314258,
516
    WL_DRM_FORMAT_XBGR4444 = 0x32314258,
492
    WL_DRM_FORMAT_RGBX4444 = 0x32315852,
517
    WL_DRM_FORMAT_RGBX4444 = 0x32315852,
493
    WL_DRM_FORMAT_BGRX4444 = 0x32315842,
518
    WL_DRM_FORMAT_BGRX4444 = 0x32315842,
494
    WL_DRM_FORMAT_ARGB4444 = 0x32315241,
519
    WL_DRM_FORMAT_ARGB4444 = 0x32315241,
495
    WL_DRM_FORMAT_ABGR4444 = 0x32314241,
520
    WL_DRM_FORMAT_ABGR4444 = 0x32314241,
496
    WL_DRM_FORMAT_RGBA4444 = 0x32314152,
521
    WL_DRM_FORMAT_RGBA4444 = 0x32314152,
497
    WL_DRM_FORMAT_BGRA4444 = 0x32314142,
522
    WL_DRM_FORMAT_BGRA4444 = 0x32314142,
498
    WL_DRM_FORMAT_XRGB1555 = 0x35315258,
523
    WL_DRM_FORMAT_XRGB1555 = 0x35315258,
499
    WL_DRM_FORMAT_XBGR1555 = 0x35314258,
524
    WL_DRM_FORMAT_XBGR1555 = 0x35314258,
500
    WL_DRM_FORMAT_RGBX5551 = 0x35315852,
525
    WL_DRM_FORMAT_RGBX5551 = 0x35315852,
501
    WL_DRM_FORMAT_BGRX5551 = 0x35315842,
526
    WL_DRM_FORMAT_BGRX5551 = 0x35315842,
502
    WL_DRM_FORMAT_ARGB1555 = 0x35315241,
527
    WL_DRM_FORMAT_ARGB1555 = 0x35315241,
503
    WL_DRM_FORMAT_ABGR1555 = 0x35314241,
528
    WL_DRM_FORMAT_ABGR1555 = 0x35314241,
504
    WL_DRM_FORMAT_RGBA5551 = 0x35314152,
529
    WL_DRM_FORMAT_RGBA5551 = 0x35314152,
505
    WL_DRM_FORMAT_BGRA5551 = 0x35314142,
530
    WL_DRM_FORMAT_BGRA5551 = 0x35314142,
506
    WL_DRM_FORMAT_RGB565 = 0x36314752,
531
    WL_DRM_FORMAT_RGB565 = 0x36314752,
507
    WL_DRM_FORMAT_BGR565 = 0x36314742,
532
    WL_DRM_FORMAT_BGR565 = 0x36314742,
508
    WL_DRM_FORMAT_RGB888 = 0x34324752,
533
    WL_DRM_FORMAT_RGB888 = 0x34324752,
509
    WL_DRM_FORMAT_BGR888 = 0x34324742,
534
    WL_DRM_FORMAT_BGR888 = 0x34324742,
510
    WL_DRM_FORMAT_XRGB8888 = 0x34325258,
535
    WL_DRM_FORMAT_XRGB8888 = 0x34325258,
511
    WL_DRM_FORMAT_XBGR8888 = 0x34324258,
536
    WL_DRM_FORMAT_XBGR8888 = 0x34324258,
512
    WL_DRM_FORMAT_RGBX8888 = 0x34325852,
537
    WL_DRM_FORMAT_RGBX8888 = 0x34325852,
513
    WL_DRM_FORMAT_BGRX8888 = 0x34325842,
538
    WL_DRM_FORMAT_BGRX8888 = 0x34325842,
514
    WL_DRM_FORMAT_ARGB8888 = 0x34325241,
539
    WL_DRM_FORMAT_ARGB8888 = 0x34325241,
515
    WL_DRM_FORMAT_ABGR8888 = 0x34324241,
540
    WL_DRM_FORMAT_ABGR8888 = 0x34324241,
516
    WL_DRM_FORMAT_RGBA8888 = 0x34324152,
541
    WL_DRM_FORMAT_RGBA8888 = 0x34324152,
517
    WL_DRM_FORMAT_BGRA8888 = 0x34324142,
542
    WL_DRM_FORMAT_BGRA8888 = 0x34324142,
518
    WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
543
    WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
519
    WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
544
    WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
520
    WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
545
    WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
521
    WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
546
    WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
522
    WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
547
    WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
523
    WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
548
    WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
524
    WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
549
    WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
525
    WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
550
    WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
526
    WL_DRM_FORMAT_YUYV = 0x56595559,
551
    WL_DRM_FORMAT_YUYV = 0x56595559,
527
    WL_DRM_FORMAT_YVYU = 0x55595659,
552
    WL_DRM_FORMAT_YVYU = 0x55595659,
528
    WL_DRM_FORMAT_UYVY = 0x59565955,
553
    WL_DRM_FORMAT_UYVY = 0x59565955,
529
    WL_DRM_FORMAT_VYUY = 0x59555956,
554
    WL_DRM_FORMAT_VYUY = 0x59555956,
530
    WL_DRM_FORMAT_AYUV = 0x56555941,
555
    WL_DRM_FORMAT_AYUV = 0x56555941,
531
    WL_DRM_FORMAT_NV12 = 0x3231564e,
556
    WL_DRM_FORMAT_NV12 = 0x3231564e,
532
    WL_DRM_FORMAT_NV21 = 0x3132564e,
557
    WL_DRM_FORMAT_NV21 = 0x3132564e,
533
    WL_DRM_FORMAT_NV16 = 0x3631564e,
558
    WL_DRM_FORMAT_NV16 = 0x3631564e,
534
    WL_DRM_FORMAT_NV61 = 0x3136564e,
559
    WL_DRM_FORMAT_NV61 = 0x3136564e,
535
    WL_DRM_FORMAT_YUV410 = 0x39565559,
560
    WL_DRM_FORMAT_YUV410 = 0x39565559,
536
    WL_DRM_FORMAT_YVU410 = 0x39555659,
561
    WL_DRM_FORMAT_YVU410 = 0x39555659,
537
    WL_DRM_FORMAT_YUV411 = 0x31315559,
562
    WL_DRM_FORMAT_YUV411 = 0x31315559,
538
    WL_DRM_FORMAT_YVU411 = 0x31315659,
563
    WL_DRM_FORMAT_YVU411 = 0x31315659,
539
    WL_DRM_FORMAT_YUV420 = 0x32315559,
564
    WL_DRM_FORMAT_YUV420 = 0x32315559,
540
    WL_DRM_FORMAT_YVU420 = 0x32315659,
565
    WL_DRM_FORMAT_YVU420 = 0x32315659,
541
    WL_DRM_FORMAT_YUV422 = 0x36315559,
566
    WL_DRM_FORMAT_YUV422 = 0x36315559,
542
    WL_DRM_FORMAT_YVU422 = 0x36315659,
567
    WL_DRM_FORMAT_YVU422 = 0x36315659,
543
    WL_DRM_FORMAT_YUV444 = 0x34325559,
568
    WL_DRM_FORMAT_YUV444 = 0x34325559,
544
    WL_DRM_FORMAT_YVU444 = 0x34325659,
569
    WL_DRM_FORMAT_YVU444 = 0x34325659,
545
};
570
};
546
 
571
 
547
void va_create_planar(vst_t *vst, vframe_t *vframe)
572
void va_create_planar(vst_t *vst, vframe_t *vframe)
548
{
573
{
549
    struct vaapi_context* const vaapi = v_context;
574
    struct vaapi_context* const vaapi = v_context;
-
 
575
    struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder;
550
    VABufferInfo info = {0};
576
    VABufferInfo info = {0};
551
 
577
 
552
    VAImage vaimage;
578
    VAImage vaimage;
553
    VAStatus status;
579
    VAStatus status;
554
    planar_t *planar;
580
    planar_t *planar;
555
 
581
 
556
    vaSyncSurface(vaapi->display,v_surface_id[vframe->index]);
582
    vaSyncSurface(vaapi->display,hw_decoder->v_surface_id[vframe->index]);
557
 
583
 
558
    if(vframe->format != AV_PIX_FMT_NONE)
584
    if(vframe->format != AV_PIX_FMT_NONE)
559
        return;
585
        return;
-
 
586
 
-
 
587
    if(vframe->planar != NULL)
-
 
588
    {
-
 
589
        pxDestroyPlanar(vframe->planar);
-
 
590
        vframe->planar = NULL;
-
 
591
    };
560
 
592
 
561
    status = vaDeriveImage(vaapi->display,v_surface_id[vframe->index],&vaimage);
593
    status = vaDeriveImage(vaapi->display,hw_decoder->v_surface_id[vframe->index],&vaimage);
562
    if (!vaapi_check_status(status, "vaDeriveImage()"))
594
    if (!vaapi_check_status(status, "vaDeriveImage()"))
563
    {
595
    {
564
        FAIL();
596
        FAIL();
565
        return;
597
        return;
566
    };
598
    };
567
/*
599
/*
568
    printf("vaDeriveImage: %x  fourcc: %x\n"
600
    printf("vaDeriveImage: %x  fourcc: %x\n"
569
           "offset0: %d pitch0: %d\n"
601
           "offset0: %d pitch0: %d\n"
570
           "offset1: %d pitch1: %d\n"
602
           "offset1: %d pitch1: %d\n"
571
           "offset2: %d pitch2: %d\n",
603
           "offset2: %d pitch2: %d\n",
572
            vaimage.buf, vaimage.format.fourcc,
604
            vaimage.buf, vaimage.format.fourcc,
573
            vaimage.offsets[0],vaimage.pitches[0],
605
            vaimage.offsets[0],vaimage.pitches[0],
574
            vaimage.offsets[1],vaimage.pitches[1],
606
            vaimage.offsets[1],vaimage.pitches[1],
575
            vaimage.offsets[2],vaimage.pitches[2]);
607
            vaimage.offsets[2],vaimage.pitches[2]);
576
*/
608
*/
577
    info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
609
    info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
578
    status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
610
    status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
579
    if (!vaapi_check_status(status, "vaAcquireBufferHandle()"))
611
    if (!vaapi_check_status(status, "vaAcquireBufferHandle()"))
580
    {
612
    {
581
        vaDestroyImage(vaapi->display, vaimage.image_id);
613
        vaDestroyImage(vaapi->display, vaimage.image_id);
582
        FAIL();
614
        FAIL();
583
        return;
615
        return;
584
    };
616
    };
585
/*
617
/*
586
    printf("vaAcquireBufferHandle: %x type: %x\n"
618
    printf("vaAcquireBufferHandle: %x type: %x\n"
587
            "mem type: %x mem size: %d\n",
619
            "mem type: %x mem size: %d\n",
588
            info.handle, info.type, info.mem_type, info.mem_size);
620
            info.handle, info.type, info.mem_type, info.mem_size);
589
*/
621
*/
590
    planar = pxCreatePlanar(info.handle, WL_DRM_FORMAT_NV12,
622
    planar = pxCreatePlanar(info.handle, WL_DRM_FORMAT_NV12,
591
                            vaimage.width, vaimage.height,
623
                            vaimage.width, vaimage.height,
592
                            vaimage.offsets[0],vaimage.pitches[0],
624
                            vaimage.offsets[0],vaimage.pitches[0],
593
                            vaimage.offsets[1],vaimage.pitches[1],
625
                            vaimage.offsets[1],vaimage.pitches[1],
594
                            vaimage.offsets[2],vaimage.pitches[2]);
626
                            vaimage.offsets[2],vaimage.pitches[2]);
595
    if(planar != NULL)
627
    if(planar != NULL)
596
    {
628
    {
597
        vframe->planar = planar;
629
        vframe->planar = planar;
598
        vframe->format = AV_PIX_FMT_NV12;
630
        vframe->format = AV_PIX_FMT_NV12;
599
    };
631
    };
600
 
632
 
601
    vaReleaseBufferHandle(vaapi->display, vaimage.buf);
633
    vaReleaseBufferHandle(vaapi->display, vaimage.buf);
602
    vaDestroyImage(vaapi->display, vaimage.image_id);
634
    vaDestroyImage(vaapi->display, vaimage.image_id);
603
 
635
 
604
}
636
}
605
 
637
 
606
static enum AVCodecID profile_to_codec(VAProfile profile)
638
static enum AVCodecID profile_to_codec(VAProfile profile)
607
{
639
{
608
    enum AVCodecID id;
640
    enum AVCodecID id;
609
 
641
 
610
    switch(profile)
642
    switch(profile)
611
    {
643
    {
612
        case VAProfileMPEG2Simple:
644
        case VAProfileMPEG2Simple:
613
        case VAProfileMPEG2Main:
645
        case VAProfileMPEG2Main:
614
            id = AV_CODEC_ID_MPEG2VIDEO;
646
            id = AV_CODEC_ID_MPEG2VIDEO;
615
            break;
647
            break;
616
 
648
 
617
        case VAProfileMPEG4Simple:
649
        case VAProfileMPEG4Simple:
618
        case VAProfileMPEG4AdvancedSimple:
650
        case VAProfileMPEG4AdvancedSimple:
619
        case VAProfileMPEG4Main:
651
        case VAProfileMPEG4Main:
620
            id = AV_CODEC_ID_MPEG4;
652
            id = AV_CODEC_ID_MPEG4;
621
            break;
653
            break;
622
 
654
 
623
        case VAProfileH264Baseline:
655
        case VAProfileH264Baseline:
624
        case VAProfileH264Main:
656
        case VAProfileH264Main:
625
        case VAProfileH264High:
657
        case VAProfileH264High:
626
        case VAProfileH264ConstrainedBaseline:
658
        case VAProfileH264ConstrainedBaseline:
627
        case VAProfileH264MultiviewHigh:
659
        case VAProfileH264MultiviewHigh:
628
        case VAProfileH264StereoHigh:
660
        case VAProfileH264StereoHigh:
629
            id = AV_CODEC_ID_H264;
661
            id = AV_CODEC_ID_H264;
630
            break;
662
            break;
631
 
663
 
632
        case VAProfileVC1Simple:
664
        case VAProfileVC1Simple:
633
        case VAProfileVC1Main:
665
        case VAProfileVC1Main:
634
        case VAProfileVC1Advanced:
666
        case VAProfileVC1Advanced:
635
            id = AV_CODEC_ID_VC1;
667
            id = AV_CODEC_ID_VC1;
636
            break;
668
            break;
637
 
669
 
638
        case VAProfileHEVCMain:
670
        case VAProfileHEVCMain:
639
        case VAProfileHEVCMain10:
671
        case VAProfileHEVCMain10:
640
            id = AV_CODEC_ID_HEVC;
672
            id = AV_CODEC_ID_HEVC;
641
            break;
673
            break;
642
 
674
 
643
        default:
675
        default:
644
            id = AV_CODEC_ID_NONE;
676
            id = AV_CODEC_ID_NONE;
645
    };
677
    };
646
    return id;
678
    return id;
647
};
679
};
648
 
680
 
649
static VAProfile get_profile(VADisplay dpy, enum AVCodecID codec_id)
681
static VAProfile get_profile(VADisplay dpy, enum AVCodecID codec_id)
650
{
682
{
651
    VAProfile profile = VAProfileNone, *profile_list = NULL;
683
    VAProfile profile = VAProfileNone, *profile_list = NULL;
652
    int num_profiles, max_num_profiles;
684
    int num_profiles, max_num_profiles;
653
    enum AVCodecID ff_id;
685
    enum AVCodecID ff_id;
654
    VAStatus va_status;
686
    VAStatus va_status;
655
    int i;
687
    int i;
656
 
688
 
657
    max_num_profiles = vaMaxNumProfiles(dpy);
689
    max_num_profiles = vaMaxNumProfiles(dpy);
658
 
690
 
659
    profile_list = alloca(max_num_profiles * sizeof(VAProfile));
691
    profile_list = alloca(max_num_profiles * sizeof(VAProfile));
660
    if (!profile_list)
692
    if (!profile_list)
661
    {
693
    {
662
        printf("Failed to allocate memory for profile list\n");
694
        printf("Failed to allocate memory for profile list\n");
663
        goto err_0;
695
        goto err_0;
664
    }
696
    }
665
 
697
 
666
    va_status = vaQueryConfigProfiles(dpy, profile_list, &num_profiles);
698
    va_status = vaQueryConfigProfiles(dpy, profile_list, &num_profiles);
667
    if(!vaapi_check_status(va_status, "vaQueryConfigProfiles()"))
699
    if(!vaapi_check_status(va_status, "vaQueryConfigProfiles()"))
668
        goto err_0;
700
        goto err_0;
669
 
701
 
670
    if(codec_id == AV_CODEC_ID_H263)
702
    if(codec_id == AV_CODEC_ID_H263)
671
        ff_id = AV_CODEC_ID_H264;
703
        ff_id = AV_CODEC_ID_H264;
672
    else if(codec_id == AV_CODEC_ID_WMV3)
704
    else if(codec_id == AV_CODEC_ID_WMV3)
673
        ff_id = AV_CODEC_ID_VC1;
705
        ff_id = AV_CODEC_ID_VC1;
674
    else
706
    else
675
        ff_id = codec_id;
707
        ff_id = codec_id;
676
 
708
 
677
    for (i = 0; i < num_profiles; i++)
709
    for (i = 0; i < num_profiles; i++)
678
    {
710
    {
679
        if(ff_id == profile_to_codec(profile_list[i]))
711
        if(ff_id == profile_to_codec(profile_list[i]))
680
        {
712
        {
681
            profile = profile_list[i];
713
            profile = profile_list[i];
682
            break;
714
            break;
683
        }
715
        }
684
    };
716
    };
685
 
717
 
686
err_0:
718
err_0:
687
    return profile;
719
    return profile;
688
}
720
}
-
 
721
 
-
 
722
static void fini_va_decoder(vst_t *vst)
-
 
723
{
-
 
724
    struct vaapi_context* const vaapi = v_context;
-
 
725
    struct va_decoder *hw_decoder = (struct va_decoder*)vst->decoder;
-
 
726
ENTER();
-
 
727
    for(int i = 0; i < hw_decoder->decoder.nframes; i++)
-
 
728
    {
-
 
729
        vframe_t *vframe = &hw_decoder->decoder.vframes[i];
-
 
730
        if(vframe->planar != NULL)
-
 
731
        {
-
 
732
            printf("destroy planar %d\n", i);
-
 
733
            pxDestroyPlanar(vframe->planar);
-
 
734
            vframe->planar = NULL;
-
 
735
        };
-
 
736
    };
-
 
737
 
-
 
738
    av_frame_free(&hw_decoder->decoder.Frame);
-
 
739
 
-
 
740
    if (vaapi->context_id != VA_INVALID_ID)
-
 
741
        vaDestroyContext(vaapi->display, vaapi->context_id);
-
 
742
 
-
 
743
    if (hw_decoder->decoder.has_surfaces)
-
 
744
        vaDestroySurfaces(vaapi->display,hw_decoder->v_surface_id,hw_decoder->decoder.nframes);
-
 
745
 
-
 
746
    if (vaapi->config_id != VA_INVALID_ID)
-
 
747
        vaDestroyConfig(vaapi->display, vaapi->config_id);
-
 
748
 
-
 
749
    vaTerminate(hw_decoder->dpy);
-
 
750
LEAVE();
-
 
751
};
-
 
752
 
689
 
753
 
690
struct decoder* va_init_decoder(vst_t *vst)
754
struct decoder* init_va_decoder(vst_t *vst)
691
{
755
{
692
    AVCodecContext *vCtx = vst->vCtx;
756
    AVCodecContext *vCtx = vst->vCtx;
693
    struct decoder *decoder;
757
    struct va_decoder *hw_decoder = &va_decoder;
694
    VADisplay dpy;
758
    struct decoder *decoder = &hw_decoder->decoder;
695
 
759
 
696
    drm_fd = get_service("DISPLAY");
760
    drm_fd = get_service("DISPLAY");
697
    if (drm_fd == 0)
761
    if (drm_fd == 0)
698
        return NULL;
762
        return NULL;
699
 
763
 
700
    dpy = vaGetDisplayDRM(drm_fd);
-
 
701
    if (dpy == NULL)
-
 
702
        goto err_0;
-
 
703
 
-
 
704
    decoder = calloc(1, sizeof(struct decoder));
764
    hw_decoder->dpy = vaGetDisplayDRM(drm_fd);
705
    if(decoder == NULL)
765
    if (hw_decoder->dpy == NULL)
706
        goto err_0;
766
        goto err_0;
707
 
767
 
708
    decoder->hwctx = vaapi_init(dpy);
768
    hw_decoder->hwctx = vaapi_init(hw_decoder->dpy);
709
    if(decoder->hwctx == NULL)
769
    if(hw_decoder->hwctx == NULL)
710
        goto err_1;
770
        goto err_1;
711
 
771
 
712
    if(get_profile(dpy, vCtx->codec_id) == VAProfileNone)
772
    if(get_profile(hw_decoder->dpy, vCtx->codec_id) == VAProfileNone)
713
        goto err_1;
773
        goto err_1;
714
 
774
 
715
    decoder->Frame = av_frame_alloc();
775
    decoder->Frame = av_frame_alloc();
716
    if(decoder->Frame == NULL)
776
    if(decoder->Frame == NULL)
717
        goto err_1;
777
        goto err_1;
718
 
778
 
719
    if(vCtx->codec_id == AV_CODEC_ID_H264)
779
    if(vCtx->codec_id == AV_CODEC_ID_H264)
720
        decoder->nframes = 16;
780
        decoder->nframes = 16;
721
    else
781
    else
722
        decoder->nframes = 4;
782
        decoder->nframes = 4;
723
 
783
 
724
    for(int i = 0; i < decoder->nframes; i++)
784
    for(int i = 0; i < decoder->nframes; i++)
725
    {
785
    {
726
        vframe_t *vframe = &decoder->vframes[i];
786
        vframe_t *vframe = &decoder->vframes[i];
727
 
787
 
728
        vframe->format    = AV_PIX_FMT_NONE;
788
        vframe->format    = AV_PIX_FMT_NONE;
729
        vframe->is_hw_pic = 1;
789
        vframe->is_hw_pic = 1;
730
        vframe->index     = i;
790
        vframe->index     = i;
731
        vframe->pts       = 0;
-
 
732
        vframe->ready     = 0;
-
 
733
        list_add_tail(&vframe->list, &vst->input_list);
791
        list_add_tail(&vframe->list, &vst->input_list);
734
    };
792
    };
735
 
793
 
736
    vCtx->opaque       = vst;
794
    vCtx->opaque       = vst;
737
    vCtx->thread_count = 1;
795
    vCtx->thread_count = 1;
738
    vCtx->get_format   = get_format;
796
    vCtx->get_format   = get_format;
739
    vCtx->get_buffer2  = get_buffer2;
797
    vCtx->get_buffer2  = get_buffer2;
740
 
798
 
741
    if(avcodec_open2(vst->vCtx, vst->vCodec, NULL) < 0)
799
    if(avcodec_open2(vst->vCtx, vst->vCodec, NULL) < 0)
742
    {
800
    {
743
        printf("Error while opening codec for input stream %d\n",
801
        printf("Error while opening codec for input stream %d\n",
744
                vst->vStream);
802
                vst->vStream);
745
        goto err_2;
803
        goto err_2;
746
    };
804
    };
747
 
805
 
748
    decoder->name     = vst->vCodec->name;
806
    decoder->name     = vst->vCodec->name;
749
    decoder->codec_id = vCtx->codec_id;
807
    decoder->codec_id = vCtx->codec_id;
-
 
808
    decoder->profile  = vCtx->profile;
750
    decoder->pix_fmt  = vCtx->pix_fmt;
809
    decoder->pix_fmt  = vCtx->pix_fmt;
751
    decoder->width    = vCtx->width;
810
    decoder->width    = vCtx->width;
752
    decoder->height   = vCtx->height;
811
    decoder->height   = vCtx->height;
753
    decoder->is_hw    = 1;
812
    decoder->is_hw    = 1;
754
    decoder->frame_reorder = 1;
813
    decoder->frame_reorder = 1;
-
 
814
    decoder->fini     = fini_va_decoder;
755
 
815
 
756
    return decoder;
816
    return (struct decoder*)decoder;
757
 
817
 
758
err_2:
818
err_2:
759
    av_frame_free(&decoder->Frame);
819
    av_frame_free(&decoder->Frame);
760
err_1:
820
err_1:
761
    vaTerminate(dpy);
821
    vaTerminate(hw_decoder->dpy);
762
    free(decoder);
-
 
763
err_0:
822
err_0:
764
    drm_fd = 0;
823
    drm_fd = 0;
765
    return NULL;
824
    return NULL;
766
}
825
}