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