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