GStreamer如何强制对伪逐行视频执行去隔行处理
问题描述
我接收一段需解码显示的H.264逐行视频流,但实际编码的是隔行图像,编码前两个场被合并交织为伪逐行图像(显示时存在梳状伪影),行排列为:第0行=偶场第0行、第1行=奇场第0行、第2行=偶场第1行、第3行=奇场第1行等。在接收端,GStreamer将其识别为逐行视频,导致去隔行(deinterlace)元素无法生效。请问:
- 如何告知GStreamer该视频实际为上述交织隔行格式,使去隔行滤镜正常工作?
- 能否通过pad probe实现?
- 是否必须编写自定义元素?
- 相关文档提到'INTERLEAVED'模式,说明'若视频信息隔行模式为interleaved,则缓冲区为普通隔行视频',请问interleaved视频具体指什么?是否就是我描述的这种场在内存中交织排列的情况?
解决方案与说明
1. 修正视频隔行属性以激活去隔行元素
GStreamer的去隔行元素(如deinterlace、vaapideinterlace)仅对标记为隔行的视频流生效。你需要修改视频流的GstVideoInfo配置:将隔行模式从GST_VIDEO_INTERLACE_MODE_PROGRESSIVE改为GST_VIDEO_INTERLACE_MODE_INTERLEAVED,同时根据实际编码情况设置正确的场顺序(GST_VIDEO_FIELD_ORDER_TFF或GST_VIDEO_FIELD_ORDER_BFF)。
2. 可通过Pad Probe实现,无需额外开发
完全可以通过pad probe完成属性修改,无需编写自定义元素,具体步骤如下:
- 在解码后的视频输出pad(比如
h264parse或avdec_h264的srcpad)上添加GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM类型的探针。 - 捕获到
GST_EVENT_CAPS事件时,复制原GstCaps并修改其中的视频信息:- 解析出
GstVideoInfo,将interlace_mode设为GST_VIDEO_INTERLACE_MODE_INTERLEAVED,同时设置匹配的field_order。 - 用修改后的
GstVideoInfo重新生成GstCaps,替换原事件中的caps后让事件继续向下传递。
- 解析出
示例C语言代码片段:
static GstPadProbeReturn caps_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) { GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info); if (GST_EVENT_TYPE(event) != GST_EVENT_CAPS) { return GST_PAD_PROBE_OK; } GstCaps *caps = NULL; gst_event_parse_caps(event, &caps); GstVideoInfo vinfo; if (!gst_video_info_from_caps(&vinfo, caps)) { return GST_PAD_PROBE_OK; } // 修改隔行模式与场顺序,根据实际情况调整field_order vinfo.interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED; vinfo.finfo->field_order = GST_VIDEO_FIELD_ORDER_TFF; GstCaps *new_caps = gst_video_info_to_caps(&vinfo); GstEvent *new_event = gst_event_new_caps(new_caps); gst_event_replace(&event, new_event); gst_caps_unref(new_caps); gst_caps_unref(caps); return GST_PAD_PROBE_OK; } // 注册探针的代码示例 GstPad *src_pad = gst_element_get_static_pad(decoder_element, "src"); gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, caps_probe_cb, NULL, NULL); g_object_unref(src_pad);
3. 无需编写自定义元素
上述pad probe方案已经可以完整实现需求,不需要开发自定义GStreamer元素,是轻量化的最优解。
4. INTERLEAVED模式的定义
你描述的场交织排列方式正是INTERLEAVED模式的标准情况:
- 在GStreamer中,
GST_VIDEO_INTERLACE_MODE_INTERLEAVED表示视频缓冲区的行按场交织排列,即偶场一行、奇场一行循环往复(与你提到的第0行=偶场第0行、第1行=奇场第0行的排列完全匹配)。 - 标记为该模式后,缓冲区会被识别为完整的隔行帧,去隔行元素可以正确解析每场内容,消除梳状伪影。
内容的提问来源于stack exchange,提问作者Vincentz
相关产品推荐
相关产品推荐

