Subversion Repositories Kolibri OS

Rev

Rev 6121 | Rev 6135 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6121 Rev 6133
Line 15... Line 15...
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;
Line 21... Line 21...
21
};
21
};
22
 
22
 
Line 37... Line 37...
37
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
37
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
Line 38... Line 38...
38
 
38
 
39
static int drm_fd = 0;
39
static int drm_fd = 0;
Line 40... Line 40...
40
static struct vaapi_context *v_context;
40
static struct vaapi_context *v_context;
Line 41... Line 41...
41
 
41
 
42
static VASurfaceID v_surface_id[4];
42
static VASurfaceID v_surface_id[HWDEC_NUM_SURFACES];
Line 43... Line 43...
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))
Line 46... Line 46...
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[] = {
Line 73... Line 73...
73
    {0}
73
    {0}
74
};
74
};
Line 75... Line 75...
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;
Line 341... Line 341...
341
        return -1;
341
        return -1;
342
    }
342
    }
Line 343... Line 343...
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);
-
 
347
    printf("v_surface_id_3 %x\n", v_surface_id[3]);
346
                              v_surface_id,HWDEC_NUM_SURFACES,NULL,0);
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;
Line 377... Line 376...
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();
Line 395... Line 394...
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)
Line 399... Line 398...
399
{
398
{
Line 400... Line 399...
400
    int i, profile;
399
    VAProfile profile = VAProfileNone;
-
 
400
 
401
 
401
    ENTER();
Line 402... Line -...
402
    ENTER();
-
 
403
 
-
 
404
//    for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++)
402
 
405
//        printf(" %s", av_get_pix_fmt_name(fmt[i]));
403
    for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
Line 406... Line 404...
406
 
404
    {
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
 
-
 
412
        switch (avctx->codec_id)
-
 
-
 
409
 
413
        {
410
        if (codec == AV_CODEC_ID_H264)
414
        case CODEC_ID_MPEG2VIDEO:
411
        {
415
            profile = VAProfileMPEG2Main;
-
 
416
            break;
412
            if (profile == FF_PROFILE_H264_CONSTRAINED_BASELINE)
417
        case CODEC_ID_MPEG4:
-
 
418
        case CODEC_ID_H263:
-
 
419
            profile = VAProfileMPEG4AdvancedSimple;
413
                profile = FF_PROFILE_H264_MAIN;
420
            break;
414
        };
421
        case CODEC_ID_H264:
-
 
422
            profile = VAProfileH264High;
415
 
423
            break;
-
 
424
        case CODEC_ID_WMV3:
-
 
425
            profile = VAProfileVC1Main;
-
 
426
            break;
-
 
427
        case CODEC_ID_VC1:
-
 
428
            profile = VAProfileVC1Advanced;
-
 
429
            break;
416
        for (int n = 0; hw_profiles[n].av_codec; n++)
430
        default:
417
        {
431
            profile = -1;
418
            if (hw_profiles[n].av_codec   == codec &&
432
            break;
419
                hw_profiles[n].ff_profile == avctx->profile)
433
        }
420
            {
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
                {
-
 
424
                    avctx->hwaccel_context = v_context;
-
 
425
                    LEAVE();
437
                avctx->hwaccel_context = v_context;
426
                    return fmt[i]; ;
438
                LEAVE();
427
                }
439
                return fmt[i]; ;
428
            }
Line 440... Line 429...
440
            }
429
        }
Line 452... Line 441...
452
};
441
};
Line 453... Line 442...
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;
-
 
457
//    VDPAUContext *ctx = opaque;
-
 
458
 
-
 
459
//    ctx->video_surface_destroy(surface);
445
    struct av_surface surface = *(struct av_surface*)data;
460
    av_freep(&data);
446
    av_freep(&data);
Line 461... Line 447...
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)
-
 
