2017-10-14 19 views
3

Camera 2 APIのsetRepeatingRequest()モードを使用して1fpsのキャプチャを行いたいと思います。Androidカメラ2 API 1fps setRepeatingRequestを使用して

CONTROL_AE_MODECONTROL_AE_MODE_OFFSENSOR_FRAME_DURATIONから1に設定しました。しかし、私はまだ以下のコードで20fpsの非常に高いフレームレートを受け取ります。

キャプチャリクエストテンプレートをTEMPLATE_PREVIEWからTEMPLATE_STILL_CAPTUREに変更してみました。 setRepeatingRequest()を使用して1fpsを達成するにはどうすればよいですか?

CaptureRequest.Builder requestBuilder 
      = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
    requestBuilder.addTarget(imageReader.getSurface()); 
     cameraDevice.createCaptureSession(Collections.singletonList(imageReader.getSurface()), 
      new CameraCaptureSession.StateCallback() { 

       @Override 
       public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { 
        // The camera is already closed 
        if (cameraDevice == null) { 
         return; 
        } 

        captureSession = cameraCaptureSession; 
        try { 
         requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, 
           CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); 
         requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF); 
         requestBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1L); 

         CameraCaptureSession.CaptureCallback captureCallback 
           = new CameraCaptureSession.CaptureCallback() { 

          @Override 
          public void onCaptureCompleted(@NonNull CameraCaptureSession session, 
            @NonNull CaptureRequest request, 
            @NonNull TotalCaptureResult result) { 
          } 
         }; 

         captureSession.setRepeatingRequest(
           requestBuilder.build(), captureCallback, callbackHandler); 
        } catch (CameraAccessException e) { 
         e.printStackTrace(); 
        } 
       } 

       @Override 
       public void onConfigureFailed(
         @NonNull CameraCaptureSession cameraCaptureSession) { 
       } 
      }, null); 
} catch (CameraAccessException e) { 
    e.printStackTrace(); 
} 

答えて

1

まず、SENSOR_FRAME_DURATIONの単位はナノ秒である、the docs

によるので、またrequestBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1000000L);

してみてください、あなたはCountDownTimerを使用して、そして取ってあまりエレガントにそれを行うことができます1秒ごとに写真。あなたが毎秒すべてのカメラのものを初期化しているので、これは悪いことが分かりますが、それはちょうどうまくいくソリューションです。例は次のようになります

new CountDownTimer(5000,1000){ 
    @Override 
    public void onFinish() { (...) } 

    @Override 
    public void onTick(long millisUntilFinished) { 
     // TODO take picture 
    } 
}.start(); 

別の第三の溶液をCamera.Parameters [setPreviewFpsRange(https://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFpsRange(int、INT))を使用することであろうが、それは代わりに、カメラ2のカメラAPIを必要とするであろう。しかし、それは単なる別の可能性です

+0

残念ながら、setPreviewFpsRange()はサポートされている範囲の1つしか選択できないため、これを簡単にしません。ほとんどのデバイスでは、サポートされているフレームレートとして1fpsが表示されません。 –

+0

@AlexCohnあなたはまったく正しいです。しかし、SENSOR_FRAME_DURATIONを正しく使用する簡単な方法では、トリックを行う必要があります – webo80

+0

必ずしもそうではありません。 [SENSOR_INFO_MAX_FRAME_DURATION](https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#SENSOR_INFO_MAX_FRAME_DURATION)に何が伝えられるのかわかりません。フル機能のデバイスでは最低100ミリ秒になることが保証されていますが、他のデバイスに対する保証はありません。** null **でも可能です。 –

1

onCaptureCompleted()の呼び出し頻度は制限されています。しかし、あなたはそのコールバックで何をするかを完全に制御できます。

カメラで20 fpsが生成された場合は、19個のコールバックをスキップして20分の1をキャプチャできます。フレームレートが十分に安定していない場合は、使用した最後のピクチャにタイムスタンプ(SystemClock.elapsedRealtime()を使用)を保持して、1秒後まですべてのコールバックを無視します。あなたが本当に必要な場合は、精度を向上させるためにsleep()で遊ぶことさえできます。

関連する問題