diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.cpp b/code/components/jomjol_controlcamera/ClassControllCamera.cpp index 13dd7ab39..8058fbf0f 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.cpp +++ b/code/components/jomjol_controlcamera/ClassControllCamera.cpp @@ -311,7 +311,7 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) loadNextDemoImage(fb); } - CImageBasis* _zwImage = new CImageBasis(); + CImageBasis* _zwImage = new CImageBasis("zwImage"); if (_zwImage) { _zwImage->LoadFromMemory(fb->buf, fb->len); } diff --git a/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp b/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp index c27b7674d..a8ffcfbc7 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp @@ -8,6 +8,7 @@ #include "ClassLogFile.h" +#include "psram.h" #include "../../include/defines.h" @@ -31,7 +32,7 @@ void ClassFlowAlignment::SetInitialParameter(void) ImageBasis = NULL; ImageTMP = NULL; #ifdef ALGROI_LOAD_FROM_MEM_AS_JPG - AlgROI = (ImageData*)heap_caps_malloc(sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + AlgROI = (ImageData*)malloc_psram_heap(std::string(TAG) + "->AlgROI", sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); #endif previousElement = NULL; disabled = false; @@ -55,7 +56,7 @@ ClassFlowAlignment::ClassFlowAlignment(std::vector* lfc) if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES { ESP_LOGD(TAG, "CImageBasis had to be created"); - ImageBasis = new CImageBasis(namerawimage); + ImageBasis = new CImageBasis("ImageBasis", namerawimage); } } @@ -189,7 +190,7 @@ bool ClassFlowAlignment::doFlow(string time) if (!ImageTMP) { - ImageTMP = new CImageBasis(ImageBasis); + ImageTMP = new CImageBasis("ImageTMP", ImageBasis); if (!ImageTMP) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate ImageTMP -> Exec this round aborted!"); @@ -199,7 +200,7 @@ bool ClassFlowAlignment::doFlow(string time) } delete AlignAndCutImage; - AlignAndCutImage = new CAlignAndCutImage(ImageBasis, ImageTMP); + AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP); if (!AlignAndCutImage) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlignAndCutImage -> Exec this round aborted!"); @@ -207,7 +208,7 @@ bool ClassFlowAlignment::doFlow(string time) return false; } - CRotateImage rt(AlignAndCutImage, ImageTMP, initialflip); + CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, initialflip); if (initialflip) { int _zw = ImageBasis->height; diff --git a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp index ed071fa92..fb3800a12 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp @@ -381,8 +381,10 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph) for (int _ana = 0; _ana < GENERAL.size(); ++_ana) for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i) { - GENERAL[_ana]->ROI[i]->image = new CImageBasis(modelxsize, modelysize, modelchannel); - GENERAL[_ana]->ROI[i]->image_org = new CImageBasis(GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, 3); + GENERAL[_ana]->ROI[i]->image = new CImageBasis("ROI " + GENERAL[_ana]->ROI[i]->name, + modelxsize, modelysize, modelchannel); + GENERAL[_ana]->ROI[i]->image_org = new CImageBasis("ROI " + GENERAL[_ana]->ROI[i]->name + " original", + GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, 3); } return true; diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index d5995b708..e9d56e3ec 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -826,7 +826,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req) return ESP_FAIL; } - _send = new CImageBasis(flowalignment->ImageBasis); + _send = new CImageBasis("alg_roi", flowalignment->ImageBasis); if (_send->ImageOkay()) { if (flowalignment) flowalignment->DrawRef(_send); diff --git a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp index 5c19fb0bd..bb8584afc 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp @@ -154,7 +154,7 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph) image_width = Camera.image_width; image_height = Camera.image_height; - rawImage = new CImageBasis(); + rawImage = new CImageBasis("rawImage"); rawImage->CreateEmptyImage(image_width, image_height, 3); waitbeforepicture_store = waitbeforepicture; @@ -231,7 +231,7 @@ esp_err_t ClassFlowTakeImage::SendRawJPG(httpd_req_t *req) ImageData* ClassFlowTakeImage::SendRawImage() { - CImageBasis *zw = new CImageBasis(rawImage); + CImageBasis *zw = new CImageBasis("SendRawImage", rawImage); ImageData *id; int flash_duration = (int) (waitbeforepicture * 1000); Camera.CaptureToBasisImage(zw, flash_duration); diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index 3417eb58b..ae3ab6838 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -64,14 +64,14 @@ string getESPHeapInfo(){ sprintf(aMsgBuf," | SPI Free: %ld", (long) aFreeSPIHeapSize); espInfoResultStr += string(aMsgBuf); - sprintf(aMsgBuf," | SPI Larg Block: %ld", (long) aHeapLargestFreeBlockSize); + sprintf(aMsgBuf," | SPI Large Block: %ld", (long) aHeapLargestFreeBlockSize); espInfoResultStr += string(aMsgBuf); sprintf(aMsgBuf," | SPI Min Free: %ld", (long) aMinFreeHeapSize); espInfoResultStr += string(aMsgBuf); sprintf(aMsgBuf," | Int Free: %ld", (long) (aFreeInternalHeapSize)); espInfoResultStr += string(aMsgBuf); - sprintf(aMsgBuf," | Int Larg Block: %ld", (long) aHeapIntLargestFreeBlockSize); + sprintf(aMsgBuf," | Int Large Block: %ld", (long) aHeapIntLargestFreeBlockSize); espInfoResultStr += string(aMsgBuf); sprintf(aMsgBuf," | Int Min Free: %ld", (long) (aMinFreeInternalHeapSize)); espInfoResultStr += string(aMsgBuf); diff --git a/code/components/jomjol_helper/psram.cpp b/code/components/jomjol_helper/psram.cpp new file mode 100644 index 000000000..8cbb64a56 --- /dev/null +++ b/code/components/jomjol_helper/psram.cpp @@ -0,0 +1,42 @@ +#include "ClassLogFile.h" +#include "esp_heap_caps.h" + +static const char* TAG = "PSRAM"; + +using namespace std; + + +void *malloc_psram_heap(std::string name, size_t size, uint32_t caps) { + void *ptr; + + ptr = heap_caps_malloc(size, caps); + if (ptr != NULL) { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'"); + } + else { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!"); + } + + return ptr; +} + + +void *calloc_psram_heap(std::string name, size_t n, size_t size, uint32_t caps) { + void *ptr; + + ptr = heap_caps_calloc(n, size, caps); + if (ptr != NULL) { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'"); + } + else { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!"); + } + + return ptr; +} + + +void free_psram_heap(std::string name, void *ptr) { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Freeing memory in PSRAM used for '" + name + "'..."); + heap_caps_free(ptr); +} \ No newline at end of file diff --git a/code/components/jomjol_helper/psram.h b/code/components/jomjol_helper/psram.h new file mode 100644 index 000000000..fafd0c732 --- /dev/null +++ b/code/components/jomjol_helper/psram.h @@ -0,0 +1,7 @@ + +#include "esp_heap_caps.h" + +void *malloc_psram_heap(std::string name, size_t size, uint32_t caps); +void *calloc_psram_heap(std::string name, size_t n, size_t size, uint32_t caps); + +void free_psram_heap(std::string name, void *ptr); \ No newline at end of file diff --git a/code/components/jomjol_image_proc/CAlignAndCutImage.cpp b/code/components/jomjol_image_proc/CAlignAndCutImage.cpp index 86cbae6c1..b7f7afbda 100644 --- a/code/components/jomjol_image_proc/CAlignAndCutImage.cpp +++ b/code/components/jomjol_image_proc/CAlignAndCutImage.cpp @@ -5,12 +5,14 @@ #include #include #include +#include "psram.h" #include "../../include/defines.h" static const char* TAG = "c_align_and_cut_image"; -CAlignAndCutImage::CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp) +CAlignAndCutImage::CAlignAndCutImage(std::string _name, CImageBasis *_org, CImageBasis *_temp) : CImageBasis(_name) { + name = _name; rgb_image = _org->rgb_image; channels = _org->channels; width = _org->width; @@ -37,7 +39,7 @@ bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2) int r0_x, r0_y, r1_x, r1_y; bool isSimilar1, isSimilar2; - CFindTemplate* ft = new CFindTemplate(rgb_image, channels, width, height, bpp); + CFindTemplate* ft = new CFindTemplate("align", rgb_image, channels, width, height, bpp); r0_x = _temp1->target_x; r0_y = _temp1->target_y; @@ -81,7 +83,7 @@ bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2) LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw); #endif*/ - CRotateImage rt(this, ImageTMP); + CRotateImage rt("Align", this, ImageTMP); rt.Translate(dx, dy); rt.Rotate(d_winkel, _temp1->target_x, _temp1->target_y); ESP_LOGD(TAG, "Alignment: dx %d - dy %d - rot %f", dx, dy, d_winkel); @@ -107,7 +109,7 @@ void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int d dy = y2 - y1; int memsize = dx * dy * channels; - uint8_t* odata = (unsigned char*) GET_MEMORY(memsize); + uint8_t* odata = (unsigned char*) malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); stbi_uc* p_target; stbi_uc* p_source; @@ -186,7 +188,7 @@ CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy) dy = y2 - y1; int memsize = dx * dy * channels; - uint8_t* odata = (unsigned char*)GET_MEMORY(memsize); + uint8_t* odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); stbi_uc* p_target; stbi_uc* p_source; @@ -202,7 +204,7 @@ CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy) p_target[_channels] = p_source[_channels]; } - CImageBasis* rs = new CImageBasis(odata, channels, dx, dy, bpp); + CImageBasis* rs = new CImageBasis("CutAndSave", odata, channels, dx, dy, bpp); RGBImageRelease(); rs->SetIndepended(); return rs; diff --git a/code/components/jomjol_image_proc/CAlignAndCutImage.h b/code/components/jomjol_image_proc/CAlignAndCutImage.h index 7267cce37..46f5016e4 100644 --- a/code/components/jomjol_image_proc/CAlignAndCutImage.h +++ b/code/components/jomjol_image_proc/CAlignAndCutImage.h @@ -12,9 +12,9 @@ class CAlignAndCutImage : public CImageBasis public: int t0_dx, t0_dy, t1_dx, t1_dy; CImageBasis *ImageTMP; - CAlignAndCutImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;}; - CAlignAndCutImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;}; - CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp); + CAlignAndCutImage(std::string name, std::string _image) : CImageBasis(name, _image) {ImageTMP = NULL;}; + CAlignAndCutImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;}; + CAlignAndCutImage(std::string name, CImageBasis *_org, CImageBasis *_temp); bool Align(RefInfo *_temp1, RefInfo *_temp2); // void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = ""); diff --git a/code/components/jomjol_image_proc/CFindTemplate.h b/code/components/jomjol_image_proc/CFindTemplate.h index b281f5026..14b0261b1 100644 --- a/code/components/jomjol_image_proc/CFindTemplate.h +++ b/code/components/jomjol_image_proc/CFindTemplate.h @@ -32,7 +32,7 @@ class CFindTemplate : public CImageBasis { public: int tpl_width, tpl_height, tpl_bpp; - CFindTemplate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {}; + CFindTemplate(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {}; bool FindTemplate(RefInfo *_ref); diff --git a/code/components/jomjol_image_proc/CImageBasis.cpp b/code/components/jomjol_image_proc/CImageBasis.cpp index a8637e3fa..ad6fee9d6 100644 --- a/code/components/jomjol_image_proc/CImageBasis.cpp +++ b/code/components/jomjol_image_proc/CImageBasis.cpp @@ -1,5 +1,6 @@ #include "CImageBasis.h" #include "Helper.h" +#include "psram.h" #include "ClassLogFile.h" #include "server_ota.h" @@ -360,8 +361,9 @@ void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int t } -CImageBasis::CImageBasis() +CImageBasis::CImageBasis(string _name) { + name = _name; externalImage = false; rgb_image = NULL; width = 0; @@ -384,8 +386,9 @@ void CImageBasis::CreateEmptyImage(int _width, int _height, int _channels) LogFile.WriteHeapInfo("CreateEmptyImage"); #endif - int memsize = width * height * channels; - rgb_image = (unsigned char*)GET_MEMORY(memsize); + memsize = width * height * channels; + + rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM); if (rgb_image == NULL) { @@ -435,8 +438,10 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len) { RGBImageLock(); - if (rgb_image) + if (rgb_image != NULL) { stbi_image_free(rgb_image); + //free_psram_heap(std::string(TAG) + "->rgb_image (LoadFromMemory)", rgb_image); + } rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3); bpp = channels; @@ -454,8 +459,9 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len) } -CImageBasis::CImageBasis(CImageBasis *_copyfrom) +CImageBasis::CImageBasis(string _name, CImageBasis *_copyfrom) { + name = _name; islocked = false; externalImage = false; channels = _copyfrom->channels; @@ -469,8 +475,9 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom) LogFile.WriteHeapInfo("CImageBasis_copyfrom - Start"); #endif - int memsize = width * height * channels; - rgb_image = (unsigned char*)GET_MEMORY(memsize); + memsize = width * height * channels; + + rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM); if (rgb_image == NULL) { @@ -489,8 +496,9 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom) } -CImageBasis::CImageBasis(int _width, int _height, int _channels) +CImageBasis::CImageBasis(string _name, int _width, int _height, int _channels) { + name = _name; islocked = false; externalImage = false; channels = _channels; @@ -504,8 +512,9 @@ CImageBasis::CImageBasis(int _width, int _height, int _channels) LogFile.WriteHeapInfo("CImageBasis_width,height,ch - Start"); #endif - int memsize = width * height * channels; - rgb_image = (unsigned char*)GET_MEMORY(memsize); + memsize = width * height * channels; + + rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM); if (rgb_image == NULL) { @@ -523,8 +532,9 @@ CImageBasis::CImageBasis(int _width, int _height, int _channels) } -CImageBasis::CImageBasis(std::string _image) +CImageBasis::CImageBasis(string _name, std::string _image) { + name = _name; islocked = false; channels = 3; externalImage = false; @@ -569,8 +579,9 @@ bool CImageBasis::ImageOkay(){ } -CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) +CImageBasis::CImageBasis(string _name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) { + name = _name; islocked = false; rgb_image = _rgb_image; channels = _channels; @@ -607,8 +618,10 @@ CImageBasis::~CImageBasis() { RGBImageLock(); - if (!externalImage) - stbi_image_free(rgb_image); + if (!externalImage) { + //stbi_image_free(rgb_image); + free_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ", " + to_string(memsize) + ")", rgb_image); + } RGBImageRelease(); } @@ -637,19 +650,19 @@ void CImageBasis::SaveToFile(std::string _imageout) void CImageBasis::Resize(int _new_dx, int _new_dy) { - int memsize = _new_dx * _new_dy * channels; - uint8_t* odata = (unsigned char*)GET_MEMORY(memsize); + memsize = _new_dx * _new_dy * channels; + uint8_t* odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); RGBImageLock(); stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels); - stbi_image_free(rgb_image); - rgb_image = (unsigned char*)GET_MEMORY(memsize); + rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis Resize (" + name + ")", memsize, MALLOC_CAP_SPIRAM); memCopy(odata, rgb_image, memsize); width = _new_dx; height = _new_dy; - stbi_image_free(odata); + + free_psram_heap(std::string(TAG) + "->odata", odata); RGBImageRelease(); } diff --git a/code/components/jomjol_image_proc/CImageBasis.h b/code/components/jomjol_image_proc/CImageBasis.h index eddf1cfd0..3f9c4b7fd 100644 --- a/code/components/jomjol_image_proc/CImageBasis.h +++ b/code/components/jomjol_image_proc/CImageBasis.h @@ -30,6 +30,8 @@ class CImageBasis protected: bool externalImage; std::string filename; + std::string name; // Just used for diagnostics + int memsize = 0; void memCopy(uint8_t* _source, uint8_t* _target, int _size); bool isInImage(int x, int y); @@ -37,7 +39,7 @@ class CImageBasis bool islocked; public: - uint8_t* rgb_image; + uint8_t* rgb_image = NULL; int channels; int width, height, bpp; @@ -64,11 +66,11 @@ class CImageBasis void EmptyImage(); - CImageBasis(); - CImageBasis(std::string _image); - CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp); - CImageBasis(int _width, int _height, int _channels); - CImageBasis(CImageBasis *_copyfrom); + CImageBasis(std::string name); + CImageBasis(std::string name, std::string _image); + CImageBasis(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp); + CImageBasis(std::string name, int _width, int _height, int _channels); + CImageBasis(std::string name, CImageBasis *_copyfrom); void Resize(int _new_dx, int _new_dy); void Resize(int _new_dx, int _new_dy, CImageBasis *_target); diff --git a/code/components/jomjol_image_proc/CRotateImage.cpp b/code/components/jomjol_image_proc/CRotateImage.cpp index 821c42690..12d441540 100644 --- a/code/components/jomjol_image_proc/CRotateImage.cpp +++ b/code/components/jomjol_image_proc/CRotateImage.cpp @@ -1,7 +1,10 @@ +#include #include "CRotateImage.h" +#include "psram.h" +static const char *TAG = "C ROTATE IMG"; -CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip) +CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_temp, bool _flip) : CImageBasis(_name) { rgb_image = _org->rgb_image; channels = _org->channels; @@ -15,6 +18,7 @@ CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip) doflip = _flip; } + void CRotateImage::Mirror(){ int memsize = width * height * channels; uint8_t* odata; @@ -24,7 +28,7 @@ void CRotateImage::Mirror(){ } else { - odata = (unsigned char*)GET_MEMORY(memsize); + odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); } @@ -50,7 +54,7 @@ void CRotateImage::Mirror(){ // memcpy(rgb_image, odata, memsize); memCopy(odata, rgb_image, memsize); if (!ImageTMP) - stbi_image_free(odata); + free_psram_heap(std::string(TAG) + "->odata", odata); if (ImageTMP) ImageTMP->RGBImageRelease(); @@ -109,7 +113,7 @@ void CRotateImage::Rotate(float _angle, int _centerx, int _centery) } else { - odata = (unsigned char*)GET_MEMORY(memsize); + odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); } @@ -148,7 +152,7 @@ void CRotateImage::Rotate(float _angle, int _centerx, int _centery) if (!ImageTMP) { - stbi_image_free(odata); + free_psram_heap(std::string(TAG) + "->odata", odata); } if (ImageTMP) ImageTMP->RGBImageRelease(); @@ -209,7 +213,7 @@ void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery) } else { - odata = (unsigned char*)GET_MEMORY(memsize); + odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); } @@ -269,7 +273,7 @@ void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery) if (!ImageTMP) { - stbi_image_free(odata); + free_psram_heap(std::string(TAG) + "->odata", odata); } if (ImageTMP) ImageTMP->RGBImageRelease(); @@ -300,7 +304,7 @@ void CRotateImage::Translate(int _dx, int _dy) } else { - odata = (unsigned char*)GET_MEMORY(memsize); + odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); } @@ -336,7 +340,7 @@ void CRotateImage::Translate(int _dx, int _dy) memCopy(odata, rgb_image, memsize); if (!ImageTMP) { - stbi_image_free(odata); + free_psram_heap(std::string(TAG) + "->odata", odata); } if (ImageTMP) diff --git a/code/components/jomjol_image_proc/CRotateImage.h b/code/components/jomjol_image_proc/CRotateImage.h index f4113f5ed..30c758d3d 100644 --- a/code/components/jomjol_image_proc/CRotateImage.h +++ b/code/components/jomjol_image_proc/CRotateImage.h @@ -8,12 +8,13 @@ class CRotateImage: public CImageBasis { + public: CImageBasis *ImageTMP, *ImageOrg; bool doflip; - CRotateImage(std::string _image, bool _flip = false) : CImageBasis(_image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; - CRotateImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; - CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip = false); + CRotateImage(std::string name, std::string _image, bool _flip = false) : CImageBasis(name, _image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; + CRotateImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; + CRotateImage(std::string name, CImageBasis *_org, CImageBasis *_temp, bool _flip = false); void Rotate(float _angle); void RotateAntiAliasing(float _angle); diff --git a/code/components/jomjol_mqtt/mqtt_outbox.c b/code/components/jomjol_mqtt/mqtt_outbox.c index 498ad7d64..c001a8b20 100644 --- a/code/components/jomjol_mqtt/mqtt_outbox.c +++ b/code/components/jomjol_mqtt/mqtt_outbox.c @@ -8,6 +8,10 @@ #include "esp_log.h" #include "esp_heap_caps.h" +/* Enable this to use the PSRAM for MQTT Publishing. + * This saves 10 kBytes of RAM, see https://github.com/jomjol/AI-on-the-edge-device/pull/2113 + * However we can run into PSRAM fragmentation issues, leading to insufficient large blocks to load the model. + * See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 */ #define USE_PSRAM #ifdef CONFIG_MQTT_CUSTOM_OUTBOX diff --git a/code/components/jomjol_tfliteclass/CTfLiteClass.cpp b/code/components/jomjol_tfliteclass/CTfLiteClass.cpp index 5d4ac844f..6a2d47114 100644 --- a/code/components/jomjol_tfliteclass/CTfLiteClass.cpp +++ b/code/components/jomjol_tfliteclass/CTfLiteClass.cpp @@ -1,6 +1,7 @@ #include "CTfLiteClass.h" #include "ClassLogFile.h" #include "Helper.h" +#include "psram.h" #include "esp_log.h" #include "../../include/defines.h" @@ -250,7 +251,7 @@ bool CTfLiteClass::ReadFileToModel(std::string _fn) LogFile.WriteHeapInfo("CTLiteClass::Alloc modelfile start"); #endif - modelfile = (unsigned char*)GET_MEMORY(size); + modelfile = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->modelfile", size, MALLOC_CAP_SPIRAM); if(modelfile != NULL) { @@ -305,17 +306,17 @@ CTfLiteClass::CTfLiteClass() this->input = nullptr; this->output = nullptr; this->kTensorArenaSize = 800 * 1024; /// according to testfile: 108000 - so far 600;; 2021-09-11: 200 * 1024 - this->tensor_arena = (uint8_t*)GET_MEMORY(kTensorArenaSize); + this->tensor_arena = (uint8_t*)malloc_psram_heap(std::string(TAG) + "->tensor_arena", kTensorArenaSize, MALLOC_CAP_SPIRAM); } CTfLiteClass::~CTfLiteClass() { - free(modelfile); - - free(this->tensor_arena); delete this->interpreter; delete this->error_reporter; + + free_psram_heap(std::string(TAG) + "->modelfile", modelfile); + free_psram_heap(std::string(TAG) + "->tensor_arena", this->tensor_arena); } diff --git a/code/components/jomjol_tfliteclass/server_tflite.cpp b/code/components/jomjol_tfliteclass/server_tflite.cpp index c22a30c22..68ed4d892 100644 --- a/code/components/jomjol_tfliteclass/server_tflite.cpp +++ b/code/components/jomjol_tfliteclass/server_tflite.cpp @@ -25,6 +25,7 @@ #include "read_wlanini.h" #include "connect_wlan.h" +#include "psram.h" ClassFlowControll tfliteflow; @@ -151,12 +152,12 @@ esp_err_t handler_get_heap(httpd_req_t *req) std::string zw = "Heap info:
" + getESPHeapInfo(); #ifdef TASK_ANALYSIS_ON - char* pcTaskList = (char*) heap_caps_calloc(1, sizeof(char) * 768, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + char* pcTaskList = (char*) calloc_psram_heap(std::string(TAG) + "->pcTaskList", 1, sizeof(char) * 768, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); if (pcTaskList) { vTaskList(pcTaskList); zw = zw + "

