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