Как заблокировать автоэкспозицию в Android с помощью Camera2 API - PullRequest
1 голос
/ 01 мая 2019

Я использую android-Camera2Basic образец Google. Я пытаюсь добавить региональную фокусировку и региональную экспозицию, используя CONTROL_AF_REGIONS и CONTROL_AE_REGIONS. У меня возникла проблема с алгоритмом блокировки автоэкспозиции.

Вот что я сделал до сих пор:

1 - отмена предыдущих срабатываний автоматической экспозиции и автоматической фокусировки:

mState = STATE_PREVIEW;
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);

2 - добавьте нужные области для автофокуса и автоматической экспозиции:


mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, meteringRectangleArr);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, meteringRectangleArr);

3 - установить триггеры фокусировки:

mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
mState = STATE_WAITING_LOCK;
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);

4- В mCaptureCallback у меня есть следующий код, который устанавливает триггер автоматической экспозиции, когда камера заблокирована в фокусе:

try {                                                                                                                                        
    switch(mState) {                                                                                                                         
        case STATE_PREVIEW: {                                                                                                                
            break;                                                                                                                           
        }                                                                                                                                    
        case STATE_WAITING_LOCK: {                                                                                                           
            Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);                                                                    
            if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||                                                                  
                CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
                mState = STATE_WAITING_PRECAPTURE;
                mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
            }                                                                                                                                
        }                                                                                                                                    
        case STATE_WAITING_PRECAPTURE: {
            Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
            if (CaptureRequest.CONTROL_AE_STATE_CONVERGED == aeState || CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED == aeState) { //2, 4  
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
                mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
        } else if(CaptureRequest.CONTROL_AE_STATE_LOCKED == aeState) {                                                                   
                mState = STATE_PREVIEW;
                mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);                                  
            }                                                                                                                                
        }                                                                                                                                    
    }                                                                                                                                        
} catch (CameraAccessException e) {                                                                                                          
    e.printStackTrace();                                                                                                                     
}

С этими кодами автофокус и автоэкспозиция будут работать нормально на Samsung Note8. Но проблема в том же коде не работает на Samsung J5. Проблема заключается в том, что когда камера пытается сфокусироваться (в J5), она находится в бесконечном цикле между CONTROL_AF_STATE_NOT_FOCUSED_LOCKED и CONTROL_AF_STATE_ACTIVE_SCAN, и предварительный просмотр остановится. Если я поменяю mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); на mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);, J5 будет нормально работать в области автофокуса (J5 не поддерживает область автоэкспозиции. Поэтому я закомментировал части автоэкспозиции для J5!). Но когда я применяю эту модификацию к Note8, экспозиция будет применяться, но не будет блокироваться, и через несколько кадров она вернется к предыдущей экспозиции.

Итак, что не так? я должен использовать mPreviewRequestBuilder.build() или mPreviewRequest в методе mCaptureSession.setRepeatingRequest? почему сток J5 если я использую mPreviewRequestBuilder.build()?

...