我想使用Win7 Media Foundation SDK将视频帧编码为H264,然后使用接收器编写器将其保存为.mp4文件。
但是,当我不手动将MF_MT_MPEG_SEQUENCE_HEADER
添加到输出媒体类型并且文件不可播放时,sinkwriter的最终确定将失败。
我检查了应添加编码器的编码器(请参见H.264 Video Encoder)。但这只会产生MF_E_ATTRIBUTENOTFOUND
错误。
IMFMediaType * outputType;
hr = m_pEncoder->GetOutputCurrentType(0, &outputType);
UINT32 sequenceHeaderDataSize;
hr = outputType->GetBlobSize(MF_MT_MPEG_SEQUENCE_HEADER, &sequenceHeaderDataSize);
使用MF_MT_MPEG_SEQUENCE_HEADER
(我在网上找到(用于1080p)),我可以得到一个可播放的文件。但是,它在亮度(每0.5秒随机变化)和遮挡误差方面仍然存在一些误差。
UINT8 blob[] = {0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x2A, 0xAD, 0x84, 0x01, 0x0C, 0x20, 0x08, 0x61, 0x00, 0x43, 0x08, 0x02, 0x18, 0x40, 0x10, 0xC2, 0x00, 0x84, 0x2B, 0x50, 0x3C, 0x01, 0x13, 0xF2, 0xC2, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x79, 0x08, 0x00, 0x00, 0x00, 0x01, 0x68, 0xEE, 0x3C, 0xB0};
//create sink attributes
IMFAttributes * sinkAttributes = NULL;
HRESULT hr = MFCreateAttributes(&sinkAttributes, 1);
hr = sinkAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, true);
//create sink
IMFSinkWriter * pSinkWriter = NULL;
hr = MFCreateSinkWriterFromURL(L"output.mp4", NULL, sinkAttributes, &pSinkWriter);
// Set the output media type.
IMFMediaType * pMediaTypeOut = NULL;
CHECK_HR(MFCreateMediaType(&pMediaTypeOut));
CHECK_HR(pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
CHECK_HR(pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, VIDEO_INPUT_FORMAT));
CHECK_HR(MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, VIDEO_WIDTH, VIDEO_HEIGHT));
CHECK_HR(MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, VIDEO_FPS, 1));
CHECK_HR(pMediaTypeOut->SetBlob(MF_MT_MPEG_SEQUENCE_HEADER, blob, sizeof(blob)));
CHECK_HR(pSinkWriter->AddStream(pMediaTypeOut, &streamIndex));
// Tell the sink writer to start accepting data.
hr = pSinkWriter->BeginWriting();
这可能与Windows 7有关,很遗憾,我无法在Windows 10计算机上进行检查。
其他地方还需要编码的帧,所以我不能只是跳过编码而直接将帧放入接收器中。
答案 0 :(得分:1)
某些编码器(例如,如果我没记错的话)在Windows 7 Intel Quick Sync上非常流行并且可用,请使MF_MT_MPEG_SEQUENCE_HEADER
仅在开始样本处理后可用。也就是说,在管理MFT时,您必须执行ProcessInput
,ProcessOutput
,处理动态格式更改,更改媒体类型,然后在新媒体类型中有了序列头。也就是说,只有在准备好从编码器接收到的数据之后,才开始编码并初始化接收器写入器。
您必须具有适当的MF_MT_MPEG_SEQUENCE_HEADER
,并且不能对随机值进行硬编码。您可以像以前一样用于故障排除目的,但是对于给定的分辨率,这些不仅仅是一些字节。
注意Windows 8 updates to MPEG-4 source and sink:
可以从MPEG-4接收器的输入样本中提取SPS和PPS。
在MPEG-4接收器的输入媒体类型上未通过MF_MT_MPEG_SEQUENCE_HEADER设置SPS和PPS时,MPEG-4接收器将尝试从输入样本中提取SPS和PPS。 MPEG-4接收器会忽略所有输入样本,直到找到第一个SPS和PPS,因为所有没有SPS和PPS的输入样本都无法解码。
因此,确实,由于更新而无法在Windows 8中运行的东西在Windows 7中不可用,您必须自己处理MF_MT_MPEG_SEQUENCE_HEADER
。