package com.yydcdut.note.model.camera.impl2;
import android.annotation.TargetApi;
import android.graphics.Rect;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.MeteringRectangle;
import android.os.Build;
import com.yydcdut.note.model.camera.ICameraFocus;
/**
* Created by yuyidong on 16/2/14.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class Camera2FocusModel implements ICameraFocus {
private static final int LENGTH = 200;
private static final String TAG = Camera2FocusModel.class.getSimpleName();
private int mState = FOCUS_STATE_IDLE;
private boolean mIsSupport = false;
private CaptureRequest.Builder mBuilder;
private Rect mRect;
public Camera2FocusModel(boolean isSupport, CaptureRequest.Builder builder, Rect rect) {
mIsSupport = isSupport;
mBuilder = builder;
mRect = rect;
}
@Override
public int getFocusState() {
if (mIsSupport) {
return mState;
} else {
//不支持,那么状态一直为IDLE
return FOCUS_STATE_IDLE;
}
}
@Override
public void triggerFocus(int viewWidth, int viewHeight, int x, int y) {
if (mIsSupport) {
mState = FOCUS_STATE_FOCUSING;
float ratioRowX = ((float) x) / viewWidth;
float ratioRowY = ((float) y) / viewHeight;
float newX = (ratioRowX) * mRect.height();
float newY = (ratioRowY) * mRect.width();
float left = newX - LENGTH < mRect.left ? mRect.left : newX - LENGTH;
left = left > mRect.right ? mRect.right - 1 : left;
float right = newX + LENGTH > mRect.right ? mRect.right : newX + LENGTH;
right = right < mRect.left ? mRect.left + 1 : right;
float top = newY - LENGTH < mRect.top ? mRect.top : newY - LENGTH;
top = top > mRect.bottom ? mRect.bottom - 1 : top;
float boom = newY + LENGTH > mRect.bottom ? mRect.bottom : newY + LENGTH;
boom = boom < mRect.top ? mRect.top + 1 : boom;
MeteringRectangle meteringRectangle = new MeteringRectangle(new Rect((int) left, (int) top, (int) right, (int) boom),
MeteringRectangle.METERING_WEIGHT_MAX);
mBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{meteringRectangle});
mBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[]{meteringRectangle});
mBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
mBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
doChange();
}
}
@Override
public void cancelFocus() {
mBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
}
public void onCaptureProgressed(CaptureRequest request, CaptureResult result) {
judgeFocus(result);
}
public void onCaptureCompleted(CaptureRequest request, TotalCaptureResult result) {
judgeFocus(result);
}
private void judgeFocus(CaptureResult result) {
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (afState != null) {
switch (afState.intValue()) {
case CaptureResult.CONTROL_AF_STATE_INACTIVE:
mState = FOCUS_STATE_IDLE;
break;
case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
mState = FOCUS_STATE_FOCUSING;
break;
case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
mState = FOCUS_STATE_FOCUSED_GOOD;
break;
case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
mState = FOCUS_STATE_FOCUSED_BAD;
break;
}
}
}
private OnParameterChangedListener mOnParameterChangedListener;
public void setOnParameterChangedListener(OnParameterChangedListener onParameterChangedListener) {
mOnParameterChangedListener = onParameterChangedListener;
}
public interface OnParameterChangedListener {
void onChanged(CaptureRequest.Builder builder);
}
private void doChange() {
if (mOnParameterChangedListener != null) {
mOnParameterChangedListener.onChanged(mBuilder);
}
}
}