Ekstensi Kamera

Produsen perangkat dapat mengekspos efek khusus seperti bokeh, mode malam, dan HDR ke pengembang pihak ketiga melalui antarmuka Ekstensi Kamera yang disediakan oleh perpustakaan vendor OEM. Pengembang dapat menggunakan Camera2 Extensions dan CameraX Extensions API untuk mengaktifkan efek, yang diimplementasikan sebagai ekstensi di pustaka vendor OEM pada perangkat.

Untuk daftar ekstensi yang didukung, yang sama di Camera2 dan CameraX, lihat CameraX Extensions API . Jika Anda ingin menambahkan ekstensi, ajukan bug di sini .

Halaman ini menjelaskan cara menerapkan dan mengaktifkan pustaka vendor OEM di perangkat.

Arsitektur

Diagram berikut menjelaskan arsitektur antarmuka Camera Extensions atau antarmuka extensions-interface : Arsitektur

Gambar 1. Diagram arsitektur Ekstensi Kamera

Seperti yang ditunjukkan dalam diagram, untuk mendukung Ekstensi Kamera, Anda perlu mengimplementasikan extensions-interface disediakan oleh pustaka vendor OEM. Pustaka vendor OEM Anda mengaktifkan dua API: CameraX Extensions API dan Camera2 Extensions API , yang masing-masing digunakan oleh aplikasi CameraX dan Camera2, untuk mengakses ekstensi vendor.

Terapkan perpustakaan vendor OEM

Untuk mengimplementasikan pustaka vendor OEM, salin file camera-extensions-stub ke proyek pustaka sistem. File-file ini menentukan antarmuka Ekstensi Kamera.

File camera-extensions-stub dibagi ke dalam kategori berikut:

File antarmuka penting (jangan diubah)

  • 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

Implementasi wajib (tambahkan implementasi Anda)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Kelas extender Bokeh (terapkan jika ekstensi Bokeh didukung)

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

Kelas ekstensi malam (terapkan jika ekstensi Malam didukung)

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

Kelas ekstensi otomatis (terapkan jika ekstensi Otomatis didukung)

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

Kelas ekstensi HDR (terapkan jika ekstensi HDR didukung)

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

Kelas ekstensi Face Retouch (terapkan jika ekstensi Face Retouch didukung)

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

Utilitas (opsional, dapat dihapus)

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

Anda tidak diharuskan memberikan implementasi untuk setiap ekstensi. Jika Anda tidak mengimplementasikan ekstensi, setel isExtensionAvailable() untuk mengembalikan false atau hapus kelas Extender yang sesuai. Camera2 dan CameraX Extensions API melaporkan ke aplikasi bahwa ekstensi tidak tersedia.

Mari kita telusuri bagaimana API Ekstensi Camera2 dan CameraX berinteraksi dengan pustaka vendor untuk mengaktifkan ekstensi. Diagram berikut mengilustrasikan aliran ujung ke ujung menggunakan ekstensi Malam sebagai contoh:

Arus utama

Gambar 2. Implementasi ekstensi malam

  1. Verifikasi versi:

    Camera2/X memanggil ExtensionVersionImpl.checkApiVersion() untuk memastikan bahwa versi extensions-interface diterapkan OEM kompatibel dengan versi yang didukung Camera2/X.

  2. Inisialisasi pustaka vendor:

    InitializerImpl memiliki metode init() yang menginisialisasi pustaka vendor. Camera2/X menyelesaikan inisialisasi sebelum mengakses kelas Extender.

  3. Buat instance kelas Extender:

    Membuat instance kelas Extender untuk ekstensi. Ada dua jenis Extender: Extender Dasar dan Extender Lanjutan. Anda harus menerapkan satu jenis Extender untuk semua Ekstensi. Untuk informasi selengkapnya, lihat Extender Dasar versus Extender Lanjutan .

    Camera2/X membuat instance dan berinteraksi dengan kelas Extender untuk mengambil informasi dan mengaktifkan ekstensi. Untuk ekstensi tertentu, Camera2/X dapat membuat instance kelas Extender beberapa kali. Akibatnya, jangan lakukan inisialisasi beban berat di konstruktor atau panggilan init() . Lakukan angkat berat hanya saat sesi kamera akan dimulai, seperti saat onInit() dipanggil di Basic Extender atau initSession() dipanggil di Advanced Extender.

    Untuk ekstensi Malam, kelas Extender berikut ini dipakai untuk tipe Basic Extender:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    Dan untuk tipe Advanced Extender:

    • NightAdvancedExtenderImpl.java
  4. Periksa ketersediaan ekstensi:

    Sebelum mengaktifkan ekstensi, isExtensionAvailable() memeriksa apakah ekstensi tersedia pada ID kamera yang ditentukan melalui instance Extender.

  5. Inisialisasi Extender dengan informasi kamera:

    Camera2/X memanggil init() pada instance Extender dan meneruskannya ID kamera dan CameraCharacteristics .

  6. Informasi kueri:

    Memanggil kelas Extender untuk mengambil informasi seperti resolusi yang didukung, masih menangkap perkiraan latensi, dan menangkap kunci permintaan dari Extender sebagai persiapan untuk mengaktifkan ekstensi.

  7. Aktifkan ekstensi pada Extender:

    Kelas Extender menyediakan semua antarmuka yang diperlukan untuk mengaktifkan kelas. Ini menawarkan mekanisme untuk mengaitkan implementasi OEM ke dalam pipa Camera2 seperti menyuntikkan parameter permintaan penangkapan atau mengaktifkan prosesor pos.

    Untuk jenis Extender Lanjutan, Camera2/X berinteraksi dengan SessionProcessorImpl untuk mengaktifkan ekstensi. Camera2/X mengambil instance SessionProcessorImpl dengan memanggil createSessionProcessor() pada Extender.

