2015-06-02 16 views
6

Ich lerne über Grafikas "Continuous Capture" Aktivität, es geht um die Aufnahme eines Videos mit MediaCodec.Crop Video vor dem Kodieren mit MediaCodec für Grafika's "Continuous Capture" -Aktivität

Die Aktivität Quellcode ist bei https://github.com/google/grafika/blob/master/src/com/android/grafika/ContinuousCaptureActivity.java

das Programm eine SurfaceTexture obj verwendet, um Daten von der Kamera zu empfangen und erzeugt 2 EGLSurface obj mit diesem SurfaceTexture OBJ, eine EGLSurface obj speist die Daten zu MediaCodec und die anderen Beschickungen Daten SurfaceView für die Kameravorschau. MediaCodec codiert die Daten in h264-Daten und das MediaMuxer-Obj schreibt h264-Daten in eine mp4-Datei.

Aber es gibt ein Problem, die Vorschau-Größe von der Kamera unterstützt Landspace (Breite> Höhe) wie 1920 * 1080, 1440 * 1080, 720 * 480 und so weiter. Normalerweise nehmen wir das Telefon im Hochformat, wenn wir ein Video aufnehmen, also sollten wir API: Camera.setDisplayOrientation (90) verwenden, um das Bild zu einem Hochformat zu drehen, dann wird ein Hochformatvideo aufgenommen.

Aber ich möchte ein Landschaftsvideo mit dem Telefonportrait in meiner Hand aufnehmen, ich muss jeden Rahmen von der Kamera zuschneiden. Meine Methode ist, dass Sie die untere und obere Kante eines jeden Frame-Bildes abschneiden und die Mitte des Bildes behalten, dann wird das linke Bild ein Landscape-Bild sein.

Aber ich bin nicht vertraut mit opengl, ich weiß nicht, wie man die SurfaceTexture Daten zuschneidet. Könnte mir jemand, der gut in OpenGL ist, helfen?

Antwort

12

Sehen Sie sich die Aktivität "Textur von Kamera" an. Beachten Sie, dass Sie das Bild auf verschiedene Arten bearbeiten können, insbesondere "Zoom". Der "Zoom" erfolgt durch Änderung der Texturkoordinaten.

Die ScaledDrawable2D Klasse tut dies; Der Aufruf setScale() ändert den "Zoom", anstatt den Rect selbst zu skalieren. Texturkoordinaten reichen von 0.0 bis einschließlich 1.0, und die getTexCoordArray()-Methode modifiziert sie, um eine Teilmenge der Textur zu überspannen.

Um die Frames zu schneiden, müssten Sie die Texturkoordinaten proportional ändern. Zum Beispiel, wenn das Eingangsvideo 720x720 Porträt 720x1280, und Sie wollen, würden Sie die Koordinaten von diesem ändern:

[0.0, 0.0] [1.0, 0.0] 
[0.0, 1.0] [1.0, 1.0] 

dazu:

[0.0, 280/1280.0] [1.0, 280/1280.0] 
[0.0, 1000/1280.0] [1.0, 1000/1280.0] 

und dann die eher auf einem Platz machen als Ein Rechteck.

+0

Vielen Dank! Deine Antwort löst genau mein Problem! Ich habe Ihr Stackoverflow-Profil besucht. Ich habe erfahren, dass du viele Jahre in Google gearbeitet hast und widme dich der Android-Entwicklung. Mit einem Wort, du bist ein gottgleicher Programmierer. – dragonfly

+0

Ich freue mich, dass Sie der Autor von grafika und bigflake sind, weil ich beide studiert habe und eine Frage stellen muss. Sie haben mehrere Demos über MediaCodec einschließlich Video und Audio geschrieben. Aber es gibt keine Demos, die sowohl Video als auch Audio aufzeichnen. Ich denke, wir können Video- und Audiodaten gleichzeitig mit MediaCodec kodieren und sie mit MediaMuxer in eine mp4-Datei schreiben. Aber warum hast du keine solche Demo geschrieben? Jetzt bereite ich mich darauf vor, eine solche Demo zu schreiben, aber ich bin neu in diesem Bereich. Können Sie mir Ratschläge geben? – dragonfly

+0

Ich war im "Grafik" -Team, nicht im "Medien" -Team, daher war das Senden von Grafiken an MediaCodec Teil meines Tagesjobs. Ich habe nicht mit Audiokomprimierung gearbeitet und bin nie dazu gekommen, damit zu spielen, also keine A/V-Demo. Ihr Plan ist richtig: Erstellen Sie einen zweiten MediaCodec, der die Audiodaten verarbeitet, und geben Sie die Ausgabe von jedem in eine einzelne MediaMuxer-Instanz mit zwei Spuren ein.Der Muxer-Teil wird in https://android.googlesource.com/platform/cts/+/lollipop-release/tests/tests/media/src/android/media/cts/MediaMuxerTest.java getestet, aber das übt stattdessen MediaExtractor aus MediaCodec. – fadden