1 /*
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 #define LOG_NDEBUG 1
17 #define LOG_TAG "VideoEditorMain"
18 #include <dlfcn.h>
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <utils/Log.h>
22 #include <utils/threads.h>
23 #include <VideoEditorClasses.h>
24 #include <VideoEditorJava.h>
25 #include <VideoEditorOsal.h>
26 #include <VideoEditorLogging.h>
27 #include <marker.h>
28 #include <VideoEditorClasses.h>
29 #include <VideoEditorThumbnailMain.h>
30 #include <M4OSA_Debug.h>
31 #include <M4xVSS_Internal.h>
32 #include <gui/Surface.h>
33 #include "VideoEditorPreviewController.h"
34
35 #include "VideoEditorMain.h"
36
37 #include <android_runtime/android_view_Surface.h>
38
39 extern "C" {
40 #include <M4OSA_Clock.h>
41 #include <M4OSA_CharStar.h>
42 #include <M4OSA_Error.h>
43 #include <M4OSA_FileCommon.h>
44 #include <M4OSA_FileReader.h>
45 #include <M4OSA_FileWriter.h>
46 #include <M4OSA_Memory.h>
47 #include <M4OSA_Thread.h>
48 #include <M4xVSS_API.h>
49 #include <M4VSS3GPP_ErrorCodes.h>
50 #include <M4MCS_API.h>
51 #include <M4MCS_ErrorCodes.h>
52 #include <M4READER_Common.h>
53 #include <M4WRITER_common.h>
54 };
55
56
57 using namespace android;
58
59 #define THREAD_STACK_SIZE (65536)
60
61 #define VIDEOEDITOR_VERSION_MAJOR 0
62 #define VIDEOEDITOR_VERSION_MINOR 0
63 #define VIDEOEDITOR_VERSION_REVISION 1
64
65
66 typedef enum
67 {
68 ManualEditState_NOT_INITIALIZED,
69 ManualEditState_INITIALIZED,
70 ManualEditState_ANALYZING,
71 ManualEditState_ANALYZING_ERROR,
72 ManualEditState_OPENED,
73 ManualEditState_SAVING,
74 ManualEditState_SAVING_ERROR,
75 ManualEditState_SAVED,
76 ManualEditState_STOPPING
77 } ManualEditState;
78
79 typedef struct
80 {
81 JavaVM* pVM;
82 jobject engine;
83 jmethodID onCompletionMethodId;
84 jmethodID onErrorMethodId;
85 jmethodID onWarningMethodId;
86 jmethodID onProgressUpdateMethodId;
87 jmethodID onPreviewProgressUpdateMethodId;
88 jmethodID previewFrameEditInfoId;
89 M4xVSS_InitParams initParams;
90 void* pTextRendererHandle;
91 M4xVSS_getTextRgbBufferFct pTextRendererFunction;
92 M4OSA_Context engineContext;
93 ManualEditState state;
94 M4VSS3GPP_EditSettings* pEditSettings;
95 M4OSA_Context threadContext;
96 M4OSA_ERR threadResult;
97 M4OSA_UInt8 threadProgress;
98 VideoEditorPreviewController *mPreviewController;
99 M4xVSS_AudioMixingSettings *mAudioSettings;
100 /* Audio Graph changes */
101 M4OSA_Context pAudioGraphMCSCtx;
102 M4OSA_Bool bSkipState;
103 jmethodID onAudioGraphProgressUpdateMethodId;
104 Mutex mLock;
105 bool mIsUpdateOverlay;
106 char *mOverlayFileName;
107 int mOverlayRenderingMode;
108 M4DECODER_VideoDecoders* decoders;
109 } ManualEditContext;
110
111 extern "C" M4OSA_ERR M4MCS_open_normalMode(
112 M4MCS_Context pContext,
113 M4OSA_Void* pFileIn,
114 M4VIDEOEDITING_FileType InputFileType,
115 M4OSA_Void* pFileOut,
116 M4OSA_Void* pTempFile);
117
118 static M4OSA_ERR videoEditor_toUTF8Fct(
119 M4OSA_Void* pBufferIn,
120 M4OSA_UInt8* pBufferOut,
121 M4OSA_UInt32* bufferOutSize);
122
123 static M4OSA_ERR videoEditor_fromUTF8Fct(
124 M4OSA_UInt8* pBufferIn,
125 M4OSA_Void* pBufferOut,
126 M4OSA_UInt32* bufferOutSize);
127
128 static M4OSA_ERR videoEditor_getTextRgbBufferFct(
129 M4OSA_Void* pRenderingData,
130 M4OSA_Void* pTextBuffer,
131 M4OSA_UInt32 textBufferSize,
132 M4VIFI_ImagePlane** pOutputPlane);
133
134 static void videoEditor_callOnProgressUpdate(
135 ManualEditContext* pContext,
136 int task,
137 int progress);
138
139 static void videoEditor_freeContext(
140 JNIEnv* pEnv,
141 ManualEditContext** ppContext);
142
143 static M4OSA_ERR videoEditor_threadProc(
144 M4OSA_Void* param);
145
146 static jobject videoEditor_getVersion(
147 JNIEnv* pEnv,
148 jobject thiz);
149
150 static void videoEditor_init(
151 JNIEnv* pEnv,
152 jobject thiz,
153 jstring tempPath,
154 jstring textRendererPath);
155
156 static void videoEditor_loadSettings(
157 JNIEnv* pEnv,
158 jobject thiz,
159 jobject settings);
160
161 static void videoEditor_unloadSettings(
162 JNIEnv* pEnv,
163 jobject thiz);
164
165
166 static void videoEditor_stopEncoding(
167 JNIEnv* pEnv,
168 jobject thiz);
169
170 static void videoEditor_release(
171 JNIEnv* pEnv,
172 jobject thiz);
173 static int videoEditor_getPixels(
174 JNIEnv* env,
175 jobject thiz,
176 jstring path,
177 jintArray pixelArray,
178 M4OSA_UInt32 width,
179 M4OSA_UInt32 height,
180 M4OSA_UInt32 timeMS);
181 static int videoEditor_getPixelsList(
182 JNIEnv* env,
183 jobject thiz,
184 jstring path,
185 jintArray pixelArray,
186 M4OSA_UInt32 width,
187 M4OSA_UInt32 height,
188 M4OSA_UInt32 noOfThumbnails,
189 jlong startTime,
190 jlong endTime,
191 jintArray indexArray,
192 jobject callback);
193
194 static void
195 videoEditor_startPreview(
196 JNIEnv* pEnv,
197 jobject thiz,
198 jobject mSurface,
199 jlong fromMs,
200 jlong toMs,
201 jint callbackInterval,
202 jboolean loop);
203
204 static void
205 videoEditor_populateSettings(
206 JNIEnv* pEnv,
207 jobject thiz,
208 jobject settings,
209 jobject object,
210 jobject audioSettingObject);
211
212 static int videoEditor_stopPreview(JNIEnv* pEnv,
213 jobject thiz);
214
215 static jobject
216 videoEditor_getProperties(
217 JNIEnv* pEnv,
218 jobject thiz,
219 jstring file);
220
221 static int videoEditor_renderPreviewFrame(JNIEnv* pEnv,
222 jobject thiz,
223 jobject mSurface,
224 jlong fromMs,
225 jint surfaceWidth,
226 jint surfaceHeight);
227
228 static int videoEditor_registerManualEditMethods(
229 JNIEnv* pEnv);
230
231 static void jniPreviewProgressCallback(void* cookie, M4OSA_UInt32 msgType,
232 void *argc);
233
234 static int videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv,
235 jobject thiz,
236 jobject mSurface,
237 jstring filePath,
238 jint frameWidth,
239 jint frameHeight,
240 jint surfaceWidth,
241 jint surfaceHeight,
242 jlong fromMs);
243
244 static int videoEditor_generateAudioWaveFormSync ( JNIEnv* pEnv,
245 jobject thiz,
246 jstring pcmfilePath,
247 jstring outGraphfilePath,
248 jint frameDuration,
249 jint channels,
250 jint samplesCount);
251
252 static int videoEditor_generateAudioRawFile(JNIEnv* pEnv,
253 jobject thiz,
254 jstring infilePath,
255 jstring pcmfilePath );
256
257 M4OSA_ERR videoEditor_generateAudio(JNIEnv* pEnv,ManualEditContext* pContext,
258 M4OSA_Char* infilePath,
259 M4OSA_Char* pcmfilePath );
260
261 static int
262 videoEditor_generateClip(
263 JNIEnv* pEnv,
264 jobject thiz,
265 jobject settings);
266
267 static void videoEditor_clearSurface(JNIEnv* pEnv,
268 jobject thiz,
269 jobject surface);
270
271 static JNINativeMethod gManualEditMethods[] = {
272 {"getVersion", "()L"VERSION_CLASS_NAME";",
273 (void *)videoEditor_getVersion },
274 {"_init", "(Ljava/lang/String;Ljava/lang/String;)V",
275 (void *)videoEditor_init },
276 {"nativeStartPreview", "(Landroid/view/Surface;JJIZ)V",
277 (void *)videoEditor_startPreview },
278 {"nativePopulateSettings",
279 "(L"EDIT_SETTINGS_CLASS_NAME";L"PREVIEW_PROPERTIES_CLASS_NAME";L"
280 AUDIO_SETTINGS_CLASS_NAME";)V",
281 (void *)videoEditor_populateSettings },
282 {"nativeRenderPreviewFrame", "(Landroid/view/Surface;JII)I",
283 (int *)videoEditor_renderPreviewFrame },
284 {"nativeRenderMediaItemPreviewFrame",
285 "(Landroid/view/Surface;Ljava/lang/String;IIIIJ)I",
286 (int *)videoEditor_renderMediaItemPreviewFrame },
287 {"nativeStopPreview", "()I",
288 (int *)videoEditor_stopPreview },
289 {"stopEncoding", "()V",
290 (void *)videoEditor_stopEncoding },
291 {"release", "()V",
292 (void *)videoEditor_release },
293 {"nativeGetPixels", "(Ljava/lang/String;[IIIJ)I",
294 (void*)videoEditor_getPixels },
295 {"nativeGetPixelsList", "(Ljava/lang/String;[IIIIJJ[ILandroid/media/videoeditor/MediaArtistNativeHelper$NativeGetPixelsListCallback;)I",
296 (void*)videoEditor_getPixelsList },
297 {"getMediaProperties",
298 "(Ljava/lang/String;)Landroid/media/videoeditor/MediaArtistNativeHelper$Properties;",
299 (void *)videoEditor_getProperties },
300 {"nativeGenerateAudioGraph","(Ljava/lang/String;Ljava/lang/String;III)I",
301 (int *)videoEditor_generateAudioWaveFormSync },
302 {"nativeGenerateRawAudio", "(Ljava/lang/String;Ljava/lang/String;)I",
303 (int *)videoEditor_generateAudioRawFile },
304 {"nativeGenerateClip", "(L"EDIT_SETTINGS_CLASS_NAME";)I",
305 (void *)videoEditor_generateClip },
306 {"nativeClearSurface", "(Landroid/view/Surface;)V",
307 (void *)videoEditor_clearSurface },
308 };
309
310 // temp file name of VSS out file
311 #define TEMP_MCS_OUT_FILE_PATH "tmpOut.3gp"
312
313 void
getClipSetting(JNIEnv * pEnv,jobject object,M4VSS3GPP_ClipSettings * pSettings)314 getClipSetting(
315 JNIEnv* pEnv,
316 jobject object,
317 M4VSS3GPP_ClipSettings* pSettings)
318 {
319
320 jfieldID fid;
321 int field = 0;
322 bool needToBeLoaded = true;
323 jclass clazz = pEnv->FindClass(PROPERTIES_CLASS_NAME);
324
325 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
326 (M4OSA_NULL == clazz),
327 "not initialized");
328
329 fid = pEnv->GetFieldID(clazz,"duration","I");
330 pSettings->ClipProperties.uiClipDuration = pEnv->GetIntField(object,fid);
331 M4OSA_TRACE1_1("duration = %d",pSettings->ClipProperties.uiClipDuration);
332
333 fid = pEnv->GetFieldID(clazz,"videoFormat","I");
334 pSettings->ClipProperties.VideoStreamType =
335 (M4VIDEOEDITING_VideoFormat)pEnv->GetIntField(object,fid);
336 M4OSA_TRACE1_1("videoFormat = %d",pSettings->ClipProperties.VideoStreamType);
337
338 fid = pEnv->GetFieldID(clazz,"videoDuration","I");
339 pSettings->ClipProperties.uiClipVideoDuration = pEnv->GetIntField(object,fid);
340 M4OSA_TRACE1_1("videoDuration = %d",
341 pSettings->ClipProperties.uiClipVideoDuration);
342
343 fid = pEnv->GetFieldID(clazz,"width","I");
344 pSettings->ClipProperties.uiVideoWidth = pEnv->GetIntField(object,fid);
345 M4OSA_TRACE1_1("width = %d",pSettings->ClipProperties.uiVideoWidth);
346
347 fid = pEnv->GetFieldID(clazz,"height","I");
348 pSettings->ClipProperties.uiVideoHeight = pEnv->GetIntField(object,fid);
349 M4OSA_TRACE1_1("height = %d",pSettings->ClipProperties.uiVideoHeight);
350
351 fid = pEnv->GetFieldID(clazz,"audioFormat","I");
352 pSettings->ClipProperties.AudioStreamType =
353 (M4VIDEOEDITING_AudioFormat)pEnv->GetIntField(object,fid);
354 M4OSA_TRACE1_1("audioFormat = %d",pSettings->ClipProperties.AudioStreamType);
355
356 fid = pEnv->GetFieldID(clazz,"audioDuration","I");
357 pSettings->ClipProperties.uiClipAudioDuration = pEnv->GetIntField(object,fid);
358 M4OSA_TRACE1_1("audioDuration = %d",
359 pSettings->ClipProperties.uiClipAudioDuration);
360
361 fid = pEnv->GetFieldID(clazz,"audioBitrate","I");
362 pSettings->ClipProperties.uiAudioBitrate = pEnv->GetIntField(object,fid);
363 M4OSA_TRACE1_1("audioBitrate = %d",pSettings->ClipProperties.uiAudioBitrate);
364
365 fid = pEnv->GetFieldID(clazz,"audioChannels","I");
366 pSettings->ClipProperties.uiNbChannels = pEnv->GetIntField(object,fid);
367 M4OSA_TRACE1_1("audioChannels = %d",pSettings->ClipProperties.uiNbChannels);
368
369 fid = pEnv->GetFieldID(clazz,"audioSamplingFrequency","I");
370 pSettings->ClipProperties.uiSamplingFrequency = pEnv->GetIntField(object,fid);
371 M4OSA_TRACE1_1("audioSamplingFrequency = %d",
372 pSettings->ClipProperties.uiSamplingFrequency);
373
374 fid = pEnv->GetFieldID(clazz,"audioVolumeValue","I");
375 pSettings->ClipProperties.uiClipAudioVolumePercentage =
376 pEnv->GetIntField(object,fid);
377 M4OSA_TRACE1_1("audioVolumeValue = %d",
378 pSettings->ClipProperties.uiClipAudioVolumePercentage);
379
380 fid = pEnv->GetFieldID(clazz,"videoRotation","I");
381 pSettings->ClipProperties.videoRotationDegrees =
382 pEnv->GetIntField(object,fid);
383 M4OSA_TRACE1_1("videoRotation = %d",
384 pSettings->ClipProperties.videoRotationDegrees);
385
386 // Free the local references to avoid memory leaks
387 pEnv->DeleteLocalRef(clazz);
388 }
389
jniPreviewProgressCallback(void * cookie,M4OSA_UInt32 msgType,void * argc)390 static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType,
391 void *argc)
392 {
393 ManualEditContext *pContext = (ManualEditContext *)cookie;
394 JNIEnv* pEnv = NULL;
395 bool isFinished = false;
396 int currentMs = 0;
397 int error = M4NO_ERROR;
398 bool isUpdateOverlay = false;
399 int overlayEffectIndex;
400 char *extPos;
401 bool isSendProgress = true;
402 jstring tmpFileName;
403 VideoEditorCurretEditInfo *pCurrEditInfo;
404
405 // Attach the current thread.
406 pContext->pVM->AttachCurrentThread(&pEnv, NULL);
407 switch(msgType)
408 {
409 case MSG_TYPE_PROGRESS_INDICATION:
410 currentMs = *(int*)argc;
411 break;
412 case MSG_TYPE_PLAYER_ERROR:
413 currentMs = -1;
414 error = *(int*)argc;
415 break;
416 case MSG_TYPE_PREVIEW_END:
417 isFinished = true;
418 break;
419 case MSG_TYPE_OVERLAY_UPDATE:
420 {
421 int overlayFileNameLen = 0;
422 isSendProgress = false;
423 pContext->mIsUpdateOverlay = true;
424 pCurrEditInfo = (VideoEditorCurretEditInfo*)argc;
425 overlayEffectIndex = pCurrEditInfo->overlaySettingsIndex;
426 ALOGV("MSG_TYPE_OVERLAY_UPDATE");
427
428 if (pContext->mOverlayFileName != NULL) {
429 free(pContext->mOverlayFileName);
430 pContext->mOverlayFileName = NULL;
431 }
432
433 overlayFileNameLen =
434 strlen((const char*)pContext->pEditSettings->Effects[overlayEffectIndex].xVSS.pFramingFilePath);
435
436 pContext->mOverlayFileName =
437 (char*)M4OSA_32bitAlignedMalloc(overlayFileNameLen+1,
438 M4VS, (M4OSA_Char*)"videoEdito JNI overlayFile");
439 if (pContext->mOverlayFileName != NULL) {
440 strncpy (pContext->mOverlayFileName,
441 (const char*)pContext->pEditSettings->\
442 Effects[overlayEffectIndex].xVSS.pFramingFilePath, overlayFileNameLen);
443 //Change the name to png file
444 extPos = strstr(pContext->mOverlayFileName, ".rgb");
445 if (extPos != NULL) {
446 *extPos = '\0';
447 } else {
448 ALOGE("ERROR the overlay file is incorrect");
449 }
450
451 strcat(pContext->mOverlayFileName, ".png");
452 ALOGV("Conv string is %s", pContext->mOverlayFileName);
453 ALOGV("Current Clip index = %d", pCurrEditInfo->clipIndex);
454
455 pContext->mOverlayRenderingMode = pContext->pEditSettings->\
456 pClipList[pCurrEditInfo->clipIndex]->xVSS.MediaRendering;
457 ALOGV("rendering mode %d ", pContext->mOverlayRenderingMode);
458
459 }
460
461 break;
462 }
463
464 case MSG_TYPE_OVERLAY_CLEAR:
465 isSendProgress = false;
466 if (pContext->mOverlayFileName != NULL) {
467 free(pContext->mOverlayFileName);
468 pContext->mOverlayFileName = NULL;
469 }
470
471 ALOGV("MSG_TYPE_OVERLAY_CLEAR");
472 //argc is not used
473 pContext->mIsUpdateOverlay = true;
474 break;
475 default:
476 break;
477 }
478
479 if (isSendProgress) {
480 tmpFileName = pEnv->NewStringUTF(pContext->mOverlayFileName);
481 pEnv->CallVoidMethod(pContext->engine,
482 pContext->onPreviewProgressUpdateMethodId,
483 currentMs,isFinished, pContext->mIsUpdateOverlay,
484 tmpFileName, pContext->mOverlayRenderingMode, error);
485
486 if (pContext->mIsUpdateOverlay) {
487 pContext->mIsUpdateOverlay = false;
488 }
489
490 if (tmpFileName) {
491 pEnv->DeleteLocalRef(tmpFileName);
492 }
493 }
494
495 // Detach the current thread.
496 pContext->pVM->DetachCurrentThread();
497
498 }
checkClipVideoProfileAndLevel(M4DECODER_VideoDecoders * pDecoders,M4OSA_Int32 format,M4OSA_UInt32 profile,M4OSA_UInt32 level)499 static M4OSA_ERR checkClipVideoProfileAndLevel(M4DECODER_VideoDecoders *pDecoders,
500 M4OSA_Int32 format, M4OSA_UInt32 profile, M4OSA_UInt32 level){
501
502 M4OSA_Int32 codec = 0;
503 M4OSA_Bool foundCodec = M4OSA_FALSE;
504 M4OSA_ERR result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE;
505 M4OSA_Bool foundProfile = M4OSA_FALSE;
506 ALOGV("checkClipVideoProfileAndLevel format %d profile;%d level:0x%x",
507 format, profile, level);
508
509 switch (format) {
510 case M4VIDEOEDITING_kH263:
511 codec = M4DA_StreamTypeVideoH263;
512 break;
513 case M4VIDEOEDITING_kH264:
514 codec = M4DA_StreamTypeVideoMpeg4Avc;
515 break;
516 case M4VIDEOEDITING_kMPEG4:
517 codec = M4DA_StreamTypeVideoMpeg4;
518 break;
519 case M4VIDEOEDITING_kNoneVideo:
520 case M4VIDEOEDITING_kNullVideo:
521 case M4VIDEOEDITING_kUnsupportedVideo:
522 // For these case we do not check the profile and level
523 return M4NO_ERROR;
524 default :
525 ALOGE("checkClipVideoProfileAndLevel unsupport Video format %ld", format);
526 break;
527 }
528
529 if (pDecoders != M4OSA_NULL && pDecoders->decoderNumber > 0) {
530 VideoDecoder *pVideoDecoder = pDecoders->decoder;
531 for(size_t k =0; k < pDecoders->decoderNumber; k++) {
532 if (pVideoDecoder != M4OSA_NULL) {
533 if (pVideoDecoder->codec == codec) {
534 foundCodec = M4OSA_TRUE;
535 break;
536 }
537 }
538 pVideoDecoder++;
539 }
540
541 if (foundCodec) {
542 VideoComponentCapabilities* pComponent = pVideoDecoder->component;
543 for (size_t i = 0; i < pVideoDecoder->componentNumber; i++) {
544 if (pComponent != M4OSA_NULL) {
545 VideoProfileLevel *pProfileLevel = pComponent->profileLevel;
546 for (size_t j =0; j < pComponent->profileNumber; j++) {
547 // Check the profile and level
548 if (pProfileLevel != M4OSA_NULL) {
549 if (profile == pProfileLevel->mProfile) {
550 foundProfile = M4OSA_TRUE;
551
552 if (level <= pProfileLevel->mLevel) {
553 return M4NO_ERROR;
554 }
555 } else {
556 foundProfile = M4OSA_FALSE;
557 }
558 }
559 pProfileLevel++;
560 }
561 }
562 pComponent++;
563 }
564 }
565 }
566
567 if (foundProfile) {
568 result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_LEVEL;
569 } else {
570 result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE;
571 }
572
573 return result;
574 }
videoEditor_stopPreview(JNIEnv * pEnv,jobject thiz)575 static int videoEditor_stopPreview(JNIEnv* pEnv,
576 jobject thiz)
577 {
578 ManualEditContext* pContext = M4OSA_NULL;
579 bool needToBeLoaded = true;
580 M4OSA_UInt32 lastProgressTimeMs = 0;
581
582 // Get the context.
583 pContext =
584 (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
585
586 // Make sure that the context was set.
587 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
588 (M4OSA_NULL == pContext),
589 "not initialized");
590 lastProgressTimeMs = pContext->mPreviewController->stopPreview();
591
592 if (pContext->mOverlayFileName != NULL) {
593 free(pContext->mOverlayFileName);
594 pContext->mOverlayFileName = NULL;
595 }
596
597 return lastProgressTimeMs;
598 }
599
videoEditor_clearSurface(JNIEnv * pEnv,jobject thiz,jobject surface)600 static void videoEditor_clearSurface(JNIEnv* pEnv,
601 jobject thiz,
602 jobject surface)
603 {
604 bool needToBeLoaded = true;
605 M4OSA_ERR result = M4NO_ERROR;
606 VideoEditor_renderPreviewFrameStr frameStr;
607 const char* pMessage = NULL;
608 // Let the size be QVGA
609 int width = 320;
610 int height = 240;
611 ManualEditContext* pContext = M4OSA_NULL;
612
613 // Get the context.
614 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
615 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
616 "VIDEO_EDITOR","pContext = 0x%x",pContext);
617
618 // Make sure that the context was set.
619 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
620 (M4OSA_NULL == pContext),
621 "not initialized");
622
623 // Make sure that the context was set.
624 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
625 (M4OSA_NULL == pContext->mPreviewController),
626 "not initialized");
627
628 // Validate the surface parameter.
629 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
630 (NULL == surface),
631 "surface is null");
632
633 sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, surface);
634
635 // Validate the mSurface's mNativeSurface field
636 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
637 (NULL == previewSurface.get()),
638 "mNativeSurface is null");
639
640 frameStr.pBuffer = M4OSA_NULL;
641 frameStr.timeMs = 0;
642 frameStr.uiSurfaceWidth = width;
643 frameStr.uiSurfaceHeight = height;
644 frameStr.uiFrameWidth = width;
645 frameStr.uiFrameHeight = height;
646 frameStr.bApplyEffect = M4OSA_FALSE;
647 frameStr.clipBeginCutTime = 0;
648 frameStr.clipEndCutTime = 0;
649
650 result = pContext->mPreviewController->clearSurface(previewSurface,
651 &frameStr);
652 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
653 (M4NO_ERROR != result), result);
654
655 }
656
videoEditor_renderPreviewFrame(JNIEnv * pEnv,jobject thiz,jobject mSurface,jlong fromMs,jint surfaceWidth,jint surfaceHeight)657 static int videoEditor_renderPreviewFrame(JNIEnv* pEnv,
658 jobject thiz,
659 jobject mSurface,
660 jlong fromMs,
661 jint surfaceWidth,
662 jint surfaceHeight )
663 {
664 bool needToBeLoaded = true;
665 M4OSA_ERR result = M4NO_ERROR;
666 M4OSA_UInt32 timeMs = (M4OSA_UInt32)fromMs;
667 M4OSA_UInt32 i=0,tnTimeMs = 0, framesizeYuv =0;
668 M4VIFI_UInt8 *pixelArray = M4OSA_NULL;
669 M4OSA_UInt32 iCurrentClipIndex = 0, uiNumberOfClipsInStoryBoard =0,
670 uiClipDuration = 0, uiTotalClipDuration = 0,
671 iIncrementedDuration = 0;
672 VideoEditor_renderPreviewFrameStr frameStr;
673 M4OSA_Context tnContext = M4OSA_NULL;
674 const char* pMessage = NULL;
675 M4VIFI_ImagePlane *yuvPlane = NULL;
676 VideoEditorCurretEditInfo currEditInfo;
677
678 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
679 "VIDEO_EDITOR", "surfaceWidth = %d",surfaceWidth);
680 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
681 "VIDEO_EDITOR", "surfaceHeight = %d",surfaceHeight);
682 ManualEditContext* pContext = M4OSA_NULL;
683 // Get the context.
684 pContext =
685 (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
686 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
687 "VIDEO_EDITOR","pContext = 0x%x",pContext);
688
689 // Make sure that the context was set.
690 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
691 (M4OSA_NULL == pContext),
692 "not initialized");
693
694 // Make sure that the context was set.
695 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
696 (M4OSA_NULL == pContext->mPreviewController),
697 "not initialized");
698
699 // Validate the mSurface parameter.
700 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
701 (NULL == mSurface),
702 "mSurface is null");
703
704 sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface);
705
706 // Validate the mSurface's mNativeSurface field
707 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
708 (NULL == previewSurface.get()),
709 "mNativeSurface is null");
710
711 /* Determine the total number of clips, total duration*/
712 uiNumberOfClipsInStoryBoard = pContext->pEditSettings->uiClipNumber;
713
714 for (i = 0; i < uiNumberOfClipsInStoryBoard; i++) {
715 uiClipDuration = pContext->pEditSettings->pClipList[i]->uiEndCutTime -
716 pContext->pEditSettings->pClipList[i]->uiBeginCutTime;
717 uiTotalClipDuration += uiClipDuration;
718 }
719
720 /* determine the clip whose thumbnail needs to be rendered*/
721 if (timeMs == 0) {
722 iCurrentClipIndex = 0;
723 i=0;
724 } else {
725 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
726 "videoEditor_renderPreviewFrame() timeMs=%d", timeMs);
727
728 if (timeMs > uiTotalClipDuration) {
729 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
730 "videoEditor_renderPreviewFrame() timeMs > uiTotalClipDuration");
731 pMessage = videoEditJava_getErrorName(M4ERR_PARAMETER);
732 jniThrowException(pEnv, "java/lang/IllegalArgumentException", pMessage);
733 return -1;
734 }
735
736 for (i = 0; i < uiNumberOfClipsInStoryBoard; i++) {
737 if (timeMs <= (iIncrementedDuration +
738 (pContext->pEditSettings->pClipList[i]->uiEndCutTime -
739 pContext->pEditSettings->pClipList[i]->uiBeginCutTime)))
740 {
741 iCurrentClipIndex = i;
742 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
743 "videoEditor_renderPreviewFrame() iCurrentClipIndex=%d for timeMs=%d",
744 iCurrentClipIndex, timeMs);
745 break;
746 }
747 else {
748 iIncrementedDuration = iIncrementedDuration +
749 (pContext->pEditSettings->pClipList[i]->uiEndCutTime -
750 pContext->pEditSettings->pClipList[i]->uiBeginCutTime);
751 }
752 }
753 }
754 /* If timestamp is beyond story board duration, return*/
755 if (i >= uiNumberOfClipsInStoryBoard) {
756 if (timeMs == iIncrementedDuration) {
757 iCurrentClipIndex = i-1;
758 } else {
759 return -1;
760 }
761 }
762
763 /*+ Handle the image files here */
764 if (pContext->pEditSettings->pClipList[iCurrentClipIndex]->FileType ==
765 /*M4VIDEOEDITING_kFileType_JPG*/ M4VIDEOEDITING_kFileType_ARGB8888 ) {
766 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", " iCurrentClipIndex %d ", iCurrentClipIndex);
767 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
768 " Height = %d",
769 pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoHeight);
770
771 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
772 " Width = %d",
773 pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoWidth);
774
775 LvGetImageThumbNail((const char *)pContext->pEditSettings->\
776 pClipList[iCurrentClipIndex]->pFile,
777 pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoHeight,
778 pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoWidth,
779 (M4OSA_Void **)&frameStr.pBuffer);
780 tnTimeMs = (M4OSA_UInt32)timeMs;
781
782 frameStr.videoRotationDegree = 0;
783 } else {
784 /* Handle 3gp/mp4 Clips here */
785 /* get thumbnail*/
786 result = ThumbnailOpen(&tnContext,
787 (const M4OSA_Char*)pContext->pEditSettings->\
788 pClipList[iCurrentClipIndex]->pFile, M4OSA_TRUE);
789 if (result != M4NO_ERROR || tnContext == M4OSA_NULL) {
790 return -1;
791 }
792
793 /* timeMs is relative to storyboard; in this api it shud be relative to this clip */
794 if ((i >= uiNumberOfClipsInStoryBoard) &&
795 (timeMs == iIncrementedDuration)) {
796 tnTimeMs = pContext->pEditSettings->\
797 pClipList[iCurrentClipIndex]->uiEndCutTime;
798 } else {
799 tnTimeMs = pContext->pEditSettings->\
800 pClipList[iCurrentClipIndex]->uiBeginCutTime
801 + (timeMs - iIncrementedDuration);
802 }
803
804 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
805 "video width = %d",pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
806 ClipProperties.uiVideoWidth);
807 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
808 "video height = %d",pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
809 ClipProperties.uiVideoHeight);
810 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
811 "current clip index = %d",iCurrentClipIndex);
812
813 M4OSA_UInt32 width = pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
814 ClipProperties.uiVideoWidth;
815 M4OSA_UInt32 height = pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
816 ClipProperties.uiVideoHeight;
817
818 framesizeYuv = width * height * 1.5;
819
820 pixelArray = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(framesizeYuv, M4VS,
821 (M4OSA_Char*)"videoEditor pixelArray");
822 if (pixelArray == M4OSA_NULL) {
823 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
824 "videoEditor_renderPreviewFrame() malloc error");
825 ThumbnailClose(tnContext);
826 pMessage = videoEditJava_getErrorName(M4ERR_ALLOC);
827 jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
828 return -1;
829 }
830
831 result = ThumbnailGetPixels16(tnContext, (M4OSA_Int16 *)pixelArray,
832 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
833 ClipProperties.uiVideoWidth,
834 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
835 ClipProperties.uiVideoHeight,
836 &tnTimeMs, 0);
837 if (result != M4NO_ERROR) {
838 free(pixelArray);
839 ThumbnailClose(tnContext);
840 return -1;
841 }
842
843 ThumbnailClose(tnContext);
844 tnContext = M4OSA_NULL;
845
846 #ifdef DUMPTOFILE
847 {
848 M4OSA_Context fileContext;
849 M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/FirstRGB565.raw";
850 remove((const char *)fileName);
851 M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\
852 M4OSA_kFileWrite|M4OSA_kFileCreate);
853 M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) pixelArray,
854 framesizeYuv);
855 M4OSA_fileWriteClose(fileContext);
856 }
857 #endif
858
859 /**
860 * Allocate output YUV planes
861 */
862 yuvPlane = (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc(3*sizeof(M4VIFI_ImagePlane), M4VS,
863 (M4OSA_Char*)"videoEditor_renderPreviewFrame Output plane YUV");
864 if (yuvPlane == M4OSA_NULL) {
865 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
866 "videoEditor_renderPreviewFrame() malloc error for yuv plane");
867 free(pixelArray);
868 pMessage = videoEditJava_getErrorName(M4ERR_ALLOC);
869 jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
870 return -1;
871 }
872
873 yuvPlane[0].u_width = width;
874 yuvPlane[0].u_height = height;
875 yuvPlane[0].u_topleft = 0;
876 yuvPlane[0].u_stride = width;
877 yuvPlane[0].pac_data = (M4VIFI_UInt8*)pixelArray;
878
879 yuvPlane[1].u_width = width>>1;
880 yuvPlane[1].u_height = height>>1;
881 yuvPlane[1].u_topleft = 0;
882 yuvPlane[1].u_stride = width>>1;
883 yuvPlane[1].pac_data = yuvPlane[0].pac_data
884 + yuvPlane[0].u_width * yuvPlane[0].u_height;
885 yuvPlane[2].u_width = (width)>>1;
886 yuvPlane[2].u_height = (height)>>1;
887 yuvPlane[2].u_topleft = 0;
888 yuvPlane[2].u_stride = (width)>>1;
889 yuvPlane[2].pac_data = yuvPlane[1].pac_data
890 + yuvPlane[1].u_width * yuvPlane[1].u_height;
891
892 #ifdef DUMPTOFILE
893 {
894 M4OSA_Context fileContext;
895 M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/ConvertedYuv.yuv";
896 remove((const char *)fileName);
897 M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\
898 M4OSA_kFileWrite|M4OSA_kFileCreate);
899 M4OSA_fileWriteData(fileContext,
900 (M4OSA_MemAddr8) yuvPlane[0].pac_data, framesizeYuv);
901 M4OSA_fileWriteClose(fileContext);
902 }
903 #endif
904
905 /* Fill up the render structure*/
906 frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data;
907
908 frameStr.videoRotationDegree = pContext->pEditSettings->\
909 pClipList[iCurrentClipIndex]->ClipProperties.videoRotationDegrees;
910 }
911
912 frameStr.timeMs = timeMs; /* timestamp on storyboard*/
913 frameStr.uiSurfaceWidth =
914 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
915 ClipProperties.uiVideoWidth;
916 frameStr.uiSurfaceHeight =
917 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
918 ClipProperties.uiVideoHeight;
919 frameStr.uiFrameWidth =
920 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
921 ClipProperties.uiVideoWidth;
922 frameStr.uiFrameHeight =
923 pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
924 ClipProperties.uiVideoHeight;
925 if (pContext->pEditSettings->nbEffects > 0) {
926 frameStr.bApplyEffect = M4OSA_TRUE;
927 } else {
928 frameStr.bApplyEffect = M4OSA_FALSE;
929 }
930 frameStr.clipBeginCutTime = iIncrementedDuration;
931 frameStr.clipEndCutTime =
932 iIncrementedDuration +
933 (pContext->pEditSettings->pClipList[iCurrentClipIndex]->uiEndCutTime -\
934 pContext->pEditSettings->pClipList[iCurrentClipIndex]->uiBeginCutTime);
935
936 pContext->mPreviewController->setPreviewFrameRenderingMode(
937 pContext->pEditSettings->\
938 pClipList[iCurrentClipIndex]->xVSS.MediaRendering,
939 pContext->pEditSettings->xVSS.outputVideoSize);
940 result = pContext->mPreviewController->renderPreviewFrame(previewSurface,
941 &frameStr, &currEditInfo);
942
943 if (currEditInfo.overlaySettingsIndex != -1) {
944 char tmpOverlayFilename[100];
945 char *extPos = NULL;
946 jstring tmpOverlayString;
947 int tmpRenderingMode = 0;
948
949 strncpy (tmpOverlayFilename,
950 (const char*)pContext->pEditSettings->Effects[currEditInfo.overlaySettingsIndex].xVSS.pFramingFilePath, 99);
951
952 //Change the name to png file
953 extPos = strstr(tmpOverlayFilename, ".rgb");
954 if (extPos != NULL) {
955 *extPos = '\0';
956 } else {
957 ALOGE("ERROR the overlay file is incorrect");
958 }
959
960 strcat(tmpOverlayFilename, ".png");
961
962 tmpRenderingMode = pContext->pEditSettings->pClipList[iCurrentClipIndex]->xVSS.MediaRendering;
963 tmpOverlayString = pEnv->NewStringUTF(tmpOverlayFilename);
964 pEnv->CallVoidMethod(pContext->engine,
965 pContext->previewFrameEditInfoId,
966 tmpOverlayString, tmpRenderingMode);
967
968 }
969
970 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
971 (M4NO_ERROR != result), result);
972
973 free(frameStr.pBuffer);
974 if (pContext->pEditSettings->pClipList[iCurrentClipIndex]->FileType !=
975 M4VIDEOEDITING_kFileType_ARGB8888) {
976 free(yuvPlane);
977 }
978
979 return tnTimeMs;
980 }
981
videoEditor_renderMediaItemPreviewFrame(JNIEnv * pEnv,jobject thiz,jobject mSurface,jstring filePath,jint frameWidth,jint frameHeight,jint surfaceWidth,jint surfaceHeight,jlong fromMs)982 static int videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv,
983 jobject thiz,
984 jobject mSurface,
985 jstring filePath,
986 jint frameWidth,
987 jint frameHeight,
988 jint surfaceWidth,
989 jint surfaceHeight,
990 jlong fromMs)
991 {
992 bool needToBeLoaded = true;
993 M4OSA_ERR result = M4NO_ERROR;
994 M4OSA_UInt32 timeMs = (M4OSA_UInt32)fromMs;
995 M4OSA_UInt32 framesizeYuv =0;
996 M4VIFI_UInt8 *pixelArray = M4OSA_NULL;
997 VideoEditor_renderPreviewFrameStr frameStr;
998 M4OSA_Context tnContext = M4OSA_NULL;
999 const char* pMessage = NULL;
1000 M4VIFI_ImagePlane yuvPlane[3], rgbPlane;
1001
1002 ManualEditContext* pContext = M4OSA_NULL;
1003 // Get the context.
1004 pContext =
1005 (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded,
1006 pEnv, thiz);
1007
1008 // Make sure that the context was set.
1009 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1010 (M4OSA_NULL == pContext),
1011 "not initialized");
1012
1013 // Make sure that the context was set.
1014 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1015 (M4OSA_NULL == pContext->mPreviewController),
1016 "not initialized");
1017
1018 // Validate the mSurface parameter.
1019 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
1020 (NULL == mSurface),
1021 "mSurface is null");
1022
1023 sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface);
1024
1025 const char *pString = pEnv->GetStringUTFChars(filePath, NULL);
1026 if (pString == M4OSA_NULL) {
1027 if (pEnv != NULL) {
1028 jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null");
1029 }
1030 }
1031 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
1032 "videoEditor_renderMediaItemPreviewFrame() timeMs=%d", timeMs);
1033 /* get thumbnail*/
1034 result = ThumbnailOpen(&tnContext,(const M4OSA_Char*)pString, M4OSA_TRUE);
1035 if (result != M4NO_ERROR || tnContext == M4OSA_NULL) {
1036 return timeMs;
1037 }
1038
1039 framesizeYuv = ((frameWidth)*(frameHeight)*1.5);
1040
1041 pixelArray = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(framesizeYuv, M4VS,\
1042 (M4OSA_Char*)"videoEditor pixelArray");
1043 if (pixelArray == M4OSA_NULL) {
1044 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
1045 "videoEditor_renderPreviewFrame() malloc error");
1046 ThumbnailClose(tnContext);
1047 pMessage = videoEditJava_getErrorName(M4ERR_ALLOC);
1048 jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
1049 return timeMs;
1050 }
1051
1052 result = ThumbnailGetPixels16(tnContext, (M4OSA_Int16 *)pixelArray,
1053 frameWidth,
1054 frameHeight, &timeMs, 0);
1055 if (result != M4NO_ERROR) {
1056 free(pixelArray);
1057 ThumbnailClose(tnContext);
1058 return fromMs;
1059 }
1060
1061 #ifdef DUMPTOFILESYSTEM
1062 {
1063 M4OSA_Context fileContext;
1064 M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/FirstRGB565.rgb";
1065 M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\
1066 M4OSA_kFileWrite|M4OSA_kFileCreate);
1067 M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) pixelArray,
1068 framesizeRgb);
1069 M4OSA_fileWriteClose(fileContext);
1070 }
1071 #endif
1072
1073 yuvPlane[0].pac_data = (M4VIFI_UInt8*)pixelArray;
1074 yuvPlane[0].u_height = frameHeight;
1075 yuvPlane[0].u_width = frameWidth;
1076 yuvPlane[0].u_stride = yuvPlane[0].u_width;
1077 yuvPlane[0].u_topleft = 0;
1078
1079 yuvPlane[1].u_height = frameHeight/2;
1080 yuvPlane[1].u_width = frameWidth/2;
1081 yuvPlane[1].u_stride = yuvPlane[1].u_width;
1082 yuvPlane[1].u_topleft = 0;
1083 yuvPlane[1].pac_data = yuvPlane[0].pac_data
1084 + yuvPlane[0].u_width*yuvPlane[0].u_height;
1085
1086 yuvPlane[2].u_height = frameHeight/2;
1087 yuvPlane[2].u_width = frameWidth/2;
1088 yuvPlane[2].u_stride = yuvPlane[2].u_width;
1089 yuvPlane[2].u_topleft = 0;
1090 yuvPlane[2].pac_data = yuvPlane[0].pac_data
1091 + yuvPlane[0].u_width*yuvPlane[0].u_height + \
1092 (yuvPlane[0].u_width/2)*(yuvPlane[0].u_height/2);
1093 #ifdef DUMPTOFILESYSTEM
1094 {
1095 M4OSA_Context fileContext;
1096 M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/ConvertedYuv.yuv";
1097 M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\
1098 M4OSA_kFileWrite|M4OSA_kFileCreate);
1099 M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) yuvPlane[0].pac_data,
1100 framesizeYuv);
1101 M4OSA_fileWriteClose(fileContext);
1102 }
1103 #endif
1104
1105 /* Fill up the render structure*/
1106 frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data;
1107 frameStr.timeMs = timeMs; /* timestamp on storyboard*/
1108 frameStr.uiSurfaceWidth = frameWidth;
1109 frameStr.uiSurfaceHeight = frameHeight;
1110 frameStr.uiFrameWidth = frameWidth;
1111 frameStr.uiFrameHeight = frameHeight;
1112 frameStr.bApplyEffect = M4OSA_FALSE;
1113 // clip begin cuttime and end cuttime set to 0
1114 // as its only required when effect needs to be applied while rendering
1115 frameStr.clipBeginCutTime = 0;
1116 frameStr.clipEndCutTime = 0;
1117
1118 /* pContext->mPreviewController->setPreviewFrameRenderingMode(M4xVSS_kBlackBorders,
1119 (M4VIDEOEDITING_VideoFrameSize)(M4VIDEOEDITING_kHD960+1));*/
1120 result
1121 = pContext->mPreviewController->renderPreviewFrame(previewSurface,&frameStr, NULL);
1122 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1123 (M4NO_ERROR != result), result);
1124
1125 /* free the pixelArray and yuvPlane[0].pac_data */
1126 free(yuvPlane[0].pac_data);
1127
1128 ThumbnailClose(tnContext);
1129
1130 if (pString != NULL) {
1131 pEnv->ReleaseStringUTFChars(filePath, pString);
1132 }
1133
1134 return timeMs;
1135 }
1136
videoEditor_generateAudioRawFile(JNIEnv * pEnv,jobject thiz,jstring infilePath,jstring pcmfilePath)1137 int videoEditor_generateAudioRawFile( JNIEnv* pEnv,
1138 jobject thiz,
1139 jstring infilePath,
1140 jstring pcmfilePath)
1141 {
1142 M4OSA_ERR result = M4NO_ERROR;
1143 bool loaded = true;
1144 ManualEditContext* pContext = M4OSA_NULL;
1145
1146
1147
1148 const char *pInputFile = pEnv->GetStringUTFChars(infilePath, NULL);
1149 if (pInputFile == M4OSA_NULL) {
1150 if (pEnv != NULL) {
1151 jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null");
1152 }
1153 }
1154
1155 const char *pStringOutPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL);
1156 if (pStringOutPCMFilePath == M4OSA_NULL) {
1157 if (pEnv != NULL) {
1158 jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null");
1159 }
1160 }
1161
1162 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
1163 "VIDEO_EDITOR", "videoEditor_generateAudioRawFile infilePath %s",
1164 pInputFile);
1165 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
1166 "VIDEO_EDITOR", "videoEditor_generateAudioRawFile pcmfilePath %s",
1167 pStringOutPCMFilePath);
1168 // Get the context.
1169 pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz);
1170
1171 result = videoEditor_generateAudio( pEnv, pContext, (M4OSA_Char*)pInputFile,
1172 (M4OSA_Char*)pStringOutPCMFilePath);
1173
1174 if (pInputFile != NULL) {
1175 pEnv->ReleaseStringUTFChars(infilePath, pInputFile);
1176 }
1177 if (pStringOutPCMFilePath != NULL) {
1178 pEnv->ReleaseStringUTFChars(pcmfilePath, pStringOutPCMFilePath);
1179 }
1180
1181 return result;
1182 }
1183
videoEditor_generateAudio(JNIEnv * pEnv,ManualEditContext * pContext,M4OSA_Char * infilePath,M4OSA_Char * pcmfilePath)1184 M4OSA_ERR videoEditor_generateAudio(JNIEnv* pEnv,ManualEditContext* pContext,
1185 M4OSA_Char* infilePath,
1186 M4OSA_Char* pcmfilePath )
1187 {
1188 bool needToBeLoaded = true;
1189 M4OSA_ERR result = M4NO_ERROR;
1190 M4MCS_Context mcsContext = M4OSA_NULL;
1191 M4OSA_Char* pInputFile = M4OSA_NULL;
1192 M4OSA_Char* pOutputFile = M4OSA_NULL;
1193 M4OSA_Char* pTempPath = M4OSA_NULL;
1194 M4MCS_OutputParams* pOutputParams = M4OSA_NULL;
1195 M4MCS_EncodingParams* pEncodingParams = M4OSA_NULL;
1196 M4OSA_Int32 pInputFileType = 0;
1197 M4OSA_UInt8 threadProgress = 0;
1198 M4OSA_Char* pTemp3gpFilePath = M4OSA_NULL;
1199
1200 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_generateAudio()");
1201
1202 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
1203 (NULL == pContext),
1204 "ManualEditContext is null");
1205
1206 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_init()");
1207
1208 pOutputParams = (M4MCS_OutputParams *)M4OSA_32bitAlignedMalloc(
1209 sizeof(M4MCS_OutputParams),0x00,
1210 (M4OSA_Char *)"M4MCS_OutputParams");
1211 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1212 (M4OSA_NULL == pOutputParams),
1213 "not initialized");
1214 if (needToBeLoaded == false) {
1215 return M4ERR_ALLOC;
1216 }
1217
1218 pEncodingParams = (M4MCS_EncodingParams *)M4OSA_32bitAlignedMalloc(
1219 sizeof(M4MCS_EncodingParams),0x00,
1220 (M4OSA_Char *)"M4MCS_EncodingParams");
1221 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1222 (M4OSA_NULL == pEncodingParams),
1223 "not initialized");
1224 if (needToBeLoaded == false) {
1225 free(pEncodingParams);
1226 pEncodingParams = M4OSA_NULL;
1227 return M4ERR_ALLOC;
1228 }
1229
1230 // Initialize the MCS library.
1231 result = M4MCS_init(&mcsContext, pContext->initParams.pFileReadPtr,
1232 pContext->initParams.pFileWritePtr);
1233 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,\
1234 (M4NO_ERROR != result), result);
1235 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1236 (M4OSA_NULL == mcsContext),
1237 "not initialized");
1238 if(needToBeLoaded == false) {
1239 free(pOutputParams);
1240 pOutputParams = M4OSA_NULL;
1241 free(pEncodingParams);
1242 pEncodingParams = M4OSA_NULL;
1243 return result;
1244 }
1245
1246 // generate the path for temp 3gp output file
1247 pTemp3gpFilePath = (M4OSA_Char*) M4OSA_32bitAlignedMalloc (
1248 (strlen((const char*)pContext->initParams.pTempPath)
1249 + strlen((const char*)TEMP_MCS_OUT_FILE_PATH)) + 1 /* for null termination */ , 0x0,
1250 (M4OSA_Char*)"Malloc for temp 3gp file");
1251 if (pTemp3gpFilePath != M4OSA_NULL)
1252 {
1253 memset((void *)pTemp3gpFilePath ,0,
1254 strlen((const char*)pContext->initParams.pTempPath)
1255 + strlen((const char*)TEMP_MCS_OUT_FILE_PATH) + 1);
1256 strncat((char *)pTemp3gpFilePath,
1257 (const char *)pContext->initParams.pTempPath ,
1258 (size_t) ((M4OSA_Char*)pContext->initParams.pTempPath));
1259 strncat((char *)pTemp3gpFilePath , (const char *)TEMP_MCS_OUT_FILE_PATH,
1260 (size_t)strlen ((const char*)TEMP_MCS_OUT_FILE_PATH));
1261 }
1262 else {
1263 M4MCS_abort(mcsContext);
1264 free(pOutputParams);
1265 pOutputParams = M4OSA_NULL;
1266 free(pEncodingParams);
1267 pEncodingParams = M4OSA_NULL;
1268 return M4ERR_ALLOC;
1269 }
1270
1271 pInputFile = (M4OSA_Char *) infilePath; //pContext->mAudioSettings->pFile;
1272 //Delete this file later
1273 pOutputFile = (M4OSA_Char *) pTemp3gpFilePath;
1274 // Temp folder path for VSS use = ProjectPath
1275 pTempPath = (M4OSA_Char *) pContext->initParams.pTempPath;
1276 pInputFileType = (M4VIDEOEDITING_FileType)pContext->mAudioSettings->fileType;
1277
1278 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "TEMP_MCS_OUT_FILE_PATH len %d",
1279 strlen ((const char*)TEMP_MCS_OUT_FILE_PATH));
1280 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pTemp3gpFilePath %s",
1281 pOutputFile);
1282
1283 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_open()");
1284
1285 result = M4MCS_open(mcsContext, pInputFile,
1286 (M4VIDEOEDITING_FileType)pInputFileType,
1287 pOutputFile, pTempPath);
1288 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1289 (M4NO_ERROR != result), result);
1290 if(needToBeLoaded == false) {
1291 free(pTemp3gpFilePath);
1292 pTemp3gpFilePath = M4OSA_NULL;
1293 M4MCS_abort(mcsContext);
1294 free(pOutputParams);
1295 pOutputParams = M4OSA_NULL;
1296 free(pEncodingParams);
1297 pEncodingParams = M4OSA_NULL;
1298 return result;
1299 }
1300
1301 pOutputParams->OutputFileType
1302 = (M4VIDEOEDITING_FileType)M4VIDEOEDITING_kFileType_3GPP;
1303 // Set the video format.
1304 pOutputParams->OutputVideoFormat =
1305 (M4VIDEOEDITING_VideoFormat)M4VIDEOEDITING_kNoneVideo;//M4VIDEOEDITING_kNoneVideo;
1306 pOutputParams->outputVideoProfile = 1;
1307 pOutputParams->outputVideoLevel = 1;
1308 // Set the frame size.
1309 pOutputParams->OutputVideoFrameSize
1310 = (M4VIDEOEDITING_VideoFrameSize)M4VIDEOEDITING_kQCIF;
1311 // Set the frame rate.
1312 pOutputParams->OutputVideoFrameRate
1313 = (M4VIDEOEDITING_VideoFramerate)M4VIDEOEDITING_k5_FPS;
1314
1315 // Set the audio format.
1316 pOutputParams->OutputAudioFormat
1317 = (M4VIDEOEDITING_AudioFormat)M4VIDEOEDITING_kAAC;
1318 // Set the audio sampling frequency.
1319 pOutputParams->OutputAudioSamplingFrequency =
1320 (M4VIDEOEDITING_AudioSamplingFrequency)M4VIDEOEDITING_k32000_ASF;
1321 // Set the audio mono.
1322 pOutputParams->bAudioMono = false;
1323 // Set the pcm file; null for now.
1324 pOutputParams->pOutputPCMfile = (M4OSA_Char *)pcmfilePath;
1325 //(M4OSA_Char *)"/sdcard/Output/AudioPcm.pcm";
1326 // Set the audio sampling frequency.
1327 pOutputParams->MediaRendering = (M4MCS_MediaRendering)M4MCS_kCropping;
1328 // new params after integrating MCS 2.0
1329 // Set the number of audio effects; 0 for now.
1330 pOutputParams->nbEffects = 0;
1331 // Set the audio effect; null for now.
1332 pOutputParams->pEffects = NULL;
1333 // Set the audio effect; null for now.
1334 pOutputParams->bDiscardExif = M4OSA_FALSE;
1335 // Set the audio effect; null for now.
1336 pOutputParams->bAdjustOrientation = M4OSA_FALSE;
1337
1338 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_setOutputParams()");
1339 result = M4MCS_setOutputParams(mcsContext, pOutputParams);
1340 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1341 (M4NO_ERROR != result), result);
1342 if (needToBeLoaded == false) {
1343 free(pTemp3gpFilePath);
1344 pTemp3gpFilePath = M4OSA_NULL;
1345 M4MCS_abort(mcsContext);
1346 free(pOutputParams);
1347 pOutputParams = M4OSA_NULL;
1348 free(pEncodingParams);
1349 pEncodingParams = M4OSA_NULL;
1350 return result;
1351 }
1352 // Set the video bitrate.
1353 pEncodingParams->OutputVideoBitrate =
1354 (M4VIDEOEDITING_Bitrate)M4VIDEOEDITING_kUndefinedBitrate;
1355 // Set the audio bitrate.
1356 pEncodingParams->OutputAudioBitrate
1357 = (M4VIDEOEDITING_Bitrate)M4VIDEOEDITING_k128_KBPS;
1358 // Set the end cut time in milliseconds.
1359 pEncodingParams->BeginCutTime = 0;
1360 // Set the end cut time in milliseconds.
1361 pEncodingParams->EndCutTime = 0;
1362 // Set the output file size in bytes.
1363 pEncodingParams->OutputFileSize = 0;
1364 // Set video time scale.
1365 pEncodingParams->OutputVideoTimescale = 0;
1366
1367 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
1368 "M4MCS_setEncodingParams()");
1369 result = M4MCS_setEncodingParams(mcsContext, pEncodingParams);
1370 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1371 (M4NO_ERROR != result), result);
1372 if (needToBeLoaded == false) {
1373 free(pTemp3gpFilePath);
1374 pTemp3gpFilePath = M4OSA_NULL;
1375 M4MCS_abort(mcsContext);
1376 free(pOutputParams);
1377 pOutputParams = M4OSA_NULL;
1378 free(pEncodingParams);
1379 pEncodingParams = M4OSA_NULL;
1380 return result;
1381 }
1382
1383 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
1384 "M4MCS_checkParamsAndStart()");
1385 result = M4MCS_checkParamsAndStart(mcsContext);
1386 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1387 (M4NO_ERROR != result), result);
1388 if (needToBeLoaded == false) {
1389 free(pTemp3gpFilePath);
1390 pTemp3gpFilePath = M4OSA_NULL;
1391 M4MCS_abort(mcsContext);
1392 free(pOutputParams);
1393 pOutputParams = M4OSA_NULL;
1394 free(pEncodingParams);
1395 pEncodingParams = M4OSA_NULL;
1396 return result;
1397 }
1398
1399 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_step()");
1400
1401 /*+ PROGRESS CB */
1402 M4OSA_UInt8 curProgress = 0;
1403 int lastProgress = 0;
1404
1405 ALOGV("LVME_generateAudio Current progress is =%d", curProgress);
1406 pEnv->CallVoidMethod(pContext->engine,
1407 pContext->onProgressUpdateMethodId, 1/*task status*/,
1408 curProgress/*progress*/);
1409 do {
1410 result = M4MCS_step(mcsContext, &curProgress);
1411
1412 if (result != M4NO_ERROR) {
1413 ALOGV("LVME_generateAudio M4MCS_step returned 0x%x",result);
1414
1415 if (result == M4MCS_WAR_TRANSCODING_DONE) {
1416 ALOGV("LVME_generateAudio MCS process ended");
1417
1418 // Send a progress notification.
1419 curProgress = 100;
1420 pEnv->CallVoidMethod(pContext->engine,
1421 pContext->onProgressUpdateMethodId, 1/*task status*/,
1422 curProgress);
1423 ALOGV("LVME_generateAudio Current progress is =%d", curProgress);
1424 }
1425 } else {
1426 // Send a progress notification if needed
1427 if (curProgress != lastProgress) {
1428 lastProgress = curProgress;
1429 pEnv->CallVoidMethod(pContext->engine,
1430 pContext->onProgressUpdateMethodId, 0/*task status*/,
1431 curProgress/*progress*/);
1432 ALOGV("LVME_generateAudio Current progress is =%d",curProgress);
1433 }
1434 }
1435 } while (result == M4NO_ERROR);
1436 /*- PROGRESS CB */
1437
1438 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1439 (M4MCS_WAR_TRANSCODING_DONE != result), result);
1440 if (needToBeLoaded == false) {
1441 free(pTemp3gpFilePath);
1442 pTemp3gpFilePath = M4OSA_NULL;
1443 M4MCS_abort(mcsContext);
1444 free(pOutputParams);
1445 pOutputParams = M4OSA_NULL;
1446 free(pEncodingParams);
1447 pEncodingParams = M4OSA_NULL;
1448 return result;
1449 }
1450
1451 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_abort()");
1452 result = M4MCS_abort(mcsContext);
1453 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1454 (M4NO_ERROR != result), result);
1455
1456 //pContext->mAudioSettings->pFile = pOutputParams->pOutputPCMfile;
1457 remove((const char *) pTemp3gpFilePath);
1458 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_generateAudio() EXIT ");
1459
1460 if (pTemp3gpFilePath != M4OSA_NULL) {
1461 free(pTemp3gpFilePath);
1462 }
1463 if (pOutputParams != M4OSA_NULL) {
1464 free(pOutputParams);
1465 }
1466 if(pEncodingParams != M4OSA_NULL) {
1467 free(pEncodingParams);
1468 }
1469 return result;
1470 }
1471
removeAlphafromRGB8888(M4OSA_Char * pFramingFilePath,M4xVSS_FramingStruct * pFramingCtx)1472 static int removeAlphafromRGB8888 (
1473 M4OSA_Char* pFramingFilePath,
1474 M4xVSS_FramingStruct *pFramingCtx)
1475 {
1476 M4OSA_UInt32 frameSize_argb = (pFramingCtx->width * pFramingCtx->height * 4); // aRGB data
1477 M4OSA_Context lImageFileFp = M4OSA_NULL;
1478 M4OSA_ERR err = M4NO_ERROR;
1479
1480 ALOGV("removeAlphafromRGB8888: width %d", pFramingCtx->width);
1481
1482 M4OSA_UInt8 *pTmpData = (M4OSA_UInt8*) M4OSA_32bitAlignedMalloc(frameSize_argb, M4VS, (M4OSA_Char*)"Image argb data");
1483 if (pTmpData == M4OSA_NULL) {
1484 ALOGE("Failed to allocate memory for Image clip");
1485 return M4ERR_ALLOC;
1486 }
1487
1488 /** Read the argb data from the passed file. */
1489 M4OSA_ERR lerr = M4OSA_fileReadOpen(&lImageFileFp, (M4OSA_Void *) pFramingFilePath, M4OSA_kFileRead);
1490
1491
1492 if ((lerr != M4NO_ERROR) || (lImageFileFp == M4OSA_NULL))
1493 {
1494 ALOGE("removeAlphafromRGB8888: Can not open the file ");
1495 free(pTmpData);
1496 return M4ERR_FILE_NOT_FOUND;
1497 }
1498
1499
1500 lerr = M4OSA_fileReadData(lImageFileFp, (M4OSA_MemAddr8)pTmpData, &frameSize_argb);
1501 if (lerr != M4NO_ERROR)
1502 {
1503 ALOGE("removeAlphafromRGB8888: can not read the data ");
1504 M4OSA_fileReadClose(lImageFileFp);
1505 free(pTmpData);
1506 return lerr;
1507 }
1508 M4OSA_fileReadClose(lImageFileFp);
1509
1510 M4OSA_UInt32 frameSize = (pFramingCtx->width * pFramingCtx->height * 3); //Size of RGB 888 data.
1511
1512 pFramingCtx->FramingRgb = (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc(
1513 sizeof(M4VIFI_ImagePlane), M4VS, (M4OSA_Char*)"Image clip RGB888 data");
1514 pFramingCtx->FramingRgb->pac_data = (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc(
1515 frameSize, M4VS, (M4OSA_Char*)"Image clip RGB888 data");
1516
1517 if (pFramingCtx->FramingRgb == M4OSA_NULL)
1518 {
1519 ALOGE("Failed to allocate memory for Image clip");
1520 free(pTmpData);
1521 return M4ERR_ALLOC;
1522 }
1523
1524 /** Remove the alpha channel */
1525 for (size_t i = 0, j = 0; i < frameSize_argb; i++) {
1526 if ((i % 4) == 0) continue;
1527 pFramingCtx->FramingRgb->pac_data[j] = pTmpData[i];
1528 j++;
1529 }
1530 free(pTmpData);
1531 return M4NO_ERROR;
1532 }
1533
1534 static void
videoEditor_populateSettings(JNIEnv * pEnv,jobject thiz,jobject settings,jobject object,jobject audioSettingObject)1535 videoEditor_populateSettings(
1536 JNIEnv* pEnv,
1537 jobject thiz,
1538 jobject settings,
1539 jobject object,
1540 jobject audioSettingObject)
1541 {
1542 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
1543 "videoEditor_populateSettings()");
1544
1545 bool needToBeLoaded = true;
1546 ManualEditContext* pContext = M4OSA_NULL;
1547 M4OSA_ERR result = M4NO_ERROR;
1548 jstring strPath = M4OSA_NULL;
1549 jstring strPCMPath = M4OSA_NULL;
1550 jobjectArray propertiesClipsArray = M4OSA_NULL;
1551 jobject properties = M4OSA_NULL;
1552 jint* bitmapArray = M4OSA_NULL;
1553 jobjectArray effectSettingsArray = M4OSA_NULL;
1554 jobject effectSettings = M4OSA_NULL;
1555 jintArray pixelArray = M4OSA_NULL;
1556 int width = 0;
1557 int height = 0;
1558 int nbOverlays = 0;
1559 int i,j = 0;
1560 int *pOverlayIndex = M4OSA_NULL;
1561 M4OSA_Char* pTempChar = M4OSA_NULL;
1562
1563 // Add a code marker (the condition must always be true).
1564 ADD_CODE_MARKER_FUN(NULL != pEnv)
1565
1566 // Validate the settings parameter.
1567 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
1568 (NULL == settings),
1569 "settings is null");
1570 // Get the context.
1571 pContext =
1572 (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
1573
1574 // Make sure that the context was set.
1575 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1576 (M4OSA_NULL == pContext),
1577 "not initialized");
1578 // Make sure that the context was set.
1579 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1580 (M4OSA_NULL == pContext->mPreviewController),
1581 "not initialized");
1582 jclass mPreviewClipPropClazz = pEnv->FindClass(PREVIEW_PROPERTIES_CLASS_NAME);
1583 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1584 (M4OSA_NULL == mPreviewClipPropClazz),
1585 "not initialized");
1586
1587 jfieldID fid = pEnv->GetFieldID(mPreviewClipPropClazz,"clipProperties",
1588 "[L"PROPERTIES_CLASS_NAME";" );
1589 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1590 (M4OSA_NULL == fid),
1591 "not initialized");
1592
1593 propertiesClipsArray = (jobjectArray)pEnv->GetObjectField(object, fid);
1594 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1595 (M4OSA_NULL == propertiesClipsArray),
1596 "not initialized");
1597
1598 jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME);
1599 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1600 (M4OSA_NULL == engineClass),
1601 "not initialized");
1602
1603 pContext->onPreviewProgressUpdateMethodId = pEnv->GetMethodID(engineClass,
1604 "onPreviewProgressUpdate", "(IZZLjava/lang/String;II)V");
1605 // Check if the context is valid (required because the context is dereferenced).
1606 if (needToBeLoaded) {
1607 // Make sure that we are in a correct state.
1608 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1609 (pContext->state != ManualEditState_INITIALIZED),
1610 "settings already loaded");
1611 if (needToBeLoaded) {
1612 // Retrieve the edit settings.
1613 if (pContext->pEditSettings != M4OSA_NULL) {
1614 videoEditClasses_freeEditSettings(&pContext->pEditSettings);
1615 pContext->pEditSettings = M4OSA_NULL;
1616 }
1617 videoEditClasses_getEditSettings(&needToBeLoaded, pEnv,
1618 settings, &pContext->pEditSettings,false);
1619 }
1620 }
1621
1622 if (needToBeLoaded == false) {
1623 j = 0;
1624 while (j < pContext->pEditSettings->nbEffects)
1625 {
1626 if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL) {
1627 if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer != M4OSA_NULL) {
1628 free(pContext->pEditSettings->\
1629 Effects[j].xVSS.pFramingBuffer);
1630 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer = M4OSA_NULL;
1631 }
1632 }
1633 j++;
1634 }
1635 return;
1636 }
1637
1638 M4OSA_TRACE1_0("videoEditorC_getEditSettings done");
1639
1640 pContext->previewFrameEditInfoId = pEnv->GetMethodID(engineClass,
1641 "previewFrameEditInfo", "(Ljava/lang/String;I)V");
1642
1643 if ( pContext->pEditSettings != NULL )
1644 {
1645 // Check if the edit settings could be retrieved.
1646 jclass mEditClazz = pEnv->FindClass(EDIT_SETTINGS_CLASS_NAME);
1647 if(mEditClazz == M4OSA_NULL)
1648 {
1649 M4OSA_TRACE1_0("cannot find object field for mEditClazz");
1650 goto videoEditor_populateSettings_cleanup;
1651 }
1652 jclass mEffectsClazz = pEnv->FindClass(EFFECT_SETTINGS_CLASS_NAME);
1653 if(mEffectsClazz == M4OSA_NULL)
1654 {
1655 M4OSA_TRACE1_0("cannot find object field for mEffectsClazz");
1656 goto videoEditor_populateSettings_cleanup;
1657 }
1658 fid = pEnv->GetFieldID(mEditClazz,"effectSettingsArray", "[L"EFFECT_SETTINGS_CLASS_NAME";" );
1659 if(fid == M4OSA_NULL)
1660 {
1661 M4OSA_TRACE1_0("cannot find field for effectSettingsArray Array");
1662 goto videoEditor_populateSettings_cleanup;
1663 }
1664 effectSettingsArray = (jobjectArray)pEnv->GetObjectField(settings, fid);
1665 if(effectSettingsArray == M4OSA_NULL)
1666 {
1667 M4OSA_TRACE1_0("cannot find object field for effectSettingsArray");
1668 goto videoEditor_populateSettings_cleanup;
1669 }
1670
1671 //int overlayIndex[pContext->pEditSettings->nbEffects];
1672 if (pContext->pEditSettings->nbEffects > 0)
1673 {
1674 pOverlayIndex
1675 = (int*) M4OSA_32bitAlignedMalloc(pContext->pEditSettings->nbEffects * sizeof(int), 0,
1676 (M4OSA_Char*)"pOverlayIndex");
1677 if (pOverlayIndex == M4OSA_NULL) {
1678 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1679 M4OSA_TRUE, M4ERR_ALLOC);
1680 goto videoEditor_populateSettings_cleanup;
1681 }
1682 }
1683
1684 i = 0;
1685 j = 0;
1686 M4OSA_TRACE1_1("no of effects = %d",pContext->pEditSettings->nbEffects);
1687 while (j < pContext->pEditSettings->nbEffects)
1688 {
1689 if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL)
1690 {
1691 pOverlayIndex[nbOverlays] = j;
1692
1693 M4xVSS_FramingStruct *aFramingCtx = M4OSA_NULL;
1694 aFramingCtx
1695 = (M4xVSS_FramingStruct*)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct), M4VS,
1696 (M4OSA_Char*)"M4xVSS_internalDecodeGIF: Context of the framing effect");
1697 if (aFramingCtx == M4OSA_NULL)
1698 {
1699 M4OSA_TRACE1_0("Allocation error in videoEditor_populateSettings");
1700 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1701 M4OSA_TRUE, M4ERR_ALLOC);
1702 goto videoEditor_populateSettings_cleanup;
1703 }
1704
1705 aFramingCtx->pCurrent = M4OSA_NULL; /* Only used by the first element of the chain */
1706 aFramingCtx->previousClipTime = -1;
1707 aFramingCtx->FramingYuv = M4OSA_NULL;
1708 aFramingCtx->FramingRgb = M4OSA_NULL;
1709 aFramingCtx->topleft_x
1710 = pContext->pEditSettings->Effects[j].xVSS.topleft_x;
1711 aFramingCtx->topleft_y
1712 = pContext->pEditSettings->Effects[j].xVSS.topleft_y;
1713
1714
1715 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF u_width %d",
1716 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width);
1717 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF u_height() %d",
1718 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height);
1719 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF rgbType() %d",
1720 pContext->pEditSettings->Effects[j].xVSS.rgbType);
1721
1722 aFramingCtx->width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width;
1723 aFramingCtx->height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height;
1724
1725 result = M4xVSS_internalConvertARGB888toYUV420_FrammingEffect(pContext->engineContext,
1726 &(pContext->pEditSettings->Effects[j]),aFramingCtx,
1727 pContext->pEditSettings->Effects[j].xVSS.framingScaledSize);
1728 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1729 (M4NO_ERROR != result), result);
1730 if (needToBeLoaded == false) {
1731 M4OSA_TRACE1_1("M4xVSS_internalConvertARGB888toYUV420_FrammingEffect returned 0x%x", result);
1732 if (aFramingCtx != M4OSA_NULL) {
1733 free(aFramingCtx);
1734 aFramingCtx = M4OSA_NULL;
1735 }
1736 goto videoEditor_populateSettings_cleanup;
1737 }
1738
1739 //framing buffers are resized to fit the output video resolution.
1740 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width =
1741 aFramingCtx->FramingRgb->u_width;
1742 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height =
1743 aFramingCtx->FramingRgb->u_height;
1744
1745 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "A framing Context aFramingCtx->width = %d",
1746 aFramingCtx->FramingRgb->u_width);
1747
1748 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "A framing Context aFramingCtx->height = %d",
1749 aFramingCtx->FramingRgb->u_height);
1750
1751
1752 width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width;
1753 height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height;
1754
1755 //RGB 565
1756 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_stride = width * 2;
1757
1758 //for RGB565
1759 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_topleft = 0;
1760 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->pac_data =
1761 (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(width*height*2,
1762 0x00,(M4OSA_Char *)"pac_data buffer");
1763
1764 if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->pac_data == M4OSA_NULL) {
1765 M4OSA_TRACE1_0("Failed to allocate memory for framing buffer");
1766 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1767 M4OSA_TRUE, M4ERR_ALLOC);
1768 goto videoEditor_populateSettings_cleanup;
1769 }
1770
1771 memcpy((void *)&pContext->pEditSettings->\
1772 Effects[j].xVSS.pFramingBuffer->\
1773 pac_data[0],(void *)&aFramingCtx->FramingRgb->pac_data[0],(width*height*2));
1774
1775 //As of now rgb type is 565
1776 pContext->pEditSettings->Effects[j].xVSS.rgbType =
1777 (M4VSS3GPP_RGBType) M4VSS3GPP_kRGB565;
1778
1779 if (aFramingCtx->FramingYuv != M4OSA_NULL )
1780 {
1781 if (aFramingCtx->FramingYuv[0].pac_data != M4OSA_NULL) {
1782 free(aFramingCtx->FramingYuv[0].pac_data);
1783 aFramingCtx->FramingYuv[0].pac_data = M4OSA_NULL;
1784 }
1785 if (aFramingCtx->FramingYuv[1].pac_data != M4OSA_NULL) {
1786 free(aFramingCtx->FramingYuv[1].pac_data);
1787 aFramingCtx->FramingYuv[1].pac_data = M4OSA_NULL;
1788 }
1789 if (aFramingCtx->FramingYuv[2].pac_data != M4OSA_NULL) {
1790 free(aFramingCtx->FramingYuv[2].pac_data);
1791 aFramingCtx->FramingYuv[2].pac_data = M4OSA_NULL;
1792 }
1793
1794 free(aFramingCtx->FramingYuv);
1795 aFramingCtx->FramingYuv = M4OSA_NULL;
1796 }
1797 if (aFramingCtx->FramingRgb->pac_data != M4OSA_NULL) {
1798 free(aFramingCtx->FramingRgb->pac_data);
1799 aFramingCtx->FramingRgb->pac_data = M4OSA_NULL;
1800 }
1801 if (aFramingCtx->FramingRgb != M4OSA_NULL) {
1802 free(aFramingCtx->FramingRgb);
1803 aFramingCtx->FramingRgb = M4OSA_NULL;
1804 }
1805 if (aFramingCtx != M4OSA_NULL) {
1806 free(aFramingCtx);
1807 aFramingCtx = M4OSA_NULL;
1808 }
1809 nbOverlays++;
1810 }
1811 j++;
1812 }
1813
1814 // Check if the edit settings could be retrieved.
1815 M4OSA_TRACE1_1("total clips are = %d",pContext->pEditSettings->uiClipNumber);
1816 for (i = 0; i < pContext->pEditSettings->uiClipNumber; i++) {
1817 M4OSA_TRACE1_1("clip no = %d",i);
1818 properties = pEnv->GetObjectArrayElement(propertiesClipsArray, i);
1819 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1820 (M4OSA_NULL == properties),
1821 "not initialized");
1822 if (needToBeLoaded) {
1823 getClipSetting(pEnv,properties, pContext->pEditSettings->pClipList[i]);
1824 pEnv->DeleteLocalRef(properties);
1825 } else {
1826 pEnv->DeleteLocalRef(properties);
1827 goto videoEditor_populateSettings_cleanup;
1828 }
1829 }
1830
1831 if (needToBeLoaded) {
1832 // Log the edit settings.
1833 VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings);
1834 }
1835 }
1836 /* free previous allocations , if any */
1837 if (pContext->mAudioSettings != M4OSA_NULL) {
1838 if (pContext->mAudioSettings->pFile != NULL) {
1839 free(pContext->mAudioSettings->pFile);
1840 pContext->mAudioSettings->pFile = M4OSA_NULL;
1841 }
1842 if (pContext->mAudioSettings->pPCMFilePath != NULL) {
1843 free(pContext->mAudioSettings->pPCMFilePath);
1844 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
1845 }
1846 }
1847
1848 if (audioSettingObject != M4OSA_NULL) {
1849 jclass audioSettingClazz = pEnv->FindClass(AUDIO_SETTINGS_CLASS_NAME);
1850 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1851 (M4OSA_NULL == audioSettingClazz),
1852 "not initialized");
1853
1854 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
1855 (M4OSA_NULL == pContext->mAudioSettings),
1856 "not initialized");
1857
1858 if (needToBeLoaded == false) {
1859 goto videoEditor_populateSettings_cleanup;
1860 }
1861
1862 fid = pEnv->GetFieldID(audioSettingClazz,"bRemoveOriginal","Z");
1863 pContext->mAudioSettings->bRemoveOriginal =
1864 pEnv->GetBooleanField(audioSettingObject,fid);
1865 M4OSA_TRACE1_1("bRemoveOriginal = %d",pContext->mAudioSettings->bRemoveOriginal);
1866
1867 fid = pEnv->GetFieldID(audioSettingClazz,"channels","I");
1868 pContext->mAudioSettings->uiNbChannels = pEnv->GetIntField(audioSettingObject,fid);
1869 M4OSA_TRACE1_1("uiNbChannels = %d",pContext->mAudioSettings->uiNbChannels);
1870
1871 fid = pEnv->GetFieldID(audioSettingClazz,"Fs","I");
1872 pContext->mAudioSettings->uiSamplingFrequency = pEnv->GetIntField(audioSettingObject,fid);
1873 M4OSA_TRACE1_1("uiSamplingFrequency = %d",pContext->mAudioSettings->uiSamplingFrequency);
1874
1875 fid = pEnv->GetFieldID(audioSettingClazz,"ExtendedFs","I");
1876 pContext->mAudioSettings->uiExtendedSamplingFrequency =
1877 pEnv->GetIntField(audioSettingObject,fid);
1878 M4OSA_TRACE1_1("uiExtendedSamplingFrequency = %d",
1879 pContext->mAudioSettings->uiExtendedSamplingFrequency);
1880
1881 fid = pEnv->GetFieldID(audioSettingClazz,"startMs","J");
1882 pContext->mAudioSettings->uiAddCts
1883 = pEnv->GetLongField(audioSettingObject,fid);
1884 M4OSA_TRACE1_1("uiAddCts = %d",pContext->mAudioSettings->uiAddCts);
1885
1886 fid = pEnv->GetFieldID(audioSettingClazz,"volume","I");
1887 pContext->mAudioSettings->uiAddVolume
1888 = pEnv->GetIntField(audioSettingObject,fid);
1889 M4OSA_TRACE1_1("uiAddVolume = %d",pContext->mAudioSettings->uiAddVolume);
1890
1891 fid = pEnv->GetFieldID(audioSettingClazz,"loop","Z");
1892 pContext->mAudioSettings->bLoop
1893 = pEnv->GetBooleanField(audioSettingObject,fid);
1894 M4OSA_TRACE1_1("bLoop = %d",pContext->mAudioSettings->bLoop);
1895
1896 fid = pEnv->GetFieldID(audioSettingClazz,"beginCutTime","J");
1897 pContext->mAudioSettings->beginCutMs
1898 = pEnv->GetLongField(audioSettingObject,fid);
1899 M4OSA_TRACE1_1("begin cut time = %d",pContext->mAudioSettings->beginCutMs);
1900
1901 fid = pEnv->GetFieldID(audioSettingClazz,"endCutTime","J");
1902 pContext->mAudioSettings->endCutMs
1903 = pEnv->GetLongField(audioSettingObject,fid);
1904 M4OSA_TRACE1_1("end cut time = %d",pContext->mAudioSettings->endCutMs);
1905
1906 fid = pEnv->GetFieldID(audioSettingClazz,"fileType","I");
1907 pContext->mAudioSettings->fileType
1908 = pEnv->GetIntField(audioSettingObject,fid);
1909 M4OSA_TRACE1_1("fileType = %d",pContext->mAudioSettings->fileType);
1910
1911 fid = pEnv->GetFieldID(audioSettingClazz,"pFile","Ljava/lang/String;");
1912 strPath = (jstring)pEnv->GetObjectField(audioSettingObject,fid);
1913 pTempChar = (M4OSA_Char*)pEnv->GetStringUTFChars(strPath, M4OSA_NULL);
1914 if (pTempChar != NULL) {
1915 pContext->mAudioSettings->pFile = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(
1916 (M4OSA_UInt32)(strlen((const char*)pTempChar))+1 /* +1 for NULL termination */, 0,
1917 (M4OSA_Char*)"strPath allocation " );
1918 if (pContext->mAudioSettings->pFile != M4OSA_NULL) {
1919 memcpy((void *)pContext->mAudioSettings->pFile ,
1920 (void *)pTempChar , strlen((const char*)pTempChar));
1921 ((M4OSA_Int8 *)(pContext->mAudioSettings->pFile))[strlen((const char*)pTempChar)] = '\0';
1922 pEnv->ReleaseStringUTFChars(strPath,(const char *)pTempChar);
1923 } else {
1924 pEnv->ReleaseStringUTFChars(strPath,(const char *)pTempChar);
1925 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
1926 "regenerateAudio() Malloc failed for pContext->mAudioSettings->pFile ");
1927 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1928 M4OSA_TRUE, M4ERR_ALLOC);
1929 goto videoEditor_populateSettings_cleanup;
1930 }
1931 }
1932 M4OSA_TRACE1_1("file name = %s",pContext->mAudioSettings->pFile);
1933 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio() file name = %s",\
1934 pContext->mAudioSettings->pFile);
1935
1936 fid = pEnv->GetFieldID(audioSettingClazz,"pcmFilePath","Ljava/lang/String;");
1937 strPCMPath = (jstring)pEnv->GetObjectField(audioSettingObject,fid);
1938 pTempChar = (M4OSA_Char*)pEnv->GetStringUTFChars(strPCMPath, M4OSA_NULL);
1939 if (pTempChar != NULL) {
1940 pContext->mAudioSettings->pPCMFilePath = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(
1941 (M4OSA_UInt32)(strlen((const char*)pTempChar))+1 /* +1 for NULL termination */, 0,
1942 (M4OSA_Char*)"strPCMPath allocation " );
1943 if (pContext->mAudioSettings->pPCMFilePath != M4OSA_NULL) {
1944 memcpy((void *)pContext->mAudioSettings->pPCMFilePath ,
1945 (void *)pTempChar , strlen((const char*)pTempChar));
1946 ((M4OSA_Int8 *)(pContext->mAudioSettings->pPCMFilePath))[strlen((const char*)pTempChar)] = '\0';
1947 pEnv->ReleaseStringUTFChars(strPCMPath,(const char *)pTempChar);
1948 } else {
1949 pEnv->ReleaseStringUTFChars(strPCMPath,(const char *)pTempChar);
1950 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
1951 "regenerateAudio() Malloc failed for pContext->mAudioSettings->pPCMFilePath ");
1952 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1953 M4OSA_TRUE, M4ERR_ALLOC);
1954 goto videoEditor_populateSettings_cleanup;
1955 }
1956 }
1957 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "pPCMFilePath -- %s ",\
1958 pContext->mAudioSettings->pPCMFilePath);
1959
1960 fid = pEnv->GetFieldID(engineClass,"mRegenerateAudio","Z");
1961 bool regenerateAudio = pEnv->GetBooleanField(thiz,fid);
1962
1963 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio -- %d ",\
1964 regenerateAudio);
1965
1966 if (regenerateAudio) {
1967 M4OSA_TRACE1_0("Calling Generate Audio now");
1968 result = videoEditor_generateAudio(pEnv,
1969 pContext,
1970 (M4OSA_Char*)pContext->mAudioSettings->pFile,
1971 (M4OSA_Char*)pContext->mAudioSettings->pPCMFilePath);
1972
1973 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
1974 (M4NO_ERROR != result), result);
1975 if (needToBeLoaded == false) {
1976 goto videoEditor_populateSettings_cleanup;
1977 }
1978
1979 regenerateAudio = false;
1980 pEnv->SetBooleanField(thiz,fid,regenerateAudio);
1981 }
1982
1983 /* Audio mix and duck */
1984 fid = pEnv->GetFieldID(audioSettingClazz,"ducking_threshold","I");
1985 pContext->mAudioSettings->uiInDucking_threshold
1986 = pEnv->GetIntField(audioSettingObject,fid);
1987
1988 M4OSA_TRACE1_1("ducking threshold = %d",
1989 pContext->mAudioSettings->uiInDucking_threshold);
1990
1991 fid = pEnv->GetFieldID(audioSettingClazz,"ducking_lowVolume","I");
1992 pContext->mAudioSettings->uiInDucking_lowVolume
1993 = pEnv->GetIntField(audioSettingObject,fid);
1994
1995 M4OSA_TRACE1_1("ducking lowVolume = %d",
1996 pContext->mAudioSettings->uiInDucking_lowVolume);
1997
1998 fid = pEnv->GetFieldID(audioSettingClazz,"bInDucking_enable","Z");
1999 pContext->mAudioSettings->bInDucking_enable
2000 = pEnv->GetBooleanField(audioSettingObject,fid);
2001 M4OSA_TRACE1_1("ducking lowVolume = %d",
2002 pContext->mAudioSettings->bInDucking_enable);
2003
2004 } else {
2005 if (pContext->mAudioSettings != M4OSA_NULL) {
2006 pContext->mAudioSettings->pFile = M4OSA_NULL;
2007 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
2008 pContext->mAudioSettings->bRemoveOriginal = 0;
2009 pContext->mAudioSettings->uiNbChannels = 0;
2010 pContext->mAudioSettings->uiSamplingFrequency = 0;
2011 pContext->mAudioSettings->uiExtendedSamplingFrequency = 0;
2012 pContext->mAudioSettings->uiAddCts = 0;
2013 pContext->mAudioSettings->uiAddVolume = 0;
2014 pContext->mAudioSettings->beginCutMs = 0;
2015 pContext->mAudioSettings->endCutMs = 0;
2016 pContext->mAudioSettings->fileType = 0;
2017 pContext->mAudioSettings->bLoop = 0;
2018 pContext->mAudioSettings->uiInDucking_lowVolume = 0;
2019 pContext->mAudioSettings->bInDucking_enable = 0;
2020 pContext->mAudioSettings->uiBTChannelCount = 0;
2021 pContext->mAudioSettings->uiInDucking_threshold = 0;
2022
2023 fid = pEnv->GetFieldID(engineClass,"mRegenerateAudio","Z");
2024 bool regenerateAudio = pEnv->GetBooleanField(thiz,fid);
2025 if (!regenerateAudio) {
2026 regenerateAudio = true;
2027 pEnv->SetBooleanField(thiz,fid,regenerateAudio);
2028 }
2029 }
2030 }
2031
2032 if (pContext->pEditSettings != NULL)
2033 {
2034 result = pContext->mPreviewController->loadEditSettings(pContext->pEditSettings,
2035 pContext->mAudioSettings);
2036 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
2037 (M4NO_ERROR != result), result);
2038
2039 if (needToBeLoaded) {
2040 pContext->mPreviewController->setJniCallback((void*)pContext,
2041 (jni_progress_callback_fct)jniPreviewProgressCallback);
2042 }
2043 }
2044
2045 videoEditor_populateSettings_cleanup:
2046 j = 0;
2047 while (j < nbOverlays)
2048 {
2049 if (pContext->pEditSettings->Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data != \
2050 M4OSA_NULL) {
2051 free(pContext->pEditSettings->\
2052 Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data);
2053 pContext->pEditSettings->\
2054 Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data = M4OSA_NULL;
2055 }
2056 j++;
2057 }
2058
2059 j = 0;
2060 while (j < pContext->pEditSettings->nbEffects)
2061 {
2062 if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL) {
2063 if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer != M4OSA_NULL) {
2064 free(pContext->pEditSettings->\
2065 Effects[j].xVSS.pFramingBuffer);
2066 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer = M4OSA_NULL;
2067 }
2068 }
2069 j++;
2070 }
2071
2072 if (pOverlayIndex != M4OSA_NULL)
2073 {
2074 free(pOverlayIndex);
2075 pOverlayIndex = M4OSA_NULL;
2076 }
2077 return;
2078 }
2079
2080 static void
videoEditor_startPreview(JNIEnv * pEnv,jobject thiz,jobject mSurface,jlong fromMs,jlong toMs,jint callbackInterval,jboolean loop)2081 videoEditor_startPreview(
2082 JNIEnv* pEnv,
2083 jobject thiz,
2084 jobject mSurface,
2085 jlong fromMs,
2086 jlong toMs,
2087 jint callbackInterval,
2088 jboolean loop)
2089 {
2090 bool needToBeLoaded = true;
2091 M4OSA_ERR result = M4NO_ERROR;
2092 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_startPreview()");
2093
2094 ManualEditContext* pContext = M4OSA_NULL;
2095 // Get the context.
2096 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
2097
2098 // Make sure that the context was set.
2099 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
2100 (M4OSA_NULL == pContext),
2101 "not initialized");
2102
2103 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
2104 (M4OSA_NULL == pContext->mAudioSettings),
2105 "not initialized");
2106 // Make sure that the context was set.
2107 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
2108 (M4OSA_NULL == pContext->mPreviewController),
2109 "not initialized");
2110
2111 // Validate the mSurface parameter.
2112 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
2113 (NULL == mSurface),
2114 "mSurface is null");
2115
2116 sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface);
2117
2118 // Validate the mSurface's mNativeSurface field
2119 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
2120 (NULL == previewSurface.get()),
2121 "mNativeSurface is null");
2122
2123 result = pContext->mPreviewController->setSurface(previewSurface);
2124 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
2125 (M4NO_ERROR != result), result);
2126 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "fromMs=%ld, toMs=%ld",
2127 (M4OSA_UInt32)fromMs, (M4OSA_Int32)toMs);
2128
2129 result = pContext->mPreviewController->startPreview((M4OSA_UInt32)fromMs,
2130 (M4OSA_Int32)toMs,
2131 (M4OSA_UInt16)callbackInterval,
2132 (M4OSA_Bool)loop);
2133 videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, (M4NO_ERROR != result), result);
2134 }
2135
2136
2137 static jobject
videoEditor_getProperties(JNIEnv * pEnv,jobject thiz,jstring file)2138 videoEditor_getProperties(
2139 JNIEnv* pEnv,
2140 jobject thiz,
2141 jstring file)
2142 {
2143 jobject object = M4OSA_NULL;
2144 jclass clazz = pEnv->FindClass(PROPERTIES_CLASS_NAME);
2145 jfieldID fid;
2146 bool needToBeLoaded = true;
2147 ManualEditContext* pContext = M4OSA_NULL;
2148 M4OSA_ERR result = M4NO_ERROR;
2149 int profile = 0;
2150 int level = 0;
2151 int videoFormat = 0;
2152
2153 // Get the context.
2154 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
2155
2156 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
2157 (M4OSA_NULL == clazz),
2158 "not initialized");
2159
2160 object = videoEditProp_getProperties(pEnv,thiz,file);
2161
2162 if (object != M4OSA_NULL) {
2163 fid = pEnv->GetFieldID(clazz,"profile","I");
2164 profile = pEnv->GetIntField(object,fid);
2165 fid = pEnv->GetFieldID(clazz,"level","I");
2166 level = pEnv->GetIntField(object,fid);
2167 fid = pEnv->GetFieldID(clazz,"videoFormat","I");
2168 videoFormat = pEnv->GetIntField(object,fid);
2169
2170 result = checkClipVideoProfileAndLevel(pContext->decoders, videoFormat, profile, level);
2171
2172 fid = pEnv->GetFieldID(clazz,"profileSupported","Z");
2173 if (M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE == result) {
2174 pEnv->SetBooleanField(object,fid,false);
2175 }
2176
2177 fid = pEnv->GetFieldID(clazz,"levelSupported","Z");
2178 if (M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_LEVEL == result) {
2179 pEnv->SetBooleanField(object,fid,false);
2180 }
2181 }
2182 return object;
2183
2184 }
videoEditor_getPixels(JNIEnv * env,jobject thiz,jstring path,jintArray pixelArray,M4OSA_UInt32 width,M4OSA_UInt32 height,M4OSA_UInt32 timeMS)2185 static int videoEditor_getPixels(
2186 JNIEnv* env,
2187 jobject thiz,
2188 jstring path,
2189 jintArray pixelArray,
2190 M4OSA_UInt32 width,
2191 M4OSA_UInt32 height,
2192 M4OSA_UInt32 timeMS)
2193 {
2194
2195 M4OSA_ERR err = M4NO_ERROR;
2196 M4OSA_Context mContext = M4OSA_NULL;
2197 jint* m_dst32 = M4OSA_NULL;
2198
2199
2200 // Add a text marker (the condition must always be true).
2201 ADD_TEXT_MARKER_FUN(NULL != env)
2202
2203 const char *pString = env->GetStringUTFChars(path, NULL);
2204 if (pString == M4OSA_NULL) {
2205 if (env != NULL) {
2206 jniThrowException(env, "java/lang/RuntimeException", "Input string null");
2207 }
2208 return M4ERR_ALLOC;
2209 }
2210
2211 err = ThumbnailOpen(&mContext,(const M4OSA_Char*)pString, M4OSA_FALSE);
2212 if (err != M4NO_ERROR || mContext == M4OSA_NULL) {
2213 if (pString != NULL) {
2214 env->ReleaseStringUTFChars(path, pString);
2215 }
2216 if (env != NULL) {
2217 jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed");
2218 }
2219 }
2220
2221 m_dst32 = env->GetIntArrayElements(pixelArray, NULL);
2222
2223 err = ThumbnailGetPixels32(mContext, (M4OSA_Int32 *)m_dst32, width,height,&timeMS,0);
2224 if (err != M4NO_ERROR ) {
2225 if (env != NULL) {
2226 jniThrowException(env, "java/lang/RuntimeException",\
2227 "ThumbnailGetPixels32 failed");
2228 }
2229 }
2230 env->ReleaseIntArrayElements(pixelArray, m_dst32, 0);
2231
2232 ThumbnailClose(mContext);
2233 if (pString != NULL) {
2234 env->ReleaseStringUTFChars(path, pString);
2235 }
2236
2237 return timeMS;
2238 }
2239
videoEditor_getPixelsList(JNIEnv * env,jobject thiz,jstring path,jintArray pixelArray,M4OSA_UInt32 width,M4OSA_UInt32 height,M4OSA_UInt32 noOfThumbnails,jlong startTime,jlong endTime,jintArray indexArray,jobject callback)2240 static int videoEditor_getPixelsList(
2241 JNIEnv* env,
2242 jobject thiz,
2243 jstring path,
2244 jintArray pixelArray,
2245 M4OSA_UInt32 width,
2246 M4OSA_UInt32 height,
2247 M4OSA_UInt32 noOfThumbnails,
2248 jlong startTime,
2249 jlong endTime,
2250 jintArray indexArray,
2251 jobject callback)
2252 {
2253
2254 M4OSA_ERR err = M4NO_ERROR;
2255 M4OSA_Context mContext = M4OSA_NULL;
2256
2257 const char *pString = env->GetStringUTFChars(path, NULL);
2258 if (pString == M4OSA_NULL) {
2259 jniThrowException(env, "java/lang/RuntimeException", "Input string null");
2260 return M4ERR_ALLOC;
2261 }
2262
2263 err = ThumbnailOpen(&mContext,(const M4OSA_Char*)pString, M4OSA_FALSE);
2264 if (err != M4NO_ERROR || mContext == M4OSA_NULL) {
2265 jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed");
2266 if (pString != NULL) {
2267 env->ReleaseStringUTFChars(path, pString);
2268 }
2269 return err;
2270 }
2271
2272 jlong duration = (endTime - startTime);
2273 M4OSA_UInt32 tolerance = duration / (2 * noOfThumbnails);
2274 jint* m_dst32 = env->GetIntArrayElements(pixelArray, NULL);
2275 jint* indices = env->GetIntArrayElements(indexArray, NULL);
2276 jsize len = env->GetArrayLength(indexArray);
2277
2278 jclass cls = env->GetObjectClass(callback);
2279 jmethodID mid = env->GetMethodID(cls, "onThumbnail", "(I)V");
2280
2281 for (int i = 0; i < len; i++) {
2282 int k = indices[i];
2283 M4OSA_UInt32 timeMS = startTime;
2284 timeMS += (2 * k + 1) * duration / (2 * noOfThumbnails);
2285 err = ThumbnailGetPixels32(mContext, ((M4OSA_Int32 *)m_dst32),
2286 width, height, &timeMS, tolerance);
2287 if (err != M4NO_ERROR) {
2288 break;
2289 }
2290 env->CallVoidMethod(callback, mid, (jint)k);
2291 if (env->ExceptionCheck()) {
2292 err = M4ERR_ALLOC;
2293 break;
2294 }
2295 }
2296
2297 env->ReleaseIntArrayElements(pixelArray, m_dst32, 0);
2298 env->ReleaseIntArrayElements(indexArray, indices, 0);
2299
2300 ThumbnailClose(mContext);
2301 if (pString != NULL) {
2302 env->ReleaseStringUTFChars(path, pString);
2303 }
2304
2305 if (err != M4NO_ERROR && !env->ExceptionCheck()) {
2306 jniThrowException(env, "java/lang/RuntimeException",\
2307 "ThumbnailGetPixels32 failed");
2308 }
2309
2310 return err;
2311 }
2312
2313 static M4OSA_ERR
videoEditor_toUTF8Fct(M4OSA_Void * pBufferIn,M4OSA_UInt8 * pBufferOut,M4OSA_UInt32 * bufferOutSize)2314 videoEditor_toUTF8Fct(
2315 M4OSA_Void* pBufferIn,
2316 M4OSA_UInt8* pBufferOut,
2317 M4OSA_UInt32* bufferOutSize)
2318 {
2319 M4OSA_ERR result = M4NO_ERROR;
2320 M4OSA_UInt32 length = 0;
2321
2322 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_toUTF8Fct()");
2323
2324 // Determine the length of the input buffer.
2325 if (M4OSA_NULL != pBufferIn)
2326 {
2327 length = strlen((const char *)pBufferIn);
2328 }
2329
2330 // Check if the output buffer is large enough to hold the input buffer.
2331 if ((*bufferOutSize) > length)
2332 {
2333 // Check if the input buffer is not M4OSA_NULL.
2334 if (M4OSA_NULL != pBufferIn)
2335 {
2336 // Copy the temp path, ignore the result.
2337 M4OSA_chrNCopy((M4OSA_Char *)pBufferOut, (M4OSA_Char *)pBufferIn, length);
2338 }
2339 else
2340 {
2341 // Set the output buffer to an empty string.
2342 (*(M4OSA_Char *)pBufferOut) = 0;
2343 }
2344 }
2345 else
2346 {
2347 // The buffer is too small.
2348 result = M4xVSSWAR_BUFFER_OUT_TOO_SMALL;
2349 }
2350
2351 // Return the buffer output size.
2352 (*bufferOutSize) = length + 1;
2353
2354 // Return the result.
2355 return(result);
2356 }
2357
2358 static M4OSA_ERR
videoEditor_fromUTF8Fct(M4OSA_UInt8 * pBufferIn,M4OSA_Void * pBufferOut,M4OSA_UInt32 * bufferOutSize)2359 videoEditor_fromUTF8Fct(
2360 M4OSA_UInt8* pBufferIn,
2361 M4OSA_Void* pBufferOut,
2362 M4OSA_UInt32* bufferOutSize)
2363 {
2364 M4OSA_ERR result = M4NO_ERROR;
2365 M4OSA_UInt32 length = 0;
2366
2367 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_fromUTF8Fct()");
2368
2369 // Determine the length of the input buffer.
2370 if (M4OSA_NULL != pBufferIn)
2371 {
2372 length = strlen((const char *)pBufferIn);
2373 }
2374
2375 // Check if the output buffer is large enough to hold the input buffer.
2376 if ((*bufferOutSize) > length)
2377 {
2378 // Check if the input buffer is not M4OSA_NULL.
2379 if (M4OSA_NULL != pBufferIn)
2380 {
2381 // Copy the temp path, ignore the result.
2382 M4OSA_chrNCopy((M4OSA_Char *)pBufferOut, (M4OSA_Char *)pBufferIn, length);
2383 }
2384 else
2385 {
2386 // Set the output buffer to an empty string.
2387 (*(M4OSA_Char *)pBufferOut) = 0;
2388 }
2389 }
2390 else
2391 {
2392 // The buffer is too small.
2393 result = M4xVSSWAR_BUFFER_OUT_TOO_SMALL;
2394 }
2395
2396 // Return the buffer output size.
2397 (*bufferOutSize) = length + 1;
2398
2399 // Return the result.
2400 return(result);
2401 }
2402
2403 static M4OSA_ERR
videoEditor_getTextRgbBufferFct(M4OSA_Void * pRenderingData,M4OSA_Void * pTextBuffer,M4OSA_UInt32 textBufferSize,M4VIFI_ImagePlane ** pOutputPlane)2404 videoEditor_getTextRgbBufferFct(
2405 M4OSA_Void* pRenderingData,
2406 M4OSA_Void* pTextBuffer,
2407 M4OSA_UInt32 textBufferSize,
2408 M4VIFI_ImagePlane** pOutputPlane)
2409 {
2410 M4OSA_ERR result = M4NO_ERROR;
2411
2412 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getTextRgbBufferFct()");
2413
2414 // Return the result.
2415 return(result);
2416 }
2417
2418 static void
videoEditor_callOnProgressUpdate(ManualEditContext * pContext,int task,int progress)2419 videoEditor_callOnProgressUpdate(
2420 ManualEditContext* pContext,
2421 int task,
2422 int progress)
2423 {
2424 JNIEnv* pEnv = NULL;
2425
2426
2427 // Attach the current thread.
2428 pContext->pVM->AttachCurrentThread(&pEnv, NULL);
2429
2430
2431 // Call the on completion callback.
2432 pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId,
2433 videoEditJava_getEngineCToJava(task), progress);
2434
2435
2436 // Detach the current thread.
2437 pContext->pVM->DetachCurrentThread();
2438 }
2439
2440 static void
videoEditor_freeContext(JNIEnv * pEnv,ManualEditContext ** ppContext)2441 videoEditor_freeContext(
2442 JNIEnv* pEnv,
2443 ManualEditContext** ppContext)
2444 {
2445 ManualEditContext* pContext = M4OSA_NULL;
2446
2447 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_freeContext");
2448
2449 // Set the context pointer.
2450 pContext = (*ppContext);
2451
2452 // Check if the context was set.
2453 if (M4OSA_NULL != pContext)
2454 {
2455 // Check if a global reference to the engine object was set.
2456 if (NULL != pContext->engine)
2457 {
2458 // Free the global reference.
2459 pEnv->DeleteGlobalRef(pContext->engine);
2460 pContext->engine = NULL;
2461 }
2462
2463 // Check if the temp path was set.
2464 if (M4OSA_NULL != pContext->initParams.pTempPath)
2465 {
2466 // Free the memory allocated for the temp path.
2467 videoEditOsal_free(pContext->initParams.pTempPath);
2468 pContext->initParams.pTempPath = M4OSA_NULL;
2469 }
2470
2471 // Check if the file writer was set.
2472 if (M4OSA_NULL != pContext->initParams.pFileWritePtr)
2473 {
2474 // Free the memory allocated for the file writer.
2475 videoEditOsal_free(pContext->initParams.pFileWritePtr);
2476 pContext->initParams.pFileWritePtr = M4OSA_NULL;
2477 }
2478
2479 // Check if the file reader was set.
2480 if (M4OSA_NULL != pContext->initParams.pFileReadPtr)
2481 {
2482 // Free the memory allocated for the file reader.
2483 videoEditOsal_free(pContext->initParams.pFileReadPtr);
2484 pContext->initParams.pFileReadPtr = M4OSA_NULL;
2485 }
2486
2487 // Free the memory allocated for the context.
2488 videoEditOsal_free(pContext);
2489 pContext = M4OSA_NULL;
2490
2491 // Reset the context pointer.
2492 (*ppContext) = M4OSA_NULL;
2493 }
2494 }
2495
2496 static jobject
videoEditor_getVersion(JNIEnv * pEnv,jobject thiz)2497 videoEditor_getVersion(
2498 JNIEnv* pEnv,
2499 jobject thiz)
2500 {
2501 bool isSuccessful = true;
2502 jobject version = NULL;
2503 M4_VersionInfo versionInfo = {0, 0, 0, 0};
2504 M4OSA_ERR result = M4NO_ERROR;
2505
2506 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getVersion()");
2507
2508 versionInfo.m_structSize = sizeof(versionInfo);
2509 versionInfo.m_major = VIDEOEDITOR_VERSION_MAJOR;
2510 versionInfo.m_minor = VIDEOEDITOR_VERSION_MINOR;
2511 versionInfo.m_revision = VIDEOEDITOR_VERSION_REVISION;
2512
2513 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getVersion() major %d,\
2514 minor %d, revision %d", versionInfo.m_major, versionInfo.m_minor, versionInfo.m_revision);
2515
2516 // Create a version object.
2517 videoEditClasses_createVersion(&isSuccessful, pEnv, &versionInfo, &version);
2518
2519 // Return the version object.
2520 return(version);
2521 }
2522
2523 static void
videoEditor_init(JNIEnv * pEnv,jobject thiz,jstring tempPath,jstring libraryPath)2524 videoEditor_init(
2525 JNIEnv* pEnv,
2526 jobject thiz,
2527 jstring tempPath,
2528 jstring libraryPath)
2529 {
2530 bool initialized = true;
2531 ManualEditContext* pContext = M4OSA_NULL;
2532 VideoEditJava_EngineMethodIds methodIds = {NULL};
2533 M4OSA_Char* pLibraryPath = M4OSA_NULL;
2534 M4OSA_Char* pTextRendererPath = M4OSA_NULL;
2535 M4OSA_UInt32 textRendererPathLength = 0;
2536 M4OSA_ERR result = M4NO_ERROR;
2537
2538 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_init()");
2539
2540 // Add a text marker (the condition must always be true).
2541 ADD_TEXT_MARKER_FUN(NULL != pEnv)
2542
2543 // Get the context.
2544 pContext = (ManualEditContext*)videoEditClasses_getContext(&initialized, pEnv, thiz);
2545
2546 // Get the engine method ids.
2547 videoEditJava_getEngineMethodIds(&initialized, pEnv, &methodIds);
2548
2549 // Validate the tempPath parameter.
2550 videoEditJava_checkAndThrowIllegalArgumentException(&initialized, pEnv,
2551 (NULL == tempPath),
2552 "tempPath is null");
2553
2554 // Make sure that the context was not set already.
2555 videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv,
2556 (M4OSA_NULL != pContext),
2557 "already initialized");
2558
2559 // Check if the initialization succeeded (required because of dereferencing of psContext,
2560 // and freeing when initialization fails).
2561 if (initialized)
2562 {
2563 // Allocate a new context.
2564 pContext = new ManualEditContext;
2565
2566 // Check if the initialization succeeded (required because of dereferencing of psContext).
2567 //if (initialized)
2568 if (pContext != NULL)
2569 {
2570 // Set the state to not initialized.
2571 pContext->state = ManualEditState_NOT_INITIALIZED;
2572
2573 // Allocate a file read pointer structure.
2574 pContext->initParams.pFileReadPtr =
2575 (M4OSA_FileReadPointer*)videoEditOsal_alloc(&initialized, pEnv,
2576 sizeof(M4OSA_FileReadPointer), "FileReadPointer");
2577
2578 // Allocate a file write pointer structure.
2579 pContext->initParams.pFileWritePtr =
2580 (M4OSA_FileWriterPointer*)videoEditOsal_alloc(&initialized, pEnv,
2581 sizeof(M4OSA_FileWriterPointer), "FileWriterPointer");
2582
2583 // Get the temp path.
2584 M4OSA_Char* tmpString =
2585 (M4OSA_Char *)videoEditJava_getString(&initialized, pEnv, tempPath,
2586 NULL, M4OSA_NULL);
2587 M4OSA_UInt32 length = strlen((const char *)tmpString);
2588 // Malloc additional 2 bytes for beginning and tail separator.
2589 M4OSA_UInt32 pathLength = length + 2;
2590
2591 pContext->initParams.pTempPath = (M4OSA_Char *)
2592 M4OSA_32bitAlignedMalloc(pathLength, 0x0, (M4OSA_Char *)"tempPath");
2593
2594 //initialize the first char. so that strcat works.
2595 M4OSA_Char *ptmpChar = (M4OSA_Char*)pContext->initParams.pTempPath;
2596 ptmpChar[0] = 0x00;
2597 strncat((char *)pContext->initParams.pTempPath, (const char *)tmpString,
2598 length);
2599 strncat((char *)pContext->initParams.pTempPath, (const char *)"/", (size_t)1);
2600 free(tmpString);
2601 tmpString = NULL;
2602 pContext->mIsUpdateOverlay = false;
2603 pContext->mOverlayFileName = NULL;
2604 pContext->decoders = NULL;
2605 }
2606
2607 // Check if the initialization succeeded
2608 // (required because of dereferencing of pContext, pFileReadPtr and pFileWritePtr).
2609 if (initialized)
2610 {
2611
2612 // Initialize the OSAL file system function pointers.
2613 videoEditOsal_getFilePointers(pContext->initParams.pFileReadPtr ,
2614 pContext->initParams.pFileWritePtr);
2615
2616 // Set the UTF8 conversion functions.
2617 pContext->initParams.pConvToUTF8Fct = videoEditor_toUTF8Fct;
2618 pContext->initParams.pConvFromUTF8Fct = videoEditor_fromUTF8Fct;
2619
2620 // Set the callback method ids.
2621 pContext->onProgressUpdateMethodId = methodIds.onProgressUpdate;
2622
2623 // Set the virtual machine.
2624 pEnv->GetJavaVM(&(pContext->pVM));
2625
2626 // Create a global reference to the engine object.
2627 pContext->engine = pEnv->NewGlobalRef(thiz);
2628
2629 // Check if the global reference could be created.
2630 videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv,
2631 (NULL == pContext->engine), M4NO_ERROR);
2632 }
2633
2634 // Check if the initialization succeeded (required because of dereferencing of pContext).
2635 if (initialized)
2636 {
2637 // Log the API call.
2638 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4xVSS_Init()");
2639
2640 // Initialize the visual studio library.
2641 result = M4xVSS_Init(&pContext->engineContext, &pContext->initParams);
2642
2643 // Log the result.
2644 VIDEOEDIT_LOG_RESULT(ANDROID_LOG_INFO, "VIDEO_EDITOR",
2645 videoEditOsal_getResultString(result));
2646
2647 // Check if the library could be initialized.
2648 videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv,
2649 (M4NO_ERROR != result), result);
2650
2651 // Get platform video decoder capablities.
2652 result = M4xVSS_getVideoDecoderCapabilities(&pContext->decoders);
2653
2654 videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv,
2655 (M4NO_ERROR != result), result);
2656 }
2657
2658 if(initialized)
2659 {
2660 pContext->mPreviewController = new VideoEditorPreviewController();
2661 videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv,
2662 (M4OSA_NULL == pContext->mPreviewController),
2663 "not initialized");
2664 pContext->mAudioSettings =
2665 (M4xVSS_AudioMixingSettings *)
2666 M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_AudioMixingSettings),0x0,
2667 (M4OSA_Char *)"mAudioSettings");
2668 videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv,
2669 (M4OSA_NULL == pContext->mAudioSettings),
2670 "not initialized");
2671 pContext->mAudioSettings->pFile = M4OSA_NULL;
2672 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
2673 pContext->mAudioSettings->bRemoveOriginal = 0;
2674 pContext->mAudioSettings->uiNbChannels = 0;
2675 pContext->mAudioSettings->uiSamplingFrequency = 0;
2676 pContext->mAudioSettings->uiExtendedSamplingFrequency = 0;
2677 pContext->mAudioSettings->uiAddCts = 0;
2678 pContext->mAudioSettings->uiAddVolume = 0;
2679 pContext->mAudioSettings->beginCutMs = 0;
2680 pContext->mAudioSettings->endCutMs = 0;
2681 pContext->mAudioSettings->fileType = 0;
2682 pContext->mAudioSettings->bLoop = 0;
2683 pContext->mAudioSettings->uiInDucking_lowVolume = 0;
2684 pContext->mAudioSettings->bInDucking_enable = 0;
2685 pContext->mAudioSettings->uiBTChannelCount = 0;
2686 pContext->mAudioSettings->uiInDucking_threshold = 0;
2687 }
2688 // Check if the library could be initialized.
2689 if (initialized)
2690 {
2691 // Set the state to initialized.
2692 pContext->state = ManualEditState_INITIALIZED;
2693 }
2694
2695 // Set the context.
2696 videoEditClasses_setContext(&initialized, pEnv, thiz, (void* )pContext);
2697 pLibraryPath = M4OSA_NULL;
2698
2699 pContext->pEditSettings = M4OSA_NULL;
2700 // Cleanup if anything went wrong during initialization.
2701 if (!initialized)
2702 {
2703 // Free the context.
2704 videoEditor_freeContext(pEnv, &pContext);
2705 }
2706 }
2707 }
2708
2709 /*+ PROGRESS CB */
2710 static
videoEditor_processClip(JNIEnv * pEnv,jobject thiz,int unuseditemID)2711 M4OSA_ERR videoEditor_processClip(
2712 JNIEnv* pEnv,
2713 jobject thiz,
2714 int unuseditemID) {
2715
2716 bool loaded = true;
2717 ManualEditContext* pContext = NULL;
2718 M4OSA_UInt8 progress = 0;
2719 M4OSA_UInt8 progressBase = 0;
2720 M4OSA_UInt8 lastProgress = 0;
2721 M4OSA_ERR result = M4NO_ERROR;
2722
2723 // Get the context.
2724 pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz);
2725
2726 // Make sure that the context was set.
2727 videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv,
2728 (M4OSA_NULL == pContext),
2729 "not initialized");
2730
2731 // We start in Analyzing state
2732 pContext->state = ManualEditState_INITIALIZED;
2733 M4OSA_ERR completionResult = M4VSS3GPP_WAR_ANALYZING_DONE;
2734 ManualEditState completionState = ManualEditState_OPENED;
2735 ManualEditState errorState = ManualEditState_ANALYZING_ERROR;
2736
2737 // While analyzing progress goes from 0 to 10 (except Kenburn clip
2738 // generation, which goes from 0 to 50)
2739 progressBase = 0;
2740
2741 // Set the text rendering function.
2742 if (M4OSA_NULL != pContext->pTextRendererFunction)
2743 {
2744 // Use the text renderer function in the library.
2745 pContext->pEditSettings->xVSS.pTextRenderingFct = pContext->pTextRendererFunction;
2746 }
2747 else
2748 {
2749 // Use the internal text renderer function.
2750 pContext->pEditSettings->xVSS.pTextRenderingFct = videoEditor_getTextRgbBufferFct;
2751 }
2752
2753 // Send the command.
2754 ALOGV("videoEditor_processClip ITEM %d Calling M4xVSS_SendCommand()", unuseditemID);
2755 result = M4xVSS_SendCommand(pContext->engineContext, pContext->pEditSettings);
2756 ALOGV("videoEditor_processClip ITEM %d M4xVSS_SendCommand() returned 0x%x",
2757 unuseditemID, (unsigned int) result);
2758
2759 // Remove warnings indications (we only care about errors here)
2760 if ((result == M4VSS3GPP_WAR_TRANSCODING_NECESSARY)
2761 || (result == M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED)) {
2762 result = M4NO_ERROR;
2763 }
2764
2765 // Send the first progress indication (=0)
2766 ALOGV("VERY FIRST PROGRESS videoEditor_processClip ITEM %d Progress indication %d",
2767 unuseditemID, progress);
2768 pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId,
2769 unuseditemID, progress);
2770
2771 // Check if a task is being performed.
2772 // ??? ADD STOPPING MECHANISM
2773 ALOGV("videoEditor_processClip Entering processing loop");
2774 M4OSA_UInt8 prevReportedProgress = 0;
2775 while((result == M4NO_ERROR)
2776 &&(pContext->state!=ManualEditState_SAVED)
2777 &&(pContext->state!=ManualEditState_STOPPING)) {
2778
2779 // Perform the next processing step.
2780 //ALOGV("LVME_processClip Entering M4xVSS_Step()");
2781 result = M4xVSS_Step(pContext->engineContext, &progress);
2782
2783 if (progress != prevReportedProgress) {
2784 prevReportedProgress = progress;
2785 // Log the 1 % .. 100 % progress after processing.
2786 if (M4OSA_TRUE ==
2787 pContext->pEditSettings->pClipList[0]->xVSS.isPanZoom) {
2788 // For KenBurn clip generation, return 0 to 50
2789 // for Analysis phase and 50 to 100 for Saving phase
2790 progress = progressBase + progress/2;
2791 } else {
2792 // For export/transition clips, 0 to 10 for Analysis phase
2793 // and 10 to 100 for Saving phase
2794 if (ManualEditState_INITIALIZED == pContext->state) {
2795 progress = 0.1*progress;
2796 } else {
2797 progress = progressBase + 0.9*progress;
2798 }
2799 }
2800
2801 if (progress > lastProgress)
2802 {
2803 // Send a progress notification.
2804 ALOGV("videoEditor_processClip ITEM %d Progress indication %d",
2805 unuseditemID, progress);
2806 pEnv->CallVoidMethod(pContext->engine,
2807 pContext->onProgressUpdateMethodId,
2808 unuseditemID, progress);
2809 lastProgress = progress;
2810 }
2811 }
2812
2813 // Check if processing has been completed.
2814 if (result == completionResult)
2815 {
2816 // Set the state to the completions state.
2817 pContext->state = completionState;
2818 ALOGV("videoEditor_processClip ITEM %d STATE changed to %d",
2819 unuseditemID, pContext->state);
2820
2821 // Reset progress indication, as we switch to next state
2822 lastProgress = 0;
2823
2824 // Reset error code, as we start a new round of processing
2825 result = M4NO_ERROR;
2826
2827 // Check if we are analyzing input
2828 if (pContext->state == ManualEditState_OPENED) {
2829 // File is opened, we must start saving it
2830 ALOGV("videoEditor_processClip Calling M4xVSS_SaveStart()");
2831 result = M4xVSS_SaveStart(pContext->engineContext,
2832 (M4OSA_Char*)pContext->pEditSettings->pOutputFile,
2833 (M4OSA_UInt32)pContext->pEditSettings->uiOutputPathSize);
2834 ALOGV("videoEditor_processClip ITEM %d SaveStart() returned 0x%x",
2835 unuseditemID, (unsigned int) result);
2836
2837 // Set the state to saving.
2838 pContext->state = ManualEditState_SAVING;
2839 completionState = ManualEditState_SAVED;
2840 completionResult = M4VSS3GPP_WAR_SAVING_DONE;
2841 errorState = ManualEditState_SAVING_ERROR;
2842
2843 // While saving, progress goes from 10 to 100
2844 // except for Kenburn clip which goes from 50 to 100
2845 if (M4OSA_TRUE ==
2846 pContext->pEditSettings->pClipList[0]->xVSS.isPanZoom) {
2847 progressBase = 50;
2848 } else {
2849 progressBase = 10;
2850 }
2851 }
2852 // Check if we encoding is ongoing
2853 else if (pContext->state == ManualEditState_SAVED) {
2854
2855 // Send a progress notification.
2856 progress = 100;
2857 ALOGV("videoEditor_processClip ITEM %d Last progress indication %d",
2858 unuseditemID, progress);
2859 pEnv->CallVoidMethod(pContext->engine,
2860 pContext->onProgressUpdateMethodId,
2861 unuseditemID, progress);
2862
2863
2864 // Stop the encoding.
2865 ALOGV("videoEditor_processClip Calling M4xVSS_SaveStop()");
2866 result = M4xVSS_SaveStop(pContext->engineContext);
2867 ALOGV("videoEditor_processClip M4xVSS_SaveStop() returned 0x%x", result);
2868 }
2869 // Other states are unexpected
2870 else {
2871 result = M4ERR_STATE;
2872 ALOGE("videoEditor_processClip ITEM %d State ERROR 0x%x",
2873 unuseditemID, (unsigned int) result);
2874 }
2875 }
2876
2877 // Check if an error occurred.
2878 if (result != M4NO_ERROR)
2879 {
2880 // Set the state to the error state.
2881 pContext->state = errorState;
2882
2883 // Log the result.
2884 ALOGE("videoEditor_processClip ITEM %d Processing ERROR 0x%x",
2885 unuseditemID, (unsigned int) result);
2886 }
2887 }
2888
2889 // Return the error result
2890 ALOGE("videoEditor_processClip ITEM %d END 0x%x", unuseditemID, (unsigned int) result);
2891 return result;
2892 }
2893 /*+ PROGRESS CB */
2894
2895 static int
videoEditor_generateClip(JNIEnv * pEnv,jobject thiz,jobject settings)2896 videoEditor_generateClip(
2897 JNIEnv* pEnv,
2898 jobject thiz,
2899 jobject settings) {
2900 bool loaded = true;
2901 ManualEditContext* pContext = M4OSA_NULL;
2902 M4OSA_ERR result = M4NO_ERROR;
2903
2904 ALOGV("videoEditor_generateClip START");
2905
2906 // Get the context.
2907 pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz);
2908
2909 Mutex::Autolock autoLock(pContext->mLock);
2910
2911 // Validate the settings parameter.
2912 videoEditJava_checkAndThrowIllegalArgumentException(&loaded, pEnv,
2913 (NULL == settings),
2914 "settings is null");
2915
2916 // Make sure that the context was set.
2917 videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv,
2918 (M4OSA_NULL == pContext),
2919 "not initialized");
2920
2921 // Load the clip settings
2922 ALOGV("videoEditor_generateClip Calling videoEditor_loadSettings");
2923 videoEditor_loadSettings(pEnv, thiz, settings);
2924 ALOGV("videoEditor_generateClip videoEditor_loadSettings returned");
2925
2926 // Generate the clip
2927 ALOGV("videoEditor_generateClip Calling LVME_processClip");
2928 result = videoEditor_processClip(pEnv, thiz, 0 /*item id is unused*/);
2929 ALOGV("videoEditor_generateClip videoEditor_processClip returned 0x%x", result);
2930
2931 if (pContext->state != ManualEditState_INITIALIZED) {
2932 // Free up memory (whatever the result)
2933 videoEditor_unloadSettings(pEnv, thiz);
2934 }
2935
2936 ALOGV("videoEditor_generateClip END 0x%x", (unsigned int) result);
2937 return result;
2938 }
2939
2940 static void
videoEditor_loadSettings(JNIEnv * pEnv,jobject thiz,jobject settings)2941 videoEditor_loadSettings(
2942 JNIEnv* pEnv,
2943 jobject thiz,
2944 jobject settings)
2945 {
2946 bool needToBeLoaded = true;
2947 ManualEditContext* pContext = M4OSA_NULL;
2948
2949 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_loadSettings()");
2950
2951 // Add a code marker (the condition must always be true).
2952 ADD_CODE_MARKER_FUN(NULL != pEnv)
2953
2954 // Get the context.
2955 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded,
2956 pEnv, thiz);
2957
2958 // Validate the settings parameter.
2959 videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
2960 (NULL == settings),
2961 "settings is null");
2962
2963 // Make sure that the context was set.
2964 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
2965 (M4OSA_NULL == pContext),
2966 "not initialized");
2967
2968 // Check if the context is valid (required because the context is dereferenced).
2969 if (needToBeLoaded)
2970 {
2971 // Make sure that we are in a correct state.
2972 videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
2973 (pContext->state != ManualEditState_INITIALIZED),
2974 "settings already loaded");
2975
2976 // Retrieve the edit settings.
2977 if(pContext->pEditSettings != M4OSA_NULL) {
2978 videoEditClasses_freeEditSettings(&pContext->pEditSettings);
2979 pContext->pEditSettings = M4OSA_NULL;
2980 }
2981 videoEditClasses_getEditSettings(&needToBeLoaded, pEnv, settings,
2982 &pContext->pEditSettings,true);
2983 }
2984
2985 // Check if the edit settings could be retrieved.
2986 if (needToBeLoaded)
2987 {
2988 // Log the edit settings.
2989 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "inside load settings");
2990 VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings);
2991 }
2992 ALOGV("videoEditor_loadSettings END");
2993 }
2994
2995
2996
2997 static void
videoEditor_unloadSettings(JNIEnv * pEnv,jobject thiz)2998 videoEditor_unloadSettings(
2999 JNIEnv* pEnv,
3000 jobject thiz)
3001 {
3002 bool needToBeUnLoaded = true;
3003 ManualEditContext* pContext = M4OSA_NULL;
3004 M4OSA_ERR result = M4NO_ERROR;
3005
3006 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_unloadSettings()");
3007
3008 // Get the context.
3009 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeUnLoaded, pEnv, thiz);
3010
3011 // Make sure that the context was set.
3012 videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv,
3013 (M4OSA_NULL == pContext),
3014 "not initialized");
3015
3016 // Check if the context is valid (required because the context is dereferenced).
3017 if (needToBeUnLoaded)
3018 {
3019 ALOGV("videoEditor_unloadSettings state %d", pContext->state);
3020 // Make sure that we are in a correct state.
3021 videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv,
3022 ((pContext->state != ManualEditState_ANALYZING ) &&
3023 (pContext->state != ManualEditState_ANALYZING_ERROR) &&
3024 (pContext->state != ManualEditState_OPENED ) &&
3025 (pContext->state != ManualEditState_SAVING_ERROR ) &&
3026 (pContext->state != ManualEditState_SAVED ) &&
3027 (pContext->state != ManualEditState_STOPPING ) ),
3028 "videoEditor_unloadSettings no load settings in progress");
3029 }
3030
3031 // Check if we are in a correct state.
3032 if (needToBeUnLoaded)
3033 {
3034 // Check if the thread could be stopped.
3035 if (needToBeUnLoaded)
3036 {
3037 // Close the command.
3038 ALOGV("videoEditor_unloadSettings Calling M4xVSS_CloseCommand()");
3039 result = M4xVSS_CloseCommand(pContext->engineContext);
3040 ALOGV("videoEditor_unloadSettings M4xVSS_CloseCommand() returned 0x%x",
3041 (unsigned int)result);
3042
3043 // Check if the command could be closed.
3044 videoEditJava_checkAndThrowRuntimeException(&needToBeUnLoaded, pEnv,
3045 (M4NO_ERROR != result), result);
3046 }
3047
3048 // Check if the command could be closed.
3049 if (needToBeUnLoaded)
3050 {
3051 // Free the edit settings.
3052 //videoEditClasses_freeEditSettings(&pContext->pEditSettings);
3053
3054 // Reset the thread result.
3055 pContext->threadResult = M4NO_ERROR;
3056
3057 // Reset the thread progress.
3058 pContext->threadProgress = 0;
3059
3060 // Set the state to initialized.
3061 pContext->state = ManualEditState_INITIALIZED;
3062 }
3063 }
3064 }
3065
3066 static void
videoEditor_stopEncoding(JNIEnv * pEnv,jobject thiz)3067 videoEditor_stopEncoding(
3068 JNIEnv* pEnv,
3069 jobject thiz)
3070 {
3071 bool stopped = true;
3072 ManualEditContext* pContext = M4OSA_NULL;
3073 M4OSA_ERR result = M4NO_ERROR;
3074
3075 ALOGV("videoEditor_stopEncoding START");
3076
3077 // Get the context.
3078 pContext = (ManualEditContext*)videoEditClasses_getContext(&stopped, pEnv, thiz);
3079
3080 // Change state and get Lock
3081 // This will ensure the generateClip function exits
3082 pContext->state = ManualEditState_STOPPING;
3083 Mutex::Autolock autoLock(pContext->mLock);
3084
3085 // Make sure that the context was set.
3086 videoEditJava_checkAndThrowIllegalStateException(&stopped, pEnv,
3087 (M4OSA_NULL == pContext),
3088 "not initialized");
3089
3090 if (stopped) {
3091
3092 // Check if the command should be closed.
3093 if (pContext->state != ManualEditState_INITIALIZED)
3094 {
3095 // Close the command.
3096 ALOGV("videoEditor_stopEncoding Calling M4xVSS_CloseCommand()");
3097 result = M4xVSS_CloseCommand(pContext->engineContext);
3098 ALOGV("videoEditor_stopEncoding M4xVSS_CloseCommand() returned 0x%x",
3099 (unsigned int)result);
3100 }
3101
3102 // Check if the command could be closed.
3103 videoEditJava_checkAndThrowRuntimeException(&stopped, pEnv,
3104 (M4NO_ERROR != result), result);
3105
3106 // Free the edit settings.
3107 videoEditClasses_freeEditSettings(&pContext->pEditSettings);
3108
3109 // Set the state to initialized.
3110 pContext->state = ManualEditState_INITIALIZED;
3111 }
3112
3113 }
3114
3115 static void
videoEditor_release(JNIEnv * pEnv,jobject thiz)3116 videoEditor_release(
3117 JNIEnv* pEnv,
3118 jobject thiz)
3119 {
3120 bool released = true;
3121 ManualEditContext* pContext = M4OSA_NULL;
3122 M4OSA_ERR result = M4NO_ERROR;
3123
3124 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_release()");
3125
3126 // Add a text marker (the condition must always be true).
3127 ADD_TEXT_MARKER_FUN(NULL != pEnv)
3128
3129 // Get the context.
3130 pContext = (ManualEditContext*)videoEditClasses_getContext(&released, pEnv, thiz);
3131
3132 // If context is not set, return (we consider release already happened)
3133 if (pContext == NULL) {
3134 ALOGV("videoEditor_release Nothing to do, context is aleady NULL");
3135 return;
3136 }
3137
3138
3139 // Check if the context is valid (required because the context is dereferenced).
3140 if (released)
3141 {
3142 if (pContext->state != ManualEditState_INITIALIZED)
3143 {
3144 // Change state and get Lock
3145 // This will ensure the generateClip function exits if it is running
3146 pContext->state = ManualEditState_STOPPING;
3147 Mutex::Autolock autoLock(pContext->mLock);
3148 }
3149
3150 // Reset the context.
3151 videoEditClasses_setContext(&released, pEnv, thiz, (void *)M4OSA_NULL);
3152
3153 // Check if the command should be closed.
3154 if (pContext->state != ManualEditState_INITIALIZED)
3155 {
3156 // Close the command.
3157 ALOGV("videoEditor_release Calling M4xVSS_CloseCommand() state =%d",
3158 pContext->state);
3159 result = M4xVSS_CloseCommand(pContext->engineContext);
3160 ALOGV("videoEditor_release M4xVSS_CloseCommand() returned 0x%x",
3161 (unsigned int)result);
3162
3163 // Check if the command could be closed.
3164 videoEditJava_checkAndThrowRuntimeException(&released, pEnv,
3165 (M4NO_ERROR != result), result);
3166 }
3167
3168 // Cleanup the engine.
3169 ALOGV("videoEditor_release Calling M4xVSS_CleanUp()");
3170 result = M4xVSS_CleanUp(pContext->engineContext);
3171 ALOGV("videoEditor_release M4xVSS_CleanUp() returned 0x%x", (unsigned int)result);
3172
3173 // Check if the cleanup succeeded.
3174 videoEditJava_checkAndThrowRuntimeException(&released, pEnv,
3175 (M4NO_ERROR != result), result);
3176
3177 // Free the edit settings.
3178 videoEditClasses_freeEditSettings(&pContext->pEditSettings);
3179 pContext->pEditSettings = M4OSA_NULL;
3180
3181
3182 if(pContext->mPreviewController != M4OSA_NULL)
3183 {
3184 delete pContext->mPreviewController;
3185 pContext->mPreviewController = M4OSA_NULL;
3186 }
3187
3188 // Free the mAudioSettings context.
3189 if(pContext->mAudioSettings != M4OSA_NULL)
3190 {
3191 if (pContext->mAudioSettings->pFile != NULL) {
3192 free(pContext->mAudioSettings->pFile);
3193 pContext->mAudioSettings->pFile = M4OSA_NULL;
3194 }
3195 if (pContext->mAudioSettings->pPCMFilePath != NULL) {
3196 free(pContext->mAudioSettings->pPCMFilePath);
3197 pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
3198 }
3199
3200 free(pContext->mAudioSettings);
3201 pContext->mAudioSettings = M4OSA_NULL;
3202 }
3203 // Free video Decoders capabilities
3204 if (pContext->decoders != M4OSA_NULL) {
3205 VideoDecoder *pDecoder = NULL;
3206 VideoComponentCapabilities *pComponents = NULL;
3207 int32_t decoderNumber = pContext->decoders->decoderNumber;
3208 if (pContext->decoders->decoder != NULL &&
3209 decoderNumber > 0) {
3210 pDecoder = pContext->decoders->decoder;
3211 for (int32_t k = 0; k < decoderNumber; k++) {
3212 // free each component
3213 ALOGV("decoder index :%d",k);
3214 if (pDecoder != NULL &&
3215 pDecoder->component != NULL &&
3216 pDecoder->componentNumber > 0) {
3217 ALOGV("component number %d",pDecoder->componentNumber);
3218 int32_t componentNumber =
3219 pDecoder->componentNumber;
3220
3221 pComponents = pDecoder->component;
3222 for (int32_t i = 0; i< componentNumber; i++) {
3223 ALOGV("component index :%d",i);
3224 if (pComponents != NULL &&
3225 pComponents->profileLevel != NULL) {
3226 free(pComponents->profileLevel);
3227 pComponents->profileLevel = NULL;
3228 }
3229 pComponents++;
3230 }
3231 free(pDecoder->component);
3232 pDecoder->component = NULL;
3233 }
3234
3235 pDecoder++;
3236 }
3237 free(pContext->decoders->decoder);
3238 pContext->decoders->decoder = NULL;
3239 }
3240 free(pContext->decoders);
3241 pContext->decoders = NULL;
3242 }
3243
3244 videoEditor_freeContext(pEnv, &pContext);
3245 }
3246 }
3247
3248 static int
videoEditor_registerManualEditMethods(JNIEnv * pEnv)3249 videoEditor_registerManualEditMethods(
3250 JNIEnv* pEnv)
3251 {
3252 int result = -1;
3253
3254 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3255 "videoEditor_registerManualEditMethods()");
3256
3257 // Look up the engine class
3258 jclass engineClazz = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME);
3259
3260 // Clear any resulting exceptions.
3261 pEnv->ExceptionClear();
3262
3263 // Check if the engine class was found.
3264 if (NULL != engineClazz)
3265 {
3266 // Register all the methods.
3267 if (pEnv->RegisterNatives(engineClazz, gManualEditMethods,
3268 sizeof(gManualEditMethods) / sizeof(gManualEditMethods[0])) == JNI_OK)
3269 {
3270 // Success.
3271 result = 0;
3272 }
3273 }
3274
3275 // Return the result.
3276 return(result);
3277 }
3278
3279 /*******Audio Graph*******/
3280
getDecibelSound(M4OSA_UInt32 value)3281 static M4OSA_UInt32 getDecibelSound(M4OSA_UInt32 value)
3282 {
3283 int dbSound = 1;
3284
3285 if (value == 0) return 0;
3286
3287 if (value > 0x4000 && value <= 0x8000) // 32768
3288 dbSound = 90;
3289 else if (value > 0x2000 && value <= 0x4000) // 16384
3290 dbSound = 84;
3291 else if (value > 0x1000 && value <= 0x2000) // 8192
3292 dbSound = 78;
3293 else if (value > 0x0800 && value <= 0x1000) // 4028
3294 dbSound = 72;
3295 else if (value > 0x0400 && value <= 0x0800) // 2048
3296 dbSound = 66;
3297 else if (value > 0x0200 && value <= 0x0400) // 1024
3298 dbSound = 60;
3299 else if (value > 0x0100 && value <= 0x0200) // 512
3300 dbSound = 54;
3301 else if (value > 0x0080 && value <= 0x0100) // 256
3302 dbSound = 48;
3303 else if (value > 0x0040 && value <= 0x0080) // 128
3304 dbSound = 42;
3305 else if (value > 0x0020 && value <= 0x0040) // 64
3306 dbSound = 36;
3307 else if (value > 0x0010 && value <= 0x0020) // 32
3308 dbSound = 30;
3309 else if (value > 0x0008 && value <= 0x0010) //16
3310 dbSound = 24;
3311 else if (value > 0x0007 && value <= 0x0008) //8
3312 dbSound = 24;
3313 else if (value > 0x0003 && value <= 0x0007) // 4
3314 dbSound = 18;
3315 else if (value > 0x0001 && value <= 0x0003) //2
3316 dbSound = 12;
3317 else if (value > 0x000 && value == 0x0001) // 1
3318 dbSound = 6;
3319 else
3320 dbSound = 0;
3321
3322 return dbSound;
3323 }
3324
3325 typedef struct
3326 {
3327 M4OSA_UInt8 *m_dataAddress;
3328 M4OSA_UInt32 m_bufferSize;
3329 } M4AM_Buffer;
3330
3331
3332 M4OSA_UInt8 logLookUp[256] = {
3333 0,120,137,146,154,159,163,167,171,173,176,178,181,182,184,186,188,189,190,192,193,
3334 194,195,196,198,199,199,200,201,202,203,204,205,205,206,207,207,208,209,209,210,
3335 211,211,212,212,213,213,214,215,215,216,216,216,217,217,218,218,219,219,220,220,
3336 220,221,221,222,222,222,223,223,223,224,224,224,225,225,225,226,226,226,227,227,
3337 227,228,228,228,229,229,229,229,230,230,230,230,231,231,231,232,232,232,232,233,
3338 233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236,236,237,237,237,
3339 237,237,238,238,238,238,238,239,239,239,239,239,240,240,240,240,240,240,241,241,
3340 241,241,241,241,242,242,242,242,242,242,243,243,243,243,243,243,244,244,244,244,
3341 244,244,245,245,245,245,245,245,245,246,246,246,246,246,246,246,247,247,247,247,
3342 247,247,247,247,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,250,
3343 250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,252,252,252,252,
3344 252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,
3345 254,254,254,254,255,255,255,255,255,255,255,255,255,255,255};
3346
M4MA_generateAudioGraphFile(JNIEnv * pEnv,M4OSA_Char * pInputFileURL,M4OSA_Char * pOutFileURL,M4OSA_UInt32 samplesPerValue,M4OSA_UInt32 channels,M4OSA_UInt32 frameDuration,ManualEditContext * pContext)3347 M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL,
3348 M4OSA_Char* pOutFileURL,
3349 M4OSA_UInt32 samplesPerValue,
3350 M4OSA_UInt32 channels,
3351 M4OSA_UInt32 frameDuration,
3352 ManualEditContext* pContext)
3353 {
3354 M4OSA_ERR err;
3355 M4OSA_Context outFileHandle = M4OSA_NULL;
3356 M4OSA_Context inputFileHandle = M4OSA_NULL;
3357 M4AM_Buffer bufferIn = {0, 0};
3358 M4OSA_UInt32 peakVolumeDbValue = 0;
3359 M4OSA_UInt32 samplesCountInBytes= 0 , numBytesToRead = 0, index = 0;
3360 M4OSA_UInt32 writeCount = 0, samplesCountBigEndian = 0, volumeValuesCount = 0;
3361 M4OSA_Int32 seekPos = 0;
3362 M4OSA_UInt32 fileSize = 0;
3363 M4OSA_UInt32 totalBytesRead = 0;
3364 M4OSA_UInt32 prevProgress = 0;
3365 bool threadStarted = true;
3366
3367 int dbValue = 0;
3368 M4OSA_Int16 *ptr16 ;
3369
3370 jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME);
3371 videoEditJava_checkAndThrowIllegalStateException(&threadStarted, pEnv,
3372 (M4OSA_NULL == engineClass),
3373 "not initialized");
3374
3375 /* register the call back function pointer */
3376 pContext->onAudioGraphProgressUpdateMethodId =
3377 pEnv->GetMethodID(engineClass, "onAudioGraphExtractProgressUpdate", "(IZ)V");
3378
3379
3380 /* ENTER */
3381 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "ENTER - M4MA_generateAudioGraphFile");
3382 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3383 "Audio Graph samplesPerValue %d channels %d", samplesPerValue, channels);
3384
3385 /******************************************************************************
3386 OPEN INPUT AND OUTPUT FILES
3387 *******************************************************************************/
3388 err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead);
3389 if (inputFileHandle == M4OSA_NULL) {
3390 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3391 "M4MA_generateAudioGraphFile: Cannot open input file 0x%lx", err);
3392 return err;
3393 }
3394
3395 /* get the file size for progress */
3396 err = M4OSA_fileReadGetOption(inputFileHandle, M4OSA_kFileReadGetFileSize,
3397 (M4OSA_Void**)&fileSize);
3398 if ( err != M4NO_ERROR) {
3399 //LVMEL_LOG_ERROR("M4MA_generateAudioGraphFile : File write failed \n");
3400 jniThrowException(pEnv, "java/lang/IOException", "file size get option failed");
3401 //return -1;
3402 }
3403
3404 err = M4OSA_fileWriteOpen (&outFileHandle,(M4OSA_Char*) pOutFileURL,
3405 M4OSA_kFileCreate | M4OSA_kFileWrite);
3406 if (outFileHandle == M4OSA_NULL) {
3407 if (inputFileHandle != NULL)
3408 {
3409 M4OSA_fileReadClose(inputFileHandle);
3410 }
3411 return err;
3412 }
3413
3414 /******************************************************************************
3415 PROCESS THE SAMPLES
3416 *******************************************************************************/
3417 samplesCountInBytes = (samplesPerValue * sizeof(M4OSA_UInt16) * channels);
3418
3419 bufferIn.m_dataAddress = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(samplesCountInBytes*sizeof(M4OSA_UInt16), 0,
3420 (M4OSA_Char*)"AudioGraph" );
3421 if ( bufferIn.m_dataAddress != M4OSA_NULL) {
3422 bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16);
3423 } else {
3424 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3425 "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%lx",
3426 M4ERR_ALLOC);
3427 return M4ERR_ALLOC;
3428 }
3429 /* sample to be converted to BIG endian ; store the frame duration */
3430 samplesCountBigEndian = ((frameDuration>>24)&0xff) | // move byte 3 to byte 0
3431 ((frameDuration<<8)&0xff0000) | // move byte 1 to byte 2
3432 ((frameDuration>>8)&0xff00) | // move byte 2 to byte 1
3433 ((frameDuration<<24)&0xff000000); // byte 0 to byte 3
3434
3435 /* write the samples per value supplied to out file */
3436 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian,
3437 sizeof(M4OSA_UInt32) );
3438 if (err != M4NO_ERROR) {
3439 jniThrowException(pEnv, "java/lang/IOException", "file write failed");
3440 }
3441
3442
3443 /* write UIn32 value 0 for no of values as place holder */
3444 samplesCountBigEndian = 0; /* reusing local var */
3445 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian,
3446 sizeof(M4OSA_UInt32) );
3447 if (err != M4NO_ERROR) {
3448 jniThrowException(pEnv, "java/lang/IOException", "file write failed");
3449 }
3450
3451 /* loop until EOF */
3452 do
3453 {
3454 memset((void *)bufferIn.m_dataAddress,0,bufferIn.m_bufferSize);
3455
3456 numBytesToRead = samplesCountInBytes;
3457
3458 err = M4OSA_fileReadData( inputFileHandle,
3459 (M4OSA_MemAddr8)bufferIn.m_dataAddress,
3460 &numBytesToRead );
3461
3462 if (err != M4NO_ERROR) {
3463 // if out value of bytes-read is 0, break
3464 if ( numBytesToRead == 0) {
3465 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%lx",
3466 numBytesToRead);
3467 break; /* stop if file is empty or EOF */
3468 }
3469 }
3470
3471 ptr16 = (M4OSA_Int16*)bufferIn.m_dataAddress;
3472
3473 peakVolumeDbValue = 0;
3474 index = 0;
3475
3476 // loop through half the lenght frame bytes read 'cause its 16 bits samples
3477 while (index < (numBytesToRead / 2)) {
3478 /* absolute values of 16 bit sample */
3479 if (ptr16[index] < 0) {
3480 ptr16[index] = -(ptr16[index]);
3481 }
3482 peakVolumeDbValue = (peakVolumeDbValue > (M4OSA_UInt32)ptr16[index] ?\
3483 peakVolumeDbValue : (M4OSA_UInt32)ptr16[index]);
3484 index++;
3485 }
3486
3487 // move 7 bits , ignore sign bit
3488 dbValue = (peakVolumeDbValue >> 7);
3489 dbValue = logLookUp[(M4OSA_UInt8)dbValue];
3490
3491 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&dbValue, sizeof(M4OSA_UInt8) );
3492 if (err != M4NO_ERROR) {
3493 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3494 "M4MA_generateAudioGraphFile : File write failed");
3495 break;
3496 }
3497
3498 volumeValuesCount ++;
3499 totalBytesRead += numBytesToRead;
3500
3501 if ((((totalBytesRead*100)/fileSize)) != prevProgress) {
3502 if ( (pContext->threadProgress != prevProgress) && (prevProgress != 0 )) {
3503 //pContext->threadProgress = prevProgress;
3504 //onWveformProgressUpdateMethodId(prevProgress, 0);
3505 //LVME_callAudioGraphOnProgressUpdate(pContext, 0, prevProgress);
3506 pEnv->CallVoidMethod(pContext->engine,
3507 pContext->onAudioGraphProgressUpdateMethodId,
3508 prevProgress, 0);
3509 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pContext->threadProgress %d",
3510 prevProgress);
3511 }
3512 }
3513 prevProgress = (((totalBytesRead*100)/fileSize));
3514
3515 } while (numBytesToRead != 0);
3516
3517 VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%lx", volumeValuesCount);
3518
3519 /* if some error occured in fwrite */
3520 if (numBytesToRead != 0) {
3521 //err = -1;
3522 jniThrowException(pEnv, "java/lang/IOException", "numBytesToRead != 0 ; file write failed");
3523 }
3524
3525 /* write the count in place holder after seek */
3526 seekPos = sizeof(M4OSA_UInt32);
3527 err = M4OSA_fileWriteSeek(outFileHandle, M4OSA_kFileSeekBeginning,
3528 &seekPos /* after samples per value */);
3529 if ( err != M4NO_ERROR) {
3530 jniThrowException(pEnv, "java/lang/IOException", "file seek failed");
3531 } else {
3532 volumeValuesCount = ((volumeValuesCount>>24)&0xff) | // move byte 3 to byte 0
3533 ((volumeValuesCount<<8)&0xff0000) | // move byte 1 to byte 2
3534 ((volumeValuesCount>>8)&0xff00) | // move byte 2 to byte 1
3535 ((volumeValuesCount<<24)&0xff000000); // byte 0 to byte 3
3536
3537 err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&volumeValuesCount,
3538 sizeof(M4OSA_UInt32) );
3539 if ( err != M4NO_ERROR) {
3540 jniThrowException(pEnv, "java/lang/IOException", "file write failed");
3541 }
3542 }
3543
3544 /******************************************************************************
3545 CLOSE AND FREE ALLOCATIONS
3546 *******************************************************************************/
3547 free(bufferIn.m_dataAddress);
3548 M4OSA_fileReadClose(inputFileHandle);
3549 M4OSA_fileWriteClose(outFileHandle);
3550 /* final finish callback */
3551 pEnv->CallVoidMethod(pContext->engine, pContext->onAudioGraphProgressUpdateMethodId, 100, 0);
3552
3553 /* EXIT */
3554 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "EXIT - M4MA_generateAudioGraphFile");
3555
3556 return err;
3557 }
3558
videoEditor_generateAudioWaveFormSync(JNIEnv * pEnv,jobject thiz,jstring pcmfilePath,jstring outGraphfilePath,jint frameDuration,jint channels,jint samplesCount)3559 static int videoEditor_generateAudioWaveFormSync (JNIEnv* pEnv, jobject thiz,
3560 jstring pcmfilePath,
3561 jstring outGraphfilePath,
3562 jint frameDuration, jint channels,
3563 jint samplesCount)
3564 {
3565 M4OSA_ERR result = M4NO_ERROR;
3566 ManualEditContext* pContext = M4OSA_NULL;
3567 bool needToBeLoaded = true;
3568 const char *pPCMFilePath, *pStringOutAudioGraphFile;
3569
3570 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3571 "videoEditor_generateAudioWaveFormSync() ");
3572
3573 /* Get the context. */
3574 pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
3575 if (pContext == M4OSA_NULL) {
3576 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3577 "videoEditor_generateAudioWaveFormSync() - pContext is NULL ");
3578 }
3579
3580 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3581 "videoEditor_generateAudioWaveFormSync Retrieving pStringOutAudioGraphFile");
3582
3583 pPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL);
3584 if (pPCMFilePath == M4OSA_NULL) {
3585 jniThrowException(pEnv, "java/lang/RuntimeException",
3586 "Input string PCMFilePath is null");
3587 result = M4ERR_PARAMETER;
3588 goto out;
3589 }
3590
3591 pStringOutAudioGraphFile = pEnv->GetStringUTFChars(outGraphfilePath, NULL);
3592 if (pStringOutAudioGraphFile == M4OSA_NULL) {
3593 jniThrowException(pEnv, "java/lang/RuntimeException",
3594 "Input string outGraphfilePath is null");
3595 result = M4ERR_PARAMETER;
3596 goto out2;
3597 }
3598
3599 VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3600 "videoEditor_generateAudioWaveFormSync Generate the waveform data %s %d %d %d",
3601 pStringOutAudioGraphFile, frameDuration, channels, samplesCount);
3602
3603 /* Generate the waveform */
3604 result = M4MA_generateAudioGraphFile(pEnv, (M4OSA_Char*) pPCMFilePath,
3605 (M4OSA_Char*) pStringOutAudioGraphFile,
3606 (M4OSA_UInt32) samplesCount,
3607 (M4OSA_UInt32) channels,
3608 (M4OSA_UInt32)frameDuration,
3609 pContext);
3610
3611 pEnv->ReleaseStringUTFChars(outGraphfilePath, pStringOutAudioGraphFile);
3612
3613 out2:
3614 if (pPCMFilePath != NULL) {
3615 pEnv->ReleaseStringUTFChars(pcmfilePath, pPCMFilePath);
3616 }
3617
3618 out:
3619 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
3620 "videoEditor_generateAudioWaveFormSync pContext->bSkipState ");
3621
3622 return result;
3623 }
3624
3625 /******** End Audio Graph *******/
JNI_OnLoad(JavaVM * pVm,void * pReserved)3626 jint JNI_OnLoad(
3627 JavaVM* pVm,
3628 void* pReserved)
3629 {
3630 void* pEnv = NULL;
3631 bool needToBeInitialized = true;
3632 jint result = -1;
3633
3634 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "JNI_OnLoad()");
3635
3636 // Add a text marker (the condition must always be true).
3637 ADD_TEXT_MARKER_FUN(NULL != pVm)
3638
3639 // Check the JNI version.
3640 if (pVm->GetEnv(&pEnv, JNI_VERSION_1_4) == JNI_OK)
3641 {
3642 // Add a code marker (the condition must always be true).
3643 ADD_CODE_MARKER_FUN(NULL != pEnv)
3644
3645 // Register the manual edit JNI methods.
3646 if (videoEditor_registerManualEditMethods((JNIEnv*)pEnv) == 0)
3647 {
3648 // Initialize the classes.
3649 videoEditClasses_init(&needToBeInitialized, (JNIEnv*)pEnv);
3650 if (needToBeInitialized)
3651 {
3652 // Success, return valid version number.
3653 result = JNI_VERSION_1_4;
3654 }
3655 }
3656 }
3657
3658 // Return the result.
3659 return(result);
3660 }
3661
3662