Я создаю приложение для потоковой передачи видео, которое адаптирует битрейт видео к доступной полосе пропускания восходящей линии связи, и мне бы хотелось, чтобы оно динамически изменяло разрешение видео, чтобы на меньших битрейтах не было так много артефактов сжатия. Хотя у меня все работает, выпуская MediaCodec
и вызывая abortCaptures()
и stopRepeating()
на CameraCaptureSession
, а затем настраивая все для нового разрешения, это вызывает очень заметное прерывание в потоке - по крайней мере, половину второй в моих тестах.
Я использую OpenGL для масштабирования изображения, когда камера изначально не поддерживает требуемое разрешение, аналогично this . Я инициализирую сеанс захвата с двумя поверхностями - одной для предварительного просмотра для пользователя (используя TextureView
) и одной для кодера, это либо непосредственно поверхность ввода MediaCodec, либо моя поверхность текстуры OpenGL.
Это потенциально может быть решено с помощью MediaCodec.createPersistentInputSurface()
, так как я смогу повторно использовать этот экземпляр масштабирующего устройства при изменении разрешения, и мне не придется ничего делать с сеансом захвата, поскольку никаких поверхностных изменений не происходит, пока Это касается камеры, но она доступна только с API 23, и мне нужна эта реализация для поддержки API 21.
Кроме того, существует проблема с повреждением и повторным созданием поверхностей. Например, когда пользователь нажимает кнопку «Назад», действие и TextureView
, которое оно содержит, уничтожаются, что делает поверхность предварительного просмотра недействительной. Затем, когда пользователь снова переходит к этому действию, создается новый TextureView
, и мне нужно начать показывать предварительный просмотр в нем, не внося никакого отставания в поток, видимый масштабирующим устройством / кодировщиком.
Итак, мой вопрос в целом: как изменить набор выходных поверхностей в CameraCaptureSession
или воссоздать CameraCaptureSession
, в то же время внося как можно меньшую задержку в видеопоток?