2016-10-14 4 views
3

제목에서 말하지만 Camera2 API를 사용하여 삼성 Note5에 비디오를 녹화하는 데 문제가 있습니다.ImageReader를 사용한 후 Samsung Note5의 Camera2 API로 비디오가 기록되지 않음

은 내가 Camera2Video 샘플에서 내 코드를 적용했지만, 차이는 I 설정 또한 MediaRecorder 사용하여 구성 CamcorderProfile 클래스 옵션 인 것을 내가 ImageReader로 캡처하고 비디오 녹화를 시작뿐만 아니라 전에 미리 동안 미리보기를 SurfaceTexture으로 렌더링합니다 (샘플에는 ImageReader이 사용되지 않음).

 // 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... 

그것은 모든 꽤 표준 물건입니다 :

여기 (샘플과 거의 동일) 내 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; 
} 

그리고 여기에 미리보기를 시작할 때 나는 이미지 리더를 설정 내 코드입니다입니다 Nexus 5에서 정상적으로 작동합니다. 캡처 화면 목록에서 ImageReader으로 미리보기 용 캡처 세션을 시작한 다음 중지하고 표면 목록에 MediaRecorder이 표시된 새 세션을 시작하고 동영상을 녹화 할 수 있습니다. 그러나 이것은 주 5에서 작동하지 않습니다. MediaRecorderstartVideoCapture에서와 createCaptureSession를 호출 할 때 나는 충돌을 얻을 : 내가 미리보기 캡처에서 ImageReader을 제거하면

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) 

다음 그것을 잘 작동합니다.

내가 closePreviewSession 여부에 ImageReader이 차이 (이미 미리보기 CaptureSessionabortCapturesclose를 호출하고 있습니다)를하지 않습니다 종료 여부.

누구든지 해결 방법을 알고 있습니까?

편집 : 아마도이 기기에서 ImageReader을 사용하면 을 닫으면 으로 끝나는 것은 엄청나게 오랜 시간 (최대 6 초)이 걸릴 수 있습니다. 나는 대부분 사용자가 이것을 별도의 스레드에서 처리하여 숨기지 만, onResume이 6 초 이내에 호출되는 경우 지연 될 것입니다. 다시 열려면 닫을 때까지 기다려야하기 때문입니다. . 비디오 녹화를 시작하면 6 초의 대기 시간을 감당할 수 없습니다.

아무 것도하지 않고 acquireLatestImage()으로 전화를 걸어 닫고 onImageAvailable 콜백 (ImageReader)으로 바로 돌아 오면 문제가 지속됩니다. ImageReader의 캡처 해상도가 실제로 작을 때도 발생합니다. 따라서 데이터가 ImageReader 데이터를 처리하는 데 오버로드 된 것이 원인 인 것 같지 않습니다.

앱 시작부터 비디오 녹화 (및 앱 종료)까지의 시스템 로그는 this Pastebin입니다.

+0

응용 프로그램 시작 및 비디오 녹화 시작을위한 기간 동안 전체 시스템 로그 (logcat) 출력이 있으면 상황을 쉽게 알 수 있습니다. 여기에는 카메라 서비스 및 카메라 HAL의 로깅이 포함됩니다. –

+0

@EddyTalvala 로그가 너무 커서 질문에 편집 할 수 없으므로 여기에 게시했습니다. http://pastebin.com/uqyaC5aM – samgak

답변

2

귀하의 페인본 로그에서 :

10-15 19:45:32.501 : E/Camera3-Device (3151) : 카메라 0 : waitUntilDrainedLocked : HAL이 유출되기를 기다리는 동안 오류가 발생했습니다. 연결 시간 초과 (-110)

이것은 일반적으로 카메라 HAL의 장 카메라 서비스는 새로운 세션을 만들기 전에 기내 캡처가 완료되기를 기다리고 있지만 일부는 절대 반환하지 않습니다. 따라서 시간이 초과되고 오류가 앱으로 반환됩니다.

이것은 장치 관련 카메라 코드의 버그입니다. 불행히도 삼성은이를 수정해야합니다.

일시적인 해결책은 반복 요청을 중지하고 모든 실행 요청이 완료 될 때까지 기다린 다음 (장치가 '준비'상태로 전환 될 때까지) 기다린 다음 새 세션을 만들 수 있습니다. 그런 다음 HAL이 잘못 처리 할 수있는 캡처가 아직 없습니다.

이렇게하면 추가 지연이 발생하고 미리보기가 조금 더 오랫동안 멈추지 만이 경우에는 더 강력합니다.

+0

감사합니다. 이 버그가 발생한 다른 사용자를위한 참고 사항 : 비디오 녹화를 중지하고 미리보기를 다시 시작할 때 똑같은 작업을 수행 할 필요는 없습니다. 그것은 예상대로 작동합니다. – samgak