Bagian berikut menjelaskan aliran ekstensi secara lebih rinci.

Verifikasi versi

Saat memuat pustaka vendor OEM dari perangkat saat runtime, Camera2/X memverifikasi apakah pustaka kompatibel dengan versi extensions-interface . extensions-interface menggunakan versi semantik, atau MAJOR.MINOR.PATCH, misalnya, 1.1.0 atau 1.2.0. Namun, hanya versi mayor dan minor yang digunakan selama verifikasi versi.

Untuk memverifikasi versi, Camera2/X memanggil ExtensionVersionImpl.checkApiVersion() dengan versi extensions-interface yang didukung. Camera2/X kemudian menggunakan versi yang dilaporkan oleh perpustakaan OEM untuk menentukan apakah ekstensi dapat diaktifkan dan kemampuan apa yang harus dipanggil.

Kompatibilitas versi utama

Jika versi utama antarmuka ekstensi berbeda antara Camera2/X dan pustaka vendor, maka itu dianggap tidak kompatibel dan ekstensi dinonaktifkan.

Kompatibilitas terbalik

Selama versi utama identik, Camera2/X memastikan kompatibilitas mundur dengan pustaka vendor OEM yang dibuat dengan versi extensions-interface sebelumnya. Misalnya, jika Camera2/X mendukung extensions-interface 1.3.0, pustaka vendor OEM yang menerapkan 1.0.0, 1.1.0, dan 1.2.0 masih kompatibel. Ini juga berarti bahwa setelah Anda mengimplementasikan versi tertentu dari pustaka vendor, Camera2/X memastikan pustaka tersebut kompatibel dengan versi extension-interface akan datang.

Kompatibilitas ke depan

Kompatibilitas ke depan dengan pustaka vendor extensions-interface lebih baru tergantung pada Anda, OEM. Jika Anda memerlukan beberapa fitur untuk menerapkan ekstensi, Anda mungkin ingin mengaktifkan ekstensi mulai dari versi tertentu. Dalam hal ini, Anda dapat mengembalikan versi extensions-interface yang didukung saat versi pustaka Camera2/X memenuhi persyaratan. Jika versi Camera2/X tidak didukung, Anda dapat mengembalikan versi yang tidak kompatibel seperti 99.0.0 untuk menonaktifkan ekstensi.

Inisialisasi pustaka vendor

Setelah memverifikasi versi extensions-interface diterapkan oleh perpustakaan OEM, Camera2/X memulai proses inisialisasi. Metode InitializerImpl.init() memberi sinyal ke pustaka OEM bahwa aplikasi sedang mencoba menggunakan ekstensi.

Camera2/X tidak membuat panggilan lain ke pustaka OEM (selain dari pemeriksaan versi) hingga pustaka vendor OEM memanggil OnExtensionsInitializedCallback.onSuccess() untuk memberi tahu penyelesaian inisialisasi.

Anda harus mengimplementasikan InitializerImpl pada extensions-interface 1.1.0. Camera2/X melewatkan langkah inisialisasi pustaka jika pustaka vendor OEM mengimplementasikan extensions-interface 1.0.0.

Extender Dasar versus Extender Tingkat Lanjut

