پسوند دوربین

تولیدکنندگان دستگاه می‌توانند افزونه‌هایی مانند بوکه، حالت شب و HDR را از طریق رابط کاربری Camera Extensions که توسط کتابخانه فروشنده OEM ارائه می‌شود، در اختیار توسعه‌دهندگان شخص ثالث قرار دهند. توسعه‌دهندگان می‌توانند از API Extensions Camera2 و API Extensions CameraX برای دسترسی به افزونه‌های پیاده‌سازی شده در کتابخانه فروشنده OEM استفاده کنند.

برای مشاهده‌ی فهرست افزونه‌های پشتیبانی‌شده، که در Camera2 و CameraX یکسان است، به CameraX Extensions API مراجعه کنید. اگر می‌خواهید افزونه‌ای اضافه کنید، در Issue Tracker یک اشکال (bug) ثبت کنید.

این صفحه نحوه پیاده‌سازی و فعال‌سازی کتابخانه فروشندگان OEM روی دستگاه‌ها را شرح می‌دهد.

معماری

نمودار زیر معماری رابط کاربری Camera Extensions یا extensions-interface را شرح می‌دهد: معماری

شکل ۱. نمودار معماری افزونه‌های دوربین

همانطور که در نمودار نشان داده شده است، برای پشتیبانی از افزونه‌های دوربین، باید extensions-interface که توسط کتابخانه فروشنده OEM ارائه می‌شود، پیاده‌سازی کنید. کتابخانه فروشنده OEM شما دو API را فعال می‌کند: CameraX Extensions API و Camera2 Extensions API که به ترتیب توسط برنامه‌های CameraX و Camera2 برای دسترسی به افزونه‌های فروشنده استفاده می‌شوند.

پیاده‌سازی کتابخانه فروشندگان OEM

برای پیاده‌سازی کتابخانه فروشنده OEM، فایل‌های camera-extensions-stub را در یک پروژه کتابخانه سیستم کپی کنید. این فایل‌ها رابط Camera Extensions را تعریف می‌کنند.

فایل‌های camera-extensions-stub به دسته‌های زیر تقسیم می‌شوند:

فایل‌های ضروری رابط کاربری (اصلاح نکنید)

  • PreviewExtenderImpl.java
  • ImageCaptureExtenderImpl.java
  • ExtenderStateListener.java
  • ProcessorImpl.java
  • PreviewImageProcessorImpl.java
  • CaptureProcessorImpl.java
  • CaptureStageImpl.java
  • RequestUpdateProcessorImpl.java
  • ProcessResultImpl.java
  • advanced/AdvancedExtenderImpl.java
  • advanced/Camera2OutputConfigImpl.java
  • advanced/Camera2SessionConfigImpl.java
  • advanced/ImageProcessorImpl.java
  • advanced/ImageReaderOutputConfigImpl.java
  • advanced/ImageReferenceImpl.java
  • advanced/MultiResolutionImageReaderOutputConfigImpl.java
  • advanced/OutputSurfaceImpl.java
  • advanced/RequestProcessorImpl.java
  • advanced/SessionProcessorImpl.java
  • advanced/SurfaceOutputConfigImpl.java

پیاده‌سازی‌های اجباری (پیاده‌سازی خود را اضافه کنید)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

کلاس‌های توسعه‌دهنده‌ی بوکه (در صورت پشتیبانی از توسعه‌ی بوکه، آن را پیاده‌سازی کنید)

  • BokehImageCaptureExtenderImpl.java
  • BokehPreviewExtenderImpl.java
  • advanced/BokehAdvancedExtenderImpl.java

کلاس‌های توسعه‌دهنده‌ی شب (در صورت پشتیبانی از توسعه‌دهنده‌ی شب، آن را پیاده‌سازی کنید)

  • NightImageCaptureExtenderImpl.java
  • NightPreviewExtenderImpl.java
  • advanced/NightAdvancedExtenderImpl.java

کلاس‌های توسعه‌دهنده خودکار (در صورت پشتیبانی از توسعه خودکار، آن را پیاده‌سازی کنید)

  • AutoImageCaptureExtenderImpl.java
  • AutoPreviewExtenderImpl.java
  • advanced/AutoAdvancedExtenderImpl.java

کلاس‌های توسعه‌دهنده HDR (در صورت پشتیبانی از افزونه HDR، آن را پیاده‌سازی کنید)

  • HdrImageCaptureExtenderImpl.java
  • HdrPreviewExtenderImpl.java
  • advanced/HdrAdvancedExtenderImpl.java

کلاس‌های توسعه‌دهنده‌ی روتوش چهره (در صورت پشتیبانی از افزونه‌ی روتوش چهره، آن را پیاده‌سازی کنید)

  • BeautyImageCaptureExtenderImpl.java
  • BeautyPreviewExtenderImpl.java
  • advanced/BeautyAdvancedExtenderImpl.java

ابزارهای کمکی (اختیاری، قابل حذف)

  • advanced/Camera2OutputConfigImplBuilder.java
  • advanced/Camera2SessionConfigImplBuilder.java

لازم نیست برای هر افزونه، پیاده‌سازی ارائه دهید. اگر افزونه‌ای را پیاده‌سازی نمی‌کنید، isExtensionAvailable() را طوری تنظیم کنید که false برگرداند یا کلاس‌های Extender مربوطه را حذف کنید. APIهای افزونه‌های Camera2 و CameraX به برنامه گزارش می‌دهند که افزونه در دسترس نیست.

بیایید نحوه تعامل APIهای افزونه‌های Camera2 و CameraX با کتابخانه فروشنده برای فعال کردن یک افزونه را بررسی کنیم. نمودار زیر جریان سرتاسری را با استفاده از افزونه Night به عنوان مثال نشان می‌دهد:

جریان اصلی

