我查看h264parse里面没有提供get-sps的相关信号 可能这样获取吗?
时间: 2023-12-04 09:02:51 浏览: 152
如果 h264parse 元素中没有提供 `get-sps` 和 `get-pps` 信号,可以使用 `GstVideoCodecFrame` 对象的方式来获取 SPS 和 PPS 数据。具体步骤如下:
1. 定义 `GstVideoCodecFrame` 对象:
```
GstVideoCodecFrame *frame = NULL;
```
2. 在 `h264parse` 元素的 `sink` pad 上添加一个 `GstPadProbe`,在 probe 的回调函数中获取 SPS 和 PPS 数据:
```
GstPad *pad = gst_element_get_static_pad(parser, "sink");
gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback)probe_callback, frame, NULL);
```
回调函数的实现如下:
```
static GstPadProbeReturn probe_callback(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) {
GstVideoCodecFrame **frame = (GstVideoCodecFrame **)user_data;
GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER(info);
GstMapInfo map;
if (!gst_buffer_map(buffer, &map, GST_MAP_READ)) {
return GST_PAD_PROBE_OK;
}
GstVideoCodecFrameFlags flags = GST_VIDEO_CODEC_FRAME_FLAG_NONE;
if (GST_H264_NAL_SLICE == gst_h264_get_nal_type(map.data[4])) {
flags |= GST_VIDEO_CODEC_FRAME_FLAG_SYNC_POINT;
}
*frame = gst_video_codec_frame_new(GST_VIDEO_CODEC_FRAME_TYPE_UNKNOWN, flags, GST_CLOCK_TIME_NONE, map.data, map.size);
gst_buffer_unmap(buffer, &map);
return GST_PAD_PROBE_REMOVE;
}
```
该回调函数会在 `h264parse` 元素的 `sink` pad 上捕获到数据时被调用。在回调函数中,先将 buffer 的数据映射到 `map` 中,然后根据数据中的 NALU 类型判断是否为关键帧 (sync point),并创建一个 `GstVideoCodecFrame` 对象存储数据。
3. 获取 SPS 和 PPS 数据:
```
GstVideoCodecState *state = gst_video_codec_state_new();
gst_video_decoder_set_output_state(GST_VIDEO_DECODER(parser), state);
GstVideoCodecFrame *sps_frame = NULL;
GstVideoCodecFrame *pps_frame = NULL;
for (int i = 0; i < state->info->sequence_header_count; i++) {
GstVideoCodecFrame *frame = state->info->sequence_headers[i];
GstH264NalUnitType nal_type = gst_h264_get_nal_type(frame->data[4]);
if (nal_type == GST_H264_NAL_SPS) {
sps_frame = frame;
}
else if (nal_type == GST_H264_NAL_PPS) {
pps_frame = frame;
}
}
if (sps_frame != NULL) {
// 打印 SPS 数据
g_print("SPS: %s\n", gst_video_codec_frame_to_string(sps_frame));
}
if (pps_frame != NULL) {
// 打印 PPS 数据
g_print("PPS: %s\n", gst_video_codec_frame_to_string(pps_frame));
}
// 释放资源
gst_video_codec_state_unref(state);
if (sps_frame != NULL) {
gst_video_codec_frame_unref(sps_frame);
}
if (pps_frame != NULL) {
gst_video_codec_frame_unref(pps_frame);
}
```
在这里,首先创建一个 `GstVideoCodecState` 对象,然后将其设置为 `h264parse` 元素的输出状态。接着遍历 `GstVideoCodecState` 中的 `sequence_headers`,查找包含 SPS 和 PPS 数据的 `GstVideoCodecFrame` 对象,最后通过 `gst_video_codec_frame_to_string` 函数将数据转换成字符串格式进行打印。
需要注意的是,在使用完 `GstVideoCodecFrame` 后需要手动释放资源,避免内存泄漏。
阅读全文