mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Remove the JPEG offset buffer.
* Set the address of the DMA transfer to addr + offset to allow JPEG Compression of the framebuffer without overwriting image pixels. * This saves 1KBs of stack and conditionals in jpeg_put_bytes/char.
This commit is contained in:
parent
544dee93ae
commit
d76fa2b558
@ -19,4 +19,13 @@ static struct framebuffer {
|
||||
uint8_t pixels[];
|
||||
// Note all instances of fb point to the same memory address.
|
||||
}*fb = (struct framebuffer *) &_fb_base;
|
||||
|
||||
// The JPEG offset allows JPEG compression of the framebuffer without overwriting the pixels.
|
||||
// The offset size may need to be adjusted depending on the quality, otherwise JPEG data may
|
||||
// overwrite image pixels before they are compressed (see framebuffer.h)
|
||||
#define FB_JPEG_OFFS_SIZE (1024)
|
||||
|
||||
// Use this macro to get a pointer to the free SRAM area located after the framebuffer.
|
||||
// If JPEG is enabled, this macro returns (framebuffer->pixels + fb_width * fb_height).
|
||||
#define FB_PIXELS() ((fb->bpp > 2)? (fb->pixels+fb->w*fb->h) : (fb->pixels+fb->w*fb->h+FB_JPEG_OFFS_SIZE))
|
||||
#endif /* __FRAMEBUFFER_H__ */
|
||||
|
||||
@ -17,7 +17,7 @@ void imlib_integral_image_alloc(struct integral_image *i_img, int w, int h)
|
||||
{
|
||||
i_img->w = w;
|
||||
i_img->h = h;
|
||||
i_img->data = (uint32_t*) (fb->pixels+(fb->w * fb->h));
|
||||
i_img->data = (uint32_t*) FB_PIXELS();
|
||||
}
|
||||
|
||||
void imlib_integral_image(struct image *src, struct integral_image *sum)
|
||||
|
||||
@ -24,16 +24,8 @@ typedef struct {
|
||||
int idx;
|
||||
int length;
|
||||
uint8_t *buf;
|
||||
// The offset buffer allows JPEG compression in place (src and dst pointers passed to jpeg_compress() can be the same).
|
||||
// JPEG headers and data are written to this buffer until enough image pixels has been read and compressed. The offset
|
||||
// buffer is then swapped with the destination buffer.
|
||||
uint8_t *offs_buf;
|
||||
} jpeg_buf_t;
|
||||
|
||||
// Note: The offset buffer size may need to be adjusted depending on the quality, otherwise JPEG data may
|
||||
// overwrite the image before compression. However, note that the offset buffer is allocated on the stack.
|
||||
#define OFFS_BUF_SIZE (1024)
|
||||
|
||||
// Quantization tables
|
||||
static float fdtbl_Y[64], fdtbl_UV[64];
|
||||
static uint8_t YTable[64], UVTable[64];
|
||||
@ -185,12 +177,6 @@ static void jpeg_put_char(jpeg_buf_t *jpeg_buf, char c)
|
||||
jpeg_buf->buf = xrealloc(jpeg_buf->buf, jpeg_buf->length);
|
||||
}
|
||||
|
||||
if (jpeg_buf->idx == OFFS_BUF_SIZE) {
|
||||
// exausted the offset buffer
|
||||
memcpy(jpeg_buf->offs_buf, jpeg_buf->buf, OFFS_BUF_SIZE);
|
||||
jpeg_buf->buf = jpeg_buf->offs_buf;
|
||||
}
|
||||
|
||||
jpeg_buf->buf[jpeg_buf->idx++]=c;
|
||||
}
|
||||
|
||||
@ -201,13 +187,6 @@ static void jpeg_put_bytes(jpeg_buf_t *jpeg_buf, const void *data, int size)
|
||||
jpeg_buf->buf = xrealloc(jpeg_buf->buf, jpeg_buf->length);
|
||||
}
|
||||
|
||||
if (jpeg_buf->idx+size >= OFFS_BUF_SIZE
|
||||
&& jpeg_buf->buf != jpeg_buf->offs_buf) {
|
||||
// Exhausted the offset buffer
|
||||
memcpy(jpeg_buf->offs_buf, jpeg_buf->buf, OFFS_BUF_SIZE);
|
||||
jpeg_buf->buf = jpeg_buf->offs_buf;
|
||||
}
|
||||
|
||||
memcpy(jpeg_buf->buf+jpeg_buf->idx, data, size);
|
||||
jpeg_buf->idx += size;
|
||||
}
|
||||
@ -446,8 +425,6 @@ void jpeg_write_headers(jpeg_buf_t *jpeg_buf, int width, int height)
|
||||
|
||||
void jpeg_compress(image_t *src, image_t *dst, int quality)
|
||||
{
|
||||
uint8_t offs_buf[1024];
|
||||
|
||||
int bitBuf=0, bitCnt=0;
|
||||
int DCY=0, DCU=0, DCV=0;
|
||||
int YDU[64], UDU[64], VDU[64];
|
||||
@ -455,8 +432,7 @@ void jpeg_compress(image_t *src, image_t *dst, int quality)
|
||||
// JPEG buffer
|
||||
jpeg_buf_t jpeg_buf = {
|
||||
.idx =0,
|
||||
.buf = offs_buf,
|
||||
.offs_buf = dst->pixels,
|
||||
.buf = dst->pixels,
|
||||
.length = dst->bpp,
|
||||
};
|
||||
|
||||
|
||||
@ -314,6 +314,9 @@ int sensor_write_reg(uint8_t reg, uint8_t val)
|
||||
return SCCB_Write(sensor.slv_addr, reg, val);
|
||||
}
|
||||
|
||||
// The JPEG offset allows JPEG compression of the framebuffer without overwriting the pixels.
|
||||
// The offset size may need to be adjusted depending on the quality, otherwise JPEG data may
|
||||
// overwrite image pixels before they are compressed.
|
||||
int sensor_snapshot(struct image *image)
|
||||
{
|
||||
volatile uint32_t addr;
|
||||
@ -324,7 +327,7 @@ int sensor_snapshot(struct image *image)
|
||||
if (sensor.pixformat != PIXFORMAT_JPEG) {
|
||||
// The framebuffer is compressed in place.
|
||||
// Assuming we have at least 128KBs of SRAM.
|
||||
image_t src = {.w=fb->w, .h=fb->h, .bpp=fb->bpp, .pixels=fb->pixels};
|
||||
image_t src = {.w=fb->w, .h=fb->h, .bpp=fb->bpp, .pixels=fb->pixels+FB_JPEG_OFFS_SIZE};
|
||||
image_t dst = {.w=fb->w, .h=fb->h, .bpp=128*1024, .pixels=fb->pixels};
|
||||
|
||||
// Note: lower quality results in a faster IDE
|
||||
@ -346,16 +349,15 @@ int sensor_snapshot(struct image *image)
|
||||
}
|
||||
fb->ready = 0;
|
||||
|
||||
// Setup the address of the transfer
|
||||
addr = (uint32_t) (fb->pixels);
|
||||
|
||||
// Setup the size of the transfer
|
||||
// Setup the size and address of the transfer
|
||||
if (sensor.pixformat == PIXFORMAT_JPEG) {
|
||||
// Sensor has hardware JPEG set max frame size.
|
||||
length = MAX_XFER_SIZE;
|
||||
addr = (uint32_t) (fb->pixels);
|
||||
} else {
|
||||
// No hardware JPEG, set w*h*2 bytes per pixel.
|
||||
length =(fb->w * fb->h * 2)/4;
|
||||
addr = (uint32_t) (fb->pixels+FB_JPEG_OFFS_SIZE);
|
||||
}
|
||||
|
||||
// Lock framebuffer mutex
|
||||
@ -384,8 +386,9 @@ int sensor_snapshot(struct image *image)
|
||||
fb->bpp = 1;
|
||||
|
||||
// If GRAYSCALE extract Y channel from YUV
|
||||
uint8_t *pixels = fb->pixels + FB_JPEG_OFFS_SIZE;
|
||||
for (int i=0; i<(fb->w * fb->h); i++) {
|
||||
fb->pixels[i] = fb->pixels[i<<1];
|
||||
pixels[i] = pixels[i<<1];
|
||||
}
|
||||
} else if (sensor.pixformat == PIXFORMAT_JPEG) {
|
||||
// The frame readout has finished, however the DMA's still waiting for data
|
||||
@ -404,6 +407,9 @@ int sensor_snapshot(struct image *image)
|
||||
image->h = fb->h;
|
||||
image->bpp = fb->bpp;
|
||||
image->pixels = fb->pixels;
|
||||
if (sensor.pixformat != PIXFORMAT_JPEG) {
|
||||
image->pixels += FB_JPEG_OFFS_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock framebuffer mutex
|
||||
|
||||
Loading…
Reference in New Issue
Block a user