blob: 953f35a893d3ea13e21ae6acd3d6a10c189a0a3c [file] [log] [blame]
Chih-Chung Chang99698662011-06-30 14:21:38 +08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
James Dong3d2d40a2012-01-27 19:01:13 -080017// #define LOG_NDEBUG 0
18#define LOG_TAG "PreviewController"
19#include <utils/Log.h>
20
Mathias Agopian90b61912012-02-26 00:40:08 -080021#include <gui/Surface.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080022#include <media/IMediaHTTPService.h>
James Dong3d2d40a2012-01-27 19:01:13 -080023
24#include "VideoEditorAudioPlayer.h"
25#include "PreviewRenderer.h"
26#include "M4OSA_Semaphore.h"
27#include "M4OSA_Thread.h"
Chih-Chung Chang99698662011-06-30 14:21:38 +080028#include "VideoEditorPreviewController.h"
29
30namespace android {
31
Chih-Chung Chang99698662011-06-30 14:21:38 +080032
33VideoEditorPreviewController::VideoEditorPreviewController()
34 : mCurrentPlayer(0),
35 mThreadContext(NULL),
36 mPlayerState(VePlayerIdle),
37 mPrepareReqest(M4OSA_FALSE),
38 mClipList(NULL),
39 mNumberClipsInStoryBoard(0),
40 mNumberClipsToPreview(0),
41 mStartingClipIndex(0),
42 mPreviewLooping(M4OSA_FALSE),
43 mCallBackAfterFrameCnt(0),
44 mEffectsSettings(NULL),
45 mNumberEffects(0),
46 mCurrentClipNumber(-1),
47 mClipTotalDuration(0),
48 mCurrentVideoEffect(VIDEO_EFFECT_NONE),
49 mBackgroundAudioSetting(NULL),
50 mAudioMixPCMFileHandle(NULL),
51 mTarget(NULL),
52 mJniCookie(NULL),
53 mJniCallback(NULL),
54 mCurrentPlayedDuration(0),
55 mCurrentClipDuration(0),
56 mVideoStoryBoardTimeMsUptoFirstPreviewClip(0),
57 mOverlayState(OVERLAY_CLEAR),
58 mActivePlayerIndex(0),
59 mOutputVideoWidth(0),
60 mOutputVideoHeight(0),
61 bStopThreadInProgress(false),
62 mSemThreadWait(NULL) {
Steve Block2703f232011-10-20 11:56:09 +010063 ALOGV("VideoEditorPreviewController");
Chih-Chung Chang99698662011-06-30 14:21:38 +080064 mRenderingMode = M4xVSS_kBlackBorders;
65 mIsFiftiesEffectStarted = false;
66
James Dong3d2d40a2012-01-27 19:01:13 -080067 for (int i = 0; i < kTotalNumPlayerInstances; ++i) {
Chih-Chung Chang99698662011-06-30 14:21:38 +080068 mVePlayer[i] = NULL;
69 }
70}
71
72VideoEditorPreviewController::~VideoEditorPreviewController() {
James Dong3d2d40a2012-01-27 19:01:13 -080073 ALOGV("~VideoEditorPreviewController");
Chih-Chung Chang99698662011-06-30 14:21:38 +080074 M4OSA_UInt32 i = 0;
75 M4OSA_ERR err = M4NO_ERROR;
Chih-Chung Chang99698662011-06-30 14:21:38 +080076
77 // Stop the thread if its still running
78 if(mThreadContext != NULL) {
79 err = M4OSA_threadSyncStop(mThreadContext);
80 if(err != M4NO_ERROR) {
Steve Block2703f232011-10-20 11:56:09 +010081 ALOGV("~VideoEditorPreviewController: error 0x%x \
Chih-Chung Chang99698662011-06-30 14:21:38 +080082 in trying to stop thread", err);
83 // Continue even if error
84 }
85
86 err = M4OSA_threadSyncClose(mThreadContext);
87 if(err != M4NO_ERROR) {
Steve Blockf8bd29c2012-01-08 10:14:44 +000088 ALOGE("~VideoEditorPreviewController: error 0x%x \
Chih-Chung Chang99698662011-06-30 14:21:38 +080089 in trying to close thread", (unsigned int) err);
90 // Continue even if error
91 }
92
93 mThreadContext = NULL;
94 }
95
James Dong3d2d40a2012-01-27 19:01:13 -080096 for (int playerInst=0; playerInst<kTotalNumPlayerInstances;
Chih-Chung Chang99698662011-06-30 14:21:38 +080097 playerInst++) {
98 if(mVePlayer[playerInst] != NULL) {
Steve Block2703f232011-10-20 11:56:09 +010099 ALOGV("clearing mVePlayer %d", playerInst);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800100 mVePlayer[playerInst].clear();
101 }
102 }
103
104 if(mClipList != NULL) {
105 // Clean up
106 for(i=0;i<mNumberClipsInStoryBoard;i++)
107 {
108 if(mClipList[i]->pFile != NULL) {
109 free(mClipList[i]->pFile);
110 mClipList[i]->pFile = NULL;
111 }
112
113 free(mClipList[i]);
114 }
115 free(mClipList);
116 mClipList = NULL;
117 }
118
119 if(mEffectsSettings) {
120 for(i=0;i<mNumberEffects;i++) {
121 if(mEffectsSettings[i].xVSS.pFramingBuffer != NULL) {
122 free(mEffectsSettings[i].xVSS.pFramingBuffer->pac_data);
123
124 free(mEffectsSettings[i].xVSS.pFramingBuffer);
125
126 mEffectsSettings[i].xVSS.pFramingBuffer = NULL;
127 }
128 }
129 free(mEffectsSettings);
130 mEffectsSettings = NULL;
131 }
132
133 if (mAudioMixPCMFileHandle) {
134 err = M4OSA_fileReadClose (mAudioMixPCMFileHandle);
135 mAudioMixPCMFileHandle = M4OSA_NULL;
136 }
137
138 if (mBackgroundAudioSetting != NULL) {
139 free(mBackgroundAudioSetting);
140 mBackgroundAudioSetting = NULL;
141 }
142
143 if(mTarget != NULL) {
144 delete mTarget;
145 mTarget = NULL;
146 }
147
148 mOverlayState = OVERLAY_CLEAR;
149
Steve Block2703f232011-10-20 11:56:09 +0100150 ALOGV("~VideoEditorPreviewController returns");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800151}
152
153M4OSA_ERR VideoEditorPreviewController::loadEditSettings(
154 M4VSS3GPP_EditSettings* pSettings,M4xVSS_AudioMixingSettings* bgmSettings) {
155
156 M4OSA_UInt32 i = 0, iClipDuration = 0, rgbSize = 0;
157 M4VIFI_UInt8 *tmp = NULL;
158 M4OSA_ERR err = M4NO_ERROR;
159
Steve Block2703f232011-10-20 11:56:09 +0100160 ALOGV("loadEditSettings");
161 ALOGV("loadEditSettings Channels = %d, sampling Freq %d",
Chih-Chung Chang99698662011-06-30 14:21:38 +0800162 bgmSettings->uiNbChannels, bgmSettings->uiSamplingFrequency );
163 bgmSettings->uiSamplingFrequency = 32000;
164
Steve Block2703f232011-10-20 11:56:09 +0100165 ALOGV("loadEditSettings Channels = %d, sampling Freq %d",
Chih-Chung Chang99698662011-06-30 14:21:38 +0800166 bgmSettings->uiNbChannels, bgmSettings->uiSamplingFrequency );
167 Mutex::Autolock autoLock(mLock);
168
169 // Clean up any previous Edit settings before loading new ones
170 mCurrentVideoEffect = VIDEO_EFFECT_NONE;
171
172 if(mAudioMixPCMFileHandle) {
173 err = M4OSA_fileReadClose (mAudioMixPCMFileHandle);
174 mAudioMixPCMFileHandle = M4OSA_NULL;
175 }
176
177 if(mBackgroundAudioSetting != NULL) {
178 free(mBackgroundAudioSetting);
179 mBackgroundAudioSetting = NULL;
180 }
181
182 if(mClipList != NULL) {
183 // Clean up
184 for(i=0;i<mNumberClipsInStoryBoard;i++)
185 {
186 if(mClipList[i]->pFile != NULL) {
187 free(mClipList[i]->pFile);
188 mClipList[i]->pFile = NULL;
189 }
190
191 free(mClipList[i]);
192 }
193 free(mClipList);
194 mClipList = NULL;
195 }
196
197 if(mEffectsSettings) {
198 for(i=0;i<mNumberEffects;i++) {
199 if(mEffectsSettings[i].xVSS.pFramingBuffer != NULL) {
200 free(mEffectsSettings[i].xVSS.pFramingBuffer->pac_data);
201
202 free(mEffectsSettings[i].xVSS.pFramingBuffer);
203
204 mEffectsSettings[i].xVSS.pFramingBuffer = NULL;
205 }
206 }
207 free(mEffectsSettings);
208 mEffectsSettings = NULL;
209 }
210
211 if(mClipList == NULL) {
212 mNumberClipsInStoryBoard = pSettings->uiClipNumber;
Steve Block2703f232011-10-20 11:56:09 +0100213 ALOGV("loadEditSettings: # of Clips = %d", mNumberClipsInStoryBoard);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800214
215 mClipList = (M4VSS3GPP_ClipSettings**)M4OSA_32bitAlignedMalloc(
216 sizeof(M4VSS3GPP_ClipSettings*)*pSettings->uiClipNumber, M4VS,
217 (M4OSA_Char*)"LvPP, copy of pClipList");
218
219 if(NULL == mClipList) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000220 ALOGE("loadEditSettings: Malloc error");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800221 return M4ERR_ALLOC;
222 }
223 memset((void *)mClipList,0,
224 sizeof(M4VSS3GPP_ClipSettings*)*pSettings->uiClipNumber);
225
226 for(i=0;i<pSettings->uiClipNumber;i++) {
227
228 // Allocate current clip
229 mClipList[i] =
230 (M4VSS3GPP_ClipSettings*)M4OSA_32bitAlignedMalloc(
231 sizeof(M4VSS3GPP_ClipSettings),M4VS,(M4OSA_Char*)"clip settings");
232
233 if(mClipList[i] == NULL) {
234
Steve Blockf8bd29c2012-01-08 10:14:44 +0000235 ALOGE("loadEditSettings: Allocation error for mClipList[%d]", (int)i);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800236 return M4ERR_ALLOC;
237 }
238 // Copy plain structure
239 memcpy((void *)mClipList[i],
240 (void *)pSettings->pClipList[i],
241 sizeof(M4VSS3GPP_ClipSettings));
242
243 if(NULL != pSettings->pClipList[i]->pFile) {
244 mClipList[i]->pFile = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(
245 pSettings->pClipList[i]->filePathSize, M4VS,
246 (M4OSA_Char*)"pClipSettingsDest->pFile");
247
248 if(NULL == mClipList[i]->pFile)
249 {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000250 ALOGE("loadEditSettings : ERROR allocating filename");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800251 return M4ERR_ALLOC;
252 }
253
254 memcpy((void *)mClipList[i]->pFile,
255 (void *)pSettings->pClipList[i]->pFile,
256 pSettings->pClipList[i]->filePathSize);
257 }
258 else {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000259 ALOGE("NULL file path");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800260 return M4ERR_PARAMETER;
261 }
262
263 // Calculate total duration of all clips
264 iClipDuration = pSettings->pClipList[i]->uiEndCutTime -
265 pSettings->pClipList[i]->uiBeginCutTime;
266
267 mClipTotalDuration = mClipTotalDuration+iClipDuration;
268 }
269 }
270
271 if(mEffectsSettings == NULL) {
272 mNumberEffects = pSettings->nbEffects;
Steve Block2703f232011-10-20 11:56:09 +0100273 ALOGV("loadEditSettings: mNumberEffects = %d", mNumberEffects);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800274
275 if(mNumberEffects != 0) {
276 mEffectsSettings = (M4VSS3GPP_EffectSettings*)M4OSA_32bitAlignedMalloc(
277 mNumberEffects*sizeof(M4VSS3GPP_EffectSettings),
278 M4VS, (M4OSA_Char*)"effects settings");
279
280 if(mEffectsSettings == NULL) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000281 ALOGE("loadEffectsSettings: Allocation error");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800282 return M4ERR_ALLOC;
283 }
284
285 memset((void *)mEffectsSettings,0,
286 mNumberEffects*sizeof(M4VSS3GPP_EffectSettings));
287
288 for(i=0;i<mNumberEffects;i++) {
289
290 mEffectsSettings[i].xVSS.pFramingFilePath = NULL;
291 mEffectsSettings[i].xVSS.pFramingBuffer = NULL;
292 mEffectsSettings[i].xVSS.pTextBuffer = NULL;
293
294 memcpy((void *)&(mEffectsSettings[i]),
295 (void *)&(pSettings->Effects[i]),
296 sizeof(M4VSS3GPP_EffectSettings));
297
298 if(pSettings->Effects[i].VideoEffectType ==
299 (M4VSS3GPP_VideoEffectType)M4xVSS_kVideoEffectType_Framing) {
300 // Allocate the pFraming RGB buffer
301 mEffectsSettings[i].xVSS.pFramingBuffer =
302 (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(sizeof(M4VIFI_ImagePlane),
303 M4VS, (M4OSA_Char*)"lvpp framing buffer");
304
305 if(mEffectsSettings[i].xVSS.pFramingBuffer == NULL) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000306 ALOGE("loadEffectsSettings:Alloc error for pFramingBuf");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800307 free(mEffectsSettings);
308 mEffectsSettings = NULL;
309 return M4ERR_ALLOC;
310 }
311
312 // Allocate the pac_data (RGB)
313 if(pSettings->Effects[i].xVSS.rgbType == M4VSS3GPP_kRGB565){
314 rgbSize =
315 pSettings->Effects[i].xVSS.pFramingBuffer->u_width *
316 pSettings->Effects[i].xVSS.pFramingBuffer->u_height*2;
317 }
318 else if(
319 pSettings->Effects[i].xVSS.rgbType == M4VSS3GPP_kRGB888) {
320 rgbSize =
321 pSettings->Effects[i].xVSS.pFramingBuffer->u_width *
322 pSettings->Effects[i].xVSS.pFramingBuffer->u_height*3;
323 }
324 else {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000325 ALOGE("loadEffectsSettings: wrong RGB type");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800326 free(mEffectsSettings);
327 mEffectsSettings = NULL;
328 return M4ERR_PARAMETER;
329 }
330
331 tmp = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(rgbSize, M4VS,
332 (M4OSA_Char*)"framing buffer pac_data");
333
334 if(tmp == NULL) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000335 ALOGE("loadEffectsSettings:Alloc error pFramingBuf pac");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800336 free(mEffectsSettings);
337 mEffectsSettings = NULL;
338 free(mEffectsSettings[i].xVSS.pFramingBuffer);
339
340 mEffectsSettings[i].xVSS.pFramingBuffer = NULL;
341 return M4ERR_ALLOC;
342 }
343 /* Initialize the pFramingBuffer*/
344 mEffectsSettings[i].xVSS.pFramingBuffer->pac_data = tmp;
345 mEffectsSettings[i].xVSS.pFramingBuffer->u_height =
346 pSettings->Effects[i].xVSS.pFramingBuffer->u_height;
347
348 mEffectsSettings[i].xVSS.pFramingBuffer->u_width =
349 pSettings->Effects[i].xVSS.pFramingBuffer->u_width;
350
351 mEffectsSettings[i].xVSS.pFramingBuffer->u_stride =
352 pSettings->Effects[i].xVSS.pFramingBuffer->u_stride;
353
354 mEffectsSettings[i].xVSS.pFramingBuffer->u_topleft =
355 pSettings->Effects[i].xVSS.pFramingBuffer->u_topleft;
356
357 mEffectsSettings[i].xVSS.uialphaBlendingStart =
358 pSettings->Effects[i].xVSS.uialphaBlendingStart;
359
360 mEffectsSettings[i].xVSS.uialphaBlendingMiddle =
361 pSettings->Effects[i].xVSS.uialphaBlendingMiddle;
362
363 mEffectsSettings[i].xVSS.uialphaBlendingEnd =
364 pSettings->Effects[i].xVSS.uialphaBlendingEnd;
365
366 mEffectsSettings[i].xVSS.uialphaBlendingFadeInTime =
367 pSettings->Effects[i].xVSS.uialphaBlendingFadeInTime;
368 mEffectsSettings[i].xVSS.uialphaBlendingFadeOutTime =
369 pSettings->Effects[i].xVSS.uialphaBlendingFadeOutTime;
370
371 // Copy the pFraming data
372 memcpy((void *)
373 mEffectsSettings[i].xVSS.pFramingBuffer->pac_data,
374 (void *)pSettings->Effects[i].xVSS.pFramingBuffer->pac_data,
375 rgbSize);
376
377 mEffectsSettings[i].xVSS.rgbType =
378 pSettings->Effects[i].xVSS.rgbType;
379 }
380 }
381 }
382 }
383
384 if (mBackgroundAudioSetting == NULL) {
385
386 mBackgroundAudioSetting = (M4xVSS_AudioMixingSettings*)M4OSA_32bitAlignedMalloc(
387 sizeof(M4xVSS_AudioMixingSettings), M4VS,
388 (M4OSA_Char*)"LvPP, copy of bgmSettings");
389
390 if(NULL == mBackgroundAudioSetting) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000391 ALOGE("loadEditSettings: mBackgroundAudioSetting Malloc failed");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800392 return M4ERR_ALLOC;
393 }
394
395 memset((void *)mBackgroundAudioSetting, 0,sizeof(M4xVSS_AudioMixingSettings*));
396 memcpy((void *)mBackgroundAudioSetting, (void *)bgmSettings, sizeof(M4xVSS_AudioMixingSettings));
397
398 if ( mBackgroundAudioSetting->pFile != M4OSA_NULL ) {
399
400 mBackgroundAudioSetting->pFile = (M4OSA_Void*) bgmSettings->pPCMFilePath;
401 mBackgroundAudioSetting->uiNbChannels = 2;
402 mBackgroundAudioSetting->uiSamplingFrequency = 32000;
403 }
404
405 // Open the BG file
406 if ( mBackgroundAudioSetting->pFile != M4OSA_NULL ) {
407 err = M4OSA_fileReadOpen(&mAudioMixPCMFileHandle,
408 mBackgroundAudioSetting->pFile, M4OSA_kFileRead);
409
410 if (err != M4NO_ERROR) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000411 ALOGE("loadEditSettings: mBackgroundAudio PCM File open failed");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800412 return M4ERR_PARAMETER;
413 }
414 }
415 }
416
417 mOutputVideoSize = pSettings->xVSS.outputVideoSize;
418 mFrameStr.pBuffer = M4OSA_NULL;
419 return M4NO_ERROR;
420}
421
422M4OSA_ERR VideoEditorPreviewController::setSurface(const sp<Surface> &surface) {
Steve Block2703f232011-10-20 11:56:09 +0100423 ALOGV("setSurface");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800424 Mutex::Autolock autoLock(mLock);
425
426 mSurface = surface;
427 return M4NO_ERROR;
428}
429
430M4OSA_ERR VideoEditorPreviewController::startPreview(
431 M4OSA_UInt32 fromMS, M4OSA_Int32 toMs, M4OSA_UInt16 callBackAfterFrameCount,
432 M4OSA_Bool loop) {
433
434 M4OSA_ERR err = M4NO_ERROR;
435 M4OSA_UInt32 i = 0, iIncrementedDuration = 0;
Steve Block2703f232011-10-20 11:56:09 +0100436 ALOGV("startPreview");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800437
438 if(fromMS > (M4OSA_UInt32)toMs) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000439 ALOGE("startPreview: fromMS > toMs");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800440 return M4ERR_PARAMETER;
441 }
442
443 if(toMs == 0) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000444 ALOGE("startPreview: toMs is 0");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800445 return M4ERR_PARAMETER;
446 }
447
448 // If already started, then stop preview first
James Dong3d2d40a2012-01-27 19:01:13 -0800449 for(int playerInst=0; playerInst<kTotalNumPlayerInstances; playerInst++) {
Chih-Chung Chang99698662011-06-30 14:21:38 +0800450 if(mVePlayer[playerInst] != NULL) {
Steve Block2703f232011-10-20 11:56:09 +0100451 ALOGV("startPreview: stopping previously started preview playback");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800452 stopPreview();
453 break;
454 }
455 }
456
457 // If renderPreview was called previously, then delete Renderer object first
458 if(mTarget != NULL) {
Steve Block2703f232011-10-20 11:56:09 +0100459 ALOGV("startPreview: delete previous PreviewRenderer");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800460 delete mTarget;
461 mTarget = NULL;
462 }
463
464 // Create Audio player to be used for entire
465 // storyboard duration
466 mVEAudioSink = new VideoEditorPlayer::VeAudioOutput();
467 mVEAudioPlayer = new VideoEditorAudioPlayer(mVEAudioSink);
468 mVEAudioPlayer->setAudioMixSettings(mBackgroundAudioSetting);
469 mVEAudioPlayer->setAudioMixPCMFileHandle(mAudioMixPCMFileHandle);
470
Chih-Chung Chang43fcc392011-08-02 16:17:39 +0800471 // Create Video Renderer to be used for the entire storyboard duration.
472 uint32_t width, height;
473 getVideoSizeByResolution(mOutputVideoSize, &width, &height);
474 mNativeWindowRenderer = new NativeWindowRenderer(mSurface, width, height);
475
Steve Block2703f232011-10-20 11:56:09 +0100476 ALOGV("startPreview: loop = %d", loop);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800477 mPreviewLooping = loop;
478
Steve Block2703f232011-10-20 11:56:09 +0100479 ALOGV("startPreview: callBackAfterFrameCount = %d", callBackAfterFrameCount);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800480 mCallBackAfterFrameCnt = callBackAfterFrameCount;
481
James Dong3d2d40a2012-01-27 19:01:13 -0800482 for (int playerInst=0; playerInst<kTotalNumPlayerInstances; playerInst++) {
Chih-Chung Chang43fcc392011-08-02 16:17:39 +0800483 mVePlayer[playerInst] = new VideoEditorPlayer(mNativeWindowRenderer);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800484 if(mVePlayer[playerInst] == NULL) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000485 ALOGE("startPreview:Error creating VideoEditorPlayer %d",playerInst);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800486 return M4ERR_ALLOC;
487 }
Steve Block2703f232011-10-20 11:56:09 +0100488 ALOGV("startPreview: object created");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800489
490 mVePlayer[playerInst]->setNotifyCallback(this,(notify_callback_f)notify);
Steve Block2703f232011-10-20 11:56:09 +0100491 ALOGV("startPreview: notify callback set");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800492
493 mVePlayer[playerInst]->loadEffectsSettings(mEffectsSettings,
494 mNumberEffects);
Steve Block2703f232011-10-20 11:56:09 +0100495 ALOGV("startPreview: effects settings loaded");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800496
497 mVePlayer[playerInst]->loadAudioMixSettings(mBackgroundAudioSetting);
Steve Block2703f232011-10-20 11:56:09 +0100498 ALOGV("startPreview: AudioMixSettings settings loaded");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800499
500 mVePlayer[playerInst]->setAudioMixPCMFileHandle(mAudioMixPCMFileHandle);
Steve Block2703f232011-10-20 11:56:09 +0100501 ALOGV("startPreview: AudioMixPCMFileHandle set");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800502
503 mVePlayer[playerInst]->setProgressCallbackInterval(
504 mCallBackAfterFrameCnt);
Steve Block2703f232011-10-20 11:56:09 +0100505 ALOGV("startPreview: setProgressCallBackInterval");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800506 }
507
508 mPlayerState = VePlayerIdle;
509 mPrepareReqest = M4OSA_FALSE;
510
511 if(fromMS == 0) {
512 mCurrentClipNumber = -1;
513 // Save original value
514 mFirstPreviewClipBeginTime = mClipList[0]->uiBeginCutTime;
515 mVideoStoryBoardTimeMsUptoFirstPreviewClip = 0;
516 }
517 else {
Steve Block2703f232011-10-20 11:56:09 +0100518 ALOGV("startPreview: fromMS=%d", fromMS);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800519 if(fromMS >= mClipTotalDuration) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000520 ALOGE("startPreview: fromMS >= mClipTotalDuration");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800521 return M4ERR_PARAMETER;
522 }
523 for(i=0;i<mNumberClipsInStoryBoard;i++) {
524 if(fromMS < (iIncrementedDuration + (mClipList[i]->uiEndCutTime -
525 mClipList[i]->uiBeginCutTime))) {
526 // Set to 1 index below,
527 // as threadProcess first increments the clip index
528 // and then processes clip in thread loop
529 mCurrentClipNumber = i-1;
Steve Block4ca06b02011-12-20 16:24:14 +0000530 ALOGD("startPreview:mCurrentClipNumber = %d fromMS=%d",i,fromMS);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800531
532 // Save original value
533 mFirstPreviewClipBeginTime = mClipList[i]->uiBeginCutTime;
534
535 // Set correct begin time to start playback
536 if((fromMS+mClipList[i]->uiBeginCutTime) >
537 (iIncrementedDuration+mClipList[i]->uiBeginCutTime)) {
538
539 mClipList[i]->uiBeginCutTime =
540 mClipList[i]->uiBeginCutTime +
541 (fromMS - iIncrementedDuration);
542 }
543 break;
544 }
545 else {
546 iIncrementedDuration = iIncrementedDuration +
547 (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime);
548 }
549 }
550 mVideoStoryBoardTimeMsUptoFirstPreviewClip = iIncrementedDuration;
551 }
552
James Dong3d2d40a2012-01-27 19:01:13 -0800553 for (int playerInst=0; playerInst<kTotalNumPlayerInstances; playerInst++) {
Chih-Chung Chang99698662011-06-30 14:21:38 +0800554 mVePlayer[playerInst]->setAudioMixStoryBoardParam(fromMS,
555 mFirstPreviewClipBeginTime,
556 mClipList[i]->ClipProperties.uiClipAudioVolumePercentage);
557
Steve Block2703f232011-10-20 11:56:09 +0100558 ALOGV("startPreview:setAudioMixStoryBoardSkimTimeStamp set %d cuttime \
Chih-Chung Chang99698662011-06-30 14:21:38 +0800559 %d", fromMS, mFirstPreviewClipBeginTime);
560 }
561
562 mStartingClipIndex = mCurrentClipNumber+1;
563
564 // Start playing with player instance 0
565 mCurrentPlayer = 0;
566 mActivePlayerIndex = 0;
567
568 if(toMs == -1) {
Steve Block2703f232011-10-20 11:56:09 +0100569 ALOGV("startPreview: Preview till end of storyboard");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800570 mNumberClipsToPreview = mNumberClipsInStoryBoard;
571 // Save original value
572 mLastPreviewClipEndTime =
573 mClipList[mNumberClipsToPreview-1]->uiEndCutTime;
574 }
575 else {
Steve Block2703f232011-10-20 11:56:09 +0100576 ALOGV("startPreview: toMs=%d", toMs);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800577 if((M4OSA_UInt32)toMs > mClipTotalDuration) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000578 ALOGE("startPreview: toMs > mClipTotalDuration");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800579 return M4ERR_PARAMETER;
580 }
581
582 iIncrementedDuration = 0;
583
584 for(i=0;i<mNumberClipsInStoryBoard;i++) {
585 if((M4OSA_UInt32)toMs <= (iIncrementedDuration +
586 (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime))) {
587 // Save original value
588 mLastPreviewClipEndTime = mClipList[i]->uiEndCutTime;
589 // Set the end cut time of clip index i to toMs
590 mClipList[i]->uiEndCutTime = toMs;
591
592 // Number of clips to be previewed is from index 0 to i
593 // increment by 1 as i starts from 0
594 mNumberClipsToPreview = i+1;
595 break;
596 }
597 else {
598 iIncrementedDuration = iIncrementedDuration +
599 (mClipList[i]->uiEndCutTime - mClipList[i]->uiBeginCutTime);
600 }
601 }
602 }
603
604 // Open the thread semaphore
605 M4OSA_semaphoreOpen(&mSemThreadWait, 1);
606
607 // Open the preview process thread
608 err = M4OSA_threadSyncOpen(&mThreadContext, (M4OSA_ThreadDoIt)threadProc);
609 if (M4NO_ERROR != err) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000610 ALOGE("VideoEditorPreviewController:M4OSA_threadSyncOpen error %d", (int) err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800611 return err;
612 }
613
614 // Set the stacksize
615 err = M4OSA_threadSyncSetOption(mThreadContext, M4OSA_ThreadStackSize,
James Dong3d2d40a2012-01-27 19:01:13 -0800616 (M4OSA_DataOption) kPreviewThreadStackSize);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800617
618 if (M4NO_ERROR != err) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000619 ALOGE("VideoEditorPreviewController: threadSyncSetOption error %d", (int) err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800620 M4OSA_threadSyncClose(mThreadContext);
621 mThreadContext = NULL;
622 return err;
623 }
624
625 // Start the thread
626 err = M4OSA_threadSyncStart(mThreadContext, (M4OSA_Void*)this);
627 if (M4NO_ERROR != err) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000628 ALOGE("VideoEditorPreviewController: threadSyncStart error %d", (int) err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800629 M4OSA_threadSyncClose(mThreadContext);
630 mThreadContext = NULL;
631 return err;
632 }
633 bStopThreadInProgress = false;
634
Steve Block2703f232011-10-20 11:56:09 +0100635 ALOGV("startPreview: process thread started");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800636 return M4NO_ERROR;
637}
638
639M4OSA_UInt32 VideoEditorPreviewController::stopPreview() {
640 M4OSA_ERR err = M4NO_ERROR;
641 uint32_t lastRenderedFrameTimeMs = 0;
Steve Block2703f232011-10-20 11:56:09 +0100642 ALOGV("stopPreview");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800643
644 // Stop the thread
645 if(mThreadContext != NULL) {
646 bStopThreadInProgress = true;
647 {
648 Mutex::Autolock autoLock(mLockSem);
649 if (mSemThreadWait != NULL) {
650 err = M4OSA_semaphorePost(mSemThreadWait);
651 }
652 }
653
654 err = M4OSA_threadSyncStop(mThreadContext);
655 if(err != M4NO_ERROR) {
Steve Block2703f232011-10-20 11:56:09 +0100656 ALOGV("stopPreview: error 0x%x in trying to stop thread", err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800657 // Continue even if error
658 }
659
660 err = M4OSA_threadSyncClose(mThreadContext);
661 if(err != M4NO_ERROR) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000662 ALOGE("stopPreview: error 0x%x in trying to close thread", (unsigned int)err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800663 // Continue even if error
664 }
665
666 mThreadContext = NULL;
667 }
668
669 // Close the semaphore first
670 {
671 Mutex::Autolock autoLock(mLockSem);
672 if(mSemThreadWait != NULL) {
673 err = M4OSA_semaphoreClose(mSemThreadWait);
Steve Block2703f232011-10-20 11:56:09 +0100674 ALOGV("stopPreview: close semaphore returns 0x%x", err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800675 mSemThreadWait = NULL;
676 }
677 }
678
James Dong3d2d40a2012-01-27 19:01:13 -0800679 for (int playerInst=0; playerInst<kTotalNumPlayerInstances; playerInst++) {
Chih-Chung Chang99698662011-06-30 14:21:38 +0800680 if(mVePlayer[playerInst] != NULL) {
681 if(mVePlayer[playerInst]->isPlaying()) {
Steve Block2703f232011-10-20 11:56:09 +0100682 ALOGV("stop the player first");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800683 mVePlayer[playerInst]->stop();
684 }
685 if (playerInst == mActivePlayerIndex) {
686 // Return the last rendered frame time stamp
687 mVePlayer[mActivePlayerIndex]->getLastRenderedTimeMs(&lastRenderedFrameTimeMs);
688 }
Raghavender Pallafa31daf2011-03-18 22:32:51 -0700689
690 //This is used to syncronize onStreamDone() in PreviewPlayer and
Chih-Chung Chang99698662011-06-30 14:21:38 +0800691 //stopPreview() in PreviewController
Raghavender Pallafa31daf2011-03-18 22:32:51 -0700692 sp<VideoEditorPlayer> temp = mVePlayer[playerInst];
693 temp->acquireLock();
Steve Block2703f232011-10-20 11:56:09 +0100694 ALOGV("stopPreview: clearing mVePlayer");
Raghavender Pallafa31daf2011-03-18 22:32:51 -0700695 mVePlayer[playerInst].clear();
Chih-Chung Chang99698662011-06-30 14:21:38 +0800696 mVePlayer[playerInst] = NULL;
Raghavender Pallafa31daf2011-03-18 22:32:51 -0700697 temp->releaseLock();
Chih-Chung Chang99698662011-06-30 14:21:38 +0800698 }
Raghavender Pallafa31daf2011-03-18 22:32:51 -0700699 }
Steve Block2703f232011-10-20 11:56:09 +0100700 ALOGV("stopPreview: clear audioSink and audioPlayer");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800701 mVEAudioSink.clear();
702 if (mVEAudioPlayer) {
703 delete mVEAudioPlayer;
704 mVEAudioPlayer = NULL;
705 }
706
Chih-Chung Chang43fcc392011-08-02 16:17:39 +0800707 delete mNativeWindowRenderer;
708 mNativeWindowRenderer = NULL;
709
Chih-Chung Chang99698662011-06-30 14:21:38 +0800710 // If image file playing, then free the buffer pointer
711 if(mFrameStr.pBuffer != M4OSA_NULL) {
712 free(mFrameStr.pBuffer);
713 mFrameStr.pBuffer = M4OSA_NULL;
714 }
715
716 // Reset original begin cuttime of first previewed clip*/
717 mClipList[mStartingClipIndex]->uiBeginCutTime = mFirstPreviewClipBeginTime;
718 // Reset original end cuttime of last previewed clip*/
719 mClipList[mNumberClipsToPreview-1]->uiEndCutTime = mLastPreviewClipEndTime;
720
721 mPlayerState = VePlayerIdle;
722 mPrepareReqest = M4OSA_FALSE;
723
724 mCurrentPlayedDuration = 0;
725 mCurrentClipDuration = 0;
726 mRenderingMode = M4xVSS_kBlackBorders;
727 mOutputVideoWidth = 0;
728 mOutputVideoHeight = 0;
729
Steve Block2703f232011-10-20 11:56:09 +0100730 ALOGV("stopPreview() lastRenderedFrameTimeMs %ld", lastRenderedFrameTimeMs);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800731 return lastRenderedFrameTimeMs;
732}
733
734M4OSA_ERR VideoEditorPreviewController::clearSurface(
735 const sp<Surface> &surface, VideoEditor_renderPreviewFrameStr* pFrameInfo) {
736
737 M4OSA_ERR err = M4NO_ERROR;
738 VideoEditor_renderPreviewFrameStr* pFrameStr = pFrameInfo;
739 M4OSA_UInt32 outputBufferWidth =0, outputBufferHeight=0;
740 M4VIFI_ImagePlane planeOut[3];
Steve Block2703f232011-10-20 11:56:09 +0100741 ALOGV("Inside preview clear frame");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800742
743 Mutex::Autolock autoLock(mLock);
744
745 // Delete previous renderer instance
746 if(mTarget != NULL) {
747 delete mTarget;
748 mTarget = NULL;
749 }
750
751 outputBufferWidth = pFrameStr->uiFrameWidth;
752 outputBufferHeight = pFrameStr->uiFrameHeight;
753
754 // Initialize the renderer
755 if(mTarget == NULL) {
756
757 mTarget = PreviewRenderer::CreatePreviewRenderer(
Chih-Chung Chang08b82bd2011-08-11 18:36:45 +0800758 surface,
759 outputBufferWidth, outputBufferHeight);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800760
761 if(mTarget == NULL) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000762 ALOGE("renderPreviewFrame: cannot create PreviewRenderer");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800763 return M4ERR_ALLOC;
764 }
765 }
766
767 // Out plane
768 uint8_t* outBuffer;
769 size_t outBufferStride = 0;
770
Steve Block2703f232011-10-20 11:56:09 +0100771 ALOGV("doMediaRendering CALL getBuffer()");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800772 mTarget->getBufferYV12(&outBuffer, &outBufferStride);
773
774 // Set the output YUV420 plane to be compatible with YV12 format
775 //In YV12 format, sizes must be even
776 M4OSA_UInt32 yv12PlaneWidth = ((outputBufferWidth +1)>>1)<<1;
777 M4OSA_UInt32 yv12PlaneHeight = ((outputBufferHeight+1)>>1)<<1;
778
779 prepareYV12ImagePlane(planeOut, yv12PlaneWidth, yv12PlaneHeight,
780 (M4OSA_UInt32)outBufferStride, (M4VIFI_UInt8 *)outBuffer);
781
782 /* Fill the surface with black frame */
783 memset((void *)planeOut[0].pac_data,0x00,planeOut[0].u_width *
784 planeOut[0].u_height * 1.5);
785 memset((void *)planeOut[1].pac_data,128,planeOut[1].u_width *
786 planeOut[1].u_height);
787 memset((void *)planeOut[2].pac_data,128,planeOut[2].u_width *
788 planeOut[2].u_height);
789
790 mTarget->renderYV12();
791 return err;
792}
793
794M4OSA_ERR VideoEditorPreviewController::renderPreviewFrame(
795 const sp<Surface> &surface,
796 VideoEditor_renderPreviewFrameStr* pFrameInfo,
797 VideoEditorCurretEditInfo *pCurrEditInfo) {
798
799 M4OSA_ERR err = M4NO_ERROR;
800 M4OSA_UInt32 i = 0, iIncrementedDuration = 0, tnTimeMs=0, framesize =0;
801 VideoEditor_renderPreviewFrameStr* pFrameStr = pFrameInfo;
802 M4VIFI_UInt8 *pixelArray = NULL;
803 Mutex::Autolock autoLock(mLock);
804
805 if (pCurrEditInfo != NULL) {
806 pCurrEditInfo->overlaySettingsIndex = -1;
807 }
808 // Delete previous renderer instance
809 if(mTarget != NULL) {
810 delete mTarget;
811 mTarget = NULL;
812 }
813
814 if(mOutputVideoWidth == 0) {
815 mOutputVideoWidth = pFrameStr->uiFrameWidth;
816 }
817
818 if(mOutputVideoHeight == 0) {
819 mOutputVideoHeight = pFrameStr->uiFrameHeight;
820 }
821
822 // Initialize the renderer
823 if(mTarget == NULL) {
Chih-Chung Chang99698662011-06-30 14:21:38 +0800824 mTarget = PreviewRenderer::CreatePreviewRenderer(
Chih-Chung Chang08b82bd2011-08-11 18:36:45 +0800825 surface,
826 mOutputVideoWidth, mOutputVideoHeight);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800827
828 if(mTarget == NULL) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000829 ALOGE("renderPreviewFrame: cannot create PreviewRenderer");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800830 return M4ERR_ALLOC;
831 }
832 }
833
834 pixelArray = NULL;
835
Rajneesh Chowdurye9eec0e2011-08-30 12:59:30 -0700836 // Apply rotation if required
837 if (pFrameStr->videoRotationDegree != 0) {
838 err = applyVideoRotation((M4OSA_Void *)pFrameStr->pBuffer,
839 pFrameStr->uiFrameWidth, pFrameStr->uiFrameHeight,
840 pFrameStr->videoRotationDegree);
841 if (M4NO_ERROR != err) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000842 ALOGE("renderPreviewFrame: cannot rotate video, err 0x%x", (unsigned int)err);
Rajneesh Chowdurye9eec0e2011-08-30 12:59:30 -0700843 delete mTarget;
844 mTarget = NULL;
845 return err;
846 } else {
847 // Video rotation done.
848 // Swap width and height if 90 or 270 degrees
849 if (pFrameStr->videoRotationDegree != 180) {
850 int32_t temp = pFrameStr->uiFrameWidth;
851 pFrameStr->uiFrameWidth = pFrameStr->uiFrameHeight;
852 pFrameStr->uiFrameHeight = temp;
853 }
854 }
855 }
Chih-Chung Chang99698662011-06-30 14:21:38 +0800856 // Postprocessing (apply video effect)
857 if(pFrameStr->bApplyEffect == M4OSA_TRUE) {
858
859 for(i=0;i<mNumberEffects;i++) {
860 // First check if effect starttime matches the clip being previewed
861 if((mEffectsSettings[i].uiStartTime < pFrameStr->clipBeginCutTime)
862 ||(mEffectsSettings[i].uiStartTime >= pFrameStr->clipEndCutTime)) {
863 // This effect doesn't belong to this clip, check next one
864 continue;
865 }
866 if((mEffectsSettings[i].uiStartTime <= pFrameStr->timeMs) &&
867 ((mEffectsSettings[i].uiStartTime+mEffectsSettings[i].uiDuration) >=
868 pFrameStr->timeMs) && (mEffectsSettings[i].uiDuration != 0)) {
869 setVideoEffectType(mEffectsSettings[i].VideoEffectType, TRUE);
870 }
871 else {
872 setVideoEffectType(mEffectsSettings[i].VideoEffectType, FALSE);
873 }
874 }
875
876 //Provide the overlay Update indication when there is an overlay effect
877 if (mCurrentVideoEffect & VIDEO_EFFECT_FRAMING) {
878 M4OSA_UInt32 index;
879 mCurrentVideoEffect &= ~VIDEO_EFFECT_FRAMING; //never apply framing here.
880
881 // Find the effect in effectSettings array
882 for (index = 0; index < mNumberEffects; index++) {
883 if(mEffectsSettings[index].VideoEffectType ==
884 (M4VSS3GPP_VideoEffectType)M4xVSS_kVideoEffectType_Framing) {
885
886 if((mEffectsSettings[index].uiStartTime <= pFrameInfo->timeMs) &&
887 ((mEffectsSettings[index].uiStartTime+
888 mEffectsSettings[index].uiDuration) >= pFrameInfo->timeMs))
889 {
890 break;
891 }
892 }
893 }
894 if ((index < mNumberEffects) && (pCurrEditInfo != NULL)) {
895 pCurrEditInfo->overlaySettingsIndex = index;
Steve Block2703f232011-10-20 11:56:09 +0100896 ALOGV("Framing index = %d", index);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800897 } else {
Steve Block2703f232011-10-20 11:56:09 +0100898 ALOGV("No framing effects found");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800899 }
900 }
901
902 if(mCurrentVideoEffect != VIDEO_EFFECT_NONE) {
903 err = applyVideoEffect((M4OSA_Void *)pFrameStr->pBuffer,
904 OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth,
905 pFrameStr->uiFrameHeight, pFrameStr->timeMs,
906 (M4OSA_Void *)pixelArray);
907
908 if(err != M4NO_ERROR) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000909 ALOGE("renderPreviewFrame: applyVideoEffect error 0x%x", (unsigned int)err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800910 delete mTarget;
911 mTarget = NULL;
912 free(pixelArray);
913 pixelArray = NULL;
914 return err;
915 }
916 mCurrentVideoEffect = VIDEO_EFFECT_NONE;
917 }
918 else {
919 // Apply the rendering mode
920 err = doImageRenderingMode((M4OSA_Void *)pFrameStr->pBuffer,
921 OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth,
922 pFrameStr->uiFrameHeight, (M4OSA_Void *)pixelArray);
923
924 if(err != M4NO_ERROR) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000925 ALOGE("renderPreviewFrame:doImageRenderingMode error 0x%x", (unsigned int)err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800926 delete mTarget;
927 mTarget = NULL;
928 free(pixelArray);
929 pixelArray = NULL;
930 return err;
931 }
932 }
933 }
934 else {
935 // Apply the rendering mode
936 err = doImageRenderingMode((M4OSA_Void *)pFrameStr->pBuffer,
937 OMX_COLOR_FormatYUV420Planar, pFrameStr->uiFrameWidth,
938 pFrameStr->uiFrameHeight, (M4OSA_Void *)pixelArray);
939
940 if(err != M4NO_ERROR) {
Steve Blockf8bd29c2012-01-08 10:14:44 +0000941 ALOGE("renderPreviewFrame: doImageRenderingMode error 0x%x", (unsigned int)err);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800942 delete mTarget;
943 mTarget = NULL;
944 free(pixelArray);
945 pixelArray = NULL;
946 return err;
947 }
948 }
949
950 mTarget->renderYV12();
951 return err;
952}
953
954M4OSA_Void VideoEditorPreviewController::setJniCallback(void* cookie,
955 jni_progress_callback_fct callbackFct) {
Steve Block2703f232011-10-20 11:56:09 +0100956 //ALOGV("setJniCallback");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800957 mJniCookie = cookie;
958 mJniCallback = callbackFct;
959}
960
961M4OSA_ERR VideoEditorPreviewController::preparePlayer(
962 void* param, int playerInstance, int index) {
963
964 M4OSA_ERR err = M4NO_ERROR;
965 VideoEditorPreviewController *pController =
966 (VideoEditorPreviewController *)param;
967
Steve Block2703f232011-10-20 11:56:09 +0100968 ALOGV("preparePlayer: instance %d file %d", playerInstance, index);
Chih-Chung Chang99698662011-06-30 14:21:38 +0800969
James Dongdaeb5b32012-01-12 12:12:40 -0800970 const char* fileName = (const char*) pController->mClipList[index]->pFile;
Andreas Huber1b86fe02014-01-29 11:13:26 -0800971 pController->mVePlayer[playerInstance]->setDataSource(
972 NULL /* httpService */, fileName, NULL);
James Dongdaeb5b32012-01-12 12:12:40 -0800973
Steve Block2703f232011-10-20 11:56:09 +0100974 ALOGV("preparePlayer: setDataSource instance %s",
Chih-Chung Chang99698662011-06-30 14:21:38 +0800975 (const char *)pController->mClipList[index]->pFile);
976
977 pController->mVePlayer[playerInstance]->setVideoSurface(
978 pController->mSurface);
Steve Block2703f232011-10-20 11:56:09 +0100979 ALOGV("preparePlayer: setVideoSurface");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800980
981 pController->mVePlayer[playerInstance]->setMediaRenderingMode(
982 pController->mClipList[index]->xVSS.MediaRendering,
983 pController->mOutputVideoSize);
Steve Block2703f232011-10-20 11:56:09 +0100984 ALOGV("preparePlayer: setMediaRenderingMode");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800985
986 if((M4OSA_UInt32)index == pController->mStartingClipIndex) {
987 pController->mVePlayer[playerInstance]->setPlaybackBeginTime(
988 pController->mFirstPreviewClipBeginTime);
989 }
990 else {
991 pController->mVePlayer[playerInstance]->setPlaybackBeginTime(
992 pController->mClipList[index]->uiBeginCutTime);
993 }
Steve Block2703f232011-10-20 11:56:09 +0100994 ALOGV("preparePlayer: setPlaybackBeginTime(%d)",
Chih-Chung Chang99698662011-06-30 14:21:38 +0800995 pController->mClipList[index]->uiBeginCutTime);
996
997 pController->mVePlayer[playerInstance]->setPlaybackEndTime(
998 pController->mClipList[index]->uiEndCutTime);
Steve Block2703f232011-10-20 11:56:09 +0100999 ALOGV("preparePlayer: setPlaybackEndTime(%d)",
Chih-Chung Chang99698662011-06-30 14:21:38 +08001000 pController->mClipList[index]->uiEndCutTime);
1001
1002 if(pController->mClipList[index]->FileType == M4VIDEOEDITING_kFileType_ARGB8888) {
1003 pController->mVePlayer[playerInstance]->setImageClipProperties(
1004 pController->mClipList[index]->ClipProperties.uiVideoWidth,
1005 pController->mClipList[index]->ClipProperties.uiVideoHeight);
Steve Block2703f232011-10-20 11:56:09 +01001006 ALOGV("preparePlayer: setImageClipProperties");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001007 }
1008
1009 pController->mVePlayer[playerInstance]->prepare();
Steve Block2703f232011-10-20 11:56:09 +01001010 ALOGV("preparePlayer: prepared");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001011
1012 if(pController->mClipList[index]->uiBeginCutTime > 0) {
1013 pController->mVePlayer[playerInstance]->seekTo(
1014 pController->mClipList[index]->uiBeginCutTime);
1015
Steve Block2703f232011-10-20 11:56:09 +01001016 ALOGV("preparePlayer: seekTo(%d)",
Chih-Chung Chang99698662011-06-30 14:21:38 +08001017 pController->mClipList[index]->uiBeginCutTime);
1018 }
1019 pController->mVePlayer[pController->mCurrentPlayer]->setAudioPlayer(pController->mVEAudioPlayer);
1020
1021 pController->mVePlayer[playerInstance]->readFirstVideoFrame();
Steve Block2703f232011-10-20 11:56:09 +01001022 ALOGV("preparePlayer: readFirstVideoFrame of clip");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001023
1024 return err;
1025}
1026
1027M4OSA_ERR VideoEditorPreviewController::threadProc(M4OSA_Void* param) {
1028 M4OSA_ERR err = M4NO_ERROR;
1029 M4OSA_Int32 index = 0;
1030 VideoEditorPreviewController *pController =
1031 (VideoEditorPreviewController *)param;
1032
Steve Block2703f232011-10-20 11:56:09 +01001033 ALOGV("inside threadProc");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001034 if(pController->mPlayerState == VePlayerIdle) {
1035 (pController->mCurrentClipNumber)++;
1036
Steve Block4ca06b02011-12-20 16:24:14 +00001037 ALOGD("threadProc: playing file index %d total clips %d",
Chih-Chung Chang99698662011-06-30 14:21:38 +08001038 pController->mCurrentClipNumber, pController->mNumberClipsToPreview);
1039
1040 if((M4OSA_UInt32)pController->mCurrentClipNumber >=
1041 pController->mNumberClipsToPreview) {
1042
Steve Block4ca06b02011-12-20 16:24:14 +00001043 ALOGD("All clips previewed");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001044
1045 pController->mCurrentPlayedDuration = 0;
1046 pController->mCurrentClipDuration = 0;
1047 pController->mCurrentPlayer = 0;
1048
1049 if(pController->mPreviewLooping == M4OSA_TRUE) {
1050 pController->mCurrentClipNumber =
1051 pController->mStartingClipIndex;
1052
Steve Block4ca06b02011-12-20 16:24:14 +00001053 ALOGD("Preview looping TRUE, restarting from clip index %d",
Chih-Chung Chang99698662011-06-30 14:21:38 +08001054 pController->mCurrentClipNumber);
1055
1056 // Reset the story board timestamp inside the player
James Dong3d2d40a2012-01-27 19:01:13 -08001057 for (int playerInst=0; playerInst<kTotalNumPlayerInstances;
Chih-Chung Chang99698662011-06-30 14:21:38 +08001058 playerInst++) {
1059 pController->mVePlayer[playerInst]->resetJniCallbackTimeStamp();
1060 }
1061 }
1062 else {
1063 M4OSA_UInt32 endArgs = 0;
1064 if(pController->mJniCallback != NULL) {
1065 pController->mJniCallback(
1066 pController->mJniCookie, MSG_TYPE_PREVIEW_END, &endArgs);
1067 }
1068 pController->mPlayerState = VePlayerAutoStop;
1069
1070 // Reset original begin cuttime of first previewed clip
1071 pController->mClipList[pController->mStartingClipIndex]->uiBeginCutTime =
1072 pController->mFirstPreviewClipBeginTime;
1073 // Reset original end cuttime of last previewed clip
1074 pController->mClipList[pController->mNumberClipsToPreview-1]->uiEndCutTime =
1075 pController->mLastPreviewClipEndTime;
1076
1077 // Return a warning to M4OSA thread handler
1078 // so that thread is moved from executing state to open state
1079 return M4WAR_NO_MORE_STREAM;
1080 }
1081 }
1082
1083 index=pController->mCurrentClipNumber;
1084 if((M4OSA_UInt32)pController->mCurrentClipNumber == pController->mStartingClipIndex) {
1085 pController->mCurrentPlayedDuration +=
1086 pController->mVideoStoryBoardTimeMsUptoFirstPreviewClip;
1087
1088 pController->mCurrentClipDuration =
1089 pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime
1090 - pController->mFirstPreviewClipBeginTime;
1091
1092 preparePlayer((void*)pController, pController->mCurrentPlayer, index);
1093 }
1094 else {
1095 pController->mCurrentPlayedDuration +=
1096 pController->mCurrentClipDuration;
1097
1098 pController->mCurrentClipDuration =
1099 pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime -
1100 pController->mClipList[pController->mCurrentClipNumber]->uiBeginCutTime;
1101 }
1102
1103 pController->mVePlayer[pController->mCurrentPlayer]->setStoryboardStartTime(
1104 pController->mCurrentPlayedDuration);
Steve Block2703f232011-10-20 11:56:09 +01001105 ALOGV("threadProc: setStoryboardStartTime");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001106
1107 // Set the next clip duration for Audio mix here
1108 if((M4OSA_UInt32)pController->mCurrentClipNumber != pController->mStartingClipIndex) {
1109
1110 pController->mVePlayer[pController->mCurrentPlayer]->setAudioMixStoryBoardParam(
1111 pController->mCurrentPlayedDuration,
1112 pController->mClipList[index]->uiBeginCutTime,
1113 pController->mClipList[index]->ClipProperties.uiClipAudioVolumePercentage);
1114
Steve Block2703f232011-10-20 11:56:09 +01001115 ALOGV("threadProc: setAudioMixStoryBoardParam fromMS %d \
Chih-Chung Chang99698662011-06-30 14:21:38 +08001116 ClipBeginTime %d", pController->mCurrentPlayedDuration +
1117 pController->mClipList[index]->uiBeginCutTime,
1118 pController->mClipList[index]->uiBeginCutTime,
1119 pController->mClipList[index]->ClipProperties.uiClipAudioVolumePercentage);
1120 }
1121 // Capture the active player being used
1122 pController->mActivePlayerIndex = pController->mCurrentPlayer;
1123
1124 pController->mVePlayer[pController->mCurrentPlayer]->start();
Steve Block2703f232011-10-20 11:56:09 +01001125 ALOGV("threadProc: started");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001126
1127 pController->mPlayerState = VePlayerBusy;
1128
1129 } else if(pController->mPlayerState == VePlayerAutoStop) {
Steve Block2703f232011-10-20 11:56:09 +01001130 ALOGV("Preview completed..auto stop the player");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001131 } else if ((pController->mPlayerState == VePlayerBusy) && (pController->mPrepareReqest)) {
1132 // Prepare the player here
1133 pController->mPrepareReqest = M4OSA_FALSE;
1134 preparePlayer((void*)pController, pController->mCurrentPlayer,
1135 pController->mCurrentClipNumber+1);
1136 if (pController->mSemThreadWait != NULL) {
1137 err = M4OSA_semaphoreWait(pController->mSemThreadWait,
1138 M4OSA_WAIT_FOREVER);
1139 }
1140 } else {
1141 if (!pController->bStopThreadInProgress) {
Steve Block2703f232011-10-20 11:56:09 +01001142 ALOGV("threadProc: state busy...wait for sem");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001143 if (pController->mSemThreadWait != NULL) {
1144 err = M4OSA_semaphoreWait(pController->mSemThreadWait,
1145 M4OSA_WAIT_FOREVER);
1146 }
1147 }
Steve Block2703f232011-10-20 11:56:09 +01001148 ALOGV("threadProc: sem wait returned err = 0x%x", err);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001149 }
1150
1151 //Always return M4NO_ERROR to ensure the thread keeps running
1152 return M4NO_ERROR;
1153}
1154
1155void VideoEditorPreviewController::notify(
1156 void* cookie, int msg, int ext1, int ext2)
1157{
1158 VideoEditorPreviewController *pController =
1159 (VideoEditorPreviewController *)cookie;
1160
1161 M4OSA_ERR err = M4NO_ERROR;
1162 uint32_t clipDuration = 0;
1163 switch (msg) {
1164 case MEDIA_NOP: // interface test message
Steve Block2703f232011-10-20 11:56:09 +01001165 ALOGV("MEDIA_NOP");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001166 break;
1167 case MEDIA_PREPARED:
Steve Block2703f232011-10-20 11:56:09 +01001168 ALOGV("MEDIA_PREPARED");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001169 break;
1170 case MEDIA_PLAYBACK_COMPLETE:
1171 {
Steve Block4ca06b02011-12-20 16:24:14 +00001172 ALOGD("notify:MEDIA_PLAYBACK_COMPLETE, mCurrentClipNumber = %d",
Chih-Chung Changd94b9272011-09-05 14:49:35 +08001173 pController->mCurrentClipNumber);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001174 pController->mPlayerState = VePlayerIdle;
1175
1176 //send progress callback with last frame timestamp
1177 if((M4OSA_UInt32)pController->mCurrentClipNumber ==
1178 pController->mStartingClipIndex) {
1179 clipDuration =
1180 pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime
1181 - pController->mFirstPreviewClipBeginTime;
1182 }
1183 else {
1184 clipDuration =
1185 pController->mClipList[pController->mCurrentClipNumber]->uiEndCutTime
1186 - pController->mClipList[pController->mCurrentClipNumber]->uiBeginCutTime;
1187 }
1188
1189 M4OSA_UInt32 playedDuration = clipDuration+pController->mCurrentPlayedDuration;
1190 pController->mJniCallback(
1191 pController->mJniCookie, MSG_TYPE_PROGRESS_INDICATION,
1192 &playedDuration);
1193
1194 if ((pController->mOverlayState == OVERLAY_UPDATE) &&
1195 ((M4OSA_UInt32)pController->mCurrentClipNumber !=
1196 (pController->mNumberClipsToPreview-1))) {
1197 VideoEditorCurretEditInfo *pEditInfo =
1198 (VideoEditorCurretEditInfo*)M4OSA_32bitAlignedMalloc(sizeof(VideoEditorCurretEditInfo),
1199 M4VS, (M4OSA_Char*)"Current Edit info");
1200 pEditInfo->overlaySettingsIndex = ext2;
1201 pEditInfo->clipIndex = pController->mCurrentClipNumber;
1202 pController->mOverlayState == OVERLAY_CLEAR;
1203 if (pController->mJniCallback != NULL) {
1204 pController->mJniCallback(pController->mJniCookie,
1205 MSG_TYPE_OVERLAY_CLEAR, pEditInfo);
1206 }
1207 free(pEditInfo);
1208 }
1209 {
1210 Mutex::Autolock autoLock(pController->mLockSem);
1211 if (pController->mSemThreadWait != NULL) {
Raghavender Pallafa31daf2011-03-18 22:32:51 -07001212 M4OSA_semaphorePost(pController->mSemThreadWait);
1213 return;
Chih-Chung Chang99698662011-06-30 14:21:38 +08001214 }
1215 }
1216
1217 break;
1218 }
1219 case MEDIA_ERROR:
1220 {
1221 int err_val = ext1;
1222 // Always log errors.
1223 // ext1: Media framework error code.
1224 // ext2: Implementation dependant error code.
Steve Blockf8bd29c2012-01-08 10:14:44 +00001225 ALOGE("MEDIA_ERROR; error (%d, %d)", ext1, ext2);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001226 if(pController->mJniCallback != NULL) {
1227 pController->mJniCallback(pController->mJniCookie,
1228 MSG_TYPE_PLAYER_ERROR, &err_val);
1229 }
1230 break;
1231 }
1232 case MEDIA_INFO:
1233 {
1234 int info_val = ext2;
1235 // ext1: Media framework error code.
1236 // ext2: Implementation dependant error code.
Steve Blocke70ff372012-01-05 23:22:50 +00001237 //ALOGW("MEDIA_INFO; info/warning (%d, %d)", ext1, ext2);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001238 if(pController->mJniCallback != NULL) {
1239 pController->mJniCallback(pController->mJniCookie,
1240 MSG_TYPE_PROGRESS_INDICATION, &info_val);
1241 }
1242 break;
1243 }
1244 case MEDIA_SEEK_COMPLETE:
Steve Block2703f232011-10-20 11:56:09 +01001245 ALOGV("MEDIA_SEEK_COMPLETE; Received seek complete");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001246 break;
1247 case MEDIA_BUFFERING_UPDATE:
Steve Block2703f232011-10-20 11:56:09 +01001248 ALOGV("MEDIA_BUFFERING_UPDATE; buffering %d", ext1);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001249 break;
1250 case MEDIA_SET_VIDEO_SIZE:
Steve Block2703f232011-10-20 11:56:09 +01001251 ALOGV("MEDIA_SET_VIDEO_SIZE; New video size %d x %d", ext1, ext2);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001252 break;
synergydev3b546ca2013-10-25 12:36:28 -07001253 case static_cast<int>(0xAAAAAAAA):
Steve Block2703f232011-10-20 11:56:09 +01001254 ALOGV("VIDEO PLAYBACK ALMOST over, prepare next player");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001255 // Select next player and prepare it
1256 // If there is a clip after this one
1257 if ((M4OSA_UInt32)(pController->mCurrentClipNumber+1) <
1258 pController->mNumberClipsToPreview) {
1259 pController->mPrepareReqest = M4OSA_TRUE;
1260 pController->mCurrentPlayer++;
James Dong3d2d40a2012-01-27 19:01:13 -08001261 if (pController->mCurrentPlayer >= kTotalNumPlayerInstances) {
Chih-Chung Chang99698662011-06-30 14:21:38 +08001262 pController->mCurrentPlayer = 0;
1263 }
1264 // Prepare the first clip to be played
1265 {
1266 Mutex::Autolock autoLock(pController->mLockSem);
1267 if (pController->mSemThreadWait != NULL) {
1268 M4OSA_semaphorePost(pController->mSemThreadWait);
1269 }
1270 }
1271 }
1272 break;
synergydev3b546ca2013-10-25 12:36:28 -07001273 case static_cast<int>(0xBBBBBBBB):
Chih-Chung Chang99698662011-06-30 14:21:38 +08001274 {
Steve Block2703f232011-10-20 11:56:09 +01001275 ALOGV("VIDEO PLAYBACK, Update Overlay");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001276 int overlayIndex = ext2;
1277 VideoEditorCurretEditInfo *pEditInfo =
1278 (VideoEditorCurretEditInfo*)M4OSA_32bitAlignedMalloc(sizeof(VideoEditorCurretEditInfo),
1279 M4VS, (M4OSA_Char*)"Current Edit info");
1280 //ext1 = 1; start the overlay display
1281 // = 2; Clear the overlay.
1282 pEditInfo->overlaySettingsIndex = ext2;
1283 pEditInfo->clipIndex = pController->mCurrentClipNumber;
Steve Block2703f232011-10-20 11:56:09 +01001284 ALOGV("pController->mCurrentClipNumber = %d",pController->mCurrentClipNumber);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001285 if (pController->mJniCallback != NULL) {
1286 if (ext1 == 1) {
1287 pController->mOverlayState = OVERLAY_UPDATE;
1288 pController->mJniCallback(pController->mJniCookie,
1289 MSG_TYPE_OVERLAY_UPDATE, pEditInfo);
1290 } else {
1291 pController->mOverlayState = OVERLAY_CLEAR;
1292 pController->mJniCallback(pController->mJniCookie,
1293 MSG_TYPE_OVERLAY_CLEAR, pEditInfo);
1294 }
1295 }
1296 free(pEditInfo);
1297 break;
1298 }
1299 default:
Steve Block2703f232011-10-20 11:56:09 +01001300 ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001301 break;
1302 }
1303}
1304
1305void VideoEditorPreviewController::setVideoEffectType(
1306 M4VSS3GPP_VideoEffectType type, M4OSA_Bool enable) {
1307
1308 M4OSA_UInt32 effect = VIDEO_EFFECT_NONE;
1309
1310 // map M4VSS3GPP_VideoEffectType to local enum
1311 switch(type) {
1312 case M4VSS3GPP_kVideoEffectType_FadeFromBlack:
1313 effect = VIDEO_EFFECT_FADEFROMBLACK;
1314 break;
1315
1316 case M4VSS3GPP_kVideoEffectType_FadeToBlack:
1317 effect = VIDEO_EFFECT_FADETOBLACK;
1318 break;
1319
Chih-Chung Chang99698662011-06-30 14:21:38 +08001320 case M4xVSS_kVideoEffectType_BlackAndWhite:
1321 effect = VIDEO_EFFECT_BLACKANDWHITE;
1322 break;
1323
1324 case M4xVSS_kVideoEffectType_Pink:
1325 effect = VIDEO_EFFECT_PINK;
1326 break;
1327
1328 case M4xVSS_kVideoEffectType_Green:
1329 effect = VIDEO_EFFECT_GREEN;
1330 break;
1331
1332 case M4xVSS_kVideoEffectType_Sepia:
1333 effect = VIDEO_EFFECT_SEPIA;
1334 break;
1335
1336 case M4xVSS_kVideoEffectType_Negative:
1337 effect = VIDEO_EFFECT_NEGATIVE;
1338 break;
1339
1340 case M4xVSS_kVideoEffectType_Framing:
1341 effect = VIDEO_EFFECT_FRAMING;
1342 break;
1343
1344 case M4xVSS_kVideoEffectType_Fifties:
1345 effect = VIDEO_EFFECT_FIFTIES;
1346 break;
1347
1348 case M4xVSS_kVideoEffectType_ColorRGB16:
1349 effect = VIDEO_EFFECT_COLOR_RGB16;
1350 break;
1351
1352 case M4xVSS_kVideoEffectType_Gradient:
1353 effect = VIDEO_EFFECT_GRADIENT;
1354 break;
1355
1356 default:
1357 effect = VIDEO_EFFECT_NONE;
1358 break;
1359 }
1360
1361 if(enable == M4OSA_TRUE) {
1362 // If already set, then no need to set again
1363 if(!(mCurrentVideoEffect & effect))
1364 mCurrentVideoEffect |= effect;
1365 if(effect == VIDEO_EFFECT_FIFTIES) {
1366 mIsFiftiesEffectStarted = true;
1367 }
1368 }
1369 else {
1370 // Reset only if already set
1371 if(mCurrentVideoEffect & effect)
1372 mCurrentVideoEffect &= ~effect;
1373 }
1374
1375 return;
1376}
1377
1378
1379M4OSA_ERR VideoEditorPreviewController::applyVideoEffect(
1380 M4OSA_Void * dataPtr, M4OSA_UInt32 colorFormat, M4OSA_UInt32 videoWidth,
1381 M4OSA_UInt32 videoHeight, M4OSA_UInt32 timeMs, M4OSA_Void* outPtr) {
1382
1383 M4OSA_ERR err = M4NO_ERROR;
1384 vePostProcessParams postProcessParams;
1385
1386 postProcessParams.vidBuffer = (M4VIFI_UInt8*)dataPtr;
1387 postProcessParams.videoWidth = videoWidth;
1388 postProcessParams.videoHeight = videoHeight;
1389 postProcessParams.timeMs = timeMs;
1390 postProcessParams.timeOffset = 0; //Since timeMS already takes care of offset in this case
1391 postProcessParams.effectsSettings = mEffectsSettings;
1392 postProcessParams.numberEffects = mNumberEffects;
1393 postProcessParams.outVideoWidth = mOutputVideoWidth;
1394 postProcessParams.outVideoHeight = mOutputVideoHeight;
1395 postProcessParams.currentVideoEffect = mCurrentVideoEffect;
1396 postProcessParams.renderingMode = mRenderingMode;
1397 if(mIsFiftiesEffectStarted == M4OSA_TRUE) {
1398 postProcessParams.isFiftiesEffectStarted = M4OSA_TRUE;
1399 mIsFiftiesEffectStarted = M4OSA_FALSE;
1400 }
1401 else {
1402 postProcessParams.isFiftiesEffectStarted = M4OSA_FALSE;
1403 }
1404 //postProcessParams.renderer = mTarget;
1405 postProcessParams.overlayFrameRGBBuffer = NULL;
1406 postProcessParams.overlayFrameYUVBuffer = NULL;
1407
1408 mTarget->getBufferYV12(&(postProcessParams.pOutBuffer), &(postProcessParams.outBufferStride));
1409
1410 err = applyEffectsAndRenderingMode(&postProcessParams, videoWidth, videoHeight);
1411 return err;
1412}
1413
Hong Teng8806b702011-07-06 18:29:28 -07001414status_t VideoEditorPreviewController::setPreviewFrameRenderingMode(
Chih-Chung Chang99698662011-06-30 14:21:38 +08001415 M4xVSS_MediaRendering mode, M4VIDEOEDITING_VideoFrameSize outputVideoSize) {
1416
Steve Block2703f232011-10-20 11:56:09 +01001417 ALOGV("setMediaRenderingMode: outputVideoSize = %d", outputVideoSize);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001418 mRenderingMode = mode;
1419
Hong Teng8806b702011-07-06 18:29:28 -07001420 status_t err = OK;
1421 /* get the video width and height by resolution */
1422 err = getVideoSizeByResolution(outputVideoSize,
1423 &mOutputVideoWidth, &mOutputVideoHeight);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001424
Hong Teng8806b702011-07-06 18:29:28 -07001425 return err;
Chih-Chung Chang99698662011-06-30 14:21:38 +08001426}
1427
1428M4OSA_ERR VideoEditorPreviewController::doImageRenderingMode(
1429 M4OSA_Void * dataPtr, M4OSA_UInt32 colorFormat, M4OSA_UInt32 videoWidth,
1430 M4OSA_UInt32 videoHeight, M4OSA_Void* outPtr) {
1431
1432 M4OSA_ERR err = M4NO_ERROR;
1433 M4VIFI_ImagePlane planeIn[3], planeOut[3];
1434 M4VIFI_UInt8 *inBuffer = M4OSA_NULL;
1435 M4OSA_UInt32 outputBufferWidth =0, outputBufferHeight=0;
1436
1437 //frameSize = (videoWidth*videoHeight*3) >> 1;
1438 inBuffer = (M4OSA_UInt8 *)dataPtr;
1439
1440 // In plane
1441 prepareYUV420ImagePlane(planeIn, videoWidth,
1442 videoHeight, (M4VIFI_UInt8 *)inBuffer, videoWidth, videoHeight);
1443
1444 outputBufferWidth = mOutputVideoWidth;
1445 outputBufferHeight = mOutputVideoHeight;
1446
1447 // Out plane
1448 uint8_t* outBuffer;
1449 size_t outBufferStride = 0;
1450
Steve Block2703f232011-10-20 11:56:09 +01001451 ALOGV("doMediaRendering CALL getBuffer()");
Chih-Chung Chang99698662011-06-30 14:21:38 +08001452 mTarget->getBufferYV12(&outBuffer, &outBufferStride);
1453
1454 // Set the output YUV420 plane to be compatible with YV12 format
1455 //In YV12 format, sizes must be even
1456 M4OSA_UInt32 yv12PlaneWidth = ((mOutputVideoWidth +1)>>1)<<1;
1457 M4OSA_UInt32 yv12PlaneHeight = ((mOutputVideoHeight+1)>>1)<<1;
1458
1459 prepareYV12ImagePlane(planeOut, yv12PlaneWidth, yv12PlaneHeight,
1460 (M4OSA_UInt32)outBufferStride, (M4VIFI_UInt8 *)outBuffer);
1461
1462 err = applyRenderingMode(planeIn, planeOut, mRenderingMode);
1463 if(err != M4NO_ERROR) {
Steve Blockf8bd29c2012-01-08 10:14:44 +00001464 ALOGE("doImageRenderingMode: applyRenderingMode returned err=0x%x", (unsigned int)err);
Chih-Chung Chang99698662011-06-30 14:21:38 +08001465 }
1466 return err;
1467}
1468
1469} //namespace android