Subversion Repositories Kolibri OS

Rev

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

Rev 6121 Rev 6133
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
 
15
 
16
struct hw_profile
16
struct hw_profile
17
{
17
{
18
    enum AVCodecID av_codec;
18
    enum AVCodecID av_codec;
19
    int ff_profile;
19
    int ff_profile;
20
    uint64_t va_profile;
20
    VAProfile va_profile;
21
};
21
};
22
 
22
 
23
 
23
 
24
#define ENTER()   printf("enter %s\n",__FUNCTION__)
24
#define ENTER()   printf("enter %s\n",__FUNCTION__)
25
#define LEAVE()   printf("leave %s\n",__FUNCTION__)
25
#define LEAVE()   printf("leave %s\n",__FUNCTION__)
26
#define FAIL()    printf("fail %s\n",__FUNCTION__)
26
#define FAIL()    printf("fail %s\n",__FUNCTION__)
27
 
27
 
28
 
28
 
29
#if DEBUG
29
#if DEBUG
30
# define D(x) x
30
# define D(x) x
31
# define bug printf
31
# define bug printf
32
#else
32
#else
33
# define D(x)
33
# define D(x)
34
#endif
34
#endif
35
 
35
 
36
#undef  ARRAY_ELEMS
36
#undef  ARRAY_ELEMS
37
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
37
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
38
 
38
 
39
static int drm_fd = 0;
39
static int drm_fd = 0;
40
static struct vaapi_context *v_context;
40
static struct vaapi_context *v_context;
41
 
41
 
42
static VASurfaceID v_surface_id[4];
42
static VASurfaceID v_surface_id[HWDEC_NUM_SURFACES];
43
 
43
 
44
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
44
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
45
#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))
46
 
46
 
