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