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