0

アンドロイドカメラ2を使用して、プレビューモードでリアルタイムフレームを抽出し、NDK側(openCv)でステッチします。 私はImageReaderサーフェイスを使ってフレームを取得しています。最大フレーム値に制限されています。アンドロイドカメラ2フレームを取得するときにプレビューが遅くなる

ImageReader.newInstance(800,600,ImageFormat.YUV_420_888, MAX_FRAME); 

すべてのフレームが必要なので、ImageReaderターゲットサーフェスをCaptureRequest.Builderから削除してもう一度追加する必要があります。私たちはこの時点で遅れを持っています。

最大フレームなしでImageReaderを使用するにはどうすればよいですか、またはプレビューでの遅れなしにカメラ2のライブビデオからすべてのフレームを取得する方法を教えてください。

マイコード:

private void startPreview() { 
     if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) { 
      return; 
     } 
     try { 

      SurfaceTexture texture = mTextureView.getSurfaceTexture(); 
      assert texture != null; 
      texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); 
      Surface previewSurface = new Surface(texture); 
      surfaces = new ArrayList<>(); 
      mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); 
      surfaces.add(previewSurface); 
      mPreviewBuilder.addTarget(previewSurface); 
      mPreviewCaptureCallback = new CameraCaptureSession.StateCallback() { 

       @Override 
       public void onConfigured(@NonNull CameraCaptureSession session) { 
//     closePreviewSession(); 
        mPreviewSession = session; 
        try { 
         session.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler); 
        } catch (CameraAccessException e) { 
         e.printStackTrace(); 
        } 
       } 

       @Override 
       public void onConfigureFailed(@NonNull CameraCaptureSession session) { 
        Activity activity = getActivity(); 
        if (null != activity) { 
         Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show(); 
        } 
       } 
      }; 
      mCameraDevice.createCaptureSession(surfaces, mPreviewCaptureCallback, mBackgroundHandler); 
     } catch (CameraAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void addImageReaderSurface() { 
     try { 

      SurfaceTexture texture = mTextureView.getSurfaceTexture(); 
      assert texture != null; 
      texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); 
      Surface previewSurface = new Surface(texture); 
      surfaces = new ArrayList<>(); 
      mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); 
      surfaces.add(previewSurface); 
      mPreviewBuilder.addTarget(previewSurface); 
      newImageReader(10); 
      surfaces.add(mImageReader.getSurface()); 
      mPreviewBuilder.addTarget(mImageReader.getSurface()); 

      mPreviewCaptureCallback = new CameraCaptureSession.StateCallback() { 

       @Override 
       public void onConfigured(@NonNull CameraCaptureSession session) { 
        mPreviewSession = session; 
        try { 
         mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackgroundHandler); 
        } catch (CameraAccessException e) { 
         e.printStackTrace(); 
        } 
       } 

       @Override 
       public void onConfigureFailed(@NonNull CameraCaptureSession session) { 
        Activity activity = getActivity(); 
        if (null != activity) { 
         Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show(); 
        } 
       } 
      }; 
      mCameraDevice.createCaptureSession(surfaces, mPreviewCaptureCallback, mBackgroundHandler); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private void newImageReader(final int count) { 
     mImageReader = ImageReader.newInstance(800, 600, ImageFormat.YUV_420_888, count); 
     mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() { 
      @Override 
      public void onImageAvailable(ImageReader reader) { 
       index++; 
       Log.e("xxx", "frame " + index + " received"); 
       if (index == count) { 
        index = 0; 
//     remove it before reached max value 
        addImageReaderSurface(); 
       } 
      } 
     }, mBackgroundHandler); 
    } 
+0

ImageReaderを再起動する必要はありません。 MAX_FRAMEはキューサイズであり、コールバックが十分に速くてもプレビューフレームがいっぱいになることはありません。プレビューフレームは引き続き流れます。 –

答えて

0

Image img = reader.acquireLatestImage()とリーダーから画像を取得した後、あなたはimg.close()を呼び出す必要があります。

public void onImageAvailable(ImageReader reader) { 
    Image img = reader.acquireLatestImage(); 
    if (img == null) { return; } 
    // do work 
    img.close(); 
} 
関連する問題