首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在媒体基础(Windows 10)中使用硬件(Nvenc)编码

如何在媒体基础(Windows 10)中使用硬件(Nvenc)编码
EN

Stack Overflow用户
提问于 2016-11-28 21:04:14
回答 1查看 2.9K关注 0票数 2

对不起我的英语。我对Windows 10中使用MF的硬件编码有疑问,我有Nvidia gtx 650 (与nvenc)。我在c#中开发了将活动帧流编码为c#文件的应用程序。

我以这段代码( https://codereview.stackexchange.com/questions/136144/h-264-image-encoding-using-media-foundation-net )为例。我创建了IMFSinkWriter对象(SinkWriter),例如,使用MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS=true

代码语言:javascript
复制
private int InitializeSinkWriter(String outputFile, int videoWidth, int videoHeight)
{            
    IMFMediaType mediaTypeIn = null;
    IMFMediaType mediaTypeOut = null;
    IMFAttributes attributes = null;

    int hr = 0;

    if (Succeeded(hr)) hr = MFExtern.MFCreateAttributes(out attributes, 1);
    if (Succeeded(hr)) hr = attributes.SetUINT32(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 1);
    if (Succeeded(hr)) hr = attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1);

    // Create the sink writer 
    if (Succeeded(hr)) hr = MFExtern.MFCreateSinkWriterFromURL(outputFile, null, attributes, out sinkWriter);

    // Create the output type
    if (Succeeded(hr)) hr = MFExtern.MFCreateMediaType(out mediaTypeOut);
    if (Succeeded(hr)) hr = mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
    if (Succeeded(hr)) hr = mediaTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.H264);
    if (Succeeded(hr)) hr = mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AVG_BITRATE, videoBitRate);
    if (Succeeded(hr)) hr = mediaTypeOut.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int) MFVideoInterlaceMode.Progressive);
    if (Succeeded(hr)) hr = MFExtern.MFSetAttributeSize(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight);
    if (Succeeded(hr)) hr = MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1);
    if (Succeeded(hr)) hr = MFExtern.MFSetAttributeRatio(mediaTypeOut, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
    if (Succeeded(hr)) hr = sinkWriter.AddStream(mediaTypeOut, out streamIndex);

    // Create the input type 
    if (Succeeded(hr))  hr = MFExtern.MFCreateMediaType(out mediaTypeIn);
    if (Succeeded(hr)) hr = mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
    if (Succeeded(hr)) hr = mediaTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.RGB24);
    if (Succeeded(hr)) hr = mediaTypeIn.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)MFVideoInterlaceMode.Progressive);
    if (Succeeded(hr)) hr = MFExtern.MFSetAttributeSize(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_SIZE, videoWidth, videoHeight);
    if (Succeeded(hr)) hr = MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_FRAME_RATE, VIDEO_FPS, 1);
    if (Succeeded(hr)) hr = MFExtern.MFSetAttributeRatio(mediaTypeIn, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
    if (Succeeded(hr)) hr = sinkWriter.SetInputMediaType(streamIndex, mediaTypeIn, null);

    // Start accepting data
    if (Succeeded(hr))  hr = sinkWriter.BeginWriting();

    COMBase.SafeRelease(mediaTypeIn);
    COMBase.SafeRelease(mediaTypeOut);

    return hr;            
}

例如,我为每个帧编码执行了以下步骤: 1.创建IMFMediaBuffer对象(缓冲区)并在其中复制框架2.创建IMFSample对象(示例)和sample.AddBuffer(缓冲区) 3.将示例写入IMFSinkWriter对象(SinkWriter)

结果是CPU上有100%的负载(这不是硬件编码!)。如何使用相同的代码进行硬件编码?

EN

回答 1

Stack Overflow用户

发布于 2016-11-29 12:07:36

接收器写入器API为您提供自动转换(尤指。(编码)的数据,当您请求时,它依次包括H.264编码。您确实是通过用MFMediaType.H264执行AddStream,然后用MFMediaType.RGB24执行SetInputMediaType来请求它。

但是,您没有选择编码器的细粒度灵活性。API是通过设计为您选择“最佳”编码器的行为。您的应用MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS意味着您可以使用硬件MFT,但这并不意味着您强制选择。你甚至不知道硬件MFT一开始是否可行,是吗?再一次,API通过设计的行为避免了所谓的“编解码地狱”的模糊性,保留了选择最佳适用编码器本身的权利。文档以这样的方式解释:如果存在经过认证的硬件编码器,则通常会使用它来代替媒体基金会相关场景中的收件箱系统编码器。

最大的CPU负载是一个提示,压缩可能是软件,但它也可能是由其他原因造成的。在您的情况下,您需要检查哪些H.264编码器可用,调试和跟踪您的应用程序。当API不自动拾取编码器时,要强制使用Media Foundation进行硬件H.264编码,您没有其他选择,只能自己将视频压缩到H.264 (使用MFT,它对应于编码器以MFT的形式存在但API不拾取它的不太可能的情况,或者编码否则esp )。使用特定于供应商的SDK),然后将压缩数据提供给Sink Writer以生成格式良好的MP4文件,可能还会混合音频。

另请参阅:

您可以使用MediaFoundationVideoEncoderTransforms工具检查硬件编码器的可用性。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40853446

复制
相关文章

相似问题

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