شکل ۲. پیاده‌سازی امتداد شب

  1. تأیید نسخه:

    Camera2/X تابع ExtensionVersionImpl.checkApiVersion() را فراخوانی می‌کند تا اطمینان حاصل کند که نسخه extensions-interface پیاده‌سازی شده توسط OEM با نسخه‌های پشتیبانی شده توسط Camera2/X سازگار است.

  2. مقداردهی اولیه کتابخانه فروشنده:

    InitializerImpl دارای متدی init() است که کتابخانه vendor را مقداردهی اولیه می‌کند. Camera2/X قبل از دسترسی به کلاس‌های Extender، مقداردهی اولیه را انجام می‌دهد.

  3. کلاس‌های Extender نمونه‌سازی شده:

    کلاس‌های Extender را برای افزونه نمونه‌سازی می‌کند. دو نوع Extender وجود دارد: Basic Extender و Advanced Extender. شما باید یک نوع Extender را برای همه افزونه‌ها پیاده‌سازی کنید. برای اطلاعات بیشتر، به Basic Extender در مقابل Advanced Extender مراجعه کنید.

    Camera2/X کلاس‌های Extender را نمونه‌سازی کرده و با آنها تعامل می‌کند تا اطلاعات را بازیابی کرده و افزونه را فعال کند. برای یک افزونه مشخص، Camera2/X می‌تواند چندین بار کلاس‌های Extender را نمونه‌سازی کند. در نتیجه، مقداردهی اولیه سنگین را در سازنده یا فراخوانی init() انجام ندهید. کارهای سنگین را فقط زمانی انجام دهید که جلسه دوربین در شرف شروع است، مانند زمانی که onInit() در Basic Extender فراخوانی می‌شود یا initSession() در Advanced Extender فراخوانی می‌شود.

    برای افزونه‌ی Night، کلاس‌های Extender زیر برای نوع Basic Extender نمونه‌سازی می‌شوند:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    و برای نوع Advanced Extender:

    • NightAdvancedExtenderImpl.java
  4. بررسی در دسترس بودن افزونه:

    قبل از فعال کردن افزونه، isExtensionAvailable() از طریق نمونه Extender بررسی می‌کند که آیا افزونه روی شناسه دوربین مشخص شده در دسترس است یا خیر.

  5. مقداردهی اولیه Extender با اطلاعات دوربین:

    Camera2/X تابع init() را روی نمونه Extender فراخوانی می‌کند و شناسه دوربین و CameraCharacteristics را به آن ارسال می‌کند.

  6. اطلاعات استعلام:

    کلاس Extender را برای بازیابی اطلاعاتی مانند رزولوشن‌های پشتیبانی‌شده، ثبت تأخیر تخمینی و ثبت کلیدهای درخواست از Extender در آماده‌سازی برای فعال‌سازی افزونه، فراخوانی می‌کند.

  7. فعال کردن افزونه روی افزونه:

    کلاس Extender تمام رابط‌های مورد نیاز برای فعال‌سازی کلاس را فراهم می‌کند. این کلاس مکانیزمی برای اتصال پیاده‌سازی OEM به خط لوله Camera2 مانند تزریق پارامترهای درخواست ضبط یا فعال‌سازی یک پردازنده پس از پردازش ارائه می‌دهد.

    برای نوع Advanced Extender، Camera2/X با SessionProcessorImpl تعامل می‌کند تا افزونه را فعال کند. Camera2/X با فراخوانی createSessionProcessor() روی Extender، نمونه SessionProcessorImpl را بازیابی می‌کند.

بخش‌های بعدی جریان افزونه را با جزئیات بیشتری شرح می‌دهند.

تأیید نسخه

هنگام بارگذاری کتابخانه فروشنده OEM از دستگاه در زمان اجرا، Camera2/X بررسی می‌کند که آیا کتابخانه با نسخه extensions-interface سازگار است یا خیر. extensions-interface از نسخه‌بندی معنایی یا MAJOR.MINOR.PATCH استفاده می‌کند، به عنوان مثال، ۱.۱.۰ یا ۱.۲.۰. با این حال، فقط نسخه‌های اصلی و فرعی در طول تأیید نسخه استفاده می‌شوند.

برای تأیید نسخه، Camera2/X تابع ExtensionVersionImpl.checkApiVersion() را با نسخه extensions-interface پشتیبانی‌شده فراخوانی می‌کند. سپس Camera2/X از نسخه گزارش‌شده توسط کتابخانه OEM برای تعیین اینکه آیا افزونه می‌تواند فعال شود و چه قابلیت‌هایی را باید فراخوانی کند، استفاده می‌کند.

سازگاری نسخه اصلی

اگر نسخه‌های اصلی رابط افزونه بین Camera2/X و کتابخانه فروشنده متفاوت باشد، آنگاه ناسازگار تلقی شده و افزونه غیرفعال می‌شود.

سازگاری با نسخه‌های قبلی

تا زمانی که نسخه اصلی یکسان باشد، Camera2/X سازگاری معکوس با کتابخانه‌های فروشندگان OEM که با نسخه‌های extensions-interface قبلی ساخته شده‌اند را تضمین می‌کند. برای مثال، اگر Camera2/X extensions-interface ۱.۳.۰ پشتیبانی کند، کتابخانه‌های فروشندگان OEM که نسخه‌های ۱.۰.۰، ۱.۱.۰ و ۱.۲.۰ را پیاده‌سازی کرده‌اند، همچنان سازگار هستند. این همچنین بدان معنی است که پس از پیاده‌سازی یک نسخه خاص از کتابخانه فروشنده، Camera2/X اطمینان حاصل می‌کند که کتابخانه با نسخه‌های extension-interface آینده سازگار است.

سازگاری رو به جلو

سازگاری رو به جلو با کتابخانه‌های فروشنده extensions-interface به شما، تولیدکننده اصلی (OEM)، بستگی دارد. اگر برای پیاده‌سازی افزونه‌ها به برخی ویژگی‌ها نیاز دارید، ممکن است بخواهید افزونه‌ها را از یک نسخه خاص فعال کنید. در این حالت، می‌توانید نسخه پشتیبانی‌شده extensions-interface را زمانی که نسخه کتابخانه Camera2/X الزامات را برآورده می‌کند، برگردانید. اگر نسخه‌های Camera2/X پشتیبانی نمی‌شوند، می‌توانید یک نسخه ناسازگار مانند 99.0.0 را برای غیرفعال کردن افزونه‌ها برگردانید.

مقداردهی اولیه کتابخانه فروشنده

پس از تأیید نسخه extensions-interface که توسط کتابخانه OEM پیاده‌سازی شده است، Camera2/X فرآیند مقداردهی اولیه را آغاز می‌کند. متد InitializerImpl.init() به کتابخانه OEM سیگنال می‌دهد که یک برنامه در حال تلاش برای استفاده از افزونه‌ها است.

Camera2/X هیچ فراخوانی دیگری به کتابخانه OEM (به جز بررسی نسخه) انجام نمی‌دهد تا زمانی که کتابخانه فروشنده OEM OnExtensionsInitializedCallback.onSuccess() را برای اعلام تکمیل مقداردهی اولیه فراخوانی کند.

شما باید InitializerImpl از نسخه extensions-interface 1.1.0 پیاده‌سازی کنید. اگر کتابخانه فروشنده OEM، extensions-interface 1.0.0 را پیاده‌سازی کند، Camera2/X از مرحله مقداردهی اولیه کتابخانه صرف نظر می‌کند.

اکستندر پایه در مقابل اکستندر پیشرفته

دو نوع پیاده‌سازی extensions-interface وجود دارد: توسعه‌دهنده پایه و توسعه‌دهنده پیشرفته. توسعه‌دهنده پیشرفته از زمان extensions-interface ۱.۲.۰ پشتیبانی می‌شود.

برای افزونه‌هایی که تصاویر را در دوربین HAL پردازش می‌کنند یا از یک پردازنده‌ی پس از پردازش که قادر به پردازش جریان‌های YUV است، استفاده می‌کنند، Basic Extender را پیاده‌سازی کنید.

برای افزونه‌هایی که نیاز به سفارشی‌سازی پیکربندی استریم Camera2 و ارسال درخواست‌های ضبط در صورت نیاز دارند، از Advanced Extender استفاده کنید.

برای مقایسه به جدول زیر مراجعه کنید:

