Added photo copying during the stream
parent
cee7ebc8ae
commit
ec7b7eabc7
|
|
@ -29,6 +29,8 @@ Camera::Camera(Configuration* i_conf, Logs* i_log, uint8_t i_FlashPin) {
|
|||
CameraFlashPin = i_FlashPin;
|
||||
StreamOnOff = false;
|
||||
frameBufferSemaphore = xSemaphoreCreateMutex();
|
||||
FrameBufferDuplicate = (camera_fb_t*)heap_caps_malloc(sizeof(camera_fb_t), MALLOC_CAP_SPIRAM);
|
||||
StreamSendingPhoto = false;
|
||||
|
||||
PhotoExifData.header = NULL;
|
||||
PhotoExifData.len = 0;
|
||||
|
|
@ -397,6 +399,13 @@ void Camera::CapturePhoto() {
|
|||
ledcWrite(FLASH_PWM_CHANNEL, FLASH_OFF_STATUS);
|
||||
}
|
||||
xSemaphoreGive(frameBufferSemaphore);
|
||||
|
||||
} else {
|
||||
/* Stream is on, set flag for sending photo */
|
||||
if (xSemaphoreTake(frameBufferSemaphore, portMAX_DELAY)) {
|
||||
StreamSendingPhoto = true;
|
||||
xSemaphoreGive(frameBufferSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reinit camera module if photo capture failed */
|
||||
|
|
@ -426,6 +435,40 @@ void Camera::CaptureStream(camera_fb_t* i_buf) {
|
|||
/* check if photo is correctly saved */
|
||||
} while (!(FrameBuffer->len > 100));
|
||||
*i_buf = *FrameBuffer;
|
||||
|
||||
/* copy the frame buffer to the duplicate frame buffer. For sending photo to Prusa Connect */
|
||||
if (false == StreamSendingPhoto) {
|
||||
/* memory allocation release */
|
||||
if (FrameBufferDuplicate != NULL) {
|
||||
if (FrameBufferDuplicate->buf != NULL) {
|
||||
free(FrameBufferDuplicate->buf);
|
||||
FrameBufferDuplicate->buf = NULL; /* Set to NULL after freeing */
|
||||
}
|
||||
|
||||
free(FrameBufferDuplicate);
|
||||
FrameBufferDuplicate = NULL; /* Set to NULL after freeing */
|
||||
}
|
||||
|
||||
/* Allocate memory for the duplicate frame structure */
|
||||
FrameBufferDuplicate = (camera_fb_t*)heap_caps_malloc(sizeof(camera_fb_t), MALLOC_CAP_SPIRAM);
|
||||
|
||||
/* Copy the metadata */
|
||||
memcpy(FrameBufferDuplicate, FrameBuffer, sizeof(camera_fb_t));
|
||||
|
||||
/* Allocate memory for the image data */
|
||||
FrameBufferDuplicate->buf = (uint8_t*)heap_caps_malloc(FrameBuffer->len, MALLOC_CAP_SPIRAM);
|
||||
|
||||
/* Check if memory allocation was successful */
|
||||
if (!FrameBufferDuplicate->buf) {
|
||||
/* Handle error */
|
||||
free(FrameBufferDuplicate);
|
||||
Serial.println("Failed to allocate memory for the duplicate frame buffer");
|
||||
} else {
|
||||
/* Copy the image data */
|
||||
memcpy(FrameBufferDuplicate->buf, FrameBuffer->buf, FrameBuffer->len);
|
||||
}
|
||||
}
|
||||
|
||||
xSemaphoreGive(frameBufferSemaphore);
|
||||
}
|
||||
}
|
||||
|
|
@ -508,6 +551,15 @@ void Camera::StreamClearFrameData() {
|
|||
StreamAverageSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Set Sending Photo for Stream
|
||||
@param bool - sending photo
|
||||
@return none
|
||||
*/
|
||||
void Camera::StreamSetSendingPhoto(bool i_data) {
|
||||
StreamSendingPhoto = i_data;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get Photo
|
||||
@param none
|
||||
|
|
@ -530,6 +582,15 @@ camera_fb_t* Camera::GetPhotoFb() {
|
|||
return FrameBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get Photo Frame Buffer Duplicate
|
||||
@param none
|
||||
@return camera_fb_t* - photo frame buffer duplicate
|
||||
*/
|
||||
camera_fb_t* Camera::GetPhotoFbDuplicate() {
|
||||
return FrameBufferDuplicate;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get Photo Exif Data
|
||||
@param none
|
||||
|
|
|
|||
|
|
@ -68,9 +68,11 @@ private:
|
|||
/* OV2640 camera module pinout and cfg*/
|
||||
camera_config_t CameraConfig; ///< camera configuration
|
||||
camera_fb_t *FrameBuffer; ///< frame buffer
|
||||
camera_fb_t *FrameBufferDuplicate; ///< frame buffer duplicate
|
||||
sensor_t* sensor; ///< sensor
|
||||
String Photo; ///< photo in string format
|
||||
bool StreamOnOff; ///< stream on/off
|
||||
bool StreamSendingPhoto; ///< sending photo to Prusa Connect during stream
|
||||
SemaphoreHandle_t frameBufferSemaphore; ///< semaphore for frame buffer
|
||||
float StreamAverageFps; ///< stream average fps
|
||||
uint16_t StreamAverageSize; ///< stream average size
|
||||
|
|
@ -104,6 +106,7 @@ public:
|
|||
uint16_t StreamGetFrameAverageSize();
|
||||
float StreamGetFrameAverageFps();
|
||||
void StreamClearFrameData();
|
||||
void StreamSetSendingPhoto(bool);
|
||||
|
||||
void CopyPhoto(camera_fb_t *);
|
||||
void CopyPhoto(String*);
|
||||
|
|
@ -112,6 +115,7 @@ public:
|
|||
int GetPhotoSize();
|
||||
String GetPhoto();
|
||||
camera_fb_t *GetPhotoFb();
|
||||
camera_fb_t* GetPhotoFbDuplicate();
|
||||
PhotoExifData_t * GetPhotoExifData();
|
||||
framesize_t TransformFrameSizeDataType(uint8_t);
|
||||
void SetPhotoSending(bool);
|
||||
|
|
|
|||
|
|
@ -126,8 +126,17 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i
|
|||
|
||||
/* get photo buffer */
|
||||
bool SendWithExif = false;
|
||||
uint8_t *fbBuf = camera->GetPhotoFb()->buf;
|
||||
size_t fbLen = camera->GetPhotoFb()->len;
|
||||
uint8_t *fbBuf = NULL;
|
||||
size_t fbLen = 0;
|
||||
if (camera->GetStreamStatus() == true) {
|
||||
/* get duplicate photo buffer from camera */
|
||||
fbBuf = camera->GetPhotoFbDuplicate()->buf;
|
||||
fbLen = camera->GetPhotoFbDuplicate()->len;
|
||||
} else {
|
||||
/* get original photo buffer from camera */
|
||||
fbBuf = camera->GetPhotoFb()->buf;
|
||||
fbLen = camera->GetPhotoFb()->len;
|
||||
}
|
||||
|
||||
/* sending exif data */
|
||||
if ((camera->GetPhotoExifData()->header != NULL) && (camera->GetStreamStatus() == false)) {
|
||||
|
|
@ -235,8 +244,10 @@ void PrusaConnect::SendPhotoToBackend() {
|
|||
|
||||
if ((camera->GetPhotoExifData()->header != NULL) && (camera->GetStreamStatus() == false)) {
|
||||
total_len = camera->GetPhotoExifData()->len + camera->GetPhotoFb()->len - camera->GetPhotoExifData()->offset;
|
||||
} else {
|
||||
} else if (camera->GetStreamStatus() == false) {
|
||||
total_len = camera->GetPhotoFb()->len;
|
||||
} else {
|
||||
total_len = camera->GetPhotoFbDuplicate()->len;
|
||||
}
|
||||
SendDataToBackend(&Photo, total_len, F("image/jpg"), F("Photo"), HOST_URL_CAM_PATH, SendPhoto);
|
||||
camera->SetPhotoSending(false);
|
||||
|
|
@ -302,8 +313,13 @@ void PrusaConnect::TakePictureAndSendToBackend() {
|
|||
log->AddEvent(LogLevel_Error, F("Error capturing photo. Stop sending to backend!"));
|
||||
}
|
||||
|
||||
/* return frame buffer */
|
||||
if (camera->GetStreamStatus() == false) {
|
||||
/* return frame buffer when photo is not sent during stream */
|
||||
camera->CaptureReturnFrameBuffer();
|
||||
} else {
|
||||
/* set stream flag for sending photo to false */
|
||||
camera->StreamSetSendingPhoto(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue