Subversion Repositories Kolibri OS

Rev

Rev 6136 | Rev 6298 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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