官方英文文档链接:https://docs.microsoft.com/en-us/windows/desktop/medfound/video-interlacing
基于05/31/2018
In this article
- Interlace Information in the Media Type
- Interlace Flags on Samples
- Recommendations
- MPEG-2 Mappings
- Single-Field Samples
- DirectShow Mappings
- Related topics
本文介绍 media source 以及 解码器(decoder)如何处理隔行扫描的视频内容。
要正确解码和渲染隔行扫描视频,需要以下信息:
-
逐行扫描还是隔行扫描。一个视频流里可以包含逐行扫描帧或隔行扫描帧,或者两者都有。
-
场序。先显示顶场还是先显示底场。
-
重复第一场。当流是隔行扫描但当前帧是逐行扫描时使用此标志(3:2 pulldown 不懂)。这种情况下,当前场既可以是顶场又可以是底场。
-
交错或单个场。一个 sample 可以包含单个场也可以包含两个场。如果只包含了单个场,那么 sample 的高就是一帧画面的高的一半,因为一个 sample 只包含了一幅画面一半的行。除非源内容规定,否则建议使用交错。
这些特征都有可能在 sample 之间发生改变。所以视频处理组件需要在正式开始流传输之前了解总体情况。例如如果视频是隔行扫描,增强视频渲染器(EVR)就需要为 去隔行扫描(转化为隔行扫描) 预留内存,如果是逐行扫描则可以进行优化。在处理流程中 去隔行扫描 的步骤会增加处理时间。
关于扫描类型的信息存储在两个地方:
-
关于流的隔行扫描信息一般存储在 media type 中。
-
可能随 sample 而变化的信息作为 attribute 存储在了每个 sample 中。
Media Type 中的隔行扫描信息
Media Type 中的 MF_MT_INTERLACE_MODE attribute 描述了一个流从整体来看是什么扫描类型。值是一个 MFVideoInterlaceMode 枚举类型。一个视频的 media type 应该始终包含这个 attribute。
- 如果一个流中只包含逐行扫描的帧,使用 MFVideoInterlace_Progressive。
- 如果一个流只包含隔行扫描的帧,而且每个 sample 包含两个交错的场,使用 MFVideoInterlace_FieldInterleavedUpperFirst 或者 MFVideoInterlace_FieldInterleavedLowerFirst。
- 如果一个流只包含隔行扫描的帧,而且每个 sample 只包含一个场,使用 MFVideoInterlace_FieldSingleUpper 或者 MFVideoInterlace_FieldSingleLower。如果场是在顶场和底场之间来回交错,则使用哪个并不重要。如果格式只包含顶场或者底场,则应设置对应的值。
- 如果流既包含逐行扫描又包含隔行扫描,或者场也不固定(?),使用 MFVideoInterlace_MixedInterlaceOrProgressive。然后检查每个 sample 的 attribute。
下表总结了这个 attribute.
MF_MT_INTERLACE_MODE | Interlaced? | Samples | First field |
---|---|---|---|
MFVideoInterlace_Progressive | No | Progressive frame | Not applicable |
MFVideoInterlace_FieldInterleavedUpperFirst | Yes | Interleaved fields | Upper first |
MFVideoInterlace_FieldInterleavedLowerFirst | Yes | Interleaved fields | Lower first |
MFVideoInterlace_FieldSingleUpper | Yes | Single field | Upper first |
MFVideoInterlace_FieldSingleLower | Yes | Single field | Lower first |
MFVideoInterlace_MixedInterlaceOrProgressive | Can vary | Interleaved fields or progressive frames | Can vary |
交错场和单个场不可以混合。要切换的话需要修改 media type。
Interlace Flags on Samples
使用 IMFSample 接口来获取这些信息。
此部分列出的所有的关于隔行扫描的 attribute 都是 bool 类型。事实上这些 attribute 都可以有三种值: TRUE, FALSE, 或者 未设置。如果是 未设置,则会从 media type 中去获取。只要设置了,就会忽略 media type 中的值。有一些标志位的组合和 media type 是无效的。
Attribute | Description |
---|---|
MFSampleExtension_Interlaced | 如果是 TRUE,此帧是隔行扫描。FALSE 则为逐行扫描。 如果 media type 中是 MFVideoInterlace_MixedInterlaceOrProgressive,则要对每个 sample 设置这个 attribute。 |
MFSampleExtension_BottomFieldFirst | 含义取决于这个 samples 包含交错场还是单个场
|
MFSampleExtension_RepeatFirstField | TRUE,重复第一场。FALSE,不重复第一场。 |
MFSampleExtension_SingleField | TRUE,sample 只包含单个场。FALSE,sample 包含交错的两个场。 |
下表显示了根据 media type,哪些标志位是必需的,可选的或者禁止的。
Media Type | Interlaced Flag | BottomFieldFirst Flag | RepeatFirstField Flag | SingleField Flag |
---|---|---|---|---|
Progressive | 可选。如果设置,必须是 FALSE。 | 不要设置 | 不要设置 | 不要设置 |
Interleaved fields | 可选。如果设置,必须是 TRUE。 | 可选。如果设置,要和 media type 一致。 | 不要设置 | 可选。如果设置,必须是 FALSE。 |
Single fields | 可选。如果设置,必须是 TRUE。 | 必需 | 不要设置 | 设置为 TRUE. |
Mixed | 必需 | 必需 | 必需 | 可选。如果设置,必须是 FALSE。 |
在这里那些可选信息是 media type 已经存在的信息。
例如 media type 是 MFVideoInterlace_Progressive,意味着流中的所有帧都是逐行扫描的。所以你可以将 MFSampleExtension_Interlaced attribute 设为 FALSE,或者不设置。
建议
T此部分包含了对各种类型的一些建议
- 所有视频帧都是逐行扫描时
-
将 media type 设为 MFVideoInterlace_Progressive。
-
不要设置 MFSampleExtension_Interlaced attribute,或者给每一帧设置为 FALSE。
-
不要设置 MFSampleExtension_BottomFieldFirst, MFSampleExtension_RepeatFirstField, or MFSampleExtension_SingleField attributes。
- 全部帧为隔行扫描,优先场相同。Samples 包含交错的两场。
-
Set the media type to MFVideoInterlace_FieldInterleavedUpperFirst or MFVideoInterlace_FieldInterleavedLowerFirst.
-
不要设置 MFSampleExtension_Interlaced,或者为每一帧设置为 TRUE。
-
不要设置 MFSampleExtension_BottomFieldFirst attribute,或者每一帧都和 media type 设置一样。
-
不要设置 MFSampleExtension_RepeatFirstField attribute, 或者为每一帧设置为 FALSE。
-
Do not set the MFSampleExtension_SingleField attribute,或者为每一帧设置为 FALSE。
- 视频既包含隔行扫描又包含逐行扫描,with repeated fields a和变化的优先场(例如 DVD 视频)。
-
media type 设为 MFVideoInterlace_MixedInterlaceOrProgressive。
-
每一帧都要设置 MFSampleExtension_Interlaced, MFSampleExtension_BottomFieldFirst, 和 MFSampleExtension_RepeatFirstField attributes。
-
不要设置 MFSampleExtension_SingleField attribute,或者为每一帧设置 FALSE。
- 视频是隔行扫描,samples 包含单个场。
-
media type 设置为 MFVideoInterlace_FieldSingleUpper 或者 MFVideoInterlace_FieldSingleLower。
-
为每一帧设置 MFSampleExtension_BottomFieldFirst attribute。
-
不要设置 MFSampleExtension_Interlaced attribute,或者为每一帧设置, or set it to TRUE。
-
不要设置 MFSampleExtension_RepeatFirstField attribute,或者为每一帧设置 FALSE。
-
不要设置 MFSampleExtension_SingleField attribute,或者为每一帧设置 TRUE。
大多数视频都是这些情况之一。
MPEG-2 Mappings
对于 MPEG-2 内容,查看下表来将 MPEG-2 flags 转换为 Media Foundation sample attributes。
picture_structure
Value | Sample Attribute |
---|---|
frame | MFSampleExtension_SingleField = FALSE |
top_field | MFSampleExtension_SingleField = TRUE MFSampleExtension_BottomFieldFirst = FALSE |
bottom_field | MFSampleExtension_SingleField = TRUE MFSampleExtension_BottomFieldFirst = TRUE |
progressive_frame
Value | Sample Attribute |
---|---|
0 | MFSampleExtension_Interlaced = TRUE |
1 | MFSampleExtension_Interlaced = FALSE |
top_field_first
Value | Sample Attribute |
---|---|
0 | MFSampleExtension_BottomFieldFirst = TRUE |
1 | MFSampleExtension_BottomFieldFirst = FALSE |
repeat_first_field
Value | Sample Attribute |
---|---|
0 | MFSampleExtension_RepeatFirstField = FALSE |
1 | MFSampleExtension_RepeatFirstField = TRUE |
Single-Field Samples
如果 media type 是 MFVideoInterlace_FieldSingleUpper 或者 MFVideoInterlace_FieldSingleLower,表示每个 sample 包含单个场。然而 media type 描述的是完整的一帧。那就是说,每个 buffer 只包含了 media type 中行数的一半。例如,如果 media type 中描述视频分辨率是 720 × 480,每场包含 240 行,那就是每个 buffer 只包含 240 行像素。如果要写一个组件接受含有单个场的 sample,则在访问 buffer 的时候需要注意一下。
同样的规则也适用于几何光圈(?geometric aperture) (MF_MT_GEOMETRIC_APERTURE attribute) 和最小显示光圈(?minimum display aperture) (MF_MT_MINIMUM_DISPLAY_APERTURE attribute)。这些区域是对整个帧来说的,而不是单个场。
DirectShow Mappings
在 DirectShow 中,每个 sample 的隔行扫描信息包含在 AM_SAMPLE2_PROPERTIES 结构的 dwTypeSpecificFlags 成员变量里。下表展示了与 mediafoundation 的对应关系。
DirectShow sample flag | Media Foundation sample attribute |
---|---|
AM_VIDEO_FLAG_INTERLEAVED_FRAME | MFSampleExtension_SingleField = FALSE. |
AM_VIDEO_FLAG_FIELD1 | MFSampleExtension_Interlaced = TRUE. MFSampleExtension_SingleField = TRUE. MFSampleExtension_BottomFieldFirst = FALSE. |
AM_VIDEO_FLAG_FIELD2 | MFSampleExtension_Interlaced = TRUE. MFSampleExtension_SingleField = TRUE. MFSampleExtension_BottomFieldFirst = TRUE. |
AM_VIDEO_FLAG_WEAVE | MFSampleExtension_Interlaced = FALSE. (此标志指示驱动程序不应 去隔行扫描) |
AM_VIDEO_FLAG_FIELD1FIRST | MFSampleExtension_BottomFieldFirst = FALSE. If the content is interlaced and the AM_VIDEO_FLAG_FIELD1FIRST flag is not present, set this attribute to TRUE. |
AM_VIDEO_FLAG_REPEAT_FIELD | MFSampleExtension_RepeatFirstField = TRUE. If the AM_VIDEO_FLAG_REPEAT_FIELD flag is not present, set this attribute to FALSE. |
If the DirectShow sample does not contain sample flags, use the value of dwInterlaceFlags from the VIDEOINFOHEADER2 structure:
DirectShow interlace flag | Media Foundation sample attribute |
---|---|
AMINTERLACE_IsInterlaced | MFSampleExtension_Interlaced = TRUE. |
AMINTERLACE_1FieldPerSample | MFSampleExtension_SingleField = TRUE. |
AMINTERLACE_Field1First | MFSampleExtension_BottomFieldFirst = FALSE. |