2012-04-11 19 views
0

我的MOTO XT910 android手機的攝像頭有問題。我只想訪問相機的(幀)緩衝區,但「onPreviewFrame」永遠不會被調用。在我的模擬器上,它工作正常。攝像頭onPreviewFrame不呼叫XT910

由於提前,

我的代碼如下:

public class Store extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback { 
static { 
    System.loadLibrary("hello-jni"); 
} 

public native void decode(Bitmap pTarget, byte[] pSource); 

private Camera mCamera; 
private byte[] mVideoSource; 
private Bitmap mBackBuffer; 
private Paint mPaint; 
private Size lSize; 
private static String TAG = Store.class.getCanonicalName(); 


public Store(Context context) { 
    super(context); 
    getHolder().addCallback(this); 
    setWillNotDraw(false); 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    try { 
     mCamera = Camera.open(); 
     mCamera.setDisplayOrientation(0); 
     mCamera.setPreviewDisplay(null); 
     mCamera.setPreviewCallbackWithBuffer(this); 
     Log.d(TAG,"surfaceCreated ok"); 
    } catch (IOException eIOException) { 
     mCamera.release(); 
     mCamera = null; 
     Log.d(TAG,"surfaceCreated failed"); 
     throw new IllegalStateException(); 
    } 
} 

public void surfaceChanged(SurfaceHolder pHolder, int pFormat, int pWidth, int pHeight) { 
    Log.d(TAG,"surfaceChanged in"); 
    mCamera.stopPreview(); 
    lSize = findBestResolution(pWidth, pHeight);   
    invalidate();  
    PixelFormat lPixelFormat = new PixelFormat(); 
    PixelFormat.getPixelFormatInfo(mCamera.getParameters() 
      .getPreviewFormat(), lPixelFormat); 
    int lSourceSize = lSize.width * lSize.height * lPixelFormat.bitsPerPixel/8; 
    mVideoSource = new byte[lSourceSize]; 
    mBackBuffer = Bitmap.createBitmap(lSize.width, lSize.height,Bitmap.Config.ARGB_8888); 
    Camera.Parameters lParameters = mCamera.getParameters(); 
    lParameters.setPreviewSize(lSize.width, lSize.height); 
    lParameters.setPreviewFormat(PixelFormat.YCbCr_420_SP); 
    mCamera.setParameters(lParameters); 
    mCamera.addCallbackBuffer(mVideoSource); 
    mCamera.startPreview(); 
    Log.d(TAG,"surfaceChanged out"); 
} 

private Size findBestResolution(int pWidth, int pHeight) { 
    List<Size> lSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
    Size lSelectedSize = mCamera.new Size(0, 0); 
    for (Size lSize : lSizes) { 
     if ((lSize.width <= pWidth) && (lSize.height <= pHeight) 
       && (lSize.width >= lSelectedSize.width) 
       && (lSize.height >= lSelectedSize.height)) { 
      lSelectedSize = lSize; 
     } 
    } 
    if ((lSelectedSize.width == 0) || (lSelectedSize.height == 0)) { 
     lSelectedSize = lSizes.get(0); 
    } 
    return lSelectedSize; 
} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    if (mCamera != null) { 
     Log.d(TAG,"surfaceDestroyed"); 
     mCamera.stopPreview(); 
     mCamera.release(); 

     mCamera = null; 
     mVideoSource = null; 
     mBackBuffer = null; 
    } 
} 

public void onPreviewFrame(byte[] pData, Camera pCamera) { 
    Log.d(TAG,"onPreviewFrame"); 
    decode(mBackBuffer, pData); 
    invalidate(); 
} 

@Override 
protected void onDraw(Canvas pCanvas) { 
    Log.d(TAG,"onDraw in"); 
    if (mCamera != null) { 
     Paint paint = new Paint(); 
     paint.setColor(Color.YELLOW); 
     String text = String.format("%dx%d", lSize.width, lSize.height); 
     pCanvas.drawText(text, 10, 10, paint);   
     pCanvas.drawLine(0, 0, 100, 100, paint); 
     pCanvas.drawLine(20, 0, 0, 20, paint); 
     pCanvas.drawBitmap(mBackBuffer, 0, 0, mPaint); 

     mCamera.addCallbackBuffer(mVideoSource); 
     Log.d(TAG,"onDraw out"); 
    } 
} 

}

回答

1

首先,我認爲你沒有得到一個例外,您所使用(的PixelFormat相機參數。 YCbCr_420_SP)由您的相機支持。

要解決該問題,您應該嘗試添加mCamera.setPreviewDisplay(view); 帶有表面視圖而不是null。不幸的是,根據Android傢伙預覽不應該沒有一個表面視圖開始:

不幸的是,如果你的目標是3.0以前的設備,沒有一個SurfaceView來顯示預覽框架是沒有辦法的。在3.0及更高版本中,您可以使用Camera#setPreviewTexture()方法將預覽數據發送到GPU紋理。即使只是想在GPU中使用YUV數據而不是RGB數據,這也可以讓您在沒有強制UI元素的情況下進行流式處理;完全忽略SurfaceTexture。

如果您堅持使用您當前的方法,您將不幸地發現您的應用在許多設備上無法正常運行;在發送預覽數據之前,有幾個API必須遵循setPreviewDisplay()或setPreviewTexture()設置的限制。

查看完整的錯誤報告位置:http://code.google.com/p/android/issues/detail?id=28238

但是我這個bug報告中說,它可以在不從表面上看工作,但沒有保證。