توسعه‌دهنده پایه توسعه‌دهنده پیشرفته
پیکربندی‌های جریان ثابت
پیش‌نمایش: PRIVATE یا YUV_420_888 (در صورت وجود پردازنده)
ضبط تصویر ثابت: JPEG یا YUV_420_888 (در صورت وجود پردازنده)
قابل تنظیم توسط OEM.
ارسال درخواست ضبط فقط Camera2/X می‌تواند درخواست‌های ضبط ارسال کند. شما می‌توانید پارامترهای این درخواست‌ها را تنظیم کنید. وقتی پردازنده برای ضبط تصویر آماده شده باشد، Camera2/X می‌تواند چندین درخواست ضبط ارسال کند و تمام تصاویر و نتایج ضبط را به پردازنده ارسال کند. یک نمونه RequestProcessorImpl برای اجرای درخواست ضبط camera2 و دریافت نتایج و تصویر در اختیار شما قرار می‌گیرد.

Camera2/X توابع startRepeating و startCapture را در SessionProcessorImpl فراخوانی می‌کند تا به OEM سیگنال دهد که درخواست تکرار پیش‌نمایش و توالی ضبط تصویر ثابت را به ترتیب آغاز کند.

قلاب‌ها در لوله دوربین
  • onPresetSession پارامترهای جلسه را فراهم می‌کند.
  • onEnableSession بلافاصله پس از پیکربندی CameraCaptureSession یک درخواست واحد ارسال می‌کند.
  • onDisableSession قبل از بسته شدن CameraCaptureSession ، یک درخواست واحد ارسال می‌کند.
  • initSession پیکربندی سشن camera2 سفارشی‌شده را برای ایجاد سشن ضبط، مقداردهی اولیه کرده و برمی‌گرداند.
  • onCaptureSessionStart درست پس از پیکربندی CameraCaptureSession فراخوانی می‌شود.
  • متد onCaptureSessionEnd قبل از بسته شدن CameraCaptureSession فراخوانی می‌شود.
مناسب برای افزونه‌هایی که در دوربین HAL یا در پردازنده‌ای که تصاویر YUV را پردازش می‌کند، پیاده‌سازی شده‌اند.
  • دارای پیاده‌سازی‌های مبتنی بر Camera2 برای افزونه‌ها است.
  • به پیکربندی جریان سفارشی مانند جریان RAW نیاز دارد.
  • به توالی ضبط تعاملی نیاز دارد.
نسخه API پشتیبانی شده افزونه‌های Camera2: اندروید ۱۳ یا بالاتر
افزونه‌های CameraX: camera-extensions ۱.۱.۰ یا بالاتر
افزونه‌های Camera2: اندروید ۱۲L یا بالاتر
افزونه‌های CameraX: camera-extensions ۱.۲.۰-alpha03 یا بالاتر

جریان‌های برنامه

جدول زیر سه نوع جریان برنامه و فراخوانی‌های API مربوط به افزونه‌های دوربین (Camera Extensions API) را نشان می‌دهد. در حالی که Camera2/X این APIها را ارائه می‌دهد، شما باید کتابخانه فروشنده را به درستی پیاده‌سازی کنید تا از این جریان‌ها پشتیبانی کند، که در بخش بعدی با جزئیات بیشتری توضیح خواهیم داد.

افزونه‌های Camera2 افزونه‌های CameraX
در دسترس بودن افزونه‌ی پرس‌وجو CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
اطلاعات پرس و جو CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX بقیه اطلاعات درون کتابخانه را مدیریت می‌کند.

پیش‌نمایش و عکس‌برداری با فعال بودن افزونه CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector bindToLifecycle(lifecycleOwner, cameraSelector, preview, ...)

توسعه‌دهنده پایه

رابط کاربری Basic Extender در چندین بخش از خط تولید دوربین، اتصالاتی را فراهم می‌کند. هر نوع افزونه، کلاس‌های Extender مربوطه را دارد که تولیدکنندگان تجهیزات اصلی (OEM) باید آنها را پیاده‌سازی کنند.

جدول زیر کلاس‌های توسعه‌دهنده‌ای را که تولیدکنندگان اصلی تجهیزات (OEM) باید برای هر افزونه پیاده‌سازی کنند، فهرست می‌کند:

کلاس‌های توسعه‌دهنده برای پیاده‌سازی
شب NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

اچ‌دی‌آر HdrPreviewExtenderImpl.java HdrImageCaptureExtenderImpl.java
خودکار AutoPreviewExtenderImpl.java AutoImageCaptureExtenderImpl.java
بوکه BokehPreviewExtenderImpl.java BokehImageCaptureExtenderImpl.java
روتوش چهره BeautyPreviewExtenderImpl.java BeautyImageCaptureExtenderImpl.java

ما در مثال زیر PreviewExtenderImpl و ImageCaptureExtenderImpl به عنوان متغیر استفاده می‌کنیم. این‌ها را با نام فایل‌های واقعی که پیاده‌سازی می‌کنید جایگزین کنید.

Basic Extender دارای قابلیت‌های زیر است:

  • پارامترهای جلسه را هنگام پیکربندی CameraCaptureSession ( onPresetSession ) تزریق کنید.
  • شما را از رویدادهای شروع و پایان جلسه ضبط مطلع می‌کند و یک درخواست واحد برای اطلاع‌رسانی به HAL با پارامترهای برگشتی ( onEnableSession ، onDisableSession ) ارسال می‌کند.
  • پارامترهای ضبط را برای درخواست ( PreviewExtenderImpl.getCaptureStage ، ImageCaptureExtenderImpl.getCaptureStages ) تزریق کنید.
  • پردازنده‌هایی را برای پیش‌نمایش و ضبط مداوم اضافه کنید که قادر به پردازش جریان YUV_420_888 باشند.

بیایید ببینیم Camera2/X چگونه extensions-interface برای دستیابی به سه جریان برنامه ذکر شده در بالا فراخوانی می‌کند.

جریان برنامه ۱: بررسی در دسترس بودن افزونه

BasicExtenderAppFlow1

شکل ۳. جریان برنامه ۱ در Basic Extender

در این جریان، Camera2/X مستقیماً متد isExtensionAvailable() را از هر دو PreviewExtenderImpl و ImageCaptureExtenderImpl بدون فراخوانی init() فراخوانی می‌کند. هر دو کلاس Extender باید true برگردانند تا افزونه‌ها فعال شوند.

این اغلب اولین قدم برای برنامه‌ها است تا قبل از فعال کردن افزونه، بررسی کنند که آیا نوع افزونه داده شده برای یک شناسه دوربین خاص پشتیبانی می‌شود یا خیر. دلیل این امر این است که برخی از افزونه‌ها فقط روی شناسه‌های دوربین خاصی پشتیبانی می‌شوند.

جریان برنامه ۲: جستجوی اطلاعات

BasicExtenderAppFlow2

شکل ۴. جریان برنامه ۲ روی Basic Extender

