VideoEditorMain.cpp revision 1f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0
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->GetIntField(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->GetIntField(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->GetIntField(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->GetIntField(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->GetIntField(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 50 2635 progressBase = 0; 2636 2637 // Set the text rendering function. 2638 if (M4OSA_NULL != pContext->pTextRendererFunction) 2639 { 2640 // Use the text renderer function in the library. 2641 pContext->pEditSettings->xVSS.pTextRenderingFct = pContext->pTextRendererFunction; 2642 } 2643 else 2644 { 2645 // Use the internal text renderer function. 2646 pContext->pEditSettings->xVSS.pTextRenderingFct = videoEditor_getTextRgbBufferFct; 2647 } 2648 2649 // Send the command. 2650 LOGV("videoEditor_processClip ITEM %d Calling M4xVSS_SendCommand()", unuseditemID); 2651 result = M4xVSS_SendCommand(pContext->engineContext, pContext->pEditSettings); 2652 LOGV("videoEditor_processClip ITEM %d M4xVSS_SendCommand() returned 0x%x", 2653 unuseditemID, (unsigned int) result); 2654 2655 // Remove warnings indications (we only care about errors here) 2656 if ((result == M4VSS3GPP_WAR_TRANSCODING_NECESSARY) 2657 || (result == M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED)) { 2658 result = M4NO_ERROR; 2659 } 2660 2661 // Send the first progress indication (=0) 2662 LOGV("VERY FIRST PROGRESS videoEditor_processClip ITEM %d Progress indication %d", 2663 unuseditemID, progress); 2664 pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId, 2665 unuseditemID, progress); 2666 2667 // Check if a task is being performed. 2668 // ??? ADD STOPPING MECHANISM 2669 LOGV("videoEditor_processClip Entering processing loop"); 2670 while((result == M4NO_ERROR) 2671 &&(pContext->state!=ManualEditState_SAVED) 2672 &&(pContext->state!=ManualEditState_STOPPING)) { 2673 2674 // Perform the next processing step. 2675 //LOGV("LVME_processClip Entering M4xVSS_Step()"); 2676 result = M4xVSS_Step(pContext->engineContext, &progress); 2677 //LOGV("LVME_processClip M4xVSS_Step() returned 0x%x", (unsigned int)result); 2678 2679 // Log the the 1 % .. 100 % progress after processing. 2680 progress = progressBase + progress/2; 2681 if (progress != lastProgress) 2682 { 2683 // Send a progress notification. 2684 LOGV("videoEditor_processClip ITEM %d Progress indication %d", 2685 unuseditemID, progress); 2686 pEnv->CallVoidMethod(pContext->engine, 2687 pContext->onProgressUpdateMethodId, 2688 unuseditemID, progress); 2689 lastProgress = progress; 2690 } 2691 2692 // Check if processing has been completed. 2693 if (result == completionResult) 2694 { 2695 // Set the state to the completions state. 2696 pContext->state = completionState; 2697 LOGV("videoEditor_processClip ITEM %d STATE changed to %d", 2698 unuseditemID, pContext->state); 2699 2700 // Reset progress indication, as we switch to next state 2701 lastProgress = 0; 2702 2703 // Reset error code, as we start a new round of processing 2704 result = M4NO_ERROR; 2705 2706 // Check if we are analyzing input 2707 if (pContext->state == ManualEditState_OPENED) { 2708 // File is opened, we must start saving it 2709 LOGV("videoEditor_processClip Calling M4xVSS_SaveStart()"); 2710 result = M4xVSS_SaveStart(pContext->engineContext, 2711 (M4OSA_Char*)pContext->pEditSettings->pOutputFile, 2712 (M4OSA_UInt32)pContext->pEditSettings->uiOutputPathSize); 2713 LOGV("videoEditor_processClip ITEM %d SaveStart() returned 0x%x", 2714 unuseditemID, (unsigned int) result); 2715 2716 // Set the state to saving. 2717 pContext->state = ManualEditState_SAVING; 2718 completionState = ManualEditState_SAVED; 2719 completionResult = M4VSS3GPP_WAR_SAVING_DONE; 2720 errorState = ManualEditState_SAVING_ERROR; 2721 2722 // While saving progress goes from 50 to 100 2723 progressBase = 50; 2724 } 2725 // Check if we encoding is ongoing 2726 else if (pContext->state == ManualEditState_SAVED) { 2727 if (progress != 100) { 2728 // Send a progress notification. 2729 progress = 100; 2730 LOGI("videoEditor_processClip ITEM %d Last progress indication %d", 2731 unuseditemID, progress); 2732 pEnv->CallVoidMethod(pContext->engine, 2733 pContext->onProgressUpdateMethodId, 2734 unuseditemID, progress); 2735 } 2736 2737 // Stop the encoding. 2738 LOGV("videoEditor_processClip Calling M4xVSS_SaveStop()"); 2739 result = M4xVSS_SaveStop(pContext->engineContext); 2740 LOGV("videoEditor_processClip M4xVSS_SaveStop() returned 0x%x", result); 2741 } 2742 // Other states are unexpected 2743 else { 2744 result = M4ERR_STATE; 2745 LOGE("videoEditor_processClip ITEM %d State ERROR 0x%x", 2746 unuseditemID, (unsigned int) result); 2747 } 2748 } 2749 2750 // Check if an error occurred. 2751 if (result != M4NO_ERROR) 2752 { 2753 // Set the state to the error state. 2754 pContext->state = errorState; 2755 2756 // Log the result. 2757 LOGE("videoEditor_processClip ITEM %d Processing ERROR 0x%x", 2758 unuseditemID, (unsigned int) result); 2759 } 2760 } 2761 2762 // Return the error result 2763 LOGE("videoEditor_processClip ITEM %d END 0x%x", unuseditemID, (unsigned int) result); 2764 return result; 2765} 2766/*+ PROGRESS CB */ 2767 2768static int 2769videoEditor_generateClip( 2770 JNIEnv* pEnv, 2771 jobject thiz, 2772 jobject settings) { 2773 bool loaded = true; 2774 ManualEditContext* pContext = M4OSA_NULL; 2775 M4OSA_ERR result = M4NO_ERROR; 2776 2777 LOGV("videoEditor_generateClip START"); 2778 2779 // Get the context. 2780 pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz); 2781 2782 Mutex::Autolock autoLock(pContext->mLock); 2783 2784 // Validate the settings parameter. 2785 videoEditJava_checkAndThrowIllegalArgumentException(&loaded, pEnv, 2786 (NULL == settings), 2787 "settings is null"); 2788 2789 // Make sure that the context was set. 2790 videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv, 2791 (M4OSA_NULL == pContext), 2792 "not initialized"); 2793 2794 // Load the clip settings 2795 LOGV("videoEditor_generateClip Calling videoEditor_loadSettings"); 2796 videoEditor_loadSettings(pEnv, thiz, settings); 2797 LOGV("videoEditor_generateClip videoEditor_loadSettings returned"); 2798 2799 // Generate the clip 2800 LOGV("videoEditor_generateClip Calling LVME_processClip"); 2801 result = videoEditor_processClip(pEnv, thiz, 0 /*item id is unused*/); 2802 LOGV("videoEditor_generateClip videoEditor_processClip returned 0x%x", result); 2803 2804 if (pContext->state != ManualEditState_INITIALIZED) { 2805 // Free up memory (whatever the result) 2806 videoEditor_unloadSettings(pEnv, thiz); 2807 } 2808 2809 LOGV("videoEditor_generateClip END 0x%x", (unsigned int) result); 2810 return result; 2811} 2812 2813static void 2814videoEditor_loadSettings( 2815 JNIEnv* pEnv, 2816 jobject thiz, 2817 jobject settings) 2818{ 2819 bool needToBeLoaded = true; 2820 ManualEditContext* pContext = M4OSA_NULL; 2821 2822 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_loadSettings()"); 2823 2824 // Add a code marker (the condition must always be true). 2825 ADD_CODE_MARKER_FUN(NULL != pEnv) 2826 2827 // Get the context. 2828 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, 2829 pEnv, thiz); 2830 2831 // Validate the settings parameter. 2832 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, 2833 (NULL == settings), 2834 "settings is null"); 2835 2836 // Make sure that the context was set. 2837 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2838 (M4OSA_NULL == pContext), 2839 "not initialized"); 2840 2841 // Check if the context is valid (required because the context is dereferenced). 2842 if (needToBeLoaded) 2843 { 2844 // Make sure that we are in a correct state. 2845 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, 2846 (pContext->state != ManualEditState_INITIALIZED), 2847 "settings already loaded"); 2848 2849 // Retrieve the edit settings. 2850 if(pContext->pEditSettings != M4OSA_NULL) { 2851 videoEditClasses_freeEditSettings(&pContext->pEditSettings); 2852 pContext->pEditSettings = M4OSA_NULL; 2853 } 2854 videoEditClasses_getEditSettings(&needToBeLoaded, pEnv, settings, 2855 &pContext->pEditSettings,true); 2856 } 2857 2858 // Check if the edit settings could be retrieved. 2859 if (needToBeLoaded) 2860 { 2861 // Log the edit settings. 2862 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "inside load settings"); 2863 VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings); 2864 } 2865 LOGV("videoEditor_loadSettings END"); 2866} 2867 2868 2869 2870static void 2871videoEditor_unloadSettings( 2872 JNIEnv* pEnv, 2873 jobject thiz) 2874{ 2875 bool needToBeUnLoaded = true; 2876 ManualEditContext* pContext = M4OSA_NULL; 2877 M4OSA_ERR result = M4NO_ERROR; 2878 2879 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_unloadSettings()"); 2880 2881 // Get the context. 2882 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeUnLoaded, pEnv, thiz); 2883 2884 // Make sure that the context was set. 2885 videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv, 2886 (M4OSA_NULL == pContext), 2887 "not initialized"); 2888 2889 // Check if the context is valid (required because the context is dereferenced). 2890 if (needToBeUnLoaded) 2891 { 2892 LOGV("videoEditor_unloadSettings state %d", pContext->state); 2893 // Make sure that we are in a correct state. 2894 videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv, 2895 ((pContext->state != ManualEditState_ANALYZING ) && 2896 (pContext->state != ManualEditState_ANALYZING_ERROR) && 2897 (pContext->state != ManualEditState_OPENED ) && 2898 (pContext->state != ManualEditState_SAVING_ERROR ) && 2899 (pContext->state != ManualEditState_SAVED ) && 2900 (pContext->state != ManualEditState_STOPPING ) ), 2901 "videoEditor_unloadSettings no load settings in progress"); 2902 } 2903 2904 // Check if we are in a correct state. 2905 if (needToBeUnLoaded) 2906 { 2907 // Check if the thread could be stopped. 2908 if (needToBeUnLoaded) 2909 { 2910 // Close the command. 2911 LOGV("videoEditor_unloadSettings Calling M4xVSS_CloseCommand()"); 2912 result = M4xVSS_CloseCommand(pContext->engineContext); 2913 LOGV("videoEditor_unloadSettings M4xVSS_CloseCommand() returned 0x%x", 2914 (unsigned int)result); 2915 2916 // Check if the command could be closed. 2917 videoEditJava_checkAndThrowRuntimeException(&needToBeUnLoaded, pEnv, 2918 (M4NO_ERROR != result), result); 2919 } 2920 2921 // Check if the command could be closed. 2922 if (needToBeUnLoaded) 2923 { 2924 // Free the edit settings. 2925 //videoEditClasses_freeEditSettings(&pContext->pEditSettings); 2926 2927 // Reset the thread result. 2928 pContext->threadResult = M4NO_ERROR; 2929 2930 // Reset the thread progress. 2931 pContext->threadProgress = 0; 2932 2933 // Set the state to initialized. 2934 pContext->state = ManualEditState_INITIALIZED; 2935 } 2936 } 2937} 2938 2939static void 2940videoEditor_stopEncoding( 2941 JNIEnv* pEnv, 2942 jobject thiz) 2943{ 2944 bool stopped = true; 2945 ManualEditContext* pContext = M4OSA_NULL; 2946 M4OSA_ERR result = M4NO_ERROR; 2947 2948 LOGV("videoEditor_stopEncoding START"); 2949 2950 // Get the context. 2951 pContext = (ManualEditContext*)videoEditClasses_getContext(&stopped, pEnv, thiz); 2952 2953 // Change state and get Lock 2954 // This will ensure the generateClip function exits 2955 pContext->state = ManualEditState_STOPPING; 2956 Mutex::Autolock autoLock(pContext->mLock); 2957 2958 // Make sure that the context was set. 2959 videoEditJava_checkAndThrowIllegalStateException(&stopped, pEnv, 2960 (M4OSA_NULL == pContext), 2961 "not initialized"); 2962 2963 if (stopped) { 2964 2965 // Check if the command should be closed. 2966 if (pContext->state != ManualEditState_INITIALIZED) 2967 { 2968 // Close the command. 2969 LOGV("videoEditor_stopEncoding Calling M4xVSS_CloseCommand()"); 2970 result = M4xVSS_CloseCommand(pContext->engineContext); 2971 LOGV("videoEditor_stopEncoding M4xVSS_CloseCommand() returned 0x%x", 2972 (unsigned int)result); 2973 } 2974 2975 // Check if the command could be closed. 2976 videoEditJava_checkAndThrowRuntimeException(&stopped, pEnv, 2977 (M4NO_ERROR != result), result); 2978 2979 // Free the edit settings. 2980 videoEditClasses_freeEditSettings(&pContext->pEditSettings); 2981 2982 // Set the state to initialized. 2983 pContext->state = ManualEditState_INITIALIZED; 2984 } 2985 2986} 2987 2988static void 2989videoEditor_release( 2990 JNIEnv* pEnv, 2991 jobject thiz) 2992{ 2993 bool released = true; 2994 ManualEditContext* pContext = M4OSA_NULL; 2995 M4OSA_ERR result = M4NO_ERROR; 2996 2997 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_release()"); 2998 2999 // Add a text marker (the condition must always be true). 3000 ADD_TEXT_MARKER_FUN(NULL != pEnv) 3001 3002 // Get the context. 3003 pContext = (ManualEditContext*)videoEditClasses_getContext(&released, pEnv, thiz); 3004 3005 // If context is not set, return (we consider release already happened) 3006 if (pContext == NULL) { 3007 LOGV("videoEditor_release Nothing to do, context is aleady NULL"); 3008 return; 3009 } 3010 3011 3012 // Check if the context is valid (required because the context is dereferenced). 3013 if (released) 3014 { 3015 if (pContext->state != ManualEditState_INITIALIZED) 3016 { 3017 // Change state and get Lock 3018 // This will ensure the generateClip function exits if it is running 3019 pContext->state = ManualEditState_STOPPING; 3020 Mutex::Autolock autoLock(pContext->mLock); 3021 } 3022 3023 // Reset the context. 3024 videoEditClasses_setContext(&released, pEnv, thiz, (void *)M4OSA_NULL); 3025 3026 // Check if the command should be closed. 3027 if (pContext->state != ManualEditState_INITIALIZED) 3028 { 3029 // Close the command. 3030 LOGV("videoEditor_release Calling M4xVSS_CloseCommand() state =%d", 3031 pContext->state); 3032 result = M4xVSS_CloseCommand(pContext->engineContext); 3033 LOGV("videoEditor_release M4xVSS_CloseCommand() returned 0x%x", 3034 (unsigned int)result); 3035 3036 // Check if the command could be closed. 3037 videoEditJava_checkAndThrowRuntimeException(&released, pEnv, 3038 (M4NO_ERROR != result), result); 3039 } 3040 3041 // Cleanup the engine. 3042 LOGV("videoEditor_release Calling M4xVSS_CleanUp()"); 3043 result = M4xVSS_CleanUp(pContext->engineContext); 3044 LOGV("videoEditor_release M4xVSS_CleanUp() returned 0x%x", (unsigned int)result); 3045 3046 // Check if the cleanup succeeded. 3047 videoEditJava_checkAndThrowRuntimeException(&released, pEnv, 3048 (M4NO_ERROR != result), result); 3049 3050 // Free the edit settings. 3051 videoEditClasses_freeEditSettings(&pContext->pEditSettings); 3052 pContext->pEditSettings = M4OSA_NULL; 3053 3054 3055 if(pContext->mPreviewController != M4OSA_NULL) 3056 { 3057 delete pContext->mPreviewController; 3058 pContext->mPreviewController = M4OSA_NULL; 3059 } 3060 3061 // Free the mAudioSettings context. 3062 if(pContext->mAudioSettings != M4OSA_NULL) 3063 { 3064 if (pContext->mAudioSettings->pFile != NULL) { 3065 free(pContext->mAudioSettings->pFile); 3066 pContext->mAudioSettings->pFile = M4OSA_NULL; 3067 } 3068 if (pContext->mAudioSettings->pPCMFilePath != NULL) { 3069 free(pContext->mAudioSettings->pPCMFilePath); 3070 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL; 3071 } 3072 3073 free(pContext->mAudioSettings); 3074 pContext->mAudioSettings = M4OSA_NULL; 3075 } 3076 videoEditor_freeContext(pEnv, &pContext); 3077 } 3078} 3079 3080static int 3081videoEditor_registerManualEditMethods( 3082 JNIEnv* pEnv) 3083{ 3084 int result = -1; 3085 3086 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3087 "videoEditor_registerManualEditMethods()"); 3088 3089 // Look up the engine class 3090 jclass engineClazz = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME); 3091 3092 // Clear any resulting exceptions. 3093 pEnv->ExceptionClear(); 3094 3095 // Check if the engine class was found. 3096 if (NULL != engineClazz) 3097 { 3098 // Register all the methods. 3099 if (pEnv->RegisterNatives(engineClazz, gManualEditMethods, 3100 sizeof(gManualEditMethods) / sizeof(gManualEditMethods[0])) == JNI_OK) 3101 { 3102 // Success. 3103 result = 0; 3104 } 3105 } 3106 3107 // Return the result. 3108 return(result); 3109} 3110 3111/*******Audio Graph*******/ 3112 3113static M4OSA_UInt32 getDecibelSound(M4OSA_UInt32 value) 3114{ 3115 int dbSound = 1; 3116 3117 if (value == 0) return 0; 3118 3119 if (value > 0x4000 && value <= 0x8000) // 32768 3120 dbSound = 90; 3121 else if (value > 0x2000 && value <= 0x4000) // 16384 3122 dbSound = 84; 3123 else if (value > 0x1000 && value <= 0x2000) // 8192 3124 dbSound = 78; 3125 else if (value > 0x0800 && value <= 0x1000) // 4028 3126 dbSound = 72; 3127 else if (value > 0x0400 && value <= 0x0800) // 2048 3128 dbSound = 66; 3129 else if (value > 0x0200 && value <= 0x0400) // 1024 3130 dbSound = 60; 3131 else if (value > 0x0100 && value <= 0x0200) // 512 3132 dbSound = 54; 3133 else if (value > 0x0080 && value <= 0x0100) // 256 3134 dbSound = 48; 3135 else if (value > 0x0040 && value <= 0x0080) // 128 3136 dbSound = 42; 3137 else if (value > 0x0020 && value <= 0x0040) // 64 3138 dbSound = 36; 3139 else if (value > 0x0010 && value <= 0x0020) // 32 3140 dbSound = 30; 3141 else if (value > 0x0008 && value <= 0x0010) //16 3142 dbSound = 24; 3143 else if (value > 0x0007 && value <= 0x0008) //8 3144 dbSound = 24; 3145 else if (value > 0x0003 && value <= 0x0007) // 4 3146 dbSound = 18; 3147 else if (value > 0x0001 && value <= 0x0003) //2 3148 dbSound = 12; 3149 else if (value > 0x000 && value == 0x0001) // 1 3150 dbSound = 6; 3151 else 3152 dbSound = 0; 3153 3154 return dbSound; 3155} 3156 3157typedef struct 3158{ 3159 M4OSA_UInt8 *m_dataAddress; 3160 M4OSA_UInt32 m_bufferSize; 3161} M4AM_Buffer; 3162 3163 3164M4OSA_UInt8 logLookUp[256] = { 31650,120,137,146,154,159,163,167,171,173,176,178,181,182,184,186,188,189,190,192,193, 3166194,195,196,198,199,199,200,201,202,203,204,205,205,206,207,207,208,209,209,210, 3167211,211,212,212,213,213,214,215,215,216,216,216,217,217,218,218,219,219,220,220, 3168220,221,221,222,222,222,223,223,223,224,224,224,225,225,225,226,226,226,227,227, 3169227,228,228,228,229,229,229,229,230,230,230,230,231,231,231,232,232,232,232,233, 3170233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236,236,237,237,237, 3171237,237,238,238,238,238,238,239,239,239,239,239,240,240,240,240,240,240,241,241, 3172241,241,241,241,242,242,242,242,242,242,243,243,243,243,243,243,244,244,244,244, 3173244,244,245,245,245,245,245,245,245,246,246,246,246,246,246,246,247,247,247,247, 3174247,247,247,247,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,250, 3175250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,252,252,252,252, 3176252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254, 3177254,254,254,254,255,255,255,255,255,255,255,255,255,255,255}; 3178 3179M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL, 3180 M4OSA_Char* pOutFileURL, 3181 M4OSA_UInt32 samplesPerValue, 3182 M4OSA_UInt32 channels, 3183 M4OSA_UInt32 frameDuration, 3184 ManualEditContext* pContext) 3185{ 3186 M4OSA_ERR err; 3187 M4OSA_Context outFileHandle = M4OSA_NULL; 3188 M4OSA_Context inputFileHandle = M4OSA_NULL; 3189 M4AM_Buffer bufferIn = {0, 0}; 3190 M4OSA_UInt32 peakVolumeDbValue = 0; 3191 M4OSA_UInt32 samplesCountInBytes= 0 , numBytesToRead = 0, index = 0; 3192 M4OSA_UInt32 writeCount = 0, samplesCountBigEndian = 0, volumeValuesCount = 0; 3193 M4OSA_Int32 seekPos = 0; 3194 M4OSA_UInt32 fileSize = 0; 3195 M4OSA_UInt32 totalBytesRead = 0; 3196 M4OSA_UInt32 prevProgress = 0; 3197 bool threadStarted = true; 3198 3199 int dbValue = 0; 3200 M4OSA_Int16 *ptr16 ; 3201 3202 jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME); 3203 videoEditJava_checkAndThrowIllegalStateException(&threadStarted, pEnv, 3204 (M4OSA_NULL == engineClass), 3205 "not initialized"); 3206 3207 /* register the call back function pointer */ 3208 pContext->onAudioGraphProgressUpdateMethodId = 3209 pEnv->GetMethodID(engineClass, "onAudioGraphExtractProgressUpdate", "(IZ)V"); 3210 3211 3212 /* ENTER */ 3213 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "ENTER - M4MA_generateAudioGraphFile"); 3214 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3215 "Audio Graph samplesPerValue %d channels %d", samplesPerValue, channels); 3216 3217 /****************************************************************************** 3218 OPEN INPUT AND OUTPUT FILES 3219 *******************************************************************************/ 3220 err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead); 3221 if (inputFileHandle == M4OSA_NULL) { 3222 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3223 "M4MA_generateAudioGraphFile: Cannot open input file 0x%lx", err); 3224 return err; 3225 } 3226 3227 /* get the file size for progress */ 3228 err = M4OSA_fileReadGetOption(inputFileHandle, M4OSA_kFileReadGetFileSize, 3229 (M4OSA_Void**)&fileSize); 3230 if ( err != M4NO_ERROR) { 3231 //LVMEL_LOG_ERROR("M4MA_generateAudioGraphFile : File write failed \n"); 3232 jniThrowException(pEnv, "java/lang/IOException", "file size get option failed"); 3233 //return -1; 3234 } 3235 3236 err = M4OSA_fileWriteOpen (&outFileHandle,(M4OSA_Char*) pOutFileURL, 3237 M4OSA_kFileCreate | M4OSA_kFileWrite); 3238 if (outFileHandle == M4OSA_NULL) { 3239 if (inputFileHandle != NULL) 3240 { 3241 M4OSA_fileReadClose(inputFileHandle); 3242 } 3243 return err; 3244 } 3245 3246 /****************************************************************************** 3247 PROCESS THE SAMPLES 3248 *******************************************************************************/ 3249 samplesCountInBytes = (samplesPerValue * sizeof(M4OSA_UInt16) * channels); 3250 3251 bufferIn.m_dataAddress = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(samplesCountInBytes*sizeof(M4OSA_UInt16), 0, 3252 (M4OSA_Char*)"AudioGraph" ); 3253 if ( bufferIn.m_dataAddress != M4OSA_NULL) { 3254 bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16); 3255 } else { 3256 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3257 "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%lx", 3258 M4ERR_ALLOC); 3259 return M4ERR_ALLOC; 3260 } 3261 /* sample to be converted to BIG endian ; store the frame duration */ 3262 samplesCountBigEndian = ((frameDuration>>24)&0xff) | // move byte 3 to byte 0 3263 ((frameDuration<<8)&0xff0000) | // move byte 1 to byte 2 3264 ((frameDuration>>8)&0xff00) | // move byte 2 to byte 1 3265 ((frameDuration<<24)&0xff000000); // byte 0 to byte 3 3266 3267 /* write the samples per value supplied to out file */ 3268 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian, 3269 sizeof(M4OSA_UInt32) ); 3270 if (err != M4NO_ERROR) { 3271 jniThrowException(pEnv, "java/lang/IOException", "file write failed"); 3272 } 3273 3274 3275 /* write UIn32 value 0 for no of values as place holder */ 3276 samplesCountBigEndian = 0; /* reusing local var */ 3277 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian, 3278 sizeof(M4OSA_UInt32) ); 3279 if (err != M4NO_ERROR) { 3280 jniThrowException(pEnv, "java/lang/IOException", "file write failed"); 3281 } 3282 3283 /* loop until EOF */ 3284 do 3285 { 3286 memset((void *)bufferIn.m_dataAddress,0,bufferIn.m_bufferSize); 3287 3288 numBytesToRead = samplesCountInBytes; 3289 3290 err = M4OSA_fileReadData( inputFileHandle, 3291 (M4OSA_MemAddr8)bufferIn.m_dataAddress, 3292 &numBytesToRead ); 3293 3294 if (err != M4NO_ERROR) { 3295 // if out value of bytes-read is 0, break 3296 if ( numBytesToRead == 0) { 3297 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%lx", 3298 numBytesToRead); 3299 break; /* stop if file is empty or EOF */ 3300 } 3301 } 3302 3303 ptr16 = (M4OSA_Int16*)bufferIn.m_dataAddress; 3304 3305 peakVolumeDbValue = 0; 3306 index = 0; 3307 3308 // loop through half the lenght frame bytes read 'cause its 16 bits samples 3309 while (index < (numBytesToRead / 2)) { 3310 /* absolute values of 16 bit sample */ 3311 if (ptr16[index] < 0) { 3312 ptr16[index] = -(ptr16[index]); 3313 } 3314 peakVolumeDbValue = (peakVolumeDbValue > (M4OSA_UInt32)ptr16[index] ?\ 3315 peakVolumeDbValue : (M4OSA_UInt32)ptr16[index]); 3316 index++; 3317 } 3318 3319 // move 7 bits , ignore sign bit 3320 dbValue = (peakVolumeDbValue >> 7); 3321 dbValue = logLookUp[(M4OSA_UInt8)dbValue]; 3322 3323 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&dbValue, sizeof(M4OSA_UInt8) ); 3324 if (err != M4NO_ERROR) { 3325 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3326 "M4MA_generateAudioGraphFile : File write failed"); 3327 break; 3328 } 3329 3330 volumeValuesCount ++; 3331 totalBytesRead += numBytesToRead; 3332 3333 if ((((totalBytesRead*100)/fileSize)) != prevProgress) { 3334 if ( (pContext->threadProgress != prevProgress) && (prevProgress != 0 )) { 3335 //pContext->threadProgress = prevProgress; 3336 //onWveformProgressUpdateMethodId(prevProgress, 0); 3337 //LVME_callAudioGraphOnProgressUpdate(pContext, 0, prevProgress); 3338 pEnv->CallVoidMethod(pContext->engine, 3339 pContext->onAudioGraphProgressUpdateMethodId, 3340 prevProgress, 0); 3341 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pContext->threadProgress %d", 3342 prevProgress); 3343 } 3344 } 3345 prevProgress = (((totalBytesRead*100)/fileSize)); 3346 3347 } while (numBytesToRead != 0); 3348 3349 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%lx", volumeValuesCount); 3350 3351 /* if some error occured in fwrite */ 3352 if (numBytesToRead != 0) { 3353 //err = -1; 3354 jniThrowException(pEnv, "java/lang/IOException", "numBytesToRead != 0 ; file write failed"); 3355 } 3356 3357 /* write the count in place holder after seek */ 3358 seekPos = sizeof(M4OSA_UInt32); 3359 err = M4OSA_fileWriteSeek(outFileHandle, M4OSA_kFileSeekBeginning, 3360 &seekPos /* after samples per value */); 3361 if ( err != M4NO_ERROR) { 3362 jniThrowException(pEnv, "java/lang/IOException", "file seek failed"); 3363 } else { 3364 volumeValuesCount = ((volumeValuesCount>>24)&0xff) | // move byte 3 to byte 0 3365 ((volumeValuesCount<<8)&0xff0000) | // move byte 1 to byte 2 3366 ((volumeValuesCount>>8)&0xff00) | // move byte 2 to byte 1 3367 ((volumeValuesCount<<24)&0xff000000); // byte 0 to byte 3 3368 3369 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&volumeValuesCount, 3370 sizeof(M4OSA_UInt32) ); 3371 if ( err != M4NO_ERROR) { 3372 jniThrowException(pEnv, "java/lang/IOException", "file write failed"); 3373 } 3374 } 3375 3376 /****************************************************************************** 3377 CLOSE AND FREE ALLOCATIONS 3378 *******************************************************************************/ 3379 free(bufferIn.m_dataAddress); 3380 M4OSA_fileReadClose(inputFileHandle); 3381 M4OSA_fileWriteClose(outFileHandle); 3382 /* final finish callback */ 3383 pEnv->CallVoidMethod(pContext->engine, pContext->onAudioGraphProgressUpdateMethodId, 100, 0); 3384 3385 /* EXIT */ 3386 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "EXIT - M4MA_generateAudioGraphFile"); 3387 3388 return err; 3389} 3390 3391static int videoEditor_generateAudioWaveFormSync (JNIEnv* pEnv, jobject thiz, 3392 jstring pcmfilePath, 3393 jstring outGraphfilePath, 3394 jint frameDuration, jint channels, 3395 jint samplesCount) 3396{ 3397 M4OSA_ERR result = M4NO_ERROR; 3398 ManualEditContext* pContext = M4OSA_NULL; 3399 bool needToBeLoaded = true; 3400 3401 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3402 "videoEditor_generateAudioWaveFormSync() "); 3403 3404 /* Get the context. */ 3405 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz); 3406 if (pContext == M4OSA_NULL) { 3407 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3408 "videoEditor_generateAudioWaveFormSync() - pContext is NULL "); 3409 } 3410 3411 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3412 "videoEditor_generateAudioWaveFormSync Retrieving pStringOutAudioGraphFile"); 3413 3414 const char *pPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL); 3415 if (pPCMFilePath == M4OSA_NULL) { 3416 if (pEnv != NULL) { 3417 jniThrowException(pEnv, "java/lang/RuntimeException", 3418 "Input string PCMFilePath is null"); 3419 } 3420 } 3421 3422 const char *pStringOutAudioGraphFile = pEnv->GetStringUTFChars(outGraphfilePath, NULL); 3423 if (pStringOutAudioGraphFile == M4OSA_NULL) { 3424 if (pEnv != NULL) { 3425 jniThrowException(pEnv, "java/lang/RuntimeException", 3426 "Input string outGraphfilePath is null"); 3427 } 3428 } 3429 3430 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3431 "videoEditor_generateAudioWaveFormSync Generate the waveform data %s %d %d %d", 3432 pStringOutAudioGraphFile, frameDuration, channels, samplesCount); 3433 3434 /* Generate the waveform */ 3435 result = M4MA_generateAudioGraphFile(pEnv, (M4OSA_Char*) pPCMFilePath, 3436 (M4OSA_Char*) pStringOutAudioGraphFile, 3437 (M4OSA_UInt32) samplesCount, 3438 (M4OSA_UInt32) channels, 3439 (M4OSA_UInt32)frameDuration, 3440 pContext); 3441 3442 if (pStringOutAudioGraphFile != NULL) { 3443 pEnv->ReleaseStringUTFChars(outGraphfilePath, pStringOutAudioGraphFile); 3444 } 3445 3446 if (pPCMFilePath != NULL) { 3447 pEnv->ReleaseStringUTFChars(pcmfilePath, pPCMFilePath); 3448 } 3449 3450 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", 3451 "videoEditor_generateAudioWaveFormSync pContext->bSkipState "); 3452 3453 return result; 3454} 3455 3456/******** End Audio Graph *******/ 3457jint JNI_OnLoad( 3458 JavaVM* pVm, 3459 void* pReserved) 3460{ 3461 void* pEnv = NULL; 3462 bool needToBeInitialized = true; 3463 jint result = -1; 3464 3465 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "JNI_OnLoad()"); 3466 3467 // Add a text marker (the condition must always be true). 3468 ADD_TEXT_MARKER_FUN(NULL != pVm) 3469 3470 // Check the JNI version. 3471 if (pVm->GetEnv(&pEnv, JNI_VERSION_1_4) == JNI_OK) 3472 { 3473 // Add a code marker (the condition must always be true). 3474 ADD_CODE_MARKER_FUN(NULL != pEnv) 3475 3476 // Register the manual edit JNI methods. 3477 if (videoEditor_registerManualEditMethods((JNIEnv*)pEnv) == 0) 3478 { 3479 // Initialize the classes. 3480 videoEditClasses_init(&needToBeInitialized, (JNIEnv*)pEnv); 3481 if (needToBeInitialized) 3482 { 3483 // Success, return valid version number. 3484 result = JNI_VERSION_1_4; 3485 } 3486 } 3487 } 3488 3489 // Return the result. 3490 return(result); 3491} 3492 3493