mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Refactor framebuffer
Moved structs along with image copying code from sensor into framebuffer.c so that we can use the new copy_fb_to_jpeg_fb() function in the image library for methods with "copy_to_fb" so that they update the IDE preview when called. Also, I noticed that the MAIN_FB_SIZE() value is not calculated correctly in all cases. Will fix later. Trying to keep this commit clean for just the refactoring. All changes have been tested. Too.
This commit is contained in:
parent
c8d7a4188f
commit
f9e124f8cd
@ -123,6 +123,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \
|
||||
fb_alloc.o \
|
||||
umm_malloc.o \
|
||||
ff_wrapper.o \
|
||||
framebuffer.o \
|
||||
array.o \
|
||||
usbdbg.o \
|
||||
sccb.o \
|
||||
|
||||
@ -5,6 +5,7 @@ SRCS += $(addprefix , \
|
||||
fb_alloc.c \
|
||||
umm_malloc.c \
|
||||
ff_wrapper.c \
|
||||
framebuffer.c \
|
||||
array.c \
|
||||
usbdbg.c \
|
||||
sccb.c \
|
||||
|
||||
75
src/omv/framebuffer.c
Normal file
75
src/omv/framebuffer.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Framebuffer stuff.
|
||||
*
|
||||
*/
|
||||
#include "imlib.h"
|
||||
#include "omv_boardconfig.h"
|
||||
#include "framebuffer.h"
|
||||
// If buffer size is bigger than this threshold, the quality is reduced.
|
||||
// This is only used for JPEG images sent to the IDE not normal compression.
|
||||
#define JPEG_QUALITY_THRESH (160*120*2)
|
||||
|
||||
extern char _fb_base;
|
||||
framebuffer_t *fb = (framebuffer_t *) &_fb_base;
|
||||
|
||||
extern char _jpeg_buf;
|
||||
jpegbuffer_t *jpeg_fb = (jpegbuffer_t *) &_jpeg_buf;
|
||||
|
||||
void copy_fb_to_jpeg_fb()
|
||||
{
|
||||
static int overflow_count = 0;
|
||||
|
||||
if ((fb->bpp > 3) && JPEG_FB()->enabled) {
|
||||
// Lock FB
|
||||
if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_OMV)) {
|
||||
if(OMV_JPEG_BUF_SIZE < fb->bpp) {
|
||||
// image won't fit. so don't copy.
|
||||
JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0;
|
||||
} else {
|
||||
memcpy(JPEG_FB()->pixels, fb->pixels, fb->bpp);
|
||||
JPEG_FB()->w = fb->w; JPEG_FB()->h = fb->h; JPEG_FB()->size = fb->bpp;
|
||||
}
|
||||
|
||||
// Unlock the framebuffer mutex
|
||||
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_OMV);
|
||||
}
|
||||
} else if ((fb->bpp > 0) && JPEG_FB()->enabled) {
|
||||
// Lock FB
|
||||
if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_OMV)) {
|
||||
// Set JPEG src and dst images.
|
||||
image_t src = {.w=fb->w, .h=fb->h, .bpp=fb->bpp, .pixels=fb->pixels};
|
||||
image_t dst = {.w=fb->w, .h=fb->h, .bpp=OMV_JPEG_BUF_SIZE, .pixels=JPEG_FB()->pixels};
|
||||
|
||||
// Note: lower quality saves USB bandwidth and results in a faster IDE FPS.
|
||||
bool overflow = jpeg_compress(&src, &dst, JPEG_FB()->quality, false);
|
||||
if (overflow == true) {
|
||||
// JPEG buffer overflowed, reduce JPEG quality for the next frame
|
||||
// and skip the current frame. The IDE doesn't receive this frame.
|
||||
if (JPEG_FB()->quality > 1) {
|
||||
// Keep this quality for the next n frames
|
||||
overflow_count = 60;
|
||||
JPEG_FB()->quality = IM_MAX(1, (JPEG_FB()->quality/2));
|
||||
}
|
||||
JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0;
|
||||
} else {
|
||||
if (overflow_count) {
|
||||
overflow_count--;
|
||||
}
|
||||
// No buffer overflow, increase quality up to max quality based on frame size
|
||||
if (overflow_count == 0 &&
|
||||
JPEG_FB()->quality < ((MAIN_FB_SIZE() > JPEG_QUALITY_THRESH) ? 35:60)) {
|
||||
JPEG_FB()->quality++;
|
||||
}
|
||||
// Set FB from JPEG image
|
||||
JPEG_FB()->w = dst.w; JPEG_FB()->h = dst.h; JPEG_FB()->size = dst.bpp;
|
||||
}
|
||||
|
||||
// Unlock the framebuffer mutex
|
||||
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_OMV);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,30 +3,32 @@
|
||||
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* Framebuffer pointer.
|
||||
* Framebuffer stuff.
|
||||
*
|
||||
*/
|
||||
#ifndef __FRAMEBUFFER_H__
|
||||
#define __FRAMEBUFFER_H__
|
||||
#include <stdint.h>
|
||||
#include "mutex.h"
|
||||
extern char _fb_base;
|
||||
static struct framebuffer {
|
||||
|
||||
typedef struct framebuffer {
|
||||
int w,h;
|
||||
int bpp;
|
||||
uint8_t pixels[];
|
||||
// Note all instances of fb point to the same memory address.
|
||||
}*__attribute__ ((__unused__)) fb = (struct framebuffer *) &_fb_base;
|
||||
} framebuffer_t;
|
||||
|
||||
extern char _jpeg_buf;
|
||||
static struct jpegbuffer {
|
||||
extern framebuffer_t *fb;
|
||||
|
||||
typedef struct jpegbuffer {
|
||||
int w,h;
|
||||
int size;
|
||||
int enabled;
|
||||
int quality;
|
||||
mutex_t lock;
|
||||
uint8_t pixels[];
|
||||
// Note all instances of jepg_fb point to the same memory address.
|
||||
}*__attribute__ ((__unused__)) jpeg_fb = (struct jpegbuffer *) &_jpeg_buf;
|
||||
} jpegbuffer_t;
|
||||
|
||||
extern jpegbuffer_t *jpeg_fb;
|
||||
|
||||
// Use these macros to get a pointer to main or JPEG framebuffer.
|
||||
#define MAIN_FB() (fb)
|
||||
@ -36,4 +38,8 @@ static struct jpegbuffer {
|
||||
|
||||
// Use this macro to get a pointer to the free SRAM area located after the framebuffer.
|
||||
#define FB_PIXELS() (MAIN_FB()->pixels+MAIN_FB_SIZE())
|
||||
|
||||
// Transfers the frame buffer to the jpeg frame buffer if not locked.
|
||||
void copy_fb_to_jpeg_fb();
|
||||
|
||||
#endif /* __FRAMEBUFFER_H__ */
|
||||
|
||||
@ -26,9 +26,6 @@
|
||||
#define REG_MIDL 0x1D
|
||||
|
||||
#define MAX_XFER_SIZE (0xFFFC)
|
||||
// If buffer size is bigger than this threshold, the quality is reduced.
|
||||
// This is only used for JPEG images sent to the IDE not normal compression.
|
||||
#define JPEG_QUALITY_THRESH (160*120*2)
|
||||
|
||||
sensor_t sensor;
|
||||
TIM_HandleTypeDef TIMHandle;
|
||||
@ -699,7 +696,6 @@ static void sensor_check_bufsize()
|
||||
// overwrite image pixels before they are compressed.
|
||||
int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_filter_args)
|
||||
{
|
||||
static int overflow_count = 0;
|
||||
uint32_t addr, length, tick_start;
|
||||
|
||||
// Set line filter
|
||||
@ -712,55 +708,7 @@ int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_f
|
||||
// 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.
|
||||
if ((fb->bpp > 3) && JPEG_FB()->enabled && sensor.pixformat != PIXFORMAT_JPEG) {
|
||||
// Lock FB
|
||||
if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_OMV)) {
|
||||
if(OMV_JPEG_BUF_SIZE < fb->bpp) {
|
||||
// image won't fit. so don't copy.
|
||||
JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0;
|
||||
} else {
|
||||
memcpy(JPEG_FB()->pixels, fb->pixels, fb->bpp);
|
||||
JPEG_FB()->w = fb->w; JPEG_FB()->h = fb->h; JPEG_FB()->size = fb->bpp;
|
||||
}
|
||||
|
||||
// Unlock the framebuffer mutex
|
||||
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_OMV);
|
||||
}
|
||||
} else if ((fb->bpp > 0) && JPEG_FB()->enabled && sensor.pixformat != PIXFORMAT_JPEG) {
|
||||
// Lock FB
|
||||
if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_OMV)) {
|
||||
// Set JPEG src and dst images.
|
||||
image_t src = {.w=fb->w, .h=fb->h, .bpp=fb->bpp, .pixels=fb->pixels};
|
||||
image_t dst = {.w=fb->w, .h=fb->h, .bpp=OMV_JPEG_BUF_SIZE, .pixels=JPEG_FB()->pixels};
|
||||
|
||||
// Note: lower quality saves USB bandwidth and results in a faster IDE FPS.
|
||||
bool overflow = jpeg_compress(&src, &dst, JPEG_FB()->quality, false);
|
||||
if (overflow == true) {
|
||||
// JPEG buffer overflowed, reduce JPEG quality for the next frame
|
||||
// and skip the current frame. The IDE doesn't receive this frame.
|
||||
if (JPEG_FB()->quality > 1) {
|
||||
// Keep this quality for the next n frames
|
||||
overflow_count = 60;
|
||||
JPEG_FB()->quality = IM_MAX(1, (JPEG_FB()->quality/2));
|
||||
}
|
||||
JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0;
|
||||
} else {
|
||||
if (overflow_count) {
|
||||
overflow_count--;
|
||||
}
|
||||
// No buffer overflow, increase quality up to max quality based on frame size
|
||||
if (overflow_count == 0 &&
|
||||
JPEG_FB()->quality < ((MAIN_FB_SIZE() > JPEG_QUALITY_THRESH) ? 35:60)) {
|
||||
JPEG_FB()->quality++;
|
||||
}
|
||||
// Set FB from JPEG image
|
||||
JPEG_FB()->w = dst.w; JPEG_FB()->h = dst.h; JPEG_FB()->size = dst.bpp;
|
||||
}
|
||||
|
||||
// Unlock the framebuffer mutex
|
||||
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_OMV);
|
||||
}
|
||||
}
|
||||
if (sensor.pixformat != PIXFORMAT_JPEG) copy_fb_to_jpeg_fb();
|
||||
|
||||
// Setup the size and address of the transfer
|
||||
switch (sensor.pixformat) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user