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#define LOG_NDEBUG 1 18#define LOG_TAG "VideoEditorPreviewController" 19#include "VideoEditorPreviewController.h" 20 21namespace android { 22 23#define PREVIEW_THREAD_STACK_SIZE (65536) 24 25VideoEditorPreviewController::VideoEditorPreviewController() 26 : mCurrentPlayer(0), 27 mThreadContext(NULL), 28 mPlayerState(VePlayerIdle), 29 mPrepareReqest(M4OSA_FALSE), 30 mClipList(NULL), 31 mNumberClipsInStoryBoard(0), 32 mNumberClipsToPreview(0), 33 mStartingClipIndex(0), 34 mPreviewLooping(M4OSA_FALSE), 35 mCallBackAfterFrameCnt(0), 36 mEffectsSettings(NULL), 37 mNumberEffects(0), 38 mCurrentClipNumber(-1), 39 mClipTotalDuration(0), 40 mCurrentVideoEffect(VIDEO_EFFECT_NONE), 41 mBackgroundAudioSetting(NULL), 42 mAudioMixPCMFileHandle(NULL), 43 mTarget(NULL), 44 mJniCookie(NULL), 45 mJniCallback(NULL), 46 mCurrentPlayedDuration(0), 47 mCurrentClipDuration(0), 48 mVideoStoryBoardTimeMsUptoFirstPreviewClip(0), 49 mOverlayState(OVERLAY_CLEAR), 50 mActivePlayerIndex(0), 51 mOutputVideoWidth(0), 52 mOutputVideoHeight(0), 53 bStopThreadInProgress(false), 54 mSemThreadWait(NULL) { 55 LOGV("VideoEditorPreviewController"); 56 mRenderingMode = M4xVSS_kBlackBorders; 57 mIsFiftiesEffectStarted = false; 58 59 for (int i=0; i<NBPLAYER_INSTANCES; i++) { 60 mVePlayer[i] = NULL; 61 } 62} 63 64VideoEditorPreviewController::~VideoEditorPreviewController() { 65 M4OSA_UInt32 i = 0; 66 M4OSA_ERR err = M4NO_ERROR; 67 LOGV("~VideoEditorPreviewController"); 68 69 // Stop the thread if its still running 70 if(mThreadContext != NULL) { 71 err = M4OSA_threadSyncStop(mThreadContext); 72 if(err != M4NO_ERROR) { 73 LOGV("~VideoEditorPreviewController: error 0x%x \ 74 in trying to stop thread", err); 75 // Continue even if error 76 } 77 78 err = M4OSA_threadSyncClose(mThreadContext); 79 if(err != M4NO_ERROR) { 80 LOGE("~VideoEditorPreviewController: error 0x%x \ 81 in trying to close thread", (unsigned int) err); 82 // Continue even if error 83 } 84 85 mThreadContext = NULL; 86 } 87 88 for (int playerInst=0; playerInst<NBPLAYER_INSTANCES; 89 playerInst++) { 90 if(mVePlayer[playerInst] != NULL) { 91 LOGV("clearing mVePlayer %d", playerInst); 92 mVePlayer[playerInst].clear(); 93 } 94 } 95 96 if(mClipList != NULL) { 97 // Clean up 98 for(i=0;i<mNumberClipsInStoryBoard;i++) 99 { 100 if(mClipList[i]->pFile != NULL) { 101 free(mClipList[i]->pFile); 102 mClipList[i]->pFile = NULL; 103 } 104 105 free(mClipList[i]); 106 } 107 free(mClipList); 108 mClipList = NULL; 109 } 110 111 if(mEffectsSettings) { 112 for(i=0;i<mNumberEffects;i++) { 113 if(mEffectsSettings[i].xVSS.pFramingBuffer != NULL) { 114 free(mEffectsSettings[i].xVSS.pFramingBuffer->pac_data); 115 116 free(mEffectsSettings[i].xVSS.pFramingBuffer); 117 118 mEffectsSettings[i].xVSS.pFramingBuffer = NULL; 119 } 120 } 121 free(mEffectsSettings); 122 mEffectsSettings = NULL; 123 } 124 125 if (mAudioMixPCMFileHandle) { 126 err = M4OSA_fileReadClose (mAudioMixPCMFileHandle); 127 mAudioMixPCMFileHandle = M4OSA_NULL; 128 } 129 130 if (mBackgroundAudioSetting != NULL) { 131 free(mBackgroundAudioSetting); 132 mBackgroundAudioSetting = NULL; 133 } 134 135 if(mTarget != NULL) { 136 delete mTarget; 137 mTarget = NULL; 138 } 139 140 mOverlayState = OVERLAY_CLEAR; 141 142 LOGV("~VideoEditorPreviewController returns"); 143} 144 145M4OSA_ERR VideoEditorPreviewController::loadEditSettings( 146 M4VSS3GPP_EditSettings* pSettings,M4xVSS_AudioMixingSettings* bgmSettings) { 147 148 M4OSA_UInt32 i = 0, iClipDuration = 0, rgbSize = 0; 149 M4VIFI_UInt8 *tmp = NULL; 150 M4OSA_ERR err = M4NO_ERROR; 151 152 LOGV("loadEditSettings"); 153 LOGV("loadEditSettings Channels = %d, sampling Freq %d", 154 bgmSettings->uiNbChannels, bgmSettings->uiSamplingFrequency ); 155 bgmSettings->uiSamplingFrequency = 32000; 156 157 LOGV("loadEditSettings Channels = %d, sampling Freq %d", 158 bgmSettings->uiNbChannels, bgmSettings->uiSamplingFrequency ); 159 Mutex::Autolock autoLock(mLock); 160 161 // Clean up any previous Edit settings before loading new ones 162 mCurrentVideoEffect = VIDEO_EFFECT_NONE; 163 164 if(mAudioMixPCMFileHandle) { 165 err = M4OSA_fileReadClose (mAudioMixPCMFileHandle); 166 mAudioMixPCMFileHandle = M4OSA_NULL; 167 } 168 169 if(mBackgroundAudioSetting != NULL) { 170 free(mBackgroundAudioSetting); 171 mBackgroundAudioSetting = NULL; 172 } 173 174 if(mClipList != NULL) { 175 // Clean up 176 for(i=0;i<mNumberClipsInStoryBoard;i++) 177 { 178 if(mClipList[i]->pFile != NULL) { 179 free(mClipList[i]->pFile); 180 mClipList[i]->pFile = NULL; 181 } 182 183 free(mClipList[i]); 184 } 185 free(mClipList); 186 mClipList = NULL; 187 } 188 189 if(mEffectsSettings) { 190 for(i=0;i<mNumberEffects;i++) { 191 if(mEffectsSettings[i].xVSS.pFramingBuffer != NULL) { 192 free(mEffectsSettings[i].xVSS.pFramingBuffer->pac_data); 193 194 free(mEffectsSettings[i].xVSS.pFramingBuffer); 195 196 mEffectsSettings[i].xVSS.pFramingBuffer = NULL; 197 } 198 } 199 free(mEffectsSettings); 200 mEffectsSettings = NULL; 201 } 202 203 if(mClipList == NULL) { 204 mNumberClipsInStoryBoard = pSettings->uiClipNumber; 205 LOGV("loadEditSettings: # of Clips = %d", mNumberClipsInStoryBoard); 206 207 mClipList = (M4VSS3GPP_ClipSettings**)M4OSA_32bitAlignedMalloc( 208 sizeof(M4VSS3GPP_ClipSettings*)*pSettings->uiClipNumber, M4VS, 209 (M4OSA_Char*)"LvPP, copy of pClipList"); 210 211 if(NULL == mClipList) { 212 LOGE("loadEditSettings: Malloc error"); 213 return M4ERR_ALLOC; 214 } 215 memset((void *)mClipList,0, 216 sizeof(M4VSS3GPP_ClipSettings*)*pSettings->uiClipNumber); 217 218 for(i=0;i<pSettings->uiClipNumber;i++) { 219 220 // Allocate current clip 221 mClipList[i] = 222 (M4VSS3GPP_ClipSettings*)M4OSA_32bitAlignedMalloc( 223 sizeof(M4VSS3GPP_ClipSettings),M4VS,(M4OSA_Char*)"clip settings"); 224 225 if(mClipList[i] == NULL) { 226 227 LOGE("loadEditSettings: Allocation error for mClipList[%d]", (int)i); 228 return M4ERR_ALLOC; 229 } 230 // Copy plain structure 231 memcpy((void *)mClipList[i], 232 (void *)pSettings->pClipList[i], 233 sizeof(M4VSS3GPP_ClipSettings)); 234 235 if(NULL != pSettings->pClipList[i]->pFile) { 236 mClipList[i]->pFile = (M4OSA_Char*)M4OSA_32bitAlignedMalloc( 237 pSettings->pClipList[i]->filePathSize, M4VS, 238 (M4OSA_Char*)"pClipSettingsDest->pFile"); 239 240 if(NULL == mClipList[i]->pFile) 241 { 242 LOGE("loadEditSettings : ERROR allocating filename"); 243 return M4ERR_ALLOC; 244 } 245 246 memcpy((void *)mClipList[i]->pFile, 247 (void *)pSettings->pClipList[i]->pFile, 248 pSettings->pClipList[i]->filePathSize); 249 } 250 else { 251 LOGE("NULL file path"); 252 return M4ERR_PARAMETER; 253 } 254 255 // Calculate total duration of all clips 256 iClipDuration = pSettings->pClipList[i]->uiEndCutTime - 257 pSettings->pClipList[i]->uiBeginCutTime; 258 259 mClipTotalDuration = mClipTotalDuration+iClipDuration; 260 } 261 } 262 263 if(mEffectsSettings == NULL) { 264 mNumberEffects = pSettings->nbEffects; 265 LOGV("loadEditSettings: mNumberEffects = %d", mNumberEffects); 266 267 if(mNumberEffects != 0) { 268 mEffectsSettings = (M4VSS3GPP_EffectSettings*)M4OSA_32bitAlignedMalloc( 269 mNumberEffects*sizeof(M4VSS3GPP_EffectSettings), 270 M4VS, (M4OSA_Char*)"effects settings"); 271 272 if(mEffectsSettings == NULL) { 273 LOGE("loadEffectsSettings: Allocation error"); 274 return M4ERR_ALLOC; 275 } 276 277 memset((void *)mEffectsSettings,0, 278 mNumberEffects*sizeof(M4VSS3GPP_EffectSettings)); 279 280 for(i=0;i<mNumberEffects;i++) { 281 282 mEffectsSettings[i].xVSS.pFramingFilePath = NULL; 283 mEffectsSettings[i].xVSS.pFramingBuffer = NULL; 284 mEffectsSettings[i].xVSS.pTextBuffer = NULL; 285 286 memcpy((void *)&(mEffectsSettings[i]), 287 (void *)&(pSettings->Effects[i]), 288 sizeof(M4VSS3GPP_EffectSettings)); 289 290 if(pSettings->Effects[i].VideoEffectType == 291 (M4VSS3GPP_VideoEffectType)M4xVSS_kVideoEffectType_Framing) { 292 // Allocate the pFraming RGB buffer 293 mEffectsSettings[i].xVSS.pFramingBuffer = 294 (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(sizeof(M4VIFI_ImagePlane), 295 M4VS, (M4OSA_Char*)"lvpp framing buffer"); 296 297 if(mEffectsSettings[i].xVSS.pFramingBuffer == NULL) { 298 LOGE("loadEffectsSettings:Alloc error for pFramingBuf"); 299 free(mEffectsSettings); 300 mEffectsSettings = NULL; 301 return M4ERR_ALLOC; 302 } 303 304 // Allocate the pac_data (RGB) 305 if(pSettings->Effects[i].xVSS.rgbType == M4VSS3GPP_kRGB565){ 306 rgbSize = 307 pSettings->Effects[i].xVSS.pFramingBuffer->u_width * 308 pSettings->Effects[i].xVSS.pFramingBuffer->u_height*2; 309 } 310 else if( 311 pSettings->Effects[i].xVSS.rgbType == M4VSS3GPP_kRGB888) { 312 rgbSize = 313 pSettings->Effects[i].xVSS.pFramingBuffer->u_width * 314 pSettings->Effects[i].xVSS.pFramingBuffer->u_height*3; 315 } 316 else { 317 LOGE("loadEffectsSettings: wrong RGB type"); 318 free(mEffectsSettings); 319 mEffectsSettings = NULL; 320 return M4ERR_PARAMETER; 321 } 322 323 tmp = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(rgbSize, M4VS, 324 (M4OSA_Char*)"framing buffer pac_data"); 325 326 if(tmp == NULL) { 327 LOGE("loadEffectsSettings:Alloc error pFramingBuf pac"); 328 free(mEffectsSettings); 329 mEffectsSettings = NULL; 330 free(mEffectsSettings[i].xVSS.pFramingBuffer); 331 332 mEffectsSettings[i].xVSS.pFramingBuffer = NULL; 333 return M4ERR_ALLOC; 334 } 335 /* Initialize the pFramingBuffer*/ 336 mEffectsSettings[i].xVSS.pFramingBuffer->pac_data = tmp; 337 mEffectsSettings[i].xVSS.pFramingBuffer->u_height = 338 pSettings->Effects[i].xVSS.pFramingBuffer->u_height; 339 340 mEffectsSettings[i].xVSS.pFramingBuffer->u_width = 341 pSettings->Effects[i].xVSS.pFramingBuffer->u_width; 342 343 mEffectsSettings[i].xVSS.pFramingBuffer->u_stride = 344 pSettings->Effects[i].xVSS.pFramingBuffer->u_stride; 345 346 mEffectsSettings[i].xVSS.pFramingBuffer->u_topleft = 347 pSettings->Effects[i].xVSS.pFramingBuffer->u_topleft; 348 349 mEffectsSettings[i].xVSS.uialphaBlendingStart = 350 pSettings->Effects[i].xVSS.uialphaBlendingStart; 351 352 mEffectsSettings[i].xVSS.uialphaBlendingMiddle = 353 pSettings->Effects[i].xVSS.uialphaBlendingMiddle; 354 355 mEffectsSettings[i].xVSS.uialphaBlendingEnd = 356 pSettings->Effects[i].xVSS.uialphaBlendingEnd; 357 358 mEffectsSettings[i].xVSS.uialphaBlendingFadeInTime = 359 pSettings->Effects[i].xVSS.uialphaBlendingFadeInTime; 360 mEffectsSettings[i].xVSS.uialphaBlendingFadeOutTime = 361 pSettings->Effects[i].xVSS.uialphaBlendingFadeOutTime; 362 363 // Copy the pFraming data 364 memcpy((void *) 365 mEffectsSettings[i].xVSS.pFramingBuffer->pac_data, 366 (void *)pSettings->Effects[i].xVSS.pFramingBuffer->pac_data, 367 rgbSize); 368 369 mEffectsSettings[i].xVSS.rgbType = 370 pSettings->Effects[i].xVSS.rgbType; 371 } 372 } 373 } 374 } 375 376 if (mBackgroundAudioSetting == NULL) { 377 378 mBackgroundAudioSetting = (M4xVSS_AudioMixingSettings*)M4OSA_32bitAlignedMalloc( 379 sizeof(M4xVSS_AudioMixingSettings), M4VS, 380 (M4OSA_Char*)"LvPP, copy of bgmSettings"); 381 382 if(NULL == mBackgroundAudioSetting) { 383 LOGE("loadEditSettings: mBackgroundAudioSetting Malloc failed"); 384 return M4ERR_ALLOC; 385 } 386 387 memset((void *)mBackgroundAudioSetting, 0,sizeof(M4xVSS_AudioMixingSettings*)); 388 memcpy((void *)mBackgroundAudioSetting, (void *)bgmSettings, sizeof(M4xVSS_AudioMixingSettings)); 389 390 if ( mBackgroundAudioSetting->pFile != M4OSA_NULL ) { 391 392 mBackgroundAudioSetting->pFile = (M4OSA_Void*) bgmSettings->pPCMFilePath; 393 mBackgroundAudioSetting->uiNbChannels = 2; 394 mBackgroundAudioSetting->uiSamplingFrequency = 32000; 395 } 396 397 // Open the BG file 398 if ( mBackgroundAudioSetting->pFile != M4OSA_NULL ) { 399 err = M4OSA_fileReadOpen(&mAudioMixPCMFileHandle, 400 mBackgroundAudioSetting->pFile, M4OSA_kFileRead); 401 402 if (err != M4NO_ERROR) { 403 LOGE("loadEditSettings: mBackgroundAudio PCM File open failed"); 404 return M4ERR_PARAMETER; 405 } 406 } 407 } 408 409 mOutputVideoSize = pSettings->xVSS.outputVideoSize; 410 mFrameStr.pBuffer = M4OSA_NULL; 411 return M4NO_ERROR; 412} 413 414M4OSA_ERR VideoEditorPreviewController::setSurface(const sp<Surface> &surface) { 415 LOGV("setSurface"); 416 Mutex::Autolock autoLock(mLock); 417 418 mSurface = surface; 419 return M4NO_ERROR; 420} 421 422M4OSA_ERR VideoEditorPreviewController::startPreview( 423 M4OSA_UInt32 fromMS, M4OSA_Int32 toMs, M4OSA_UInt16 callBackAfterFrameCount, 424 M4OSA_Bool loop) { 425 426 M4OSA_ERR err = M4NO_ERROR; 427 M4OSA_UInt32 i = 0, iIncrementedDuration = 0; 428 LOGV("startPreview"); 429 430 if(fromMS > (M4OSA_UInt32)toMs) { 431 LOGE("startPreview: fromMS > toMs"); 432 return M4ERR_PARAMETER; 433 } 434 435 if(toMs == 0) { 436 LOGE("startPreview: toMs is 0"); 437 return M4ERR_PARAMETER; 438 } 439 440 // If already started, then stop preview first 441 for(int playerInst=0; playerInst<NBPLAYER_INSTANCES; playerInst++) { 442 if(mVePlayer[playerInst] != NULL) { 443 LOGV("startPreview: stopping previously started preview playback"); 444 stopPreview(); 445 break; 446 } 447 } 448 449 // If renderPreview was called previously, then delete Renderer object first 450 if(mTarget != NULL) { 451 LOGV("startPreview: delete previous PreviewRenderer"); 452 delete mTarget; 453 mTarget = NULL; 454 } 455 456 // Create Audio player to be used for entire 457 // storyboard duration 458 mVEAudioSink = new VideoEditorPlayer::VeAudioOutput(); 459 mVEAudioPlayer = new VideoEditorAudioPlayer(mVEAudioSink); 460 mVEAudioPlayer->setAudioMixSettings(mBackgroundAudioSetting); 461 mVEAudioPlayer->setAudioMixPCMFileHandle(mAudioMixPCMFileHandle); 462 463 // Create Video Renderer to be used for the entire storyboard duration. 464 uint32_t width, height; 465 getVideoSizeByResolution(mOutputVideoSize, &width, &height); 466 mNativeWindowRenderer = new NativeWindowRenderer(mSurface, width, height); 467 468 LOGV("startPreview: loop = %d", loop); 469 mPreviewLooping = loop; 470 471 LOGV("startPreview: callBackAfterFrameCount = %d", callBackAfterFrameCount); 472 mCallBackAfterFrameCnt = callBackAfterFrameCount; 473 474 for (int playerInst=0; playerInst<NBPLAYER_INSTANCES; playerInst++) { 475 mVePlayer[playerInst] = new VideoEditorPlayer(mNativeWindowRenderer); 476 if(mVePlayer[playerInst] == NULL) { 477 LOGE("startPreview:Error creating VideoEditorPlayer %d",playerInst); 478 return M4ERR_ALLOC; 479 } 480 LOGV("startPreview: object created"); 481 482 mVePlayer[playerInst]->setNotifyCallback(this,(notify_callback_f)notify); 483 LOGV("startPreview: notify callback set"); 484 485 mVePlayer[playerInst]->loadEffectsSettings(mEffectsSettings, 486 mNumberEffects); 487 LOGV("startPreview: effects settings loaded"); 488 489 mVePlayer[playerInst]->loadAudioMixSettings(mBackgroundAudioSetting); 490 LOGV("startPreview: AudioMixSettings settings loaded"); 491 492 mVePlayer[playerInst]->setAudioMixPCMFileHandle(mAudioMixPCMFileHandle); 493 LOGV("startPreview: AudioMixPCMFileHandle set"); 494 495 mVePlayer[playerInst]->setProgressCallbackInterval( 496 mCallBackAfterFrameCnt); 497 LOGV("startPreview: setProgressCallBackInterval"); 498 } 499 500 mPlayerState = VePlayerIdle; 501 mPrepareReqest = M4OSA_FALSE; 502 503 if(fromMS == 0) { 504 mCurrentClipNumber = -1; 505 // Save original value 506 mFirstPreviewClipBeginTime = mClipList[0]->uiBeginCutTime; 507 mVideoStoryBoardTimeMsUptoFirstPreviewClip = 0; 508 } 509 else { 510 LOGV("startPreview: fromMS=%d", fromMS); 511 if(fromMS >= mClipTotalDuration) { 512 LOGE("startPreview: fromMS >= mClipTotalDuration"); 513 return M4ERR_PARAMETER; 514 } 515 for(i=0;i<mNumberClipsInStoryBoard;i++) { 516 if(fromMS < (iIncrementedDuration + (mClipList[i]->uiEndCutTime - 517 mClipList[i]->uiBeginCutTime))) { 518 // Set to 1 index below, 519 // as threadProcess first increments the clip index 520 // and then processes clip in thread loop 521 mCurrentClipNumber = i-1; 522 LOGD("startPreview:mCurrentClipNumber = %d fromMS=%d",i,fromMS); 523 524 // Save original value 525 mFirstPreviewClipBeginTime = mClipList[i]->uiBeginCutTime; 526 527 // Set correct begin time to start playback 528 if((fromMS+mClipList[i]->uiBeginCutTime) > 529 (iIncrementedDuration+mClipList[i]->uiBeginCutTime)) { 530 531 mClipList[i]->uiBeginCutTime = 532 mClipList[i]->uiBeginCutTime + 533 (fromMS - iIncrementedDuration); 534 } 535 break; 536 } 537 else { 538 iIncrementedDuration = iIncrementedDuration + 539 (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime); 540 } 541 } 542 mVideoStoryBoardTimeMsUptoFirstPreviewClip = iIncrementedDuration; 543 } 544 545 for (int playerInst=0; playerInst<NBPLAYER_INSTANCES; playerInst++) { 546 mVePlayer[playerInst]->setAudioMixStoryBoardParam(fromMS, 547 mFirstPreviewClipBeginTime, 548 mClipList[i]->ClipProperties.uiClipAudioVolumePercentage); 549 550 LOGV("startPreview:setAudioMixStoryBoardSkimTimeStamp set %d cuttime \ 551 %d", fromMS, mFirstPreviewClipBeginTime); 552 } 553 554 mStartingClipIndex = mCurrentClipNumber+1; 555 556 // Start playing with player instance 0 557 mCurrentPlayer = 0; 558 mActivePlayerIndex = 0; 559 560 if(toMs == -1) { 561 LOGV("startPreview: Preview till end of storyboard"); 562 mNumberClipsToPreview = mNumberClipsInStoryBoard; 563 // Save original value 564 mLastPreviewClipEndTime = 565 mClipList[mNumberClipsToPreview-1]->uiEndCutTime; 566 } 567 else { 568 LOGV("startPreview: toMs=%d", toMs); 569 if((M4OSA_UInt32)toMs > mClipTotalDuration) { 570 LOGE("startPreview: toMs > mClipTotalDuration"); 571 return M4ERR_PARAMETER; 572 } 573 574 iIncrementedDuration = 0; 575 576 for(i=0;i<mNumberClipsInStoryBoard;i++) { 577 if((M4OSA_UInt32)toMs <= (iIncrementedDuration + 578 (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime))) { 579 // Save original value 580 mLastPreviewClipEndTime = mClipList[i]->uiEndCutTime; 581 // Set the end cut time of clip index i to toMs 582 mClipList[i]->uiEndCutTime = toMs; 583 584 // Number of clips to be previewed is from index 0 to i 585 // increment by 1 as i starts from 0 586 mNumberClipsToPreview = i+1; 587 break; 588 } 589 else { 590 iIncrementedDuration = iIncrementedDuration + 591 (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime); 592 } 593 } 594 } 595 596 // Open the thread semaphore 597 M4OSA_semaphoreOpen(&mSemThreadWait, 1); 598 599 // Open the preview process thread 600 err = M4OSA_threadSyncOpen(&mThreadContext, (M4OSA_ThreadDoIt)threadProc); 601 if (M4NO_ERROR != err) { 602 LOGE("VideoEditorPreviewController:M4OSA_threadSyncOpen error %d", (int) err); 603 return err; 604 } 605 606 // Set the stacksize 607 err = M4OSA_threadSyncSetOption(mThreadContext, M4OSA_ThreadStackSize, 608 (M4OSA_DataOption)PREVIEW_THREAD_STACK_SIZE); 609 610 if (M4NO_ERROR != err) { 611 LOGE("VideoEditorPreviewController: threadSyncSetOption error %d", (int) err); 612 M4OSA_threadSyncClose(mThreadContext); 613 mThreadContext = NULL; 614 return err; 615 } 616 617 // Start the thread 618 err = M4OSA_threadSyncStart(mThreadContext, (M4OSA_Void*)this); 619 if (M4NO_ERROR != err) { 620 LOGE("VideoEditorPreviewController: threadSyncStart error %d", (int) err); 621 M4OSA_threadSyncClose(mThreadContext); 622 mThreadContext = NULL; 623 return err; 624 } 625 bStopThreadInProgress = false; 626 627 LOGV("startPreview: process thread started"); 628 return M4NO_ERROR; 629} 630 631M4OSA_UInt32 VideoEditorPreviewController::stopPreview() { 632 M4OSA_ERR err = M4NO_ERROR; 633 uint32_t lastRenderedFrameTimeMs = 0; 634 LOGV("stopPreview"); 635 636 // Stop the thread 637 if(mThreadContext != NULL) { 638 bStopThreadInProgress = true; 639 { 640 Mutex::Autolock autoLock(mLockSem); 641 if (mSemThreadWait != NULL) { 642 err = M4OSA_semaphorePost(mSemThreadWait); 643 } 644 } 645 646 err = M4OSA_threadSyncStop(mThreadContext); 647 if(err != M4NO_ERROR) { 648 LOGV("stopPreview: error 0x%x in trying to stop thread", err); 649 // Continue even if error 650 } 651 652 err = M4OSA_threadSyncClose(mThreadContext); 653 if(err != M4NO_ERROR) { 654 LOGE("stopPreview: error 0x%x in trying to close thread", (unsigned int)err); 655 // Continue even if error 656 } 657 658 mThreadContext = NULL; 659 } 660 661 // Close the semaphore first 662 { 663 Mutex::Autolock autoLock(mLockSem); 664 if(mSemThreadWait != NULL) { 665 err = M4OSA_semaphoreClose(mSemThreadWait); 666 LOGV("stopPreview: close semaphore returns 0x%x", err); 667 mSemThreadWait = NULL; 668 } 669 } 670 671 for (int playerInst=0; playerInst<NBPLAYER_INSTANCES; playerInst++) { 672 if(mVePlayer[playerInst] != NULL) { 673 if(mVePlayer[playerInst]->isPlaying()) { 674 LOGV("stop the player first"); 675 mVePlayer[playerInst]->stop(); 676 } 677 if (playerInst == mActivePlayerIndex) { 678 // Return the last rendered frame time stamp 679 mVePlayer[mActivePlayerIndex]->getLastRenderedTimeMs(&lastRenderedFrameTimeMs); 680 } 681 682 //This is used to syncronize onStreamDone() in PreviewPlayer and 683 //stopPreview() in PreviewController 684 sp<VideoEditorPlayer> temp = mVePlayer[playerInst]; 685 temp->acquireLock(); 686 LOGV("stopPreview: clearing mVePlayer"); 687 mVePlayer[playerInst].clear(); 688 mVePlayer[playerInst] = NULL; 689 temp->releaseLock(); 690 } 691 } 692 LOGV("stopPreview: clear audioSink and audioPlayer"); 693 mVEAudioSink.clear(); 694 if (mVEAudioPlayer) { 695 delete mVEAudioPlayer; 696 mVEAudioPlayer = NULL; 697 } 698 699 delete mNativeWindowRenderer; 700 mNativeWindowRenderer = NULL; 701 702 // If image file playing, then free the buffer pointer 703 if(mFrameStr.pBuffer != M4OSA_NULL) { 704 free(mFrameStr.pBuffer); 705 mFrameStr.pBuffer = M4OSA_NULL; 706 } 707 708 // Reset original begin cuttime of first previewed clip*/ 709 mClipList[mStartingClipIndex]->uiBeginCutTime = mFirstPreviewClipBeginTime; 710 // Reset original end cuttime of last previewed clip*/ 711 mClipList[mNumberClipsToPreview-1]->uiEndCutTime = mLastPreviewClipEndTime; 712 713 mPlayerState = VePlayerIdle; 714 mPrepareReqest = M4OSA_FALSE; 715 716 mCurrentPlayedDuration = 0; 717 mCurrentClipDuration = 0; 718 mRenderingMode = M4xVSS_kBlackBorders; 719 mOutputVideoWidth = 0; 720 mOutputVideoHeight = 0; 721 722 LOGV("stopPreview() lastRenderedFrameTimeMs %ld", lastRenderedFrameTimeMs); 723 return lastRenderedFrameTimeMs; 724} 725 726M4OSA_ERR VideoEditorPreviewController::clearSurface( 727 const sp<Surface> &surface, VideoEditor_renderPreviewFrameStr* pFrameInfo) { 728 729 M4OSA_ERR err = M4NO_ERROR; 730 VideoEditor_renderPreviewFrameStr* pFrameStr = pFrameInfo; 731 M4OSA_UInt32 outputBufferWidth =0, outputBufferHeight=0; 732 M4VIFI_ImagePlane planeOut[3]; 733 LOGV("Inside preview clear frame"); 734 735 Mutex::Autolock autoLock(mLock); 736 737 // Delete previous renderer instance 738 if(mTarget != NULL) { 739 delete mTarget; 740 mTarget = NULL; 741 } 742 743 outputBufferWidth = pFrameStr->uiFrameWidth; 744 outputBufferHeight = pFrameStr->uiFrameHeight; 745 746 // Initialize the renderer 747 if(mTarget == NULL) { 748 749 mTarget = PreviewRenderer::CreatePreviewRenderer( 750 surface, 751 outputBufferWidth, outputBufferHeight); 752 753 if(mTarget == NULL) { 754 LOGE("renderPreviewFrame: cannot create PreviewRenderer"); 755 return M4ERR_ALLOC; 756 } 757 } 758 759 // Out plane 760 uint8_t* outBuffer; 761 size_t outBufferStride = 0; 762 763 LOGV("doMediaRendering CALL getBuffer()"); 764 mTarget->getBufferYV12(&outBuffer, &outBufferStride); 765 766 // Set the output YUV420 plane to be compatible with YV12 format 767 //In YV12 format, sizes must be even 768 M4OSA_UInt32 yv12PlaneWidth = ((outputBufferWidth +1)>>1)<<1; 769 M4OSA_UInt32 yv12PlaneHeight = ((outputBufferHeight+1)>>1)<<1; 770 771 prepareYV12ImagePlane(planeOut, yv12PlaneWidth, yv12PlaneHeight, 772 (M4OSA_UInt32)outBufferStride, (M4VIFI_UInt8 *)outBuffer); 773 774 /* Fill the surface with black frame */ 775 memset((void *)planeOut[0].pac_data,0x00,planeOut[0].u_width * 776 planeOut[0].u_height * 1.5); 777 memset((void *)planeOut[1].pac_data,128,planeOut[1].u_width * 778 planeOut[1].u_height); 779 memset((void *)planeOut[2].pac_data,128,planeOut[2].u_width * 780 planeOut[2].u_height); 781 782 mTarget->renderYV12(); 783 return err; 784} 785 786M4OSA_ERR VideoEditorPreviewController::renderPreviewFrame( 787 const sp<Surface> &surface, 788 VideoEditor_renderPreviewFrameStr* pFrameInfo, 789 VideoEditorCurretEditInfo *pCurrEditInfo) { 790 791 M4OSA_ERR err = M4NO_ERROR; 792 M4OSA_UInt32 i = 0, iIncrementedDuration = 0, tnTimeMs=0, framesize =0; 793 VideoEditor_renderPreviewFrameStr* pFrameStr = pFrameInfo; 794 M4VIFI_UInt8 *pixelArray = NULL; 795 Mutex::Autolock autoLock(mLock); 796 797 if (pCurrEditInfo != NULL) { 798 pCurrEditInfo->overlaySettingsIndex = -1; 799 } 800 // Delete previous renderer instance 801 if(mTarget != NULL) { 802 delete mTarget; 803 mTarget = NULL; 804 } 805 806 if(mOutputVideoWidth == 0) { 807 mOutputVideoWidth = pFrameStr->uiFrameWidth; 808 } 809 810 if(mOutputVideoHeight == 0) { 811 mOutputVideoHeight = pFrameStr->uiFrameHeight; 812 } 813 814 // Initialize the renderer 815 if(mTarget == NULL) { 816 mTarget = PreviewRenderer::CreatePreviewRenderer( 817 surface, 818 mOutputVideoWidth, mOutputVideoHeight); 819 820 if(mTarget == NULL) { 821 LOGE("renderPreviewFrame: cannot create PreviewRenderer"); 822 return M4ERR_ALLOC; 823 } 824 } 825 826 pixelArray = NULL; 827 828 // Apply rotation if required 829 if (pFrameStr->videoRotationDegree != 0) { 830 err = applyVideoRotation((M4OSA_Void *)pFrameStr->pBuffer, 831 pFrameStr->uiFrameWidth, pFrameStr->uiFrameHeight, 832 pFrameStr->videoRotationDegree); 833 if (M4NO_ERROR != err) { 834 LOGE("renderPreviewFrame: cannot rotate video, err 0x%x", (unsigned int)err); 835 delete mTarget; 836 mTarget = NULL; 837 return err; 838 } else { 839 // Video rotation done. 840 // Swap width and height if 90 or 270 degrees 841 if (pFrameStr->videoRotationDegree != 180) { 842 int32_t temp = pFrameStr->uiFrameWidth; 843 pFrameStr->uiFrameWidth = pFrameStr->uiFrameHeight; 844 pFrameStr->uiFrameHeight = temp; 845 } 846 } 847 } 848 // Postprocessing (apply video effect) 849 if(pFrameStr->bApplyEffect == M4OSA_TRUE) { 850 851 for(i=0;i<mNumberEffects;i++) { 852 // First check if effect starttime matches the clip being previewed 853 if((mEffectsSettings[i].uiStartTime < pFrameStr->clipBeginCutTime) 854 ||(mEffectsSettings[i].uiStartTime >= pFrameStr->clipEndCutTime)) { 855 // This effect doesn't belong to this clip, check next one 856 continue; 857 } 858 if((mEffectsSettings[i].uiStartTime <= pFrameStr->timeMs) && 859 ((mEffectsSettings[i].uiStartTime+mEffectsSettings[i].uiDuration) >= 860 pFrameStr->timeMs) && (mEffectsSettings[i].uiDuration != 0)) { 861 setVideoEffectType(mEffectsSettings[i].VideoEffectType, TRUE); 862 } 863 else { 864 setVideoEffectType(mEffectsSettings[i].VideoEffectType, FALSE); 865 } 866 } 867 868 //Provide the overlay Update indication when there is an overlay effect 869 if (mCurrentVideoEffect & VIDEO_EFFECT_FRAMING) { 870 M4OSA_UInt32 index; 871 mCurrentVideoEffect &= ~VIDEO_EFFECT_FRAMING; //never apply framing here. 872 873 // Find the effect in effectSettings array 874 for (index = 0; index < mNumberEffects; index++) { 875 if(mEffectsSettings[index].VideoEffectType == 876 (M4VSS3GPP_VideoEffectType)M4xVSS_kVideoEffectType_Framing) { 877 878 if((mEffectsSettings[index].uiStartTime <= pFrameInfo->timeMs) && 879 ((mEffectsSettings[index].uiStartTime+ 880 mEffectsSettings[index].uiDuration) >= pFrameInfo->timeMs)) 881 { 882 break; 883 } 884 } 885 } 886 if ((index < mNumberEffects) && (pCurrEditInfo != NULL)) { 887 pCurrEditInfo->overlaySettingsIndex = index; 888 LOGV("Framing index = %d", index); 889 } else { 890 LOGV("No framing effects found"); 891 } 892 } 893 894 if(mCurrentVideoEffect != VIDEO_EFFECT_NONE) { 895 err = applyVideoEffect((M4OSA_Void *)pFrameStr->pBuffer, 896 OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth, 897 pFrameStr->uiFrameHeight, pFrameStr->timeMs, 898 (M4OSA_Void *)pixelArray); 899 900 if(err != M4NO_ERROR) { 901 LOGE("renderPreviewFrame: applyVideoEffect error 0x%x", (unsigned int)err); 902 delete mTarget; 903 mTarget = NULL; 904 free(pixelArray); 905 pixelArray = NULL; 906 return err; 907 } 908 mCurrentVideoEffect = VIDEO_EFFECT_NONE; 909 } 910 else { 911 // Apply the rendering mode 912 err = doImageRenderingMode((M4OSA_Void *)pFrameStr->pBuffer, 913 OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth, 914 pFrameStr->uiFrameHeight, (M4OSA_Void *)pixelArray); 915 916 if(err != M4NO_ERROR) { 917 LOGE("renderPreviewFrame:doImageRenderingMode error 0x%x", (unsigned int)err); 918 delete mTarget; 919 mTarget = NULL; 920 free(pixelArray); 921 pixelArray = NULL; 922 return err; 923 } 924 } 925 } 926 else { 927 // Apply the rendering mode 928 err = doImageRenderingMode((M4OSA_Void *)pFrameStr->pBuffer, 929 OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth, 930 pFrameStr->uiFrameHeight, (M4OSA_Void *)pixelArray); 931 932 if(err != M4NO_ERROR) { 933 LOGE("renderPreviewFrame: doImageRenderingMode error 0x%x", (unsigned int)err); 934 delete mTarget; 935 mTarget = NULL; 936 free(pixelArray); 937 pixelArray = NULL; 938 return err; 939 } 940 } 941 942 mTarget->renderYV12(); 943 return err; 944} 945 946M4OSA_Void VideoEditorPreviewController::setJniCallback(void* cookie, 947 jni_progress_callback_fct callbackFct) { 948 //LOGV("setJniCallback"); 949 mJniCookie = cookie; 950 mJniCallback = callbackFct; 951} 952 953M4OSA_ERR VideoEditorPreviewController::preparePlayer( 954 void* param, int playerInstance, int index) { 955 956 M4OSA_ERR err = M4NO_ERROR; 957 VideoEditorPreviewController *pController = 958 (VideoEditorPreviewController *)param; 959 960 LOGV("preparePlayer: instance %d file %d", playerInstance, index); 961 962 pController->mVePlayer[playerInstance]->setDataSource( 963 (const char *)pController->mClipList[index]->pFile, NULL); 964 LOGV("preparePlayer: setDataSource instance %s", 965 (const char *)pController->mClipList[index]->pFile); 966 967 pController->mVePlayer[playerInstance]->setVideoSurface( 968 pController->mSurface); 969 LOGV("preparePlayer: setVideoSurface"); 970 971 pController->mVePlayer[playerInstance]->setMediaRenderingMode( 972 pController->mClipList[index]->xVSS.MediaRendering, 973 pController->mOutputVideoSize); 974 LOGV("preparePlayer: setMediaRenderingMode"); 975 976 if((M4OSA_UInt32)index == pController->mStartingClipIndex) { 977 pController->mVePlayer[playerInstance]->setPlaybackBeginTime( 978 pController->mFirstPreviewClipBeginTime); 979 } 980 else { 981 pController->mVePlayer[playerInstance]->setPlaybackBeginTime( 982 pController->mClipList[index]->uiBeginCutTime); 983 } 984 LOGV("preparePlayer: setPlaybackBeginTime(%d)", 985 pController->mClipList[index]->uiBeginCutTime); 986 987 pController->mVePlayer[playerInstance]->setPlaybackEndTime( 988 pController->mClipList[index]->uiEndCutTime); 989 LOGV("preparePlayer: setPlaybackEndTime(%d)", 990 pController->mClipList[index]->uiEndCutTime); 991 992 if(pController->mClipList[index]->FileType == M4VIDEOEDITING_kFileType_ARGB8888) { 993 pController->mVePlayer[playerInstance]->setImageClipProperties( 994 pController->mClipList[index]->ClipProperties.uiVideoWidth, 995 pController->mClipList[index]->ClipProperties.uiVideoHeight); 996 LOGV("preparePlayer: setImageClipProperties"); 997 } 998 999 pController->mVePlayer[playerInstance]->prepare(); 1000 LOGV("preparePlayer: prepared"); 1001 1002 if(pController->mClipList[index]->uiBeginCutTime > 0) { 1003 pController->mVePlayer[playerInstance]->seekTo( 1004 pController->mClipList[index]->uiBeginCutTime); 1005 1006 LOGV("preparePlayer: seekTo(%d)", 1007 pController->mClipList[index]->uiBeginCutTime); 1008 } 1009 pController->mVePlayer[pController->mCurrentPlayer]->setAudioPlayer(pController->mVEAudioPlayer); 1010 1011 pController->mVePlayer[playerInstance]->readFirstVideoFrame(); 1012 LOGV("preparePlayer: readFirstVideoFrame of clip"); 1013 1014 return err; 1015} 1016 1017M4OSA_ERR VideoEditorPreviewController::threadProc(M4OSA_Void* param) { 1018 M4OSA_ERR err = M4NO_ERROR; 1019 M4OSA_Int32 index = 0; 1020 VideoEditorPreviewController *pController = 1021 (VideoEditorPreviewController *)param; 1022 1023 LOGV("inside threadProc"); 1024 if(pController->mPlayerState == VePlayerIdle) { 1025 (pController->mCurrentClipNumber)++; 1026 1027 LOGD("threadProc: playing file index %d total clips %d", 1028 pController->mCurrentClipNumber, pController->mNumberClipsToPreview); 1029 1030 if((M4OSA_UInt32)pController->mCurrentClipNumber >= 1031 pController->mNumberClipsToPreview) { 1032 1033 LOGD("All clips previewed"); 1034 1035 pController->mCurrentPlayedDuration = 0; 1036 pController->mCurrentClipDuration = 0; 1037 pController->mCurrentPlayer = 0; 1038 1039 if(pController->mPreviewLooping == M4OSA_TRUE) { 1040 pController->mCurrentClipNumber = 1041 pController->mStartingClipIndex; 1042 1043 LOGD("Preview looping TRUE, restarting from clip index %d", 1044 pController->mCurrentClipNumber); 1045 1046 // Reset the story board timestamp inside the player 1047 for (int playerInst=0; playerInst<NBPLAYER_INSTANCES; 1048 playerInst++) { 1049 pController->mVePlayer[playerInst]->resetJniCallbackTimeStamp(); 1050 } 1051 } 1052 else { 1053 M4OSA_UInt32 endArgs = 0; 1054 if(pController->mJniCallback != NULL) { 1055 pController->mJniCallback( 1056 pController->mJniCookie, MSG_TYPE_PREVIEW_END, &endArgs); 1057 } 1058 pController->mPlayerState = VePlayerAutoStop; 1059 1060 // Reset original begin cuttime of first previewed clip 1061 pController->mClipList[pController->mStartingClipIndex]->uiBeginCutTime = 1062 pController->mFirstPreviewClipBeginTime; 1063 // Reset original end cuttime of last previewed clip 1064 pController->mClipList[pController->mNumberClipsToPreview-1]->uiEndCutTime = 1065 pController->mLastPreviewClipEndTime; 1066 1067 // Return a warning to M4OSA thread handler 1068 // so that thread is moved from executing state to open state 1069 return M4WAR_NO_MORE_STREAM; 1070 } 1071 } 1072 1073 index=pController->mCurrentClipNumber; 1074 if((M4OSA_UInt32)pController->mCurrentClipNumber == pController->mStartingClipIndex) { 1075 pController->mCurrentPlayedDuration += 1076 pController->mVideoStoryBoardTimeMsUptoFirstPreviewClip; 1077 1078 pController->mCurrentClipDuration = 1079 pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime 1080 - pController->mFirstPreviewClipBeginTime; 1081 1082 preparePlayer((void*)pController, pController->mCurrentPlayer, index); 1083 } 1084 else { 1085 pController->mCurrentPlayedDuration += 1086 pController->mCurrentClipDuration; 1087 1088 pController->mCurrentClipDuration = 1089 pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime - 1090 pController->mClipList[pController->mCurrentClipNumber]->uiBeginCutTime; 1091 } 1092 1093 pController->mVePlayer[pController->mCurrentPlayer]->setStoryboardStartTime( 1094 pController->mCurrentPlayedDuration); 1095 LOGV("threadProc: setStoryboardStartTime"); 1096 1097 // Set the next clip duration for Audio mix here 1098 if((M4OSA_UInt32)pController->mCurrentClipNumber != pController->mStartingClipIndex) { 1099 1100 pController->mVePlayer[pController->mCurrentPlayer]->setAudioMixStoryBoardParam( 1101 pController->mCurrentPlayedDuration, 1102 pController->mClipList[index]->uiBeginCutTime, 1103 pController->mClipList[index]->ClipProperties.uiClipAudioVolumePercentage); 1104 1105 LOGV("threadProc: setAudioMixStoryBoardParam fromMS %d \ 1106 ClipBeginTime %d", pController->mCurrentPlayedDuration + 1107 pController->mClipList[index]->uiBeginCutTime, 1108 pController->mClipList[index]->uiBeginCutTime, 1109 pController->mClipList[index]->ClipProperties.uiClipAudioVolumePercentage); 1110 } 1111 // Capture the active player being used 1112 pController->mActivePlayerIndex = pController->mCurrentPlayer; 1113 1114 pController->mVePlayer[pController->mCurrentPlayer]->start(); 1115 LOGV("threadProc: started"); 1116 1117 pController->mPlayerState = VePlayerBusy; 1118 1119 } else if(pController->mPlayerState == VePlayerAutoStop) { 1120 LOGV("Preview completed..auto stop the player"); 1121 } else if ((pController->mPlayerState == VePlayerBusy) && (pController->mPrepareReqest)) { 1122 // Prepare the player here 1123 pController->mPrepareReqest = M4OSA_FALSE; 1124 preparePlayer((void*)pController, pController->mCurrentPlayer, 1125 pController->mCurrentClipNumber+1); 1126 if (pController->mSemThreadWait != NULL) { 1127 err = M4OSA_semaphoreWait(pController->mSemThreadWait, 1128 M4OSA_WAIT_FOREVER); 1129 } 1130 } else { 1131 if (!pController->bStopThreadInProgress) { 1132 LOGV("threadProc: state busy...wait for sem"); 1133 if (pController->mSemThreadWait != NULL) { 1134 err = M4OSA_semaphoreWait(pController->mSemThreadWait, 1135 M4OSA_WAIT_FOREVER); 1136 } 1137 } 1138 LOGV("threadProc: sem wait returned err = 0x%x", err); 1139 } 1140 1141 //Always return M4NO_ERROR to ensure the thread keeps running 1142 return M4NO_ERROR; 1143} 1144 1145void VideoEditorPreviewController::notify( 1146 void* cookie, int msg, int ext1, int ext2) 1147{ 1148 VideoEditorPreviewController *pController = 1149 (VideoEditorPreviewController *)cookie; 1150 1151 M4OSA_ERR err = M4NO_ERROR; 1152 uint32_t clipDuration = 0; 1153 switch (msg) { 1154 case MEDIA_NOP: // interface test message 1155 LOGV("MEDIA_NOP"); 1156 break; 1157 case MEDIA_PREPARED: 1158 LOGV("MEDIA_PREPARED"); 1159 break; 1160 case MEDIA_PLAYBACK_COMPLETE: 1161 { 1162 LOGD("notify:MEDIA_PLAYBACK_COMPLETE, mCurrentClipNumber = %d", 1163 pController->mCurrentClipNumber); 1164 pController->mPlayerState = VePlayerIdle; 1165 1166 //send progress callback with last frame timestamp 1167 if((M4OSA_UInt32)pController->mCurrentClipNumber == 1168 pController->mStartingClipIndex) { 1169 clipDuration = 1170 pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime 1171 - pController->mFirstPreviewClipBeginTime; 1172 } 1173 else { 1174 clipDuration = 1175 pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime 1176 - pController->mClipList[pController->mCurrentClipNumber]->uiBeginCutTime; 1177 } 1178 1179 M4OSA_UInt32 playedDuration = clipDuration+pController->mCurrentPlayedDuration; 1180 pController->mJniCallback( 1181 pController->mJniCookie, MSG_TYPE_PROGRESS_INDICATION, 1182 &playedDuration); 1183 1184 if ((pController->mOverlayState == OVERLAY_UPDATE) && 1185 ((M4OSA_UInt32)pController->mCurrentClipNumber != 1186 (pController->mNumberClipsToPreview-1))) { 1187 VideoEditorCurretEditInfo *pEditInfo = 1188 (VideoEditorCurretEditInfo*)M4OSA_32bitAlignedMalloc(sizeof(VideoEditorCurretEditInfo), 1189 M4VS, (M4OSA_Char*)"Current Edit info"); 1190 pEditInfo->overlaySettingsIndex = ext2; 1191 pEditInfo->clipIndex = pController->mCurrentClipNumber; 1192 pController->mOverlayState == OVERLAY_CLEAR; 1193 if (pController->mJniCallback != NULL) { 1194 pController->mJniCallback(pController->mJniCookie, 1195 MSG_TYPE_OVERLAY_CLEAR, pEditInfo); 1196 } 1197 free(pEditInfo); 1198 } 1199 { 1200 Mutex::Autolock autoLock(pController->mLockSem); 1201 if (pController->mSemThreadWait != NULL) { 1202 M4OSA_semaphorePost(pController->mSemThreadWait); 1203 return; 1204 } 1205 } 1206 1207 break; 1208 } 1209 case MEDIA_ERROR: 1210 { 1211 int err_val = ext1; 1212 // Always log errors. 1213 // ext1: Media framework error code. 1214 // ext2: Implementation dependant error code. 1215 LOGE("MEDIA_ERROR; error (%d, %d)", ext1, ext2); 1216 if(pController->mJniCallback != NULL) { 1217 pController->mJniCallback(pController->mJniCookie, 1218 MSG_TYPE_PLAYER_ERROR, &err_val); 1219 } 1220 break; 1221 } 1222 case MEDIA_INFO: 1223 { 1224 int info_val = ext2; 1225 // ext1: Media framework error code. 1226 // ext2: Implementation dependant error code. 1227 //LOGW("MEDIA_INFO; info/warning (%d, %d)", ext1, ext2); 1228 if(pController->mJniCallback != NULL) { 1229 pController->mJniCallback(pController->mJniCookie, 1230 MSG_TYPE_PROGRESS_INDICATION, &info_val); 1231 } 1232 break; 1233 } 1234 case MEDIA_SEEK_COMPLETE: 1235 LOGV("MEDIA_SEEK_COMPLETE; Received seek complete"); 1236 break; 1237 case MEDIA_BUFFERING_UPDATE: 1238 LOGV("MEDIA_BUFFERING_UPDATE; buffering %d", ext1); 1239 break; 1240 case MEDIA_SET_VIDEO_SIZE: 1241 LOGV("MEDIA_SET_VIDEO_SIZE; New video size %d x %d", ext1, ext2); 1242 break; 1243 case 0xAAAAAAAA: 1244 LOGV("VIDEO PLAYBACK ALMOST over, prepare next player"); 1245 // Select next player and prepare it 1246 // If there is a clip after this one 1247 if ((M4OSA_UInt32)(pController->mCurrentClipNumber+1) < 1248 pController->mNumberClipsToPreview) { 1249 pController->mPrepareReqest = M4OSA_TRUE; 1250 pController->mCurrentPlayer++; 1251 if (pController->mCurrentPlayer >= NBPLAYER_INSTANCES) { 1252 pController->mCurrentPlayer = 0; 1253 } 1254 // Prepare the first clip to be played 1255 { 1256 Mutex::Autolock autoLock(pController->mLockSem); 1257 if (pController->mSemThreadWait != NULL) { 1258 M4OSA_semaphorePost(pController->mSemThreadWait); 1259 } 1260 } 1261 } 1262 break; 1263 case 0xBBBBBBBB: 1264 { 1265 LOGV("VIDEO PLAYBACK, Update Overlay"); 1266 int overlayIndex = ext2; 1267 VideoEditorCurretEditInfo *pEditInfo = 1268 (VideoEditorCurretEditInfo*)M4OSA_32bitAlignedMalloc(sizeof(VideoEditorCurretEditInfo), 1269 M4VS, (M4OSA_Char*)"Current Edit info"); 1270 //ext1 = 1; start the overlay display 1271 // = 2; Clear the overlay. 1272 pEditInfo->overlaySettingsIndex = ext2; 1273 pEditInfo->clipIndex = pController->mCurrentClipNumber; 1274 LOGV("pController->mCurrentClipNumber = %d",pController->mCurrentClipNumber); 1275 if (pController->mJniCallback != NULL) { 1276 if (ext1 == 1) { 1277 pController->mOverlayState = OVERLAY_UPDATE; 1278 pController->mJniCallback(pController->mJniCookie, 1279 MSG_TYPE_OVERLAY_UPDATE, pEditInfo); 1280 } else { 1281 pController->mOverlayState = OVERLAY_CLEAR; 1282 pController->mJniCallback(pController->mJniCookie, 1283 MSG_TYPE_OVERLAY_CLEAR, pEditInfo); 1284 } 1285 } 1286 free(pEditInfo); 1287 break; 1288 } 1289 default: 1290 LOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2); 1291 break; 1292 } 1293} 1294 1295void VideoEditorPreviewController::setVideoEffectType( 1296 M4VSS3GPP_VideoEffectType type, M4OSA_Bool enable) { 1297 1298 M4OSA_UInt32 effect = VIDEO_EFFECT_NONE; 1299 1300 // map M4VSS3GPP_VideoEffectType to local enum 1301 switch(type) { 1302 case M4VSS3GPP_kVideoEffectType_FadeFromBlack: 1303 effect = VIDEO_EFFECT_FADEFROMBLACK; 1304 break; 1305 1306 case M4VSS3GPP_kVideoEffectType_FadeToBlack: 1307 effect = VIDEO_EFFECT_FADETOBLACK; 1308 break; 1309 1310 case M4xVSS_kVideoEffectType_BlackAndWhite: 1311 effect = VIDEO_EFFECT_BLACKANDWHITE; 1312 break; 1313 1314 case M4xVSS_kVideoEffectType_Pink: 1315 effect = VIDEO_EFFECT_PINK; 1316 break; 1317 1318 case M4xVSS_kVideoEffectType_Green: 1319 effect = VIDEO_EFFECT_GREEN; 1320 break; 1321 1322 case M4xVSS_kVideoEffectType_Sepia: 1323 effect = VIDEO_EFFECT_SEPIA; 1324 break; 1325 1326 case M4xVSS_kVideoEffectType_Negative: 1327 effect = VIDEO_EFFECT_NEGATIVE; 1328 break; 1329 1330 case M4xVSS_kVideoEffectType_Framing: 1331 effect = VIDEO_EFFECT_FRAMING; 1332 break; 1333 1334 case M4xVSS_kVideoEffectType_Fifties: 1335 effect = VIDEO_EFFECT_FIFTIES; 1336 break; 1337 1338 case M4xVSS_kVideoEffectType_ColorRGB16: 1339 effect = VIDEO_EFFECT_COLOR_RGB16; 1340 break; 1341 1342 case M4xVSS_kVideoEffectType_Gradient: 1343 effect = VIDEO_EFFECT_GRADIENT; 1344 break; 1345 1346 default: 1347 effect = VIDEO_EFFECT_NONE; 1348 break; 1349 } 1350 1351 if(enable == M4OSA_TRUE) { 1352 // If already set, then no need to set again 1353 if(!(mCurrentVideoEffect & effect)) 1354 mCurrentVideoEffect |= effect; 1355 if(effect == VIDEO_EFFECT_FIFTIES) { 1356 mIsFiftiesEffectStarted = true; 1357 } 1358 } 1359 else { 1360 // Reset only if already set 1361 if(mCurrentVideoEffect & effect) 1362 mCurrentVideoEffect &= ~effect; 1363 } 1364 1365 return; 1366} 1367 1368 1369M4OSA_ERR VideoEditorPreviewController::applyVideoEffect( 1370 M4OSA_Void * dataPtr, M4OSA_UInt32 colorFormat, M4OSA_UInt32 videoWidth, 1371 M4OSA_UInt32 videoHeight, M4OSA_UInt32 timeMs, M4OSA_Void* outPtr) { 1372 1373 M4OSA_ERR err = M4NO_ERROR; 1374 vePostProcessParams postProcessParams; 1375 1376 postProcessParams.vidBuffer = (M4VIFI_UInt8*)dataPtr; 1377 postProcessParams.videoWidth = videoWidth; 1378 postProcessParams.videoHeight = videoHeight; 1379 postProcessParams.timeMs = timeMs; 1380 postProcessParams.timeOffset = 0; //Since timeMS already takes care of offset in this case 1381 postProcessParams.effectsSettings = mEffectsSettings; 1382 postProcessParams.numberEffects = mNumberEffects; 1383 postProcessParams.outVideoWidth = mOutputVideoWidth; 1384 postProcessParams.outVideoHeight = mOutputVideoHeight; 1385 postProcessParams.currentVideoEffect = mCurrentVideoEffect; 1386 postProcessParams.renderingMode = mRenderingMode; 1387 if(mIsFiftiesEffectStarted == M4OSA_TRUE) { 1388 postProcessParams.isFiftiesEffectStarted = M4OSA_TRUE; 1389 mIsFiftiesEffectStarted = M4OSA_FALSE; 1390 } 1391 else { 1392 postProcessParams.isFiftiesEffectStarted = M4OSA_FALSE; 1393 } 1394 //postProcessParams.renderer = mTarget; 1395 postProcessParams.overlayFrameRGBBuffer = NULL; 1396 postProcessParams.overlayFrameYUVBuffer = NULL; 1397 1398 mTarget->getBufferYV12(&(postProcessParams.pOutBuffer), &(postProcessParams.outBufferStride)); 1399 1400 err = applyEffectsAndRenderingMode(&postProcessParams, videoWidth, videoHeight); 1401 return err; 1402} 1403 1404status_t VideoEditorPreviewController::setPreviewFrameRenderingMode( 1405 M4xVSS_MediaRendering mode, M4VIDEOEDITING_VideoFrameSize outputVideoSize) { 1406 1407 LOGV("setMediaRenderingMode: outputVideoSize = %d", outputVideoSize); 1408 mRenderingMode = mode; 1409 1410 status_t err = OK; 1411 /* get the video width and height by resolution */ 1412 err = getVideoSizeByResolution(outputVideoSize, 1413 &mOutputVideoWidth, &mOutputVideoHeight); 1414 1415 return err; 1416} 1417 1418M4OSA_ERR VideoEditorPreviewController::doImageRenderingMode( 1419 M4OSA_Void * dataPtr, M4OSA_UInt32 colorFormat, M4OSA_UInt32 videoWidth, 1420 M4OSA_UInt32 videoHeight, M4OSA_Void* outPtr) { 1421 1422 M4OSA_ERR err = M4NO_ERROR; 1423 M4VIFI_ImagePlane planeIn[3], planeOut[3]; 1424 M4VIFI_UInt8 *inBuffer = M4OSA_NULL; 1425 M4OSA_UInt32 outputBufferWidth =0, outputBufferHeight=0; 1426 1427 //frameSize = (videoWidth*videoHeight*3) >> 1; 1428 inBuffer = (M4OSA_UInt8 *)dataPtr; 1429 1430 // In plane 1431 prepareYUV420ImagePlane(planeIn, videoWidth, 1432 videoHeight, (M4VIFI_UInt8 *)inBuffer, videoWidth, videoHeight); 1433 1434 outputBufferWidth = mOutputVideoWidth; 1435 outputBufferHeight = mOutputVideoHeight; 1436 1437 // Out plane 1438 uint8_t* outBuffer; 1439 size_t outBufferStride = 0; 1440 1441 LOGV("doMediaRendering CALL getBuffer()"); 1442 mTarget->getBufferYV12(&outBuffer, &outBufferStride); 1443 1444 // Set the output YUV420 plane to be compatible with YV12 format 1445 //In YV12 format, sizes must be even 1446 M4OSA_UInt32 yv12PlaneWidth = ((mOutputVideoWidth +1)>>1)<<1; 1447 M4OSA_UInt32 yv12PlaneHeight = ((mOutputVideoHeight+1)>>1)<<1; 1448 1449 prepareYV12ImagePlane(planeOut, yv12PlaneWidth, yv12PlaneHeight, 1450 (M4OSA_UInt32)outBufferStride, (M4VIFI_UInt8 *)outBuffer); 1451 1452 err = applyRenderingMode(planeIn, planeOut, mRenderingMode); 1453 if(err != M4NO_ERROR) { 1454 LOGE("doImageRenderingMode: applyRenderingMode returned err=0x%x", (unsigned int)err); 1455 } 1456 return err; 1457} 1458 1459} //namespace android 1460