|
73 | 73 | PROP_USB_MODE, |
74 | 74 | PROP_STREAM, |
75 | 75 | PROP_TRIGGER, |
| 76 | + PROP_ADD_REFERENCE_TIMESTAMP_META, |
76 | 77 | N_PROPERTIES |
77 | 78 | }; |
78 | 79 |
|
@@ -560,6 +561,11 @@ gst_aravis_get_times (GstBaseSrc * basesrc, GstBuffer * buffer, |
560 | 561 | } |
561 | 562 | } |
562 | 563 |
|
| 564 | +/* Reference caps for the optional capture-time meta. The device timestamp is |
| 565 | + * nanoseconds on the PTP timescale when the device is PTP-synchronized (IEEE |
| 566 | + * 1588), matching the timestamp/x-ptp convention of rtpjitterbuffer. */ |
| 567 | +static GstStaticCaps ptp_reference_timestamp_caps = GST_STATIC_CAPS ("timestamp/x-ptp"); |
| 568 | + |
563 | 569 | static GstFlowReturn |
564 | 570 | gst_aravis_create (GstPushSrc * push_src, GstBuffer ** buffer) |
565 | 571 | { |
@@ -623,6 +629,17 @@ gst_aravis_create (GstPushSrc * push_src, GstBuffer ** buffer) |
623 | 629 | gst_aravis->last_timestamp = timestamp_ns; |
624 | 630 | } |
625 | 631 |
|
| 632 | + /* Optionally expose the absolute device timestamp, which is otherwise lost |
| 633 | + * when it is folded into the first-frame-relative GST_BUFFER_PTS. A zero |
| 634 | + * timestamp means the device did not provide one. */ |
| 635 | + if (gst_aravis->add_reference_timestamp_meta && timestamp_ns != 0) { |
| 636 | + GstCaps *reference = gst_static_caps_get (&ptp_reference_timestamp_caps); |
| 637 | + |
| 638 | + gst_buffer_add_reference_timestamp_meta (*buffer, reference, |
| 639 | + timestamp_ns, GST_CLOCK_TIME_NONE); |
| 640 | + gst_caps_unref (reference); |
| 641 | + } |
| 642 | + |
626 | 643 | arv_stream_push_buffer (gst_aravis->stream, arv_buffer); |
627 | 644 | GST_OBJECT_UNLOCK (gst_aravis); |
628 | 645 |
|
@@ -709,6 +726,7 @@ gst_aravis_init (GstAravis *gst_aravis) |
709 | 726 | gst_aravis->frame_rate = 0.0; |
710 | 727 |
|
711 | 728 | gst_aravis->trigger_source = NULL; |
| 729 | + gst_aravis->add_reference_timestamp_meta = FALSE; |
712 | 730 |
|
713 | 731 | gst_aravis->camera = NULL; |
714 | 732 | gst_aravis->stream = NULL; |
@@ -863,6 +881,11 @@ gst_aravis_set_property (GObject * object, guint prop_id, |
863 | 881 | gst_aravis->trigger_source = g_strdup (g_value_get_string (value)); |
864 | 882 | GST_OBJECT_UNLOCK (gst_aravis); |
865 | 883 | break; |
| 884 | + case PROP_ADD_REFERENCE_TIMESTAMP_META: |
| 885 | + GST_OBJECT_LOCK (gst_aravis); |
| 886 | + gst_aravis->add_reference_timestamp_meta = g_value_get_boolean (value); |
| 887 | + GST_OBJECT_UNLOCK (gst_aravis); |
| 888 | + break; |
866 | 889 | default: |
867 | 890 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
868 | 891 | break; |
@@ -976,6 +999,11 @@ gst_aravis_get_property (GObject * object, guint prop_id, GValue * value, |
976 | 999 | g_value_set_string (value, gst_aravis->trigger_source); |
977 | 1000 | GST_OBJECT_UNLOCK (gst_aravis); |
978 | 1001 | break; |
| 1002 | + case PROP_ADD_REFERENCE_TIMESTAMP_META: |
| 1003 | + GST_OBJECT_LOCK (gst_aravis); |
| 1004 | + g_value_set_boolean (value, gst_aravis->add_reference_timestamp_meta); |
| 1005 | + GST_OBJECT_UNLOCK (gst_aravis); |
| 1006 | + break; |
979 | 1007 | default: |
980 | 1008 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
981 | 1009 | break; |
@@ -1171,6 +1199,15 @@ gst_aravis_class_init (GstAravisClass * klass) |
1171 | 1199 | NULL, |
1172 | 1200 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); |
1173 | 1201 |
|
| 1202 | + properties[PROP_ADD_REFERENCE_TIMESTAMP_META] = |
| 1203 | + g_param_spec_boolean("add-reference-timestamp-meta", |
| 1204 | + "Add reference timestamp meta", |
| 1205 | + "Add a GstReferenceTimestampMeta with timestamp/x-ptp reference" |
| 1206 | + " caps to buffers, carrying the device timestamp. Only an" |
| 1207 | + " absolute time if the device clock is PTP-synchronized", |
| 1208 | + FALSE, |
| 1209 | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); |
| 1210 | + |
1174 | 1211 | g_object_class_install_properties (gobject_class, |
1175 | 1212 | G_N_ELEMENTS (properties), |
1176 | 1213 | properties); |
|
0 commit comments