Ada dua jenis implementasi extensions-interface : Extender Dasar dan Extender Lanjutan. Advanced Extender telah didukung sejak extensions-interface 1.2.0.

Terapkan Extender Dasar untuk ekstensi yang memproses gambar di kamera HAL atau menggunakan prosesor pasca yang mampu memproses aliran YUV.

Terapkan Extender Tingkat Lanjut untuk ekstensi yang perlu menyesuaikan konfigurasi aliran Camera2 dan mengirim permintaan pengambilan sesuai kebutuhan.

Lihat tabel berikut untuk perbandingannya:

Pemanjang Dasar Extender Tingkat Lanjut
Konfigurasi aliran Tetap
Pratinjau: PRIVATE atau YUV_420_888 (jika prosesor ada)
Gambar diam: JPEG atau YUV_420_888 (jika prosesor ada)
Dapat disesuaikan oleh OEM.
Mengirim permintaan tangkapan Hanya Camera2/X yang dapat mengirim permintaan pengambilan. Anda dapat mengatur parameter untuk permintaan ini. Ketika prosesor disediakan untuk pengambilan gambar, Camera2/X dapat mengirim beberapa permintaan pengambilan dan mengirim semua gambar dan hasil tangkapan ke prosesor. RequestProcessorImpl diberikan kepada Anda untuk menjalankan permintaan pengambilan kamera2 dan mendapatkan hasil dan Gambar.

Camera2/X memanggil startRepeating dan startCapture pada SessionProcessorImpl untuk memberi sinyal kepada OEM untuk memulai permintaan berulang untuk pratinjau dan memulai urutan pengambilan gambar secara berurutan.

Kait di saluran kamera
  • onPresetSession menyediakan parameter sesi.
  • onEnableSession mengirimkan satu permintaan tepat setelah CameraCaptureSession dikonfigurasi.
  • onDisableSession mengirimkan satu permintaan sebelum CameraCaptureSession ditutup.
  • initSession menginisialisasi dan mengembalikan konfigurasi sesi camera2 yang disesuaikan untuk membuat sesi pengambilan.
  • onCaptureSessionStart dipanggil tepat setelah CameraCaptureSession dikonfigurasi.
  • onCaptureSessionEnd dipanggil sebelum CameraCaptureSession ditutup.
Cocok untuk Ekstensi diimplementasikan di kamera HAL atau di prosesor yang memproses gambar YUV.
  • Memiliki implementasi berbasis Camera2 untuk efeknya.
  • Membutuhkan konfigurasi aliran yang disesuaikan seperti aliran RAW.
  • Membutuhkan urutan pengambilan Interaktif.
Versi API yang didukung Ekstensi Camera2: Android T (AOSP eksperimental) atau lebih tinggi
Ekstensi CameraX: ekstensi camera-extensions 1.1.0 atau lebih tinggi
Ekstensi Camera2: Android 12L atau lebih tinggi
Ekstensi CameraX: ekstensi camera-extensions 1.2.0-alpha03 atau lebih tinggi

Alur aplikasi

Tabel berikut menunjukkan tiga jenis alur aplikasi dan panggilan API Ekstensi Kamera yang sesuai. Sementara Camera2/X menyediakan API ini, Anda harus mengimplementasikan pustaka vendor dengan benar untuk mendukung alur ini, yang akan kami jelaskan lebih detail di bagian selanjutnya.

Ekstensi Camera2 Ekstensi CameraX
Ketersediaan ekstensi kueri CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
Informasi kueri CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX menangani sisa informasi di dalam perpustakaan.

Pratinjau dan jepret foto dengan ekstensi diaktifkan CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector

bindToLifecycle(lifecycleOwner, cameraSelector, pratinjau, ...)

Pemanjang Dasar

Antarmuka Basic Extender menyediakan kait ke beberapa tempat di saluran kamera. Setiap jenis ekstensi memiliki kelas Extender yang sesuai yang perlu diterapkan oleh OEM.

Tabel berikut mencantumkan kelas Extender yang perlu diterapkan OEM untuk setiap ekstensi:

Kelas Extender untuk diimplementasikan
Malam NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

Mobil AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

bokeh BokehPreviewExtenderImpl.java

BokehImageCaptureExtenderImpl.java

Retouch wajah BeautyPreviewExtenderImpl.java

BeautyImageCaptureExtenderImpl.java

Kami menggunakan PreviewExtenderImpl dan ImageCaptureExtenderImpl sebagai placeholder dalam contoh berikut. Ganti ini dengan nama file aktual yang Anda terapkan.