47
#define PE(av_codec_id, ff_profile, vdp_profile)                \
47
#define PE(av_codec_id, ff_profile, vdp_profile)                \
48
    {AV_CODEC_ID_ ## av_codec_id, FF_PROFILE_ ## ff_profile,    \
48
    {AV_CODEC_ID_ ## av_codec_id, FF_PROFILE_ ## ff_profile,    \
49
     VAProfile ## vdp_profile}
49
     VAProfile ## vdp_profile}
50
 
50
 
51
static const struct hw_profile profiles[] = {
51
static const struct hw_profile hw_profiles[] = {
52
    PE(MPEG2VIDEO,  MPEG2_MAIN,         MPEG2Main),
52
    PE(MPEG2VIDEO,  MPEG2_MAIN,         MPEG2Main),
53
    PE(MPEG2VIDEO,  MPEG2_SIMPLE,       MPEG2Simple),
53
    PE(MPEG2VIDEO,  MPEG2_SIMPLE,       MPEG2Simple),
54
    PE(MPEG4,       MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple),
54
    PE(MPEG4,       MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple),
55
    PE(MPEG4,       MPEG4_MAIN,         MPEG4Main),
55
    PE(MPEG4,       MPEG4_MAIN,         MPEG4Main),
56
    PE(MPEG4,       MPEG4_SIMPLE,       MPEG4Simple),
56
    PE(MPEG4,       MPEG4_SIMPLE,       MPEG4Simple),
57
    PE(H264,        H264_HIGH,          H264High),
57
    PE(H264,        H264_HIGH,          H264High),
58
    PE(H264,        H264_MAIN,          H264Main),
58
    PE(H264,        H264_MAIN,          H264Main),
59
    PE(H264,        H264_BASELINE,      H264Baseline),
59
    PE(H264,        H264_BASELINE,      H264Baseline),
60
    PE(VC1,         VC1_ADVANCED,       VC1Advanced),
60
    PE(VC1,         VC1_ADVANCED,       VC1Advanced),
61
    PE(VC1,         VC1_MAIN,           VC1Main),
61
    PE(VC1,         VC1_MAIN,           VC1Main),
62
    PE(VC1,         VC1_SIMPLE,         VC1Simple),
62
    PE(VC1,         VC1_SIMPLE,         VC1Simple),
63
    PE(WMV3,        VC1_ADVANCED,       VC1Advanced),
63
    PE(WMV3,        VC1_ADVANCED,       VC1Advanced),
64
    PE(WMV3,        VC1_MAIN,           VC1Main),
64
    PE(WMV3,        VC1_MAIN,           VC1Main),
65
    PE(WMV3,        VC1_SIMPLE,         VC1Simple),
65
    PE(WMV3,        VC1_SIMPLE,         VC1Simple),
66
#if HAS_HEVC
66
#if HAS_HEVC
67
    PE(HEVC,        HEVC_MAIN,          HEVCMain),
67
    PE(HEVC,        HEVC_MAIN,          HEVCMain),
68
    PE(HEVC,        HEVC_MAIN_10,       HEVCMain10),
68
    PE(HEVC,        HEVC_MAIN_10,       HEVCMain10),
69
#endif
69
#endif
70
#if HAS_VP9
70
#if HAS_VP9
71
    PE(VP9,         VP9_0,              VP9Profile0),
71
    PE(VP9,         VP9_0,              VP9Profile0),
72
#endif
72
#endif
73
    {0}
73
    {0}
74
};
74
};
75
 
75
 
76
int va_check_codec_support(enum AVCodecID id)
76
int va_check_codec_support(enum AVCodecID id)
77
{
77
{
78
    for (int n = 0; profiles[n].av_codec; n++) {
78
    for (int n = 0; hw_profiles[n].av_codec; n++) {
79
        if (profiles[n].av_codec == id)
79
        if (hw_profiles[n].av_codec == id)
80
            return 1;
80
            return 1;
81
    }
81
    }
82
    return 0;
82
    return 0;
83
}
83
}
84
 
84
 
85
static int vaapi_check_status(VAStatus status, const char *msg)
85
static int vaapi_check_status(VAStatus status, const char *msg)
86
{
86
{
87
    if (status != VA_STATUS_SUCCESS) {
87
    if (status != VA_STATUS_SUCCESS) {
88
        fprintf(stderr, "[%s] %s: %s\n", PACKAGE_NAME, msg, vaErrorStr(status));
88
        fprintf(stderr, "[%s] %s: %s\n", PACKAGE_NAME, msg, vaErrorStr(status));
89
        return 0;
89
        return 0;
90
    }
90
    }
91
    return 1;
91
    return 1;
92
};
92
};
93
 
93
 
94
static const char *string_of_VADisplayAttribType(VADisplayAttribType type)
94
static const char *string_of_VADisplayAttribType(VADisplayAttribType type)
95
{
95
{
96
    switch (type) {
96
    switch (type) {
97
#define TYPE(type) \
97
#define TYPE(type) \
98
        case VADisplayAttrib##type: return "VADisplayAttrib" #type
98
        case VADisplayAttrib##type: return "VADisplayAttrib" #type
99
        TYPE(Brightness);
99
        TYPE(Brightness);
100
        TYPE(Contrast);
100
        TYPE(Contrast);
101
        TYPE(Hue);
101
        TYPE(Hue);
102
        TYPE(Saturation);
102
        TYPE(Saturation);
103
        TYPE(BackgroundColor);
103
        TYPE(BackgroundColor);
104
#if !VA_CHECK_VERSION(0,34,0)
104
#if !VA_CHECK_VERSION(0,34,0)
105
        TYPE(DirectSurface);
105
        TYPE(DirectSurface);
106
#endif
106
#endif
107
#if VA_CHECK_VERSION(0,32,0)
107
#if VA_CHECK_VERSION(0,32,0)
108
        TYPE(Rotation);
108
        TYPE(Rotation);
109
#endif
109
#endif
110
#undef TYPE
110
#undef TYPE
111
    default: break;
111
    default: break;
112
    }
112
    }
113
    return "";
113
    return "";
114
}
114
}
115
 
115
 
116
static const char *string_of_VAProfile(VAProfile profile)
116
static const char *string_of_VAProfile(VAProfile profile)
117
{
117
{
118
    switch (profile) {
118
    switch (profile) {
119
#define PROFILE(profile) \
119
#define PROFILE(profile) \
120
        case VAProfile##profile: return "VAProfile" #profile
120
        case VAProfile##profile: return "VAProfile" #profile
121
        PROFILE(MPEG2Simple);
121
        PROFILE(MPEG2Simple);
122
        PROFILE(MPEG2Main);
122
        PROFILE(MPEG2Main);
123
        PROFILE(MPEG4Simple);
123
        PROFILE(MPEG4Simple);
124
        PROFILE(MPEG4AdvancedSimple);
124
        PROFILE(MPEG4AdvancedSimple);
125
        PROFILE(MPEG4Main);
125
        PROFILE(MPEG4Main);
126
#if VA_CHECK_VERSION(0,32,0)
126
#if VA_CHECK_VERSION(0,32,0)
127
        PROFILE(JPEGBaseline);
127
        PROFILE(JPEGBaseline);
128
        PROFILE(H263Baseline);
128
        PROFILE(H263Baseline);
129
        PROFILE(H264ConstrainedBaseline);
129
        PROFILE(H264ConstrainedBaseline);
130
#endif
130
#endif
131
        PROFILE(H264Baseline);
131
        PROFILE(H264Baseline);
132
        PROFILE(H264Main);
132
        PROFILE(H264Main);
133
        PROFILE(H264High);
133
        PROFILE(H264High);
134
        PROFILE(VC1Simple);
134
        PROFILE(VC1Simple);
135
        PROFILE(VC1Main);
135
        PROFILE(VC1Main);
136
        PROFILE(VC1Advanced);
136
        PROFILE(VC1Advanced);
137
#undef PROFILE
137
#undef PROFILE
138
    default: break;
138
    default: break;
139
    }
139
    }
140
    return "";
140
    return "";
141
}
141
}
142
 
142
 
143
static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint)
143
static const char *string_of_VAEntrypoint(VAEntrypoint entrypoint)
144
{
144
{
145
    switch (entrypoint) {
145
    switch (entrypoint) {
146
#define ENTRYPOINT(entrypoint) \
146
#define ENTRYPOINT(entrypoint) \
147
        case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint
147
        case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint
148
        ENTRYPOINT(VLD);
148
        ENTRYPOINT(VLD);
149
        ENTRYPOINT(IZZ);
149
        ENTRYPOINT(IZZ);
150
        ENTRYPOINT(IDCT);
150
        ENTRYPOINT(IDCT);
151
        ENTRYPOINT(MoComp);
151
        ENTRYPOINT(MoComp);
152
        ENTRYPOINT(Deblocking);
152
        ENTRYPOINT(Deblocking);
153
#if VA_CHECK_VERSION(0,32,0)
153
#if VA_CHECK_VERSION(0,32,0)
154
        ENTRYPOINT(EncSlice);
154
        ENTRYPOINT(EncSlice);
155
        ENTRYPOINT(EncPicture);
155
        ENTRYPOINT(EncPicture);
156
#endif
156
#endif
157
#undef ENTRYPOINT
157
#undef ENTRYPOINT
158
    default: break;
158
    default: break;
159
    }
159
    }
160
    return "";
160
    return "";
161
}
161
}
162
 
162
 
163
VADisplay va_open_display(void)
163
VADisplay va_open_display(void)
164
{
164
{
165
    VADisplay va_dpy;
165
    VADisplay va_dpy;
166
 
166
 
167
    drm_fd = get_service("DISPLAY");
167
    drm_fd = get_service("DISPLAY");
168
    if (drm_fd == 0)
168
    if (drm_fd == 0)
169
        return NULL;
169
        return NULL;
170
 
170
 
171
    va_dpy = vaGetDisplayDRM(drm_fd);
171
    va_dpy = vaGetDisplayDRM(drm_fd);
172
    if (va_dpy)
172
    if (va_dpy)
173
        return va_dpy;
173
        return va_dpy;
174
 
174
 
175
    drm_fd = 0;
175
    drm_fd = 0;
176
    return NULL;
176
    return NULL;
177
};
177
};
178
 
178
 
179
void *vaapi_init(VADisplay display)
179
void *vaapi_init(VADisplay display)
180
{
180
{
181
    struct vaapi_context *vaapi;
181
    struct vaapi_context *vaapi;
182
    int major_version, minor_version;
182
    int major_version, minor_version;
183
    int i, num_display_attrs, max_display_attrs;
183
    int i, num_display_attrs, max_display_attrs;
184
    VADisplayAttribute *display_attrs = NULL;
184
    VADisplayAttribute *display_attrs = NULL;
185
    VAStatus status;
185
    VAStatus status;
186
 
186
 
187
    if (v_context)
187
    if (v_context)
188
        return 0;
188
        return 0;
189
 
189
 
190
    if (!display)
190
    if (!display)
191
        goto error;
191
        goto error;
192
    D(bug("VA display %p\n", display));
192
    D(bug("VA display %p\n", display));
193
 
193
 
194
    status = vaInitialize(display, &major_version, &minor_version);
194
    status = vaInitialize(display, &major_version, &minor_version);
195
    if (!vaapi_check_status(status, "vaInitialize()"))
195
    if (!vaapi_check_status(status, "vaInitialize()"))
196
        goto error;
196
        goto error;
197
    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));
198
 
198
 
199
    max_display_attrs = vaMaxNumDisplayAttributes(display);
199
    max_display_attrs = vaMaxNumDisplayAttributes(display);
200
    display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0]));
