@Override public void onTextureFrameAvailable(int oesTextureId, float[] transformMatrix, long timestampNs) { checkIsOnCameraThread(); if (camera == null) { // Camera is stopped, we need to return the buffer immediately. surfaceHelper.returnTextureFrame(); return; } if (!dropNextFrame) { surfaceHelper.returnTextureFrame(); dropNextFrame = true; return; } int rotation = getFrameOrientation(); if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { // Undo the mirror that the OS "helps" us with. // http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int) transformMatrix = RendererCommon.multiplyMatrices(transformMatrix, RendererCommon.horizontalFlipMatrix()); } transformMatrix = RendererCommon.rotateTextureMatrix(transformMatrix, rotation); final int rotatedWidth = (rotation % 180 == 0) ? captureFormat.width : captureFormat.height; final int rotatedHeight = (rotation % 180 == 0) ? captureFormat.height : captureFormat.width; cameraStatistics.addPendingFrame(timestampNs); frameObserver.onTextureFrameCaptured( rotatedWidth, rotatedHeight, oesTextureId, transformMatrix, timestampNs); }
// Called on cameraThread so must not "synchronized". @Override public void onPreviewFrame(byte[] data, Camera callbackCamera) { checkIsOnCameraThread(); if (camera == null) { return; } if (camera != callbackCamera) { throw new RuntimeException("Unexpected camera in callback!"); } final long captureTimeNs = TimeUnit.MILLISECONDS.toNanos(SystemClock.elapsedRealtime()); if (eventsHandler != null && !firstFrameReported) { eventsHandler.onFirstFrameAvailable(); firstFrameReported = true; } // Mark the frame owning |data| as used. // Note that since data is directBuffer, // data.length >= videoBuffers.frameSize. if (videoBuffers.reserveByteBuffer(data, captureTimeNs)) { cameraStatistics.addPendingFrame(captureTimeNs); frameObserver.onByteBufferFrameCaptured( data, videoBuffers.frameSize, captureFormat.width, captureFormat.height, getFrameOrientation(), captureTimeNs); } else { Logging.w(TAG, "reserveByteBuffer failed - dropping frame."); } }
private void onOutputFormatRequestOnCameraThread(int width, int height, int framerate) { checkIsOnCameraThread(); if (camera == null) { Logging.e(TAG, "Calling onOutputFormatRequest() on stopped camera."); return; } Logging.d( TAG, "onOutputFormatRequestOnCameraThread: " + width + "x" + height + "@" + framerate); frameObserver.onOutputFormatRequest(width, height, framerate); }
private void startCaptureOnCameraThread( final int width, final int height, final int framerate, final CapturerObserver frameObserver, final Context applicationContext) { Throwable error = null; checkIsOnCameraThread(); if (camera != null) { throw new RuntimeException("Camera has already been started."); } this.applicationContext = applicationContext; this.frameObserver = frameObserver; this.firstFrameReported = false; try { try { synchronized (cameraIdLock) { Logging.d(TAG, "Opening camera " + id); if (eventsHandler != null) { eventsHandler.onCameraOpening(id); } camera = Camera.open(id); info = new Camera.CameraInfo(); Camera.getCameraInfo(id, info); } } catch (RuntimeException e) { openCameraAttempts++; if (openCameraAttempts < MAX_OPEN_CAMERA_ATTEMPTS) { Logging.e(TAG, "Camera.open failed, retrying", e); openCameraOnCodecThreadRunner = new Runnable() { @Override public void run() { startCaptureOnCameraThread( width, height, framerate, frameObserver, applicationContext); } }; cameraThreadHandler.postDelayed(openCameraOnCodecThreadRunner, OPEN_CAMERA_DELAY_MS); return; } openCameraAttempts = 0; throw e; } try { camera.setPreviewTexture(surfaceHelper.getSurfaceTexture()); } catch (IOException e) { Logging.e(TAG, "setPreviewTexture failed", error); throw new RuntimeException(e); } Logging.d( TAG, "Camera orientation: " + info.orientation + " .Device orientation: " + getDeviceOrientation()); camera.setErrorCallback(cameraErrorCallback); startPreviewOnCameraThread(width, height, framerate); frameObserver.onCapturerStarted(true); // Start camera observer. cameraThreadHandler.postDelayed(cameraObserver, CAMERA_OBSERVER_PERIOD_MS); return; } catch (RuntimeException e) { error = e; } Logging.e(TAG, "startCapture failed", error); stopCaptureOnCameraThread(); frameObserver.onCapturerStarted(false); if (eventsHandler != null) { eventsHandler.onCameraError("Camera can not be started."); } return; }