我正在学习使用Windows Media Foundation使用本教程创建带有原始固定彩色图像的视频文件http://blogs.msdn.com/b/eternalcoding/archive/2013/03/06/developing-a-winrt-component-to-create-a-video-file-using-media-foundation.aspx
我能够创建上面链接中显示的RGB编码的WMV视频。但我需要从图像中以NV12格式创建YUV编码的MP4视频。由于NV12为每帧使用(W x H x 3/2)个字节的内存缓冲区,我为图像缓冲区(教程中的变量'target')创建了(W x H x 3/2)个字节的缓冲区并设置了一些固定的作为图像数据的值。然后将图像步幅“W”(ARGB使用Wx4作为步幅)设置为MFCopyImage(),并将高度设置为“H”。但这似乎不起作用。 MF_MT_SUBTYPE设置为MFVideoFormat_NV12。
创建NV12编码的mp4视频文件的正确方法是什么?
答案 0 :(得分:1)
我怀疑你做了太多的工作(希望这是好消息)。首先请记住,该示例不会将输出编码为RGB。 RGB只是接收器的输入类型,您可以随意离开。
容器是MFTranscodeContainerType_ASF(在一秒内更多), 子类型是MFVideoFormat_WMV3, 结果是一个压缩良好的Windows媒体视频文件。
创建接收器编写器时,在您的情况下会自动创建容器,因为未指定该属性。实际上,添加的唯一属性是以下行中的MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS:
MFCreateAttributes(&spAttr, 10);
spAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
hr = MFCreateSinkWriterFromURL(L".wmv",
spByteStream.Get(),
spAttr.Get(),
&sinkWriter);
这引出了一个问题 - '为什么要分配10个属性?' ... (耸耸肩)哦,好吧,没关系。
关键是,您将RGB帧发送到接收器,并且正在进行转换以完成符合您规范的编码。容器可以在这里找到:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd388919(v=vs.85).aspx
在创建接收器之前,您将指定一个类似于以下内容的给定容器:
spAttr->SetGUID(MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType_ASF);
// or MFTranscodeContainerType_MPEG4, MFTranscodeContainerType_AVI, etc
您之前使用以下行设置了子类型:
hr = mediaTypeOut->SetGUID(MF_MT_SUBTYPE, encodingFormat);
// where encodingFormat was hardcoded to MFVideoFormat_WMV3 in the ctor
但请记住,某些格式需要自下而上的图片。尝试将文件扩展名更改为“.mp4”,将容器更改为MFTranscodeContainerType_AVI,将子类型更改为MFVideoFormat_NV12,您将看到同一视频倒置。而且,与wmv相比,您的文件将是巨大的,因为所有YUV值都放在文件中。
正确获取容器和格式详细信息需要非常谨慎,有些细节很难研究。
希望这有帮助。