پس از تعیین اینکه آیا افزونه در دسترس است، برنامه‌ها باید قبل از فعال کردن افزونه، اطلاعات زیر را جستجو کنند.

  • محدوده تأخیر ضبط همچنان: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange محدوده تأخیر ضبط را برای برنامه برمی‌گرداند تا ارزیابی کند که آیا فعال کردن افزونه برای سناریوی فعلی مناسب است یا خیر.

  • اندازه‌های پشتیبانی‌شده برای پیش‌نمایش و سطح ضبط: ImageCaptureExtenderImpl.getSupportedResolutions و PreviewExtenderImpl.getSupportedResolutions فهرستی از فرمت‌های تصویر و اندازه‌هایی که برای فرمت و اندازه سطح پشتیبانی می‌شوند را برمی‌گردانند.

  • کلیدهای درخواست و نتیجه‌ی پشتیبانی‌شده: Camera2/X متدهای زیر را برای بازیابی کلیدهای درخواست ضبط و کلیدهای نتیجه‌ی پشتیبانی‌شده از پیاده‌سازی شما فراخوانی می‌کند:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X همیشه قبل از پرس‌وجو برای اطلاعات بیشتر، ابتدا تابع init() را روی این کلاس‌های Extender فراخوانی می‌کند.

جریان برنامه ۳: پیش‌نمایش/ضبط تصویر ثابت با فعال بودن افزونه (پیاده‌سازی HAL)

BasicExtenderAppFlow3

شکل ۵. جریان برنامه ۳ روی Basic Extender

نمودار بالا جریان اصلی فعال‌سازی پیش‌نمایش و ضبط مداوم با یک افزونه بدون هیچ پردازنده‌ای را نشان می‌دهد. این بدان معناست که دوربین HAL افزونه را پردازش می‌کند.

در این جریان، Camera2/X ابتدا init() و سپس onInit را فراخوانی می‌کند، که به شما اطلاع می‌دهد که یک جلسه دوربین با افزونه‌های مشخص شده در شرف شروع است. می‌توانید مقداردهی اولیه سنگین را در onInit() انجام دهید.

هنگام پیکربندی CameraCaptureSession ، Camera2/X برای دریافت پارامترهای session، onPresetSession فراخوانی می‌کند. پس از پیکربندی موفقیت‌آمیز session ضبط، Camera2/X متد onEnableSession فراخوانی می‌کند و یک نمونه CaptureStageImpl را که حاوی پارامترهای ضبط است، برمی‌گرداند. Camera2/X بلافاصله یک درخواست واحد با این پارامترهای ضبط ارسال می‌کند تا به HAL اطلاع دهد. به طور مشابه، قبل از بسته شدن session ضبط، Camera2/X onDisableSession را فراخوانی می‌کند و سپس یک درخواست واحد با پارامترهای ضبط برگشتی ارسال می‌کند.

درخواست تکراری که توسط Camera2/X ایجاد می‌شود، حاوی پارامترهای درخواستی است که توسط PreviewExtenderImpl.getCaptureStage() برگردانده می‌شود. علاوه بر این، درخواست ضبط تصویر ثابت حاوی پارامترهایی است که توسط ImageCaptureExtenderImpl.getCaptureStages() برگردانده می‌شود.

در نهایت، Camera2/X پس از پایان جلسه دوربین، onDeInit() را فراخوانی می‌کند. می‌توانید منابع را در onDeinit() آزاد کنید.

پردازنده پیش‌نمایش

علاوه بر دوربین HAL، می‌توانید افزونه‌هایی را نیز در یک پردازنده پیاده‌سازی کنید.

برای مشخص کردن نوع پردازنده، PreviewExtenderImpl.getProcessorType را مطابق توضیحات زیر پیاده‌سازی کنید:

  • PROCESSOR_TYPE_NONE : بدون پردازنده. تصاویر در دوربین HAL پردازش می‌شوند.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY : نوع پردازنده به شما امکان می‌دهد درخواست تکراری را با پارامترهای درخواست ضبط جدید بر اساس آخرین TotalCaptureResult به‌روزرسانی کنید.

    PreviewExtenderImpl.getProcessor باید یک نمونه RequestUpdateProcessorImpl برگرداند که نمونه TotalCaptureResult را پردازش می‌کند و یک نمونه CaptureStageImpl برای به‌روزرسانی درخواست تکراری برمی‌گرداند. PreviewExtenderImpl.getCaptureStage() همچنین باید نتیجه پردازش را منعکس کند و آخرین CaptureStageImpl برگرداند.

  • PROCESSOR_TYPE_IMAGE_PROCESSOR : این نوع به شما امکان می‌دهد پردازنده‌ای را برای پردازش تصاویر YUV_420_888 پیاده‌سازی کنید و خروجی را روی یک سطح PRIVATE بنویسید.

    شما باید یک نمونه PreviewImageProcessorImpl در PreviewExtenderImpl.getProcessor پیاده‌سازی و بازگردانید. پردازنده مسئول پردازش تصاویر ورودی YUV_420_888 است. باید خروجی را به فرمت PRIVATE پیش‌نمایش بنویسد. Camera2/X از سطح YUV_420_888 به جای PRIVATE برای پیکربندی CameraCaptureSession برای پیش‌نمایش استفاده می‌کند.

    برای جریان به تصویر زیر مراجعه کنید:

پیش‌نمایشپردازنده

شکل ۶. جریان پیش‌نمایش با PreviewImageProcessorImpl

رابط PreviewImageProcessorImpl ProcessImpl ارث‌بری می‌کند و سه متد مهم دارد:

  • onOutputSurface(Surface surface, int imageFormat) سطح خروجی را برای پردازنده تنظیم می‌کند. برای PreviewImageProcessorImpl ، imageFormat یک فرمت پیکسلی مانند PixelFormat.RGBA_8888 است.

  • onResolutionUpdate(Size size) اندازه تصویر ورودی را تنظیم می‌کند.

  • onImageFormatUpdate(int imageFormat) فرمت تصویر ورودی را تنظیم می‌کند. در حال حاضر، فقط می‌تواند YUV_420_888 باشد.

پردازنده ضبط تصویر

برای ضبط تصویر ثابت، می‌توانید با برگرداندن یک نمونه CaptureProcessorImpl با استفاده از ImageCaptureExtenderImpl.getCaptureProcessor ، یک پردازنده پیاده‌سازی کنید. پردازنده مسئول پردازش لیستی از تصاویر YUV_420_888 ضبط شده و نمونه‌های TotalCaptureResult و نوشتن خروجی در سطح YUV_420_888 است.

می‌توانید با اطمینان فرض کنید که پیش‌نمایش فعال شده و قبل از ارسال درخواست ضبط تصویر ثابت، در حال اجرا است.

جریان را در نمودار زیر ببینید:

پردازنده ضبط

