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