1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #define LOG_NDEBUG 1 17 #define LOG_TAG "VideoEditorMain" 18 #include <dlfcn.h> 19 #include <stdio.h> 20 #include <unistd.h> 21 #include <utils/Log.h> 22 #include <utils/threads.h> 23 #include <VideoEditorClasses.h> 24 #include <VideoEditorJava.h> 25 #include <VideoEditorOsal.h> 26 #include <VideoEditorLogging.h> 27 #include <marker.h> 28 #include <VideoEditorClasses.h> 29 #include <VideoEditorThumbnailMain.h> 30 #include <M4OSA_Debug.h> 31 #include <M4xVSS_Internal.h> 32 #include <gui/Surface.h> 33 #include "VideoEditorPreviewController.h" 34 35 #include "VideoEditorMain.h" 36 37 extern "C" { 38 #include <M4OSA_Clock.h> 39 #include <M4OSA_CharStar.h> 40 #include <M4OSA_Error.h> 41 #include <M4OSA_FileCommon.h> 42 #include <M4OSA_FileReader.h> 43 #include <M4OSA_FileWriter.h> 44 #include <M4OSA_Memory.h> 45 #include <M4OSA_Thread.h> 46 #include <M4xVSS_API.h> 47 #include <M4VSS3GPP_ErrorCodes.h> 48 #include <M4MCS_API.h> 49 #include <M4MCS_ErrorCodes.h> 50 #include <M4READER_Common.h> 51 #include <M4WRITER_common.h> 52 }; 53 54 55 using namespace android; 56 57 #define THREAD_STACK_SIZE (65536) 58 59 #define VIDEOEDITOR_VERSION_MAJOR 0 60 #define VIDEOEDITOR_VERSION_MINOR 0 61 #define VIDEOEDITOR_VERSION_REVISION 1 62 63 64 typedef enum 65 { 66 ManualEditState_NOT_INITIALIZED, 67 ManualEditState_INITIALIZED, 68 ManualEditState_ANALYZING, 69 ManualEditState_ANALYZING_ERROR, 70 ManualEditState_OPENED, 71 ManualEditState_SAVING, 72 ManualEditState_SAVING_ERROR, 73 ManualEditState_SAVED, 74 ManualEditState_STOPPING 75 } ManualEditState; 76 77 typedef struct 78 { 79 JavaVM* pVM; 80 jobject engine; 81 jmethodID onCompletionMethodId; 82 jmethodID onErrorMethodId; 83 jmethodID onWarningMethodId; 84 jmethodID onProgressUpdateMethodId; 85 jmethodID onPreviewProgressUpdateMethodId; 86 jmethodID previewFrameEditInfoId; 87 M4xVSS_InitParams initParams; 88 void* pTextRendererHandle; 89 M4xVSS_getTextRgbBufferFct pTextRendererFunction; 90 M4OSA_Context engineContext; 91 ManualEditState state; 92 M4VSS3GPP_EditSettings* pEditSettings; 93 M4OSA_Context threadContext; 94 M4OSA_ERR threadResult; 95 M4OSA_UInt8 threadProgress; 96 VideoEditorPreviewController *mPreviewController; 97 M4xVSS_AudioMixingSettings *mAudioSettings; 98 /* Audio Graph changes */ 99 M4OSA_Context pAudioGraphMCSCtx; 100 M4OSA_Bool bSkipState; 101 jmethodID onAudioGraphProgressUpdateMethodId; 102 Mutex mLock; 103 bool mIsUpdateOverlay; 104 char *mOverlayFileName; 105 int mOverlayRenderingMode; 106 M4DECODER_VideoDecoders* decoders; 107 } ManualEditContext; 108 109 extern "C" M4OSA_ERR M4MCS_open_normalMode( 110 M4MCS_Context pContext, 111 M4OSA_Void* pFileIn, 112 M4VIDEOEDITING_FileType InputFileType, 113 M4OSA_Void* pFileOut, 114 M4OSA_Void* pTempFile); 115 116 static M4OSA_ERR videoEditor_toUTF8Fct( 117 M4OSA_Void* pBufferIn, 118 M4OSA_UInt8* pBufferOut, 119 M4OSA_UInt32* bufferOutSize); 120 121 static M4OSA_ERR videoEditor_fromUTF8Fct( 122 M4OSA_UInt8* pBufferIn, 123 M4OSA_Void* pBufferOut, 124 M4OSA_UInt32* bufferOutSize); 125 126 static M4OSA_ERR videoEditor_getTextRgbBufferFct( 127 M4OSA_Void* pRenderingData, 128 M4OSA_Void* pTextBuffer, 129 M4OSA_UInt32 textBufferSize, 130 M4VIFI_ImagePlane** pOutputPlane); 131 132 static void videoEditor_callOnProgressUpdate( 133 ManualEditContext* pContext, 134 int task, 135 int progress); 136 137 static void videoEditor_freeContext( 138 JNIEnv* pEnv, 139 ManualEditContext** ppContext); 140 141 static M4OSA_ERR videoEditor_threadProc( 142 M4OSA_Void* param); 143 144 static jobject videoEditor_getVersion( 145 JNIEnv* pEnv, 146 jobject thiz); 147 148 static void videoEditor_init( 149 JNIEnv* pEnv, 150 jobject thiz, 151 jstring tempPath, 152 jstring textRendererPath); 153 154 static void videoEditor_loadSettings( 155 JNIEnv* pEnv, 156 jobject thiz, 157 jobject settings); 158 159 static void videoEditor_unloadSettings( 160 JNIEnv* pEnv, 161 jobject thiz); 162 163 164 static void videoEditor_stopEncoding( 165 JNIEnv* pEnv, 166 jobject thiz); 167 168 static void videoEditor_release( 169 JNIEnv* pEnv, 170 jobject thiz); 171 static int videoEditor_getPixels( 172 JNIEnv* env, 173 jobject thiz, 174 jstring path, 175 jintArray pixelArray, 176 M4OSA_UInt32 width, 177 M4OSA_UInt32 height, 178 M4OSA_UInt32 timeMS); 179 static int videoEditor_getPixelsList( 180 JNIEnv* env, 181 jobject thiz, 182 jstring path, 183 jintArray pixelArray, 184 M4OSA_UInt32 width, 185 M4OSA_UInt32 height, 186 M4OSA_UInt32 noOfThumbnails, 187 jlong startTime, 188 jlong endTime, 189 jintArray indexArray, 190 jobject callback); 191 192 static void 193 videoEditor_startPreview( 194 JNIEnv* pEnv, 195 jobject thiz, 196 jobject mSurface, 197 jlong fromMs, 198 jlong toMs, 199 jint callbackInterval, 200 jboolean loop); 201 202 static void 203 videoEditor_populateSettings( 204 JNIEnv* pEnv, 205 jobject thiz, 206 jobject settings, 207 jobject object, 208 jobject audioSettingObject); 209 210 static int videoEditor_stopPreview(JNIEnv* pEnv, 211 jobject thiz); 212 213 static jobject 214 videoEditor_getProperties( 215 JNIEnv* pEnv, 216 jobject thiz, 217 jstring file); 218 219 static int videoEditor_renderPreviewFrame(JNIEnv* pEnv, 220 jobject thiz, 221 jobject mSurface, 222 jlong fromMs, 223 jint surfaceWidth, 224 jint surfaceHeight); 225 226 static int videoEditor_registerManualEditMethods( 227 JNIEnv* pEnv); 228 229 static void jniPreviewProgressCallback(void* cookie, M4OSA_UInt32 msgType, 230 void *argc); 231 232 static int videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv, 233 jobject thiz, 234 jobject mSurface, 235 jstring filePath, 236 jint frameWidth, 237 jint frameHeight, 238 jint surfaceWidth, 239 jint surfaceHeight, 240 jlong fromMs); 241 242 static int videoEditor_generateAudioWaveFormSync ( JNIEnv* pEnv, 243 jobject thiz, 244 jstring pcmfilePath, 245 jstring outGraphfilePath, 246 jint frameDuration, 247 jint channels, 248 jint samplesCount); 249 250 static int videoEditor_generateAudioRawFile(JNIEnv* pEnv, 251 jobject thiz, 252 jstring infilePath, 253 jstring pcmfilePath ); 254 255 M4OSA_ERR videoEditor_generateAudio(JNIEnv* pEnv,ManualEditContext* pContext, 256 M4OSA_Char* infilePath, 257 M4OSA_Char* pcmfilePath ); 258 259 static int 260 videoEditor_generateClip( 261 JNIEnv* pEnv, 262 jobject thiz, 263 jobject settings); 264 265 static void videoEditor_clearSurface(JNIEnv* pEnv, 266 jobject thiz, 267 jobject surface); 268 269 static JNINativeMethod gManualEditMethods[] = { 270 {"getVersion", "()L"VERSION_CLASS_NAME";", 271 (void *)videoEditor_getVersion }, 272 {"_init", "(Ljava/lang/String;Ljava/lang/String;)V", 273 (void *)videoEditor_init }, 274 {"nativeStartPreview", "(Landroid/view/Surface;JJIZ)V", 275 (void *)videoEditor_startPreview }, 276 {"nativePopulateSettings", 277 "(L"EDIT_SETTINGS_CLASS_NAME";L"PREVIEW_PROPERTIES_CLASS_NAME";L" 278 AUDIO_SETTINGS_CLASS_NAME";)V", 279 (void *)videoEditor_populateSettings }, 280 {"nativeRenderPreviewFrame", "(Landroid/view/Surface;JII)I", 281 (int *)videoEditor_renderPreviewFrame }, 282 {"nativeRenderMediaItemPreviewFrame", 283 "(Landroid/view/Surface;Ljava/lang/String;IIIIJ)I", 284 (int *)videoEditor_renderMediaItemPreviewFrame }, 285 {"nativeStopPreview", "()I", 286 (int *)videoEditor_stopPreview }, 287 {"stopEncoding", "()V", 288 (void *)videoEditor_stopEncoding }, 289 {"release", "()V", 290 (void *)videoEditor_release }, 291 {"nativeGetPixels", "(Ljava/lang/String;[IIIJ)I", 292 (void*)videoEditor_getPixels }, 293 {"nativeGetPixelsList", "(Ljava/lang/String;[IIIIJJ[ILandroid/media/videoeditor/MediaArtistNativeHelper$NativeGetPixelsListCallback;)I", 294 (void*)videoEditor_getPixelsList }, 295 {"getMediaProperties", 296 "(Ljava/lang/String;)Landroid/media/videoeditor/MediaArtistNativeHelper$Properties;", 297 (void *)videoEditor_getProperties }, 298 {"nativeGenerateAudioGraph","(Ljava/lang/String;Ljava/lang/String;III)I", 299 (int *)videoEditor_generateAudioWaveFormSync }, 300 {"nativeGenerateRawAudio", "(Ljava/lang/String;Ljava/lang/String;)I", 301 (int *)videoEditor_generateAudioRawFile }, 302 {"nativeGenerateClip", "(L"EDIT_SETTINGS_CLASS_NAME";)I", 303 (void *)videoEditor_generateClip }, 304 {"nativeClearSurface", "(Landroid/view/Surface;)V", 305 (void *)videoEditor_clearSurface }, 306 }; 307 308 // temp file name of VSS out file 309 #define TEMP_MCS_OUT_FILE_PATH "tmpOut.3gp" 310 311 void 312 getClipSetting( 313 JNIEnv* pEnv, 314 jobject object, 315 M4VSS3GPP_ClipSettings* pSettings) 316 { 317 318 jfieldID fid; 319 int field = 0; 320 bool needToBeLoaded = true; 321 jclass clazz = pEnv->FindClass(PROPERTIES_CLASS_NAME); 322 323 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 324 (M4OSA_NULL == clazz), 325 "not initialized"); 326 327 fid = pEnv->GetFieldID(clazz,"duration","I"); 328 pSettings->ClipProperties.uiClipDuration = pEnv->GetIntField(object,fid); 329 M4OSA_TRACE1_1("duration = %d",pSettings->ClipProperties.uiClipDuration); 330 331 fid = pEnv->GetFieldID(clazz,"videoFormat","I"); 332 pSettings->ClipProperties.VideoStreamType = 333 (M4VIDEOEDITING_VideoFormat)pEnv->GetIntField(object,fid); 334 M4OSA_TRACE1_1("videoFormat = %d",pSettings->ClipProperties.VideoStreamType); 335 336 fid = pEnv->GetFieldID(clazz,"videoDuration","I"); 337 pSettings->ClipProperties.uiClipVideoDuration = pEnv->GetIntField(object,fid); 338 M4OSA_TRACE1_1("videoDuration = %d", 339 pSettings->ClipProperties.uiClipVideoDuration); 340 341 fid = pEnv->GetFieldID(clazz,"width","I"); 342 pSettings->ClipProperties.uiVideoWidth = pEnv->GetIntField(object,fid); 343 M4OSA_TRACE1_1("width = %d",pSettings->ClipProperties.uiVideoWidth); 344 345 fid = pEnv->GetFieldID(clazz,"height","I"); 346 pSettings->ClipProperties.uiVideoHeight = pEnv->GetIntField(object,fid); 347 M4OSA_TRACE1_1("height = %d",pSettings->ClipProperties.uiVideoHeight); 348 349 fid = pEnv->GetFieldID(clazz,"audioFormat","I"); 350 pSettings->ClipProperties.AudioStreamType = 351 (M4VIDEOEDITING_AudioFormat)pEnv->GetIntField(object,fid); 352 M4OSA_TRACE1_1("audioFormat = %d",pSettings->ClipProperties.AudioStreamType); 353 354 fid = pEnv->GetFieldID(clazz,"audioDuration","I"); 355 pSettings->ClipProperties.uiClipAudioDuration = pEnv->GetIntField(object,fid); 356 M4OSA_TRACE1_1("audioDuration = %d", 357 pSettings->ClipProperties.uiClipAudioDuration); 358 359 fid = pEnv->GetFieldID(clazz,"audioBitrate","I"); 360 pSettings->ClipProperties.uiAudioBitrate = pEnv->GetIntField(object,fid); 361 M4OSA_TRACE1_1("audioBitrate = %d",pSettings->ClipProperties.uiAudioBitrate); 362 363 fid = pEnv->GetFieldID(clazz,"audioChannels","I"); 364 pSettings->ClipProperties.uiNbChannels = pEnv->GetIntField(object,fid); 365 M4OSA_TRACE1_1("audioChannels = %d",pSettings->ClipProperties.uiNbChannels); 366 367 fid = pEnv->GetFieldID(clazz,"audioSamplingFrequency","I"); 368 pSettings->ClipProperties.uiSamplingFrequency = pEnv->GetIntField(object,fid); 369 M4OSA_TRACE1_1("audioSamplingFrequency = %d", 370 pSettings->ClipProperties.uiSamplingFrequency); 371 372 fid = pEnv->GetFieldID(clazz,"audioVolumeValue","I"); 373 pSettings->ClipProperties.uiClipAudioVolumePercentage = 374 pEnv->GetIntField(object,fid); 375 M4OSA_TRACE1_1("audioVolumeValue = %d", 376 pSettings->ClipProperties.uiClipAudioVolumePercentage); 377 378 fid = pEnv->GetFieldID(clazz,"videoRotation","I"); 379 pSettings->ClipProperties.videoRotationDegrees = 380 pEnv->GetIntField(object,fid); 381 M4OSA_TRACE1_1("videoRotation = %d", 382 pSettings->ClipProperties.videoRotationDegrees); 383 } 384 385 static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType, 386 void *argc) 387 { 388 ManualEditContext *pContext = (ManualEditContext *)cookie; 389 JNIEnv* pEnv = NULL; 390 bool isFinished = false; 391 int currentMs = 0; 392 int error = M4NO_ERROR; 393 bool isUpdateOverlay = false; 394 int overlayEffectIndex; 395 char *extPos; 396 bool isSendProgress = true; 397 jstring tmpFileName; 398 VideoEditorCurretEditInfo *pCurrEditInfo; 399 400 // Attach the current thread. 401 pContext->pVM->AttachCurrentThread(&pEnv, NULL); 402 switch(msgType) 403 { 404 case MSG_TYPE_PROGRESS_INDICATION: 405 currentMs = *(int*)argc; 406 break; 407 case MSG_TYPE_PLAYER_ERROR: 408 currentMs = -1; 409 error = *(int*)argc; 410 break; 411 case MSG_TYPE_PREVIEW_END: 412 isFinished = true; 413 break; 414 case MSG_TYPE_OVERLAY_UPDATE: 415 { 416 int overlayFileNameLen = 0; 417 isSendProgress = false; 418 pContext->mIsUpdateOverlay = true; 419 pCurrEditInfo = (VideoEditorCurretEditInfo*)argc; 420 overlayEffectIndex = pCurrEditInfo->overlaySettingsIndex; 421 ALOGV("MSG_TYPE_OVERLAY_UPDATE"); 422 423 if (pContext->mOverlayFileName != NULL) { 424 free(pContext->mOverlayFileName); 425 pContext->mOverlayFileName = NULL; 426 } 427 428 overlayFileNameLen = 429 strlen((const char*)pContext->pEditSettings->Effects[overlayEffectIndex].xVSS.pFramingFilePath); 430 431 pContext->mOverlayFileName = 432 (char*)M4OSA_32bitAlignedMalloc(overlayFileNameLen+1, 433 M4VS, (M4OSA_Char*)"videoEdito JNI overlayFile"); 434 if (pContext->mOverlayFileName != NULL) { 435 strncpy (pContext->mOverlayFileName, 436 (const char*)pContext->pEditSettings->\ 437 Effects[overlayEffectIndex].xVSS.pFramingFilePath, overlayFileNameLen); 438 //Change the name to png file 439 extPos = strstr(pContext->mOverlayFileName, ".rgb"); 440 if (extPos != NULL) { 441 *extPos = '\0'; 442 } else { 443 ALOGE("ERROR the overlay file is incorrect"); 444 } 445 446 strcat(pContext->mOverlayFileName, ".png"); 447 ALOGV("Conv string is %s", pContext->mOverlayFileName); 448 ALOGV("Current Clip index = %d", pCurrEditInfo->clipIndex); 449 450 pContext->mOverlayRenderingMode = pContext->pEditSettings->\ 451 pClipList[pCurrEditInfo->clipIndex]->xVSS.MediaRendering; 452 ALOGV("rendering mode %d ", pContext->mOverlayRenderingMode); 453 454 } 455 456 break; 457 } 458 459 case MSG_TYPE_OVERLAY_CLEAR: 460 isSendProgress = false; 461 if (pContext->mOverlayFileName != NULL) { 462 free(pContext->mOverlayFileName); 463 pContext->mOverlayFileName = NULL; 464 } 465 466 ALOGV("MSG_TYPE_OVERLAY_CLEAR"); 467 //argc is not used 468 pContext->mIsUpdateOverlay = true; 469 break; 470 default: 471 break; 472 } 473 474 if (isSendProgress) { 475 tmpFileName = pEnv->NewStringUTF(pContext->mOverlayFileName); 476 pEnv->CallVoidMethod(pContext->engine, 477 pContext->onPreviewProgressUpdateMethodId, 478 currentMs,isFinished, pContext->mIsUpdateOverlay, 479 tmpFileName, pContext->mOverlayRenderingMode, error); 480 481 if (pContext->mIsUpdateOverlay) { 482 pContext->mIsUpdateOverlay = false; 483 } 484 485 if (tmpFileName) { 486 pEnv->DeleteLocalRef(tmpFileName); 487 } 488 } 489 490 // Detach the current thread. 491 pContext->pVM->DetachCurrentThread(); 492 493 } 494 static M4OSA_ERR checkClipVideoProfileAndLevel(M4DECODER_VideoDecoders *pDecoders, 495 M4OSA_Int32 format, M4OSA_UInt32 profile, M4OSA_UInt32 level){ 496 497 M4OSA_Int32 codec = 0; 498 M4OSA_Bool foundCodec = M4OSA_FALSE; 499 M4OSA_ERR result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE; 500 M4OSA_Bool foundProfile = M4OSA_FALSE; 501 ALOGV("checkClipVideoProfileAndLevel format %d profile;%d level:0x%x", 502 format, profile, level); 503 504 switch (format) { 505 case M4VIDEOEDITING_kH263: 506 codec = M4DA_StreamTypeVideoH263; 507 break; 508 case M4VIDEOEDITING_kH264: 509 codec = M4DA_StreamTypeVideoMpeg4Avc; 510 break; 511 case M4VIDEOEDITING_kMPEG4: 512 codec = M4DA_StreamTypeVideoMpeg4; 513 break; 514 case M4VIDEOEDITING_kNoneVideo: 515 case M4VIDEOEDITING_kNullVideo: 516 case M4VIDEOEDITING_kUnsupportedVideo: 517 // For these case we do not check the profile and level 518 return M4NO_ERROR; 519 default : 520 ALOGE("checkClipVideoProfileAndLevel unsupport Video format %ld", format); 521 break; 522 } 523 524 if (pDecoders != M4OSA_NULL && pDecoders->decoderNumber > 0) { 525 VideoDecoder *pVideoDecoder = pDecoders->decoder; 526 for(size_t k =0; k < pDecoders->decoderNumber; k++) { 527 if (pVideoDecoder != M4OSA_NULL) { 528 if (pVideoDecoder->codec == codec) { 529 foundCodec = M4OSA_TRUE; 530 break; 531 } 532 } 533 pVideoDecoder++; 534 } 535 536 if (foundCodec) { 537 VideoComponentCapabilities* pComponent = pVideoDecoder->component; 538 for (size_t i = 0; i < pVideoDecoder->componentNumber; i++) { 539 if (pComponent != M4OSA_NULL) { 540 VideoProfileLevel *pProfileLevel = pComponent->profileLevel; 541 for (size_t j =0; j < pComponent->profileNumber; j++) { 542 // Check the profile and level 543 if (pProfileLevel != M4OSA_NULL) { 544 if (profile == pProfileLevel->mProfile) { 545 foundProfile = M4OSA_TRUE; 546 547 if (level <= pProfileLevel->mLevel) { 548 return M4NO_ERROR; 549 } 550 } else { 551 foundProfile = M4OSA_FALSE; 552 } 553 } 554 pProfileLevel++; 555 } 556 } 557 pComponent++; 558 } 559 } 560 } 561 562 if (foundProfile) { 563 result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_LEVEL; 564 } else { 565 result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE; 566 } 567 568 return result; 569 } 570 static int videoEditor_stopPreview(JNIEnv* pEnv, 571 jobject thiz) 572 { 573 ManualEditContext* pContext = M4OSA_NULL; 574 bool needToBeLoaded = true; 575 M4OSA_UInt32 lastProgressTimeMs = 0; 576 577 // Get the context. 578 pContext = 579 (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); 580 581 // Make sure that the context was set. 582 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 583 (M4OSA_NULL == pContext), 584 "not initialized"); 585 lastProgressTimeMs = pContext->mPreviewController->stopPreview(); 586 587 if (pContext->mOverlayFileName != NULL) { 588 free(pContext->mOverlayFileName); 589 pContext->mOverlayFileName = NULL; 590 } 591 592 return lastProgressTimeMs; 593 } 594 595 static void videoEditor_clearSurface(JNIEnv* pEnv, 596 jobject thiz, 597 jobject surface) 598 { 599 bool needToBeLoaded = true; 600 M4OSA_ERR result = M4NO_ERROR; 601 VideoEditor_renderPreviewFrameStr frameStr; 602 const char* pMessage = NULL; 603 // Let the size be QVGA 604 int width = 320; 605 int height = 240; 606 ManualEditContext* pContext = M4OSA_NULL; 607 608 // Get the context. 609 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); 610 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, 611 "VIDEO_EDITOR","pContext = 0x%x",pContext); 612 613 // Make sure that the context was set. 614 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 615 (M4OSA_NULL == pContext), 616 "not initialized"); 617 618 // Make sure that the context was set. 619 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 620 (M4OSA_NULL == pContext->mPreviewController), 621 "not initialized"); 622 623 // Validate the surface parameter. 624 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, 625 (NULL == surface), 626 "surface is null"); 627 628 jclass surfaceClass = pEnv->FindClass("android/view/Surface"); 629 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 630 (M4OSA_NULL == surfaceClass), 631 "not initialized"); 632 633 jfieldID surface_native = 634 pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); 635 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 636 (M4OSA_NULL == surface_native), 637 "not initialized"); 638 639 Surface* const p = (Surface*)pEnv->GetIntField(surface, surface_native); 640 sp<Surface> previewSurface = sp<Surface>(p); 641 // Validate the mSurface's mNativeSurface field 642 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 643 (NULL == previewSurface.get()), 644 "mNativeSurface is null"); 645 646 frameStr.pBuffer = M4OSA_NULL; 647 frameStr.timeMs = 0; 648 frameStr.uiSurfaceWidth = width; 649 frameStr.uiSurfaceHeight = height; 650 frameStr.uiFrameWidth = width; 651 frameStr.uiFrameHeight = height; 652 frameStr.bApplyEffect = M4OSA_FALSE; 653 frameStr.clipBeginCutTime = 0; 654 frameStr.clipEndCutTime = 0; 655 656 result = pContext->mPreviewController->clearSurface(previewSurface, 657 &frameStr); 658 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 659 (M4NO_ERROR != result), result); 660 661 } 662 663 static int videoEditor_renderPreviewFrame(JNIEnv* pEnv, 664 jobject thiz, 665 jobject mSurface, 666 jlong fromMs, 667 jint surfaceWidth, 668 jint surfaceHeight ) 669 { 670 bool needToBeLoaded = true; 671 M4OSA_ERR result = M4NO_ERROR; 672 M4OSA_UInt32 timeMs = (M4OSA_UInt32)fromMs; 673 M4OSA_UInt32 i=0,tnTimeMs = 0, framesizeYuv =0; 674 M4VIFI_UInt8 *pixelArray = M4OSA_NULL; 675 M4OSA_UInt32 iCurrentClipIndex = 0, uiNumberOfClipsInStoryBoard =0, 676 uiClipDuration = 0, uiTotalClipDuration = 0, 677 iIncrementedDuration = 0; 678 VideoEditor_renderPreviewFrameStr frameStr; 679 M4OSA_Context tnContext = M4OSA_NULL; 680 const char* pMessage = NULL; 681 M4VIFI_ImagePlane *yuvPlane = NULL; 682 VideoEditorCurretEditInfo currEditInfo; 683 684 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, 685 "VIDEO_EDITOR", "surfaceWidth = %d",surfaceWidth); 686 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, 687 "VIDEO_EDITOR", "surfaceHeight = %d",surfaceHeight); 688 ManualEditContext* pContext = M4OSA_NULL; 689 // Get the context. 690 pContext = 691 (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); 692 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, 693 "VIDEO_EDITOR","pContext = 0x%x",pContext); 694 695 // Make sure that the context was set. 696 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 697 (M4OSA_NULL == pContext), 698 "not initialized"); 699 700 // Make sure that the context was set. 701 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 702 (M4OSA_NULL == pContext->mPreviewController), 703 "not initialized"); 704 705 // Validate the mSurface parameter. 706 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, 707 (NULL == mSurface), 708 "mSurface is null"); 709 jclass surfaceClass = pEnv->FindClass("android/view/Surface"); 710 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 711 (M4OSA_NULL == surfaceClass), 712 "not initialized"); 713 714 jfieldID surface_native = 715 pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); 716 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 717 (M4OSA_NULL == surface_native), 718 "not initialized"); 719 720 Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); 721 sp<Surface> previewSurface = sp<Surface>(p); 722 // Validate the mSurface's mNativeSurface field 723 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 724 (NULL == previewSurface.get()), 725 "mNativeSurface is null"); 726 727 /* Determine the total number of clips, total duration*/ 728 uiNumberOfClipsInStoryBoard = pContext->pEditSettings->uiClipNumber; 729 730 for (i = 0; i < uiNumberOfClipsInStoryBoard; i++) { 731 uiClipDuration = pContext->pEditSettings->pClipList[i]->uiEndCutTime - 732 pContext->pEditSettings->pClipList[i]->uiBeginCutTime; 733 uiTotalClipDuration += uiClipDuration; 734 } 735 736 /* determine the clip whose thumbnail needs to be rendered*/ 737 if (timeMs == 0) { 738 iCurrentClipIndex = 0; 739 i=0; 740 } else { 741 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 742 "videoEditor_renderPreviewFrame() timeMs=%d", timeMs); 743 744 if (timeMs > uiTotalClipDuration) { 745 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 746 "videoEditor_renderPreviewFrame() timeMs > uiTotalClipDuration"); 747 pMessage = videoEditJava_getErrorName(M4ERR_PARAMETER); 748 jniThrowException(pEnv, "java/lang/IllegalArgumentException", pMessage); 749 return -1; 750 } 751 752 for (i = 0; i < uiNumberOfClipsInStoryBoard; i++) { 753 if (timeMs <= (iIncrementedDuration + 754 (pContext->pEditSettings->pClipList[i]->uiEndCutTime - 755 pContext->pEditSettings->pClipList[i]->uiBeginCutTime))) 756 { 757 iCurrentClipIndex = i; 758 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 759 "videoEditor_renderPreviewFrame() iCurrentClipIndex=%d for timeMs=%d", 760 iCurrentClipIndex, timeMs); 761 break; 762 } 763 else { 764 iIncrementedDuration = iIncrementedDuration + 765 (pContext->pEditSettings->pClipList[i]->uiEndCutTime - 766 pContext->pEditSettings->pClipList[i]->uiBeginCutTime); 767 } 768 } 769 } 770 /* If timestamp is beyond story board duration, return*/ 771 if (i >= uiNumberOfClipsInStoryBoard) { 772 if (timeMs == iIncrementedDuration) { 773 iCurrentClipIndex = i-1; 774 } else { 775 return -1; 776 } 777 } 778 779 /*+ Handle the image files here */ 780 if (pContext->pEditSettings->pClipList[iCurrentClipIndex]->FileType == 781 /*M4VIDEOEDITING_kFileType_JPG*/ M4VIDEOEDITING_kFileType_ARGB8888 ) { 782 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", " iCurrentClipIndex %d ", iCurrentClipIndex); 783 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 784 " Height = %d", 785 pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoHeight); 786 787 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 788 " Width = %d", 789 pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoWidth); 790 791 LvGetImageThumbNail((const char *)pContext->pEditSettings->\ 792 pClipList[iCurrentClipIndex]->pFile, 793 pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoHeight, 794 pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoWidth, 795 (M4OSA_Void **)&frameStr.pBuffer); 796 tnTimeMs = (M4OSA_UInt32)timeMs; 797 798 frameStr.videoRotationDegree = 0; 799 } else { 800 /* Handle 3gp/mp4 Clips here */ 801 /* get thumbnail*/ 802 result = ThumbnailOpen(&tnContext, 803 (const M4OSA_Char*)pContext->pEditSettings->\ 804 pClipList[iCurrentClipIndex]->pFile, M4OSA_TRUE); 805 if (result != M4NO_ERROR || tnContext == M4OSA_NULL) { 806 return -1; 807 } 808 809 /* timeMs is relative to storyboard; in this api it shud be relative to this clip */ 810 if ((i >= uiNumberOfClipsInStoryBoard) && 811 (timeMs == iIncrementedDuration)) { 812 tnTimeMs = pContext->pEditSettings->\ 813 pClipList[iCurrentClipIndex]->uiEndCutTime; 814 } else { 815 tnTimeMs = pContext->pEditSettings->\ 816 pClipList[iCurrentClipIndex]->uiBeginCutTime 817 + (timeMs - iIncrementedDuration); 818 } 819 820 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 821 "video width = %d",pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 822 ClipProperties.uiVideoWidth); 823 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 824 "video height = %d",pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 825 ClipProperties.uiVideoHeight); 826 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 827 "current clip index = %d",iCurrentClipIndex); 828 829 M4OSA_UInt32 width = pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 830 ClipProperties.uiVideoWidth; 831 M4OSA_UInt32 height = pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 832 ClipProperties.uiVideoHeight; 833 834 framesizeYuv = width * height * 1.5; 835 836 pixelArray = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(framesizeYuv, M4VS, 837 (M4OSA_Char*)"videoEditor pixelArray"); 838 if (pixelArray == M4OSA_NULL) { 839 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 840 "videoEditor_renderPreviewFrame() malloc error"); 841 ThumbnailClose(tnContext); 842 pMessage = videoEditJava_getErrorName(M4ERR_ALLOC); 843 jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); 844 return -1; 845 } 846 847 result = ThumbnailGetPixels16(tnContext, (M4OSA_Int16 *)pixelArray, 848 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 849 ClipProperties.uiVideoWidth, 850 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 851 ClipProperties.uiVideoHeight, 852 &tnTimeMs, 0); 853 if (result != M4NO_ERROR) { 854 free(pixelArray); 855 ThumbnailClose(tnContext); 856 return -1; 857 } 858 859 ThumbnailClose(tnContext); 860 tnContext = M4OSA_NULL; 861 862 #ifdef DUMPTOFILE 863 { 864 M4OSA_Context fileContext; 865 M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/FirstRGB565.raw"; 866 remove((const char *)fileName); 867 M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\ 868 M4OSA_kFileWrite|M4OSA_kFileCreate); 869 M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) pixelArray, 870 framesizeYuv); 871 M4OSA_fileWriteClose(fileContext); 872 } 873 #endif 874 875 /** 876 * Allocate output YUV planes 877 */ 878 yuvPlane = (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc(3*sizeof(M4VIFI_ImagePlane), M4VS, 879 (M4OSA_Char*)"videoEditor_renderPreviewFrame Output plane YUV"); 880 if (yuvPlane == M4OSA_NULL) { 881 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 882 "videoEditor_renderPreviewFrame() malloc error for yuv plane"); 883 free(pixelArray); 884 pMessage = videoEditJava_getErrorName(M4ERR_ALLOC); 885 jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); 886 return -1; 887 } 888 889 yuvPlane[0].u_width = width; 890 yuvPlane[0].u_height = height; 891 yuvPlane[0].u_topleft = 0; 892 yuvPlane[0].u_stride = width; 893 yuvPlane[0].pac_data = (M4VIFI_UInt8*)pixelArray; 894 895 yuvPlane[1].u_width = width>>1; 896 yuvPlane[1].u_height = height>>1; 897 yuvPlane[1].u_topleft = 0; 898 yuvPlane[1].u_stride = width>>1; 899 yuvPlane[1].pac_data = yuvPlane[0].pac_data 900 + yuvPlane[0].u_width * yuvPlane[0].u_height; 901 yuvPlane[2].u_width = (width)>>1; 902 yuvPlane[2].u_height = (height)>>1; 903 yuvPlane[2].u_topleft = 0; 904 yuvPlane[2].u_stride = (width)>>1; 905 yuvPlane[2].pac_data = yuvPlane[1].pac_data 906 + yuvPlane[1].u_width * yuvPlane[1].u_height; 907 908 #ifdef DUMPTOFILE 909 { 910 M4OSA_Context fileContext; 911 M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/ConvertedYuv.yuv"; 912 remove((const char *)fileName); 913 M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\ 914 M4OSA_kFileWrite|M4OSA_kFileCreate); 915 M4OSA_fileWriteData(fileContext, 916 (M4OSA_MemAddr8) yuvPlane[0].pac_data, framesizeYuv); 917 M4OSA_fileWriteClose(fileContext); 918 } 919 #endif 920 921 /* Fill up the render structure*/ 922 frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data; 923 924 frameStr.videoRotationDegree = pContext->pEditSettings->\ 925 pClipList[iCurrentClipIndex]->ClipProperties.videoRotationDegrees; 926 } 927 928 frameStr.timeMs = timeMs; /* timestamp on storyboard*/ 929 frameStr.uiSurfaceWidth = 930 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 931 ClipProperties.uiVideoWidth; 932 frameStr.uiSurfaceHeight = 933 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 934 ClipProperties.uiVideoHeight; 935 frameStr.uiFrameWidth = 936 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 937 ClipProperties.uiVideoWidth; 938 frameStr.uiFrameHeight = 939 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\ 940 ClipProperties.uiVideoHeight; 941 if (pContext->pEditSettings->nbEffects > 0) { 942 frameStr.bApplyEffect = M4OSA_TRUE; 943 } else { 944 frameStr.bApplyEffect = M4OSA_FALSE; 945 } 946 frameStr.clipBeginCutTime = iIncrementedDuration; 947 frameStr.clipEndCutTime = 948 iIncrementedDuration + 949 (pContext->pEditSettings->pClipList[iCurrentClipIndex]->uiEndCutTime -\ 950 pContext->pEditSettings->pClipList[iCurrentClipIndex]->uiBeginCutTime); 951 952 pContext->mPreviewController->setPreviewFrameRenderingMode( 953 pContext->pEditSettings->\ 954 pClipList[iCurrentClipIndex]->xVSS.MediaRendering, 955 pContext->pEditSettings->xVSS.outputVideoSize); 956 result = pContext->mPreviewController->renderPreviewFrame(previewSurface, 957 &frameStr, &currEditInfo); 958 959 if (currEditInfo.overlaySettingsIndex != -1) { 960 char tmpOverlayFilename[100]; 961 char *extPos = NULL; 962 jstring tmpOverlayString; 963 int tmpRenderingMode = 0; 964 965 strncpy (tmpOverlayFilename, 966 (const char*)pContext->pEditSettings->Effects[currEditInfo.overlaySettingsIndex].xVSS.pFramingFilePath, 99); 967 968 //Change the name to png file 969 extPos = strstr(tmpOverlayFilename, ".rgb"); 970 if (extPos != NULL) { 971 *extPos = '\0'; 972 } else { 973 ALOGE("ERROR the overlay file is incorrect"); 974 } 975 976 strcat(tmpOverlayFilename, ".png"); 977 978 tmpRenderingMode = pContext->pEditSettings->pClipList[iCurrentClipIndex]->xVSS.MediaRendering; 979 tmpOverlayString = pEnv->NewStringUTF(tmpOverlayFilename); 980 pEnv->CallVoidMethod(pContext->engine, 981 pContext->previewFrameEditInfoId, 982 tmpOverlayString, tmpRenderingMode); 983 984 } 985 986 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 987 (M4NO_ERROR != result), result); 988 989 free(frameStr.pBuffer); 990 if (pContext->pEditSettings->pClipList[iCurrentClipIndex]->FileType != 991 M4VIDEOEDITING_kFileType_ARGB8888) { 992 free(yuvPlane); 993 } 994 995 return tnTimeMs; 996 } 997 998 static int videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv, 999 jobject thiz, 1000 jobject mSurface, 1001 jstring filePath, 1002 jint frameWidth, 1003 jint frameHeight, 1004 jint surfaceWidth, 1005 jint surfaceHeight, 1006 jlong fromMs) 1007 { 1008 bool needToBeLoaded = true; 1009 M4OSA_ERR result = M4NO_ERROR; 1010 M4OSA_UInt32 timeMs = (M4OSA_UInt32)fromMs; 1011 M4OSA_UInt32 framesizeYuv =0; 1012 M4VIFI_UInt8 *pixelArray = M4OSA_NULL; 1013 VideoEditor_renderPreviewFrameStr frameStr; 1014 M4OSA_Context tnContext = M4OSA_NULL; 1015 const char* pMessage = NULL; 1016 M4VIFI_ImagePlane yuvPlane[3], rgbPlane; 1017 1018 ManualEditContext* pContext = M4OSA_NULL; 1019 // Get the context. 1020 pContext = 1021 (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, 1022 pEnv, thiz); 1023 1024 // Make sure that the context was set. 1025 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1026 (M4OSA_NULL == pContext), 1027 "not initialized"); 1028 1029 // Make sure that the context was set. 1030 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1031 (M4OSA_NULL == pContext->mPreviewController), 1032 "not initialized"); 1033 1034 // Validate the mSurface parameter. 1035 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, 1036 (NULL == mSurface), 1037 "mSurface is null"); 1038 jclass surfaceClass = pEnv->FindClass("android/view/Surface"); 1039 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1040 (M4OSA_NULL == surfaceClass), 1041 "not initialized"); 1042 1043 jfieldID surface_native = 1044 pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); 1045 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1046 (M4OSA_NULL == surface_native), 1047 "not initialized"); 1048 1049 Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); 1050 sp<Surface> previewSurface = sp<Surface>(p); 1051 1052 1053 const char *pString = pEnv->GetStringUTFChars(filePath, NULL); 1054 if (pString == M4OSA_NULL) { 1055 if (pEnv != NULL) { 1056 jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null"); 1057 } 1058 } 1059 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 1060 "videoEditor_renderMediaItemPreviewFrame() timeMs=%d", timeMs); 1061 /* get thumbnail*/ 1062 result = ThumbnailOpen(&tnContext,(const M4OSA_Char*)pString, M4OSA_TRUE); 1063 if (result != M4NO_ERROR || tnContext == M4OSA_NULL) { 1064 return timeMs; 1065 } 1066 1067 framesizeYuv = ((frameWidth)*(frameHeight)*1.5); 1068 1069 pixelArray = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(framesizeYuv, M4VS,\ 1070 (M4OSA_Char*)"videoEditor pixelArray"); 1071 if (pixelArray == M4OSA_NULL) { 1072 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 1073 "videoEditor_renderPreviewFrame() malloc error"); 1074 ThumbnailClose(tnContext); 1075 pMessage = videoEditJava_getErrorName(M4ERR_ALLOC); 1076 jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); 1077 return timeMs; 1078 } 1079 1080 result = ThumbnailGetPixels16(tnContext, (M4OSA_Int16 *)pixelArray, 1081 frameWidth, 1082 frameHeight, &timeMs, 0); 1083 if (result != M4NO_ERROR) { 1084 free(pixelArray); 1085 ThumbnailClose(tnContext); 1086 return fromMs; 1087 } 1088 1089 #ifdef DUMPTOFILESYSTEM 1090 { 1091 M4OSA_Context fileContext; 1092 M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/FirstRGB565.rgb"; 1093 M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\ 1094 M4OSA_kFileWrite|M4OSA_kFileCreate); 1095 M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) pixelArray, 1096 framesizeRgb); 1097 M4OSA_fileWriteClose(fileContext); 1098 } 1099 #endif 1100 1101 yuvPlane[0].pac_data = (M4VIFI_UInt8*)pixelArray; 1102 yuvPlane[0].u_height = frameHeight; 1103 yuvPlane[0].u_width = frameWidth; 1104 yuvPlane[0].u_stride = yuvPlane[0].u_width; 1105 yuvPlane[0].u_topleft = 0; 1106 1107 yuvPlane[1].u_height = frameHeight/2; 1108 yuvPlane[1].u_width = frameWidth/2; 1109 yuvPlane[1].u_stride = yuvPlane[1].u_width; 1110 yuvPlane[1].u_topleft = 0; 1111 yuvPlane[1].pac_data = yuvPlane[0].pac_data 1112 + yuvPlane[0].u_width*yuvPlane[0].u_height; 1113 1114 yuvPlane[2].u_height = frameHeight/2; 1115 yuvPlane[2].u_width = frameWidth/2; 1116 yuvPlane[2].u_stride = yuvPlane[2].u_width; 1117 yuvPlane[2].u_topleft = 0; 1118 yuvPlane[2].pac_data = yuvPlane[0].pac_data 1119 + yuvPlane[0].u_width*yuvPlane[0].u_height + \ 1120 (yuvPlane[0].u_width/2)*(yuvPlane[0].u_height/2); 1121 #ifdef DUMPTOFILESYSTEM 1122 { 1123 M4OSA_Context fileContext; 1124 M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/ConvertedYuv.yuv"; 1125 M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\ 1126 M4OSA_kFileWrite|M4OSA_kFileCreate); 1127 M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) yuvPlane[0].pac_data, 1128 framesizeYuv); 1129 M4OSA_fileWriteClose(fileContext); 1130 } 1131 #endif 1132 1133 /* Fill up the render structure*/ 1134 frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data; 1135 frameStr.timeMs = timeMs; /* timestamp on storyboard*/ 1136 frameStr.uiSurfaceWidth = frameWidth; 1137 frameStr.uiSurfaceHeight = frameHeight; 1138 frameStr.uiFrameWidth = frameWidth; 1139 frameStr.uiFrameHeight = frameHeight; 1140 frameStr.bApplyEffect = M4OSA_FALSE; 1141 // clip begin cuttime and end cuttime set to 0 1142 // as its only required when effect needs to be applied while rendering 1143 frameStr.clipBeginCutTime = 0; 1144 frameStr.clipEndCutTime = 0; 1145 1146 /* pContext->mPreviewController->setPreviewFrameRenderingMode(M4xVSS_kBlackBorders, 1147 (M4VIDEOEDITING_VideoFrameSize)(M4VIDEOEDITING_kHD960+1));*/ 1148 result 1149 = pContext->mPreviewController->renderPreviewFrame(previewSurface,&frameStr, NULL); 1150 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1151 (M4NO_ERROR != result), result); 1152 1153 /* free the pixelArray and yuvPlane[0].pac_data */ 1154 free(yuvPlane[0].pac_data); 1155 1156 ThumbnailClose(tnContext); 1157 1158 if (pString != NULL) { 1159 pEnv->ReleaseStringUTFChars(filePath, pString); 1160 } 1161 1162 return timeMs; 1163 } 1164 1165 int videoEditor_generateAudioRawFile( JNIEnv* pEnv, 1166 jobject thiz, 1167 jstring infilePath, 1168 jstring pcmfilePath) 1169 { 1170 M4OSA_ERR result = M4NO_ERROR; 1171 bool loaded = true; 1172 ManualEditContext* pContext = M4OSA_NULL; 1173 1174 1175 1176 const char *pInputFile = pEnv->GetStringUTFChars(infilePath, NULL); 1177 if (pInputFile == M4OSA_NULL) { 1178 if (pEnv != NULL) { 1179 jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null"); 1180 } 1181 } 1182 1183 const char *pStringOutPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL); 1184 if (pStringOutPCMFilePath == M4OSA_NULL) { 1185 if (pEnv != NULL) { 1186 jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null"); 1187 } 1188 } 1189 1190 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, 1191 "VIDEO_EDITOR", "videoEditor_generateAudioRawFile infilePath %s", 1192 pInputFile); 1193 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, 1194 "VIDEO_EDITOR", "videoEditor_generateAudioRawFile pcmfilePath %s", 1195 pStringOutPCMFilePath); 1196 // Get the context. 1197 pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz); 1198 1199 result = videoEditor_generateAudio( pEnv, pContext, (M4OSA_Char*)pInputFile, 1200 (M4OSA_Char*)pStringOutPCMFilePath); 1201 1202 if (pInputFile != NULL) { 1203 pEnv->ReleaseStringUTFChars(infilePath, pInputFile); 1204 } 1205 if (pStringOutPCMFilePath != NULL) { 1206 pEnv->ReleaseStringUTFChars(pcmfilePath, pStringOutPCMFilePath); 1207 } 1208 1209 return result; 1210 } 1211 1212 M4OSA_ERR videoEditor_generateAudio(JNIEnv* pEnv,ManualEditContext* pContext, 1213 M4OSA_Char* infilePath, 1214 M4OSA_Char* pcmfilePath ) 1215 { 1216 bool needToBeLoaded = true; 1217 M4OSA_ERR result = M4NO_ERROR; 1218 M4MCS_Context mcsContext = M4OSA_NULL; 1219 M4OSA_Char* pInputFile = M4OSA_NULL; 1220 M4OSA_Char* pOutputFile = M4OSA_NULL; 1221 M4OSA_Char* pTempPath = M4OSA_NULL; 1222 M4MCS_OutputParams* pOutputParams = M4OSA_NULL; 1223 M4MCS_EncodingParams* pEncodingParams = M4OSA_NULL; 1224 M4OSA_Int32 pInputFileType = 0; 1225 M4OSA_UInt8 threadProgress = 0; 1226 M4OSA_Char* pTemp3gpFilePath = M4OSA_NULL; 1227 1228 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_generateAudio()"); 1229 1230 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, 1231 (NULL == pContext), 1232 "ManualEditContext is null"); 1233 1234 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_init()"); 1235 1236 pOutputParams = (M4MCS_OutputParams *)M4OSA_32bitAlignedMalloc( 1237 sizeof(M4MCS_OutputParams),0x00, 1238 (M4OSA_Char *)"M4MCS_OutputParams"); 1239 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1240 (M4OSA_NULL == pOutputParams), 1241 "not initialized"); 1242 if (needToBeLoaded == false) { 1243 return M4ERR_ALLOC; 1244 } 1245 1246 pEncodingParams = (M4MCS_EncodingParams *)M4OSA_32bitAlignedMalloc( 1247 sizeof(M4MCS_EncodingParams),0x00, 1248 (M4OSA_Char *)"M4MCS_EncodingParams"); 1249 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1250 (M4OSA_NULL == pEncodingParams), 1251 "not initialized"); 1252 if (needToBeLoaded == false) { 1253 free(pEncodingParams); 1254 pEncodingParams = M4OSA_NULL; 1255 return M4ERR_ALLOC; 1256 } 1257 1258 // Initialize the MCS library. 1259 result = M4MCS_init(&mcsContext, pContext->initParams.pFileReadPtr, 1260 pContext->initParams.pFileWritePtr); 1261 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,\ 1262 (M4NO_ERROR != result), result); 1263 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1264 (M4OSA_NULL == mcsContext), 1265 "not initialized"); 1266 if(needToBeLoaded == false) { 1267 free(pOutputParams); 1268 pOutputParams = M4OSA_NULL; 1269 free(pEncodingParams); 1270 pEncodingParams = M4OSA_NULL; 1271 return result; 1272 } 1273 1274 // generate the path for temp 3gp output file 1275 pTemp3gpFilePath = (M4OSA_Char*) M4OSA_32bitAlignedMalloc ( 1276 (strlen((const char*)pContext->initParams.pTempPath) 1277 + strlen((const char*)TEMP_MCS_OUT_FILE_PATH)) + 1 /* for null termination */ , 0x0, 1278 (M4OSA_Char*)"Malloc for temp 3gp file"); 1279 if (pTemp3gpFilePath != M4OSA_NULL) 1280 { 1281 memset((void *)pTemp3gpFilePath ,0, 1282 strlen((const char*)pContext->initParams.pTempPath) 1283 + strlen((const char*)TEMP_MCS_OUT_FILE_PATH) + 1); 1284 strncat((char *)pTemp3gpFilePath, 1285 (const char *)pContext->initParams.pTempPath , 1286 (size_t) ((M4OSA_Char*)pContext->initParams.pTempPath)); 1287 strncat((char *)pTemp3gpFilePath , (const char *)TEMP_MCS_OUT_FILE_PATH, 1288 (size_t)strlen ((const char*)TEMP_MCS_OUT_FILE_PATH)); 1289 } 1290 else { 1291 M4MCS_abort(mcsContext); 1292 free(pOutputParams); 1293 pOutputParams = M4OSA_NULL; 1294 free(pEncodingParams); 1295 pEncodingParams = M4OSA_NULL; 1296 return M4ERR_ALLOC; 1297 } 1298 1299 pInputFile = (M4OSA_Char *) infilePath; //pContext->mAudioSettings->pFile; 1300 //Delete this file later 1301 pOutputFile = (M4OSA_Char *) pTemp3gpFilePath; 1302 // Temp folder path for VSS use = ProjectPath 1303 pTempPath = (M4OSA_Char *) pContext->initParams.pTempPath; 1304 pInputFileType = (M4VIDEOEDITING_FileType)pContext->mAudioSettings->fileType; 1305 1306 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "TEMP_MCS_OUT_FILE_PATH len %d", 1307 strlen ((const char*)TEMP_MCS_OUT_FILE_PATH)); 1308 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pTemp3gpFilePath %s", 1309 pOutputFile); 1310 1311 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_open()"); 1312 1313 result = M4MCS_open(mcsContext, pInputFile, 1314 (M4VIDEOEDITING_FileType)pInputFileType, 1315 pOutputFile, pTempPath); 1316 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1317 (M4NO_ERROR != result), result); 1318 if(needToBeLoaded == false) { 1319 free(pTemp3gpFilePath); 1320 pTemp3gpFilePath = M4OSA_NULL; 1321 M4MCS_abort(mcsContext); 1322 free(pOutputParams); 1323 pOutputParams = M4OSA_NULL; 1324 free(pEncodingParams); 1325 pEncodingParams = M4OSA_NULL; 1326 return result; 1327 } 1328 1329 pOutputParams->OutputFileType 1330 = (M4VIDEOEDITING_FileType)M4VIDEOEDITING_kFileType_3GPP; 1331 // Set the video format. 1332 pOutputParams->OutputVideoFormat = 1333 (M4VIDEOEDITING_VideoFormat)M4VIDEOEDITING_kNoneVideo;//M4VIDEOEDITING_kNoneVideo; 1334 pOutputParams->outputVideoProfile = 1; 1335 pOutputParams->outputVideoLevel = 1; 1336 // Set the frame size. 1337 pOutputParams->OutputVideoFrameSize 1338 = (M4VIDEOEDITING_VideoFrameSize)M4VIDEOEDITING_kQCIF; 1339 // Set the frame rate. 1340 pOutputParams->OutputVideoFrameRate 1341 = (M4VIDEOEDITING_VideoFramerate)M4VIDEOEDITING_k5_FPS; 1342 1343 // Set the audio format. 1344 pOutputParams->OutputAudioFormat 1345 = (M4VIDEOEDITING_AudioFormat)M4VIDEOEDITING_kAAC; 1346 // Set the audio sampling frequency. 1347 pOutputParams->OutputAudioSamplingFrequency = 1348 (M4VIDEOEDITING_AudioSamplingFrequency)M4VIDEOEDITING_k32000_ASF; 1349 // Set the audio mono. 1350 pOutputParams->bAudioMono = false; 1351 // Set the pcm file; null for now. 1352 pOutputParams->pOutputPCMfile = (M4OSA_Char *)pcmfilePath; 1353 //(M4OSA_Char *)"/sdcard/Output/AudioPcm.pcm"; 1354 // Set the audio sampling frequency. 1355 pOutputParams->MediaRendering = (M4MCS_MediaRendering)M4MCS_kCropping; 1356 // new params after integrating MCS 2.0 1357 // Set the number of audio effects; 0 for now. 1358 pOutputParams->nbEffects = 0; 1359 // Set the audio effect; null for now. 1360 pOutputParams->pEffects = NULL; 1361 // Set the audio effect; null for now. 1362 pOutputParams->bDiscardExif = M4OSA_FALSE; 1363 // Set the audio effect; null for now. 1364 pOutputParams->bAdjustOrientation = M4OSA_FALSE; 1365 1366 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_setOutputParams()"); 1367 result = M4MCS_setOutputParams(mcsContext, pOutputParams); 1368 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1369 (M4NO_ERROR != result), result); 1370 if (needToBeLoaded == false) { 1371 free(pTemp3gpFilePath); 1372 pTemp3gpFilePath = M4OSA_NULL; 1373 M4MCS_abort(mcsContext); 1374 free(pOutputParams); 1375 pOutputParams = M4OSA_NULL; 1376 free(pEncodingParams); 1377 pEncodingParams = M4OSA_NULL; 1378 return result; 1379 } 1380 // Set the video bitrate. 1381 pEncodingParams->OutputVideoBitrate = 1382 (M4VIDEOEDITING_Bitrate)M4VIDEOEDITING_kUndefinedBitrate; 1383 // Set the audio bitrate. 1384 pEncodingParams->OutputAudioBitrate 1385 = (M4VIDEOEDITING_Bitrate)M4VIDEOEDITING_k128_KBPS; 1386 // Set the end cut time in milliseconds. 1387 pEncodingParams->BeginCutTime = 0; 1388 // Set the end cut time in milliseconds. 1389 pEncodingParams->EndCutTime = 0; 1390 // Set the output file size in bytes. 1391 pEncodingParams->OutputFileSize = 0; 1392 // Set video time scale. 1393 pEncodingParams->OutputVideoTimescale = 0; 1394 1395 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 1396 "M4MCS_setEncodingParams()"); 1397 result = M4MCS_setEncodingParams(mcsContext, pEncodingParams); 1398 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1399 (M4NO_ERROR != result), result); 1400 if (needToBeLoaded == false) { 1401 free(pTemp3gpFilePath); 1402 pTemp3gpFilePath = M4OSA_NULL; 1403 M4MCS_abort(mcsContext); 1404 free(pOutputParams); 1405 pOutputParams = M4OSA_NULL; 1406 free(pEncodingParams); 1407 pEncodingParams = M4OSA_NULL; 1408 return result; 1409 } 1410 1411 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 1412 "M4MCS_checkParamsAndStart()"); 1413 result = M4MCS_checkParamsAndStart(mcsContext); 1414 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1415 (M4NO_ERROR != result), result); 1416 if (needToBeLoaded == false) { 1417 free(pTemp3gpFilePath); 1418 pTemp3gpFilePath = M4OSA_NULL; 1419 M4MCS_abort(mcsContext); 1420 free(pOutputParams); 1421 pOutputParams = M4OSA_NULL; 1422 free(pEncodingParams); 1423 pEncodingParams = M4OSA_NULL; 1424 return result; 1425 } 1426 1427 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_step()"); 1428 1429 /*+ PROGRESS CB */ 1430 M4OSA_UInt8 curProgress = 0; 1431 int lastProgress = 0; 1432 1433 ALOGV("LVME_generateAudio Current progress is =%d", curProgress); 1434 pEnv->CallVoidMethod(pContext->engine, 1435 pContext->onProgressUpdateMethodId, 1/*task status*/, 1436 curProgress/*progress*/); 1437 do { 1438 result = M4MCS_step(mcsContext, &curProgress); 1439 1440 if (result != M4NO_ERROR) { 1441 ALOGV("LVME_generateAudio M4MCS_step returned 0x%x",result); 1442 1443 if (result == M4MCS_WAR_TRANSCODING_DONE) { 1444 ALOGV("LVME_generateAudio MCS process ended"); 1445 1446 // Send a progress notification. 1447 curProgress = 100; 1448 pEnv->CallVoidMethod(pContext->engine, 1449 pContext->onProgressUpdateMethodId, 1/*task status*/, 1450 curProgress); 1451 ALOGV("LVME_generateAudio Current progress is =%d", curProgress); 1452 } 1453 } else { 1454 // Send a progress notification if needed 1455 if (curProgress != lastProgress) { 1456 lastProgress = curProgress; 1457 pEnv->CallVoidMethod(pContext->engine, 1458 pContext->onProgressUpdateMethodId, 0/*task status*/, 1459 curProgress/*progress*/); 1460 ALOGV("LVME_generateAudio Current progress is =%d",curProgress); 1461 } 1462 } 1463 } while (result == M4NO_ERROR); 1464 /*- PROGRESS CB */ 1465 1466 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1467 (M4MCS_WAR_TRANSCODING_DONE != result), result); 1468 if (needToBeLoaded == false) { 1469 free(pTemp3gpFilePath); 1470 pTemp3gpFilePath = M4OSA_NULL; 1471 M4MCS_abort(mcsContext); 1472 free(pOutputParams); 1473 pOutputParams = M4OSA_NULL; 1474 free(pEncodingParams); 1475 pEncodingParams = M4OSA_NULL; 1476 return result; 1477 } 1478 1479 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_abort()"); 1480 result = M4MCS_abort(mcsContext); 1481 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1482 (M4NO_ERROR != result), result); 1483 1484 //pContext->mAudioSettings->pFile = pOutputParams->pOutputPCMfile; 1485 remove((const char *) pTemp3gpFilePath); 1486 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_generateAudio() EXIT "); 1487 1488 if (pTemp3gpFilePath != M4OSA_NULL) { 1489 free(pTemp3gpFilePath); 1490 } 1491 if (pOutputParams != M4OSA_NULL) { 1492 free(pOutputParams); 1493 } 1494 if(pEncodingParams != M4OSA_NULL) { 1495 free(pEncodingParams); 1496 } 1497 return result; 1498 } 1499 1500 static int removeAlphafromRGB8888 ( 1501 M4OSA_Char* pFramingFilePath, 1502 M4xVSS_FramingStruct *pFramingCtx) 1503 { 1504 M4OSA_UInt32 frameSize_argb = (pFramingCtx->width * pFramingCtx->height * 4); // aRGB data 1505 M4OSA_Context lImageFileFp = M4OSA_NULL; 1506 M4OSA_ERR err = M4NO_ERROR; 1507 1508 ALOGV("removeAlphafromRGB8888: width %d", pFramingCtx->width); 1509 1510 M4OSA_UInt8 *pTmpData = (M4OSA_UInt8*) M4OSA_32bitAlignedMalloc(frameSize_argb, M4VS, (M4OSA_Char*)"Image argb data"); 1511 if (pTmpData == M4OSA_NULL) { 1512 ALOGE("Failed to allocate memory for Image clip"); 1513 return M4ERR_ALLOC; 1514 } 1515 1516 /** Read the argb data from the passed file. */ 1517 M4OSA_ERR lerr = M4OSA_fileReadOpen(&lImageFileFp, (M4OSA_Void *) pFramingFilePath, M4OSA_kFileRead); 1518 1519 1520 if ((lerr != M4NO_ERROR) || (lImageFileFp == M4OSA_NULL)) 1521 { 1522 ALOGE("removeAlphafromRGB8888: Can not open the file "); 1523 free(pTmpData); 1524 return M4ERR_FILE_NOT_FOUND; 1525 } 1526 1527 1528 lerr = M4OSA_fileReadData(lImageFileFp, (M4OSA_MemAddr8)pTmpData, &frameSize_argb); 1529 if (lerr != M4NO_ERROR) 1530 { 1531 ALOGE("removeAlphafromRGB8888: can not read the data "); 1532 M4OSA_fileReadClose(lImageFileFp); 1533 free(pTmpData); 1534 return lerr; 1535 } 1536 M4OSA_fileReadClose(lImageFileFp); 1537 1538 M4OSA_UInt32 frameSize = (pFramingCtx->width * pFramingCtx->height * 3); //Size of RGB 888 data. 1539 1540 pFramingCtx->FramingRgb = (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc( 1541 sizeof(M4VIFI_ImagePlane), M4VS, (M4OSA_Char*)"Image clip RGB888 data"); 1542 pFramingCtx->FramingRgb->pac_data = (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc( 1543 frameSize, M4VS, (M4OSA_Char*)"Image clip RGB888 data"); 1544 1545 if (pFramingCtx->FramingRgb == M4OSA_NULL) 1546 { 1547 ALOGE("Failed to allocate memory for Image clip"); 1548 free(pTmpData); 1549 return M4ERR_ALLOC; 1550 } 1551 1552 /** Remove the alpha channel */ 1553 for (size_t i = 0, j = 0; i < frameSize_argb; i++) { 1554 if ((i % 4) == 0) continue; 1555 pFramingCtx->FramingRgb->pac_data[j] = pTmpData[i]; 1556 j++; 1557 } 1558 free(pTmpData); 1559 return M4NO_ERROR; 1560 } 1561 1562 static void 1563 videoEditor_populateSettings( 1564 JNIEnv* pEnv, 1565 jobject thiz, 1566 jobject settings, 1567 jobject object, 1568 jobject audioSettingObject) 1569 { 1570 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 1571 "videoEditor_populateSettings()"); 1572 1573 bool needToBeLoaded = true; 1574 ManualEditContext* pContext = M4OSA_NULL; 1575 M4OSA_ERR result = M4NO_ERROR; 1576 jstring strPath = M4OSA_NULL; 1577 jstring strPCMPath = M4OSA_NULL; 1578 jobjectArray propertiesClipsArray = M4OSA_NULL; 1579 jobject properties = M4OSA_NULL; 1580 jint* bitmapArray = M4OSA_NULL; 1581 jobjectArray effectSettingsArray = M4OSA_NULL; 1582 jobject effectSettings = M4OSA_NULL; 1583 jintArray pixelArray = M4OSA_NULL; 1584 int width = 0; 1585 int height = 0; 1586 int nbOverlays = 0; 1587 int i,j = 0; 1588 int *pOverlayIndex = M4OSA_NULL; 1589 M4OSA_Char* pTempChar = M4OSA_NULL; 1590 1591 // Add a code marker (the condition must always be true). 1592 ADD_CODE_MARKER_FUN(NULL != pEnv) 1593 1594 // Validate the settings parameter. 1595 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, 1596 (NULL == settings), 1597 "settings is null"); 1598 // Get the context. 1599 pContext = 1600 (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); 1601 1602 // Make sure that the context was set. 1603 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1604 (M4OSA_NULL == pContext), 1605 "not initialized"); 1606 // Make sure that the context was set. 1607 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1608 (M4OSA_NULL == pContext->mPreviewController), 1609 "not initialized"); 1610 jclass mPreviewClipPropClazz = pEnv->FindClass(PREVIEW_PROPERTIES_CLASS_NAME); 1611 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1612 (M4OSA_NULL == mPreviewClipPropClazz), 1613 "not initialized"); 1614 1615 jfieldID fid = pEnv->GetFieldID(mPreviewClipPropClazz,"clipProperties", 1616 "[L"PROPERTIES_CLASS_NAME";" ); 1617 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1618 (M4OSA_NULL == fid), 1619 "not initialized"); 1620 1621 propertiesClipsArray = (jobjectArray)pEnv->GetObjectField(object, fid); 1622 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1623 (M4OSA_NULL == propertiesClipsArray), 1624 "not initialized"); 1625 1626 jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME); 1627 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1628 (M4OSA_NULL == engineClass), 1629 "not initialized"); 1630 1631 pContext->onPreviewProgressUpdateMethodId = pEnv->GetMethodID(engineClass, 1632 "onPreviewProgressUpdate", "(IZZLjava/lang/String;II)V"); 1633 // Check if the context is valid (required because the context is dereferenced). 1634 if (needToBeLoaded) { 1635 // Make sure that we are in a correct state. 1636 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1637 (pContext->state != ManualEditState_INITIALIZED), 1638 "settings already loaded"); 1639 if (needToBeLoaded) { 1640 // Retrieve the edit settings. 1641 if (pContext->pEditSettings != M4OSA_NULL) { 1642 videoEditClasses_freeEditSettings(&pContext->pEditSettings); 1643 pContext->pEditSettings = M4OSA_NULL; 1644 } 1645 videoEditClasses_getEditSettings(&needToBeLoaded, pEnv, 1646 settings, &pContext->pEditSettings,false); 1647 } 1648 } 1649 1650 if (needToBeLoaded == false) { 1651 j = 0; 1652 while (j < pContext->pEditSettings->nbEffects) 1653 { 1654 if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL) { 1655 if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer != M4OSA_NULL) { 1656 free(pContext->pEditSettings->\ 1657 Effects[j].xVSS.pFramingBuffer); 1658 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer = M4OSA_NULL; 1659 } 1660 } 1661 j++; 1662 } 1663 return; 1664 } 1665 1666 M4OSA_TRACE1_0("videoEditorC_getEditSettings done"); 1667 1668 pContext->previewFrameEditInfoId = pEnv->GetMethodID(engineClass, 1669 "previewFrameEditInfo", "(Ljava/lang/String;I)V"); 1670 1671 if ( pContext->pEditSettings != NULL ) 1672 { 1673 // Check if the edit settings could be retrieved. 1674 jclass mEditClazz = pEnv->FindClass(EDIT_SETTINGS_CLASS_NAME); 1675 if(mEditClazz == M4OSA_NULL) 1676 { 1677 M4OSA_TRACE1_0("cannot find object field for mEditClazz"); 1678 goto videoEditor_populateSettings_cleanup; 1679 } 1680 jclass mEffectsClazz = pEnv->FindClass(EFFECT_SETTINGS_CLASS_NAME); 1681 if(mEffectsClazz == M4OSA_NULL) 1682 { 1683 M4OSA_TRACE1_0("cannot find object field for mEffectsClazz"); 1684 goto videoEditor_populateSettings_cleanup; 1685 } 1686 fid = pEnv->GetFieldID(mEditClazz,"effectSettingsArray", "[L"EFFECT_SETTINGS_CLASS_NAME";" ); 1687 if(fid == M4OSA_NULL) 1688 { 1689 M4OSA_TRACE1_0("cannot find field for effectSettingsArray Array"); 1690 goto videoEditor_populateSettings_cleanup; 1691 } 1692 effectSettingsArray = (jobjectArray)pEnv->GetObjectField(settings, fid); 1693 if(effectSettingsArray == M4OSA_NULL) 1694 { 1695 M4OSA_TRACE1_0("cannot find object field for effectSettingsArray"); 1696 goto videoEditor_populateSettings_cleanup; 1697 } 1698 1699 //int overlayIndex[pContext->pEditSettings->nbEffects]; 1700 if (pContext->pEditSettings->nbEffects > 0) 1701 { 1702 pOverlayIndex 1703 = (int*) M4OSA_32bitAlignedMalloc(pContext->pEditSettings->nbEffects * sizeof(int), 0, 1704 (M4OSA_Char*)"pOverlayIndex"); 1705 if (pOverlayIndex == M4OSA_NULL) { 1706 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1707 M4OSA_TRUE, M4ERR_ALLOC); 1708 goto videoEditor_populateSettings_cleanup; 1709 } 1710 } 1711 1712 i = 0; 1713 j = 0; 1714 M4OSA_TRACE1_1("no of effects = %d",pContext->pEditSettings->nbEffects); 1715 while (j < pContext->pEditSettings->nbEffects) 1716 { 1717 if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL) 1718 { 1719 pOverlayIndex[nbOverlays] = j; 1720 1721 M4xVSS_FramingStruct *aFramingCtx = M4OSA_NULL; 1722 aFramingCtx 1723 = (M4xVSS_FramingStruct*)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct), M4VS, 1724 (M4OSA_Char*)"M4xVSS_internalDecodeGIF: Context of the framing effect"); 1725 if (aFramingCtx == M4OSA_NULL) 1726 { 1727 M4OSA_TRACE1_0("Allocation error in videoEditor_populateSettings"); 1728 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1729 M4OSA_TRUE, M4ERR_ALLOC); 1730 goto videoEditor_populateSettings_cleanup; 1731 } 1732 1733 aFramingCtx->pCurrent = M4OSA_NULL; /* Only used by the first element of the chain */ 1734 aFramingCtx->previousClipTime = -1; 1735 aFramingCtx->FramingYuv = M4OSA_NULL; 1736 aFramingCtx->FramingRgb = M4OSA_NULL; 1737 aFramingCtx->topleft_x 1738 = pContext->pEditSettings->Effects[j].xVSS.topleft_x; 1739 aFramingCtx->topleft_y 1740 = pContext->pEditSettings->Effects[j].xVSS.topleft_y; 1741 1742 1743 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF u_width %d", 1744 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width); 1745 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF u_height() %d", 1746 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height); 1747 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF rgbType() %d", 1748 pContext->pEditSettings->Effects[j].xVSS.rgbType); 1749 1750 aFramingCtx->width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width; 1751 aFramingCtx->height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height; 1752 1753 result = M4xVSS_internalConvertARGB888toYUV420_FrammingEffect(pContext->engineContext, 1754 &(pContext->pEditSettings->Effects[j]),aFramingCtx, 1755 pContext->pEditSettings->Effects[j].xVSS.framingScaledSize); 1756 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1757 (M4NO_ERROR != result), result); 1758 if (needToBeLoaded == false) { 1759 M4OSA_TRACE1_1("M4xVSS_internalConvertARGB888toYUV420_FrammingEffect returned 0x%x", result); 1760 if (aFramingCtx != M4OSA_NULL) { 1761 free(aFramingCtx); 1762 aFramingCtx = M4OSA_NULL; 1763 } 1764 goto videoEditor_populateSettings_cleanup; 1765 } 1766 1767 //framing buffers are resized to fit the output video resolution. 1768 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width = 1769 aFramingCtx->FramingRgb->u_width; 1770 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height = 1771 aFramingCtx->FramingRgb->u_height; 1772 1773 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "A framing Context aFramingCtx->width = %d", 1774 aFramingCtx->FramingRgb->u_width); 1775 1776 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "A framing Context aFramingCtx->height = %d", 1777 aFramingCtx->FramingRgb->u_height); 1778 1779 1780 width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width; 1781 height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height; 1782 1783 //RGB 565 1784 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_stride = width * 2; 1785 1786 //for RGB565 1787 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_topleft = 0; 1788 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->pac_data = 1789 (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(width*height*2, 1790 0x00,(M4OSA_Char *)"pac_data buffer"); 1791 1792 if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->pac_data == M4OSA_NULL) { 1793 M4OSA_TRACE1_0("Failed to allocate memory for framing buffer"); 1794 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1795 M4OSA_TRUE, M4ERR_ALLOC); 1796 goto videoEditor_populateSettings_cleanup; 1797 } 1798 1799 memcpy((void *)&pContext->pEditSettings->\ 1800 Effects[j].xVSS.pFramingBuffer->\ 1801 pac_data[0],(void *)&aFramingCtx->FramingRgb->pac_data[0],(width*height*2)); 1802 1803 //As of now rgb type is 565 1804 pContext->pEditSettings->Effects[j].xVSS.rgbType = 1805 (M4VSS3GPP_RGBType) M4VSS3GPP_kRGB565; 1806 1807 if (aFramingCtx->FramingYuv != M4OSA_NULL ) 1808 { 1809 if (aFramingCtx->FramingYuv[0].pac_data != M4OSA_NULL) { 1810 free(aFramingCtx->FramingYuv[0].pac_data); 1811 aFramingCtx->FramingYuv[0].pac_data = M4OSA_NULL; 1812 } 1813 if (aFramingCtx->FramingYuv[1].pac_data != M4OSA_NULL) { 1814 free(aFramingCtx->FramingYuv[1].pac_data); 1815 aFramingCtx->FramingYuv[1].pac_data = M4OSA_NULL; 1816 } 1817 if (aFramingCtx->FramingYuv[2].pac_data != M4OSA_NULL) { 1818 free(aFramingCtx->FramingYuv[2].pac_data); 1819 aFramingCtx->FramingYuv[2].pac_data = M4OSA_NULL; 1820 } 1821 1822 free(aFramingCtx->FramingYuv); 1823 aFramingCtx->FramingYuv = M4OSA_NULL; 1824 } 1825 if (aFramingCtx->FramingRgb->pac_data != M4OSA_NULL) { 1826 free(aFramingCtx->FramingRgb->pac_data); 1827 aFramingCtx->FramingRgb->pac_data = M4OSA_NULL; 1828 } 1829 if (aFramingCtx->FramingRgb != M4OSA_NULL) { 1830 free(aFramingCtx->FramingRgb); 1831 aFramingCtx->FramingRgb = M4OSA_NULL; 1832 } 1833 if (aFramingCtx != M4OSA_NULL) { 1834 free(aFramingCtx); 1835 aFramingCtx = M4OSA_NULL; 1836 } 1837 nbOverlays++; 1838 } 1839 j++; 1840 } 1841 1842 // Check if the edit settings could be retrieved. 1843 M4OSA_TRACE1_1("total clips are = %d",pContext->pEditSettings->uiClipNumber); 1844 for (i = 0; i < pContext->pEditSettings->uiClipNumber; i++) { 1845 M4OSA_TRACE1_1("clip no = %d",i); 1846 properties = pEnv->GetObjectArrayElement(propertiesClipsArray, i); 1847 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1848 (M4OSA_NULL == properties), 1849 "not initialized"); 1850 if (needToBeLoaded) { 1851 getClipSetting(pEnv,properties, pContext->pEditSettings->pClipList[i]); 1852 } else { 1853 goto videoEditor_populateSettings_cleanup; 1854 } 1855 } 1856 1857 if (needToBeLoaded) { 1858 // Log the edit settings. 1859 VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings); 1860 } 1861 } 1862 /* free previous allocations , if any */ 1863 if (pContext->mAudioSettings != M4OSA_NULL) { 1864 if (pContext->mAudioSettings->pFile != NULL) { 1865 free(pContext->mAudioSettings->pFile); 1866 pContext->mAudioSettings->pFile = M4OSA_NULL; 1867 } 1868 if (pContext->mAudioSettings->pPCMFilePath != NULL) { 1869 free(pContext->mAudioSettings->pPCMFilePath); 1870 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL; 1871 } 1872 } 1873 1874 if (audioSettingObject != M4OSA_NULL) { 1875 jclass audioSettingClazz = pEnv->FindClass(AUDIO_SETTINGS_CLASS_NAME); 1876 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1877 (M4OSA_NULL == audioSettingClazz), 1878 "not initialized"); 1879 1880 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 1881 (M4OSA_NULL == pContext->mAudioSettings), 1882 "not initialized"); 1883 1884 if (needToBeLoaded == false) { 1885 goto videoEditor_populateSettings_cleanup; 1886 } 1887 1888 fid = pEnv->GetFieldID(audioSettingClazz,"bRemoveOriginal","Z"); 1889 pContext->mAudioSettings->bRemoveOriginal = 1890 pEnv->GetBooleanField(audioSettingObject,fid); 1891 M4OSA_TRACE1_1("bRemoveOriginal = %d",pContext->mAudioSettings->bRemoveOriginal); 1892 1893 fid = pEnv->GetFieldID(audioSettingClazz,"channels","I"); 1894 pContext->mAudioSettings->uiNbChannels = pEnv->GetIntField(audioSettingObject,fid); 1895 M4OSA_TRACE1_1("uiNbChannels = %d",pContext->mAudioSettings->uiNbChannels); 1896 1897 fid = pEnv->GetFieldID(audioSettingClazz,"Fs","I"); 1898 pContext->mAudioSettings->uiSamplingFrequency = pEnv->GetIntField(audioSettingObject,fid); 1899 M4OSA_TRACE1_1("uiSamplingFrequency = %d",pContext->mAudioSettings->uiSamplingFrequency); 1900 1901 fid = pEnv->GetFieldID(audioSettingClazz,"ExtendedFs","I"); 1902 pContext->mAudioSettings->uiExtendedSamplingFrequency = 1903 pEnv->GetIntField(audioSettingObject,fid); 1904 M4OSA_TRACE1_1("uiExtendedSamplingFrequency = %d", 1905 pContext->mAudioSettings->uiExtendedSamplingFrequency); 1906 1907 fid = pEnv->GetFieldID(audioSettingClazz,"startMs","J"); 1908 pContext->mAudioSettings->uiAddCts 1909 = pEnv->GetLongField(audioSettingObject,fid); 1910 M4OSA_TRACE1_1("uiAddCts = %d",pContext->mAudioSettings->uiAddCts); 1911 1912 fid = pEnv->GetFieldID(audioSettingClazz,"volume","I"); 1913 pContext->mAudioSettings->uiAddVolume 1914 = pEnv->GetIntField(audioSettingObject,fid); 1915 M4OSA_TRACE1_1("uiAddVolume = %d",pContext->mAudioSettings->uiAddVolume); 1916 1917 fid = pEnv->GetFieldID(audioSettingClazz,"loop","Z"); 1918 pContext->mAudioSettings->bLoop 1919 = pEnv->GetBooleanField(audioSettingObject,fid); 1920 M4OSA_TRACE1_1("bLoop = %d",pContext->mAudioSettings->bLoop); 1921 1922 fid = pEnv->GetFieldID(audioSettingClazz,"beginCutTime","J"); 1923 pContext->mAudioSettings->beginCutMs 1924 = pEnv->GetLongField(audioSettingObject,fid); 1925 M4OSA_TRACE1_1("begin cut time = %d",pContext->mAudioSettings->beginCutMs); 1926 1927 fid = pEnv->GetFieldID(audioSettingClazz,"endCutTime","J"); 1928 pContext->mAudioSettings->endCutMs 1929 = pEnv->GetLongField(audioSettingObject,fid); 1930 M4OSA_TRACE1_1("end cut time = %d",pContext->mAudioSettings->endCutMs); 1931 1932 fid = pEnv->GetFieldID(audioSettingClazz,"fileType","I"); 1933 pContext->mAudioSettings->fileType 1934 = pEnv->GetIntField(audioSettingObject,fid); 1935 M4OSA_TRACE1_1("fileType = %d",pContext->mAudioSettings->fileType); 1936 1937 fid = pEnv->GetFieldID(audioSettingClazz,"pFile","Ljava/lang/String;"); 1938 strPath = (jstring)pEnv->GetObjectField(audioSettingObject,fid); 1939 pTempChar = (M4OSA_Char*)pEnv->GetStringUTFChars(strPath, M4OSA_NULL); 1940 if (pTempChar != NULL) { 1941 pContext->mAudioSettings->pFile = (M4OSA_Char*) M4OSA_32bitAlignedMalloc( 1942 (M4OSA_UInt32)(strlen((const char*)pTempChar))+1 /* +1 for NULL termination */, 0, 1943 (M4OSA_Char*)"strPath allocation " ); 1944 if (pContext->mAudioSettings->pFile != M4OSA_NULL) { 1945 memcpy((void *)pContext->mAudioSettings->pFile , 1946 (void *)pTempChar , strlen((const char*)pTempChar)); 1947 ((M4OSA_Int8 *)(pContext->mAudioSettings->pFile))[strlen((const char*)pTempChar)] = '\0'; 1948 pEnv->ReleaseStringUTFChars(strPath,(const char *)pTempChar); 1949 } else { 1950 pEnv->ReleaseStringUTFChars(strPath,(const char *)pTempChar); 1951 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", 1952 "regenerateAudio() Malloc failed for pContext->mAudioSettings->pFile "); 1953 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1954 M4OSA_TRUE, M4ERR_ALLOC); 1955 goto videoEditor_populateSettings_cleanup; 1956 } 1957 } 1958 M4OSA_TRACE1_1("file name = %s",pContext->mAudioSettings->pFile); 1959 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio() file name = %s",\ 1960 pContext->mAudioSettings->pFile); 1961 1962 fid = pEnv->GetFieldID(audioSettingClazz,"pcmFilePath","Ljava/lang/String;"); 1963 strPCMPath = (jstring)pEnv->GetObjectField(audioSettingObject,fid); 1964 pTempChar = (M4OSA_Char*)pEnv->GetStringUTFChars(strPCMPath, M4OSA_NULL); 1965 if (pTempChar != NULL) { 1966 pContext->mAudioSettings->pPCMFilePath = (M4OSA_Char*) M4OSA_32bitAlignedMalloc( 1967 (M4OSA_UInt32)(strlen((const char*)pTempChar))+1 /* +1 for NULL termination */, 0, 1968 (M4OSA_Char*)"strPCMPath allocation " ); 1969 if (pContext->mAudioSettings->pPCMFilePath != M4OSA_NULL) { 1970 memcpy((void *)pContext->mAudioSettings->pPCMFilePath , 1971 (void *)pTempChar , strlen((const char*)pTempChar)); 1972 ((M4OSA_Int8 *)(pContext->mAudioSettings->pPCMFilePath))[strlen((const char*)pTempChar)] = '\0'; 1973 pEnv->ReleaseStringUTFChars(strPCMPath,(const char *)pTempChar); 1974 } else { 1975 pEnv->ReleaseStringUTFChars(strPCMPath,(const char *)pTempChar); 1976 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", 1977 "regenerateAudio() Malloc failed for pContext->mAudioSettings->pPCMFilePath "); 1978 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 1979 M4OSA_TRUE, M4ERR_ALLOC); 1980 goto videoEditor_populateSettings_cleanup; 1981 } 1982 } 1983 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "pPCMFilePath -- %s ",\ 1984 pContext->mAudioSettings->pPCMFilePath); 1985 1986 fid = pEnv->GetFieldID(engineClass,"mRegenerateAudio","Z"); 1987 bool regenerateAudio = pEnv->GetBooleanField(thiz,fid); 1988 1989 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio -- %d ",\ 1990 regenerateAudio); 1991 1992 if (regenerateAudio) { 1993 M4OSA_TRACE1_0("Calling Generate Audio now"); 1994 result = videoEditor_generateAudio(pEnv, 1995 pContext, 1996 (M4OSA_Char*)pContext->mAudioSettings->pFile, 1997 (M4OSA_Char*)pContext->mAudioSettings->pPCMFilePath); 1998 1999 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 2000 (M4NO_ERROR != result), result); 2001 if (needToBeLoaded == false) { 2002 goto videoEditor_populateSettings_cleanup; 2003 } 2004 2005 regenerateAudio = false; 2006 pEnv->SetBooleanField(thiz,fid,regenerateAudio); 2007 } 2008 2009 /* Audio mix and duck */ 2010 fid = pEnv->GetFieldID(audioSettingClazz,"ducking_threshold","I"); 2011 pContext->mAudioSettings->uiInDucking_threshold 2012 = pEnv->GetIntField(audioSettingObject,fid); 2013 2014 M4OSA_TRACE1_1("ducking threshold = %d", 2015 pContext->mAudioSettings->uiInDucking_threshold); 2016 2017 fid = pEnv->GetFieldID(audioSettingClazz,"ducking_lowVolume","I"); 2018 pContext->mAudioSettings->uiInDucking_lowVolume 2019 = pEnv->GetIntField(audioSettingObject,fid); 2020 2021 M4OSA_TRACE1_1("ducking lowVolume = %d", 2022 pContext->mAudioSettings->uiInDucking_lowVolume); 2023 2024 fid = pEnv->GetFieldID(audioSettingClazz,"bInDucking_enable","Z"); 2025 pContext->mAudioSettings->bInDucking_enable 2026 = pEnv->GetBooleanField(audioSettingObject,fid); 2027 M4OSA_TRACE1_1("ducking lowVolume = %d", 2028 pContext->mAudioSettings->bInDucking_enable); 2029 2030 } else { 2031 if (pContext->mAudioSettings != M4OSA_NULL) { 2032 pContext->mAudioSettings->pFile = M4OSA_NULL; 2033 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL; 2034 pContext->mAudioSettings->bRemoveOriginal = 0; 2035 pContext->mAudioSettings->uiNbChannels = 0; 2036 pContext->mAudioSettings->uiSamplingFrequency = 0; 2037 pContext->mAudioSettings->uiExtendedSamplingFrequency = 0; 2038 pContext->mAudioSettings->uiAddCts = 0; 2039 pContext->mAudioSettings->uiAddVolume = 0; 2040 pContext->mAudioSettings->beginCutMs = 0; 2041 pContext->mAudioSettings->endCutMs = 0; 2042 pContext->mAudioSettings->fileType = 0; 2043 pContext->mAudioSettings->bLoop = 0; 2044 pContext->mAudioSettings->uiInDucking_lowVolume = 0; 2045 pContext->mAudioSettings->bInDucking_enable = 0; 2046 pContext->mAudioSettings->uiBTChannelCount = 0; 2047 pContext->mAudioSettings->uiInDucking_threshold = 0; 2048 2049 fid = pEnv->GetFieldID(engineClass,"mRegenerateAudio","Z"); 2050 bool regenerateAudio = pEnv->GetBooleanField(thiz,fid); 2051 if (!regenerateAudio) { 2052 regenerateAudio = true; 2053 pEnv->SetBooleanField(thiz,fid,regenerateAudio); 2054 } 2055 } 2056 } 2057 2058 if (pContext->pEditSettings != NULL) 2059 { 2060 result = pContext->mPreviewController->loadEditSettings(pContext->pEditSettings, 2061 pContext->mAudioSettings); 2062 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 2063 (M4NO_ERROR != result), result); 2064 2065 if (needToBeLoaded) { 2066 pContext->mPreviewController->setJniCallback((void*)pContext, 2067 (jni_progress_callback_fct)jniPreviewProgressCallback); 2068 } 2069 } 2070 2071 videoEditor_populateSettings_cleanup: 2072 j = 0; 2073 while (j < nbOverlays) 2074 { 2075 if (pContext->pEditSettings->Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data != \ 2076 M4OSA_NULL) { 2077 free(pContext->pEditSettings->\ 2078 Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data); 2079 pContext->pEditSettings->\ 2080 Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data = M4OSA_NULL; 2081 } 2082 j++; 2083 } 2084 2085 j = 0; 2086 while (j < pContext->pEditSettings->nbEffects) 2087 { 2088 if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL) { 2089 if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer != M4OSA_NULL) { 2090 free(pContext->pEditSettings->\ 2091 Effects[j].xVSS.pFramingBuffer); 2092 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer = M4OSA_NULL; 2093 } 2094 } 2095 j++; 2096 } 2097 2098 if (pOverlayIndex != M4OSA_NULL) 2099 { 2100 free(pOverlayIndex); 2101 pOverlayIndex = M4OSA_NULL; 2102 } 2103 return; 2104 } 2105 2106 static void 2107 videoEditor_startPreview( 2108 JNIEnv* pEnv, 2109 jobject thiz, 2110 jobject mSurface, 2111 jlong fromMs, 2112 jlong toMs, 2113 jint callbackInterval, 2114 jboolean loop) 2115 { 2116 bool needToBeLoaded = true; 2117 M4OSA_ERR result = M4NO_ERROR; 2118 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_startPreview()"); 2119 2120 ManualEditContext* pContext = M4OSA_NULL; 2121 // Get the context. 2122 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); 2123 2124 // Make sure that the context was set. 2125 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2126 (M4OSA_NULL == pContext), 2127 "not initialized"); 2128 2129 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2130 (M4OSA_NULL == pContext->mAudioSettings), 2131 "not initialized"); 2132 // Make sure that the context was set. 2133 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2134 (M4OSA_NULL == pContext->mPreviewController), 2135 "not initialized"); 2136 2137 // Validate the mSurface parameter. 2138 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, 2139 (NULL == mSurface), 2140 "mSurface is null"); 2141 2142 jclass surfaceClass = pEnv->FindClass("android/view/Surface"); 2143 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2144 (M4OSA_NULL == surfaceClass), 2145 "not initialized"); 2146 //jfieldID surface_native = pEnv->GetFieldID(surfaceClass, "mSurface", "I"); 2147 jfieldID surface_native 2148 = pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); 2149 2150 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2151 (M4OSA_NULL == surface_native), 2152 "not initialized"); 2153 2154 Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); 2155 2156 sp<Surface> previewSurface = sp<Surface>(p); 2157 // Validate the mSurface's mNativeSurface field 2158 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2159 (NULL == previewSurface.get()), 2160 "mNativeSurface is null"); 2161 2162 result = pContext->mPreviewController->setSurface(previewSurface); 2163 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, 2164 (M4NO_ERROR != result), result); 2165 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "fromMs=%ld, toMs=%ld", 2166 (M4OSA_UInt32)fromMs, (M4OSA_Int32)toMs); 2167 2168 result = pContext->mPreviewController->startPreview((M4OSA_UInt32)fromMs, 2169 (M4OSA_Int32)toMs, 2170 (M4OSA_UInt16)callbackInterval, 2171 (M4OSA_Bool)loop); 2172 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, (M4NO_ERROR != result), result); 2173 } 2174 2175 2176 static jobject 2177 videoEditor_getProperties( 2178 JNIEnv* pEnv, 2179 jobject thiz, 2180 jstring file) 2181 { 2182 jobject object = M4OSA_NULL; 2183 jclass clazz = pEnv->FindClass(PROPERTIES_CLASS_NAME); 2184 jfieldID fid; 2185 bool needToBeLoaded = true; 2186 ManualEditContext* pContext = M4OSA_NULL; 2187 M4OSA_ERR result = M4NO_ERROR; 2188 int profile = 0; 2189 int level = 0; 2190 int videoFormat = 0; 2191 2192 // Get the context. 2193 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); 2194 2195 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2196 (M4OSA_NULL == clazz), 2197 "not initialized"); 2198 2199 object = videoEditProp_getProperties(pEnv,thiz,file); 2200 2201 if (object != M4OSA_NULL) { 2202 fid = pEnv->GetFieldID(clazz,"profile","I"); 2203 profile = pEnv->GetIntField(object,fid); 2204 fid = pEnv->GetFieldID(clazz,"level","I"); 2205 level = pEnv->GetIntField(object,fid); 2206 fid = pEnv->GetFieldID(clazz,"videoFormat","I"); 2207 videoFormat = pEnv->GetIntField(object,fid); 2208 2209 result = checkClipVideoProfileAndLevel(pContext->decoders, videoFormat, profile, level); 2210 2211 fid = pEnv->GetFieldID(clazz,"profileSupported","Z"); 2212 if (M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE == result) { 2213 pEnv->SetBooleanField(object,fid,false); 2214 } 2215 2216 fid = pEnv->GetFieldID(clazz,"levelSupported","Z"); 2217 if (M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_LEVEL == result) { 2218 pEnv->SetBooleanField(object,fid,false); 2219 } 2220 } 2221 return object; 2222 2223 } 2224 static int videoEditor_getPixels( 2225 JNIEnv* env, 2226 jobject thiz, 2227 jstring path, 2228 jintArray pixelArray, 2229 M4OSA_UInt32 width, 2230 M4OSA_UInt32 height, 2231 M4OSA_UInt32 timeMS) 2232 { 2233 2234 M4OSA_ERR err = M4NO_ERROR; 2235 M4OSA_Context mContext = M4OSA_NULL; 2236 jint* m_dst32 = M4OSA_NULL; 2237 2238 2239 // Add a text marker (the condition must always be true). 2240 ADD_TEXT_MARKER_FUN(NULL != env) 2241 2242 const char *pString = env->GetStringUTFChars(path, NULL); 2243 if (pString == M4OSA_NULL) { 2244 if (env != NULL) { 2245 jniThrowException(env, "java/lang/RuntimeException", "Input string null"); 2246 } 2247 return M4ERR_ALLOC; 2248 } 2249 2250 err = ThumbnailOpen(&mContext,(const M4OSA_Char*)pString, M4OSA_FALSE); 2251 if (err != M4NO_ERROR || mContext == M4OSA_NULL) { 2252 if (pString != NULL) { 2253 env->ReleaseStringUTFChars(path, pString); 2254 } 2255 if (env != NULL) { 2256 jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed"); 2257 } 2258 } 2259 2260 m_dst32 = env->GetIntArrayElements(pixelArray, NULL); 2261 2262 err = ThumbnailGetPixels32(mContext, (M4OSA_Int32 *)m_dst32, width,height,&timeMS,0); 2263 if (err != M4NO_ERROR ) { 2264 if (env != NULL) { 2265 jniThrowException(env, "java/lang/RuntimeException",\ 2266 "ThumbnailGetPixels32 failed"); 2267 } 2268 } 2269 env->ReleaseIntArrayElements(pixelArray, m_dst32, 0); 2270 2271 ThumbnailClose(mContext); 2272 if (pString != NULL) { 2273 env->ReleaseStringUTFChars(path, pString); 2274 } 2275 2276 return timeMS; 2277 } 2278 2279 static int videoEditor_getPixelsList( 2280 JNIEnv* env, 2281 jobject thiz, 2282 jstring path, 2283 jintArray pixelArray, 2284 M4OSA_UInt32 width, 2285 M4OSA_UInt32 height, 2286 M4OSA_UInt32 noOfThumbnails, 2287 jlong startTime, 2288 jlong endTime, 2289 jintArray indexArray, 2290 jobject callback) 2291 { 2292 2293 M4OSA_ERR err = M4NO_ERROR; 2294 M4OSA_Context mContext = M4OSA_NULL; 2295 2296 const char *pString = env->GetStringUTFChars(path, NULL); 2297 if (pString == M4OSA_NULL) { 2298 jniThrowException(env, "java/lang/RuntimeException", "Input string null"); 2299 return M4ERR_ALLOC; 2300 } 2301 2302 err = ThumbnailOpen(&mContext,(const M4OSA_Char*)pString, M4OSA_FALSE); 2303 if (err != M4NO_ERROR || mContext == M4OSA_NULL) { 2304 jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed"); 2305 if (pString != NULL) { 2306 env->ReleaseStringUTFChars(path, pString); 2307 } 2308 return err; 2309 } 2310 2311 jlong duration = (endTime - startTime); 2312 M4OSA_UInt32 tolerance = duration / (2 * noOfThumbnails); 2313 jint* m_dst32 = env->GetIntArrayElements(pixelArray, NULL); 2314 jint* indices = env->GetIntArrayElements(indexArray, NULL); 2315 jsize len = env->GetArrayLength(indexArray); 2316 2317 jclass cls = env->GetObjectClass(callback); 2318 jmethodID mid = env->GetMethodID(cls, "onThumbnail", "(I)V"); 2319 2320 for (int i = 0; i < len; i++) { 2321 int k = indices[i]; 2322 M4OSA_UInt32 timeMS = startTime; 2323 timeMS += (2 * k + 1) * duration / (2 * noOfThumbnails); 2324 err = ThumbnailGetPixels32(mContext, ((M4OSA_Int32 *)m_dst32), 2325 width, height, &timeMS, tolerance); 2326 if (err != M4NO_ERROR) { 2327 break; 2328 } 2329 env->CallVoidMethod(callback, mid, (jint)k); 2330 if (env->ExceptionCheck()) { 2331 err = M4ERR_ALLOC; 2332 break; 2333 } 2334 } 2335 2336 env->ReleaseIntArrayElements(pixelArray, m_dst32, 0); 2337 env->ReleaseIntArrayElements(indexArray, indices, 0); 2338 2339 ThumbnailClose(mContext); 2340 if (pString != NULL) { 2341 env->ReleaseStringUTFChars(path, pString); 2342 } 2343 2344 if (err != M4NO_ERROR && !env->ExceptionCheck()) { 2345 jniThrowException(env, "java/lang/RuntimeException",\ 2346 "ThumbnailGetPixels32 failed"); 2347 } 2348 2349 return err; 2350 } 2351 2352 static M4OSA_ERR 2353 videoEditor_toUTF8Fct( 2354 M4OSA_Void* pBufferIn, 2355 M4OSA_UInt8* pBufferOut, 2356 M4OSA_UInt32* bufferOutSize) 2357 { 2358 M4OSA_ERR result = M4NO_ERROR; 2359 M4OSA_UInt32 length = 0; 2360 2361 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_toUTF8Fct()"); 2362 2363 // Determine the length of the input buffer. 2364 if (M4OSA_NULL != pBufferIn) 2365 { 2366 length = strlen((const char *)pBufferIn); 2367 } 2368 2369 // Check if the output buffer is large enough to hold the input buffer. 2370 if ((*bufferOutSize) > length) 2371 { 2372 // Check if the input buffer is not M4OSA_NULL. 2373 if (M4OSA_NULL != pBufferIn) 2374 { 2375 // Copy the temp path, ignore the result. 2376 M4OSA_chrNCopy((M4OSA_Char *)pBufferOut, (M4OSA_Char *)pBufferIn, length); 2377 } 2378 else 2379 { 2380 // Set the output buffer to an empty string. 2381 (*(M4OSA_Char *)pBufferOut) = 0; 2382 } 2383 } 2384 else 2385 { 2386 // The buffer is too small. 2387 result = M4xVSSWAR_BUFFER_OUT_TOO_SMALL; 2388 } 2389 2390 // Return the buffer output size. 2391 (*bufferOutSize) = length + 1; 2392 2393 // Return the result. 2394 return(result); 2395 } 2396 2397 static M4OSA_ERR 2398 videoEditor_fromUTF8Fct( 2399 M4OSA_UInt8* pBufferIn, 2400 M4OSA_Void* pBufferOut, 2401 M4OSA_UInt32* bufferOutSize) 2402 { 2403 M4OSA_ERR result = M4NO_ERROR; 2404 M4OSA_UInt32 length = 0; 2405 2406 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_fromUTF8Fct()"); 2407 2408 // Determine the length of the input buffer. 2409 if (M4OSA_NULL != pBufferIn) 2410 { 2411 length = strlen((const char *)pBufferIn); 2412 } 2413 2414 // Check if the output buffer is large enough to hold the input buffer. 2415 if ((*bufferOutSize) > length) 2416 { 2417 // Check if the input buffer is not M4OSA_NULL. 2418 if (M4OSA_NULL != pBufferIn) 2419 { 2420 // Copy the temp path, ignore the result. 2421 M4OSA_chrNCopy((M4OSA_Char *)pBufferOut, (M4OSA_Char *)pBufferIn, length); 2422 } 2423 else 2424 { 2425 // Set the output buffer to an empty string. 2426 (*(M4OSA_Char *)pBufferOut) = 0; 2427 } 2428 } 2429 else 2430 { 2431 // The buffer is too small. 2432 result = M4xVSSWAR_BUFFER_OUT_TOO_SMALL; 2433 } 2434 2435 // Return the buffer output size. 2436 (*bufferOutSize) = length + 1; 2437 2438 // Return the result. 2439 return(result); 2440 } 2441 2442 static M4OSA_ERR 2443 videoEditor_getTextRgbBufferFct( 2444 M4OSA_Void* pRenderingData, 2445 M4OSA_Void* pTextBuffer, 2446 M4OSA_UInt32 textBufferSize, 2447 M4VIFI_ImagePlane** pOutputPlane) 2448 { 2449 M4OSA_ERR result = M4NO_ERROR; 2450 2451 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getTextRgbBufferFct()"); 2452 2453 // Return the result. 2454 return(result); 2455 } 2456 2457 static void 2458 videoEditor_callOnProgressUpdate( 2459 ManualEditContext* pContext, 2460 int task, 2461 int progress) 2462 { 2463 JNIEnv* pEnv = NULL; 2464 2465 2466 // Attach the current thread. 2467 pContext->pVM->AttachCurrentThread(&pEnv, NULL); 2468 2469 2470 // Call the on completion callback. 2471 pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId, 2472 videoEditJava_getEngineCToJava(task), progress); 2473 2474 2475 // Detach the current thread. 2476 pContext->pVM->DetachCurrentThread(); 2477 } 2478 2479 static void 2480 videoEditor_freeContext( 2481 JNIEnv* pEnv, 2482 ManualEditContext** ppContext) 2483 { 2484 ManualEditContext* pContext = M4OSA_NULL; 2485 2486 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_freeContext"); 2487 2488 // Set the context pointer. 2489 pContext = (*ppContext); 2490 2491 // Check if the context was set. 2492 if (M4OSA_NULL != pContext) 2493 { 2494 // Check if a global reference to the engine object was set. 2495 if (NULL != pContext->engine) 2496 { 2497 // Free the global reference. 2498 pEnv->DeleteGlobalRef(pContext->engine); 2499 pContext->engine = NULL; 2500 } 2501 2502 // Check if the temp path was set. 2503 if (M4OSA_NULL != pContext->initParams.pTempPath) 2504 { 2505 // Free the memory allocated for the temp path. 2506 videoEditOsal_free(pContext->initParams.pTempPath); 2507 pContext->initParams.pTempPath = M4OSA_NULL; 2508 } 2509 2510 // Check if the file writer was set. 2511 if (M4OSA_NULL != pContext->initParams.pFileWritePtr) 2512 { 2513 // Free the memory allocated for the file writer. 2514 videoEditOsal_free(pContext->initParams.pFileWritePtr); 2515 pContext->initParams.pFileWritePtr = M4OSA_NULL; 2516 } 2517 2518 // Check if the file reader was set. 2519 if (M4OSA_NULL != pContext->initParams.pFileReadPtr) 2520 { 2521 // Free the memory allocated for the file reader. 2522 videoEditOsal_free(pContext->initParams.pFileReadPtr); 2523 pContext->initParams.pFileReadPtr = M4OSA_NULL; 2524 } 2525 2526 // Free the memory allocated for the context. 2527 videoEditOsal_free(pContext); 2528 pContext = M4OSA_NULL; 2529 2530 // Reset the context pointer. 2531 (*ppContext) = M4OSA_NULL; 2532 } 2533 } 2534 2535 static jobject 2536 videoEditor_getVersion( 2537 JNIEnv* pEnv, 2538 jobject thiz) 2539 { 2540 bool isSuccessful = true; 2541 jobject version = NULL; 2542 M4_VersionInfo versionInfo = {0, 0, 0, 0}; 2543 M4OSA_ERR result = M4NO_ERROR; 2544 2545 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getVersion()"); 2546 2547 versionInfo.m_structSize = sizeof(versionInfo); 2548 versionInfo.m_major = VIDEOEDITOR_VERSION_MAJOR; 2549 versionInfo.m_minor = VIDEOEDITOR_VERSION_MINOR; 2550 versionInfo.m_revision = VIDEOEDITOR_VERSION_REVISION; 2551 2552 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getVersion() major %d,\ 2553 minor %d, revision %d", versionInfo.m_major, versionInfo.m_minor, versionInfo.m_revision); 2554 2555 // Create a version object. 2556 videoEditClasses_createVersion(&isSuccessful, pEnv, &versionInfo, &version); 2557 2558 // Return the version object. 2559 return(version); 2560 } 2561 2562 static void 2563 videoEditor_init( 2564 JNIEnv* pEnv, 2565 jobject thiz, 2566 jstring tempPath, 2567 jstring libraryPath) 2568 { 2569 bool initialized = true; 2570 ManualEditContext* pContext = M4OSA_NULL; 2571 VideoEditJava_EngineMethodIds methodIds = {NULL}; 2572 M4OSA_Char* pLibraryPath = M4OSA_NULL; 2573 M4OSA_Char* pTextRendererPath = M4OSA_NULL; 2574 M4OSA_UInt32 textRendererPathLength = 0; 2575 M4OSA_ERR result = M4NO_ERROR; 2576 2577 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_init()"); 2578 2579 // Add a text marker (the condition must always be true). 2580 ADD_TEXT_MARKER_FUN(NULL != pEnv) 2581 2582 // Get the context. 2583 pContext = (ManualEditContext*)videoEditClasses_getContext(&initialized, pEnv, thiz); 2584 2585 // Get the engine method ids. 2586 videoEditJava_getEngineMethodIds(&initialized, pEnv, &methodIds); 2587 2588 // Validate the tempPath parameter. 2589 videoEditJava_checkAndThrowIllegalArgumentException(&initialized, pEnv, 2590 (NULL == tempPath), 2591 "tempPath is null"); 2592 2593 // Make sure that the context was not set already. 2594 videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv, 2595 (M4OSA_NULL != pContext), 2596 "already initialized"); 2597 2598 // Check if the initialization succeeded (required because of dereferencing of psContext, 2599 // and freeing when initialization fails). 2600 if (initialized) 2601 { 2602 // Allocate a new context. 2603 pContext = new ManualEditContext; 2604 2605 // Check if the initialization succeeded (required because of dereferencing of psContext). 2606 //if (initialized) 2607 if (pContext != NULL) 2608 { 2609 // Set the state to not initialized. 2610 pContext->state = ManualEditState_NOT_INITIALIZED; 2611 2612 // Allocate a file read pointer structure. 2613 pContext->initParams.pFileReadPtr = 2614 (M4OSA_FileReadPointer*)videoEditOsal_alloc(&initialized, pEnv, 2615 sizeof(M4OSA_FileReadPointer), "FileReadPointer"); 2616 2617 // Allocate a file write pointer structure. 2618 pContext->initParams.pFileWritePtr = 2619 (M4OSA_FileWriterPointer*)videoEditOsal_alloc(&initialized, pEnv, 2620 sizeof(M4OSA_FileWriterPointer), "FileWriterPointer"); 2621 2622 // Get the temp path. 2623 M4OSA_Char* tmpString = 2624 (M4OSA_Char *)videoEditJava_getString(&initialized, pEnv, tempPath, 2625 NULL, M4OSA_NULL); 2626 M4OSA_UInt32 length = strlen((const char *)tmpString); 2627 // Malloc additional 2 bytes for beginning and tail separator. 2628 M4OSA_UInt32 pathLength = length + 2; 2629 2630 pContext->initParams.pTempPath = (M4OSA_Char *) 2631 M4OSA_32bitAlignedMalloc(pathLength, 0x0, (M4OSA_Char *)"tempPath"); 2632 2633 //initialize the first char. so that strcat works. 2634 M4OSA_Char *ptmpChar = (M4OSA_Char*)pContext->initParams.pTempPath; 2635 ptmpChar[0] = 0x00; 2636 strncat((char *)pContext->initParams.pTempPath, (const char *)tmpString, 2637 length); 2638 strncat((char *)pContext->initParams.pTempPath, (const char *)"/", (size_t)1); 2639 free(tmpString); 2640 tmpString = NULL; 2641 pContext->mIsUpdateOverlay = false; 2642 pContext->mOverlayFileName = NULL; 2643 pContext->decoders = NULL; 2644 } 2645 2646 // Check if the initialization succeeded 2647 // (required because of dereferencing of pContext, pFileReadPtr and pFileWritePtr). 2648 if (initialized) 2649 { 2650 2651 // Initialize the OSAL file system function pointers. 2652 videoEditOsal_getFilePointers(pContext->initParams.pFileReadPtr , 2653 pContext->initParams.pFileWritePtr); 2654 2655 // Set the UTF8 conversion functions. 2656 pContext->initParams.pConvToUTF8Fct = videoEditor_toUTF8Fct; 2657 pContext->initParams.pConvFromUTF8Fct = videoEditor_fromUTF8Fct; 2658 2659 // Set the callback method ids. 2660 pContext->onProgressUpdateMethodId = methodIds.onProgressUpdate; 2661 2662 // Set the virtual machine. 2663 pEnv->GetJavaVM(&(pContext->pVM)); 2664 2665 // Create a global reference to the engine object. 2666 pContext->engine = pEnv->NewGlobalRef(thiz); 2667 2668 // Check if the global reference could be created. 2669 videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv, 2670 (NULL == pContext->engine), M4NO_ERROR); 2671 } 2672 2673 // Check if the initialization succeeded (required because of dereferencing of pContext). 2674 if (initialized) 2675 { 2676 // Log the API call. 2677 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4xVSS_Init()"); 2678 2679 // Initialize the visual studio library. 2680 result = M4xVSS_Init(&pContext->engineContext, &pContext->initParams); 2681 2682 // Log the result. 2683 VIDEOEDIT_LOG_RESULT(ANDROID_LOG_INFO, "VIDEO_EDITOR", 2684 videoEditOsal_getResultString(result)); 2685 2686 // Check if the library could be initialized. 2687 videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv, 2688 (M4NO_ERROR != result), result); 2689 2690 // Get platform video decoder capablities. 2691 result = M4xVSS_getVideoDecoderCapabilities(&pContext->decoders); 2692 2693 videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv, 2694 (M4NO_ERROR != result), result); 2695 } 2696 2697 if(initialized) 2698 { 2699 pContext->mPreviewController = new VideoEditorPreviewController(); 2700 videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv, 2701 (M4OSA_NULL == pContext->mPreviewController), 2702 "not initialized"); 2703 pContext->mAudioSettings = 2704 (M4xVSS_AudioMixingSettings *) 2705 M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_AudioMixingSettings),0x0, 2706 (M4OSA_Char *)"mAudioSettings"); 2707 videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv, 2708 (M4OSA_NULL == pContext->mAudioSettings), 2709 "not initialized"); 2710 pContext->mAudioSettings->pFile = M4OSA_NULL; 2711 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL; 2712 pContext->mAudioSettings->bRemoveOriginal = 0; 2713 pContext->mAudioSettings->uiNbChannels = 0; 2714 pContext->mAudioSettings->uiSamplingFrequency = 0; 2715 pContext->mAudioSettings->uiExtendedSamplingFrequency = 0; 2716 pContext->mAudioSettings->uiAddCts = 0; 2717 pContext->mAudioSettings->uiAddVolume = 0; 2718 pContext->mAudioSettings->beginCutMs = 0; 2719 pContext->mAudioSettings->endCutMs = 0; 2720 pContext->mAudioSettings->fileType = 0; 2721 pContext->mAudioSettings->bLoop = 0; 2722 pContext->mAudioSettings->uiInDucking_lowVolume = 0; 2723 pContext->mAudioSettings->bInDucking_enable = 0; 2724 pContext->mAudioSettings->uiBTChannelCount = 0; 2725 pContext->mAudioSettings->uiInDucking_threshold = 0; 2726 } 2727 // Check if the library could be initialized. 2728 if (initialized) 2729 { 2730 // Set the state to initialized. 2731 pContext->state = ManualEditState_INITIALIZED; 2732 } 2733 2734 // Set the context. 2735 videoEditClasses_setContext(&initialized, pEnv, thiz, (void* )pContext); 2736 pLibraryPath = M4OSA_NULL; 2737 2738 pContext->pEditSettings = M4OSA_NULL; 2739 // Cleanup if anything went wrong during initialization. 2740 if (!initialized) 2741 { 2742 // Free the context. 2743 videoEditor_freeContext(pEnv, &pContext); 2744 } 2745 } 2746 } 2747 2748 /*+ PROGRESS CB */ 2749 static 2750 M4OSA_ERR videoEditor_processClip( 2751 JNIEnv* pEnv, 2752 jobject thiz, 2753 int unuseditemID) { 2754 2755 bool loaded = true; 2756 ManualEditContext* pContext = NULL; 2757 M4OSA_UInt8 progress = 0; 2758 M4OSA_UInt8 progressBase = 0; 2759 M4OSA_UInt8 lastProgress = 0; 2760 M4OSA_ERR result = M4NO_ERROR; 2761 2762 // Get the context. 2763 pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz); 2764 2765 // Make sure that the context was set. 2766 videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv, 2767 (M4OSA_NULL == pContext), 2768 "not initialized"); 2769 2770 // We start in Analyzing state 2771 pContext->state = ManualEditState_INITIALIZED; 2772 M4OSA_ERR completionResult = M4VSS3GPP_WAR_ANALYZING_DONE; 2773 ManualEditState completionState = ManualEditState_OPENED; 2774 ManualEditState errorState = ManualEditState_ANALYZING_ERROR; 2775 2776 // While analyzing progress goes from 0 to 10 (except Kenburn clip 2777 // generation, which goes from 0 to 50) 2778 progressBase = 0; 2779 2780 // Set the text rendering function. 2781 if (M4OSA_NULL != pContext->pTextRendererFunction) 2782 { 2783 // Use the text renderer function in the library. 2784 pContext->pEditSettings->xVSS.pTextRenderingFct = pContext->pTextRendererFunction; 2785 } 2786 else 2787 { 2788 // Use the internal text renderer function. 2789 pContext->pEditSettings->xVSS.pTextRenderingFct = videoEditor_getTextRgbBufferFct; 2790 } 2791 2792 // Send the command. 2793 ALOGV("videoEditor_processClip ITEM %d Calling M4xVSS_SendCommand()", unuseditemID); 2794 result = M4xVSS_SendCommand(pContext->engineContext, pContext->pEditSettings); 2795 ALOGV("videoEditor_processClip ITEM %d M4xVSS_SendCommand() returned 0x%x", 2796 unuseditemID, (unsigned int) result); 2797 2798 // Remove warnings indications (we only care about errors here) 2799 if ((result == M4VSS3GPP_WAR_TRANSCODING_NECESSARY) 2800 || (result == M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED)) { 2801 result = M4NO_ERROR; 2802 } 2803 2804 // Send the first progress indication (=0) 2805 ALOGV("VERY FIRST PROGRESS videoEditor_processClip ITEM %d Progress indication %d", 2806 unuseditemID, progress); 2807 pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId, 2808 unuseditemID, progress); 2809 2810 // Check if a task is being performed. 2811 // ??? ADD STOPPING MECHANISM 2812 ALOGV("videoEditor_processClip Entering processing loop"); 2813 M4OSA_UInt8 prevReportedProgress = 0; 2814 while((result == M4NO_ERROR) 2815 &&(pContext->state!=ManualEditState_SAVED) 2816 &&(pContext->state!=ManualEditState_STOPPING)) { 2817 2818 // Perform the next processing step. 2819 //ALOGV("LVME_processClip Entering M4xVSS_Step()"); 2820 result = M4xVSS_Step(pContext->engineContext, &progress); 2821 2822 if (progress != prevReportedProgress) { 2823 prevReportedProgress = progress; 2824 // Log the 1 % .. 100 % progress after processing. 2825 if (M4OSA_TRUE == 2826 pContext->pEditSettings->pClipList[0]->xVSS.isPanZoom) { 2827 // For KenBurn clip generation, return 0 to 50 2828 // for Analysis phase and 50 to 100 for Saving phase 2829 progress = progressBase + progress/2; 2830 } else { 2831 // For export/transition clips, 0 to 10 for Analysis phase 2832 // and 10 to 100 for Saving phase 2833 if (ManualEditState_INITIALIZED == pContext->state) { 2834 progress = 0.1*progress; 2835 } else { 2836 progress = progressBase + 0.9*progress; 2837 } 2838 } 2839 2840 if (progress > lastProgress) 2841 { 2842 // Send a progress notification. 2843 ALOGV("videoEditor_processClip ITEM %d Progress indication %d", 2844 unuseditemID, progress); 2845 pEnv->CallVoidMethod(pContext->engine, 2846 pContext->onProgressUpdateMethodId, 2847 unuseditemID, progress); 2848 lastProgress = progress; 2849 } 2850 } 2851 2852 // Check if processing has been completed. 2853 if (result == completionResult) 2854 { 2855 // Set the state to the completions state. 2856 pContext->state = completionState; 2857 ALOGV("videoEditor_processClip ITEM %d STATE changed to %d", 2858 unuseditemID, pContext->state); 2859 2860 // Reset progress indication, as we switch to next state 2861 lastProgress = 0; 2862 2863 // Reset error code, as we start a new round of processing 2864 result = M4NO_ERROR; 2865 2866 // Check if we are analyzing input 2867 if (pContext->state == ManualEditState_OPENED) { 2868 // File is opened, we must start saving it 2869 ALOGV("videoEditor_processClip Calling M4xVSS_SaveStart()"); 2870 result = M4xVSS_SaveStart(pContext->engineContext, 2871 (M4OSA_Char*)pContext->pEditSettings->pOutputFile, 2872 (M4OSA_UInt32)pContext->pEditSettings->uiOutputPathSize); 2873 ALOGV("videoEditor_processClip ITEM %d SaveStart() returned 0x%x", 2874 unuseditemID, (unsigned int) result); 2875 2876 // Set the state to saving. 2877 pContext->state = ManualEditState_SAVING; 2878 completionState = ManualEditState_SAVED; 2879 completionResult = M4VSS3GPP_WAR_SAVING_DONE; 2880 errorState = ManualEditState_SAVING_ERROR; 2881 2882 // While saving, progress goes from 10 to 100 2883 // except for Kenburn clip which goes from 50 to 100 2884 if (M4OSA_TRUE == 2885 pContext->pEditSettings->pClipList[0]->xVSS.isPanZoom) { 2886 progressBase = 50; 2887 } else { 2888 progressBase = 10; 2889 } 2890 } 2891 // Check if we encoding is ongoing 2892 else if (pContext->state == ManualEditState_SAVED) { 2893 2894 // Send a progress notification. 2895 progress = 100; 2896 ALOGV("videoEditor_processClip ITEM %d Last progress indication %d", 2897 unuseditemID, progress); 2898 pEnv->CallVoidMethod(pContext->engine, 2899 pContext->onProgressUpdateMethodId, 2900 unuseditemID, progress); 2901 2902 2903 // Stop the encoding. 2904 ALOGV("videoEditor_processClip Calling M4xVSS_SaveStop()"); 2905 result = M4xVSS_SaveStop(pContext->engineContext); 2906 ALOGV("videoEditor_processClip M4xVSS_SaveStop() returned 0x%x", result); 2907 } 2908 // Other states are unexpected 2909 else { 2910 result = M4ERR_STATE; 2911 ALOGE("videoEditor_processClip ITEM %d State ERROR 0x%x", 2912 unuseditemID, (unsigned int) result); 2913 } 2914 } 2915 2916 // Check if an error occurred. 2917 if (result != M4NO_ERROR) 2918 { 2919 // Set the state to the error state. 2920 pContext->state = errorState; 2921 2922 // Log the result. 2923 ALOGE("videoEditor_processClip ITEM %d Processing ERROR 0x%x", 2924 unuseditemID, (unsigned int) result); 2925 } 2926 } 2927 2928 // Return the error result 2929 ALOGE("videoEditor_processClip ITEM %d END 0x%x", unuseditemID, (unsigned int) result); 2930 return result; 2931 } 2932 /*+ PROGRESS CB */ 2933 2934 static int 2935 videoEditor_generateClip( 2936 JNIEnv* pEnv, 2937 jobject thiz, 2938 jobject settings) { 2939 bool loaded = true; 2940 ManualEditContext* pContext = M4OSA_NULL; 2941 M4OSA_ERR result = M4NO_ERROR; 2942 2943 ALOGV("videoEditor_generateClip START"); 2944 2945 // Get the context. 2946 pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz); 2947 2948 Mutex::Autolock autoLock(pContext->mLock); 2949 2950 // Validate the settings parameter. 2951 videoEditJava_checkAndThrowIllegalArgumentException(&loaded, pEnv, 2952 (NULL == settings), 2953 "settings is null"); 2954 2955 // Make sure that the context was set. 2956 videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv, 2957 (M4OSA_NULL == pContext), 2958 "not initialized"); 2959 2960 // Load the clip settings 2961 ALOGV("videoEditor_generateClip Calling videoEditor_loadSettings"); 2962 videoEditor_loadSettings(pEnv, thiz, settings); 2963 ALOGV("videoEditor_generateClip videoEditor_loadSettings returned"); 2964 2965 // Generate the clip 2966 ALOGV("videoEditor_generateClip Calling LVME_processClip"); 2967 result = videoEditor_processClip(pEnv, thiz, 0 /*item id is unused*/); 2968 ALOGV("videoEditor_generateClip videoEditor_processClip returned 0x%x", result); 2969 2970 if (pContext->state != ManualEditState_INITIALIZED) { 2971 // Free up memory (whatever the result) 2972 videoEditor_unloadSettings(pEnv, thiz); 2973 } 2974 2975 ALOGV("videoEditor_generateClip END 0x%x", (unsigned int) result); 2976 return result; 2977 } 2978 2979 static void 2980 videoEditor_loadSettings( 2981 JNIEnv* pEnv, 2982 jobject thiz, 2983 jobject settings) 2984 { 2985 bool needToBeLoaded = true; 2986 ManualEditContext* pContext = M4OSA_NULL; 2987 2988 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_loadSettings()"); 2989 2990 // Add a code marker (the condition must always be true). 2991 ADD_CODE_MARKER_FUN(NULL != pEnv) 2992 2993 // Get the context. 2994 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, 2995 pEnv, thiz); 2996 2997 // Validate the settings parameter. 2998 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, 2999 (NULL == settings), 3000 "settings is null"); 3001 3002 // Make sure that the context was set. 3003 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 3004 (M4OSA_NULL == pContext), 3005 "not initialized"); 3006 3007 // Check if the context is valid (required because the context is dereferenced). 3008 if (needToBeLoaded) 3009 { 3010 // Make sure that we are in a correct state. 3011 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 3012 (pContext->state != ManualEditState_INITIALIZED), 3013 "settings already loaded"); 3014 3015 // Retrieve the edit settings. 3016 if(pContext->pEditSettings != M4OSA_NULL) { 3017 videoEditClasses_freeEditSettings(&pContext->pEditSettings); 3018 pContext->pEditSettings = M4OSA_NULL; 3019 } 3020 videoEditClasses_getEditSettings(&needToBeLoaded, pEnv, settings, 3021 &pContext->pEditSettings,true); 3022 } 3023 3024 // Check if the edit settings could be retrieved. 3025 if (needToBeLoaded) 3026 { 3027 // Log the edit settings. 3028 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "inside load settings"); 3029 VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings); 3030 } 3031 ALOGV("videoEditor_loadSettings END"); 3032 } 3033 3034 3035 3036 static void 3037 videoEditor_unloadSettings( 3038 JNIEnv* pEnv, 3039 jobject thiz) 3040 { 3041 bool needToBeUnLoaded = true; 3042 ManualEditContext* pContext = M4OSA_NULL; 3043 M4OSA_ERR result = M4NO_ERROR; 3044 3045 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_unloadSettings()"); 3046 3047 // Get the context. 3048 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeUnLoaded, pEnv, thiz); 3049 3050 // Make sure that the context was set. 3051 videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv, 3052 (M4OSA_NULL == pContext), 3053 "not initialized"); 3054 3055 // Check if the context is valid (required because the context is dereferenced). 3056 if (needToBeUnLoaded) 3057 { 3058 ALOGV("videoEditor_unloadSettings state %d", pContext->state); 3059 // Make sure that we are in a correct state. 3060 videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv, 3061 ((pContext->state != ManualEditState_ANALYZING ) && 3062 (pContext->state != ManualEditState_ANALYZING_ERROR) && 3063 (pContext->state != ManualEditState_OPENED ) && 3064 (pContext->state != ManualEditState_SAVING_ERROR ) && 3065 (pContext->state != ManualEditState_SAVED ) && 3066 (pContext->state != ManualEditState_STOPPING ) ), 3067 "videoEditor_unloadSettings no load settings in progress"); 3068 } 3069 3070 // Check if we are in a correct state. 3071 if (needToBeUnLoaded) 3072 { 3073 // Check if the thread could be stopped. 3074 if (needToBeUnLoaded) 3075 { 3076 // Close the command. 3077 ALOGV("videoEditor_unloadSettings Calling M4xVSS_CloseCommand()"); 3078 result = M4xVSS_CloseCommand(pContext->engineContext); 3079 ALOGV("videoEditor_unloadSettings M4xVSS_CloseCommand() returned 0x%x", 3080 (unsigned int)result); 3081 3082 // Check if the command could be closed. 3083 videoEditJava_checkAndThrowRuntimeException(&needToBeUnLoaded, pEnv, 3084 (M4NO_ERROR != result), result); 3085 } 3086 3087 // Check if the command could be closed. 3088 if (needToBeUnLoaded) 3089 { 3090 // Free the edit settings. 3091 //videoEditClasses_freeEditSettings(&pContext->pEditSettings); 3092 3093 // Reset the thread result. 3094 pContext->threadResult = M4NO_ERROR; 3095 3096 // Reset the thread progress. 3097 pContext->threadProgress = 0; 3098 3099 // Set the state to initialized. 3100 pContext->state = ManualEditState_INITIALIZED; 3101 } 3102 } 3103 } 3104 3105 static void 3106 videoEditor_stopEncoding( 3107 JNIEnv* pEnv, 3108 jobject thiz) 3109 { 3110 bool stopped = true; 3111 ManualEditContext* pContext = M4OSA_NULL; 3112 M4OSA_ERR result = M4NO_ERROR; 3113 3114 ALOGV("videoEditor_stopEncoding START"); 3115 3116 // Get the context. 3117 pContext = (ManualEditContext*)videoEditClasses_getContext(&stopped, pEnv, thiz); 3118 3119 // Change state and get Lock 3120 // This will ensure the generateClip function exits 3121 pContext->state = ManualEditState_STOPPING; 3122 Mutex::Autolock autoLock(pContext->mLock); 3123 3124 // Make sure that the context was set. 3125 videoEditJava_checkAndThrowIllegalStateException(&stopped, pEnv, 3126 (M4OSA_NULL == pContext), 3127 "not initialized"); 3128 3129 if (stopped) { 3130 3131 // Check if the command should be closed. 3132 if (pContext->state != ManualEditState_INITIALIZED) 3133 { 3134 // Close the command. 3135 ALOGV("videoEditor_stopEncoding Calling M4xVSS_CloseCommand()"); 3136 result = M4xVSS_CloseCommand(pContext->engineContext); 3137 ALOGV("videoEditor_stopEncoding M4xVSS_CloseCommand() returned 0x%x", 3138 (unsigned int)result); 3139 } 3140 3141 // Check if the command could be closed. 3142 videoEditJava_checkAndThrowRuntimeException(&stopped, pEnv, 3143 (M4NO_ERROR != result), result); 3144 3145 // Free the edit settings. 3146 videoEditClasses_freeEditSettings(&pContext->pEditSettings); 3147 3148 // Set the state to initialized. 3149 pContext->state = ManualEditState_INITIALIZED; 3150 } 3151 3152 } 3153 3154 static void 3155 videoEditor_release( 3156 JNIEnv* pEnv, 3157 jobject thiz) 3158 { 3159 bool released = true; 3160 ManualEditContext* pContext = M4OSA_NULL; 3161 M4OSA_ERR result = M4NO_ERROR; 3162 3163 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_release()"); 3164 3165 // Add a text marker (the condition must always be true). 3166 ADD_TEXT_MARKER_FUN(NULL != pEnv) 3167 3168 // Get the context. 3169 pContext = (ManualEditContext*)videoEditClasses_getContext(&released, pEnv, thiz); 3170 3171 // If context is not set, return (we consider release already happened) 3172 if (pContext == NULL) { 3173 ALOGV("videoEditor_release Nothing to do, context is aleady NULL"); 3174 return; 3175 } 3176 3177 3178 // Check if the context is valid (required because the context is dereferenced). 3179 if (released) 3180 { 3181 if (pContext->state != ManualEditState_INITIALIZED) 3182 { 3183 // Change state and get Lock 3184 // This will ensure the generateClip function exits if it is running 3185 pContext->state = ManualEditState_STOPPING; 3186 Mutex::Autolock autoLock(pContext->mLock); 3187 } 3188 3189 // Reset the context. 3190 videoEditClasses_setContext(&released, pEnv, thiz, (void *)M4OSA_NULL); 3191 3192 // Check if the command should be closed. 3193 if (pContext->state != ManualEditState_INITIALIZED) 3194 { 3195 // Close the command. 3196 ALOGV("videoEditor_release Calling M4xVSS_CloseCommand() state =%d", 3197 pContext->state); 3198 result = M4xVSS_CloseCommand(pContext->engineContext); 3199 ALOGV("videoEditor_release M4xVSS_CloseCommand() returned 0x%x", 3200 (unsigned int)result); 3201 3202 // Check if the command could be closed. 3203 videoEditJava_checkAndThrowRuntimeException(&released, pEnv, 3204 (M4NO_ERROR != result), result); 3205 } 3206 3207 // Cleanup the engine. 3208 ALOGV("videoEditor_release Calling M4xVSS_CleanUp()"); 3209 result = M4xVSS_CleanUp(pContext->engineContext); 3210 ALOGV("videoEditor_release M4xVSS_CleanUp() returned 0x%x", (unsigned int)result); 3211 3212 // Check if the cleanup succeeded. 3213 videoEditJava_checkAndThrowRuntimeException(&released, pEnv, 3214 (M4NO_ERROR != result), result); 3215 3216 // Free the edit settings. 3217 videoEditClasses_freeEditSettings(&pContext->pEditSettings); 3218 pContext->pEditSettings = M4OSA_NULL; 3219 3220 3221 if(pContext->mPreviewController != M4OSA_NULL) 3222 { 3223 delete pContext->mPreviewController; 3224 pContext->mPreviewController = M4OSA_NULL; 3225 } 3226 3227 // Free the mAudioSettings context. 3228 if(pContext->mAudioSettings != M4OSA_NULL) 3229 { 3230 if (pContext->mAudioSettings->pFile != NULL) { 3231 free(pContext->mAudioSettings->pFile); 3232 pContext->mAudioSettings->pFile = M4OSA_NULL; 3233 } 3234 if (pContext->mAudioSettings->pPCMFilePath != NULL) { 3235 free(pContext->mAudioSettings->pPCMFilePath); 3236 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL; 3237 } 3238 3239 free(pContext->mAudioSettings); 3240 pContext->mAudioSettings = M4OSA_NULL; 3241 } 3242 // Free video Decoders capabilities 3243 if (pContext->decoders != M4OSA_NULL) { 3244 VideoDecoder *pDecoder = NULL; 3245 VideoComponentCapabilities *pComponents = NULL; 3246 int32_t decoderNumber = pContext->decoders->decoderNumber; 3247 if (pContext->decoders->decoder != NULL && 3248 decoderNumber > 0) { 3249 pDecoder = pContext->decoders->decoder; 3250 for (int32_t k = 0; k < decoderNumber; k++) { 3251 // free each component 3252 ALOGV("decoder index :%d",k); 3253 if (pDecoder != NULL && 3254 pDecoder->component != NULL && 3255 pDecoder->componentNumber > 0) { 3256 ALOGV("component number %d",pDecoder->componentNumber); 3257 int32_t componentNumber = 3258 pDecoder->componentNumber; 3259 3260 pComponents = pDecoder->component; 3261 for (int32_t i = 0; i< componentNumber; i++) { 3262 ALOGV("component index :%d",i); 3263 if (pComponents != NULL && 3264 pComponents->profileLevel != NULL) { 3265 free(pComponents->profileLevel); 3266 pComponents->profileLevel = NULL; 3267 } 3268 pComponents++; 3269 } 3270 free(pDecoder->component); 3271 pDecoder->component = NULL; 3272 } 3273 3274 pDecoder++; 3275 } 3276 free(pContext->decoders->decoder); 3277 pContext->decoders->decoder = NULL; 3278 } 3279 free(pContext->decoders); 3280 pContext->decoders = NULL; 3281 } 3282 3283 videoEditor_freeContext(pEnv, &pContext); 3284 } 3285 } 3286 3287 static int 3288 videoEditor_registerManualEditMethods( 3289 JNIEnv* pEnv) 3290 { 3291 int result = -1; 3292 3293 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3294 "videoEditor_registerManualEditMethods()"); 3295 3296 // Look up the engine class 3297 jclass engineClazz = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME); 3298 3299 // Clear any resulting exceptions. 3300 pEnv->ExceptionClear(); 3301 3302 // Check if the engine class was found. 3303 if (NULL != engineClazz) 3304 { 3305 // Register all the methods. 3306 if (pEnv->RegisterNatives(engineClazz, gManualEditMethods, 3307 sizeof(gManualEditMethods) / sizeof(gManualEditMethods[0])) == JNI_OK) 3308 { 3309 // Success. 3310 result = 0; 3311 } 3312 } 3313 3314 // Return the result. 3315 return(result); 3316 } 3317 3318 /*******Audio Graph*******/ 3319 3320 static M4OSA_UInt32 getDecibelSound(M4OSA_UInt32 value) 3321 { 3322 int dbSound = 1; 3323 3324 if (value == 0) return 0; 3325 3326 if (value > 0x4000 && value <= 0x8000) // 32768 3327 dbSound = 90; 3328 else if (value > 0x2000 && value <= 0x4000) // 16384 3329 dbSound = 84; 3330 else if (value > 0x1000 && value <= 0x2000) // 8192 3331 dbSound = 78; 3332 else if (value > 0x0800 && value <= 0x1000) // 4028 3333 dbSound = 72; 3334 else if (value > 0x0400 && value <= 0x0800) // 2048 3335 dbSound = 66; 3336 else if (value > 0x0200 && value <= 0x0400) // 1024 3337 dbSound = 60; 3338 else if (value > 0x0100 && value <= 0x0200) // 512 3339 dbSound = 54; 3340 else if (value > 0x0080 && value <= 0x0100) // 256 3341 dbSound = 48; 3342 else if (value > 0x0040 && value <= 0x0080) // 128 3343 dbSound = 42; 3344 else if (value > 0x0020 && value <= 0x0040) // 64 3345 dbSound = 36; 3346 else if (value > 0x0010 && value <= 0x0020) // 32 3347 dbSound = 30; 3348 else if (value > 0x0008 && value <= 0x0010) //16 3349 dbSound = 24; 3350 else if (value > 0x0007 && value <= 0x0008) //8 3351 dbSound = 24; 3352 else if (value > 0x0003 && value <= 0x0007) // 4 3353 dbSound = 18; 3354 else if (value > 0x0001 && value <= 0x0003) //2 3355 dbSound = 12; 3356 else if (value > 0x000 && value == 0x0001) // 1 3357 dbSound = 6; 3358 else 3359 dbSound = 0; 3360 3361 return dbSound; 3362 } 3363 3364 typedef struct 3365 { 3366 M4OSA_UInt8 *m_dataAddress; 3367 M4OSA_UInt32 m_bufferSize; 3368 } M4AM_Buffer; 3369 3370 3371 M4OSA_UInt8 logLookUp[256] = { 3372 0,120,137,146,154,159,163,167,171,173,176,178,181,182,184,186,188,189,190,192,193, 3373 194,195,196,198,199,199,200,201,202,203,204,205,205,206,207,207,208,209,209,210, 3374 211,211,212,212,213,213,214,215,215,216,216,216,217,217,218,218,219,219,220,220, 3375 220,221,221,222,222,222,223,223,223,224,224,224,225,225,225,226,226,226,227,227, 3376 227,228,228,228,229,229,229,229,230,230,230,230,231,231,231,232,232,232,232,233, 3377 233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236,236,237,237,237, 3378 237,237,238,238,238,238,238,239,239,239,239,239,240,240,240,240,240,240,241,241, 3379 241,241,241,241,242,242,242,242,242,242,243,243,243,243,243,243,244,244,244,244, 3380 244,244,245,245,245,245,245,245,245,246,246,246,246,246,246,246,247,247,247,247, 3381 247,247,247,247,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,250, 3382 250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,252,252,252,252, 3383 252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254, 3384 254,254,254,254,255,255,255,255,255,255,255,255,255,255,255}; 3385 3386 M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL, 3387 M4OSA_Char* pOutFileURL, 3388 M4OSA_UInt32 samplesPerValue, 3389 M4OSA_UInt32 channels, 3390 M4OSA_UInt32 frameDuration, 3391 ManualEditContext* pContext) 3392 { 3393 M4OSA_ERR err; 3394 M4OSA_Context outFileHandle = M4OSA_NULL; 3395 M4OSA_Context inputFileHandle = M4OSA_NULL; 3396 M4AM_Buffer bufferIn = {0, 0}; 3397 M4OSA_UInt32 peakVolumeDbValue = 0; 3398 M4OSA_UInt32 samplesCountInBytes= 0 , numBytesToRead = 0, index = 0; 3399 M4OSA_UInt32 writeCount = 0, samplesCountBigEndian = 0, volumeValuesCount = 0; 3400 M4OSA_Int32 seekPos = 0; 3401 M4OSA_UInt32 fileSize = 0; 3402 M4OSA_UInt32 totalBytesRead = 0; 3403 M4OSA_UInt32 prevProgress = 0; 3404 bool threadStarted = true; 3405 3406 int dbValue = 0; 3407 M4OSA_Int16 *ptr16 ; 3408 3409 jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME); 3410 videoEditJava_checkAndThrowIllegalStateException(&threadStarted, pEnv, 3411 (M4OSA_NULL == engineClass), 3412 "not initialized"); 3413 3414 /* register the call back function pointer */ 3415 pContext->onAudioGraphProgressUpdateMethodId = 3416 pEnv->GetMethodID(engineClass, "onAudioGraphExtractProgressUpdate", "(IZ)V"); 3417 3418 3419 /* ENTER */ 3420 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "ENTER - M4MA_generateAudioGraphFile"); 3421 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3422 "Audio Graph samplesPerValue %d channels %d", samplesPerValue, channels); 3423 3424 /****************************************************************************** 3425 OPEN INPUT AND OUTPUT FILES 3426 *******************************************************************************/ 3427 err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead); 3428 if (inputFileHandle == M4OSA_NULL) { 3429 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3430 "M4MA_generateAudioGraphFile: Cannot open input file 0x%lx", err); 3431 return err; 3432 } 3433 3434 /* get the file size for progress */ 3435 err = M4OSA_fileReadGetOption(inputFileHandle, M4OSA_kFileReadGetFileSize, 3436 (M4OSA_Void**)&fileSize); 3437 if ( err != M4NO_ERROR) { 3438 //LVMEL_LOG_ERROR("M4MA_generateAudioGraphFile : File write failed \n"); 3439 jniThrowException(pEnv, "java/lang/IOException", "file size get option failed"); 3440 //return -1; 3441 } 3442 3443 err = M4OSA_fileWriteOpen (&outFileHandle,(M4OSA_Char*) pOutFileURL, 3444 M4OSA_kFileCreate | M4OSA_kFileWrite); 3445 if (outFileHandle == M4OSA_NULL) { 3446 if (inputFileHandle != NULL) 3447 { 3448 M4OSA_fileReadClose(inputFileHandle); 3449 } 3450 return err; 3451 } 3452 3453 /****************************************************************************** 3454 PROCESS THE SAMPLES 3455 *******************************************************************************/ 3456 samplesCountInBytes = (samplesPerValue * sizeof(M4OSA_UInt16) * channels); 3457 3458 bufferIn.m_dataAddress = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(samplesCountInBytes*sizeof(M4OSA_UInt16), 0, 3459 (M4OSA_Char*)"AudioGraph" ); 3460 if ( bufferIn.m_dataAddress != M4OSA_NULL) { 3461 bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16); 3462 } else { 3463 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3464 "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%lx", 3465 M4ERR_ALLOC); 3466 return M4ERR_ALLOC; 3467 } 3468 /* sample to be converted to BIG endian ; store the frame duration */ 3469 samplesCountBigEndian = ((frameDuration>>24)&0xff) | // move byte 3 to byte 0 3470 ((frameDuration<<8)&0xff0000) | // move byte 1 to byte 2 3471 ((frameDuration>>8)&0xff00) | // move byte 2 to byte 1 3472 ((frameDuration<<24)&0xff000000); // byte 0 to byte 3 3473 3474 /* write the samples per value supplied to out file */ 3475 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian, 3476 sizeof(M4OSA_UInt32) ); 3477 if (err != M4NO_ERROR) { 3478 jniThrowException(pEnv, "java/lang/IOException", "file write failed"); 3479 } 3480 3481 3482 /* write UIn32 value 0 for no of values as place holder */ 3483 samplesCountBigEndian = 0; /* reusing local var */ 3484 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian, 3485 sizeof(M4OSA_UInt32) ); 3486 if (err != M4NO_ERROR) { 3487 jniThrowException(pEnv, "java/lang/IOException", "file write failed"); 3488 } 3489 3490 /* loop until EOF */ 3491 do 3492 { 3493 memset((void *)bufferIn.m_dataAddress,0,bufferIn.m_bufferSize); 3494 3495 numBytesToRead = samplesCountInBytes; 3496 3497 err = M4OSA_fileReadData( inputFileHandle, 3498 (M4OSA_MemAddr8)bufferIn.m_dataAddress, 3499 &numBytesToRead ); 3500 3501 if (err != M4NO_ERROR) { 3502 // if out value of bytes-read is 0, break 3503 if ( numBytesToRead == 0) { 3504 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%lx", 3505 numBytesToRead); 3506 break; /* stop if file is empty or EOF */ 3507 } 3508 } 3509 3510 ptr16 = (M4OSA_Int16*)bufferIn.m_dataAddress; 3511 3512 peakVolumeDbValue = 0; 3513 index = 0; 3514 3515 // loop through half the lenght frame bytes read 'cause its 16 bits samples 3516 while (index < (numBytesToRead / 2)) { 3517 /* absolute values of 16 bit sample */ 3518 if (ptr16[index] < 0) { 3519 ptr16[index] = -(ptr16[index]); 3520 } 3521 peakVolumeDbValue = (peakVolumeDbValue > (M4OSA_UInt32)ptr16[index] ?\ 3522 peakVolumeDbValue : (M4OSA_UInt32)ptr16[index]); 3523 index++; 3524 } 3525 3526 // move 7 bits , ignore sign bit 3527 dbValue = (peakVolumeDbValue >> 7); 3528 dbValue = logLookUp[(M4OSA_UInt8)dbValue]; 3529 3530 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&dbValue, sizeof(M4OSA_UInt8) ); 3531 if (err != M4NO_ERROR) { 3532 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3533 "M4MA_generateAudioGraphFile : File write failed"); 3534 break; 3535 } 3536 3537 volumeValuesCount ++; 3538 totalBytesRead += numBytesToRead; 3539 3540 if ((((totalBytesRead*100)/fileSize)) != prevProgress) { 3541 if ( (pContext->threadProgress != prevProgress) && (prevProgress != 0 )) { 3542 //pContext->threadProgress = prevProgress; 3543 //onWveformProgressUpdateMethodId(prevProgress, 0); 3544 //LVME_callAudioGraphOnProgressUpdate(pContext, 0, prevProgress); 3545 pEnv->CallVoidMethod(pContext->engine, 3546 pContext->onAudioGraphProgressUpdateMethodId, 3547 prevProgress, 0); 3548 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pContext->threadProgress %d", 3549 prevProgress); 3550 } 3551 } 3552 prevProgress = (((totalBytesRead*100)/fileSize)); 3553 3554 } while (numBytesToRead != 0); 3555 3556 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%lx", volumeValuesCount); 3557 3558 /* if some error occured in fwrite */ 3559 if (numBytesToRead != 0) { 3560 //err = -1; 3561 jniThrowException(pEnv, "java/lang/IOException", "numBytesToRead != 0 ; file write failed"); 3562 } 3563 3564 /* write the count in place holder after seek */ 3565 seekPos = sizeof(M4OSA_UInt32); 3566 err = M4OSA_fileWriteSeek(outFileHandle, M4OSA_kFileSeekBeginning, 3567 &seekPos /* after samples per value */); 3568 if ( err != M4NO_ERROR) { 3569 jniThrowException(pEnv, "java/lang/IOException", "file seek failed"); 3570 } else { 3571 volumeValuesCount = ((volumeValuesCount>>24)&0xff) | // move byte 3 to byte 0 3572 ((volumeValuesCount<<8)&0xff0000) | // move byte 1 to byte 2 3573 ((volumeValuesCount>>8)&0xff00) | // move byte 2 to byte 1 3574 ((volumeValuesCount<<24)&0xff000000); // byte 0 to byte 3 3575 3576 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&volumeValuesCount, 3577 sizeof(M4OSA_UInt32) ); 3578 if ( err != M4NO_ERROR) { 3579 jniThrowException(pEnv, "java/lang/IOException", "file write failed"); 3580 } 3581 } 3582 3583 /****************************************************************************** 3584 CLOSE AND FREE ALLOCATIONS 3585 *******************************************************************************/ 3586 free(bufferIn.m_dataAddress); 3587 M4OSA_fileReadClose(inputFileHandle); 3588 M4OSA_fileWriteClose(outFileHandle); 3589 /* final finish callback */ 3590 pEnv->CallVoidMethod(pContext->engine, pContext->onAudioGraphProgressUpdateMethodId, 100, 0); 3591 3592 /* EXIT */ 3593 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "EXIT - M4MA_generateAudioGraphFile"); 3594 3595 return err; 3596 } 3597 3598 static int videoEditor_generateAudioWaveFormSync (JNIEnv* pEnv, jobject thiz, 3599 jstring pcmfilePath, 3600 jstring outGraphfilePath, 3601 jint frameDuration, jint channels, 3602 jint samplesCount) 3603 { 3604 M4OSA_ERR result = M4NO_ERROR; 3605 ManualEditContext* pContext = M4OSA_NULL; 3606 bool needToBeLoaded = true; 3607 const char *pPCMFilePath, *pStringOutAudioGraphFile; 3608 3609 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3610 "videoEditor_generateAudioWaveFormSync() "); 3611 3612 /* Get the context. */ 3613 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); 3614 if (pContext == M4OSA_NULL) { 3615 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3616 "videoEditor_generateAudioWaveFormSync() - pContext is NULL "); 3617 } 3618 3619 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3620 "videoEditor_generateAudioWaveFormSync Retrieving pStringOutAudioGraphFile"); 3621 3622 pPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL); 3623 if (pPCMFilePath == M4OSA_NULL) { 3624 jniThrowException(pEnv, "java/lang/RuntimeException", 3625 "Input string PCMFilePath is null"); 3626 result = M4ERR_PARAMETER; 3627 goto out; 3628 } 3629 3630 pStringOutAudioGraphFile = pEnv->GetStringUTFChars(outGraphfilePath, NULL); 3631 if (pStringOutAudioGraphFile == M4OSA_NULL) { 3632 jniThrowException(pEnv, "java/lang/RuntimeException", 3633 "Input string outGraphfilePath is null"); 3634 result = M4ERR_PARAMETER; 3635 goto out2; 3636 } 3637 3638 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3639 "videoEditor_generateAudioWaveFormSync Generate the waveform data %s %d %d %d", 3640 pStringOutAudioGraphFile, frameDuration, channels, samplesCount); 3641 3642 /* Generate the waveform */ 3643 result = M4MA_generateAudioGraphFile(pEnv, (M4OSA_Char*) pPCMFilePath, 3644 (M4OSA_Char*) pStringOutAudioGraphFile, 3645 (M4OSA_UInt32) samplesCount, 3646 (M4OSA_UInt32) channels, 3647 (M4OSA_UInt32)frameDuration, 3648 pContext); 3649 3650 pEnv->ReleaseStringUTFChars(outGraphfilePath, pStringOutAudioGraphFile); 3651 3652 out2: 3653 if (pPCMFilePath != NULL) { 3654 pEnv->ReleaseStringUTFChars(pcmfilePath, pPCMFilePath); 3655 } 3656 3657 out: 3658 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3659 "videoEditor_generateAudioWaveFormSync pContext->bSkipState "); 3660 3661 return result; 3662 } 3663 3664 /******** End Audio Graph *******/ 3665 jint JNI_OnLoad( 3666 JavaVM* pVm, 3667 void* pReserved) 3668 { 3669 void* pEnv = NULL; 3670 bool needToBeInitialized = true; 3671 jint result = -1; 3672 3673 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "JNI_OnLoad()"); 3674 3675 // Add a text marker (the condition must always be true). 3676 ADD_TEXT_MARKER_FUN(NULL != pVm) 3677 3678 // Check the JNI version. 3679 if (pVm->GetEnv(&pEnv, JNI_VERSION_1_4) == JNI_OK) 3680 { 3681 // Add a code marker (the condition must always be true). 3682 ADD_CODE_MARKER_FUN(NULL != pEnv) 3683 3684 // Register the manual edit JNI methods. 3685 if (videoEditor_registerManualEditMethods((JNIEnv*)pEnv) == 0) 3686 { 3687 // Initialize the classes. 3688 videoEditClasses_init(&needToBeInitialized, (JNIEnv*)pEnv); 3689 if (needToBeInitialized) 3690 { 3691 // Success, return valid version number. 3692 result = JNI_VERSION_1_4; 3693 } 3694 } 3695 } 3696 3697 // Return the result. 3698 return(result); 3699 } 3700 3701