شکل 7. ضبط جریان ثابت با CaptureProcessorImpl

  1. Camera2/X برای پیکربندی جلسه ضبط، از یک سطح با فرمت YUV_420_888 برای ضبط تصاویر ثابت استفاده می‌کند. Camera2/X با فراخوانی دستور زیر، CaptureProcessorImpl آماده می‌کند:

    • CaptureProcessorImpl.onImageFormatUpdate() به همراه YUV_420_888
    • CaptureProcessorImpl.onResolutionUpdate() با اندازه تصویر ورودی.
    • CaptureProcessorImpl.onOutputSurface() ‎ با سطح خروجی YUV_420_888 اجرا می‌شود.
  2. ImageCaptureExtenderImpl.getCaptureStages فهرستی از CaptureStageImpl را برمی‌گرداند، که در آن هر عنصر به یک نمونه CaptureRequest با پارامترهای ضبط که توسط Camera2/X ارسال می‌شوند، نگاشت می‌شود. برای مثال، اگر فهرستی از سه نمونه CaptureStageImpl را برگرداند، Camera2/X سه درخواست ضبط با پارامترهای ضبط مربوطه را با استفاده از API captureBurst ارسال می‌کند.

  3. تصاویر دریافتی و نمونه‌های TotalCaptureResult با هم ترکیب شده و برای پردازش به CaptureProcessorImpl ارسال می‌شوند.

  4. CaptureProcessorImpl تصویر حاصل (با فرمت YUV_420_888 ) را در سطح خروجی مشخص شده توسط فراخوانی onOutputSurface() می‌نویسد. در صورت لزوم، Camera2/X آن را به تصاویر JPEG تبدیل می‌کند.

پشتیبانی از کلیدها و نتایج درخواست ضبط

علاوه بر پیش‌نمایش و ضبط دوربین، برنامه‌ها می‌توانند پارامترهای زوم، فلاش یا فوکوس با لمس را تنظیم کنند. این پارامترها ممکن است با پیاده‌سازی افزونه شما سازگار نباشند.

متدهای زیر به extensions-interface 1.3.0 اضافه شده‌اند تا به شما امکان دهند پارامترهایی را که پیاده‌سازی شما پشتیبانی می‌کند، نمایش دهید:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() کلیدهای درخواست ضبط پشتیبانی شده توسط پیاده‌سازی شما را برمی‌گرداند.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() کلیدهای نتیجه‌ی ضبط را که در نتیجه‌ی ضبط وجود دارند، برمی‌گرداند.

اگر دوربین HAL افزونه را پردازش کند، Camera2/X نتایج ضبط را در CameraCaptureSession.CaptureCallback بازیابی می‌کند. با این حال، اگر پردازنده پیاده‌سازی شده باشد، Camera2/X نتایج ضبط را در ProcessResultImpl بازیابی می‌کند که به متد process() در PreviewImageProcessorImpl و CaptureProcessorImpl ارسال می‌شود. شما مسئول گزارش نتیجه ضبط از طریق ProcessResultImpl به Camera2/X هستید.

به عنوان مثال، تعریف رابط CaptureProcessorImpl را در زیر ببینید. در extensions-interface ۱.۳.۰ یا بالاتر، فراخوانی process() دوم فراخوانی می‌شود:

Interface CaptureProcessorImpl extends ProcessorImpl {
    // invoked when extensions-interface version < 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
    // invoked when extensions-interface version >= 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
            ProcessResultImpl resultCallback, Executor executor);
}

برای عملکردهای رایج دوربین مانند زوم، فوکوس با لمس، فلاش و جبران نوردهی، توصیه می‌کنیم از کلیدهای زیر هم برای درخواست ضبط و هم برای نتیجه ضبط پشتیبانی کنید:

  • بزرگنمایی:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • ضربه برای فوکوس:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • فلش:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • جبران نوردهی:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

برای توسعه‌دهنده‌های پایه که نسخه ۱.۲.۰ یا قبل از آن را پیاده‌سازی می‌کنند، رابط برنامه‌نویسی نرم‌افزار CameraX Extensions به صراحت از تمام کلیدهای فوق پشتیبانی می‌کند. برای extensions-interface نسخه ۱.۳.۰، هم CameraX و هم Camera2 لیست بازگشتی را رعایت می‌کنند و فقط از کلیدهای موجود در آن پشتیبانی می‌کنند. به عنوان مثال، اگر تصمیم بگیرید فقط CaptureRequest#CONTROL_ZOOM_RATIO و CaptureRequest#SCALER_CROP_REGION در پیاده‌سازی نسخه ۱.۳.۰ برگردانید، این بدان معناست که فقط زوم برای برنامه پشتیبانی می‌شود در حالی که فوکوس با لمس، فلاش و جبران نوردهی مجاز نیستند.

توسعه‌دهنده پیشرفته

افزونه‌ی پیشرفته (Advanced Extender) نوعی پیاده‌سازی مبتنی بر Camera2 API است که توسط فروشنده ارائه می‌شود. این نوع افزونه در نسخه ۱.۲.۰ extensions-interface ) اضافه شده است. بسته به سازنده‌ی دستگاه، افزونه‌ها ممکن است در لایه‌ی اپلیکیشن (app layer) پیاده‌سازی شوند که به عوامل زیر بستگی دارد:

  • پیکربندی جریان سفارشی: جریان‌های سفارشی مانند جریان RAW را پیکربندی کنید یا چندین جریان برای شناسه‌های مختلف دوربین فیزیکی داشته باشید.

  • قابلیت ارسال درخواست‌های Camera2: از یک منطق تعاملی پیچیده پشتیبانی می‌کند که می‌تواند درخواست‌های ضبط را با پارامترهایی بر اساس نتایج درخواست‌های قبلی ارسال کند.

Advanced Extender یک لایه پوششی یا میانی ارائه می‌دهد، بنابراین می‌توانید پیکربندی جریان را سفارشی کنید و درخواست‌های ضبط را در صورت تقاضا ارسال کنید.

فایل‌هایی برای پیاده‌سازی

برای تغییر به پیاده‌سازی Advanced Extender، متد isAdvancedExtenderImplemented() در ExtensionVersionImpl باید true را برگرداند. برای هر نوع افزونه، تولیدکنندگان اصلی تجهیزات (OEM) باید کلاس‌های Extender مربوطه را پیاده‌سازی کنند. فایل‌های پیاده‌سازی Advanced Extender در بسته advanced قرار دارند.

کلاس‌های توسعه‌دهنده برای پیاده‌سازی
شب advanced/NightAdvancedExtenderImpl.java
اچ‌دی‌آر advanced/HdrAdvancedExtenderImpl.java
خودکار advanced/AutoAdvancedExtenderImpl.java
بوکه advanced/BokehAdvancedExtenderImpl.java
روتوش چهره advanced/BeautyAdvancedExtenderImpl.java

ما در مثال زیر AdvancedExtenderImpl به عنوان یک متغیر استفاده می‌کنیم. آن را با نام فایل Extender مربوط به افزونه‌ای که پیاده‌سازی می‌کنید جایگزین کنید.

بیایید ببینیم Camera2/X چگونه extensions-interface برای دستیابی به سه جریان برنامه فراخوانی می‌کند.

جریان برنامه ۱: بررسی در دسترس بودن افزونه‌ها

AdvancedAppFlow1

شکل ۸. جریان برنامه ۱ در Advanced Extender

ابتدا، برنامه بررسی می‌کند که آیا افزونه‌ی داده شده پشتیبانی می‌شود یا خیر.

جریان برنامه ۲: جستجوی اطلاعات

AdvancedAppFlow2

شکل ۹. جریان برنامه ۲ در Advanced Extender

