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