diff options
5 files changed, 105 insertions, 47 deletions
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index 14705597c..d4d83813f 100644 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -286,6 +286,7 @@ public class CaptureModule implements CameraModule, PhotoController, private static final int SELFIE_FLASH_DURATION = 680; private MediaActionSound mSound; + private Size mSupportedMaxPictureSize; private class SelfieThread extends Thread { public void run() { @@ -864,7 +865,6 @@ public class CaptureModule implements CameraModule, PhotoController, }; if(id == getMainCameraId()) { - mFrameProcessor.init(mPreviewSize); mFrameProcessor.setOutputSurface(surface); } @@ -1361,8 +1361,13 @@ public class CaptureModule implements CameraModule, PhotoController, } } else { // No Clearsight - mImageReader[i] = ImageReader.newInstance(mPictureSize.getWidth(), - mPictureSize.getHeight(), imageFormat, PostProcessor.MAX_REQUIRED_IMAGE_NUM); + if(mPostProcessor.isZSLEnabled()) { + mImageReader[i] = ImageReader.newInstance(mSupportedMaxPictureSize.getWidth(), + mSupportedMaxPictureSize.getHeight(), imageFormat, PostProcessor.MAX_REQUIRED_IMAGE_NUM); + } else { + mImageReader[i] = ImageReader.newInstance(mPictureSize.getWidth(), + mPictureSize.getHeight(), imageFormat, PostProcessor.MAX_REQUIRED_IMAGE_NUM); + } if ((mPostProcessor.isFilterOn() || getFrameFilters().size() != 0 || mPostProcessor.isZSLEnabled()) && i == getMainCameraId()) { mImageReader[i].setOnImageAvailableListener(mPostProcessor.getImageHandler(), mImageAvailableHandler); @@ -1479,6 +1484,10 @@ public class CaptureModule implements CameraModule, PhotoController, mUI.enableShutter(true); } }); + } catch (NullPointerException e) { + Log.w(TAG, "Session is already closed"); + } catch (IllegalStateException e) { + Log.w(TAG, "Session is already closed"); } catch (CameraAccessException e) { e.printStackTrace(); } @@ -1878,7 +1887,7 @@ public class CaptureModule implements CameraModule, PhotoController, } } if(mFrameProcessor != null) { - mFrameProcessor.onOpen(getFrameProcFilterId()); + mFrameProcessor.onOpen(getFrameProcFilterId(), mPreviewSize); } if(mPostProcessor.isFilterOn() || getFrameFilters().size() != 0 || mPostProcessor.isZSLEnabled()) { @@ -2278,6 +2287,7 @@ public class CaptureModule implements CameraModule, PhotoController, mActivity.getWindowManager().getDefaultDisplay().getSize(screenSize); Size[] prevSizes = mSettingsManager.getSupportedOutputSize(getMainCameraId(), SurfaceHolder.class); + mSupportedMaxPictureSize = prevSizes[0]; mPreviewSize = getOptimalPreviewSize(mPictureSize, prevSizes, screenSize.x, screenSize.y); } @@ -2359,23 +2369,17 @@ public class CaptureModule implements CameraModule, PhotoController, List<Surface> surfaces = new ArrayList<>(); Surface surface = getPreviewSurfaceForSession(cameraId); - + mFrameProcessor.onOpen(getFrameProcFilterId(),mVideoSize); if(mFrameProcessor.isFrameFilterEnabled()) { - mFrameProcessor.init(mVideoSize); mActivity.runOnUiThread(new Runnable() { public void run() { mUI.getSurfaceHolder().setFixedSize(mVideoSize.getHeight(), mVideoSize.getWidth()); } }); - mFrameProcessor.setOutputSurface(surface); - mFrameProcessor.setVideoOutputSurface(mMediaRecorder.getSurface()); - addPreviewSurface(mPreviewBuilder, surfaces, cameraId); - } else { - surfaces.add(surface); - mPreviewBuilder.addTarget(surface); - surfaces.add(mMediaRecorder.getSurface()); - mPreviewBuilder.addTarget(mMediaRecorder.getSurface()); } + mFrameProcessor.setOutputSurface(surface); + mFrameProcessor.setVideoOutputSurface(mMediaRecorder.getSurface()); + addPreviewSurface(mPreviewBuilder, surfaces, cameraId); if (!mHighSpeedCapture) surfaces.add(mVideoSnapshotImageReader.getSurface()); else mPreviewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, mHighSpeedFPSRange); @@ -2617,15 +2621,18 @@ public class CaptureModule implements CameraModule, PhotoController, Log.d(TAG, "stopRecordingVideo " + cameraId); // Stop recording - mFrameProcessor.onClose(); mFrameProcessor.setVideoOutputSurface(null); + mFrameProcessor.onClose(); closePreviewSession(); mMediaRecorder.stop(); mMediaRecorder.reset(); - saveVideo(); mUI.showRecordingUI(false); mIsRecordingVideo = false; + + if(mFrameProcessor != null) { + mFrameProcessor.onOpen(getFrameProcFilterId(), mPreviewSize); + } boolean changed = mUI.setPreviewSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); if (changed) { mUI.hideSurfaceView(); @@ -3143,7 +3150,7 @@ public class CaptureModule implements CameraModule, PhotoController, private void checkAndPlayShutterSound(int id) { if (id == getMainCameraId()) { String value = mSettingsManager.getValue(SettingsManager.KEY_SHUTTER_SOUND); - if (value != null && value.equals("on")) { + if (value != null && value.equals("on") && mSound != null) { mSound.play(MediaActionSound.SHUTTER_CLICK); } } diff --git a/src/com/android/camera/imageprocessor/FrameProcessor.java b/src/com/android/camera/imageprocessor/FrameProcessor.java index 4bee19194..193e8ee17 100644 --- a/src/com/android/camera/imageprocessor/FrameProcessor.java +++ b/src/com/android/camera/imageprocessor/FrameProcessor.java @@ -90,6 +90,7 @@ public class FrameProcessor { public static final int LISTENER_TRACKING_FOCUS = 2; private CaptureModule mModule; private boolean mIsVideoOn = false; + private boolean mIsInitialized = false; public FrameProcessor(Activity activity, CaptureModule module) { mActivity = activity; @@ -98,7 +99,7 @@ public class FrameProcessor { mFinalFilters = new ArrayList<ImageFilter>(); } - public void init(Size previewDim) { + private void init(Size previewDim) { mIsActive = true; mSize = previewDim; synchronized (mAllocationLock) { @@ -135,6 +136,7 @@ public class FrameProcessor { mTask = new ProcessingTask(); mInputImageReader.setOnImageAvailableListener(mTask, mProcessingHandler); mIsAllocationEverUsed = false; + mIsInitialized = true; } } @@ -177,13 +179,22 @@ public class FrameProcessor { mFinalFilters = new ArrayList<ImageFilter>(); } - public void onOpen(ArrayList<Integer> filterIds) { + public void onOpen(ArrayList<Integer> filterIds, final Size size) { cleanFilterSet(); if (filterIds != null) { for (Integer i : filterIds) { addFilter(i.intValue()); } } + if(isFrameFilterEnabled() || isFrameListnerEnabled()) { + new Thread() { + public void run() { + init(size); + } + }.start(); + } else { + mIsInitialized = true; + } } private void addFilter(int filterId) { @@ -203,8 +214,18 @@ public class FrameProcessor { } + private void waitForInitialization() { + while(!mIsInitialized) { + try { + Thread.sleep(10); + } catch(InterruptedException e) { + } + } + } + public void onClose() { mIsActive = false; + waitForInitialization(); synchronized (mAllocationLock) { if (mIsAllocationEverUsed) { if (mInputAllocation != null) { @@ -228,6 +249,7 @@ public class FrameProcessor { mOutputAllocation = null; mInputAllocation = null; mVideoOutputAllocation = null; + mIsInitialized = false; } if (mProcessingThread != null) { mProcessingThread.quitSafely(); @@ -299,7 +321,15 @@ public class FrameProcessor { return true; } + public boolean isFrameListnerEnabled() { + if (mPreviewFilters.size() == 0) { + return false; + } + return true; + } + public void setOutputSurface(Surface surface) { + waitForInitialization(); mSurfaceAsItIs = surface; if (mFinalFilters.size() != 0) { mOutputAllocation.setSurface(surface); @@ -307,6 +337,7 @@ public class FrameProcessor { } public void setVideoOutputSurface(Surface surface) { + waitForInitialization(); if (surface == null) { synchronized (mAllocationLock) { if (mVideoOutputAllocation != null) { diff --git a/src/com/android/camera/imageprocessor/PostProcessor.java b/src/com/android/camera/imageprocessor/PostProcessor.java index 6a6265316..817ea246d 100644 --- a/src/com/android/camera/imageprocessor/PostProcessor.java +++ b/src/com/android/camera/imageprocessor/PostProcessor.java @@ -214,7 +214,8 @@ public class PostProcessor{ mImageReader = imageReader; } ZSLQueue.ImageItem imageItem = mZSLQueue.tryToGetMatchingItem(); - if(mController.getPreviewCaptureResult().get(CaptureResult.CONTROL_AE_STATE) == CameraMetadata.CONTROL_AE_STATE_FLASH_REQUIRED) { + if(mController.getPreviewCaptureResult() == null || + mController.getPreviewCaptureResult().get(CaptureResult.CONTROL_AE_STATE) == CameraMetadata.CONTROL_AE_STATE_FLASH_REQUIRED) { if(DEBUG_ZSL) Log.d(TAG, "Flash required image"); imageItem = null; } @@ -226,7 +227,7 @@ public class PostProcessor{ reprocessImage(imageItem); return true; } else { - if(DEBUG_ZSL) Log.d(TAG, "No good item in queue, reigster the request for the future"); + if(DEBUG_ZSL) Log.d(TAG, "No good item in queue, register the request for the future"); mZSLQueue.addPictureRequest(); return false; } @@ -332,8 +333,12 @@ public class PostProcessor{ } public void manualCapture(CaptureRequest.Builder builder, CameraCaptureSession captureSession, - CameraCaptureSession.CaptureCallback callback, Handler handler) throws CameraAccessException { - mFilter.manualCapture(builder, captureSession, callback, handler); + CameraCaptureSession.CaptureCallback callback, Handler handler) throws CameraAccessException{ + try { + mFilter.manualCapture(builder, captureSession, callback, handler); + } catch(IllegalStateException e) { + Log.w(TAG, "Session is closed while taking manual pictures "); + } } public boolean isFilterOn() { @@ -580,7 +585,7 @@ public class PostProcessor{ mHandler.post(new Runnable() { public void run() { synchronized (lock) { - if(!handler.isRunning) { + if(!handler.isRunning || mStatus != STATUS.BUSY) { return; } ByteBuffer yBuf = image.getPlanes()[0].getBuffer(); @@ -630,7 +635,7 @@ public class PostProcessor{ private void processImage(final String title, final long date, final MediaSaveService.OnMediaSavedListener mediaSavedListener, final ContentResolver contentResolver) { - if(mHandler == null || !mHandler.isRunning) { + if(mHandler == null || !mHandler.isRunning || mStatus != STATUS.BUSY) { return; } final ProcessorHandler handler = mHandler; diff --git a/src/com/android/camera/imageprocessor/filter/BestpictureFilter.java b/src/com/android/camera/imageprocessor/filter/BestpictureFilter.java index 638d037ce..d9c9f5cb8 100644 --- a/src/com/android/camera/imageprocessor/filter/BestpictureFilter.java +++ b/src/com/android/camera/imageprocessor/filter/BestpictureFilter.java @@ -78,6 +78,8 @@ public class BestpictureFilter implements ImageFilter { private PhotoModule.NamedImages mNamedImages; private ByteBuffer mBY; private ByteBuffer mBVU; + private Object mClosingLock = new Object(); + private boolean mIsOn = false; private static void Log(String msg) { if (DEBUG) { @@ -117,12 +119,16 @@ public class BestpictureFilter implements ImageFilter { mHeight = height/2*2; mStrideY = strideY/2*2; mStrideVU = strideVU / 2 * 2; + mIsOn = true; Log("width: " + mWidth + " height: " + mHeight + " strideY: " + mStrideY + " strideVU: " + mStrideVU); } @Override public void deinit() { Log("deinit"); + synchronized (mClosingLock) { + mIsOn = false; + } } @Override @@ -136,8 +142,13 @@ public class BestpictureFilter implements ImageFilter { } new Thread() { public void run() { - saveToPrivateFile(imageNum, nv21ToJpeg(bY, bVU, new Rect(0, 0, mWidth, mHeight), mOrientation)); - mSavedCount++; + synchronized (mClosingLock) { + if (!mIsOn) { + return; + } + saveToPrivateFile(imageNum, nv21ToJpeg(bY, bVU, new Rect(0, 0, mWidth, mHeight), mOrientation)); + mSavedCount++; + } } }.start(); } diff --git a/src/com/android/camera/imageprocessor/filter/UbifocusFilter.java b/src/com/android/camera/imageprocessor/filter/UbifocusFilter.java index c68b5091e..37ee1dc27 100644 --- a/src/com/android/camera/imageprocessor/filter/UbifocusFilter.java +++ b/src/com/android/camera/imageprocessor/filter/UbifocusFilter.java @@ -73,6 +73,7 @@ public class UbifocusFilter implements ImageFilter { private CameraActivity mActivity; private int mOrientation = 0; private float mMinFocusDistance = -1f; + private Object mClosingLock = new Object(); final String[] NAMES = {"00.jpg", "01.jpg", "02.jpg", "03.jpg", "04.jpg", "DepthMapImage.y", "AllFocusImage.jpg"}; @@ -119,8 +120,10 @@ public class UbifocusFilter implements ImageFilter { @Override public void deinit() { Log("deinit"); - mOutBuf = null; - nativeDeinit(); + synchronized (mClosingLock) { + mOutBuf = null; + nativeDeinit(); + } } @Override @@ -138,8 +141,13 @@ public class UbifocusFilter implements ImageFilter { } new Thread() { public void run() { - saveToPrivateFile(imageNum, nv21ToJpeg(bY, bVU, new Rect(0, 0, mWidth, mHeight), mOrientation)); - mSavedCount++; + synchronized (mClosingLock) { + if(mOutBuf == null) { + return; + } + saveToPrivateFile(imageNum, nv21ToJpeg(bY, bVU, new Rect(0, 0, mWidth, mHeight), mOrientation)); + mSavedCount++; + } } }.start(); } @@ -247,22 +255,18 @@ public class UbifocusFilter implements ImageFilter { } private void saveToPrivateFile(final int index, final byte[] bytes) { - new Thread() { - public void run() { - String filesPath = mActivity.getFilesDir()+"/Ubifocus"; - File file = new File(filesPath); - if(!file.exists()) { - file.mkdir(); - } - file = new File(filesPath+"/"+NAMES[index]); - try { - FileOutputStream out = new FileOutputStream(file); - out.write(bytes, 0, bytes.length); - out.close(); - } catch (Exception e) { - } - } - }.start(); + String filesPath = mActivity.getFilesDir()+"/Ubifocus"; + File file = new File(filesPath); + if(!file.exists()) { + file.mkdir(); + } + file = new File(filesPath+"/"+NAMES[index]); + try { + FileOutputStream out = new FileOutputStream(file); + out.write(bytes, 0, bytes.length); + out.close(); + } catch (Exception e) { + } } private native int nativeInit(int width, int height, int yStride, int vuStride, int numImages); |