پس از فراخوانی AdvancedExtenderImpl.init() ، برنامه می‌تواند اطلاعات زیر را در AdvancedExtenderImpl جستجو کند:

  • تأخیر تخمینی ضبط تصویر ثابت: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() محدوده تأخیر ضبط تصویر را برای برنامه برمی‌گرداند تا ارزیابی کند که آیا فعال کردن افزونه برای سناریوی فعلی مناسب است یا خیر.

  • رزولوشن‌های پشتیبانی‌شده برای پیش‌نمایش و ضبط تصویر ثابت:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() نقشه‌ای از فرمت تصویر را به لیست اندازه‌هایی که برای فرمت و اندازه سطح پیش‌نمایش پشتیبانی می‌شوند، برمی‌گرداند. تولیدکنندگان اصلی تجهیزات (OEM) باید حداقل از فرمت PRIVATE پشتیبانی کنند.

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() فرمت و اندازه‌های پشتیبانی‌شده برای سطح ضبط تصویر ثابت را برمی‌گرداند. تولیدکنندگان اصلی تجهیزات (OEM) باید از خروجی با فرمت JPEG و YUV_420_888 پشتیبانی کنند.

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() اندازه‌های پشتیبانی‌شده برای یک جریان اضافی YUV_420_888 را برای تجزیه و تحلیل تصویر برمی‌گرداند. اگر سطح YUV تجزیه و تحلیل تصویر پشتیبانی نشود، getSupportedYuvAnalysisResolutions() باید null یا یک لیست خالی را برگرداند.

  • کلیدها/نتایج درخواست ضبط موجود (اضافه شده در extensions-interface 1.3.0): Camera2/X متدهای زیر را برای بازیابی کلیدهای درخواست ضبط و کلیدهای نتیجه پشتیبانی شده از پیاده‌سازی شما فراخوانی می‌کند:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

برای اطلاعات بیشتر، به پشتیبانی از کلیدها و نتایج درخواست ضبط مراجعه کنید.

جریان برنامه ۳: پیش‌نمایش/ضبط ثابت با فعال بودن افزونه

AdvancedAppFlow3

شکل ۱۰. جریان برنامه ۳ در Advanced Extender

نمودار بالا جریان اصلی شروع پیش‌نمایش و ضبط مداوم را برای نوع Advanced Extender نشان می‌دهد. بیایید هر مرحله را بررسی کنیم.

  1. نمونه SessionProcessorImpl

    پیاده‌سازی اصلی Advanced Extender در SessionProcessorImpl قرار دارد که مسئول ارائه پیکربندی سفارشی جلسه و ارسال درخواست‌های ضبط برای شروع پیش‌نمایش و درخواست ضبط مداوم است. AdvancedExtenderImpl.createSessionProcessor() برای بازگرداندن نمونه SessionProcessorImpl فراخوانی می‌شود.

  2. initSession

    SessionProcessorImpl.initSession() جلسه را برای افزونه مقداردهی اولیه می‌کند. اینجاست که شما منابع را اختصاص می‌دهید و پیکربندی جلسه را برای آماده‌سازی CameraCaptureSession برمی‌گردانید.

    برای پارامترهای ورودی، Camera2/X پیکربندی‌های سطح خروجی را برای پیش‌نمایش، ضبط تصویر ثابت و تجزیه و تحلیل تصویر YUV اختیاری مشخص می‌کند. این پیکربندی سطح خروجی ( OutputSurfaceImpl ) شامل سطح، اندازه و فرمت تصویر است که با روش‌های زیر در AdvancedExtenderImpl بازیابی می‌شوند:

    • getSupportedPreviewOutputResolutions()
    • getSupportedCaptureOutputResolutions()
    • getSupportedYuvAnalysisResolutions()

    شما باید یک نمونه Camera2SessionConfigImpl برگردانید، که شامل لیستی از نمونه‌های Camera2OutputConfigImpl و پارامترهای جلسه مورد استفاده برای پیکربندی CameraCaptureSession است. شما مسئول خروجی دادن تصاویر صحیح دوربین به سطوح خروجی ارسال شده توسط Camera2/X هستید. در اینجا چند گزینه برای فعال کردن خروجی وجود دارد:

    • پردازش در دوربین HAL: شما می‌توانید سطوح خروجی را مستقیماً با پیاده‌سازی SurfaceOutputConfigImpl به CameraCaptureSession اضافه کنید. این کار سطح خروجی ارائه شده به خط لوله دوربین را پیکربندی می‌کند و به دوربین HAL اجازه می‌دهد تا تصویر را پردازش کند.
    • پردازش سطح میانی ImageReader (RAW، YUV و غیره): سطوح میانی ImageReader را با یک نمونه ImageReaderOutputConfigImpl به CameraCaptureSession اضافه کنید.

      شما باید تصاویر میانی را پردازش کنید و تصویر حاصل را روی سطح خروجی بنویسید.

    • استفاده از اشتراک‌گذاری سطح Camera2: با اضافه کردن هر نمونه Camera2OutputConfigImpl به متد getSurfaceSharingOutputConfigs() از یک نمونه Camera2OutputConfigImpl دیگر، از اشتراک‌گذاری سطح با یک سطح دیگر استفاده کنید. قالب و اندازه سطح باید یکسان باشد.

    تمام Camera2OutputConfigImpl از جمله SurfaceOutputConfigImpl و ImageReaderOutputConfigImpl باید یک شناسه منحصر به فرد ( getId() ) داشته باشند که برای مشخص کردن سطح هدف و بازیابی تصویر از ImageReaderOutputConfigImpl استفاده می‌شود.

  3. onCaptureSessionStart و RequestProcessorImpl

    وقتی CameraCaptureSession شروع می‌شود و چارچوب Camera تابع onConfigured() را فراخوانی می‌کند، Camera2/X تابع SessionProcessorImpl.onCaptureSessionStart() را با پوشش درخواست Camera2 به نام RequestProcessImpl فراخوانی می‌کند. Camera2/X تابع RequestProcessImpl را پیاده‌سازی می‌کند که به شما امکان می‌دهد درخواست‌های ضبط را اجرا کنید و در صورت استفاده از ImageReaderOutputConfigImpl ، تصاویر را بازیابی کنید .

    APIهای RequestProcessImpl از نظر اجرای درخواست‌ها مشابه APIهای Camera2 CameraCaptureSession هستند. تفاوت‌ها عبارتند از:

    • سطح هدف توسط شناسه‌ی نمونه‌ی Camera2OutputConfigImpl مشخص می‌شود.
    • قابلیت بازیابی تصویر از ImageReader .

    شما می‌توانید RequestProcessorImpl.setImageProcessor() با یک شناسه مشخص Camera2OutputConfigImpl فراخوانی کنید تا یک نمونه ImageProcessorImpl برای دریافت تصاویر ثبت کنید.

    نمونه RequestProcessImpl پس از فراخوانی SessionProcessorImpl.onCaptureSessionEnd() توسط Camera2/X نامعتبر می‌شود.

  4. پیش‌نمایش را شروع کنید و عکس بگیرید

    در پیاده‌سازی Advanced Extender، می‌توانید درخواست‌های ضبط را از طریق رابط RequestProcessorImpl ارسال کنید. Camera2/X با فراخوانی SessionProcessorImpl#startRepeating و SessionProcessorImpl#startCapture به ترتیب به شما اطلاع می‌دهد که درخواست تکرار برای پیش‌نمایش یا توالی ضبط تصویر ثابت را آغاز کنید. شما باید درخواست‌های ضبط را برای برآورده کردن این درخواست‌های پیش‌نمایش و ضبط تصویر ثابت ارسال کنید.

    Camera2/X همچنین پارامترهای درخواست ضبط را از طریق SessionProcessorImpl#setParameters تنظیم می‌کند. شما باید این پارامترهای درخواست را (در صورت پشتیبانی پارامترها) هم در درخواست‌های تکراری و هم در درخواست‌های تکی تنظیم کنید.

    شما باید حداقل CaptureRequest.JPEG_ORIENTATION و CaptureRequest.JPEG_QUALITY پشتیبانی کنید. extensions-interface 1.3.0 از کلیدهای درخواست و نتیجه پشتیبانی می‌کند که با روش‌های زیر قابل نمایش هستند:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys()

    وقتی توسعه‌دهندگان کلیدهای موجود در لیست getAvailableCaptureRequestKeys را تنظیم می‌کنند، شما باید پارامترها را فعال کنید و مطمئن شوید که نتیجه‌ی ضبط شامل کلیدهای موجود در لیست getAvailableCaptureResultKeys است.

  5. startTrigger

    SessionProcessorImpl.startTrigger() برای شروع triggerهایی مانند CaptureRequest.CONTROL_AF_TRIGGER و CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER فراخوانی می‌شود. می‌توانید از هرگونه کلید درخواست ضبط که در AdvancedExtenderImpl.getAvailableCaptureRequestKeys() اعلام نشده‌اند، صرف نظر کنید.

    startTrigger() از زمان extensions-interface نسخه ۱.۳.۰ پشتیبانی می‌شود. این تابع به برنامه‌ها امکان می‌دهد تا با استفاده از افزونه‌ها، فوکوس لمسی و فلش را پیاده‌سازی کنند.

  6. تمیز کردن

    هنگام پایان یک جلسه ضبط، SessionProcessorImpl.onCaptureSessionEnd() قبل از بسته شدن CameraCaptureSession فراخوانی می‌شود. پس از بسته شدن جلسه ضبط، deInitSession() پاکسازی را انجام می‌دهد.