200
    display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0]));
201
    if (!display_attrs)
201
    if (!display_attrs)
202
        goto error;
202
        goto error;
203
 
203
 
204
    num_display_attrs = 0; /* XXX: workaround old GMA500 bug */
204
    num_display_attrs = 0; /* XXX: workaround old GMA500 bug */
205
    status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs);
205
    status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs);
206
    if (!vaapi_check_status(status, "vaQueryDisplayAttributes()"))
206
    if (!vaapi_check_status(status, "vaQueryDisplayAttributes()"))
207
        goto error;
207
        goto error;
208
    D(bug("%d display attributes available\n", num_display_attrs));
208
    D(bug("%d display attributes available\n", num_display_attrs));
209
    for (i = 0; i < num_display_attrs; i++) {
209
    for (i = 0; i < num_display_attrs; i++) {
210
        VADisplayAttribute * const display_attr = &display_attrs[i];
210
        VADisplayAttribute * const display_attr = &display_attrs[i];
211
        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",
212
              string_of_VADisplayAttribType(display_attr->type),
212
              string_of_VADisplayAttribType(display_attr->type),
213
              (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---",
213
              (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---",
214
              (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---",
214
              (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---",
215
              display_attr->min_value,
215
              display_attr->min_value,
216
              display_attr->max_value,
216
              display_attr->max_value,
217
              display_attr->value));
217
              display_attr->value));
218
    }
218
    }
219
 
219
 
220
    if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL)
220
    if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL)
221
        goto error;
221
        goto error;
222
    vaapi->display               = display;
222
    vaapi->display    = display;
223
    vaapi->config_id             = VA_INVALID_ID;
223
    vaapi->config_id  = VA_INVALID_ID;
224
    vaapi->context_id            = VA_INVALID_ID;
224
    vaapi->context_id = VA_INVALID_ID;
225
 
225
 
226
    v_context = vaapi;
226
    v_context = vaapi;
227
 
227
 
228
    return vaapi;
228
    return vaapi;
229
 
229
 
230
error:
230
error:
231
    free(display_attrs);
231
    free(display_attrs);
232
    return NULL;
232
    return NULL;
233
}
233
}
234
 
234
 
235
static int has_profile(struct vaapi_context *vaapi, VAProfile profile)
235
static int has_profile(struct vaapi_context *vaapi, VAProfile profile)
236
{
236
{
237
    VAProfile *profiles;
237
    VAProfile *profiles;
238
    int        n_profiles;
238
    int        n_profiles;
239
    VAStatus   status;
239
    VAStatus   status;
240
    int i;
240
    int i;
241
 
241
 
242
    profiles = calloc(vaMaxNumProfiles(vaapi->display), sizeof(profiles[0]));
242
    profiles = calloc(vaMaxNumProfiles(vaapi->display), sizeof(profiles[0]));
243
 
243
 
244
    status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles);
244
    status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles);
245
 
245
 
246
    if (!vaapi_check_status(status, "vaQueryConfigProfiles()"))
246
    if (!vaapi_check_status(status, "vaQueryConfigProfiles()"))
247
        return 0;
247
        return 0;
248
 
248
 
249
    D(bug("%d profiles available\n", n_profiles));
249
    D(bug("%d profiles available\n", n_profiles));
250
 
250
 
251
    for (i = 0; i < n_profiles; i++)
251
    for (i = 0; i < n_profiles; i++)
252
    {
252
    {
253
        if (profiles[i] == profile)
253
        if (profiles[i] == profile)
254
            return 1;
254
            return 1;
255
    }
255
    }
256
    return 0;
256
    return 0;
257
}
257
}
258
 
258
 
259
static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint)
259
static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint)
260
{
260
{
261
    VAEntrypoint *entrypoints;
261
    VAEntrypoint *entrypoints;
262
    int           n_entrypoints;
262
    int           n_entrypoints;
263
    VAStatus      status;
263
    VAStatus      status;
264
    int i;
264
    int i;
265
 
265
 
266
    entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(entrypoints[0]));
266
    entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(entrypoints[0]));
267
 
267
 
