我有一個擴展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導致的。
所以我想這涉及到這些問題:
- 多少緩衝區,我需要提供(給予一定的分辨率和一定的處理時間)?
- 爲什麼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);
}
}
我發現一些線程(也在SO上)討論這可能是由於有一個虛擬的SurfaceView。讓我們看看我們是否可以更新我們的代碼,以不使用虛擬SurfaceView並驗證發生了什麼。 – BCL 2013-05-07 06:03:46
對於SO帖子,請參閱[這裏](http://stackoverflow.com/questions/2386025/android-camera-without-preview) – BCL 2013-05-07 06:19:55
imageBufferSize的值是什麼?你是否在代碼中的任何地方調用stopPreview()並重新開始預覽?嘗試每次調用startPreview()時嘗試調用setPreviewCallbackwithBuffer()。 – abggcv 2017-08-16 14:44:04