پشتیبانی از پیش‌نمایش، عکس‌برداری و تحلیل تصویر

شما باید این افزونه را هم برای پیش‌نمایش و هم برای ضبط تصویر ثابت اعمال کنید. با این حال، اگر تأخیر برای نمایش روان پیش‌نمایش خیلی زیاد است، می‌توانید این افزونه را فقط برای ضبط تصویر ثابت اعمال کنید.

For the Basic Extender type, regardless of enabling the extension for preview, you must implement both ImageCaptureExtenderImpl and PreviewExtenderImpl for a given extension. Often, an app also uses a YUV stream to analyze the image content such as finding QR codes or text. To better support this use case , you should support the stream combination of preview, still capture, and a YUV_420_888 stream for configuring CameraCaptureSession . This means that if you implement a processor, then you have to support the stream combination of three YUV_420_888 streams.

For Advanced Extender, Camera2/X passes three output surfaces to the SessionProcessorImpl.initSession() call. These output surfaces are for preview , still capture, and image analysis, respectively. You must ensure that preview and still capture output surfaces show the valid output. However, for the image analysis output surface, ensure it's working only when it's non-null. If your implementation can't support the image analysis stream, you can return an empty list in AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . This ensures the image analysis output surface is always null in SessionProcessorImpl.initSession() .

Support video capture

The current Camera Extension architecture supports only the preview and still capture use cases. We don't support enabling the extension on the MediaCodec or MediaRecorder surfaces for recording the video. However, it's possible for apps to record the preview output.

Supporting MediaCodec and MediaRecorder surfaces is under investigation.

Extension-specific metadata

For Android 14 and higher, extension-specific metadata lets camera extension clients set and receive extension specific capture request settings and results. Specifically, camera extension clients can use the EXTENSION_STRENGTH capture request parameter to control the extension strength and the EXTENSION_CURRENT_TYPE capture result to indicate the enabled extension type.

Capture requests

The EXTENSION_STRENGTH capture request parameter controls the strength of the extension post-processing effect. The corresponding capture result includes the default strength value if this parameter isn't set explicitly by the client. This parameter can be applied as follows for these extension types:

  • BOKEH : Controls the amount of blur.
  • HDR and NIGHT : Controls the amount of images fused and the brightness of the final image.
  • FACE_RETOUCH : Controls the amount of cosmetic enhancement and skin smoothing.

The supported range for the EXTENSION_STRENGTH parameter is between 0 and 100 , with 0 indicating no extension processing or simple passthrough and 100 indicating the maximum extension strength of the processing effect.

To add support for EXTENSION_STRENGTH , use the vendor specific parameter APIs introduced in version 1.3.0 of the extension library interface. For more information, see getAvailableCaptureRequestKeys() .

Capture results

The EXTENSION_CURRENT_TYPE capture result lets extension implementations notify clients about the active extension type.

Because extensions using the AUTO type dynamically switch between extension types such as HDR and NIGHT depending on the scene conditions, camera extensions apps can use EXTENSION_CURRENT_TYPE to display information about the current extension selected by the AUTO extension.

Real-time still capture latency estimate

For Android 14 and higher, camera extension clients can query real-time still capture latency estimates based on the scene and environment conditions using getRealtimeStillCaptureLatency() . This method provides more accurate estimates than the static getEstimatedCaptureLatencyRangeMillis() method. Based on the latency estimate, apps can decide to skip extension processing or to display an indication to notify users about a long running operation.

CameraExtensionSession.StillCaptureLatency latency;

latency = extensionSession.getRealtimeStillCaptureLatency();

// The capture latency from ExtensionCaptureCallback#onCaptureStarted() until ExtensionCaptureCallback#onCaptureProcessStarted().

latency.getCaptureLatency();

// The processing latency from  ExtensionCaptureCallback#onCaptureProcessStarted() until  the processed frame returns to the client.

latency.getProcessingLatency();

To support real-time still capture latency estimates, implement the following:

Capture processing progress callbacks

For Android 14 and higher, camera extension clients can receive callbacks for the progress of long running still capture processing operations. Apps can display the current progress to users to improve the overall user experience.

Apps can use the following code to integrate this feature:

import android.hardware.camera2.CameraExtensionSession.
ExtensionCaptureCallback;

{

  class AppCallbackImpl extends ExtensionCaptureCallback {

    @Override
    public void onCaptureProcessProgressed(
      @NonNull CameraExtensionSession session,
      @NonNull CaptureRequest request,
      @IntRange(from = 0, to = 100) int progress) {
      // Update app UI with current progress
    }
  }

}

To support capture processing progress callbacks, your extension vendor implementation must call the following callbacks with the current progress value:

Postview still capture

