You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D3D11硬件加速解码NV12格式AVFrame画面损坏问题求助

D3D11硬件加速解码NV12帧画面损坏问题解决记录

我基于ffmpeg-autogen实现视频解码器,尝试采用D3D11作为硬件加速器时,解码得到的NV12格式AVFrame画面损坏;改用Vulkan加速器则一切正常,但Vulkan会占用更多显卡资源。渲染环节使用OpenTK,通过纹理和着色器将接收的帧转换为RGB格式。

解码器初始化代码

public VideoStreamDecoder(AVCodecParameters* parameters, AVCodec* codec)
{
    AVCodec* _codec = codec;
    
    _pCodecContext = ffmpeg.avcodec_alloc_context3(_codec);

    ffmpeg.av_hwdevice_ctx_create(&_pCodecContext->hw_device_ctx, AVHWDeviceType.AV_HWDEVICE_TYPE_D3D11VA, null, null, 0).ThrowExceptionIfError();

    ffmpeg.avcodec_parameters_to_context(_pCodecContext, parameters).ThrowExceptionIfError();
    ffmpeg.avcodec_open2(_pCodecContext, _codec, null).ThrowExceptionIfError();

    CodecName = ffmpeg.avcodec_get_name(_codec->id);
    FrameSize = new Size(_pCodecContext->width, _pCodecContext->height);
    PixelFormat = _pCodecContext->pix_fmt;

    _pFrame = ffmpeg.av_frame_alloc();
    _receivedFrame = ffmpeg.av_frame_alloc();
}

帧读取函数

public bool TryReadNextFrame(out AVFrame frame, AVPacket packet)
{
    int error;

    do
    {
        ffmpeg.avcodec_send_packet(_pCodecContext, &packet).ThrowExceptionIfError();

        error = ffmpeg.avcodec_receive_frame(_pCodecContext, _pFrame);

    } while (error == ffmpeg.AVERROR(ffmpeg.EAGAIN));

    error.ThrowExceptionIfError();

    ffmpeg.av_hwframe_transfer_data(_receivedFrame, _pFrame, 0);
    // 获取NV12格式帧

    var clonedFrame = ffmpeg.av_frame_clone(_receivedFrame);

    frame = *clonedFrame;

    return true;
}

现象对比

  • Vulkan:显示正常
  • D3D11(同一摄像头,视频格式为yuv420p):画面损坏
  • 特殊现象:仅视频格式为yuvj420的摄像头能在D3D11下正常工作

尝试过的解决方案

  • 使用sws_scale将NV12格式转NV12,可解决问题但CPU占用过高
  • 在av_hwframe_transfer_data前将帧转换为RGB格式,Vulkan下勉强可用,但D3D11下无效

更新记录

  1. 发现帧的linesize大于宽度,尝试修改:
_receivedFrame->linesize[0] = _receivedFrame->width;

画面有所改善,但仍不完美。

  1. 添加以下代码后,画面恢复正常:
_receivedFrame->linesize[1] = _receivedFrame->width;

耗时一整天仅写了两行代码 :)

内容的提问来源于stack exchange,提问作者faith0058

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:02:05