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