MediaArtistNativeHelper.java revision 6bcbb3bd095daf2c630454f2ac0c26f48b6edf60
1/*
2 * Copyright (C) 2010 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
17package android.media.videoeditor;
18
19import java.io.File;
20import java.io.IOException;
21import java.math.BigDecimal;
22import java.nio.IntBuffer;
23import java.util.ArrayList;
24import java.util.Iterator;
25import java.util.List;
26import android.graphics.Bitmap;
27import android.media.videoeditor.VideoEditor.ExportProgressListener;
28import android.media.videoeditor.VideoEditor.PreviewProgressListener;
29import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
30import android.util.Log;
31import android.util.Pair;
32import android.view.Surface;
33import android.graphics.Canvas;
34import android.graphics.Paint;
35import android.graphics.Rect;
36
37/**
38 *This class provide Native methods to be used by MediaArtist {@hide}
39 */
40class MediaArtistNativeHelper {
41
42    static {
43        System.loadLibrary("videoeditor_jni");
44    }
45
46    private final int MAX_THUMBNAIL_PERMITTED = 8;
47
48    private final VideoEditor mVideoEditor;
49
50    public EditSettings mStoryBoardSettings;
51
52    private String mOutputFilename;
53
54    EditSettings mEditSettings = null;
55
56    PreviewClipProperties mClipProperties = null;
57
58    private EditSettings mPreviewEditSettings;
59
60    private AudioSettings mAudioSettings = null;
61
62    private AudioTrack mAudioTrack = null;
63
64    public boolean mInvalidatePreviewArray = true;
65
66    private boolean mRegenerateAudio = true;
67
68    private String mExportFilename = null;
69
70    private boolean mExportDone = false;
71
72    private int mProgressToApp;
73    /**
74     *  The resize paint
75     */
76    private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
77
78    public static final int TASK_LOADING_SETTINGS = 1;
79
80    public static final int TASK_ENCODING = 2;
81
82    private static final String AUDIO_TRACK_PCM_FILE = "AudioPcm.pcm";
83
84    // Processing indication
85    public static final int PROCESSING_NONE          = 0;
86    public static final int PROCESSING_AUDIO_PCM     = 1;
87    public static final int PROCESSING_TRANSITION    = 2;
88    public static final int PROCESSING_KENBURNS      = 3;
89    public static final int PROCESSING_INTERMEDIATE1 = 11;
90    public static final int PROCESSING_INTERMEDIATE2 = 12;
91    public static final int PROCESSING_INTERMEDIATE3 = 13;
92    public static final int PROCESSING_EXPORT        = 20;
93
94    private int    mProcessingState;
95    private Object mProcessingObject;
96
97    private PreviewProgressListener mPreviewProgressListener;
98    private ExportProgressListener mExportProgressListener;
99    private ExtractAudioWaveformProgressListener mExtractAudioWaveformProgressListener;
100    private MediaProcessingProgressListener      mMediaProcessingProgressListener;
101    private final String mProjectPath;
102
103    private long mPreviewProgress;
104
105    private String mAudioTrackPCMFilePath;
106
107    int mTotalClips = 0;
108
109    int mPreviewEffectsSize = 0;
110
111    private boolean mErrorFlagSet = false;
112
113    @SuppressWarnings("unused")
114    private int mManualEditContext;
115
116
117    List<Effect> mMediaEffectList;
118
119    List<Overlay> mMediaOverLayList;
120
121    /* Listeners */
122
123    /**
124     * Interface definition for a listener to be invoked when there is an update
125     * in a running task.
126     */
127    public interface OnProgressUpdateListener {
128        /**
129         * Called when there is an update.
130         *
131         * @param taskId id of the task reporting an update.
132         * @param progress progress of the task [0..100].
133         * @see BasicEdit#TASK_ENCODING
134         */
135        public void OnProgressUpdate(int taskId, int progress);
136    }
137
138    /** Defines the version. */
139    public final class Version {
140
141        /** Major version number */
142        public int major;
143
144        /** Minor version number */
145        public int minor;
146
147        /** Revision number */
148        public int revision;
149
150        /** VIDEOEDITOR major version number */
151        private static final int VIDEOEDITOR_MAJOR_VERSION = 0;
152
153        /** VIDEOEDITOR minor version number */
154        private static final int VIDEOEDITOR_MINOR_VERSION = 0;
155
156        /** VIDEOEDITOR revision number */
157        private static final int VIDEOEDITOR_REVISION_VERSION = 1;
158
159        /** Method which returns the current VIDEOEDITOR version */
160        public Version getVersion() {
161            Version version = new Version();
162
163            version.major = Version.VIDEOEDITOR_MAJOR_VERSION;
164            version.minor = Version.VIDEOEDITOR_MINOR_VERSION;
165            version.revision = Version.VIDEOEDITOR_REVISION_VERSION;
166
167            return version;
168        }
169    }
170
171    /**
172     * Defines output audio formats.
173     */
174    public final class AudioFormat {
175        /** No audio present in output clip. Used to generate video only clip */
176        public static final int NO_AUDIO = 0;
177
178        /** AMR Narrow Band. */
179        public static final int AMR_NB = 1;
180
181        /** Advanced Audio Coding (AAC). */
182        public static final int AAC = 2;
183
184        /** Advanced Audio Codec Plus (HE-AAC v1). */
185        public static final int AAC_PLUS = 3;
186
187        /** Advanced Audio Codec Plus (HE-AAC v2). */
188        public static final int ENHANCED_AAC_PLUS = 4;
189
190        /** MPEG layer 3 (MP3). */
191        public static final int MP3 = 5;
192
193        /** Enhanced Variable RateCodec (EVRC). */
194        public static final int EVRC = 6;
195
196        /** PCM (PCM). */
197        public static final int PCM = 7;
198
199        /** No transcoding. Output audio format is same as input audio format */
200        public static final int NULL_AUDIO = 254;
201
202        /** Unsupported audio format. */
203        public static final int UNSUPPORTED_AUDIO = 255;
204    }
205
206    /**
207     * Defines audio sampling frequencies.
208     */
209    public final class AudioSamplingFrequency {
210        /**
211         * Default sampling frequency. Uses the default frequency for a specific
212         * audio format. For AAC the only supported (and thus default) sampling
213         * frequency is 16 kHz. For this audio format the sampling frequency in
214         * the OutputParams.
215         **/
216        public static final int FREQ_DEFAULT = 0;
217
218        /** Audio sampling frequency of 8000 Hz. */
219        public static final int FREQ_8000 = 8000;
220
221        /** Audio sampling frequency of 11025 Hz. */
222        public static final int FREQ_11025 = 11025;
223
224        /** Audio sampling frequency of 12000 Hz. */
225        public static final int FREQ_12000 = 12000;
226
227        /** Audio sampling frequency of 16000 Hz. */
228        public static final int FREQ_16000 = 16000;
229
230        /** Audio sampling frequency of 22050 Hz. */
231        public static final int FREQ_22050 = 22050;
232
233        /** Audio sampling frequency of 24000 Hz. */
234        public static final int FREQ_24000 = 24000;
235
236        /** Audio sampling frequency of 32000 Hz. */
237        public static final int FREQ_32000 = 32000;
238
239        /** Audio sampling frequency of 44100 Hz. */
240        public static final int FREQ_44100 = 44100;
241
242        /** Audio sampling frequency of 48000 Hz. Not available for output file. */
243        public static final int FREQ_48000 = 48000;
244    }
245
246    /**
247     * Defines the supported fixed audio and video bitrates. These values are
248     * for output audio video only.
249     */
250    public final class Bitrate {
251        /** Variable bitrate. Means no bitrate regulation */
252        public static final int VARIABLE = -1;
253
254        /** An undefined bitrate. */
255        public static final int UNDEFINED = 0;
256
257        /** A bitrate of 9.2 kbits/s. */
258        public static final int BR_9_2_KBPS = 9200;
259
260        /** A bitrate of 12.2 kbits/s. */
261        public static final int BR_12_2_KBPS = 12200;
262
263        /** A bitrate of 16 kbits/s. */
264        public static final int BR_16_KBPS = 16000;
265
266        /** A bitrate of 24 kbits/s. */
267        public static final int BR_24_KBPS = 24000;
268
269        /** A bitrate of 32 kbits/s. */
270        public static final int BR_32_KBPS = 32000;
271
272        /** A bitrate of 48 kbits/s. */
273        public static final int BR_48_KBPS = 48000;
274
275        /** A bitrate of 64 kbits/s. */
276        public static final int BR_64_KBPS = 64000;
277
278        /** A bitrate of 96 kbits/s. */
279        public static final int BR_96_KBPS = 96000;
280
281        /** A bitrate of 128 kbits/s. */
282        public static final int BR_128_KBPS = 128000;
283
284        /** A bitrate of 192 kbits/s. */
285        public static final int BR_192_KBPS = 192000;
286
287        /** A bitrate of 256 kbits/s. */
288        public static final int BR_256_KBPS = 256000;
289
290        /** A bitrate of 288 kbits/s. */
291        public static final int BR_288_KBPS = 288000;
292
293        /** A bitrate of 384 kbits/s. */
294        public static final int BR_384_KBPS = 384000;
295
296        /** A bitrate of 512 kbits/s. */
297        public static final int BR_512_KBPS = 512000;
298
299        /** A bitrate of 800 kbits/s. */
300        public static final int BR_800_KBPS = 800000;
301
302        /** A bitrate of 2 Mbits/s. */
303        public static final int BR_2_MBPS = 2000000;
304
305        /** A bitrate of 5 Mbits/s. */
306        public static final int BR_5_MBPS = 5000000;
307
308        /** A bitrate of 8 Mbits/s. */
309        public static final int BR_8_MBPS = 8000000;
310    }
311
312    /**
313     * Defines all supported file types.
314     */
315    public final class FileType {
316        /** 3GPP file type. */
317        public static final int THREE_GPP = 0;
318
319        /** MP4 file type. */
320        public static final int MP4 = 1;
321
322        /** AMR file type. */
323        public static final int AMR = 2;
324
325        /** MP3 audio file type. */
326        public static final int MP3 = 3;
327
328        /** PCM audio file type. */
329        public static final int PCM = 4;
330
331        /** JPEG image file type. */
332        public static final int JPG = 5;
333
334        /** GIF image file type. */
335        public static final int GIF = 6;
336
337        /** PNG image file type. */
338        public static final int PNG = 7;
339
340        /** Unsupported file type. */
341        public static final int UNSUPPORTED = 255;
342    }
343
344    /**
345     * Defines rendering types. Rendering can only be applied to files
346     * containing video streams.
347     **/
348    public final class MediaRendering {
349        /**
350         * Resize to fit the output video with changing the aspect ratio if
351         * needed.
352         */
353        public static final int RESIZING = 0;
354
355        /**
356         * Crop the input video to fit it with the output video resolution.
357         **/
358        public static final int CROPPING = 1;
359
360        /**
361         * Resize to fit the output video resolution but maintain the aspect
362         * ratio. This framing type adds black borders if needed.
363         */
364        public static final int BLACK_BORDERS = 2;
365    }
366
367    /**
368     * Defines the results.
369     */
370    public final class Result {
371        /** No error. result OK */
372        public static final int NO_ERROR = 0;
373
374        /** File not found */
375        public static final int ERR_FILE_NOT_FOUND = 1;
376
377        /**
378         * In case of UTF8 conversion, the size of the converted path will be
379         * more than the corresponding allocated buffer.
380         */
381        public static final int ERR_BUFFER_OUT_TOO_SMALL = 2;
382
383        /** Invalid file type. */
384        public static final int ERR_INVALID_FILE_TYPE = 3;
385
386        /** Invalid effect kind. */
387        public static final int ERR_INVALID_EFFECT_KIND = 4;
388
389        /** Invalid video effect. */
390        public static final int ERR_INVALID_VIDEO_EFFECT_TYPE = 5;
391
392        /** Invalid audio effect. */
393        public static final int ERR_INVALID_AUDIO_EFFECT_TYPE = 6;
394
395        /** Invalid video transition. */
396        public static final int ERR_INVALID_VIDEO_TRANSITION_TYPE = 7;
397
398        /** Invalid audio transition. */
399        public static final int ERR_INVALID_AUDIO_TRANSITION_TYPE = 8;
400
401        /** Invalid encoding frame rate. */
402        public static final int ERR_INVALID_VIDEO_ENCODING_FRAME_RATE = 9;
403
404        /** External effect is called but this function is not set. */
405        public static final int ERR_EXTERNAL_EFFECT_NULL = 10;
406
407        /** External transition is called but this function is not set. */
408        public static final int ERR_EXTERNAL_TRANSITION_NULL = 11;
409
410        /** Begin time cut is larger than the video clip duration. */
411        public static final int ERR_BEGIN_CUT_LARGER_THAN_DURATION = 12;
412
413        /** Begin cut time is larger or equal than end cut. */
414        public static final int ERR_BEGIN_CUT_LARGER_THAN_END_CUT = 13;
415
416        /** Two consecutive transitions are overlapping on one clip. */
417        public static final int ERR_OVERLAPPING_TRANSITIONS = 14;
418
419        /** Internal error, type size mismatch. */
420        public static final int ERR_ANALYSIS_DATA_SIZE_TOO_SMALL = 15;
421
422        /** An input 3GPP file is invalid/corrupted. */
423        public static final int ERR_INVALID_3GPP_FILE = 16;
424
425        /** A file contains an unsupported video format. */
426        public static final int ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT = 17;
427
428        /** A file contains an unsupported audio format. */
429        public static final int ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT = 18;
430
431        /** A file format is not supported. */
432        public static final int ERR_AMR_EDITING_UNSUPPORTED = 19;
433
434        /** An input clip has an unexpectedly large Video AU. */
435        public static final int ERR_INPUT_VIDEO_AU_TOO_LARGE = 20;
436
437        /** An input clip has an unexpectedly large Audio AU. */
438        public static final int ERR_INPUT_AUDIO_AU_TOO_LARGE = 21;
439
440        /** An input clip has a corrupted Audio AU. */
441        public static final int ERR_INPUT_AUDIO_CORRUPTED_AU = 22;
442
443        /** The video encoder encountered an Access Unit error. */
444        public static final int ERR_ENCODER_ACCES_UNIT_ERROR = 23;
445
446        /** Unsupported video format for Video Editing. */
447        public static final int ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT = 24;
448
449        /** Unsupported H263 profile for Video Editing. */
450        public static final int ERR_EDITING_UNSUPPORTED_H263_PROFILE = 25;
451
452        /** Unsupported MPEG-4 profile for Video Editing. */
453        public static final int ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE = 26;
454
455        /** Unsupported MPEG-4 RVLC tool for Video Editing. */
456        public static final int ERR_EDITING_UNSUPPORTED_MPEG4_RVLC = 27;
457
458        /** Unsupported audio format for Video Editing. */
459        public static final int ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT = 28;
460
461        /** File contains no supported stream. */
462        public static final int ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE = 29;
463
464        /** File contains no video stream or an unsupported video stream. */
465        public static final int ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE = 30;
466
467        /** Internal error, clip analysis version mismatch. */
468        public static final int ERR_INVALID_CLIP_ANALYSIS_VERSION = 31;
469
470        /**
471         * At least one of the clip analysis has been generated on another
472         * platform (WIN32, ARM, etc.).
473         */
474        public static final int ERR_INVALID_CLIP_ANALYSIS_PLATFORM = 32;
475
476        /** Clips don't have the same video format (H263 or MPEG4). */
477        public static final int ERR_INCOMPATIBLE_VIDEO_FORMAT = 33;
478
479        /** Clips don't have the same frame size. */
480        public static final int ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE = 34;
481
482        /** Clips don't have the same MPEG-4 time scale. */
483        public static final int ERR_INCOMPATIBLE_VIDEO_TIME_SCALE = 35;
484
485        /** Clips don't have the same use of MPEG-4 data partitioning. */
486        public static final int ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING = 36;
487
488        /** MP3 clips can't be assembled. */
489        public static final int ERR_UNSUPPORTED_MP3_ASSEMBLY = 37;
490
491        /**
492         * The input 3GPP file does not contain any supported audio or video
493         * track.
494         */
495        public static final int ERR_NO_SUPPORTED_STREAM_IN_FILE = 38;
496
497        /**
498         * The Volume of the added audio track (AddVolume) must be strictly
499         * superior than zero.
500         */
501        public static final int ERR_ADDVOLUME_EQUALS_ZERO = 39;
502
503        /**
504         * The time at which an audio track is added can't be higher than the
505         * input video track duration..
506         */
507        public static final int ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION = 40;
508
509        /** The audio track file format setting is undefined. */
510        public static final int ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT = 41;
511
512        /** The added audio track stream has an unsupported format. */
513        public static final int ERR_UNSUPPORTED_ADDED_AUDIO_STREAM = 42;
514
515        /** The audio mixing feature doesn't support the audio track type. */
516        public static final int ERR_AUDIO_MIXING_UNSUPPORTED = 43;
517
518        /** The audio mixing feature doesn't support MP3 audio tracks. */
519        public static final int ERR_AUDIO_MIXING_MP3_UNSUPPORTED = 44;
520
521        /**
522         * An added audio track limits the available features: uiAddCts must be
523         * 0 and bRemoveOriginal must be true.
524         */
525        public static final int ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK = 45;
526
527        /**
528         * An added audio track limits the available features: uiAddCts must be
529         * 0 and bRemoveOriginal must be true.
530         */
531        public static final int ERR_FEATURE_UNSUPPORTED_WITH_AAC = 46;
532
533        /** Input audio track is not of a type that can be mixed with output. */
534        public static final int ERR_AUDIO_CANNOT_BE_MIXED = 47;
535
536        /** Input audio track is not AMR-NB, so it can't be mixed with output. */
537        public static final int ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED = 48;
538
539        /**
540         * An added EVRC audio track limit the available features: uiAddCts must
541         * be 0 and bRemoveOriginal must be true.
542         */
543        public static final int ERR_FEATURE_UNSUPPORTED_WITH_EVRC = 49;
544
545        /** H263 profiles other than 0 are not supported. */
546        public static final int ERR_H263_PROFILE_NOT_SUPPORTED = 51;
547
548        /** File contains no video stream or an unsupported video stream. */
549        public static final int ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE = 52;
550
551        /** Transcoding of the input file(s) is necessary. */
552        public static final int WAR_TRANSCODING_NECESSARY = 53;
553
554        /**
555         * The size of the output file will exceed the maximum configured value.
556         */
557        public static final int WAR_MAX_OUTPUT_SIZE_EXCEEDED = 54;
558
559        /** The time scale is too big. */
560        public static final int WAR_TIMESCALE_TOO_BIG = 55;
561
562        /** The year is out of range */
563        public static final int ERR_CLOCK_BAD_REF_YEAR = 56;
564
565        /** The directory could not be opened */
566        public static final int ERR_DIR_OPEN_FAILED = 57;
567
568        /** The directory could not be read */
569        public static final int ERR_DIR_READ_FAILED = 58;
570
571        /** There are no more entries in the current directory */
572        public static final int ERR_DIR_NO_MORE_ENTRY = 59;
573
574        /** The input parameter/s has error */
575        public static final int ERR_PARAMETER = 60;
576
577        /** There is a state machine error */
578        public static final int ERR_STATE = 61;
579
580        /** Memory allocation failed */
581        public static final int ERR_ALLOC = 62;
582
583        /** Context is invalid */
584        public static final int ERR_BAD_CONTEXT = 63;
585
586        /** Context creation failed */
587        public static final int ERR_CONTEXT_FAILED = 64;
588
589        /** Invalid stream ID */
590        public static final int ERR_BAD_STREAM_ID = 65;
591
592        /** Invalid option ID */
593        public static final int ERR_BAD_OPTION_ID = 66;
594
595        /** The option is write only */
596        public static final int ERR_WRITE_ONLY = 67;
597
598        /** The option is read only */
599        public static final int ERR_READ_ONLY = 68;
600
601        /** The feature is not implemented in this version */
602        public static final int ERR_NOT_IMPLEMENTED = 69;
603
604        /** The media type is not supported */
605        public static final int ERR_UNSUPPORTED_MEDIA_TYPE = 70;
606
607        /** No data to be encoded */
608        public static final int WAR_NO_DATA_YET = 71;
609
610        /** No data to be decoded */
611        public static final int WAR_NO_MORE_STREAM = 72;
612
613        /** Time stamp is invalid */
614        public static final int WAR_INVALID_TIME = 73;
615
616        /** No more data to be decoded */
617        public static final int WAR_NO_MORE_AU = 74;
618
619        /** Semaphore timed out */
620        public static final int WAR_TIME_OUT = 75;
621
622        /** Memory buffer is full */
623        public static final int WAR_BUFFER_FULL = 76;
624
625        /** Server has asked for redirection */
626        public static final int WAR_REDIRECT = 77;
627
628        /** Too many streams in input */
629        public static final int WAR_TOO_MUCH_STREAMS = 78;
630
631        /** The file cannot be opened/ written into as it is locked */
632        public static final int ERR_FILE_LOCKED = 79;
633
634        /** The file access mode is invalid */
635        public static final int ERR_FILE_BAD_MODE_ACCESS = 80;
636
637        /** The file pointer points to an invalid location */
638        public static final int ERR_FILE_INVALID_POSITION = 81;
639
640        /** Invalid string */
641        public static final int ERR_STR_BAD_STRING = 94;
642
643        /** The input string cannot be converted */
644        public static final int ERR_STR_CONV_FAILED = 95;
645
646        /** The string size is too large */
647        public static final int ERR_STR_OVERFLOW = 96;
648
649        /** Bad string arguments */
650        public static final int ERR_STR_BAD_ARGS = 97;
651
652        /** The string value is larger than maximum size allowed */
653        public static final int WAR_STR_OVERFLOW = 98;
654
655        /** The string value is not present in this comparison operation */
656        public static final int WAR_STR_NOT_FOUND = 99;
657
658        /** The thread is not started */
659        public static final int ERR_THREAD_NOT_STARTED = 100;
660
661        /** Trancoding done warning */
662        public static final int WAR_TRANSCODING_DONE = 101;
663
664        /** Unsupported mediatype */
665        public static final int WAR_MEDIATYPE_NOT_SUPPORTED = 102;
666
667        /** Input file contains invalid/unsupported streams */
668        public static final int ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM = 103;
669
670        /** Invalid input file */
671        public static final int ERR_INVALID_INPUT_FILE = 104;
672
673        /** Invalid output video format */
674        public static final int ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT = 105;
675
676        /** Invalid output video frame size */
677        public static final int ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE = 106;
678
679        /** Invalid output video frame rate */
680        public static final int ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE = 107;
681
682        /** Invalid output audio format */
683        public static final int ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT = 108;
684
685        /** Invalid video frame size for H.263 */
686        public static final int ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263 = 109;
687
688        /** Invalid video frame rate for H.263 */
689        public static final int ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263 = 110;
690
691        /** invalid playback duration */
692        public static final int ERR_DURATION_IS_NULL = 111;
693
694        /** Invalid H.263 profile in file */
695        public static final int ERR_H263_FORBIDDEN_IN_MP4_FILE = 112;
696
697        /** Invalid AAC sampling frequency */
698        public static final int ERR_INVALID_AAC_SAMPLING_FREQUENCY = 113;
699
700        /** Audio conversion failure */
701        public static final int ERR_AUDIO_CONVERSION_FAILED = 114;
702
703        /** Invalid trim start and end times */
704        public static final int ERR_BEGIN_CUT_EQUALS_END_CUT = 115;
705
706        /** End time smaller than start time for trim */
707        public static final int ERR_END_CUT_SMALLER_THAN_BEGIN_CUT = 116;
708
709        /** Output file size is small */
710        public static final int ERR_MAXFILESIZE_TOO_SMALL = 117;
711
712        /** Output video bitrate is too low */
713        public static final int ERR_VIDEOBITRATE_TOO_LOW = 118;
714
715        /** Output audio bitrate is too low */
716        public static final int ERR_AUDIOBITRATE_TOO_LOW = 119;
717
718        /** Output video bitrate is too high */
719        public static final int ERR_VIDEOBITRATE_TOO_HIGH = 120;
720
721        /** Output audio bitrate is too high */
722        public static final int ERR_AUDIOBITRATE_TOO_HIGH = 121;
723
724        /** Output file size is too small */
725        public static final int ERR_OUTPUT_FILE_SIZE_TOO_SMALL = 122;
726
727        /** Unknown stream type */
728        public static final int ERR_READER_UNKNOWN_STREAM_TYPE = 123;
729
730        /** Invalid metadata in input stream */
731        public static final int WAR_READER_NO_METADATA = 124;
732
733        /** Invalid file reader info warning */
734        public static final int WAR_READER_INFORMATION_NOT_PRESENT = 125;
735
736        /** Warning to indicate the the writer is being stopped */
737        public static final int WAR_WRITER_STOP_REQ = 131;
738
739        /** Video decoder failed to provide frame for transcoding */
740        public static final int WAR_VIDEORENDERER_NO_NEW_FRAME = 132;
741
742        /** Video deblocking filter is not implemented */
743        public static final int WAR_DEBLOCKING_FILTER_NOT_IMPLEMENTED = 133;
744
745        /** H.263 decoder profile not supported */
746        public static final int ERR_DECODER_H263_PROFILE_NOT_SUPPORTED = 134;
747
748        /** The input file contains unsupported H.263 profile */
749        public static final int ERR_DECODER_H263_NOT_BASELINE = 135;
750
751        /** There is no more space to store the output file */
752        public static final int ERR_NOMORE_SPACE_FOR_FILE = 136;
753
754        /** Internal error. */
755        public static final int ERR_INTERNAL = 255;
756
757    }
758
759    /**
760     * Defines output video formats.
761     */
762    public final class VideoFormat {
763        /** No video present in output clip. Used to generate audio only clip */
764        public static final int NO_VIDEO = 0;
765
766        /** H263 baseline format. */
767        public static final int H263 = 1;
768
769        /** MPEG4 video Simple Profile format. */
770        public static final int MPEG4 = 2;
771
772        /** MPEG4 video Simple Profile format with support for EMP. */
773        public static final int MPEG4_EMP = 3;
774
775        /** H264 video */
776        public static final int H264 = 4;
777
778        /** No transcoding. Output video format is same as input video format */
779        public static final int NULL_VIDEO = 254;
780
781        /** Unsupported video format. */
782        public static final int UNSUPPORTED = 255;
783    }
784
785    /** Defines video profiles and levels. */
786    public final class VideoProfile {
787        /** MPEG4, Simple Profile, Level 0. */
788        public static final int MPEG4_SP_LEVEL_0 = 0;
789
790        /** MPEG4, Simple Profile, Level 0B. */
791        public static final int MPEG4_SP_LEVEL_0B = 1;
792
793        /** MPEG4, Simple Profile, Level 1. */
794        public static final int MPEG4_SP_LEVEL_1 = 2;
795
796        /** MPEG4, Simple Profile, Level 2. */
797        public static final int MPEG4_SP_LEVEL_2 = 3;
798
799        /** MPEG4, Simple Profile, Level 3. */
800        public static final int MPEG4_SP_LEVEL_3 = 4;
801
802        /** H263, Profile 0, Level 10. */
803        public static final int H263_PROFILE_0_LEVEL_10 = 5;
804
805        /** H263, Profile 0, Level 20. */
806        public static final int H263_PROFILE_0_LEVEL_20 = 6;
807
808        /** H263, Profile 0, Level 30. */
809        public static final int H263_PROFILE_0_LEVEL_30 = 7;
810
811        /** H263, Profile 0, Level 40. */
812        public static final int H263_PROFILE_0_LEVEL_40 = 8;
813
814        /** H263, Profile 0, Level 45. */
815        public static final int H263_PROFILE_0_LEVEL_45 = 9;
816
817        /** MPEG4, Simple Profile, Level 4A. */
818        public static final int MPEG4_SP_LEVEL_4A = 10;
819
820        /** MPEG4, Simple Profile, Level 0. */
821        public static final int MPEG4_SP_LEVEL_5 = 11;
822
823        /** H264, Profile 0, Level 1. */
824        public static final int H264_PROFILE_0_LEVEL_1 = 12;
825
826        /** H264, Profile 0, Level 1b. */
827        public static final int H264_PROFILE_0_LEVEL_1b = 13;
828
829        /** H264, Profile 0, Level 1.1 */
830        public static final int H264_PROFILE_0_LEVEL_1_1 = 14;
831
832        /** H264, Profile 0, Level 1.2 */
833        public static final int H264_PROFILE_0_LEVEL_1_2 = 15;
834
835        /** H264, Profile 0, Level 1.3 */
836        public static final int H264_PROFILE_0_LEVEL_1_3 = 16;
837
838        /** H264, Profile 0, Level 2. */
839        public static final int H264_PROFILE_0_LEVEL_2 = 17;
840
841        /** H264, Profile 0, Level 2.1 */
842        public static final int H264_PROFILE_0_LEVEL_2_1 = 18;
843
844        /** H264, Profile 0, Level 2.2 */
845        public static final int H264_PROFILE_0_LEVEL_2_2 = 19;
846
847        /** H264, Profile 0, Level 3. */
848        public static final int H264_PROFILE_0_LEVEL_3 = 20;
849
850        /** H264, Profile 0, Level 3.1 */
851        public static final int H264_PROFILE_0_LEVEL_3_1 = 21;
852
853        /** H264, Profile 0, Level 3.2 */
854        public static final int H264_PROFILE_0_LEVEL_3_2 = 22;
855
856        /** H264, Profile 0, Level 4. */
857        public static final int H264_PROFILE_0_LEVEL_4 = 23;
858
859        /** H264, Profile 0, Level 4.1 */
860        public static final int H264_PROFILE_0_LEVEL_4_1 = 24;
861
862        /** H264, Profile 0, Level 4.2 */
863        public static final int H264_PROFILE_0_LEVEL_4_2 = 25;
864
865        /** H264, Profile 0, Level 5. */
866        public static final int H264_PROFILE_0_LEVEL_5 = 26;
867
868        /** H264, Profile 0, Level 5.1 */
869        public static final int H264_PROFILE_0_LEVEL_5_1 = 27;
870
871        /** Profile out of range. */
872        public static final int OUT_OF_RANGE = 255;
873    }
874
875    /** Defines video frame sizes. */
876    public final class VideoFrameSize {
877
878        public static final int SIZE_UNDEFINED = -1;
879
880        /** SQCIF 128 x 96 pixels. */
881        public static final int SQCIF = 0;
882
883        /** QQVGA 160 x 120 pixels. */
884        public static final int QQVGA = 1;
885
886        /** QCIF 176 x 144 pixels. */
887        public static final int QCIF = 2;
888
889        /** QVGA 320 x 240 pixels. */
890        public static final int QVGA = 3;
891
892        /** CIF 352 x 288 pixels. */
893        public static final int CIF = 4;
894
895        /** VGA 640 x 480 pixels. */
896        public static final int VGA = 5;
897
898        /** WVGA 800 X 480 pixels */
899        public static final int WVGA = 6;
900
901        /** NTSC 720 X 480 pixels */
902        public static final int NTSC = 7;
903
904        /** 640 x 360 */
905        public static final int nHD = 8;
906
907        /** 854 x 480 */
908        public static final int WVGA16x9 = 9;
909
910        /** 720p 1280 X 720 */
911        public static final int V720p = 10;
912
913        /** 1080 x 720 */
914        public static final int W720p = 11;
915
916        /** 1080 960 x 720 */
917        public static final int S720p = 12;
918    }
919
920    /**
921     * Defines output video frame rates.
922     */
923    public final class VideoFrameRate {
924        /** Frame rate of 5 frames per second. */
925        public static final int FR_5_FPS = 0;
926
927        /** Frame rate of 7.5 frames per second. */
928        public static final int FR_7_5_FPS = 1;
929
930        /** Frame rate of 10 frames per second. */
931        public static final int FR_10_FPS = 2;
932
933        /** Frame rate of 12.5 frames per second. */
934        public static final int FR_12_5_FPS = 3;
935
936        /** Frame rate of 15 frames per second. */
937        public static final int FR_15_FPS = 4;
938
939        /** Frame rate of 20 frames per second. */
940        public static final int FR_20_FPS = 5;
941
942        /** Frame rate of 25 frames per second. */
943        public static final int FR_25_FPS = 6;
944
945        /** Frame rate of 30 frames per second. */
946        public static final int FR_30_FPS = 7;
947    }
948
949    /**
950     * Defines Video Effect Types.
951     */
952    public static class VideoEffect {
953
954        public static final int NONE = 0;
955
956        public static final int FADE_FROM_BLACK = 8;
957
958        public static final int CURTAIN_OPENING = 9;
959
960        public static final int FADE_TO_BLACK = 16;
961
962        public static final int CURTAIN_CLOSING = 17;
963
964        public static final int EXTERNAL = 256;
965
966        public static final int BLACK_AND_WHITE = 257;
967
968        public static final int PINK = 258;
969
970        public static final int GREEN = 259;
971
972        public static final int SEPIA = 260;
973
974        public static final int NEGATIVE = 261;
975
976        public static final int FRAMING = 262;
977
978        public static final int TEXT = 263;
979
980        public static final int ZOOM_IN = 264;
981
982        public static final int ZOOM_OUT = 265;
983
984        public static final int FIFTIES = 266;
985
986        public static final int COLORRGB16 = 267;
987
988        public static final int GRADIENT = 268;
989    }
990
991    /**
992     * Defines the video transitions.
993     */
994    public static class VideoTransition {
995        /** No transition */
996        public static final int NONE = 0;
997
998        /** Cross fade transition */
999        public static final int CROSS_FADE = 1;
1000
1001        /** External transition. Currently not available. */
1002        public static final int EXTERNAL = 256;
1003
1004        /** AlphaMagic transition. */
1005        public static final int ALPHA_MAGIC = 257;
1006
1007        /** Slide transition. */
1008        public static final int SLIDE_TRANSITION = 258;
1009
1010        /** Fade to black transition. */
1011        public static final int FADE_BLACK = 259;
1012    }
1013
1014    /**
1015     * Defines settings for the AlphaMagic transition
1016     */
1017    public static class AlphaMagicSettings {
1018        /** Name of the alpha file (JPEG file). */
1019        public String file;
1020
1021        /** Blending percentage [0..100] 0 = no blending. */
1022        public int blendingPercent;
1023
1024        /** Invert the default rotation direction of the AlphaMagic effect. */
1025        public boolean invertRotation;
1026
1027        public int rgbWidth;
1028        public int rgbHeight;
1029    }
1030
1031    /** Defines the direction of the Slide transition. */
1032    public static final class SlideDirection {
1033
1034        /** Right out left in. */
1035        public static final int RIGHT_OUT_LEFT_IN = 0;
1036
1037        /** Left out right in. */
1038        public static final int LEFT_OUT_RIGTH_IN = 1;
1039
1040        /** Top out bottom in. */
1041        public static final int TOP_OUT_BOTTOM_IN = 2;
1042
1043        /** Bottom out top in */
1044        public static final int BOTTOM_OUT_TOP_IN = 3;
1045    }
1046
1047    /** Defines the Slide transition settings. */
1048    public static class SlideTransitionSettings {
1049        /**
1050         * Direction of the slide transition. See {@link SlideDirection
1051         * SlideDirection} for valid values.
1052         */
1053        public int direction;
1054    }
1055
1056    /**
1057     * Defines the settings of a single clip.
1058     */
1059    public static class ClipSettings {
1060
1061        /**
1062         * The path to the clip file.
1063         * <p>
1064         * File format of the clip, it can be:
1065         * <ul>
1066         * <li>3GP file containing MPEG4/H263/H264 video and AAC/AMR audio
1067         * <li>JPG file
1068         * </ul>
1069         */
1070
1071        public String clipPath;
1072
1073        /**
1074         * The path of the decoded file. This is used only for image files.
1075         */
1076        public String clipDecodedPath;
1077
1078        /**
1079         * The path of the Original file. This is used only for image files.
1080         */
1081        public String clipOriginalPath;
1082
1083        /**
1084         * File type of the clip. See {@link FileType FileType} for valid
1085         * values.
1086         */
1087        public int fileType;
1088
1089        /** Begin of the cut in the clip in milliseconds. */
1090        public int beginCutTime;
1091
1092        /**
1093         * End of the cut in the clip in milliseconds. Set both
1094         * <code>beginCutTime</code> and <code>endCutTime</code> to
1095         * <code>0</code> to get the full length of the clip without a cut. In
1096         * case of JPG clip, this is the duration of the JPEG file.
1097         */
1098        public int endCutTime;
1099
1100        /**
1101         * Begin of the cut in the clip in percentage of the file duration.
1102         */
1103        public int beginCutPercent;
1104
1105        /**
1106         * End of the cut in the clip in percentage of the file duration. Set
1107         * both <code>beginCutPercent</code> and <code>endCutPercent</code> to
1108         * <code>0</code> to get the full length of the clip without a cut.
1109         */
1110        public int endCutPercent;
1111
1112        /** Enable panning and zooming. */
1113        public boolean panZoomEnabled;
1114
1115        /** Zoom percentage at start of clip. 0 = no zoom, 100 = full zoom */
1116        public int panZoomPercentStart;
1117
1118        /** Top left X coordinate at start of clip. */
1119        public int panZoomTopLeftXStart;
1120
1121        /** Top left Y coordinate at start of clip. */
1122        public int panZoomTopLeftYStart;
1123
1124        /** Zoom percentage at start of clip. 0 = no zoom, 100 = full zoom */
1125        public int panZoomPercentEnd;
1126
1127        /** Top left X coordinate at end of clip. */
1128        public int panZoomTopLeftXEnd;
1129
1130        /** Top left Y coordinate at end of clip. */
1131        public int panZoomTopLeftYEnd;
1132
1133        /**
1134         * Set The media rendering. See {@link MediaRendering MediaRendering}
1135         * for valid values.
1136         */
1137        public int mediaRendering;
1138
1139        /**
1140         * RGB width and Height
1141         */
1142         public int rgbWidth;
1143         public int rgbHeight;
1144    }
1145
1146    /**
1147     * Defines settings for a transition.
1148     */
1149    public static class TransitionSettings {
1150
1151        /** Duration of the transition in msec. */
1152        public int duration;
1153
1154        /**
1155         * Transition type for video. See {@link VideoTransition
1156         * VideoTransition} for valid values.
1157         */
1158        public int videoTransitionType;
1159
1160        /**
1161         * Transition type for audio. See {@link AudioTransition
1162         * AudioTransition} for valid values.
1163         */
1164        public int audioTransitionType;
1165
1166        /**
1167         * Transition behaviour. See {@link TransitionBehaviour
1168         * TransitionBehaviour} for valid values.
1169         */
1170        public int transitionBehaviour;
1171
1172        /**
1173         * Settings for AlphaMagic transition. Only needs to be set if
1174         * <code>videoTransitionType</code> is set to
1175         * <code>VideoTransition.ALPHA_MAGIC</code>. See
1176         * {@link AlphaMagicSettings AlphaMagicSettings}.
1177         */
1178        public AlphaMagicSettings alphaSettings;
1179
1180        /**
1181         * Settings for the Slide transition. See
1182         * {@link SlideTransitionSettings SlideTransitionSettings}.
1183         */
1184        public SlideTransitionSettings slideSettings;
1185    }
1186
1187    public static final class AudioTransition {
1188        /** No audio transition. */
1189        public static final int NONE = 0;
1190
1191        /** Cross-fade audio transition. */
1192        public static final int CROSS_FADE = 1;
1193    }
1194
1195    /**
1196     * Defines transition behaviours.
1197     **/
1198
1199    public static final class TransitionBehaviour {
1200
1201        /** The transition uses an increasing speed. */
1202        public static final int SPEED_UP = 0;
1203
1204        /** The transition uses a linear (constant) speed. */
1205        public static final int LINEAR = 1;
1206
1207        /** The transition uses a decreasing speed. */
1208        public static final int SPEED_DOWN = 2;
1209
1210        /**
1211         * The transition uses a constant speed, but slows down in the middle
1212         * section.
1213         */
1214        public static final int SLOW_MIDDLE = 3;
1215
1216        /**
1217         * The transition uses a constant speed, but increases speed in the
1218         * middle section.
1219         */
1220        public static final int FAST_MIDDLE = 4;
1221    }
1222
1223    /** Defines settings for the background music. */
1224    public static class BackgroundMusicSettings {
1225
1226        /** Background music file. */
1227        public String file;
1228
1229        /** File type. See {@link FileType FileType} for valid values. */
1230        public int fileType;
1231
1232        /**
1233         * Insertion time in milliseconds, in the output video where the
1234         * background music must be inserted.
1235         */
1236        public long insertionTime;
1237
1238        /**
1239         * Volume, as a percentage of the background music track, to use. If
1240         * this field is set to 100, the background music will replace the audio
1241         * from the video input file(s).
1242         */
1243        public int volumePercent;
1244
1245        /**
1246         * Start time in milliseconds in the background muisc file from where
1247         * the background music should loop. Set both <code>beginLoop</code> and
1248         * <code>endLoop</code> to <code>0</code> to disable looping.
1249         */
1250        public long beginLoop;
1251
1252        /**
1253         * End time in milliseconds in the background music file to where the
1254         * background music should loop. Set both <code>beginLoop</code> and
1255         * <code>endLoop</code> to <code>0</code> to disable looping.
1256         */
1257        public long endLoop;
1258
1259        public boolean enableDucking;
1260
1261        public int duckingThreshold;
1262
1263        public int lowVolume;
1264
1265        public boolean isLooping;
1266
1267    }
1268
1269    /** Defines settings for an effect. */
1270    public static class AudioEffect {
1271        /** No audio effect. */
1272        public static final int NONE = 0;
1273
1274        /** Fade-in effect. */
1275        public static final int FADE_IN = 8;
1276
1277        /** Fade-out effect. */
1278        public static final int FADE_OUT = 16;
1279    }
1280
1281    /** Defines the effect settings. */
1282    public static class EffectSettings {
1283
1284        /** Start time of the effect in milliseconds. */
1285        public int startTime;
1286
1287        /** Duration of the effect in milliseconds. */
1288        public int duration;
1289
1290        /**
1291         * Video effect type. See {@link VideoEffect VideoEffect} for valid
1292         * values.
1293         */
1294        public int videoEffectType;
1295
1296        /**
1297         * Audio effect type. See {@link AudioEffect AudioEffect} for valid
1298         * values.
1299         */
1300        public int audioEffectType;
1301
1302        /**
1303         * Start time of the effect in percents of the duration of the clip. A
1304         * value of 0 percent means start time is from the beginning of the
1305         * clip.
1306         */
1307        public int startPercent;
1308
1309        /**
1310         * Duration of the effect in percents of the duration of the clip.
1311         */
1312        public int durationPercent;
1313
1314        /**
1315         * Framing file.
1316         * <p>
1317         * This field is only used when the field <code>videoEffectType</code>
1318         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise
1319         * this field is ignored.
1320         */
1321        public String framingFile;
1322
1323        /**
1324         * Framing buffer.
1325         * <p>
1326         * This field is only used when the field <code>videoEffectType</code>
1327         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise
1328         * this field is ignored.
1329         */
1330        public int[] framingBuffer;
1331
1332        /**
1333         * Bitmap type Can be from RGB_565 (4), ARGB_4444 (5), ARGB_8888 (6);
1334         **/
1335
1336        public int bitmapType;
1337
1338        public int width;
1339
1340        public int height;
1341
1342        /**
1343         * Top left x coordinate. This coordinate is used to set the x
1344         * coordinate of the picture in the framing file when the framing file
1345         * is selected. The x coordinate is also used to set the location of the
1346         * text in the text effect.
1347         * <p>
1348         * This field is only used when the field <code>videoEffectType</code>
1349         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING} or
1350         * {@link VideoEffect#TEXT VideoEffect.TEXT}. Otherwise this field is
1351         * ignored.
1352         */
1353        public int topLeftX;
1354
1355        /**
1356         * Top left y coordinate. This coordinate is used to set the y
1357         * coordinate of the picture in the framing file when the framing file
1358         * is selected. The y coordinate is also used to set the location of the
1359         * text in the text effect.
1360         * <p>
1361         * This field is only used when the field <code>videoEffectType</code>
1362         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING} or
1363         * {@link VideoEffect#TEXT VideoEffect.TEXT}. Otherwise this field is
1364         * ignored.
1365         */
1366        public int topLeftY;
1367
1368        /**
1369         * Should the frame be resized or not. If this field is set to
1370         * <link>true</code> then the frame size is matched with the output
1371         * video size.
1372         * <p>
1373         * This field is only used when the field <code>videoEffectType</code>
1374         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise
1375         * this field is ignored.
1376         */
1377        public boolean framingResize;
1378
1379        /**
1380         * Size to which the framing buffer needs to be resized to
1381         * This is valid only if framingResize is true
1382         */
1383        public int framingScaledSize;
1384        /**
1385         * Text to insert in the video.
1386         * <p>
1387         * This field is only used when the field <code>videoEffectType</code>
1388         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT}. Otherwise this
1389         * field is ignored.
1390         */
1391        public String text;
1392
1393        /**
1394         * Text attributes for the text to insert in the video.
1395         * <p>
1396         * This field is only used when the field <code>videoEffectType</code>
1397         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT}. Otherwise this
1398         * field is ignored. For more details about this field see the
1399         * integration guide.
1400         */
1401        public String textRenderingData;
1402
1403        /** Width of the text buffer in pixels. */
1404        public int textBufferWidth;
1405
1406        /** Height of the text buffer in pixels. */
1407        public int textBufferHeight;
1408
1409        /**
1410         * Processing rate for the fifties effect. A high value (e.g. 30)
1411         * results in high effect strength.
1412         * <p>
1413         * This field is only used when the field <code>videoEffectType</code>
1414         * is set to {@link VideoEffect#FIFTIES VideoEffect.FIFTIES}. Otherwise
1415         * this field is ignored.
1416         */
1417        public int fiftiesFrameRate;
1418
1419        /**
1420         * RGB 16 color of the RGB16 and gradient color effect.
1421         * <p>
1422         * This field is only used when the field <code>videoEffectType</code>
1423         * is set to {@link VideoEffect#COLORRGB16 VideoEffect.COLORRGB16} or
1424         * {@link VideoEffect#GRADIENT VideoEffect.GRADIENT}. Otherwise this
1425         * field is ignored.
1426         */
1427        public int rgb16InputColor;
1428
1429        /**
1430         * Start alpha blending percentage.
1431         * <p>
1432         * This field is only used when the field <code>videoEffectType</code>
1433         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
1434         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
1435         * is ignored.
1436         */
1437        public int alphaBlendingStartPercent;
1438
1439        /**
1440         * Middle alpha blending percentage.
1441         * <p>
1442         * This field is only used when the field <code>videoEffectType</code>
1443         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
1444         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
1445         * is ignored.
1446         */
1447        public int alphaBlendingMiddlePercent;
1448
1449        /**
1450         * End alpha blending percentage.
1451         * <p>
1452         * This field is only used when the field <code>videoEffectType</code>
1453         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
1454         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
1455         * is ignored.
1456         */
1457        public int alphaBlendingEndPercent;
1458
1459        /**
1460         * Duration, in percentage of effect duration of the fade-in phase.
1461         * <p>
1462         * This field is only used when the field <code>videoEffectType</code>
1463         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
1464         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
1465         * is ignored.
1466         */
1467        public int alphaBlendingFadeInTimePercent;
1468
1469        /**
1470         * Duration, in percentage of effect duration of the fade-out phase.
1471         * <p>
1472         * This field is only used when the field <code>videoEffectType</code>
1473         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
1474         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
1475         * is ignored.
1476         */
1477        public int alphaBlendingFadeOutTimePercent;
1478    }
1479
1480    /** Defines the clip properties for preview */
1481    public static class PreviewClips {
1482
1483        /**
1484         * The path to the clip file.
1485         * <p>
1486         * File format of the clip, it can be:
1487         * <ul>
1488         * <li>3GP file containing MPEG4/H263 video and AAC/AMR audio
1489         * <li>JPG file
1490         * </ul>
1491         */
1492
1493        public String clipPath;
1494
1495        /**
1496         * File type of the clip. See {@link FileType FileType} for valid
1497         * values.
1498         */
1499        public int fileType;
1500
1501        /** Begin of the cut in the clip in milliseconds. */
1502        public long beginPlayTime;
1503
1504        public long endPlayTime;
1505
1506        /**
1507         * Set The media rendering. See {@link MediaRendering MediaRendering}
1508         * for valid values.
1509         */
1510        public int mediaRendering;
1511
1512    }
1513
1514    /** Defines the audio settings. */
1515    public static class AudioSettings {
1516
1517        String pFile;
1518
1519        /** < PCM file path */
1520        String Id;
1521
1522        boolean bRemoveOriginal;
1523
1524        /** < If true, the original audio track is not taken into account */
1525        int channels;
1526
1527        /** < Number of channels (1=mono, 2=stereo) of BGM clip */
1528        int Fs;
1529
1530        /**
1531         * < Sampling audio frequency (8000 for amr, 16000 or more for aac) of
1532         * BGM clip
1533         */
1534        int ExtendedFs;
1535
1536        /** < Extended frequency for AAC+, eAAC+ streams of BGM clip */
1537        long startMs;
1538
1539        /** < Time, in milliseconds, at which the added audio track is inserted */
1540        long beginCutTime;
1541
1542        long endCutTime;
1543
1544        int fileType;
1545
1546        int volume;
1547
1548        /** < Volume, in percentage, of the added audio track */
1549        boolean loop;
1550
1551        /** < Looping on/off > **/
1552
1553        /** Audio mix and Duck **/
1554        int ducking_threshold;
1555
1556        int ducking_lowVolume;
1557
1558        boolean bInDucking_enable;
1559
1560        String pcmFilePath;
1561
1562    }
1563
1564    /** Encapsulates preview clips and effect settings */
1565    public static class PreviewSettings {
1566
1567        public PreviewClips[] previewClipsArray;
1568
1569        /** The effect settings. */
1570        public EffectSettings[] effectSettingsArray;
1571
1572    }
1573
1574    /** Encapsulates clip properties */
1575    public static class PreviewClipProperties {
1576
1577        public Properties[] clipProperties;
1578
1579    }
1580
1581    /** Defines the editing settings. */
1582    public static class EditSettings {
1583
1584        /**
1585         * Array of clip settings. There is one <code>clipSetting</code> for
1586         * each clip.
1587         */
1588        public ClipSettings[] clipSettingsArray;
1589
1590        /**
1591         * Array of transition settings. If there are n clips (and thus n
1592         * <code>clipSettings</code>) then there are (n-1) transitions and (n-1)
1593         * <code>transistionSettings</code> in
1594         * <code>transistionSettingsArray</code>.
1595         */
1596        public TransitionSettings[] transitionSettingsArray;
1597
1598        /** The effect settings. */
1599        public EffectSettings[] effectSettingsArray;
1600
1601        /**
1602         * Video frame rate of the output clip. See {@link VideoFrameRate
1603         * VideoFrameRate} for valid values.
1604         */
1605        public int videoFrameRate;
1606
1607        /** Output file name. Must be an absolute path. */
1608        public String outputFile;
1609
1610        /**
1611         * Size of the video frames in the output clip. See
1612         * {@link VideoFrameSize VideoFrameSize} for valid values.
1613         */
1614        public int videoFrameSize;
1615
1616        /**
1617         * Format of the video stream in the output clip. See
1618         * {@link VideoFormat VideoFormat} for valid values.
1619         */
1620        public int videoFormat;
1621
1622        /**
1623         * Format of the audio stream in the output clip. See
1624         * {@link AudioFormat AudioFormat} for valid values.
1625         */
1626        public int audioFormat;
1627
1628        /**
1629         * Sampling frequency of the audio stream in the output clip. See
1630         * {@link AudioSamplingFrequency AudioSamplingFrequency} for valid
1631         * values.
1632         */
1633        public int audioSamplingFreq;
1634
1635        /**
1636         * Maximum file size. By setting this you can set the maximum size of
1637         * the output clip. Set it to <code>0</code> to let the class ignore
1638         * this filed.
1639         */
1640        public int maxFileSize;
1641
1642        /**
1643         * Number of audio channels in output clip. Use <code>0</code> for none,
1644         * <code>1</code> for mono or <code>2</code> for stereo. None is only
1645         * allowed when the <code>audioFormat</code> field is set to
1646         * {@link AudioFormat#NO_AUDIO AudioFormat.NO_AUDIO} or
1647         * {@link AudioFormat#NULL_AUDIO AudioFormat.NULL_AUDIO} Mono is only
1648         * allowed when the <code>audioFormat</code> field is set to
1649         * {@link AudioFormat#AAC AudioFormat.AAC}
1650         */
1651        public int audioChannels;
1652
1653        /** Video bitrate. See {@link Bitrate Bitrate} for valid values. */
1654        public int videoBitrate;
1655
1656        /** Audio bitrate. See {@link Bitrate Bitrate} for valid values. */
1657        public int audioBitrate;
1658
1659        /**
1660         * Background music settings. See {@link BackgroundMusicSettings
1661         * BackgroundMusicSettings} for valid values.
1662         */
1663        public BackgroundMusicSettings backgroundMusicSettings;
1664
1665        public int primaryTrackVolume;
1666
1667    }
1668
1669    /**
1670     * Defines the media properties.
1671     **/
1672
1673    public static class Properties {
1674
1675        /**
1676         * Duration of the media in milliseconds.
1677         */
1678
1679        public int duration;
1680
1681        /**
1682         * File type.
1683         */
1684
1685        public int fileType;
1686
1687        /**
1688         * Video format.
1689         */
1690
1691        public int videoFormat;
1692
1693        /**
1694         * Duration of the video stream of the media in milliseconds.
1695         */
1696
1697        public int videoDuration;
1698
1699        /**
1700         * Bitrate of the video stream of the media.
1701         */
1702
1703        public int videoBitrate;
1704
1705        /**
1706         * Width of the video frames or the width of the still picture in
1707         * pixels.
1708         */
1709
1710        public int width;
1711
1712        /**
1713         * Height of the video frames or the height of the still picture in
1714         * pixels.
1715         */
1716
1717        public int height;
1718
1719        /**
1720         * Average frame rate of video in the media in frames per second.
1721         */
1722
1723        public float averageFrameRate;
1724
1725        /**
1726         * Profile and level of the video in the media.
1727         */
1728
1729        public int profileAndLevel;
1730
1731        /**
1732         * Audio format.
1733         */
1734
1735        public int audioFormat;
1736
1737        /**
1738         * Duration of the audio stream of the media in milliseconds.
1739         */
1740
1741        public int audioDuration;
1742
1743        /**
1744         * Bitrate of the audio stream of the media.
1745         */
1746
1747        public int audioBitrate;
1748
1749        /**
1750         * Number of audio channels in the media.
1751         */
1752
1753        public int audioChannels;
1754
1755        /**
1756         * Sampling frequency of the audio stream in the media in samples per
1757         * second.
1758         */
1759
1760        public int audioSamplingFrequency;
1761
1762        /**
1763         * Volume value of the audio track as percentage.
1764         */
1765        public int audioVolumeValue;
1766
1767        public String Id;
1768
1769    }
1770
1771    /**
1772     * Constructor
1773     *
1774     * @param projectPath The path where the VideoEditor stores all files
1775     *        related to the project
1776     * @param veObj The video editor reference
1777     */
1778    public MediaArtistNativeHelper(String projectPath, VideoEditor veObj) {
1779        mProjectPath = projectPath;
1780        if (veObj != null) {
1781            mVideoEditor = veObj;
1782        } else {
1783            mVideoEditor = null;
1784            throw new IllegalArgumentException("video editor object is null");
1785        }
1786        if (mStoryBoardSettings == null)
1787            mStoryBoardSettings = new EditSettings();
1788
1789        mMediaEffectList = new ArrayList<Effect>();
1790        mMediaOverLayList = new ArrayList<Overlay>();
1791        _init(mProjectPath, "null");
1792        mAudioTrackPCMFilePath = null;
1793    }
1794
1795    /**
1796     * @return The project path
1797     */
1798    String getProjectPath() {
1799        return mProjectPath;
1800    }
1801
1802    /**
1803     * @return The Audio Track PCM file path
1804     */
1805    String getProjectAudioTrackPCMFilePath() {
1806        return mAudioTrackPCMFilePath;
1807    }
1808
1809    /**
1810     * Invalidates the PCM file
1811     */
1812    void invalidatePcmFile() {
1813        if (mAudioTrackPCMFilePath != null) {
1814            new File(mAudioTrackPCMFilePath).delete();
1815            mAudioTrackPCMFilePath = null;
1816        }
1817    }
1818
1819    @SuppressWarnings("unused")
1820    private void onProgressUpdate(int taskId, int progress) {
1821        if (mProcessingState == PROCESSING_EXPORT) {
1822            if (mExportProgressListener != null) {
1823                if (mProgressToApp < progress) {
1824                    mExportProgressListener.onProgress(mVideoEditor, mOutputFilename, progress);
1825                    /* record previous progress */
1826                    mProgressToApp = progress;
1827                }
1828            }
1829        }
1830        else {
1831            // Adapt progress depending on current state
1832            int actualProgress = 0;
1833            int action = 0;
1834
1835            if (mProcessingState == PROCESSING_AUDIO_PCM) {
1836                action = MediaProcessingProgressListener.ACTION_DECODE;
1837            } else {
1838                action = MediaProcessingProgressListener.ACTION_ENCODE;
1839            }
1840
1841            switch (mProcessingState) {
1842                case PROCESSING_AUDIO_PCM:
1843                    actualProgress = progress;
1844                    break;
1845                case PROCESSING_TRANSITION:
1846                    actualProgress = progress;
1847                    break;
1848                case PROCESSING_KENBURNS:
1849                    actualProgress = progress;
1850                    break;
1851                case PROCESSING_INTERMEDIATE1:
1852                    if ((progress == 0) && (mProgressToApp != 0)) {
1853                        mProgressToApp = 0;
1854                    }
1855                    if ((progress != 0) || (mProgressToApp != 0)) {
1856                        actualProgress = progress/4;
1857                    }
1858                    break;
1859                case PROCESSING_INTERMEDIATE2:
1860                    if ((progress != 0) || (mProgressToApp != 0)) {
1861                        actualProgress = 25 + progress/4;
1862                    }
1863                    break;
1864                case PROCESSING_INTERMEDIATE3:
1865                    if ((progress != 0) || (mProgressToApp != 0)) {
1866                        actualProgress = 50 + progress/2;
1867                    }
1868                    break;
1869                case PROCESSING_NONE:
1870
1871                default:
1872                    Log.e("MediaArtistNativeHelper", "ERROR unexpected State=" + mProcessingState);
1873                    return;
1874            }
1875            if ((mProgressToApp != actualProgress) && (actualProgress != 0)) {
1876
1877                mProgressToApp = actualProgress;
1878
1879                if (mMediaProcessingProgressListener != null) {
1880                    // Send the progress indication
1881                    mMediaProcessingProgressListener.onProgress(mProcessingObject,
1882                                                                action,
1883                                                                actualProgress);
1884                }
1885            }
1886            /* avoid 0 in next intermediate call */
1887            if (mProgressToApp == 0) {
1888                if (mMediaProcessingProgressListener != null) {
1889                    /*
1890                     *  Send the progress indication
1891                     */
1892                    mMediaProcessingProgressListener.onProgress(mProcessingObject,
1893                                                                action,
1894                                                                actualProgress);
1895                }
1896                mProgressToApp = 1;
1897            }
1898        }
1899    }
1900
1901    @SuppressWarnings("unused")
1902    private void onPreviewProgressUpdate(int progress, boolean isFinished) {
1903        if (mPreviewProgressListener != null) {
1904            mPreviewProgressListener.onProgress(mVideoEditor, progress, isFinished);
1905            if (progress != 0) {
1906                mPreviewProgress = progress;
1907            }
1908        }
1909    }
1910
1911    /**
1912     * Release the native helper object
1913     */
1914    public void releaseNativeHelper() {
1915        try {
1916            release();
1917        } catch (IllegalStateException ex) {
1918            Log.e("MediaArtistNativeHelper",
1919            "Illegal State exeption caught in releaseNativeHelper");
1920            throw ex;
1921        } catch (RuntimeException ex) {
1922            Log.e("MediaArtistNativeHelper", "Runtime exeption caught in releaseNativeHelper");
1923            throw ex;
1924        }
1925    }
1926
1927    /**
1928     * Release the native helper to end the Audio Graph process
1929     */
1930    @SuppressWarnings("unused")
1931    private void onAudioGraphExtractProgressUpdate(int progress, boolean isVideo) {
1932
1933        if ((mExtractAudioWaveformProgressListener != null) && (progress > 0))
1934        {
1935            mExtractAudioWaveformProgressListener.onProgress(progress);
1936        }
1937    }
1938
1939    /**
1940     * Populates the Effect Settings in EffectSettings
1941     *
1942     * @param effects The reference of EffectColor
1943     *
1944     * @return The populated effect settings in EffectSettings
1945     * reference
1946     */
1947    EffectSettings getEffectSettings(EffectColor effects) {
1948        EffectSettings effectSettings = new EffectSettings();
1949        effectSettings.startTime = (int)effects.getStartTime();
1950        effectSettings.duration = (int)effects.getDuration();
1951        effectSettings.videoEffectType = getEffectColorType(effects);
1952        effectSettings.audioEffectType = 0;
1953        effectSettings.startPercent = 0;
1954        effectSettings.durationPercent = 0;
1955        effectSettings.framingFile = null;
1956        effectSettings.topLeftX = 0;
1957        effectSettings.topLeftY = 0;
1958        effectSettings.framingResize = false;
1959        effectSettings.text = null;
1960        effectSettings.textRenderingData = null;
1961        effectSettings.textBufferWidth = 0;
1962        effectSettings.textBufferHeight = 0;
1963        if (effects.getType() == EffectColor.TYPE_FIFTIES) {
1964            effectSettings.fiftiesFrameRate = 15;
1965        } else {
1966            effectSettings.fiftiesFrameRate = 0;
1967        }
1968
1969        if ((effectSettings.videoEffectType == VideoEffect.COLORRGB16)
1970                || (effectSettings.videoEffectType == VideoEffect.GRADIENT)) {
1971            effectSettings.rgb16InputColor = effects.getColor();
1972        }
1973
1974        effectSettings.alphaBlendingStartPercent = 0;
1975        effectSettings.alphaBlendingMiddlePercent = 0;
1976        effectSettings.alphaBlendingEndPercent = 0;
1977        effectSettings.alphaBlendingFadeInTimePercent = 0;
1978        effectSettings.alphaBlendingFadeOutTimePercent = 0;
1979        return effectSettings;
1980    }
1981
1982    /**
1983     * Populates the Overlay Settings in EffectSettings
1984     *
1985     * @param overlay The reference of OverlayFrame
1986     *
1987     * @return The populated overlay settings in EffectSettings
1988     * reference
1989     */
1990    EffectSettings getOverlaySettings(OverlayFrame overlay) {
1991        EffectSettings effectSettings = new EffectSettings();
1992        Bitmap bitmap = null;
1993
1994        effectSettings.startTime = (int)overlay.getStartTime();
1995        effectSettings.duration = (int)overlay.getDuration();
1996        effectSettings.videoEffectType = VideoEffect.FRAMING;
1997        effectSettings.audioEffectType = 0;
1998        effectSettings.startPercent = 0;
1999        effectSettings.durationPercent = 0;
2000        effectSettings.framingFile = null;
2001
2002        if ((bitmap = overlay.getBitmap()) != null) {
2003            effectSettings.framingFile = overlay.getFilename();
2004
2005            if (effectSettings.framingFile == null) {
2006                try {
2007                    (overlay).save(mProjectPath);
2008                } catch (IOException e) {
2009                    Log.e("MediaArtistNativeHelper","getOverlaySettings : File not found");
2010                }
2011                effectSettings.framingFile = overlay.getFilename();
2012            }
2013            if (bitmap.getConfig() == Bitmap.Config.ARGB_8888)
2014                effectSettings.bitmapType = 6;
2015            else if (bitmap.getConfig() == Bitmap.Config.ARGB_4444)
2016                effectSettings.bitmapType = 5;
2017            else if (bitmap.getConfig() == Bitmap.Config.RGB_565)
2018                effectSettings.bitmapType = 4;
2019            else if (bitmap.getConfig() == Bitmap.Config.ALPHA_8)
2020                throw new RuntimeException("Bitmap config not supported");
2021
2022            effectSettings.width = bitmap.getWidth();
2023            effectSettings.height = bitmap.getHeight();
2024            effectSettings.framingBuffer = new int[effectSettings.width];
2025            int tmp = 0;
2026            short maxAlpha = 0;
2027            short minAlpha = (short)0xFF;
2028            short alpha = 0;
2029            while (tmp < effectSettings.height) {
2030                bitmap.getPixels(effectSettings.framingBuffer, 0,
2031                                 effectSettings.width, 0, tmp,
2032                                 effectSettings.width, 1);
2033                for (int i = 0; i < effectSettings.width; i++) {
2034                    alpha = (short)((effectSettings.framingBuffer[i] >> 24) & 0xFF);
2035                    if (alpha > maxAlpha) {
2036                        maxAlpha = alpha;
2037                    }
2038                    if (alpha < minAlpha) {
2039                        minAlpha = alpha;
2040                    }
2041                }
2042                tmp += 1;
2043            }
2044            alpha = (short)((maxAlpha + minAlpha) / 2);
2045            alpha = (short)((alpha * 100) / 256);
2046            effectSettings.alphaBlendingEndPercent = alpha;
2047            effectSettings.alphaBlendingMiddlePercent = alpha;
2048            effectSettings.alphaBlendingStartPercent = alpha;
2049            effectSettings.alphaBlendingFadeInTimePercent = 100;
2050            effectSettings.alphaBlendingFadeOutTimePercent = 100;
2051            effectSettings.framingBuffer = null;
2052        }
2053
2054        effectSettings.topLeftX = 0;
2055        effectSettings.topLeftY = 0;
2056
2057        effectSettings.framingResize = true;
2058        effectSettings.text = null;
2059        effectSettings.textRenderingData = null;
2060        effectSettings.textBufferWidth = 0;
2061        effectSettings.textBufferHeight = 0;
2062        effectSettings.fiftiesFrameRate = 0;
2063        effectSettings.rgb16InputColor = 0;
2064        int mediaItemHeight;
2065        int aspectRatio;
2066        if (overlay.getMediaItem() instanceof MediaImageItem) {
2067            if (((MediaImageItem)overlay.getMediaItem()).getGeneratedImageClip() != null) {
2068                //Kenburns was applied
2069                mediaItemHeight = ((MediaImageItem)overlay.getMediaItem()).getGeneratedClipHeight();
2070                aspectRatio = getAspectRatio(
2071                    ((MediaImageItem)overlay.getMediaItem()).getGeneratedClipWidth()
2072                    , mediaItemHeight);
2073            }
2074            else {
2075                //For image get the scaled height. Aspect ratio would remain the same
2076                mediaItemHeight = ((MediaImageItem)overlay.getMediaItem()).getScaledHeight();
2077                aspectRatio = overlay.getMediaItem().getAspectRatio();
2078                effectSettings.framingResize = false; //since the image can be of odd size.
2079            }
2080        } else {
2081            aspectRatio = overlay.getMediaItem().getAspectRatio();
2082            mediaItemHeight = overlay.getMediaItem().getHeight();
2083        }
2084        effectSettings.framingScaledSize = findVideoResolution(aspectRatio, mediaItemHeight);
2085        return effectSettings;
2086    }
2087
2088    /**
2089     * Sets the audio regenerate flag
2090     *
2091     * @param flag The boolean to set the audio regenerate flag
2092     *
2093     */
2094    void setAudioflag(boolean flag) {
2095        //check if the file exists.
2096        if (!(new File(String.format(mProjectPath + "/" + AUDIO_TRACK_PCM_FILE)).exists())) {
2097            flag = true;
2098        }
2099        mRegenerateAudio = flag;
2100    }
2101
2102    /**
2103     * Gets the audio regenerate flag
2104     *
2105     * @param return The boolean to get the audio regenerate flag
2106     *
2107     */
2108    boolean getAudioflag() {
2109        return mRegenerateAudio;
2110    }
2111
2112    /**
2113     * Maps the average frame rate to one of the defined enum values
2114     *
2115     * @param averageFrameRate The average frame rate of video item
2116     *
2117     * @return The frame rate from one of the defined enum values
2118     */
2119    public int GetClosestVideoFrameRate(int averageFrameRate) {
2120        if (averageFrameRate >= 25) {
2121            return VideoFrameRate.FR_30_FPS;
2122        } else if (averageFrameRate >= 20) {
2123            return VideoFrameRate.FR_25_FPS;
2124        } else if (averageFrameRate >= 15) {
2125            return VideoFrameRate.FR_20_FPS;
2126        } else if (averageFrameRate >= 12) {
2127            return VideoFrameRate.FR_15_FPS;
2128        } else if (averageFrameRate >= 10) {
2129            return VideoFrameRate.FR_12_5_FPS;
2130        } else if (averageFrameRate >= 7) {
2131            return VideoFrameRate.FR_10_FPS;
2132        } else if (averageFrameRate >= 5) {
2133            return VideoFrameRate.FR_7_5_FPS;
2134        } else {
2135            return -1;
2136        }
2137    }
2138
2139    /**
2140     * Helper function to adjust the effect or overlay start time
2141     * depending on the begin and end boundary time of meddia item
2142     */
2143    public void adjustEffectsStartTimeAndDuration(EffectSettings lEffect,
2144                                                  int beginCutTime,
2145                                                  int endCutTime) {
2146
2147        int effectStartTime = 0;
2148        int effectDuration = 0;
2149
2150        /**
2151         * cbct -> clip begin cut time
2152         * cect -> clip end cut time
2153         ****************************************
2154         *  |                                 |
2155         *  |         cbct        cect        |
2156         *  | <-1-->   |           |          |
2157         *  |       <--|-2->       |          |
2158         *  |          | <---3---> |          |
2159         *  |          |        <--|-4--->    |
2160         *  |          |           | <--5-->  |
2161         *  |      <---|------6----|---->     |
2162         *  |                                 |
2163         *  < : effectStart
2164         *  > : effectStart + effectDuration
2165         ****************************************
2166         **/
2167
2168        /** 1 & 5 */
2169        /**
2170         * Effect falls out side the trim duration. In such a case effects shall
2171         * not be applied.
2172         */
2173        if ((lEffect.startTime > endCutTime)
2174                || ((lEffect.startTime + lEffect.duration) <= beginCutTime)) {
2175
2176            effectStartTime = 0;
2177            effectDuration = 0;
2178
2179            lEffect.startTime = effectStartTime;
2180            lEffect.duration = effectDuration;
2181            return;
2182        }
2183
2184        /** 2 */
2185        if ((lEffect.startTime < beginCutTime)
2186                && ((lEffect.startTime + lEffect.duration) > beginCutTime)
2187                && ((lEffect.startTime + lEffect.duration) <= endCutTime)) {
2188            effectStartTime = 0;
2189            effectDuration = lEffect.duration;
2190
2191            effectDuration -= (beginCutTime - lEffect.startTime);
2192            lEffect.startTime = effectStartTime;
2193            lEffect.duration = effectDuration;
2194            return;
2195        }
2196
2197        /** 3 */
2198        if ((lEffect.startTime >= beginCutTime)
2199                && ((lEffect.startTime + lEffect.duration) <= endCutTime)) {
2200            effectStartTime = lEffect.startTime - beginCutTime;
2201            lEffect.startTime = effectStartTime;
2202            lEffect.duration = lEffect.duration;
2203            return;
2204        }
2205
2206        /** 4 */
2207        if ((lEffect.startTime >= beginCutTime)
2208                && ((lEffect.startTime + lEffect.duration) > endCutTime)) {
2209            effectStartTime = lEffect.startTime - beginCutTime;
2210            effectDuration = endCutTime - lEffect.startTime;
2211            lEffect.startTime = effectStartTime;
2212            lEffect.duration = effectDuration;
2213            return;
2214        }
2215
2216        /** 6 */
2217        if ((lEffect.startTime < beginCutTime)
2218                && ((lEffect.startTime + lEffect.duration) > endCutTime)) {
2219            effectStartTime = 0;
2220            effectDuration = endCutTime - beginCutTime;
2221            lEffect.startTime = effectStartTime;
2222            lEffect.duration = effectDuration;
2223            return;
2224        }
2225
2226    }
2227
2228    /**
2229     * Generates the clip for preview or export
2230     *
2231     * @param editSettings The EditSettings reference for generating
2232     * a clip for preview or export
2233     *
2234     * @return error value
2235     */
2236    public int generateClip(EditSettings editSettings) {
2237        int err = 0;
2238
2239        try {
2240            err = nativeGenerateClip(editSettings);
2241        } catch (IllegalArgumentException ex) {
2242            Log.e("MediaArtistNativeHelper","Illegal Argument exception in load settings");
2243            return -1;
2244        } catch (IllegalStateException ex) {
2245            Log.e("MediaArtistNativeHelper","Illegal state exception in load settings");
2246            return -1;
2247        } catch (RuntimeException ex) {
2248            Log.e("MediaArtistNativeHelper", "Runtime exception in load settings");
2249            return -1;
2250        }
2251        return err;
2252    }
2253
2254    /**
2255     * Init function to initialise the  ClipSettings reference to
2256     * default values
2257     *
2258     * @param lclipSettings The ClipSettings reference
2259     */
2260    void initClipSettings(ClipSettings lclipSettings) {
2261        lclipSettings.clipPath = null;
2262        lclipSettings.clipDecodedPath = null;
2263        lclipSettings.clipOriginalPath = null;
2264        lclipSettings.fileType = 0;
2265        lclipSettings.endCutTime = 0;
2266        lclipSettings.beginCutTime = 0;
2267        lclipSettings.beginCutPercent = 0;
2268        lclipSettings.endCutPercent = 0;
2269        lclipSettings.panZoomEnabled = false;
2270        lclipSettings.panZoomPercentStart = 0;
2271        lclipSettings.panZoomTopLeftXStart = 0;
2272        lclipSettings.panZoomTopLeftYStart = 0;
2273        lclipSettings.panZoomPercentEnd = 0;
2274        lclipSettings.panZoomTopLeftXEnd = 0;
2275        lclipSettings.panZoomTopLeftYEnd = 0;
2276        lclipSettings.mediaRendering = 0;
2277    }
2278
2279
2280    /**
2281     * Populates the settings for generating an effect clip
2282     *
2283     * @param lMediaItem The media item for which the effect clip
2284     * needs to be generated
2285     * @param lclipSettings The ClipSettings reference containing
2286     * clips data
2287     * @param e The EditSettings reference containing effect specific data
2288     * @param uniqueId The unique id used in the name of the output clip
2289     * @param clipNo Used for internal purpose
2290     *
2291     * @return The name and path of generated clip
2292     */
2293    String generateEffectClip(MediaItem lMediaItem, ClipSettings lclipSettings,
2294            EditSettings e,String uniqueId,int clipNo) {
2295        int err = 0;
2296        EditSettings editSettings = null;
2297        String EffectClipPath = null;
2298
2299        editSettings = new EditSettings();
2300
2301        editSettings.clipSettingsArray = new ClipSettings[1];
2302        editSettings.clipSettingsArray[0] = lclipSettings;
2303
2304        editSettings.backgroundMusicSettings = null;
2305        editSettings.transitionSettingsArray = null;
2306        editSettings.effectSettingsArray = e.effectSettingsArray;
2307
2308        EffectClipPath = String.format(mProjectPath + "/" + "ClipEffectIntermediate" + "_"
2309                + lMediaItem.getId() + uniqueId + ".3gp");
2310
2311        File tmpFile = new File(EffectClipPath);
2312        if (tmpFile.exists()) {
2313            tmpFile.delete();
2314        }
2315
2316        if (lMediaItem instanceof MediaVideoItem) {
2317            MediaVideoItem m = (MediaVideoItem)lMediaItem;
2318
2319            editSettings.audioFormat = AudioFormat.AAC;
2320            editSettings.audioChannels = 2;
2321            editSettings.audioBitrate = Bitrate.BR_64_KBPS;
2322            editSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
2323
2324            editSettings.videoBitrate = Bitrate.BR_5_MBPS;
2325            //editSettings.videoFormat = VideoFormat.MPEG4;
2326            editSettings.videoFormat = VideoFormat.H264;
2327            editSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
2328            editSettings.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(), m
2329                    .getHeight());
2330
2331        } else {
2332            MediaImageItem m = (MediaImageItem)lMediaItem;
2333            editSettings.audioBitrate = Bitrate.BR_64_KBPS;
2334            editSettings.audioChannels = 2;
2335            editSettings.audioFormat = AudioFormat.AAC;
2336            editSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
2337
2338            editSettings.videoBitrate = Bitrate.BR_5_MBPS;
2339            editSettings.videoFormat = VideoFormat.H264;
2340            editSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
2341            editSettings.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(), m
2342                    .getScaledHeight());
2343        }
2344
2345        editSettings.outputFile = EffectClipPath;
2346
2347        if (clipNo == 1) {
2348            mProcessingState  = PROCESSING_INTERMEDIATE1;
2349        } else if (clipNo == 2) {
2350            mProcessingState  = PROCESSING_INTERMEDIATE2;
2351        }
2352        mProcessingObject = lMediaItem;
2353        err = generateClip(editSettings);
2354        mProcessingState  = PROCESSING_NONE;
2355
2356        if (err == 0) {
2357            lclipSettings.clipPath = EffectClipPath;
2358            lclipSettings.fileType = FileType.THREE_GPP;
2359            return EffectClipPath;
2360        } else {
2361            throw new RuntimeException("preview generation cannot be completed");
2362        }
2363    }
2364
2365
2366    /**
2367     * Populates the settings for generating a Ken Burn effect clip
2368     *
2369     * @param m The media image item for which the Ken Burn effect clip
2370     * needs to be generated
2371     * @param e The EditSettings reference clip specific data
2372     *
2373     * @return The name and path of generated clip
2374     */
2375    String generateKenBurnsClip(EditSettings e, MediaImageItem m) {
2376        String output = null;
2377        int err = 0;
2378
2379        e.backgroundMusicSettings = null;
2380        e.transitionSettingsArray = null;
2381        e.effectSettingsArray = null;
2382        output = String.format(mProjectPath + "/" + "ImageClip-" + m.getId() + ".3gp");
2383
2384        File tmpFile = new File(output);
2385        if (tmpFile.exists()) {
2386            tmpFile.delete();
2387        }
2388
2389        e.outputFile = output;
2390        e.audioBitrate = Bitrate.BR_64_KBPS;
2391        e.audioChannels = 2;
2392        e.audioFormat = AudioFormat.AAC;
2393        e.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
2394
2395        e.videoBitrate = Bitrate.BR_5_MBPS;
2396        e.videoFormat = VideoFormat.H264;
2397        e.videoFrameRate = VideoFrameRate.FR_30_FPS;
2398        e.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(),
2399                                                           m.getScaledHeight());
2400        mProcessingState  = PROCESSING_KENBURNS;
2401        mProcessingObject = m;
2402        err = generateClip(e);
2403        // Reset the processing state and check for errors
2404        mProcessingState  = PROCESSING_NONE;
2405        if (err != 0) {
2406            throw new RuntimeException("preview generation cannot be completed");
2407        }
2408        return output;
2409    }
2410
2411
2412    /**
2413     * Calculates the output resolution for transition clip
2414     *
2415     * @param m1 First media item associated with transition
2416     * @param m2 Second media item associated with transition
2417     *
2418     * @return The transition resolution
2419     */
2420    private int getTransitionResolution(MediaItem m1, MediaItem m2) {
2421        int clip1Height = 0;
2422        int clip2Height = 0;
2423        int videoSize = 0;
2424
2425        if (m1 != null && m2 != null) {
2426            if (m1 instanceof MediaVideoItem) {
2427                clip1Height = m1.getHeight();
2428            } else if (m1 instanceof MediaImageItem) {
2429                clip1Height = ((MediaImageItem)m1).getScaledHeight();
2430            }
2431            if (m2 instanceof MediaVideoItem) {
2432                clip2Height = m2.getHeight();
2433            } else if (m2 instanceof MediaImageItem) {
2434                clip2Height = ((MediaImageItem)m2).getScaledHeight();
2435            }
2436            if (clip1Height > clip2Height) {
2437                videoSize = findVideoResolution(mVideoEditor.getAspectRatio(),
2438                                                                   clip1Height);
2439            } else {
2440                videoSize = findVideoResolution(mVideoEditor.getAspectRatio(),
2441                                                                   clip2Height);
2442            }
2443        } else if (m1 == null && m2 != null) {
2444            if (m2 instanceof MediaVideoItem) {
2445                clip2Height = m2.getHeight();
2446            } else if (m2 instanceof MediaImageItem) {
2447                clip2Height = ((MediaImageItem)m2).getScaledHeight();
2448            }
2449            videoSize = findVideoResolution(mVideoEditor.getAspectRatio(),
2450                                                                   clip2Height);
2451        } else if (m1 != null && m2 == null) {
2452            if (m1 instanceof MediaVideoItem) {
2453                clip1Height = m1.getHeight();
2454            } else if (m1 instanceof MediaImageItem) {
2455                clip1Height = ((MediaImageItem)m1).getScaledHeight();
2456            }
2457            videoSize = findVideoResolution(mVideoEditor.getAspectRatio(),
2458                                                                   clip1Height);
2459        }
2460        return videoSize;
2461    }
2462
2463    /**
2464     * Populates the settings for generating an transition clip
2465     *
2466     * @param m1 First media item associated with transition
2467     * @param m2 Second media item associated with transition
2468     * @param e The EditSettings reference containing
2469     * clip specific data
2470     * @param uniqueId The unique id used in the name of the output clip
2471     * @param t The Transition specific data
2472     *
2473     * @return The name and path of generated clip
2474     */
2475    String generateTransitionClip(EditSettings e, String uniqueId,
2476            MediaItem m1, MediaItem m2,Transition t) {
2477        String outputFilename = null;
2478        int err = 0;
2479
2480        outputFilename = String.format(mProjectPath + "/" + uniqueId + ".3gp");
2481        e.outputFile = outputFilename;
2482        e.audioBitrate = Bitrate.BR_64_KBPS;
2483        e.audioChannels = 2;
2484        e.audioFormat = AudioFormat.AAC;
2485        e.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
2486
2487        e.videoBitrate = Bitrate.BR_5_MBPS;
2488        e.videoFormat = VideoFormat.H264;
2489        e.videoFrameRate = VideoFrameRate.FR_30_FPS;
2490        e.videoFrameSize = getTransitionResolution(m1, m2);
2491
2492        if (new File(outputFilename).exists()) {
2493            new File(outputFilename).delete();
2494        }
2495        mProcessingState  = PROCESSING_INTERMEDIATE3;
2496        mProcessingObject = t;
2497        err = generateClip(e);
2498        // Reset the processing state and check for errors
2499        mProcessingState  = PROCESSING_NONE;
2500        if (err != 0) {
2501            throw new RuntimeException("preview generation cannot be completed");
2502        }
2503        return outputFilename;
2504    }
2505
2506    /**
2507     * Populates effects and overlays in EffectSettings structure
2508     * and also adjust the start time and duration of effects and overlays
2509     * w.r.t to total story board time
2510     *
2511     * @param m1 Media item associated with effect
2512     * @param effectSettings The EffectSettings reference containing
2513     * effect specific data
2514     * @param beginCutTime The begin cut time of the clip associated with effect
2515     * @param endCutTime The end cut time of the clip associated with effect
2516     * @param storyBoardTime The current story board time
2517     *
2518     * @return The updated index
2519     */
2520    private int populateEffects(MediaItem m, EffectSettings[] effectSettings, int i,
2521            int beginCutTime, int endCutTime, int storyBoardTime) {
2522        List<Effect> effects = m.getAllEffects();
2523        List<Overlay> overlays = m.getAllOverlays();
2524
2525        if (m.getBeginTransition() != null && m.getBeginTransition().getDuration() > 0
2526                && m.getEndTransition() != null && m.getEndTransition().getDuration() > 0) {
2527            beginCutTime += m.getBeginTransition().getDuration();
2528            endCutTime -= m.getEndTransition().getDuration();
2529        } else if (m.getBeginTransition() == null && m.getEndTransition() != null
2530                && m.getEndTransition().getDuration() > 0) {
2531            endCutTime -= m.getEndTransition().getDuration();
2532        } else if (m.getEndTransition() == null && m.getBeginTransition() != null
2533                && m.getBeginTransition().getDuration() > 0) {
2534            beginCutTime += m.getBeginTransition().getDuration();
2535        }
2536
2537        for (Effect effect : effects) {
2538            if (effect instanceof EffectColor) {
2539                effectSettings[i] = getEffectSettings((EffectColor)effect);
2540                adjustEffectsStartTimeAndDuration(effectSettings[i],
2541                                                      beginCutTime, endCutTime);
2542                effectSettings[i].startTime += storyBoardTime;
2543                i++;
2544            }
2545        }
2546        for (Overlay overlay : overlays) {
2547            effectSettings[i] = getOverlaySettings((OverlayFrame)overlay);
2548            adjustEffectsStartTimeAndDuration(effectSettings[i],
2549                                                      beginCutTime, endCutTime);
2550            effectSettings[i].startTime += storyBoardTime;
2551            i++;
2552        }
2553        return i;
2554    }
2555
2556    /**
2557     * Adjusts the media item boundaries for use in export or preview
2558     *
2559     * @param clipSettings The ClipSettings reference
2560     * @param clipProperties The Properties reference
2561     * @param m The media item
2562     */
2563    private void adjustMediaItemBoundary(ClipSettings clipSettings,
2564                                         Properties clipProperties, MediaItem m) {
2565        if (m.getBeginTransition() != null && m.getBeginTransition().getDuration() > 0
2566                && m.getEndTransition() != null && m.getEndTransition().getDuration() > 0) {
2567
2568            clipSettings.beginCutTime += m.getBeginTransition().getDuration();
2569            clipSettings.endCutTime -= m.getEndTransition().getDuration();
2570
2571        } else if (m.getBeginTransition() == null && m.getEndTransition() != null
2572                && m.getEndTransition().getDuration() > 0) {
2573
2574            clipSettings.endCutTime -= m.getEndTransition().getDuration();
2575
2576        } else if (m.getEndTransition() == null && m.getBeginTransition() != null
2577                && m.getBeginTransition().getDuration() > 0) {
2578
2579            clipSettings.beginCutTime += m.getBeginTransition().getDuration();
2580        }
2581        clipProperties.duration = clipSettings.endCutTime -
2582                                                      clipSettings.beginCutTime;
2583
2584        if (clipProperties.videoDuration != 0) {
2585            clipProperties.videoDuration = clipSettings.endCutTime -
2586                                                      clipSettings.beginCutTime;
2587        }
2588
2589        if (clipProperties.audioDuration != 0) {
2590            clipProperties.audioDuration = clipSettings.endCutTime -
2591                                                      clipSettings.beginCutTime;
2592        }
2593    }
2594
2595    /**
2596     * Generates the transition if transition is present
2597     * and is in invalidated state
2598     *
2599     * @param transition The Transition reference
2600     * @param editSettings The EditSettings reference
2601     * @param clipPropertiesArray The clip Properties array
2602     * @param i The index in clip Properties array for current clip
2603     */
2604    private void generateTransition(Transition transition, EditSettings editSettings,
2605            PreviewClipProperties clipPropertiesArray, int index) {
2606        if (!(transition.isGenerated())) {
2607            transition.generate();
2608        }
2609        editSettings.clipSettingsArray[index] = new ClipSettings();
2610        editSettings.clipSettingsArray[index].clipPath = transition.getFilename();
2611        editSettings.clipSettingsArray[index].fileType = FileType.THREE_GPP;
2612        editSettings.clipSettingsArray[index].beginCutTime = 0;
2613        editSettings.clipSettingsArray[index].endCutTime =
2614                                                  (int)transition.getDuration();
2615        editSettings.clipSettingsArray[index].mediaRendering =
2616                                                   MediaRendering.BLACK_BORDERS;
2617        try {
2618            clipPropertiesArray.clipProperties[index] =
2619                                   getMediaProperties(transition.getFilename());
2620        } catch (Exception e) {
2621            throw new IllegalArgumentException("Unsupported file or file not found");
2622        }
2623        clipPropertiesArray.clipProperties[index].Id = null;
2624        clipPropertiesArray.clipProperties[index].audioVolumeValue = 100;
2625        clipPropertiesArray.clipProperties[index].duration =
2626                                                  (int)transition.getDuration();
2627        if (clipPropertiesArray.clipProperties[index].videoDuration != 0) {
2628            clipPropertiesArray.clipProperties[index].videoDuration =
2629                                                  (int)transition.getDuration();
2630        }
2631        if (clipPropertiesArray.clipProperties[index].audioDuration != 0) {
2632            clipPropertiesArray.clipProperties[index].audioDuration =
2633                                                  (int)transition.getDuration();
2634        }
2635    }
2636
2637    /**
2638     * Sets the volume for current media item in clip properties array
2639     *
2640     * @param m The media item
2641     * @param clipProperties The clip properties array reference
2642     * @param i The index in clip Properties array for current clip
2643     */
2644    private void adjustVolume(MediaItem m, PreviewClipProperties clipProperties,
2645                              int index) {
2646        if (m instanceof MediaVideoItem) {
2647            boolean videoMuted = ((MediaVideoItem)m).isMuted();
2648            if (videoMuted == false) {
2649                mClipProperties.clipProperties[index].audioVolumeValue = ((MediaVideoItem)m)
2650                .getVolume();
2651            } else {
2652                mClipProperties.clipProperties[index].audioVolumeValue = 0;
2653            }
2654        } else if (m instanceof MediaImageItem) {
2655            mClipProperties.clipProperties[index].audioVolumeValue = 0;
2656        }
2657    }
2658
2659    /**
2660     * Checks for odd size image width and height
2661     *
2662     * @param m The media item
2663     * @param clipProperties The clip properties array reference
2664     * @param i The index in clip Properties array for current clip
2665     */
2666    private void checkOddSizeImage(MediaItem m, PreviewClipProperties clipProperties, int index) {
2667        if (m instanceof MediaImageItem) {
2668            int width = mClipProperties.clipProperties[index].width;
2669            int height = mClipProperties.clipProperties[index].height;
2670
2671            if ((width % 2) != 0) {
2672                width -= 1;
2673            }
2674            if ((height % 2) != 0) {
2675                height -= 1;
2676            }
2677            mClipProperties.clipProperties[index].width = width;
2678            mClipProperties.clipProperties[index].height = height;
2679        }
2680    }
2681
2682    /**
2683     * Populates the media item properties and calculates the maximum
2684     * height among all the clips
2685     *
2686     * @param m The media item
2687     * @param i The index in clip Properties array for current clip
2688     * @param maxHeight The max height from the clip properties
2689     *
2690     * @return Updates the max height if current clip's height is greater
2691     * than all previous clips height
2692     */
2693    private int populateMediaItemProperties(MediaItem m, int index, int maxHeight) {
2694        mPreviewEditSettings.clipSettingsArray[index] = new ClipSettings();
2695        if (m instanceof MediaVideoItem) {
2696            mPreviewEditSettings.clipSettingsArray[index] = ((MediaVideoItem)m)
2697            .getVideoClipProperties();
2698            if (((MediaVideoItem)m).getHeight() > maxHeight) {
2699                maxHeight = ((MediaVideoItem)m).getHeight();
2700            }
2701        } else if (m instanceof MediaImageItem) {
2702            mPreviewEditSettings.clipSettingsArray[index] = ((MediaImageItem)m)
2703            .getImageClipProperties();
2704            if (((MediaImageItem)m).getScaledHeight() > maxHeight) {
2705                maxHeight = ((MediaImageItem)m).getScaledHeight();
2706            }
2707        }
2708        /** + Handle the image files here */
2709        if (mPreviewEditSettings.clipSettingsArray[index].fileType == FileType.JPG) {
2710            mPreviewEditSettings.clipSettingsArray[index].clipDecodedPath = ((MediaImageItem)m)
2711            .getDecodedImageFileName();
2712
2713            mPreviewEditSettings.clipSettingsArray[index].clipOriginalPath =
2714                         mPreviewEditSettings.clipSettingsArray[index].clipPath;
2715        }
2716        return maxHeight;
2717    }
2718
2719    /**
2720     * Populates the background music track properties
2721     *
2722     * @param mediaBGMList The background music list
2723     *
2724     */
2725    private void populateBackgroundMusicProperties(List<AudioTrack> mediaBGMList) {
2726
2727        if (mediaBGMList.size() == 1) {
2728            mAudioTrack = mediaBGMList.get(0);
2729        } else
2730        {
2731            mAudioTrack = null;
2732        }
2733
2734        if (mAudioTrack != null) {
2735            mAudioSettings = new AudioSettings();
2736            Properties mAudioProperties = new Properties();
2737            mAudioSettings.pFile = null;
2738            mAudioSettings.Id = mAudioTrack.getId();
2739            try {
2740                mAudioProperties = getMediaProperties(mAudioTrack.getFilename());
2741            } catch (Exception e) {
2742               throw new IllegalArgumentException("Unsupported file or file not found");
2743            }
2744            mAudioSettings.bRemoveOriginal = false;
2745            mAudioSettings.channels = mAudioProperties.audioChannels;
2746            mAudioSettings.Fs = mAudioProperties.audioSamplingFrequency;
2747            mAudioSettings.loop = mAudioTrack.isLooping();
2748            mAudioSettings.ExtendedFs = 0;
2749            mAudioSettings.pFile = mAudioTrack.getFilename();
2750            mAudioSettings.startMs = mAudioTrack.getStartTime();
2751            mAudioSettings.beginCutTime = mAudioTrack.getBoundaryBeginTime();
2752            mAudioSettings.endCutTime = mAudioTrack.getBoundaryEndTime();
2753            if (mAudioTrack.isMuted()) {
2754                mAudioSettings.volume = 0;
2755            } else {
2756                mAudioSettings.volume = mAudioTrack.getVolume();
2757            }
2758            mAudioSettings.fileType = mAudioProperties.fileType;
2759            mAudioSettings.ducking_lowVolume = mAudioTrack.getDuckedTrackVolume();
2760            mAudioSettings.ducking_threshold = mAudioTrack.getDuckingThreshhold();
2761            mAudioSettings.bInDucking_enable = mAudioTrack.isDuckingEnabled();
2762            mAudioTrackPCMFilePath = String.format(mProjectPath + "/" + AUDIO_TRACK_PCM_FILE);
2763            //String.format(mProjectPath + "/" + "AudioPcm" + ".pcm");
2764            mAudioSettings.pcmFilePath = mAudioTrackPCMFilePath;
2765
2766            mPreviewEditSettings.backgroundMusicSettings =
2767                                                  new BackgroundMusicSettings();
2768            mPreviewEditSettings.backgroundMusicSettings.file =
2769                                                         mAudioTrackPCMFilePath;
2770            mPreviewEditSettings.backgroundMusicSettings.fileType =
2771                                                      mAudioProperties.fileType;
2772            mPreviewEditSettings.backgroundMusicSettings.insertionTime =
2773                                                     mAudioTrack.getStartTime();
2774            mPreviewEditSettings.backgroundMusicSettings.volumePercent =
2775                                                        mAudioTrack.getVolume();
2776            mPreviewEditSettings.backgroundMusicSettings.beginLoop = mAudioTrack
2777            .getBoundaryBeginTime();
2778            mPreviewEditSettings.backgroundMusicSettings.endLoop =
2779                                               mAudioTrack.getBoundaryEndTime();
2780            mPreviewEditSettings.backgroundMusicSettings.enableDucking = mAudioTrack
2781            .isDuckingEnabled();
2782            mPreviewEditSettings.backgroundMusicSettings.duckingThreshold = mAudioTrack
2783            .getDuckingThreshhold();
2784            mPreviewEditSettings.backgroundMusicSettings.lowVolume = mAudioTrack
2785            .getDuckedTrackVolume();
2786            mPreviewEditSettings.backgroundMusicSettings.isLooping =
2787                                                        mAudioTrack.isLooping();
2788            mPreviewEditSettings.primaryTrackVolume = 100;
2789            mProcessingState  = PROCESSING_AUDIO_PCM;
2790            mProcessingObject = mAudioTrack;
2791        } else {
2792            if (mAudioSettings != null) {
2793                mAudioSettings = null;
2794            }
2795            if (mPreviewEditSettings.backgroundMusicSettings != null) {
2796                mPreviewEditSettings.backgroundMusicSettings = null;
2797            }
2798            mAudioTrackPCMFilePath = null;
2799        }
2800    }
2801
2802    /**
2803     * Calculates all the effects in all the media items
2804     * in media items list
2805     *
2806     * @param mediaItemsList The media item list
2807     *
2808     * @return The total number of effects
2809     *
2810     */
2811    private int getTotalEffects(List<MediaItem> mediaItemsList) {
2812        int totalEffects = 0;
2813        final Iterator<MediaItem> it = mediaItemsList.iterator();
2814        while (it.hasNext()) {
2815            final MediaItem t = it.next();
2816            totalEffects += t.getAllEffects().size();
2817            totalEffects += t.getAllOverlays().size();
2818            final Iterator<Effect> ef = t.getAllEffects().iterator();
2819            while (ef.hasNext()) {
2820                final Effect e = ef.next();
2821                if (e instanceof EffectKenBurns)
2822                    totalEffects--;
2823            }
2824        }
2825        return totalEffects;
2826    }
2827
2828    /**
2829     * This function is responsible for forming clip settings
2830     * array and clip properties array including transition clips
2831     * and effect settings for preview purpose or export.
2832     *
2833     *
2834     * @param mediaItemsList The media item list
2835     * @param mediaTransitionList The transitions list
2836     * @param mediaBGMList The background music list
2837     * @param listener The MediaProcessingProgressListener
2838     *
2839     */
2840    public void previewStoryBoard(List<MediaItem> mediaItemsList,
2841            List<Transition> mediaTransitionList, List<AudioTrack> mediaBGMList,
2842            MediaProcessingProgressListener listener) {
2843        if (mInvalidatePreviewArray) {
2844            int previewIndex = 0;
2845            int totalEffects = 0;
2846            int storyBoardTime = 0;
2847            int maxHeight = 0;
2848            int beginCutTime = 0;
2849            int endCutTime = 0;
2850            int effectIndex = 0;
2851            Transition lTransition = null;
2852            MediaItem lMediaItem = null;
2853            mPreviewEditSettings = new EditSettings();
2854            mClipProperties = new PreviewClipProperties();
2855            mTotalClips = 0;
2856
2857            mTotalClips = mediaItemsList.size();
2858            for (Transition transition : mediaTransitionList) {
2859                if (transition.getDuration() > 0)
2860                    mTotalClips++;
2861            }
2862
2863            totalEffects = getTotalEffects(mediaItemsList);
2864
2865            mPreviewEditSettings.clipSettingsArray = new ClipSettings[mTotalClips];
2866            mPreviewEditSettings.effectSettingsArray = new EffectSettings[totalEffects];
2867            mClipProperties.clipProperties = new Properties[mTotalClips];
2868
2869            /** record the call back progress listner */
2870            if (listener != null)
2871            {
2872                mMediaProcessingProgressListener = listener;
2873                mProgressToApp = 0;
2874            }
2875
2876            if (mediaItemsList.size() > 0) {
2877                for (int i = 0; i < mediaItemsList.size(); i++) {
2878                    /* Get the Media Item from the list */
2879                    lMediaItem = mediaItemsList.get(i);
2880                    if (lMediaItem instanceof MediaVideoItem) {
2881                        beginCutTime = (int)((MediaVideoItem)lMediaItem).getBoundaryBeginTime();
2882                        endCutTime = (int)((MediaVideoItem)lMediaItem).getBoundaryEndTime();
2883                    } else if (lMediaItem instanceof MediaImageItem) {
2884                        beginCutTime = 0;
2885                        endCutTime = (int)((MediaImageItem)lMediaItem).getTimelineDuration();
2886                    }
2887                    /* Get the transition associated with Media Item */
2888                    lTransition = lMediaItem.getBeginTransition();
2889                    if (lTransition != null && (lTransition.getDuration() > 0)) {
2890                        /* generate transition clip */
2891                        generateTransition(lTransition, mPreviewEditSettings,
2892                                           mClipProperties, previewIndex);
2893                        storyBoardTime += mClipProperties.clipProperties[previewIndex].duration;
2894                        previewIndex++;
2895                    }
2896                    /* Populate media item properties */
2897                    maxHeight = populateMediaItemProperties(lMediaItem,
2898                                                            previewIndex,
2899                                                            maxHeight);
2900                    if (lMediaItem instanceof MediaImageItem)
2901                    {
2902                        int tmpCnt = 0;
2903                        boolean bEffectKbPresent = false;
2904                        List<Effect> effectList = lMediaItem.getAllEffects();
2905                        /**
2906                         * check if Kenburns effect is present
2907                         */
2908                        while ( tmpCnt < effectList.size()) {
2909                            if (effectList.get(tmpCnt) instanceof EffectKenBurns) {
2910                                bEffectKbPresent = true;
2911                                break;
2912                            }
2913                            tmpCnt++;
2914                        }
2915
2916                        if (bEffectKbPresent) {
2917                            try {
2918                                mClipProperties.clipProperties[previewIndex]
2919                                    = getMediaProperties(((MediaImageItem)lMediaItem).getGeneratedImageClip());
2920                            } catch (Exception e) {
2921                                throw new IllegalArgumentException("Unsupported file or file not found");
2922                            }
2923                        } else {
2924                            try {
2925                                mClipProperties.clipProperties[previewIndex]
2926                                    = getMediaProperties(((MediaImageItem)lMediaItem).getScaledImageFileName());
2927                            } catch (Exception e) {
2928                                throw new IllegalArgumentException("Unsupported file or file not found");
2929                            }
2930                            mClipProperties.clipProperties[previewIndex].width = ((MediaImageItem)lMediaItem).getScaledWidth();
2931                            mClipProperties.clipProperties[previewIndex].height = ((MediaImageItem)lMediaItem).getScaledHeight();
2932                        }
2933
2934                    }else
2935                    {
2936                        try {
2937                            mClipProperties.clipProperties[previewIndex]
2938                                 = getMediaProperties(lMediaItem.getFilename());
2939                        } catch (Exception e) {
2940                            throw new IllegalArgumentException("Unsupported file or file not found");
2941                        }
2942                    }
2943                    mClipProperties.clipProperties[previewIndex].Id = lMediaItem.getId();
2944                    checkOddSizeImage(lMediaItem, mClipProperties, previewIndex);
2945                    adjustVolume(lMediaItem, mClipProperties, previewIndex);
2946
2947                    /*
2948                     * Adjust media item start time and end time w.r.t to begin
2949                     * and end transitions associated with media item
2950                     */
2951
2952                    adjustMediaItemBoundary(mPreviewEditSettings.clipSettingsArray[previewIndex],
2953                            mClipProperties.clipProperties[previewIndex], lMediaItem);
2954
2955                    /*
2956                     * Get all the effects and overlays for that media item and
2957                     * adjust start time and duration of effects
2958                     */
2959
2960                    effectIndex = populateEffects(lMediaItem,
2961                            mPreviewEditSettings.effectSettingsArray, effectIndex, beginCutTime,
2962                            endCutTime, storyBoardTime);
2963                    storyBoardTime += mClipProperties.clipProperties[previewIndex].duration;
2964                    previewIndex++;
2965
2966                    /* Check if there is any end transition at last media item */
2967
2968                    if (i == (mediaItemsList.size() - 1)) {
2969                        lTransition = lMediaItem.getEndTransition();
2970                        if (lTransition != null && (lTransition.getDuration() > 0)) {
2971                            generateTransition(lTransition, mPreviewEditSettings, mClipProperties,
2972                                    previewIndex);
2973                            break;
2974                        }
2975                    }
2976                }
2977            }
2978            if (!mErrorFlagSet) {
2979                mPreviewEditSettings.videoFrameSize = findVideoResolution(mVideoEditor
2980                        .getAspectRatio(), maxHeight);
2981                /*if (mediaBGMList.size() == 1) //for remove Audio check */ {
2982                    populateBackgroundMusicProperties(mediaBGMList);
2983                }
2984                /** call to native populate settings */
2985                try {
2986                    nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
2987                } catch (IllegalArgumentException ex) {
2988                    Log.e("MediaArtistNativeHelper",
2989                    "Illegal argument exception in nativePopulateSettings");
2990                    throw ex;
2991                } catch (IllegalStateException ex) {
2992                    Log.e("MediaArtistNativeHelper",
2993                    "Illegal state exception in nativePopulateSettings");
2994                    throw ex;
2995                } catch (RuntimeException ex) {
2996                    Log.e("MediaArtistNativeHelper", "Runtime exception in nativePopulateSettings");
2997                    throw ex;
2998                }
2999                mInvalidatePreviewArray = false;
3000                mProcessingState  = PROCESSING_NONE;
3001            }
3002            if (mErrorFlagSet) {
3003                mErrorFlagSet = false;
3004                throw new RuntimeException("preview generation cannot be completed");
3005            }
3006        }
3007    } /* END of previewStoryBoard */
3008
3009    /**
3010     * This function is responsible for starting the preview
3011     *
3012     *
3013     * @param surface The surface on which preview has to be displayed
3014     * @param fromMs The time in ms from which preview has to be started
3015     * @param toMs The time in ms till preview has to be played
3016     * @param loop To loop the preview or not
3017     * @param callbackAfterFrameCount INdicated after how many frames
3018     * the callback is needed
3019     * @param listener The PreviewProgressListener
3020     *
3021     */
3022    public void doPreview(Surface surface, long fromMs, long toMs, boolean loop,
3023            int callbackAfterFrameCount, PreviewProgressListener listener) {
3024        mPreviewProgress = 0;
3025        if (listener != null) {
3026            mPreviewProgressListener = listener;
3027        }
3028        if (!mInvalidatePreviewArray) {
3029            try {
3030                /** Modify the image files names to rgb image files. */
3031                for (int clipCnt = 0; clipCnt < mPreviewEditSettings.clipSettingsArray.length; clipCnt++) {
3032                    if (mPreviewEditSettings.clipSettingsArray[clipCnt].fileType == FileType.JPG) {
3033                        mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath = mPreviewEditSettings.clipSettingsArray[clipCnt].clipDecodedPath;
3034                    }
3035                }
3036                nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
3037                nativeStartPreview(surface, fromMs, toMs, callbackAfterFrameCount, loop);
3038            } catch (IllegalArgumentException ex) {
3039                Log.e("MediaArtistNativeHelper",
3040                "Illegal argument exception in nativeStartPreview");
3041                throw ex;
3042            } catch (IllegalStateException ex) {
3043                Log.e("MediaArtistNativeHelper", "Illegal state exception in nativeStartPreview");
3044                throw ex;
3045            } catch (RuntimeException ex) {
3046                Log.e("MediaArtistNativeHelper", "Runtime exception in nativeStartPreview");
3047                throw ex;
3048            }
3049
3050        } else {
3051            return;
3052        }
3053    }
3054
3055    /**
3056     * This function is responsible for stopping the preview
3057     */
3058    public long stopPreview() {
3059        nativeStopPreview();
3060        return mPreviewProgress;
3061    }
3062
3063    /**
3064     * This function is responsible for rendering a single frame
3065     * from the complete story board on the surface
3066     *
3067     * @param surface The surface on which frame has to be rendered
3068     * @param time The time in ms at which the frame has to be rendered
3069     * @param surfaceWidth The surface width
3070     * @param surfaceHeight The surface height
3071     *
3072     * @return The actual time from the story board at which the  frame was extracted
3073     * and rendered
3074     */
3075    public long renderPreviewFrame(Surface surface, long time, int surfaceWidth,
3076                                   int surfaceHeight) {
3077        long timeMs = 0;
3078        if (!mInvalidatePreviewArray) {
3079            try {
3080                for (int clipCnt = 0; clipCnt < mPreviewEditSettings.clipSettingsArray.length; clipCnt++) {
3081                    if (mPreviewEditSettings.clipSettingsArray[clipCnt].fileType == FileType.JPG) {
3082                        mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath = mPreviewEditSettings.clipSettingsArray[clipCnt].clipDecodedPath;
3083                    }
3084                }
3085                nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
3086                timeMs = (long)nativeRenderPreviewFrame(surface, time, surfaceWidth, surfaceHeight);
3087            } catch (IllegalArgumentException ex) {
3088                Log.e("MediaArtistNativeHelper",
3089                "Illegal Argument exception in nativeRenderPreviewFrame");
3090                throw ex;
3091            } catch (IllegalStateException ex) {
3092                Log.e("MediaArtistNativeHelper",
3093                "Illegal state exception in nativeRenderPreviewFrame");
3094                throw ex;
3095            } catch (RuntimeException ex) {
3096                Log.e("MediaArtistNativeHelper", "Runtime exception in nativeRenderPreviewFrame");
3097                throw ex;
3098            }
3099            return timeMs;
3100        } else {
3101
3102            throw new RuntimeException("Call generate preview first");
3103        }
3104    }
3105
3106    /**
3107     * This function is responsible for rendering a single frame
3108     * from a single media item on the surface
3109     *
3110     * @param surface The surface on which frame has to be rendered
3111     * @param filepath The file path for which the frame needs to be displayed
3112     * @param time The time in ms at which the frame has to be rendered
3113     * @param framewidth The frame width
3114     * @param framewidth The frame height
3115     *
3116     * @return The actual time from media item at which the  frame was extracted
3117     * and rendered
3118     */
3119    public long renderMediaItemPreviewFrame(Surface surface, String filepath,
3120                                            long time, int framewidth,
3121                                            int frameheight) {
3122        long timeMs = 0;
3123        try {
3124
3125            timeMs = (long)nativeRenderMediaItemPreviewFrame(surface, filepath, framewidth,
3126                    frameheight, 0, 0, time);
3127        } catch (IllegalArgumentException ex) {
3128            Log.e("MediaArtistNativeHelper",
3129            "Illegal Argument exception in renderMediaItemPreviewFrame");
3130            throw ex;
3131        } catch (IllegalStateException ex) {
3132            Log.e("MediaArtistNativeHelper",
3133            "Illegal state exception in renderMediaItemPreviewFrame");
3134            throw ex;
3135        } catch (RuntimeException ex) {
3136            Log.e("MediaArtistNativeHelper", "Runtime exception in renderMediaItemPreviewFrame");
3137            throw ex;
3138        }
3139
3140        return timeMs;
3141    }
3142
3143    /**
3144     * This function sets the flag to invalidate the preview array
3145     * and for generating the preview again
3146     */
3147    void setGeneratePreview(boolean isRequired) {
3148        mInvalidatePreviewArray = isRequired;
3149    }
3150
3151    /**
3152     * @return Returns the current status of preview invalidation
3153     * flag
3154     */
3155    boolean getGeneratePreview() {
3156        return mInvalidatePreviewArray;
3157    }
3158
3159    /**
3160     * Calculates the aspect ratio from widht and height
3161     *
3162     * @param w The width of media item
3163     * @param h The height of media item
3164     *
3165     * @return The calculated aspect ratio
3166     */
3167    public int getAspectRatio(int w, int h) {
3168        double apRatio = (double)(w) / (double)(h);
3169        BigDecimal bd = new BigDecimal(apRatio);
3170        bd = bd.setScale(3, BigDecimal.ROUND_HALF_UP);
3171        apRatio = bd.doubleValue();
3172        int var = MediaProperties.ASPECT_RATIO_16_9;
3173        if (apRatio >= 1.7) {
3174            var = MediaProperties.ASPECT_RATIO_16_9;
3175        } else if (apRatio >= 1.6) {
3176            var = MediaProperties.ASPECT_RATIO_5_3;
3177        } else if (apRatio >= 1.5) {
3178            var = MediaProperties.ASPECT_RATIO_3_2;
3179        } else if (apRatio > 1.3) {
3180            var = MediaProperties.ASPECT_RATIO_4_3;
3181        } else if (apRatio >= 1.2) {
3182            var = MediaProperties.ASPECT_RATIO_11_9;
3183        }
3184        return var;
3185    }
3186
3187    /**
3188     * Maps the file type used in native layer
3189     * to file type used in JAVA layer
3190     *
3191     * @param fileType The file type in native layer
3192     *
3193     * @return The File type in JAVA layer
3194     */
3195    public int getFileType(int fileType) {
3196        int retValue = -1;
3197        switch (fileType) {
3198            case FileType.UNSUPPORTED:
3199                retValue = MediaProperties.FILE_UNSUPPORTED;
3200                break;
3201            case FileType.THREE_GPP:
3202                retValue = MediaProperties.FILE_3GP;
3203                break;
3204            case FileType.MP4:
3205                retValue = MediaProperties.FILE_MP4;
3206                break;
3207            case FileType.JPG:
3208                retValue = MediaProperties.FILE_JPEG;
3209                break;
3210            case FileType.PNG:
3211                retValue = MediaProperties.FILE_PNG;
3212                break;
3213            case FileType.MP3:
3214                retValue = MediaProperties.FILE_MP3;
3215                break;
3216
3217            default:
3218                retValue = -1;
3219        }
3220        return retValue;
3221    }
3222
3223    /**
3224     * Maps the video codec type used in native layer
3225     * to video codec type used in JAVA layer
3226     *
3227     * @param codecType The video codec type in native layer
3228     *
3229     * @return The video codec type in JAVA layer
3230     */
3231    public int getVideoCodecType(int codecType) {
3232        int retValue = -1;
3233        switch (codecType) {
3234            case VideoFormat.H263:
3235                retValue = MediaProperties.VCODEC_H263;
3236                break;
3237            case VideoFormat.H264:
3238                retValue = MediaProperties.VCODEC_H264BP;
3239                break;
3240            case VideoFormat.MPEG4:
3241                retValue = MediaProperties.VCODEC_MPEG4;
3242                break;
3243            case VideoFormat.UNSUPPORTED:
3244
3245            default:
3246                retValue = -1;
3247        }
3248        return retValue;
3249    }
3250
3251    /**
3252     * Maps the audio codec type used in native layer
3253     * to audio codec type used in JAVA layer
3254     *
3255     * @param audioType The audio codec type in native layer
3256     *
3257     * @return The audio codec type in JAVA layer
3258     */
3259    public int getAudioCodecType(int codecType) {
3260        int retValue = -1;
3261        switch (codecType) {
3262            case AudioFormat.AMR_NB:
3263                retValue = MediaProperties.ACODEC_AMRNB;
3264                break;
3265            case AudioFormat.AAC:
3266                retValue = MediaProperties.ACODEC_AAC_LC;
3267                break;
3268            case AudioFormat.MP3:
3269                retValue = MediaProperties.ACODEC_MP3;
3270                break;
3271
3272            default:
3273                retValue = -1;
3274        }
3275        return retValue;
3276    }
3277
3278    /**
3279     * Returns the frame rate as integer
3280     *
3281     * @param fps The fps as enum
3282     *
3283     * @return The frame rate as integer
3284     */
3285    public int getFrameRate(int fps) {
3286        int retValue = -1;
3287        switch (fps) {
3288            case VideoFrameRate.FR_5_FPS:
3289                retValue = 5;
3290                break;
3291            case VideoFrameRate.FR_7_5_FPS:
3292                retValue = 8;
3293                break;
3294            case VideoFrameRate.FR_10_FPS:
3295                retValue = 10;
3296                break;
3297            case VideoFrameRate.FR_12_5_FPS:
3298                retValue = 13;
3299                break;
3300            case VideoFrameRate.FR_15_FPS:
3301                retValue = 15;
3302                break;
3303            case VideoFrameRate.FR_20_FPS:
3304                retValue = 20;
3305                break;
3306            case VideoFrameRate.FR_25_FPS:
3307                retValue = 25;
3308                break;
3309            case VideoFrameRate.FR_30_FPS:
3310                retValue = 30;
3311                break;
3312
3313            default:
3314                retValue = -1;
3315        }
3316        return retValue;
3317    }
3318
3319    /**
3320     * Maps the file type used in JAVA layer
3321     * to file type used in native layer
3322     *
3323     * @param fileType The file type in JAVA layer
3324     *
3325     * @return The File type in native layer
3326     */
3327    int getMediaItemFileType(int fileType) {
3328        int retValue = -1;
3329
3330        switch (fileType) {
3331            case MediaProperties.FILE_UNSUPPORTED:
3332                retValue = FileType.UNSUPPORTED;
3333                break;
3334            case MediaProperties.FILE_3GP:
3335                retValue = FileType.THREE_GPP;
3336                break;
3337            case MediaProperties.FILE_MP4:
3338                retValue = FileType.MP4;
3339                break;
3340            case MediaProperties.FILE_JPEG:
3341                retValue = FileType.JPG;
3342                break;
3343            case MediaProperties.FILE_PNG:
3344                retValue = FileType.PNG;
3345                break;
3346
3347            default:
3348                retValue = -1;
3349        }
3350        return retValue;
3351
3352    }
3353
3354    /**
3355     * Maps the rendering mode used in native layer
3356     * to rendering mode used in JAVA layer
3357     *
3358     * @param renderingMode The rendering mode in JAVA layer
3359     *
3360     * @return The rendering mode in native layer
3361     */
3362    int getMediaItemRenderingMode(int renderingMode) {
3363        int retValue = -1;
3364        switch (renderingMode) {
3365            case MediaItem.RENDERING_MODE_BLACK_BORDER:
3366                retValue = MediaRendering.BLACK_BORDERS;
3367                break;
3368            case MediaItem.RENDERING_MODE_STRETCH:
3369                retValue = MediaRendering.RESIZING;
3370                break;
3371            case MediaItem.RENDERING_MODE_CROPPING:
3372                retValue = MediaRendering.CROPPING;
3373                break;
3374
3375            default:
3376                retValue = -1;
3377        }
3378        return retValue;
3379    }
3380
3381    /**
3382     * Maps the transition behavior used in JAVA layer
3383     * to transition behavior used in native layer
3384     *
3385     * @param transitionType The transition behavior in JAVA layer
3386     *
3387     * @return The transition behavior in native layer
3388     */
3389    int getVideoTransitionBehaviour(int transitionType) {
3390        int retValue = -1;
3391        switch (transitionType) {
3392            case Transition.BEHAVIOR_SPEED_UP:
3393                retValue = TransitionBehaviour.SPEED_UP;
3394                break;
3395            case Transition.BEHAVIOR_SPEED_DOWN:
3396                retValue = TransitionBehaviour.SPEED_DOWN;
3397                break;
3398            case Transition.BEHAVIOR_LINEAR:
3399                retValue = TransitionBehaviour.LINEAR;
3400                break;
3401            case Transition.BEHAVIOR_MIDDLE_SLOW:
3402                retValue = TransitionBehaviour.SLOW_MIDDLE;
3403                break;
3404            case Transition.BEHAVIOR_MIDDLE_FAST:
3405                retValue = TransitionBehaviour.FAST_MIDDLE;
3406                break;
3407
3408            default:
3409                retValue = -1;
3410        }
3411        return retValue;
3412    }
3413
3414    /**
3415     * Maps the transition slide direction used in JAVA layer
3416     * to transition slide direction used in native layer
3417     *
3418     * @param slideDirection The transition slide direction
3419     * in JAVA layer
3420     *
3421     * @return The transition slide direction in native layer
3422     */
3423    int getSlideSettingsDirection(int slideDirection) {
3424        int retValue = -1;
3425        switch (slideDirection) {
3426            case TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN:
3427                retValue = SlideDirection.RIGHT_OUT_LEFT_IN;
3428                break;
3429            case TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN:
3430                retValue = SlideDirection.LEFT_OUT_RIGTH_IN;
3431                break;
3432            case TransitionSliding.DIRECTION_TOP_OUT_BOTTOM_IN:
3433                retValue = SlideDirection.TOP_OUT_BOTTOM_IN;
3434                break;
3435            case TransitionSliding.DIRECTION_BOTTOM_OUT_TOP_IN:
3436                retValue = SlideDirection.BOTTOM_OUT_TOP_IN;
3437                break;
3438
3439            default:
3440                retValue = -1;
3441        }
3442        return retValue;
3443    }
3444
3445    /**
3446     * Maps the effect color type used in JAVA layer
3447     * to effect color type used in native layer
3448     *
3449     * @param effect The EffectColor reference
3450     *
3451     * @return The color effect value from native layer
3452     */
3453    private int getEffectColorType(EffectColor effect) {
3454        int retValue = -1;
3455        switch (effect.getType()) {
3456            case EffectColor.TYPE_COLOR:
3457                if (effect.getColor() == EffectColor.GREEN) {
3458                    retValue = VideoEffect.GREEN;
3459                } else if (effect.getColor() == EffectColor.PINK) {
3460                    retValue = VideoEffect.PINK;
3461                } else if (effect.getColor() == EffectColor.GRAY) {
3462                    retValue = VideoEffect.BLACK_AND_WHITE;
3463                } else {
3464                    retValue = VideoEffect.COLORRGB16;
3465                }
3466                break;
3467            case EffectColor.TYPE_GRADIENT:
3468                retValue = VideoEffect.GRADIENT;
3469                break;
3470            case EffectColor.TYPE_SEPIA:
3471                retValue = VideoEffect.SEPIA;
3472                break;
3473            case EffectColor.TYPE_NEGATIVE:
3474                retValue = VideoEffect.NEGATIVE;
3475                break;
3476            case EffectColor.TYPE_FIFTIES:
3477                retValue = VideoEffect.FIFTIES;
3478                break;
3479
3480            default:
3481                retValue = -1;
3482        }
3483        return retValue;
3484    }
3485
3486    /**
3487     * Calculates videdo resolution for output clip
3488     * based on clip's height and aspect ratio of storyboard
3489     *
3490     * @param aspectRatio The aspect ratio of story board
3491     * @param height The height of clip
3492     *
3493     * @return The video resolution
3494     */
3495    private int findVideoResolution(int aspectRatio, int height) {
3496        final Pair<Integer, Integer>[] resolutions;
3497        final Pair<Integer, Integer> maxResolution;
3498        int retValue = VideoFrameSize.SIZE_UNDEFINED;
3499        switch (aspectRatio) {
3500            case MediaProperties.ASPECT_RATIO_3_2:
3501                if (height == MediaProperties.HEIGHT_480)
3502                    retValue = VideoFrameSize.NTSC;
3503                else if (height == MediaProperties.HEIGHT_720)
3504                    retValue = VideoFrameSize.W720p;
3505                break;
3506            case MediaProperties.ASPECT_RATIO_16_9:
3507                if (height == MediaProperties.HEIGHT_480)
3508                    retValue = VideoFrameSize.WVGA16x9;
3509                else if (height == MediaProperties.HEIGHT_720)
3510                    retValue = VideoFrameSize.V720p;
3511                break;
3512            case MediaProperties.ASPECT_RATIO_4_3:
3513                if (height == MediaProperties.HEIGHT_480)
3514                    retValue = VideoFrameSize.VGA;
3515                if (height == MediaProperties.HEIGHT_720)
3516                    retValue = VideoFrameSize.S720p;
3517                break;
3518            case MediaProperties.ASPECT_RATIO_5_3:
3519                if (height == MediaProperties.HEIGHT_480)
3520                    retValue = VideoFrameSize.WVGA;
3521                break;
3522            case MediaProperties.ASPECT_RATIO_11_9:
3523                if (height == MediaProperties.HEIGHT_144)
3524                    retValue = VideoFrameSize.QCIF;
3525                break;
3526        }
3527        if (retValue == VideoFrameSize.SIZE_UNDEFINED) {
3528            resolutions = MediaProperties.getSupportedResolutions(mVideoEditor.getAspectRatio());
3529            // Get the highest resolution
3530            maxResolution = resolutions[resolutions.length - 1];
3531            retValue = findVideoResolution(mVideoEditor.getAspectRatio(),
3532                                           maxResolution.second);
3533        }
3534
3535        return retValue;
3536    }
3537
3538    /**
3539     * This method is responsible for exporting a movie
3540     *
3541     * @param filePath The output file path
3542     * @param projectDir The output project directory
3543     * @param height The height of clip
3544     * @param bitrate The bitrate at which the movie should be exported
3545     * @param mediaItemsList The media items list
3546     * @param mediaTransitionList The transitons list
3547     * @param mediaBGMList The background track list
3548     * @param listener The ExportProgressListener
3549     *
3550     */
3551    public void export(String filePath, String projectDir, int height, int bitrate,
3552            List<MediaItem> mediaItemsList, List<Transition> mediaTransitionList,
3553            List<AudioTrack> mediaBGMList, ExportProgressListener listener) {
3554
3555        int outBitrate = 0;
3556        mExportFilename = filePath;
3557        previewStoryBoard(mediaItemsList, mediaTransitionList, mediaBGMList,null);
3558        if (listener != null) {
3559            mExportProgressListener = listener;
3560        }
3561        mProgressToApp = 0;
3562
3563        switch (bitrate) {
3564            case MediaProperties.BITRATE_28K:
3565                outBitrate = Bitrate.BR_32_KBPS;
3566                break;
3567            case MediaProperties.BITRATE_40K:
3568                outBitrate = Bitrate.BR_48_KBPS;
3569                break;
3570            case MediaProperties.BITRATE_64K:
3571                outBitrate = Bitrate.BR_64_KBPS;
3572                break;
3573            case MediaProperties.BITRATE_96K:
3574                outBitrate = Bitrate.BR_96_KBPS;
3575                break;
3576            case MediaProperties.BITRATE_128K:
3577                outBitrate = Bitrate.BR_128_KBPS;
3578                break;
3579            case MediaProperties.BITRATE_192K:
3580                outBitrate = Bitrate.BR_192_KBPS;
3581                break;
3582            case MediaProperties.BITRATE_256K:
3583                outBitrate = Bitrate.BR_256_KBPS;
3584                break;
3585            case MediaProperties.BITRATE_384K:
3586                outBitrate = Bitrate.BR_384_KBPS;
3587                break;
3588            case MediaProperties.BITRATE_512K:
3589                outBitrate = Bitrate.BR_512_KBPS;
3590                break;
3591            case MediaProperties.BITRATE_800K:
3592                outBitrate = Bitrate.BR_800_KBPS;
3593                break;
3594            case MediaProperties.BITRATE_2M:
3595                outBitrate = Bitrate.BR_2_MBPS;
3596                break;
3597
3598            case MediaProperties.BITRATE_5M:
3599                outBitrate = Bitrate.BR_5_MBPS;
3600                break;
3601            case MediaProperties.BITRATE_8M:
3602                outBitrate = Bitrate.BR_8_MBPS;
3603                break;
3604
3605            default:
3606                throw new IllegalArgumentException("Argument Bitrate incorrect");
3607        }
3608        mPreviewEditSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
3609        mPreviewEditSettings.outputFile = mOutputFilename = filePath;
3610
3611        int aspectRatio = mVideoEditor.getAspectRatio();
3612        mPreviewEditSettings.videoFrameSize = findVideoResolution(aspectRatio, height);
3613        mPreviewEditSettings.videoFormat = VideoFormat.H264;
3614        mPreviewEditSettings.audioFormat = AudioFormat.AAC;
3615        mPreviewEditSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
3616        mPreviewEditSettings.maxFileSize = 0;
3617        mPreviewEditSettings.audioChannels = 2;
3618        mPreviewEditSettings.videoBitrate = outBitrate;
3619        mPreviewEditSettings.audioBitrate = Bitrate.BR_96_KBPS;
3620
3621        mPreviewEditSettings.transitionSettingsArray = new TransitionSettings[mTotalClips - 1];
3622        for (int index = 0; index < mTotalClips - 1; index++) {
3623            mPreviewEditSettings.transitionSettingsArray[index] = new TransitionSettings();
3624            mPreviewEditSettings.transitionSettingsArray[index].videoTransitionType = VideoTransition.NONE;
3625            mPreviewEditSettings.transitionSettingsArray[index].audioTransitionType = AudioTransition.NONE;
3626        }
3627        for (int clipCnt = 0; clipCnt < mPreviewEditSettings.clipSettingsArray.length; clipCnt++) {
3628            if (mPreviewEditSettings.clipSettingsArray[clipCnt].fileType == FileType.JPG) {
3629                mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath =
3630                mPreviewEditSettings.clipSettingsArray[clipCnt].clipOriginalPath;
3631            }
3632        }
3633        nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
3634
3635        int err = 0;
3636        try {
3637            mProcessingState  = PROCESSING_EXPORT;
3638            mProcessingObject = null;
3639            err = generateClip(mPreviewEditSettings);
3640            mProcessingState  = PROCESSING_NONE;
3641        } catch (IllegalArgumentException ex) {
3642            Log.e("MediaArtistNativeHelper", "IllegalArgument for generateClip");
3643            throw ex;
3644        } catch (IllegalStateException ex) {
3645            Log.e("MediaArtistNativeHelper", "IllegalStateExceptiont for generateClip");
3646            throw ex;
3647        } catch (RuntimeException ex) {
3648            Log.e("MediaArtistNativeHelper", "RuntimeException for generateClip");
3649            throw ex;
3650        }
3651
3652        if (err != 0) {
3653            Log.e("MediaArtistNativeHelper", "RuntimeException for generateClip");
3654            throw new RuntimeException("generateClip failed with error="+err );
3655        }
3656
3657        mExportDone = true;
3658        setGeneratePreview(true);
3659        mExportProgressListener = null;
3660    }
3661
3662    /**
3663     * This method is responsible for exporting a movie
3664     *
3665     * @param filePath The output file path
3666     * @param projectDir The output project directory
3667     * @param height The height of clip
3668     * @param bitrate The bitrate at which the movie should be exported
3669     * @param audioCodec The audio codec to use
3670     * @param videoCodec The video codec to use
3671     * @param mediaItemsList The media items list
3672     * @param mediaTransitionList The transitons list
3673     * @param mediaBGMList The background track list
3674     * @param listener The ExportProgressListener
3675     *
3676     */
3677    public void export(String filePath, String projectDir,int height,int bitrate,
3678            int audioCodec,int videoCodec,List<MediaItem> mediaItemsList,
3679            List<Transition> mediaTransitionList,List<AudioTrack> mediaBGMList,
3680            ExportProgressListener listener) {
3681
3682        int outBitrate = 0;
3683        mExportFilename = filePath;
3684        previewStoryBoard(mediaItemsList, mediaTransitionList, mediaBGMList,null);
3685        if (listener != null) {
3686            mExportProgressListener = listener;
3687        }
3688        mProgressToApp = 0;
3689
3690        switch (bitrate) {
3691            case MediaProperties.BITRATE_28K:
3692                outBitrate = Bitrate.BR_32_KBPS;
3693                break;
3694            case MediaProperties.BITRATE_40K:
3695                outBitrate = Bitrate.BR_48_KBPS;
3696                break;
3697            case MediaProperties.BITRATE_64K:
3698                outBitrate = Bitrate.BR_64_KBPS;
3699                break;
3700            case MediaProperties.BITRATE_96K:
3701                outBitrate = Bitrate.BR_96_KBPS;
3702                break;
3703            case MediaProperties.BITRATE_128K:
3704                outBitrate = Bitrate.BR_128_KBPS;
3705                break;
3706            case MediaProperties.BITRATE_192K:
3707                outBitrate = Bitrate.BR_192_KBPS;
3708                break;
3709            case MediaProperties.BITRATE_256K:
3710                outBitrate = Bitrate.BR_256_KBPS;
3711                break;
3712            case MediaProperties.BITRATE_384K:
3713                outBitrate = Bitrate.BR_384_KBPS;
3714                break;
3715            case MediaProperties.BITRATE_512K:
3716                outBitrate = Bitrate.BR_512_KBPS;
3717                break;
3718            case MediaProperties.BITRATE_800K:
3719                outBitrate = Bitrate.BR_800_KBPS;
3720                break;
3721            case MediaProperties.BITRATE_2M:
3722                outBitrate = Bitrate.BR_2_MBPS;
3723                break;
3724            case MediaProperties.BITRATE_5M:
3725                outBitrate = Bitrate.BR_5_MBPS;
3726                break;
3727            case MediaProperties.BITRATE_8M:
3728                outBitrate = Bitrate.BR_8_MBPS;
3729                break;
3730
3731            default:
3732                throw new IllegalArgumentException("Argument Bitrate incorrect");
3733        }
3734        mPreviewEditSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
3735        mPreviewEditSettings.outputFile = mOutputFilename = filePath;
3736
3737        int aspectRatio = mVideoEditor.getAspectRatio();
3738        mPreviewEditSettings.videoFrameSize = findVideoResolution(aspectRatio, height);
3739        switch (audioCodec) {
3740            case MediaProperties.ACODEC_AAC_LC:
3741                mPreviewEditSettings.audioFormat = AudioFormat.AAC;
3742                break;
3743            case MediaProperties.ACODEC_AMRNB:
3744                mPreviewEditSettings.audioFormat = AudioFormat.AMR_NB;
3745                break;
3746        }
3747
3748        switch (videoCodec) {
3749            case MediaProperties.VCODEC_H263:
3750                mPreviewEditSettings.videoFormat = VideoFormat.H263;
3751                break;
3752            case MediaProperties.VCODEC_H264BP:
3753                mPreviewEditSettings.videoFormat = VideoFormat.H264;
3754                break;
3755            case MediaProperties.VCODEC_MPEG4:
3756                mPreviewEditSettings.videoFormat = VideoFormat.MPEG4;
3757                break;
3758        }
3759
3760        mPreviewEditSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
3761        mPreviewEditSettings.maxFileSize = 0;
3762        mPreviewEditSettings.audioChannels = 2;
3763        mPreviewEditSettings.videoBitrate = outBitrate;
3764        mPreviewEditSettings.audioBitrate = Bitrate.BR_96_KBPS;
3765
3766        mPreviewEditSettings.transitionSettingsArray =
3767                                        new TransitionSettings[mTotalClips - 1];
3768        for (int index = 0; index < mTotalClips - 1; index++) {
3769            mPreviewEditSettings.transitionSettingsArray[index] =
3770                                                       new TransitionSettings();
3771            mPreviewEditSettings.transitionSettingsArray[index].videoTransitionType =
3772                                                                      VideoTransition.NONE;
3773            mPreviewEditSettings.transitionSettingsArray[index].audioTransitionType =
3774                                                                      AudioTransition.NONE;
3775        }
3776        for (int clipCnt = 0; clipCnt < mPreviewEditSettings.clipSettingsArray.length; clipCnt++) {
3777            if (mPreviewEditSettings.clipSettingsArray[clipCnt].fileType == FileType.JPG) {
3778                mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath =
3779                  mPreviewEditSettings.clipSettingsArray[clipCnt].clipOriginalPath;
3780            }
3781        }
3782        nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
3783
3784        int err = 0;
3785        try {
3786            mProcessingState  = PROCESSING_EXPORT;
3787            mProcessingObject = null;
3788            err = generateClip(mPreviewEditSettings);
3789            mProcessingState  = PROCESSING_NONE;
3790        } catch (IllegalArgumentException ex) {
3791            Log.e("MediaArtistNativeHelper", "IllegalArgument for generateClip");
3792            throw ex;
3793        } catch (IllegalStateException ex) {
3794            Log.e("MediaArtistNativeHelper", "IllegalStateExceptiont for generateClip");
3795            throw ex;
3796        } catch (RuntimeException ex) {
3797            Log.e("MediaArtistNativeHelper", "RuntimeException for generateClip");
3798            throw ex;
3799        }
3800
3801        if (err != 0) {
3802            Log.e("MediaArtistNativeHelper", "RuntimeException for generateClip");
3803            throw new RuntimeException("generateClip failed with error="+err );
3804        }
3805
3806        mExportDone = true;
3807        setGeneratePreview(true);
3808        mExportProgressListener = null;
3809    }
3810
3811
3812    /**
3813     * This methods takes care of stopping the Export process
3814     *
3815     * @param The input file name for which export has to be stopped
3816     */
3817    public void stop(String filename) {
3818        if (!mExportDone) {
3819            try {
3820                stopEncoding();
3821            } catch (IllegalStateException ex) {
3822                Log.e("MediaArtistNativeHelper", "Illegal state exception in unload settings");
3823                throw ex;
3824            } catch (RuntimeException ex) {
3825                Log.e("MediaArtistNativeHelper", "Runtime exception in unload settings");
3826                throw ex;
3827            }
3828
3829            new File(mExportFilename).delete();
3830        }
3831    }
3832
3833    /**
3834     * This method extracts a frame from the input file
3835     * and returns the frame as a bitmap
3836     *
3837     * @param inputFile The inputFile
3838     * @param width The width of the output frame
3839     * @param height The height of the output frame
3840     * @param timeMS The time in ms at which the frame hass to be extracted
3841     */
3842    public Bitmap getPixels(String inputFile, int width, int height, long timeMS) {
3843        if (inputFile == null) {
3844            throw new IllegalArgumentException();
3845        }
3846
3847        int newWidth = 0;
3848        int newHeight = 0;
3849        Bitmap tempBitmap = null;
3850
3851        /* Make width and height as even */
3852        newWidth = (width + 1) & 0xFFFFFFFE;
3853        newHeight = (height + 1) & 0xFFFFFFFE;
3854
3855        /* Create a temp bitmap for resized thumbnails */
3856        if ((newWidth != width) || (newHeight != height)) {
3857             tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
3858        }
3859
3860        IntBuffer rgb888 = IntBuffer.allocate(newWidth * newHeight * 4);
3861        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
3862        nativeGetPixels(inputFile, rgb888.array(), newWidth, newHeight, timeMS);
3863
3864        if ((newWidth == width) && (newHeight == height)) {
3865            bitmap.copyPixelsFromBuffer(rgb888);
3866        } else {
3867            /* Create a temp bitmap to be used for resize */
3868            tempBitmap.copyPixelsFromBuffer(rgb888);
3869
3870            /* Create a canvas to resize */
3871            final Canvas canvas = new Canvas(bitmap);
3872            canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
3873                                          new Rect(0, 0, width, height),
3874                                          sResizePaint);
3875        }
3876
3877        if (tempBitmap != null) {
3878            tempBitmap.recycle();
3879        }
3880        return bitmap;
3881    }
3882
3883    /**
3884     * This method extracts a list of frame from the
3885     * input file and returns the frame in bitmap array
3886     *
3887     * @param filename The inputFile
3888     * @param width The width of the output frame
3889     * @param height The height of the output frame
3890     * @param startMs The starting time in ms
3891     * @param endMs The end time in ms
3892     * @param thumbnailCount The number of frames to be extracted
3893     * from startMs to endMs
3894     *
3895     * @return The frames as bitmaps in bitmap array
3896     **/
3897    public Bitmap[] getPixelsList(String filename, int width, int height, long startMs, long endMs,
3898            int thumbnailCount) {
3899        int[] rgb888 = null;
3900        int thumbnailSize = 0;
3901        int newWidth = 0;
3902        int newHeight = 0;
3903        Bitmap tempBitmap = null;
3904
3905        /* Make width and height as even */
3906        newWidth = (width + 1) & 0xFFFFFFFE;
3907        newHeight = (height + 1) & 0xFFFFFFFE;
3908        thumbnailSize = newWidth * newHeight * 4;
3909
3910        /* Create a temp bitmap for resized thumbnails */
3911        if ((newWidth != width) || (newHeight != height)) {
3912            tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
3913        }
3914        int i = 0;
3915        int deltaTime = (int)(endMs - startMs) / thumbnailCount;
3916        Bitmap[] bitmap = null;
3917
3918        try {
3919            // This may result in out of Memory Error
3920            rgb888 = new int[thumbnailSize * thumbnailCount];
3921            bitmap = new Bitmap[thumbnailCount];
3922        } catch (Throwable e) {
3923            // Allocating to new size with Fixed count
3924            try {
3925                System.gc();
3926                rgb888 = new int[thumbnailSize * MAX_THUMBNAIL_PERMITTED];
3927                bitmap = new Bitmap[MAX_THUMBNAIL_PERMITTED];
3928                thumbnailCount = MAX_THUMBNAIL_PERMITTED;
3929            } catch (Throwable ex) {
3930                throw new RuntimeException("Memory allocation fails, thumbnail count too large: "+thumbnailCount);
3931            }
3932        }
3933        IntBuffer tmpBuffer = IntBuffer.allocate(thumbnailSize);
3934        nativeGetPixelsList(filename, rgb888, newWidth, newHeight, deltaTime, thumbnailCount, startMs,
3935                endMs);
3936
3937        for (; i < thumbnailCount; i++) {
3938            bitmap[i] = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
3939            tmpBuffer.put(rgb888, (i * thumbnailSize), thumbnailSize);
3940            tmpBuffer.rewind();
3941
3942            if ((newWidth == width) && (newHeight == height)) {
3943                bitmap[i].copyPixelsFromBuffer(tmpBuffer);
3944            } else {
3945                /* Copy the out rgb buffer to temp bitmap */
3946                tempBitmap.copyPixelsFromBuffer(tmpBuffer);
3947
3948                /* Create a canvas to resize */
3949                final Canvas canvas = new Canvas(bitmap[i]);
3950                canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
3951                                              new Rect(0, 0, width, height),
3952                                              sResizePaint);
3953            }
3954        }
3955
3956        if (tempBitmap != null) {
3957            tempBitmap.recycle();
3958        }
3959        return bitmap;
3960    }
3961
3962    /**
3963     * This method generates the audio graph
3964     *
3965     * @param uniqueId The unique id
3966     * @param inFileName The inputFile
3967     * @param OutAudiGraphFileName output filename
3968     * @param frameDuration The each frame duration
3969     * @param audioChannels The number of audio channels
3970     * @param samplesCount Total number of samples count
3971     * @param listener ExtractAudioWaveformProgressListener reference
3972     * @param isVideo The flag to indicate if the file is video file or not
3973     *
3974     **/
3975    public void generateAudioGraph(String uniqueId, String inFileName, String OutAudiGraphFileName,
3976            int frameDuration, int audioChannels, int samplesCount,
3977            ExtractAudioWaveformProgressListener listener, boolean isVideo) {
3978        String tempPCMFileName;
3979
3980        if (listener != null) {
3981            mExtractAudioWaveformProgressListener = listener;
3982        }
3983        /**
3984         * in case of Video , first call will generate the PCM file to make the
3985         * audio graph
3986         */
3987        if (isVideo) {
3988            tempPCMFileName = String.format(mProjectPath + "/" + uniqueId + ".pcm");
3989        } else {
3990            tempPCMFileName = mAudioTrackPCMFilePath;
3991        }
3992        /**
3993         * For Video item, generate the PCM
3994         */
3995        if (isVideo) {
3996            nativeGenerateRawAudio(inFileName, tempPCMFileName);
3997        }
3998
3999        nativeGenerateAudioGraph(tempPCMFileName, OutAudiGraphFileName, frameDuration,
4000                audioChannels, samplesCount);
4001
4002        /* once the audio graph file is generated, delete the pcm file */
4003        if (isVideo) {
4004            new File(tempPCMFileName).delete();
4005        }
4006    }
4007
4008    public void clearPreviewSurface(Surface surface, int width, int height) {
4009       nativeClearSurface(surface,width,height);
4010    }
4011    /**     Native Methods        */
4012
4013    public native Properties getMediaProperties(String file) throws IllegalArgumentException,
4014    IllegalStateException, RuntimeException, Exception;
4015
4016    /**
4017     * Get the version of ManualEdit.
4018     *
4019     * @return version of ManualEdit
4020     * @throws RuntimeException if an error occurred
4021     * @see Version
4022     */
4023    public static native Version getVersion() throws RuntimeException;
4024
4025    /**
4026     * Returns the video thumbnail in an array of integers. Output format is
4027     * ARGB8888.
4028     *
4029     * @param pixelArray the array that receives the pixelvalues
4030     * @param width width of the video thumbnail
4031     * @param height height of the video thumbnail
4032     * @param timeMS desired time of the thumbnail in ms
4033     * @return actual time in ms of the thumbnail generated
4034     * @throws IllegalStateException if the class has not been initialized
4035     * @throws IllegalArgumentException if the pixelArray is not available or
4036     *             one of the dimensions is negative or zero or the time is
4037     *             negative
4038     * @throws RuntimeException on runtime errors in native code
4039     */
4040    public native int nativeGetPixels(String fileName, int[] pixelArray, int width, int height,
4041            long timeMS);
4042
4043    public native int nativeGetPixelsList(String fileName, int[] pixelArray, int width, int height,
4044            int timeMS, int nosofTN, long startTimeMs, long endTimeMs);
4045
4046    /**
4047     * Releases the JNI and cleans up the core native module.. Should be called
4048     * only after init( )
4049     *
4050     * @throws IllegalStateException if the method could not be called
4051     */
4052    public native void release() throws IllegalStateException, RuntimeException;
4053
4054    /*
4055     * Clear the preview surface
4056     */
4057    public native void nativeClearSurface(Surface surface, int width, int height);
4058
4059
4060    /**
4061     * Stops the encoding. This method should only be called after encoding has
4062     * started using method <code> startEncoding</code>
4063     *
4064     * @throws IllegalStateException if the method could not be called
4065     */
4066    public native void stopEncoding() throws IllegalStateException, RuntimeException;
4067
4068
4069
4070    private native void _init(String tempPath, String libraryPath)
4071            throws IllegalArgumentException, IllegalStateException, RuntimeException;
4072
4073    private native void nativeStartPreview(Surface mSurface, long fromMs, long toMs,
4074            int callbackAfterFrameCount, boolean loop) throws IllegalArgumentException,
4075            IllegalStateException, RuntimeException;
4076
4077    private native void nativePopulateSettings(EditSettings mEditSettings,
4078            PreviewClipProperties mProperties, AudioSettings mAudioSettings)
4079    throws IllegalArgumentException, IllegalStateException, RuntimeException;
4080
4081    private native int nativeRenderPreviewFrame(Surface mSurface, long timeMs,
4082                                                 int surfaceWidth, int surfaceHeight)
4083                                                 throws IllegalArgumentException,
4084                                                 IllegalStateException, RuntimeException;
4085
4086    private native int nativeRenderMediaItemPreviewFrame(Surface mSurface, String filepath,
4087            int framewidth, int frameheight, int surfacewidth, int surfaceheight, long timeMs)
4088    throws IllegalArgumentException, IllegalStateException, RuntimeException;
4089
4090    private native void nativeStopPreview();
4091
4092    public native int nativeGenerateAudioGraph(String pcmFilePath, String outGraphPath,
4093            int frameDuration, int channels, int sampleCount);
4094
4095    public native int nativeGenerateRawAudio(String InFileName, String PCMFileName);
4096
4097    public native int nativeGenerateClip(EditSettings editSettings)
4098    throws IllegalArgumentException, IllegalStateException, RuntimeException;
4099
4100}
4101