Ausgabestreams, Zuschneiden und Zoomen

Ausgabestreams

Das Kamerasubsystem arbeitet ausschließlich mit der ANativeWindow-basierten Pipeline für alle Auflösungen und Ausgabeformate. Es können mehrere Streams gleichzeitig konfiguriert werden, um einen einzelnen Frame an viele Ziele zu senden, z. B. an die GPU, den Video-Encoder, RenderScript oder an für die App sichtbare Puffer (RAW-Bayer-, verarbeitete YUV- oder JPEG-codierte Puffer).

Zur Optimierung müssen diese Ausgabestreams im Voraus konfiguriert werden. Es kann jeweils nur eine begrenzte Anzahl vorhanden sein. So können Speicherpuffer vorab zugewiesen und die Kamerahardware konfiguriert werden. Wenn Anfragen mit mehreren oder unterschiedlichen Ausgabepipelines gesendet werden, kommt es daher nicht zu Verzögerungen oder Latenz bei der Bearbeitung der Anfrage.

Weitere Informationen zu den garantierten Stream-Ausgabekombinationen, die vom unterstützten Hardware-Level abhängen, finden Sie unter createCaptureSession().

Zuschneiden

Das Zuschneiden des gesamten Pixelarrays (für digitalen Zoom und andere Anwendungsfälle, in denen ein kleineres Sichtfeld gewünscht wird) wird über die Einstellung ANDROID_SCALER_CROP_REGION kommuniziert. Dies ist eine Einstellung pro Anfrage, die sich pro Anfrage ändern kann. Das ist wichtig für die Implementierung eines reibungslosen digitalen Zooms.

Die Region wird als Rechteck (x, y, Breite, Höhe) definiert, wobei (x, y) die obere linke Ecke des Rechtecks beschreibt. Das Rechteck wird im Koordinatensystem des aktiven Pixel-Arrays des Sensors definiert. (0,0) ist dabei das Pixel oben links im aktiven Pixel-Array. Breite und Höhe dürfen also nicht größer sein als die im statischen Informationsfeld ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY angegebenen Abmessungen. Die minimal zulässige Breite und Höhe werden vom HAL über das statische Informationsfeld ANDROID_SCALER_MAX_DIGITAL_ZOOM gemeldet, das den maximal unterstützten Zoomfaktor beschreibt. Die Mindestbreite und ‑höhe des Zuschneidebereichs sind also:

  {width, height} =
   { floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM),
     floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM) }

Wenn der Zuschneidebereich bestimmte Anforderungen erfüllen muss (z. B. muss er mit geraden Koordinaten beginnen und seine Breite/Höhe muss gerade sein), muss das HAL die erforderliche Rundung vornehmen und den endgültigen Zuschneidebereich in die Metadaten des Ausgaberesultats schreiben. Wenn das HAL die Videostabilisierung implementiert, muss es die Zuschneideregion des Ergebnisses anpassen, um die Region zu beschreiben, die nach der Videostabilisierung tatsächlich in der Ausgabe enthalten ist. Im Allgemeinen muss eine App, die die Kamera verwendet, das empfangene Sichtfeld anhand des Zuschneidebereichs, der Abmessungen des Bildsensors und der Brennweite des Objektivs bestimmen können.

Da der Zuschneidebereich für alle Streams gilt, die möglicherweise ein anderes Seitenverhältnis als der Zuschneidebereich haben, kann der für jeden Stream verwendete genaue Sensorbereich kleiner als der Zuschneidebereich sein. Konkret sollte jeder Stream quadratische Pixel und sein Seitenverhältnis beibehalten, indem der definierte Zuschneidebereich nur minimal weiter zugeschnitten wird. Wenn das Seitenverhältnis des Streams breiter als der Zuschneidebereich ist, sollte der Stream vertikal weiter zugeschnitten werden. Wenn das Seitenverhältnis des Streams schmaler als der Zuschneidebereich ist, sollte der Stream horizontal weiter zugeschnitten werden.