268
    status = vaQueryConfigEntrypoints(vaapi->display, profile,
268
    status = vaQueryConfigEntrypoints(vaapi->display, profile,
269
                                      entrypoints, &n_entrypoints);
269
                                      entrypoints, &n_entrypoints);
270
    if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()"))
270
    if (!vaapi_check_status(status, "vaQueryConfigEntrypoints()"))
271
        return 0;
271
        return 0;
272
 
272
 
273
    D(bug("%d entrypoints available for %s\n", n_entrypoints,
273
    D(bug("%d entrypoints available for %s\n", n_entrypoints,
274
          string_of_VAProfile(profile)));
274
          string_of_VAProfile(profile)));
275
 
275
 
276
    for (i = 0; i < n_entrypoints; i++)
276
    for (i = 0; i < n_entrypoints; i++)
277
    {
277
    {
278
        if (entrypoints[i] == entrypoint)
278
        if (entrypoints[i] == entrypoint)
279
            return 1;
279
            return 1;
280
    }
280
    }
281
    return 0;
281
    return 0;
282
}
282
}
283
 
283
 
284
static int vaapi_init_decoder(VAProfile    profile,
284
static int vaapi_init_decoder(VAProfile profile,
285
                       VAEntrypoint entrypoint,
285
                       VAEntrypoint entrypoint,
286
                       unsigned int picture_width,
286
                       unsigned int picture_width,
287
                       unsigned int picture_height)
287
                       unsigned int picture_height)
288
{
288
{
289
    struct vaapi_context* const vaapi = v_context;
289
    struct vaapi_context* const vaapi = v_context;
290
    VAConfigAttrib attrib;
290
    VAConfigAttrib attrib;
291
    VAConfigID  config_id = VA_INVALID_ID;
291
    VAConfigID  config_id = VA_INVALID_ID;
292
    VAContextID context_id = VA_INVALID_ID;
292
    VAContextID context_id = VA_INVALID_ID;
293
    VAStatus status;
293
    VAStatus status;
294
 
294
 
295
ENTER();
295
ENTER();
296
    if (!vaapi)
296
    if (!vaapi)
297
    {
297
    {
298
        FAIL();
298
        FAIL();
299
        return -1;
299
        return -1;
300
    };
300
    };
301
 
301
 
302
    if (!has_profile(vaapi, profile))
302
    if (!has_profile(vaapi, profile))
303
    {
303
    {
304
        FAIL();
304
        FAIL();
305
        return -1;
305
        return -1;
306
    };
306
    };
307
 
307
 
308
    if (!has_entrypoint(vaapi, profile, entrypoint))
308
    if (!has_entrypoint(vaapi, profile, entrypoint))
309
    {
309
    {
310
        FAIL();
310
        FAIL();
311
        return -1;
311
        return -1;
312
    };
312
    };
313
 
313
 
314
    if (vaapi->config_id != VA_INVALID_ID)
314
    if (vaapi->config_id != VA_INVALID_ID)
315
        vaDestroyConfig(vaapi->display, vaapi->config_id);
315
        vaDestroyConfig(vaapi->display, vaapi->config_id);
316
 
316
 
317
    attrib.type = VAConfigAttribRTFormat;
317
    attrib.type = VAConfigAttribRTFormat;
318
 
318
 
319
    printf("vaGetConfigAttributes\n");
319
    printf("vaGetConfigAttributes\n");
320
    status = vaGetConfigAttributes(vaapi->display, profile, entrypoint,
320
    status = vaGetConfigAttributes(vaapi->display, profile, entrypoint,
321
                                   &attrib, 1);
321
                                   &attrib, 1);
322
    if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
322
    if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
323
    {
323
    {
324
        FAIL();
324
        FAIL();
325
        return -1;
325
        return -1;
326
    }
326
    }
327
 
327
 
328
    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
328
    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
329
    {
329
    {
330
        printf("Chroma format not supported.\n");
330
        printf("Chroma format not supported.\n");
331
        FAIL();
331
        FAIL();
332
        return -1;
332
        return -1;
333
    };
333
    };
334
 
334
 
335
    printf("vaCreateConfig\n");
335
    printf("vaCreateConfig\n");
336
    status = vaCreateConfig(vaapi->display, profile, entrypoint,
336
    status = vaCreateConfig(vaapi->display, profile, entrypoint,
337
                            &attrib, 1, &config_id);
337
                            &attrib, 1, &config_id);
338
    if (!vaapi_check_status(status, "vaCreateConfig()"))
338
    if (!vaapi_check_status(status, "vaCreateConfig()"))
339
    {
339
    {
340
        FAIL();
340
        FAIL();
341
        return -1;
341
        return -1;
342
    }
342
    }
343
 
343
 
344
    printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
344
    printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
345
    status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
345
    status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
346
                              v_surface_id,4,NULL,0);
346
                              v_surface_id,HWDEC_NUM_SURFACES,NULL,0);
347
    printf("v_surface_id_3 %x\n", v_surface_id[3]);
-
 
348
    if (!vaapi_check_status(status, "vaCreateSurfaces()"))
347
    if (!vaapi_check_status(status, "vaCreateSurfaces()"))
349
    {
348
    {
350
        FAIL();
349
        FAIL();
351
        return -1;
350
        return -1;
352
    };
351
    };
353
    {
352
    {
354
        VAImage vaimage;
353
        VAImage vaimage;
355
        VABufferInfo info = {0};
354
        VABufferInfo info = {0};
356
 
355
 
357
        vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage);
356
        vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage);
