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