我有一个功能良好的编码器使用媒体基金会,它使用硬件加速。我已经决定添加微软的软件H264编码器作为后盾,如果硬件加速是由于某些原因无法提供。
我的问题是,当我开始从编码器流,质量开始很好,然后迅速下降,直到没有任何可读性/可见性。这似乎是在有任何动议的时候触发的。这个问题只在我使用软件编码器时才存在。当我使用任何硬件编码器,它可能会退化片刻,当有运动,但它很快恢复了质量以某种方式。
以下是任何形式的运动之前的一个框架:

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

这是我的编码器配置
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属性,希望能有所改变,但我无法做出任何明显的改变。
// 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;```发布于 2022-04-05 05:39:27
您的代码中没有设置软件编码器。
CComPtr<IMFAttributes> attrs;
MFCreateAttributes(&attrs, 0);
attrs->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, false);
hr = MFCreateSinkWriterFromURL(file, NULL, attrs, &pSinkWriter);https://stackoverflow.com/questions/71746114
复制相似问题