358
        printf("vaDeriveImage: %x  fourcc: %x\n"
357
        printf("vaDeriveImage: %x  fourcc: %x\n"
359
               "offset0: %d pitch0: %d\n"
358
               "offset0: %d pitch0: %d\n"
360
               "offset1: %d pitch1: %d\n"
359
               "offset1: %d pitch1: %d\n"
361
               "offset2: %d pitch2: %d\n",
360
               "offset2: %d pitch2: %d\n",
362
                vaimage.buf, vaimage.format.fourcc,
361
                vaimage.buf, vaimage.format.fourcc,
363
                vaimage.offsets[0],vaimage.pitches[0],
362
                vaimage.offsets[0],vaimage.pitches[0],
364
                vaimage.offsets[1],vaimage.pitches[1],
363
                vaimage.offsets[1],vaimage.pitches[1],
365
                vaimage.offsets[2],vaimage.pitches[2]);
364
                vaimage.offsets[2],vaimage.pitches[2]);
366
 
365
 
367
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
366
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
368
        vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
367
        vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
369
        printf("vaAcquireBufferHandle: %x type: %x\n"
368
        printf("vaAcquireBufferHandle: %x type: %x\n"
370
                "mem type: %x mem size: %x\n",
369
                "mem type: %x mem size: %x\n",
371
                info.handle, info.type, info.mem_type, info.mem_size);
370
                info.handle, info.type, info.mem_type, info.mem_size);
372
 
371
 
373
        vaReleaseBufferHandle(vaapi->display, vaimage.buf);
372
        vaReleaseBufferHandle(vaapi->display, vaimage.buf);
374
 
373
 
375
        vaDestroyImage(vaapi->display,vaimage.image_id);
374
        vaDestroyImage(vaapi->display,vaimage.image_id);
376
    };
375
    };
377
 
376
 
378
    printf("vaCreateContext %dx%d\n",picture_width,picture_height);
377
    printf("vaCreateContext %dx%d\n",picture_width,picture_height);
379
    status = vaCreateContext(vaapi->display, config_id,
378
    status = vaCreateContext(vaapi->display, config_id,
380
                             picture_width, picture_height,
379
                             picture_width, picture_height,
381
                             VA_PROGRESSIVE,
380
                             VA_PROGRESSIVE,
382
                             v_surface_id, 4,
381
                             v_surface_id, HWDEC_NUM_SURFACES,
383
                             &context_id);
382
                             &context_id);
384
    if (!vaapi_check_status(status, "vaCreateContext()"))
383
    if (!vaapi_check_status(status, "vaCreateContext()"))
385
    {
384
    {
386
        FAIL();
385
        FAIL();
387
        return -1;
386
        return -1;
388
    };
387
    };
389
 
388
 
390
    vaapi->config_id      = config_id;
389
    vaapi->config_id  = config_id;
391
    vaapi->context_id     = context_id;
390
    vaapi->context_id = context_id;
392
    LEAVE();
391
    LEAVE();
393
    return 0;
392
    return 0;
394
}
393
}
395
 
394
 
396
 
395
 
397
static enum PixelFormat get_format(struct AVCodecContext *avctx,
396
static enum PixelFormat get_format(struct AVCodecContext *avctx,
398
                                   const enum AVPixelFormat *fmt)
397
                                   const enum AVPixelFormat *fmt)