450
{
-
 
451
    vst_t *vst = (vst_t*)avctx->opaque;
464
{
452
    void *surface;
Line 465... Line 453...
465
    vst_t *vst = (vst_t*)avctx->opaque;
453
 
Line 466... Line 454...
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
 
Line 491... Line 479...
491
        dpy = va_open_display();
479
        dpy = va_open_display();
492
        vst->hwCtx = vaapi_init(dpy);
480
        vst->hwCtx = vaapi_init(dpy);
Line 493... Line 481...
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
            {
Line 498... Line 486...
498
                int ret;
486
                vframe_t *vframe = calloc(1, sizeof(*vframe));
499
 
-
 
500
                ret = avpicture_alloc(&vst->vframe[i].picture, AV_PIX_FMT_BGRA,
487
 
501
                                      vst->vCtx->width, vst->vCtx->height);
-
 
502
                if ( ret != 0 )
-
 
503
                {
488
                vframe->format    = AV_PIX_FMT_NONE;
504
                    printf("Cannot alloc video buffer\n\r");
-
 
505
                    return ret;
489
                vframe->is_hw_pic = 1;
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;
Line 509... Line 493...
509
                vst->vframe[i].ready  = 0;
493
                list_add_tail(&vframe->list, &vst->input_list);
510
            };
494
            };
511
 
495
 
Line 518... Line 502...
518
        };
502
        };
519
    };
503
    };
Line 520... Line 504...
520
 
504
 
Line 521... Line 505...
521
    vst->hwdec = 0;
505
    vst->hwdec = 0;
522
 
506
 
-
 
507
    for(int i = 0; i < HWDEC_NUM_SURFACES; i++)
523
    for(int i = 0; i < 4; i++)
508
    {
Line -... Line 509...
-
 
509
        vframe_t *vframe;
-
 
510
        int ret;
524
    {
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");
-
 
519
            return ret;
532
            return ret;
520
        };
533
        };
521
        vframe->format = vst->vCtx->pix_fmt;
-
 
522
        vframe->index  = i;
534
        vst->vframe[i].format = vst->vCtx->pix_fmt;
523
        vframe->pts    = 0;
Line 535... Line 524...
535
        vst->vframe[i].pts    = 0;
524
        vframe->ready  = 0;
536
        vst->vframe[i].ready  = 0;
525
        list_add_tail(&vframe->list, &vst->input_list);
Line -... Line 526...
-
 
526
    };
-
 
527
 
-
 
528
    return 0;
-
 
529
}
537
    };
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
-
 
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,
Line 538... Line 590...
538
 
590
    WL_DRM_FORMAT_YVU420 = 0x32315659,
539
    return 0;
591
    WL_DRM_FORMAT_YUV422 = 0x36315559,
540
}
592
    WL_DRM_FORMAT_YVU422 = 0x36315659,
541
 
593
    WL_DRM_FORMAT_YUV444 = 0x34325559,
-
 
594
    WL_DRM_FORMAT_YVU444 = 0x34325659,
542
 
595
};
543
struct SwsContext *vacvt_ctx;
596
 
544
 
597
void va_create_planar(vst_t *vst, vframe_t *vframe)
545
void va_convert_picture(vst_t *vst, int width, int height, AVPicture *pic)
-
 
