MediaCodec и Camera: цветовые пространства не совпадают

Я пытался заставить кодирование H264 работать с входом, снятым камерой на планшете Android, используя новый низкоуровневыйMediaCodec, С этим я столкнулся с некоторыми трудностями, поскольку MediaCodecAPI плохо документирован, но я наконец-то получил работу.

Я настраиваю камеру следующим образом:

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

Для части кодирования я создаю экземпляр объекта MediaCodec следующим образом:

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

Конечная цель - создать RTP-поток (и переписываться по Skype), но пока я только транслирую необработанный H264 прямо на мой рабочий стол. Там я использую следующий GStreamer-pipe, чтобы показать результат:

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

Все работает хорошо, кроме цветов. Мне нужно установить 2 цветовых формата на компьютере: один для предварительного просмотра камеры (строка помечена как<1>) и один для объекта MediaCodec (помеченный<2>)

Определить приемлемые значения для линий<1> я использовалparameters.getSupportedPreviewFormats(), Исходя из этого, я знаю, что единственные поддерживаемые форматы на камереImageFormat.NV21 а такжеImageFormat.YV2.

За<2>Я извлекMediaCodecInfo.CodecCapabilities-объект для типавидео / АВК, являясь целочисленными значениями 19 (соответствующимиMediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar и 2130708361 (который не соответствует ни одному значениюMediaCodecInfo.CodecCapabilities).

Любое другое значение, кроме указанного выше, приводит к сбою.

Объединение этих настроек дает разные результаты, которые я покажу ниже. Вот скриншот на Android (то есть «настоящие» цвета): Вот результаты, показанные Gstreamer:

<1> = NV21,<2> = COLOR_FormatYUV420Planar

<1> = NV21,<2> = 2130708361

<1> = YV2,<2> = COLOR_FormatYUV420Planar

<1> = YV2,<2> = 2130708361

Как видно, ни один из них не удовлетворяет. YV2-цветовое пространство выглядит наиболее перспективным, но похоже, что красный (Cr) и синий (Cb) инвертированы. Я думаю, что NV21 выглядит чересстрочным (но я не эксперт в этой области).

Поскольку цель состоит в том, чтобы общаться со Skype, я предполагаю, что не должен менять декодер (то есть команду Gstreamer), верно? Это нужно решить в Android и если да, то как? Или это может быть решено путем добавления определенной информации полезной нагрузки RTP? Любое другое предложение?

Ответы на вопрос(4)

Ваш ответ на вопрос