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