Line 546... Line 598...
546
{
598
{
-
 
599
    struct vaapi_context* const vaapi = v_context;
-
 
600
    VABufferInfo info = {0};
-
 
601
 
Line -... Line 602...
-
 
602
    VAImage vaimage;
-
 
603
    VAStatus status;
547
    uint8_t  *src_data[4];
604
    planar_t *planar;
548
    int       src_linesize[4];
605
 
549
    VAImage vaimage;
606
    vaSyncSurface(vaapi->display,v_surface_id[vframe->index]);
550
    VAStatus status;
607
 
551
    uint8_t *vdata;
608
    if(vframe->format != AV_PIX_FMT_NONE)
552
    struct vaapi_context* const vaapi = v_context;
609
        return;
553
 
-
 
554
    vaSyncSurface(vaapi->display,v_surface_id[vst->dfx]);
-
 
555
 
-
 
556
    status = vaDeriveImage(vaapi->display,v_surface_id[vst->dfx],&vaimage);
-
 
557
    if (!vaapi_check_status(status, "vaDeriveImage()"))
-
 
558
    {
-
 
559
        FAIL();
610
 
560
        return;
611
ENTER();
561
    };
612
 
562
 
613
    status = vaDeriveImage(vaapi->display,v_surface_id[vframe->index],&vaimage);
563
    static int once = 2;
614
    if (!vaapi_check_status(status, "vaDeriveImage()"))
564
 
615
    {
565
    if(once && vst->dfx == 0)
616
        FAIL();
566
    {
617
        return;
567
        VABufferInfo info = {0};
618
    };
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",
-
 
573
                vaimage.buf, vaimage.format.fourcc,
-
 
574
                vaimage.offsets[0],vaimage.pitches[0],
-
 
575
                vaimage.offsets[1],vaimage.pitches[1],
-
 
576
                vaimage.offsets[2],vaimage.pitches[2]);
-
 
577
 
-
 
578
        info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
-
 
579
        status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
-
 
580
        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
    };
623
           "offset2: %d pitch2: %d\n",
-
 
624
            vaimage.buf, vaimage.format.fourcc,
590
 
625
            vaimage.offsets[0],vaimage.pitches[0],
591
    src_linesize[0] = vaimage.pitches[0];
626
            vaimage.offsets[1],vaimage.pitches[1],
592
    src_linesize[1] = vaimage.pitches[1];
627
            vaimage.offsets[2],vaimage.pitches[2]);
593
    src_linesize[2] = vaimage.pitches[2];
628
*/
594
    src_linesize[3] = 0;
629
    info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
595
 
-
 
596
    status = vaMapBuffer(vaapi->display,vaimage.buf,(void **)&vdata);
630
    status = vaAcquireBufferHandle(vaapi->display, vaimage.buf, &info);
597
    if (!vaapi_check_status(status, "vaMapBuffer()"))
631
    if (!vaapi_check_status(status, "vaAcquireBufferHandle()"))
598
    {
632
    {
599
        FAIL();
633
        vaDestroyImage(vaapi->display, vaimage.image_id);
600
        return;
634
        FAIL();
601
    };
635
        return;
602
 
-
 
603
//    printf("vdata: %x offset0: %d offset1: %d offset2: %d\n", vdata,
-
 
604
//            vaimage.offsets[0],
-
 
605
//            vaimage.offsets[1],
636
    };
606
//            vaimage.offsets[2]);
637
/*
607
 
638
    printf("vaAcquireBufferHandle: %x type: %x\n"
608
    src_data[0] = vdata + vaimage.offsets[0];
639
            "mem type: %x mem size: %d\n",
609
    src_data[1] = vdata + vaimage.offsets[1];
640
            info.handle, info.type, info.mem_type, info.mem_size);
610
    src_data[2] = vdata + vaimage.offsets[2];
641
*/
-
 
642
    planar = pxCreatePlanar(info.handle, WL_DRM_FORMAT_NV12,
611
    src_data[3] = 0;
643
                            vaimage.width, vaimage.height,
Line 612... Line -...
612
 
-
 
613
    vacvt_ctx = sws_getCachedContext(vacvt_ctx, width, height, AV_PIX_FMT_NV12,
-
 
614
              width, height, AV_PIX_FMT_BGRA,
644
                            vaimage.offsets[0],vaimage.pitches[0],
615
              SWS_FAST_BILINEAR, NULL, NULL, NULL);
645
                            vaimage.offsets[1],vaimage.pitches[1],
-
 
646
                            vaimage.offsets[2],vaimage.pitches[2]);
616
    if(vacvt_ctx == NULL)
647
    if(planar != NULL)