videoeditor preview code on honeycomb
Change-Id: I9c3c9cb921ea697ab16732973d26ef9035cda2ee
diff --git a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp
new file mode 100755
index 0000000..d862255
--- /dev/null
+++ b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp
@@ -0,0 +1,1303 @@
+/*
+ * Copyright (C) 2011 NXP Software
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 1
+#define LOG_TAG "VideoEditorPreviewController"
+#include "VideoEditorPreviewController.h"
+
+namespace android {
+
+#define PREVIEW_THREAD_STACK_SIZE (65536)
+
+VideoEditorPreviewController::VideoEditorPreviewController()
+ : mCurrentPlayer(0),
+ mThreadContext(NULL),
+ mPlayerState(VePlayerIdle),
+ mClipList(NULL),
+ mNumberClipsInStoryBoard(0),
+ mNumberClipsToPreview(0),
+ mStartingClipIndex(0),
+ mPreviewLooping(M4OSA_FALSE),
+ mCallBackAfterFrameCnt(0),
+ mEffectsSettings(NULL),
+ mNumberEffects(0),
+ mCurrentClipNumber(-1),
+ mClipTotalDuration(0),
+ mCurrentVideoEffect(VIDEO_EFFECT_NONE),
+ mTarget(NULL),
+ mJniCookie(NULL),
+ mJniCallback(NULL),
+ mBackgroundAudioSetting(NULL),
+ mAudioMixPCMFileHandle(NULL),
+ mVideoStoryBoardTimeMsUptoFirstPreviewClip(0),
+ mCurrentPlayedDuration(0),
+ mCurrentClipDuration(0),
+ mOutputVideoWidth(0),
+ mOutputVideoHeight(0),
+ bStopThreadInProgress(false),
+ mSemThreadWait(NULL) {
+ LOGV("VideoEditorPreviewController");
+ mRenderingMode = M4xVSS_kBlackBorders;
+ mIsFiftiesEffectStarted = false;
+
+ for (int i=0; i<NBPLAYER_INSTANCES; i++) {
+ mVePlayer[i] = NULL;
+ }
+}
+
+VideoEditorPreviewController::~VideoEditorPreviewController() {
+ M4OSA_UInt32 i = 0;
+ M4OSA_ERR err = M4NO_ERROR;
+ LOGV("~VideoEditorPreviewController");
+
+ // Stop the thread if its still running
+ if(mThreadContext != NULL) {
+ err = M4OSA_threadSyncStop(mThreadContext);
+ if(err != M4NO_ERROR) {
+ LOGV("~VideoEditorPreviewController: error 0x%x \
+ in trying to stop thread", err);
+ // Continue even if error
+ }
+
+ err = M4OSA_threadSyncClose(mThreadContext);
+ if(err != M4NO_ERROR) {
+ LOGE("~VideoEditorPreviewController: error 0x%x \
+ in trying to close thread", err);
+ // Continue even if error
+ }
+
+ mThreadContext = NULL;
+ }
+
+ for (int playerInst=0; playerInst<NBPLAYER_INSTANCES;
+ playerInst++) {
+ if(mVePlayer[playerInst] != NULL) {
+ LOGV("clearing mVePlayer %d", playerInst);
+ mVePlayer[playerInst].clear();
+ }
+ }
+
+ if(mClipList != NULL) {
+ // Clean up
+ for(i=0;i<mNumberClipsInStoryBoard;i++)
+ {
+ if(mClipList[i]->pFile != NULL) {
+ M4OSA_free((M4OSA_MemAddr32)mClipList[i]->pFile);
+ mClipList[i]->pFile = NULL;
+ }
+
+ M4OSA_free((M4OSA_MemAddr32)mClipList[i]);
+ }
+ M4OSA_free((M4OSA_MemAddr32)mClipList);
+ mClipList = NULL;
+ }
+
+ if(mEffectsSettings) {
+ for(i=0;i<mNumberEffects;i++) {
+ if(mEffectsSettings[i].xVSS.pFramingBuffer != NULL) {
+ M4OSA_free(
+ (M4OSA_MemAddr32)mEffectsSettings[i].xVSS.pFramingBuffer->pac_data);
+
+ M4OSA_free(
+ (M4OSA_MemAddr32)mEffectsSettings[i].xVSS.pFramingBuffer);
+
+ mEffectsSettings[i].xVSS.pFramingBuffer = NULL;
+ }
+ }
+ M4OSA_free((M4OSA_MemAddr32)mEffectsSettings);
+ mEffectsSettings = NULL;
+ }
+
+ if(mTarget != NULL) {
+ delete mTarget;
+ mTarget = NULL;
+ }
+
+ LOGV("~VideoEditorPreviewController returns");
+}
+
+M4OSA_ERR VideoEditorPreviewController::loadEditSettings(
+ M4VSS3GPP_EditSettings* pSettings,M4xVSS_AudioMixingSettings* bgmSettings) {
+
+ M4OSA_UInt32 i = 0, iClipDuration = 0, rgbSize = 0;
+ M4VIFI_UInt8 *tmp = NULL;
+ M4OSA_ERR err = M4NO_ERROR;
+
+ LOGV("loadEditSettings");
+ LOGV("loadEditSettings Channels = %d, sampling Freq %d",
+ bgmSettings->uiNbChannels, bgmSettings->uiSamplingFrequency );
+ bgmSettings->uiSamplingFrequency = 32000;
+
+ LOGV("loadEditSettings Channels = %d, sampling Freq %d",
+ bgmSettings->uiNbChannels, bgmSettings->uiSamplingFrequency );
+ Mutex::Autolock autoLock(mLock);
+
+ // Clean up any previous Edit settings before loading new ones
+ mCurrentVideoEffect = VIDEO_EFFECT_NONE;
+
+ if(mAudioMixPCMFileHandle) {
+ err = M4OSA_fileReadClose (mAudioMixPCMFileHandle);
+ mAudioMixPCMFileHandle = M4OSA_NULL;
+ }
+
+ if(mBackgroundAudioSetting != NULL) {
+ M4OSA_free((M4OSA_MemAddr32)mBackgroundAudioSetting);
+ mBackgroundAudioSetting = NULL;
+ }
+
+ if(mClipList != NULL) {
+ // Clean up
+ for(i=0;i<mNumberClipsInStoryBoard;i++)
+ {
+ if(mClipList[i]->pFile != NULL) {
+ M4OSA_free((M4OSA_MemAddr32)mClipList[i]->pFile);
+ mClipList[i]->pFile = NULL;
+ }
+
+ M4OSA_free((M4OSA_MemAddr32)mClipList[i]);
+ }
+ M4OSA_free((M4OSA_MemAddr32)mClipList);
+ mClipList = NULL;
+ }
+
+ if(mEffectsSettings) {
+ for(i=0;i<mNumberEffects;i++) {
+ if(mEffectsSettings[i].xVSS.pFramingBuffer != NULL) {
+ M4OSA_free(
+ (M4OSA_MemAddr32)mEffectsSettings[i].xVSS.pFramingBuffer->pac_data);
+
+ M4OSA_free(
+ (M4OSA_MemAddr32)mEffectsSettings[i].xVSS.pFramingBuffer);
+
+ mEffectsSettings[i].xVSS.pFramingBuffer = NULL;
+ }
+ }
+ M4OSA_free((M4OSA_MemAddr32)mEffectsSettings);
+ mEffectsSettings = NULL;
+ }
+
+ if(mClipList == NULL) {
+ mNumberClipsInStoryBoard = pSettings->uiClipNumber;
+ LOGV("loadEditSettings: # of Clips = %d", mNumberClipsInStoryBoard);
+
+ mClipList = (M4VSS3GPP_ClipSettings**)M4OSA_malloc(
+ sizeof(M4VSS3GPP_ClipSettings*)*pSettings->uiClipNumber, M4VS,
+ (M4OSA_Char*)"LvPP, copy of pClipList");
+
+ if(NULL == mClipList) {
+ LOGE("loadEditSettings: Malloc error");
+ return M4ERR_ALLOC;
+ }
+ M4OSA_memset((M4OSA_MemAddr8)mClipList,
+ sizeof(M4VSS3GPP_ClipSettings*)*pSettings->uiClipNumber, 0);
+
+ for(i=0;i<pSettings->uiClipNumber;i++) {
+
+ // Allocate current clip
+ mClipList[i] =
+ (M4VSS3GPP_ClipSettings*)M4OSA_malloc(
+ sizeof(M4VSS3GPP_ClipSettings),M4VS,(M4OSA_Char*)"clip settings");
+
+ if(mClipList[i] == NULL) {
+
+ LOGE("loadEditSettings: Allocation error for mClipList[%d]", i);
+ return M4ERR_ALLOC;
+ }
+ // Copy plain structure
+ M4OSA_memcpy((M4OSA_MemAddr8)mClipList[i],
+ (M4OSA_MemAddr8)pSettings->pClipList[i],
+ sizeof(M4VSS3GPP_ClipSettings));
+
+ if(NULL != pSettings->pClipList[i]->pFile) {
+ mClipList[i]->pFile = (M4OSA_Char*)M4OSA_malloc(
+ pSettings->pClipList[i]->filePathSize, M4VS,
+ (M4OSA_Char*)"pClipSettingsDest->pFile");
+
+ if(NULL == mClipList[i]->pFile)
+ {
+ LOGE("loadEditSettings : ERROR allocating filename");
+ return M4ERR_ALLOC;
+ }
+
+ M4OSA_memcpy((M4OSA_MemAddr8)mClipList[i]->pFile,
+ (M4OSA_MemAddr8)pSettings->pClipList[i]->pFile,
+ pSettings->pClipList[i]->filePathSize);
+ }
+ else {
+ LOGE("NULL file path");
+ return M4ERR_PARAMETER;
+ }
+
+ // Calculate total duration of all clips
+ iClipDuration = pSettings->pClipList[i]->uiEndCutTime -
+ pSettings->pClipList[i]->uiBeginCutTime;
+
+ mClipTotalDuration = mClipTotalDuration+iClipDuration;
+ }
+ }
+
+ if(mEffectsSettings == NULL) {
+ mNumberEffects = pSettings->nbEffects;
+ LOGV("loadEditSettings: mNumberEffects = %d", mNumberEffects);
+
+ if(mNumberEffects != 0) {
+ mEffectsSettings = (M4VSS3GPP_EffectSettings*)M4OSA_malloc(
+ mNumberEffects*sizeof(M4VSS3GPP_EffectSettings),
+ M4VS, (M4OSA_Char*)"effects settings");
+
+ if(mEffectsSettings == NULL) {
+ LOGE("loadEffectsSettings: Allocation error");
+ return M4ERR_ALLOC;
+ }
+
+ M4OSA_memset((M4OSA_MemAddr8)mEffectsSettings,
+ mNumberEffects*sizeof(M4VSS3GPP_EffectSettings), 0);
+
+ for(i=0;i<mNumberEffects;i++) {
+
+ mEffectsSettings[i].xVSS.pFramingFilePath = NULL;
+ mEffectsSettings[i].xVSS.pFramingBuffer = NULL;
+ mEffectsSettings[i].xVSS.pTextBuffer = NULL;
+
+ M4OSA_memcpy((M4OSA_MemAddr8)&(mEffectsSettings[i]),
+ (M4OSA_MemAddr8)&(pSettings->Effects[i]),
+ sizeof(M4VSS3GPP_EffectSettings));
+
+ if(pSettings->Effects[i].VideoEffectType ==
+ M4xVSS_kVideoEffectType_Framing) {
+ // Allocate the pFraming RGB buffer
+ mEffectsSettings[i].xVSS.pFramingBuffer =
+ (M4VIFI_ImagePlane *)M4OSA_malloc(sizeof(M4VIFI_ImagePlane),
+ M4VS, (M4OSA_Char*)"lvpp framing buffer");
+
+ if(mEffectsSettings[i].xVSS.pFramingBuffer == NULL) {
+ LOGE("loadEffectsSettings:Alloc error for pFramingBuf");
+ M4OSA_free((M4OSA_MemAddr32)mEffectsSettings);
+ mEffectsSettings = NULL;
+ return M4ERR_ALLOC;
+ }
+
+ // Allocate the pac_data (RGB)
+ if(pSettings->Effects[i].xVSS.rgbType == M4VSS3GPP_kRGB565){
+ rgbSize =
+ pSettings->Effects[i].xVSS.pFramingBuffer->u_width *
+ pSettings->Effects[i].xVSS.pFramingBuffer->u_height*2;
+ }
+ else if(
+ pSettings->Effects[i].xVSS.rgbType == M4VSS3GPP_kRGB888) {
+ rgbSize =
+ pSettings->Effects[i].xVSS.pFramingBuffer->u_width *
+ pSettings->Effects[i].xVSS.pFramingBuffer->u_height*3;
+ }
+ else {
+ LOGE("loadEffectsSettings: wrong RGB type");
+ M4OSA_free((M4OSA_MemAddr32)mEffectsSettings);
+ mEffectsSettings = NULL;
+ return M4ERR_PARAMETER;
+ }
+
+ tmp = (M4VIFI_UInt8 *)M4OSA_malloc(rgbSize, M4VS,
+ (M4OSA_Char*)"framing buffer pac_data");
+
+ if(tmp == NULL) {
+ LOGE("loadEffectsSettings:Alloc error pFramingBuf pac");
+ M4OSA_free((M4OSA_MemAddr32)mEffectsSettings);
+ mEffectsSettings = NULL;
+ M4OSA_free(
+ (M4OSA_MemAddr32)mEffectsSettings[i].xVSS.pFramingBuffer);
+
+ mEffectsSettings[i].xVSS.pFramingBuffer = NULL;
+ return M4ERR_ALLOC;
+ }
+ /* Initialize the pFramingBuffer*/
+ mEffectsSettings[i].xVSS.pFramingBuffer->pac_data = tmp;
+ mEffectsSettings[i].xVSS.pFramingBuffer->u_height =
+ pSettings->Effects[i].xVSS.pFramingBuffer->u_height;
+
+ mEffectsSettings[i].xVSS.pFramingBuffer->u_width =
+ pSettings->Effects[i].xVSS.pFramingBuffer->u_width;
+
+ mEffectsSettings[i].xVSS.pFramingBuffer->u_stride =
+ pSettings->Effects[i].xVSS.pFramingBuffer->u_stride;
+
+ mEffectsSettings[i].xVSS.pFramingBuffer->u_topleft =
+ pSettings->Effects[i].xVSS.pFramingBuffer->u_topleft;
+
+ mEffectsSettings[i].xVSS.uialphaBlendingStart =
+ pSettings->Effects[i].xVSS.uialphaBlendingStart;
+
+ mEffectsSettings[i].xVSS.uialphaBlendingMiddle =
+ pSettings->Effects[i].xVSS.uialphaBlendingMiddle;
+
+ mEffectsSettings[i].xVSS.uialphaBlendingEnd =
+ pSettings->Effects[i].xVSS.uialphaBlendingEnd;
+
+ mEffectsSettings[i].xVSS.uialphaBlendingFadeInTime =
+ pSettings->Effects[i].xVSS.uialphaBlendingFadeInTime;
+ mEffectsSettings[i].xVSS.uialphaBlendingFadeOutTime =
+ pSettings->Effects[i].xVSS.uialphaBlendingFadeOutTime;
+
+ // Copy the pFraming data
+ M4OSA_memcpy((M4OSA_MemAddr8)
+ mEffectsSettings[i].xVSS.pFramingBuffer->pac_data,
+ (M4OSA_MemAddr8)pSettings->Effects[i].xVSS.pFramingBuffer->pac_data,
+ rgbSize);
+
+ mEffectsSettings[i].xVSS.rgbType =
+ pSettings->Effects[i].xVSS.rgbType;
+ }
+ }
+ }
+ }
+
+ if (mBackgroundAudioSetting == NULL) {
+
+ mBackgroundAudioSetting = (M4xVSS_AudioMixingSettings*)M4OSA_malloc(
+ sizeof(M4xVSS_AudioMixingSettings), M4VS,
+ (M4OSA_Char*)"LvPP, copy of bgmSettings");
+
+ if(NULL == mBackgroundAudioSetting) {
+ LOGE("loadEditSettings: mBackgroundAudioSetting Malloc failed");
+ return M4ERR_ALLOC;
+ }
+
+ M4OSA_memset((M4OSA_MemAddr8)mBackgroundAudioSetting, sizeof(M4xVSS_AudioMixingSettings*), 0);
+ M4OSA_memcpy((M4OSA_MemAddr8)mBackgroundAudioSetting, (M4OSA_MemAddr8)bgmSettings, sizeof(M4xVSS_AudioMixingSettings));
+
+ if ( mBackgroundAudioSetting->pFile != M4OSA_NULL ) {
+
+ mBackgroundAudioSetting->pFile = (M4OSA_Void*) bgmSettings->pPCMFilePath;
+ mBackgroundAudioSetting->uiNbChannels = 2;
+ mBackgroundAudioSetting->uiSamplingFrequency = 32000;
+ }
+
+ // Open the BG file
+ if ( mBackgroundAudioSetting->pFile != M4OSA_NULL ) {
+ err = M4OSA_fileReadOpen(&mAudioMixPCMFileHandle,
+ mBackgroundAudioSetting->pFile, M4OSA_kFileRead);
+
+ if (err != M4NO_ERROR) {
+ LOGE("loadEditSettings: mBackgroundAudio PCM File open failed");
+ return M4ERR_PARAMETER;
+ }
+ }
+ }
+
+ mOutputVideoSize = pSettings->xVSS.outputVideoSize;
+ mFrameStr.pBuffer = M4OSA_NULL;
+ return M4NO_ERROR;
+}
+
+M4OSA_ERR VideoEditorPreviewController::setSurface(const sp<Surface> &surface) {
+ LOGV("setSurface");
+ Mutex::Autolock autoLock(mLock);
+
+ mSurface = surface;
+ mISurface = surface->getISurface();
+ LOGV("setSurface: mISurface = %p", mISurface.get());
+ return M4NO_ERROR;
+}
+
+M4OSA_ERR VideoEditorPreviewController::startPreview(
+ M4OSA_UInt32 fromMS, M4OSA_Int32 toMs, M4OSA_UInt16 callBackAfterFrameCount,
+ M4OSA_Bool loop) {
+
+ M4OSA_ERR err = M4NO_ERROR;
+ M4OSA_UInt32 i = 0, iIncrementedDuration = 0;
+ LOGV("startPreview");
+
+ if(fromMS > toMs) {
+ LOGE("startPreview: fromMS > toMs");
+ return M4ERR_PARAMETER;
+ }
+
+ if(toMs == 0) {
+ LOGE("startPreview: toMs is 0");
+ return M4ERR_PARAMETER;
+ }
+
+ // If already started, then stop preview first
+ for(int playerInst=0; playerInst<NBPLAYER_INSTANCES; playerInst++) {
+ if(mVePlayer[playerInst] != NULL) {
+ LOGV("startPreview: stopping previously started preview playback");
+ stopPreview();
+ break;
+ }
+ }
+
+ // If renderPreview was called previously, then delete Renderer object first
+ if(mTarget != NULL) {
+ LOGV("startPreview: delete previous PreviewRenderer");
+ delete mTarget;
+ mTarget = NULL;
+ }
+
+ LOGV("startPreview: loop = %d", loop);
+ mPreviewLooping = loop;
+
+ LOGV("startPreview: callBackAfterFrameCount = %d", callBackAfterFrameCount);
+ mCallBackAfterFrameCnt = callBackAfterFrameCount;
+
+ for (int playerInst=0; playerInst<NBPLAYER_INSTANCES; playerInst++) {
+ mVePlayer[playerInst] = new VideoEditorPlayer();
+ if(mVePlayer[playerInst] == NULL) {
+ LOGE("startPreview:Error creating VideoEditorPlayer %d",playerInst);
+ return M4ERR_ALLOC;
+ }
+ LOGV("startPreview: object created");
+
+ mVePlayer[playerInst]->setNotifyCallback(this,(notify_callback_f)notify);
+ LOGV("startPreview: notify callback set");
+
+ mVePlayer[playerInst]->loadEffectsSettings(mEffectsSettings,
+ mNumberEffects);
+ LOGV("startPreview: effects settings loaded");
+
+ mVePlayer[playerInst]->loadAudioMixSettings(mBackgroundAudioSetting);
+ LOGV("startPreview: AudioMixSettings settings loaded");
+
+ mVePlayer[playerInst]->setAudioMixPCMFileHandle(mAudioMixPCMFileHandle);
+ LOGV("startPreview: AudioMixPCMFileHandle set");
+
+ mVePlayer[playerInst]->setProgressCallbackInterval(
+ mCallBackAfterFrameCnt);
+ LOGV("startPreview: setProgressCallBackInterval");
+ }
+
+ mPlayerState = VePlayerIdle;
+
+ if(fromMS == 0) {
+ mCurrentClipNumber = -1;
+ // Save original value
+ mFirstPreviewClipBeginTime = mClipList[0]->uiBeginCutTime;
+ mVideoStoryBoardTimeMsUptoFirstPreviewClip = 0;
+ }
+ else {
+ LOGV("startPreview: fromMS=%d", fromMS);
+ if(fromMS >= mClipTotalDuration) {
+ LOGE("startPreview: fromMS >= mClipTotalDuration");
+ return M4ERR_PARAMETER;
+ }
+ for(i=0;i<mNumberClipsInStoryBoard;i++) {
+ if(fromMS < (iIncrementedDuration + (mClipList[i]->uiEndCutTime -
+ mClipList[i]->uiBeginCutTime))) {
+ // Set to 1 index below,
+ // as threadProcess first increments the clip index
+ // and then processes clip in thread loop
+ mCurrentClipNumber = i-1;
+ LOGV("startPreview:mCurrentClipNumber = %d fromMS=%d",i,fromMS);
+
+ // Save original value
+ mFirstPreviewClipBeginTime = mClipList[i]->uiBeginCutTime;
+
+ // Set correct begin time to start playback
+ if((fromMS+mClipList[i]->uiBeginCutTime) >
+ (iIncrementedDuration+mClipList[i]->uiBeginCutTime)) {
+
+ mClipList[i]->uiBeginCutTime =
+ mClipList[i]->uiBeginCutTime +
+ (fromMS - iIncrementedDuration);
+ }
+ break;
+ }
+ else {
+ iIncrementedDuration = iIncrementedDuration +
+ (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime);
+ }
+ }
+ mVideoStoryBoardTimeMsUptoFirstPreviewClip = iIncrementedDuration;
+ }
+
+ for (int playerInst=0; playerInst<NBPLAYER_INSTANCES; playerInst++) {
+ mVePlayer[playerInst]->setAudioMixStoryBoardParam(fromMS,
+ mFirstPreviewClipBeginTime,
+ mClipList[i]->ClipProperties.uiClipAudioVolumePercentage);
+
+ LOGV("startPreview:setAudioMixStoryBoardSkimTimeStamp set %d cuttime \
+ %d", fromMS, mFirstPreviewClipBeginTime);
+ }
+
+ mStartingClipIndex = mCurrentClipNumber+1;
+
+ // Start playing with player instance 0
+ mCurrentPlayer = 0;
+
+ if(toMs == -1) {
+ LOGV("startPreview: Preview till end of storyboard");
+ mNumberClipsToPreview = mNumberClipsInStoryBoard;
+ // Save original value
+ mLastPreviewClipEndTime =
+ mClipList[mNumberClipsToPreview-1]->uiEndCutTime;
+ }
+ else {
+ LOGV("startPreview: toMs=%d", toMs);
+ if(toMs > mClipTotalDuration) {
+ LOGE("startPreview: toMs > mClipTotalDuration");
+ return M4ERR_PARAMETER;
+ }
+
+ iIncrementedDuration = 0;
+
+ for(i=0;i<mNumberClipsInStoryBoard;i++) {
+ if(toMs <= (iIncrementedDuration +
+ (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime))) {
+ // Save original value
+ mLastPreviewClipEndTime = mClipList[i]->uiEndCutTime;
+ // Set the end cut time of clip index i to toMs
+ mClipList[i]->uiEndCutTime = toMs;
+
+ // Number of clips to be previewed is from index 0 to i
+ // increment by 1 as i starts from 0
+ mNumberClipsToPreview = i+1;
+ break;
+ }
+ else {
+ iIncrementedDuration = iIncrementedDuration +
+ (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime);
+ }
+ }
+ }
+
+ // Open the thread semaphore
+ M4OSA_semaphoreOpen(&mSemThreadWait, 1);
+
+ // Open the preview process thread
+ err = M4OSA_threadSyncOpen(&mThreadContext, (M4OSA_ThreadDoIt)threadProc);
+ if (M4NO_ERROR != err) {
+ LOGE("VideoEditorPreviewController:M4OSA_threadSyncOpen error %d", err);
+ return err;
+ }
+
+ // Set the stacksize
+ err = M4OSA_threadSyncSetOption(mThreadContext, M4OSA_ThreadStackSize,
+ (M4OSA_DataOption)PREVIEW_THREAD_STACK_SIZE);
+
+ if (M4NO_ERROR != err) {
+ LOGE("VideoEditorPreviewController: threadSyncSetOption error %d", err);
+ M4OSA_threadSyncClose(mThreadContext);
+ mThreadContext = NULL;
+ return err;
+ }
+
+ // Start the thread
+ err = M4OSA_threadSyncStart(mThreadContext, (M4OSA_Void*)this);
+ if (M4NO_ERROR != err) {
+ LOGE("VideoEditorPreviewController: threadSyncStart error %d", err);
+ M4OSA_threadSyncClose(mThreadContext);
+ mThreadContext = NULL;
+ return err;
+ }
+ bStopThreadInProgress = false;
+
+ LOGV("startPreview: process thread started");
+ return M4NO_ERROR;
+}
+
+M4OSA_ERR VideoEditorPreviewController::stopPreview() {
+ M4OSA_ERR err = M4NO_ERROR;
+ LOGV("stopPreview");
+
+ // Stop the thread
+ if(mThreadContext != NULL) {
+ bStopThreadInProgress = true;
+ err = M4OSA_semaphorePost(mSemThreadWait);
+
+ err = M4OSA_threadSyncStop(mThreadContext);
+ if(err != M4NO_ERROR) {
+ LOGV("stopPreview: error 0x%x in trying to stop thread", err);
+ // Continue even if error
+ }
+
+ err = M4OSA_threadSyncClose(mThreadContext);
+ if(err != M4NO_ERROR) {
+ LOGE("stopPreview: error 0x%x in trying to close thread", err);
+ // Continue even if error
+ }
+
+ mThreadContext = NULL;
+ }
+
+ // Close the semaphore first
+ if(mSemThreadWait != NULL) {
+ err = M4OSA_semaphoreClose(mSemThreadWait);
+ LOGV("stopPreview: close semaphore returns 0x%x", err);
+ }
+
+ for (int playerInst=0; playerInst<NBPLAYER_INSTANCES; playerInst++) {
+ if(mVePlayer[playerInst] != NULL) {
+ if(mVePlayer[playerInst]->isPlaying()) {
+ LOGV("stop the player first");
+ mVePlayer[playerInst]->stop();
+ }
+
+ LOGV("stopPreview: clearing mVePlayer");
+ mVePlayer[playerInst].clear();
+ mVePlayer[playerInst] = NULL;
+ }
+ }
+
+ // If image file playing, then free the buffer pointer
+ if(mFrameStr.pBuffer != M4OSA_NULL) {
+ M4OSA_free((M4OSA_MemAddr32)mFrameStr.pBuffer);
+ mFrameStr.pBuffer = M4OSA_NULL;
+ }
+
+ // Reset original begin cuttime of first previewed clip*/
+ mClipList[mStartingClipIndex]->uiBeginCutTime = mFirstPreviewClipBeginTime;
+ // Reset original end cuttime of last previewed clip*/
+ mClipList[mNumberClipsToPreview-1]->uiEndCutTime = mLastPreviewClipEndTime;
+
+ mPlayerState = VePlayerIdle;
+
+ mCurrentPlayedDuration = 0;
+ mCurrentClipDuration = 0;
+ mRenderingMode = M4xVSS_kBlackBorders;
+ mOutputVideoWidth = 0;
+ mOutputVideoHeight = 0;
+
+ return M4NO_ERROR;
+}
+
+M4OSA_ERR VideoEditorPreviewController::renderPreviewFrame(
+ const sp<Surface> &surface, VideoEditor_renderPreviewFrameStr* pFrameInfo) {
+
+ M4OSA_ERR err = M4NO_ERROR;
+ M4OSA_UInt32 i = 0, iIncrementedDuration = 0, tnTimeMs=0, framesize =0;
+ VideoEditor_renderPreviewFrameStr* pFrameStr = pFrameInfo;
+ M4VIFI_UInt8 *pixelArray = NULL;
+
+ Mutex::Autolock autoLock(mLock);
+
+ // Get the Isurface to be passed to renderer
+ mISurface = surface->getISurface();
+
+ // Delete previous renderer instance
+ if(mTarget != NULL) {
+ delete mTarget;
+ mTarget = NULL;
+ }
+
+ if(mOutputVideoWidth == 0) {
+ mOutputVideoWidth = pFrameStr->uiFrameWidth;
+ }
+ if(mOutputVideoHeight == 0) {
+ mOutputVideoHeight = pFrameStr->uiFrameHeight;
+ }
+
+ // Initialize the renderer
+ if(mTarget == NULL) {
+ mTarget = new PreviewRenderer(
+ OMX_COLOR_FormatYUV420Planar, surface, mOutputVideoWidth, mOutputVideoHeight,
+ mOutputVideoWidth, mOutputVideoHeight, 0);
+ if(mTarget == NULL) {
+ LOGE("renderPreviewFrame: cannot create PreviewRenderer");
+ return M4ERR_ALLOC;
+ }
+ }
+
+ pixelArray = NULL;
+
+ // Postprocessing (apply video effect)
+ if(pFrameStr->bApplyEffect == M4OSA_TRUE) {
+
+ for(i=0;i<mNumberEffects;i++) {
+ // First check if effect starttime matches the clip being previewed
+ if((mEffectsSettings[i].uiStartTime < pFrameStr->clipBeginCutTime)
+ ||(mEffectsSettings[i].uiStartTime >= pFrameStr->clipEndCutTime)) {
+ // This effect doesn't belong to this clip, check next one
+ continue;
+ }
+ if((mEffectsSettings[i].uiStartTime <= pFrameStr->timeMs) &&
+ ((mEffectsSettings[i].uiStartTime+mEffectsSettings[i].uiDuration) >=
+ pFrameStr->timeMs) && (mEffectsSettings[i].uiDuration != 0)) {
+ setVideoEffectType(mEffectsSettings[i].VideoEffectType, TRUE);
+ }
+ else {
+ setVideoEffectType(mEffectsSettings[i].VideoEffectType, FALSE);
+ }
+ }
+
+ if(mCurrentVideoEffect != VIDEO_EFFECT_NONE) {
+ err = applyVideoEffect((M4OSA_Void *)pFrameStr->pBuffer,
+ OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth,
+ pFrameStr->uiFrameHeight, pFrameStr->timeMs,
+ (M4OSA_Void *)pixelArray);
+
+ if(err != M4NO_ERROR) {
+ LOGE("renderPreviewFrame: applyVideoEffect error 0x%x", err);
+ delete mTarget;
+ mTarget = NULL;
+ M4OSA_free((M4OSA_MemAddr32)pixelArray);
+ pixelArray = NULL;
+ return err;
+ }
+ mCurrentVideoEffect = VIDEO_EFFECT_NONE;
+ }
+ else {
+ // Apply the rendering mode
+ err = doImageRenderingMode((M4OSA_Void *)pFrameStr->pBuffer,
+ OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth,
+ pFrameStr->uiFrameHeight, (M4OSA_Void *)pixelArray);
+
+ if(err != M4NO_ERROR) {
+ LOGE("renderPreviewFrame:doImageRenderingMode error 0x%x", err);
+ delete mTarget;
+ mTarget = NULL;
+ M4OSA_free((M4OSA_MemAddr32)pixelArray);
+ pixelArray = NULL;
+ return err;
+ }
+ }
+ }
+ else {
+ // Apply the rendering mode
+ err = doImageRenderingMode((M4OSA_Void *)pFrameStr->pBuffer,
+ OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth,
+ pFrameStr->uiFrameHeight, (M4OSA_Void *)pixelArray);
+
+ if(err != M4NO_ERROR) {
+ LOGE("renderPreviewFrame: doImageRenderingMode error 0x%x", err);
+ delete mTarget;
+ mTarget = NULL;
+ M4OSA_free((M4OSA_MemAddr32)pixelArray);
+ pixelArray = NULL;
+ return err;
+ }
+ }
+
+ mTarget->renderYV12();
+ return err;
+}
+
+M4OSA_Void VideoEditorPreviewController::setJniCallback(void* cookie,
+ jni_progress_callback_fct callbackFct) {
+ //LOGV("setJniCallback");
+ mJniCookie = cookie;
+ mJniCallback = callbackFct;
+}
+
+M4OSA_ERR VideoEditorPreviewController::preparePlayer(
+ void* param, int playerInstance, int index) {
+
+ M4OSA_ERR err = M4NO_ERROR;
+ VideoEditorPreviewController *pController =
+ (VideoEditorPreviewController *)param;
+
+ LOGV("preparePlayer: instance %d file %d", playerInstance, index);
+
+ pController->mVePlayer[playerInstance]->setDataSource(
+ (const char *)pController->mClipList[index]->pFile, NULL);
+ LOGV("preparePlayer: setDataSource instance %s",
+ (const char *)pController->mClipList[index]->pFile);
+
+ pController->mVePlayer[playerInstance]->setVideoISurface(
+ pController->mISurface);
+ LOGV("preparePlayer: setVideoISurface");
+
+ pController->mVePlayer[playerInstance]->setVideoSurface(
+ pController->mSurface);
+ LOGV("preparePlayer: setVideoSurface");
+
+ pController->mVePlayer[playerInstance]->setMediaRenderingMode(
+ pController->mClipList[index]->xVSS.MediaRendering,
+ pController->mOutputVideoSize);
+ LOGV("preparePlayer: setMediaRenderingMode");
+
+ if(index == pController->mStartingClipIndex) {
+ pController->mVePlayer[playerInstance]->setPlaybackBeginTime(
+ pController->mFirstPreviewClipBeginTime);
+ }
+ else {
+ pController->mVePlayer[playerInstance]->setPlaybackBeginTime(
+ pController->mClipList[index]->uiBeginCutTime);
+ }
+ LOGV("preparePlayer: setPlaybackBeginTime(%d)",
+ pController->mClipList[index]->uiBeginCutTime);
+
+ pController->mVePlayer[playerInstance]->setPlaybackEndTime(
+ pController->mClipList[index]->uiEndCutTime);
+ LOGV("preparePlayer: setPlaybackEndTime(%d)",
+ pController->mClipList[index]->uiEndCutTime);
+
+ if(pController->mClipList[index]->FileType == M4VIDEOEDITING_kFileType_ARGB8888) {
+ pController->mVePlayer[playerInstance]->setImageClipProperties(
+ pController->mClipList[index]->ClipProperties.uiVideoWidth,
+ pController->mClipList[index]->ClipProperties.uiVideoHeight);
+ LOGV("preparePlayer: setImageClipProperties");
+ }
+
+ pController->mVePlayer[playerInstance]->prepare();
+ LOGV("preparePlayer: prepared");
+
+ if(pController->mClipList[index]->uiBeginCutTime > 0) {
+ pController->mVePlayer[playerInstance]->seekTo(
+ pController->mClipList[index]->uiBeginCutTime);
+
+ LOGV("preparePlayer: seekTo(%d)",
+ pController->mClipList[index]->uiBeginCutTime);
+ }
+
+ pController->mVePlayer[playerInstance]->readFirstVideoFrame();
+ LOGV("preparePlayer: readFirstVideoFrame of clip");
+
+ return err;
+}
+
+M4OSA_ERR VideoEditorPreviewController::threadProc(M4OSA_Void* param) {
+ M4OSA_ERR err = M4NO_ERROR;
+ M4OSA_Int32 index = 0;
+ VideoEditorPreviewController *pController =
+ (VideoEditorPreviewController *)param;
+
+ LOGV("inside threadProc");
+ if(pController->mPlayerState == VePlayerIdle) {
+ (pController->mCurrentClipNumber)++;
+
+ LOGV("threadProc: playing file index %d total clips %d",
+ pController->mCurrentClipNumber, pController->mNumberClipsToPreview);
+
+ if(pController->mCurrentClipNumber >=
+ pController->mNumberClipsToPreview) {
+
+ LOGV("All clips previewed");
+
+ pController->mCurrentPlayedDuration = 0;
+ pController->mCurrentClipDuration = 0;
+ pController->mCurrentPlayer = 0;
+
+ if(pController->mPreviewLooping == M4OSA_TRUE) {
+ pController->mCurrentClipNumber =
+ pController->mStartingClipIndex;
+
+ LOGV("Preview looping TRUE, restarting from clip index %d",
+ pController->mCurrentClipNumber);
+
+ // Reset the story board timestamp inside the player
+ for (int playerInst=0; playerInst<NBPLAYER_INSTANCES;
+ playerInst++) {
+ pController->mVePlayer[playerInst]->resetJniCallbackTimeStamp();
+ }
+ }
+ else {
+ if(pController->mJniCallback != NULL) {
+ pController->mJniCallback(
+ pController->mJniCookie, MSG_TYPE_PREVIEW_END, 0);
+ }
+ pController->mPlayerState = VePlayerAutoStop;
+
+ // Reset original begin cuttime of first previewed clip
+ pController->mClipList[pController->mStartingClipIndex]->uiBeginCutTime =
+ pController->mFirstPreviewClipBeginTime;
+ // Reset original end cuttime of last previewed clip
+ pController->mClipList[pController->mNumberClipsToPreview-1]->uiEndCutTime =
+ pController->mLastPreviewClipEndTime;
+
+ // Return a warning to M4OSA thread handler
+ // so that thread is moved from executing state to open state
+ return M4WAR_NO_MORE_STREAM;
+ }
+ }
+
+ index=pController->mCurrentClipNumber;
+ if(pController->mCurrentClipNumber == pController->mStartingClipIndex) {
+ pController->mCurrentPlayedDuration +=
+ pController->mVideoStoryBoardTimeMsUptoFirstPreviewClip;
+
+ pController->mCurrentClipDuration =
+ pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime
+ - pController->mFirstPreviewClipBeginTime;
+
+ preparePlayer((void*)pController, pController->mCurrentPlayer, index);
+ }
+ else {
+ pController->mCurrentPlayedDuration +=
+ pController->mCurrentClipDuration;
+
+ pController->mCurrentClipDuration =
+ pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime -
+ pController->mClipList[pController->mCurrentClipNumber]->uiBeginCutTime;
+ }
+
+ pController->mVePlayer[pController->mCurrentPlayer]->setStoryboardStartTime(
+ pController->mCurrentPlayedDuration);
+ LOGV("threadProc: setStoryboardStartTime");
+
+ // Set the next clip duration for Audio mix here
+ if(pController->mCurrentClipNumber != pController->mStartingClipIndex) {
+
+ pController->mVePlayer[pController->mCurrentPlayer]->setAudioMixStoryBoardParam(
+ pController->mCurrentPlayedDuration,
+ pController->mClipList[index]->uiBeginCutTime,
+ pController->mClipList[index]->ClipProperties.uiClipAudioVolumePercentage);
+
+ LOGV("threadProc: setAudioMixStoryBoardParam fromMS %d \
+ ClipBeginTime %d", pController->mCurrentPlayedDuration +
+ pController->mClipList[index]->uiBeginCutTime,
+ pController->mClipList[index]->uiBeginCutTime,
+ pController->mClipList[index]->ClipProperties.uiClipAudioVolumePercentage);
+ }
+
+ pController->mVePlayer[pController->mCurrentPlayer]->start();
+ LOGV("threadProc: started");
+
+ pController->mPlayerState = VePlayerBusy;
+
+ }
+ else if(pController->mPlayerState == VePlayerAutoStop) {
+ LOGV("Preview completed..auto stop the player");
+ }
+ else {
+ if(!pController->bStopThreadInProgress) {
+ LOGV("threadProc: state busy...wait for sem");
+ err = M4OSA_semaphoreWait(pController->mSemThreadWait,
+ M4OSA_WAIT_FOREVER);
+ }
+ LOGV("threadProc: sem wait returned err = 0x%x", err);
+ }
+
+ //Always return M4NO_ERROR to ensure the thread keeps running
+ return M4NO_ERROR;
+}
+
+void VideoEditorPreviewController::notify(
+ void* cookie, int msg, int ext1, int ext2)
+{
+ VideoEditorPreviewController *pController =
+ (VideoEditorPreviewController *)cookie;
+
+ M4OSA_ERR err = M4NO_ERROR;
+ uint32_t clipDuration = 0;
+ switch (msg) {
+ case MEDIA_NOP: // interface test message
+ LOGV("MEDIA_NOP");
+ break;
+ case MEDIA_PREPARED:
+ LOGV("MEDIA_PREPARED");
+ break;
+ case MEDIA_PLAYBACK_COMPLETE:
+ LOGV("notify:MEDIA_PLAYBACK_COMPLETE");
+ pController->mPlayerState = VePlayerIdle;
+
+ //send progress callback with last frame timestamp
+ if(pController->mCurrentClipNumber ==
+ pController->mStartingClipIndex) {
+ clipDuration =
+ pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime
+ - pController->mFirstPreviewClipBeginTime;
+ }
+ else {
+ clipDuration =
+ pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime
+ - pController->mClipList[pController->mCurrentClipNumber]->uiBeginCutTime;
+ }
+ pController->mJniCallback(
+ pController->mJniCookie, MSG_TYPE_PROGRESS_INDICATION,
+ (clipDuration+pController->mCurrentPlayedDuration));
+
+ M4OSA_semaphorePost(pController->mSemThreadWait);
+ break;
+ case MEDIA_ERROR:
+ // Always log errors.
+ // ext1: Media framework error code.
+ // ext2: Implementation dependant error code.
+ LOGE("MEDIA_ERROR; error (%d, %d)", ext1, ext2);
+ if(pController->mJniCallback != NULL) {
+ pController->mJniCallback(pController->mJniCookie,
+ MSG_TYPE_PLAYER_ERROR, ext1);
+ }
+ break;
+ case MEDIA_INFO:
+ // ext1: Media framework error code.
+ // ext2: Implementation dependant error code.
+ //LOGW("MEDIA_INFO; info/warning (%d, %d)", ext1, ext2);
+ if(pController->mJniCallback != NULL) {
+ pController->mJniCallback(pController->mJniCookie,
+ MSG_TYPE_PROGRESS_INDICATION, ext2);
+ }
+ break;
+ case MEDIA_SEEK_COMPLETE:
+ LOGV("MEDIA_SEEK_COMPLETE; Received seek complete");
+ break;
+ case MEDIA_BUFFERING_UPDATE:
+ LOGV("MEDIA_BUFFERING_UPDATE; buffering %d", ext1);
+ break;
+ case MEDIA_SET_VIDEO_SIZE:
+ LOGV("MEDIA_SET_VIDEO_SIZE; New video size %d x %d", ext1, ext2);
+ break;
+ case 0xAAAAAAAA:
+ LOGV("VIDEO PLAYBACK ALMOST over, prepare next player");
+
+ // Select next player and prepare it
+ // If there is a clip after this one
+ if ((pController->mCurrentClipNumber+1) <
+ pController->mNumberClipsToPreview) {
+
+ pController->mCurrentPlayer++;
+ if (pController->mCurrentPlayer >= NBPLAYER_INSTANCES) {
+ pController->mCurrentPlayer = 0;
+ }
+ // Prepare the first clip to be played
+ preparePlayer((void*)pController, pController->mCurrentPlayer,
+ pController->mCurrentClipNumber+1);
+ }
+ break;
+ default:
+ LOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
+ break;
+ }
+}
+
+void VideoEditorPreviewController::setVideoEffectType(
+ M4VSS3GPP_VideoEffectType type, M4OSA_Bool enable) {
+
+ M4OSA_UInt32 effect = VIDEO_EFFECT_NONE;
+
+ // map M4VSS3GPP_VideoEffectType to local enum
+ switch(type) {
+ case M4VSS3GPP_kVideoEffectType_FadeFromBlack:
+ effect = VIDEO_EFFECT_FADEFROMBLACK;
+ break;
+
+ case M4VSS3GPP_kVideoEffectType_FadeToBlack:
+ effect = VIDEO_EFFECT_FADETOBLACK;
+ break;
+
+ case M4VSS3GPP_kVideoEffectType_CurtainOpening:
+ effect = VIDEO_EFFECT_CURTAINOPEN;
+ break;
+
+ case M4VSS3GPP_kVideoEffectType_CurtainClosing:
+ effect = VIDEO_EFFECT_CURTAINCLOSE;
+ break;
+
+ case M4xVSS_kVideoEffectType_BlackAndWhite:
+ effect = VIDEO_EFFECT_BLACKANDWHITE;
+ break;
+
+ case M4xVSS_kVideoEffectType_Pink:
+ effect = VIDEO_EFFECT_PINK;
+ break;
+
+ case M4xVSS_kVideoEffectType_Green:
+ effect = VIDEO_EFFECT_GREEN;
+ break;
+
+ case M4xVSS_kVideoEffectType_Sepia:
+ effect = VIDEO_EFFECT_SEPIA;
+ break;
+
+ case M4xVSS_kVideoEffectType_Negative:
+ effect = VIDEO_EFFECT_NEGATIVE;
+ break;
+
+ case M4xVSS_kVideoEffectType_Framing:
+ effect = VIDEO_EFFECT_FRAMING;
+ break;
+
+ case M4xVSS_kVideoEffectType_Fifties:
+ effect = VIDEO_EFFECT_FIFTIES;
+ break;
+
+ case M4xVSS_kVideoEffectType_ColorRGB16:
+ effect = VIDEO_EFFECT_COLOR_RGB16;
+ break;
+
+ case M4xVSS_kVideoEffectType_Gradient:
+ effect = VIDEO_EFFECT_GRADIENT;
+ break;
+
+ default:
+ effect = VIDEO_EFFECT_NONE;
+ break;
+ }
+
+ if(enable == M4OSA_TRUE) {
+ // If already set, then no need to set again
+ if(!(mCurrentVideoEffect & effect))
+ mCurrentVideoEffect |= effect;
+ if(effect == VIDEO_EFFECT_FIFTIES) {
+ mIsFiftiesEffectStarted = true;
+ }
+ }
+ else {
+ // Reset only if already set
+ if(mCurrentVideoEffect & effect)
+ mCurrentVideoEffect &= ~effect;
+ }
+
+ return;
+}
+
+
+M4OSA_ERR VideoEditorPreviewController::applyVideoEffect(
+ M4OSA_Void * dataPtr, M4OSA_UInt32 colorFormat, M4OSA_UInt32 videoWidth,
+ M4OSA_UInt32 videoHeight, M4OSA_UInt32 timeMs, M4OSA_Void* outPtr) {
+
+ M4OSA_ERR err = M4NO_ERROR;
+ vePostProcessParams postProcessParams;
+
+ postProcessParams.vidBuffer = (M4VIFI_UInt8*)dataPtr;
+ postProcessParams.videoWidth = videoWidth;
+ postProcessParams.videoHeight = videoHeight;
+ postProcessParams.timeMs = timeMs;
+ postProcessParams.timeOffset = 0; //Since timeMS already takes care of offset in this case
+ postProcessParams.effectsSettings = mEffectsSettings;
+ postProcessParams.numberEffects = mNumberEffects;
+ postProcessParams.outVideoWidth = mOutputVideoWidth;
+ postProcessParams.outVideoHeight = mOutputVideoHeight;
+ postProcessParams.currentVideoEffect = mCurrentVideoEffect;
+ postProcessParams.renderingMode = mRenderingMode;
+ if(mIsFiftiesEffectStarted == M4OSA_TRUE) {
+ postProcessParams.isFiftiesEffectStarted = M4OSA_TRUE;
+ mIsFiftiesEffectStarted = M4OSA_FALSE;
+ }
+ else {
+ postProcessParams.isFiftiesEffectStarted = M4OSA_FALSE;
+ }
+ //postProcessParams.renderer = mTarget;
+ postProcessParams.overlayFrameRGBBuffer = NULL;
+ postProcessParams.overlayFrameYUVBuffer = NULL;
+
+ mTarget->getBufferYV12(&(postProcessParams.pOutBuffer), &(postProcessParams.outBufferStride));
+
+ err = applyEffectsAndRenderingMode(&postProcessParams);
+ return err;
+}
+
+M4OSA_ERR VideoEditorPreviewController::setPreviewFrameRenderingMode(
+ M4xVSS_MediaRendering mode, M4VIDEOEDITING_VideoFrameSize outputVideoSize) {
+
+ //LOGV("setMediaRenderingMode: outputVideoSize = %d", outputVideoSize);
+ mRenderingMode = mode;
+
+ switch(outputVideoSize) {
+ case M4VIDEOEDITING_kSQCIF:
+ mOutputVideoWidth = 128;
+ mOutputVideoHeight = 96;
+ break;
+
+ case M4VIDEOEDITING_kQQVGA:
+ mOutputVideoWidth = 160;
+ mOutputVideoHeight = 120;
+ break;
+
+ case M4VIDEOEDITING_kQCIF:
+ mOutputVideoWidth = 176;
+ mOutputVideoHeight = 144;
+ break;
+
+ case M4VIDEOEDITING_kQVGA:
+ mOutputVideoWidth = 320;
+ mOutputVideoHeight = 240;
+ break;
+
+ case M4VIDEOEDITING_kCIF:
+ mOutputVideoWidth = 352;
+ mOutputVideoHeight = 288;
+ break;
+
+ case M4VIDEOEDITING_kVGA:
+ mOutputVideoWidth = 640;
+ mOutputVideoHeight = 480;
+ break;
+
+ case M4VIDEOEDITING_kWVGA:
+ mOutputVideoWidth = 800;
+ mOutputVideoHeight = 480;
+ break;
+
+ case M4VIDEOEDITING_kNTSC:
+ mOutputVideoWidth = 720;
+ mOutputVideoHeight = 480;
+ break;
+
+ case M4VIDEOEDITING_k640_360:
+ mOutputVideoWidth = 640;
+ mOutputVideoHeight = 360;
+ break;
+
+ case M4VIDEOEDITING_k854_480:
+ mOutputVideoWidth = 854;
+ mOutputVideoHeight = 480;
+ break;
+
+ case M4VIDEOEDITING_kHD1280:
+ mOutputVideoWidth = 1280;
+ mOutputVideoHeight = 720;
+ break;
+
+ case M4VIDEOEDITING_kHD1080:
+ mOutputVideoWidth = 1080;
+ mOutputVideoHeight = 720;
+ break;
+
+ case M4VIDEOEDITING_kHD960:
+ mOutputVideoWidth = 960;
+ mOutputVideoHeight = 720;
+ break;
+
+ default:
+ mOutputVideoWidth = 0;
+ mOutputVideoHeight = 0;
+ break;
+ }
+
+ return OK;
+}
+
+M4OSA_ERR VideoEditorPreviewController::doImageRenderingMode(
+ M4OSA_Void * dataPtr, M4OSA_UInt32 colorFormat, M4OSA_UInt32 videoWidth,
+ M4OSA_UInt32 videoHeight, M4OSA_Void* outPtr) {
+
+ M4OSA_ERR err = M4NO_ERROR;
+ M4VIFI_ImagePlane planeIn[3], planeOut[3];
+ M4VIFI_UInt8 *inBuffer = M4OSA_NULL;
+ M4OSA_UInt32 outputBufferWidth =0, outputBufferHeight=0;
+
+ //frameSize = (videoWidth*videoHeight*3) >> 1;
+ inBuffer = (M4OSA_UInt8 *)dataPtr;
+
+ // In plane
+ prepareYUV420ImagePlane(planeIn, videoWidth,
+ videoHeight, (M4VIFI_UInt8 *)inBuffer);
+
+ outputBufferWidth = mOutputVideoWidth;
+ outputBufferHeight = mOutputVideoHeight;
+
+ // Out plane
+ uint8_t* outBuffer;
+ size_t outBufferStride = 0;
+
+ LOGV("doMediaRendering CALL getBuffer()");
+ mTarget->getBufferYV12(&outBuffer, &outBufferStride);
+
+ // Set the output YUV420 plane to be compatible with YV12 format
+ //In YV12 format, sizes must be even
+ M4OSA_UInt32 yv12PlaneWidth = ((mOutputVideoWidth +1)>>1)<<1;
+ M4OSA_UInt32 yv12PlaneHeight = ((mOutputVideoHeight+1)>>1)<<1;
+
+ prepareYV12ImagePlane(planeOut, yv12PlaneWidth, yv12PlaneHeight,
+ (M4OSA_UInt32)outBufferStride, (M4VIFI_UInt8 *)outBuffer);
+
+ err = applyRenderingMode(planeIn, planeOut, mRenderingMode);
+ if(err != M4NO_ERROR) {
+ LOGE("doImageRenderingMode: applyRenderingMode returned err=0x%x", err);
+ }
+ return err;
+}
+
+} //namespace android