问题如标题所示,不知道问题出在那里,能正常出数据,但是画面就是没有,请各位大神指点迷津
代码如下
package com.jiechu.wnd.sl;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import java.io.IOException;
import java.util.List;
/**
* Created by zhuyt on 2016/10/20.
*/
public class LiveStreamDisplay extends SurfaceView implements SurfaceHolder.Callback,View.OnTouchListener{
private static String TAG = LiveStreamDisplay.class.getSimpleName();
Camera mCamInance=null;
Camera.Parameters mCamPmr = null;
PreviewAction mAction;
SurfaceHolder mHolder;
int displayWidth = 360;
int displayHeight = 480;
int current_width;
int current_height;
double iAspectRatio = 3.0/3.0;//设备宽高比
int iDelta = 0x7FFFFF;
int current_fps = 25;
int current_rate;
int current_camera = Camera.CameraInfo.CAMERA_FACING_BACK;
String current_video_encode = "H264";
boolean isPreview=false;
long mTimestampBegin=0;
long mTimestampRec=0;
int current_picture_format = ImageFormat.NV21;
List<Camera.Size> mSupportPreviewSizes;
List<int[]> mSupportPreviewFPSRanges;
private byte[] mYuvDataBuff;
int iYuvBuffSize = 0;
public LiveStreamDisplay(Context context,int pCamNum,int iWidth,int iHeight) {
super(context);
current_camera = pCamNum>=0?pCamNum: Camera.CameraInfo.CAMERA_FACING_BACK;
displayWidth = iWidth>0?iWidth:displayWidth;
displayHeight = iHeight>0?iHeight:displayHeight;
mHolder = getHolder();
initTouchView();
}
public void initCamera(int pCamNum,PreviewAction pPA){
if(mCamInance==null){
if (pPA!=null && pPA instanceof PreviewAction){
mAction = pPA;
}
current_camera = pCamNum>=0?pCamNum: Camera.CameraInfo.CAMERA_FACING_BACK;
mCamInance = Camera.open(current_camera);
mCamPmr = mCamInance.getParameters();
List<Integer> tpFormat = mCamPmr.getSupportedPreviewFormats();
if(tpFormat.contains(ImageFormat.NV21)){
mCamPmr.setPreviewFormat(ImageFormat.NV21);
}else{
Log.e(TAG, "initCamera: Camera not support NV21 format data!");
try {
throw new Throwable("Camera not support NV21 format data");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
if (tpFormat.contains(ImageFormat.JPEG)){
mCamPmr.setPictureFormat(ImageFormat.JPEG);
}
//找到手机支持的最大的分辨率,并赋值
mSupportPreviewSizes = mCamPmr.getSupportedPreviewSizes();
Camera.Size temp=null;
for (Camera.Size s:mSupportPreviewSizes){
//寻找投备支持最大宽高
/*if(temp==null){
temp = s;
}else{
if(s.width>temp.width){
temp = s;
}
}*/
//寻找设备最合适宽高
Log.e(TAG, "initCamera: current element:[W]:"+s.width+" [H]:"+s.height);
if (Math.abs(current_width-displayWidth)<iDelta){
iDelta = Math.abs(current_width-displayHeight);
temp = s;
}
}
current_width = temp.width;
current_height = temp.height;
mCamPmr.setPreviewSize(current_width,current_height);
//mCamPmr.setPictureSize(current_width,current_height);
temp=null;
//寻找最合适设备的帧率
int[] tempFPS;
mSupportPreviewFPSRanges = mCamPmr.getSupportedPreviewFpsRange();
for(int[] mi:mSupportPreviewFPSRanges){
Log.e(TAG, "initCamera: FPSRange:min["+mi[0]+"] max["+mi[1]+"]");
//还没有赋值到实际的相机参数中去.需要注意
//mCamPmr.setPreviewFpsRange((int)(mi[0]/1000),(int)(mi[1]/1000));
}
mCamInance.setParameters(mCamPmr);
iAspectRatio = current_width/current_height;
iYuvBuffSize = current_width*current_height*3/2;
mYuvDataBuff = new byte[iYuvBuffSize];
Log.e(TAG, "initCamera: Test Debug 1");
mCamInance.addCallbackBuffer(mYuvDataBuff);
Log.e(TAG, "initCamera: Test Debug 2");
mCamInance.setPreviewCallback(new LivePreivewCallback());
Log.e(TAG, "initCamera: Test Debug 3");
mCamInance.setDisplayOrientation(90);
try {
mCamInance.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
setOnTouchListener(this);
//requestLayout();
mCamInance.startPreview();
isPreview=true;
mTimestampBegin = System.currentTimeMillis();
}else{
Log.e(TAG, "initCamera: Camera Instance had exists!");
}
}
public void release(){
mCamInance.stopPreview();
mCamInance.setPreviewCallback(null);
try {
mCamInance.setPreviewDisplay(null);
} catch (IOException e) {
e.printStackTrace();
}
mYuvDataBuff = null;
mCamInance.release();
isPreview=false;
}
public void setAction(PreviewAction pPa){
if(null==pPa)return;
mAction = pPa;
}
//设置点击屏幕进行对焦
void initTouchView(){
this.setFocusable(true);
this.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
mCamInance.autoFocus(null);
return false;
}
});
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//initCamera(current_camera,mAction);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
release();
initCamera(current_camera,mAction);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//release();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e(TAG, "onTouch: Camera AutoFoucs!");
mCamInance.autoFocus(null);
return false;
}
class LivePreivewCallback implements Camera.PreviewCallback{
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
mTimestampRec = System.currentTimeMillis();
if (data==null){
Log.e(TAG, "onPreviewFrame: undefined video data!");
}else{
if (mAction!=null && data.length==iYuvBuffSize && mAction instanceof PreviewAction){
Log.e(TAG, "onPreviewFrame: find video data & call doTakeVideo[length:"+data.length+"]!");
mAction.doTakeVideo(mYuvDataBuff,mYuvDataBuff.length);
}else{
Log.e(TAG, "onPreviewFrame: find video data but else error!");
}
}
mCamInance.addCallbackBuffer(mYuvDataBuff);
}
}
//根据传入的宽高值,重新计算VIEW的宽高并应用
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int tpWidth = MeasureSpec.getSize(widthMeasureSpec);
int tpHeight = MeasureSpec.getSize(heightMeasureSpec);
if (tpWidth>tpHeight*iAspectRatio){
tpWidth = (int)(tpHeight*iAspectRatio+.5);
}else{
tpHeight = (int)(tpWidth/iAspectRatio+.5);
}
Log.e(TAG, "onMeasure: reconstructed!");
super.onMeasure(MeasureSpec.makeMeasureSpec(tpWidth,MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(tpHeight,MeasureSpec.EXACTLY));
}
public interface PreviewAction{
void doTakePicture();
void doTakeVideo(byte[] data,int length);
}
}
调用如下
Display mDisplay = getWindowManager().getDefaultDisplay();
DisplayMetrics mDet=new DisplayMetrics();
mDisplay.getMetrics(mDet);
mLSD = new LiveStreamDisplay(getApplicationContext(), Camera.CameraInfo.CAMERA_FACING_BACK,mDet.widthPixels,mDet.heightPixels);
...
addContentView(mLSD,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mLSD.initCamera(0,new LiveStreamDisplay.PreviewAction() {
@Override
public void doTakePicture() {
}
@Override
public void doTakeVideo(byte[] data, int length) {
Log.e(TAG, "doTakeVideo: get video data!");
}
});
这是输出
10-20 13:30:11.336 5970-5970/com.jiechu.wnd.lv E/LiveStreamDisplay: onPreviewFrame: find video data & call doTakeVideo[length:1382400]!
10-20 13:30:11.336 5970-5970/com.jiechu.wnd.lv E/MainActivity: doTakeVideo: get video data!
10-20 13:30:11.337 5970-5970/com.jiechu.wnd.lv D/Camera-JNI: Adding callback buffer to queue, 1 total
10-20 13:30:11.448 5970-6053/com.jiechu.wnd.lv D/Camera-JNI: Allocating callback buffer
10-20 13:30:11.484 5970-6053/com.jiechu.wnd.lv D/dalvikvm: GC_FOR_ALLOC freed 1350K (10), 17% free 14810K/17632K, paused 36ms, total 36ms
10-20 13:30:11.489 5970-5970/com.jiechu.wnd.lv I/CameraFramework: handleMessage: 16
10-20 13:30:11.489 5970-5970/com.jiechu.wnd.lv D/Camera-JNI: setHasPreviewCallback: installed:1, manualBuffer:0
10-20 13:30:11.491 5970-5970/com.jiechu.wnd.lv E/LiveStreamDisplay: onPreviewFrame: find video data & call doTakeVideo[length:1382400]!
10-20 13:30:11.491 5970-5970/com.jiechu.wnd.lv E/MainActivity: doTakeVideo: get video data!
10-20 13:30:11.491 5970-5970/com.jiechu.wnd.lv D/Camera-JNI: Adding callback buffer to queue, 1 total
10-20 13:30:11.609 5970-5983/com.jiechu.wnd.lv D/Camera-JNI: Allocating callback buffer