mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:16:13 +00:00
camerabin: Scale incoming frames if their size does not match requested size
If capture preparation in videosrc results in frame size different from requested size, then we need to scale them.
This commit is contained in:
parent
617f34895c
commit
24d99bbe56
1 changed files with 71 additions and 20 deletions
|
@ -1266,24 +1266,75 @@ gst_camerabin_set_capsfilter_caps (GstCameraBin * camera, GstCaps * new_caps)
|
||||||
g_object_set (G_OBJECT (camera->src_zoom_filter), "caps", new_caps, NULL);
|
g_object_set (G_OBJECT (camera->src_zoom_filter), "caps", new_caps, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_camerabin_adapt_video_resolution (GstCameraBin * camera, GstCaps * caps)
|
||||||
|
{
|
||||||
|
GstStructure *st;
|
||||||
|
gint width = 0, height = 0;
|
||||||
|
GstCaps *filter_caps = NULL;
|
||||||
|
|
||||||
|
/* Get width and height from caps */
|
||||||
|
st = gst_caps_get_structure (caps, 0);
|
||||||
|
gst_structure_get_int (st, "width", &width);
|
||||||
|
gst_structure_get_int (st, "height", &height);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (camera,
|
||||||
|
"changing %dx%d -> %dx%d filter to %" GST_PTR_FORMAT,
|
||||||
|
camera->width, camera->height, width, height, camera->src_filter);
|
||||||
|
|
||||||
|
/* Apply the width and height to filter caps */
|
||||||
|
g_object_get (G_OBJECT (camera->src_filter), "caps", &filter_caps, NULL);
|
||||||
|
filter_caps = gst_caps_make_writable (filter_caps);
|
||||||
|
gst_caps_set_simple (filter_caps, "width", G_TYPE_INT, width,
|
||||||
|
"height", G_TYPE_INT, height, NULL);
|
||||||
|
g_object_set (G_OBJECT (camera->src_filter), "caps", filter_caps, NULL);
|
||||||
|
gst_caps_unref (filter_caps);
|
||||||
|
/* FIXME: implement cropping according to requested aspect ratio */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* img_capture_prepared:
|
* img_capture_prepared:
|
||||||
* @data: camerabin object
|
* @data: camerabin object
|
||||||
|
* @caps: caps describing the prepared image format
|
||||||
*
|
*
|
||||||
* Callback which is called after image capture has been prepared.
|
* Callback which is called after image capture has been prepared.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
img_capture_prepared (gpointer data)
|
img_capture_prepared (gpointer data, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstCameraBin *camera = GST_CAMERABIN (data);
|
GstCameraBin *camera = GST_CAMERABIN (data);
|
||||||
|
GstStructure *st, *new_st;
|
||||||
|
gint i;
|
||||||
|
const gchar *field_name;
|
||||||
|
|
||||||
GST_INFO_OBJECT (camera, "image capture prepared");
|
GST_INFO_OBJECT (camera, "image capture prepared");
|
||||||
|
|
||||||
if (camera->image_capture_caps) {
|
/* It is possible we are about to get something else that we requested */
|
||||||
/* Set capsfilters to match arriving image data */
|
if (!gst_caps_is_equal (camera->image_capture_caps, caps)) {
|
||||||
gst_camerabin_set_capsfilter_caps (camera, camera->image_capture_caps);
|
/* If capture preparation has added new fields to requested caps,
|
||||||
|
we need to copy them */
|
||||||
|
st = gst_caps_get_structure (camera->image_capture_caps, 0);
|
||||||
|
new_st = gst_structure_copy (st);
|
||||||
|
st = gst_caps_get_structure (caps, 0);
|
||||||
|
for (i = 0; i < gst_structure_n_fields (st); i++) {
|
||||||
|
field_name = gst_structure_nth_field_name (st, i);
|
||||||
|
if (!gst_structure_has_field (new_st, field_name)) {
|
||||||
|
GST_DEBUG_OBJECT (camera, "new field in prepared caps: %s", field_name);
|
||||||
|
gst_structure_set_value (new_st, field_name,
|
||||||
|
gst_structure_get_value (st, field_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gst_caps_replace (&camera->image_capture_caps,
|
||||||
|
gst_caps_new_full (new_st, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update capsfilters */
|
||||||
|
gst_camerabin_set_capsfilter_caps (camera, camera->image_capture_caps);
|
||||||
|
|
||||||
|
/* If incoming buffer resolution is different from what application
|
||||||
|
requested, then we need to fix this in camerabin */
|
||||||
|
gst_camerabin_adapt_video_resolution (camera, caps);
|
||||||
|
|
||||||
g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", FALSE,
|
g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", FALSE,
|
||||||
"active-pad", camera->pad_src_img, NULL);
|
"active-pad", camera->pad_src_img, NULL);
|
||||||
gst_camerabin_rewrite_tags (camera);
|
gst_camerabin_rewrite_tags (camera);
|
||||||
|
@ -1300,9 +1351,7 @@ static void
|
||||||
gst_camerabin_start_image_capture (GstCameraBin * camera)
|
gst_camerabin_start_image_capture (GstCameraBin * camera)
|
||||||
{
|
{
|
||||||
GstStateChangeReturn state_ret;
|
GstStateChangeReturn state_ret;
|
||||||
gboolean wait_for_prepare = FALSE;
|
gboolean wait_for_prepare = FALSE, ret = FALSE;
|
||||||
gint width = 0, height = 0, fps_n = 0, fps_d = 0;
|
|
||||||
GstStructure *st;
|
|
||||||
|
|
||||||
GST_INFO_OBJECT (camera, "starting image capture");
|
GST_INFO_OBJECT (camera, "starting image capture");
|
||||||
|
|
||||||
|
@ -1312,17 +1361,6 @@ gst_camerabin_start_image_capture (GstCameraBin * camera)
|
||||||
/* Start image capture preparations using photography iface */
|
/* Start image capture preparations using photography iface */
|
||||||
wait_for_prepare = TRUE;
|
wait_for_prepare = TRUE;
|
||||||
g_mutex_lock (camera->capture_mutex);
|
g_mutex_lock (camera->capture_mutex);
|
||||||
if (camera->image_capture_caps) {
|
|
||||||
st = gst_caps_get_structure (camera->image_capture_caps, 0);
|
|
||||||
} else {
|
|
||||||
st = gst_caps_get_structure (camera->view_finder_caps, 0);
|
|
||||||
}
|
|
||||||
gst_structure_get_int (st, "width", &width);
|
|
||||||
gst_structure_get_int (st, "height", &height);
|
|
||||||
gst_structure_get_fraction (st, "framerate", &fps_n, &fps_d);
|
|
||||||
/* Set image capture resolution and frame rate */
|
|
||||||
g_signal_emit_by_name (camera->src_vid_src, "user-res-fps",
|
|
||||||
width, height, fps_n, fps_d, 0);
|
|
||||||
|
|
||||||
/* Enable still image capture mode in v4l2camsrc */
|
/* Enable still image capture mode in v4l2camsrc */
|
||||||
if (g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src_vid_src),
|
if (g_object_class_find_property (G_OBJECT_GET_CLASS (camera->src_vid_src),
|
||||||
|
@ -1330,9 +1368,17 @@ gst_camerabin_start_image_capture (GstCameraBin * camera)
|
||||||
g_object_set (G_OBJECT (camera->src_vid_src), "capture-mode", 1, NULL);
|
g_object_set (G_OBJECT (camera->src_vid_src), "capture-mode", 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!camera->image_capture_caps) {
|
||||||
|
camera->image_capture_caps = gst_caps_copy (camera->view_finder_caps);
|
||||||
|
}
|
||||||
|
|
||||||
/* Start preparations for image capture */
|
/* Start preparations for image capture */
|
||||||
gst_photography_prepare_for_capture (GST_PHOTOGRAPHY (camera->src_vid_src),
|
GST_DEBUG_OBJECT (camera, "prepare image capture caps %" GST_PTR_FORMAT,
|
||||||
(GstPhotoCapturePrepared) img_capture_prepared, camera);
|
camera->image_capture_caps);
|
||||||
|
ret =
|
||||||
|
gst_photography_prepare_for_capture (GST_PHOTOGRAPHY
|
||||||
|
(camera->src_vid_src), (GstPhotoCapturePrepared) img_capture_prepared,
|
||||||
|
camera->image_capture_caps, camera);
|
||||||
camera->capturing = TRUE;
|
camera->capturing = TRUE;
|
||||||
g_mutex_unlock (camera->capture_mutex);
|
g_mutex_unlock (camera->capture_mutex);
|
||||||
}
|
}
|
||||||
|
@ -1345,12 +1391,17 @@ gst_camerabin_start_image_capture (GstCameraBin * camera)
|
||||||
g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", TRUE,
|
g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", TRUE,
|
||||||
"active-pad", camera->pad_src_img, NULL);
|
"active-pad", camera->pad_src_img, NULL);
|
||||||
camera->capturing = TRUE;
|
camera->capturing = TRUE;
|
||||||
|
ret = TRUE;
|
||||||
g_mutex_unlock (camera->capture_mutex);
|
g_mutex_unlock (camera->capture_mutex);
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING_OBJECT (camera, "imagebin state change failed");
|
GST_WARNING_OBJECT (camera, "imagebin state change failed");
|
||||||
gst_element_set_state (camera->imgbin, GST_STATE_NULL);
|
gst_element_set_state (camera->imgbin, GST_STATE_NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
GST_WARNING_OBJECT (camera, "starting image capture failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue