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