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