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