diff --git a/gst/camerabin/gstcamerabin-enum.h b/gst/camerabin/gstcamerabin-enum.h index c7f4102748..d1695594df 100644 --- a/gst/camerabin/gstcamerabin-enum.h +++ b/gst/camerabin/gstcamerabin-enum.h @@ -63,7 +63,10 @@ enum ARG_FOCUS_MODE, ARG_BLOCK_VIEWFINDER, ARG_IMAGE_CAPTURE_WIDTH, - ARG_IMAGE_CAPTURE_HEIGHT + ARG_IMAGE_CAPTURE_HEIGHT, + ARG_VIDEO_CAPTURE_WIDTH, + ARG_VIDEO_CAPTURE_HEIGHT, + ARG_VIDEO_CAPTURE_FRAMERATE }; /** diff --git a/gst/camerabin/gstcamerabin.c b/gst/camerabin/gstcamerabin.c index 9e9284770c..bd71794745 100644 --- a/gst/camerabin/gstcamerabin.c +++ b/gst/camerabin/gstcamerabin.c @@ -488,6 +488,9 @@ camerabin_setup_src_elements (GstCameraBin * camera) GstCaps *new_caps; gboolean detect_framerate = FALSE; + /* clear video update status */ + camera->video_capture_caps_update = FALSE; + if (!camera->view_finder_caps) { st = gst_structure_from_string (CAMERABIN_DEFAULT_VF_CAPS, NULL); } else { @@ -1534,6 +1537,47 @@ gst_camerabin_start_image_capture (GstCameraBin * camera) } } + /* + * FIXME ideally a caps renegotiation is better here + */ +static void +reset_video_capture_caps (GstCameraBin * camera) +{ + GstState state, pending; + GstPad *activepad = NULL; + + GST_INFO_OBJECT (camera, "switching resolution to %dx%d and fps to %d/%d", + camera->width, camera->height, camera->fps_n, camera->fps_d); + + /* Interrupt ongoing capture */ + gst_camerabin_do_stop (camera); + + gst_element_get_state (GST_ELEMENT (camera), &state, &pending, 0); + if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING) { + GST_INFO_OBJECT (camera, + "changing to READY to initialize videosrc with new format"); + g_object_get (G_OBJECT (camera->src_out_sel), "active-pad", &activepad, + NULL); + gst_element_set_state (GST_ELEMENT (camera), GST_STATE_READY); + } + if (pending != GST_STATE_VOID_PENDING) { + GST_LOG_OBJECT (camera, "restoring pending state: %s", + gst_element_state_get_name (pending)); + state = pending; + } + + /* Re-set the active pad since switching camerabin to READY state clears this + * setting in output-selector */ + if (activepad) { + GST_INFO_OBJECT (camera, "re-setting active pad in output-selector"); + + g_object_set (G_OBJECT (camera->src_out_sel), "active-pad", activepad, + NULL); + } + + gst_element_set_state (GST_ELEMENT (camera), state); +} + /* * gst_camerabin_start_video_recording: * @camera: camerabin object @@ -1549,6 +1593,11 @@ gst_camerabin_start_video_recording (GstCameraBin * camera) */ GST_INFO_OBJECT (camera, "starting video capture"); + /* check if need to update video capture caps */ + if (camera->video_capture_caps_update) { + reset_video_capture_caps (camera); + } + gst_camerabin_rewrite_tags (camera); /* Pause the pipeline in order to distribute new clock in paused_to_playing */ @@ -2835,6 +2884,40 @@ gst_camerabin_class_init (GstCameraBinClass * klass) "The height used for image capture", 0, G_MAXINT16, DEFAULT_CAPTURE_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstCameraBin:video-capture-width: + * + * The width to be used when capturing video. + */ + g_object_class_install_property (gobject_class, ARG_VIDEO_CAPTURE_WIDTH, + g_param_spec_int ("video-capture-width", + "The width used for video capture", + "The width used for video capture", 0, G_MAXINT16, + DEFAULT_CAPTURE_WIDTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstCameraBin:video-capture-height: + * + * The height to be used when capturing video. + */ + g_object_class_install_property (gobject_class, ARG_VIDEO_CAPTURE_HEIGHT, + g_param_spec_int ("video-capture-height", + "The height used for video capture", + "The height used for video capture", 0, G_MAXINT16, + DEFAULT_CAPTURE_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstCameraBin:video-capture-framerate: + * + * The framerate to be used when capturing video. + */ + g_object_class_install_property (gobject_class, ARG_VIDEO_CAPTURE_FRAMERATE, + gst_param_spec_fraction ("video-capture-framerate", + "The framerate used for video capture", + "The framerate used for video capture", 0, 1, G_MAXINT32, 1, + DEFAULT_FPS_N, DEFAULT_FPS_D, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** * GstCameraBin::capture-start: * @camera: the camera bin element @@ -2895,6 +2978,10 @@ gst_camerabin_class_init (GstCameraBinClass * klass) * * Setting @fps_n or @fps_d to 0 configures maximum framerate for the * given resolution, unless in night mode when minimum is configured. + * + * This is the same as setting the 'video-capture-width', + * 'video-capture-height' and 'video-capture-framerate' properties, but it + * already updates the caps to force use this resolution and framerate. */ camerabin_signals[SET_VIDEO_RESOLUTION_FPS_SIGNAL] = @@ -3321,6 +3408,40 @@ gst_camerabin_set_property (GObject * object, guint prop_id, } } break; + case ARG_VIDEO_CAPTURE_WIDTH: + { + gint width = g_value_get_int (value); + + if (width != camera->width) { + camera->width = width; + camera->video_capture_caps_update = TRUE; + } + } + break; + case ARG_VIDEO_CAPTURE_HEIGHT: + { + gint height = g_value_get_int (value); + + if (height != camera->height) { + camera->height = height; + camera->video_capture_caps_update = TRUE; + } + } + break; + case ARG_VIDEO_CAPTURE_FRAMERATE: + { + gint fps_n, fps_d; + + fps_n = gst_value_get_fraction_numerator (value); + fps_d = gst_value_get_fraction_denominator (value); + + if (fps_n != camera->fps_n || fps_d != camera->fps_d) { + camera->fps_n = fps_n; + camera->fps_d = fps_d; + camera->video_capture_caps_update = TRUE; + } + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3425,6 +3546,15 @@ gst_camerabin_get_property (GObject * object, guint prop_id, case ARG_IMAGE_CAPTURE_HEIGHT: g_value_set_int (value, camera->image_capture_height); break; + case ARG_VIDEO_CAPTURE_WIDTH: + g_value_set_int (value, camera->width); + break; + case ARG_VIDEO_CAPTURE_HEIGHT: + g_value_set_int (value, camera->height); + break; + case ARG_VIDEO_CAPTURE_FRAMERATE: + gst_value_set_fraction (value, camera->fps_n, camera->fps_d); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3705,43 +3835,10 @@ static void gst_camerabin_set_video_resolution_fps (GstCameraBin * camera, gint width, gint height, gint fps_n, gint fps_d) { - GstState state, pending; - GstPad *activepad = NULL; + g_object_set (camera, "video-capture-width", width, "video-capture-height", + height, "video-capture-framerate", fps_n, fps_d, NULL); - GST_INFO_OBJECT (camera, "switching resolution to %dx%d and fps to %d/%d", - width, height, fps_n, fps_d); - - /* Interrupt ongoing capture */ - gst_camerabin_do_stop (camera); - - gst_element_get_state (GST_ELEMENT (camera), &state, &pending, 0); - if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING) { - GST_INFO_OBJECT (camera, - "changing to READY to initialize videosrc with new format"); - g_object_get (G_OBJECT (camera->src_out_sel), "active-pad", &activepad, - NULL); - gst_element_set_state (GST_ELEMENT (camera), GST_STATE_READY); - } - camera->width = width; - camera->height = height; - camera->fps_n = fps_n; - camera->fps_d = fps_d; - if (pending != GST_STATE_VOID_PENDING) { - GST_LOG_OBJECT (camera, "restoring pending state: %s", - gst_element_state_get_name (pending)); - state = pending; - } - - /* Re-set the active pad since switching camerabin to READY state clears this - * setting in output-selector */ - if (activepad) { - GST_INFO_OBJECT (camera, "re-setting active pad in output-selector"); - - g_object_set (G_OBJECT (camera->src_out_sel), "active-pad", activepad, - NULL); - } - - gst_element_set_state (GST_ELEMENT (camera), state); + reset_video_capture_caps (camera); } static void diff --git a/gst/camerabin/gstcamerabin.h b/gst/camerabin/gstcamerabin.h index 9d47d65339..bd4a8e9404 100644 --- a/gst/camerabin/gstcamerabin.h +++ b/gst/camerabin/gstcamerabin.h @@ -72,6 +72,8 @@ struct _GstCameraBin gint fps_n; gint fps_d; + gboolean video_capture_caps_update; + /* Image capture resolution */ gint image_capture_width; gint image_capture_height; diff --git a/gst/camerabin/gstcamerabinphotography.c b/gst/camerabin/gstcamerabinphotography.c index 7148151653..4780909f2a 100644 --- a/gst/camerabin/gstcamerabinphotography.c +++ b/gst/camerabin/gstcamerabinphotography.c @@ -428,7 +428,7 @@ gst_camerabin_handle_scene_mode (GstCameraBin * camera, GstSceneMode scene_mode) camera->pre_night_fps_n = camera->fps_n; camera->pre_night_fps_d = camera->fps_d; g_signal_emit_by_name (camera, "set-video-resolution-fps", camera->width, - camera->height, 0, 0, 0); + camera->height, 0, 1, NULL); } else { GST_DEBUG ("night mode already enabled"); }