summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@noraisin.net>2017-07-01 00:51:13 +1000
committerTim-Philipp Müller <tim@centricular.com>2020-07-10 16:46:12 +0100
commited893592eaa5493fa3b3b92e7255b209da1672ab (patch)
treec869cf383e06d1abf3e9f97832ad9af935a36639 /sys
parentf093e3f5fb168cde45be71d8646ed7ac042a1389 (diff)
downloadgstreamer-plugins-good-ed893592eaa5493fa3b3b92e7255b209da1672ab.tar.gz
rpicamsrc: Implement use-stc property to disable STC timestamps
If use-stc=false, then rpicamsrc won't apply the camera timestamping to outgoing buffers, instead relying on real-time timestamping by the GStreamer clock. It means slightly less accuracy and more jitter in timestamps, but might help on some CSI inputs with broken timestamping.
Diffstat (limited to 'sys')
-rw-r--r--sys/rpicamsrc/RaspiCapture.c12
-rw-r--r--sys/rpicamsrc/RaspiCapture.h2
-rw-r--r--sys/rpicamsrc/gstrpicamsrc.c27
3 files changed, 32 insertions, 9 deletions
diff --git a/sys/rpicamsrc/RaspiCapture.c b/sys/rpicamsrc/RaspiCapture.c
index c50ef9957..d0616c5f8 100644
--- a/sys/rpicamsrc/RaspiCapture.c
+++ b/sys/rpicamsrc/RaspiCapture.c
@@ -929,6 +929,7 @@ GstFlowReturn
raspi_capture_fill_buffer(RASPIVID_STATE *state, GstBuffer **bufp,
GstClock *clock, GstClockTime base_time)
{
+ RASPIVID_CONFIG *config = &state->config;
GstBuffer *buf;
MMAL_BUFFER_HEADER_T *buffer;
GstFlowReturn ret = GST_FLOW_ERROR;
@@ -939,7 +940,7 @@ raspi_capture_fill_buffer(RASPIVID_STATE *state, GstBuffer **bufp,
buffer = mmal_queue_wait(state->encoded_buffer_q);
- if (G_LIKELY (clock)) {
+ if (G_LIKELY (config->useSTC && clock)) {
MMAL_PARAMETER_INT64_T param;
GstClockTime runtime;
@@ -951,7 +952,7 @@ raspi_capture_fill_buffer(RASPIVID_STATE *state, GstBuffer **bufp,
mmal_port_parameter_get(state->encoder_output_port, &param.hdr);
- if (param.value != -1 && param.value >= buffer->pts) {
+ if (buffer->pts != -1 && param.value != -1 && param.value >= buffer->pts) {
/* Convert microsecond RPi TS to GStreamer clock: */
GstClockTime offset = (param.value - buffer->pts) * 1000;
if (runtime >= offset)
@@ -963,13 +964,16 @@ raspi_capture_fill_buffer(RASPIVID_STATE *state, GstBuffer **bufp,
buffer->pts, buffer->dts, param.value, param.value - buffer->pts,
GST_TIME_ARGS (gst_pts));
}
-
+ else {
+ GST_LOG ("use-stc=false. Not applying STC to buffer");
+ }
mmal_buffer_header_mem_lock(buffer);
buf = gst_buffer_new_allocate(NULL, buffer->length, NULL);
if (buf) {
+ if (config->useSTC)
+ GST_BUFFER_DTS(buf) = GST_BUFFER_PTS(buf) = gst_pts;
/* FIXME: Can we avoid copies and give MMAL our own buffers to fill? */
- GST_BUFFER_PTS(buf) = gst_pts;
gst_buffer_fill(buf, 0, buffer->data, buffer->length);
ret = GST_FLOW_OK;
}
diff --git a/sys/rpicamsrc/RaspiCapture.h b/sys/rpicamsrc/RaspiCapture.h
index 6a79ac524..053ae1c03 100644
--- a/sys/rpicamsrc/RaspiCapture.h
+++ b/sys/rpicamsrc/RaspiCapture.h
@@ -116,6 +116,8 @@ typedef struct
int jpegQuality;
int jpegRestartInterval;
+
+ int useSTC;
} RASPIVID_CONFIG;
typedef struct RASPIVID_STATE_T RASPIVID_STATE;
diff --git a/sys/rpicamsrc/gstrpicamsrc.c b/sys/rpicamsrc/gstrpicamsrc.c
index f2a993c0b..7cd369e80 100644
--- a/sys/rpicamsrc/gstrpicamsrc.c
+++ b/sys/rpicamsrc/gstrpicamsrc.c
@@ -138,7 +138,8 @@ enum
#ifdef GST_RPI_CAM_SRC_ENABLE_VIDEO_DIRECTION
PROP_VIDEO_DIRECTION,
#endif
- PROP_JPEG_QUALITY
+ PROP_JPEG_QUALITY,
+ PROP_USE_STC
};
#define CAMERA_DEFAULT 0
@@ -488,6 +489,10 @@ gst_rpi_cam_src_class_init (GstRpiCamSrcClass * klass)
g_object_class_override_property (gobject_class, PROP_VIDEO_DIRECTION,
"video-direction");
#endif
+ g_object_class_install_property (gobject_class, PROP_USE_STC,
+ g_param_spec_boolean ("use-stc", "Use System Time Clock",
+ "Use the camera STC for timestamping buffers", TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_static_metadata (gstelement_class,
"Raspberry Pi Camera Source", "Source/Video",
@@ -517,12 +522,12 @@ gst_rpi_cam_src_init (GstRpiCamSrc * src)
raspicapture_default_config (&src->capture_config);
src->capture_config.intraperiod = KEYFRAME_INTERVAL_DEFAULT;
src->capture_config.verbose = 1;
+ src->capture_config.useSTC = TRUE;
g_mutex_init (&src->config_lock);
- /* Don't let basesrc set timestamps, we'll do it using
- * buffer PTS and system times */
- gst_base_src_set_do_timestamp (GST_BASE_SRC (src), FALSE);
+ /* basesrc will generate timestamps if use-stc = false */
+ gst_base_src_set_do_timestamp (GST_BASE_SRC (src), TRUE);
/* Generate the channels list */
channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL);
@@ -1006,6 +1011,9 @@ gst_rpi_cam_src_set_property (GObject * object, guint prop_id,
gst_rpi_cam_src_set_orientation (src, g_value_get_enum (value));
break;
#endif
+ case PROP_USE_STC:
+ src->capture_config.useSTC = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1170,6 +1178,9 @@ gst_rpi_cam_src_get_property (GObject * object, guint prop_id,
g_value_set_enum (value, src->orientation);
break;
#endif
+ case PROP_USE_STC:
+ g_value_set_boolean (value, src->capture_config.useSTC);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1182,6 +1193,9 @@ gst_rpi_cam_src_start (GstBaseSrc * parent)
{
GstRpiCamSrc *src = GST_RPICAMSRC (parent);
GST_LOG_OBJECT (src, "In src_start()");
+ /* Ensure basesrc timestamping is off is use-stc is on */
+ if (src->capture_config.useSTC)
+ gst_base_src_set_do_timestamp (GST_BASE_SRC (src), FALSE);
g_mutex_lock (&src->config_lock);
src->capture_state = raspi_capture_setup (&src->capture_config);
/* Clear all capture flags */
@@ -1417,7 +1431,10 @@ gst_rpi_cam_src_create (GstPushSrc * parent, GstBuffer ** buf)
if (*buf) {
GST_LOG_OBJECT (src, "Made buffer of size %" G_GSIZE_FORMAT,
gst_buffer_get_size (*buf));
- GST_BUFFER_DURATION (*buf) = src->duration;
+ /* Only set the duration when we have a PTS update from the rpi encoder.
+ * not every buffer is a frame */
+ if (GST_BUFFER_PTS_IS_VALID (*buf))
+ GST_BUFFER_DURATION (*buf) = src->duration;
}
if (clock)