Basic Extender memiliki kemampuan sebagai berikut:

  • Suntikkan parameter sesi saat mengonfigurasi CameraCaptureSession ( onPresetSession ).
  • Memberi tahu Anda tentang acara awal dan penutupan sesi pengambilan dan mengirim satu permintaan untuk memberi tahu HAL dengan parameter yang dikembalikan ( onEnableSession , onDisableSession ).
  • Suntikkan parameter pengambilan untuk permintaan ( PreviewExtenderImpl.getCaptureStage , ImageCaptureExtenderImpl.getCaptureStages ).
  • Tambahkan prosesor untuk pratinjau dan pengambilan gambar tetap yang mampu memproses aliran YUV_420_888 .

Mari kita lihat bagaimana Camera2/X memanggil extensions-interface untuk mencapai tiga alur aplikasi yang disebutkan di atas.

Alur aplikasi 1: Periksa ketersediaan ekstensi

BasicExtenderAppFlow1

Gambar 3. Alur aplikasi 1 pada Basic Extender

Dalam alur ini, Camera2/X secara langsung memanggil metode isExtensionAvailable() dari PreviewExtenderImpl dan ImageCaptureExtenderImpl tanpa memanggil init() . Kedua kelas Extender harus mengembalikan true untuk mengaktifkan ekstensi.

Ini sering kali merupakan langkah pertama aplikasi untuk memeriksa apakah jenis ekstensi yang diberikan didukung untuk ID kamera tertentu sebelum mengaktifkan ekstensi. Ini karena beberapa ekstensi hanya didukung pada ID kamera tertentu.

Alur aplikasi 2: Informasi kueri

BasicExtenderAppFlow2

Gambar 4. Alur aplikasi 2 pada Basic Extender

Setelah menentukan apakah ekstensi tersedia, aplikasi harus menanyakan informasi berikut sebelum mengaktifkan ekstensi.

  • Tetap menangkap rentang latensi: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange mengembalikan rentang latensi tangkapan untuk dievaluasi aplikasi apakah perlu mengaktifkan ekstensi untuk skenario saat ini.

  • Ukuran yang didukung untuk pratinjau dan pengambilan permukaan: ImageCaptureExtenderImpl.getSupportedResolutions dan PreviewExtenderImpl.getSupportedResolutions mengembalikan daftar format gambar dan ukuran yang didukung untuk format dan ukuran permukaan.

  • Kunci permintaan dan hasil yang didukung: Camera2/X memanggil metode berikut untuk mengambil kunci permintaan pengambilan yang didukung dan kunci hasil dari implementasi Anda:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X selalu memanggil init() terlebih dahulu pada kelas Extender ini sebelum menanyakan informasi lebih lanjut.

Alur aplikasi 3: Pratinjau/jepret foto dengan ekstensi diaktifkan (implementasi HAL)

BasicExtenderAppFlow3

Gambar 5. Alur aplikasi 3 pada Basic Extender

Diagram di atas mengilustrasikan alur utama pengaktifan pratinjau dan pengambilan gambar tetap dengan ekstensi tanpa prosesor apa pun. Ini berarti kamera HAL memproses ekstensi.

Dalam alur ini, Camera2/X pertama-tama memanggil init() lalu onInit , yang memberi tahu Anda bahwa sesi kamera akan dimulai dengan ekstensi yang ditentukan. Anda dapat melakukan inisialisasi angkat berat di onInit() .

Saat mengonfigurasi CameraCaptureSession , Camera2/X memanggil onPresetSession untuk mendapatkan parameter sesi. Setelah sesi pengambilan berhasil dikonfigurasi, Camera2/X memanggil onEnableSession yang mengembalikan CaptureStageImpl yang berisi parameter pengambilan. Camera2/X segera mengirimkan satu permintaan dengan parameter pengambilan ini untuk memberi tahu HAL. Demikian pula, sebelum sesi pengambilan ditutup, Camera2/X memanggil onDisableSession dan kemudian mengirimkan satu permintaan dengan parameter pengambilan yang dikembalikan.

Permintaan berulang yang dipicu oleh Camera2/X berisi parameter permintaan yang dikembalikan oleh PreviewExtenderImpl.getCaptureStage() . Selanjutnya, permintaan pengambilan gambar berisi parameter yang dikembalikan oleh ImageCaptureExtenderImpl.getCaptureStages() .

Terakhir, Camera2/X memanggil onDeInit() setelah sesi kamera selesai. Anda dapat melepaskan sumber daya di onDeinit() .

