[libcamera-devel] [PATCH 5/8] android: camera_device: Calculate metadata size
Jacopo Mondi
jacopo at jmondi.org
Thu Jun 4 14:38:56 CEST 2020
Hi Laurent,
On Thu, Jun 04, 2020 at 05:39:42AM +0300, Laurent Pinchart wrote:
> Hi Jacopo,
>
> Thank you for the patch.
>
> On Tue, May 26, 2020 at 04:22:34PM +0200, Jacopo Mondi wrote:
> > As we move to have more and more dynamically generated static metadata
> > entries, the size of the metadata buffer has to be calculated
> > dynamically inspecting the information collected from the camera.
> >
> > Provide a method to perform metadata buffers size calculation and
> > use it when generating camera static metadata.
> >
> > Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> > ---
> > src/android/camera_device.cpp | 42 ++++++++++++++++++++++++++++++-----
> > src/android/camera_device.h | 2 ++
> > 2 files changed, 38 insertions(+), 6 deletions(-)
> >
> > diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> > index 534bfb1df1ef..6cc377820210 100644
> > --- a/src/android/camera_device.cpp
> > +++ b/src/android/camera_device.cpp
> > @@ -331,6 +331,40 @@ void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
> > /*
> > * Return static information for the camera.
> > */
> > +std::pair<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
> > +{
> > + /*
> > + * \todo Keep this in sync with the actual number of entries.
> > + * Currently: 50 entries, 647 bytes of static metadata
> > + */
> > + std::pair<uint32_t, uint32_t> metadataSize;
> > + metadataSize.first = 50;
> > + metadataSize.second = 647;
> > +
>
> Do you think we will end up reworking the CameraMetadata class to avoid
> pre-allocation ?
>
How so ? If I'm not mistaken the Android camera_metadata library we
wrap requires pre-allocation.
We could add all metadata one by one to a temporary storage in CameraMetadata,
and calculate the size requirements as we add them. When done we could
write them to camera_metadata... I'm not sure it's worth the effort
though..
> > + /*
> > + * Calculate space occupation in bytes for dynamically built metadata
> > + * entries.
> > + */
> > +
> > + /* std::forward_list does not provide a size() method :( */
>
> Let's make it a vector :-)
>
> > + for (const auto &entry : streamConfigurations_) {
> > + /* Just please the compiler, otherwise entry is not used. */
> > + switch (entry.androidScalerCode) {
> > + default:
> > + break;
> > + }
>
> This hack can be dropped if you use a vector.
>
Yes indeed, much better
> > +
> > + /*
> > + * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
> > + * 1 32bits integer for ANDROID_SCALER_AVAILABLE_FORMATS
> > + * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
> > + */
> > + metadataSize.second += 52;
> > + }
>
> We currently have 700 bytes, with a comment stating 666 bytes, and the
666 ( \m/ ) was mentioned in a removed comment as well as 700 bytes (I
guess we were 'larger' on purpose).
> code here will return 699 bytes when there's a single stream
> configuration. Which of those, if any, is correct ? :-) Could you add a
> note about this to the commit message ?
What's now reported is that we currently have 50 entries and 647 bytes
of static information, plus 52 bytes for each stream configuration
entry. Not sure what's wrong there.
>
> > +
> > + return metadataSize;
> > +}
> > +
> > const camera_metadata_t *CameraDevice::getStaticMetadata()
> > {
> > if (staticMetadata_)
> > @@ -341,12 +375,8 @@ const camera_metadata_t *CameraDevice::getStaticMetadata()
> > * example application, but a real camera implementation will require
> > * more.
> > */
> > -
> > - /*
> > - * \todo Keep this in sync with the actual number of entries.
> > - * Currently: 50 entries, 666 bytes
> > - */
> > - staticMetadata_ = new CameraMetadata(50, 700);
> > + const std::pair<uint32_t, uint32_t> sizes = calculateStaticMetadataSize();
> > + staticMetadata_ = new CameraMetadata(sizes.first, sizes.second);
>
> Returning a pair is confusing, we could easily swap the first and second
> arguments. Creating a struct would be best, but maybe using a std::tuple
> could be an acceptable solution as you could write
>
> uint32_t numEntries;
> uint32_t numBytes;
> std::tie(numEntries, numBytes) = calculateStaticMetadataSize();
>
> There's still a possibility of swapping the arguments, but at least
> they're not called first and second.
Well, that's not API code, but if it makes you sleep more peacefully I
could try with a tuple.
>
> > if (!staticMetadata_->isValid()) {
> > LOG(HAL, Error) << "Failed to allocate static metadata";
> > delete staticMetadata_;
> > diff --git a/src/android/camera_device.h b/src/android/camera_device.h
> > index 95bd39f590ab..f22a6e3e6c28 100644
> > --- a/src/android/camera_device.h
> > +++ b/src/android/camera_device.h
> > @@ -10,6 +10,7 @@
> > #include <forward_list>
> > #include <map>
> > #include <memory>
> > +#include <utility>
> >
> > #include <hardware/camera3.h>
> >
> > @@ -69,6 +70,7 @@ private:
> > };
> >
> > int initializeFormats();
> > + std::pair<uint32_t, uint32_t> calculateStaticMetadataSize();
> > void notifyShutter(uint32_t frameNumber, uint64_t timestamp);
> > void notifyError(uint32_t frameNumber, camera3_stream_t *stream);
> > std::unique_ptr<CameraMetadata> getResultMetadata(int frame_number,
>
> --
> Regards,
>
> Laurent Pinchart
More information about the libcamera-devel
mailing list