mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
ports/all: Refactor frame rate control.
This commit is contained in:
parent
f1f1bd1258
commit
db65ab81d8
@ -454,6 +454,9 @@ bool sensor_get_auto_rotation();
|
|||||||
// Set the number of virtual frame buffers.
|
// Set the number of virtual frame buffers.
|
||||||
int sensor_set_framebuffers(int count);
|
int sensor_set_framebuffers(int count);
|
||||||
|
|
||||||
|
// Drop the next frame to match the current frame rate.
|
||||||
|
void sensor_throttle_framerate();
|
||||||
|
|
||||||
// Set special digital effects (SDE).
|
// Set special digital effects (SDE).
|
||||||
int sensor_set_special_effect(sde_t sde);
|
int sensor_set_special_effect(sde_t sde);
|
||||||
|
|
||||||
|
|||||||
@ -666,6 +666,25 @@ __weak int sensor_set_framerate(int framerate) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__weak void sensor_throttle_framerate() {
|
||||||
|
if (!sensor.first_line) {
|
||||||
|
sensor.first_line = true;
|
||||||
|
uint32_t tick = mp_hal_ticks_ms();
|
||||||
|
uint32_t framerate_ms = IM_DIV(1000, sensor.framerate);
|
||||||
|
|
||||||
|
if (sensor.last_frame_ms_valid && ((tick - sensor.last_frame_ms) < framerate_ms)) {
|
||||||
|
// Drop the current frame to match the requested frame rate. Note that if the frame
|
||||||
|
// is marked to be dropped, it should not be copied to SRAM/SDRAM to save CPU time.
|
||||||
|
sensor.drop_frame = true;
|
||||||
|
} else if (sensor.last_frame_ms_valid) {
|
||||||
|
sensor.last_frame_ms += framerate_ms;
|
||||||
|
} else {
|
||||||
|
sensor.last_frame_ms = tick;
|
||||||
|
sensor.last_frame_ms_valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__weak bool sensor_get_cropped() {
|
__weak bool sensor_get_cropped() {
|
||||||
if (sensor.framesize != FRAMESIZE_INVALID) {
|
if (sensor.framesize != FRAMESIZE_INVALID) {
|
||||||
return (MAIN_FB()->x != 0) // should be zero if not cropped.
|
return (MAIN_FB()->x != 0) // should be zero if not cropped.
|
||||||
@ -676,7 +695,6 @@ __weak bool sensor_get_cropped() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__weak uint32_t sensor_get_src_bpp() {
|
__weak uint32_t sensor_get_src_bpp() {
|
||||||
switch (sensor.pixformat) {
|
switch (sensor.pixformat) {
|
||||||
case PIXFORMAT_GRAYSCALE:
|
case PIXFORMAT_GRAYSCALE:
|
||||||
@ -1231,6 +1249,10 @@ __weak int sensor_auto_crop_framebuffer() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__weak int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
const char *sensor_strerror(int error) {
|
const char *sensor_strerror(int error) {
|
||||||
static const char *sensor_errors[] = {
|
static const char *sensor_errors[] = {
|
||||||
"No error.",
|
"No error.",
|
||||||
@ -1265,8 +1287,4 @@ const char *sensor_strerror(int error) {
|
|||||||
return sensor_errors[error];
|
return sensor_errors[error];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__weak int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif //MICROPY_PY_SENSOR
|
#endif //MICROPY_PY_SENSOR
|
||||||
|
|||||||
@ -188,23 +188,8 @@ void sensor_sof_callback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sensor_line_callback(uint32_t addr) {
|
void sensor_line_callback(uint32_t addr) {
|
||||||
if (!sensor.first_line) {
|
// Throttle frames to match the current frame rate.
|
||||||
sensor.first_line = true;
|
sensor_throttle_framerate();
|
||||||
uint32_t tick = mp_hal_ticks_ms();
|
|
||||||
uint32_t framerate_ms = IM_DIV(1000, sensor.framerate);
|
|
||||||
|
|
||||||
// Drops frames to match the frame rate requested by the user. The frame is NOT copied to
|
|
||||||
// SRAM/SDRAM when dropping to save CPU cycles/energy that would be wasted.
|
|
||||||
// If framerate is zero then this does nothing...
|
|
||||||
if (sensor.last_frame_ms_valid && ((tick - sensor.last_frame_ms) < framerate_ms)) {
|
|
||||||
sensor.drop_frame = true;
|
|
||||||
} else if (sensor.last_frame_ms_valid) {
|
|
||||||
sensor.last_frame_ms += framerate_ms;
|
|
||||||
} else {
|
|
||||||
sensor.last_frame_ms = tick;
|
|
||||||
sensor.last_frame_ms_valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current framebuffer.
|
// Get current framebuffer.
|
||||||
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
|
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
|
||||||
|
|||||||
@ -442,27 +442,11 @@ static void mdma_memcpy(vbuffer_t *buffer, void *dst, void *src, int bpp, bool t
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This function is called back after each line transfer is complete,
|
// This function is called back after each line transfer is complete, with a pointer to the
|
||||||
// with a pointer to the line buffer that was used. At this point the
|
// buffer that was used. At this point the DMA transfers the next line to the next buffer.
|
||||||
// DMA transfers the next line to the other half of the line buffer.
|
|
||||||
void DCMI_DMAConvCpltUser(uint32_t addr) {
|
void DCMI_DMAConvCpltUser(uint32_t addr) {
|
||||||
if (!sensor.first_line) {
|
// Throttle frames to match the current frame rate.
|
||||||
sensor.first_line = true;
|
sensor_throttle_framerate();
|
||||||
uint32_t tick = HAL_GetTick();
|
|
||||||
uint32_t framerate_ms = IM_DIV(1000, sensor.framerate);
|
|
||||||
|
|
||||||
// Drops frames to match the frame rate requested by the user. The frame is NOT copied to
|
|
||||||
// SRAM/SDRAM when dropping to save CPU cycles/energy that would be wasted.
|
|
||||||
// If framerate is zero then this does nothing...
|
|
||||||
if (sensor.last_frame_ms_valid && ((tick - sensor.last_frame_ms) < framerate_ms)) {
|
|
||||||
sensor.drop_frame = true;
|
|
||||||
} else if (sensor.last_frame_ms_valid) {
|
|
||||||
sensor.last_frame_ms += framerate_ms;
|
|
||||||
} else {
|
|
||||||
sensor.last_frame_ms = tick;
|
|
||||||
sensor.last_frame_ms_valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sensor.drop_frame) {
|
if (sensor.drop_frame) {
|
||||||
// If we're dropping a frame in full offload mode it's safe to disable this interrupt saving
|
// If we're dropping a frame in full offload mode it's safe to disable this interrupt saving
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user