Pratinjau prosesor

Selain kamera HAL, Anda juga dapat menerapkan ekstensi dalam prosesor.

Terapkan PreviewExtenderImpl.getProcessorType untuk menentukan jenis prosesor seperti yang dijelaskan di bawah ini:

  • PROCESSOR_TYPE_NONE : Tidak ada prosesor. Gambar diproses di kamera HAL.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY : Jenis prosesor memungkinkan Anda memperbarui permintaan berulang dengan parameter permintaan penangkapan baru berdasarkan TotalCaptureResult terbaru.

    PreviewExtenderImpl.getProcessor harus mengembalikan instance RequestUpdateProcessorImpl yang memproses instance TotalCaptureResult dan mengembalikan instance CaptureStageImpl untuk memperbarui permintaan berulang. PreviewExtenderImpl.getCaptureStage() juga harus mencerminkan hasil pemrosesan dan mengembalikan CaptureStageImpl terbaru.

  • PROCESSOR_TYPE_IMAGE_PROCESSOR : Jenis ini memungkinkan Anda untuk menerapkan prosesor untuk memproses gambar YUV_420_888 dan menulis output ke permukaan PRIVATE .

    Anda perlu menerapkan dan mengembalikan instance PreviewImageProcessorImpl di PreviewExtenderImpl.getProcessor . Prosesor bertanggung jawab untuk memproses gambar input YUV_420_888 . Itu harus menulis output ke format PRIVATE preview. Camera2/X menggunakan permukaan YUV_420_888 alih-alih PRIVATE untuk mengonfigurasi CameraCaptureSession untuk pratinjau.

    Lihat ilustrasi berikut untuk alurnya:

Pratinjau Prosesor

Gambar 6. Alur pratinjau dengan PreviewImageProcessorImpl

Antarmuka PreviewImageProcessorImpl memperluas ProcessImpl dan memiliki tiga metode penting:

  • onOutputSurface(Surface surface, int imageFormat) mengatur permukaan keluaran untuk prosesor. Untuk PreviewImageProcessorImpl , imageFormat adalah format piksel seperti PixelFormat.RGBA_8888 .

  • onResolutionUpdate(Size size) mengatur ukuran gambar input.

  • onImageFormatUpdate(int imageFormat) mengatur format gambar dari gambar input. Saat ini, hanya bisa YUV_420_888 .

Prosesor pengambilan gambar

Untuk pengambilan gambar diam, Anda dapat menerapkan prosesor dengan mengembalikan instance CaptureProcessorImpl menggunakan ImageCaptureExtenderImpl.getCaptureProcessor . Prosesor bertanggung jawab untuk memproses daftar gambar YUV_420_888 yang diambil dan TotalCaptureResult dan menulis output ke permukaan YUV_420_888 .

Anda dapat dengan aman berasumsi bahwa pratinjau diaktifkan dan dijalankan sebelum mengirim permintaan pengambilan gambar diam.

Lihat alurnya pada diagram di bawah ini:

CaptureProcessor

Gambar 7. Tetap menangkap aliran dengan CaptureProcessorImpl

  1. Camera2/X menggunakan permukaan format YUV_420_888 untuk pengambilan gambar diam guna mengonfigurasi sesi pengambilan gambar. Camera2/X menyiapkan CaptureProcessorImpl dengan memanggil:

    • CaptureProcessorImpl.onImageFormatUpdate() dengan YUV_420_888 .
    • CaptureProcessorImpl.onResolutionUpdate() dengan ukuran gambar input.
    • CaptureProcessorImpl.onOutputSurface() dengan permukaan keluaran YUV_420_888 .
  2. ImageCaptureExtenderImpl.getCaptureStages mengembalikan daftar CaptureStageImpl , di mana setiap elemen dipetakan ke instance CaptureRequest dengan parameter pengambilan yang dikirim oleh Camera2/X. Misalnya, jika mengembalikan daftar tiga CaptureStageImpl , Camera2/X mengirimkan tiga permintaan penangkapan dengan parameter penangkapan yang sesuai menggunakan API captureBurst .

  3. Gambar yang diterima dan TotalCaptureResult digabungkan bersama dan dikirim ke CaptureProcessorImpl untuk diproses.

  4. CaptureProcessorImpl menulis Gambar hasil (format YUV_420_888 ) ke permukaan output yang ditentukan oleh panggilan onOutputSurface() . Camera2/X mengubahnya menjadi gambar JPEG jika perlu.

