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