In allen Fällen muss der Stream-Zuschnitt in der Mitte des vollständigen Zuschnittbereichs zentriert sein. Jeder Stream wird nur entweder horizontal oder vertikal relativ zum vollständigen Zuschnittbereich zugeschnitten, nie beides.

Wenn beispielsweise zwei Streams definiert sind, ein Stream mit 640 × 480 Pixeln (Seitenverhältnis 4:3) und ein Stream mit 1.280 × 720 Pixeln (Seitenverhältnis 16:9), sehen Sie unten die erwarteten Ausgabebereiche für jeden Stream für einige Beispielbereiche für den Zuschnitt auf einem hypothetischen 3-MP-Sensor (2.000 × 1.500 Pixel).

Zuschneidebereich: (500, 375, 1000, 750) (Seitenverhältnis 4:3)
Zuschneiden des Streams mit 640 × 480 Pixeln: (500, 375, 1000, 750) (entspricht dem Zuschneidebereich)
Zuschneiden des Streams mit 1.280 × 720 Pixeln: (500, 469, 1000, 562)

crop-region-43-ratio

Abbildung 1: Bildverhältnis 4:3

Zuschneidebereich: (500, 375, 1333, 750) (Seitenverhältnis 16:9)
Zuschneiden des Streams auf 640 × 480: (666, 375, 1000, 750)
Zuschneiden des Streams auf 1280 × 720: (500, 375, 1333, 750) (entspricht dem Zuschneidebereich)

crop-region-169-ratio

Abbildung 2: Seitenverhältnis von 16:9

Zuschneidebereich: (500, 375, 750, 750) (Seitenverhältnis 1:1)
Zuschneiden des Streams bei 640 × 480: (500, 469, 750, 562)
Zuschneiden des Streams bei 1.280 × 720: (500, 543, 750, 414)

crop-region-11-ratio

Abbildung 3: Seitenverhältnis 1:1

Ein letztes Beispiel: Ein Stream mit einem quadratischen Seitenverhältnis von 1024 × 1024 anstelle des 480p-Streams:
Zuschneidebereich: (500, 375, 1000, 750) (Seitenverhältnis 4:3)
Zuschneiden des 1024 × 1024-Streams: (625, 375, 750, 750)
Zuschneiden des 1280 × 720-Streams: (500, 469, 1000, 562)

crop-region-43-square-ratio

Abbildung 4: Seitenverhältnis 4:3, quadratisch

Erneute Verarbeitung

Zusätzliche Unterstützung für RAW-Bilddateien wird durch die Unterstützung der Neuverarbeitung von RAW-Bayer-Daten bereitgestellt. Durch diese Unterstützung kann die Kamerapipeline einen zuvor aufgenommenen RAW-Puffer und Metadaten (einen zuvor aufgenommenen Frame) verarbeiten, um eine neue gerenderte YUV- oder JPEG-Ausgabe zu erzeugen.

Zoom

Auf Geräten mit Android 11 oder höher kann eine App den Zoom (digital und optisch) einer Kamera über die Einstellung ANDROID_CONTROL_ZOOM_RATIO verwenden.

Das Zoomverhältnis wird als Gleitkommafaktor definiert. Anstatt ANDROID_SCALER_CROP_REGION für Zuschneiden und Zoomen zu verwenden, kann eine App ANDROID_CONTROL_ZOOM_RATIO verwenden, um die Zoomstufe zu steuern, und ANDROID_SCALER_CROP_REGION für das horizontale und vertikale Zuschneiden, um Seitenverhältnisse zu erzielen, die sich vom nativen Kamerasensor unterscheiden.