Mendukung kunci dan hasil permintaan pengambilan

Selain pratinjau dan pengambilan kamera, aplikasi dapat mengatur zoom, parameter lampu kilat, atau memicu ketukan untuk fokus. Parameter ini mungkin tidak kompatibel dengan penerapan ekstensi Anda.

Metode berikut telah ditambahkan ke extensions-interface 1.3.0 untuk memungkinkan Anda mengekspos parameter yang didukung implementasi Anda:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() mengembalikan kunci permintaan pengambilan yang didukung oleh implementasi Anda.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() mengembalikan kunci hasil pengambilan yang terdapat dalam hasil pengambilan.

Jika kamera HAL memproses ekstensi, Camera2/X mengambil hasil tangkapan di CameraCaptureSession.CaptureCallback . Namun, jika prosesor diimplementasikan, maka Camera2/X mengambil hasil tangkapan di ProcessResultImpl , yang diteruskan ke metode process() di PreviewImageProcessorImpl dan CaptureProcessorImpl . Anda bertanggung jawab untuk melaporkan hasil tangkapan melalui ProcessResultImpl ke Camera2/X.

Lihat definisi antarmuka CaptureProcessorImpl di bawah ini sebagai contoh. Di extensions-interface 1.3.0 atau lebih tinggi, panggilan process() kedua dipanggil:

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);
}

Untuk pengoperasian kamera umum seperti zoom, ketuk untuk fokus, lampu kilat, dan kompensasi pencahayaan, kami sarankan untuk mendukung tombol berikut untuk permintaan pengambilan dan hasil pengambilan:

  • Perbesar:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Ketuk untuk fokus:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Kilatan:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Kompensasi pencahayaan:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Untuk Basic Extender yang mengimplementasikan 1.2.0 atau versi sebelumnya, CameraX Extensions API secara eksplisit mendukung semua kunci di atas. Untuk extensions-interface 1.3.0, baik CameraX dan Camera2 menghormati daftar yang dikembalikan dan hanya mendukung kunci yang ada di dalamnya. Misalnya, jika Anda memutuskan untuk mengembalikan hanya CaptureRequest#CONTROL_ZOOM_RATIO dan CaptureRequest#SCALER_CROP_REGION dalam implementasi 1.3.0, maka itu berarti hanya zoom yang didukung untuk aplikasi sementara tap-to-focus, flash, dan kompensasi eksposur tidak diizinkan.

Extender Tingkat Lanjut

Advanced Extender adalah jenis implementasi vendor berdasarkan Camera2 API. Jenis Extender ini ditambahkan di extensions-interface 1.2.0. Bergantung pada produsen perangkat, ekstensi mungkin diterapkan di lapisan aplikasi, yang bergantung pada faktor berikut:

  • Konfigurasi aliran kustom : Konfigurasikan aliran kustom seperti aliran RAW atau miliki beberapa aliran untuk ID kamera fisik yang berbeda.

  • Kemampuan untuk mengirim permintaan Camera2: Mendukung logika interaksi rumit yang dapat mengirim permintaan pengambilan dengan parameter berdasarkan hasil permintaan sebelumnya.

Advanced Extender menyediakan pembungkus, atau lapisan perantara, sehingga Anda dapat menyesuaikan konfigurasi aliran dan mengirim permintaan pengambilan sesuai permintaan.

File untuk diimplementasikan

Untuk beralih ke implementasi Extender Lanjutan, metode isAdvancedExtenderImplemented() di ExtensionVersionImpl harus mengembalikan true . Untuk setiap jenis ekstensi, OEM harus mengimplementasikan kelas Extender yang sesuai. File implementasi Extender Lanjutan ada dalam paket lanjutan .

Kelas Extender untuk diimplementasikan
Malam advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Mobil advanced/AutoAdvancedExtenderImpl.java
bokeh advanced/BokehAdvancedExtenderImpl.java
Perbaikan Wajah advanced/BeautyAdvancedExtenderImpl.java

Kami menggunakan AdvancedExtenderImpl sebagai pengganti dalam contoh berikut. Ganti dengan nama file Extender untuk ekstensi yang Anda terapkan.

Mari kita lihat bagaimana Camera2/X memanggil extensions-interface untuk mencapai tiga alur aplikasi.

Alur aplikasi 1: Periksa ketersediaan ekstensi

AdvancedAppFlow1

Gambar 8. Alur aplikasi 1 pada Extender Tingkat Lanjut

Pertama, aplikasi memeriksa apakah ekstensi yang diberikan didukung.

