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