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