【问题标题】:Low quality H.265 Media Foundation encoding?低质量 H.265 媒体基础编码?
【发布时间】:2020-01-17 10:45:29
【问题描述】:

我正在尝试使用 MF H.265 对视频进行编码,无论我尝试什么,质量总是低于非 MF 编码器产生的相同设置的视频,例如 VideoPad 使用的(比如 ffmpeg)相同的 4000 比特率。

Videopad 制作this 游泳男孩的视频。我的应用程序生成 this 视频。我的应用程序中的天空在 6K 比特率时明显更差,而 VideoPad 为 1K。

pMediaTypeOutVideo->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
pMediaTypeOutVideo->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_HEVC);

pMediaTypeOutVideo->SetUINT32(MF_MT_AVG_BITRATE, 4000000);
MFSetAttributeSize(pMediaTypeOutVideo, MF_MT_FRAME_SIZE, 1920,1080);
MFSetAttributeRatio(pMediaTypeOutVideo, MF_MT_FRAME_RATE, 25, 1);
MFSetAttributeRatio(pMediaTypeOutVideo, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
pMediaTypeOutVideo->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
pMediaTypeOutVideo->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_Wide);



CComPtr<ICodecAPI> ca;
hr = pSinkWriter->GetServiceForStream(OutVideoStreamIndex, GUID_NULL, __uuidof(ICodecAPI), (void**)&ca);
if (ca)
{
    if (true)
    {
        VARIANT v = {};
        v.vt = VT_BOOL;
        v.boolVal  = VARIANT_FALSE;
        ca->SetValue(&CODECAPI_AVLowLatencyMode, &v);

    }
    if (true)
    {
        VARIANT v = {};
        v.vt = VT_UI4;
        v.ulVal = 100;
        hr = ca->SetValue(&CODECAPI_AVEncCommonQualityVsSpeed, &v);
    }

    if (true)
    {
        VARIANT v = {};
        v.vt = VT_UI4;
        v.ulVal = eAVEncCommonRateControlMode_Quality;
        ca->SetValue(&CODECAPI_AVEncCommonRateControlMode, &v);
        if (true)
        {
            VARIANT v = {};
            v.vt = VT_UI4;
            v.ulVal = 100;
            ca->SetValue(&CODECAPI_AVEncCommonQuality, &v);
        }
    }
}

无论如何,4000k 的质量仍然不如 ffmpeg 产生的质量。 eAVEncCommonRateControlMode_QualityCODECAPI_AVEncCommonQuality 似乎也没有生效(它适用于 H.264)。看到更好质量的唯一方法是提高比特率。

另外,速度参数似乎不会影响质量或编码器速度。

即使是 1000k Videopad 制作的视频在天空中也没有像素化。当然,它的速度是 1/100。

Media Foundation 的编码器比 ffmpeg 的差吗?我错过了什么?

编辑:使用软件渲染(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS 为 FALSE)也同样糟糕。

更新:在我的笔记本电脑上尝试了 AMD 硬件编码器。类似的问题,码率低的时候画质很差。

【问题讨论】:

  • 您能否将 Nvidia 编码器和其他编码器生成的文件与 MediaInfo 进行比较,看看它们可能有哪些其他差异?
  • @VuVirt 问题已编辑以包含视频。
  • 您使用的转换是什么?在我的系统上,我只看到用于 H265 的 Intel 和 nVidia MFT,两者都是基于硬件的。使用 topoedit,我可以看到英特尔 MFT 的 CodecApi 属性是 AVEncCommonBufferSize、AVEncCommonQualityVsSpeed 等。您能否提供您尝试使用的转换的所有 CodecAPI 属性和当前值?

标签: c++ winapi ms-media-foundation


【解决方案1】:

我用 MediaInfo 检查了这两个视频,很明显它们使用了不同的 HEVC 配置文件,这应该是影响 NVidia 编码视频质量的主要原因。 下面是对比截图:

您可以尝试将输入 IMFMediaType 中的 MF_MT_VIDEO_PROFILE 设置为 eAVEncH265VProfile_Main_420_8。此外,还应相应地设置 MF_MT_MPEG2_LEVEL。以 eAVEncH265VLevel4_1 为例。

您也可以考虑使用IClassFactory approach 以保证调用 ICodecAPI 方法的正确顺序。

【讨论】:

  • 设置配置文件后仍然是相同的媒体信息。总是留在 Main@L0.4@Main
  • 如何设置 MF_MT_MPEG2_LEVEL ?
  • 你也可以看看这个:*.com/questions/53291761/…
  • 我更新了答案:您可以将配置文件设置为 eAVEncH265VLevel4_1。
  • 我使用 MF_FT_MPEG2_LEVEL 设置配置文件,现在 Main@L.0 已更改。但是我没有看到质量差异。也许主要问题是无论我设置什么,ICodecAPI 中的内容都没有响应。
【解决方案2】:

也许仅仅是因为软件编码器比硬件编码器好。

如果我看看这个:https://www.techspot.com/article/1131-hevc-h256-enconding-playback/page7.html,我也会确认硬件 nvidia 编码器是坏的,与 x265(日期 2016)相比。

我无法进行更多调查,但从我看到的关于您的帖子的情况来看:

  • pMediaTypeOutVideo->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_Wide); -> 为什么不是 MFNominalRange_Normal ?
  • 除了 CODECAPI_AVLowLatencyMode/CODECAPI_AVEncCommonQualityVsSpeed/CODECAPI_AVEncCommonRateControlMode,还有其他来自 NVidia 编码器的 ICodecAPI...
  • 2遍编码参数在哪里?

我发现至少有三个论坛说 NVidia HEVC 编码器会模糊图像。并且您确认了这一点,所以... 假新闻与否,(日期 2018/2019)..

来自 NVidia https://developer.nvidia.com/nvidia-video-codec-sdk#NVENCFeatures(日期未定义)。

我对这个图表一无所知,但 NVidia 似乎假装他们是最好的……所以不管是不是假新闻。

编辑

使用软件渲染(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS 到 FALSE)也同样糟糕。

您能在软件模式下确认,H.265 / HEVC Video Encoder 使用了吗?

如果是,您是否使用过 Codec Properties ?

  • CODECAPI_AVEncCommonRateControlMode
  • CODECAPI_AVEncCommonMeanBitRate
  • CODECAPI_AVEncCommonBufferSize
  • CODECAPI_AVEncCommonMaxBitRate
  • CODECAPI_AVEncMPVGOPSize
  • CODECAPI_AVLowLatencyMode
  • CODECAPI_AVEncCommonQualityVsSpeed
  • CODECAPI_AVEncVideoForceKeyFrame
  • CODECAPI_AVEncVideoEncodeQP
  • CODECAPI_AVEncVideoMinQP
  • CODECAPI_AVEncVideoMaxQP
  • CODECAPI_VideoEncoderDisplayContentType
  • CODECAPI_AVEncNumWorkerThreads

【讨论】:

  • 我的问题是,当不设置MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS时,它也一样,但是,而且更慢。
  • 如果不启用硬件转换,我想是使用MF软件编码器。
  • 是的,但质量很差 - 再次。
  • 我编辑我的答案。不幸的是,我不会再帮你了,我没有带硬件 hevc 编码器的 NVidia GPU。