diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index 2a7bda7d1c14..873ddaf0c543 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -81,6 +81,9 @@ void InstallZipScreen::CreateViews() { returnToHomebrew_ = false; } else { leftColumn->Add(new TextView(iz->T("Zip file does not contain PSP software"), ALIGN_LEFT, false, new AnchorLayoutParams(10, 10, NONE, NONE))); + doneView_ = nullptr; + progressBar_ = nullptr; + installChoice_ = nullptr; backChoice_ = rightColumnItems->Add(new Choice(di->T("Back"))); } @@ -99,7 +102,9 @@ bool InstallZipScreen::key(const KeyInput &key) { UI::EventReturn InstallZipScreen::OnInstall(UI::EventParams ¶ms) { if (g_GameManager.InstallGameOnThread(zipPath_, zipPath_, deleteZipFile_)) { installStarted_ = true; - installChoice_->SetEnabled(false); + if (installChoice_) { + installChoice_->SetEnabled(false); + } } return UI::EVENT_DONE; } diff --git a/android/src/org/ppsspp/ppsspp/CameraHelper.java b/android/src/org/ppsspp/ppsspp/CameraHelper.java index 2b46fe8393ef..642504f03841 100644 --- a/android/src/org/ppsspp/ppsspp/CameraHelper.java +++ b/android/src/org/ppsspp/ppsspp/CameraHelper.java @@ -33,6 +33,8 @@ class CameraHelper { private long mLastFrameTime = 0; private SurfaceTexture mSurfaceTexture; + private static boolean firstRotation = true; + private int getCameraRotation() { int displayRotation = mDisplay.getRotation(); int displayDegrees = 0; @@ -49,8 +51,13 @@ private int getCameraRotation() { } } + // Does not work if the source is smaller than the destination! static byte[] rotateNV21(final byte[] input, final int inWidth, final int inHeight, final int outWidth, final int outHeight, final int rotation) { + if (firstRotation) { + Log.i(TAG, "rotateNV21: in: " + inWidth + "x" + inHeight + " out: " + outWidth + "x" + outHeight + " rotation: " + rotation); + firstRotation = false; + } final int inFrameSize = inWidth * inHeight; final int outFrameSize = outWidth * outHeight; @@ -59,6 +66,12 @@ static byte[] rotateNV21(final byte[] input, final int inWidth, final int inHeig if (rotation == 0 || rotation == 180) { final int crop_left = (inWidth - outWidth) / 2; final int crop_top = (inHeight - outHeight) / 2; + + if (crop_left < 0 || crop_top < 0) { + // Math will fail. Return a black image. + return output; + } + for (int j = 0; j < outHeight; j++) { final int yInCol = (crop_top + j) * inWidth + crop_left; final int uvInCol = inFrameSize + ((crop_top + j) >> 1) * inWidth + crop_left; @@ -79,8 +92,14 @@ static byte[] rotateNV21(final byte[] input, final int inWidth, final int inHeig } } } else if (rotation == 90 || rotation == 270) { - int crop_left = (inWidth - outHeight) / 2; - int crop_top = (inHeight - outWidth) / 2; + final int crop_left = (inWidth - outHeight) / 2; + final int crop_top = (inHeight - outWidth) / 2; + + if (crop_left < 0 || crop_top < 0) { + // Math will fail. Return a black image. + return output; + } + for (int j = 0; j < outWidth; j++) { final int yInCol = (crop_top + j) * inWidth + crop_left; final int uvInCol = inFrameSize + ((crop_top + j) >> 1) * inWidth + crop_left; @@ -98,6 +117,8 @@ static byte[] rotateNV21(final byte[] input, final int inWidth, final int inHeig output[vOut] = input[vIn]; } } + } else { + Log.e(TAG, "Unknown rotation " + rotation); } return output; } @@ -166,16 +187,41 @@ void startCamera() { mCamera = Camera.open(cameraId); Camera.Parameters param = mCamera.getParameters(); + List supportedPreviewFormats = param.getSupportedPreviewFormats(); + for (int i = 0; i < supportedPreviewFormats.size(); i++) { + Log.i(TAG, "Supported preview format: " + i); + } + // Set preview size List previewSizes = param.getSupportedPreviewSizes(); - mPreviewSize = previewSizes.get(0); + mPreviewSize = null; + + // Find the preview size that's the closest above or equal the requested size. + // We can not depend on the ordering of the incoming sizes. for (int i = 0; i < previewSizes.size(); i++) { - Log.d(TAG, "getSupportedPreviewSizes[" + i + "]: " + previewSizes.get(i).height + " " + previewSizes.get(i).width); - if (previewSizes.get(i).width <= 640 && previewSizes.get(i).height <= 480) { + int width = previewSizes.get(i).width; + int height = previewSizes.get(i).height; + Log.d(TAG, "getSupportedPreviewSizes[" + i + "]: " + width + "x" + height); + + // Reject too small preview sizes. + if (width < mTargetWidth || height < mTargetHeight) { + continue; + } + + if (mPreviewSize == null) { + Log.i(TAG, "Selected first viable preview size: " + width + "x" + height); + mPreviewSize = previewSizes.get(i); + } else if (width < mPreviewSize.width || height < mPreviewSize.height) { + // Only select the new size if it's smaller. + Log.i(TAG, "Selected better viable preview size: " + width + "x" + height); mPreviewSize = previewSizes.get(i); - break; } } + + if (mPreviewSize == null) { + throw new Exception("Couldn't find a viable preview size"); + } + Log.d(TAG, "setPreviewSize(" + mPreviewSize.width + ", " + mPreviewSize.height + ")"); param.setPreviewSize(mPreviewSize.width, mPreviewSize.height); @@ -197,7 +243,7 @@ void startCamera() { mCamera.setPreviewCallback(mPreviewCallback); mCamera.startPreview(); mIsCameraRunning = true; - } catch (IOException e) { + } catch (Exception e) { Log.e(TAG, "Cannot start camera: " + e.toString()); } }