From a6f0b9e759fa2d19d493bde7ffa8105ec2978b94 Mon Sep 17 00:00:00 2001 From: mbansal Date: Fri, 19 Aug 2011 10:18:54 -0400 Subject: Updates to remove compile warnings and stop the viewfinder panning at UI boundary. Also, new logic for rendering the preview mosaic. 1) Fixed compiler warnings reported by Wei-Ta. 2) The viewfinder now stops panning (for both left-to-right and right-to-left motions) when it hits a pre-defined border region within the screen viewport. 3) Updated the logic for rendering to always maintain the preview mosaic (previewFBO) in the current-frame coordinate system. This fixes the repeating issues. Change-Id: I6619ffe96955965ba523e330fa6561c88e6e6d5c --- jni/feature_mos/src/mosaic/Blend.h | 1 - .../src/mosaic_renderer/SurfaceTextureRenderer.cpp | 1 - .../src/mosaic_renderer/WarpRenderer.cpp | 2 +- jni/feature_mos_jni.cpp | 13 +- .../db_vlvm/db_rob_image_homography.cpp | 3 +- jni/feature_stab/db_vlvm/db_utilities_linalg.cpp | 3 +- jni/mosaic_renderer_jni.cpp | 360 ++++++++++++--------- jni/mosaic_renderer_jni.h | 12 +- 8 files changed, 229 insertions(+), 166 deletions(-) (limited to 'jni') diff --git a/jni/feature_mos/src/mosaic/Blend.h b/jni/feature_mos/src/mosaic/Blend.h index 3e5b17c..b58eef9 100644 --- a/jni/feature_mos/src/mosaic/Blend.h +++ b/jni/feature_mos/src/mosaic/Blend.h @@ -38,7 +38,6 @@ #include #define ANDROID_LOG_VERBOSE ANDROID_LOG_DEBUG #define LOG_TAG "CVJNI" -#define LOGV(...) __android_log_print(ANDROID_LOG_SILENT, LOG_TAG, __VA_ARGS__) #define LOGII(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGIE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #else diff --git a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp index e37406c..c547d4d 100755 --- a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp @@ -139,7 +139,6 @@ bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine) glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices2); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glFinish(); succeeded = true; } while (false); return succeeded; diff --git a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp index f1d5883..80eaa42 100755 --- a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp @@ -23,7 +23,7 @@ const int VERTEX_STRIDE = 6 * sizeof(GLfloat); GLushort g_iIndices[] = { 0, 1, 2, 3 }; WarpRenderer::WarpRenderer() : Renderer() - { +{ } WarpRenderer::~WarpRenderer() { diff --git a/jni/feature_mos_jni.cpp b/jni/feature_mos_jni.cpp index de87241..d82c47d 100644 --- a/jni/feature_mos_jni.cpp +++ b/jni/feature_mos_jni.cpp @@ -51,10 +51,6 @@ extern "C" { char buffer[1024]; -double g_dAffinetrans[16]; -double g_dAffinetransInv[16]; -double g_dTranslation[16]; - const int MAX_FRAMES_HR = 100; const int MAX_FRAMES_LR = 200; @@ -541,13 +537,20 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_Mosaic_createMosaic( if(high_res) { + double t0, t1, time_c; + + t0 = now_ms(); + Init(HR, frame_number_HR); for(int k = 0; k < frame_number_HR; k++) { AddFrame(HR, k, NULL); - LOGV("Added Frame [%d]", k); } + t1 = now_ms(); + time_c = t1 - t0; + LOGV("AlignAll [HR]: %g ms",time_c); + Finalize(HR); high_res = false; } diff --git a/jni/feature_stab/db_vlvm/db_rob_image_homography.cpp b/jni/feature_stab/db_vlvm/db_rob_image_homography.cpp index f40bef9..82dec0c 100644 --- a/jni/feature_stab/db_vlvm/db_rob_image_homography.cpp +++ b/jni/feature_stab/db_vlvm/db_rob_image_homography.cpp @@ -567,7 +567,8 @@ inline void db_ImageHomographyUpdateGeneric(double H_p_dx[9],double H[9],double void db_RobCamRotation_Polish_Generic(double H[9],int point_count,int homography_type,double *x_i,double *xp_i,double one_over_scale2, int max_iterations,double improvement_requirement) { - int i,update,stop,frozen_coord,n; + int i,update,stop,n; + int frozen_coord = 0; double lambda,cost,current_cost; double JtJ[72],min_Jtf[9],dx[8],H_p_dx[9]; double *JtJ_ref[9],d[8]; diff --git a/jni/feature_stab/db_vlvm/db_utilities_linalg.cpp b/jni/feature_stab/db_vlvm/db_utilities_linalg.cpp index 4147dce..8f68b30 100644 --- a/jni/feature_stab/db_vlvm/db_utilities_linalg.cpp +++ b/jni/feature_stab/db_vlvm/db_utilities_linalg.cpp @@ -80,7 +80,8 @@ subdiagonal part in A and diagonal in d, which is n-dimensional*/ void db_CholeskyDecompSeparateDiagonal(double **A,double *d,int n) { int i,j,k; - double s,temp; + double s; + double temp = 0.0; for(i=0;i normalizedScreenLimitRight || + normalizedXPositionOnScreenLeft < normalizedScreenLimitLeft) + gPanViewfinder = false; - // Hp = inv(K) * Hinv * K - db_Identity3x3(Htemp); - db_Multiply3x3_3x3(Htemp, Hinv, K); - db_Multiply3x3_3x3(Hp, Kinv, Htemp); - - ConvertAffine3x3toGL4x4(g_dAffinetransInv, Hp); - - // Tp = inv(K) * T * K - db_Identity3x3(Ttemp); - db_Multiply3x3_3x3(Ttemp, T, K); - db_Multiply3x3_3x3(Tp, Kinv, Ttemp); + db_Identity3x3(H); + H[2] = gPanOffset; - ConvertAffine3x3toGL4x4(g_dTranslation, Tp); + // Hp = inv(K) * H * K + db_Identity3x3(Htemp1); + db_Multiply3x3_3x3(Htemp1, H, gKm); + db_Multiply3x3_3x3(Hp, gKminv, Htemp1); + ConvertAffine3x3toGL4x4(g_dAffinetransPan, Hp); } void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) @@ -313,8 +321,68 @@ void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR]; gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]; - gOriginX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[LR] / 2); - gOriginY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[LR] / 2); + // The origin is such that the current frame will sit with its center + // at the center of the previewFBO + gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[LR] / 2); + gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[LR] / 2); + + gPanOffset = 0.0f; + + db_Identity3x3(gThisH1t); + db_Identity3x3(gLastH1t); + + gPanViewfinder = true; + + int w = gPreviewImageWidth[LR]; + int h = gPreviewImageHeight[LR]; + + int wm = gPreviewFBOWidth; + int hm = gPreviewFBOHeight; + + // K is the transformation to map the canonical [-1,1] vertex coordinate + // system to the [0,w] image coordinate system before applying the given + // affine transformation trs. + gKm[0] = wm / 2.0 - 0.5; + gKm[1] = 0.0; + gKm[2] = wm / 2.0 - 0.5; + gKm[3] = 0.0; + gKm[4] = hm / 2.0 - 0.5; + gKm[5] = hm / 2.0 - 0.5; + gKm[6] = 0.0; + gKm[7] = 0.0; + gKm[8] = 1.0; + + gK[0] = w / 2.0 - 0.5; + gK[1] = 0.0; + gK[2] = w / 2.0 - 0.5; + gK[3] = 0.0; + gK[4] = h / 2.0 - 0.5; + gK[5] = h / 2.0 - 0.5; + gK[6] = 0.0; + gK[7] = 0.0; + gK[8] = 1.0; + + db_Identity3x3(gKinv); + db_InvertCalibrationMatrix(gKinv, gK); + + db_Identity3x3(gKminv); + db_InvertCalibrationMatrix(gKminv, gKm); + + ////////////////////////////////////////// + ////// Compute g_Translation now... ////// + ////////////////////////////////////////// + double T[9], Tp[9], Ttemp[9]; + + db_Identity3x3(T); + T[2] = gCenterOffsetX; + T[5] = gCenterOffsetY; + + // Tp = inv(K) * T * K + db_Identity3x3(Ttemp); + db_Multiply3x3_3x3(Ttemp, T, gK); + db_Multiply3x3_3x3(Tp, gKinv, Ttemp); + + ConvertAffine3x3toGL4x4(g_dTranslationToFBOCenter, Tp); UpdateWarpTransformation(g_dIdent3x3); } @@ -377,6 +445,11 @@ JNIEXPORT jint JNICALL Java_com_android_camera_panorama_MosaicRenderer_init( JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset( JNIEnv * env, jobject obj, jint width, jint height) { + gUILayoutScalingX = (PREVIEW_FBO_WIDTH_SCALE / PREVIEW_FBO_HEIGHT_SCALE) * + (gPreviewImageWidth[LR] / gPreviewImageHeight[LR]) / (width / height) * + PREVIEW_FBO_HEIGHT_SCALE; + gUILayoutScalingY = PREVIEW_FBO_HEIGHT_SCALE; + gBuffer[0].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); gBuffer[1].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); @@ -424,22 +497,22 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset( gYVURenderer[HR].SetInputTextureName(gBufferInput[HR].GetTextureName()); gYVURenderer[HR].SetInputTextureType(GL_TEXTURE_2D); - // gBufferInput[LR] --> gWarper1 --> gBuffer[gCurrentFBOIndex] + // gBuffer[1-gCurrentFBOIndex] --> gWarper1 --> gBuffer[gCurrentFBOIndex] gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); gWarper1.Clear(0.0, 0.0, 0.0, 1.0); - gWarper1.SetViewportMatrix(gPreviewImageWidth[LR], - gPreviewImageHeight[LR], gBuffer[gCurrentFBOIndex].GetWidth(), - gBuffer[gCurrentFBOIndex].GetHeight()); + gWarper1.SetViewportMatrix(1, 1, 1, 1); gWarper1.SetScalingMatrix(1.0f, 1.0f); - gWarper1.SetInputTextureName(gBufferInput[LR].GetTextureName()); + gWarper1.SetInputTextureName(gBuffer[1 - gCurrentFBOIndex].GetTextureName()); gWarper1.SetInputTextureType(GL_TEXTURE_2D); - // gBuffer[gCurrentFBOIndex] --> gWarper2 --> gBuffer[1-gCurrentFBOIndex] - gWarper2.SetupGraphics(&gBuffer[1-gCurrentFBOIndex]); + // gBufferInput[LR] --> gWarper2 --> gBuffer[gCurrentFBOIndex] + gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); gWarper2.Clear(0.0, 0.0, 0.0, 1.0); - gWarper2.SetViewportMatrix(1, 1, 1, 1); + gWarper2.SetViewportMatrix(gPreviewImageWidth[LR], + gPreviewImageHeight[LR], gBuffer[gCurrentFBOIndex].GetWidth(), + gBuffer[gCurrentFBOIndex].GetHeight()); gWarper2.SetScalingMatrix(1.0f, 1.0f); - gWarper2.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); + gWarper2.SetInputTextureName(gBufferInput[LR].GetTextureName()); gWarper2.SetInputTextureType(GL_TEXTURE_2D); gPreview.SetupGraphics(width, height); @@ -447,10 +520,8 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset( gPreview.SetViewportMatrix(1, 1, 1, 1); // Scale the previewFBO so that the viewfinder window fills the layout height // while maintaining the image aspect ratio - gPreview.SetScalingMatrix((PREVIEW_FBO_WIDTH_SCALE / PREVIEW_FBO_HEIGHT_SCALE) * - (gPreviewImageWidth[LR] / gPreviewImageHeight[LR]) / (width / height) * - PREVIEW_FBO_HEIGHT_SCALE, -1.0f*PREVIEW_FBO_HEIGHT_SCALE); - gPreview.SetInputTextureName(gBuffer[1-gCurrentFBOIndex].GetTextureName()); + gPreview.SetScalingMatrix(gUILayoutScalingX, -1.0f * gUILayoutScalingY); + gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); gPreview.SetInputTextureType(GL_TEXTURE_2D); } @@ -536,37 +607,27 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_transferG JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_step( JNIEnv * env, jobject obj) { - if(!gWarpImage) + if(!gWarpImage) // ViewFinder { - gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); + gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); - // Use gWarper1 shader to apply the current frame transformation to the - // current frame and then add it to the gBuffer FBO. - gWarper1.DrawTexture(g_dAffinetransGL); - - // Use the gPreview shader to apply the inverse of the current frame - // transformation to the gBuffer FBO and render it to the screen. - gPreview.DrawTexture(g_dAffinetransInvGL); + gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); + gPreview.DrawTexture(g_dAffinetransIdent); } else { gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); - gWarper2.SetupGraphics(&gBuffer[1-gCurrentFBOIndex]); - gWarper2.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); - gPreview.SetInputTextureName(gBuffer[1-gCurrentFBOIndex].GetTextureName()); + // Clear the destination so that we can paint on it afresh + gWarper1.Clear(0.0, 0.0, 0.0, 1.0); + gWarper1.SetInputTextureName( + gBuffer[1 - gCurrentFBOIndex].GetTextureName()); + gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); + gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); - // Use gWarper1 shader to apply the current frame transformation to the - // current frame and then add it to the gBuffer FBO. gWarper1.DrawTexture(g_dAffinetransGL); - - // Use gWarper2 to translate the contents of the gBuffer FBO and copy - // it into the second gBuffer FBO - gWarper2.DrawTexture(g_dTranslationGL); - - // Use the gPreview shader to apply the inverse of the current frame - // transformation to the gBuffer FBO and render it to the screen. - gPreview.DrawTexture(g_dAffinetransInvGL); + gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); + gPreview.DrawTexture(g_dAffinetransPanGL); gCurrentFBOIndex = 1 - gCurrentFBOIndex; } @@ -578,14 +639,23 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_setWarpin // TODO: Review this logic if(gWarpImage != (bool) flag) //switching from viewfinder to capture or vice-versa { + // Clear gBuffer[0] + gWarper1.SetupGraphics(&gBuffer[0]); + gWarper1.Clear(0.0, 0.0, 0.0, 1.0); + // Clear gBuffer[1] + gWarper1.SetupGraphics(&gBuffer[1]); gWarper1.Clear(0.0, 0.0, 0.0, 1.0); - gWarper2.Clear(0.0, 0.0, 0.0, 1.0); - gPreview.Clear(0.0, 0.0, 0.0, 1.0); // Clear the screen to black. - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + gPreview.Clear(0.0, 0.0, 0.0, 1.0); + + gLastTx = 0.0f; + gPanOffset = 0.0f; + gPanViewfinder = true; + + db_Identity3x3(gThisH1t); + db_Identity3x3(gLastH1t); } + gWarpImage = (bool)flag; } @@ -593,20 +663,10 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_setWarpin JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_ready( JNIEnv * env, jobject obj) { - if(!gWarpImage) - { - UpdateWarpTransformation(g_dIdent3x3); - - for(int i=0; i<16; i++) - { - g_dAffinetransInv[i] = g_dAffinetransIdent[i]; - } - } - for(int i=0; i<16; i++) { g_dAffinetransGL[i] = g_dAffinetrans[i]; - g_dAffinetransInvGL[i] = g_dAffinetransInv[i]; - g_dTranslationGL[i] = g_dTranslation[i]; + g_dAffinetransPanGL[i] = g_dAffinetransPan[i]; + g_dTranslationToFBOCenterGL[i] = g_dTranslationToFBOCenter[i]; } } diff --git a/jni/mosaic_renderer_jni.h b/jni/mosaic_renderer_jni.h index 31dd3f0..cd405f9 100644 --- a/jni/mosaic_renderer_jni.h +++ b/jni/mosaic_renderer_jni.h @@ -6,14 +6,18 @@ // The Preview FBO dimensions are determined from the low-res // frame dimensions (gPreviewImageWidth, gPreviewImageHeight) // using the scale factors below. -const int PREVIEW_FBO_WIDTH_SCALE = 8; +const int PREVIEW_FBO_WIDTH_SCALE = 4; const int PREVIEW_FBO_HEIGHT_SCALE = 2; // The factor below determines the (horizontal) speed at which the viewfinder // will pan across the UI during capture. A value of 0.0 will keep the viewfinder // static in the center of the screen and 1.0f will make it pan at the // same speed as the device. -const float VIEWFINDER_PAN_FACTOR_HORZ = 0.2f; +const float VIEWFINDER_PAN_FACTOR_HORZ = 0.3f; + +// What fraction of the screen viewport width has been allocated to show the +// arrows on the direction of motion side. +const float VIEWPORT_BORDER_FACTOR_HORZ = 0.1f; const int LR = 0; // Low-resolution mode const int HR = 1; // High-resolution mode @@ -29,7 +33,3 @@ extern int gPreviewImageWidth[NR]; extern int gPreviewImageHeight[NR]; extern sem_t gPreviewImage_semaphore; - -extern double g_dAffinetrans[16]; -extern double g_dAffinetransInv[16]; -extern double g_dTranslation[16]; -- cgit v1.1