如何在不修改h265parse代码时修改其src caps适配h265decoder
解决方案
方法1:插入capsfilter元素强制补全caps字段
在h265parse和h265decoder之间插入capsfilter元素,手动设置包含maxwidth/maxheight的目标caps,通过管线中间层修正caps格式,让解码器能匹配。这是最简单直接的管线端控制方案:
// 创建capsfilter并配置目标caps GstElement *caps_filter = gst_element_factory_make("capsfilter", "h265-caps-filter"); // 可根据实际分辨率动态生成,这里以1080p为例 GstCaps *target_caps = gst_caps_from_string("video/x-h265, width=1920, height=1080, maxwidth=1920, maxheight=1080"); g_object_set(caps_filter, "caps", target_caps, NULL); gst_caps_unref(target_caps); // 重新链接管线:h265parse → capsfilter → h265decoder gst_element_link_many(h265parse, caps_filter, h265decoder, NULL);
如果需要适配动态分辨率,可以先通过h265parse的src pad获取原始caps中的宽高,再生成对应的目标caps:
// 假设已通过notify::caps信号拿到parse的原始caps gint width, height; gst_caps_get_simple_int(original_caps, "width", &width); gst_caps_get_simple_int(original_caps, "height", &height); GstCaps *target_caps = gst_caps_new_simple("video/x-h265", "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "maxwidth", G_TYPE_INT, width, "maxheight", G_TYPE_INT, height, NULL);
方法2:通过Pad Probe拦截并修改CAPS事件
在h265parse的src pad添加探针,拦截下游传递的GST_EVENT_CAPS事件,在事件到达解码器前补全maxwidth/maxheight字段,从根源修正协商用的caps:
static GstPadProbeReturn caps_probe_callback(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) { GstEvent *event = gst_pad_probe_info_get_event(info); if (GST_EVENT_TYPE(event) != GST_EVENT_CAPS) { return GST_PAD_PROBE_OK; } // 取出原始caps GstCaps *original_caps; gst_event_parse_caps(event, &original_caps); // 复制并补全字段 GstCaps *modified_caps = gst_caps_copy(original_caps); gint width, height; gst_caps_get_simple_int(original_caps, "width", &width); gst_caps_get_simple_int(original_caps, "height", &height); gst_caps_set_simple(modified_caps, "maxwidth", G_TYPE_INT, width, "maxheight", G_TYPE_INT, height, NULL); // 替换事件中的caps GstEvent *new_event = gst_event_new_caps(modified_caps); gst_pad_probe_info_set_event(info, new_event); gst_caps_unref(modified_caps); return GST_PAD_PROBE_OK; } // 为h265parse的src pad添加探针 GstPad *parse_src_pad = gst_element_get_static_pad(h265parse, "src"); gst_pad_add_probe(parse_src_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, caps_probe_callback, NULL, NULL); g_object_unref(parse_src_pad);
关于获取caps时机的说明
- 不要等到
PLAYING状态再调用gst_pad_get_current_caps:caps协商通常在PAUSED状态或管线从READY到PAUSED的过渡阶段完成,PLAYING阶段后部分元素会释放caps缓存导致返回NULL。 - 最可靠的获取时机是监听pad的
notify::caps信号:当pad的caps属性变化时触发回调,此时调用gst_pad_get_current_caps能拿到有效caps。 GST_EVENT_RECONFIGURE无效的原因:部分解码器收到该事件后不会重新发起caps协商,因此优先用上述两种主动修正caps的方案。
内容的提问来源于stack exchange,提问作者allforwhat24
相关产品推荐
相关产品推荐

