Camera 1/2 / X introduction

Camera1 is available on systems prior to 5.0 and is simple to use Open the Camera, obtain the number of cameras on the current device, open the Camera according to the ID, if you want to do live video, set the preview callback, set the preview buffer, set the Camera capture video stream format, general capture format Nv21, Android standard collection method, preview buff in the preview callback, and then transform YUV data, to FFMPEG soft coding H264 data or through MediaCodec hard coding H264 data, send to the server basically this is the camera data collection method

Before doing android smart tablet project, because the system 5.0 is less, so it has been using camera1 version, in addition to the expansion and reference is foreign god OpenCamera and do a lot of expansion on Camera1, check the address

Camera2 is 5.0, Google’s new set of APIS for cameras by obtaining CameraService to obtain CameraManagr, and through the cameramanager. openCamera method to open the camera, and register the camera to open the listening callback, Add ImageReader Settings and listen to the ImageReader Settings. Listen to the callback to get the preview buffer from the ImageReader

CameraX is a support library for JetPack that provides methods

CameraX Core Library. implementation "Androidx. camera:camera-core:1.0.0" // If you want to use Camera2 extensions. Implementation " camera2:1.0.0" implementation "Androidx. camera:camera-lifecycle:1.0.0" //other // If you to use the Camera View class implementation "Androidx. Camera :camera-view:1.0.0-alpha24 Extensions implementation "androidx. Camera: the camera - Extensions: 1.0.0 - alpha24"Copy the code
Private fun startCamera () {/ / get CameraProvider val cameraProviderFuture = ProcessCameraProvider. GetInstance (this) / / add to monitor CameraProviderFuture. AddListener (Runnable {get cameraProvider val cameraProvider = cameraProviderFuture. The get () // Set imageCapturem mode to initialize imageCapture = ImageCapture.builder ().setCaptuRemode (ImageCapture.capture_mode_minimize_latency).build() ByteBuffer imageAnalyzer = ImageAnalysis.builder ().build().also { it.setAnalyzer(cameraExecutor,ImageAnalysis.Analyzer { image -> val rotationDegrees = image.imageInfo.rotationDegrees Val buffer = image.planes[0].buffer as ByteBuffer = image.close()})} preview = Preview.Builder().build() val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build() cameraProvider.unbindAll() / / bind cameraProvider lifecycle camera = cameraProvider. BindToLifecycle (this, cameraSelector, preview, imageCapture, ImageAnalyzer) // Version 1.0.0 surfaceProvider with preview already created? .setSurfaceProvider(viewFinder.surfaceProvider) }, ContextCompat.getMainExecutor(this)) }Copy the code
/ / get CameraProvider val cameraProviderFuture = ProcessCameraProvider. GetInstance (this) / / @ NonNull source method public static ListenableFuture<ProcessCameraProvider> getInstance( @NonNull Context context) { return Futures.transform(CameraX.getOrCreateInstance(context), cameraX -> { sAppInstance.setCameraX(cameraX); return sAppInstance; }, CameraXExecutors.directExecutor()); } @RestrictTo(Scope.LIBRARY_GROUP) @NonNull public static ListenableFuture<CameraX> getOrCreateInstance(@NonNull Context  context) { Preconditions.checkNotNull(context, "Context must not be null."); synchronized (INSTANCE_LOCK) { boolean isConfigured = sConfigProvider ! = null; ListenableFuture<CameraX> instanceFuture = getInstanceLocked(); if (instanceFuture.isDone()) { try { instanceFuture.get(); } catch (InterruptedException e) { // Should not be possible since future is complete. throw new RuntimeException("Unexpected thread interrupt. Should not be " + "possible since future is already complete.", e); } catch (ExecutionException e) { // Either initialization failed or initialize() has not been called, ensure we // can try to reinitialize. shutdownLocked(); instanceFuture = null; } } if (instanceFuture == null) { if (! isConfigured) { // Attempt initialization through Application or Resources CameraXConfig.Provider configProvider = getConfigProvider(context); if (configProvider == null) { throw new IllegalStateException("CameraX is not configured properly. " + "The most likely cause is you did not include a default " + "implementation in your build such as 'camera-camera2'."); } configureInstanceLocked(configProvider); } // Initialize the cameraX method initializeInstanceLocked(context); instanceFuture = getInstanceLocked(); } return instanceFuture; } } @GuardedBy("INSTANCE_LOCK") private static void initializeInstanceLocked(@NonNull Context context) { Preconditions.checkNotNull(context); Preconditions.checkState(sInstance == null, "CameraX already initialized."); Preconditions.checkNotNull(sConfigProvider); / / initialize camerax camerax camerax = new camerax (sConfigProvider. GetCameraXConfig ()); sInstance = cameraX; sInitializeFuture = CallbackToFutureAdapter.getFuture(completer -> { synchronized (INSTANCE_LOCK) { // The sShutdownFuture should always be successful, otherwise it will not // propagate to transformAsync() due to the behavior of FutureChain. ListenableFuture<Void> future  = FutureChain.from(sShutdownFuture) .transformAsync(input -> cameraX.initInternal(context), CameraXExecutors.directExecutor()); Futures.addCallback(future, new FutureCallback<Void>() { @Override public void onSuccess(@Nullable Void result) { completer.set(null); } @SuppressWarnings("FutureReturnValueIgnored") @Override public void onFailure(Throwable t) { Logger.w(TAG, "CameraX initialize() failed", t); // Call shutdown() automatically, if initialization fails. synchronized (INSTANCE_LOCK) { // Make sure it is the same instance to prevent reinitialization  // during initialization. if (sInstance == cameraX) { shutdownLocked(); } } completer.setException(t); } }, CameraXExecutors.directExecutor()); return "CameraX-initialize"; }}); }Copy the code

preview? .setSurfaceProvider(viewFinder.surfaceProvider)

When creating a Preview method using the PreviewViews view, the system already creates a Preview.SurfaceProvider() binding

  // Synthetic access
    final Preview.SurfaceProvider mSurfaceProvider = new Preview.SurfaceProvider() {

        @OptIn(markerClass = ExperimentalUseCaseGroup.class)
        public void onSurfaceRequested(@NonNull SurfaceRequest surfaceRequest) {
            if (!Threads.isMainThread()) {
                // Post on main thread to ensure thread safety.
                        () -> mSurfaceProvider.onSurfaceRequested(surfaceRequest));
            Logger.d(TAG, "Surface requested by Preview.");
            CameraInternal camera = surfaceRequest.getCamera();
                    transformationInfo -> {
                                "Preview transformation info updated. " + transformationInfo);
                        // TODO(b/159127402): maybe switch to COMPATIBLE mode if target
                        //  rotation is not display rotation.
                        boolean isFrontCamera =
                                        == CameraSelector.LENS_FACING_FRONT;
                                surfaceRequest.getResolution(), isFrontCamera);

            mImplementation = shouldUseTextureView(surfaceRequest, mImplementationMode)
                    ? new TextureViewImplementation(PreviewView.this, mPreviewTransform)
                    : new SurfaceViewImplementation(PreviewView.this, mPreviewTransform);

            PreviewStreamStateObserver streamStateObserver =
                    new PreviewStreamStateObserver(camera.getCameraInfoInternal(),
                            mPreviewStreamStateLiveData, mImplementation);

                    ContextCompat.getMainExecutor(getContext()), streamStateObserver);
            mImplementation.onSurfaceRequested(surfaceRequest, () -> {
                // We've no longer needed this observer, if there is no new StreamStateObserver
                // (another SurfaceRequest), reset the streamState to IDLE.
                // This is needed for the case when unbinding preview while other use cases are
                // still bound.
                if (mActiveStreamStateObserver.compareAndSet(streamStateObserver, null)) {

Copy the code