399
{
398
{
400
    int i, profile;
399
    VAProfile profile = VAProfileNone;
401
 
400
 
402
    ENTER();
401
    ENTER();
403
 
402
 
-
 
403
    for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
404
//    for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++)
404
    {
405
//        printf(" %s", av_get_pix_fmt_name(fmt[i]));
-
 
406
 
-
 
407
    for (i = 0; fmt[i] != PIX_FMT_NONE; i++) {
405
        enum AVCodecID codec = avctx->codec_id;
408
        printf("pixformat %x\n", fmt[i]);
406
 
409
        if (fmt[i] != AV_PIX_FMT_VAAPI_VLD)
407
        if (fmt[i] != AV_PIX_FMT_VAAPI_VLD)
410
            continue;
408
            continue;
411
 
409
 
412
        switch (avctx->codec_id)
410
        if (codec == AV_CODEC_ID_H264)
413
        {
411
        {
414
        case CODEC_ID_MPEG2VIDEO:
412
            if (profile == FF_PROFILE_H264_CONSTRAINED_BASELINE)
415
            profile = VAProfileMPEG2Main;
413
                profile = FF_PROFILE_H264_MAIN;
416
            break;
-
 
417
        case CODEC_ID_MPEG4:
-
 
-
 
414
        };
418
        case CODEC_ID_H263:
415
 
419
            profile = VAProfileMPEG4AdvancedSimple;
416
        for (int n = 0; hw_profiles[n].av_codec; n++)
420
            break;
-
 
421
        case CODEC_ID_H264:
417
        {
422
            profile = VAProfileH264High;
-
 
423
            break;
-
 
424
        case CODEC_ID_WMV3:
418
            if (hw_profiles[n].av_codec   == codec &&
425
            profile = VAProfileVC1Main;
419
                hw_profiles[n].ff_profile == avctx->profile)
426
            break;
-
 
427
        case CODEC_ID_VC1:
420
            {
428
            profile = VAProfileVC1Advanced;
-
 
429
            break;
-
 
430
        default:
-
 
431
            profile = -1;
-
 
432
            break;
-
 
433
        }
-
 
434
        if (profile >= 0) {
421
                profile = hw_profiles[n].va_profile;
435
            if (vaapi_init_decoder(profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
422
                if (vaapi_init_decoder(profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
436
            {
423
                {
437
                avctx->hwaccel_context = v_context;
424
                    avctx->hwaccel_context = v_context;
438
                LEAVE();
425
                    LEAVE();
439
                return fmt[i]; ;
426
                    return fmt[i]; ;
440
            }
427
                }
441
        }
428
            }
442
    }
429
        }
-
 
430
 
-
 
431
    }
443
    FAIL();
432
    FAIL();
444
    return PIX_FMT_NONE;
433
    return PIX_FMT_NONE;
445
}
434
}
446
 
435
 
447
struct av_surface
436
struct av_surface
448
{
437
{
449
    int         w;
438
    int         w;
450
    int         h;
439
    int         h;
451
    VASurfaceID id;
440
    VASurfaceID id;
452
};
441
};
453
 
442
 
454
static void av_release_buffer(void *opaque, uint8_t *data)
443
static void av_release_buffer(void *opaque, uint8_t *data)
455
{
444
{
456
    struct av_surface surface = *(struct av_surface*)data;
445
    struct av_surface surface = *(struct av_surface*)data;
457
//    VDPAUContext *ctx = opaque;
-
 
458
 
-
 
459
//    ctx->video_surface_destroy(surface);
-
 
460
    av_freep(&data);
446
    av_freep(&data);
461
}
447
}
462
 
448
 
463
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
449
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
464
{
450
{
465
    vst_t *vst = (vst_t*)avctx->opaque;
451
    vst_t *vst = (vst_t*)avctx->opaque;
-
 
452
    void *surface;
-
 
453
 
466
    void *surface = (void *)(uintptr_t)v_surface_id[vst->dfx];
454
    surface = (void *)(uintptr_t)v_surface_id[vst->decoder_frame->index];
467
 
455
 
468
    pic->data[3] = surface;
456
    pic->data[3] = surface;
469
 
457
 
470
    struct av_surface *avsurface;
458
    struct av_surface *avsurface;
471
    surface = av_malloc(sizeof(*avsurface));
459
    surface = av_malloc(sizeof(*avsurface));
472
    if (!surface)
460
    if (!surface)
473
        return AVERROR(ENOMEM);
461
        return AVERROR(ENOMEM);
474
 
462
 
475
    pic->buf[0] = av_buffer_create((uint8_t*)avsurface, sizeof(*avsurface),
463
    pic->buf[0] = av_buffer_create((uint8_t*)avsurface, sizeof(*avsurface),
476
                                     av_release_buffer, avctx,
464
                                     av_release_buffer, avctx,
477
                                     AV_BUFFER_FLAG_READONLY);
465
                                     AV_BUFFER_FLAG_READONLY);
478
    return 0;
466
    return 0;
479
}
467
}
480
 
468
 
481
struct vaapi_context va_context_storage;
469
struct vaapi_context va_context_storage;
482
 
470
 
483
int fplay_init_context(vst_t *vst)
471
int fplay_init_context(vst_t *vst)
484
{
472
{
485
    AVCodecContext *vCtx = vst->vCtx;
473
    AVCodecContext *vCtx = vst->vCtx;
486
 
474
 
487
    if(va_check_codec_support(vCtx->codec_id))
475
    if(va_check_codec_support(vCtx->codec_id))
488
    {
476
    {
489
        VADisplay dpy;
477
        VADisplay dpy;
490
 
478
 
491
        dpy = va_open_display();
479
        dpy = va_open_display();
492
        vst->hwCtx = vaapi_init(dpy);
480
        vst->hwCtx = vaapi_init(dpy);
493
 
481
 
494
        if(vst->hwCtx != NULL)
482
        if(vst->hwCtx != NULL)
495
        {
483
        {
496
            for(int i = 0; i < 4; i++)
484
            for(int i = 0; i < HWDEC_NUM_SURFACES; i++)
497
            {
485
            {
498
                int ret;
486
                vframe_t *vframe = calloc(1, sizeof(*vframe));
499
 
487
 
500
                ret = avpicture_alloc(&vst->vframe[i].picture, AV_PIX_FMT_BGRA,
-
 
501
                                      vst->vCtx->width, vst->vCtx->height);
488
                vframe->format    = AV_PIX_FMT_NONE;
502
                if ( ret != 0 )
-
 
503
                {
-
 
504
                    printf("Cannot alloc video buffer\n\r");
489
                vframe->is_hw_pic = 1;
505
                    return ret;
-
 
506
                };
490
                vframe->index     = i;
507
                vst->vframe[i].format = AV_PIX_FMT_BGRA;
491
                vframe->pts       = 0;
508
                vst->vframe[i].pts   = 0;
492
                vframe->ready     = 0;
509
                vst->vframe[i].ready  = 0;
493
                list_add_tail(&vframe->list, &vst->input_list);
510
            };
494
            };
511
 
495
 
512
            vst->hwdec         = 1;
496
            vst->hwdec         = 1;
513
            vCtx->opaque       = vst;
497
            vCtx->opaque       = vst;
514
            vCtx->thread_count = 1;
498
            vCtx->thread_count = 1;
515
            vCtx->get_format   = get_format;
499
            vCtx->get_format   = get_format;
516
            vCtx->get_buffer2  = get_buffer2;
500
            vCtx->get_buffer2  = get_buffer2;
517
            return 0;
501
            return 0;
518
        };
502
        };
519
    };
503
    };
520
 
504
 
521
    vst->hwdec = 0;
505
    vst->hwdec = 0;
522
 
506
 
523
    for(int i = 0; i < 4; i++)
507
    for(int i = 0; i < HWDEC_NUM_SURFACES; i++)
-
 
508
    {
524
    {
509
        vframe_t *vframe;
-
 
510
        int ret;
-
 
511
 
525
        int ret;
512
        vframe = calloc(1, sizeof(*vframe));
526
 
513
 
527
        ret = avpicture_alloc(&vst->vframe[i].picture, vst->vCtx->pix_fmt,
514
        ret = avpicture_alloc(&vframe->picture, vst->vCtx->pix_fmt,
528
                               vst->vCtx->width, vst->vCtx->height);
515
                               vst->vCtx->width, vst->vCtx->height);
529
        if ( ret != 0 )
516
        if ( ret != 0 )
530
        {
517
        {
531
            printf("Cannot alloc video buffer\n\r");
518
            printf("Cannot alloc video buffer\n\r");
532
            return ret;
519
            return ret;
533
        };
520
        };
534
        vst->vframe[i].format = vst->vCtx->pix_fmt;
521
        vframe->format = vst->vCtx->pix_fmt;
-
 
522
        vframe->index  = i;
535
        vst->vframe[i].pts    = 0;
523
        vframe->pts    = 0;
536
        vst->vframe[i].ready  = 0;
524
        vframe->ready  = 0;
-
 
525
        list_add_tail(&vframe->list, &vst->input_list);
537
    };
526
    };
538
 
527
 
539
    return 0;
528
    return 0;
540
}
529
}
541
 
530
 
-
 
531
 
-
 
532
#define EGL_TEXTURE_Y_U_V_WL            0x31D7
-
 
533
#define EGL_TEXTURE_Y_UV_WL             0x31D8
-
 
534
#define EGL_TEXTURE_Y_XUXV_WL           0x31D9
542
 
535
 
-
 
536
enum wl_drm_format {
-
 
537
    WL_DRM_FORMAT_C8 = 0x20203843,
-
 
538
    WL_DRM_FORMAT_RGB332 = 0x38424752,
-
 
539
    WL_DRM_FORMAT_BGR233 = 0x38524742,
-
 
540
    WL_DRM_FORMAT_XRGB4444 = 0x32315258,
-
 
541
    WL_DRM_FORMAT_XBGR4444 = 0x32314258,
-
 
542
    WL_DRM_FORMAT_RGBX4444 = 0x32315852,
-
 
543
    WL_DRM_FORMAT_BGRX4444 = 0x32315842,
-
 
544
    WL_DRM_FORMAT_ARGB4444 = 0x32315241,
-
 
545
    WL_DRM_FORMAT_ABGR4444 = 0x32314241,
-
 
546
    WL_DRM_FORMAT_RGBA4444 = 0x32314152,
-
 
547
    WL_DRM_FORMAT_BGRA4444 = 0x32314142,
-
 
548
    WL_DRM_FORMAT_XRGB1555 = 0x35315258,
-
 
549
    WL_DRM_FORMAT_XBGR1555 = 0x35314258,
-
 
550
    WL_DRM_FORMAT_RGBX5551 = 0x35315852,
-
 
551
    WL_DRM_FORMAT_BGRX5551 = 0x35315842,
-
 
552
    WL_DRM_FORMAT_ARGB1555 = 0x35315241,
-
 
553
    WL_DRM_FORMAT_ABGR1555 = 0x35314241,
-
 
554
    WL_DRM_FORMAT_RGBA5551 = 0x35314152,
-
 
555
    WL_DRM_FORMAT_BGRA5551 = 0x35314142,
-
 
556
    WL_DRM_FORMAT_RGB565 = 0x36314752,
-
 
557
    WL_DRM_FORMAT_BGR565 = 0x36314742,
-
 
558
    WL_DRM_FORMAT_RGB888 = 0x34324752,
-
 
559
    WL_DRM_FORMAT_BGR888 = 0x34324742,
-
 
560
    WL_DRM_FORMAT_XRGB8888 = 0x34325258,
-
 
561
    WL_DRM_FORMAT_XBGR8888 = 0x34324258,
-
 
562
    WL_DRM_FORMAT_RGBX8888 = 0x34325852,
-
 
563
    WL_DRM_FORMAT_BGRX8888 = 0x34325842,
-
 
564
    WL_DRM_FORMAT_ARGB8888 = 0x34325241,
-
 
565
    WL_DRM_FORMAT_ABGR8888 = 0x34324241,
-
 
566
    WL_DRM_FORMAT_RGBA8888 = 0x34324152,
-
 
567
    WL_DRM_FORMAT_BGRA8888 = 0x34324142,
-
 
568
    WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
-
 
569
    WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
-
 
570
    WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
-
 
571
    WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
-
 
572
    WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
-
 
573
    WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
-
 
574
    WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
-
 
575
    WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
-
 
576
    WL_DRM_FORMAT_YUYV = 0x56595559,
-
 
577
    WL_DRM_FORMAT_YVYU = 0x55595659,
-
 
578
    WL_DRM_FORMAT_UYVY = 0x59565955,
-
 
579
    WL_DRM_FORMAT_VYUY = 0x59555956,
-
 
580
    WL_DRM_FORMAT_AYUV = 0x56555941,
-
 
581
    WL_DRM_FORMAT_NV12 = 0x3231564e,
-
 
582
    WL_DRM_FORMAT_NV21 = 0x3132564e,
-
 
583
    WL_DRM_FORMAT_NV16 = 0x3631564e,
-
 
584
    WL_DRM_FORMAT_NV61 = 0x3136564e,
-
 
585
    WL_DRM_FORMAT_YUV410 = 0x39565559,
-
 
586
    WL_DRM_FORMAT_YVU410 = 0x39555659,
-
 
587
    WL_DRM_FORMAT_YUV411 = 0x31315559,
-
 
588
    WL_DRM_FORMAT_YVU411 = 0x31315659,
-
 
589
    WL_DRM_FORMAT_YUV420 = 0x32315559,
-
 
590
    WL_DRM_FORMAT_YVU420 = 0x32315659,
-
 
591
    WL_DRM_FORMAT_YUV422 = 0x36315559,
-
 
592
    WL_DRM_FORMAT_YVU422 = 0x36315659,
-
 
593
    WL_DRM_FORMAT_YUV444 = 0x34325559,
-
 
594
    WL_DRM_FORMAT_YVU444 = 0x34325659,
543
struct SwsContext *vacvt_ctx;
595
};
544
 
596
 
545
void va_convert_picture(vst_t *vst, int width, int height, AVPicture *pic)
597
void va_create_planar(vst_t *vst, vframe_t *vframe)
546
{
598
{
-
 
599
    struct vaapi_context* const vaapi = v_context;
547
    uint8_t  *src_data[4];
600
    VABufferInfo info = {0};
548
    int       src_linesize[4];
601
 
549
    VAImage vaimage;
602
    VAImage vaimage;
550
    VAStatus status;
-
 
551
    uint8_t *vdata;
603
    VAStatus status;
-
 
604
    planar_t *planar;
-
 
605
 
-
 
606
    vaSyncSurface(vaapi->display,v_surface_id[vframe->index]);
-
 
607
 
-
 
608
    if(vframe->format != AV_PIX_FMT_NONE)
552
    struct vaapi_context* const vaapi = v_context;
609
        return;
553
 
610
 
554
    vaSyncSurface(vaapi->display,v_surface_id[vst->dfx]);
611
ENTER();
555
 
612
 
556
    status = vaDeriveImage(vaapi->display,v_surface_id[vst->dfx],&vaimage);
613
    status = vaDeriveImage(vaapi->display,v_surface_id[vframe->index],&vaimage);
557
    if (!vaapi_check_status(status, "vaDeriveImage()"))
614
    if (!vaapi_check_status(status, "vaDeriveImage()"))
558
    {
615
    {
559
        FAIL();
616
        FAIL();
560
        return;
617
        return;
561
    };
618
    };
562
 
-
 
563
    static int once = 2;
-
 
564
 
-
 
565
    if(once && vst->dfx == 0)
-
 
566
    {
-
 
567
        VABufferInfo info = {0};
-
 
568
 
619
/*
569
        printf("vaDeriveImage: %x  fourcc: %x\n"
620
    printf("vaDeriveImage: %x  fourcc: %x\n"
570
               "offset0: %d pitch0: %d\n"
621
           "offset0: %d pitch0: %d\n"
571
               "offset1: %d pitch1: %d\n"
622
           "offset1: %d pitch1: %d\n"
572
               "offset2: %d pitch2: %d\n",
623
           "offset2: %d pitch2: %d\n",
573
                vaimage.buf, vaimage.format.fourcc,
624
            vaimage.buf, vaimage.format.fourcc,
574
                vaimage.offsets[0],vaimage.pitches[0],
625
            vaimage.offsets[0],vaimage.pitches[0],
575
                vaimage.offsets[1],vaimage.pitches[1],
626
            vaimage.offsets[1],vaimage.pitches[1],
576
                vaimage.offsets[2],vaimage.pitches[2]);
627
            vaimage.offsets[2],vaimage.pitches[2]);
577
 
628
*/
578
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
629
    info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
579
        status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
630
    status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
580
        if (vaapi_check_status(status, "vaAcquireBufferHandle()"))
631
    if (!vaapi_check_status(status, "vaAcquireBufferHandle()"))
581
        {
-
 
582
            printf("vaAcquireBufferHandle: %x type: %x\n"
-
 
583
                    "mem type: %x mem size: %d\n",
-
 
584
                    info.handle, info.type, info.mem_type, info.mem_size);
-
 
585
 
-
 
586
            vaReleaseBufferHandle(vaapi->display, vaimage.buf);
-
 
587
        }
-
 
588
        once--;
-
 
589
    };
-
 
590
 
-
 
591
    src_linesize[0] = vaimage.pitches[0];
-
 
592
    src_linesize[1] = vaimage.pitches[1];
-
 
593
    src_linesize[2] = vaimage.pitches[2];
-
 
594
    src_linesize[3] = 0;
-
 
595
 
-
 
596
    status = vaMapBuffer(vaapi->display,vaimage.buf,(void **)&vdata);
-
 
597
    if (!vaapi_check_status(status, "vaMapBuffer()"))
-
 
598
    {
632
    {
-
 
633
        vaDestroyImage(vaapi->display, vaimage.image_id);
599
        FAIL();
634
        FAIL();
600
        return;
635
        return;
601
    };
636
    };
602
 
637
/*
603
//    printf("vdata: %x offset0: %d offset1: %d offset2: %d\n", vdata,
638
    printf("vaAcquireBufferHandle: %x type: %x\n"
604
//            vaimage.offsets[0],
-
 
605
//            vaimage.offsets[1],
639
            "mem type: %x mem size: %d\n",
606
//            vaimage.offsets[2]);
640
            info.handle, info.type, info.mem_type, info.mem_size);
607
 
641
*/
608
    src_data[0] = vdata + vaimage.offsets[0];
642
    planar = pxCreatePlanar(info.handle, WL_DRM_FORMAT_NV12,
609
    src_data[1] = vdata + vaimage.offsets[1];
643
                            vaimage.width, vaimage.height,
610
    src_data[2] = vdata + vaimage.offsets[2];
644
                            vaimage.offsets[0],vaimage.pitches[0],
611
    src_data[3] = 0;
-
 
612
 
-
 
613
    vacvt_ctx = sws_getCachedContext(vacvt_ctx, width, height, AV_PIX_FMT_NV12,
-
 
614
              width, height, AV_PIX_FMT_BGRA,
645
                            vaimage.offsets[1],vaimage.pitches[1],
615
              SWS_FAST_BILINEAR, NULL, NULL, NULL);
646
                            vaimage.offsets[2],vaimage.pitches[2]);
616
    if(vacvt_ctx == NULL)
647
    if(planar != NULL)
617
    {
648
    {
618
        printf("Cannot initialize the conversion context!\n");
649
        printf("create planar image\n",planar);
619
        return ;
650
        vframe->planar = planar;
-
 
651
        vframe->format = AV_PIX_FMT_NV12;
620
    };
652
    };
621
 
-
 
622
    sws_scale(vacvt_ctx, (const uint8_t* const *)src_data, src_linesize, 0, height, pic->data, pic->linesize);
-
 
623
 
653
 
624
    vaUnmapBuffer (vaapi->display, vaimage.buf);
654
    vaReleaseBufferHandle(vaapi->display, vaimage.buf);
-
 
655
    vaDestroyImage(vaapi->display, vaimage.image_id);
625
    vaDestroyImage(vaapi->display, vaimage.image_id);
656
LEAVE();
626
}
657
}