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