MediaCodec und Kamera: Farbräume stimmen nicht überein

Ich habe versucht, die H264-Codierung so zu gestalten, dass sie mit den von der Kamera auf einem Android-Tablet mit dem neuen Low-Level-Modus erfassten Eingaben funktioniertMediaCodec. Ich habe einige Schwierigkeiten damit gehabt, da die MediaCodecAPI schlecht dokumentiert ist, aber ich habe endlich etwas zum Arbeiten bekommen.

Ich richte die Kamera wie folgt ein:

        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewFormat(ImageFormat.YV12); // <1>
        parameters.setPreviewFpsRange(4000,60000);
        parameters.setPreviewSize(640, 480);            
        mCamera.setParameters(parameters);

Für den Codierungsteil instanziiere ich das MediaCodec-Objekt wie folgt:

    mediaCodec = MediaCodec.createEncoderByType("video/avc");
    MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 640, 480);
    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 500000);
    mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
    mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar); // <2>
    mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
    mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mediaCodec.start();

Das letzte Ziel ist es, einen RTP-Stream zu erstellen (und mit Skype zu korrespondieren), aber bisher streame ich nur den rohen H264 direkt auf meinen Desktop. Dort verwende ich die folgende GStreamer-Pipeline, um das Ergebnis anzuzeigen:

gst-launch udpsrc port=5555 ! video/x-h264,width=640,height=480,framerate=15/1 ! ffdec_h264 ! autovideosink

Alles funktioniert gut, bis auf die Farben. Ich muss im Computer 2 Farbformate einstellen: eines für die Kameravorschau (Zeile markiert mit<1>) und eine für das MediaCodec-Objekt (markiert mit<2>)

Festlegen der zulässigen Werte für die Zeilen<1> ich benutzteparameters.getSupportedPreviewFormats(). Daraus weiß ich, dass die einzigen unterstützten Formate auf der Kamera sindImageFormat.NV21 undImageFormat.YV2.

Zum<2>Ich holte dieMediaCodecInfo.CodecCapabilities-Objekt für Typvideo / avcwobei es sich um die ganzzahligen Werte 19 handelt (entsprechendMediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar und 2130708361 (entspricht keinem Wert vonMediaCodecInfo.CodecCapabilities).

Jeder andere Wert als der oben angegebene führt zu einem Absturz.

Wenn Sie diese Einstellungen kombinieren, erhalten Sie verschiedene Ergebnisse, die im Folgenden gezeigt werden. Hier ist der Screenshot auf Android (d. H. Die "echten" Farben): Hier sind die von Gstreamer gezeigten Ergebnisse:

<1> = NV21,<2> = COLOR_FormatYUV420Planar

<1> = NV21,<2> = 2130708361

<1> = YV2,<2> = COLOR_FormatYUV420Planar

<1> = YV2,<2> = 2130708361

Wie zu sehen ist, ist keines davon zufriedenstellend. Der YV2-Farbraum sieht am vielversprechendsten aus, sieht aber so aus, als ob Rot (Cr) und Blau (Cb) invertiert sind. Die NV21 sieht wohl interlaced aus (allerdings bin ich kein Experte auf diesem Gebiet).

Da der Zweck die Kommunikation mit Skype ist, gehe ich davon aus, dass ich den Decoder (d. H. Den Gstreamer-Befehl) nicht ändern sollte, oder? Soll das in Android gelöst werden und wenn ja: wie? Oder kann dies gelöst werden, indem bestimmte RTP-Nutzdaten hinzugefügt werden? Irgendwelche anderen Vorschläge?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage