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