1 diff --git a/jni/Android.mk b/jni/Android.mk 2 index 8b816270..d48e0d8e 100755 3 --- a/jni/Android.mk 4 +++ b/jni/Android.mk 5 @@ -1,50 +1,53 @@ 6 +local_target_dir := $(TARGET_OUT_DATA)/local/tmp 7 + 8 LOCAL_PATH:= $(call my-dir) 9 10 include $(CLEAR_VARS) 11 12 LOCAL_C_INCLUDES := \ 13 - $(LOCAL_PATH)/feature_stab/db_vlvm \ 14 - $(LOCAL_PATH)/feature_stab/src \ 15 - $(LOCAL_PATH)/feature_stab/src/dbreg \ 16 - $(LOCAL_PATH)/feature_mos/src \ 17 - $(LOCAL_PATH)/feature_mos/src/mosaic 18 - 19 -LOCAL_CFLAGS := -O3 -DNDEBUG 20 -LOCAL_CPPFLAGS := -std=gnu++98 21 - 22 -LOCAL_SRC_FILES := \ 23 - feature_mos_jni.cpp \ 24 - mosaic_renderer_jni.cpp \ 25 - feature_mos/src/mosaic/trsMatrix.cpp \ 26 - feature_mos/src/mosaic/AlignFeatures.cpp \ 27 - feature_mos/src/mosaic/Blend.cpp \ 28 - feature_mos/src/mosaic/Delaunay.cpp \ 29 - feature_mos/src/mosaic/ImageUtils.cpp \ 30 - feature_mos/src/mosaic/Mosaic.cpp \ 31 - feature_mos/src/mosaic/Pyramid.cpp \ 32 - feature_mos/src/mosaic_renderer/Renderer.cpp \ 33 - feature_mos/src/mosaic_renderer/WarpRenderer.cpp \ 34 - feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp \ 35 - feature_mos/src/mosaic_renderer/YVURenderer.cpp \ 36 - feature_mos/src/mosaic_renderer/FrameBuffer.cpp \ 37 - feature_stab/db_vlvm/db_feature_detection.cpp \ 38 - feature_stab/db_vlvm/db_feature_matching.cpp \ 39 - feature_stab/db_vlvm/db_framestitching.cpp \ 40 - feature_stab/db_vlvm/db_image_homography.cpp \ 41 - feature_stab/db_vlvm/db_rob_image_homography.cpp \ 42 - feature_stab/db_vlvm/db_utilities.cpp \ 43 - feature_stab/db_vlvm/db_utilities_camera.cpp \ 44 - feature_stab/db_vlvm/db_utilities_indexing.cpp \ 45 - feature_stab/db_vlvm/db_utilities_linalg.cpp \ 46 - feature_stab/db_vlvm/db_utilities_poly.cpp \ 47 - feature_stab/src/dbreg/dbreg.cpp \ 48 - feature_stab/src/dbreg/dbstabsmooth.cpp \ 49 - feature_stab/src/dbreg/vp_motionmodel.c 50 + $(LOCAL_PATH)/feature_mos/src \ 51 + $(LOCAL_PATH)/feature_stab/src \ 52 + $(LOCAL_PATH)/feature_stab/db_vlvm 53 54 -LOCAL_SHARED_LIBRARIES := liblog libnativehelper libGLESv2 55 -#LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -ldl -llog -lGLESv2 -L$(TARGET_OUT) 56 +LOCAL_SRC_FILES := benchmark.cpp \ 57 + feature_mos/src/mosaic/ImageUtils.cpp \ 58 + feature_mos/src/mosaic/Mosaic.cpp \ 59 + feature_mos/src/mosaic/AlignFeatures.cpp \ 60 + feature_mos/src/mosaic/Blend.cpp \ 61 + feature_mos/src/mosaic/Pyramid.cpp \ 62 + feature_mos/src/mosaic/trsMatrix.cpp \ 63 + feature_mos/src/mosaic/Delaunay.cpp \ 64 + feature_mos/src/mosaic_renderer/Renderer.cpp \ 65 + feature_mos/src/mosaic_renderer/WarpRenderer.cpp \ 66 + feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp \ 67 + feature_mos/src/mosaic_renderer/YVURenderer.cpp \ 68 + feature_mos/src/mosaic_renderer/FrameBuffer.cpp \ 69 + feature_stab/db_vlvm/db_rob_image_homography.cpp \ 70 + feature_stab/db_vlvm/db_feature_detection.cpp \ 71 + feature_stab/db_vlvm/db_image_homography.cpp \ 72 + feature_stab/db_vlvm/db_framestitching.cpp \ 73 + feature_stab/db_vlvm/db_feature_matching.cpp \ 74 + feature_stab/db_vlvm/db_utilities.cpp \ 75 + feature_stab/db_vlvm/db_utilities_camera.cpp \ 76 + feature_stab/db_vlvm/db_utilities_indexing.cpp \ 77 + feature_stab/db_vlvm/db_utilities_linalg.cpp \ 78 + feature_stab/db_vlvm/db_utilities_poly.cpp \ 79 + feature_stab/src/dbreg/dbstabsmooth.cpp \ 80 + feature_stab/src/dbreg/dbreg.cpp \ 81 + feature_stab/src/dbreg/vp_motionmodel.c 82 83 -LOCAL_MODULE_TAGS := optional 84 +LOCAL_CFLAGS := -O3 -DNDEBUG -Wno-unused-parameter -Wno-maybe-uninitialized 85 +LOCAL_CFLAGS += $(CFLAGS_FOR_BENCH_SUITE) 86 +LOCAL_LDFLAGS := $(LDFLAGS_FOR_BENCH_SUITE) 87 +LOCAL_CPPFLAGS := -std=c++98 88 +LOCAL_MODULE_TAGS := tests 89 +LOCAL_MODULE := panorama_bench 90 +LOCAL_MODULE_STEM_32 := panorama_bench 91 +LOCAL_MODULE_STEM_64 := panorama_bench64 92 +LOCAL_MULTILIB := both 93 +LOCAL_MODULE_PATH := $(local_target_dir) 94 +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk 95 +LOCAL_FORCE_STATIC_EXECUTABLE := true 96 +LOCAL_STATIC_LIBRARIES := libc libm 97 98 -LOCAL_MODULE := libjni_legacymosaic 99 -include $(BUILD_SHARED_LIBRARY) 100 +include $(BUILD_EXECUTABLE) 101 diff --git a/jni/benchmark.cpp b/jni/benchmark.cpp 102 new file mode 100755 103 index 00000000..2a6440f4 104 --- /dev/null 105 +++ b/jni/benchmark.cpp 106 @@ -0,0 +1,131 @@ 107 +/* 108 + * Copyright (C) 2012 The Android Open Source Project 109 + * 110 + * Licensed under the Apache License, Version 2.0 (the "License"); 111 + * you may not use this file except in compliance with the License. 112 + * You may obtain a copy of the License at 113 + * 114 + * http://www.apache.org/licenses/LICENSE-2.0 115 + * 116 + * Unless required by applicable law or agreed to in writing, software 117 + * distributed under the License is distributed on an "AS IS" BASIS, 118 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 119 + * See the License for the specific language governing permissions and 120 + * limitations under the License. 121 + */ 122 + 123 +#include <time.h> 124 +#include <sys/types.h> 125 +#include <sys/stat.h> 126 +#include <unistd.h> 127 + 128 +#include "mosaic/Mosaic.h" 129 +#include "mosaic/ImageUtils.h" 130 + 131 +#define MAX_FRAMES 200 132 +#define KERNEL_ITERATIONS 10 133 + 134 +const int blendingType = Blend::BLEND_TYPE_HORZ; 135 +const int stripType = Blend::STRIP_TYPE_WIDE; 136 + 137 +ImageType yvuFrames[MAX_FRAMES]; 138 + 139 +int loadImages(const char* basename, int &width, int &height) 140 +{ 141 + char filename[512]; 142 + struct stat filestat; 143 + int i; 144 + 145 + for (i = 0; i < MAX_FRAMES; i++) { 146 + sprintf(filename, "%s_%03d.ppm", basename, i + 1); 147 + if (stat(filename, &filestat) != 0) break; 148 + ImageType rgbFrame = ImageUtils::readBinaryPPM(filename, width, height); 149 + yvuFrames[i] = ImageUtils::allocateImage(width, height, 150 + ImageUtils::IMAGE_TYPE_NUM_CHANNELS); 151 + ImageUtils::rgb2yvu(yvuFrames[i], rgbFrame, width, height); 152 + ImageUtils::freeImage(rgbFrame); 153 + } 154 + return i; 155 +} 156 + 157 +int main(int argc, char **argv) 158 +{ 159 + struct timespec t1, t2, t3; 160 + 161 + int width, height; 162 + float totalElapsedTime = 0; 163 + 164 + const char *basename; 165 + const char *filename; 166 + 167 + if (argc != 3) { 168 + printf("Usage: %s input_dir output_filename\n", argv[0]); 169 + return 0; 170 + } else { 171 + basename = argv[1]; 172 + filename = argv[2]; 173 + } 174 + 175 + // Load the images outside the computational kernel 176 + int totalFrames = loadImages(basename, width, height); 177 + 178 + if (totalFrames == 0) { 179 + printf("Image files not found. Make sure %s exists.\n", 180 + basename); 181 + return 1; 182 + } 183 + 184 + printf("%d frames loaded\n", totalFrames); 185 + 186 + 187 + // Interesting stuff is here 188 + for (int iteration = 0; iteration < KERNEL_ITERATIONS; iteration++) { 189 + Mosaic mosaic; 190 + 191 + mosaic.initialize(blendingType, stripType, width, height, -1, false, 0); 192 + 193 + clock_gettime(CLOCK_MONOTONIC, &t1); 194 + for (int i = 0; i < totalFrames; i++) { 195 + mosaic.addFrame(yvuFrames[i]); 196 + } 197 + clock_gettime(CLOCK_MONOTONIC, &t2); 198 + 199 + float progress = 0.0; 200 + bool cancelComputation = false; 201 + 202 + mosaic.createMosaic(progress, cancelComputation); 203 + 204 + int mosaicWidth, mosaicHeight; 205 + ImageType resultYVU = mosaic.getMosaic(mosaicWidth, mosaicHeight); 206 + 207 + ImageType imageRGB = ImageUtils::allocateImage( 208 + mosaicWidth, mosaicHeight, ImageUtils::IMAGE_TYPE_NUM_CHANNELS); 209 + 210 + clock_gettime(CLOCK_MONOTONIC, &t3); 211 + 212 + float elapsedTime = 213 + (t3.tv_sec - t1.tv_sec) + (t3.tv_nsec - t1.tv_nsec)/1e9; 214 + float addImageTime = 215 + (t2.tv_sec - t1.tv_sec) + (t2.tv_nsec - t1.tv_nsec)/1e9; 216 + float stitchImageTime = 217 + (t3.tv_sec - t2.tv_sec) + (t3.tv_nsec - t2.tv_nsec)/1e9; 218 + 219 + totalElapsedTime += elapsedTime; 220 + 221 + printf("Iteration %d: %dx%d moasic created: " 222 + "%.2f seconds (%.2f + %.2f)\n", 223 + iteration, mosaicWidth, mosaicHeight, 224 + elapsedTime, addImageTime, stitchImageTime); 225 + 226 + // Write the output only once for correctness check 227 + if (iteration == 0) { 228 + ImageUtils::yvu2rgb(imageRGB, resultYVU, mosaicWidth, 229 + mosaicHeight); 230 + ImageUtils::writeBinaryPPM(imageRGB, filename, mosaicWidth, 231 + mosaicHeight); 232 + } 233 + } 234 + printf("Total elapsed time: %.2f seconds\n", totalElapsedTime); 235 + 236 + return 0; 237 +} 238 diff --git a/jni/feature_mos/src/mosaic/AlignFeatures.cpp b/jni/feature_mos/src/mosaic/AlignFeatures.cpp 239 index aeabf8f9..703a5ea5 100644 240 --- a/jni/feature_mos/src/mosaic/AlignFeatures.cpp 241 +++ b/jni/feature_mos/src/mosaic/AlignFeatures.cpp 242 @@ -30,6 +30,8 @@ 243 244 #define LOG_TAG "AlignFeatures" 245 246 +const double Align::DEFAULT_MAX_DISPARITY = 0.1; 247 + 248 Align::Align() 249 { 250 width = height = 0; 251 diff --git a/jni/feature_mos/src/mosaic/AlignFeatures.h b/jni/feature_mos/src/mosaic/AlignFeatures.h 252 index 19f39051..9999f575 100644 253 --- a/jni/feature_mos/src/mosaic/AlignFeatures.h 254 +++ b/jni/feature_mos/src/mosaic/AlignFeatures.h 255 @@ -44,7 +44,7 @@ public: 256 ///// Settings for feature-based alignment 257 // Number of features to use from corner detection 258 static const int DEFAULT_NR_CORNERS=750; 259 - static const double DEFAULT_MAX_DISPARITY=0.1;//0.4; 260 + static const double DEFAULT_MAX_DISPARITY;//0.4; 261 // Type of homography to model 262 static const int DEFAULT_MOTION_MODEL=DB_HOMOGRAPHY_TYPE_R_T; 263 // static const int DEFAULT_MOTION_MODEL=DB_HOMOGRAPHY_TYPE_PROJECTIVE; 264 diff --git a/jni/feature_mos/src/mosaic/Blend.cpp b/jni/feature_mos/src/mosaic/Blend.cpp 265 index e37755de..b6a843a2 100644 266 --- a/jni/feature_mos/src/mosaic/Blend.cpp 267 +++ b/jni/feature_mos/src/mosaic/Blend.cpp 268 @@ -26,8 +26,8 @@ 269 #include "Geometry.h" 270 #include "trsMatrix.h" 271 272 -#include "Log.h" 273 -#define LOG_TAG "BLEND" 274 +const float Blend::LIMIT_SIZE_MULTIPLIER = 50.f * 2.0f; 275 +const float Blend::LIMIT_HEIGHT_MULTIPLIER = 2.5f; 276 277 Blend::Blend() 278 { 279 @@ -67,7 +67,6 @@ int Blend::initialize(int blendingType, int stripType, int frame_width, int fram 280 281 if (!m_pFrameYPyr || !m_pFrameUPyr || !m_pFrameVPyr) 282 { 283 - LOGE("Error: Could not allocate pyramids for blending"); 284 return BLEND_RET_ERROR_MEMORY; 285 } 286 287 @@ -122,7 +121,6 @@ int Blend::runBlend(MosaicFrame **oframes, MosaicFrame **rframes, 288 289 if (numCenters == 0) 290 { 291 - LOGE("Error: No frames to blend"); 292 return BLEND_RET_ERROR; 293 } 294 295 @@ -228,9 +226,6 @@ int Blend::runBlend(MosaicFrame **oframes, MosaicFrame **rframes, 296 297 if (xRightMost <= xLeftMost || yBottomMost <= yTopMost) 298 { 299 - LOGE("RunBlend: aborting -consistency check failed," 300 - "(xLeftMost, xRightMost, yTopMost, yBottomMost): (%d, %d, %d, %d)", 301 - xLeftMost, xRightMost, yTopMost, yBottomMost); 302 return BLEND_RET_ERROR; 303 } 304 305 @@ -241,17 +236,12 @@ int Blend::runBlend(MosaicFrame **oframes, MosaicFrame **rframes, 306 ret = MosaicSizeCheck(LIMIT_SIZE_MULTIPLIER, LIMIT_HEIGHT_MULTIPLIER); 307 if (ret != BLEND_RET_OK) 308 { 309 - LOGE("RunBlend: aborting - mosaic size check failed, " 310 - "(frame_width, frame_height) vs (mosaic_width, mosaic_height): " 311 - "(%d, %d) vs (%d, %d)", width, height, Mwidth, Mheight); 312 return ret; 313 } 314 315 - LOGI("Allocate mosaic image for blending - size: %d x %d", Mwidth, Mheight); 316 YUVinfo *imgMos = YUVinfo::allocateImage(Mwidth, Mheight); 317 if (imgMos == NULL) 318 { 319 - LOGE("RunBlend: aborting - couldn't alloc %d x %d mosaic image", Mwidth, Mheight); 320 return BLEND_RET_ERROR_MEMORY; 321 } 322 323 @@ -362,7 +352,6 @@ int Blend::FillFramePyramid(MosaicFrame *mb) 324 !PyramidShort::BorderReduce(m_pFrameUPyr, m_wb.nlevsC) || !PyramidShort::BorderExpand(m_pFrameUPyr, m_wb.nlevsC, -1) || 325 !PyramidShort::BorderReduce(m_pFrameVPyr, m_wb.nlevsC) || !PyramidShort::BorderExpand(m_pFrameVPyr, m_wb.nlevsC, -1)) 326 { 327 - LOGE("Error: Could not generate Laplacian pyramids"); 328 return BLEND_RET_ERROR; 329 } 330 else 331 @@ -384,7 +373,6 @@ int Blend::DoMergeAndBlend(MosaicFrame **frames, int nsite, 332 m_pMosaicVPyr = PyramidShort::allocatePyramidPacked(m_wb.nlevsC,(unsigned short)rect.Width(),(unsigned short)rect.Height(),BORDER); 333 if (!m_pMosaicYPyr || !m_pMosaicUPyr || !m_pMosaicVPyr) 334 { 335 - LOGE("Error: Could not allocate pyramids for blending"); 336 return BLEND_RET_ERROR_MEMORY; 337 } 338 339 @@ -579,6 +567,11 @@ int Blend::DoMergeAndBlend(MosaicFrame **frames, int nsite, 340 // Blend 341 PerformFinalBlending(imgMos, cropping_rect); 342 343 + if (cropping_rect.Width() <= 0 || cropping_rect.Height() <= 0) 344 + { 345 + return BLEND_RET_ERROR; 346 + } 347 + 348 if (m_pMosaicVPyr) free(m_pMosaicVPyr); 349 if (m_pMosaicUPyr) free(m_pMosaicUPyr); 350 if (m_pMosaicYPyr) free(m_pMosaicYPyr); 351 @@ -632,7 +625,6 @@ int Blend::PerformFinalBlending(YUVinfo &imgMos, MosaicRect &cropping_rect) 352 if (!PyramidShort::BorderExpand(m_pMosaicYPyr, m_wb.nlevs, 1) || !PyramidShort::BorderExpand(m_pMosaicUPyr, m_wb.nlevsC, 1) || 353 !PyramidShort::BorderExpand(m_pMosaicVPyr, m_wb.nlevsC, 1)) 354 { 355 - LOGE("Error: Could not BorderExpand!"); 356 return BLEND_RET_ERROR; 357 } 358 359 @@ -785,18 +777,31 @@ int Blend::PerformFinalBlending(YUVinfo &imgMos, MosaicRect &cropping_rect) 360 break; 361 } 362 } 363 + 364 } 365 366 + RoundingCroppingSizeToMultipleOf8(cropping_rect); 367 + 368 for(int j=0; j<imgMos.Y.height; j++) 369 { 370 delete b[j]; 371 } 372 373 - delete b; 374 + delete[] b; 375 376 return BLEND_RET_OK; 377 } 378 379 +void Blend::RoundingCroppingSizeToMultipleOf8(MosaicRect &rect) { 380 + int height = rect.bottom - rect.top + 1; 381 + int residue = height & 7; 382 + rect.bottom -= residue; 383 + 384 + int width = rect.right - rect.left + 1; 385 + residue = width & 7; 386 + rect.right -= residue; 387 +} 388 + 389 void Blend::ComputeMask(CSite *csite, BlendRect &vcrect, BlendRect &brect, MosaicRect &rect, YUVinfo &imgMos, int site_idx) 390 { 391 PyramidShort *dptr = m_pMosaicYPyr; 392 diff --git a/jni/feature_mos/src/mosaic/Blend.h b/jni/feature_mos/src/mosaic/Blend.h 393 index 6371fdeb..175eacd4 100644 394 --- a/jni/feature_mos/src/mosaic/Blend.h 395 +++ b/jni/feature_mos/src/mosaic/Blend.h 396 @@ -119,9 +119,10 @@ protected: 397 void CropFinalMosaic(YUVinfo &imgMos, MosaicRect &cropping_rect); 398 399 private: 400 - static const float LIMIT_SIZE_MULTIPLIER = 5.0f * 2.0f; 401 - static const float LIMIT_HEIGHT_MULTIPLIER = 2.5f; 402 + static const float LIMIT_SIZE_MULTIPLIER; 403 + static const float LIMIT_HEIGHT_MULTIPLIER; 404 int MosaicSizeCheck(float sizeMultiplier, float heightMultiplier); 405 + void RoundingCroppingSizeToMultipleOf8(MosaicRect& rect); 406 }; 407 408 #endif 409 diff --git a/jni/feature_mos/src/mosaic/Delaunay.cpp b/jni/feature_mos/src/mosaic/Delaunay.cpp 410 index 82f5d203..0ce09fc5 100644 411 --- a/jni/feature_mos/src/mosaic/Delaunay.cpp 412 +++ b/jni/feature_mos/src/mosaic/Delaunay.cpp 413 @@ -24,7 +24,7 @@ 414 415 #define QQ 9 // Optimal value as determined by testing 416 #define DM 38 // 2^(1+DM/2) element sort capability. DM=38 for >10^6 elements 417 -#define NYL (-1) 418 +#define NYL -1 419 #define valid(l) ccw(orig(basel), dest(l), dest(basel)) 420 421 422 diff --git a/jni/feature_mos/src/mosaic/ImageUtils.cpp b/jni/feature_mos/src/mosaic/ImageUtils.cpp 423 index 6d0aac0c..daa86060 100644 424 --- a/jni/feature_mos/src/mosaic/ImageUtils.cpp 425 +++ b/jni/feature_mos/src/mosaic/ImageUtils.cpp 426 @@ -283,7 +283,7 @@ ImageType ImageUtils::readBinaryPPM(const char *filename, int &width, int &heigh 427 428 FILE *imgin = NULL; 429 int mval=0, format=0, eret; 430 - ImageType ret = IMAGE_TYPE_NOIMAGE; 431 + ImageType ret = NULL;//IMAGE_TYPE_NOIMAGE; 432 433 imgin = fopen(filename, "r"); 434 if (imgin == NULL) { 435 diff --git a/jni/feature_mos/src/mosaic/ImageUtils.h b/jni/feature_mos/src/mosaic/ImageUtils.h 436 index 87782383..92965ca8 100644 437 --- a/jni/feature_mos/src/mosaic/ImageUtils.h 438 +++ b/jni/feature_mos/src/mosaic/ImageUtils.h 439 @@ -47,7 +47,7 @@ public: 440 /** 441 * Definition of an empty image. 442 */ 443 - static const int IMAGE_TYPE_NOIMAGE = NULL; 444 + static const int IMAGE_TYPE_NOIMAGE = 0; 445 446 /** 447 * Convert image from BGR (interlaced) to YVU (non-interlaced) 448 diff --git a/jni/feature_mos/src/mosaic/Log.h b/jni/feature_mos/src/mosaic/Log.h 449 index cf6f14b1..2adfeda9 100644 450 --- a/jni/feature_mos/src/mosaic/Log.h 451 +++ b/jni/feature_mos/src/mosaic/Log.h 452 @@ -14,7 +14,7 @@ 453 * limitations under the License. 454 */ 455 #ifndef LOG_H_ 456 -#define LOG_H_ 457 +#define LOG_H_ 458 459 #include <android/log.h> 460 #define LOGV(...) __android_log_print(ANDROID_LOG_SILENT, LOG_TAG, __VA_ARGS__) 461 diff --git a/jni/feature_mos/src/mosaic/Mosaic.cpp b/jni/feature_mos/src/mosaic/Mosaic.cpp 462 index f17c030b..4abc6f68 100644 463 --- a/jni/feature_mos/src/mosaic/Mosaic.cpp 464 +++ b/jni/feature_mos/src/mosaic/Mosaic.cpp 465 @@ -26,9 +26,6 @@ 466 #include "Mosaic.h" 467 #include "trsMatrix.h" 468 469 -#include "Log.h" 470 -#define LOG_TAG "MOSAIC" 471 - 472 Mosaic::Mosaic() 473 { 474 initialized = false; 475 @@ -47,6 +44,10 @@ Mosaic::~Mosaic() 476 delete frames; 477 delete rframes; 478 479 + for (int j = 0; j < owned_size; j++) 480 + delete owned_frames[j]; 481 + delete owned_frames; 482 + 483 if (aligner != NULL) 484 delete aligner; 485 if (blender != NULL) 486 @@ -88,13 +89,10 @@ int Mosaic::initialize(int blendingType, int stripType, int width, int height, i 487 { 488 frames[i] = NULL; 489 } 490 - 491 - 492 } 493 494 - LOGV("Initialize %d %d", width, height); 495 - LOGV("Frame width %d,%d", width, height); 496 - LOGV("Max num frames %d", max_frames); 497 + owned_frames = new ImageType[max_frames]; 498 + owned_size = 0; 499 500 aligner = new Align(); 501 aligner->initialize(width, height,quarter_res,thresh_still); 502 @@ -107,7 +105,6 @@ int Mosaic::initialize(int blendingType, int stripType, int width, int height, i 503 blender->initialize(blendingType, stripType, width, height); 504 } else { 505 blender = NULL; 506 - LOGE("Error: Unknown blending type %d",blendingType); 507 return MOSAIC_RET_ERROR; 508 } 509 510 @@ -123,7 +120,15 @@ int Mosaic::addFrameRGB(ImageType imageRGB) 511 imageYVU = ImageUtils::allocateImage(this->width, this->height, ImageUtils::IMAGE_TYPE_NUM_CHANNELS); 512 ImageUtils::rgb2yvu(imageYVU, imageRGB, width, height); 513 514 - return addFrame(imageYVU); 515 + int existing_frames_size = frames_size; 516 + int ret = addFrame(imageYVU); 517 + 518 + if (frames_size > existing_frames_size) 519 + owned_frames[owned_size++] = imageYVU; 520 + else 521 + ImageUtils::freeImage(imageYVU); 522 + 523 + return ret; 524 } 525 526 int Mosaic::addFrame(ImageType imageYVU) 527 @@ -146,8 +151,6 @@ int Mosaic::addFrame(ImageType imageYVU) 528 529 if (frames_size >= max_frames) 530 { 531 - LOGV("WARNING: More frames than preallocated, ignoring." 532 - "Increase maximum number of frames (-f <max_frames>) to avoid this"); 533 return MOSAIC_RET_ERROR; 534 } 535 536 diff --git a/jni/feature_mos/src/mosaic/Mosaic.h b/jni/feature_mos/src/mosaic/Mosaic.h 537 index fc6ecd90..9dea6642 100644 538 --- a/jni/feature_mos/src/mosaic/Mosaic.h 539 +++ b/jni/feature_mos/src/mosaic/Mosaic.h 540 @@ -181,6 +181,12 @@ protected: 541 int frames_size; 542 int max_frames; 543 544 + /** 545 + * Implicitly created frames, should be freed by Mosaic. 546 + */ 547 + ImageType *owned_frames; 548 + int owned_size; 549 + 550 /** 551 * Initialization state. 552 */ 553 diff --git a/jni/feature_mos/src/mosaic/Pyramid.cpp b/jni/feature_mos/src/mosaic/Pyramid.cpp 554 index 945eafba..b022d73d 100644 555 --- a/jni/feature_mos/src/mosaic/Pyramid.cpp 556 +++ b/jni/feature_mos/src/mosaic/Pyramid.cpp 557 @@ -154,24 +154,30 @@ void PyramidShort::BorderExpandOdd(PyramidShort *in, PyramidShort *out, PyramidS 558 // Vertical Filter 559 for (j = -off; j < in->height + off; j++) { 560 int j2 = j * 2; 561 - for (i = -scr->border; i < scr->width + scr->border; i++) { 562 + int limit = scr->width + scr->border; 563 + for (i = -scr->border; i < limit; i++) { 564 + int t1 = in->ptr[j][i]; 565 + int t2 = in->ptr[j+1][i]; 566 scr->ptr[j2][i] = (short) 567 - ((6 * in->ptr[j][i] + (in->ptr[j-1][i] + in->ptr[j+1][i]) + 4) >> 3); 568 - scr->ptr[j2+1][i] = (short)((in->ptr[j][i] + in->ptr[j+1][i] + 1) >> 1); 569 + ((6 * t1 + (in->ptr[j-1][i] + t2) + 4) >> 3); 570 + scr->ptr[j2+1][i] = (short)((t1 + t2 + 1) >> 1); 571 } 572 } 573 574 BorderSpread(scr, 0, 0, 3, 3); 575 576 // Horizontal Filter 577 - for (i = -off; i < scr->width + off; i++) { 578 - int i2 = i * 2; 579 - for (j = -out->border; j < out->height + out->border; j++) { 580 + int limit = out->height + out->border; 581 + for (j = -out->border; j < limit; j++) { 582 + for (i = -off; i < scr->width + off; i++) { 583 + int i2 = i * 2; 584 + int t1 = scr->ptr[j][i]; 585 + int t2 = scr->ptr[j][i+1]; 586 out->ptr[j][i2] = (short) (out->ptr[j][i2] + 587 - (mode * ((6 * scr->ptr[j][i] + 588 - scr->ptr[j][i-1] + scr->ptr[j][i+1] + 4) >> 3))); 589 + (mode * ((6 * t1 + 590 + scr->ptr[j][i-1] + t2 + 4) >> 3))); 591 out->ptr[j][i2+1] = (short) (out->ptr[j][i2+1] + 592 - (mode * ((scr->ptr[j][i] + scr->ptr[j][i+1] + 1) >> 1))); 593 + (mode * ((t1 + t2 + 1) >> 1))); 594 } 595 } 596 597 diff --git a/jni/feature_mos/src/mosaic_renderer/FrameBuffer.cpp b/jni/feature_mos/src/mosaic_renderer/FrameBuffer.cpp 598 index 9a07e496..a956f23b 100755 599 --- a/jni/feature_mos/src/mosaic_renderer/FrameBuffer.cpp 600 +++ b/jni/feature_mos/src/mosaic_renderer/FrameBuffer.cpp 601 @@ -55,6 +55,8 @@ bool FrameBuffer::Init(int width, int height, GLenum format) { 602 GL_TEXTURE_2D, 603 mTextureName, 604 0); 605 + checkFramebufferStatus("FrameBuffer.cpp"); 606 + checkGlError("framebuffertexture2d"); 607 608 if (!checkGlError("texture setup")) { 609 return false; 610 @@ -94,6 +96,3 @@ int FrameBuffer::GetWidth() const { 611 int FrameBuffer::GetHeight() const { 612 return mHeight; 613 } 614 - 615 - 616 - 617 diff --git a/jni/feature_mos/src/mosaic_renderer/FrameBuffer.h b/jni/feature_mos/src/mosaic_renderer/FrameBuffer.h 618 index b6a20ad1..314b1262 100755 619 --- a/jni/feature_mos/src/mosaic_renderer/FrameBuffer.h 620 +++ b/jni/feature_mos/src/mosaic_renderer/FrameBuffer.h 621 @@ -4,7 +4,10 @@ 622 #include <GLES2/gl2.h> 623 #include <GLES2/gl2ext.h> 624 625 -extern bool checkGlError(const char* op); 626 +#define checkGlError(op) checkGLErrorDetail(__FILE__, __LINE__, (op)) 627 + 628 +extern bool checkGLErrorDetail(const char* file, int line, const char* op); 629 +extern void checkFramebufferStatus(const char* name); 630 631 class FrameBuffer { 632 public: 633 diff --git a/jni/feature_mos/src/mosaic_renderer/Renderer.cpp b/jni/feature_mos/src/mosaic_renderer/Renderer.cpp 634 index c5c143f9..b9938eb6 100755 635 --- a/jni/feature_mos/src/mosaic_renderer/Renderer.cpp 636 +++ b/jni/feature_mos/src/mosaic_renderer/Renderer.cpp 637 @@ -87,7 +87,7 @@ GLuint Renderer::createProgram(const char* pVertexSource, const char* pFragmentS 638 GLint linkStatus = GL_FALSE; 639 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 640 641 - LOGI("Program Linked!"); 642 + LOGI("Program Linked (%d)!", program); 643 644 if (linkStatus != GL_TRUE) 645 { 646 diff --git a/jni/feature_stab/db_vlvm/db_utilities_constants.h b/jni/feature_stab/db_vlvm/db_utilities_constants.h 647 index 612fc783..07565efd 100644 648 --- a/jni/feature_stab/db_vlvm/db_utilities_constants.h 649 +++ b/jni/feature_stab/db_vlvm/db_utilities_constants.h 650 @@ -64,7 +64,7 @@ 651 #define DB_DEFAULT_ABS_CORNER_THRESHOLD 50000000.0 652 #define DB_DEFAULT_REL_CORNER_THRESHOLD 0.00005 653 #define DB_DEFAULT_MAX_DISPARITY 0.1 654 -#define DB_DEFAULT_NO_DISPARITY (-1.0) 655 +#define DB_DEFAULT_NO_DISPARITY -1.0 656 #define DB_DEFAULT_MAX_TRACK_LENGTH 300 657 658 #define DB_DEFAULT_MAX_NR_CAMERAS 1000 659 diff --git a/jni/feature_stab/src/dbreg/dbreg.cpp b/jni/feature_stab/src/dbreg/dbreg.cpp 660 index dc7d58fe..da06aa2a 100644 661 --- a/jni/feature_stab/src/dbreg/dbreg.cpp 662 +++ b/jni/feature_stab/src/dbreg/dbreg.cpp 663 @@ -485,7 +485,8 @@ int db_FrameToReferenceRegistration::AddFrame(const unsigned char * const * im, 664 if(m_do_motion_smoothing) 665 SmoothMotion(); 666 667 - db_PrintDoubleMatrix(m_H_ref_to_ins,3,3); 668 + // Disable debug printing 669 + // db_PrintDoubleMatrix(m_H_ref_to_ins,3,3); 670 671 db_Copy9(H, m_H_ref_to_ins); 672 673 diff --git a/jni/feature_stab/src/dbreg/dbstabsmooth.cpp b/jni/feature_stab/src/dbreg/dbstabsmooth.cpp 674 index dffff8ab..2bb5d2e5 100644 675 --- a/jni/feature_stab/src/dbreg/dbstabsmooth.cpp 676 +++ b/jni/feature_stab/src/dbreg/dbstabsmooth.cpp 677 @@ -136,7 +136,7 @@ bool db_StabilizationSmoother::smoothMotionAdaptive(/*VP_BIMG *bimg,*/int hsize, 678 smoothFactor = minSmoothFactor; 679 680 // Find the amount of motion that must be compensated so that no "border" pixels are seen in the stable video 681 - for (smoothFactor = smoothFactor; smoothFactor >= minSmoothFactor; smoothFactor -= 0.01) { 682 + for (; smoothFactor >= minSmoothFactor; smoothFactor -= 0.01) { 683 // Compute the smoothed motion 684 if(!smoothMotion(inmot, &tmpMotion, smoothFactor)) 685 break; 686 diff --git a/jni/feature_stab/src/dbreg/vp_motionmodel.h b/jni/feature_stab/src/dbreg/vp_motionmodel.h 687 index 71a7f7e7..a63ac001 100644 688 --- a/jni/feature_stab/src/dbreg/vp_motionmodel.h 689 +++ b/jni/feature_stab/src/dbreg/vp_motionmodel.h 690 @@ -120,7 +120,7 @@ enum VP_MOTION_MODEL { 691 VP_VFE_AFFINE=120 692 }; 693 694 -#define VP_REFID (-1) /* Default ID used for reference frame */ 695 +#define VP_REFID -1 /* Default ID used for reference frame */ 696 697 typedef struct { 698 VP_TRS par; /* Contains the motion paramerers. 699 @@ -205,16 +205,16 @@ typedef struct { 700 /* Warp a 2d point (assuming the z component is zero) */ 701 #define VP_WARP_POINT_2D(inx,iny,m,outx,outy) do {\ 702 VP_PAR vpTmpWarpPnt___= MWX(m)*(inx)+MWY(m)*(iny)+MWW(m); \ 703 - (outx) = (MXX(m)*((VP_PAR)(inx))+MXY(m)*((VP_PAR)(iny))+MXW(m))/vpTmpWarpPnt___; \ 704 - (outy) = (MYX(m)*((VP_PAR)(inx))+MYY(m)*((VP_PAR)(iny))+MYW(m))/vpTmpWarpPnt___; } while (0) 705 + outx = (MXX(m)*((VP_PAR)inx)+MXY(m)*((VP_PAR)iny)+MXW(m))/vpTmpWarpPnt___; \ 706 + outy = (MYX(m)*((VP_PAR)inx)+MYY(m)*((VP_PAR)iny)+MYW(m))/vpTmpWarpPnt___; } while (0) 707 708 /* Warp a 3d point */ 709 #define VP_WARP_POINT_3D(inx,iny,inz,m,outx,outy,outz) do {\ 710 - VP_PAR vpTmpWarpPnt___= MWX(m)*(inx)+MWY(m)*(iny)+MWZ(m)*((VP_PAR)(inz))+MWW(m); \ 711 - (outx) = (MXX(m)*((VP_PAR)(inx))+MXY(m)*((VP_PAR)(iny))+MXZ(m)*((VP_PAR)(inz))+MXW(m))/vpTmpWarpPnt___; \ 712 - (outy) = (MYX(m)*((VP_PAR)(inx))+MYY(m)*((VP_PAR)(iny))+MYZ(m)*((VP_PAR)(inz))+MYW(m))/vpTmpWarpPnt___; \ 713 - (outz) = MZX(m)*((VP_PAR)(inx))+MZY(m)*((VP_PAR)(iny))+MZZ(m)*((VP_PAR)(inz))+MZW(m); \ 714 - if ((m).type==VP_MOTION_PROJ_3D) (outz)/=vpTmpWarpPnt___; } while (0) 715 + VP_PAR vpTmpWarpPnt___= MWX(m)*(inx)+MWY(m)*(iny)+MWZ(m)*((VP_PAR)inz)+MWW(m); \ 716 + outx = (MXX(m)*((VP_PAR)inx)+MXY(m)*((VP_PAR)iny)+MXZ(m)*((VP_PAR)inz)+MXW(m))/vpTmpWarpPnt___; \ 717 + outy = (MYX(m)*((VP_PAR)inx)+MYY(m)*((VP_PAR)iny)+MYZ(m)*((VP_PAR)inz)+MYW(m))/vpTmpWarpPnt___; \ 718 + outz = MZX(m)*((VP_PAR)inx)+MZY(m)*((VP_PAR)iny)+MZZ(m)*((VP_PAR)inz)+MZW(m); \ 719 + if ((m).type==VP_MOTION_PROJ_3D) outz/=vpTmpWarpPnt___; } while (0) 720 721 /* Projections of each component */ 722 #define VP_PROJW_3D(m,x,y,z,f) ( MWX(m)*(x)+MWY(m)*(y)+MWZ(m)*(z)+MWW(m) ) 723 @@ -224,15 +224,15 @@ typedef struct { 724 725 /* Scale Down a matrix by Sfactor */ 726 #define VP_SCALEDOWN(m,Sfactor) do { \ 727 - MXW(m) /= (VP_PAR)(Sfactor); MWX(m) *= (VP_PAR)(Sfactor); \ 728 - MYW(m) /= (VP_PAR)(Sfactor); MWY(m) *= (VP_PAR)(Sfactor); \ 729 - MZW(m) /= (VP_PAR)(Sfactor); MWZ(m) *= (VP_PAR)(Sfactor); } while (0) 730 + MXW(m) /= (VP_PAR)Sfactor; MWX(m) *= (VP_PAR)Sfactor; \ 731 + MYW(m) /= (VP_PAR)Sfactor; MWY(m) *= (VP_PAR)Sfactor; \ 732 + MZW(m) /= (VP_PAR)Sfactor; MWZ(m) *= (VP_PAR)Sfactor; } while (0) 733 734 /* Scale Up a matrix by Sfactor */ 735 #define VP_SCALEUP(m,Sfactor) do { \ 736 - MXW(m) *= (VP_PAR)(Sfactor); MWX(m) /= (VP_PAR)(Sfactor); \ 737 - MYW(m) *= (VP_PAR)(Sfactor); MWY(m) /= (VP_PAR)(Sfactor); \ 738 - MZW(m) *= (VP_PAR)(Sfactor); MWZ(m) /= (VP_PAR)(Sfactor); } while (0) 739 + MXW(m) *= (VP_PAR)Sfactor; MWX(m) /= (VP_PAR)Sfactor; \ 740 + MYW(m) *= (VP_PAR)Sfactor; MWY(m) /= (VP_PAR)Sfactor; \ 741 + MZW(m) *= (VP_PAR)Sfactor; MWZ(m) /= (VP_PAR)Sfactor; } while (0) 742 743 /* Normalize the transformation matrix so that MWW is 1 */ 744 #define VP_NORMALIZE(m) if (MWW(m)!=(VP_PAR)0.0) do { \ 745 @@ -253,15 +253,15 @@ typedef struct { 746 747 /* w' projection given a point x,y,0,f */ 748 #define VP_PROJZ(m,x,y,f) ( \ 749 - MWX(m)*((VP_PAR)(x))+MWY(m)*((VP_PAR)(y))+MWW(m)*((VP_PAR)(f))) 750 + MWX(m)*((VP_PAR)x)+MWY(m)*((VP_PAR)y)+MWW(m)*((VP_PAR)f)) 751 752 /* X Projection given a point x,y,0,f and w' */ 753 #define VP_PROJX(m,x,y,w,f) (\ 754 - (MXX(m)*((VP_PAR)(x))+MXY(m)*((VP_PAR)(y))+MXW(m)*((VP_PAR)(f)))/((VP_PAR)(w))) 755 + (MXX(m)*((VP_PAR)x)+MXY(m)*((VP_PAR)y)+MXW(m)*((VP_PAR)f))/((VP_PAR)w)) 756 757 /* Y Projection given a point x,y,0,f and the w' */ 758 #define VP_PROJY(m,x,y,w,f) (\ 759 - (MYX(m)*((VP_PAR)(x))+MYY(m)*((VP_PAR)(y))+MYW(m)*((VP_PAR)(f)))/((VP_PAR)(w))) 760 + (MYX(m)*((VP_PAR)x)+MYY(m)*((VP_PAR)y)+MYW(m)*((VP_PAR)f))/((VP_PAR)w)) 761 762 /* Set the reference id for a motion */ 763 #define VP_SET_REFID(m,id) do { (m).refid=id; } while (0) 764