Невозможно передать изображения на поверхность RecordingSession с помощью ImageWriter ⇐ JAVA
-
Гость
Невозможно передать изображения на поверхность RecordingSession с помощью ImageWriter
Я пытаюсь создать приложение, которое использует Camera2 как для обнаружения QR-кодов, так и для записи видео.
У меня много выходов, и поскольку я не могу подключить все сразу к камере, мне нужно было выполнить как обработку кадров (QR-код или что-то еще), так и запись мультимедиа в одном выходе камеры. Я решил использовать ImageReader, где я получаю свои Image, которые затем могу обработать, а затем передать их на другую выходную поверхность, в данном случае MediaRecorder's Surface, используя ImageWriter. Итак:
ImageReader -> выполните обработку ML для Image -> ImageWriter -> MediaRecorder Моя текущая настройка выглядит следующим образом:
класс VideoPipeline(ширина: Int, высота: Int, формат: Int): ImageReader.OnImageAvailableListener { частная переменная passThroughImageWriter: ImageWriter? = ноль в этом { imageReader = ImageReader.newInstance(ширина, высота, формат, 5) imageReader.setOnImageAvailableListener(this, videoThreadHandler) setupCamera(imageReader.surface,viewSurface, photoOutputSurface) } весело startRecording() { val RecorderSurface = MediaCodec.createPersistentInputSurface() val-рекордер = MediaRecorder(...) Recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE) //куча другого кода настройки для медиа-рекордера Recorder.setInputSurface(поверхность) рекордер.prepare() рекордер.start() passThroughImageWriter = ImageWriter.newInstance(recorderSurface, 5) } переопределить удовольствие onImageAvailable(читатель: ImageReader) { val image = reader.acquireLatestImage() если (passThroughImageWriter! = ноль) { // Перемещает изображение в ImageWriter, закрывать не нужно passThroughImageWriter?.queueInputImage(изображение) } еще { // Здесь больше ничего не происходит, закройте изображение. изображение.закрыть() } } } Но это каждый раз терпит неудачу, независимо от того, какой format я использую (пробовал ImageFormat.YUV_420_888, ImageFormat.PRIVATE и ) PixelFormat.RGB888):
VideoPipeline D --> запись 1280 x 960, 34 кадра.. GraphicBufferSource D получил буфер с новым dataSpace # 104. GraphicBufferSource W выпустил незаполненные слоты: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22. , 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 , 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] VideoPipeline D --> запись 1280 x 960 34 кадра.. GraphicBufferSource W выпустил незаполненные слоты: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22. , 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 , 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] Ошибка RecordingSession E MediaRecorder: 268435556 (-1007) Сеанс записи. Остановка сеанса записи.. VideoPipeline D --> запись 1280 x 960 34 кадра.. GraphicBufferSource W выпустил незаполненные слоты: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22. , 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 , 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] Ошибка остановки MediaRecorder E: -1007 AndroidRuntime D Завершение работы виртуальной машины AndroidRuntime E ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: основное Процесс: com.mrousavy.camera.example, PID: 6406. java.lang.RuntimeException: остановка не удалась. в android.media.MediaRecorder.stop (собственный метод) по адресу com.mrousavy.camera.core.RecordingSession.stop(RecordingSession.kt:103) по адресу com.mrousavy.camera.core.RecordingSession._init_$lambda$0(RecordingSession.kt:75) на com.mrousavy.camera.core.RecordingSession.$r8$lambda$enBPf4dA0r-MTevnd6ChW75ZCDg (неизвестный источник: 0) на com.mrousavy.camera.core.RecordingSession$$ExternalSyntheticLambda0.onError (неизвестный источник: 2) в android.media.MediaRecorder$EventHandler.handleMessage(MediaRecorder.java:1615) в android.os.Handler.dispatchMessage(Handler.java:106) в android.os.Looper.loopOnce(Looper.java:201) в android.os.Looper.loop(Looper.java:288) в android.app.ActivityThread.main(ActivityThread.java:7872) в java.lang.reflect.Method.invoke (собственный метод) на com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) Есть идеи, почему?
Полный код:
[*]VideoPipeline.kt [*]RecordingSession.kt
К вашему сведению: до того, как я использовал ImageWriter, у меня был конвейер OpenGL, который просто передавал данные на поверхность MediaRecorder с использованием поверхностей OpenGL, и он работал прекрасно. Итак, я думаю, что MediaRecorder настроен правильно, должно быть что-то с ImageWriter, по моему мнению.
Вот разница, в которой я переключился с конвейера OpenGL на ImageWriter: 4e96eb7 (причина в том, что OpenGL всегда RGB, а мне нужны ЧАСТНЫЕ/YUV-кадры) Буду признателен за любые подсказки/помощь!
Я пытаюсь создать приложение, которое использует Camera2 как для обнаружения QR-кодов, так и для записи видео.
У меня много выходов, и поскольку я не могу подключить все сразу к камере, мне нужно было выполнить как обработку кадров (QR-код или что-то еще), так и запись мультимедиа в одном выходе камеры. Я решил использовать ImageReader, где я получаю свои Image, которые затем могу обработать, а затем передать их на другую выходную поверхность, в данном случае MediaRecorder's Surface, используя ImageWriter. Итак:
ImageReader -> выполните обработку ML для Image -> ImageWriter -> MediaRecorder Моя текущая настройка выглядит следующим образом:
класс VideoPipeline(ширина: Int, высота: Int, формат: Int): ImageReader.OnImageAvailableListener { частная переменная passThroughImageWriter: ImageWriter? = ноль в этом { imageReader = ImageReader.newInstance(ширина, высота, формат, 5) imageReader.setOnImageAvailableListener(this, videoThreadHandler) setupCamera(imageReader.surface,viewSurface, photoOutputSurface) } весело startRecording() { val RecorderSurface = MediaCodec.createPersistentInputSurface() val-рекордер = MediaRecorder(...) Recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE) //куча другого кода настройки для медиа-рекордера Recorder.setInputSurface(поверхность) рекордер.prepare() рекордер.start() passThroughImageWriter = ImageWriter.newInstance(recorderSurface, 5) } переопределить удовольствие onImageAvailable(читатель: ImageReader) { val image = reader.acquireLatestImage() если (passThroughImageWriter! = ноль) { // Перемещает изображение в ImageWriter, закрывать не нужно passThroughImageWriter?.queueInputImage(изображение) } еще { // Здесь больше ничего не происходит, закройте изображение. изображение.закрыть() } } } Но это каждый раз терпит неудачу, независимо от того, какой format я использую (пробовал ImageFormat.YUV_420_888, ImageFormat.PRIVATE и ) PixelFormat.RGB888):
VideoPipeline D --> запись 1280 x 960, 34 кадра.. GraphicBufferSource D получил буфер с новым dataSpace # 104. GraphicBufferSource W выпустил незаполненные слоты: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22. , 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 , 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] VideoPipeline D --> запись 1280 x 960 34 кадра.. GraphicBufferSource W выпустил незаполненные слоты: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22. , 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 , 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] Ошибка RecordingSession E MediaRecorder: 268435556 (-1007) Сеанс записи. Остановка сеанса записи.. VideoPipeline D --> запись 1280 x 960 34 кадра.. GraphicBufferSource W выпустил незаполненные слоты: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22. , 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 , 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63] Ошибка остановки MediaRecorder E: -1007 AndroidRuntime D Завершение работы виртуальной машины AndroidRuntime E ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: основное Процесс: com.mrousavy.camera.example, PID: 6406. java.lang.RuntimeException: остановка не удалась. в android.media.MediaRecorder.stop (собственный метод) по адресу com.mrousavy.camera.core.RecordingSession.stop(RecordingSession.kt:103) по адресу com.mrousavy.camera.core.RecordingSession._init_$lambda$0(RecordingSession.kt:75) на com.mrousavy.camera.core.RecordingSession.$r8$lambda$enBPf4dA0r-MTevnd6ChW75ZCDg (неизвестный источник: 0) на com.mrousavy.camera.core.RecordingSession$$ExternalSyntheticLambda0.onError (неизвестный источник: 2) в android.media.MediaRecorder$EventHandler.handleMessage(MediaRecorder.java:1615) в android.os.Handler.dispatchMessage(Handler.java:106) в android.os.Looper.loopOnce(Looper.java:201) в android.os.Looper.loop(Looper.java:288) в android.app.ActivityThread.main(ActivityThread.java:7872) в java.lang.reflect.Method.invoke (собственный метод) на com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) Есть идеи, почему?
Полный код:
[*]VideoPipeline.kt [*]RecordingSession.kt
К вашему сведению: до того, как я использовал ImageWriter, у меня был конвейер OpenGL, который просто передавал данные на поверхность MediaRecorder с использованием поверхностей OpenGL, и он работал прекрасно. Итак, я думаю, что MediaRecorder настроен правильно, должно быть что-то с ImageWriter, по моему мнению.
Вот разница, в которой я переключился с конвейера OpenGL на ImageWriter: 4e96eb7 (причина в том, что OpenGL всегда RGB, а мне нужны ЧАСТНЫЕ/YUV-кадры) Буду признателен за любые подсказки/помощь!
Мобильная версия