Android FOCUS_MODE_CONTINUOUS_VIDEO и захват кадров предварительного просмотра

Я разрабатываю приложение для распознавания изображений и хотел бы, чтобы камера постоянно фокусировалась автоматически. Ребята из ZXing решили эту проблему, вызывая autofocus() каждые несколько секунд, но на некоторых камерах это не фокусируется плавно, а перемещается в один конец и перефокусируется. На моем телефоне Alcatel 995, gingerbread 2.3.3 API level 10 каждый раз, когда это происходит, он издает тревожный щелчок.

Этот телефон не поддерживает FOCUS_MODE_CONTINUOUS_PICTURE. Я попытался использовать FOCUS_MODE_CONTINUOUS_VIDEO, который поддерживается, и это не сработало. Я написал тестовое приложение, которое обычно фиксировало каждый кадр предварительного просмотра камеры с обратным вызовом, но оно не фокусировалось. Я добавил в приложение функцию видеозаписи, и при записи видео камера постоянно делает автофокус. Но я думаю, что запись видео лишает возможности получать обратный вызов для каждого кадра. Это обсуждалось на странице https://stackoverflow.com/questions/9477042/extract-video-frames-while-recording-the-video-on-android?rq=1 и Как показывать предварительный просмотр с камеры в режиме реального времени во время записи видео?

Вот часть этого тестового кода:

public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open();
    try {
        Camera.Parameters parameters = mCamera.getParameters();
        mCamera.setDisplayOrientation(90); // just get it right for testing
        mCamera.setParameters(parameters);
        mCamera.setPreviewDisplay(holder);
        mCamera.setPreviewCallback(new PreviewCallback() {
            public void onPreviewFrame(byte[] data, Camera arg1) {
                Log.d(TAG, String.format("Frame %d", mFrameNumber++)); // see the frames in the logcat
            }
        });
    } catch (IOException exception) {
        mCamera.release();
        mCamera = null;
        Log.d(TAG, "exception setting parameters");
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
    Camera.Parameters parameters = mCamera.getParameters();
    List<Size> previewSizes = parameters.getSupportedPreviewSizes();
    Size previewSize = getOptimalPreviewSize(previewSizes, w, h);
    parameters.setPreviewSize(previewSize.width, previewSize.height);
    parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); 
    mCamera.setParameters(parameters);
    mCamera.startPreview();
    if (mRecordingVideo)
        startVideo(mCamera, holder);
}

// derived from http://developer.android.com/guide/topics/media/camera.html#capture-video
private void startVideo(Camera camera, SurfaceHolder holder) {
    camera.stopPreview(); // not specified in documentation but seems to be needed
    camera.unlock();
    mMediaRecorder = new MediaRecorder();
    mMediaRecorder.setCamera(camera);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // No audio is recorded
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
    mMediaRecorder.setOutputFile("/dev/null");
    try {
        mMediaRecorder.setPreviewDisplay(holder.getSurface());
        mMediaRecorder.prepare();
    } catch (IOException e) {
        camera.release();
        Log.d(TAG, "startVideo: Failed.");
        e.printStackTrace();
    }
    mMediaRecorder.start();
}

Если я установлю mRecordingVideo в приведенном выше коде для запуска видеомагнитофона, я получу автофокус, но потеряю обратные вызовы для каждого кадра предварительного просмотра.

В определении класса Camera.Parameters указано, что FOCUS_MODE_CONTINUOUS_VIDEO «предназначен для записи видео», но не дает понять, что иначе он не работает.

  1. Есть ли что-нибудь еще, что я могу сделать, чтобы заставить работать непрерывный автофокус в пряничном телефоне без записи видео? Я что-то пропустил?
  2. Это конкретно для телефона? Есть ли в других телефонах постоянная автофокусировка в этом режиме без записи видео? Я разместил исходный код полного тестового приложения на Github, если кто-то захочет попробовать его на своем телефоне.

person emrys57    schedule 29.10.2012    source источник


Ответы (2)


Кто-то любезно помог мне, протестировав это на другом телефоне на другом континенте. Большое спасибо, Колин!

  1. Похоже, что приведенный выше код правильный и должен заставить камеру правильно сфокусироваться.

  2. Это поведение зависит от телефона. Алкатель 995 с прошивкой 2.3.6 точно не фокусируется в этом режиме без запущенного видеорегистратора. Samsung Galaxy Nexus (не знаю, какая ОС) с тем же кодом фокусируется без работающего видеомагнитофона.

person emrys57    schedule 29.11.2012

попробуйте "setRecordingHint(true)" для параметров камеры

person mAx    schedule 09.09.2015
comment
Возможно, вы правы, но все телефоны, которые я сейчас использую для тестирования, прекрасно работают и без него, поэтому я не могу сказать. Работа камеры телефона значительно улучшилась за последние 3 года. Спасибо, в любом случае! - person emrys57; 09.09.2015
comment
Сегодня у меня возникла аналогичная проблема с Nexus 5, SGS 6 и т. д., когда я просто установил параметр CONTINUOUS_VIDEO для камеры, он не работает... вместо этого используется параметр CONTINUOUS_PICTURE. Только когда я тоже вызываю setRecordingHint(true), фокус действительно использует CONTINUOUS_VIDEO. - person mAx; 10.09.2015
comment
Код, который я сейчас использую, предпочитает Continuous_picture, а не Continuous_video, поэтому я не вижу проблемы на Nexus 5. Но спасибо за (буквальный) намек! - person emrys57; 10.09.2015