2013-05-02 21 views
0

我有一個擴展SurfaceView並實現Camera.PreviewCallback的類。在這個類中,我設置相機預覽提供的緩衝區(setPreviewCallbackWithBuffer)和一對緩衝區(addCallbackBuffer)。在我調用startPreview之後,onPreviewFrame回調被成功調用。 在onPreviewFrame中,我將工作交給了一個不同的線程來完成一些處理並最終將數據可視化。onPreviewFrame在一段時間沒有調用之前,它運行得很好

但是,我注意到偶爾onPreviewFrame不再被調用。在探討這個問題的過程中,我發現處理1280x720幀時最有可能發生這種情況 - 攝像機支持這種幀),但它也發生在較低的分辨率但較少的頻率上。 我最終將代碼分解成幾乎空的onPreviewFrame(它只記錄接收調用並再次調用addCallbackBuffer;僅此而已)。處理線程未啓動。可以觀察到同樣的行爲。

在這種情況下,在1280x720預覽3個緩衝區,運行約20分鐘,然後onPreviewFrame不再被調用。 Logcat不會顯示任何其他問題。 這20分鐘不等,有時5分鐘,有時不到1分鐘。 使用日誌記錄我驗證了緩衝區序列在每個onPreviewFrame調用上相當乾淨(buffer1,buffer2,buffer3,buffer1,buffer2,...)。

我正在使用的設備是Galaxy Tab 2(使用Android 4.2.2 CyanogenMod);但我在其他使用庫存ROM的設備上也看到了這一點 - 所以我懷疑這是由於ROM導致的。

所以我想這涉及到這些問題:

  1. 多少緩衝區,我需要提供(給予一定的分辨率和一定的處理時間)?
  2. 爲什麼onPreviewFrame不會再被調用(當時是空閒緩衝區)?

相關的代碼歸結爲:

private void startPreview() 
{ 
    Camera.Parameters parameters = mCamera.getParameters(); 
    int width = 1280; 
    int height = 720; 
    Resolution bestCameraResolution = getBestCameraResolutionMatch(width, height); 
    width = bestCameraResolution.width(); 
    height = bestCameraResolution.height(); 
    parameters.setPreviewSize(width, height); 
    mCamera.setParameters(parameters); 

    try { 
     mCamera.setPreviewDisplay(mSurfaceHolder); 
    } catch (IOException e) { 
     Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
    } 

    // calculate imageBufferSize here... 

    mCamera.addCallbackBuffer(new byte[imageBufferSize]); 
    mCamera.addCallbackBuffer(new byte[imageBufferSize]); 
    mCamera.addCallbackBuffer(new byte[imageBufferSize]); 
    mCamera.setPreviewCallbackWithBuffer(this); 
    mCamera.startPreview(); 
    Log.d(TAG, "Start preview with " + width + "x" + height); 
} 

@Override 
public void onPreviewFrame(byte[] frameData, Camera camera) 
{ 
    // Log to a separate tag to allow better filtering 
    Log.d(TAG + "Frame", "preview frame on buffer " + frameData.toString()); 

    // Give used buffer back for future grabbing 
    if (mCamera != null) { 
     mCamera.addCallbackBuffer(frameData); 
    } 
} 
+0

我發現一些線程(也在SO上)討論這可能是由於有一個虛擬的SurfaceView。讓我們看看我們是否可以更新我們的代碼,以不使用虛擬SurfaceView並驗證發生了什麼。 – BCL 2013-05-07 06:03:46

+0

對於SO帖子,請參閱[這裏](http://stackoverflow.com/questions/2386025/android-camera-without-preview) – BCL 2013-05-07 06:19:55

+0

imageBufferSize的值是什麼?你是否在代碼中的任何地方調用stopPreview()並重新開始預覽?嘗試每次調用startPreview()時嘗試調用setPreviewCallbackwithBuffer()。 – abggcv 2017-08-16 14:44:04

回答

0

如果代碼被更新爲使用不爲虛擬SurfaceView,我們使我們的處理結果的第二SurfaceView(即位於頂部)的代碼作品。 我們必須更加小心地進行同步,但它適用於迄今爲止我們測試過的所有設備。

+0

你是什麼意思的「虛擬」'SurfaceView'?我面臨的問題是''onPreviewFrame()'不會爲每個顯示在「SurfaceView」上的幀調用。調用'onPreviewFrame()'的次數約爲4次/秒,但相機預覽非常流暢。 – 2013-09-17 19:47:48

相關問題