2016-10-14 9 views
3

Как говорится в названии, у меня проблема с записью видео на Samsung Note5 с использованием Camera2 API.Запись видео, не работающая с Camera2 API на Samsung Note5 после использования ImageReader

Я адаптировать свой код из образца Camera2Video, но разница в том, что установка я в MediaRecorder с помощью опции конфигурации из CamcorderProfile класса, а также, что во время предварительного просмотра перед началом записи видео я захватывая к ImageReader, а также рендеринг предварительного просмотра до SurfaceTexture (образец не использует ImageReader).

Вот моя startVideoCapture функции (почти идентичен образец)

private boolean startVideoCapture() { 
    if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) { 
     debugToast("Can't start video preview"); 
     return false; 
    } 
    try {   
     closePreviewSession(); 
     if(!setUpMediaRecorder()) 
     { 
      debugToast("setUpMediaRecorder failed"); 
      return false; 
     } 
     SurfaceTexture texture = mTextureView.getSurfaceTexture(); 
     assert texture != null; 
     texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); 
     final CaptureRequest.Builder previewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); 
     List<Surface> surfaces = new ArrayList<Surface>(); 

     Surface previewSurface = new Surface(texture); 
     surfaces.add(previewSurface); 
     previewRequestBuilder.addTarget(previewSurface); 

     Surface recorderSurface = mMediaRecorder.getSurface(); 
     surfaces.add(recorderSurface); 
     previewRequestBuilder.addTarget(recorderSurface); 

     mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { 

      @Override 
      public void onConfigured(CameraCaptureSession cameraCaptureSession) { 
       debugToast("onConfigured callback received"); 
       mCaptureSession = cameraCaptureSession; 
       updateVideoPreview(previewRequestBuilder); 
      } 

      @Override 
      public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { 
       debugToast("onConfigureFailed");      
      } 
     }, mCallbacksInterface.getBackgroundHandler()); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
     debugToast("CameraAccessException"); 
     return false; 
    } catch (IOException e) { 
     e.printStackTrace(); 
     debugToast("IOException"); 
     return false; 
    } 
    debugToast("startVideoCapture success");   
    return true; 
} 

И вот мой код, где я настроить читатель изображений при запуске предварительного просмотра:

 // We set up a CaptureRequest.Builder with the output Surface. 
     CaptureRequest.Builder previewRequestBuilder = mCameraDevice 
       .createCaptureRequest(templateType); 

     previewRequestBuilder.addTarget(mImageReader.getSurface()); 
     previewRequestBuilder.addTarget(surface); 

     // Here, we create a CameraCaptureSession for camera preview. 
     // surface), 
     mCameraDevice.createCaptureSession(
       Arrays.asList(mImageReader.getSurface(), surface), 
       new CameraCaptureSession.StateCallback() { 

     // etc... 

Это все довольно стандартный материал , и он отлично работает на Nexus 5: я могу начать один сеанс захвата для предварительного просмотра с ImageReader в списке поверхностей захвата, затем остановить его и запустить новый с MediaRecorder в списке поверхности и записать видео. Но это не работает на Note5. Я получаю сбой при вызове createCaptureSession с MediaRecorder в startVideoCapture:

10-14 14:49:25.991: E/CameraCaptureSession(13566): Session 1: Failed to create capture session; configuration failed 
10-14 14:49:26.011: W/System.err(13566): android.hardware.camera2.CameraAccessException: Operation timed out in camera service 
10-14 14:49:26.011: W/System.err(13566): at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:118) 
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.utils.CameraBinderDecorator$CameraBinderDecoratorListener.onAfterInvocation(CameraBinderDecorator.java:73) 
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.utils.Decorator.invoke(Decorator.java:81) 
10-14 14:49:26.021: W/System.err(13566): at java.lang.reflect.Proxy.invoke(Proxy.java:393) 
10-14 14:49:26.021: W/System.err(13566): at $Proxy1.waitUntilIdle(Unknown Source) 
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.impl.CameraDeviceImpl.waitUntilIdle(CameraDeviceImpl.java:950) 
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.impl.CameraDeviceImpl.configureStreamsChecked(CameraDeviceImpl.java:399) 
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSessionInternal(CameraDeviceImpl.java:561) 
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSession(CameraDeviceImpl.java:476) 
10-14 14:49:26.021: W/System.err(13566): at com.example.Camera2Object.startVideoCapture(Camera2Object.java:2262) 

Если удалить ImageReader от захвата предварительного просмотра, то он работает отлично.

ли я закрыть ImageReader в closePreviewSession или не нет никакой разницы (я уже призывающую abortCaptures и close на превью CaptureSession).

Кто-нибудь знает, как это решить?

Редактировать: что-то, что возможно связано с тем, что при использовании ImageReader на этом устройстве закрытие CameraDevice в занимает смехотворное долгое время (до 6 секунд). Мне удалось в основном скрыть это от пользователя, сделав это в отдельном потоке, однако если onResume вызывается в течение 6 секунд от , будет задержка, потому что я должен дождаться, когда он закончит закрытие, прежде чем я смогу открыть его снова , Очевидно, что я не могу позволить себе задержка в 6 секунд при начале видеозаписи.

Проблема остается, даже если я ничего не делаю, кроме как позвонить acquireLatestImage(), закройте ее и немедленно верните в обратном вызове ImageReader. Это также происходит, когда разрешение захвата для ImageReader действительно мало. Таким образом, похоже, что это не связано с перегрузкой данных ImageReader.

Системный журнал, охватывающий период от начала приложения до записи видео (и закрытия приложения) в this Pastebin.

+0

Если у вас есть полный системный журнал (logcat) выход за период времени, охватывающий запуск приложения и попытку начать запись видео, было бы легче сказать, что происходит. Это будет включать регистрацию с камеры и камеры HAL. –

+0

@EddyTalvala журнал был слишком велик, чтобы редактировать вопрос, поэтому я разместил его здесь: http://pastebin.com/uqyaC5aM – samgak

ответ

2

из журнала Pastebin:

10-15 19:45:32.501: E/Camera3-Device (3151): камера 0: waitUntilDrainedLocked: ошибка ожидания HAL для слива: время ожидания подключения (-110)

Это обычно означает, что что-то пошло не так в кистях камеры HAL - служба камеры ждет завершения захвата в полете до создания нового сеанса, но некоторые из них никогда не возвращаются. Итак, время ожидания и ошибка возвращается в приложение.

Это, к сожалению, ошибка в коде камеры, предназначенном для устройства, поэтому Samsung должен будет ее исправить.

В качестве обходного пути вы можете попытаться остановить повторяющийся запрос, дождаться завершения всех запросов в полете (устройство переключится в состояние готовности), а затем создаст новый сеанс. Тогда нет никаких захватов для HAL для неправильного использования.

Это добавит дополнительную задержку, и предварительный просмотр замерзнет немного дольше, но, вероятно, будет более надежным в этом случае.

+0

Большое спасибо, обходной путь работает. Обратите внимание, что кто-то еще сталкивается с этой ошибкой: нет необходимости делать то же самое при остановке видеозаписи и перезапуска предварительного просмотра. Это работает так, как ожидалось. – samgak