Task info:
Name | State | Prio | Lowest stacksize | Creation order | CPU (-1=NoAffinity)
" + std::string(pcTaskList) + "
"; - heap_caps_free(pcTaskList); + free_psram_heap(std::string(TAG) + "->pcTaskList", pcTaskList); } else { zw = zw + "

Task info:
ERROR - Allocation of TaskList buffer in PSRAM failed"; @@ -617,11 +618,11 @@ esp_err_t handler_editflow(httpd_req_t *req) string out2 = out.substr(0, out.length() - 4) + "_org.jpg"; - CAlignAndCutImage *caic = new CAlignAndCutImage(in); + CAlignAndCutImage *caic = new CAlignAndCutImage("cutref", in); caic->CutAndSave(out2, x, y, dx, dy); delete caic; - CImageBasis *cim = new CImageBasis(out2); + CImageBasis *cim = new CImageBasis("cutref", out2); if (enhance) { cim->Contrast(90); diff --git a/code/include/defines.h b/code/include/defines.h index 7dc831270..a64aeee0e 100644 --- a/code/include/defines.h +++ b/code/include/defines.h @@ -131,14 +131,8 @@ //CImageBasis #define HTTP_BUFFER_SENT 1024 - #define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM) #define MAX_JPG_SIZE 128000 - - //CAlignAndCutImage + CImageBasis - #define _USE_MATH_DEFINES - #define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM) - //make_stb + stb_image_resize + stb_image_write + stb_image //do not work if not in make_stb.cpp //#define STB_IMAGE_IMPLEMENTATION //#define STB_IMAGE_WRITE_IMPLEMENTATION diff --git a/code/sdkconfig.defaults b/code/sdkconfig.defaults index d2056178f..74abdd5c0 100644 --- a/code/sdkconfig.defaults +++ b/code/sdkconfig.defaults @@ -1,7 +1,7 @@ ################################################## # Application specific configuration # Edit this file instead of sdkconfig.esp32cam! -# After editting, make sure to explicitly delete +# After editing make sure to explicitly delete # sdkconfig.esp32cam to apply your changes! ################################################## @@ -94,6 +94,7 @@ CONFIG_SPIRAM_SPEED_40M=y CONFIG_SPIRAM=y CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_USE_MALLOC=y +#CONFIG_SPIRAM_USE_MEMMAP=y => Does not work: "cam_dma_config(306): frame buffer malloc failed" CONFIG_SPIRAM_MEMTEST=y CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=40960