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;
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;
mmal_port_parameter_get(state->encoder_output_port, ¶m.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)
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;
}
#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
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",
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);
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;
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;
{
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 */
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)