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