Ein Mehrkamerasystem kann mehrere Objektive mit unterschiedlichen Brennweiten enthalten. Der Nutzer kann den optischen Zoom verwenden, indem er zwischen den Objektiven wechselt. Die Verwendung von ANDROID_CONTROL_ZOOM_RATIO bietet in den folgenden Szenarien Vorteile:

  • Beim Zoomen von einem Weitwinkel- zu einem Teleobjektiv: Ein Gleitkommaverhältnis bietet eine bessere Präzision als Ganzzahlwerte von ANDROID_SCALER_CROP_REGION.
  • Herauszoomen von einem Weitwinkelobjektiv zu einem Ultraweitwinkelobjektiv: ANDROID_CONTROL_ZOOM_RATIO unterstützt das Herauszoomen (<1.0f), ANDROID_SCALER_CROP_REGION hingegen nicht.

Zur Veranschaulichung finden Sie hier mehrere Szenarien mit unterschiedlichen Zoomverhältnissen, Zuschneidebereichen und Ausgabestreams, die dieselbe hypothetische Kamera verwenden, die im vorherigen Abschnitt definiert wurde.

Zoomfaktor: 2,0; 1/4 des ursprünglichen Sichtfelds
Zuschneidebereich: (0, 0, 2000, 1500) (Seitenverhältnis 4:3)
Zuschneiden des Streams mit 640 × 480: (0, 0, 2000, 1500) (entspricht dem Zuschneidebereich)
Zuschneiden des Streams mit 1280 × 720: (0, 187, 2000, 1125)

zoom-ratio-2-crop-43

Abbildung 5: 2,0‑facher Zoom, Seitenverhältnis 4:3

Zoomfaktor: 2,0; 1/4 des ursprünglichen Sichtfelds
Zuschneidebereich: (0, 187, 2000, 1125) (Seitenverhältnis 16:9)
Zuschneiden des Streams auf 640 × 480: (250, 187, 1500, 1125) (Pillarboxing)
Zuschneiden des Streams auf 1280 × 720: (0, 187, 2000, 1125) (entspricht dem Zuschneidebereich)

zoom-ratio-2-crop-169

Abbildung 6 2,0‑facher Zoom, Seitenverhältnis 16:9

Zoomfaktor: 0,5; 4-faches des ursprünglichen Sichtfelds (Weitwinkelobjektiv zu Ultraweitwinkelobjektiv gewechselt)
Zuschneidebereich: (250, 0, 1500, 1500) (Seitenverhältnis 1:1)
Zuschneiden des 640 × 480-Streams: (250, 187, 1500, 1125) (Letterbox-Bild)
Zuschneiden des 1280 × 720-Streams: (250, 328, 1500, 844) (Letterbox-Bild)

images/zoom-ratio-0.5-crop-11

Abbildung 7. 0,5-facher Zoom, Seitenverhältnis 1:1

Wie in den Grafiken oben zu sehen ist, ändert sich das Koordinatensystem des Zuschneidebereichs zum effektiven Sichtfeld nach dem Zoomen und wird durch das Rechteck mit den folgenden Abmessungen dargestellt: (0, 0, activeArrayWith, activeArrayHeight). Das Gleiche gilt für AE-/AWB-/AF-Bereiche und Gesichter. Diese Änderung des Koordinatensystems gilt nicht für RAW-Aufnahmen und die zugehörigen Metadaten wie intrinsicCalibration und lensShadingMap.

Im obigen hypothetischen Beispiel und unter der Annahme, dass Ausgabestream 1 (640 × 480) der Sucherstream ist, kann ein 2‑facher Zoom auf zwei Arten erreicht werden:

  • zoomRatio = 2.0, scaler.cropRegion = (0, 0, 2000, 1500)
  • zoomRatio = 1.0 (Standard), scaler.cropRegion = (500, 375, 1000, 750)

Wenn eine App android.control.aeRegions auf das obere linke Viertel des Sucher-Sichtfelds festlegen soll, muss android.control.aeRegions auf (0, 0, 1000, 750) und android.control.zoomRatio auf 2.0 festgelegt werden. Alternativ kann die App android.control.aeRegions auf die entsprechende Region von (500, 375, 1000, 750) für android.control.zoomRatio von 1.0 festlegen.