Android MediaCodec медленнее в асинхронном режиме, чем в синхронном режиме?

опять мой вопрос относительно андроидов класса MediaCodec. Мне успешно удалось декодировать необработанный контент h264 и отобразить результат в двух TextureView. Поток h264 поступает с сервера, на котором запущена сцена openGL. Сцена имеет камеру и поэтому реагирует на ввод данных пользователем. Чтобы еще больше уменьшить задержку между входом на сервере и реальным результатом на смартфоне, я думал об использовании асинхронного режима MediaCodecs. Вот как я настроил оба варианта, синхронный и асинхронный:

асинхронный:

//decoderCodec is "video/avc"
MediaFormat fmt = MediaFormat.createVideoFormat(decoderCodec, 1280,720);
codec.setCallback(new MediaCodec.Callback() {

    @Override
    public void onInputBufferAvailable(MediaCodec codec, int index) {
        byte[] frameData;
        try {
            frameData = frameQueue.take(); //this call is blocking
        } catch (InterruptedException e) {
            return;
        }

        ByteBuffer inputData = codec.getInputBuffer(index);
        inputData.clear();
        inputData.put(frameData);

        codec.queueInputBuffer(index, 0, frameData.length, 0, 0);
    }

    @Override
    public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) {
        codec.releaseOutputBuffer(index, true);
    }

     //The two other methods are left blank at the moment.

});


codec.configure(fmt, surface, null, 0);
codec.start();

Синхронизация: (настраивается как Async, кромеcodec.setCallback(...) часть. Класс, в котором находятся оба варианта, - Runnable.

public void run() {

    while(!Thread.interrupted())
    {
        if(!IS_ASYNC) {
            byte[] frameData;
            try {
                frameData = frameQueue.take(); //this call is blocking
            } catch (InterruptedException e) {
                break;
            }

            int inIndex = codec.dequeueInputBuffer(BUFFER_TIMEOUT);

            if (inIndex >= 0) {
                ByteBuffer input = codec.getInputBuffer(inIndex);
                input.clear();
                input.put(frameData);
                codec.queueInputBuffer(inIndex, 0, frameData.length, 0, 0);
            }

            MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
            int outIndex = codec.dequeueOutputBuffer(bufferInfo, BUFFER_TIMEOUT);

            if(outIndex >= 0)
                codec.releaseOutputBuffer(outIndex, true);
        }
        else sleep(3000); //Just for testing, if we are in Async, this thread has nothing to do actually...
    }
}

Оба подхода работают, но я наблюдаю, что видео, воспроизводимые в синхронном режиме, намного плавнее, а задержка также ниже.

Я пришел с идеей использования асинхронного режима, потому чтоframeQueue этоLinkedBlockingDeque и я подумал, что если синхронный декодер слишком долго ожидает поступления данных нового кадра, декодированный вывод уже может быть доступен, но не отображается из-за характера блокировки очереди. С другой стороны, я не хотел делать что-то вроде занятого ожидания и опрашивать очередь, inputBuffers и outputBuffers все время.

Поэтому я попробовал AsyncMode, используя Callbacks, но результат, который я получаю, хуже, чем в синхронном режиме. Вопрос к вам, ребята: почему? Я неправильно использую асинхронный режим или это что-то еще?

Спасибо за любые отзывы!

Christoph

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

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