/* * * Camera1Provider.java * * Created by Wuwang on 2017/3/3 * Copyright © 2016年 深圳哎吖科技. All rights reserved. */ package com.aiyaapp.aiya.mvc; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.graphics.Rect; import android.hardware.Camera; import com.aiyaapp.camera.sdk.base.Log; import com.aiyaapp.camera.sdk.base.Renderer; import com.aiyaapp.camera.sdk.widget.AiyaController; import com.aiyaapp.camera.sdk.widget.AiyaModel; /** * Description: 使用{@link Camera}提供数据时的Model示例 */ public class Camera1Model implements AiyaModel{ private Camera mCamera; private CameraController mCameraController; private int cameraId=1; private AiyaController mController; public void setCameraController(CameraController controller){ this.mCameraController=controller; } @Override public void attachToController(final AiyaController controller) { if (mCameraController==null){ mCameraController=new CameraController(); } this.mController=controller; controller.setRenderer(new Renderer() { @Override public void onDestroy() { mCameraController.release(); mCamera=null; } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { if(mCamera!=null){ mCamera.stopPreview(); mCamera.release(); mCamera=null; } mCamera=mCameraController.openCamera(cameraId); controller.setImageDirection(cameraId); controller.setDataSize(mCamera.getParameters().getPreviewSize().height, mCamera.getParameters().getPreviewSize().width); mCameraController.setCameraCallback(mCamera); try { mCamera.setPreviewTexture(controller.getTexture()); } catch (IOException e) { e.printStackTrace(); } mCameraController.preview(mCamera); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { } @Override public void onDrawFrame(GL10 gl) { mCameraController.dataRecycle(); } }); } public class CameraController{ private Camera camera; private Camera.Size previewSize; private Queue<byte[]> dataPoll; public CameraController(){ dataPoll=new ConcurrentLinkedQueue<>(); } protected Camera.Size setSize(int cameraId,Camera.Parameters param){ Camera.Size picSize = getPropPictureSize(param.getSupportedPictureSizes(), 1.778f, 720); Camera.Size preSize = getPropPreviewSize(param.getSupportedPreviewSizes(), 1.778f, 720); param.setPictureSize(picSize.width, picSize.height); param.setPreviewSize(preSize.width, preSize.height); return getPropPreviewSize(param.getSupportedPreviewSizes(),1.778f,720); } protected void otherSetting(Camera.Parameters param){ if (param.getMaxNumFocusAreas() > 0) { Rect areaRect1 = new Rect(-50, -50, 50, 50); List<Camera.Area> focusAreas = new ArrayList<>(); focusAreas.add(new Camera.Area(areaRect1, 1000)); param.setFocusAreas(focusAreas); } // if the camera support setting of metering area. if (param.getMaxNumMeteringAreas() > 0) { List<Camera.Area> meteringAreas = new ArrayList<>(); Rect areaRect1 = new Rect(-100, -100, 100, 100); meteringAreas.add(new Camera.Area(areaRect1, 1000)); param.setMeteringAreas(meteringAreas); } // Log.e("wuwang","camera isVideoStabilizationSupported:"+param // .isVideoStabilizationSupported()); // param.setVideoStabilization(true); //无效 // param.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT); //无效 // List<int[]> al=param.getSupportedPreviewFpsRange(); // for (int[] a:al){ // Log.e("previewSize","size->"+a[0]+"/"+a[1]); // } // param.setPreviewFpsRange(30000,30000); } protected void setRecordHint(Camera.Parameters param){ param.setRecordingHint(true); param.set("video-size", param.getPreviewSize().width + "x" + param.getPreviewSize().height); } public Camera openCamera(int cameraId){ camera=Camera.open(cameraId); if(camera!=null) { Camera.Parameters param = camera.getParameters(); Camera.Size size=setSize(cameraId,param); if(previewSize==null||!(size.width==previewSize.width&&size.height==previewSize .height)){ dataPoll.clear(); for (int i=0;i<3;i++){ dataPoll.add(new byte[size.width*size.height*4]); } } previewSize=size; setRecordHint(param); otherSetting(param); camera.setParameters(param); } return camera; } protected void onPreviewCallback(byte[] data,Camera camera){ mController.requestRender(); } public void setCameraCallback(Camera camera){ for (int i=0;i<3;i++){ byte[] dt=dataPoll.poll(); if(dt!=null){ camera.addCallbackBuffer(dt); }else{ break; } } camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { if(data!=null&&dataPoll!=null){ dataPoll.add(data); Log.e("camera1","data poll size:"+dataPoll.size()); } onPreviewCallback(data,camera); } }); } public void dataRecycle(){ byte[] dt=dataPoll.poll(); if(dt!=null){ camera.addCallbackBuffer(dt); } } public void preview(Camera camera){ camera.startPreview(); } protected void release(){ if(camera!=null){ try { camera.setPreviewCallback(null); camera.stopPreview(); camera.release(); }catch (RuntimeException e){ e.printStackTrace(); } camera=null; } } protected Camera.Size getPropPreviewSize(List<Camera.Size> list, float th, int minWidth){ Collections.sort(list, sizeComparator); int i = 0; for(Camera.Size s:list){ if((s.height >= minWidth) && equalRate(s, th)){ break; } i++; } if(i == list.size()){ i = 0; } return list.get(i); } protected Camera.Size getPropPictureSize(List<Camera.Size> list, float th, int minWidth){ Collections.sort(list, sizeComparator); int i = 0; for(Camera.Size s:list){ if((s.height >= minWidth) && equalRate(s, th)){ break; } i++; } if(i == list.size()){ i = 0; } return list.get(i); } private boolean equalRate(Camera.Size s, float rate){ float r = (float)(s.width)/(float)(s.height); return Math.abs(r - rate) <= 0.03; } private Comparator<Camera.Size> sizeComparator=new Comparator<Camera.Size>(){ public int compare(Camera.Size lhs, Camera.Size rhs) { // TODO Auto-generated method stub if(lhs.height == rhs.height){ return 0; } else if(lhs.height > rhs.height){ return 1; } else{ return -1; } } }; } }