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