2016-03-30 4 views
1

Ich unterstütze die Anwendung mit Videochat Funktionen. Ich verwende für API>=21. Die Kamera funktioniert. Jetzt muss ich Daten von der Kamera meines Geräts empfangen und in ein Byte [] schreiben, und dann übergebe das Array an eine native Methode zur Verarbeitung und Übertragung von Bildern des Gegners. In C++ geschriebene Videoübertragungsfunktion Meine Aufgabe - Video in Byte [] richtig aufzuzeichnen (weil dieses Argument eine native Methode akzeptiert, die alle nächsten Aktionen auf der Videoanzeige ausführen soll).Speichern Camera2 Ausgangsstrom in Byte []

Wenn ich etwas hinzufügen möchte, hört die Kamera auf zu arbeiten. Hilf mir richtig und einfach wie möglich diese Aufgabe zu implementieren. Ich habe versucht, MediaRecorder zu verwenden, aber es schreibt keine Daten in das Byte []. Ich habe standart Google-Beispiele wie Camera2Basic, Camera2Video angesehen. Ich habe versucht, MediaRecorder wie in diesen Tutorials zu realisieren. aber es funktioniert nicht. ImageReader wie ich verstehe, nur für Bilder verwendet. MediaCodec - es ist zu kompliziert, ich konnte es nicht wirklich verstehen. Was ist die bessere und bequemste Art zu implementieren, um ein Bild von der Kamera meines Geräts zu erhalten und es in Byte [] zu speichern. und wenn möglich, geben Sie mir Code oder eine Ressource, wo ich sie sehen kann. Danke

+0

Haben Sie sich die Zuordnungen angesehen? http://developer.android.com/reference/android/renderscript/Allocation.html – rcsumner

+0

@Sumner - Ich habe das versucht. es funktioniert nicht https://android.googlesource.com/platform/cts/+/de096f7/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java#493 – Jackky777

+0

auch ich verstehe nicht, was zu tun ist mit Texturansicht. Beispiel verwende es nicht – Jackky777

Antwort

6

Sie möchten ein ImageReader verwenden; Es ist der beabsichtigte Ersatz der alten Kamera-API-Vorschau-Rückrufe (sowie für die Aufnahme von JPEG- oder RAW-Bildern, die andere häufige Verwendung).

Verwenden Sie das Format YUV_420_888.

ImageReaders Bilder verwenden ByteBuffer anstelle von byte [], aber Sie können den ByteBuffer direkt über JNI übergeben und einen void * Zeiger auf jede Ebene des Bildes mit standard JNI methods erhalten. Das ist viel effizienter, als zuerst in ein Byte [] zu kopieren.


Edit: Noch ein paar Details:

Dies wird vorausgesetzt, Sie Ihre eigene Software Video-Codierung/Übertragung über das Netzwerk Bibliothek, und Sie nicht möchten, dass Android-Hardware-Videoencoder verwenden. (Wenn Sie dies tun, müssen Sie die MediaCodec-Klasse verwenden).

  1. Legen Sie die Vorschauansicht (SurfaceView oder TextureView) fest, und legen Sie die Größe für die gewünschte Vorschauauflösung fest.
  2. Erstellen Sie ImageReader mit dem Format YUV_420_888 und der gewünschten Aufzeichnungsauflösung. Schließen Sie eine listener to it an.
  3. Öffnen Sie die Kameravorrichtung (kann mit den vorherigen Schritten parallel durchgeführt werden)
  4. von der sowohl die Ansicht einer Oberfläche bekommen und die Imagereader, und nutzen sie sowohl eine camera capture session
  5. erstellen Sobald die Sitzung erstellt wird, create a capture request builder mit TEMPLATE_RECORDING (um die Einstellungen für einen Aufzeichnungs-Anwendungsfall zu optimieren) und add both the Surfaces as targets für die Anforderung
  6. Erstellen Sie die Anforderung und legen Sie sie als repeating request fest.
  7. Die Kamera beginnt, Puffer in die Vorschau und den ImageReader zu schieben. Sie erhalten einen OnImageAvailable-Rückruf, sobald ein neuer Frame bereit ist. Erwerben Sie die latest Image from the ImageReader's queue, holen Sie sich die drei ByteBuffer, aus denen das YCbCr-Image besteht, und übergeben Sie sie über JNI an Ihren nativen Code.
  8. Sobald Sie mit der Verarbeitung eines Bildes fertig sind, stellen Sie sicher, close it.Aus Effizienzgründen gibt es eine feste Anzahl von Bildern im ImageReader, und wenn Sie sie nicht zurückgeben, bleibt die Kamera stehen, da keine Puffer zum Beschreiben vorhanden sind. Wenn Sie mehrere Frames parallel verarbeiten müssen, müssen Sie möglicherweise das maxMages-Argument des ImageReader-Konstruktors erhöhen.