MediaCodec and Camera: przestrzenie kolorów się nie zgadzają

Starałem się, aby kodowanie H264 działało z wejściem przechwyconym przez kamerę na tablecie z Androidem przy użyciu nowego niskiego poziomuMediaCodec. Przeżyłem z tym pewne trudności, ponieważ MediaCodecAPI jest słabo udokumentowany, ale w końcu mam coś do roboty.

Konfiguruję kamerę w następujący sposób:

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

Dla części kodującej tworzę instancję obiektu MediaCodec w następujący sposób:

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

Ostatecznym celem jest stworzenie strumienia RTP (i korespondowanie ze Skype), ale jak dotąd przesyłam strumieniowo surowy H264 bezpośrednio na mój pulpit. Korzystam z następującego potoku GStreamer, aby pokazać wynik:

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

Wszystko działa dobrze, z wyjątkiem kolorów. Muszę ustawić 2 formaty kolorów w komputerze: jeden dla podglądu kamery (linia oznaczona za pomocą<1>) i jeden dla obiektu MediaCodec (oznaczonego tagiem<2>)

Aby określić dopuszczalne wartości dla linii<1> użyłemparameters.getSupportedPreviewFormats(). Z tego wiem, że jedynymi obsługiwanymi formatami w aparacie sąImageFormat.NV21 iImageFormat.YV2.

Dla<2>, OdzyskałemMediaCodecInfo.CodecCapabilities-obiekt dla typuwideo / avc, będące wartościami całkowitymi 19 (odpowiadająceMediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar i 2130708361 (co nie odpowiada żadnej wartościMediaCodecInfo.CodecCapabilities).

Każda inna wartość niż powyższa powoduje awarię.

Połączenie tych ustawień daje różne wyniki, które pokażę poniżej. Oto zrzut ekranu na Androida (tzn. „Prawdziwe” kolory): Oto wyniki pokazane przez Gstreamer:

<1> = NV21,<2> = COLOR_FormatYUV420Planar

<1> = NV21,<2> = 2130708361

<1> = YV2,<2> = COLOR_FormatYUV420Planar

<1> = YV2,<2> = 2130708361

Jak widać, żaden z nich nie jest zadowalający. Przestrzeń kolorów YV2 wygląda najbardziej obiecująco, ale wygląda na to, że czerwony (Cr) i niebieski (Cb) są odwrócone. Wygląda na to, że NV21 przeplata się (jednak nie jestem ekspertem w tej dziedzinie).

Ponieważ celem jest komunikowanie się ze Skype, zakładam, że nie powinienem zmieniać dekodera (tj. Polecenia Gstreamer), prawda? Czy to ma być rozwiązane w Androidzie, a jeśli tak, to w jaki sposób? Czy można to rozwiązać, dodając pewne informacje o ładunku RTP? Jakieś inne sugestie?

questionAnswers(4)

yourAnswerToTheQuestion