@@ -266,6 +266,12 @@ void LibCameraWorker::captureImage() {
266266 return ;
267267 }
268268
269+ // Reset retry count and queue first capture request
270+ mCaptureRetryCount = 0 ;
271+ queueCaptureRequest ();
272+ }
273+
274+ void LibCameraWorker::queueCaptureRequest () {
269275 // Create and queue capture request
270276 std::unique_ptr<Request> request = mCamera ->createRequest ();
271277 if (!request) {
@@ -319,24 +325,63 @@ void LibCameraWorker::captureImage() {
319325 return ;
320326 }
321327
322- qDebug () << " [INFO] Capture request queued successfully" ;
328+ qDebug () << " [INFO] Capture request queued successfully (retry: " << mCaptureRetryCount << " ) " ;
323329 // Completion will be handled by processCaptureComplete
324330}
325331
326332void LibCameraWorker::processCaptureComplete (Request *request) {
327- qDebug () << " [DEBUG] processCaptureComplete called, status:" << request->status ();
333+ qDebug () << " [DEBUG] processCaptureComplete called, request_status:" << request->status ();
334+
335+ // Return buffer to free list first
336+ const std::map<const Stream *, FrameBuffer *> &buffers = request->buffers ();
337+ {
338+ std::lock_guard<std::mutex> lock (mBufferMutex );
339+ for (auto it = buffers.begin (); it != buffers.end (); ++it) {
340+ mBuffersInFlight .erase (it->second );
341+ mFreeBuffers .push_back (it->second );
342+ }
343+ }
328344
329- if (request->status () != Request::RequestCancelled) {
330- if (!request->buffers ().empty ()) {
331- QImage img = convertBufferToImage (request->buffers ());
332- if (!img.isNull ()) {
333- Q_EMIT imageCaptured (img);
345+ if (request->status () == Request::RequestCancelled) {
346+ qDebug () << " [DEBUG] Request was cancelled" ;
347+ Q_EMIT captureCompleted ();
348+ return ;
349+ }
350+
351+ // Check frame metadata status
352+ if (!buffers.empty ()) {
353+ FrameBuffer *buffer = buffers.begin ()->second ;
354+ const FrameMetadata &metadata = buffer->metadata ();
355+
356+ // If frame has error, retry up to 5 times
357+ if (metadata.status != 0 ) {
358+ qDebug () << " [WARNING] Frame has error status:" << metadata.status << " , retrying..." ;
359+ mCaptureRetryCount ++;
360+ if (mCaptureRetryCount < 5 ) {
361+ // Queue another capture request
362+ queueCaptureRequest ();
363+ return ;
334364 } else {
335- Q_EMIT errorOccurred (" libcamera: failed to convert capture buffer" );
365+ qDebug () << " [ERROR] Max capture retries exceeded" ;
366+ Q_EMIT errorOccurred (" libcamera: capture failed after 5 retries" );
367+ Q_EMIT captureCompleted ();
368+ return ;
336369 }
370+ }
371+ }
372+
373+ // Reset retry count on success
374+ mCaptureRetryCount = 0 ;
375+
376+ if (!buffers.empty ()) {
377+ QImage img = convertBufferToImage (buffers);
378+ if (!img.isNull ()) {
379+ Q_EMIT imageCaptured (img);
337380 } else {
338- Q_EMIT errorOccurred (" libcamera: capture request has no buffers " );
381+ Q_EMIT errorOccurred (" libcamera: failed to convert capture buffer " );
339382 }
383+ } else {
384+ Q_EMIT errorOccurred (" libcamera: capture request has no buffers" );
340385 }
341386
342387 // Emit signal to trigger resume on Qt thread
@@ -497,6 +542,13 @@ QImage LibCameraWorker::convertBufferToImage(
497542 << " num_planes=" << planes.size ()
498543 << " metadata_status=" << metadata.status ;
499544
545+ // Check frame status - 0=Success, 1=Error, 2=Cancelled
546+ if (metadata.status != 0 ) {
547+ qDebug () << " [WARNING] Frame has error status:" << metadata.status
548+ << " (0=Success, 1=Error, 2=Cancelled)" ;
549+ // Continue anyway to see what we get, but the data may be corrupted
550+ }
551+
500552 for (size_t i = 0 ; i < planes.size () && i < metadata.planes ().size (); i++) {
501553 qDebug () << " [DEBUG] Plane" << i << " : fd=" << planes[i].fd .get ()
502554 << " offset=" << planes[i].offset
0 commit comments