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