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