Почему MediaCodec.reset() генерирует исключение java.lang.IllegalStateException

Официальный документ гласит: "Вызовите reset(), чтобы снова использовать кодек. Вы можете вызвать его из любого состояния, чтобы перевести кодек обратно в неинициализированное состояние".

Однако следующий код иногда создает исключение java.lang.IllegalStateException:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    //do nothing
} else {
    try {
        mediaCodec.reset();
    } catch (Exception ex) {
          //occasionally throws java.lang.IllegalStateException
    }
}

Исключение:

Class: java.lang.IllegalStateException
 Stack trace: java.lang.IllegalStateException
    at android.media.MediaCodec.native_reset(Native Method)
    at android.media.MediaCodec.reset(MediaCodec.java:1794)

1 ответ

Решение

Вы правы, документация немного вводит в заблуждение, потому что есть два возможных состояния, в которых может находиться экземпляр MediaCodec, которые не могут быть сброшены.

Если экземпляр MediaCodec освобожден, состояние "Выпущено" явно не сбрасывается, что приводит к исключению IllegalStateException.

Если экземпляр MediaCodec находится в состоянии "ошибка", поскольку он не может быть создан, он также не сбрасывается, но на этот раз возникает исключение MediaCodec.CodecException. Например, если вы создаете много экземпляров.

Комментарий в исходном коде libstagefright описывает, что в основном делает вызов сброса.

    /* When external-facing MediaCodec object is created,
       it is already initialized.  Thus, reset is essentially
       release() followed by init(), plus clearing the state */

Если вы посмотрите код, то увидите, что при вызове release для уже выпущенного экземпляра MediaCodec это приведет к ошибке INVALID_OPERATION, что приведет к повторной инициализации кодека и в конечном итоге к исключению IllegalStateException.

Надеюсь это прояснило твой вопрос

С наилучшими пожеланиями

Крис

Другие вопросы по тегам