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