如何正确使用 GstReferenceTimestampMeta

How to use GstReferenceTimestampMeta properly

我的目标是将时间戳附加到 GstBuffer,这与 GST 时间无关。我找到了 GstReferenceTimestampMeta,这正是我所追求的。但是我在尝试使用它时遇到了一些问题。可能是我理解错了GstMeta结构体的用法

管道简要概述:

服务器:appsrc -> h265enc -> rtp -> udpsink

客户:udpsrc -> h265decode -> appsink

我在服务器中所做的是在将缓冲区推入 appsrc 之前将 GstMeta 附加到 GstBuffer,因此:

auto buffer = gst_buffer_new_allocate(NULL, buffer_size, NULL);

// ------------------------- GstReferenceTimestampMeta START

GstCaps *caps = gst_caps_from_string("timestamp/x-test-stream");
gst_buffer_add_reference_timestamp_meta(
  buffer,
  caps,
  timestamp.nanoseconds(),
  GST_CLOCK_TIME_NONE 
);  

// ------------------------- GstReferenceTimestampMeta END
    
GstMapInfo info;
gst_buffer_map(buffer, &info, GST_MAP_READ);
std::memcpy(info.data, image.data, buffer_size);
gst_buffer_unmap(buffer, &info);
gst_app_src_push_buffer(GST_APP_SRC(appsrc_), buffer);

同样,我在客户端做的是:

GstSample *sample = gst_app_sink_try_pull_sample(GST_APP_SINK(appsink_), 10000000);
GstBuffer *buffer = gst_sample_get_buffer(sample);

// ------------------------- GstReferenceTimestampMeta START

GstReferenceTimestampMeta *meta;
GstCaps *reference = gst_caps_from_string("timestamp/x-test-stream");
meta = gst_buffer_get_reference_timestamp_meta(buffer, reference);
if (meta == NULL){
  std::cout << "daim" << std::endl;   
  break;
}
else {
  std::cout << meta->timestamp << std::endl; 
}

// ------------------------- GstReferenceTimestampMeta END

MapInfo buffer_mapping;
gst_buffer_map(buffer, &buffer_mapping, GST_MAP_READ);
GstCaps *caps = gst_sample_get_caps(sample);

GstStructure *properties = gst_caps_get_structure(caps, 0);

int width, height;
gst_structure_get_int(properties, "width", &width);
gst_structure_get_int(properties, "height", &height);
std::string format = gst_structure_get_string(properties, "format");

int numChannels = (format == "BGR") ? 3 : 1;

renderTracks(buffer_mapping.data, width, height, numChannels);

loadBufferOnDevice(width, height, numChannels, buffer_mapping.data);

gst_buffer_unmap(buffer, &buffer_mapping);
gst_sample_unref(sample);

这里的结果是“daim”打印到 cout,因为未找到带有引用大写“timestamp/x-test-stream”的 GstMeta,因此变量 meta == NULL.

我可能误解了 GstMeta 结构的用法。希望有人能指出我正确的方向。如果有其他方法可以将“自定义”时间戳附加到缓冲区,请告诉我!

据我所知,GstMeta 数据只有 intra-pipeline。如果您需要 inter-pipeline 解决方案,则需要在编码(H.264、H.265、...)或 RTP header.

中实现它

干杯,