mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #2755 from kwagyeman/kwabena/fix_update_jpeg_fb
Some checks are pending
🔥 Firmware Build / build-firmware (ARDUINO_GIGA) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_33_BLE_SENSE) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_RP2040_CONNECT) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NICLA_VISION) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_PORTENTA_H7) (push) Waiting to run
🔥 Firmware Build / build-firmware (DOCKER) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV2) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4P) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMVPT) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_AE3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_N6) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_RT1060) (push) Waiting to run
🔥 Firmware Build / code-size-report (push) Blocked by required conditions
🔥 Firmware Build / stable-release (push) Blocked by required conditions
🔥 Firmware Build / development-release (push) Blocked by required conditions
Some checks are pending
🔥 Firmware Build / build-firmware (ARDUINO_GIGA) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_33_BLE_SENSE) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_RP2040_CONNECT) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NICLA_VISION) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_PORTENTA_H7) (push) Waiting to run
🔥 Firmware Build / build-firmware (DOCKER) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV2) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4P) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMVPT) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_AE3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_N6) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_RT1060) (push) Waiting to run
🔥 Firmware Build / code-size-report (push) Blocked by required conditions
🔥 Firmware Build / stable-release (push) Blocked by required conditions
🔥 Firmware Build / development-release (push) Blocked by required conditions
lib/imlib: Fix update_jpeg_buffer to update from the passed image.
This commit is contained in:
commit
5f119db05f
@ -411,7 +411,9 @@ static int snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
}
|
||||
|
||||
if (flags & OMV_CSI_CAPTURE_FLAGS_UPDATE) {
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
image_t tmp;
|
||||
framebuffer_init_image(fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
}
|
||||
|
||||
if (csi->pixformat == PIXFORMAT_INVALID) {
|
||||
|
||||
@ -69,7 +69,9 @@ static int snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
}
|
||||
|
||||
if (flags & OMV_CSI_CAPTURE_FLAGS_UPDATE) {
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
image_t tmp;
|
||||
framebuffer_init_image(fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
}
|
||||
|
||||
if (fb->n_buffers != 1) {
|
||||
|
||||
@ -61,7 +61,6 @@ void framebuffer_init_fb(framebuffer_t *fb, size_t size, bool dynamic) {
|
||||
memset(fb, 0, sizeof(*fb));
|
||||
|
||||
fb->raw_size = size;
|
||||
fb->streaming_enabled = true;
|
||||
fb->dynamic = dynamic;
|
||||
framebuffer_set_buffers(fb, 1);
|
||||
}
|
||||
@ -83,7 +82,7 @@ void framebuffer_init_from_image(framebuffer_t *fb, image_t *img) {
|
||||
fb->pixfmt = img->pixfmt;
|
||||
}
|
||||
|
||||
static void jpegbuffer_init_from_image(framebuffer_t *fb, image_t *img) {
|
||||
static void jpegbuffer_init_from_image(image_t *img) {
|
||||
if (img == NULL) {
|
||||
jpegbuffer->w = 0;
|
||||
jpegbuffer->h = 0;
|
||||
@ -95,39 +94,22 @@ static void jpegbuffer_init_from_image(framebuffer_t *fb, image_t *img) {
|
||||
}
|
||||
}
|
||||
|
||||
void framebuffer_update_jpeg_buffer(framebuffer_t *fb) {
|
||||
void framebuffer_update_jpeg_buffer(image_t *src) {
|
||||
static int overflow_count = 0;
|
||||
|
||||
image_t main_fb_src;
|
||||
framebuffer_init_image(fb, &main_fb_src);
|
||||
image_t *src = &main_fb_src;
|
||||
|
||||
if (src->pixfmt != PIXFORMAT_INVALID &&
|
||||
fb->streaming_enabled && jpegbuffer->enabled) {
|
||||
if (src->pixfmt != PIXFORMAT_INVALID && jpegbuffer->enabled) {
|
||||
if (src->is_compressed) {
|
||||
bool does_not_fit = false;
|
||||
|
||||
if (mutex_try_lock_alternate(&jpegbuffer->lock, MUTEX_TID_OMV)) {
|
||||
if (OMV_JPEG_BUFFER_SIZE_MAX < src->size) {
|
||||
jpegbuffer_init_from_image(fb, NULL);
|
||||
does_not_fit = true;
|
||||
jpegbuffer_init_from_image(NULL);
|
||||
mp_printf(MP_PYTHON_PRINTER, "\x1b[40O\n");
|
||||
} else {
|
||||
jpegbuffer_init_from_image(fb, src);
|
||||
jpegbuffer_init_from_image(src);
|
||||
memcpy(jpegbuffer->pixels, src->pixels, src->size);
|
||||
}
|
||||
|
||||
mutex_unlock(&jpegbuffer->lock, MUTEX_TID_OMV);
|
||||
}
|
||||
|
||||
if (does_not_fit) {
|
||||
printf("Warning: JPEG/PNG too big! Trying framebuffer transfer using fallback method!\n");
|
||||
int new_size = framebuffer_encoded_size(fb, src);
|
||||
fb_alloc_mark();
|
||||
uint8_t *temp = fb_alloc(new_size, FB_ALLOC_NO_HINT);
|
||||
framebuffer_encode(fb, temp, src);
|
||||
(MP_PYTHON_PRINTER)->print_strn((MP_PYTHON_PRINTER)->data, (const char *) temp, new_size);
|
||||
fb_alloc_free_till_mark();
|
||||
}
|
||||
} else if (src->pixfmt != PIXFORMAT_INVALID) {
|
||||
if (mutex_try_lock_alternate(&jpegbuffer->lock, MUTEX_TID_OMV)) {
|
||||
image_t dst = {
|
||||
@ -180,7 +162,7 @@ void framebuffer_update_jpeg_buffer(framebuffer_t *fb) {
|
||||
jpegbuffer->quality = IM_MAX(1, (jpegbuffer->quality / 2));
|
||||
}
|
||||
|
||||
jpegbuffer_init_from_image(fb, NULL);
|
||||
jpegbuffer_init_from_image(NULL);
|
||||
} else {
|
||||
if (overflow_count) {
|
||||
overflow_count--;
|
||||
@ -195,7 +177,7 @@ void framebuffer_update_jpeg_buffer(framebuffer_t *fb) {
|
||||
jpegbuffer->quality++;
|
||||
}
|
||||
|
||||
jpegbuffer_init_from_image(fb, &dst);
|
||||
jpegbuffer_init_from_image(&dst);
|
||||
}
|
||||
|
||||
mutex_unlock(&jpegbuffer->lock, MUTEX_TID_OMV);
|
||||
@ -236,53 +218,6 @@ int32_t framebuffer_get_depth(framebuffer_t *fb) {
|
||||
return fb->bpp;
|
||||
}
|
||||
|
||||
void framebuffer_set_streaming(framebuffer_t *fb, bool enable) {
|
||||
fb->streaming_enabled = enable;
|
||||
}
|
||||
|
||||
bool framebuffer_get_streaming(framebuffer_t *fb) {
|
||||
return fb->streaming_enabled;
|
||||
}
|
||||
|
||||
void framebuffer_encode(framebuffer_t *fb, uint8_t *ptr, image_t *img) {
|
||||
*ptr++ = 0xFE;
|
||||
|
||||
for (int i = 0, j = (img->size / 3) * 3; i < j; i += 3) {
|
||||
int x = 0;
|
||||
x |= img->data[i + 0] << 0;
|
||||
x |= img->data[i + 1] << 8;
|
||||
x |= img->data[i + 2] << 16;
|
||||
*ptr++ = 0x80 | ((x >> 0) & 0x3F);
|
||||
*ptr++ = 0x80 | ((x >> 6) & 0x3F);
|
||||
*ptr++ = 0x80 | ((x >> 12) & 0x3F);
|
||||
*ptr++ = 0x80 | ((x >> 18) & 0x3F);
|
||||
}
|
||||
|
||||
if ((img->size % 3) == 2) {
|
||||
// 2 bytes -> 16-bits -> 24-bits sent
|
||||
int x = 0;
|
||||
x |= img->data[img->size - 2] << 0;
|
||||
x |= img->data[img->size - 1] << 8;
|
||||
*ptr++ = 0x80 | ((x >> 0) & 0x3F);
|
||||
*ptr++ = 0x80 | ((x >> 6) & 0x3F);
|
||||
*ptr++ = 0x80 | ((x >> 12) & 0x3F);
|
||||
}
|
||||
|
||||
if ((img->size % 3) == 1) {
|
||||
// 1 byte -> 8-bits -> 16-bits sent
|
||||
int x = 0;
|
||||
x |= img->data[img->size - 1] << 0;
|
||||
*ptr++ = 0x80 | ((x >> 0) & 0x3F);
|
||||
*ptr++ = 0x80 | ((x >> 6) & 0x3F);
|
||||
}
|
||||
|
||||
*ptr++ = 0xFE;
|
||||
}
|
||||
|
||||
int framebuffer_encoded_size(framebuffer_t *fb, image_t *img) {
|
||||
return (((img->size * 8) + 5) / 6) + 2;
|
||||
}
|
||||
|
||||
// Returns the current frame buffer size, factoring in the space taken by fb_alloc.
|
||||
static uint32_t framebuffer_max_buffer_size(framebuffer_t *fb) {
|
||||
uint32_t fb_total_size = FB_ALIGN_SIZE_ROUND_DOWN(fb->raw_size);
|
||||
|
||||
@ -42,7 +42,6 @@ typedef struct framebuffer {
|
||||
int32_t w, h;
|
||||
int32_t u, v;
|
||||
PIXFORMAT_STRUCT;
|
||||
int32_t streaming_enabled;
|
||||
uint32_t raw_size;
|
||||
uint32_t buff_size;
|
||||
uint32_t n_buffers;
|
||||
@ -96,14 +95,6 @@ int32_t framebuffer_get_width(framebuffer_t *fb);
|
||||
int32_t framebuffer_get_height(framebuffer_t *fb);
|
||||
int32_t framebuffer_get_depth(framebuffer_t *fb);
|
||||
|
||||
// Force fb streaming to the IDE off.
|
||||
void framebuffer_set_streaming(framebuffer_t *fb, bool enable);
|
||||
bool framebuffer_get_streaming(framebuffer_t *fb);
|
||||
|
||||
// Encode jpeg data for transmission over a text channel.
|
||||
void framebuffer_encode(framebuffer_t *fb, uint8_t *ptr, image_t *img);
|
||||
int framebuffer_encoded_size(framebuffer_t *fb, image_t *img);
|
||||
|
||||
// Return the number of bytes in the current buffer.
|
||||
uint32_t framebuffer_get_buffer_size(framebuffer_t *fb);
|
||||
|
||||
@ -121,7 +112,7 @@ void framebuffer_init_from_image(framebuffer_t *fb, image_t *img);
|
||||
|
||||
// Compress src image to the JPEG buffer if src is mutable, otherwise copy src to the JPEG buffer
|
||||
// if the src is JPEG and fits in the JPEG buffer, or encode and stream src image to the IDE if not.
|
||||
void framebuffer_update_jpeg_buffer(framebuffer_t *fb);
|
||||
void framebuffer_update_jpeg_buffer(image_t *src);
|
||||
|
||||
// Clear the framebuffer FIFO. If fifo_flush is true, reset and discard all framebuffers,
|
||||
// otherwise, retain the last frame in the fifo.
|
||||
|
||||
@ -137,7 +137,9 @@ static MP_DEFINE_CONST_FUN_OBJ_1(py_omv_csi_shutdown_obj, py_omv_csi_shutdown);
|
||||
|
||||
static mp_obj_t py_omv_csi_flush() {
|
||||
omv_csi_t *csi = omv_csi_get(-1);
|
||||
framebuffer_update_jpeg_buffer(csi->fb);
|
||||
image_t tmp;
|
||||
framebuffer_init_image(csi->fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(py_omv_csi_flush_obj, py_omv_csi_flush);
|
||||
|
||||
@ -177,8 +177,9 @@ static MP_DEFINE_CONST_FUN_OBJ_2(py_csi_sleep_obj, py_csi_sleep);
|
||||
|
||||
static mp_obj_t py_csi_flush(mp_obj_t self_in) {
|
||||
py_csi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
framebuffer_update_jpeg_buffer(self->csi->fb);
|
||||
image_t tmp;
|
||||
framebuffer_init_image(self->csi->fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(py_csi_flush_obj, py_csi_flush);
|
||||
|
||||
@ -1108,8 +1108,7 @@ mp_obj_t py_fir_snapshot(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
if (args[ARG_copy_to_fb].u_bool) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
framebuffer_update_jpeg_buffer(&dst_img);
|
||||
}
|
||||
return py_image_from_struct(&dst_img);
|
||||
}
|
||||
|
||||
@ -400,28 +400,21 @@ static mp_obj_t py_image_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
|
||||
|
||||
static void py_image_print(const mp_print_t *print, mp_obj_t self, mp_print_kind_t kind) {
|
||||
image_t *image = py_image_cobj(self);
|
||||
if (image->is_compressed
|
||||
&& image->pixels[0] == 0xFE
|
||||
&& image->pixels[image->size - 1] == 0xFE) {
|
||||
// print for ide.
|
||||
print->print_strn(print->data, (const char *) image->pixels, image->size);
|
||||
} else {
|
||||
mp_printf(print, "{\"w\":%d, \"h\":%d, \"type\":\"%s\", \"size\":%d}",
|
||||
image->w,
|
||||
image->h,
|
||||
(image->pixfmt == PIXFORMAT_BINARY) ? "binary" :
|
||||
(image->pixfmt == PIXFORMAT_GRAYSCALE) ? "grayscale" :
|
||||
(image->pixfmt == PIXFORMAT_RGB565) ? "rgb565" :
|
||||
(image->pixfmt == PIXFORMAT_BAYER_BGGR) ? "bayer_bggr" :
|
||||
(image->pixfmt == PIXFORMAT_BAYER_GBRG) ? "bayer_gbrg" :
|
||||
(image->pixfmt == PIXFORMAT_BAYER_GRBG) ? "bayer_grbg" :
|
||||
(image->pixfmt == PIXFORMAT_BAYER_RGGB) ? "bayer_rggb" :
|
||||
(image->pixfmt == PIXFORMAT_YUV422) ? "yuv422" :
|
||||
(image->pixfmt == PIXFORMAT_YVU422) ? "yvu422" :
|
||||
(image->pixfmt == PIXFORMAT_JPEG) ? "jpeg" :
|
||||
(image->pixfmt == PIXFORMAT_PNG) ? "png" : "unknown",
|
||||
image_size(image));
|
||||
}
|
||||
mp_printf(print, "{\"w\":%d, \"h\":%d, \"type\":\"%s\", \"size\":%d}",
|
||||
image->w,
|
||||
image->h,
|
||||
(image->pixfmt == PIXFORMAT_BINARY) ? "binary" :
|
||||
(image->pixfmt == PIXFORMAT_GRAYSCALE) ? "grayscale" :
|
||||
(image->pixfmt == PIXFORMAT_RGB565) ? "rgb565" :
|
||||
(image->pixfmt == PIXFORMAT_BAYER_BGGR) ? "bayer_bggr" :
|
||||
(image->pixfmt == PIXFORMAT_BAYER_GBRG) ? "bayer_gbrg" :
|
||||
(image->pixfmt == PIXFORMAT_BAYER_GRBG) ? "bayer_grbg" :
|
||||
(image->pixfmt == PIXFORMAT_BAYER_RGGB) ? "bayer_rggb" :
|
||||
(image->pixfmt == PIXFORMAT_YUV422) ? "yuv422" :
|
||||
(image->pixfmt == PIXFORMAT_YVU422) ? "yvu422" :
|
||||
(image->pixfmt == PIXFORMAT_JPEG) ? "jpeg" :
|
||||
(image->pixfmt == PIXFORMAT_PNG) ? "png" : "unknown",
|
||||
image_size(image));
|
||||
}
|
||||
|
||||
static mp_obj_t py_image_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
@ -993,8 +986,8 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_set_pixel_obj, 2, py_image_set_pixel)
|
||||
static mp_obj_t py_image_to(pixformat_t pixfmt, mp_rom_obj_t default_color_palette, bool default_copy,
|
||||
size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum {
|
||||
ARG_x_scale, ARG_y_scale, ARG_roi, ARG_channel, ARG_alpha, ARG_color_palette, ARG_alpha_palette, ARG_hint,
|
||||
ARG_copy, ARG_copy_to_fb, ARG_quality, ARG_encode_for_ide, ARG_subsampling
|
||||
ARG_x_scale, ARG_y_scale, ARG_roi, ARG_channel, ARG_alpha, ARG_color_palette, ARG_alpha_palette,
|
||||
ARG_hint, ARG_copy, ARG_copy_to_fb, ARG_quality, ARG_subsampling
|
||||
};
|
||||
const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_x_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
@ -1008,7 +1001,6 @@ static mp_obj_t py_image_to(pixformat_t pixfmt, mp_rom_obj_t default_color_palet
|
||||
{ MP_QSTR_copy, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = default_copy} },
|
||||
{ MP_QSTR_copy_to_fb, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ MP_QSTR_quality, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 90} },
|
||||
{ MP_QSTR_encode_for_ide, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ MP_QSTR_subsampling, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = JPEG_SUBSAMPLING_AUTO} },
|
||||
};
|
||||
|
||||
@ -1045,7 +1037,9 @@ static mp_obj_t py_image_to(pixformat_t pixfmt, mp_rom_obj_t default_color_palet
|
||||
|
||||
if (args[ARG_copy_to_fb].u_bool) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
image_t tmp;
|
||||
framebuffer_init_image(fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
}
|
||||
|
||||
image_t dst_img = {
|
||||
@ -1128,19 +1122,11 @@ static mp_obj_t py_image_to(pixformat_t pixfmt, mp_rom_obj_t default_color_palet
|
||||
|| ((dst_img.pixfmt == PIXFORMAT_PNG) && png_compress(&temp, &dst_img_tmp))) {
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Compression Failed!"));
|
||||
}
|
||||
} else if (args[ARG_encode_for_ide].u_bool) {
|
||||
dst_img_tmp.data = fb_alloc(image_size(&dst_img_tmp), FB_ALLOC_NO_HINT);
|
||||
memcpy(dst_img_tmp.data, src_img->data, dst_img_tmp.size);
|
||||
} else {
|
||||
dst_img_tmp.data = src_img->data;
|
||||
}
|
||||
|
||||
if (args[ARG_encode_for_ide].u_bool) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
dst_img.size = framebuffer_encoded_size(fb, &dst_img_tmp);
|
||||
} else {
|
||||
dst_img.size = dst_img_tmp.size;
|
||||
}
|
||||
dst_img.size = dst_img_tmp.size;
|
||||
}
|
||||
|
||||
uint32_t size = image_size(&dst_img);
|
||||
@ -1161,10 +1147,7 @@ static mp_obj_t py_image_to(pixformat_t pixfmt, mp_rom_obj_t default_color_palet
|
||||
}
|
||||
|
||||
if (dst_img.is_compressed) {
|
||||
if (args[ARG_encode_for_ide].u_bool) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
framebuffer_encode(fb, dst_img.data, &dst_img_tmp);
|
||||
} else if (dst_img.data != dst_img_tmp.data) {
|
||||
if (dst_img.data != dst_img_tmp.data) {
|
||||
memcpy(dst_img.data, dst_img_tmp.data, dst_img.size);
|
||||
}
|
||||
fb_alloc_free_till_mark();
|
||||
@ -1268,8 +1251,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_save_obj, 2, py_image_save);
|
||||
#endif //IMLIB_ENABLE_IMAGE_FILE_IO
|
||||
|
||||
static mp_obj_t py_image_flush(mp_obj_t img_obj) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
framebuffer_update_jpeg_buffer(py_image_cobj(img_obj));
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(py_image_flush_obj, py_image_flush);
|
||||
@ -6235,8 +6217,7 @@ mp_obj_t py_image_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw
|
||||
}
|
||||
|
||||
if (args[ARG_copy_to_fb].u_bool) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
framebuffer_update_jpeg_buffer(&image);
|
||||
}
|
||||
return py_image_from_struct(&image);
|
||||
}
|
||||
|
||||
@ -415,8 +415,7 @@ static mp_obj_t py_imageio_read(size_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
py_helper_update_framebuffer(&image);
|
||||
|
||||
if (args[ARG_copy_to_fb].u_bool) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
framebuffer_update_jpeg_buffer(&image);
|
||||
}
|
||||
return py_image_from_struct(&image);
|
||||
}
|
||||
|
||||
@ -76,17 +76,6 @@ static mp_obj_t py_omv_debug_mode() {
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(py_omv_debug_mode_obj, py_omv_debug_mode);
|
||||
|
||||
static mp_obj_t py_omv_disable_fb(size_t n_args, const mp_obj_t *args) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
|
||||
if (!n_args) {
|
||||
return mp_obj_new_bool(!framebuffer_get_streaming(fb));
|
||||
}
|
||||
framebuffer_set_streaming(fb, !mp_obj_get_int(args[0]));
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_omv_disable_fb_obj, 0, 1, py_omv_disable_fb);
|
||||
|
||||
static const mp_rom_map_elem_t globals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_omv) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_version_major), MP_ROM_INT(FIRMWARE_VERSION_MAJOR) },
|
||||
@ -96,8 +85,7 @@ static const mp_rom_map_elem_t globals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_arch), MP_ROM_PTR(&py_omv_arch_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_board_type), MP_ROM_PTR(&py_omv_board_type_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_board_id), MP_ROM_PTR(&py_omv_board_id_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_debug_mode), MP_ROM_PTR(&py_omv_debug_mode_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_disable_fb), MP_ROM_PTR(&py_omv_disable_fb_obj) }
|
||||
{ MP_ROM_QSTR(MP_QSTR_debug_mode), MP_ROM_PTR(&py_omv_debug_mode_obj) }
|
||||
};
|
||||
|
||||
static MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
|
||||
|
||||
@ -589,8 +589,7 @@ mp_obj_t py_tof_snapshot(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
if (args[ARG_copy_to_fb].u_bool) {
|
||||
framebuffer_t *fb = framebuffer_get(0);
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
framebuffer_update_jpeg_buffer(&dst_img);
|
||||
}
|
||||
return py_image_from_struct(&dst_img);
|
||||
}
|
||||
|
||||
@ -240,7 +240,11 @@ int alif_csi_snapshot(omv_csi_t *csi, image_t *dst_image, uint32_t flags) {
|
||||
}
|
||||
|
||||
// Compress the framebuffer for the IDE preview.
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
if (flags & OMV_CSI_CAPTURE_FLAGS_UPDATE) {
|
||||
image_t tmp;
|
||||
framebuffer_init_image(fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
}
|
||||
|
||||
// Free the current FB head.
|
||||
framebuffer_free_current_buffer(fb);
|
||||
|
||||
@ -351,7 +351,11 @@ int imx_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
}
|
||||
|
||||
// Compress the framebuffer for the IDE preview.
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
if (flags & OMV_CSI_CAPTURE_FLAGS_UPDATE) {
|
||||
image_t tmp;
|
||||
framebuffer_init_image(fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
}
|
||||
|
||||
// Free the current FB head.
|
||||
framebuffer_free_current_buffer(fb);
|
||||
|
||||
@ -125,7 +125,11 @@ static int nrf_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
// Compress the framebuffer for the IDE preview, only if it's not the first frame,
|
||||
// the framebuffer is enabled and the image sensor does not support JPEG encoding.
|
||||
// Note: This doesn't run unless the IDE is connected and the framebuffer is enabled.
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
if (flags & OMV_CSI_CAPTURE_FLAGS_UPDATE) {
|
||||
image_t tmp;
|
||||
framebuffer_init_image(fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
}
|
||||
|
||||
// This driver supports a single buffer.
|
||||
if (fb->n_buffers != 1) {
|
||||
|
||||
@ -156,7 +156,11 @@ static int rp2_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
framebuffer_t *fb = csi->fb;
|
||||
|
||||
// Compress the framebuffer for the IDE preview.
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
if (flags & OMV_CSI_CAPTURE_FLAGS_UPDATE) {
|
||||
image_t tmp;
|
||||
framebuffer_init_image(fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
}
|
||||
|
||||
if (omv_csi_check_framebuffer_size(csi) != 0) {
|
||||
return OMV_CSI_ERROR_FRAMEBUFFER_OVERFLOW;
|
||||
|
||||
@ -554,7 +554,9 @@ static int stm_csi_snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
// Compress the framebuffer for the IDE preview, if not the first frame, the
|
||||
// framebuffer is enabled, and the image sensor doesn't support JPEG encoding.
|
||||
if (flags & OMV_CSI_CAPTURE_FLAGS_UPDATE) {
|
||||
framebuffer_update_jpeg_buffer(fb);
|
||||
image_t tmp;
|
||||
framebuffer_init_image(fb, &tmp);
|
||||
framebuffer_update_jpeg_buffer(&tmp);
|
||||
}
|
||||
|
||||
// Ensure that the raw frame fits into the FB. It will be switched from RGB565 to BAYER
|
||||
|
||||
@ -1,101 +0,0 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2023 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# Image Transfer - As The Remote Device
|
||||
#
|
||||
# This script is meant to talk to the "image_transfer_jpg_as_the_controller_device.py" on your computer.
|
||||
#
|
||||
# This script shows off how to transfer the frame buffer to your computer as a jpeg image.
|
||||
|
||||
import omv
|
||||
import rpc
|
||||
import sensor
|
||||
import struct
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
sensor.set_framesize(sensor.QVGA)
|
||||
sensor.skip_frames(time=2000)
|
||||
|
||||
# Turn off the frame buffer connection to the IDE from the OpenMV Cam side.
|
||||
#
|
||||
# This needs to be done when manually compressing jpeg images at higher quality
|
||||
# so that the OpenMV Cam does not try to stream them to the IDE using a fall back
|
||||
# mechanism if the JPEG image is too large to fit in the IDE JPEG frame buffer on the OpenMV Cam.
|
||||
|
||||
omv.disable_fb(True)
|
||||
|
||||
# The RPC library above is installed on your OpenMV Cam and provides multiple classes for
|
||||
# allowing your OpenMV Cam to be controlled over USB or LAN/WLAN.
|
||||
|
||||
################################################################
|
||||
# Choose the interface you wish to control your OpenMV Cam over.
|
||||
################################################################
|
||||
|
||||
# Uncomment the below line to setup your OpenMV Cam for control over a USB VCP.
|
||||
#
|
||||
interface = rpc.rpc_usb_vcp_slave()
|
||||
|
||||
# Uncomment the below line to setup your OpenMV Cam for control over the lan.
|
||||
# import network
|
||||
#
|
||||
# network_if = network.LAN()
|
||||
# network_if.active(True)
|
||||
# network_if.ifconfig('dhcp')
|
||||
#
|
||||
# interface = rpc.rpc_network_slave(network_if)
|
||||
|
||||
# Uncomment the below line to setup your OpenMV Cam for control over the wlan.
|
||||
#
|
||||
# import network
|
||||
# network_if = network.WLAN(network.STA_IF)
|
||||
# network_if.active(True)
|
||||
# network_if.connect('your-ssid', 'your-password')
|
||||
#
|
||||
# interface = rpc.rpc_network_slave(network_if)
|
||||
|
||||
################################################################
|
||||
# Call Backs
|
||||
################################################################
|
||||
|
||||
|
||||
# When called sets the pixformat and framesize, takes a snapshot
|
||||
# and then returns the frame buffer jpg size to store the image in.
|
||||
#
|
||||
# data is a pixformat string and framesize string.
|
||||
def jpeg_image_snapshot(data):
|
||||
pixformat, framesize = bytes(data).decode().split(",")
|
||||
sensor.set_pixformat(eval(pixformat))
|
||||
sensor.set_framesize(eval(framesize))
|
||||
img = sensor.snapshot()
|
||||
img.to_jpeg(quality=90)
|
||||
return struct.pack("<I", img.size())
|
||||
|
||||
|
||||
def jpeg_image_read_cb():
|
||||
interface.put_bytes(sensor.get_fb().bytearray(), 5000) # timeout
|
||||
|
||||
|
||||
# Read data from the frame buffer given a offset and size.
|
||||
# If data is empty then a transfer is scheduled after the RPC call finishes.
|
||||
#
|
||||
# data is a 4 byte size and 4 byte offset.
|
||||
def jpeg_image_read(data):
|
||||
if not len(data):
|
||||
interface.schedule_callback(jpeg_image_read_cb)
|
||||
return bytes()
|
||||
else:
|
||||
offset, size = struct.unpack("<II", data)
|
||||
return memoryview(sensor.get_fb().bytearray())[offset : offset + size]
|
||||
|
||||
|
||||
# Register call backs.
|
||||
|
||||
interface.register_callback(jpeg_image_snapshot)
|
||||
interface.register_callback(jpeg_image_read)
|
||||
|
||||
# Once all call backs have been registered we can start
|
||||
# processing remote events. interface.loop() does not return.
|
||||
|
||||
interface.loop()
|
||||
@ -1,93 +0,0 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2023 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# Image Transfer - As The Remote Device
|
||||
#
|
||||
# This script is meant to talk to the "image_transfer_jpg_streaming_as_the_controller_device.py" on your computer.
|
||||
#
|
||||
# This script shows off how to transfer the frame buffer to your computer as a jpeg image.
|
||||
|
||||
import omv
|
||||
import rpc
|
||||
import sensor
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
sensor.set_framesize(sensor.QVGA)
|
||||
sensor.skip_frames(time=2000)
|
||||
|
||||
# Turn off the frame buffer connection to the IDE from the OpenMV Cam side.
|
||||
#
|
||||
# This needs to be done when manually compressing jpeg images at higher quality
|
||||
# so that the OpenMV Cam does not try to stream them to the IDE using a fall back
|
||||
# mechanism if the JPEG image is too large to fit in the IDE JPEG frame buffer on the OpenMV Cam.
|
||||
|
||||
omv.disable_fb(True)
|
||||
|
||||
# The RPC library above is installed on your OpenMV Cam and provides multiple classes for
|
||||
# allowing your OpenMV Cam to be controlled over USB or LAN/WLAN.
|
||||
|
||||
################################################################
|
||||
# Choose the interface you wish to control your OpenMV Cam over.
|
||||
################################################################
|
||||
|
||||
# Uncomment the below line to setup your OpenMV Cam for control over a USB VCP.
|
||||
#
|
||||
interface = rpc.rpc_usb_vcp_slave()
|
||||
|
||||
# Uncomment the below line to setup your OpenMV Cam for control over the lan.
|
||||
#
|
||||
# import network
|
||||
# network_if = network.LAN()
|
||||
# network_if.active(True)
|
||||
# network_if.ifconfig('dhcp')
|
||||
#
|
||||
# interface = rpc.rpc_network_slave(network_if)
|
||||
|
||||
# Uncomment the below line to setup your OpenMV Cam for control over the wlan.
|
||||
#
|
||||
# import network
|
||||
# network_if = network.WLAN(network.STA_IF)
|
||||
# network_if.active(True)
|
||||
# network_if.connect('your-ssid', 'your-password')
|
||||
#
|
||||
# interface = rpc.rpc_network_slave(network_if)
|
||||
|
||||
################################################################
|
||||
# Call Backs
|
||||
################################################################
|
||||
|
||||
|
||||
# This is called repeatedly by interface.stream_writer().
|
||||
def stream_generator_cb():
|
||||
img = sensor.snapshot()
|
||||
img.to_jpeg(quality=90)
|
||||
return img.bytearray()
|
||||
|
||||
|
||||
# Transmits a stream of bytes()'s generated by stream_generator_cb to the master device.
|
||||
def jpeg_image_stream_cb():
|
||||
interface.stream_writer(stream_generator_cb)
|
||||
|
||||
|
||||
# When called sets the pixformat and framesize, and then schedules
|
||||
# frame streaming to start after the RPC call finishes.
|
||||
#
|
||||
# data is a pixformat string and framesize string.
|
||||
def jpeg_image_stream(data):
|
||||
pixformat, framesize = bytes(data).decode().split(",")
|
||||
sensor.set_pixformat(eval(pixformat))
|
||||
sensor.set_framesize(eval(framesize))
|
||||
interface.schedule_callback(jpeg_image_stream_cb)
|
||||
return bytes()
|
||||
|
||||
|
||||
# Register call backs.
|
||||
|
||||
interface.register_callback(jpeg_image_stream)
|
||||
|
||||
# Once all call backs have been registered we can start
|
||||
# processing remote events. interface.loop() does not return.
|
||||
|
||||
interface.loop()
|
||||
@ -11,9 +11,8 @@
|
||||
# you can use by going to Tools->Video Tools->Play RSTP Stream.
|
||||
|
||||
import network
|
||||
import omv
|
||||
import rtsp
|
||||
import sensor
|
||||
import csi
|
||||
import time
|
||||
|
||||
# If you are using VLC on linux you may need to install the live555 library for RTSP support to
|
||||
@ -26,18 +25,10 @@ import time
|
||||
# "show more options" when you open the network stream in VLC. You can reduce this to like 10ms
|
||||
# to make the video real-time.
|
||||
|
||||
sensor.reset()
|
||||
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
sensor.set_framesize(sensor.VGA)
|
||||
|
||||
# Turn off the frame buffer connection to the IDE from the OpenMV Cam side.
|
||||
#
|
||||
# This needs to be done when manually compressing jpeg images at higher quality
|
||||
# so that the OpenMV Cam does not try to stream them to the IDE using a fall back
|
||||
# mechanism if the JPEG image is too large to fit in the IDE JPEG frame buffer on the OpenMV Cam.
|
||||
|
||||
omv.disable_fb(True)
|
||||
csi0 = csi.CSI()
|
||||
csi0.reset()
|
||||
csi0.pixformat(csi.RGB565)
|
||||
csi0.framesize(csi.VGA)
|
||||
|
||||
# Setup Network Interface
|
||||
|
||||
@ -67,6 +58,7 @@ def setup_callback(pathname, session):
|
||||
|
||||
|
||||
def play_callback(pathname, session):
|
||||
global clock
|
||||
clock.reset()
|
||||
clock.tick()
|
||||
print('Playing "%s" in session %d' % (pathname, session))
|
||||
@ -88,7 +80,9 @@ server.register_teardown_cb(teardown_callback)
|
||||
|
||||
# Called each time a new frame is needed.
|
||||
def image_callback(pathname, session):
|
||||
img = sensor.snapshot()
|
||||
global csi0
|
||||
global clock
|
||||
img = csi0.snapshot(update=False)
|
||||
# Markup image and/or do various things.
|
||||
print(clock.fps())
|
||||
clock.tick()
|
||||
|
||||
@ -11,9 +11,8 @@
|
||||
# you can use by going to Tools->Video Tools->Play RSTP Stream.
|
||||
|
||||
import network
|
||||
import omv
|
||||
import rtsp
|
||||
import sensor
|
||||
import csi
|
||||
import time
|
||||
|
||||
# If you are using VLC on linux you may need to install the live555 library for RTSP support to
|
||||
@ -26,18 +25,10 @@ import time
|
||||
# "show more options" when you open the network stream in VLC. You can reduce this to like 10ms
|
||||
# to make the video real-time.
|
||||
|
||||
sensor.reset()
|
||||
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
sensor.set_framesize(sensor.VGA)
|
||||
|
||||
# Turn off the frame buffer connection to the IDE from the OpenMV Cam side.
|
||||
#
|
||||
# This needs to be done when manually compressing jpeg images at higher quality
|
||||
# so that the OpenMV Cam does not try to stream them to the IDE using a fall back
|
||||
# mechanism if the JPEG image is too large to fit in the IDE JPEG frame buffer on the OpenMV Cam.
|
||||
|
||||
omv.disable_fb(True)
|
||||
csi0 = csi.CSI()
|
||||
csi0.reset()
|
||||
csi0.pixformat(csi.RGB565)
|
||||
csi0.framesize(csi.VGA)
|
||||
|
||||
# Setup Network Interface
|
||||
|
||||
@ -70,6 +61,7 @@ def setup_callback(pathname, session):
|
||||
|
||||
|
||||
def play_callback(pathname, session):
|
||||
global clock
|
||||
clock.reset()
|
||||
clock.tick()
|
||||
print('Playing "%s" in session %d' % (pathname, session))
|
||||
@ -91,7 +83,9 @@ server.register_teardown_cb(teardown_callback)
|
||||
|
||||
# Called each time a new frame is needed.
|
||||
def image_callback(pathname, session):
|
||||
img = sensor.snapshot()
|
||||
global csi0
|
||||
global clock
|
||||
img = csi0.snapshot(update=False)
|
||||
# Markup image and/or do various things.
|
||||
print(clock.fps())
|
||||
clock.tick()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user