Skip to content

Commit 9f66ed2

Browse files
authored
Merge pull request #777 from RubenKelevra/bugfix/implement_jpeg_eoi_check_for_psram_dma
fix jpeg eoi check for psram_mode (DMA)
2 parents e6378d2 + 7b9e4f7 commit 9f66ed2

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

driver/cam_hal.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ static portMUX_TYPE g_psram_dma_lock = portMUX_INITIALIZER_UNLOCKED;
6969
#define CAM_SOI_PROBE_BYTES 32
7070
#endif
7171

72+
/* Number of bytes copied to SRAM for EOI validation when capturing
73+
* directly to PSRAM. Tunable to probe more of the frame tail if needed. */
74+
#ifndef CAM_EOI_PROBE_BYTES
75+
#define CAM_EOI_PROBE_BYTES 32
76+
#endif
77+
7278
/*
7379
* PSRAM DMA may bypass the CPU cache. Always call esp_cache_msync() on the
7480
* SOI probe region so cached reads see the data written by DMA.
@@ -669,7 +675,37 @@ camera_fb_t *cam_take(TickType_t timeout)
669675

670676
if (cam_obj->jpeg_mode) {
671677
/* find the end marker for JPEG. Data after that can be discarded */
672-
int offset_e = cam_verify_jpeg_eoi(dma_buffer->buf, dma_buffer->len);
678+
int offset_e = -1;
679+
if (cam_obj->psram_mode) {
680+
size_t probe_len = dma_buffer->len;
681+
if (probe_len > CAM_EOI_PROBE_BYTES) {
682+
probe_len = CAM_EOI_PROBE_BYTES;
683+
}
684+
if (probe_len == 0) {
685+
goto skip_eoi_check;
686+
}
687+
size_t line = dcache_line_size();
688+
if (line == 0) {
689+
line = 32; /* sane fallback */
690+
}
691+
uintptr_t addr = (uintptr_t)(dma_buffer->buf + dma_buffer->len - probe_len);
692+
uintptr_t start = addr & ~(line - 1);
693+
size_t sync_len = (probe_len + (addr - start) + line - 1) & ~(line - 1);
694+
esp_cache_msync((void *)start, sync_len,
695+
ESP_CACHE_MSYNC_FLAG_DIR_M2C | ESP_CACHE_MSYNC_FLAG_INVALIDATE);
696+
697+
uint8_t eoi_probe[CAM_EOI_PROBE_BYTES];
698+
memcpy(eoi_probe, dma_buffer->buf + dma_buffer->len - probe_len, probe_len);
699+
int off = cam_verify_jpeg_eoi(eoi_probe, probe_len);
700+
if (off >= 0) {
701+
offset_e = dma_buffer->len - probe_len + off;
702+
}
703+
} else {
704+
offset_e = cam_verify_jpeg_eoi(dma_buffer->buf, dma_buffer->len);
705+
}
706+
707+
skip_eoi_check:
708+
673709
if (offset_e >= 0) {
674710
dma_buffer->len = offset_e + sizeof(JPEG_EOI_MARKER);
675711
return dma_buffer;

0 commit comments

Comments
 (0)