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