Windows Phone 8.1 Media Foundation H264 最大分辨率

Posted

技术标签:

【中文标题】Windows Phone 8.1 Media Foundation H264 最大分辨率【英文标题】:Windows Phone 8.1 Media Foundation H264 max resolution 【发布时间】:2017-04-06 17:17:48 【问题描述】:

我正在尝试使用 Media Foundation 库和接收器编写器在 Windows Phone 8.1 中对视频进行编码。

我已经能够通过将MFVideoFormat_H264 设置为MF_MT_SUBTYPE 用于我的媒体输出并使用720p 和480p 等分辨率来实现这一点..

但是当我将分辨率更改为 1920x1080(或 1920x1088)时,我收到了 Incorrect Parameter 错误。所以我猜我的 H.264 编解码器的最大分辨率是 1280x720。

我尝试将编解码器更改为 HVEC 或 MPEG2 等...但没有成功。

这是我设置输出类型并将其添加到流的 cpp 代码:

// Setup the output video type   

ComPtr<IMFMediaType> spvideoTypeOut;
CHK(MFCreateMediaType(&spvideoTypeOut));
CHK(spvideoTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));

GUID _vformat =  MFVideoFormat_H264;

CHK(spvideoTypeOut->SetGUID(MF_MT_SUBTYPE, _vformat));
CHK(spvideoTypeOut->SetUINT32(MF_MT_AVG_BITRATE, _bitrate));
CHK(spvideoTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
CHK(MFSetAttributeSize(spvideoTypeOut.Get(), MF_MT_FRAME_SIZE, _width, _height));
CHK(MFSetAttributeRatio(spvideoTypeOut.Get(), MF_MT_FRAME_RATE, framerate, 1));
CHK(MFSetAttributeRatio(spvideoTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, ASPECT_NUM, ASPECT_DENOM));

CHK(_spSinkWriter->AddStream(spvideoTypeOut.Get(), &_streamIndex));

这是我设置输入类型的地方:

// Setup the input video type   

    ComPtr<IMFMediaType> spvideoTypeIn;
    CHK(MFCreateMediaType(&spvideoTypeIn));
    CHK(spvideoTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
    CHK(spvideoTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32));
    CHK(spvideoTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
    CHK(MFSetAttributeSize(spvideoTypeIn.Get(), MF_MT_FRAME_SIZE, _width, _height));
    CHK(MFSetAttributeRatio(spvideoTypeIn.Get(), MF_MT_FRAME_RATE, framerate, 1));
    CHK(MFSetAttributeRatio(spvideoTypeIn.Get(), MF_MT_PIXEL_ASPECT_RATIO, ASPECT_NUM, ASPECT_DENOM));

    CHK(_spSinkWriter->SetInputMediaType(_streamIndex, spvideoTypeIn.Get(), nullptr));

    CHK(_spSinkWriter->BeginWriting());

为了向接收器写入器添加样本,我正在使用此函数,这就是发生异常的地方:

void PictureWriter::AddFrame(const Platform::Array<uint8>^ videoFrameBuffer, int imageWidth, int imageHeight)

    // Create a media sample   
    ComPtr<IMFSample> spSample;
    CHK(MFCreateSample(&spSample));
    CHK(spSample->SetSampleDuration(_duration));
    CHK(spSample->SetSampleTime(_hnsSampleTime));

    _hnsSampleTime += _duration;

    // Add a media buffer
    ComPtr<IMFMediaBuffer> spBuffer;
    CHK(MFCreateMemoryBuffer(_bufferLength, &spBuffer));
    CHK(spBuffer->SetCurrentLength(_bufferLength));
    CHK(spSample->AddBuffer(spBuffer.Get()));

    // Copy the picture into the buffer
    unsigned char *pbBuffer = nullptr;
    CHK(spBuffer->Lock(&pbBuffer, nullptr, nullptr));
    BYTE* buffer = (BYTE*)videoFrameBuffer->begin() + 4 * imageWidth * (imageHeight - 1);
    CHK(MFCopyImage(pbBuffer + 4 * _width * (_height - imageHeight),
        4 * _width, buffer, -4 * imageWidth, 4 * imageWidth, imageHeight));

CHK(spBuffer->Unlock());

    // Write the media sample   
    CHK(_spSinkWriter->WriteSample(_streamIndex, spSample.Get()));

您认为我为什么会收到异常,我该如何解决?

谢谢。

【问题讨论】:

如何在 sink writer 的 AddStream 中设置媒体类型?您是否尝试过在其中指定 High profile? 我添加了与此问题相关的所有代码。不,我不知道该怎么做。 您可以尝试添加:spvideoTypeOut->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_High); 今晚我一定会尝试并通知您。 Codecapi.h 中的 eAVEncH264VProfile 枚举对吗? 是的:msdn.microsoft.com/en-us/library/windows/desktop/… 【参考方案1】:

通过搜索每种分辨率的默认比特率找到解决方案,

1080p 适用于 5.0 Mbps 的比特率,

1600x900 适用于 2.5 Mbps 的比特率,

720p 适用于 1.25 Mbps 的比特率...

【讨论】:

以上是关于Windows Phone 8.1 Media Foundation H264 最大分辨率的主要内容,如果未能解决你的问题,请参考以下文章

xml 适用于Windows 8.1和Windows Phone 8.1应用程序的扩展器控件的模板。

如何将 Windows 商店中的 Windows Phone 应用程序(8.1 XAML)迁移到 8.1 Silverlight?

csharp 在Windows 8.1和Windows Phone 8.1应用程序中运行的Expander控件的代码隐藏。

使用 Windows RT 的客户端证书(windows 8.1/windows phone 8.1)

Windows Phone 8.0 DLL 是不是与 Windows Phone 8.1 应用程序兼容?

当 Windows (phone) 8.1 应用程序在前台时接收并处理通知参数