Patch Detail
Show a patch.
GET /api/patches/3863/?format=api
{ "id": 3863, "url": "https://patchwork.libcamera.org/api/patches/3863/?format=api", "web_url": "https://patchwork.libcamera.org/patch/3863/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20200526142237.407557-5-jacopo@jmondi.org>", "date": "2020-05-26T14:22:33", "name": "[libcamera-devel,4/8] android: camera_device: Build stream configuration", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "54d2bd63a9c9d6edde0a5c7b177acea1c18e2607", "submitter": { "id": 3, "url": "https://patchwork.libcamera.org/api/people/3/?format=api", "name": "Jacopo Mondi", "email": "jacopo@jmondi.org" }, "delegate": { "id": 15, "url": "https://patchwork.libcamera.org/api/users/15/?format=api", "username": "jmondi", "first_name": "Jacopo", "last_name": "Mondi", "email": "jacopo@jmondi.org" }, "mbox": "https://patchwork.libcamera.org/patch/3863/mbox/", "series": [ { "id": 930, "url": "https://patchwork.libcamera.org/api/series/930/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=930", "date": "2020-05-26T14:22:29", "name": "android: Implament format translation", "version": 1, "mbox": "https://patchwork.libcamera.org/series/930/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/3863/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/3863/checks/", "tags": {}, "headers": { "Return-Path": "<jacopo@jmondi.org>", "Received": [ "from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net\n\t[217.70.183.194])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E097B61075\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 May 2020 16:19:26 +0200 (CEST)", "from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it\n\t[2.224.242.101]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 676BB40002;\n\tTue, 26 May 2020 14:19:26 +0000 (UTC)" ], "X-Originating-IP": "2.224.242.101", "From": "Jacopo Mondi <jacopo@jmondi.org>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Tue, 26 May 2020 16:22:33 +0200", "Message-Id": "<20200526142237.407557-5-jacopo@jmondi.org>", "X-Mailer": "git-send-email 2.26.2", "In-Reply-To": "<20200526142237.407557-1-jacopo@jmondi.org>", "References": "<20200526142237.407557-1-jacopo@jmondi.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH 4/8] android: camera_device: Build stream\n\tconfiguration", "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>", "X-List-Received-Date": "Tue, 26 May 2020 14:19:27 -0000" }, "content": "Build the stream configuration map by applying the Android Camera3\nrequested resolutions and formats to the libcamera Camera device.\n\nFor each required format test a list of required and optional\nresolutions, construct a map to translate from Android format to the\nlibcamera formats and store the available stream configuration to\nbe provided to the Android framework through static metadata.\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n src/android/camera_device.cpp | 184 ++++++++++++++++++++++++++++++++++\n src/android/camera_device.h | 13 +++\n 2 files changed, 197 insertions(+)", "diff": "diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\nindex 69b25ed2f11f..534bfb1df1ef 100644\n--- a/src/android/camera_device.cpp\n+++ b/src/android/camera_device.cpp\n@@ -8,6 +8,8 @@\n #include \"camera_device.h\"\n #include \"camera_ops.h\"\n \n+#include <set>\n+\n #include <libcamera/controls.h>\n #include <libcamera/property_ids.h>\n \n@@ -15,9 +17,37 @@\n #include \"libcamera/internal/utils.h\"\n \n #include \"camera_metadata.h\"\n+#include \"system/graphics.h\"\n \n using namespace libcamera;\n \n+namespace {\n+\n+std::set<Size> camera3Resolutions = {\n+\t{ 320, 240 },\n+\t{ 640, 480 },\n+\t{ 1280, 720 },\n+\t{ 1920, 1080 }\n+};\n+\n+std::map<int, std::forward_list<uint32_t>> camera3FormatsMap = {\n+\t{ HAL_PIXEL_FORMAT_BLOB, { DRM_FORMAT_MJPEG } },\n+\t{ HAL_PIXEL_FORMAT_YCbCr_420_888, { DRM_FORMAT_NV12, DRM_FORMAT_NV21 } },\n+\t/*\n+\t * \\todo Translate IMPLEMENTATION_DEFINED inspecting the\n+\t * gralloc usage flag. For now, copy the YCbCr_420 configuration.\n+\t */\n+\t{ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, { DRM_FORMAT_NV12, DRM_FORMAT_NV21 } },\n+};\n+\n+std::map<int32_t, int32_t> camera3ScalerFormatMap = {\n+\t{ HAL_PIXEL_FORMAT_BLOB, ANDROID_SCALER_AVAILABLE_FORMATS_BLOB },\n+\t{ HAL_PIXEL_FORMAT_YCbCr_420_888, ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 },\n+\t{ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED },\n+};\n+\n+} /* namespace */\n+\n LOG_DECLARE_CATEGORY(HAL);\n \n /*\n@@ -100,6 +130,160 @@ int CameraDevice::initialize()\n \tif (properties.contains(properties::Rotation))\n \t\torientation_ = properties.get(properties::Rotation);\n \n+\tint ret = camera_->acquire();\n+\tif (ret) {\n+\t\tLOG(HAL, Error) << \"Failed to temporary acquire the camera\";\n+\t\treturn ret;\n+\t}\n+\n+\tret = initializeFormats();\n+\tcamera_->release();\n+\treturn ret;\n+}\n+\n+int CameraDevice::initializeFormats()\n+{\n+\t/*\n+\t * Get the maximum output resolutions\n+\t * \\todo Get this from the camera properties once defined\n+\t */\n+\tstd::unique_ptr<CameraConfiguration> cameraConfig =\n+\t\tcamera_->generateConfiguration({ StillCapture });\n+\tif (!cameraConfig) {\n+\t\tLOG(HAL, Error) << \"Failed to get maximum resolution\";\n+\t\treturn -EINVAL;\n+\t}\n+\tStreamConfiguration &cfg = cameraConfig->at(0);\n+\n+\t/*\n+\t * \\todo JPEG - Adjust the maximum available resolution by\n+\t * taking the JPEG encoder requirements into account (alignement\n+\t * and aspect ratio).\n+\t */\n+\tconst Size maxRes = cfg.size;\n+\tLOG(HAL, Debug) << \"Maximum supported resolution: \" << maxRes.toString();\n+\n+\t/*\n+\t * Build the list of supported image resolutions.\n+\t *\n+\t * The resolutions listed in camera3Resolution are mandatory to be\n+\t * supported, up to the camera maximum resolution.\n+\t *\n+\t * Augment the list by adding resolutions calculated from the camera\n+\t * maximum one.\n+\t */\n+\tstd::set<Size> cameraResolutions;\n+\tfor (const Size &res : camera3Resolutions) {\n+\t\tif (res > maxRes)\n+\t\t\tcontinue;\n+\n+\t\tcameraResolutions.insert(res);\n+\t}\n+\n+\t/* Camera3 specification suggest to add 1/2 and 1/4 max resolution. */\n+\tfor (unsigned int divider = 2;; divider <<= 1) {\n+\t\tSize derivedSize{};\n+\t\tderivedSize.width = maxRes.width / divider;\n+\t\tderivedSize.height = maxRes.height / divider;\n+\n+\t\tif (derivedSize.width < 320 ||\n+\t\t derivedSize.height < 240)\n+\t\t\tbreak;\n+\n+\t\t/* std::set::insert() guarantees the entry is unique. */\n+\t\tcameraResolutions.insert(derivedSize);\n+\t}\n+\tcameraResolutions.insert(maxRes);\n+\n+\t/*\n+\t * Build the list of supported camera format.\n+\t *\n+\t * To each Android format a list of compatible libcamera formats is\n+\t * associated. The first libcamera format that tests successful is added\n+\t * to the format translation map used when configuring the streams.\n+\t * It is then tested against the list of supported camera resolutions to\n+\t * build the stream configuration map reported in the camera static\n+\t * metadata.\n+\t */\n+\tfor (const auto &format : camera3FormatsMap) {\n+\t\tint androidFormatCode = format.first;\n+\t\tconst std::forward_list<uint32_t> testFormats = format.second;\n+\n+\t\t/*\n+\t\t * Test the libcamera formats that can produce images\n+\t\t * compatible with the Android's defined format\n+\t\t */\n+\t\tuint32_t mappedFormatCode = 0;\n+\t\tfor (int32_t formatCode : testFormats) {\n+\t\t\t/*\n+\t\t\t * \\todo Fixed mapping for JPEG\n+\t\t\t */\n+\t\t\tif (androidFormatCode == HAL_PIXEL_FORMAT_BLOB) {\n+\t\t\t\tmappedFormatCode = DRM_FORMAT_MJPEG;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\t/*\n+\t\t\t * The stream configuration size can be adjusted,\n+\t\t\t * not the pixel format.\n+\t\t\t */\n+\t\t\tPixelFormat pixelFormat = PixelFormat(formatCode);\n+\t\t\tcfg.pixelFormat = pixelFormat;\n+\n+\t\t\tCameraConfiguration::Status status = cameraConfig->validate();\n+\t\t\tif (status != CameraConfiguration::Invalid &&\n+\t\t\t cfg.pixelFormat == pixelFormat) {\n+\t\t\t\tmappedFormatCode = pixelFormat.fourcc();\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tif (!mappedFormatCode) {\n+\t\t\tLOG(HAL, Error) << \"Failed to get map Android format \"\n+\t\t\t\t\t<< utils::hex(androidFormatCode);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/*\n+\t\t * Record the mapping and then proceed to generate the\n+\t\t * stream configuration map, by testing the image resolutions.\n+\t\t */\n+\t\tformatsMap_[androidFormatCode] = mappedFormatCode;\n+\n+\t\tfor (const Size &res : cameraResolutions) {\n+\t\t\tPixelFormat pixelFormat = PixelFormat(mappedFormatCode);\n+\t\t\tcfg.pixelFormat = pixelFormat;\n+\t\t\tcfg.size = res;\n+\n+\t\t\tCameraConfiguration::Status status = cameraConfig->validate();\n+\t\t\t/* \\todo Assume we the camera can produce JPEG */\n+\t\t\tif (androidFormatCode != HAL_PIXEL_FORMAT_BLOB &&\n+\t\t\t status != CameraConfiguration::Valid)\n+\t\t\t\tcontinue;\n+\n+\t\t\tauto it = camera3ScalerFormatMap.find(androidFormatCode);\n+\t\t\tif (it == camera3ScalerFormatMap.end()) {\n+\t\t\t\tLOG(HAL, Error) << \"Format \" << utils::hex(androidFormatCode)\n+\t\t\t\t\t\t<< \" has no scaler format associated\";\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\t\t\tint32_t androidScalerCode = it->second;\n+\n+\t\t\t/*\n+\t\t\t * \\todo Add support for input streams. At the moment\n+\t\t\t * register all stream configurations as output-only.\n+\t\t\t */\n+\t\t\tstreamConfigurations_.push_front(\n+\t\t\t\t{ res, androidScalerCode, false });\n+\t\t}\n+\t}\n+\n+\tLOG(HAL, Debug) << \"Collected stream configuration map: \";\n+\tfor (const auto &entry : streamConfigurations_) {\n+\t\tLOG(HAL, Debug) << \"{ \" << entry.resolution.toString() << \" - \"\n+\t\t\t\t<< utils::hex(entry.androidScalerCode) << \": \"\n+\t\t\t\t<< (entry.input ? \"input\" : \"output\") << \" }\";\n+\t}\n+\n \treturn 0;\n }\n \ndiff --git a/src/android/camera_device.h b/src/android/camera_device.h\nindex ace9c1b7c929..95bd39f590ab 100644\n--- a/src/android/camera_device.h\n+++ b/src/android/camera_device.h\n@@ -7,12 +7,15 @@\n #ifndef __ANDROID_CAMERA_DEVICE_H__\n #define __ANDROID_CAMERA_DEVICE_H__\n \n+#include <forward_list>\n+#include <map>\n #include <memory>\n \n #include <hardware/camera3.h>\n \n #include <libcamera/buffer.h>\n #include <libcamera/camera.h>\n+#include <libcamera/geometry.h>\n #include <libcamera/request.h>\n #include <libcamera/stream.h>\n \n@@ -59,6 +62,13 @@ private:\n \t\tcamera3_stream_buffer_t *buffers;\n \t};\n \n+\tstruct Camera3StreamConfiguration {\n+\t\tlibcamera::Size resolution;\n+\t\tint androidScalerCode;\n+\t\tbool input;\n+\t};\n+\n+\tint initializeFormats();\n \tvoid notifyShutter(uint32_t frameNumber, uint64_t timestamp);\n \tvoid notifyError(uint32_t frameNumber, camera3_stream_t *stream);\n \tstd::unique_ptr<CameraMetadata> getResultMetadata(int frame_number,\n@@ -75,6 +85,9 @@ private:\n \tstd::map<unsigned int, CameraMetadata *> requestTemplates_;\n \tconst camera3_callback_ops_t *callbacks_;\n \n+\tstd::forward_list<Camera3StreamConfiguration> streamConfigurations_;\n+\tstd::map<int, uint32_t> formatsMap_;\n+\n \tint facing_;\n \tint orientation_;\n };\n", "prefixes": [ "libcamera-devel", "4/8" ] }