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