我是靠谱客的博主 有魅力钢铁侠,最近开发中收集的这篇文章主要介绍使用D3D11将NV12转成RGB,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我显示使用硬解解码出视频,但是解码器只支持NV12的格式,需要转成RGB格式显示,并且这部分在GPU里面做,速度也会比较快,但是,碰到问题:D3D11 CORRUPTION:ID3D11DeviceContext::VideoProcessorBlt: Second parameter does not match device;

D3D11_TEXTURE2D_DESC dstDesc;
ZeroMemory(&dstDesc, sizeof(dstDesc));
dstDesc.Width = s->width;
dstDesc.Height = s->height;
dstDesc.MipLevels = 1;
dstDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dstDesc.SampleDesc.Count = 1;
dstDesc.ArraySize = ctx->num_surfaces;
dstDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
dstDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;

ID3D11Texture2D *srcTextureNV12Fmt = texture;
ID3D11Texture2D *dstTextureRGBFmt;
ID3D11Device_CreateTexture2D((ID3D11Device*)ist->d3ddev, &dstDesc, NULL, &dstTextureRGBFmt);

//Create Views for VideoProc In/Output

D3D11_VIDEO_PROCESSOR_CONTENT_DESC contentDesc;
ZeroMemory(&contentDesc, 0, sizeof(contentDesc));
contentDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
contentDesc.InputWidth = frame->width;
contentDesc.InputHeight = frame->height;
contentDesc.OutputWidth = frame->width;
contentDesc.OutputHeight = frame->height;
contentDesc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL;

hr = ID3D11VideoDevice_CreateVideoProcessorEnumerator((ID3D11VideoDevice*) ist->d3dviddev, &contentDesc, ist->d3dvideoProcEnum);
if (hr < 0)
{
    printf("Cann't get a video Processor for the video!");
    destroy_video_proc(s);
    return -1;
}

D3D11_VIDEO_PROCESSOR_CAPS processorCaps;
hr = ID3D11VideoProcessorEnumerator_GetVideoProcessorCaps(ist->d3dvideoProcEnum, &processorCaps);
for (int i = 0; i < processorCaps.RateConversionCapsCount; i++) {
    hr = ID3D11VideoDevice_CreateVideoProcessor((ID3D11VideoDevice*)ist->d3dviddev, ist->d3dvideoProcEnum, i, ist->d3dVideoProc);
    if (hr >= 0)
        break;
    ist->d3dVideoProc = NULL;
}

ID3D11VideoProcessorOutputView *videoProcOuputView;
ID3D11VideoProcessorInputView * videoProcInputView;

D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputViewDesc = { 0 };
inputViewDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
inputViewDesc.Texture2D.ArraySlice = ctx->num_surfaces;// view_desc.Texture2D.ArraySlice;
inputViewDesc.Texture2D.MipSlice = 0;
hr = ID3D11VideoDevice_CreateVideoProcessorInputView((ID3D11VideoDevice*)ist->d3dviddev, srcTextureNV12Fmt, ist->d3dvideoProcEnum, &inputViewDesc, &videoProcInputView);
if (hr < 0) {
    printf("Cann't CreateVideoProcessorInputView!");
    destroy_video_proc(s);
    return -1;
}

D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputViewDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D };
outputViewDesc.Texture2D.MipSlice = 0;
hr = ID3D11VideoDevice_CreateVideoProcessorOutputView((ID3D11VideoDevice*)ist->d3dviddev, dstTextureRGBFmt, ist->d3dvideoProcEnum, &outputViewDesc, &videoProcOuputView);
if (hr < 0) {
    printf("Cann't CreateVideoProcessorOutputView!");
    destroy_video_proc(s);
    return -1;
}

// Setup Streams
D3D11_VIDEO_PROCESSOR_STREAM streams = {0};
streams.Enable = TRUE;
streams.pInputSurface = &videoProcInputView;

hr = ID3D11VideoContext_VideoProcessorBlt((ID3D11VideoContext*) ist->d3dvidctx, ist->d3dVideoProc, &videoProcOuputView, 0, 1, &streams);
if (hr < 0) {
    printf("Cann't VideoProcessorBlt!");
    destroy_video_proc(s);
    return -1;
}

 

最后

以上就是有魅力钢铁侠为你收集整理的使用D3D11将NV12转成RGB的全部内容,希望文章能够帮你解决使用D3D11将NV12转成RGB所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部