Windows Phone 8.1媒体基础库H264最大分辨率

3

我正在尝试使用Media Foundation库和sink writer在Windows Phone 8.1中对视频进行编码。

通过将MF_MT_SUBTYPE设置为MFVideoFormat_H264,并使用分辨率如720p和480p,我已经成功实现了这一点。

但是当我将分辨率更改为1920x1080(或1920x1088)时,会出现“参数不正确”的错误。因此,我猜我的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());

为了向sink writer添加样本,我使用了这个函数,而这也是异常发生的地方:
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()));
}

你认为我为什么会出现异常,我该如何解决?

谢谢。


1
如何在接收器编写器的AddStream中设置媒体类型?您是否尝试在其中指定高级配置文件? - VuVirt
1
我添加了所有与此问题相关的代码。不,我不知道怎么做。 - uncommon_name
1
你可以尝试添加:spvideoTypeOut->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_High); - VuVirt
1
我今晚一定会尝试并通知您。eAVEncH264VProfile枚举在Codecapi.h中是正确的吗? - uncommon_name
1
是的:https://msdn.microsoft.com/zh-cn/library/windows/desktop/dd318776(v=vs.85).aspx - VuVirt
显示剩余4条评论
1个回答

2

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

1080p的比特率为5.0 Mbps,

1600x900的比特率为2.5 Mbps,

720p的比特率为1.25 Mbps...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接