diff options
-rw-r--r-- | gst/camerabin2/gstcamerabin2.c | 123 | ||||
-rw-r--r-- | gst/camerabin2/gstcamerabin2.h | 7 |
2 files changed, 129 insertions, 1 deletions
diff --git a/gst/camerabin2/gstcamerabin2.c b/gst/camerabin2/gstcamerabin2.c index 456a7ea26..85a56967a 100644 --- a/gst/camerabin2/gstcamerabin2.c +++ b/gst/camerabin2/gstcamerabin2.c @@ -40,7 +40,10 @@ * have room to set the destination filename). * There is no problem to leave it on playing after an EOS, so * no action is taken on stop-capture. + * * - TODO: What happens when an error pops? + * - TODO: Should we split properties in image/video variants? We already do so + * for some of them * * */ @@ -69,7 +72,10 @@ enum PROP_VIDEO_CAPTURE_CAPS, PROP_POST_PREVIEWS, PROP_PREVIEW_CAPS, - PROP_VIDEO_ENCODING_PROFILE + PROP_VIDEO_ENCODING_PROFILE, + PROP_IMAGE_FILTER, + PROP_VIDEO_FILTER, + PROP_VIEWFINDER_FILTER }; enum @@ -278,6 +284,20 @@ gst_camera_bin_dispose (GObject * object) if (camerabin->imagebin_capsfilter) gst_object_unref (camerabin->imagebin_capsfilter); + if (camerabin->video_filter) + gst_object_unref (camerabin->video_filter); + if (camerabin->image_filter) + gst_object_unref (camerabin->image_filter); + if (camerabin->viewfinder_filter) + gst_object_unref (camerabin->viewfinder_filter); + + if (camerabin->user_video_filter) + gst_object_unref (camerabin->user_video_filter); + if (camerabin->user_image_filter) + gst_object_unref (camerabin->user_image_filter); + if (camerabin->user_viewfinder_filter) + gst_object_unref (camerabin->user_viewfinder_filter); + if (camerabin->video_profile) gst_encoding_profile_unref (camerabin->video_profile); @@ -394,6 +414,25 @@ gst_camera_bin_class_init (GstCameraBinClass * klass) GST_TYPE_ENCODING_PROFILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_IMAGE_FILTER, + g_param_spec_object ("image-filter", "Image filter", + "The element that will process captured image frames. (Should be" + " set on NULL state)", + GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_VIDEO_FILTER, + g_param_spec_object ("video-filter", "Video filter", + "The element that will process captured video frames. (Should be" + " set on NULL state)", + GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_VIEWFINDER_FILTER, + g_param_spec_object ("viewfinder-filter", "Viewfinder filter", + "The element that will process frames going to the viewfinder." + " (Should be set on NULL state)", + GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** * GstCameraBin::capture-start: * @camera: the camera bin element @@ -479,6 +518,48 @@ gst_camera_bin_handle_message (GstBin * bin, GstMessage * message) GST_BIN_CLASS (parent_class)->handle_message (bin, message); } +/* + * Transforms: + * ... ! previous_element [ ! current_filter ] ! next_element ! ... + * + * into: + * ... ! previous_element [ ! new_filter ] ! next_element ! ... + * + * Where current_filter and new_filter might or might not be NULL + */ +static void +gst_camera_bin_check_and_replace_filter (GstCameraBin * camera, + GstElement ** current_filter, GstElement * new_filter, + GstElement * previous_element, GstElement * next_element) +{ + if (*current_filter == new_filter) { + GST_DEBUG_OBJECT (camera, "Current filter is the same as the previous, " + "no switch needed."); + return; + } + + GST_DEBUG_OBJECT (camera, "Replacing current filter (%s) with new filter " + "(%s)", *current_filter ? GST_ELEMENT_NAME (*current_filter) : "null", + new_filter ? GST_ELEMENT_NAME (new_filter) : "null"); + + if (*current_filter) { + gst_bin_remove (GST_BIN_CAST (camera), *current_filter); + gst_object_unref (*current_filter); + *current_filter = NULL; + } else { + /* unlink the pads */ + gst_element_unlink (previous_element, next_element); + } + + if (new_filter) { + *current_filter = gst_object_ref (new_filter); + gst_bin_add (GST_BIN_CAST (camera), gst_object_ref (new_filter)); + gst_element_link_many (previous_element, new_filter, next_element, NULL); + } else { + gst_element_link (previous_element, next_element); + } +} + /** * gst_camera_bin_create_elements: * @param camera: the #GstCameraBin @@ -612,6 +693,16 @@ gst_camera_bin_create_elements (GstCameraBin * camera) "sink"); } + gst_camera_bin_check_and_replace_filter (camera, &camera->image_filter, + camera->user_image_filter, camera->imagebin_queue, + camera->imagebin_capsfilter); + gst_camera_bin_check_and_replace_filter (camera, &camera->video_filter, + camera->user_video_filter, camera->videobin_queue, + camera->videobin_capsfilter); + gst_camera_bin_check_and_replace_filter (camera, &camera->viewfinder_filter, + camera->user_viewfinder_filter, camera->viewfinderbin_queue, + camera->viewfinderbin_capsfilter); + camera->elements_created = TRUE; return TRUE; } @@ -763,6 +854,24 @@ gst_camera_bin_set_property (GObject * object, guint prop_id, camera->video_profile = (GstEncodingProfile *) gst_value_dup_mini_object (value); break; + case PROP_IMAGE_FILTER: + if (camera->user_image_filter) + g_object_unref (camera->user_image_filter); + + camera->user_image_filter = g_value_dup_object (value); + break; + case PROP_VIDEO_FILTER: + if (camera->user_video_filter) + g_object_unref (camera->user_video_filter); + + camera->user_video_filter = g_value_dup_object (value); + break; + case PROP_VIEWFINDER_FILTER: + if (camera->user_viewfinder_filter) + g_object_unref (camera->user_viewfinder_filter); + + camera->user_viewfinder_filter = g_value_dup_object (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -851,6 +960,18 @@ gst_camera_bin_get_property (GObject * object, guint prop_id, (GstMiniObject *) camera->video_profile); } break; + case PROP_VIDEO_FILTER: + if (camera->video_filter) + g_value_set_object (value, camera->video_filter); + break; + case PROP_IMAGE_FILTER: + if (camera->image_filter) + g_value_set_object (value, camera->image_filter); + break; + case PROP_VIEWFINDER_FILTER: + if (camera->viewfinder_filter) + g_value_set_object (value, camera->viewfinder_filter); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/camerabin2/gstcamerabin2.h b/gst/camerabin2/gstcamerabin2.h index 8534674aa..f24417f1e 100644 --- a/gst/camerabin2/gstcamerabin2.h +++ b/gst/camerabin2/gstcamerabin2.h @@ -55,6 +55,13 @@ struct _GstCameraBin GstElement *imagebin_queue; GstElement *imagebin_capsfilter; + GstElement *video_filter; + GstElement *image_filter; + GstElement *viewfinder_filter; + GstElement *user_video_filter; + GstElement *user_image_filter; + GstElement *user_viewfinder_filter; + /* Index of the auto incrementing file index for video recordings */ gint video_index; |