@@ -148,11 +148,15 @@ void mp_camera_hal_construct(
148148
149149 // defaul parameters
150150 self -> camera_config .fb_location = CAMERA_FB_IN_PSRAM ;
151- self -> camera_config .ledc_timer = LEDC_TIMER_0 ;
151+ self -> camera_config .ledc_timer = LEDC_TIMER_3 ;
152152 self -> camera_config .ledc_channel = LEDC_CHANNEL_0 ;
153153
154154 self -> initialized = false;
155155 self -> captured_buffer = NULL ;
156+ self -> converted_buffer .len = 0 ;
157+ self -> converted_buffer .buf = NULL ;
158+ self -> converted_buffer .typecode = 'B' ;
159+ self -> bmp_out = false;
156160 }
157161
158162void mp_camera_hal_init (mp_camera_obj_t * self ) {
@@ -171,6 +175,11 @@ void mp_camera_hal_init(mp_camera_obj_t *self) {
171175
172176void mp_camera_hal_deinit (mp_camera_obj_t * self ) {
173177 if (self -> initialized ) {
178+ if (self -> converted_buffer .buf ) {
179+ free (self -> converted_buffer .buf );
180+ self -> converted_buffer .buf = NULL ;
181+ self -> converted_buffer .len = 0 ;
182+ }
174183 if (self -> captured_buffer ) {
175184 esp_camera_return_all ();
176185 self -> captured_buffer = NULL ;
@@ -205,21 +214,68 @@ void mp_camera_hal_reconfigure(mp_camera_obj_t *self, mp_camera_framesize_t fram
205214 ESP_LOGI (TAG , "Camera reconfigured successfully" );
206215}
207216
217+ static bool ensure_buffer (mp_camera_obj_t * self , size_t req_len ) {
218+ if (self -> converted_buffer .len == req_len ) {
219+ return true;
220+ }
221+ if (self -> converted_buffer .len > 0 || self -> converted_buffer .buf ) {
222+ free (self -> converted_buffer .buf );
223+ }
224+ self -> converted_buffer .buf = (uint8_t * )malloc (req_len );
225+ if (!self -> converted_buffer .buf ) {
226+ self -> converted_buffer .len = 0 ;
227+ ESP_LOGE (TAG , "converted_buffer malloc failed" );
228+ return false;
229+ }
230+ self -> converted_buffer .len = req_len ;
231+ return true;
232+ }
233+
234+ static bool mp_camera_convert (mp_camera_obj_t * self , mp_camera_pixformat_t out_format ) {
235+ ESP_LOGI (TAG , "Converting image to pixel format: %d" , out_format );
236+
237+ switch (out_format ) {
238+ case PIXFORMAT_JPEG :
239+ return frame2jpg (self -> captured_buffer , self -> camera_config .jpeg_quality , self -> converted_buffer .buf , & self -> converted_buffer .len );
240+
241+ case PIXFORMAT_RGB888 :
242+ if (ensure_buffer (self , self -> captured_buffer -> width * self -> captured_buffer -> height * 3 )) {
243+ return fmt2rgb888 (self -> captured_buffer -> buf , self -> captured_buffer -> len , self -> captured_buffer -> format , self -> converted_buffer .buf );
244+ } else {
245+ return false;
246+ }
247+
248+ case PIXFORMAT_RGB565 :
249+ if (self -> camera_config .pixel_format == PIXFORMAT_JPEG ) {
250+ if (ensure_buffer (self , self -> captured_buffer -> width * self -> captured_buffer -> height * 2 )) {
251+ return jpg2rgb565 (self -> captured_buffer -> buf , self -> captured_buffer -> len , self -> converted_buffer .buf , JPG_SCALE_NONE );
252+ } else {
253+ return false;
254+ }
255+ } else {
256+ mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("Can only convert JPEG to RGB565" ));
257+ }
258+
259+ default :
260+ mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("Unsupported pixel format for conversion" ));
261+ }
262+ }
263+ mp_obj_t mp_camera_hal_convert (mp_camera_obj_t * self , int8_t out_format ) {
264+ check_init (self );
265+ if (mp_camera_convert (self , (mp_camera_pixformat_t )out_format )) {
266+ return mp_obj_new_memoryview ('b' , self -> converted_buffer .len , self -> converted_buffer .buf );
267+ } else {
268+ return mp_const_none ;
269+ }
270+ }
271+
208272mp_obj_t mp_camera_hal_capture (mp_camera_obj_t * self , int8_t out_format ) {
209273 check_init (self );
210274 if (self -> captured_buffer ) {
211275 esp_camera_fb_return (self -> captured_buffer );
212276 self -> captured_buffer = NULL ;
213277 }
214278
215- static size_t out_len = 0 ;
216- static uint8_t * out_buf = NULL ;
217- if (out_len > 0 || out_buf ) {
218- free (out_buf );
219- out_len = 0 ;
220- out_buf = NULL ;
221- }
222-
223279 ESP_LOGI (TAG , "Capturing image" );
224280 self -> captured_buffer = esp_camera_fb_get ();
225281 if (!self -> captured_buffer ) {
@@ -228,56 +284,12 @@ mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, int8_t out_format) {
228284 }
229285
230286 if (out_format >= 0 && (mp_camera_pixformat_t )out_format != self -> camera_config .pixel_format ) {
231- ESP_LOGI (TAG , "Converting image to pixel format: %d" , out_format );
232- switch ((mp_camera_pixformat_t )out_format ) {
233- case PIXFORMAT_JPEG :
234- if (frame2jpg (self -> captured_buffer , self -> camera_config .jpeg_quality , & out_buf , & out_len )) {
235- esp_camera_fb_return (self -> captured_buffer );
236- mp_obj_t result = mp_obj_new_memoryview ('b' , out_len , out_buf );
237- return result ;
238- } else {
239- return mp_const_none ;
240- }
241-
242- case PIXFORMAT_RGB888 :
243- out_len = self -> captured_buffer -> width * self -> captured_buffer -> height * 3 ;
244- out_buf = (uint8_t * )malloc (out_len );
245- if (!out_buf ) {
246- ESP_LOGE (TAG , "out_buf malloc failed" );
247- return mp_const_none ;
248- }
249- if (fmt2rgb888 (self -> captured_buffer -> buf , self -> captured_buffer -> len , self -> captured_buffer -> format , out_buf )) {
250- esp_camera_fb_return (self -> captured_buffer );
251- mp_obj_t result = mp_obj_new_memoryview ('b' , out_len , out_buf );
252- return result ;
253- } else {
254- return mp_const_none ;
255- }
256-
257- case PIXFORMAT_RGB565 :
258- out_len = self -> captured_buffer -> width * self -> captured_buffer -> height * 2 ;
259- out_buf = (uint8_t * )malloc (out_len );
260- if (!out_buf ) {
261- ESP_LOGE (TAG , "out_buf malloc failed" );
262- return mp_const_none ;
263- }
264- if (self -> camera_config .pixel_format == PIXFORMAT_JPEG ){
265- if (jpg2rgb565 (self -> captured_buffer -> buf , self -> captured_buffer -> len , out_buf , JPG_SCALE_NONE )) {
266- esp_camera_fb_return (self -> captured_buffer );
267- mp_obj_t result = mp_obj_new_memoryview ('b' , out_len , out_buf );
268- return result ;
269- } else {
270- return mp_const_none ;
271- }
272- } else {
273- mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("Can only convert JPEG to RGB565" ));
274- return mp_const_none ;
275- }
276-
277- default :
278- mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("Unsupported pixel format for conversion" ));
279- return mp_const_none ;
280-
287+ if (mp_camera_convert (self , (mp_camera_pixformat_t )out_format )) {
288+ esp_camera_fb_return (self -> captured_buffer );
289+ mp_obj_t result = mp_obj_new_memoryview ('b' , self -> converted_buffer .len , self -> converted_buffer .buf );
290+ return result ;
291+ } else {
292+ return mp_const_none ;
281293 }
282294 }
283295
@@ -286,16 +298,15 @@ mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, int8_t out_format) {
286298 return mp_obj_new_memoryview ('b' , self -> captured_buffer -> len , self -> captured_buffer -> buf );
287299 } else {
288300 ESP_LOGI (TAG , "Returning image as bitmap" );
289- if (frame2bmp (self -> captured_buffer , & out_buf , & out_len )) {
301+ if (frame2bmp (self -> captured_buffer , self -> converted_buffer . buf , & self -> converted_buffer . len )) {
290302 esp_camera_fb_return (self -> captured_buffer );
291- mp_obj_t result = mp_obj_new_memoryview ('b' , out_len , out_buf );
303+ mp_obj_t result = mp_obj_new_memoryview ('b' , self -> converted_buffer . len , self -> converted_buffer . buf );
292304 return result ;
293305 } else {
294- free (out_buf );
295- out_buf = NULL ;
296- out_len = 0 ;
306+ free (self -> converted_buffer . buf );
307+ self -> converted_buffer . buf = NULL ;
308+ self -> converted_buffer . len = 0 ;
297309 mp_raise_msg (& mp_type_OSError , MP_ERROR_TEXT ("Failed to convert image to BMP" ));
298- return mp_const_none ;
299310 }
300311 }
301312} // mp_camera_hal_capture
0 commit comments