/** * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fanxin.app.utils; import android.content.res.Configuration; import android.graphics.ImageFormat; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.hardware.Camera.PreviewCallback; import android.os.Build; import android.util.Log; import android.view.SurfaceHolder; import com.easemob.chat.EMVideoCallHelper; import com.fanxin.app.MYApplication; public class CameraHelper implements PreviewCallback { private static final String TAG = "CameraHelper"; static final int mwidth = 640; static final int mheight = 480; private Camera mCamera; private int camera_count; private Parameters mParameters; private byte[] yuv_frame; private byte[] yuv_Rotate90; private byte[] yuv_Rotate90lr; private SurfaceHolder localSurfaceHolder; private boolean start_flag; private EMVideoCallHelper callHelper; public CameraHelper(EMVideoCallHelper callHelper, SurfaceHolder localSurfaceHolder) { this.callHelper = callHelper; this.localSurfaceHolder = localSurfaceHolder; } /** * 开启相机拍摄 */ public void startCapture(){ try { if (mCamera == null) { // mCamera = Camera.open(); camera_count = Camera.getNumberOfCameras(); Log.e(TAG, "camera count:" + camera_count); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { for (int i = 0; i < camera_count; i++) { CameraInfo info = new CameraInfo(); Camera.getCameraInfo(i, info); // find front camera if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { Log.e(TAG, "to open front camera"); mCamera = Camera.open(i); } } } if (mCamera == null) { Log.e(TAG, "AAAAA OPEN camera"); mCamera = Camera.open(); } } mCamera.stopPreview(); mParameters = mCamera.getParameters(); if (isScreenOriatationPortrait()) { mCamera.setDisplayOrientation(90); } mParameters.setPreviewSize(mwidth, mheight); mParameters.setPreviewFrameRate(25); mCamera.setParameters(mParameters); int mformat = mParameters.getPreviewFormat(); int bitsperpixel = ImageFormat.getBitsPerPixel(mformat); Log.e(TAG, "pzy bitsperpixel: " + bitsperpixel); yuv_frame = new byte[mwidth * mheight * bitsperpixel / 8]; yuv_Rotate90 = new byte[mwidth * mheight * bitsperpixel / 8]; yuv_Rotate90lr = new byte[mwidth * mheight * bitsperpixel / 8]; mCamera.addCallbackBuffer(yuv_frame); // mCamera.setPreviewDisplay(holder); mCamera.setPreviewDisplay(localSurfaceHolder); mCamera.setPreviewCallbackWithBuffer(this); EMVideoCallHelper.getInstance().setResolution(mwidth, mheight); mCamera.startPreview(); Log.d(TAG, "camera start preview"); } catch (Exception e) { e.printStackTrace(); if(mCamera != null) mCamera.release(); } } @Override public void onPreviewFrame(byte[] data, Camera camera) { if (start_flag == true) { // 根据屏幕方向写入及传输数据 if (isScreenOriatationPortrait()) { YUV420spRotate90(yuv_Rotate90, yuv_frame, mwidth, mheight); YUV42left2right(yuv_Rotate90lr, yuv_Rotate90, mheight, mwidth); callHelper.processPreviewData(mheight, mwidth, yuv_Rotate90lr); } else { YUV42left2right(yuv_Rotate90, yuv_frame, mwidth, mheight); callHelper.processPreviewData(mheight, mwidth, yuv_Rotate90); } } camera.addCallbackBuffer(yuv_frame); } /** * 停止拍摄 */ public void stopCapture() { start_flag = false; if (mCamera != null) { mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); mCamera = null; } } /** * 获取是否已开启视频数据传输 * * @return */ public boolean isStarted() { return start_flag; } /** * 设置是否传输视频数据 * * @param start */ public void setStartFlag(boolean start) { this.start_flag = start; } void YUV420spRotate90(byte[] dst, byte[] src, int srcWidth, int srcHeight) { int nWidth = 0, nHeight = 0; int wh = 0; int uvHeight = 0; if (srcWidth != nWidth || srcHeight != nHeight) { nWidth = srcWidth; nHeight = srcHeight; wh = srcWidth * srcHeight; uvHeight = srcHeight >> 1;// uvHeight = height / 2 } int k = 0; for (int i = 0; i < srcWidth; i++) { int nPos = srcWidth - 1; for (int j = 0; j < srcHeight; j++) { dst[k] = src[nPos - i]; k++; nPos += srcWidth; } } for (int i = 0; i < srcWidth; i += 2) { int nPos = wh + srcWidth - 1; for (int j = 0; j < uvHeight; j++) { dst[k] = src[nPos - i - 1]; dst[k + 1] = src[nPos - i]; k += 2; nPos += srcWidth; } } return; } void YUV42left2right(byte[] dst, byte[] src, int srcWidth, int srcHeight) { // int nWidth = 0, nHeight = 0; int wh = 0; int uvHeight = 0; // if(srcWidth != nWidth || srcHeight != nHeight) { // nWidth = srcWidth; // nHeight = srcHeight; wh = srcWidth * srcHeight; uvHeight = srcHeight >> 1;// uvHeight = height / 2 } // 转换Y int k = 0; int nPos = 0; for (int i = 0; i < srcHeight; i++) { nPos += srcWidth; for (int j = 0; j < srcWidth; j++) { dst[k] = src[nPos - j - 1]; k++; } } nPos = wh + srcWidth - 1; for (int i = 0; i < uvHeight; i++) { for (int j = 0; j < srcWidth; j += 2) { dst[k] = src[nPos - j - 1]; dst[k + 1] = src[nPos - j]; k += 2; } nPos += srcWidth; } return; } boolean isScreenOriatationPortrait() { return MYApplication.applicationContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; } }