static gboolean gst_rpi_cam_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps) { GstRpiCamSrc *src = GST_RPICAMSRC (bsrc); GstVideoInfo info; GstStructure *structure; const gchar *profile_str = NULL; GST_DEBUG_OBJECT (src, "In set_caps %" GST_PTR_FORMAT, caps); if (!gst_video_info_from_caps (&info, caps)) return FALSE; structure = gst_caps_get_structure (caps, 0); profile_str = gst_structure_get_string (structure, "profile"); if (profile_str) { if (g_str_equal (profile_str, "baseline")) src->capture_config.profile = MMAL_VIDEO_PROFILE_H264_BASELINE; else if (g_str_equal (profile_str, "main")) src->capture_config.profile = MMAL_VIDEO_PROFILE_H264_MAIN; else if (g_str_equal (profile_str, "high")) src->capture_config.profile = MMAL_VIDEO_PROFILE_H264_HIGH; else g_warning ("Unknown profile string in rpicamsrc caps: %s", profile_str); } src->capture_config.width = info.width; src->capture_config.height = info.height; src->capture_config.fps_n = info.fps_n; src->capture_config.fps_d = info.fps_d; return TRUE; }
static gboolean gst_rpi_cam_src_event (GstBaseSrc * parent, GstEvent * event) { GstRpiCamSrc *src = GST_RPICAMSRC (parent); gboolean ret; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CUSTOM_DOWNSTREAM: case GST_EVENT_CUSTOM_UPSTREAM: if (gst_video_event_is_force_key_unit (event)) { if (src->started) { ret = raspi_capture_request_i_frame (src->capture_state); } else { ret = FALSE; } gst_event_unref (event); } else { ret = GST_BASE_SRC_CLASS (parent_class)->event (parent, event); } break; default: ret = GST_BASE_SRC_CLASS (parent_class)->event (parent, event); break; } return ret; }
static gint gst_rpi_cam_src_colorbalance_get_value (GstColorBalance * balance, GstColorBalanceChannel * channel) { GstRpiCamSrc *src = GST_RPICAMSRC (balance); gint value = 0; g_return_val_if_fail (src != NULL, 0); g_return_val_if_fail (GST_IS_RPICAMSRC (src), 0); g_return_val_if_fail (channel->label != NULL, 0); g_mutex_lock (&src->config_lock); if (!g_ascii_strcasecmp (channel->label, "SATURATION")) { value = src->capture_config.camera_parameters.saturation; } else if (!g_ascii_strcasecmp (channel->label, "BRIGHTNESS")) { value = src->capture_config.camera_parameters.brightness; } else if (!g_ascii_strcasecmp (channel->label, "CONTRAST")) { value = src->capture_config.camera_parameters.contrast; } g_mutex_unlock (&src->config_lock); return value; }
static void gst_rpi_cam_src_colorbalance_set_value (GstColorBalance * balance, GstColorBalanceChannel * channel, gint value) { GstRpiCamSrc *src = GST_RPICAMSRC (balance); gboolean changed = FALSE; g_return_if_fail (src != NULL); g_return_if_fail (GST_IS_RPICAMSRC (src)); g_return_if_fail (channel->label != NULL); g_mutex_lock (&src->config_lock); if (!g_ascii_strcasecmp (channel->label, "SATURATION")) { changed = value != src->capture_config.camera_parameters.saturation; src->capture_config.camera_parameters.saturation = value; } else if (!g_ascii_strcasecmp (channel->label, "BRIGHTNESS")) { changed = value != src->capture_config.camera_parameters.brightness; src->capture_config.camera_parameters.brightness = value; } else if (!g_ascii_strcasecmp (channel->label, "CONTRAST")) { changed = value != src->capture_config.camera_parameters.contrast; src->capture_config.camera_parameters.contrast = value; } if (changed) src->capture_config.change_flags |= PROP_CHANGE_COLOURBALANCE; g_mutex_unlock (&src->config_lock); if (changed) { gst_color_balance_value_changed (balance, channel, gst_color_balance_get_value (balance, channel)); } }
static void gst_rpi_cam_src_finalize (GObject *object) { GstRpiCamSrc *src = GST_RPICAMSRC (object); g_mutex_clear (&src->config_lock); G_OBJECT_CLASS (gst_rpi_cam_src_parent_class)->finalize (object); }
static gboolean gst_rpi_cam_src_stop (GstBaseSrc * parent) { GstRpiCamSrc *src = GST_RPICAMSRC (parent); if (src->started) raspi_capture_stop (src->capture_state); raspi_capture_free (src->capture_state); src->capture_state = NULL; return TRUE; }
static const GList * gst_rpi_cam_src_colorbalance_list_channels (GstColorBalance * balance) { GstRpiCamSrc *src = GST_RPICAMSRC (balance); g_return_val_if_fail (src != NULL, NULL); g_return_val_if_fail (GST_IS_RPICAMSRC (src), NULL); return src->channels; }
static gboolean gst_rpi_cam_src_start (GstBaseSrc * parent) { GstRpiCamSrc *src = GST_RPICAMSRC (parent); GST_LOG_OBJECT (src, "In src_start()"); g_mutex_lock (&src->config_lock); src->capture_state = raspi_capture_setup (&src->capture_config); /* Clear all capture flags */ src->capture_config.change_flags = 0; g_mutex_unlock (&src->config_lock); if (src->capture_state == NULL) return FALSE; return TRUE; }
static gboolean gst_rpi_cam_src_orientation_get_vflip (GstVideoOrientation * orientation, gboolean * flip) { GstRpiCamSrc *src = GST_RPICAMSRC (orientation); g_return_val_if_fail (src != NULL, FALSE); g_return_val_if_fail (GST_IS_RPICAMSRC (src), FALSE); g_mutex_lock (&src->config_lock); *flip = src->capture_config.camera_parameters.vflip; g_mutex_unlock (&src->config_lock); return TRUE; }
static gboolean gst_rpi_cam_src_orientation_set_vflip (GstVideoOrientation * orientation, gboolean flip) { GstRpiCamSrc *src = GST_RPICAMSRC (orientation); g_return_val_if_fail (src != NULL, FALSE); g_return_val_if_fail (GST_IS_RPICAMSRC (src), FALSE); g_mutex_lock (&src->config_lock); src->capture_config.camera_parameters.vflip = flip; src->capture_config.change_flags |= PROP_CHANGE_ORIENTATION; g_mutex_unlock (&src->config_lock); return TRUE; }
static GstCaps * gst_rpi_cam_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter) { GstRpiCamSrc *src = GST_RPICAMSRC (bsrc); GstCaps *caps; caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc)); if (src->capture_state == NULL) goto done; /* FIXME: Retrieve limiting parameters from the camera module, max width/height fps-range */ caps = gst_caps_make_writable (caps); gst_caps_set_simple (caps, "width", GST_TYPE_INT_RANGE, 1, 1920, "height", GST_TYPE_INT_RANGE, 1, 1080, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 90, 1, NULL); done: GST_DEBUG_OBJECT (src, "get_caps returning %" GST_PTR_FORMAT, caps); return caps; }
static GstFlowReturn gst_rpi_cam_src_create (GstPushSrc * parent, GstBuffer ** buf) { GstRpiCamSrc *src = GST_RPICAMSRC (parent); GstFlowReturn ret; GstClock *clock = NULL; GstClockTime base_time; if (!src->started) { g_mutex_lock (&src->config_lock); raspi_capture_update_config (src->capture_state, &src->capture_config, FALSE); src->capture_config.change_flags = 0; g_mutex_unlock (&src->config_lock); if (!raspi_capture_start (src->capture_state)) return GST_FLOW_ERROR; src->started = TRUE; } GST_OBJECT_LOCK (src); if ((clock = GST_ELEMENT_CLOCK (src)) != NULL) gst_object_ref (clock); base_time = GST_ELEMENT_CAST (src)->base_time; GST_OBJECT_UNLOCK (src); g_mutex_lock (&src->config_lock); if (src->capture_config.change_flags) { raspi_capture_update_config (src->capture_state, &src->capture_config, TRUE); src->capture_config.change_flags = 0; } g_mutex_unlock (&src->config_lock); /* FIXME: Use custom allocator */ ret = raspi_capture_fill_buffer (src->capture_state, buf, clock, base_time); if (*buf) GST_LOG_OBJECT (src, "Made buffer of size %" G_GSIZE_FORMAT, gst_buffer_get_size (*buf)); if (clock) gst_object_unref (clock); return ret; }
static void gst_rpi_cam_src_finalize (GObject *object) { GstRpiCamSrc *src = GST_RPICAMSRC (object); GList *channels = NULL; g_mutex_clear (&src->config_lock); channels = src->channels; while (channels) { GstColorBalanceChannel *channel = channels->data; g_object_unref (channel); channels->data = NULL; channels = g_list_next (channels); } if (src->channels) g_list_free (src->channels); G_OBJECT_CLASS (gst_rpi_cam_src_parent_class)->finalize (object); }
static void gst_rpi_cam_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstRpiCamSrc *src = GST_RPICAMSRC (object); g_mutex_lock (&src->config_lock); switch (prop_id) { case PROP_CAMERA_NUMBER: g_value_set_int (value, src->capture_config.cameraNum); break; case PROP_BITRATE: g_value_set_int (value, src->capture_config.bitrate); break; case PROP_KEYFRAME_INTERVAL: g_value_set_int (value, src->capture_config.intraperiod); break; case PROP_PREVIEW: g_value_set_boolean (value, src->capture_config.preview_parameters.wantPreview); break; case PROP_PREVIEW_ENCODED: g_value_set_boolean (value, src->capture_config.immutableInput); break; case PROP_FULLSCREEN: g_value_set_boolean (value, src->capture_config.preview_parameters.wantFullScreenPreview); break; case PROP_PREVIEW_OPACITY: g_value_set_int (value, src->capture_config.preview_parameters.opacity); break; case PROP_SHARPNESS: g_value_set_int (value, src->capture_config.camera_parameters.sharpness); break; case PROP_CONTRAST: g_value_set_int (value, src->capture_config.camera_parameters.contrast); break; case PROP_BRIGHTNESS: g_value_set_int (value, src->capture_config.camera_parameters.brightness); break; case PROP_SATURATION: g_value_set_int (value, src->capture_config.camera_parameters.saturation); break; case PROP_ISO: g_value_set_int (value, src->capture_config.camera_parameters.ISO); break; case PROP_VIDEO_STABILISATION: g_value_set_boolean (value, ! !(src->capture_config.camera_parameters.videoStabilisation)); break; case PROP_EXPOSURE_COMPENSATION: g_value_set_int (value, src->capture_config.camera_parameters.exposureCompensation); break; case PROP_EXPOSURE_MODE: g_value_set_enum (value, src->capture_config.camera_parameters.exposureMode); break; case PROP_EXPOSURE_METERING_MODE: g_value_set_enum (value, src->capture_config.camera_parameters.exposureMeterMode); break; case PROP_ROTATION: g_value_set_int (value, src->capture_config.camera_parameters.rotation); break; case PROP_AWB_MODE: g_value_set_enum (value, src->capture_config.camera_parameters.awbMode); break; case PROP_AWB_GAIN_RED: g_value_set_float (value, src->capture_config.camera_parameters.awb_gains_r); break; case PROP_AWB_GAIN_BLUE: g_value_set_float (value, src->capture_config.camera_parameters.awb_gains_b); break; case PROP_IMAGE_EFFECT: g_value_set_enum (value, src->capture_config.camera_parameters.imageEffect); break; case PROP_HFLIP: g_value_set_boolean (value, ! !(src->capture_config.camera_parameters.hflip)); break; case PROP_VFLIP: g_value_set_boolean (value, ! !(src->capture_config.camera_parameters.vflip)); break; case PROP_ROI_X: g_value_set_float (value, src->capture_config.camera_parameters.roi.x); break; case PROP_ROI_Y: g_value_set_float (value, src->capture_config.camera_parameters.roi.y); break; case PROP_ROI_W: g_value_set_float (value, src->capture_config.camera_parameters.roi.w); break; case PROP_ROI_H: g_value_set_float (value, src->capture_config.camera_parameters.roi.h); break; case PROP_QUANTISATION_PARAMETER: g_value_set_int (value, src->capture_config.quantisationParameter); break; case PROP_INLINE_HEADERS: g_value_set_boolean (value, src->capture_config.bInlineHeaders); break; case PROP_SHUTTER_SPEED: g_value_set_int (value, src->capture_config.camera_parameters.shutter_speed); break; case PROP_DRC: g_value_set_enum (value, src->capture_config.camera_parameters.drc_level); break; case PROP_SENSOR_MODE: g_value_set_enum (value, src->capture_config.sensor_mode); break; case PROP_ANNOTATION_MODE: g_value_set_flags (value, src->capture_config.camera_parameters.enable_annotate); break; case PROP_ANNOTATION_TEXT: g_value_set_string (value, src->capture_config.camera_parameters.annotate_string); break; case PROP_INTRA_REFRESH_TYPE: g_value_set_enum (value, src->capture_config.intra_refresh_type); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } g_mutex_unlock (&src->config_lock); }
static void gst_rpi_cam_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstRpiCamSrc *src = GST_RPICAMSRC (object); g_mutex_lock (&src->config_lock); switch (prop_id) { case PROP_CAMERA_NUMBER: src->capture_config.cameraNum = g_value_get_int (value); break; case PROP_BITRATE: src->capture_config.bitrate = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_ENCODING; break; case PROP_KEYFRAME_INTERVAL: src->capture_config.intraperiod = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_ENCODING; break; case PROP_PREVIEW: src->capture_config.preview_parameters.wantPreview = g_value_get_boolean (value); src->capture_config.change_flags |= PROP_CHANGE_PREVIEW; break; case PROP_PREVIEW_ENCODED: src->capture_config.immutableInput = g_value_get_boolean (value); src->capture_config.change_flags |= PROP_CHANGE_PREVIEW; break; case PROP_FULLSCREEN: src->capture_config.preview_parameters.wantFullScreenPreview = g_value_get_boolean (value); src->capture_config.change_flags |= PROP_CHANGE_PREVIEW; break; case PROP_PREVIEW_OPACITY: src->capture_config.preview_parameters.opacity = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_PREVIEW; break; case PROP_SHARPNESS: src->capture_config.camera_parameters.sharpness = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_COLOURBALANCE; break; case PROP_CONTRAST: src->capture_config.camera_parameters.contrast = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_COLOURBALANCE; break; case PROP_BRIGHTNESS: src->capture_config.camera_parameters.brightness = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_COLOURBALANCE; break; case PROP_SATURATION: src->capture_config.camera_parameters.saturation = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_COLOURBALANCE; break; case PROP_ISO: src->capture_config.camera_parameters.ISO = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_SENSOR_SETTINGS; break; case PROP_VIDEO_STABILISATION: src->capture_config.camera_parameters.videoStabilisation = g_value_get_boolean (value); src->capture_config.change_flags |= PROP_CHANGE_VIDEO_STABILISATION; break; case PROP_EXPOSURE_COMPENSATION: src->capture_config.camera_parameters.exposureCompensation = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_SENSOR_SETTINGS; break; case PROP_EXPOSURE_MODE: src->capture_config.camera_parameters.exposureMode = g_value_get_enum (value); src->capture_config.change_flags |= PROP_CHANGE_SENSOR_SETTINGS; break; case PROP_EXPOSURE_METERING_MODE: src->capture_config.camera_parameters.exposureMeterMode = g_value_get_enum (value); src->capture_config.change_flags |= PROP_CHANGE_SENSOR_SETTINGS; break; case PROP_ROTATION: src->capture_config.camera_parameters.rotation = g_value_get_int (value); break; case PROP_AWB_MODE: src->capture_config.camera_parameters.awbMode = g_value_get_enum (value); src->capture_config.change_flags |= PROP_CHANGE_AWB; break; case PROP_AWB_GAIN_RED: src->capture_config.camera_parameters.awb_gains_r = g_value_get_float (value); src->capture_config.change_flags |= PROP_CHANGE_AWB; break; case PROP_AWB_GAIN_BLUE: src->capture_config.camera_parameters.awb_gains_b = g_value_get_float (value); src->capture_config.change_flags |= PROP_CHANGE_AWB; break; case PROP_IMAGE_EFFECT: src->capture_config.camera_parameters.imageEffect = g_value_get_enum (value); src->capture_config.change_flags |= PROP_CHANGE_IMAGE_COLOUR_EFFECT; break; case PROP_HFLIP: src->capture_config.camera_parameters.hflip = g_value_get_boolean (value); src->capture_config.change_flags |= PROP_CHANGE_ORIENTATION; break; case PROP_VFLIP: src->capture_config.camera_parameters.vflip = g_value_get_boolean (value); src->capture_config.change_flags |= PROP_CHANGE_ORIENTATION; break; case PROP_ROI_X: src->capture_config.camera_parameters.roi.x = g_value_get_float (value); src->capture_config.change_flags |= PROP_CHANGE_ROI; break; case PROP_ROI_Y: src->capture_config.camera_parameters.roi.y = g_value_get_float (value); src->capture_config.change_flags |= PROP_CHANGE_ROI; break; case PROP_ROI_W: src->capture_config.camera_parameters.roi.w = g_value_get_float (value); src->capture_config.change_flags |= PROP_CHANGE_ROI; break; case PROP_ROI_H: src->capture_config.camera_parameters.roi.h = g_value_get_float (value); src->capture_config.change_flags |= PROP_CHANGE_ROI; break; case PROP_QUANTISATION_PARAMETER: src->capture_config.quantisationParameter = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_ENCODING; break; case PROP_INLINE_HEADERS: src->capture_config.bInlineHeaders = g_value_get_boolean (value); break; case PROP_SHUTTER_SPEED: src->capture_config.camera_parameters.shutter_speed = g_value_get_int (value); src->capture_config.change_flags |= PROP_CHANGE_SENSOR_SETTINGS; break; case PROP_DRC: src->capture_config.camera_parameters.drc_level = g_value_get_enum (value); src->capture_config.change_flags |= PROP_CHANGE_SENSOR_SETTINGS; break; case PROP_SENSOR_MODE: src->capture_config.sensor_mode = g_value_get_enum (value); src->capture_config.change_flags |= PROP_CHANGE_SENSOR_SETTINGS; break; case PROP_ANNOTATION_MODE: src->capture_config.camera_parameters.enable_annotate = g_value_get_flags (value); src->capture_config.change_flags |= PROP_CHANGE_ANNOTATION; break; case PROP_ANNOTATION_TEXT: strncpy (src->capture_config.camera_parameters.annotate_string, g_value_get_string (value), MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V2); src->capture_config. camera_parameters.annotate_string[MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V2 - 1] = '\0'; src->capture_config.change_flags |= PROP_CHANGE_ANNOTATION; break; case PROP_INTRA_REFRESH_TYPE: src->capture_config.intra_refresh_type = g_value_get_enum (value); src->capture_config.change_flags |= PROP_CHANGE_ENCODING; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } g_mutex_unlock (&src->config_lock); }