use pts in gst buffer time.

This commit is contained in:
Miroslav Šedivý
2026-01-24 10:43:06 +01:00
parent 7624bbb6c1
commit 684f92d4d9
3 changed files with 32 additions and 7 deletions
+25 -4
View File
@@ -95,10 +95,31 @@ static GstFlowReturn gstreamer_send_new_sample_handler(GstElement *object, gpoin
buffer = gst_sample_get_buffer(sample); buffer = gst_sample_get_buffer(sample);
if (buffer) { if (buffer) {
gst_buffer_extract_dup(buffer, 0, gst_buffer_get_size(buffer), &copy, &copy_size); gst_buffer_extract_dup(buffer, 0, gst_buffer_get_size(buffer), &copy, &copy_size);
goHandlePipelineBuffer(ctx->pipelineId, copy, copy_size,
GST_BUFFER_DURATION(buffer), // Get the buffer PTS (presentation timestamp)
GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT) GstClockTime pts = GST_BUFFER_PTS(buffer);
);
// Convert PTS to wallclock time by adding base time and subtracting pipeline time
GstClock *clock = gst_pipeline_get_clock(GST_PIPELINE(ctx->pipeline));
if (clock) {
gst_object_ref(clock);
GstClockTime base_time = gst_element_get_base_time(ctx->pipeline);
GstClockTime wallclock_time = pts + base_time;
gst_object_unref(clock);
goHandlePipelineBuffer(ctx->pipelineId, copy, copy_size,
wallclock_time,
GST_BUFFER_DURATION(buffer),
GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)
);
} else {
// Fallback to just PTS if clock is not available
goHandlePipelineBuffer(ctx->pipelineId, copy, copy_size,
pts,
GST_BUFFER_DURATION(buffer),
GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)
);
}
} }
gst_sample_unref(sample); gst_sample_unref(sample);
} }
+6 -2
View File
@@ -200,7 +200,7 @@ func CheckPlugins(plugins []string) error {
} }
//export goHandlePipelineBuffer //export goHandlePipelineBuffer
func goHandlePipelineBuffer(pipelineID C.int, buf C.gpointer, bufLen C.int, duration C.guint64, deltaUnit C.gboolean) { func goHandlePipelineBuffer(pipelineID C.int, buf C.gpointer, bufLen C.int, pts C.guint64, duration C.guint64, deltaUnit C.gboolean) {
defer C.g_free(buf) defer C.g_free(buf)
pipelinesLock.Lock() pipelinesLock.Lock()
@@ -208,10 +208,14 @@ func goHandlePipelineBuffer(pipelineID C.int, buf C.gpointer, bufLen C.int, dura
pipelinesLock.Unlock() pipelinesLock.Unlock()
if ok { if ok {
// Convert GStreamer PTS (in nanoseconds since epoch) to Go time.Time
// GStreamer timestamps are in nanoseconds
timestamp := time.Unix(0, int64(pts))
pipeline.sample <- types.Sample{ pipeline.sample <- types.Sample{
Data: C.GoBytes(unsafe.Pointer(buf), bufLen), Data: C.GoBytes(unsafe.Pointer(buf), bufLen),
Length: int(bufLen), Length: int(bufLen),
Timestamp: time.Now(), Timestamp: timestamp,
Duration: time.Duration(duration), Duration: time.Duration(duration),
DeltaUnit: deltaUnit == C.TRUE, DeltaUnit: deltaUnit == C.TRUE,
} }
+1 -1
View File
@@ -23,7 +23,7 @@ typedef struct GstPipelineCtx {
GstElement *appsrc; GstElement *appsrc;
} GstPipelineCtx; } GstPipelineCtx;
extern void goHandlePipelineBuffer(int pipelineId, void *buffer, int bufferLen, guint64 duration, gboolean deltaUnit); extern void goHandlePipelineBuffer(int pipelineId, void *buffer, int bufferLen, guint64 pts, guint64 duration, gboolean deltaUnit);
extern void goPipelineLog(int pipelineId, char *level, char *msg); extern void goPipelineLog(int pipelineId, char *level, char *msg);
GstPipelineCtx *gstreamer_pipeline_create(char *pipelineStr, int pipelineId, GError **error); GstPipelineCtx *gstreamer_pipeline_create(char *pipelineStr, int pipelineId, GError **error);