camera: improve resolution scaling to avoid extra rescallers
This commit is contained in:
parent
425bbe7745
commit
6ce1869f71
@ -94,5 +94,5 @@ int camera_configure_pipeline(camera_t *camera, buffer_list_t *camera_capture);
|
|||||||
buffer_list_t *camera_configure_isp(camera_t *camera, buffer_list_t *src_capture);
|
buffer_list_t *camera_configure_isp(camera_t *camera, buffer_list_t *src_capture);
|
||||||
buffer_list_t *camera_configure_decoder(camera_t *camera, buffer_list_t *src_capture);
|
buffer_list_t *camera_configure_decoder(camera_t *camera, buffer_list_t *src_capture);
|
||||||
buffer_list_t *camera_configure_rescaller(camera_t *camera, buffer_list_t *src_capture, const char *name, unsigned target_height, unsigned formats[]);
|
buffer_list_t *camera_configure_rescaller(camera_t *camera, buffer_list_t *src_capture, const char *name, unsigned target_height, unsigned formats[]);
|
||||||
int camera_configure_output(camera_t *camera, const char *name, unsigned target_height, unsigned formats[], link_callbacks_t callbacks, device_t **device);
|
int camera_configure_output(camera_t *camera, buffer_list_t *camera_capture, const char *name, camera_output_options_t *options, unsigned formats[], link_callbacks_t callbacks, device_t **device);
|
||||||
bool camera_get_scaled_resolution(camera_t *camera, camera_output_options_t *options, buffer_format_t *format);
|
bool camera_get_scaled_resolution(buffer_format_t capture_format, camera_output_options_t *options, buffer_format_t *format);
|
||||||
|
@ -80,11 +80,11 @@ static int camera_configure_input_libcamera(camera_t *camera)
|
|||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
found = camera_get_scaled_resolution(camera, &camera->options.snapshot, &capture_fmt);
|
found = camera_get_scaled_resolution(capture_fmt, &camera->options.snapshot, &capture_fmt);
|
||||||
if (!found)
|
if (!found)
|
||||||
found = camera_get_scaled_resolution(camera, &camera->options.stream, &capture_fmt);
|
found = camera_get_scaled_resolution(capture_fmt, &camera->options.stream, &capture_fmt);
|
||||||
if (!found)
|
if (!found)
|
||||||
found = camera_get_scaled_resolution(camera, &camera->options.video, &capture_fmt);
|
found = camera_get_scaled_resolution(capture_fmt, &camera->options.video, &capture_fmt);
|
||||||
|
|
||||||
buffer_list_t *camera_capture = device_open_buffer_list(camera->camera, true, capture_fmt, true);
|
buffer_list_t *camera_capture = device_open_buffer_list(camera->camera, true, capture_fmt, true);
|
||||||
if (!camera_capture) {
|
if (!camera_capture) {
|
||||||
|
@ -74,20 +74,58 @@ static unsigned rescalled_formats[] =
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
int camera_configure_output(camera_t *camera, const char *name, unsigned target_height, unsigned formats[], link_callbacks_t callbacks, device_t **device)
|
int camera_configure_output(camera_t *camera, buffer_list_t *camera_capture, const char *name, camera_output_options_t *options, unsigned formats[], link_callbacks_t callbacks, device_t **device)
|
||||||
{
|
{
|
||||||
buffer_list_t *src_capture = camera_find_capture2(camera, target_height, formats);
|
buffer_format_t selected_format = {0};
|
||||||
|
|
||||||
|
if (!camera_get_scaled_resolution(camera_capture->fmt, options, &selected_format)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find an existing format
|
||||||
|
buffer_list_t *src_capture = camera_find_capture2(camera, selected_format.height, formats);
|
||||||
if (src_capture) {
|
if (src_capture) {
|
||||||
camera_capture_add_callbacks(camera, src_capture, callbacks);
|
camera_capture_add_callbacks(camera, src_capture, callbacks);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
src_capture = camera_find_capture2(camera, target_height, rescalled_formats);
|
// Try to find exact output
|
||||||
|
src_capture = camera_find_capture2(camera, selected_format.height, rescalled_formats);
|
||||||
|
|
||||||
|
// Try to re-scale output
|
||||||
if (!src_capture) {
|
if (!src_capture) {
|
||||||
// Try to find re-scallabe output
|
buffer_list_t *other_capture = camera_find_capture2(camera, 0, rescalled_formats);
|
||||||
src_capture = camera_find_capture2(camera, 0, rescalled_formats);
|
|
||||||
if (src_capture) {
|
if (other_capture) {
|
||||||
src_capture = camera_configure_rescaller(camera, src_capture, name, target_height, rescalled_formats);
|
src_capture = camera_configure_rescaller(camera, other_capture, name, selected_format.height, rescalled_formats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to decode output
|
||||||
|
if (!src_capture) {
|
||||||
|
buffer_list_t *decoded_capture = NULL;
|
||||||
|
|
||||||
|
switch (camera_capture->fmt.format) {
|
||||||
|
case V4L2_PIX_FMT_SRGGB10P:
|
||||||
|
case V4L2_PIX_FMT_SGRBG10P:
|
||||||
|
case V4L2_PIX_FMT_SBGGR10P:
|
||||||
|
case V4L2_PIX_FMT_SRGGB10:
|
||||||
|
case V4L2_PIX_FMT_SGRBG10:
|
||||||
|
decoded_capture = camera_configure_isp(camera, camera_capture);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case V4L2_PIX_FMT_MJPEG:
|
||||||
|
case V4L2_PIX_FMT_H264:
|
||||||
|
decoded_capture = camera_configure_decoder(camera, camera_capture);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, do we have exact match
|
||||||
|
src_capture = camera_find_capture2(camera, selected_format.height, rescalled_formats);
|
||||||
|
|
||||||
|
// Otherwise rescalle decoded output
|
||||||
|
if (!src_capture && decoded_capture) {
|
||||||
|
src_capture = camera_configure_rescaller(camera, decoded_capture, name, selected_format.height, rescalled_formats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,39 +42,22 @@ static link_callbacks_t video_callbacks =
|
|||||||
.buf_lock = &video_lock
|
.buf_lock = &video_lock
|
||||||
};
|
};
|
||||||
|
|
||||||
int camera_configure_pipeline(camera_t *camera, buffer_list_t *capture)
|
int camera_configure_pipeline(camera_t *camera, buffer_list_t *camera_capture)
|
||||||
{
|
{
|
||||||
if (capture) {
|
camera_capture->do_timestamps = true;
|
||||||
capture->do_timestamps = true;
|
|
||||||
|
|
||||||
switch (capture->fmt.format) {
|
if (camera_configure_output(camera, camera_capture, "SNAPSHOT", &camera->options.snapshot,
|
||||||
case V4L2_PIX_FMT_SRGGB10P:
|
snapshot_formats, snapshot_callbacks, &camera->codec_snapshot) < 0) {
|
||||||
case V4L2_PIX_FMT_SGRBG10P:
|
|
||||||
case V4L2_PIX_FMT_SBGGR10P:
|
|
||||||
case V4L2_PIX_FMT_SRGGB10:
|
|
||||||
case V4L2_PIX_FMT_SGRBG10:
|
|
||||||
camera_configure_isp(camera, capture);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case V4L2_PIX_FMT_MJPEG:
|
|
||||||
case V4L2_PIX_FMT_H264:
|
|
||||||
camera_configure_decoder(camera, capture);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!camera->options.snapshot.disabled && camera_configure_output(
|
|
||||||
camera, "SNAPSHOT", camera->options.snapshot.height, snapshot_formats, snapshot_callbacks, &camera->codec_snapshot) < 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!camera->options.stream.disabled && camera_configure_output(
|
if (camera_configure_output(camera, camera_capture, "STREAM", &camera->options.stream,
|
||||||
camera, "STREAM", camera->options.stream.height, snapshot_formats, stream_callbacks, &camera->codec_stream) < 0) {
|
snapshot_formats, stream_callbacks, &camera->codec_stream) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!camera->options.video.disabled && camera_configure_output(
|
if (camera_configure_output(camera, camera_capture, "VIDEO", &camera->options.video,
|
||||||
camera, "VIDEO", camera->options.video.height, video_formats, video_callbacks, &camera->codec_video) < 0) {
|
video_formats, video_callbacks, &camera->codec_video) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ static unsigned camera_rescaller_align_size(unsigned size, unsigned align_size)
|
|||||||
return (size + align_size - 1) / align_size * align_size;
|
return (size + align_size - 1) / align_size * align_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void camera_get_scaled_resolution2(unsigned in_width, unsigned in_height, unsigned proposed_height, unsigned *target_width, unsigned *target_height)
|
void camera_get_scaled_resolution2(unsigned in_width, unsigned in_height, unsigned proposed_height, unsigned *target_width, unsigned *target_height)
|
||||||
{
|
{
|
||||||
proposed_height = MIN(proposed_height, in_height);
|
proposed_height = MIN(proposed_height, in_height);
|
||||||
|
|
||||||
@ -35,19 +35,19 @@ static void camera_get_scaled_resolution2(unsigned in_width, unsigned in_height,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool camera_get_scaled_resolution(camera_t *camera, camera_output_options_t *options, buffer_format_t *format)
|
bool camera_get_scaled_resolution(buffer_format_t capture_format, camera_output_options_t *options, buffer_format_t *format)
|
||||||
{
|
{
|
||||||
if (options->disabled)
|
if (options->disabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
camera_get_scaled_resolution2(
|
camera_get_scaled_resolution2(
|
||||||
camera->options.width,
|
capture_format.width,
|
||||||
camera->options.height,
|
capture_format.height,
|
||||||
options->height,
|
options->height,
|
||||||
&format->width,
|
&format->width,
|
||||||
&format->height
|
&format->height
|
||||||
);
|
);
|
||||||
return true;
|
return format->height > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_list_t *camera_try_rescaller(camera_t *camera, buffer_list_t *src_capture, const char *name, unsigned target_height, unsigned target_format)
|
buffer_list_t *camera_try_rescaller(camera_t *camera, buffer_list_t *src_capture, const char *name, unsigned target_height, unsigned target_format)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user