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