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