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