[libcamera-devel,1/2] android: camera_capabilities: Add function to convert PixelFormat to android format
diff mbox series

Message ID 20211130124428.2163669-2-hiroh@chromium.org
State New
Headers show
Series
  • Use PlatfromFrameBufferAllocator in CameraStream
Related show

Commit Message

Hirokazu Honda Nov. 30, 2021, 12:44 p.m. UTC
This adds a function to CameraCapabilities of converting PixelFormat
to android format.

Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
---
 src/android/camera_capabilities.cpp | 18 ++++++++++++++++++
 src/android/camera_capabilities.h   |  2 ++
 2 files changed, 20 insertions(+)

Comments

Jacopo Mondi Nov. 30, 2021, 9:30 p.m. UTC | #1
Hi Hiro

On Tue, Nov 30, 2021 at 09:44:27PM +0900, Hirokazu Honda wrote:
> This adds a function to CameraCapabilities of converting PixelFormat
> to android format.
>
> Signed-off-by: Hirokazu Honda <hiroh@chromium.org>

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
  j

> ---
>  src/android/camera_capabilities.cpp | 18 ++++++++++++++++++
>  src/android/camera_capabilities.h   |  2 ++
>  2 files changed, 20 insertions(+)
>
> diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp
> index f357902e..4c1dc87c 100644
> --- a/src/android/camera_capabilities.cpp
> +++ b/src/android/camera_capabilities.cpp
> @@ -545,6 +545,7 @@ int CameraCapabilities::initializeStreamConfigurations()
>  		 */
>  		if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
>  			formatsMap_[androidFormat] = formats::MJPEG;
> +			revFormatsMap_[formats::MJPEG] = androidFormat;
>  			LOG(HAL, Debug) << "Mapped Android format "
>  					<< camera3Format.name << " to "
>  					<< formats::MJPEG.toString()
> @@ -596,6 +597,7 @@ int CameraCapabilities::initializeStreamConfigurations()
>  		 * stream configurations map, by testing the image resolutions.
>  		 */
>  		formatsMap_[androidFormat] = mappedFormat;
> +		revFormatsMap_[mappedFormat] = androidFormat;
>  		LOG(HAL, Debug) << "Mapped Android format "
>  				<< camera3Format.name << " to "
>  				<< mappedFormat.toString();
> @@ -1422,6 +1424,22 @@ PixelFormat CameraCapabilities::toPixelFormat(int format) const
>  	return it->second;
>  }
>
> +/*
> + * Translate libcamera pixel format to Android format code. -1 if no mapped
> + * android format is found.
> + */
> +int CameraCapabilities::toAndroidFormat(PixelFormat format) const
> +{
> +	auto it = revFormatsMap_.find(format);
> +	if (it == revFormatsMap_.end()) {
> +		LOG(HAL, Error) << "Requested format " << format.toString()
> +				<< " not supported";
> +		return -1;
> +	}
> +
> +	return it->second;
> +}
> +
>  std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateManual() const
>  {
>  	if (!capabilities_.count(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
> diff --git a/src/android/camera_capabilities.h b/src/android/camera_capabilities.h
> index 2cf97ae8..df6361f1 100644
> --- a/src/android/camera_capabilities.h
> +++ b/src/android/camera_capabilities.h
> @@ -30,6 +30,7 @@ public:
>
>  	CameraMetadata *staticMetadata() const { return staticMetadata_.get(); }
>  	libcamera::PixelFormat toPixelFormat(int format) const;
> +	int toAndroidFormat(libcamera::PixelFormat format) const;
>  	unsigned int maxJpegBufferSize() const { return maxJpegBufferSize_; }
>
>  	std::unique_ptr<CameraMetadata> requestTemplateManual() const;
> @@ -77,6 +78,7 @@ private:
>
>  	std::vector<Camera3StreamConfiguration> streamConfigurations_;
>  	std::map<int, libcamera::PixelFormat> formatsMap_;
> +	std::map<libcamera::PixelFormat, int> revFormatsMap_;
>  	std::unique_ptr<CameraMetadata> staticMetadata_;
>  	unsigned int maxJpegBufferSize_;
>
> --
> 2.34.0.rc2.393.gf8c9666880-goog
>
Laurent Pinchart Dec. 1, 2021, 2:26 a.m. UTC | #2
Hi Hiro,

Thank you for the patch.

On Tue, Nov 30, 2021 at 09:44:27PM +0900, Hirokazu Honda wrote:
> This adds a function to CameraCapabilities of converting PixelFormat
> to android format.
> 
> Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
> ---
>  src/android/camera_capabilities.cpp | 18 ++++++++++++++++++
>  src/android/camera_capabilities.h   |  2 ++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp
> index f357902e..4c1dc87c 100644
> --- a/src/android/camera_capabilities.cpp
> +++ b/src/android/camera_capabilities.cpp
> @@ -545,6 +545,7 @@ int CameraCapabilities::initializeStreamConfigurations()
>  		 */
>  		if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
>  			formatsMap_[androidFormat] = formats::MJPEG;
> +			revFormatsMap_[formats::MJPEG] = androidFormat;
>  			LOG(HAL, Debug) << "Mapped Android format "
>  					<< camera3Format.name << " to "
>  					<< formats::MJPEG.toString()
> @@ -596,6 +597,7 @@ int CameraCapabilities::initializeStreamConfigurations()
>  		 * stream configurations map, by testing the image resolutions.
>  		 */
>  		formatsMap_[androidFormat] = mappedFormat;
> +		revFormatsMap_[mappedFormat] = androidFormat;
>  		LOG(HAL, Debug) << "Mapped Android format "
>  				<< camera3Format.name << " to "
>  				<< mappedFormat.toString();
> @@ -1422,6 +1424,22 @@ PixelFormat CameraCapabilities::toPixelFormat(int format) const
>  	return it->second;
>  }
>  
> +/*
> + * Translate libcamera pixel format to Android format code. -1 if no mapped
> + * android format is found.
> + */
> +int CameraCapabilities::toAndroidFormat(PixelFormat format) const
> +{
> +	auto it = revFormatsMap_.find(format);
> +	if (it == revFormatsMap_.end()) {
> +		LOG(HAL, Error) << "Requested format " << format.toString()
> +				<< " not supported";
> +		return -1;
> +	}
> +
> +	return it->second;

I think there's a conceptual problem here. While a given Android format
can always be translated to a PixelFormat, the mapping isn't 1:1. We
already map different Android formats to NV21 for instance, and I expect
this to continue as we support more formats. A reverse map is thus
ill-defined, there's no guarantee that

	toAndroidFormat(toPixelFormat(format)) == format

which I think can lead to subtle bugs. Can't we instead, in the next
patch, get the Android format from camera3Stream_->format ?

> +}
> +
>  std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateManual() const
>  {
>  	if (!capabilities_.count(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
> diff --git a/src/android/camera_capabilities.h b/src/android/camera_capabilities.h
> index 2cf97ae8..df6361f1 100644
> --- a/src/android/camera_capabilities.h
> +++ b/src/android/camera_capabilities.h
> @@ -30,6 +30,7 @@ public:
>  
>  	CameraMetadata *staticMetadata() const { return staticMetadata_.get(); }
>  	libcamera::PixelFormat toPixelFormat(int format) const;
> +	int toAndroidFormat(libcamera::PixelFormat format) const;
>  	unsigned int maxJpegBufferSize() const { return maxJpegBufferSize_; }
>  
>  	std::unique_ptr<CameraMetadata> requestTemplateManual() const;
> @@ -77,6 +78,7 @@ private:
>  
>  	std::vector<Camera3StreamConfiguration> streamConfigurations_;
>  	std::map<int, libcamera::PixelFormat> formatsMap_;
> +	std::map<libcamera::PixelFormat, int> revFormatsMap_;
>  	std::unique_ptr<CameraMetadata> staticMetadata_;
>  	unsigned int maxJpegBufferSize_;
>
Hirokazu Honda Dec. 1, 2021, 7:28 a.m. UTC | #3
Hi Laurent, thank you for reviewing.

On Wed, Dec 1, 2021 at 11:26 AM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Hiro,
>
> Thank you for the patch.
>
> On Tue, Nov 30, 2021 at 09:44:27PM +0900, Hirokazu Honda wrote:
> > This adds a function to CameraCapabilities of converting PixelFormat
> > to android format.
> >
> > Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
> > ---
> >  src/android/camera_capabilities.cpp | 18 ++++++++++++++++++
> >  src/android/camera_capabilities.h   |  2 ++
> >  2 files changed, 20 insertions(+)
> >
> > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp
> > index f357902e..4c1dc87c 100644
> > --- a/src/android/camera_capabilities.cpp
> > +++ b/src/android/camera_capabilities.cpp
> > @@ -545,6 +545,7 @@ int CameraCapabilities::initializeStreamConfigurations()
> >                */
> >               if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
> >                       formatsMap_[androidFormat] = formats::MJPEG;
> > +                     revFormatsMap_[formats::MJPEG] = androidFormat;
> >                       LOG(HAL, Debug) << "Mapped Android format "
> >                                       << camera3Format.name << " to "
> >                                       << formats::MJPEG.toString()
> > @@ -596,6 +597,7 @@ int CameraCapabilities::initializeStreamConfigurations()
> >                * stream configurations map, by testing the image resolutions.
> >                */
> >               formatsMap_[androidFormat] = mappedFormat;
> > +             revFormatsMap_[mappedFormat] = androidFormat;
> >               LOG(HAL, Debug) << "Mapped Android format "
> >                               << camera3Format.name << " to "
> >                               << mappedFormat.toString();
> > @@ -1422,6 +1424,22 @@ PixelFormat CameraCapabilities::toPixelFormat(int format) const
> >       return it->second;
> >  }
> >
> > +/*
> > + * Translate libcamera pixel format to Android format code. -1 if no mapped
> > + * android format is found.
> > + */
> > +int CameraCapabilities::toAndroidFormat(PixelFormat format) const
> > +{
> > +     auto it = revFormatsMap_.find(format);
> > +     if (it == revFormatsMap_.end()) {
> > +             LOG(HAL, Error) << "Requested format " << format.toString()
> > +                             << " not supported";
> > +             return -1;
> > +     }
> > +
> > +     return it->second;
>
> I think there's a conceptual problem here. While a given Android format
> can always be translated to a PixelFormat, the mapping isn't 1:1. We
> already map different Android formats to NV21 for instance, and I expect
> this to continue as we support more formats. A reverse map is thus
> ill-defined, there's no guarantee that
>
>         toAndroidFormat(toPixelFormat(format)) == format
>
> which I think can lead to subtle bugs. Can't we instead, in the next
> patch, get the Android format from camera3Stream_->format ?
>

camera3Stream_->format is what Android HAL client requests.
From camera3Stream_->format, we decide to request configuration to camera.
Since the created buffer is the input to camera, its format must be
configuration().pixelFormat.
Both PlatformFrameBufferAllocator (gralloc and
cros::CameraBufferManager) demands android format.
Further, pixelFormat resolved from android format is dependent on the
backend implementation.
Therefore it is probably correct to lookup a proper android format
from pixelFormat.
But there is no such API in gralloc API and cros::CameraBufferManager.

-Hiro
> > +}
> > +
> >  std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateManual() const
> >  {
> >       if (!capabilities_.count(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
> > diff --git a/src/android/camera_capabilities.h b/src/android/camera_capabilities.h
> > index 2cf97ae8..df6361f1 100644
> > --- a/src/android/camera_capabilities.h
> > +++ b/src/android/camera_capabilities.h
> > @@ -30,6 +30,7 @@ public:
> >
> >       CameraMetadata *staticMetadata() const { return staticMetadata_.get(); }
> >       libcamera::PixelFormat toPixelFormat(int format) const;
> > +     int toAndroidFormat(libcamera::PixelFormat format) const;
> >       unsigned int maxJpegBufferSize() const { return maxJpegBufferSize_; }
> >
> >       std::unique_ptr<CameraMetadata> requestTemplateManual() const;
> > @@ -77,6 +78,7 @@ private:
> >
> >       std::vector<Camera3StreamConfiguration> streamConfigurations_;
> >       std::map<int, libcamera::PixelFormat> formatsMap_;
> > +     std::map<libcamera::PixelFormat, int> revFormatsMap_;
> >       std::unique_ptr<CameraMetadata> staticMetadata_;
> >       unsigned int maxJpegBufferSize_;
> >
>
> --
> Regards,
>
> Laurent Pinchart
Laurent Pinchart Dec. 6, 2021, 11:09 a.m. UTC | #4
Hi Hiro,

On Wed, Dec 01, 2021 at 04:28:07PM +0900, Hirokazu Honda wrote:
> On Wed, Dec 1, 2021 at 11:26 AM Laurent Pinchart wrote:
> > On Tue, Nov 30, 2021 at 09:44:27PM +0900, Hirokazu Honda wrote:
> > > This adds a function to CameraCapabilities of converting PixelFormat
> > > to android format.
> > >
> > > Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
> > > ---
> > >  src/android/camera_capabilities.cpp | 18 ++++++++++++++++++
> > >  src/android/camera_capabilities.h   |  2 ++
> > >  2 files changed, 20 insertions(+)
> > >
> > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp
> > > index f357902e..4c1dc87c 100644
> > > --- a/src/android/camera_capabilities.cpp
> > > +++ b/src/android/camera_capabilities.cpp
> > > @@ -545,6 +545,7 @@ int CameraCapabilities::initializeStreamConfigurations()
> > >                */
> > >               if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
> > >                       formatsMap_[androidFormat] = formats::MJPEG;
> > > +                     revFormatsMap_[formats::MJPEG] = androidFormat;
> > >                       LOG(HAL, Debug) << "Mapped Android format "
> > >                                       << camera3Format.name << " to "
> > >                                       << formats::MJPEG.toString()
> > > @@ -596,6 +597,7 @@ int CameraCapabilities::initializeStreamConfigurations()
> > >                * stream configurations map, by testing the image resolutions.
> > >                */
> > >               formatsMap_[androidFormat] = mappedFormat;
> > > +             revFormatsMap_[mappedFormat] = androidFormat;
> > >               LOG(HAL, Debug) << "Mapped Android format "
> > >                               << camera3Format.name << " to "
> > >                               << mappedFormat.toString();
> > > @@ -1422,6 +1424,22 @@ PixelFormat CameraCapabilities::toPixelFormat(int format) const
> > >       return it->second;
> > >  }
> > >
> > > +/*
> > > + * Translate libcamera pixel format to Android format code. -1 if no mapped
> > > + * android format is found.
> > > + */
> > > +int CameraCapabilities::toAndroidFormat(PixelFormat format) const
> > > +{
> > > +     auto it = revFormatsMap_.find(format);
> > > +     if (it == revFormatsMap_.end()) {
> > > +             LOG(HAL, Error) << "Requested format " << format.toString()
> > > +                             << " not supported";
> > > +             return -1;
> > > +     }
> > > +
> > > +     return it->second;
> >
> > I think there's a conceptual problem here. While a given Android format
> > can always be translated to a PixelFormat, the mapping isn't 1:1. We
> > already map different Android formats to NV21 for instance, and I expect
> > this to continue as we support more formats. A reverse map is thus
> > ill-defined, there's no guarantee that
> >
> >         toAndroidFormat(toPixelFormat(format)) == format
> >
> > which I think can lead to subtle bugs. Can't we instead, in the next
> > patch, get the Android format from camera3Stream_->format ?
> 
> camera3Stream_->format is what Android HAL client requests.
> From camera3Stream_->format, we decide to request configuration to camera.
> Since the created buffer is the input to camera, its format must be
> configuration().pixelFormat.
> Both PlatformFrameBufferAllocator (gralloc and
> cros::CameraBufferManager) demands android format.
> Further, pixelFormat resolved from android format is dependent on the
> backend implementation.
> Therefore it is probably correct to lookup a proper android format
> from pixelFormat.
> But there is no such API in gralloc API and cros::CameraBufferManager.

I understand that the gralloc and cros::CameraBufferManager APIs are
based on Android pixel formats and not on 4CCs. My concern is that the
CameraCapabilities::toAndroidFormat() function is meant to be generic,
but doesn't actually guarantee that

	toAndroidFormat(toPixelFormat(format)) == format

It's probably fine as-is for the specific use case of patch 2/2, but I
think it could cause issues if we start using it elsewhere.

If my understanding is correct, we can't really use
camera3Stream_->format in a generic way for internal streams. Because
internal streams are internal, they're not created directly from an
Android pixel format. At this time, we want to use post-processing to
produce

- JPEG streams, which we hardcode being produced from an internal NV12
  stream in case no compatible non-compressed streams is also requested.

- YUV streams, produced by scalign through libyuv, but without format
  conversion.

There may be other use cases in the future that would involve format
conversion, but I wonder if it wouldn't be best at this point to use the
Android pixel format directly in both cases instead of converting from a
libcamera pixel format.

> > > +}
> > > +
> > >  std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateManual() const
> > >  {
> > >       if (!capabilities_.count(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
> > > diff --git a/src/android/camera_capabilities.h b/src/android/camera_capabilities.h
> > > index 2cf97ae8..df6361f1 100644
> > > --- a/src/android/camera_capabilities.h
> > > +++ b/src/android/camera_capabilities.h
> > > @@ -30,6 +30,7 @@ public:
> > >
> > >       CameraMetadata *staticMetadata() const { return staticMetadata_.get(); }
> > >       libcamera::PixelFormat toPixelFormat(int format) const;
> > > +     int toAndroidFormat(libcamera::PixelFormat format) const;
> > >       unsigned int maxJpegBufferSize() const { return maxJpegBufferSize_; }
> > >
> > >       std::unique_ptr<CameraMetadata> requestTemplateManual() const;
> > > @@ -77,6 +78,7 @@ private:
> > >
> > >       std::vector<Camera3StreamConfiguration> streamConfigurations_;
> > >       std::map<int, libcamera::PixelFormat> formatsMap_;
> > > +     std::map<libcamera::PixelFormat, int> revFormatsMap_;
> > >       std::unique_ptr<CameraMetadata> staticMetadata_;
> > >       unsigned int maxJpegBufferSize_;
> > >
Hirokazu Honda Jan. 6, 2022, 5:28 a.m. UTC | #5
Thanks Laurent for the comment.

It sounds a good solution so far.
I also noticed Jacopo has merged a patch with your idea.
Thanks Jacopo.

Best Regards,
-Hiro

On Mon, Dec 6, 2021 at 8:09 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Hiro,
>
> On Wed, Dec 01, 2021 at 04:28:07PM +0900, Hirokazu Honda wrote:
> > On Wed, Dec 1, 2021 at 11:26 AM Laurent Pinchart wrote:
> > > On Tue, Nov 30, 2021 at 09:44:27PM +0900, Hirokazu Honda wrote:
> > > > This adds a function to CameraCapabilities of converting PixelFormat
> > > > to android format.
> > > >
> > > > Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
> > > > ---
> > > >  src/android/camera_capabilities.cpp | 18 ++++++++++++++++++
> > > >  src/android/camera_capabilities.h   |  2 ++
> > > >  2 files changed, 20 insertions(+)
> > > >
> > > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp
> > > > index f357902e..4c1dc87c 100644
> > > > --- a/src/android/camera_capabilities.cpp
> > > > +++ b/src/android/camera_capabilities.cpp
> > > > @@ -545,6 +545,7 @@ int CameraCapabilities::initializeStreamConfigurations()
> > > >                */
> > > >               if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
> > > >                       formatsMap_[androidFormat] = formats::MJPEG;
> > > > +                     revFormatsMap_[formats::MJPEG] = androidFormat;
> > > >                       LOG(HAL, Debug) << "Mapped Android format "
> > > >                                       << camera3Format.name << " to "
> > > >                                       << formats::MJPEG.toString()
> > > > @@ -596,6 +597,7 @@ int CameraCapabilities::initializeStreamConfigurations()
> > > >                * stream configurations map, by testing the image resolutions.
> > > >                */
> > > >               formatsMap_[androidFormat] = mappedFormat;
> > > > +             revFormatsMap_[mappedFormat] = androidFormat;
> > > >               LOG(HAL, Debug) << "Mapped Android format "
> > > >                               << camera3Format.name << " to "
> > > >                               << mappedFormat.toString();
> > > > @@ -1422,6 +1424,22 @@ PixelFormat CameraCapabilities::toPixelFormat(int format) const
> > > >       return it->second;
> > > >  }
> > > >
> > > > +/*
> > > > + * Translate libcamera pixel format to Android format code. -1 if no mapped
> > > > + * android format is found.
> > > > + */
> > > > +int CameraCapabilities::toAndroidFormat(PixelFormat format) const
> > > > +{
> > > > +     auto it = revFormatsMap_.find(format);
> > > > +     if (it == revFormatsMap_.end()) {
> > > > +             LOG(HAL, Error) << "Requested format " << format.toString()
> > > > +                             << " not supported";
> > > > +             return -1;
> > > > +     }
> > > > +
> > > > +     return it->second;
> > >
> > > I think there's a conceptual problem here. While a given Android format
> > > can always be translated to a PixelFormat, the mapping isn't 1:1. We
> > > already map different Android formats to NV21 for instance, and I expect
> > > this to continue as we support more formats. A reverse map is thus
> > > ill-defined, there's no guarantee that
> > >
> > >         toAndroidFormat(toPixelFormat(format)) == format
> > >
> > > which I think can lead to subtle bugs. Can't we instead, in the next
> > > patch, get the Android format from camera3Stream_->format ?
> >
> > camera3Stream_->format is what Android HAL client requests.
> > From camera3Stream_->format, we decide to request configuration to camera.
> > Since the created buffer is the input to camera, its format must be
> > configuration().pixelFormat.
> > Both PlatformFrameBufferAllocator (gralloc and
> > cros::CameraBufferManager) demands android format.
> > Further, pixelFormat resolved from android format is dependent on the
> > backend implementation.
> > Therefore it is probably correct to lookup a proper android format
> > from pixelFormat.
> > But there is no such API in gralloc API and cros::CameraBufferManager.
>
> I understand that the gralloc and cros::CameraBufferManager APIs are
> based on Android pixel formats and not on 4CCs. My concern is that the
> CameraCapabilities::toAndroidFormat() function is meant to be generic,
> but doesn't actually guarantee that
>
>         toAndroidFormat(toPixelFormat(format)) == format
>
> It's probably fine as-is for the specific use case of patch 2/2, but I
> think it could cause issues if we start using it elsewhere.
>
> If my understanding is correct, we can't really use
> camera3Stream_->format in a generic way for internal streams. Because
> internal streams are internal, they're not created directly from an
> Android pixel format. At this time, we want to use post-processing to
> produce
>
> - JPEG streams, which we hardcode being produced from an internal NV12
>   stream in case no compatible non-compressed streams is also requested.
>
> - YUV streams, produced by scalign through libyuv, but without format
>   conversion.
>
> There may be other use cases in the future that would involve format
> conversion, but I wonder if it wouldn't be best at this point to use the
> Android pixel format directly in both cases instead of converting from a
> libcamera pixel format.
>
> > > > +}
> > > > +
> > > >  std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateManual() const
> > > >  {
> > > >       if (!capabilities_.count(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
> > > > diff --git a/src/android/camera_capabilities.h b/src/android/camera_capabilities.h
> > > > index 2cf97ae8..df6361f1 100644
> > > > --- a/src/android/camera_capabilities.h
> > > > +++ b/src/android/camera_capabilities.h
> > > > @@ -30,6 +30,7 @@ public:
> > > >
> > > >       CameraMetadata *staticMetadata() const { return staticMetadata_.get(); }
> > > >       libcamera::PixelFormat toPixelFormat(int format) const;
> > > > +     int toAndroidFormat(libcamera::PixelFormat format) const;
> > > >       unsigned int maxJpegBufferSize() const { return maxJpegBufferSize_; }
> > > >
> > > >       std::unique_ptr<CameraMetadata> requestTemplateManual() const;
> > > > @@ -77,6 +78,7 @@ private:
> > > >
> > > >       std::vector<Camera3StreamConfiguration> streamConfigurations_;
> > > >       std::map<int, libcamera::PixelFormat> formatsMap_;
> > > > +     std::map<libcamera::PixelFormat, int> revFormatsMap_;
> > > >       std::unique_ptr<CameraMetadata> staticMetadata_;
> > > >       unsigned int maxJpegBufferSize_;
> > > >
>
> --
> Regards,
>
> Laurent Pinchart

Patch
diff mbox series

diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp
index f357902e..4c1dc87c 100644
--- a/src/android/camera_capabilities.cpp
+++ b/src/android/camera_capabilities.cpp
@@ -545,6 +545,7 @@  int CameraCapabilities::initializeStreamConfigurations()
 		 */
 		if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
 			formatsMap_[androidFormat] = formats::MJPEG;
+			revFormatsMap_[formats::MJPEG] = androidFormat;
 			LOG(HAL, Debug) << "Mapped Android format "
 					<< camera3Format.name << " to "
 					<< formats::MJPEG.toString()
@@ -596,6 +597,7 @@  int CameraCapabilities::initializeStreamConfigurations()
 		 * stream configurations map, by testing the image resolutions.
 		 */
 		formatsMap_[androidFormat] = mappedFormat;
+		revFormatsMap_[mappedFormat] = androidFormat;
 		LOG(HAL, Debug) << "Mapped Android format "
 				<< camera3Format.name << " to "
 				<< mappedFormat.toString();
@@ -1422,6 +1424,22 @@  PixelFormat CameraCapabilities::toPixelFormat(int format) const
 	return it->second;
 }
 
+/*
+ * Translate libcamera pixel format to Android format code. -1 if no mapped
+ * android format is found.
+ */
+int CameraCapabilities::toAndroidFormat(PixelFormat format) const
+{
+	auto it = revFormatsMap_.find(format);
+	if (it == revFormatsMap_.end()) {
+		LOG(HAL, Error) << "Requested format " << format.toString()
+				<< " not supported";
+		return -1;
+	}
+
+	return it->second;
+}
+
 std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateManual() const
 {
 	if (!capabilities_.count(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
diff --git a/src/android/camera_capabilities.h b/src/android/camera_capabilities.h
index 2cf97ae8..df6361f1 100644
--- a/src/android/camera_capabilities.h
+++ b/src/android/camera_capabilities.h
@@ -30,6 +30,7 @@  public:
 
 	CameraMetadata *staticMetadata() const { return staticMetadata_.get(); }
 	libcamera::PixelFormat toPixelFormat(int format) const;
+	int toAndroidFormat(libcamera::PixelFormat format) const;
 	unsigned int maxJpegBufferSize() const { return maxJpegBufferSize_; }
 
 	std::unique_ptr<CameraMetadata> requestTemplateManual() const;
@@ -77,6 +78,7 @@  private:
 
 	std::vector<Camera3StreamConfiguration> streamConfigurations_;
 	std::map<int, libcamera::PixelFormat> formatsMap_;
+	std::map<libcamera::PixelFormat, int> revFormatsMap_;
 	std::unique_ptr<CameraMetadata> staticMetadata_;
 	unsigned int maxJpegBufferSize_;