Skip to content

Commit 1275346

Browse files
committed
Added sharpness controls for the OV2640 sensor
Cleaned the camera driver even more
1 parent 9d746d6 commit 1275346

File tree

5 files changed

+117
-266
lines changed

5 files changed

+117
-266
lines changed

air_firmware/components/esp32-camera/driver/camera.c

+1-245
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ static const char* TAG = "camera";
8484
static const char* CAMERA_SENSOR_NVS_KEY = "sensor";
8585
static const char* CAMERA_PIXFORMAT_NVS_KEY = "pixformat";
8686

87-
typedef void (*dma_filter_t)(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst);
88-
8987
camera_fb_data_cb_t s_cb = NULL;
9088

9189
typedef struct camera_fb_s {
@@ -132,7 +130,6 @@ typedef struct {
132130
size_t dma_desc_cur;
133131

134132
i2s_sampling_mode_t sampling_mode;
135-
dma_filter_t dma_filter;
136133
intr_handle_t i2s_intr_handle;
137134
QueueHandle_t data_ready;
138135

@@ -149,11 +146,6 @@ static void IRAM_ATTR i2s_isr(void* arg);
149146
static esp_err_t dma_desc_init();
150147
static void dma_desc_deinit();
151148
static void dma_filter_task(void *pvParameters);
152-
static void dma_filter_grayscale(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst);
153-
static void dma_filter_grayscale_highspeed(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst);
154-
static void dma_filter_yuyv(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst);
155-
static void dma_filter_yuyv_highspeed(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst);
156-
static void dma_filter_jpeg(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst);
157149
static void i2s_stop(bool* need_yield);
158150

159151
static bool is_hs_mode()
@@ -667,26 +659,6 @@ static void IRAM_ATTR dma_finish_frame()
667659
} else {
668660
s_state->fb->len = s_state->dma_filtered_count * buf_len;
669661
if(s_state->fb->len) {
670-
//find the end marker for JPEG. Data after that can be discarded
671-
/*
672-
if(s_state->fb->format == PIXFORMAT_JPEG){
673-
uint8_t * dptr = &s_state->fb->buf[s_state->fb->len - 4];
674-
while(dptr > s_state->fb->buf){
675-
if(dptr[0] == 0xFF && dptr[1] == 0xD9 && dptr[2] == 0x00 && dptr[3] == 0x00){
676-
dptr += 2;
677-
s_state->fb->len = dptr - s_state->fb->buf;
678-
if((s_state->fb->len & 0x1FF) == 0){
679-
s_state->fb->len += 1;
680-
}
681-
if((s_state->fb->len % 100) == 0){
682-
s_state->fb->len += 1;
683-
}
684-
break;
685-
}
686-
dptr--;
687-
}
688-
}
689-
*/
690662
//send out the frame
691663
s_cb(NULL, 0, 0, true);
692664
camera_fb_done();
@@ -720,22 +692,10 @@ static void IRAM_ATTR dma_filter_buffer(size_t buf_idx, bool last)
720692
return;
721693
}
722694

723-
if (!s_state->dma_filtered_count)
724-
{
695+
if (!s_state->dma_filtered_count) {
725696
s_cb(NULL, 0, 0, false); //start frame
726697
}
727698

728-
// static void IRAM_ATTR dma_filter_grayscale(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst)
729-
// {
730-
// size_t end = dma_desc->length / sizeof(dma_elem_t);
731-
// for (size_t i = 0; i < end; ++i) {
732-
// dst[0] = src[0].sample1;
733-
// src += 1;
734-
// dst += 1;
735-
// }
736-
// }
737-
//convert I2S DMA buffer to pixel data
738-
//(*s_state->dma_filter)(s_state->dma_buf[buf_idx], &s_state->dma_desc[buf_idx], s_state->fb->buf + fb_pos);
739699
{
740700
const uint8_t* src = ((const uint8_t*)s_state->dma_buf[buf_idx]) + 2; //starting at sample1 field
741701
size_t count = buf_len;//s_state->dma_desc[buf_idx].length / sizeof(dma_elem_t);
@@ -745,25 +705,10 @@ static void IRAM_ATTR dma_filter_buffer(size_t buf_idx, bool last)
745705

746706
//first frame buffer
747707
if(!s_state->dma_filtered_count) {
748-
//check for correct JPEG header
749-
/*
750-
if(s_state->sensor.pixformat == PIXFORMAT_JPEG) {
751-
uint32_t sig = *((uint32_t *)s_state->fb->buf) & 0xFFFFFF;
752-
if(sig != 0xffd8ff) {
753-
ESP_LOGD(TAG,"unexpected JPEG signature 0x%08x\n", sig);
754-
s_state->fb->bad = 1;
755-
return;
756-
}
757-
}
758-
*/
759708
//set the frame properties
760709
s_state->fb->width = resolution[s_state->sensor.status.framesize].width;
761710
s_state->fb->height = resolution[s_state->sensor.status.framesize].height;
762711
s_state->fb->format = s_state->sensor.pixformat;
763-
764-
//uint64_t us = (uint64_t)esp_timer_get_time();
765-
//s_state->fb->timestamp.tv_sec = us / 1000000UL;
766-
//s_state->fb->timestamp.tv_usec = us % 1000000UL;
767712
}
768713
s_state->dma_filtered_count++;
769714
}
@@ -786,186 +731,6 @@ static void IRAM_ATTR dma_filter_task(void *pvParameters)
786731
}
787732
}
788733

789-
static void IRAM_ATTR dma_filter_jpeg(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst)
790-
{
791-
size_t end = dma_desc->length / sizeof(dma_elem_t) / 4;
792-
const uint8_t* src8 = ((const uint8_t*)src) + 2; //starting at sample1 field
793-
uint32_t* dst32 = (uint32_t*)dst;
794-
// manually unrolling 4 iterations of the loop here
795-
for (size_t i = end; i > 0; --i) {
796-
uint32_t v = src8[0] | (src8[4] << 8) | (src8[8] << 16) | (src8[12] << 24);
797-
*dst32++ = v;
798-
src8 += 16;
799-
}
800-
/*
801-
size_t end = dma_desc->length / sizeof(dma_elem_t) / 4;
802-
// manually unrolling 4 iterations of the loop here
803-
for (size_t i = 0; i < end; ++i) {
804-
dst[0] = src[0].sample1;
805-
dst[1] = src[1].sample1;
806-
dst[2] = src[2].sample1;
807-
dst[3] = src[3].sample1;
808-
src += 4;
809-
dst += 4;
810-
}
811-
*/
812-
}
813-
814-
static void IRAM_ATTR dma_filter_grayscale(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst)
815-
{
816-
size_t end = dma_desc->length / sizeof(dma_elem_t) / 4;
817-
for (size_t i = 0; i < end; ++i) {
818-
// manually unrolling 4 iterations of the loop here
819-
dst[0] = src[0].sample1;
820-
dst[1] = src[1].sample1;
821-
dst[2] = src[2].sample1;
822-
dst[3] = src[3].sample1;
823-
src += 4;
824-
dst += 4;
825-
}
826-
}
827-
828-
static void IRAM_ATTR dma_filter_grayscale_highspeed(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst)
829-
{
830-
size_t end = dma_desc->length / sizeof(dma_elem_t) / 8;
831-
for (size_t i = 0; i < end; ++i) {
832-
// manually unrolling 4 iterations of the loop here
833-
dst[0] = src[0].sample1;
834-
dst[1] = src[2].sample1;
835-
dst[2] = src[4].sample1;
836-
dst[3] = src[6].sample1;
837-
src += 8;
838-
dst += 4;
839-
}
840-
// the final sample of a line in SM_0A0B_0B0C sampling mode needs special handling
841-
if ((dma_desc->length & 0x7) != 0) {
842-
dst[0] = src[0].sample1;
843-
dst[1] = src[2].sample1;
844-
}
845-
}
846-
847-
static void IRAM_ATTR dma_filter_yuyv(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst)
848-
{
849-
size_t end = dma_desc->length / sizeof(dma_elem_t) / 4;
850-
for (size_t i = 0; i < end; ++i) {
851-
dst[0] = src[0].sample1;//y0
852-
dst[1] = src[0].sample2;//u
853-
dst[2] = src[1].sample1;//y1
854-
dst[3] = src[1].sample2;//v
855-
856-
dst[4] = src[2].sample1;//y0
857-
dst[5] = src[2].sample2;//u
858-
dst[6] = src[3].sample1;//y1
859-
dst[7] = src[3].sample2;//v
860-
src += 4;
861-
dst += 8;
862-
}
863-
}
864-
865-
static void IRAM_ATTR dma_filter_yuyv_highspeed(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst)
866-
{
867-
size_t end = dma_desc->length / sizeof(dma_elem_t) / 8;
868-
for (size_t i = 0; i < end; ++i) {
869-
dst[0] = src[0].sample1;//y0
870-
dst[1] = src[1].sample1;//u
871-
dst[2] = src[2].sample1;//y1
872-
dst[3] = src[3].sample1;//v
873-
874-
dst[4] = src[4].sample1;//y0
875-
dst[5] = src[5].sample1;//u
876-
dst[6] = src[6].sample1;//y1
877-
dst[7] = src[7].sample1;//v
878-
src += 8;
879-
dst += 8;
880-
}
881-
if ((dma_desc->length & 0x7) != 0) {
882-
dst[0] = src[0].sample1;//y0
883-
dst[1] = src[1].sample1;//u
884-
dst[2] = src[2].sample1;//y1
885-
dst[3] = src[2].sample2;//v
886-
}
887-
}
888-
889-
static void IRAM_ATTR dma_filter_rgb888(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst)
890-
{
891-
size_t end = dma_desc->length / sizeof(dma_elem_t) / 4;
892-
uint8_t lb, hb;
893-
for (size_t i = 0; i < end; ++i) {
894-
hb = src[0].sample1;
895-
lb = src[0].sample2;
896-
dst[0] = (lb & 0x1F) << 3;
897-
dst[1] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
898-
dst[2] = hb & 0xF8;
899-
900-
hb = src[1].sample1;
901-
lb = src[1].sample2;
902-
dst[3] = (lb & 0x1F) << 3;
903-
dst[4] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
904-
dst[5] = hb & 0xF8;
905-
906-
hb = src[2].sample1;
907-
lb = src[2].sample2;
908-
dst[6] = (lb & 0x1F) << 3;
909-
dst[7] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
910-
dst[8] = hb & 0xF8;
911-
912-
hb = src[3].sample1;
913-
lb = src[3].sample2;
914-
dst[9] = (lb & 0x1F) << 3;
915-
dst[10] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
916-
dst[11] = hb & 0xF8;
917-
src += 4;
918-
dst += 12;
919-
}
920-
}
921-
922-
static void IRAM_ATTR dma_filter_rgb888_highspeed(const dma_elem_t* src, lldesc_t* dma_desc, uint8_t* dst)
923-
{
924-
size_t end = dma_desc->length / sizeof(dma_elem_t) / 8;
925-
uint8_t lb, hb;
926-
for (size_t i = 0; i < end; ++i) {
927-
hb = src[0].sample1;
928-
lb = src[1].sample1;
929-
dst[0] = (lb & 0x1F) << 3;
930-
dst[1] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
931-
dst[2] = hb & 0xF8;
932-
933-
hb = src[2].sample1;
934-
lb = src[3].sample1;
935-
dst[3] = (lb & 0x1F) << 3;
936-
dst[4] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
937-
dst[5] = hb & 0xF8;
938-
939-
hb = src[4].sample1;
940-
lb = src[5].sample1;
941-
dst[6] = (lb & 0x1F) << 3;
942-
dst[7] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
943-
dst[8] = hb & 0xF8;
944-
945-
hb = src[6].sample1;
946-
lb = src[7].sample1;
947-
dst[9] = (lb & 0x1F) << 3;
948-
dst[10] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
949-
dst[11] = hb & 0xF8;
950-
951-
src += 8;
952-
dst += 12;
953-
}
954-
if ((dma_desc->length & 0x7) != 0) {
955-
hb = src[0].sample1;
956-
lb = src[1].sample1;
957-
dst[0] = (lb & 0x1F) << 3;
958-
dst[1] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
959-
dst[2] = hb & 0xF8;
960-
961-
hb = src[2].sample1;
962-
lb = src[2].sample2;
963-
dst[3] = (lb & 0x1F) << 3;
964-
dst[4] = (hb & 0x07) << 5 | (lb & 0xE0) >> 3;
965-
dst[5] = hb & 0xF8;
966-
}
967-
}
968-
969734
/*
970735
* Public Methods
971736
* */
@@ -1202,19 +967,15 @@ esp_err_t camera_init(const camera_config_t* config)
1202967
if (s_state->sensor.id.PID == OV3660_PID || s_state->sensor.id.PID == OV5640_PID || s_state->sensor.id.PID == NT99141_PID) {
1203968
if (is_hs_mode()) {
1204969
s_state->sampling_mode = SM_0A00_0B00;
1205-
s_state->dma_filter = &dma_filter_yuyv_highspeed;
1206970
} else {
1207971
s_state->sampling_mode = SM_0A0B_0C0D;
1208-
s_state->dma_filter = &dma_filter_yuyv;
1209972
}
1210973
s_state->in_bytes_per_pixel = 1; // camera sends Y8
1211974
} else {
1212975
if (is_hs_mode() && s_state->sensor.id.PID != OV7725_PID) {
1213976
s_state->sampling_mode = SM_0A00_0B00;
1214-
s_state->dma_filter = &dma_filter_grayscale_highspeed;
1215977
} else {
1216978
s_state->sampling_mode = SM_0A0B_0C0D;
1217-
s_state->dma_filter = &dma_filter_grayscale;
1218979
}
1219980
s_state->in_bytes_per_pixel = 2; // camera sends YU/YV
1220981
}
@@ -1227,10 +988,8 @@ esp_err_t camera_init(const camera_config_t* config)
1227988
}else{
1228989
s_state->sampling_mode = SM_0A00_0B00;
1229990
}
1230-
s_state->dma_filter = &dma_filter_yuyv_highspeed;
1231991
} else {
1232992
s_state->sampling_mode = SM_0A0B_0C0D;
1233-
s_state->dma_filter = &dma_filter_yuyv;
1234993
}
1235994
s_state->in_bytes_per_pixel = 2; // camera sends YU/YV
1236995
s_state->fb_bytes_per_pixel = 2; // frame buffer stores YU/YV/RGB565
@@ -1242,10 +1001,8 @@ esp_err_t camera_init(const camera_config_t* config)
12421001
}else{
12431002
s_state->sampling_mode = SM_0A00_0B00;
12441003
}
1245-
s_state->dma_filter = &dma_filter_rgb888_highspeed;
12461004
} else {
12471005
s_state->sampling_mode = SM_0A0B_0C0D;
1248-
s_state->dma_filter = &dma_filter_rgb888;
12491006
}
12501007
s_state->in_bytes_per_pixel = 2; // camera sends RGB565
12511008
s_state->fb_bytes_per_pixel = 3; // frame buffer stores RGB888
@@ -1268,7 +1025,6 @@ esp_err_t camera_init(const camera_config_t* config)
12681025
s_state->in_bytes_per_pixel = 2;
12691026
s_state->fb_bytes_per_pixel = 2;
12701027
s_state->fb_size = (s_state->width * s_state->height * s_state->fb_bytes_per_pixel) / compression_ratio_bound;
1271-
s_state->dma_filter = &dma_filter_jpeg;
12721028
s_state->sampling_mode = SM_0A00_0B00;
12731029
} else {
12741030
ESP_LOGE(TAG, "Requested format is not supported");

0 commit comments

Comments
 (0)