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