ports/all: Refactor frame rate control.

This commit is contained in:
iabdalkader 2024-02-02 12:58:21 +02:00
parent f1f1bd1258
commit db65ab81d8
4 changed files with 32 additions and 42 deletions

View File

@ -454,6 +454,9 @@ bool sensor_get_auto_rotation();
// Set the number of virtual frame buffers.
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).
int sensor_set_special_effect(sde_t sde);

View File

@ -666,6 +666,25 @@ __weak int sensor_set_framerate(int framerate) {
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() {
if (sensor.framesize != FRAMESIZE_INVALID) {
return (MAIN_FB()->x != 0) // should be zero if not cropped.
@ -676,7 +695,6 @@ __weak bool sensor_get_cropped() {
return false;
}
__weak uint32_t sensor_get_src_bpp() {
switch (sensor.pixformat) {
case PIXFORMAT_GRAYSCALE:
@ -1231,6 +1249,10 @@ __weak int sensor_auto_crop_framebuffer() {
return 0;
}
__weak int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
return -1;
}
const char *sensor_strerror(int error) {
static const char *sensor_errors[] = {
"No error.",
@ -1265,8 +1287,4 @@ const char *sensor_strerror(int error) {
return sensor_errors[error];
}
}
__weak int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
return -1;
}
#endif //MICROPY_PY_SENSOR

View File

@ -188,23 +188,8 @@ void sensor_sof_callback() {
}
void sensor_line_callback(uint32_t addr) {
if (!sensor.first_line) {
sensor.first_line = true;
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;
}
}
// Throttle frames to match the current frame rate.
sensor_throttle_framerate();
// Get current framebuffer.
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);

View File

@ -442,27 +442,11 @@ static void mdma_memcpy(vbuffer_t *buffer, void *dst, void *src, int bpp, bool t
}
#endif
// This function is called back after each line transfer is complete,
// with a pointer to the line buffer that was used. At this point the
// DMA transfers the next line to the other half of the line buffer.
// This function is called back after each line transfer is complete, with a pointer to the
// buffer that was used. At this point the DMA transfers the next line to the next buffer.
void DCMI_DMAConvCpltUser(uint32_t addr) {
if (!sensor.first_line) {
sensor.first_line = true;
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;
}
}
// Throttle frames to match the current frame rate.
sensor_throttle_framerate();
if (sensor.drop_frame) {
// If we're dropping a frame in full offload mode it's safe to disable this interrupt saving