diff options
27 files changed, 373 insertions, 138 deletions
diff --git a/jni/feature_mos/src/mosaic_renderer/Renderer.cpp b/jni/feature_mos/src/mosaic_renderer/Renderer.cpp index b9938eb6b..8d0632402 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/Renderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/Renderer.cpp @@ -111,8 +111,8 @@ GLuint Renderer::createProgram(const char* pVertexSource, const char* pFragmentS } // Set this renderer to use the default frame-buffer (screen) and -// set the viewport size to be the given width and height (pixels). -bool Renderer::SetupGraphics(int width, int height) +// set the viewport size to be the given x, y, width and height (pixels). +bool Renderer::SetupGraphics(int x, int y, int width, int height) { bool succeeded = false; do { @@ -131,8 +131,10 @@ bool Renderer::SetupGraphics(int width, int height) mFrameBuffer = NULL; mSurfaceWidth = width; mSurfaceHeight = height; + mSurfaceXOffset = x; + mSurfaceYOffset = y; - glViewport(0, 0, mSurfaceWidth, mSurfaceHeight); + glViewport(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight); if (!checkGlError("glViewport")) break; succeeded = true; } while (false); @@ -176,7 +178,7 @@ bool Renderer::Clear(float r, float g, float b, float a) bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? - SetupGraphics(mSurfaceWidth, mSurfaceHeight) : + SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) diff --git a/jni/feature_mos/src/mosaic_renderer/Renderer.h b/jni/feature_mos/src/mosaic_renderer/Renderer.h index a43e8028e..ffb9cbd25 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/Renderer.h +++ b/jni/feature_mos/src/mosaic_renderer/Renderer.h @@ -18,7 +18,7 @@ class Renderer { virtual bool InitializeGLProgram() = 0; bool SetupGraphics(FrameBuffer* buffer); - bool SetupGraphics(int width, int height); + bool SetupGraphics(int x, int y, int width, int height); bool Clear(float r, float g, float b, float a); @@ -59,6 +59,8 @@ class Renderer { int mSurfaceWidth; // Width of target surface. int mSurfaceHeight; // Height of target surface. + int mSurfaceXOffset; // X Offset target surface. + int mSurfaceYOffset; // Y Offset of target surface. FrameBuffer *mFrameBuffer; }; diff --git a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp index 88aac3626..4725463f2 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp @@ -119,7 +119,7 @@ bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine) bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? - SetupGraphics(mSurfaceWidth, mSurfaceHeight) : + SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) diff --git a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp index af6779a3f..c030ce25e 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp @@ -110,7 +110,7 @@ bool WarpRenderer::DrawTexture(GLfloat *affine) bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? - SetupGraphics(mSurfaceWidth, mSurfaceHeight) : + SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) diff --git a/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp b/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp index f7dcf6f61..b30e6f7b6 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp @@ -79,7 +79,7 @@ bool YVURenderer::DrawTexture() bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? - SetupGraphics(mSurfaceWidth, mSurfaceHeight) : + SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) diff --git a/jni/mosaic_renderer_jni.cpp b/jni/mosaic_renderer_jni.cpp index 36f8064c7..f35599375 100644 --- a/jni/mosaic_renderer_jni.cpp +++ b/jni/mosaic_renderer_jni.cpp @@ -27,6 +27,7 @@ #include "mosaic_renderer/SurfaceTextureRenderer.h" #include "mosaic_renderer/YVURenderer.h" + #include "mosaic/Log.h" #define LOG_TAG "MosaicRenderer" @@ -36,6 +37,7 @@ GLuint gSurfaceTextureID[1]; bool gWarpImage = true; +bool gPreviewBackgroundImage = true; // Low-Res input image frame in YUVA format for preview rendering and processing // and high-res YUVA input image for processing. @@ -87,6 +89,9 @@ FrameBuffer gBuffer[2]; // Shader to warp and render the preview FBO to the screen WarpRenderer gPreview; +// Shader to render the fullscreen preview background FBO to the screen +WarpRenderer gPreviewBackground; + // Index of the gBuffer FBO gWarper1 is going to write into int gCurrentFBOIndex = 0; @@ -140,6 +145,12 @@ double g_dAffinetransPan[16]; GLfloat g_dTranslationToFBOCenterGL[16]; double g_dTranslationToFBOCenter[16]; + + + + + + // GL 4x4 Identity transformation GLfloat g_dAffinetransIdentGL[] = { 1., 0., 0., 0., @@ -315,8 +326,8 @@ void UpdateWarpTransformation(float *trs) // Alignment is done based on low-res data. // To render the preview mosaic, the translation of the high-res mosaic is estimated to // H2L_FACTOR x low-res-based tranlation. - gThisH1t[2] *= H2L_FACTOR; - gThisH1t[5] *= H2L_FACTOR; + //gThisH1t[2] *= H2L_FACTOR; + //gThisH1t[5] *= H2L_FACTOR; db_Identity3x3(T); T[2] = -gCenterOffsetX; @@ -368,6 +379,7 @@ void UpdateWarpTransformation(float *trs) db_Identity3x3(H); H[2] = gPanOffset; + // Hp = inv(Km) * H * Km db_Identity3x3(Htemp1); db_Multiply3x3_3x3(Htemp1, H, gKm); @@ -397,13 +409,13 @@ void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) gPreviewImageHeight[HR], 4); sem_post(&gPreviewImage_semaphore); - gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[HR]; - gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[HR]; + gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR]; + gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]; // The origin is such that the current frame will sit with its center // at the center of the previewFBO - gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[HR] / 2); - gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[HR] / 2); + gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[LR] / 2); + gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[LR] / 2); gPanOffset = 0.0f; @@ -412,8 +424,8 @@ void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) gPanViewfinder = true; - int w = gPreviewImageWidth[HR]; - int h = gPreviewImageHeight[HR]; + int w = gPreviewImageWidth[LR]; + int h = gPreviewImageHeight[LR]; int wm = gPreviewFBOWidth; int hm = gPreviewFBOHeight; @@ -493,6 +505,8 @@ extern "C" JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping( JNIEnv * env, jobject obj, jboolean flag); + JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setPreviewBackground( + JNIEnv * env, jobject obj, jboolean flag); }; @@ -524,6 +538,7 @@ JNIEXPORT jint JNICALL Java_com_android_camera_MosaicRenderer_init( gBufferInput[HR].InitializeGLContext(); gBufferInputYVU[LR].InitializeGLContext(); gBufferInputYVU[HR].InitializeGLContext(); + gPreviewBackground.InitializeGLProgram(); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -548,13 +563,16 @@ void calculateUILayoutScaling(int width, int height, bool isLandscape) { // // Scale the preview FBO's height to the height of view and // maintain the aspect ratio of the current frame on the screen. + gUILayoutScalingY = PREVIEW_FBO_HEIGHT_SCALE; // Note that OpenGL scales a texture to view's width and height automatically. // The "width / height" inverts the scaling, so as to maintain the aspect ratio // of the current frame. + gUILayoutScalingX = ((float) gPreviewFBOWidth / gPreviewFBOHeight) / ((float) width / height) * PREVIEW_FBO_HEIGHT_SCALE; + } else { // ___ // __________ | | ______ @@ -573,8 +591,10 @@ void calculateUILayoutScaling(int width, int height, bool isLandscape) { // Note that OpenGL scales a texture to view's width and height automatically. // The "height / width" inverts the scaling, so as to maintain the aspect ratio // of the current frame. + gUILayoutScalingX = ((float) gPreviewFBOHeight / gPreviewFBOWidth) / ((float) width / height) * PREVIEW_FBO_WIDTH_SCALE; + } } @@ -582,7 +602,7 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( JNIEnv * env, jobject obj, jint width, jint height, jboolean isLandscapeOrientation) { gIsLandscapeOrientation = isLandscapeOrientation; - calculateUILayoutScaling(width, height, gIsLandscapeOrientation); + calculateUILayoutScaling(gPreviewFBOWidth, gPreviewFBOHeight, gIsLandscapeOrientation); gBuffer[0].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); gBuffer[1].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); @@ -636,20 +656,23 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( gWarper1.SetInputTextureName(gBuffer[1 - gCurrentFBOIndex].GetTextureName()); gWarper1.SetInputTextureType(GL_TEXTURE_2D); - // gBufferInput[HR] --> gWarper2 --> gBuffer[gCurrentFBOIndex] + // gBufferInput[LR] --> gWarper2 --> gBuffer[gCurrentFBOIndex] gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); // gWarp2's destination buffer is the same to gWarp1's. No need to clear it // again. - gWarper2.SetViewportMatrix(gPreviewImageWidth[HR], - gPreviewImageHeight[HR], gBuffer[gCurrentFBOIndex].GetWidth(), + gWarper2.SetViewportMatrix(gPreviewImageWidth[LR], + gPreviewImageHeight[LR], gBuffer[gCurrentFBOIndex].GetWidth(), gBuffer[gCurrentFBOIndex].GetHeight()); gWarper2.SetScalingMatrix(1.0f, 1.0f); - gWarper2.SetInputTextureName(gBufferInput[HR].GetTextureName()); + gWarper2.SetInputTextureName(gBufferInput[LR].GetTextureName()); gWarper2.SetInputTextureType(GL_TEXTURE_2D); + int xoffset = (width/2 - gPreviewFBOWidth/2); + int yoffset = (height/2 - gPreviewFBOHeight/2); + // gBuffer[gCurrentFBOIndex] --> gPreview --> Screen - gPreview.SetupGraphics(width, height); + gPreview.SetupGraphics(xoffset,yoffset,gPreviewFBOWidth, gPreviewFBOHeight); gPreview.SetViewportMatrix(1, 1, 1, 1); // Scale the previewFBO so that the viewfinder window fills the layout height @@ -657,6 +680,13 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( gPreview.SetScalingMatrix(gUILayoutScalingX, -1.0f * gUILayoutScalingY); gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); gPreview.SetInputTextureType(GL_TEXTURE_2D); + + // gBufferInput[HR] --> gPreviewBackground --> screen + gPreviewBackground.SetupGraphics(0,0,width, height); + gPreviewBackground.SetViewportMatrix(1,1,1,1); + gPreviewBackground.SetScalingMatrix(1.0f, -1.0f); + gPreviewBackground.SetInputTextureName(gBufferInput[HR].GetTextureName()); + gPreviewBackground.SetInputTextureType(GL_TEXTURE_2D); } JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_preprocess( @@ -731,15 +761,18 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_step( { if(!gWarpImage) // ViewFinder { - gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); - gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); - - gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); - + if (gIsLandscapeOrientation) { + gPreviewBackground.DrawTexture(g_dAffinetransIdentGL); + } else { + gPreviewBackground.DrawTexture(g_dAffinetransRotation90GL); + } + } + else if(gPreviewBackgroundImage) + { if (gIsLandscapeOrientation) { - gPreview.DrawTexture(g_dAffinetransIdentGL); + gPreviewBackground.DrawTexture(g_dAffinetransIdentGL); } else { - gPreview.DrawTexture(g_dAffinetransRotation90GL); + gPreviewBackground.DrawTexture(g_dAffinetransRotation90GL); } } else @@ -774,7 +807,7 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping( gWarper1.Clear(0.0, 0.0, 0.0, 1.0); // Clear the screen to black. gPreview.Clear(0.0, 0.0, 0.0, 1.0); - + gPreviewBackground.Clear(0.0, 0.0, 0.0, 1.0); gLastTx = 0.0f; gPanOffset = 0.0f; gPanViewfinder = true; @@ -802,3 +835,9 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_updateMatrix( g_dTranslationToFBOCenterGL[i] = g_dTranslationToFBOCenter[i]; } } + +JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setPreviewBackground( + JNIEnv * env, jobject obj, jboolean flag) +{ + gPreviewBackgroundImage = (bool)flag; +} diff --git a/res/layout-land/camera_controls.xml b/res/layout-land/camera_controls.xml index 65a17caae..eecc13f2e 100644 --- a/res/layout-land/camera_controls.xml +++ b/res/layout-land/camera_controls.xml @@ -109,4 +109,12 @@ android:layout_gravity="center" /> </com.android.camera.ui.RotatableLayout> + <TextView + android:id="@+id/remaining_photos" + android:background="@android:color/transparent" + android:textColor="@android:color/white" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" /> + </com.android.camera.ui.CameraControls> diff --git a/res/layout-land/pano_preview_progress.xml b/res/layout-land/pano_preview_progress.xml new file mode 100644 index 000000000..772b8529e --- /dev/null +++ b/res/layout-land/pano_preview_progress.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/panorama_preview_progress" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_gravity="bottom|center_horizontal"> + + <com.android.camera.PanoProgressBar + android:id="@+id/pano_pan_progress_bar" + android:visibility="gone" + android:src="@drawable/ic_pan_progression" + android:layout_centerInParent="true" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <ImageView + android:id="@+id/pano_pan_left_indicator" + android:src="@drawable/pano_direction_left_indicator" + android:visibility="gone" + android:layout_marginRight="5dp" + android:layout_toLeftOf="@id/pano_pan_progress_bar" + android:layout_centerVertical="true" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <ImageView + android:id="@+id/pano_pan_right_indicator" + android:src="@drawable/pano_direction_right_indicator" + android:visibility="gone" + android:layout_marginLeft="5dp" + android:layout_toRightOf="@id/pano_pan_progress_bar" + android:layout_centerVertical="true" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> +</RelativeLayout> diff --git a/res/layout-port/camera_controls.xml b/res/layout-port/camera_controls.xml index bf3cda0ab..52be755dd 100644 --- a/res/layout-port/camera_controls.xml +++ b/res/layout-port/camera_controls.xml @@ -109,4 +109,12 @@ android:layout_gravity="center" /> </com.android.camera.ui.RotatableLayout> + <TextView + android:id="@+id/remaining_photos" + android:background="@android:color/transparent" + android:textColor="@android:color/white" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" /> + </com.android.camera.ui.CameraControls> diff --git a/res/layout-port/pano_preview_progress.xml b/res/layout-port/pano_preview_progress.xml new file mode 100644 index 000000000..426ef0ba7 --- /dev/null +++ b/res/layout-port/pano_preview_progress.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/panorama_preview_progress" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_gravity="bottom|center_horizontal" + android:layout_marginBottom="100dp"> + + <com.android.camera.PanoProgressBar + android:id="@+id/pano_pan_progress_bar" + android:visibility="gone" + android:src="@drawable/ic_pan_progression" + android:layout_centerInParent="true" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <ImageView + android:id="@+id/pano_pan_left_indicator" + android:src="@drawable/pano_direction_left_indicator" + android:visibility="gone" + android:layout_marginRight="5dp" + android:layout_toLeftOf="@id/pano_pan_progress_bar" + android:layout_centerVertical="true" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <ImageView + android:id="@+id/pano_pan_right_indicator" + android:src="@drawable/pano_direction_right_indicator" + android:visibility="gone" + android:layout_marginLeft="5dp" + android:layout_toRightOf="@id/pano_pan_progress_bar" + android:layout_centerVertical="true" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> +</RelativeLayout> diff --git a/res/layout/count_down_to_capture.xml b/res/layout/count_down_to_capture.xml index 68276ad40..20437506d 100644 --- a/res/layout/count_down_to_capture.xml +++ b/res/layout/count_down_to_capture.xml @@ -25,11 +25,11 @@ android:textColor="@android:color/white" android:gravity="center" /> <TextView android:id="@+id/count_down_title" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingLeft="10dp" - android:paddingTop="20dp" + android:layout_marginTop="@dimen/count_down_title_margin_top" + android:gravity="center_horizontal" android:textSize="20sp" android:textColor="@android:color/white" android:text="@string/count_down_title_text" /> -</com.android.camera.ui.CountDownView>
\ No newline at end of file +</com.android.camera.ui.CountDownView> diff --git a/res/layout/pano_module_capture.xml b/res/layout/pano_module_capture.xml index c6c131741..d842ea12c 100644 --- a/res/layout/pano_module_capture.xml +++ b/res/layout/pano_module_capture.xml @@ -19,94 +19,36 @@ android:layout_height="match_parent" android:layout_width="match_parent"> - <LinearLayout + <FrameLayout + android:layout_gravity="center" + android:id="@+id/pano_preview_layout" + android:layout_weight="@integer/SRI_pano_layout_weight" android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> + android:layout_height="match_parent"> - <!-- The top bar with capture indication --> - <FrameLayout - style="@style/PanoViewHorizontalBar" + <TextureView + android:id="@+id/pano_preview_textureview" android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1"> - - <TextView - android:id="@+id/pano_capture_indicator" - android:text="@string/pano_capture_indication" - android:textAppearance="?android:textAppearanceMedium" - android:layout_gravity="center" - android:visibility="gone" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - </FrameLayout> + android:layout_height="match_parent" /> - <FrameLayout - android:layout_gravity="center" - android:id="@+id/pano_preview_layout" - android:layout_weight="@integer/SRI_pano_layout_weight" + <View + android:id="@+id/pano_preview_area_border" + android:visibility="gone" + android:background="@drawable/ic_pan_border_fast" android:layout_width="match_parent" - android:layout_height="0dp"> - - <TextureView - android:id="@+id/pano_preview_textureview" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - - <View - android:id="@+id/pano_preview_area_border" - android:visibility="gone" - android:background="@drawable/ic_pan_border_fast" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - </FrameLayout> - - <!-- The bottom bar with progress bar and direction indicators --> - <FrameLayout - style="@style/PanoViewHorizontalBar" - android:paddingTop="20dp" - android:gravity="top" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1"> - - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="match_parent" /> + </FrameLayout> - <com.android.camera.PanoProgressBar - android:id="@+id/pano_pan_progress_bar" - android:visibility="gone" - android:src="@drawable/ic_pan_progression" - android:layout_centerInParent="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - - <ImageView - android:id="@+id/pano_pan_left_indicator" - android:src="@drawable/pano_direction_left_indicator" - android:visibility="gone" - android:layout_marginRight="5dp" - android:layout_toLeftOf="@id/pano_pan_progress_bar" - android:layout_centerVertical="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - - <ImageView - android:id="@+id/pano_pan_right_indicator" - android:src="@drawable/pano_direction_right_indicator" - android:visibility="gone" - android:layout_marginLeft="5dp" - android:layout_toRightOf="@id/pano_pan_progress_bar" - android:layout_centerVertical="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - </RelativeLayout> - </FrameLayout> - - - </LinearLayout> + <include layout="@layout/pano_preview_progress" /> + <TextView + android:id="@+id/pano_capture_indicator" + android:text="@string/pano_capture_indication" + android:textAppearance="?android:textAppearanceMedium" + android:layout_gravity="top|center_horizontal" + android:visibility="gone" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> <!-- The hint for "Too fast" text view --> <TextView android:id="@+id/pano_capture_too_fast_textview" diff --git a/res/values-land/dimensions.xml b/res/values-land/dimensions.xml index 41eea19ed..9f768fc98 100644 --- a/res/values-land/dimensions.xml +++ b/res/values-land/dimensions.xml @@ -18,4 +18,5 @@ <dimen name="manage_cache_bottom_height">39dp</dimen> <dimen name="capture_top_margin">0dip</dimen> <integer name="SRI_pano_layout_weight">3</integer> + <dimen name="count_down_title_margin_top">20dp</dimen> </resources> diff --git a/res/values-port/dimensions.xml b/res/values-port/dimensions.xml index 6f3fe7636..67e3ebc3f 100644 --- a/res/values-port/dimensions.xml +++ b/res/values-port/dimensions.xml @@ -15,4 +15,5 @@ --> <resources> <integer name="SRI_pano_layout_weight">2</integer> + <dimen name="count_down_title_margin_top">90dp</dimen> </resources> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index e1a8f7985..e248a4523 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -527,4 +527,6 @@ <!-- The alas of CameraActivity for gesture operation --> <string name="camera_gesture_title">打开相机</string> + + <string name="remaining_photos_format">剩余 %d 张</string> </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 6b81ab906..dac42d22e 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -25,7 +25,7 @@ <dimen name="setting_knob_text_size">20dp</dimen> <dimen name="setting_item_text_width">95dp</dimen> <dimen name="setting_popup_window_width">240dp</dimen> - <dimen name="setting_item_list_margin">14dp</dimen> + <dimen name="setting_item_list_margin">2dp</dimen> <dimen name="indicator_bar_width">48dp</dimen> <dimen name="popup_title_text_size">22dp</dimen> <dimen name="popup_title_frame_min_height">49dp</dimen> @@ -164,4 +164,6 @@ <dimen name="filter_mode_height">100dp</dimen> <dimen name="filter_mode_width">80dp</dimen> <dimen name="filter_mode_padding">10dp</dimen> + + <dimen name="remaining_photos_margin">67dp</dimen> </resources> diff --git a/res/values/qcomarrays.xml b/res/values/qcomarrays.xml index 73c34bd39..23ba3d382 100644 --- a/res/values/qcomarrays.xml +++ b/res/values/qcomarrays.xml @@ -203,6 +203,19 @@ <item>normal</item> </string-array> + <!-- Rough estimates of jpeg compression ratio corresponding to qualities defined above. --> + <integer-array name="jpegquality_compression_ratio"> + <item>48</item> + <item>38</item> + <item>31</item> + <item>20</item> + <item>11</item> + <item>6</item> + <item>20</item> + <item>31</item> + <item>38</item> + </integer-array> + <!-- Camera Preferences Color effect dialog box entries --> <string-array name="pref_camera_coloreffect_entries" translatable="false"> <item>@string/pref_camera_coloreffect_entry_none</item> diff --git a/res/values/strings.xml b/res/values/strings.xml index 54ef31f9d..0ad549a41 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -712,4 +712,6 @@ CHAR LIMIT = NONE] --> <string name="pref_camera_video_rotation_label_90">90</string> <string name="pref_camera_video_rotation_label_180">180</string> <string name="pref_camera_video_rotation_label_270">270</string> + + <string name="remaining_photos_format">%d left</string> </resources> diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index b85a7de06..8fd8f9daa 100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -1433,8 +1433,8 @@ public class CameraActivity extends Activity //This is a temporal solution to share LED resource //as Android doesn’t have any default intent to share the state. // if the led flash light is open, turn it off - Log.d(TAG, "send the turn off LED Flashlight the broadcast"); - Intent intent = new Intent("qualcomm.android.LEDFlashlight.appWidgetUpdate"); + Log.d(TAG, "send the turn off Flashlight broadcast"); + Intent intent = new Intent("org.codeaurora.snapcam.action.CLOSE_FLASHLIGHT"); intent.putExtra("camera_led", true); sendBroadcast(intent); } diff --git a/src/com/android/camera/MosaicPreviewRenderer.java b/src/com/android/camera/MosaicPreviewRenderer.java index 42da4d9e7..77c260eb5 100644 --- a/src/com/android/camera/MosaicPreviewRenderer.java +++ b/src/com/android/camera/MosaicPreviewRenderer.java @@ -83,10 +83,13 @@ public class MosaicPreviewRenderer { mInputSurfaceTexture.updateTexImage(); mInputSurfaceTexture.getTransformMatrix(mTransformMatrix); - MosaicRenderer.setWarping(true); - // Call preprocess to render it to low-res and high-res RGB textures. + // Call setPreviewBackground to render high-res RGB textures to full screen. + MosaicRenderer.setPreviewBackground(true); MosaicRenderer.preprocess(mTransformMatrix); - // Now, transfer the textures from GPU to CPU memory for processing + MosaicRenderer.step(); + MosaicRenderer.setPreviewBackground(false); + + MosaicRenderer.setWarping(true); MosaicRenderer.transferGPUtoCPU(); MosaicRenderer.updateMatrix(); MosaicRenderer.step(); diff --git a/src/com/android/camera/MosaicRenderer.java b/src/com/android/camera/MosaicRenderer.java index 92d9cb7b6..daf94abe6 100644 --- a/src/com/android/camera/MosaicRenderer.java +++ b/src/com/android/camera/MosaicRenderer.java @@ -86,4 +86,14 @@ public class MosaicRenderer * @param flag boolean flag to set the warping to true or false. */ public static native void setWarping(boolean flag); + /** + * This function allows toggling between drawing the background full + * screen preview image data to screen and drawing the warped smaller + * preview on top of it. To render the full screen background preview, + * we set the falsg to true and to render the warped image on top of this + * we set the flag to false and flag in setWarping to true. + * + * @param flag boolean flag to set the warping to true or false. + */ + public static native void setPreviewBackground(boolean flag); } diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java index 14e80ceb2..32cd5dcf7 100644 --- a/src/com/android/camera/PhotoModule.java +++ b/src/com/android/camera/PhotoModule.java @@ -357,6 +357,8 @@ public class PhotoModule private static final int MANUAL_EXPOSURE = 4; private boolean mAnimateCapture = true; + private int mJpegFileSizeEstimation = 0; + private MediaSaveService.OnMediaSavedListener mOnMediaSavedListener = new MediaSaveService.OnMediaSavedListener() { @Override @@ -960,15 +962,16 @@ public class PhotoModule mUI.doShutterAnimation(); + Location loc = getLocationAccordPictureFormat(mParameters.get(KEY_PICTURE_FORMAT)); if (mLongshotSave) { mCameraDevice.takePicture(mHandler, new LongshotShutterCallback(), mRawPictureCallback, mPostViewPictureCallback, - new LongshotPictureCallback(null)); + new LongshotPictureCallback(loc)); } else { mCameraDevice.takePicture(mHandler,new LongshotShutterCallback(), mRawPictureCallback, mPostViewPictureCallback, - new JpegPictureCallback(null)); + new JpegPictureCallback(loc)); } } } @@ -1319,6 +1322,7 @@ public class PhotoModule // the mean time and fill it, but that could have happened between the // shutter press and saving the JPEG too. mActivity.updateStorageSpaceAndHint(); + updateRemainingPhotos(); long now = System.currentTimeMillis(); mJpegCallbackFinishTime = now - mJpegPictureCallbackTime; Log.v(TAG, "mJpegCallbackFinishTime = " @@ -1529,11 +1533,7 @@ public class PhotoModule mJpegRotation = CameraUtil.getJpegRotation(mCameraId, orientation); mParameters.setRotation(mJpegRotation); String pictureFormat = mParameters.get(KEY_PICTURE_FORMAT); - Location loc = null; - if (pictureFormat != null && - PIXEL_FORMAT_JPEG.equalsIgnoreCase(pictureFormat)) { - loc = mLocationManager.getCurrentLocation(); - } + Location loc = getLocationAccordPictureFormat(pictureFormat); CameraUtil.setGpsParameters(mParameters, loc); if (mRefocus) { @@ -1598,6 +1598,14 @@ public class PhotoModule setCameraParameters(UPDATE_PARAM_PREFERENCE); } + private Location getLocationAccordPictureFormat(String pictureFormat) { + if (pictureFormat != null && + PIXEL_FORMAT_JPEG.equalsIgnoreCase(pictureFormat)) { + return mLocationManager.getCurrentLocation(); + } + return null; + } + private int getPreferredCameraId(ComboPreferences preferences) { int intentCameraId = CameraUtil.getCameraFacingIntentExtras(mActivity); if (intentCameraId != -1) { @@ -2207,10 +2215,20 @@ public class PhotoModule @Override public void run(){ mActivity.updateStorageSpaceAndHint(); + updateRemainingPhotos(); } }); } + private void updateRemainingPhotos() { + if (mJpegFileSizeEstimation != 0) { + mUI.updateRemainingPhotos((int) (mActivity.getStorageSpaceBytes() + / mJpegFileSizeEstimation)); + } else { + mUI.updateRemainingPhotos(-1); + } + } + private void onResumeTasks() { Log.v(TAG, "Executing onResumeTasks."); if (mOpenCameraFail || mCameraDisabled) return; @@ -2808,6 +2826,7 @@ public class PhotoModule //mUnsupportedJpegQuality = true; }else { mParameters.setJpegQuality(JpegEncodingQualityMappings.getQualityNumber(jpegQuality)); + setJpegFileSizeEstimation(pic_size, jpegQuality); } } @@ -3205,6 +3224,25 @@ public class PhotoModule } } + private void setJpegFileSizeEstimation(final Size size, final String quality) { + int[] ratios = mActivity.getResources().getIntArray(R.array.jpegquality_compression_ratio); + String[] qualities = mActivity.getResources().getStringArray( + R.array.pref_camera_jpegquality_entryvalues); + int ratio = 0; + for (int i = ratios.length - 1; i >= 0; --i) { + if (qualities[i].equals(quality)) { + ratio = ratios[i]; + break; + } + } + + if (ratio == 0) { + mJpegFileSizeEstimation = 0; + } else { + mJpegFileSizeEstimation = size.width * size.height * 3 / ratio; + } + } + private void setFlipValue() { // Read Flip mode from adb command //value: 0(default) - FLIP_MODE_OFF diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java index 48fb2f704..eb55b72be 100644 --- a/src/com/android/camera/PhotoUI.java +++ b/src/com/android/camera/PhotoUI.java @@ -1159,4 +1159,7 @@ public class PhotoUI implements PieListener, mMenu.setPreference(key, value); } + public void updateRemainingPhotos(int remaining) { + mCameraControls.updateRemainingPhotos(remaining); + } } diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index ae429dd2d..1bd395188 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -1727,7 +1727,7 @@ public class VideoModule implements CameraModule, Log.v(TAG, "pauseVideoRecording"); mMediaRecorderPausing = true; mRecordingTotalTime += SystemClock.uptimeMillis() - mRecordingStartTime; - //mMediaRecorder.pause(); + mMediaRecorder.pause(); } private void resumeVideoRecording() { @@ -1735,7 +1735,7 @@ public class VideoModule implements CameraModule, mMediaRecorderPausing = false; mRecordingStartTime = SystemClock.uptimeMillis(); updateRecordingTime(); - //mMediaRecorder.start(); + mMediaRecorder.start(); } private boolean stopVideoRecording() { diff --git a/src/com/android/camera/WideAnglePanoramaUI.java b/src/com/android/camera/WideAnglePanoramaUI.java index 8f9643971..952a31909 100644 --- a/src/com/android/camera/WideAnglePanoramaUI.java +++ b/src/com/android/camera/WideAnglePanoramaUI.java @@ -434,14 +434,6 @@ public class WideAnglePanoramaUI implements private void setViews(Resources appRes) { int weight = appRes.getInteger(R.integer.SRI_pano_layout_weight); - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mPreviewLayout.getLayoutParams(); - lp.weight = weight; - mPreviewLayout.setLayoutParams(lp); - - lp = (LinearLayout.LayoutParams) mReview.getLayoutParams(); - lp.weight = weight; - mPreviewLayout.setLayoutParams(lp); - mSavingProgressBar = (PanoProgressBar) mRootView.findViewById(R.id.pano_saving_progress_bar); mSavingProgressBar.setIndicatorWidth(0); mSavingProgressBar.setMaxProgress(100); diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java index 1c9419569..181bd991e 100644 --- a/src/com/android/camera/ui/CameraControls.java +++ b/src/com/android/camera/ui/CameraControls.java @@ -26,6 +26,7 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewPropertyAnimator; import android.widget.FrameLayout; +import android.widget.TextView; import java.util.ArrayList; import org.codeaurora.snapcam.R; @@ -66,6 +67,8 @@ public class CameraControls extends RotatableLayout { private boolean[] mTempEnabled = new boolean[9]; private boolean mLocSet = false; + private TextView mRemainingPhotos; + AnimatorListener outlistener = new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { @@ -205,6 +208,7 @@ public class CameraControls extends RotatableLayout { mPreview = findViewById(R.id.preview_thumb); mSceneModeSwitcher = findViewById(R.id.scene_mode_switcher); mFilterModeSwitcher = findViewById(R.id.filter_mode_switcher); + mRemainingPhotos = (TextView) findViewById(R.id.remaining_photos); } @Override @@ -238,6 +242,8 @@ public class CameraControls extends RotatableLayout { View done = findViewById(R.id.btn_done); toRight(done, shutter, rotation); } + + layoutRemaingPhotos(); } private void setLocation(int w, int h) { @@ -388,6 +394,7 @@ public class CameraControls extends RotatableLayout { mPreview.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); break; } + mRemainingPhotos.setVisibility(View.INVISIBLE); } public void showUI() { @@ -475,6 +482,9 @@ public class CameraControls extends RotatableLayout { mPreview.animate().translationXBy(mSize).setDuration(ANIME_DURATION); break; } + if (mRemainingPhotos.getVisibility() == View.INVISIBLE) { + mRemainingPhotos.setVisibility(View.VISIBLE); + } } private void center(View v, Rect other, int rotation) { @@ -646,4 +656,45 @@ public class CameraControls extends RotatableLayout { mBackgroundView.setBackgroundResource(R.drawable.switcher_bg); } + private void layoutRemaingPhotos() { + int rl = mPreview.getLeft(); + int rt = mPreview.getTop(); + int rr = mPreview.getRight(); + int rb = mPreview.getBottom(); + int w = mRemainingPhotos.getMeasuredWidth(); + int h = mRemainingPhotos.getMeasuredHeight(); + int m = getResources().getDimensionPixelSize(R.dimen.remaining_photos_margin); + + int hc, vc; + int rotation = getUnifiedRotation(); + switch (rotation) { + case 90: + hc = (rl + rr) / 2 - m; + vc = (rt + rb) / 2; + break; + case 180: + hc = (rl + rr) / 2; + vc = (rt + rb) / 2 + m; + break; + case 270: + hc = (rl + rr) / 2 + m; + vc = (rt + rb) / 2; + break; + default: + hc = (rl + rr) / 2; + vc = (rt + rb) / 2 - m; + break; + } + mRemainingPhotos.layout(hc - w / 2, vc - h / 2, hc + w / 2, vc + h / 2); + } + + public void updateRemainingPhotos(int remaining) { + if (remaining < 0) { + mRemainingPhotos.setVisibility(View.GONE); + } else { + mRemainingPhotos.setVisibility(View.VISIBLE); + mRemainingPhotos.setText(String.format( + getResources().getString(R.string.remaining_photos_format), remaining)); + } + } } diff --git a/src/com/android/camera/ui/CountDownView.java b/src/com/android/camera/ui/CountDownView.java index 75cdf5e8a..d479b684a 100644 --- a/src/com/android/camera/ui/CountDownView.java +++ b/src/com/android/camera/ui/CountDownView.java @@ -19,6 +19,7 @@ package com.android.camera.ui; import java.util.Locale; import android.content.Context; +import android.content.res.Configuration; import android.media.AudioManager; import android.media.SoundPool; import android.os.Handler; @@ -38,6 +39,8 @@ public class CountDownView extends FrameLayout { private static final String TAG = "CAM_CountDownView"; private static final int SET_TIMER_TEXT = 1; private TextView mRemainingSecondsView; + private TextView mCountDownTitle = null; + private Context mContext; private int mRemainingSecs = 0; private OnCountDownFinishedListener mListener; private Animation mCountDownAnim; @@ -49,6 +52,7 @@ public class CountDownView extends FrameLayout { public CountDownView(Context context, AttributeSet attrs) { super(context, attrs); + mContext = context; mCountDownAnim = AnimationUtils.loadAnimation(context, R.anim.count_down_exit); // Load the beeps if (context.getResources().getBoolean(R.bool.force_count_down_sound)) { @@ -100,8 +104,19 @@ public class CountDownView extends FrameLayout { protected void onFinishInflate() { super.onFinishInflate(); mRemainingSecondsView = (TextView) findViewById(R.id.remaining_seconds); + mCountDownTitle = (TextView) findViewById(R.id.count_down_title); } + @Override + public void onConfigurationChanged(Configuration config) { + if (mCountDownTitle == null) return; + LayoutParams lp = (LayoutParams) mCountDownTitle.getLayoutParams(); + lp.topMargin = mContext.getResources() + .getDimensionPixelSize(R.dimen.count_down_title_margin_top); + mCountDownTitle.setLayoutParams(lp); + } + + public void setCountDownFinishedListener(OnCountDownFinishedListener listener) { mListener = listener; } |