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_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[]);
|
||||
int camera_configure_output(camera_t *camera, const char *name, unsigned target_height, 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);
|
||||
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(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;
|
||||
|
||||
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)
|
||||
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)
|
||||
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);
|
||||
if (!camera_capture) {
|
||||
|
@ -74,20 +74,58 @@ static unsigned rescalled_formats[] =
|
||||
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) {
|
||||
camera_capture_add_callbacks(camera, src_capture, callbacks);
|
||||
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) {
|
||||
// Try to find re-scallabe output
|
||||
src_capture = camera_find_capture2(camera, 0, rescalled_formats);
|
||||
if (src_capture) {
|
||||
src_capture = camera_configure_rescaller(camera, src_capture, name, target_height, rescalled_formats);
|
||||
buffer_list_t *other_capture = camera_find_capture2(camera, 0, rescalled_formats);
|
||||
|
||||
if (other_capture) {
|
||||
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
|
||||
};
|
||||
|
||||
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) {
|
||||
capture->do_timestamps = true;
|
||||
camera_capture->do_timestamps = true;
|
||||
|
||||
switch (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:
|
||||
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) {
|
||||
if (camera_configure_output(camera, camera_capture, "SNAPSHOT", &camera->options.snapshot,
|
||||
snapshot_formats, snapshot_callbacks, &camera->codec_snapshot) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!camera->options.stream.disabled && camera_configure_output(
|
||||
camera, "STREAM", camera->options.stream.height, snapshot_formats, stream_callbacks, &camera->codec_stream) < 0) {
|
||||
if (camera_configure_output(camera, camera_capture, "STREAM", &camera->options.stream,
|
||||
snapshot_formats, stream_callbacks, &camera->codec_stream) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!camera->options.video.disabled && camera_configure_output(
|
||||
camera, "VIDEO", camera->options.video.height, video_formats, video_callbacks, &camera->codec_video) < 0) {
|
||||
if (camera_configure_output(camera, camera_capture, "VIDEO", &camera->options.video,
|
||||
video_formats, video_callbacks, &camera->codec_video) < 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -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)
|
||||
return false;
|
||||
|
||||
camera_get_scaled_resolution2(
|
||||
camera->options.width,
|
||||
camera->options.height,
|
||||
capture_format.width,
|
||||
capture_format.height,
|
||||
options->height,
|
||||
&format->width,
|
||||
&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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user