vaapi 格式空间转换

D3D12转换格式空间,D3D12编码仅支持nv12类型,如输入是RGBA BGRA BGRX等图像各种均可通过改模块进行格式空间的转换。代码为GPU接口handle的传入转换,其他格式改为文件或缓存空间即可

其vaapi接口参考来自https://github.com/intel/libva-utils/blob/master/videoprocess/vavpp.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/time.h>
#include <assert.h>
#include <va/va.h>
#include <va/va_vpp.h>

static VAContextID context_id = 0;
static VAConfigID  config_id = 0;
static VASurfaceID g_in_surface_id = VA_INVALID_ID;
static VASurfaceID g_out_surface_id = VA_INVALID_ID;

static uint32_t g_in_pic_width = 352;
static uint32_t g_in_pic_height = 288;
static uint32_t g_out_pic_width = 352;
static uint32_t g_out_pic_height = 288;

static uint32_t g_in_fourcc  = VA_FOURCC('N', 'V', '1', '2');
static uint32_t g_in_format  = VA_RT_FORMAT_YUV420;
static uint32_t g_out_fourcc = VA_FOURCC('N', 'V', '1', '2');
static uint32_t g_out_format = VA_RT_FORMAT_YUV420;

static get_context(VAContextID &context_id)
{  
    /* Render target surface format check */
    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    va_status = vaGetConfigAttributes(va_dpy,
                                      VAProfileNone,
                                      VAEntrypointVideoProc,
                                      &attrib,
                                      1);
    CHECK_VASTATUS(va_status, "vaGetConfigAttributes");
    if (!(attrib.value & g_out_format)) {
        printf("RT format %d is not supported by VPP !\n", g_out_format);
        assert(0);
    }

   va_status = vaCreateConfig(va_dpy,
                               VAProfileNone,
                               VAEntrypointVideoProc,
                               &attrib,
                               1,
                               &config_id);
    CHECK_VASTATUS(va_status, "vaCreateConfig");

    va_status = vaCreateContext(va_dpy,
                                config_id,
                                g_out_pic_width,
                                g_out_pic_height,
                                VA_PROGRESSIVE,
                                &g_out_surface_id,
                                1,
                                &context_id);
    CHECK_VASTATUS(va_status, "vaCreateContext");
}

static VAStatus
video_frame_process(VAProcFilterType filter_type,
                    uint32_t frame_idx,
                    VASurfaceID in_surface_id,
                    VASurfaceID out_surface_id)
{
    VAStatus va_status;
    VAProcPipelineParameterBuffer pipeline_param;
    VARectangle surface_region, output_region;
    VABufferID pipeline_param_buf_id = VA_INVALID_ID;
    VABufferID filter_param_buf_id = VA_INVALID_ID;

    uint32_t filter_count = 0;

    /* Fill pipeline buffer */
    surface_region.x = 0;
    surface_region.y = 0;
    surface_region.width = g_in_pic_width;
    surface_region.height = g_in_pic_height;
    output_region.x = 0;
    output_region.y = 0;
    output_region.width = g_out_pic_width;
    output_region.height = g_out_pic_height;

    memset(&pipeline_param, 0, sizeof(pipeline_param));
    pipeline_param.surface = in_surface_id;
    pipeline_param.surface_region = &surface_region;
    pipeline_param.output_region = &output_region;

    pipeline_param.filter_flags = 0;
    pipeline_param.filters      = &filter_param_buf_id;
    pipeline_param.num_filters  = filter_count;

    va_status = vaCreateBuffer(va_dpy,
                               context_id,
                               VAProcPipelineParameterBufferType,
                               sizeof(pipeline_param),
                               1,
                               &pipeline_param,
                               &pipeline_param_buf_id);
    CHECK_VASTATUS(va_status, "vaCreateBuffer");

    va_status = vaBeginPicture(va_dpy,
                               context_id,
                               out_surface_id);
    CHECK_VASTATUS(va_status, "vaBeginPicture");

    va_status = vaRenderPicture(va_dpy,
                                context_id,
                                &pipeline_param_buf_id,
                                1);
    CHECK_VASTATUS(va_status, "vaRenderPicture");
    
    va_status = vaEndPicture(va_dpy, context_id);
    CHECK_VASTATUS(va_status, "vaEndPicture");

    va_status = vaSyncSurface(va_dpy, out_surface_id); //wait gpu finish
    CHECK_VASTATUS(va_status, "vaEndPicture");

    if (filter_param_buf_id != VA_INVALID_ID)
        vaDestroyBuffer(va_dpy, filter_param_buf_id);

    if (pipeline_param_buf_id != VA_INVALID_ID)
        vaDestroyBuffer(va_dpy, pipeline_param_buf_id);

    return va_status;
}


int main()
{

// handle is gpu capture 
 VAStatus va_status;
 VASurfaceID surface_id;
VASurfaceID out_surface_id;

HANDLE nt_handle[2];
nt_handles[0] = handle;
VASurfaceAttrib attrs[3];
VASurfaceAttrib attrs_process[2];
attrs[0].type = VASurfaceAttribPixelFormat;
attrs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
attrs[0].value.type = VAGencericValueTypeTnteger;
attrs[0].value.value.i = VA_FOURCC('B', 'G', 'R', 'A');

attrs[1].type = VASurfaceAttribMemoryType;
attrs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
attrs[1].value.type = VAGencericValueTypeTnteger;
attrs[1].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE;

attrs[2].type = VASurfaceAttribPixelFormat;
attrs[2].flags = VA_SURFACE_ATTRIB_SETTABLE;
attrs[2].value.type = VAGencericValueTypePointer;
attrs[2].value.value.p = &nt_handles;

attrs_process[0].type = VASurfaceAttribPixelFormat;
attrs_process[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
attrs_process[0].value.type = VAGencericValueTypeTnteger;
attrs_process[0].value.value.i = VA_FOURCC('N', 'V', '1', '2');


 va_status = vaCreateSurface(va_ctx_va_dpy, VA_RT_FORMAT_RGB32, va_ctx->witch, va_ctx_height, &surface_id, 1, attrs, FF_ARRAY_ELEMS(attrs)); //attrs = 3
 CHECK_VASTATUS(va_status, "vaCreateSurface");

va_status = vaCreateSurface(va_ctx_va_dpy, VA_RT_FORMAT_YUV420, va_ctx->witch, va_ctx_height, &out_surface_id, 1, attrs_process, FF_ARRAY_ELEMS(attrs_process)); //attrs = 2
 CHECK_VASTATUS(va_status, "vaCreateSurface");

 video_frame_process(g_filter_type, context_process_id, surface_id, out_surface_id);
 
 vaDestroySurface(va_ctx->va_dpy, &surface_id, 1);

 src_surface = out_surface_id;
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值