Alur aplikasi 2: Informasi kueri

AdvancedAppFlow2

Gambar 9. Alur aplikasi 2 pada Extender Tingkat Lanjut

Setelah memanggil AdvancedExtenderImpl.init() , aplikasi dapat menanyakan informasi berikut tentang AdvancedExtenderImpl :

  • Perkiraan latensi pengambilan gambar: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() mengembalikan rentang latensi pengambilan untuk dievaluasi oleh aplikasi apakah perlu mengaktifkan ekstensi untuk skenario saat ini.

  • Resolusi yang didukung untuk pratinjau dan pengambilan gambar:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() mengembalikan peta format gambar ke daftar ukuran yang didukung untuk format dan ukuran permukaan pratinjau. OEM harus mendukung setidaknya format PRIVATE .

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() mengembalikan format dan ukuran yang didukung untuk permukaan gambar diam. OEM harus mendukung keluaran format JPEG dan YUV_420_888 .

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() mengembalikan ukuran yang didukung untuk aliran YUV_420_888 tambahan untuk analisis gambar. Jika permukaan YUV analisis gambar tidak didukung, getSupportedYuvAnalysisResolutions() harus mengembalikan null atau daftar kosong.

  • Kunci/hasil permintaan pengambilan yang tersedia (ditambahkan dalam extensions-interface 1.3.0): Camera2/X memanggil metode berikut untuk mengambil kunci permintaan pengambilan yang didukung dan kunci hasil dari implementasi Anda:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Untuk informasi lebih lanjut, lihat Mendukung kunci dan hasil permintaan pengambilan .

Alur aplikasi 3: Pratinjau/jepret foto dengan ekstensi diaktifkan

AdvancedAppFlow3

Gambar 10. Alur aplikasi 3 pada Extender Tingkat Lanjut