For Android 14 and higher, camera extensions can supply a postview (preview image) using setPostviewOutputConfiguration . To improve the user experience, apps can display a postview image as a placeholder when an extension is experiencing increased processing latency, and replace the image when the final image is available. Apps can configure and issue postview capture requests using the following reference code:

{

if (!CameraExtensionCharacteristics.isPostviewAvailable()) {
    continue;
}

ExtensionSessionConfiguration extensionConfiguration = new
        ExtensionSessionConfiguration(
                CameraExtensionCharacteristics.EXTENSION_NIGHT,
                outputConfig,
                backgroundExecutor,
                extensionSessionStateCallback
    );

extensionConfiguration.setPostviewOutputConfiguration(
    postviewImageOutput);

CaptureRequest.Builder captureRequestBuilder =
    cameraDevice.createCaptureRequest(
        CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(stillImageReader.getSurface());
captureRequestBuilder.addTarget(postviewImageSurface);

CaptureRequest captureRequest = captureRequestBuilder.build();

}

To support postview still capture, your vendor implementation must implement the following:

Support SurfaceView output

For Android 14 and higher, camera extension clients can use power and performance optimized preview render paths by registering a SurfaceView instance for preview output for repeating requests.

To support SurfaceView output, your vendor extension implementation must be capable of streaming and outputting preview to SurfaceView instances. To verify that this is supported, run the SurfaceViewExtensionPreviewTest.java CTS module.

Vendor specific session types

The feature enables vendor extension implementations to select a vendor specific session type that will be set in the internal camera capture session instead of the default value.

The feature works entirely within the framework and vendor stack and has no client/public visible API impact.

To select a vendor-specific session type, implement the following for your extension libraries: * ExtenderStateListener.onSessionType() for basic extensions * Camera2SessionConfigImpl.getSessionType() for advanced extensions

Extensions interface version history

The following table shows the Camera Extension interface version history. You should always implement the vendor library with the latest version.

نسخه Added features
۱.۰.۰
  • Version verification
    • ExtensionVersionImpl
  • Basic Extender
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
۱.۱.۰
  • Library initialization
    • InitializerImpl
  • Expose supported resolutions
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Get estimated capture latency
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
۱.۳.۰
  • Expose supported capture request keys/results keys
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys and getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys and getAvailableCaptureResultKeys
    • New process() call that takes ProcessResultImpl in PreviewImageProcessorImpl and CaptureProcessorImpl
    • Support trigger type request
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Extension-specific metadata
  • Dynamic still capture latency estimates
  • Capture processing progress callbacks
  • Postview still capture
  • Support for SurfaceView output
  • Vendor specific session types

Reference implementation

The following reference OEM vendor library implementations are available in frameworks/ex .

  • advancedSample : A basic implementation of Advanced Extender.

  • sample : A basic implementation of Basic Extender.

  • service_based_sample : An implementation that demonstrates how to host Camera Extensions in a Service . This implementation contains the following components:

    • oem_library : A Camera Extensions OEM library for Camera2 and CameraX Extensions APIs that implements Extensions-Interface . This acts as a passthrough that forwards calls from Extensions-Interface to the service. This library also provides AIDL files and wrapper classes to communicate with the service.

      Advanced Extender is enabled by default. To enable the Basic Extender, change ExtensionsVersionImpl#isAdvancedExtenderImplemented to return false .

    • extensions_service : A sample implementation of the Extensions Service. Add your implementation here. The interface to implement in the service is similar to the Extensions-Interface . For example, implementing the IAdvancedExtenderImpl.Stub performs the same operations as AdvancedExtenderImpl . ImageWrapper and TotalCaptureResultWrapper are required to make Image and TotalCaptureResult parcelable.

Set up the vendor library on a device

The OEM vendor library isn't built into an app; it's loaded from the device at runtime by Camera2/X. In CameraX, the <uses-library> tag declares that the androidx.camera.extensions.impl library, which is defined in the AndroidManifest.xml file of the camera-extensions library, is a dependency of CameraX and must be loaded at runtime. In Camera2, the framework loads an extensions service that also declares that the <uses-library> loads the same androidx.camera.extensions.impl library at runtime.

This allows third-party apps using extensions to automatically load the OEM vendor library. The OEM library is marked as optional so apps can run on devices that don't have the library on the device. Camera2/X handles this behavior automatically when an app tries to use a camera extension as long as the device manufacturer places the OEM library on the device so that it can be discovered by the app.

To set up the OEM library on a device, do the following:

  1. Add a permission file, which is required by the <uses-library> tag, using the following format: /etc/permissions/ ANY_FILENAME .xml . For example, /etc/permissions/camera_extensions.xml . The files in this directory provide a mapping of the library named in <uses-library> to the actual file path on the device.
  2. Use the example below to add the required information to the file.

    • name must be androidx.camera.extensions.impl as that's the library that CameraX searches for.
    • file is the absolute path of the file that contains the extensions implementation (for example, /system/framework/androidx.camera.extensions.impl.jar ).
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="androidx.camera.extensions.impl"
                 file="OEM_IMPLEMENTED_JAR" />
    </permissions>

In Android 12 or higher, devices supporting CameraX extensions must have the ro.camerax.extensions.enabled property set to true , which allows for querying whether a device supports extensions. To do this, add the following line in the device make file:

PRODUCT_VENDOR_PROPERTIES += \
    ro.camerax.extensions.enabled=true \

Validation

To test your implementation of the OEM vendor library during the development stage, use the example app at androidx-main/camera/integration-tests/extensionstestapp/ , which runs through various vendor extensions.

After you complete your implementation, use the camera extensions validation tool to run automated and manual tests to verify that the vendor library is implemented correctly.

Extended scene mode versus camera extensions

For the bokeh extension, in addition to exposing it using camera extensions, you can expose the extension using the extended scene mode, which is enabled through the CONTROL_EXTENDED_SCENE_MODE key. For more implementation details, see Camera bokeh .

Extended scene mode has fewer restrictions compared to camera extensions for camera2 apps. For example, you can enable extended scene mode in a regular CameraCaptureSession instance that supports flexible stream combinations and capture request parameters. In contrast, camera extensions support only a fixed set of stream types and have limited support for capture request parameters.

A downside of extended scene mode is that you can only implement it in the camera HAL, which means that it must be verified to work across all orthogonal controls available to app developers.

We recommend exposing bokeh using both the extended scene mode and Camera Extensions because apps might prefer to use a particular API to enable bokeh. We recommend first using the extended scene mode because this is the most flexible way for apps to enable the bokeh extension. Then you can implement the camera extensions interface based on the extended scene mode. If implementing bokeh in the camera HAL is difficult, for example, because it requires a post processor running in the app layer to process images, we recommend implementing the bokeh extension using the Camera Extensions interface.

سوالات متداول (FAQ)

Are there any restrictions on API levels?

Yes. This depends on the Android API feature set that's required by the OEM vendor library implementation. For example, ExtenderStateListener.onPresetSession() uses the SessionConfiguration.setSessionParameters() call to set a baseline set of tags. This call is available only on API level 28 and higher. For details on specific interface methods, see the API reference documentation .