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