[{"id":22800,"web_url":"https://patchwork.libcamera.org/comment/22800/","msgid":"<YmiHPGP6G0fTeXOb@pendragon.ideasonboard.com>","date":"2022-04-26T23:58:52","subject":"Re: [libcamera-devel] [PATCH v3 4/4] Add JEA implementation","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Harvey,\n\nThank you for the patch.\n\nOn Tue, Apr 26, 2022 at 09:14:09AM +0000, Harvey Yang via libcamera-devel wrote:\n> This CL adds JEA implementation to replace Lib Jpeg in cros platform,\n> where HW accelerator is available.\n> \n> Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>\n> ---\n>  src/android/cros/camera3_hal.cpp              |  3 +\n>  src/android/jpeg/cros_post_processor_jpeg.cpp | 14 ++++\n>  src/android/jpeg/encoder_jea.cpp              | 82 +++++++++++++++++++\n>  src/android/jpeg/encoder_jea.h                | 35 ++++++++\n>  src/android/jpeg/meson.build                  | 13 ++-\n>  5 files changed, 144 insertions(+), 3 deletions(-)\n>  create mode 100644 src/android/jpeg/cros_post_processor_jpeg.cpp\n>  create mode 100644 src/android/jpeg/encoder_jea.cpp\n>  create mode 100644 src/android/jpeg/encoder_jea.h\n> \n> diff --git a/src/android/cros/camera3_hal.cpp b/src/android/cros/camera3_hal.cpp\n> index fb863b5f..ea5577f0 100644\n> --- a/src/android/cros/camera3_hal.cpp\n> +++ b/src/android/cros/camera3_hal.cpp\n> @@ -9,8 +9,11 @@\n>  \n>  #include \"../camera_hal_manager.h\"\n>  \n> +cros::CameraMojoChannelManagerToken *g_cros_camera_token = nullptr;\n\ngCrosCameraToken to match the coding style, but I'd name the variable\ngCrosMojoToken to make it clearer it refers to mojo.\n\n> +\n>  static void set_up([[maybe_unused]] cros::CameraMojoChannelManagerToken *token)\n>  {\n> +\tg_cros_camera_token = token;\n>  }\n>  \n>  static void tear_down()\n> diff --git a/src/android/jpeg/cros_post_processor_jpeg.cpp b/src/android/jpeg/cros_post_processor_jpeg.cpp\n> new file mode 100644\n> index 00000000..7020f0d0\n> --- /dev/null\n> +++ b/src/android/jpeg/cros_post_processor_jpeg.cpp\n> @@ -0,0 +1,14 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2022, Google Inc.\n> + *\n> + * cros_post_processor_jpeg.cpp - CrOS JPEG Post Processor\n> + */\n> +\n> +#include \"encoder_jea.h\"\n> +#include \"post_processor_jpeg.h\"\n> +\n> +void PostProcessorJpeg::SetEncoder()\n> +{\n> +\tencoder_ = std::make_unique<EncoderJea>();\n> +}\n> diff --git a/src/android/jpeg/encoder_jea.cpp b/src/android/jpeg/encoder_jea.cpp\n> new file mode 100644\n> index 00000000..838e8647\n> --- /dev/null\n> +++ b/src/android/jpeg/encoder_jea.cpp\n> @@ -0,0 +1,82 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2022, Google Inc.\n> + *\n> + * encoder_jea.cpp - JPEG encoding using CrOS JEA\n> + */\n> +\n> +#include \"encoder_jea.h\"\n> +\n> +#include <libcamera/base/log.h>\n> +\n> +#include \"libcamera/internal/mapped_framebuffer.h\"\n> +\n> +#include <cros-camera/camera_mojo_channel_manager_token.h>\n> +\n> +#include \"../android_framebuffer.h\"\n> +\n> +extern cros::CameraMojoChannelManagerToken *g_cros_camera_token;\n\nPlease add this to a header file as appropriate.\n\n> +\n> +EncoderJea::EncoderJea() = default;\n> +\n> +EncoderJea::~EncoderJea() = default;\n> +\n> +int EncoderJea::configure(const libcamera::StreamConfiguration &cfg)\n> +{\n> +\tsize_ = cfg.size;\n> +\n> +\tif (jpeg_compressor_.get())\n\nYou can write\n\n\tif (jpeg_compressor_)\n\nSame below.\n\n> +\t\treturn 0;\n> +\n> +\tif (g_cros_camera_token == nullptr)\n> +\t\treturn -ENOTSUP;\n> +\n> +\tjpeg_compressor_ = cros::JpegCompressor::GetInstance(g_cros_camera_token);\n> +\n> +\treturn 0;\n> +}\n> +\n> +int EncoderJea::encode(Camera3RequestDescriptor::StreamBuffer *streamBuffer,\n> +\t\t       libcamera::Span<const uint8_t> exifData,\n> +\t\t       unsigned int quality)\n> +{\n> +\tif (!jpeg_compressor_.get())\n> +\t\treturn -1;\n\nCould you pick an error code instead of -1 ? Same below.\n\n> +\n> +\tuint32_t out_data_size = 0;\n\noutDataSize\n\nSame below.\n\n> +\n> +\tif (!jpeg_compressor_->CompressImageFromHandle(\n> +\t\t    dynamic_cast<const AndroidFrameBuffer *>(\n> +\t\t\t    streamBuffer->srcBuffer)\n> +\t\t\t    ->getHandle(),\n> +\t\t    *streamBuffer->camera3Buffer, size_.width, size_.height, quality,\n> +\t\t    exifData.data(), exifData.size(), &out_data_size)) {\n> +\t\treturn -1;\n> +\t}\n\nAn intermediate variable would make this easier to read.\n\n\tconst AndroidFrameBuffer *fb =\n\t\tdynamic_cast<const AndroidFrameBuffer *>(streamBuffer->srcBuffer);\n\n\tif (!jpeg_compressor_->CompressImageFromHandle(fb->getHandle(),\n\t\t\t\t\t\t       *streamBuffer->camera3Buffer,\n\t\t\t\t\t\t       size_.width, size_.height, quality,\n\t\t\t\t\t\t       exifData.data(), exifData.size(),\n\t\t\t\t\t\t       &out_data_size))\n\t\treturn -1;\n\n> +\n> +\treturn out_data_size;\n> +}\n> +\n> +int EncoderJea::generateThumbnail(const libcamera::FrameBuffer &source,\n> +\t\t\t\t  const libcamera::Size &targetSize,\n> +\t\t\t\t  unsigned int quality,\n> +\t\t\t\t  std::vector<unsigned char> *thumbnail)\n> +{\n> +\tif (!jpeg_compressor_.get())\n> +\t\treturn -1;\n> +\n> +\tlibcamera::MappedFrameBuffer frame(&source, libcamera::MappedFrameBuffer::MapFlag::Read);\n> +\n> +\tif (frame.planes().empty())\n> +\t\treturn 0;\n\nIsn't this an error ?\n\n> +\n> +\tuint32_t out_data_size = 0;\n> +\n> +\tif (!jpeg_compressor_->GenerateThumbnail(frame.planes()[0].data(),\n> +\t\t\t\t\t\t size_.width, size_.height, targetSize.width, targetSize.height,\n> +\t\t\t\t\t\t quality, thumbnail->size(), thumbnail->data(), &out_data_size)) {\n> +\t\treturn -1;\n> +\t}\n\nNo need for curly braces, and a bit of line wrap would be nice :-)\n\n> +\n> +\treturn out_data_size;\n> +}\n> diff --git a/src/android/jpeg/encoder_jea.h b/src/android/jpeg/encoder_jea.h\n> new file mode 100644\n> index 00000000..d5c9f1f7\n> --- /dev/null\n> +++ b/src/android/jpeg/encoder_jea.h\n> @@ -0,0 +1,35 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2022, Google Inc.\n> + *\n> + * encoder_jea.h - JPEG encoding using CrOS JEA\n> + */\n> +\n> +#pragma once\n> +\n> +#include <libcamera/geometry.h>\n> +\n> +#include <cros-camera/jpeg_compressor.h>\n> +\n> +#include \"encoder.h\"\n> +\n> +class EncoderJea : public Encoder\n> +{\n> +public:\n> +\tEncoderJea();\n> +\t~EncoderJea();\n> +\n> +\tint configure(const libcamera::StreamConfiguration &cfg) override;\n> +\tint encode(Camera3RequestDescriptor::StreamBuffer *streamBuffer,\n> +\t\t   libcamera::Span<const uint8_t> exifData,\n> +\t\t   unsigned int quality) override;\n> +\tint generateThumbnail(const libcamera::FrameBuffer &source,\n> +\t\t\t      const libcamera::Size &targetSize,\n> +\t\t\t      unsigned int quality,\n> +\t\t\t      std::vector<unsigned char> *thumbnail) override;\n> +\n> +private:\n> +\tlibcamera::Size size_;\n> +\n> +\tstd::unique_ptr<cros::JpegCompressor> jpeg_compressor_;\n\njpegCompressor_\n\nor just compressor_ to shorten lines.\n\n> +};\n> diff --git a/src/android/jpeg/meson.build b/src/android/jpeg/meson.build\n> index 94522dc0..8606acc4 100644\n> --- a/src/android/jpeg/meson.build\n> +++ b/src/android/jpeg/meson.build\n> @@ -4,6 +4,13 @@ android_hal_sources += files([\n>      'exif.cpp',\n>      'post_processor_jpeg.cpp'])\n>  \n> -android_hal_sources += files(['encoder_libjpeg.cpp',\n> -                              'generic_post_processor_jpeg.cpp',\n> -                              'thumbnailer.cpp'])\n> +platform = get_option('android_platform')\n> +if platform == 'generic'\n> +    android_hal_sources += files(['encoder_libjpeg.cpp',\n> +                                  'generic_post_processor_jpeg.cpp',\n> +                                  'thumbnailer.cpp'])\n> +elif platform == 'cros'\n> +    android_hal_sources += files(['cros_post_processor_jpeg.cpp',\n> +                                  'encoder_jea.cpp'])\n> +    android_deps += [dependency('libcros_camera')]\n> +endif","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 394E4C0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 26 Apr 2022 23:58:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A046565645;\n\tWed, 27 Apr 2022 01:58:54 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id ABC70604A9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 Apr 2022 01:58:53 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1237B30B;\n\tWed, 27 Apr 2022 01:58:53 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1651017534;\n\tbh=oc1kFuhX3yD5OOi0I0g5HzQcpAptIH0BsZEgW5MXe6U=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=sp7DE/FmJLHSB5xppoWHM9DJvO4FkZv7C00FxTooRqhagnuF7Y7VHY0uELvfAI9hE\n\tRpFbHA8C6zqAfXCJYx1D7+nYPDepVnyXNmj9xvxA7v0FW2OTL2yiYJdIt0eeVEs0OD\n\tvHn0/+JG05Y9EdLDJaHht4gE3DvNLFTxblkY3CxCpNPnQqQtwUmLLWcqaa3orIaXZy\n\tFoSyRp97kMD1EZ5Utz/GkFgMdtZFW7+GSxMe0nXcDP4L9Te4PLFutnvPa4Wwfffktc\n\toDO/rbTzKXQlZBCfBkEI5YDFf9/A1CYwB4GU/Nd8CeXZy0gt54o7mL4p2glLdNF5VL\n\t/wZSoIo8kUSNw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1651017533;\n\tbh=oc1kFuhX3yD5OOi0I0g5HzQcpAptIH0BsZEgW5MXe6U=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=TXhjeQ2Pzjfl6KmhLM/zmhAMelYvM/xDsgl0846LhGRXjAG2lvA7zPFPmHeR2Mxfx\n\tC9uBR0uZOfSdcrKAKqBjUi/+DPzgM/jWqXeBSjoeD0u9z5aJ+h+P0HWb/6wh4j9CIm\n\tFseJBXYh0Qp15yFuHa+rERxfYp+2GAXfFfE2Yo2g="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"TXhjeQ2P\"; dkim-atps=neutral","Date":"Wed, 27 Apr 2022 02:58:52 +0300","To":"Harvey Yang <chenghaoyang@chromium.org>","Message-ID":"<YmiHPGP6G0fTeXOb@pendragon.ideasonboard.com>","References":"<20220426091409.1352047-1-chenghaoyang@chromium.org>\n\t<20220426091409.1352047-5-chenghaoyang@chromium.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220426091409.1352047-5-chenghaoyang@chromium.org>","Subject":"Re: [libcamera-devel] [PATCH v3 4/4] Add JEA implementation","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":22832,"web_url":"https://patchwork.libcamera.org/comment/22832/","msgid":"<CAEB1ahup2Wfdc_WXHL0p9y4wbam7i=MP4VabfCJdjpCY88xWeA@mail.gmail.com>","date":"2022-05-04T07:18:04","subject":"Re: [libcamera-devel] [PATCH v3 4/4] Add JEA implementation","submitter":{"id":117,"url":"https://patchwork.libcamera.org/api/people/117/","name":"Cheng-Hao Yang","email":"chenghaoyang@chromium.org"},"content":"Thanks Laurent!\n\nSorry I forgot to send this reply before going on vacation...\nAnd I should also reply to libcamera-devel as well.\n\n> Could you pick an error code instead of -1 ? Same below.\nNot sure which error code to use when |jpegCompressor_| fails to do the\ncompression. Using -EBUSY for now.\n\nFollowed mostly your suggestions. Please check if I miss anything.\n\nBR,\nHarvey\n\nOn Wed, Apr 27, 2022 at 7:58 AM Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> Hi Harvey,\n>\n> Thank you for the patch.\n>\n> On Tue, Apr 26, 2022 at 09:14:09AM +0000, Harvey Yang via libcamera-devel\n> wrote:\n> > This CL adds JEA implementation to replace Lib Jpeg in cros platform,\n> > where HW accelerator is available.\n> >\n> > Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>\n> > ---\n> >  src/android/cros/camera3_hal.cpp              |  3 +\n> >  src/android/jpeg/cros_post_processor_jpeg.cpp | 14 ++++\n> >  src/android/jpeg/encoder_jea.cpp              | 82 +++++++++++++++++++\n> >  src/android/jpeg/encoder_jea.h                | 35 ++++++++\n> >  src/android/jpeg/meson.build                  | 13 ++-\n> >  5 files changed, 144 insertions(+), 3 deletions(-)\n> >  create mode 100644 src/android/jpeg/cros_post_processor_jpeg.cpp\n> >  create mode 100644 src/android/jpeg/encoder_jea.cpp\n> >  create mode 100644 src/android/jpeg/encoder_jea.h\n> >\n> > diff --git a/src/android/cros/camera3_hal.cpp\n> b/src/android/cros/camera3_hal.cpp\n> > index fb863b5f..ea5577f0 100644\n> > --- a/src/android/cros/camera3_hal.cpp\n> > +++ b/src/android/cros/camera3_hal.cpp\n> > @@ -9,8 +9,11 @@\n> >\n> >  #include \"../camera_hal_manager.h\"\n> >\n> > +cros::CameraMojoChannelManagerToken *g_cros_camera_token = nullptr;\n>\n> gCrosCameraToken to match the coding style, but I'd name the variable\n> gCrosMojoToken to make it clearer it refers to mojo.\n>\n> > +\n> >  static void set_up([[maybe_unused]] cros::CameraMojoChannelManagerToken\n> *token)\n> >  {\n> > +     g_cros_camera_token = token;\n> >  }\n> >\n> >  static void tear_down()\n> > diff --git a/src/android/jpeg/cros_post_processor_jpeg.cpp\n> b/src/android/jpeg/cros_post_processor_jpeg.cpp\n> > new file mode 100644\n> > index 00000000..7020f0d0\n> > --- /dev/null\n> > +++ b/src/android/jpeg/cros_post_processor_jpeg.cpp\n> > @@ -0,0 +1,14 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2022, Google Inc.\n> > + *\n> > + * cros_post_processor_jpeg.cpp - CrOS JPEG Post Processor\n> > + */\n> > +\n> > +#include \"encoder_jea.h\"\n> > +#include \"post_processor_jpeg.h\"\n> > +\n> > +void PostProcessorJpeg::SetEncoder()\n> > +{\n> > +     encoder_ = std::make_unique<EncoderJea>();\n> > +}\n> > diff --git a/src/android/jpeg/encoder_jea.cpp\n> b/src/android/jpeg/encoder_jea.cpp\n> > new file mode 100644\n> > index 00000000..838e8647\n> > --- /dev/null\n> > +++ b/src/android/jpeg/encoder_jea.cpp\n> > @@ -0,0 +1,82 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2022, Google Inc.\n> > + *\n> > + * encoder_jea.cpp - JPEG encoding using CrOS JEA\n> > + */\n> > +\n> > +#include \"encoder_jea.h\"\n> > +\n> > +#include <libcamera/base/log.h>\n> > +\n> > +#include \"libcamera/internal/mapped_framebuffer.h\"\n> > +\n> > +#include <cros-camera/camera_mojo_channel_manager_token.h>\n> > +\n> > +#include \"../android_framebuffer.h\"\n> > +\n> > +extern cros::CameraMojoChannelManagerToken *g_cros_camera_token;\n>\n> Please add this to a header file as appropriate.\n>\n> > +\n> > +EncoderJea::EncoderJea() = default;\n> > +\n> > +EncoderJea::~EncoderJea() = default;\n> > +\n> > +int EncoderJea::configure(const libcamera::StreamConfiguration &cfg)\n> > +{\n> > +     size_ = cfg.size;\n> > +\n> > +     if (jpeg_compressor_.get())\n>\n> You can write\n>\n>         if (jpeg_compressor_)\n>\n> Same below.\n>\n> > +             return 0;\n> > +\n> > +     if (g_cros_camera_token == nullptr)\n> > +             return -ENOTSUP;\n> > +\n> > +     jpeg_compressor_ =\n> cros::JpegCompressor::GetInstance(g_cros_camera_token);\n> > +\n> > +     return 0;\n> > +}\n> > +\n> > +int EncoderJea::encode(Camera3RequestDescriptor::StreamBuffer\n> *streamBuffer,\n> > +                    libcamera::Span<const uint8_t> exifData,\n> > +                    unsigned int quality)\n> > +{\n> > +     if (!jpeg_compressor_.get())\n> > +             return -1;\n>\n> Could you pick an error code instead of -1 ? Same below.\n>\n> > +\n> > +     uint32_t out_data_size = 0;\n>\n> outDataSize\n>\n> Same below.\n>\n> > +\n> > +     if (!jpeg_compressor_->CompressImageFromHandle(\n> > +                 dynamic_cast<const AndroidFrameBuffer *>(\n> > +                         streamBuffer->srcBuffer)\n> > +                         ->getHandle(),\n> > +                 *streamBuffer->camera3Buffer, size_.width,\n> size_.height, quality,\n> > +                 exifData.data(), exifData.size(), &out_data_size)) {\n> > +             return -1;\n> > +     }\n>\n> An intermediate variable would make this easier to read.\n>\n>         const AndroidFrameBuffer *fb =\n>                 dynamic_cast<const AndroidFrameBuffer\n> *>(streamBuffer->srcBuffer);\n>\n>         if (!jpeg_compressor_->CompressImageFromHandle(fb->getHandle(),\n>\n>  *streamBuffer->camera3Buffer,\n>                                                        size_.width,\n> size_.height, quality,\n>                                                        exifData.data(),\n> exifData.size(),\n>                                                        &out_data_size))\n>                 return -1;\n>\n> > +\n> > +     return out_data_size;\n> > +}\n> > +\n> > +int EncoderJea::generateThumbnail(const libcamera::FrameBuffer &source,\n> > +                               const libcamera::Size &targetSize,\n> > +                               unsigned int quality,\n> > +                               std::vector<unsigned char> *thumbnail)\n> > +{\n> > +     if (!jpeg_compressor_.get())\n> > +             return -1;\n> > +\n> > +     libcamera::MappedFrameBuffer frame(&source,\n> libcamera::MappedFrameBuffer::MapFlag::Read);\n> > +\n> > +     if (frame.planes().empty())\n> > +             return 0;\n>\n> Isn't this an error ?\n>\n> > +\n> > +     uint32_t out_data_size = 0;\n> > +\n> > +     if (!jpeg_compressor_->GenerateThumbnail(frame.planes()[0].data(),\n> > +                                              size_.width,\n> size_.height, targetSize.width, targetSize.height,\n> > +                                              quality,\n> thumbnail->size(), thumbnail->data(), &out_data_size)) {\n> > +             return -1;\n> > +     }\n>\n> No need for curly braces, and a bit of line wrap would be nice :-)\n>\n> > +\n> > +     return out_data_size;\n> > +}\n> > diff --git a/src/android/jpeg/encoder_jea.h\n> b/src/android/jpeg/encoder_jea.h\n> > new file mode 100644\n> > index 00000000..d5c9f1f7\n> > --- /dev/null\n> > +++ b/src/android/jpeg/encoder_jea.h\n> > @@ -0,0 +1,35 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2022, Google Inc.\n> > + *\n> > + * encoder_jea.h - JPEG encoding using CrOS JEA\n> > + */\n> > +\n> > +#pragma once\n> > +\n> > +#include <libcamera/geometry.h>\n> > +\n> > +#include <cros-camera/jpeg_compressor.h>\n> > +\n> > +#include \"encoder.h\"\n> > +\n> > +class EncoderJea : public Encoder\n> > +{\n> > +public:\n> > +     EncoderJea();\n> > +     ~EncoderJea();\n> > +\n> > +     int configure(const libcamera::StreamConfiguration &cfg) override;\n> > +     int encode(Camera3RequestDescriptor::StreamBuffer *streamBuffer,\n> > +                libcamera::Span<const uint8_t> exifData,\n> > +                unsigned int quality) override;\n> > +     int generateThumbnail(const libcamera::FrameBuffer &source,\n> > +                           const libcamera::Size &targetSize,\n> > +                           unsigned int quality,\n> > +                           std::vector<unsigned char> *thumbnail)\n> override;\n> > +\n> > +private:\n> > +     libcamera::Size size_;\n> > +\n> > +     std::unique_ptr<cros::JpegCompressor> jpeg_compressor_;\n>\n> jpegCompressor_\n>\n> or just compressor_ to shorten lines.\n>\n> > +};\n> > diff --git a/src/android/jpeg/meson.build b/src/android/jpeg/meson.build\n> > index 94522dc0..8606acc4 100644\n> > --- a/src/android/jpeg/meson.build\n> > +++ b/src/android/jpeg/meson.build\n> > @@ -4,6 +4,13 @@ android_hal_sources += files([\n> >      'exif.cpp',\n> >      'post_processor_jpeg.cpp'])\n> >\n> > -android_hal_sources += files(['encoder_libjpeg.cpp',\n> > -                              'generic_post_processor_jpeg.cpp',\n> > -                              'thumbnailer.cpp'])\n> > +platform = get_option('android_platform')\n> > +if platform == 'generic'\n> > +    android_hal_sources += files(['encoder_libjpeg.cpp',\n> > +                                  'generic_post_processor_jpeg.cpp',\n> > +                                  'thumbnailer.cpp'])\n> > +elif platform == 'cros'\n> > +    android_hal_sources += files(['cros_post_processor_jpeg.cpp',\n> > +                                  'encoder_jea.cpp'])\n> > +    android_deps += [dependency('libcros_camera')]\n> > +endif\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 92BDEC3256\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  4 May 2022 07:18:18 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D7A3A65644;\n\tWed,  4 May 2022 09:18:17 +0200 (CEST)","from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com\n\t[IPv6:2a00:1450:4864:20::22f])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 400F165642\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  4 May 2022 09:18:16 +0200 (CEST)","by mail-lj1-x22f.google.com with SMTP id m23so613228ljc.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 04 May 2022 00:18:16 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1651648697;\n\tbh=YSNtvyeNJ5ueFSIlS3PxoPSO4oqniCYv8m9tYKRz3TE=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=h9nxDVpGPD0elZHIfCT74ISrfjSzaThVv6shxmVTfpS7V3ZWxGA0BvNSca2Hd7VcV\n\thSLmGhSlxXpTCuJsPxaWsHSiH8CBvzXltY7fdeD7WZL+UqoH4TA5W5BP0T3mUX89MI\n\t5rvvXGfkPQyefCHSN39QS/NIDkmaF8Ynswg3qUsfycMrlrcdPL98sATkoP8jpDwNLU\n\tYxCw0hQyC8GH0icIxaV6lpOVvSVffQ+iCl2+g+nkJreilWFhgQOr2RDmNx+5SMUwVH\n\tWnzETg8yJIoqrIelFCk/k1WE7FZEKy4XImNTvvPXCVnm3IDjYD0+pIqk/dcVWS1o1f\n\tZmBdWCcSI1PMA==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=7uOle0m9nZ30IIeqnGxkKiTRAWjYqdSIaZML73oL4a8=;\n\tb=DX9Njw8hzTR0cr9jDHU3bOKGrvbgFDOmabKKrYlpbSaoOJ1YDoZzf39QRzLkZ5eo7Z\n\tOy9oNwARs/3uTN7qyEHAfzX0Lyxthpul4pLpuBNVlBWnXZC9zISBePD8FO3280AwdEuF\n\t/5EgaTkerP5RbEBSwO0lWhriK8fddpnWnz6BM="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=chromium.org\n\theader.i=@chromium.org header.b=\"DX9Njw8h\"; \n\tdkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=7uOle0m9nZ30IIeqnGxkKiTRAWjYqdSIaZML73oL4a8=;\n\tb=4kHmfrGSPQqGFip7bWH53oRdhzUMW+clRtjXS8/ifhhXhlTeqL+7XBzhQ5rT6nLz6q\n\taTlfLrS3A1v/EPATguacAg5kUnjwe7UqrPb8A/1XKpkxc37uhECgVzSNWVjbwEELo+pv\n\t6s6Nt4UtZ7Dff2xuTqvery7wodrVCx5aLCtrbUu0rXE9FAUSZycs1kY5MDyl7zhHrH6l\n\tX6CWA48ioKVj22XTsyFRuekp06+hh1qpHeIcGiFb76MzxxqCNB15W6U0t0z0y9dFEM8H\n\tRmo9dAoIZYVE/V6UR9jx2VODbSgd/6+K96udlf3bS6f/YCW9Bt2PpwSQeIv70NaZQaEP\n\tnXMg==","X-Gm-Message-State":"AOAM530cwvR84OSj5sgPEwa6o82kdu6f8JM33gBpUFItwnyT9TuJO1VP\n\tWNASS5MYJYkbnDPVlZi7QSS0vOEaniS+P69e8FHarQPcbHxQ7w==","X-Google-Smtp-Source":"ABdhPJxQbn8kJ+5TxbLw9kDYf84bDEjamOcd9//v8TWhNKk8DYVU9Dszqi4Rvdaaecqbz+EE7ZT5YV/M8iVV1TzhX9o=","X-Received":"by 2002:a2e:a585:0:b0:24f:528f:3621 with SMTP id\n\tm5-20020a2ea585000000b0024f528f3621mr8852455ljp.416.1651648695393;\n\tWed, 04 May 2022 00:18:15 -0700 (PDT)","MIME-Version":"1.0","References":"<20220426091409.1352047-1-chenghaoyang@chromium.org>\n\t<20220426091409.1352047-5-chenghaoyang@chromium.org>\n\t<YmiHPGP6G0fTeXOb@pendragon.ideasonboard.com>","In-Reply-To":"<YmiHPGP6G0fTeXOb@pendragon.ideasonboard.com>","Date":"Wed, 4 May 2022 15:18:04 +0800","Message-ID":"<CAEB1ahup2Wfdc_WXHL0p9y4wbam7i=MP4VabfCJdjpCY88xWeA@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"000000000000c86f4805de2a6df8\"","Subject":"Re: [libcamera-devel] [PATCH v3 4/4] Add JEA implementation","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Cheng-Hao Yang via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Cheng-Hao Yang <chenghaoyang@chromium.org>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]