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