<commit_before>package com.tokbox.android.tutorials.custom_video_driver;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;

import com.opentok.android.BaseVideoCapturer;
import com.opentok.android.Publisher;
import com.opentok.android.VideoUtils;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;


public class CustomVideoCapturer extends BaseVideoCapturer implements
        PreviewCallback,
        BaseVideoCapturer.CaptureSwitch {

    private static final String LOG_TAG = CustomVideoCapturer.class.getSimpleName();
    private int cameraIndex = 0;
    private Camera camera;
    private Camera.CameraInfo currentDeviceInfo = null;
    public ReentrantLock previewBufferLock = new ReentrantLock();

    private static final int PIXEL_FORMAT = ImageFormat.NV21;
    PixelFormat pixelFormat = new PixelFormat();

    // True when the C++ layer has ordered the camera to be started.
    private boolean isCaptureStarted = false;
    private boolean isCaptureRunning = false;

    private final int numCaptureBuffers = 3;
    private int expectedFrameSize = 0;

    private int captureWidth = -1;
    private int captureHeight = -1;
    private int[] captureFpsRange;

    private Display currentDisplay;

    private SurfaceTexture surfaceTexture;

    private Publisher publisher;
    private boolean blackFrames = false;
    private boolean isCapturePaused = false;

    private Publisher.CameraCaptureResolution preferredResolution =
            Publisher.CameraCaptureResolution.MEDIUM;
    private Publisher.CameraCaptureFrameRate preferredFramerate =
            Publisher.CameraCaptureFrameRate.FPS_30;

    //default case
    int fps = 1;
    int width = 0;
    int height = 0;
    int[] frame;
    Handler handler = new Handler();

    Runnable newFrame = new Runnable() {
        @Override
        public void run() {
            if (isCaptureRunning) {
                if (frame == null) {
                    VideoUtils.Size resolution = new VideoUtils.Size();
                    resolution = getPreferredResolution();
                    fps = getPreferredFramerate();
                    width = resolution.width;
                    height = resolution.height;
                    frame = new int[width * height];
                }

                provideIntArrayFrame(frame, ARGB, width, height, 0, false);
                handler.postDelayed(newFrame, 1000 / fps);
            }
        }
    };

    public CustomVideoCapturer(Context context, Publisher.CameraCaptureResolution resolution,
                                Publisher.CameraCaptureFrameRate fps) {
        this.cameraIndex = getCameraIndexUsingFront(true);

        // Get current display to query UI orientation
        WindowManager windowManager = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        currentDisplay = windowManager.getDefaultDisplay();
        this.preferredFramerate = fps;
        this.preferredResolution = resolution;
    }

    public synchronized void init() {
        Log.w(LOG_TAG, "init() enetered");
        try {
            camera = Camera.open(cameraIndex);
        } catch (RuntimeException exp) {
            Log.e(LOG_TAG, "The camera is in use by another app");
        }

        currentDeviceInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraIndex, currentDeviceInfo);
        Log.w(LOG_TAG, "init() exit");
    }

    @Override
    public synchronized int startCapture() {
        Log.w(LOG_TAG, "started() entered");
        if (isCaptureStarted) {
            return -1;
        }

        if (camera != null) {
            //check preferredResolution and preferredFramerate values
            VideoUtils.Size resolution = getPreferredResolution();
            configureCaptureSize(resolution.width, resolution.height);

            Camera.Parameters parameters = camera.getParameters();
            parameters.setPreviewSize(captureWidth, captureHeight);
            parameters.setPreviewFormat(PIXEL_FORMAT);
            parameters.setPreviewFpsRange(captureFpsRange[0], captureFpsRange[1]);

            try {
                camera.setParameters(parameters);
            } catch (RuntimeException exp) {
                Log.e(LOG_TAG, "Camera.setParameters(parameters) - failed");
                return -1;
            }

            // Create capture buffers
            PixelFormat.getPixelFormatInfo(PIXEL_FORMAT, pixelFormat);
            int bufSize = captureWidth * captureHeight * pixelFormat.bitsPerPixel
                    / 8;
            byte[] buffer = null;
            for (int i = 0; i < numCaptureBuffers; i++) {
                buffer = new byte[bufSize];
                camera.addCallbackBuffer(buffer);
            }

            try {
                surfaceTexture = new SurfaceTexture(42);
                camera.setPreviewTexture(surfaceTexture);

            } catch (Exception e) {
                e.printStackTrace();
                return -1;
            }

            camera.setPreviewCallbackWithBuffer(this);
            camera.startPreview();

            previewBufferLock.lock();
            expectedFrameSize = bufSize;

            previewBufferLock.unlock();

        } else {
            blackFrames = true;
            handler.postDelayed(newFrame, 1000 / fps);
        }

        isCaptureRunning = true;
        isCaptureStarted = true;
        Log.w(LOG_TAG, "started() exit");
        return 0;
    }

    @Override
    public synchronized int stopCapture() {
        if (camera != null) {
            previewBufferLock.lock();
            try {
                if (isCaptureRunning) {
                    isCaptureRunning = false;<commit_msg>Adding autofocus in custom video capturer<commit_after>package com.tokbox.android.tutorials.custom_video_driver;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;

import com.opentok.android.BaseVideoCapturer;
import com.opentok.android.Publisher;
import com.opentok.android.VideoUtils;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;


public class CustomVideoCapturer extends BaseVideoCapturer implements
        PreviewCallback,
        BaseVideoCapturer.CaptureSwitch {

    private static final String LOG_TAG = CustomVideoCapturer.class.getSimpleName();
    private int cameraIndex = 0;
    private Camera camera;
    private Camera.CameraInfo currentDeviceInfo = null;
    public ReentrantLock previewBufferLock = new ReentrantLock();

    private static final int PIXEL_FORMAT = ImageFormat.NV21;
    PixelFormat pixelFormat = new PixelFormat();

    // True when the C++ layer has ordered the camera to be started.
    private boolean isCaptureStarted = false;
    private boolean isCaptureRunning = false;

    private final int numCaptureBuffers = 3;
    private int expectedFrameSize = 0;

    private int captureWidth = -1;
    private int captureHeight = -1;
    private int[] captureFpsRange;

    private Display currentDisplay;

    private SurfaceTexture surfaceTexture;

    private Publisher publisher;
    private boolean blackFrames = false;
    private boolean isCapturePaused = false;

    private Publisher.CameraCaptureResolution preferredResolution =
            Publisher.CameraCaptureResolution.MEDIUM;
    private Publisher.CameraCaptureFrameRate preferredFramerate =
            Publisher.CameraCaptureFrameRate.FPS_30;

    //default case
    int fps = 1;
    int width = 0;
    int height = 0;
    int[] frame;
    Handler handler = new Handler();

    Runnable newFrame = new Runnable() {
        @Override
        public void run() {
            if (isCaptureRunning) {
                if (frame == null) {
                    VideoUtils.Size resolution = new VideoUtils.Size();
                    resolution = getPreferredResolution();
                    fps = getPreferredFramerate();
                    width = resolution.width;
                    height = resolution.height;
                    frame = new int[width * height];
                }

                provideIntArrayFrame(frame, ARGB, width, height, 0, false);
                handler.postDelayed(newFrame, 1000 / fps);
            }
        }
    };

    public CustomVideoCapturer(Context context, Publisher.CameraCaptureResolution resolution,
                                Publisher.CameraCaptureFrameRate fps) {
        this.cameraIndex = getCameraIndexUsingFront(true);

        // Get current display to query UI orientation
        WindowManager windowManager = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        currentDisplay = windowManager.getDefaultDisplay();
        this.preferredFramerate = fps;
        this.preferredResolution = resolution;
    }

    public synchronized void init() {
        Log.d(LOG_TAG, "init() enetered");
        try {
            camera = Camera.open(cameraIndex);
        } catch (RuntimeException exp) {
            Log.e(LOG_TAG, "The camera is in use by another app");
        }

        currentDeviceInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraIndex, currentDeviceInfo);
        Log.d(LOG_TAG, "init() exit");
    }

    @Override
    public synchronized int startCapture() {
        Log.d(LOG_TAG, "started() entered");
        if (isCaptureStarted) {
            return -1;
        }

        if (camera != null) {
            //check preferredResolution and preferredFramerate values
            VideoUtils.Size resolution = getPreferredResolution();
            configureCaptureSize(resolution.width, resolution.height);

            Camera.Parameters parameters = camera.getParameters();
            parameters.setPreviewSize(captureWidth, captureHeight);
            parameters.setPreviewFormat(PIXEL_FORMAT);
            parameters.setPreviewFpsRange(captureFpsRange[0], captureFpsRange[1]);

            List<String> focusModes = parameters.getSupportedFocusModes();
            if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            }

            try {
                camera.setParameters(parameters);
            } catch (RuntimeException exp) {
                Log.e(LOG_TAG, "Camera.setParameters(parameters) - failed");
                return -1;
            }

            // Create capture buffers
            PixelFormat.getPixelFormatInfo(PIXEL_FORMAT, pixelFormat);
            int bufSize = captureWidth * captureHeight * pixelFormat.bitsPerPixel
                    / 8;
            byte[] buffer = null;
            for (int i = 0; i < numCaptureBuffers; i++) {
                buffer = new byte[bufSize];
                camera.addCallbackBuffer(buffer);
            }

            try {
                surfaceTexture = new SurfaceTexture(42);
                camera.setPreviewTexture(surfaceTexture);

            } catch (Exception e) {
                e.printStackTrace();
                return -1;
            }

            camera.setPreviewCallbackWithBuffer(this);
            camera.startPreview();

            previewBufferLock.lock();
            expectedFrameSize = bufSize;

            previewBufferLock.unlock();

        } else {
            blackFrames = true;
            handler.postDelayed(newFrame, 1000 / fps);
        }

        isCaptureRunning = true;
        isCaptureStarted = true;
        Log.d(LOG_TAG, "started() exit");
        return 0;
    }

    @Override
    public synchronized int stopCapture() {
        if (camera != null) {
            previewBufferLock.lock();
            try {
                if (isCaptureRunning) {
                    isCaptureRunning = false;
{'fraction_non_alphanumeric': 0.08135860979462875, 'fraction_numerical': 0.004897314375987362, 'mean_word_length': 2.3117970180486527, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3442719', 'n_tokens_mistral': 3296, 'n_tokens_neox': 3105, 'n_words': 760}