[PATCH v4 5/7] android: Drop notify CAMERA3_MSG_ERROR_REQUEST when a request fails

Cheng-Hao Yang chenghaoyang at chromium.org
Thu Dec 12 10:16:01 CET 2024


Hi Jacopo,

On Wed, Dec 11, 2024 at 7:06 PM Jacopo Mondi
<jacopo.mondi at ideasonboard.com> wrote:
>
> Hi Harvey
>
> On Tue, Dec 10, 2024 at 02:23:58PM +0000, Harvey Yang wrote:
> > According to Android Camera API v3.2, CAMERA3_MSG_ERROR_REQUEST is used
> > for requests that have not done any processing. When a request is
> > completed with failure, CAMERA3_MSG_ERROR_RESULT should be used instead.
> >
> > To avoid code duplication, when CameraMetadata cannot be generated,
> > CAMERA3_MSG_ERROR_RESULT is notified after process_capture_result.
> >
> > Signed-off-by: Han-Lin Chen <hanlinchen at chromium.org>
> > Co-developed-by: Harvey Yang <chenghaoyang at chromium.org>
> > Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
> > ---
> >  src/android/camera_device.cpp | 40 ++++++++++++++++++++++++++++-------
> >  1 file changed, 32 insertions(+), 8 deletions(-)
> >
> > diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> > index f3f570544..3b10f207e 100644
> > --- a/src/android/camera_device.cpp
> > +++ b/src/android/camera_device.cpp
> > @@ -1182,6 +1182,18 @@ void CameraDevice::requestComplete(Request *request)
> >        * post-processing/compression fails.
> >        */
> >       for (auto &buffer : descriptor->buffers_) {
> > +             for (auto &[_, frameBuffer] : request->buffers()) {
>
> I've been thinking about ways to avoid the double lookup here, we
> don't have that many requests or descriptor, but avoiding doing it for every
> request might be desirable.
>
> I've been trying to do so by setting a pointer to a StreamBuffer as
> libcamera::FrameBuffer::cookie and retrieve it here. However, as
> now multiple Android streams can map to the same FrameBuffer there's
> no 1-to-1 association anymore between a StreamBuffer and a
> FrameBuffer...
>
> Too bad, I would have liked to avoid this

Yeah, unless we introduce new member variables, it's hard to fix it here.

I don't think we need to worry about this too much, as the upcoming
bufferCompleted only allows source buffers to be completed one by one.

>
> > +                     if (buffer.srcBuffer != frameBuffer &&
> > +                         buffer.frameBuffer.get() != frameBuffer)
> > +                             continue;
> > +
> > +                     StreamBuffer::Status status = StreamBuffer::Status::Success;
> > +                     if (frameBuffer->metadata().status != FrameMetadata::FrameSuccess) {
> > +                             status = StreamBuffer::Status::Error;
> > +                     }
>
> No {} for single line statements

Done

>
> > +                     setBufferStatus(buffer, status);
> > +             }
> > +
> >               CameraStream *stream = buffer.stream;
>
> Can you move this after the comment block if you have to resend ?

Sure

>
> >
> >               /*
> > @@ -1198,22 +1210,18 @@ void CameraDevice::requestComplete(Request *request)
> >                       if (fence)
> >                               buffer.fence = fence->release();
> >               }
> > -             buffer.status = StreamBuffer::Status::Success;
> >       }
> >
> >       /*
> > -      * If the Request has failed, abort the request by notifying the error
> > -      * and complete the request with all buffers in error state.
> > +      * If the Request has failed, complete the request with all buffers in
> > +      * error state and notify an error result.
>
> With this patch buffers are completed indivdually in error state just
> below. I would move the below if() before inspecting the single
> buffers or even drop it completely and just rely on the above loop, after
> all if one buffer has failed the whole request has failed and you now
> set its state to Camera3RequestDescriptor::Status::Error in the above
> call to setBufferStatus()

Yeah the comment doesn't make sense anymore. Let's remove it.

>
> >        */
> >       if (request->status() != Request::RequestComplete) {
> >               LOG(HAL, Error) << "Request " << request->cookie()
> >                               << " not successfully completed: "
> >                               << request->status();
> >
> > -             abortRequest(descriptor);
> > -             completeDescriptor(descriptor);
> > -
> > -             return;
> > +             descriptor->status_ = Camera3RequestDescriptor::Status::Error;
> >       }
> >
> >       /*
> > @@ -1238,7 +1246,7 @@ void CameraDevice::requestComplete(Request *request)
> >        */
> >       descriptor->resultMetadata_ = getResultMetadata(*descriptor);
> >       if (!descriptor->resultMetadata_) {
> > -             notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_RESULT);
> > +             descriptor->status_ = Camera3RequestDescriptor::Status::Error;
> >
> >               /*
> >                * The camera framework expects an empty metadata pack on error.
> > @@ -1271,7 +1279,13 @@ void CameraDevice::requestComplete(Request *request)
> >                       continue;
> >               }
> >
> > +             if (buffer->status == StreamBuffer::Status::Error) {
> > +                     iter = descriptor->pendingStreamsToProcess_.erase(iter);
> > +                     continue;
> > +             }
>
> nit: could you move this before the previous if() ? There's no point
> in searching the FrameBuffer if we know the stream has failed ?

Right, done.

>
> > +
> >               ++iter;
> > +
> >               int ret = stream->process(buffer);
> >               if (ret) {
> >                       setBufferStatus(*buffer, StreamBuffer::Status::Error);
> > @@ -1324,6 +1338,16 @@ void CameraDevice::sendCaptureResults()
> >               descriptors_.pop();
> >
> >               sendCaptureResult(descriptor.get());
> > +
> > +             /*
> > +              * Call notify with CAMERA3_MSG_ERROR_RESULT to indicate some
> > +              * of the expected result metadata might not be available
>
> metdata and buffers ?

Sure, updated.

>
> > +              * because the capture is cancelled by the camera. Only notify
> > +              * it when the final result is sent, since Android will ignore
> > +              * the following metadata.
> > +              */
>
> I would drop "since ..."

Done

BR,
Harvey

>
> All minors, next one should be good to go
>
> Thanks
>   j
>
> > +             if (descriptor->status_ == Camera3RequestDescriptor::Status::Error)
> > +                     notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_RESULT);
> >       }
> >  }
> >
> > --
> > 2.47.0.338.g60cca15819-goog
> >


More information about the libcamera-devel mailing list