Низкое качество кодирования H.265 Media Foundation? - PullRequest
2 голосов
/ 17 января 2020

Я пытаюсь кодировать видео с помощью MF H.265, и независимо от того, что я пытаюсь, качество всегда ниже, чем видео с одинаковыми настройками, передаваемое не кодировщиками MF, как, например, то, что использует VideoPad (скажем, ffmpeg) в тот же самый битрейт 4000.

Видеопад производит это видео плавательного мальчика. Мое приложение производит это видео. Небо в моем приложении явно хуже при битрейте 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_Quality и CODECAPI_AVEncCommonQuality, кажется, не вступают в силу (это работает в H.264). Единственный способ улучшить качество - повысить битрейт.

Кроме того, параметр скорости, похоже, не влияет на качество или скорость кодера.

Даже при 1000k видео, произведенное Videopad, не влияет иметь пикселизацию в небе. Конечно, его скорость равна 1/100.

Кодеры Media Foundation хуже, чем у ffmpeg? Чего мне не хватает?

Редактировать: Рендеринг с программным обеспечением (MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS в FALSE) также одинаково плох.

Обновление: попробовал на моем ноутбуке с аппаратным кодером AMD. Аналогичная проблема, когда битрейт низкий, качество ужасное.

Ответы [ 2 ]

0 голосов
/ 21 января 2020

Возможно, просто потому, что программные кодировщики лучше аппаратных.

Если бы я взглянул на это: 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_AVEncCommonRateControlMode
  • CODECAPI_AVEncCommonMe одна тысяча сорок-девять *
  • CODECAPI_AVEncCommonBufferSize
  • CODECAPI_AVEncMPVGOPSize
  • CODECAPI_AVLowLatencyMode
  • CODECAPI_AVEncVideoForceKeyFrame
  • CODECAPI_AVEncVideoEncodeQP
  • CODECAPI_AVEncVideoMaxQP
  • CODECAPI_VideoEncoderDisplayContentType
  • CODECAPI_AVEncNumWorker * 10 * 1071
0 голосов
/ 19 января 2020

Я проверил два видео с MediaInfo, и очевидно, что они используют другой профиль HEV C, что должно быть основной причиной, влияющей на качество видео, кодированного NVidia. Вот скриншот для сравнения:

enter image description here

Вы можете попробовать установить MF_MT_VIDEO_PROFILE во входном IMFMediaType для eAVEncH265VProfile_Main_420_8. Кроме того, MF_MT_MPEG2_LEVEL также должен быть установлен соответствующим образом. Например, для eAVEncH265VLevel4_1.

Вы также можете рассмотреть возможность использования IClassFactory подход , чтобы гарантировать правильный порядок вызова методов ICodecAPI.

...