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