首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >微软软件H264编码器的质量逐渐下降

微软软件H264编码器的质量逐渐下降
EN

Stack Overflow用户
提问于 2022-04-05 03:50:07
回答 1查看 164关注 0票数 0

我有一个功能良好的编码器使用媒体基金会,它使用硬件加速。我已经决定添加微软的软件H264编码器作为后盾,如果硬件加速是由于某些原因无法提供。

我的问题是,当我开始从编码器流,质量开始很好,然后迅速下降,直到没有任何可读性/可见性。这似乎是在有任何动议的时候触发的。这个问题只在我使用软件编码器时才存在。当我使用任何硬件编码器,它可能会退化片刻,当有运动,但它很快恢复了质量以某种方式。

以下是任何形式的运动之前的一个框架:

以下是它如何处理发生的任何运动:

这是我的编码器配置

代码语言:javascript
运行
复制
HRESULT configure_encoder(const CComPtr<IMFTransform>& in_transform, CComPtr<IMFDXGIDeviceManager>& in_device_manager,
    const DWORD in_input_stream_id, const DWORD output_stream_id
)
{
    HRESULT hr = S_OK;

    // Sets or clears the Direct3D Device Manager for DirectX Video Acceleration (DXVA)
    if (FAILED(hr = in_transform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, reinterpret_cast<ULONG_PTR>(in_device_manager.p))))
    {
        std::cout << "Failed to enable DXVA acceleration for encoder";
        //return hr;
    }

    // Create output type
    CComPtr<IMFMediaType> output_type;
    if (FAILED(hr = MFCreateMediaType(&output_type)))
        return hr;

    // Set output type
    if (FAILED(hr = output_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)))
        return hr;
    if (FAILED(hr = output_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264)))
        return hr;
    if (FAILED(hr = output_type->SetUINT32(MF_MT_AVG_BITRATE, encode_bitrate)))
        return hr;
    if (FAILED(hr = output_type->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_High)))
        return hr;
    if (FAILED(hr = MFSetAttributeSize(output_type, MF_MT_FRAME_SIZE, encode_width, encode_height)))
        return hr;
    if (FAILED(hr = MFSetAttributeRatio(output_type, MF_MT_FRAME_RATE, 60, 1)))
        return hr;
    if (FAILED(hr = output_type->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlaceMode::MFVideoInterlace_Progressive)))
        return hr;

    // Set output type
    if (FAILED(hr = in_transform->SetOutputType(output_stream_id, output_type, 0)))
        return hr;

    // Input type
    CComPtr<IMFMediaType> input_type;

    if (FAILED(hr = in_transform->GetInputAvailableType(in_input_stream_id, 0, &input_type)))
        return hr;

    // Input type settings
    if (FAILED(hr = input_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)))
        return hr;
    if (FAILED(hr = input_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12)))
        return hr;
    if (FAILED(hr = MFSetAttributeSize(input_type, MF_MT_FRAME_SIZE, encode_width, encode_height)))
        return hr;
    if (FAILED(hr = MFSetAttributeRatio(input_type, MF_MT_FRAME_RATE, 60, 1)))
        return hr;
    if (FAILED(hr = input_type->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlaceMode::MFVideoInterlace_Progressive)))
        return hr;

    // Set input type
    if (FAILED(hr = in_transform->SetInputType(in_input_stream_id, input_type, 0)))
        return hr;

    std::cout << "- Set encoder configuration" << std::endl;

    // AMD encoder crashes on this line
    /*DWORD flags;
    if (FAILED(hr = inTransform->GetInputStatus(0, &flags)))
        return hr;*/

    return hr;
}

我试着篡改了下面的codec属性,希望能有所改变,但我无法做出任何明显的改变。

代码语言:javascript
运行
复制
// Get Codec API pointer
ICodecAPI* mpCodecAPI = NULL;
if (FAILED(hr = encoder_transform->QueryInterface(IID_PPV_ARGS(&mpCodecAPI))))
return hr;

VARIANT var;

// Set mode to CBR
var = { 0 };
var.vt = VT_UI4;
var.lVal = eAVEncCommonRateControlMode_CBR;
if (FAILED(hr = mpCodecAPI->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var)))
return hr;

var.vt = VT_BOOL;
var.boolVal = VARIANT_TRUE;
if (FAILED(hr = mpCodecAPI->SetValue(&CODECAPI_AVLowLatencyMode, &var)))
return hr;

var = { 0 };
var.vt = VT_UI4;
var.lVal = 100;
if (FAILED(hr = mpCodecAPI->SetValue(&CODECAPI_AVEncCommonQuality, &var)))
return hr;

var = { 0 };
var.vt = VT_UI4;
var.lVal = 4;
if (FAILED(hr = mpCodecAPI->SetValue(&CODECAPI_AVEncVideoMaxNumRefFrame, &var)))
return hr;

var = { 0 };
var.vt = VT_UI4;
var.lVal = 0;
if (FAILED(hr = mpCodecAPI->SetValue(&CODECAPI_AVEncMPVDefaultBPictureCount, &var)))
return hr;

var = { 0 };
var.vt = VT_UI4;
var.lVal = 0;
if (FAILED(hr = mpCodecAPI->SetValue(&CODECAPI_AVEncMPVGOPSize, &var)))
return hr;```
EN

回答 1

Stack Overflow用户

发布于 2022-04-05 05:39:27

您的代码中没有设置软件编码器。

代码语言:javascript
运行
复制
    CComPtr<IMFAttributes> attrs;
    MFCreateAttributes(&attrs, 0);
    attrs->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, false);
    hr = MFCreateSinkWriterFromURL(file, NULL, attrs, &pSinkWriter);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71746114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档