当尝试读取左右标记为3D的4K视频时,IMFSourceReader返回大小为1920x2160的图像(图像的一半)。如果可能的话,我想获取完整的图像,或者至少可以访问下半部分。
我知道MF_ENABLE_3DVIDEO_OUTPUT,但是我不确定如何将其应用于IMFSourceReader。我尝试将其设置为媒体类型,但没有任何改变。
源读者告诉我,流的宽度是帧大小的一半(对于4K影片,为1920x2160),但是当我在样本上使用GetBufferCount时,结果为1。所以我不知道如何获得所有帧的数据。
我看了看DX11VideoRenderer示例,它似乎假定GetBufferCount返回2。但是它不使用IMFSourceReader,所以我不确定如何将其应用于该情况。
理想情况下,我要使用MF3DVideoOutputType_BaseView并获取完整的4K源图像。
编辑:
这与Facebook 180数据有关。 (设置“半等边矩形”和“并排”。这会在MP4中生成YouTube V1球形元数据,并且Facebook可以识别180度的立体声视频。)
此处提供了一个示例视频:https://drive.google.com/open?id=154dl33y9RKZcvTqdBZkLQ5Y5ckG2mZtf(将来会删除该视频;如果有人对上传位置有更好的建议,请随时提出建议)。
答案 0 :(得分:1)
这可能不是一个确切的答案,因为我可以通过简单的阅读来完成您想做的事情。但是,下面的步骤可能会提示您进行故障排除。
IMFSourceReader
返回大小为1920x2160的图像(图像的一半)。如果可能的话,我想获取完整的图像,或者至少可以访问下半部分。
我使用一个使用MF Source Reader读取视频,解压缩并将其另存为单个帧的应用程序处理了示例视频。我看到这两个视频都可以访问。
这是详细信息。
视频媒体类型表示3D视频:
MF_MT_MAJOR_TYPE, vValue {73646976-0000-0010-8000-00AA00389B71} (Type VT_CLSID, MFMediaType_Video, FourCC vids)
MF_MT_SUBTYPE, vValue {34363248-0000-0010-8000-00AA00389B71} (Type VT_CLSID, MFVideoFormat_H264, FourCC H264)
MF_MT_AM_FORMAT_TYPE, vValue {E06D80E3-DB46-11CF-B4D1-00805F6CBBEA} (Type VT_CLSID, WMFORMAT_MPEG2Video)
MF_MT_VIDEO_PROFILE, vValue 100 (Type VT_UI4)
MF_MT_VIDEO_LEVEL, vValue 51 (Type VT_UI4)
MF_MT_FRAME_SIZE, vValue 16492674418800 (Type VT_UI8, 3840x2160)
MF_MT_PIXEL_ASPECT_RATIO, vValue 4294967297 (Type VT_UI8, 1:1)
MF_MT_INTERLACE_MODE, vValue 7 (Type VT_UI4)
MF_MT_FRAME_RATE, vValue 128849018881001 (Type VT_UI8, 30000/1001, 29.970)
MF_MT_SAMPLE_SIZE, vValue 1 (Type VT_UI4)
MF_MT_AVG_BITRATE, vValue 82101870 (Type VT_UI4)
MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY, vValue 0 (Type VT_UI4)
MF_MT_MPEG4_SAMPLE_DESCRIPTION, vValue 00 00 59 2A 73 74 73 64 00 00 00 00 00 00 00 01 00 00 59 1A 61 76 63 31 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 00 08 70 00 48 00 00 00 48 00 00 00 00 00 00 00 01 15 41 6D 62 61 72 65 6C 6C 61 20 41 56 43 20 65 6E 63 6F 64 65 72 00 00 00 00 00 00 00 00 00 00 00 18 FF FF 00 00 00 4B 61 76 63 43 01 64 00 33 FF E1 00 34 27 64 00 33 AC 34 C8 03 C0 04... (Type VT_VECTOR | VT_UI1)
MF_MT_MPEG_SEQUENCE_HEADER, vValue 00 00 01 27 64 00 33 AC 34 C8 03 C0 04 3E 84 00 00 0F A4 00 03 A9 83 A1 80 00 4C 4B 40 00 03 93 87 0B BC B8 D0 C0 00 26 25 A0 00 01 C9 C3 85 DE 5C 3E 11 08 D4 00 00 00 00 01 28 EE 38 B0 (Type VT_VECTOR | VT_UI1)
MF_MT_VIDEO_3D, vValue 1 (Type VT_UI4)
MF_MT_VIDEO_3D_FORMAT, vValue 2 (Type VT_UI4)
MF_MT_VIDEO_ROTATION, vValue 0 (Type VT_UI4)
MF_NALU_LENGTH_SET, vValue 1 (Type VT_UI4)
MF_PROGRESSIVE_CODING_CONTENT, vValue 1 (Type VT_UI4)
{11D25A49-BB62-467F-9DB1-C17165716C49}, vValue 00 00 00 00 00 00 00 00 00 00 00 00 (Type VT_VECTOR | VT_UI1)
{4A8FC407-6EA1-46C8-B567-6971D4A139C3}, vValue 0 (Type VT_UI4)
{A51DA449-3FDC-478C-BCB5-30BE76595F55}, vValue 1 (Type VT_UI4)
请注意3840x2160的分辨率和MFVideo3DSampleFormat_Packed_LeftRight
的MF_MT_VIDEO_3D_FORMAT
值:
每个媒体样本都包含一个缓冲区,两个视图并排封装在一个帧中。
这似乎是对文件的正确读取。我的应用程序使用以下媒体类型通过SetCurrentMediaType
调用来设置Source Reader:
MF_MT_MAJOR_TYPE, vValue {73646976-0000-0010-8000-00AA00389B71} (Type VT_CLSID, MFMediaType_Video, FourCC vids)
MF_MT_SUBTYPE, vValue {00000016-0000-0010-8000-00AA00389B71} (Type VT_CLSID, MFVideoFormat_RGB32, FourCC 0x00000016)
MF_MT_FRAME_SIZE, vValue 16492674418800 (Type VT_UI8, 3840x2160)
MF_MT_PIXEL_ASPECT_RATIO, vValue 4294967297 (Type VT_UI8, 1:1)
MF_MT_INTERLACE_MODE, vValue 2 (Type VT_UI4)
MF_MT_FRAME_RATE, vValue 128849018881001 (Type VT_UI8, 30000/1001, 29.970)
也就是说,它要求将视频解压缩为全分辨率RGB格式。
Source Reader可以接受这样的请求,并提供视频解码器以满足格式转换的要求:
Category MFT_CATEGORY_VIDEO_DECODER, Direct3D 11 Aware, Input MFVideoFormat_H264, 3840 x 2160, Output MFVideoFormat_NV12, 3840 x 2160
显然,如果您想直接在内部Source Reader管道之外进行管理,则解码器为H.264 Video Decoder。
第一个阅读的视频样本具有以下属性:
MF_NALU_LENGTH_INFORMATION, vValue (Type VT_VECTOR | VT_UI1)
MFSampleExtension_ForwardedDecodeUnits, vValue ??? (Type VT_UNKNOWN)
MFSampleExtension_AccumulatedNonRefPicPercent, vValue 0 (Type VT_UI4)
MFSampleExtension_Token, vValue ??? (Type VT_UNKNOWN, 0x00000282397B1020)
MFSampleExtension_CleanPoint, vValue 1 (Type VT_UI4)
MFSampleExtension_Discontinuity, vValue 1 (Type VT_UI4)
MFSampleExtension_FrameCorruption, vValue 0 (Type VT_UI4)
nSampleTime 0, nSampleDuration 33 3666, nBufferCount 1, nTotalLength 33177600
nBufferIndex 0, nCurrentLength 33177600, nMaxLength 33177600
如您所见,它具有一个缓冲区,数据大小为3840 * 2160 * 4字节。图片本身就是我上面附加的两个部分。
这是Windows 10 October 2018 Update(版本1809)上的行为。我认为该行为基本上与您的原始请求匹配。我还看到MP4原子也表示完全分辨率(3840x2160),因此总体上我上面提到的以及我实际看到的行为是可以预期的。更重要的是,即使SDK topoedit可以同时播放文件,这意味着要从两半混合立体声以实现电影和电视的行为,必须以某种方式专门配置解码器。
据我了解,您看到的是不同的行为,这应该是有原因的,最有可能与视频解码器或交替进行的后解码步骤有关,该步骤要么剥离了一半的视频,要么在没有要求它。由于视频是以左右格式编码的,因此,我想说管道中的某些内容不太可能被硬编码掉下一半,并且对此没有任何控制,也许这可能是管道配置存在问题。
仍然有可能发生,早期版本的Windows缺少对球形视频的支持,并截断了视频,因为它包含一半,但同时还没有球形功能的代码路径和实现。
2018年12月27日更新:该问题似乎仅限于或至少与启用MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING
有关。启用后,源阅读器将Video Processor MFT用于格式转换需求,而不是内部转换器(但是AFAIR不是硬件加速的)。内部非硬件转换器透明地输出两个视图,甚至可能都不知道框架中有两个视图。但是,视频处理器MFT声明了立体声3D功能,在其默认操作模式下,它放弃了后半部分。
快速浏览一下,我无法启用其3D输出选项并切换为保留最右边的一半,无论是作为单个缓冲区的一部分,还是作为辅助缓冲区的一部分,还是作为辅助纹理表面。但是,由于看起来后半部分在后解码器步骤中被剥离,因此,例如,如果-可能有许多类似的方法可以执行此操作-从Source Reader读取NV12纹理,则它应该可以很好地工作从样本/纹理中删除了3D信息,进一步转换(包括启用GPU的像素格式)可转换为完整的3840x2160帧,而无需去除后半部分。