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