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