Diagram di atas menunjukkan alur utama untuk memulai pratinjau dan pengambilan gambar tetap untuk jenis Extender Lanjutan. Mari kita berjalan melalui setiap langkah.

  1. Contoh SessionProcessorImpl

    Implementasi inti Advanced Extender ada di SessionProcessorImpl , yang bertanggung jawab untuk menyediakan konfigurasi sesi yang disesuaikan dan mengirim permintaan pengambilan untuk memulai pratinjau dan permintaan pengambilan tetap. AdvancedExtenderImpl.createSessionProcessor() dipanggil untuk mengembalikan instance SessionProcessorImpl .

  2. initSession

    SessionProcessorImpl.initSession() menginisialisasi sesi untuk ekstensi. Di sinilah Anda mengalokasikan sumber daya dan mengembalikan konfigurasi sesi untuk menyiapkan CameraCaptureSession .

    Untuk parameter input, Camera2/X menentukan konfigurasi permukaan output untuk pratinjau, pengambilan gambar diam, dan analisis gambar YUV opsional. Konfigurasi permukaan keluaran ini ( OutputSurfaceImpl ) berisi permukaan, ukuran, dan format gambar yang diambil dengan metode berikut di AdvancedExtenderImpl :

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

    Anda harus mengembalikan instance Camera2SessionConfigImpl , yang terdiri dari daftar instance Camera2OutputConfigImpl dan parameter sesi yang digunakan untuk mengonfigurasi CameraCaptureSession . Anda bertanggung jawab untuk mengeluarkan gambar kamera yang benar ke permukaan keluaran yang diteruskan oleh Camera2/X. Berikut adalah beberapa opsi untuk mengaktifkan output:

    • Pemrosesan di kamera HAL: Anda dapat langsung menambahkan permukaan output ke CameraCaptureSession dengan implementasi SurfaceOutputConfigImpl . Ini mengonfigurasi permukaan keluaran yang disediakan ke saluran kamera dan memungkinkan kamera HAL untuk memproses gambar.
    • Memproses permukaan ImageReader perantara (RAW, YUV, dll): Tambahkan permukaan ImageReader perantara ke CameraCaptureSession dengan instance ImageReaderOutputConfigImpl .

      Anda perlu memproses gambar perantara dan menulis gambar hasil ke permukaan keluaran.

    • Menggunakan berbagi permukaan Camera2: Gunakan berbagi permukaan dengan permukaan lain dengan menambahkan Camera2OutputConfigImpl ke metode getSurfaceSharingOutputConfigs() dari Camera2OutputConfigImpl lainnya. Format dan ukuran permukaan harus sama.

    Semua Camera2OutputConfigImpl termasuk SurfaceOutputConfigImpl dan ImageReaderOutputConfigImpl harus memiliki ID unik ( getId() ), yang digunakan untuk menentukan permukaan target dan mengambil gambar dari ImageReaderOutputConfigImpl .

  3. onCaptureSessionStart dan RequestProcessorImpl

    Saat CameraCaptureSession dimulai dan kerangka kerja Kamera memanggil onConfigured() , lalu Camera2/X memanggil SessionProcessorImpl.onCaptureSessionStart() dengan pembungkus permintaan Camera2 RequestProcessImpl . Camera2/X mengimplementasikan RequestProcessImpl , yang memungkinkan Anda untuk mengeksekusi permintaan pengambilan , dan mengambil gambar jika ImageReaderOutputConfigImpl digunakan.

    RequestProcessImpl API mirip dengan Camera2 CameraCaptureSession API dalam hal mengeksekusi permintaan. Perbedaannya adalah:

    • Permukaan target ditentukan oleh ID instance Camera2OutputConfigImpl .
    • Kemampuan mengambil gambar ImageReader .

    Anda dapat memanggil RequestProcessorImpl.setImageProcessor() dengan ID Camera2OutputConfigImpl yang ditentukan untuk mendaftarkan instance ImageProcessorImpl untuk menerima gambar.

    RequestProcessImpl menjadi tidak valid setelah Camera2/X memanggil SessionProcessorImpl.onCaptureSessionEnd() .

  4. Mulai pratinjau dan ambil gambar

    Dalam implementasi Advanced Extender, Anda dapat mengirim permintaan pengambilan melalui antarmuka RequestProcessorImpl . Camera2/X memberi tahu Anda untuk memulai permintaan berulang untuk pratinjau atau urutan pengambilan gambar dengan memanggil masing-masing SessionProcessorImpl#startRepeating dan SessionProcessorImpl#startCapture . Anda harus mengirim permintaan pengambilan untuk memenuhi permintaan pratinjau dan pengambilan gambar ini.

    Camera2/X juga menetapkan parameter permintaan pengambilan melalui SessionProcessorImpl#setParameters . Anda harus mengatur parameter permintaan ini (jika parameter didukung) pada permintaan berulang dan permintaan tunggal.

    Anda harus mendukung setidaknya CaptureRequest.JPEG_ORIENTATION dan CaptureRequest.JPEG_QUALITY . extensions-interface 1.3.0 mendukung kunci permintaan dan hasil, yang diekspos dengan metode berikut:

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

    Saat pengembang menyetel kunci dalam daftar getAvailableCaptureRequestKeys , Anda harus mengaktifkan parameter dan memastikan hasil tangkapan berisi kunci dalam daftar getAvailableCaptureResultKeys .

  5. startTrigger

    SessionProcessorImpl.startTrigger() dipanggil untuk memulai pemicu seperti CaptureRequest.CONTROL_AF_TRIGGER dan CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER . Anda dapat mengabaikan kunci permintaan pengambilan apa pun yang tidak diiklankan di AdvancedExtenderImpl.getAvailableCaptureRequestKeys() .

    startTrigger() telah didukung sejak extensions-interface 1.3.0. Ini memungkinkan aplikasi untuk menerapkan tap-to-focus dan flash dengan ekstensi.

  6. Membersihkan

    Saat menyelesaikan sesi pengambilan, SessionProcessorImpl.onCaptureSessionEnd() dipanggil sebelum menutup CameraCaptureSession . Setelah sesi pengambilan ditutup, deInitSession() melakukan pembersihan.

Mendukung pratinjau, pengambilan gambar diam, dan analisis gambar

Anda harus menerapkan ekstensi untuk pratinjau dan masih merekam kasus penggunaan. Namun, jika latensi terlalu tinggi untuk menampilkan pratinjau dengan lancar, Anda dapat menerapkan efeknya hanya untuk pengambilan gambar diam.

Untuk tipe Basic Extender, terlepas dari mengaktifkan efek untuk pratinjau, Anda harus mengimplementasikan ImageCaptureExtenderImpl dan PreviewExtenderImpl untuk ekstensi tertentu. 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.

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.

Version Added features
1.0.0
  • Version verification
    • ExtensionVersionImpl
  • Basic Extender
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Library initialization
    • InitializerImpl
  • Expose supported resolutions
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Get estimated capture latency
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • 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

Reference implementation

For a reference OEM vendor library implementation, see camera-testlib-extensions . Note that this implementation performs passthroughs without actually implementing the effects.

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.

Frequently asked questions (FAQs)

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 .