diff --git a/media/java/android/media/videoeditor/AudioTrack.java b/media/java/android/media/videoeditor/AudioTrack.java
deleted file mode 100644
index c5cc2ca..0000000
--- a/media/java/android/media/videoeditor/AudioTrack.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.ref.SoftReference;
-
-import android.media.videoeditor.MediaArtistNativeHelper.Properties;
-
-/**
- * This class allows to handle an audio track. This audio file is mixed with the
- * audio samples of the media items.
- * {@hide}
- */
-public class AudioTrack {
-
-    /**
-     *  Instance variables
-     *  Private object for calling native methods via MediaArtistNativeHelper
-     */
-    private final MediaArtistNativeHelper mMANativeHelper;
-    private final String mUniqueId;
-    private final String mFilename;
-    private long mStartTimeMs;
-    private long mTimelineDurationMs;
-    private int mVolumePercent;
-    private long mBeginBoundaryTimeMs;
-    private long mEndBoundaryTimeMs;
-    private boolean mLoop;
-    private boolean mMuted;
-    private final long mDurationMs;
-    private final int mAudioChannels;
-    private final int mAudioType;
-    private final int mAudioBitrate;
-    private final int mAudioSamplingFrequency;
-    /**
-     *  Ducking variables
-     */
-    private int mDuckingThreshold;
-    private int mDuckedTrackVolume;
-    private boolean mIsDuckingEnabled;
-
-    /**
-     *  The audio waveform filename
-     */
-    private String mAudioWaveformFilename;
-
-    /**
-     *  The audio waveform data
-     */
-    private SoftReference<WaveformData> mWaveformData;
-
-    /**
-     * An object of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private AudioTrack() throws IOException {
-        this(null, null, null);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param editor The video editor reference
-     * @param audioTrackId The audio track id
-     * @param filename The absolute file name
-     *
-     * @throws IOException if file is not found
-     * @throws IllegalArgumentException if file format is not supported or if
-     *         the codec is not supported or if editor is not of type
-     *         VideoEditorImpl.
-     */
-    public AudioTrack(VideoEditor editor, String audioTrackId, String filename) throws IOException {
-        this(editor, audioTrackId, filename, 0, 0, MediaItem.END_OF_FILE, false, 100, false, false,
-                0, 0, null);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param editor The video editor reference
-     * @param audioTrackId The audio track id
-     * @param filename The audio filename. In case file contains Audio and Video,
-     *         only the Audio stream will be used as Audio Track.
-     * @param startTimeMs the start time in milliseconds (relative to the
-     *         timeline)
-     * @param beginMs start time in the audio track in milliseconds (relative to
-     *         the beginning of the audio track)
-     * @param endMs end time in the audio track in milliseconds (relative to the
-     *         beginning of the audio track)
-     * @param loop true to loop the audio track
-     * @param volume The volume in percentage
-     * @param muted true if the audio track is muted
-     * @param threshold Ducking will be activated when the relative energy in
-     *         the media items audio signal goes above this value. The valid
-     *         range of values is 0 to 90.
-     * @param duckedTrackVolume The relative volume of the audio track when
-     *         ducking is active. The valid range of values is 0 to 100.
-     * @param audioWaveformFilename The name of the waveform file
-     *
-     * @throws IOException if file is not found
-     * @throws IllegalArgumentException if file format is not supported or if
-     *             the codec is not supported or if editor is not of type
-     *             VideoEditorImpl.
-     */
-    AudioTrack(VideoEditor editor, String audioTrackId, String filename,
-               long startTimeMs,long beginMs, long endMs, boolean loop,
-               int volume, boolean muted,boolean duckingEnabled,
-               int duckThreshold, int duckedTrackVolume,
-            String audioWaveformFilename) throws IOException {
-        Properties properties = null;
-
-        File file = new File(filename);
-        if (!file.exists()) {
-            throw new IOException(filename + " not found ! ");
-        }
-
-        /*Compare file_size with 2GB*/
-        if (VideoEditor.MAX_SUPPORTED_FILE_SIZE <= file.length()) {
-            throw new IllegalArgumentException("File size is more than 2GB");
-        }
-
-        if (editor instanceof VideoEditorImpl) {
-            mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
-        } else {
-            throw new IllegalArgumentException("editor is not of type VideoEditorImpl");
-        }
-        try {
-          properties = mMANativeHelper.getMediaProperties(filename);
-        } catch (Exception e) {
-            throw new IllegalArgumentException(e.getMessage() + " : " + filename);
-        }
-        int fileType = mMANativeHelper.getFileType(properties.fileType);
-        switch (fileType) {
-            case MediaProperties.FILE_3GP:
-            case MediaProperties.FILE_MP4:
-            case MediaProperties.FILE_MP3:
-            case MediaProperties.FILE_AMR:
-                break;
-
-            default: {
-                throw new IllegalArgumentException("Unsupported input file type: " + fileType);
-            }
-        }
-        switch (mMANativeHelper.getAudioCodecType(properties.audioFormat)) {
-            case MediaProperties.ACODEC_AMRNB:
-            case MediaProperties.ACODEC_AMRWB:
-            case MediaProperties.ACODEC_AAC_LC:
-            case MediaProperties.ACODEC_MP3:
-                break;
-            default:
-                throw new IllegalArgumentException("Unsupported Audio Codec Format in Input File");
-        }
-
-        if (endMs == MediaItem.END_OF_FILE) {
-            endMs = properties.audioDuration;
-        }
-
-        mUniqueId = audioTrackId;
-        mFilename = filename;
-        mStartTimeMs = startTimeMs;
-        mDurationMs = properties.audioDuration;
-        mAudioChannels = properties.audioChannels;
-        mAudioBitrate = properties.audioBitrate;
-        mAudioSamplingFrequency = properties.audioSamplingFrequency;
-        mAudioType = properties.audioFormat;
-        mTimelineDurationMs = endMs - beginMs;
-        mVolumePercent = volume;
-
-        mBeginBoundaryTimeMs = beginMs;
-        mEndBoundaryTimeMs = endMs;
-
-        mLoop = loop;
-        mMuted = muted;
-        mIsDuckingEnabled = duckingEnabled;
-        mDuckingThreshold = duckThreshold;
-        mDuckedTrackVolume = duckedTrackVolume;
-
-        mAudioWaveformFilename = audioWaveformFilename;
-        if (audioWaveformFilename != null) {
-            mWaveformData =
-                new SoftReference<WaveformData>(new WaveformData(audioWaveformFilename));
-        } else {
-            mWaveformData = null;
-        }
-    }
-
-    /**
-     * Get the id of the audio track
-     *
-     * @return The id of the audio track
-     */
-    public String getId() {
-        return mUniqueId;
-    }
-
-    /**
-     * Get the filename for this audio track source.
-     *
-     * @return The filename as an absolute file name
-     */
-    public String getFilename() {
-        return mFilename;
-    }
-
-    /**
-     * Get the number of audio channels in the source of this audio track
-     *
-     * @return The number of audio channels in the source of this audio track
-     */
-    public int getAudioChannels() {
-        return mAudioChannels;
-    }
-
-    /**
-     * Get the audio codec of the source of this audio track
-     *
-     * @return The audio codec of the source of this audio track
-     * {@link android.media.videoeditor.MediaProperties}
-     */
-    public int getAudioType() {
-        return mAudioType;
-    }
-
-    /**
-     * Get the audio sample frequency of the audio track
-     *
-     * @return The audio sample frequency of the audio track
-     */
-    public int getAudioSamplingFrequency() {
-        return mAudioSamplingFrequency;
-    }
-
-    /**
-     * Get the audio bitrate of the audio track
-     *
-     * @return The audio bitrate of the audio track
-     */
-    public int getAudioBitrate() {
-        return mAudioBitrate;
-    }
-
-    /**
-     * Set the volume of this audio track as percentage of the volume in the
-     * original audio source file.
-     *
-     * @param volumePercent Percentage of the volume to apply. If it is set to
-     *         0, then volume becomes mute. It it is set to 100, then volume
-     *         is same as original volume. It it is set to 200, then volume
-     *         is doubled (provided that volume amplification is supported)
-     *
-     * @throws UnsupportedOperationException if volume amplification is
-     *         requested and is not supported.
-     */
-    public void setVolume(int volumePercent) {
-        if (volumePercent > MediaProperties.AUDIO_MAX_VOLUME_PERCENT) {
-            throw new IllegalArgumentException("Volume set exceeds maximum allowed value");
-        }
-
-        if (volumePercent < 0) {
-            throw new IllegalArgumentException("Invalid Volume ");
-        }
-
-        /**
-         *  Force update of preview settings
-         */
-        mMANativeHelper.setGeneratePreview(true);
-
-        mVolumePercent = volumePercent;
-    }
-
-    /**
-     * Get the volume of the audio track as percentage of the volume in the
-     * original audio source file.
-     *
-     * @return The volume in percentage
-     */
-    public int getVolume() {
-        return mVolumePercent;
-    }
-
-    /**
-     * Mute/Unmute the audio track
-     *
-     * @param muted true to mute the audio track. SetMute(true) will make
-     *         the volume of this Audio Track to 0.
-     */
-    public void setMute(boolean muted) {
-        /**
-         *  Force update of preview settings
-         */
-        mMANativeHelper.setGeneratePreview(true);
-        mMuted = muted;
-    }
-
-    /**
-     * Check if the audio track is muted
-     *
-     * @return true if the audio track is muted
-     */
-    public boolean isMuted() {
-        return mMuted;
-    }
-
-    /**
-     * Get the start time of this audio track relative to the storyboard
-     * timeline.
-     *
-     * @return The start time in milliseconds
-     */
-
-    public long getStartTime() {
-        return mStartTimeMs;
-    }
-
-    /**
-     * Get the audio track duration
-     *
-     * @return The duration in milliseconds. This value represents actual audio
-     *         track duration. This value is not effected by 'enableLoop' or
-     *         'setExtractBoundaries'.
-     */
-    public long getDuration() {
-        return mDurationMs;
-    }
-
-    /**
-     * Get the audio track timeline duration
-     *
-     * @return The timeline duration as defined by the begin and end boundaries
-     */
-    public long getTimelineDuration() {
-        return mTimelineDurationMs;
-    }
-
-    /**
-     * Sets the start and end marks for trimming an audio track
-     *
-     * @param beginMs start time in the audio track in milliseconds (relative to
-     *         the beginning of the audio track)
-     * @param endMs end time in the audio track in milliseconds (relative to the
-     *         beginning of the audio track)
-     */
-    public void setExtractBoundaries(long beginMs, long endMs) {
-        if (beginMs > mDurationMs) {
-            throw new IllegalArgumentException("Invalid start time");
-        }
-        if (endMs > mDurationMs) {
-            throw new IllegalArgumentException("Invalid end time");
-        }
-        if (beginMs < 0) {
-            throw new IllegalArgumentException("Invalid start time; is < 0");
-        }
-        if (endMs < 0) {
-            throw new IllegalArgumentException("Invalid end time; is < 0");
-        }
-
-        /**
-         *  Force update of preview settings
-         */
-        mMANativeHelper.setGeneratePreview(true);
-
-        mBeginBoundaryTimeMs = beginMs;
-        mEndBoundaryTimeMs = endMs;
-
-        mTimelineDurationMs = mEndBoundaryTimeMs - mBeginBoundaryTimeMs;
-    }
-
-    /**
-     * Get the boundary begin time
-     *
-     * @return The boundary begin time
-     */
-    public long getBoundaryBeginTime() {
-        return mBeginBoundaryTimeMs;
-    }
-
-    /**
-     * Get the boundary end time
-     *
-     * @return The boundary end time
-     */
-    public long getBoundaryEndTime() {
-        return mEndBoundaryTimeMs;
-    }
-
-    /**
-     * Enable the loop mode for this audio track. Note that only one of the
-     * audio tracks in the timeline can have the loop mode enabled. When looping
-     * is enabled the samples between mBeginBoundaryTimeMs and
-     * mEndBoundaryTimeMs are looped.
-     */
-    public void enableLoop() {
-        if (!mLoop) {
-            /**
-             *  Force update of preview settings
-             */
-            mMANativeHelper.setGeneratePreview(true);
-            mLoop = true;
-        }
-    }
-
-    /**
-     * Disable the loop mode
-     */
-    public void disableLoop() {
-        if (mLoop) {
-            /**
-             *  Force update of preview settings
-             */
-            mMANativeHelper.setGeneratePreview(true);
-            mLoop = false;
-        }
-    }
-
-    /**
-     * Check if looping is enabled
-     *
-     * @return true if looping is enabled
-     */
-    public boolean isLooping() {
-        return mLoop;
-    }
-
-    /**
-     * Disable the audio duck effect
-     */
-    public void disableDucking() {
-        if (mIsDuckingEnabled) {
-            /**
-             *  Force update of preview settings
-             */
-            mMANativeHelper.setGeneratePreview(true);
-            mIsDuckingEnabled = false;
-        }
-    }
-
-    /**
-     * Enable ducking by specifying the required parameters
-     *
-     * @param threshold Ducking will be activated when the energy in
-     *         the media items audio signal goes above this value. The valid
-     *         range of values is 0db to 90dB. 0dB is equivalent to disabling
-     *         ducking.
-     * @param duckedTrackVolume The relative volume of the audio track when ducking
-     *         is active. The valid range of values is 0 to 100.
-     */
-    public void enableDucking(int threshold, int duckedTrackVolume) {
-        if (threshold < 0 || threshold > 90) {
-            throw new IllegalArgumentException("Invalid threshold value: " + threshold);
-        }
-
-        if (duckedTrackVolume < 0 || duckedTrackVolume > 100) {
-            throw new IllegalArgumentException("Invalid duckedTrackVolume value: "
-                    + duckedTrackVolume);
-        }
-
-        /**
-         *  Force update of preview settings
-         */
-        mMANativeHelper.setGeneratePreview(true);
-
-        mDuckingThreshold = threshold;
-        mDuckedTrackVolume = duckedTrackVolume;
-        mIsDuckingEnabled = true;
-    }
-
-    /**
-     * Check if ducking is enabled
-     *
-     * @return true if ducking is enabled
-     */
-    public boolean isDuckingEnabled() {
-        return mIsDuckingEnabled;
-    }
-
-    /**
-     * Get the ducking threshold.
-     *
-     * @return The ducking threshold
-     */
-    public int getDuckingThreshhold() {
-        return mDuckingThreshold;
-    }
-
-    /**
-     * Get the ducked track volume.
-     *
-     * @return The ducked track volume
-     */
-    public int getDuckedTrackVolume() {
-        return mDuckedTrackVolume;
-    }
-
-    /**
-     * This API allows to generate a file containing the sample volume levels of
-     * this audio track object. This function may take significant time and is
-     * blocking. The filename can be retrieved using getAudioWaveformFilename().
-     *
-     * @param listener The progress listener
-     *
-     * @throws IOException if the output file cannot be created
-     * @throws IllegalArgumentException if the audio file does not have a valid
-     *         audio track
-     * @throws IllegalStateException if the codec type is unsupported
-     */
-    public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener)
-    throws IOException {
-        if (mAudioWaveformFilename == null) {
-            /**
-             *  AudioWaveformFilename is generated
-             */
-            final String projectPath = mMANativeHelper.getProjectPath();
-            final String audioWaveFilename = String.format(projectPath + "/audioWaveformFile-"
-                    + getId() + ".dat");
-
-            /**
-             * Logic to get frame duration = (no. of frames per sample * 1000)/
-             * sampling frequency
-             */
-            final int frameDuration;
-            final int sampleCount;
-            final int codecType = mMANativeHelper.getAudioCodecType(mAudioType);
-            switch (codecType) {
-                case MediaProperties.ACODEC_AMRNB: {
-                    frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRNB * 1000)
-                    / MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
-                    sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRNB;
-                    break;
-                }
-
-                case MediaProperties.ACODEC_AMRWB: {
-                    frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRWB * 1000)
-                    / MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
-                    sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRWB;
-                    break;
-                }
-
-                case MediaProperties.ACODEC_AAC_LC: {
-                    frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AAC * 1000)
-                    / MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
-                    sampleCount = MediaProperties.SAMPLES_PER_FRAME_AAC;
-                    break;
-                }
-
-                case MediaProperties.ACODEC_MP3: {
-                    frameDuration = (MediaProperties.SAMPLES_PER_FRAME_MP3 * 1000)
-                    / MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
-                    sampleCount = MediaProperties.SAMPLES_PER_FRAME_MP3;
-                    break;
-                }
-
-                default: {
-                    throw new IllegalStateException("Unsupported codec type: "
-                                                                   + codecType);
-                }
-            }
-
-            mMANativeHelper.generateAudioGraph( mUniqueId,
-                    mFilename,
-                    audioWaveFilename,
-                    frameDuration,
-                    MediaProperties.DEFAULT_CHANNEL_COUNT,
-                    sampleCount,
-                    listener,
-                    false);
-            /**
-             *  Record the generated file name
-             */
-            mAudioWaveformFilename = audioWaveFilename;
-        }
-        mWaveformData = new SoftReference<WaveformData>(new WaveformData(mAudioWaveformFilename));
-    }
-
-    /**
-     * Get the audio waveform file name if extractAudioWaveform was successful.
-     *
-     * @return the name of the file, null if the file does not exist
-     */
-    String getAudioWaveformFilename() {
-        return mAudioWaveformFilename;
-    }
-
-    /**
-     * Delete the waveform file
-     */
-    void invalidate() {
-        if (mAudioWaveformFilename != null) {
-            new File(mAudioWaveformFilename).delete();
-            mAudioWaveformFilename = null;
-            mWaveformData = null;
-        }
-    }
-
-    /**
-     * Get the audio waveform data.
-     *
-     * @return The waveform data
-     *
-     * @throws IOException if the waveform file cannot be found
-     */
-    public WaveformData getWaveformData() throws IOException {
-        if (mWaveformData == null) {
-            return null;
-        }
-
-        WaveformData waveformData = mWaveformData.get();
-        if (waveformData != null) {
-            return waveformData;
-        } else if (mAudioWaveformFilename != null) {
-            try {
-                waveformData = new WaveformData(mAudioWaveformFilename);
-            } catch (IOException e) {
-                throw e;
-            }
-            mWaveformData = new SoftReference<WaveformData>(waveformData);
-            return waveformData;
-        } else {
-            return null;
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (!(object instanceof AudioTrack)) {
-            return false;
-        }
-        return mUniqueId.equals(((AudioTrack)object).mUniqueId);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int hashCode() {
-        return mUniqueId.hashCode();
-    }
-}
diff --git a/media/java/android/media/videoeditor/Effect.java b/media/java/android/media/videoeditor/Effect.java
deleted file mode 100644
index 2f7ae03..0000000
--- a/media/java/android/media/videoeditor/Effect.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-/**
- * This is the super class for all effects. An effect can only be applied to a
- * single media item.
- * {@hide}
- */
-public abstract class Effect {
-    /**
-     *  Instance variables
-     */
-    private final String mUniqueId;
-    /**
-     *  The effect owner
-     */
-    private final MediaItem mMediaItem;
-
-    protected long mDurationMs;
-    /**
-     *  The start time of the effect relative to the beginning
-     *  of the media item
-     */
-    protected long mStartTimeMs;
-
-    /**
-     * Default constructor
-     */
-    @SuppressWarnings("unused")
-    private Effect() {
-        mMediaItem = null;
-        mUniqueId = null;
-        mStartTimeMs = 0;
-        mDurationMs = 0;
-    }
-
-    /**
-     * Constructor
-     *
-     * @param mediaItem The media item owner
-     * @param effectId The effect id
-     * @param startTimeMs The start time relative to the media item to which it
-     *            is applied
-     * @param durationMs The effect duration in milliseconds
-     */
-    public Effect(MediaItem mediaItem, String effectId, long startTimeMs,
-                  long durationMs) {
-        if (mediaItem == null) {
-            throw new IllegalArgumentException("Media item cannot be null");
-        }
-
-        if ((startTimeMs < 0) || (durationMs < 0)) {
-             throw new IllegalArgumentException("Invalid start time Or/And Duration");
-        }
-        if (startTimeMs + durationMs > mediaItem.getDuration()) {
-            throw new IllegalArgumentException("Invalid start time and duration");
-        }
-
-        mMediaItem = mediaItem;
-        mUniqueId = effectId;
-        mStartTimeMs = startTimeMs;
-        mDurationMs = durationMs;
-    }
-
-    /**
-     * Get the id of the effect.
-     *
-     * @return The id of the effect
-     */
-    public String getId() {
-        return mUniqueId;
-    }
-
-    /**
-     * Set the duration of the effect. If a preview or export is in progress,
-     * then this change is effective for next preview or export session.
-     *
-     * @param durationMs of the effect in milliseconds
-     */
-    public void setDuration(long durationMs) {
-        if (durationMs <0) {
-            throw new IllegalArgumentException("Invalid duration");
-        }
-
-        if (mStartTimeMs + durationMs > mMediaItem.getDuration()) {
-            throw new IllegalArgumentException("Duration is too large");
-        }
-
-        getMediaItem().getNativeContext().setGeneratePreview(true);
-
-        final long oldDurationMs = mDurationMs;
-        mDurationMs = durationMs;
-
-        mMediaItem.invalidateTransitions(mStartTimeMs, oldDurationMs, mStartTimeMs, mDurationMs);
-    }
-
-    /**
-     * Get the duration of the effect
-     *
-     * @return The duration of the effect in milliseconds
-     */
-    public long getDuration() {
-        return mDurationMs;
-    }
-
-    /**
-     * Set start time of the effect. If a preview or export is in progress, then
-     * this change is effective for next preview or export session.
-     *
-     * @param startTimeMs The start time of the effect relative to the beginning
-     *            of the media item in milliseconds
-     */
-    public void setStartTime(long startTimeMs) {
-        if (startTimeMs + mDurationMs > mMediaItem.getDuration()) {
-            throw new IllegalArgumentException("Start time is too large");
-        }
-
-        getMediaItem().getNativeContext().setGeneratePreview(true);
-        final long oldStartTimeMs = mStartTimeMs;
-        mStartTimeMs = startTimeMs;
-
-        mMediaItem.invalidateTransitions(oldStartTimeMs, mDurationMs, mStartTimeMs, mDurationMs);
-    }
-
-    /**
-     * Get the start time of the effect
-     *
-     * @return The start time in milliseconds
-     */
-    public long getStartTime() {
-        return mStartTimeMs;
-    }
-
-    /**
-     * Set the start time and duration
-     *
-     * @param startTimeMs start time in milliseconds
-     * @param durationMs The duration in milliseconds
-     */
-    public void setStartTimeAndDuration(long startTimeMs, long durationMs) {
-        if (startTimeMs + durationMs > mMediaItem.getDuration()) {
-            throw new IllegalArgumentException("Invalid start time or duration");
-        }
-
-        getMediaItem().getNativeContext().setGeneratePreview(true);
-        final long oldStartTimeMs = mStartTimeMs;
-        final long oldDurationMs = mDurationMs;
-
-        mStartTimeMs = startTimeMs;
-        mDurationMs = durationMs;
-
-        mMediaItem.invalidateTransitions(oldStartTimeMs, oldDurationMs, mStartTimeMs, mDurationMs);
-    }
-
-    /**
-     * Get the media item owner.
-     *
-     * @return The media item owner
-     */
-    public MediaItem getMediaItem() {
-        return mMediaItem;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (!(object instanceof Effect)) {
-            return false;
-        }
-        return mUniqueId.equals(((Effect)object).mUniqueId);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int hashCode() {
-        return mUniqueId.hashCode();
-    }
-}
diff --git a/media/java/android/media/videoeditor/EffectColor.java b/media/java/android/media/videoeditor/EffectColor.java
deleted file mode 100644
index 6c5ac2d..0000000
--- a/media/java/android/media/videoeditor/EffectColor.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-/**
- * This class allows to apply color effect on a media item.
- * {@hide}
- */
-public class EffectColor extends Effect {
-
-    /**
-     * Change the video frame color to the RGB color value provided
-     */
-    public static final int TYPE_COLOR = 1;
-    /**
-     * Change the video frame color to a gradation from RGB color (at the top of
-     * the frame) to black (at the bottom of the frame).
-     */
-    public static final int TYPE_GRADIENT = 2;
-    /**
-     * Change the video frame color to sepia
-     */
-    public static final int TYPE_SEPIA = 3;
-    /**
-     * Invert the video frame color
-     */
-    public static final int TYPE_NEGATIVE = 4;
-    /**
-     * Make the video look like as if it was recorded in 50's
-     */
-    public static final int TYPE_FIFTIES = 5;
-    /**
-     * Change the video frame color to the RGB color value GREEN
-     */
-    public static final int GREEN = 0x0000ff00;
-    /**
-     * Change the video frame color to the RGB color value PINK
-     */
-    public static final int PINK = 0x00ff66cc;
-    /**
-     * Change the video frame color to the RGB color value GRAY
-     */
-    public static final int GRAY = 0x007f7f7f;
-
-    /**
-     *  The effect type
-     */
-    private final int mType;
-
-    /**
-     *  The effect color
-     */
-    private final int mColor;
-
-    /**
-     * An object of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private EffectColor() {
-        this(null, null, 0, 0, 0, 0);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param mediaItem The media item owner
-     * @param effectId The effect id
-     * @param startTimeMs The start time relative to the media item to which it
-     *            is applied
-     * @param durationMs The duration of this effect in milliseconds
-     * @param type type of the effect. type is one of: TYPE_COLOR,
-     *            TYPE_GRADIENT, TYPE_SEPIA, TYPE_NEGATIVE, TYPE_FIFTIES.
-     * @param color If type is TYPE_COLOR, color is the RGB color as 888.
-     *              If type is TYPE_GRADIENT, color is the RGB color at the
-     *              top of the frame. Otherwise, color is ignored
-     */
-    public EffectColor(MediaItem mediaItem, String effectId, long startTimeMs,
-                      long durationMs, int type, int color) {
-        super(mediaItem, effectId, startTimeMs, durationMs);
-        switch (type) {
-            case TYPE_COLOR:
-            case TYPE_GRADIENT: {
-                switch (color) {
-                    case GREEN:
-                    case PINK:
-                    case GRAY:
-                        mColor = color;
-                        break;
-
-                    default:
-                        throw new IllegalArgumentException("Invalid Color: " + color);
-                    }
-                    break;
-            }
-            case TYPE_SEPIA:
-            case TYPE_NEGATIVE:
-            case TYPE_FIFTIES: {
-                mColor = -1;
-                break;
-            }
-
-            default: {
-                throw new IllegalArgumentException("Invalid type: " + type);
-            }
-        }
-        mType = type;
-    }
-
-    /**
-     * Get the effect type.
-     *
-     * @return The effect type
-     */
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Get the color if effect type is TYPE_COLOR or TYPE_GRADIENT.
-     *
-     * @return the color as RGB 888 if type is TYPE_COLOR or TYPE_GRADIENT.
-     */
-    public int getColor() {
-        return mColor;
-    }
-}
diff --git a/media/java/android/media/videoeditor/EffectKenBurns.java b/media/java/android/media/videoeditor/EffectKenBurns.java
deleted file mode 100644
index 64be6b8..0000000
--- a/media/java/android/media/videoeditor/EffectKenBurns.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import android.graphics.Rect;
-
-/**
- * This class represents a Ken Burns effect.
- * {@hide}
- */
-public class EffectKenBurns extends Effect {
-    /**
-     *  Instance variables
-     */
-    private Rect mStartRect;
-    private Rect mEndRect;
-
-    /**
-     * Objects of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private EffectKenBurns() {
-        this(null, null, null, null, 0, 0);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param mediaItem The media item owner
-     * @param effectId The effect id
-     * @param startRect The start rectangle
-     * @param endRect The end rectangle
-     * @param startTimeMs The start time
-     * @param durationMs The duration of the Ken Burns effect in milliseconds
-     */
-    public EffectKenBurns(MediaItem mediaItem, String effectId, Rect startRect,
-                         Rect endRect, long startTimeMs, long durationMs) {
-        super(mediaItem, effectId, startTimeMs, durationMs);
-
-        if ( (startRect.width() <= 0) || (startRect.height() <= 0) ) {
-            throw new IllegalArgumentException("Invalid Start rectangle");
-        }
-        if ( (endRect.width() <= 0) || (endRect.height() <= 0) ) {
-            throw new IllegalArgumentException("Invalid End rectangle");
-        }
-
-        mStartRect = startRect;
-        mEndRect = endRect;
-    }
-
-
-    /**
-     * Get the start rectangle.
-     *
-     * @return The start rectangle
-     */
-    public Rect getStartRect() {
-        return mStartRect;
-    }
-
-
-    /**
-     * Get the end rectangle.
-     *
-     * @return The end rectangle
-     */
-    public Rect getEndRect() {
-        return mEndRect;
-    }
-
-    /**
-     * Get the KenBurn effect start and end rectangle coordinates
-     * @param start The rect object to be populated with start
-     * rectangle coordinates
-     *
-     * @param end The rect object to be populated with end
-     * rectangle coordinates
-     */
-    void getKenBurnsSettings(Rect start, Rect end) {
-        start.left = getStartRect().left;
-        start.top = getStartRect().top;
-        start.right = getStartRect().right;
-        start.bottom = getStartRect().bottom;
-        end.left = getEndRect().left;
-        end.top = getEndRect().top;
-        end.right = getEndRect().right;
-        end.bottom = getEndRect().bottom;
-    }
-}
diff --git a/media/java/android/media/videoeditor/ExtractAudioWaveformProgressListener.java b/media/java/android/media/videoeditor/ExtractAudioWaveformProgressListener.java
deleted file mode 100644
index 7ba7de3..0000000
--- a/media/java/android/media/videoeditor/ExtractAudioWaveformProgressListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-/**
- * This listener interface is used by
- * {@link MediaVideoItem#extractAudioWaveform(ExtractAudioWaveformProgressListener listener)}
- * or
- * {@link AudioTrack#extractAudioWaveform(ExtractAudioWaveformProgressListener listener)}
- * {@hide}
- */
-public interface ExtractAudioWaveformProgressListener {
-    /**
-     * This method notifies the listener of the progress status of
-     * an extractAudioWaveform operation.
-     * This method may be called maximum 100 times for one operation.
-     *
-     * @param progress The progress in %. At the beginning of the operation,
-     *          this value is set to 0; at the end, the value is set to 100.
-     */
-    public void onProgress(int progress);
-}
-
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
deleted file mode 100644
index 2d3de85..0000000
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ /dev/null
@@ -1,4034 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.nio.IntBuffer;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.Semaphore;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Matrix;
-import android.media.videoeditor.VideoEditor.ExportProgressListener;
-import android.media.videoeditor.VideoEditor.PreviewProgressListener;
-import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
-import android.util.Log;
-import android.util.Pair;
-import android.view.Surface;
-
-/**
- *This class provide Native methods to be used by MediaArtist {@hide}
- */
-class MediaArtistNativeHelper {
-    private static final String TAG = "MediaArtistNativeHelper";
-
-    static {
-        System.loadLibrary("videoeditor_jni");
-    }
-
-    private static final int MAX_THUMBNAIL_PERMITTED = 8;
-
-    public static final int TASK_LOADING_SETTINGS = 1;
-    public static final int TASK_ENCODING = 2;
-
-    /**
-     *  The resize paint
-     */
-    private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
-
-    private final VideoEditor mVideoEditor;
-    /*
-     *  Semaphore to control preview calls
-     */
-    private final Semaphore mLock;
-
-    private EditSettings mStoryBoardSettings;
-
-    private String mOutputFilename;
-
-    private PreviewClipProperties mClipProperties = null;
-
-    private EditSettings mPreviewEditSettings;
-
-    private AudioSettings mAudioSettings = null;
-
-    private AudioTrack mAudioTrack = null;
-
-    private boolean mInvalidatePreviewArray = true;
-
-    private boolean mRegenerateAudio = true;
-
-    private String mExportFilename = null;
-    private int mExportVideoCodec = 0;
-    private int mExportAudioCodec = 0;
-    private int mProgressToApp;
-
-    private String mRenderPreviewOverlayFile;
-    private int mRenderPreviewRenderingMode;
-
-    private boolean mIsFirstProgress;
-
-    private static final String AUDIO_TRACK_PCM_FILE = "AudioPcm.pcm";
-
-    // Processing indication
-    public static final int PROCESSING_NONE          = 0;
-    public static final int PROCESSING_AUDIO_PCM     = 1;
-    public static final int PROCESSING_TRANSITION    = 2;
-    public static final int PROCESSING_KENBURNS      = 3;
-    public static final int PROCESSING_INTERMEDIATE1 = 11;
-    public static final int PROCESSING_INTERMEDIATE2 = 12;
-    public static final int PROCESSING_INTERMEDIATE3 = 13;
-    public static final int PROCESSING_EXPORT        = 20;
-
-    private int mProcessingState;
-    private Object mProcessingObject;
-    private PreviewProgressListener mPreviewProgressListener;
-    private ExportProgressListener mExportProgressListener;
-    private ExtractAudioWaveformProgressListener mExtractAudioWaveformProgressListener;
-    private MediaProcessingProgressListener mMediaProcessingProgressListener;
-    private final String mProjectPath;
-
-    private long mPreviewProgress;
-
-    private String mAudioTrackPCMFilePath;
-
-    private int mTotalClips = 0;
-
-    private boolean mErrorFlagSet = false;
-
-    @SuppressWarnings("unused")
-    private long mManualEditContext;
-
-    /* Listeners */
-
-    /**
-     * Interface definition for a listener to be invoked when there is an update
-     * in a running task.
-     */
-    public interface OnProgressUpdateListener {
-        /**
-         * Called when there is an update.
-         *
-         * @param taskId id of the task reporting an update.
-         * @param progress progress of the task [0..100].
-         * @see BasicEdit#TASK_ENCODING
-         */
-        public void OnProgressUpdate(int taskId, int progress);
-    }
-
-    /** Defines the version. */
-    public final class Version {
-
-        /** Major version number */
-        public int major;
-
-        /** Minor version number */
-        public int minor;
-
-        /** Revision number */
-        public int revision;
-
-        /** VIDEOEDITOR major version number */
-        private static final int VIDEOEDITOR_MAJOR_VERSION = 0;
-
-        /** VIDEOEDITOR minor version number */
-        private static final int VIDEOEDITOR_MINOR_VERSION = 0;
-
-        /** VIDEOEDITOR revision number */
-        private static final int VIDEOEDITOR_REVISION_VERSION = 1;
-
-        /** Method which returns the current VIDEOEDITOR version */
-        public Version getVersion() {
-            Version version = new Version();
-
-            version.major = Version.VIDEOEDITOR_MAJOR_VERSION;
-            version.minor = Version.VIDEOEDITOR_MINOR_VERSION;
-            version.revision = Version.VIDEOEDITOR_REVISION_VERSION;
-
-            return version;
-        }
-    }
-
-    /**
-     * Defines output audio formats.
-     */
-    public final class AudioFormat {
-        /** No audio present in output clip. Used to generate video only clip */
-        public static final int NO_AUDIO = 0;
-
-        /** AMR Narrow Band. */
-        public static final int AMR_NB = 1;
-
-        /** Advanced Audio Coding (AAC). */
-        public static final int AAC = 2;
-
-        /** Advanced Audio Codec Plus (HE-AAC v1). */
-        public static final int AAC_PLUS = 3;
-
-        /** Advanced Audio Codec Plus (HE-AAC v2). */
-        public static final int ENHANCED_AAC_PLUS = 4;
-
-        /** MPEG layer 3 (MP3). */
-        public static final int MP3 = 5;
-
-        /** Enhanced Variable RateCodec (EVRC). */
-        public static final int EVRC = 6;
-
-        /** PCM (PCM). */
-        public static final int PCM = 7;
-
-        /** No transcoding. Output audio format is same as input audio format */
-        public static final int NULL_AUDIO = 254;
-
-        /** Unsupported audio format. */
-        public static final int UNSUPPORTED_AUDIO = 255;
-    }
-
-    /**
-     * Defines audio sampling frequencies.
-     */
-    public final class AudioSamplingFrequency {
-        /**
-         * Default sampling frequency. Uses the default frequency for a specific
-         * audio format. For AAC the only supported (and thus default) sampling
-         * frequency is 16 kHz. For this audio format the sampling frequency in
-         * the OutputParams.
-         **/
-        public static final int FREQ_DEFAULT = 0;
-
-        /** Audio sampling frequency of 8000 Hz. */
-        public static final int FREQ_8000 = 8000;
-
-        /** Audio sampling frequency of 11025 Hz. */
-        public static final int FREQ_11025 = 11025;
-
-        /** Audio sampling frequency of 12000 Hz. */
-        public static final int FREQ_12000 = 12000;
-
-        /** Audio sampling frequency of 16000 Hz. */
-        public static final int FREQ_16000 = 16000;
-
-        /** Audio sampling frequency of 22050 Hz. */
-        public static final int FREQ_22050 = 22050;
-
-        /** Audio sampling frequency of 24000 Hz. */
-        public static final int FREQ_24000 = 24000;
-
-        /** Audio sampling frequency of 32000 Hz. */
-        public static final int FREQ_32000 = 32000;
-
-        /** Audio sampling frequency of 44100 Hz. */
-        public static final int FREQ_44100 = 44100;
-
-        /** Audio sampling frequency of 48000 Hz. Not available for output file. */
-        public static final int FREQ_48000 = 48000;
-    }
-
-    /**
-     * Defines the supported fixed audio and video bitrates. These values are
-     * for output audio video only.
-     */
-    public final class Bitrate {
-        /** Variable bitrate. Means no bitrate regulation */
-        public static final int VARIABLE = -1;
-
-        /** An undefined bitrate. */
-        public static final int UNDEFINED = 0;
-
-        /** A bitrate of 9.2 kbits/s. */
-        public static final int BR_9_2_KBPS = 9200;
-
-        /** A bitrate of 12.2 kbits/s. */
-        public static final int BR_12_2_KBPS = 12200;
-
-        /** A bitrate of 16 kbits/s. */
-        public static final int BR_16_KBPS = 16000;
-
-        /** A bitrate of 24 kbits/s. */
-        public static final int BR_24_KBPS = 24000;
-
-        /** A bitrate of 32 kbits/s. */
-        public static final int BR_32_KBPS = 32000;
-
-        /** A bitrate of 48 kbits/s. */
-        public static final int BR_48_KBPS = 48000;
-
-        /** A bitrate of 64 kbits/s. */
-        public static final int BR_64_KBPS = 64000;
-
-        /** A bitrate of 96 kbits/s. */
-        public static final int BR_96_KBPS = 96000;
-
-        /** A bitrate of 128 kbits/s. */
-        public static final int BR_128_KBPS = 128000;
-
-        /** A bitrate of 192 kbits/s. */
-        public static final int BR_192_KBPS = 192000;
-
-        /** A bitrate of 256 kbits/s. */
-        public static final int BR_256_KBPS = 256000;
-
-        /** A bitrate of 288 kbits/s. */
-        public static final int BR_288_KBPS = 288000;
-
-        /** A bitrate of 384 kbits/s. */
-        public static final int BR_384_KBPS = 384000;
-
-        /** A bitrate of 512 kbits/s. */
-        public static final int BR_512_KBPS = 512000;
-
-        /** A bitrate of 800 kbits/s. */
-        public static final int BR_800_KBPS = 800000;
-
-        /** A bitrate of 2 Mbits/s. */
-        public static final int BR_2_MBPS = 2000000;
-
-        /** A bitrate of 5 Mbits/s. */
-        public static final int BR_5_MBPS = 5000000;
-
-        /** A bitrate of 8 Mbits/s. */
-        public static final int BR_8_MBPS = 8000000;
-    }
-
-    /**
-     * Defines all supported file types.
-     */
-    public final class FileType {
-        /** 3GPP file type. */
-        public static final int THREE_GPP = 0;
-
-        /** MP4 file type. */
-        public static final int MP4 = 1;
-
-        /** AMR file type. */
-        public static final int AMR = 2;
-
-        /** MP3 audio file type. */
-        public static final int MP3 = 3;
-
-        /** PCM audio file type. */
-        public static final int PCM = 4;
-
-        /** JPEG image file type. */
-        public static final int JPG = 5;
-
-        /** GIF image file type. */
-        public static final int GIF = 7;
-
-        /** PNG image file type. */
-        public static final int PNG = 8;
-
-        /** M4V file type. */
-        public static final int M4V = 10;
-
-        /** Unsupported file type. */
-        public static final int UNSUPPORTED = 255;
-    }
-
-    /**
-     * Defines rendering types. Rendering can only be applied to files
-     * containing video streams.
-     **/
-    public final class MediaRendering {
-        /**
-         * Resize to fit the output video with changing the aspect ratio if
-         * needed.
-         */
-        public static final int RESIZING = 0;
-
-        /**
-         * Crop the input video to fit it with the output video resolution.
-         **/
-        public static final int CROPPING = 1;
-
-        /**
-         * Resize to fit the output video resolution but maintain the aspect
-         * ratio. This framing type adds black borders if needed.
-         */
-        public static final int BLACK_BORDERS = 2;
-    }
-
-    /**
-     * Defines the results.
-     */
-    public final class Result {
-        /** No error. result OK */
-        public static final int NO_ERROR = 0;
-
-        /** File not found */
-        public static final int ERR_FILE_NOT_FOUND = 1;
-
-        /**
-         * In case of UTF8 conversion, the size of the converted path will be
-         * more than the corresponding allocated buffer.
-         */
-        public static final int ERR_BUFFER_OUT_TOO_SMALL = 2;
-
-        /** Invalid file type. */
-        public static final int ERR_INVALID_FILE_TYPE = 3;
-
-        /** Invalid effect kind. */
-        public static final int ERR_INVALID_EFFECT_KIND = 4;
-
-        /** Invalid video effect. */
-        public static final int ERR_INVALID_VIDEO_EFFECT_TYPE = 5;
-
-        /** Invalid audio effect. */
-        public static final int ERR_INVALID_AUDIO_EFFECT_TYPE = 6;
-
-        /** Invalid video transition. */
-        public static final int ERR_INVALID_VIDEO_TRANSITION_TYPE = 7;
-
-        /** Invalid audio transition. */
-        public static final int ERR_INVALID_AUDIO_TRANSITION_TYPE = 8;
-
-        /** Invalid encoding frame rate. */
-        public static final int ERR_INVALID_VIDEO_ENCODING_FRAME_RATE = 9;
-
-        /** External effect is called but this function is not set. */
-        public static final int ERR_EXTERNAL_EFFECT_NULL = 10;
-
-        /** External transition is called but this function is not set. */
-        public static final int ERR_EXTERNAL_TRANSITION_NULL = 11;
-
-        /** Begin time cut is larger than the video clip duration. */
-        public static final int ERR_BEGIN_CUT_LARGER_THAN_DURATION = 12;
-
-        /** Begin cut time is larger or equal than end cut. */
-        public static final int ERR_BEGIN_CUT_LARGER_THAN_END_CUT = 13;
-
-        /** Two consecutive transitions are overlapping on one clip. */
-        public static final int ERR_OVERLAPPING_TRANSITIONS = 14;
-
-        /** Internal error, type size mismatch. */
-        public static final int ERR_ANALYSIS_DATA_SIZE_TOO_SMALL = 15;
-
-        /** An input 3GPP file is invalid/corrupted. */
-        public static final int ERR_INVALID_3GPP_FILE = 16;
-
-        /** A file contains an unsupported video format. */
-        public static final int ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT = 17;
-
-        /** A file contains an unsupported audio format. */
-        public static final int ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT = 18;
-
-        /** A file format is not supported. */
-        public static final int ERR_AMR_EDITING_UNSUPPORTED = 19;
-
-        /** An input clip has an unexpectedly large Video AU. */
-        public static final int ERR_INPUT_VIDEO_AU_TOO_LARGE = 20;
-
-        /** An input clip has an unexpectedly large Audio AU. */
-        public static final int ERR_INPUT_AUDIO_AU_TOO_LARGE = 21;
-
-        /** An input clip has a corrupted Audio AU. */
-        public static final int ERR_INPUT_AUDIO_CORRUPTED_AU = 22;
-
-        /** The video encoder encountered an Access Unit error. */
-        public static final int ERR_ENCODER_ACCES_UNIT_ERROR = 23;
-
-        /** Unsupported video format for Video Editing. */
-        public static final int ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT = 24;
-
-        /** Unsupported H263 profile for Video Editing. */
-        public static final int ERR_EDITING_UNSUPPORTED_H263_PROFILE = 25;
-
-        /** Unsupported MPEG-4 profile for Video Editing. */
-        public static final int ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE = 26;
-
-        /** Unsupported MPEG-4 RVLC tool for Video Editing. */
-        public static final int ERR_EDITING_UNSUPPORTED_MPEG4_RVLC = 27;
-
-        /** Unsupported audio format for Video Editing. */
-        public static final int ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT = 28;
-
-        /** File contains no supported stream. */
-        public static final int ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE = 29;
-
-        /** File contains no video stream or an unsupported video stream. */
-        public static final int ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE = 30;
-
-        /** Internal error, clip analysis version mismatch. */
-        public static final int ERR_INVALID_CLIP_ANALYSIS_VERSION = 31;
-
-        /**
-         * At least one of the clip analysis has been generated on another
-         * platform (WIN32, ARM, etc.).
-         */
-        public static final int ERR_INVALID_CLIP_ANALYSIS_PLATFORM = 32;
-
-        /** Clips don't have the same video format (H263 or MPEG4). */
-        public static final int ERR_INCOMPATIBLE_VIDEO_FORMAT = 33;
-
-        /** Clips don't have the same frame size. */
-        public static final int ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE = 34;
-
-        /** Clips don't have the same MPEG-4 time scale. */
-        public static final int ERR_INCOMPATIBLE_VIDEO_TIME_SCALE = 35;
-
-        /** Clips don't have the same use of MPEG-4 data partitioning. */
-        public static final int ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING = 36;
-
-        /** MP3 clips can't be assembled. */
-        public static final int ERR_UNSUPPORTED_MP3_ASSEMBLY = 37;
-
-        /**
-         * The input 3GPP file does not contain any supported audio or video
-         * track.
-         */
-        public static final int ERR_NO_SUPPORTED_STREAM_IN_FILE = 38;
-
-        /**
-         * The Volume of the added audio track (AddVolume) must be strictly
-         * superior than zero.
-         */
-        public static final int ERR_ADDVOLUME_EQUALS_ZERO = 39;
-
-        /**
-         * The time at which an audio track is added can't be higher than the
-         * input video track duration..
-         */
-        public static final int ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION = 40;
-
-        /** The audio track file format setting is undefined. */
-        public static final int ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT = 41;
-
-        /** The added audio track stream has an unsupported format. */
-        public static final int ERR_UNSUPPORTED_ADDED_AUDIO_STREAM = 42;
-
-        /** The audio mixing feature doesn't support the audio track type. */
-        public static final int ERR_AUDIO_MIXING_UNSUPPORTED = 43;
-
-        /** The audio mixing feature doesn't support MP3 audio tracks. */
-        public static final int ERR_AUDIO_MIXING_MP3_UNSUPPORTED = 44;
-
-        /**
-         * An added audio track limits the available features: uiAddCts must be
-         * 0 and bRemoveOriginal must be true.
-         */
-        public static final int ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK = 45;
-
-        /**
-         * An added audio track limits the available features: uiAddCts must be
-         * 0 and bRemoveOriginal must be true.
-         */
-        public static final int ERR_FEATURE_UNSUPPORTED_WITH_AAC = 46;
-
-        /** Input audio track is not of a type that can be mixed with output. */
-        public static final int ERR_AUDIO_CANNOT_BE_MIXED = 47;
-
-        /** Input audio track is not AMR-NB, so it can't be mixed with output. */
-        public static final int ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED = 48;
-
-        /**
-         * An added EVRC audio track limit the available features: uiAddCts must
-         * be 0 and bRemoveOriginal must be true.
-         */
-        public static final int ERR_FEATURE_UNSUPPORTED_WITH_EVRC = 49;
-
-        /** H263 profiles other than 0 are not supported. */
-        public static final int ERR_H263_PROFILE_NOT_SUPPORTED = 51;
-
-        /** File contains no video stream or an unsupported video stream. */
-        public static final int ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE = 52;
-
-        /** Transcoding of the input file(s) is necessary. */
-        public static final int WAR_TRANSCODING_NECESSARY = 53;
-
-        /**
-         * The size of the output file will exceed the maximum configured value.
-         */
-        public static final int WAR_MAX_OUTPUT_SIZE_EXCEEDED = 54;
-
-        /** The time scale is too big. */
-        public static final int WAR_TIMESCALE_TOO_BIG = 55;
-
-        /** The year is out of range */
-        public static final int ERR_CLOCK_BAD_REF_YEAR = 56;
-
-        /** The directory could not be opened */
-        public static final int ERR_DIR_OPEN_FAILED = 57;
-
-        /** The directory could not be read */
-        public static final int ERR_DIR_READ_FAILED = 58;
-
-        /** There are no more entries in the current directory */
-        public static final int ERR_DIR_NO_MORE_ENTRY = 59;
-
-        /** The input parameter/s has error */
-        public static final int ERR_PARAMETER = 60;
-
-        /** There is a state machine error */
-        public static final int ERR_STATE = 61;
-
-        /** Memory allocation failed */
-        public static final int ERR_ALLOC = 62;
-
-        /** Context is invalid */
-        public static final int ERR_BAD_CONTEXT = 63;
-
-        /** Context creation failed */
-        public static final int ERR_CONTEXT_FAILED = 64;
-
-        /** Invalid stream ID */
-        public static final int ERR_BAD_STREAM_ID = 65;
-
-        /** Invalid option ID */
-        public static final int ERR_BAD_OPTION_ID = 66;
-
-        /** The option is write only */
-        public static final int ERR_WRITE_ONLY = 67;
-
-        /** The option is read only */
-        public static final int ERR_READ_ONLY = 68;
-
-        /** The feature is not implemented in this version */
-        public static final int ERR_NOT_IMPLEMENTED = 69;
-
-        /** The media type is not supported */
-        public static final int ERR_UNSUPPORTED_MEDIA_TYPE = 70;
-
-        /** No data to be encoded */
-        public static final int WAR_NO_DATA_YET = 71;
-
-        /** No data to be decoded */
-        public static final int WAR_NO_MORE_STREAM = 72;
-
-        /** Time stamp is invalid */
-        public static final int WAR_INVALID_TIME = 73;
-
-        /** No more data to be decoded */
-        public static final int WAR_NO_MORE_AU = 74;
-
-        /** Semaphore timed out */
-        public static final int WAR_TIME_OUT = 75;
-
-        /** Memory buffer is full */
-        public static final int WAR_BUFFER_FULL = 76;
-
-        /** Server has asked for redirection */
-        public static final int WAR_REDIRECT = 77;
-
-        /** Too many streams in input */
-        public static final int WAR_TOO_MUCH_STREAMS = 78;
-
-        /** The file cannot be opened/ written into as it is locked */
-        public static final int ERR_FILE_LOCKED = 79;
-
-        /** The file access mode is invalid */
-        public static final int ERR_FILE_BAD_MODE_ACCESS = 80;
-
-        /** The file pointer points to an invalid location */
-        public static final int ERR_FILE_INVALID_POSITION = 81;
-
-        /** Invalid string */
-        public static final int ERR_STR_BAD_STRING = 94;
-
-        /** The input string cannot be converted */
-        public static final int ERR_STR_CONV_FAILED = 95;
-
-        /** The string size is too large */
-        public static final int ERR_STR_OVERFLOW = 96;
-
-        /** Bad string arguments */
-        public static final int ERR_STR_BAD_ARGS = 97;
-
-        /** The string value is larger than maximum size allowed */
-        public static final int WAR_STR_OVERFLOW = 98;
-
-        /** The string value is not present in this comparison operation */
-        public static final int WAR_STR_NOT_FOUND = 99;
-
-        /** The thread is not started */
-        public static final int ERR_THREAD_NOT_STARTED = 100;
-
-        /** Trancoding done warning */
-        public static final int WAR_TRANSCODING_DONE = 101;
-
-        /** Unsupported mediatype */
-        public static final int WAR_MEDIATYPE_NOT_SUPPORTED = 102;
-
-        /** Input file contains invalid/unsupported streams */
-        public static final int ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM = 103;
-
-        /** Invalid input file */
-        public static final int ERR_INVALID_INPUT_FILE = 104;
-
-        /** Invalid output video format */
-        public static final int ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT = 105;
-
-        /** Invalid output video frame size */
-        public static final int ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE = 106;
-
-        /** Invalid output video frame rate */
-        public static final int ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE = 107;
-
-        /** Invalid output audio format */
-        public static final int ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT = 108;
-
-        /** Invalid video frame size for H.263 */
-        public static final int ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263 = 109;
-
-        /** Invalid video frame rate for H.263 */
-        public static final int ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263 = 110;
-
-        /** invalid playback duration */
-        public static final int ERR_DURATION_IS_NULL = 111;
-
-        /** Invalid H.263 profile in file */
-        public static final int ERR_H263_FORBIDDEN_IN_MP4_FILE = 112;
-
-        /** Invalid AAC sampling frequency */
-        public static final int ERR_INVALID_AAC_SAMPLING_FREQUENCY = 113;
-
-        /** Audio conversion failure */
-        public static final int ERR_AUDIO_CONVERSION_FAILED = 114;
-
-        /** Invalid trim start and end times */
-        public static final int ERR_BEGIN_CUT_EQUALS_END_CUT = 115;
-
-        /** End time smaller than start time for trim */
-        public static final int ERR_END_CUT_SMALLER_THAN_BEGIN_CUT = 116;
-
-        /** Output file size is small */
-        public static final int ERR_MAXFILESIZE_TOO_SMALL = 117;
-
-        /** Output video bitrate is too low */
-        public static final int ERR_VIDEOBITRATE_TOO_LOW = 118;
-
-        /** Output audio bitrate is too low */
-        public static final int ERR_AUDIOBITRATE_TOO_LOW = 119;
-
-        /** Output video bitrate is too high */
-        public static final int ERR_VIDEOBITRATE_TOO_HIGH = 120;
-
-        /** Output audio bitrate is too high */
-        public static final int ERR_AUDIOBITRATE_TOO_HIGH = 121;
-
-        /** Output file size is too small */
-        public static final int ERR_OUTPUT_FILE_SIZE_TOO_SMALL = 122;
-
-        /** Unknown stream type */
-        public static final int ERR_READER_UNKNOWN_STREAM_TYPE = 123;
-
-        /** Invalid metadata in input stream */
-        public static final int WAR_READER_NO_METADATA = 124;
-
-        /** Invalid file reader info warning */
-        public static final int WAR_READER_INFORMATION_NOT_PRESENT = 125;
-
-        /** Warning to indicate the the writer is being stopped */
-        public static final int WAR_WRITER_STOP_REQ = 131;
-
-        /** Video decoder failed to provide frame for transcoding */
-        public static final int WAR_VIDEORENDERER_NO_NEW_FRAME = 132;
-
-        /** Video deblocking filter is not implemented */
-        public static final int WAR_DEBLOCKING_FILTER_NOT_IMPLEMENTED = 133;
-
-        /** H.263 decoder profile not supported */
-        public static final int ERR_DECODER_H263_PROFILE_NOT_SUPPORTED = 134;
-
-        /** The input file contains unsupported H.263 profile */
-        public static final int ERR_DECODER_H263_NOT_BASELINE = 135;
-
-        /** There is no more space to store the output file */
-        public static final int ERR_NOMORE_SPACE_FOR_FILE = 136;
-
-        /** Internal error. */
-        public static final int ERR_INTERNAL = 255;
-    }
-
-    /**
-     * Defines output video formats.
-     */
-    public final class VideoFormat {
-        /** No video present in output clip. Used to generate audio only clip */
-        public static final int NO_VIDEO = 0;
-
-        /** H263 video format. */
-        public static final int H263 = 1;
-
-        /** H264 video */
-        public static final int H264 = 2;
-
-        /** MPEG4 video format. */
-        public static final int MPEG4 = 3;
-
-        /** No transcoding. Output video format is same as input video format */
-        public static final int NULL_VIDEO = 254;
-
-        /** Unsupported video format. */
-        public static final int UNSUPPORTED = 255;
-    }
-
-    /** Defines video frame sizes. */
-    public final class VideoFrameSize {
-
-        public static final int SIZE_UNDEFINED = -1;
-
-        /** SQCIF 128 x 96 pixels. */
-        public static final int SQCIF = 0;
-
-        /** QQVGA 160 x 120 pixels. */
-        public static final int QQVGA = 1;
-
-        /** QCIF 176 x 144 pixels. */
-        public static final int QCIF = 2;
-
-        /** QVGA 320 x 240 pixels. */
-        public static final int QVGA = 3;
-
-        /** CIF 352 x 288 pixels. */
-        public static final int CIF = 4;
-
-        /** VGA 640 x 480 pixels. */
-        public static final int VGA = 5;
-
-        /** WVGA 800 X 480 pixels */
-        public static final int WVGA = 6;
-
-        /** NTSC 720 X 480 pixels */
-        public static final int NTSC = 7;
-
-        /** 640 x 360 */
-        public static final int nHD = 8;
-
-        /** 854 x 480 */
-        public static final int WVGA16x9 = 9;
-
-        /** 720p 1280 X 720 */
-        public static final int V720p = 10;
-
-        /** W720p 1080 x 720 */
-        public static final int W720p = 11;
-
-        /** S720p 960 x 720 */
-        public static final int S720p = 12;
-
-        /** 1080p 1920 x 1080 */
-        public static final int V1080p = 13;
-    }
-
-    /**
-     * Defines output video frame rates.
-     */
-    public final class VideoFrameRate {
-        /** Frame rate of 5 frames per second. */
-        public static final int FR_5_FPS = 0;
-
-        /** Frame rate of 7.5 frames per second. */
-        public static final int FR_7_5_FPS = 1;
-
-        /** Frame rate of 10 frames per second. */
-        public static final int FR_10_FPS = 2;
-
-        /** Frame rate of 12.5 frames per second. */
-        public static final int FR_12_5_FPS = 3;
-
-        /** Frame rate of 15 frames per second. */
-        public static final int FR_15_FPS = 4;
-
-        /** Frame rate of 20 frames per second. */
-        public static final int FR_20_FPS = 5;
-
-        /** Frame rate of 25 frames per second. */
-        public static final int FR_25_FPS = 6;
-
-        /** Frame rate of 30 frames per second. */
-        public static final int FR_30_FPS = 7;
-    }
-
-    /**
-     * Defines Video Effect Types.
-     */
-    public static class VideoEffect {
-
-        public static final int NONE = 0;
-
-        public static final int FADE_FROM_BLACK = 8;
-
-        public static final int FADE_TO_BLACK = 16;
-
-        public static final int EXTERNAL = 256;
-
-        public static final int BLACK_AND_WHITE = 257;
-
-        public static final int PINK = 258;
-
-        public static final int GREEN = 259;
-
-        public static final int SEPIA = 260;
-
-        public static final int NEGATIVE = 261;
-
-        public static final int FRAMING = 262;
-
-        public static final int TEXT = 263;
-
-        public static final int ZOOM_IN = 264;
-
-        public static final int ZOOM_OUT = 265;
-
-        public static final int FIFTIES = 266;
-
-        public static final int COLORRGB16 = 267;
-
-        public static final int GRADIENT = 268;
-    }
-
-    /**
-     * Defines the video transitions.
-     */
-    public static class VideoTransition {
-        /** No transition */
-        public static final int NONE = 0;
-
-        /** Cross fade transition */
-        public static final int CROSS_FADE = 1;
-
-        /** External transition. Currently not available. */
-        public static final int EXTERNAL = 256;
-
-        /** AlphaMagic transition. */
-        public static final int ALPHA_MAGIC = 257;
-
-        /** Slide transition. */
-        public static final int SLIDE_TRANSITION = 258;
-
-        /** Fade to black transition. */
-        public static final int FADE_BLACK = 259;
-    }
-
-    /**
-     * Defines settings for the AlphaMagic transition
-     */
-    public static class AlphaMagicSettings {
-        /** Name of the alpha file (JPEG file). */
-        public String file;
-
-        /** Blending percentage [0..100] 0 = no blending. */
-        public int blendingPercent;
-
-        /** Invert the default rotation direction of the AlphaMagic effect. */
-        public boolean invertRotation;
-
-        public int rgbWidth;
-        public int rgbHeight;
-    }
-
-    /** Defines the direction of the Slide transition. */
-    public static final class SlideDirection {
-
-        /** Right out left in. */
-        public static final int RIGHT_OUT_LEFT_IN = 0;
-
-        /** Left out right in. */
-        public static final int LEFT_OUT_RIGTH_IN = 1;
-
-        /** Top out bottom in. */
-        public static final int TOP_OUT_BOTTOM_IN = 2;
-
-        /** Bottom out top in */
-        public static final int BOTTOM_OUT_TOP_IN = 3;
-    }
-
-    /** Defines the Slide transition settings. */
-    public static class SlideTransitionSettings {
-        /**
-         * Direction of the slide transition. See {@link SlideDirection
-         * SlideDirection} for valid values.
-         */
-        public int direction;
-    }
-
-    /**
-     * Defines the settings of a single clip.
-     */
-    public static class ClipSettings {
-
-        /**
-         * The path to the clip file.
-         * <p>
-         * File format of the clip, it can be:
-         * <ul>
-         * <li>3GP file containing MPEG4/H263/H264 video and AAC/AMR audio
-         * <li>JPG file
-         * </ul>
-         */
-
-        public String clipPath;
-
-        /**
-         * The path of the decoded file. This is used only for image files.
-         */
-        public String clipDecodedPath;
-
-        /**
-         * The path of the Original file. This is used only for image files.
-         */
-        public String clipOriginalPath;
-
-        /**
-         * File type of the clip. See {@link FileType FileType} for valid
-         * values.
-         */
-        public int fileType;
-
-        /** Begin of the cut in the clip in milliseconds. */
-        public int beginCutTime;
-
-        /**
-         * End of the cut in the clip in milliseconds. Set both
-         * <code>beginCutTime</code> and <code>endCutTime</code> to
-         * <code>0</code> to get the full length of the clip without a cut. In
-         * case of JPG clip, this is the duration of the JPEG file.
-         */
-        public int endCutTime;
-
-        /**
-         * Begin of the cut in the clip in percentage of the file duration.
-         */
-        public int beginCutPercent;
-
-        /**
-         * End of the cut in the clip in percentage of the file duration. Set
-         * both <code>beginCutPercent</code> and <code>endCutPercent</code> to
-         * <code>0</code> to get the full length of the clip without a cut.
-         */
-        public int endCutPercent;
-
-        /** Enable panning and zooming. */
-        public boolean panZoomEnabled;
-
-        /** Zoom percentage at start of clip. 0 = no zoom, 100 = full zoom */
-        public int panZoomPercentStart;
-
-        /** Top left X coordinate at start of clip. */
-        public int panZoomTopLeftXStart;
-
-        /** Top left Y coordinate at start of clip. */
-        public int panZoomTopLeftYStart;
-
-        /** Zoom percentage at start of clip. 0 = no zoom, 100 = full zoom */
-        public int panZoomPercentEnd;
-
-        /** Top left X coordinate at end of clip. */
-        public int panZoomTopLeftXEnd;
-
-        /** Top left Y coordinate at end of clip. */
-        public int panZoomTopLeftYEnd;
-
-        /**
-         * Set The media rendering. See {@link MediaRendering MediaRendering}
-         * for valid values.
-         */
-        public int mediaRendering;
-
-        /**
-         * RGB width and Height
-         */
-         public int rgbWidth;
-         public int rgbHeight;
-         /**
-         * Video rotation degree.
-         */
-         public int rotationDegree;
-    }
-
-    /**
-     * Defines settings for a transition.
-     */
-    public static class TransitionSettings {
-
-        /** Duration of the transition in msec. */
-        public int duration;
-
-        /**
-         * Transition type for video. See {@link VideoTransition
-         * VideoTransition} for valid values.
-         */
-        public int videoTransitionType;
-
-        /**
-         * Transition type for audio. See {@link AudioTransition
-         * AudioTransition} for valid values.
-         */
-        public int audioTransitionType;
-
-        /**
-         * Transition behaviour. See {@link TransitionBehaviour
-         * TransitionBehaviour} for valid values.
-         */
-        public int transitionBehaviour;
-
-        /**
-         * Settings for AlphaMagic transition. Only needs to be set if
-         * <code>videoTransitionType</code> is set to
-         * <code>VideoTransition.ALPHA_MAGIC</code>. See
-         * {@link AlphaMagicSettings AlphaMagicSettings}.
-         */
-        public AlphaMagicSettings alphaSettings;
-
-        /**
-         * Settings for the Slide transition. See
-         * {@link SlideTransitionSettings SlideTransitionSettings}.
-         */
-        public SlideTransitionSettings slideSettings;
-    }
-
-    public static final class AudioTransition {
-        /** No audio transition. */
-        public static final int NONE = 0;
-
-        /** Cross-fade audio transition. */
-        public static final int CROSS_FADE = 1;
-    }
-
-    /**
-     * Defines transition behaviors.
-     */
-    public static final class TransitionBehaviour {
-
-        /** The transition uses an increasing speed. */
-        public static final int SPEED_UP = 0;
-
-        /** The transition uses a linear (constant) speed. */
-        public static final int LINEAR = 1;
-
-        /** The transition uses a decreasing speed. */
-        public static final int SPEED_DOWN = 2;
-
-        /**
-         * The transition uses a constant speed, but slows down in the middle
-         * section.
-         */
-        public static final int SLOW_MIDDLE = 3;
-
-        /**
-         * The transition uses a constant speed, but increases speed in the
-         * middle section.
-         */
-        public static final int FAST_MIDDLE = 4;
-    }
-
-    /**
-     * Defines settings for the background music.
-     */
-    public static class BackgroundMusicSettings {
-
-        /** Background music file. */
-        public String file;
-
-        /** File type. See {@link FileType FileType} for valid values. */
-        public int fileType;
-
-        /**
-         * Insertion time in milliseconds, in the output video where the
-         * background music must be inserted.
-         */
-        public long insertionTime;
-
-        /**
-         * Volume, as a percentage of the background music track, to use. If
-         * this field is set to 100, the background music will replace the audio
-         * from the video input file(s).
-         */
-        public int volumePercent;
-
-        /**
-         * Start time in milliseconds in the background muisc file from where
-         * the background music should loop. Set both <code>beginLoop</code> and
-         * <code>endLoop</code> to <code>0</code> to disable looping.
-         */
-        public long beginLoop;
-
-        /**
-         * End time in milliseconds in the background music file to where the
-         * background music should loop. Set both <code>beginLoop</code> and
-         * <code>endLoop</code> to <code>0</code> to disable looping.
-         */
-        public long endLoop;
-
-        public boolean enableDucking;
-
-        public int duckingThreshold;
-
-        public int lowVolume;
-
-        public boolean isLooping;
-    }
-
-    /** Defines settings for an effect. */
-    public static class AudioEffect {
-        /** No audio effect. */
-        public static final int NONE = 0;
-
-        /** Fade-in effect. */
-        public static final int FADE_IN = 8;
-
-        /** Fade-out effect. */
-        public static final int FADE_OUT = 16;
-    }
-
-    /** Defines the effect settings. */
-    public static class EffectSettings {
-
-        /** Start time of the effect in milliseconds. */
-        public int startTime;
-
-        /** Duration of the effect in milliseconds. */
-        public int duration;
-
-        /**
-         * Video effect type. See {@link VideoEffect VideoEffect} for valid
-         * values.
-         */
-        public int videoEffectType;
-
-        /**
-         * Audio effect type. See {@link AudioEffect AudioEffect} for valid
-         * values.
-         */
-        public int audioEffectType;
-
-        /**
-         * Start time of the effect in percents of the duration of the clip. A
-         * value of 0 percent means start time is from the beginning of the
-         * clip.
-         */
-        public int startPercent;
-
-        /**
-         * Duration of the effect in percents of the duration of the clip.
-         */
-        public int durationPercent;
-
-        /**
-         * Framing file.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise
-         * this field is ignored.
-         */
-        public String framingFile;
-
-        /**
-         * Framing buffer.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise
-         * this field is ignored.
-         */
-        public int[] framingBuffer;
-
-        /**
-         * Bitmap type Can be from RGB_565 (4), ARGB_4444 (5), ARGB_8888 (6);
-         **/
-
-        public int bitmapType;
-
-        public int width;
-
-        public int height;
-
-        /**
-         * Top left x coordinate. This coordinate is used to set the x
-         * coordinate of the picture in the framing file when the framing file
-         * is selected. The x coordinate is also used to set the location of the
-         * text in the text effect.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING} or
-         * {@link VideoEffect#TEXT VideoEffect.TEXT}. Otherwise this field is
-         * ignored.
-         */
-        public int topLeftX;
-
-        /**
-         * Top left y coordinate. This coordinate is used to set the y
-         * coordinate of the picture in the framing file when the framing file
-         * is selected. The y coordinate is also used to set the location of the
-         * text in the text effect.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING} or
-         * {@link VideoEffect#TEXT VideoEffect.TEXT}. Otherwise this field is
-         * ignored.
-         */
-        public int topLeftY;
-
-        /**
-         * Should the frame be resized or not. If this field is set to
-         * <link>true</code> then the frame size is matched with the output
-         * video size.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise
-         * this field is ignored.
-         */
-        public boolean framingResize;
-
-        /**
-         * Size to which the framing buffer needs to be resized to
-         * This is valid only if framingResize is true
-         */
-        public int framingScaledSize;
-        /**
-         * Text to insert in the video.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT}. Otherwise this
-         * field is ignored.
-         */
-        public String text;
-
-        /**
-         * Text attributes for the text to insert in the video.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT}. Otherwise this
-         * field is ignored. For more details about this field see the
-         * integration guide.
-         */
-        public String textRenderingData;
-
-        /** Width of the text buffer in pixels. */
-        public int textBufferWidth;
-
-        /** Height of the text buffer in pixels. */
-        public int textBufferHeight;
-
-        /**
-         * Processing rate for the fifties effect. A high value (e.g. 30)
-         * results in high effect strength.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#FIFTIES VideoEffect.FIFTIES}. Otherwise
-         * this field is ignored.
-         */
-        public int fiftiesFrameRate;
-
-        /**
-         * RGB 16 color of the RGB16 and gradient color effect.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#COLORRGB16 VideoEffect.COLORRGB16} or
-         * {@link VideoEffect#GRADIENT VideoEffect.GRADIENT}. Otherwise this
-         * field is ignored.
-         */
-        public int rgb16InputColor;
-
-        /**
-         * Start alpha blending percentage.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
-         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
-         * is ignored.
-         */
-        public int alphaBlendingStartPercent;
-
-        /**
-         * Middle alpha blending percentage.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
-         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
-         * is ignored.
-         */
-        public int alphaBlendingMiddlePercent;
-
-        /**
-         * End alpha blending percentage.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
-         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
-         * is ignored.
-         */
-        public int alphaBlendingEndPercent;
-
-        /**
-         * Duration, in percentage of effect duration of the fade-in phase.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
-         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
-         * is ignored.
-         */
-        public int alphaBlendingFadeInTimePercent;
-
-        /**
-         * Duration, in percentage of effect duration of the fade-out phase.
-         * <p>
-         * This field is only used when the field <code>videoEffectType</code>
-         * is set to {@link VideoEffect#TEXT VideoEffect.TEXT} or
-         * {@link VideoEffect#FRAMING VideoEffect.FRAMING}. Otherwise this field
-         * is ignored.
-         */
-        public int alphaBlendingFadeOutTimePercent;
-    }
-
-    /** Defines the clip properties for preview */
-    public static class PreviewClips {
-
-        /**
-         * The path to the clip file.
-         * <p>
-         * File format of the clip, it can be:
-         * <ul>
-         * <li>3GP file containing MPEG4/H263 video and AAC/AMR audio
-         * <li>JPG file
-         * </ul>
-         */
-
-        public String clipPath;
-
-        /**
-         * File type of the clip. See {@link FileType FileType} for valid
-         * values.
-         */
-        public int fileType;
-
-        /** Begin of the cut in the clip in milliseconds. */
-        public long beginPlayTime;
-
-        public long endPlayTime;
-
-        /**
-         * Set The media rendering. See {@link MediaRendering MediaRendering}
-         * for valid values.
-         */
-        public int mediaRendering;
-
-    }
-
-    /** Defines the audio settings. */
-    public static class AudioSettings {
-
-        String pFile;
-
-        /** < PCM file path */
-        String Id;
-
-        boolean bRemoveOriginal;
-
-        /** < If true, the original audio track is not taken into account */
-        int channels;
-
-        /** < Number of channels (1=mono, 2=stereo) of BGM clip */
-        int Fs;
-
-        /**
-         * < Sampling audio frequency (8000 for amr, 16000 or more for aac) of
-         * BGM clip
-         */
-        int ExtendedFs;
-
-        /** < Extended frequency for AAC+, eAAC+ streams of BGM clip */
-        long startMs;
-
-        /** < Time, in milliseconds, at which the added audio track is inserted */
-        long beginCutTime;
-
-        long endCutTime;
-
-        int fileType;
-
-        int volume;
-
-        /** < Volume, in percentage, of the added audio track */
-        boolean loop;
-
-        /** < Looping on/off > **/
-
-        /** Audio mix and Duck **/
-        int ducking_threshold;
-
-        int ducking_lowVolume;
-
-        boolean bInDucking_enable;
-
-        String pcmFilePath;
-    }
-
-    /** Encapsulates preview clips and effect settings */
-    public static class PreviewSettings {
-
-        public PreviewClips[] previewClipsArray;
-
-        /** The effect settings. */
-        public EffectSettings[] effectSettingsArray;
-
-    }
-
-    /** Encapsulates clip properties */
-    public static class PreviewClipProperties {
-
-        public Properties[] clipProperties;
-
-    }
-
-    /** Defines the editing settings. */
-    public static class EditSettings {
-
-        /**
-         * Array of clip settings. There is one <code>clipSetting</code> for
-         * each clip.
-         */
-        public ClipSettings[] clipSettingsArray;
-
-        /**
-         * Array of transition settings. If there are n clips (and thus n
-         * <code>clipSettings</code>) then there are (n-1) transitions and (n-1)
-         * <code>transistionSettings</code> in
-         * <code>transistionSettingsArray</code>.
-         */
-        public TransitionSettings[] transitionSettingsArray;
-
-        /** The effect settings. */
-        public EffectSettings[] effectSettingsArray;
-
-        /**
-         * Video frame rate of the output clip. See {@link VideoFrameRate
-         * VideoFrameRate} for valid values.
-         */
-        public int videoFrameRate;
-
-        /** Output file name. Must be an absolute path. */
-        public String outputFile;
-
-        /**
-         * Size of the video frames in the output clip. See
-         * {@link VideoFrameSize VideoFrameSize} for valid values.
-         */
-        public int videoFrameSize;
-
-        /**
-         * Format of the video stream in the output clip. See
-         * {@link VideoFormat VideoFormat} for valid values.
-         */
-        public int videoFormat;
-
-        /**
-         * Profile of the video stream in the output clip.
-         */
-        public int videoProfile;
-
-        /**
-         * Level of the video stream in the output clip.
-         */
-        public int videoLevel;
-
-        /**
-         * Format of the audio stream in the output clip. See
-         * {@link AudioFormat AudioFormat} for valid values.
-         */
-        public int audioFormat;
-
-        /**
-         * Sampling frequency of the audio stream in the output clip. See
-         * {@link AudioSamplingFrequency AudioSamplingFrequency} for valid
-         * values.
-         */
-        public int audioSamplingFreq;
-
-        /**
-         * Maximum file size. By setting this you can set the maximum size of
-         * the output clip. Set it to <code>0</code> to let the class ignore
-         * this filed.
-         */
-        public int maxFileSize;
-
-        /**
-         * Number of audio channels in output clip. Use <code>0</code> for none,
-         * <code>1</code> for mono or <code>2</code> for stereo. None is only
-         * allowed when the <code>audioFormat</code> field is set to
-         * {@link AudioFormat#NO_AUDIO AudioFormat.NO_AUDIO} or
-         * {@link AudioFormat#NULL_AUDIO AudioFormat.NULL_AUDIO} Mono is only
-         * allowed when the <code>audioFormat</code> field is set to
-         * {@link AudioFormat#AAC AudioFormat.AAC}
-         */
-        public int audioChannels;
-
-        /** Video bitrate. See {@link Bitrate Bitrate} for valid values. */
-        public int videoBitrate;
-
-        /** Audio bitrate. See {@link Bitrate Bitrate} for valid values. */
-        public int audioBitrate;
-
-        /**
-         * Background music settings. See {@link BackgroundMusicSettings
-         * BackgroundMusicSettings} for valid values.
-         */
-        public BackgroundMusicSettings backgroundMusicSettings;
-
-        public int primaryTrackVolume;
-
-    }
-
-    /**
-     * Defines the media properties.
-     **/
-
-    public static class Properties {
-
-        /**
-         * Duration of the media in milliseconds.
-         */
-
-        public int duration;
-
-        /**
-         * File type.
-         */
-
-        public int fileType;
-
-        /**
-         * Video format.
-         */
-
-        public int videoFormat;
-
-        /**
-         * Duration of the video stream of the media in milliseconds.
-         */
-
-        public int videoDuration;
-
-        /**
-         * Bitrate of the video stream of the media.
-         */
-
-        public int videoBitrate;
-
-        /**
-         * Width of the video frames or the width of the still picture in
-         * pixels.
-         */
-
-        public int width;
-
-        /**
-         * Height of the video frames or the height of the still picture in
-         * pixels.
-         */
-
-        public int height;
-
-        /**
-         * Average frame rate of video in the media in frames per second.
-         */
-
-        public float averageFrameRate;
-
-        /**
-         * Profile of the video in the media.
-         */
-
-        public int profile;
-
-        /**
-         * Level of the video in the media.
-         */
-
-        public int level;
-
-        /**
-         * Is Video Profile supported.
-         */
-
-        public boolean profileSupported;
-
-        /**
-         * Is Video Level supported.
-         */
-
-        public boolean levelSupported;
-
-        /**
-         * Audio format.
-         */
-
-        public int audioFormat;
-
-        /**
-         * Duration of the audio stream of the media in milliseconds.
-         */
-
-        public int audioDuration;
-
-        /**
-         * Bitrate of the audio stream of the media.
-         */
-
-        public int audioBitrate;
-
-        /**
-         * Number of audio channels in the media.
-         */
-
-        public int audioChannels;
-
-        /**
-         * Sampling frequency of the audio stream in the media in samples per
-         * second.
-         */
-
-        public int audioSamplingFrequency;
-
-        /**
-         * Volume value of the audio track as percentage.
-         */
-        public int audioVolumeValue;
-
-        /**
-         * Video rotation degree.
-         */
-        public int videoRotation;
-
-        public String Id;
-    }
-
-    /**
-     * Constructor
-     *
-     * @param projectPath The path where the VideoEditor stores all files
-     *        related to the project
-     * @param lock The semaphore
-     * @param veObj The video editor reference
-     */
-    public MediaArtistNativeHelper(String projectPath, Semaphore lock, VideoEditor veObj) {
-        mProjectPath = projectPath;
-        if (veObj != null) {
-            mVideoEditor = veObj;
-        } else {
-            mVideoEditor = null;
-            throw new IllegalArgumentException("video editor object is null");
-        }
-        if (mStoryBoardSettings == null) {
-            mStoryBoardSettings = new EditSettings();
-        }
-
-        mLock = lock;
-
-        _init(mProjectPath, "null");
-        mAudioTrackPCMFilePath = null;
-    }
-
-    /**
-     * @return The project path
-     */
-    String getProjectPath() {
-        return mProjectPath;
-    }
-
-    /**
-     * @return The Audio Track PCM file path
-     */
-    String getProjectAudioTrackPCMFilePath() {
-        return mAudioTrackPCMFilePath;
-    }
-
-    /**
-     * Invalidates the PCM file
-     */
-    void invalidatePcmFile() {
-        if (mAudioTrackPCMFilePath != null) {
-            new File(mAudioTrackPCMFilePath).delete();
-            mAudioTrackPCMFilePath = null;
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private void onProgressUpdate(int taskId, int progress) {
-        if (mProcessingState == PROCESSING_EXPORT) {
-            if (mExportProgressListener != null) {
-                if (mProgressToApp < progress) {
-                    mExportProgressListener.onProgress(mVideoEditor, mOutputFilename, progress);
-                    /* record previous progress */
-                    mProgressToApp = progress;
-                }
-            }
-        }
-        else {
-            // Adapt progress depending on current state
-            int actualProgress = 0;
-            int action = 0;
-
-            if (mProcessingState == PROCESSING_AUDIO_PCM) {
-                action = MediaProcessingProgressListener.ACTION_DECODE;
-            } else {
-                action = MediaProcessingProgressListener.ACTION_ENCODE;
-            }
-
-            switch (mProcessingState) {
-                case PROCESSING_AUDIO_PCM:
-                    actualProgress = progress;
-                    break;
-                case PROCESSING_TRANSITION:
-                    actualProgress = progress;
-                    break;
-                case PROCESSING_KENBURNS:
-                    actualProgress = progress;
-                    break;
-                case PROCESSING_INTERMEDIATE1:
-                    if ((progress == 0) && (mProgressToApp != 0)) {
-                        mProgressToApp = 0;
-                    }
-                    if ((progress != 0) || (mProgressToApp != 0)) {
-                        actualProgress = progress/4;
-                    }
-                    break;
-                case PROCESSING_INTERMEDIATE2:
-                    if ((progress != 0) || (mProgressToApp != 0)) {
-                        actualProgress = 25 + progress/4;
-                    }
-                    break;
-                case PROCESSING_INTERMEDIATE3:
-                    if ((progress != 0) || (mProgressToApp != 0)) {
-                        actualProgress = 50 + progress/2;
-                    }
-                    break;
-                case PROCESSING_NONE:
-
-                default:
-                    Log.e(TAG, "ERROR unexpected State=" + mProcessingState);
-                    return;
-            }
-            if ((mProgressToApp != actualProgress) && (actualProgress != 0)) {
-
-                mProgressToApp = actualProgress;
-
-                if (mMediaProcessingProgressListener != null) {
-                    // Send the progress indication
-                    mMediaProcessingProgressListener.onProgress(mProcessingObject, action,
-                                                                actualProgress);
-                }
-            }
-            /* avoid 0 in next intermediate call */
-            if (mProgressToApp == 0) {
-                if (mMediaProcessingProgressListener != null) {
-                    /*
-                     *  Send the progress indication
-                     */
-                    mMediaProcessingProgressListener.onProgress(mProcessingObject, action,
-                                                                actualProgress);
-                }
-                mProgressToApp = 1;
-            }
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private void onPreviewProgressUpdate(int progress, boolean isFinished,
-                  boolean updateOverlay, String filename, int renderingMode, int error) {
-        if (mPreviewProgressListener != null) {
-            if (mIsFirstProgress) {
-                mPreviewProgressListener.onStart(mVideoEditor);
-                mIsFirstProgress = false;
-            }
-
-            final VideoEditor.OverlayData overlayData;
-            if (updateOverlay) {
-                overlayData = new VideoEditor.OverlayData();
-                if (filename != null) {
-                    overlayData.set(BitmapFactory.decodeFile(filename), renderingMode);
-                } else {
-                    overlayData.setClear();
-                }
-            } else {
-                overlayData = null;
-            }
-
-            if (progress != 0) {
-                mPreviewProgress = progress;
-            }
-
-            if (isFinished) {
-                mPreviewProgressListener.onStop(mVideoEditor);
-            } else if (error != 0) {
-                mPreviewProgressListener.onError(mVideoEditor, error);
-            } else {
-                mPreviewProgressListener.onProgress(mVideoEditor, progress, overlayData);
-            }
-        }
-    }
-
-    /**
-     * Release the native helper object
-     */
-    void releaseNativeHelper() throws InterruptedException {
-        release();
-    }
-
-    /**
-     * Release the native helper to end the Audio Graph process
-     */
-    @SuppressWarnings("unused")
-    private void onAudioGraphExtractProgressUpdate(int progress, boolean isVideo) {
-        if ((mExtractAudioWaveformProgressListener != null) && (progress > 0)) {
-            mExtractAudioWaveformProgressListener.onProgress(progress);
-        }
-    }
-
-    /**
-     * Populates the Effect Settings in EffectSettings
-     *
-     * @param effects The reference of EffectColor
-     *
-     * @return The populated effect settings in EffectSettings reference
-     */
-    EffectSettings getEffectSettings(EffectColor effects) {
-        EffectSettings effectSettings = new EffectSettings();
-        effectSettings.startTime = (int)effects.getStartTime();
-        effectSettings.duration = (int)effects.getDuration();
-        effectSettings.videoEffectType = getEffectColorType(effects);
-        effectSettings.audioEffectType = 0;
-        effectSettings.startPercent = 0;
-        effectSettings.durationPercent = 0;
-        effectSettings.framingFile = null;
-        effectSettings.topLeftX = 0;
-        effectSettings.topLeftY = 0;
-        effectSettings.framingResize = false;
-        effectSettings.text = null;
-        effectSettings.textRenderingData = null;
-        effectSettings.textBufferWidth = 0;
-        effectSettings.textBufferHeight = 0;
-        if (effects.getType() == EffectColor.TYPE_FIFTIES) {
-            effectSettings.fiftiesFrameRate = 15;
-        } else {
-            effectSettings.fiftiesFrameRate = 0;
-        }
-
-        if ((effectSettings.videoEffectType == VideoEffect.COLORRGB16)
-                || (effectSettings.videoEffectType == VideoEffect.GRADIENT)) {
-            effectSettings.rgb16InputColor = effects.getColor();
-        }
-
-        effectSettings.alphaBlendingStartPercent = 0;
-        effectSettings.alphaBlendingMiddlePercent = 0;
-        effectSettings.alphaBlendingEndPercent = 0;
-        effectSettings.alphaBlendingFadeInTimePercent = 0;
-        effectSettings.alphaBlendingFadeOutTimePercent = 0;
-        return effectSettings;
-    }
-
-    /**
-     * Populates the Overlay Settings in EffectSettings
-     *
-     * @param overlay The reference of OverlayFrame
-     *
-     * @return The populated overlay settings in EffectSettings reference
-     */
-    EffectSettings getOverlaySettings(OverlayFrame overlay) {
-        EffectSettings effectSettings = new EffectSettings();
-        Bitmap bitmap = null;
-
-        effectSettings.startTime = (int)overlay.getStartTime();
-        effectSettings.duration = (int)overlay.getDuration();
-        effectSettings.videoEffectType = VideoEffect.FRAMING;
-        effectSettings.audioEffectType = 0;
-        effectSettings.startPercent = 0;
-        effectSettings.durationPercent = 0;
-        effectSettings.framingFile = null;
-
-        if ((bitmap = overlay.getBitmap()) != null) {
-            effectSettings.framingFile = overlay.getFilename();
-
-            if (effectSettings.framingFile == null) {
-                try {
-                    (overlay).save(mProjectPath);
-                } catch (IOException e) {
-                    Log.e(TAG, "getOverlaySettings : File not found");
-                }
-                effectSettings.framingFile = overlay.getFilename();
-            }
-            if (bitmap.getConfig() == Bitmap.Config.ARGB_8888)
-                effectSettings.bitmapType = 6;
-            else if (bitmap.getConfig() == Bitmap.Config.ARGB_4444)
-                effectSettings.bitmapType = 5;
-            else if (bitmap.getConfig() == Bitmap.Config.RGB_565)
-                effectSettings.bitmapType = 4;
-            else if (bitmap.getConfig() == Bitmap.Config.ALPHA_8)
-                throw new RuntimeException("Bitmap config not supported");
-
-            effectSettings.width = bitmap.getWidth();
-            effectSettings.height = bitmap.getHeight();
-            effectSettings.framingBuffer = new int[effectSettings.width];
-            int tmp = 0;
-            short maxAlpha = 0;
-            short minAlpha = (short)0xFF;
-            short alpha = 0;
-            while (tmp < effectSettings.height) {
-                bitmap.getPixels(effectSettings.framingBuffer, 0,
-                                 effectSettings.width, 0, tmp,
-                                 effectSettings.width, 1);
-                for (int i = 0; i < effectSettings.width; i++) {
-                    alpha = (short)((effectSettings.framingBuffer[i] >> 24) & 0xFF);
-                    if (alpha > maxAlpha) {
-                        maxAlpha = alpha;
-                    }
-                    if (alpha < minAlpha) {
-                        minAlpha = alpha;
-                    }
-                }
-                tmp += 1;
-            }
-            alpha = (short)((maxAlpha + minAlpha) / 2);
-            alpha = (short)((alpha * 100) / 256);
-            effectSettings.alphaBlendingEndPercent = alpha;
-            effectSettings.alphaBlendingMiddlePercent = alpha;
-            effectSettings.alphaBlendingStartPercent = alpha;
-            effectSettings.alphaBlendingFadeInTimePercent = 100;
-            effectSettings.alphaBlendingFadeOutTimePercent = 100;
-            effectSettings.framingBuffer = null;
-
-            /*
-             * Set the resized RGB file dimensions
-             */
-            effectSettings.width = overlay.getResizedRGBSizeWidth();
-            if(effectSettings.width == 0) {
-                effectSettings.width = bitmap.getWidth();
-            }
-
-            effectSettings.height = overlay.getResizedRGBSizeHeight();
-            if(effectSettings.height == 0) {
-                effectSettings.height = bitmap.getHeight();
-            }
-
-        }
-
-        effectSettings.topLeftX = 0;
-        effectSettings.topLeftY = 0;
-
-        effectSettings.framingResize = true;
-        effectSettings.text = null;
-        effectSettings.textRenderingData = null;
-        effectSettings.textBufferWidth = 0;
-        effectSettings.textBufferHeight = 0;
-        effectSettings.fiftiesFrameRate = 0;
-        effectSettings.rgb16InputColor = 0;
-        int mediaItemHeight;
-        int aspectRatio;
-        if (overlay.getMediaItem() instanceof MediaImageItem) {
-            if (((MediaImageItem)overlay.getMediaItem()).getGeneratedImageClip() != null) {
-                // Ken Burns was applied
-                mediaItemHeight = ((MediaImageItem)overlay.getMediaItem()).getGeneratedClipHeight();
-                aspectRatio = getAspectRatio(
-                    ((MediaImageItem)overlay.getMediaItem()).getGeneratedClipWidth()
-                    , mediaItemHeight);
-            } else {
-                //For image get the scaled height. Aspect ratio would remain the same
-                mediaItemHeight = ((MediaImageItem)overlay.getMediaItem()).getScaledHeight();
-                aspectRatio = overlay.getMediaItem().getAspectRatio();
-            }
-        } else {
-            aspectRatio = overlay.getMediaItem().getAspectRatio();
-            mediaItemHeight = overlay.getMediaItem().getHeight();
-        }
-        effectSettings.framingScaledSize = findVideoResolution(aspectRatio, mediaItemHeight);
-        return effectSettings;
-    }
-
-     /* get Video Editor aspect ratio */
-    int nativeHelperGetAspectRatio() {
-        return mVideoEditor.getAspectRatio();
-    }
-
-    /**
-     * Sets the export audio codec
-     *
-     * @param export audio codec
-     *
-     */
-    void setAudioCodec(int codec) {
-        mExportAudioCodec = codec;
-    }
-    /**
-     * Sets the export video codec
-     *
-     * @param export video codec
-     *
-     */
-    void setVideoCodec(int codec) {
-        mExportVideoCodec = codec;
-    }
-
-    /**
-     * Sets the audio regenerate flag
-     *
-     * @param flag The boolean to set the audio regenerate flag
-     *
-     */
-    void setAudioflag(boolean flag) {
-        //check if the file exists.
-        if (!(new File(String.format(mProjectPath + "/" + AUDIO_TRACK_PCM_FILE)).exists())) {
-            flag = true;
-        }
-        mRegenerateAudio = flag;
-    }
-
-    /**
-     * Gets the audio regenerate flag
-     *
-     * @param return The boolean to get the audio regenerate flag
-     *
-     */
-    boolean getAudioflag() {
-        return mRegenerateAudio;
-    }
-
-    /**
-     * Maps the average frame rate to one of the defined enum values
-     *
-     * @param averageFrameRate The average frame rate of video item
-     *
-     * @return The frame rate from one of the defined enum values
-     */
-    int GetClosestVideoFrameRate(int averageFrameRate) {
-        if (averageFrameRate >= 25) {
-            return VideoFrameRate.FR_30_FPS;
-        } else if (averageFrameRate >= 20) {
-            return VideoFrameRate.FR_25_FPS;
-        } else if (averageFrameRate >= 15) {
-            return VideoFrameRate.FR_20_FPS;
-        } else if (averageFrameRate >= 12) {
-            return VideoFrameRate.FR_15_FPS;
-        } else if (averageFrameRate >= 10) {
-            return VideoFrameRate.FR_12_5_FPS;
-        } else if (averageFrameRate >= 7) {
-            return VideoFrameRate.FR_10_FPS;
-        } else if (averageFrameRate >= 5) {
-            return VideoFrameRate.FR_7_5_FPS;
-        } else {
-            return -1;
-        }
-    }
-
-    /**
-     * Helper function to adjust the effect or overlay start time
-     * depending on the begin and end boundary time of meddia item
-     */
-    public void adjustEffectsStartTimeAndDuration(EffectSettings lEffect, int beginCutTime,
-                                                  int endCutTime) {
-
-        int effectStartTime = 0;
-        int effectDuration = 0;
-
-        /**
-         * cbct -> clip begin cut time
-         * cect -> clip end cut time
-         ****************************************
-         *  |                                 |
-         *  |         cbct        cect        |
-         *  | <-1-->   |           |          |
-         *  |       <--|-2->       |          |
-         *  |          | <---3---> |          |
-         *  |          |        <--|-4--->    |
-         *  |          |           | <--5-->  |
-         *  |      <---|------6----|---->     |
-         *  |                                 |
-         *  < : effectStart
-         *  > : effectStart + effectDuration
-         ****************************************
-         **/
-
-        /** 1 & 5 */
-        /**
-         * Effect falls out side the trim duration. In such a case effects shall
-         * not be applied.
-         */
-        if ((lEffect.startTime > endCutTime)
-                || ((lEffect.startTime + lEffect.duration) <= beginCutTime)) {
-
-            effectStartTime = 0;
-            effectDuration = 0;
-
-            lEffect.startTime = effectStartTime;
-            lEffect.duration = effectDuration;
-            return;
-        }
-
-        /** 2 */
-        if ((lEffect.startTime < beginCutTime)
-                && ((lEffect.startTime + lEffect.duration) > beginCutTime)
-                && ((lEffect.startTime + lEffect.duration) <= endCutTime)) {
-            effectStartTime = 0;
-            effectDuration = lEffect.duration;
-
-            effectDuration -= (beginCutTime - lEffect.startTime);
-            lEffect.startTime = effectStartTime;
-            lEffect.duration = effectDuration;
-            return;
-        }
-
-        /** 3 */
-        if ((lEffect.startTime >= beginCutTime)
-                && ((lEffect.startTime + lEffect.duration) <= endCutTime)) {
-            effectStartTime = lEffect.startTime - beginCutTime;
-            lEffect.startTime = effectStartTime;
-            lEffect.duration = lEffect.duration;
-            return;
-        }
-
-        /** 4 */
-        if ((lEffect.startTime >= beginCutTime)
-                && ((lEffect.startTime + lEffect.duration) > endCutTime)) {
-            effectStartTime = lEffect.startTime - beginCutTime;
-            effectDuration = endCutTime - lEffect.startTime;
-            lEffect.startTime = effectStartTime;
-            lEffect.duration = effectDuration;
-            return;
-        }
-
-        /** 6 */
-        if ((lEffect.startTime < beginCutTime)
-                && ((lEffect.startTime + lEffect.duration) > endCutTime)) {
-            effectStartTime = 0;
-            effectDuration = endCutTime - beginCutTime;
-            lEffect.startTime = effectStartTime;
-            lEffect.duration = effectDuration;
-            return;
-        }
-
-    }
-
-    /**
-     * Generates the clip for preview or export
-     *
-     * @param editSettings The EditSettings reference for generating
-     * a clip for preview or export
-     *
-     * @return error value
-     */
-    public int generateClip(EditSettings editSettings) {
-        int err = 0;
-
-        try {
-            err = nativeGenerateClip(editSettings);
-        } catch (IllegalArgumentException ex) {
-            Log.e(TAG, "Illegal Argument exception in load settings");
-            return -1;
-        } catch (IllegalStateException ex) {
-            Log.e(TAG, "Illegal state exception in load settings");
-            return -1;
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "Runtime exception in load settings");
-            return -1;
-        }
-        return err;
-    }
-
-    /**
-     * Init function to initialiZe the  ClipSettings reference to
-     * default values
-     *
-     * @param lclipSettings The ClipSettings reference
-     */
-    void initClipSettings(ClipSettings lclipSettings) {
-        lclipSettings.clipPath = null;
-        lclipSettings.clipDecodedPath = null;
-        lclipSettings.clipOriginalPath = null;
-        lclipSettings.fileType = 0;
-        lclipSettings.endCutTime = 0;
-        lclipSettings.beginCutTime = 0;
-        lclipSettings.beginCutPercent = 0;
-        lclipSettings.endCutPercent = 0;
-        lclipSettings.panZoomEnabled = false;
-        lclipSettings.panZoomPercentStart = 0;
-        lclipSettings.panZoomTopLeftXStart = 0;
-        lclipSettings.panZoomTopLeftYStart = 0;
-        lclipSettings.panZoomPercentEnd = 0;
-        lclipSettings.panZoomTopLeftXEnd = 0;
-        lclipSettings.panZoomTopLeftYEnd = 0;
-        lclipSettings.mediaRendering = 0;
-        lclipSettings.rotationDegree = 0;
-    }
-
-
-    /**
-     * Populates the settings for generating an effect clip
-     *
-     * @param lMediaItem The media item for which the effect clip
-     * needs to be generated
-     * @param lclipSettings The ClipSettings reference containing
-     * clips data
-     * @param e The EditSettings reference containing effect specific data
-     * @param uniqueId The unique id used in the name of the output clip
-     * @param clipNo Used for internal purpose
-     *
-     * @return The name and path of generated clip
-     */
-    String generateEffectClip(MediaItem lMediaItem, ClipSettings lclipSettings,
-            EditSettings e,String uniqueId,int clipNo) {
-        int err = 0;
-        EditSettings editSettings = null;
-        String EffectClipPath = null;
-        int outVideoProfile = 0;
-        int outVideoLevel = 0;
-        editSettings = new EditSettings();
-
-        editSettings.clipSettingsArray = new ClipSettings[1];
-        editSettings.clipSettingsArray[0] = lclipSettings;
-
-        editSettings.backgroundMusicSettings = null;
-        editSettings.transitionSettingsArray = null;
-        editSettings.effectSettingsArray = e.effectSettingsArray;
-
-        EffectClipPath = String.format(mProjectPath + "/" + "ClipEffectIntermediate" + "_"
-                + lMediaItem.getId() + uniqueId + ".3gp");
-
-        File tmpFile = new File(EffectClipPath);
-        if (tmpFile.exists()) {
-            tmpFile.delete();
-        }
-
-        outVideoProfile = VideoEditorProfile.getExportProfile(VideoFormat.H264);
-        outVideoLevel = VideoEditorProfile.getExportLevel(VideoFormat.H264);
-        editSettings.videoProfile = outVideoProfile;
-        editSettings.videoLevel= outVideoLevel;
-
-        if (lMediaItem instanceof MediaVideoItem) {
-            MediaVideoItem m = (MediaVideoItem)lMediaItem;
-
-            editSettings.audioFormat = AudioFormat.AAC;
-            editSettings.audioChannels = 2;
-            editSettings.audioBitrate = Bitrate.BR_64_KBPS;
-            editSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
-
-            editSettings.videoFormat = VideoFormat.H264;
-            editSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
-            editSettings.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(),
-                    m.getHeight());
-            editSettings.videoBitrate = findVideoBitrate(editSettings.videoFrameSize);
-        } else {
-            MediaImageItem m = (MediaImageItem)lMediaItem;
-            editSettings.audioBitrate = Bitrate.BR_64_KBPS;
-            editSettings.audioChannels = 2;
-            editSettings.audioFormat = AudioFormat.AAC;
-            editSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
-
-            editSettings.videoFormat = VideoFormat.H264;
-            editSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
-            editSettings.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(),
-                    m.getScaledHeight());
-            editSettings.videoBitrate = findVideoBitrate(editSettings.videoFrameSize);
-        }
-
-        editSettings.outputFile = EffectClipPath;
-
-        if (clipNo == 1) {
-            mProcessingState  = PROCESSING_INTERMEDIATE1;
-        } else if (clipNo == 2) {
-            mProcessingState  = PROCESSING_INTERMEDIATE2;
-        }
-        mProcessingObject = lMediaItem;
-        err = generateClip(editSettings);
-        mProcessingState  = PROCESSING_NONE;
-
-        if (err == 0) {
-            lclipSettings.clipPath = EffectClipPath;
-            lclipSettings.fileType = FileType.THREE_GPP;
-            return EffectClipPath;
-        } else {
-            throw new RuntimeException("preview generation cannot be completed");
-        }
-    }
-
-
-    /**
-     * Populates the settings for generating a Ken Burn effect clip
-     *
-     * @param m The media image item for which the Ken Burn effect clip
-     * needs to be generated
-     * @param e The EditSettings reference clip specific data
-     *
-     * @return The name and path of generated clip
-     */
-    String generateKenBurnsClip(EditSettings e, MediaImageItem m) {
-        String output = null;
-        int err = 0;
-        int outVideoProfile = 0;
-        int outVideoLevel = 0;
-
-        e.backgroundMusicSettings = null;
-        e.transitionSettingsArray = null;
-        e.effectSettingsArray = null;
-        output = String.format(mProjectPath + "/" + "ImageClip-" + m.getId() + ".3gp");
-
-        File tmpFile = new File(output);
-        if (tmpFile.exists()) {
-            tmpFile.delete();
-        }
-
-        outVideoProfile = VideoEditorProfile.getExportProfile(VideoFormat.H264);
-        outVideoLevel = VideoEditorProfile.getExportLevel(VideoFormat.H264);
-        e.videoProfile = outVideoProfile;
-        e.videoLevel = outVideoLevel;
-
-        e.outputFile = output;
-        e.audioBitrate = Bitrate.BR_64_KBPS;
-        e.audioChannels = 2;
-        e.audioFormat = AudioFormat.AAC;
-        e.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
-
-        e.videoFormat = VideoFormat.H264;
-        e.videoFrameRate = VideoFrameRate.FR_30_FPS;
-        e.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(),
-                                                           m.getScaledHeight());
-        e.videoBitrate = findVideoBitrate(e.videoFrameSize);
-
-        mProcessingState  = PROCESSING_KENBURNS;
-        mProcessingObject = m;
-        err = generateClip(e);
-        // Reset the processing state and check for errors
-        mProcessingState  = PROCESSING_NONE;
-        if (err != 0) {
-            throw new RuntimeException("preview generation cannot be completed");
-        }
-        return output;
-    }
-
-
-    /**
-     * Calculates the output resolution for transition clip
-     *
-     * @param m1 First media item associated with transition
-     * @param m2 Second media item associated with transition
-     *
-     * @return The transition resolution
-     */
-    private int getTransitionResolution(MediaItem m1, MediaItem m2) {
-        int clip1Height = 0;
-        int clip2Height = 0;
-        int videoSize = 0;
-
-        if (m1 != null && m2 != null) {
-            if (m1 instanceof MediaVideoItem) {
-                clip1Height = m1.getHeight();
-            } else if (m1 instanceof MediaImageItem) {
-                clip1Height = ((MediaImageItem)m1).getScaledHeight();
-            }
-            if (m2 instanceof MediaVideoItem) {
-                clip2Height = m2.getHeight();
-            } else if (m2 instanceof MediaImageItem) {
-                clip2Height = ((MediaImageItem)m2).getScaledHeight();
-            }
-            if (clip1Height > clip2Height) {
-                videoSize = findVideoResolution(mVideoEditor.getAspectRatio(), clip1Height);
-            } else {
-                videoSize = findVideoResolution(mVideoEditor.getAspectRatio(), clip2Height);
-            }
-        } else if (m1 == null && m2 != null) {
-            if (m2 instanceof MediaVideoItem) {
-                clip2Height = m2.getHeight();
-            } else if (m2 instanceof MediaImageItem) {
-                clip2Height = ((MediaImageItem)m2).getScaledHeight();
-            }
-            videoSize = findVideoResolution(mVideoEditor.getAspectRatio(), clip2Height);
-        } else if (m1 != null && m2 == null) {
-            if (m1 instanceof MediaVideoItem) {
-                clip1Height = m1.getHeight();
-            } else if (m1 instanceof MediaImageItem) {
-                clip1Height = ((MediaImageItem)m1).getScaledHeight();
-            }
-            videoSize = findVideoResolution(mVideoEditor.getAspectRatio(), clip1Height);
-        }
-        return videoSize;
-    }
-
-    /**
-     * Populates the settings for generating an transition clip
-     *
-     * @param m1 First media item associated with transition
-     * @param m2 Second media item associated with transition
-     * @param e The EditSettings reference containing
-     * clip specific data
-     * @param uniqueId The unique id used in the name of the output clip
-     * @param t The Transition specific data
-     *
-     * @return The name and path of generated clip
-     */
-    String generateTransitionClip(EditSettings e, String uniqueId,
-            MediaItem m1, MediaItem m2,Transition t) {
-        String outputFilename = null;
-        int err = 0;
-        int outVideoProfile = 0;
-        int outVideoLevel = 0;
-        outputFilename = String.format(mProjectPath + "/" + uniqueId + ".3gp");
-
-        outVideoProfile = VideoEditorProfile.getExportProfile(VideoFormat.H264);
-        outVideoLevel = VideoEditorProfile.getExportLevel(VideoFormat.H264);
-        e.videoProfile = outVideoProfile;
-        e.videoLevel = outVideoLevel;
-
-        e.outputFile = outputFilename;
-        e.audioBitrate = Bitrate.BR_64_KBPS;
-        e.audioChannels = 2;
-        e.audioFormat = AudioFormat.AAC;
-        e.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
-
-        e.videoFormat = VideoFormat.H264;
-        e.videoFrameRate = VideoFrameRate.FR_30_FPS;
-        e.videoFrameSize = getTransitionResolution(m1, m2);
-        e.videoBitrate = findVideoBitrate(e.videoFrameSize);
-
-        if (new File(outputFilename).exists()) {
-            new File(outputFilename).delete();
-        }
-        mProcessingState  = PROCESSING_INTERMEDIATE3;
-        mProcessingObject = t;
-        err = generateClip(e);
-        // Reset the processing state and check for errors
-        mProcessingState  = PROCESSING_NONE;
-        if (err != 0) {
-            throw new RuntimeException("preview generation cannot be completed");
-        }
-        return outputFilename;
-    }
-
-    /**
-     * Populates effects and overlays in EffectSettings structure
-     * and also adjust the start time and duration of effects and overlays
-     * w.r.t to total story board time
-     *
-     * @param m1 Media item associated with effect
-     * @param effectSettings The EffectSettings reference containing
-     *      effect specific data
-     * @param beginCutTime The begin cut time of the clip associated with effect
-     * @param endCutTime The end cut time of the clip associated with effect
-     * @param storyBoardTime The current story board time
-     *
-     * @return The updated index
-     */
-    private int populateEffects(MediaItem m, EffectSettings[] effectSettings, int i,
-            int beginCutTime, int endCutTime, int storyBoardTime) {
-
-        if (m.getBeginTransition() != null && m.getBeginTransition().getDuration() > 0
-                && m.getEndTransition() != null && m.getEndTransition().getDuration() > 0) {
-            beginCutTime += m.getBeginTransition().getDuration();
-            endCutTime -= m.getEndTransition().getDuration();
-        } else if (m.getBeginTransition() == null && m.getEndTransition() != null
-                && m.getEndTransition().getDuration() > 0) {
-            endCutTime -= m.getEndTransition().getDuration();
-        } else if (m.getEndTransition() == null && m.getBeginTransition() != null
-                && m.getBeginTransition().getDuration() > 0) {
-            beginCutTime += m.getBeginTransition().getDuration();
-        }
-
-        final List<Effect> effects = m.getAllEffects();
-        final List<Overlay> overlays = m.getAllOverlays();
-
-        for (Overlay overlay : overlays) {
-            effectSettings[i] = getOverlaySettings((OverlayFrame)overlay);
-            adjustEffectsStartTimeAndDuration(effectSettings[i], beginCutTime, endCutTime);
-            effectSettings[i].startTime += storyBoardTime;
-            i++;
-        }
-
-        for (Effect effect : effects) {
-            if (effect instanceof EffectColor) {
-                effectSettings[i] = getEffectSettings((EffectColor)effect);
-                adjustEffectsStartTimeAndDuration(effectSettings[i], beginCutTime, endCutTime);
-                effectSettings[i].startTime += storyBoardTime;
-                i++;
-            }
-        }
-
-        return i;
-    }
-
-    /**
-     * Adjusts the media item boundaries for use in export or preview
-     *
-     * @param clipSettings The ClipSettings reference
-     * @param clipProperties The Properties reference
-     * @param m The media item
-     */
-    private void adjustMediaItemBoundary(ClipSettings clipSettings,
-                                         Properties clipProperties, MediaItem m) {
-        if (m.getBeginTransition() != null && m.getBeginTransition().getDuration() > 0
-                && m.getEndTransition() != null && m.getEndTransition().getDuration() > 0) {
-            clipSettings.beginCutTime += m.getBeginTransition().getDuration();
-            clipSettings.endCutTime -= m.getEndTransition().getDuration();
-        } else if (m.getBeginTransition() == null && m.getEndTransition() != null
-                && m.getEndTransition().getDuration() > 0) {
-            clipSettings.endCutTime -= m.getEndTransition().getDuration();
-        } else if (m.getEndTransition() == null && m.getBeginTransition() != null
-                && m.getBeginTransition().getDuration() > 0) {
-            clipSettings.beginCutTime += m.getBeginTransition().getDuration();
-        }
-
-        clipProperties.duration = clipSettings.endCutTime - clipSettings.beginCutTime;
-
-        if (clipProperties.videoDuration != 0) {
-            clipProperties.videoDuration = clipSettings.endCutTime - clipSettings.beginCutTime;
-        }
-
-        if (clipProperties.audioDuration != 0) {
-            clipProperties.audioDuration = clipSettings.endCutTime - clipSettings.beginCutTime;
-        }
-    }
-
-    /**
-     * Generates the transition if transition is present
-     * and is in invalidated state
-     *
-     * @param transition The Transition reference
-     * @param editSettings The EditSettings reference
-     * @param clipPropertiesArray The clip Properties array
-     * @param i The index in clip Properties array for current clip
-     */
-    private void generateTransition(Transition transition, EditSettings editSettings,
-            PreviewClipProperties clipPropertiesArray, int index) {
-        if (!(transition.isGenerated())) {
-            transition.generate();
-        }
-        editSettings.clipSettingsArray[index] = new ClipSettings();
-        editSettings.clipSettingsArray[index].clipPath = transition.getFilename();
-        editSettings.clipSettingsArray[index].fileType = FileType.THREE_GPP;
-        editSettings.clipSettingsArray[index].beginCutTime = 0;
-        editSettings.clipSettingsArray[index].endCutTime = (int)transition.getDuration();
-        editSettings.clipSettingsArray[index].mediaRendering = MediaRendering.BLACK_BORDERS;
-
-        try {
-            clipPropertiesArray.clipProperties[index] =
-                getMediaProperties(transition.getFilename());
-        } catch (Exception e) {
-            throw new IllegalArgumentException("Unsupported file or file not found");
-        }
-
-        clipPropertiesArray.clipProperties[index].Id = null;
-        clipPropertiesArray.clipProperties[index].audioVolumeValue = 100;
-        clipPropertiesArray.clipProperties[index].duration = (int)transition.getDuration();
-        if (clipPropertiesArray.clipProperties[index].videoDuration != 0) {
-            clipPropertiesArray.clipProperties[index].videoDuration = (int)transition.getDuration();
-        }
-
-        if (clipPropertiesArray.clipProperties[index].audioDuration != 0) {
-            clipPropertiesArray.clipProperties[index].audioDuration = (int)transition.getDuration();
-        }
-    }
-
-    /**
-     * Sets the volume for current media item in clip properties array
-     *
-     * @param m The media item
-     * @param clipProperties The clip properties array reference
-     * @param i The index in clip Properties array for current clip
-     */
-    private void adjustVolume(MediaItem m, PreviewClipProperties clipProperties,
-                              int index) {
-        if (m instanceof MediaVideoItem) {
-            final boolean videoMuted = ((MediaVideoItem)m).isMuted();
-            if (videoMuted == false) {
-                mClipProperties.clipProperties[index].audioVolumeValue =
-                    ((MediaVideoItem)m).getVolume();
-            } else {
-                mClipProperties.clipProperties[index].audioVolumeValue = 0;
-            }
-        } else if (m instanceof MediaImageItem) {
-            mClipProperties.clipProperties[index].audioVolumeValue = 0;
-        }
-    }
-
-    /**
-     * Checks for odd size image width and height
-     *
-     * @param m The media item
-     * @param clipProperties The clip properties array reference
-     * @param i The index in clip Properties array for current clip
-     */
-    private void checkOddSizeImage(MediaItem m, PreviewClipProperties clipProperties, int index) {
-        if (m instanceof MediaImageItem) {
-            int width = mClipProperties.clipProperties[index].width;
-            int height = mClipProperties.clipProperties[index].height;
-
-            if ((width % 2) != 0) {
-                width -= 1;
-            }
-            if ((height % 2) != 0) {
-                height -= 1;
-            }
-            mClipProperties.clipProperties[index].width = width;
-            mClipProperties.clipProperties[index].height = height;
-        }
-    }
-
-    /**
-     * Populates the media item properties and calculates the maximum
-     * height among all the clips
-     *
-     * @param m The media item
-     * @param i The index in clip Properties array for current clip
-     * @param maxHeight The max height from the clip properties
-     *
-     * @return Updates the max height if current clip's height is greater
-     * than all previous clips height
-     */
-    private int populateMediaItemProperties(MediaItem m, int index, int maxHeight) {
-        mPreviewEditSettings.clipSettingsArray[index] = new ClipSettings();
-        if (m instanceof MediaVideoItem) {
-            mPreviewEditSettings.clipSettingsArray[index] =
-                ((MediaVideoItem)m).getVideoClipProperties();
-            if (((MediaVideoItem)m).getHeight() > maxHeight) {
-                maxHeight = ((MediaVideoItem)m).getHeight();
-            }
-        } else if (m instanceof MediaImageItem) {
-            mPreviewEditSettings.clipSettingsArray[index] =
-                ((MediaImageItem)m).getImageClipProperties();
-            if (((MediaImageItem)m).getScaledHeight() > maxHeight) {
-                maxHeight = ((MediaImageItem)m).getScaledHeight();
-            }
-        }
-        /** + Handle the image files here */
-        if (mPreviewEditSettings.clipSettingsArray[index].fileType == FileType.JPG) {
-            mPreviewEditSettings.clipSettingsArray[index].clipDecodedPath =
-                ((MediaImageItem)m).getDecodedImageFileName();
-
-            mPreviewEditSettings.clipSettingsArray[index].clipOriginalPath =
-                         mPreviewEditSettings.clipSettingsArray[index].clipPath;
-        }
-        return maxHeight;
-    }
-
-    /**
-     * Populates the background music track properties
-     *
-     * @param mediaBGMList The background music list
-     *
-     */
-    private void populateBackgroundMusicProperties(List<AudioTrack> mediaBGMList) {
-
-        if (mediaBGMList.size() == 1) {
-            mAudioTrack = mediaBGMList.get(0);
-        } else {
-            mAudioTrack = null;
-        }
-
-        if (mAudioTrack != null) {
-            mAudioSettings = new AudioSettings();
-            Properties mAudioProperties = new Properties();
-            mAudioSettings.pFile = null;
-            mAudioSettings.Id = mAudioTrack.getId();
-            try {
-                mAudioProperties = getMediaProperties(mAudioTrack.getFilename());
-            } catch (Exception e) {
-               throw new IllegalArgumentException("Unsupported file or file not found");
-            }
-            mAudioSettings.bRemoveOriginal = false;
-            mAudioSettings.channels = mAudioProperties.audioChannels;
-            mAudioSettings.Fs = mAudioProperties.audioSamplingFrequency;
-            mAudioSettings.loop = mAudioTrack.isLooping();
-            mAudioSettings.ExtendedFs = 0;
-            mAudioSettings.pFile = mAudioTrack.getFilename();
-            mAudioSettings.startMs = mAudioTrack.getStartTime();
-            mAudioSettings.beginCutTime = mAudioTrack.getBoundaryBeginTime();
-            mAudioSettings.endCutTime = mAudioTrack.getBoundaryEndTime();
-            if (mAudioTrack.isMuted()) {
-                mAudioSettings.volume = 0;
-            } else {
-                mAudioSettings.volume = mAudioTrack.getVolume();
-            }
-            mAudioSettings.fileType = mAudioProperties.fileType;
-            mAudioSettings.ducking_lowVolume = mAudioTrack.getDuckedTrackVolume();
-            mAudioSettings.ducking_threshold = mAudioTrack.getDuckingThreshhold();
-            mAudioSettings.bInDucking_enable = mAudioTrack.isDuckingEnabled();
-            mAudioTrackPCMFilePath = String.format(mProjectPath + "/" + AUDIO_TRACK_PCM_FILE);
-            mAudioSettings.pcmFilePath = mAudioTrackPCMFilePath;
-
-            mPreviewEditSettings.backgroundMusicSettings = new BackgroundMusicSettings();
-            mPreviewEditSettings.backgroundMusicSettings.file = mAudioTrackPCMFilePath;
-            mPreviewEditSettings.backgroundMusicSettings.fileType = mAudioProperties.fileType;
-            mPreviewEditSettings.backgroundMusicSettings.insertionTime =
-                mAudioTrack.getStartTime();
-            mPreviewEditSettings.backgroundMusicSettings.volumePercent = mAudioTrack.getVolume();
-            mPreviewEditSettings.backgroundMusicSettings.beginLoop =
-                mAudioTrack.getBoundaryBeginTime();
-            mPreviewEditSettings.backgroundMusicSettings.endLoop =
-                                               mAudioTrack.getBoundaryEndTime();
-            mPreviewEditSettings.backgroundMusicSettings.enableDucking =
-                mAudioTrack.isDuckingEnabled();
-            mPreviewEditSettings.backgroundMusicSettings.duckingThreshold =
-                mAudioTrack.getDuckingThreshhold();
-            mPreviewEditSettings.backgroundMusicSettings.lowVolume =
-                mAudioTrack.getDuckedTrackVolume();
-            mPreviewEditSettings.backgroundMusicSettings.isLooping = mAudioTrack.isLooping();
-            mPreviewEditSettings.primaryTrackVolume = 100;
-            mProcessingState  = PROCESSING_AUDIO_PCM;
-            mProcessingObject = mAudioTrack;
-        } else {
-            mAudioSettings = null;
-            mPreviewEditSettings.backgroundMusicSettings = null;
-            mAudioTrackPCMFilePath = null;
-        }
-    }
-
-    /**
-     * Calculates all the effects in all the media items
-     * in media items list
-     *
-     * @param mediaItemsList The media item list
-     *
-     * @return The total number of effects
-     *
-     */
-    private int getTotalEffects(List<MediaItem> mediaItemsList) {
-        int totalEffects = 0;
-        final Iterator<MediaItem> it = mediaItemsList.iterator();
-        while (it.hasNext()) {
-            final MediaItem t = it.next();
-            totalEffects += t.getAllEffects().size();
-            totalEffects += t.getAllOverlays().size();
-            final Iterator<Effect> ef = t.getAllEffects().iterator();
-            while (ef.hasNext()) {
-                final Effect e = ef.next();
-                if (e instanceof EffectKenBurns) {
-                    totalEffects--;
-                }
-            }
-        }
-        return totalEffects;
-    }
-
-    /**
-     * This function is responsible for forming clip settings
-     * array and clip properties array including transition clips
-     * and effect settings for preview purpose or export.
-     *
-     *
-     * @param mediaItemsList The media item list
-     * @param mediaTransitionList The transitions list
-     * @param mediaBGMList The background music list
-     * @param listener The MediaProcessingProgressListener
-     *
-     */
-    void previewStoryBoard(List<MediaItem> mediaItemsList,
-            List<Transition> mediaTransitionList, List<AudioTrack> mediaBGMList,
-            MediaProcessingProgressListener listener) {
-        if (mInvalidatePreviewArray) {
-            int previewIndex = 0;
-            int totalEffects = 0;
-            int storyBoardTime = 0;
-            int maxHeight = 0;
-            int beginCutTime = 0;
-            int endCutTime = 0;
-            int effectIndex = 0;
-            Transition lTransition = null;
-            MediaItem lMediaItem = null;
-            mPreviewEditSettings = new EditSettings();
-            mClipProperties = new PreviewClipProperties();
-            mTotalClips = 0;
-
-            mTotalClips = mediaItemsList.size();
-            for (Transition transition : mediaTransitionList) {
-                if (transition.getDuration() > 0) {
-                    mTotalClips++;
-                }
-            }
-
-            totalEffects = getTotalEffects(mediaItemsList);
-
-            mPreviewEditSettings.clipSettingsArray = new ClipSettings[mTotalClips];
-            mPreviewEditSettings.effectSettingsArray = new EffectSettings[totalEffects];
-            mClipProperties.clipProperties = new Properties[mTotalClips];
-
-            /** record the call back progress listener */
-            mMediaProcessingProgressListener = listener;
-            mProgressToApp = 0;
-
-            if (mediaItemsList.size() > 0) {
-                for (int i = 0; i < mediaItemsList.size(); i++) {
-                    /* Get the Media Item from the list */
-                    lMediaItem = mediaItemsList.get(i);
-                    if (lMediaItem instanceof MediaVideoItem) {
-                        beginCutTime = (int)((MediaVideoItem)lMediaItem).getBoundaryBeginTime();
-                        endCutTime = (int)((MediaVideoItem)lMediaItem).getBoundaryEndTime();
-                    } else if (lMediaItem instanceof MediaImageItem) {
-                        beginCutTime = 0;
-                        endCutTime = (int)((MediaImageItem)lMediaItem).getTimelineDuration();
-                    }
-                    /* Get the transition associated with Media Item */
-                    lTransition = lMediaItem.getBeginTransition();
-                    if (lTransition != null && (lTransition.getDuration() > 0)) {
-                        /* generate transition clip */
-                        generateTransition(lTransition, mPreviewEditSettings,
-                                           mClipProperties, previewIndex);
-                        storyBoardTime += mClipProperties.clipProperties[previewIndex].duration;
-                        previewIndex++;
-                    }
-                    /* Populate media item properties */
-                    maxHeight = populateMediaItemProperties(lMediaItem, previewIndex, maxHeight);
-                    /* Get the clip properties of the media item. */
-                    if (lMediaItem instanceof MediaImageItem) {
-                        int tmpCnt = 0;
-                        boolean bEffectKbPresent = false;
-                        final List<Effect> effectList = lMediaItem.getAllEffects();
-                        /**
-                         * Check if Ken Burns effect is present
-                         */
-                        while (tmpCnt < effectList.size()) {
-                            if (effectList.get(tmpCnt) instanceof EffectKenBurns) {
-                                bEffectKbPresent = true;
-                                break;
-                            }
-                            tmpCnt++;
-                        }
-
-                        if (bEffectKbPresent) {
-                            try {
-                                  if(((MediaImageItem)lMediaItem).getGeneratedImageClip() != null) {
-                                     mClipProperties.clipProperties[previewIndex]
-                                        = getMediaProperties(((MediaImageItem)lMediaItem).
-                                                             getGeneratedImageClip());
-                                  }
-                                  else {
-                                   mClipProperties.clipProperties[previewIndex]
-                                      = getMediaProperties(((MediaImageItem)lMediaItem).
-                                                             getScaledImageFileName());
-                                   mClipProperties.clipProperties[previewIndex].width =
-                                             ((MediaImageItem)lMediaItem).getScaledWidth();
-                                   mClipProperties.clipProperties[previewIndex].height =
-                                             ((MediaImageItem)lMediaItem).getScaledHeight();
-                                  }
-                                } catch (Exception e) {
-                                   throw new IllegalArgumentException("Unsupported file or file not found");
-                                }
-                         } else {
-                              try {
-                                  mClipProperties.clipProperties[previewIndex]
-                                      = getMediaProperties(((MediaImageItem)lMediaItem).
-                                                               getScaledImageFileName());
-                              } catch (Exception e) {
-                                throw new IllegalArgumentException("Unsupported file or file not found");
-                              }
-                            mClipProperties.clipProperties[previewIndex].width =
-                                        ((MediaImageItem)lMediaItem).getScaledWidth();
-                            mClipProperties.clipProperties[previewIndex].height =
-                                        ((MediaImageItem)lMediaItem).getScaledHeight();
-                        }
-                    } else {
-                        try {
-                            mClipProperties.clipProperties[previewIndex]
-                                 = getMediaProperties(lMediaItem.getFilename());
-                            } catch (Exception e) {
-                              throw new IllegalArgumentException("Unsupported file or file not found");
-                          }
-                    }
-                    mClipProperties.clipProperties[previewIndex].Id = lMediaItem.getId();
-                    checkOddSizeImage(lMediaItem, mClipProperties, previewIndex);
-                    adjustVolume(lMediaItem, mClipProperties, previewIndex);
-
-                    /*
-                     * Adjust media item start time and end time w.r.t to begin
-                     * and end transitions associated with media item
-                     */
-
-                    adjustMediaItemBoundary(mPreviewEditSettings.clipSettingsArray[previewIndex],
-                            mClipProperties.clipProperties[previewIndex], lMediaItem);
-
-                    /*
-                     * Get all the effects and overlays for that media item and
-                     * adjust start time and duration of effects
-                     */
-
-                    effectIndex = populateEffects(lMediaItem,
-                            mPreviewEditSettings.effectSettingsArray, effectIndex, beginCutTime,
-                            endCutTime, storyBoardTime);
-                    storyBoardTime += mClipProperties.clipProperties[previewIndex].duration;
-                    previewIndex++;
-
-                    /* Check if there is any end transition at last media item */
-
-                    if (i == (mediaItemsList.size() - 1)) {
-                        lTransition = lMediaItem.getEndTransition();
-                        if (lTransition != null && (lTransition.getDuration() > 0)) {
-                            generateTransition(lTransition, mPreviewEditSettings, mClipProperties,
-                                    previewIndex);
-                            break;
-                        }
-                    }
-                }
-
-                if (!mErrorFlagSet) {
-                    mPreviewEditSettings.videoFrameSize = findVideoResolution(mVideoEditor
-                            .getAspectRatio(), maxHeight);
-                    populateBackgroundMusicProperties(mediaBGMList);
-
-                    /** call to native populate settings */
-                    try {
-                        nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
-                    } catch (IllegalArgumentException ex) {
-                        Log.e(TAG, "Illegal argument exception in nativePopulateSettings");
-                        throw ex;
-                    } catch (IllegalStateException ex) {
-                        Log.e(TAG, "Illegal state exception in nativePopulateSettings");
-                        throw ex;
-                    } catch (RuntimeException ex) {
-                        Log.e(TAG, "Runtime exception in nativePopulateSettings");
-                        throw ex;
-                    }
-                    mInvalidatePreviewArray = false;
-                    mProcessingState  = PROCESSING_NONE;
-                }
-            }
-            if (mErrorFlagSet) {
-                mErrorFlagSet = false;
-                throw new RuntimeException("preview generation cannot be completed");
-            }
-        }
-    } /* END of previewStoryBoard */
-
-    /**
-     * This function is responsible for starting the preview
-     *
-     *
-     * @param surface The surface on which preview has to be displayed
-     * @param fromMs The time in ms from which preview has to be started
-     * @param toMs The time in ms till preview has to be played
-     * @param loop To loop the preview or not
-     * @param callbackAfterFrameCount INdicated after how many frames
-     * the callback is needed
-     * @param listener The PreviewProgressListener
-     */
-    void doPreview(Surface surface, long fromMs, long toMs, boolean loop,
-            int callbackAfterFrameCount, PreviewProgressListener listener) {
-        mPreviewProgress = fromMs;
-        mIsFirstProgress = true;
-        mPreviewProgressListener = listener;
-
-        if (!mInvalidatePreviewArray) {
-            try {
-                /** Modify the image files names to rgb image files. */
-                for (int clipCnt = 0; clipCnt < mPreviewEditSettings.clipSettingsArray.length;
-                    clipCnt++) {
-                    if (mPreviewEditSettings.clipSettingsArray[clipCnt].fileType == FileType.JPG) {
-                        mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath =
-                            mPreviewEditSettings.clipSettingsArray[clipCnt].clipDecodedPath;
-                    }
-                }
-                nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
-                nativeStartPreview(surface, fromMs, toMs, callbackAfterFrameCount, loop);
-            } catch (IllegalArgumentException ex) {
-                Log.e(TAG, "Illegal argument exception in nativeStartPreview");
-                throw ex;
-            } catch (IllegalStateException ex) {
-                Log.e(TAG, "Illegal state exception in nativeStartPreview");
-                throw ex;
-            } catch (RuntimeException ex) {
-                Log.e(TAG, "Runtime exception in nativeStartPreview");
-                throw ex;
-            }
-        } else {
-            throw new IllegalStateException("generatePreview is in progress");
-        }
-    }
-
-    /**
-     * This function is responsible for stopping the preview
-     */
-    long stopPreview() {
-        return nativeStopPreview();
-    }
-
-    /**
-     * This function is responsible for rendering a single frame
-     * from the complete story board on the surface
-     *
-     * @param surface The surface on which frame has to be rendered
-     * @param time The time in ms at which the frame has to be rendered
-     * @param surfaceWidth The surface width
-     * @param surfaceHeight The surface height
-     * @param overlayData The overlay data
-     *
-     * @return The actual time from the story board at which the  frame was extracted
-     * and rendered
-     */
-    long renderPreviewFrame(Surface surface, long time, int surfaceWidth,
-            int surfaceHeight, VideoEditor.OverlayData overlayData) {
-        if (mInvalidatePreviewArray) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "Call generate preview first");
-            }
-            throw new IllegalStateException("Call generate preview first");
-        }
-
-        long timeMs = 0;
-        try {
-            for (int clipCnt = 0; clipCnt < mPreviewEditSettings.clipSettingsArray.length;
-                  clipCnt++) {
-                if (mPreviewEditSettings.clipSettingsArray[clipCnt].fileType == FileType.JPG) {
-                    mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath =
-                        mPreviewEditSettings.clipSettingsArray[clipCnt].clipDecodedPath;
-                }
-            }
-
-            // Reset the render preview frame params that shall be set by native.
-            mRenderPreviewOverlayFile = null;
-            mRenderPreviewRenderingMode = MediaRendering.RESIZING;
-
-            nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
-
-            timeMs = (long)nativeRenderPreviewFrame(surface, time, surfaceWidth, surfaceHeight);
-
-            if (mRenderPreviewOverlayFile != null) {
-                overlayData.set(BitmapFactory.decodeFile(mRenderPreviewOverlayFile),
-                        mRenderPreviewRenderingMode);
-            } else {
-                overlayData.setClear();
-            }
-        } catch (IllegalArgumentException ex) {
-            Log.e(TAG, "Illegal Argument exception in nativeRenderPreviewFrame");
-            throw ex;
-        } catch (IllegalStateException ex) {
-            Log.e(TAG, "Illegal state exception in nativeRenderPreviewFrame");
-            throw ex;
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "Runtime exception in nativeRenderPreviewFrame");
-            throw ex;
-        }
-
-        return timeMs;
-    }
-
-    private void previewFrameEditInfo(String filename, int renderingMode) {
-        mRenderPreviewOverlayFile = filename;
-        mRenderPreviewRenderingMode = renderingMode;
-    }
-
-
-    /**
-     * This function is responsible for rendering a single frame
-     * from a single media item on the surface
-     *
-     * @param surface The surface on which frame has to be rendered
-     * @param filepath The file path for which the frame needs to be displayed
-     * @param time The time in ms at which the frame has to be rendered
-     * @param framewidth The frame width
-     * @param framewidth The frame height
-     *
-     * @return The actual time from media item at which the  frame was extracted
-     * and rendered
-     */
-    long renderMediaItemPreviewFrame(Surface surface, String filepath,
-                                            long time, int framewidth, int frameheight) {
-        long timeMs = 0;
-        try {
-            timeMs = (long)nativeRenderMediaItemPreviewFrame(surface, filepath, framewidth,
-                    frameheight, 0, 0, time);
-        } catch (IllegalArgumentException ex) {
-            Log.e(TAG, "Illegal Argument exception in renderMediaItemPreviewFrame");
-            throw ex;
-        } catch (IllegalStateException ex) {
-            Log.e(TAG, "Illegal state exception in renderMediaItemPreviewFrame");
-            throw ex;
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "Runtime exception in renderMediaItemPreviewFrame");
-            throw ex;
-        }
-
-        return timeMs;
-    }
-
-    /**
-     * This function sets the flag to invalidate the preview array
-     * and for generating the preview again
-     */
-    void setGeneratePreview(boolean isRequired) {
-        boolean semAcquiredDone = false;
-        try {
-            lock();
-            semAcquiredDone = true;
-            mInvalidatePreviewArray = isRequired;
-        } catch (InterruptedException ex) {
-            Log.e(TAG, "Runtime exception in renderMediaItemPreviewFrame");
-        } finally {
-            if (semAcquiredDone) {
-                unlock();
-            }
-        }
-    }
-
-    /**
-     * @return Returns the current status of preview invalidation
-     * flag
-     */
-    boolean getGeneratePreview() {
-        return mInvalidatePreviewArray;
-    }
-
-    /**
-     * Calculates the aspect ratio from widht and height
-     *
-     * @param w The width of media item
-     * @param h The height of media item
-     *
-     * @return The calculated aspect ratio
-     */
-    int getAspectRatio(int w, int h) {
-        double apRatio = (double)(w) / (double)(h);
-        BigDecimal bd = new BigDecimal(apRatio);
-        bd = bd.setScale(3, BigDecimal.ROUND_HALF_UP);
-        apRatio = bd.doubleValue();
-        int var = MediaProperties.ASPECT_RATIO_16_9;
-        if (apRatio >= 1.7) {
-            var = MediaProperties.ASPECT_RATIO_16_9;
-        } else if (apRatio >= 1.6) {
-            var = MediaProperties.ASPECT_RATIO_5_3;
-        } else if (apRatio >= 1.5) {
-            var = MediaProperties.ASPECT_RATIO_3_2;
-        } else if (apRatio > 1.3) {
-            var = MediaProperties.ASPECT_RATIO_4_3;
-        } else if (apRatio >= 1.2) {
-            var = MediaProperties.ASPECT_RATIO_11_9;
-        }
-        return var;
-    }
-
-    /**
-     * Maps the file type used in native layer
-     * to file type used in JAVA layer
-     *
-     * @param fileType The file type in native layer
-     *
-     * @return The File type in JAVA layer
-     */
-    int getFileType(int fileType) {
-        int retValue = -1;
-        switch (fileType) {
-            case FileType.UNSUPPORTED:
-                retValue = MediaProperties.FILE_UNSUPPORTED;
-                break;
-            case FileType.THREE_GPP:
-                retValue = MediaProperties.FILE_3GP;
-                break;
-            case FileType.MP4:
-                retValue = MediaProperties.FILE_MP4;
-                break;
-            case FileType.JPG:
-                retValue = MediaProperties.FILE_JPEG;
-                break;
-            case FileType.PNG:
-                retValue = MediaProperties.FILE_PNG;
-                break;
-            case FileType.MP3:
-                retValue = MediaProperties.FILE_MP3;
-                break;
-            case FileType.M4V:
-                retValue = MediaProperties.FILE_M4V;
-                break;
-            case FileType.AMR:
-                retValue = MediaProperties.FILE_AMR;
-                break;
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-    }
-
-    /**
-     * Maps the video codec type used in native layer
-     * to video codec type used in JAVA layer
-     *
-     * @param codecType The video codec type in native layer
-     *
-     * @return The video codec type in JAVA layer
-     */
-    int getVideoCodecType(int codecType) {
-        int retValue = -1;
-        switch (codecType) {
-            case VideoFormat.H263:
-                retValue = MediaProperties.VCODEC_H263;
-                break;
-            case VideoFormat.H264:
-                retValue = MediaProperties.VCODEC_H264;
-                break;
-            case VideoFormat.MPEG4:
-                retValue = MediaProperties.VCODEC_MPEG4;
-                break;
-            case VideoFormat.UNSUPPORTED:
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-    }
-
-    /**
-     * Maps the audio codec type used in native layer
-     * to audio codec type used in JAVA layer
-     *
-     * @param audioType The audio codec type in native layer
-     *
-     * @return The audio codec type in JAVA layer
-     */
-    int getAudioCodecType(int codecType) {
-        int retValue = -1;
-        switch (codecType) {
-            case AudioFormat.AMR_NB:
-                retValue = MediaProperties.ACODEC_AMRNB;
-                break;
-            case AudioFormat.AAC:
-                retValue = MediaProperties.ACODEC_AAC_LC;
-                break;
-            case AudioFormat.MP3:
-                retValue = MediaProperties.ACODEC_MP3;
-                break;
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-    }
-
-    /**
-     * Returns the frame rate as integer
-     *
-     * @param fps The fps as enum
-     *
-     * @return The frame rate as integer
-     */
-    int getFrameRate(int fps) {
-        int retValue = -1;
-        switch (fps) {
-            case VideoFrameRate.FR_5_FPS:
-                retValue = 5;
-                break;
-            case VideoFrameRate.FR_7_5_FPS:
-                retValue = 8;
-                break;
-            case VideoFrameRate.FR_10_FPS:
-                retValue = 10;
-                break;
-            case VideoFrameRate.FR_12_5_FPS:
-                retValue = 13;
-                break;
-            case VideoFrameRate.FR_15_FPS:
-                retValue = 15;
-                break;
-            case VideoFrameRate.FR_20_FPS:
-                retValue = 20;
-                break;
-            case VideoFrameRate.FR_25_FPS:
-                retValue = 25;
-                break;
-            case VideoFrameRate.FR_30_FPS:
-                retValue = 30;
-                break;
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-    }
-
-    /**
-     * Maps the file type used in JAVA layer
-     * to file type used in native layer
-     *
-     * @param fileType The file type in JAVA layer
-     *
-     * @return The File type in native layer
-     */
-    int getMediaItemFileType(int fileType) {
-        int retValue = -1;
-
-        switch (fileType) {
-            case MediaProperties.FILE_UNSUPPORTED:
-                retValue = FileType.UNSUPPORTED;
-                break;
-            case MediaProperties.FILE_3GP:
-                retValue = FileType.THREE_GPP;
-                break;
-            case MediaProperties.FILE_MP4:
-                retValue = FileType.MP4;
-                break;
-            case MediaProperties.FILE_JPEG:
-                retValue = FileType.JPG;
-                break;
-            case MediaProperties.FILE_PNG:
-                retValue = FileType.PNG;
-                break;
-            case MediaProperties.FILE_M4V:
-                retValue = FileType.M4V;
-                break;
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-
-    }
-
-    /**
-     * Maps the rendering mode used in native layer
-     * to rendering mode used in JAVA layer
-     *
-     * @param renderingMode The rendering mode in JAVA layer
-     *
-     * @return The rendering mode in native layer
-     */
-    int getMediaItemRenderingMode(int renderingMode) {
-        int retValue = -1;
-        switch (renderingMode) {
-            case MediaItem.RENDERING_MODE_BLACK_BORDER:
-                retValue = MediaRendering.BLACK_BORDERS;
-                break;
-            case MediaItem.RENDERING_MODE_STRETCH:
-                retValue = MediaRendering.RESIZING;
-                break;
-            case MediaItem.RENDERING_MODE_CROPPING:
-                retValue = MediaRendering.CROPPING;
-                break;
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-    }
-
-    /**
-     * Maps the transition behavior used in JAVA layer
-     * to transition behavior used in native layer
-     *
-     * @param transitionType The transition behavior in JAVA layer
-     *
-     * @return The transition behavior in native layer
-     */
-    int getVideoTransitionBehaviour(int transitionType) {
-        int retValue = -1;
-        switch (transitionType) {
-            case Transition.BEHAVIOR_SPEED_UP:
-                retValue = TransitionBehaviour.SPEED_UP;
-                break;
-            case Transition.BEHAVIOR_SPEED_DOWN:
-                retValue = TransitionBehaviour.SPEED_DOWN;
-                break;
-            case Transition.BEHAVIOR_LINEAR:
-                retValue = TransitionBehaviour.LINEAR;
-                break;
-            case Transition.BEHAVIOR_MIDDLE_SLOW:
-                retValue = TransitionBehaviour.SLOW_MIDDLE;
-                break;
-            case Transition.BEHAVIOR_MIDDLE_FAST:
-                retValue = TransitionBehaviour.FAST_MIDDLE;
-                break;
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-    }
-
-    /**
-     * Maps the transition slide direction used in JAVA layer
-     * to transition slide direction used in native layer
-     *
-     * @param slideDirection The transition slide direction
-     * in JAVA layer
-     *
-     * @return The transition slide direction in native layer
-     */
-    int getSlideSettingsDirection(int slideDirection) {
-        int retValue = -1;
-        switch (slideDirection) {
-            case TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN:
-                retValue = SlideDirection.RIGHT_OUT_LEFT_IN;
-                break;
-            case TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN:
-                retValue = SlideDirection.LEFT_OUT_RIGTH_IN;
-                break;
-            case TransitionSliding.DIRECTION_TOP_OUT_BOTTOM_IN:
-                retValue = SlideDirection.TOP_OUT_BOTTOM_IN;
-                break;
-            case TransitionSliding.DIRECTION_BOTTOM_OUT_TOP_IN:
-                retValue = SlideDirection.BOTTOM_OUT_TOP_IN;
-                break;
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-    }
-
-    /**
-     * Maps the effect color type used in JAVA layer
-     * to effect color type used in native layer
-     *
-     * @param effect The EffectColor reference
-     *
-     * @return The color effect value from native layer
-     */
-    private int getEffectColorType(EffectColor effect) {
-        int retValue = -1;
-        switch (effect.getType()) {
-            case EffectColor.TYPE_COLOR:
-                if (effect.getColor() == EffectColor.GREEN) {
-                    retValue = VideoEffect.GREEN;
-                } else if (effect.getColor() == EffectColor.PINK) {
-                    retValue = VideoEffect.PINK;
-                } else if (effect.getColor() == EffectColor.GRAY) {
-                    retValue = VideoEffect.BLACK_AND_WHITE;
-                } else {
-                    retValue = VideoEffect.COLORRGB16;
-                }
-                break;
-            case EffectColor.TYPE_GRADIENT:
-                retValue = VideoEffect.GRADIENT;
-                break;
-            case EffectColor.TYPE_SEPIA:
-                retValue = VideoEffect.SEPIA;
-                break;
-            case EffectColor.TYPE_NEGATIVE:
-                retValue = VideoEffect.NEGATIVE;
-                break;
-            case EffectColor.TYPE_FIFTIES:
-                retValue = VideoEffect.FIFTIES;
-                break;
-
-            default:
-                retValue = -1;
-        }
-        return retValue;
-    }
-
-    /**
-     * Calculates video resolution for output clip
-     * based on clip's height and aspect ratio of storyboard
-     *
-     * @param aspectRatio The aspect ratio of story board
-     * @param height The height of clip
-     *
-     * @return The video resolution
-     */
-    private int findVideoResolution(int aspectRatio, int height) {
-        final Pair<Integer, Integer>[] resolutions;
-        final Pair<Integer, Integer> maxResolution;
-        int retValue = VideoFrameSize.SIZE_UNDEFINED;
-        switch (aspectRatio) {
-            case MediaProperties.ASPECT_RATIO_3_2:
-                if (height == MediaProperties.HEIGHT_480)
-                    retValue = VideoFrameSize.NTSC;
-                else if (height == MediaProperties.HEIGHT_720)
-                    retValue = VideoFrameSize.W720p;
-                break;
-            case MediaProperties.ASPECT_RATIO_16_9:
-                if (height == MediaProperties.HEIGHT_480)
-                    retValue = VideoFrameSize.WVGA16x9;
-                else if (height == MediaProperties.HEIGHT_720)
-                    retValue = VideoFrameSize.V720p;
-                else if (height == MediaProperties.HEIGHT_1080)
-                    retValue = VideoFrameSize.V1080p;
-                break;
-            case MediaProperties.ASPECT_RATIO_4_3:
-                if (height == MediaProperties.HEIGHT_480)
-                    retValue = VideoFrameSize.VGA;
-                else if (height == MediaProperties.HEIGHT_720)
-                    retValue = VideoFrameSize.S720p;
-                break;
-            case MediaProperties.ASPECT_RATIO_5_3:
-                if (height == MediaProperties.HEIGHT_480)
-                    retValue = VideoFrameSize.WVGA;
-                break;
-            case MediaProperties.ASPECT_RATIO_11_9:
-                if (height == MediaProperties.HEIGHT_144)
-                    retValue = VideoFrameSize.QCIF;
-                else if (height == MediaProperties.HEIGHT_288)
-                    retValue = VideoFrameSize.CIF;
-                break;
-        }
-        if (retValue == VideoFrameSize.SIZE_UNDEFINED) {
-            resolutions = MediaProperties.getSupportedResolutions(mVideoEditor.getAspectRatio());
-            // Get the highest resolution
-            maxResolution = resolutions[resolutions.length - 1];
-            retValue = findVideoResolution(mVideoEditor.getAspectRatio(), maxResolution.second);
-        }
-
-        return retValue;
-    }
-
-    /**
-     *  Calculate a reasonable bitrate for generating intermediate clips.
-     */
-    private int findVideoBitrate(int videoFrameSize) {
-        switch (videoFrameSize) {
-            case VideoFrameSize.SQCIF:
-            case VideoFrameSize.QQVGA:
-            case VideoFrameSize.QCIF:
-                return Bitrate.BR_128_KBPS;
-            case VideoFrameSize.QVGA:
-            case VideoFrameSize.CIF:
-                return Bitrate.BR_384_KBPS;
-            case VideoFrameSize.VGA:
-            case VideoFrameSize.WVGA:
-            case VideoFrameSize.NTSC:
-            case VideoFrameSize.nHD:
-            case VideoFrameSize.WVGA16x9:
-                return Bitrate.BR_2_MBPS;
-            case VideoFrameSize.V720p:
-            case VideoFrameSize.W720p:
-            case VideoFrameSize.S720p:
-                return Bitrate.BR_5_MBPS;
-            case VideoFrameSize.V1080p:
-            default:
-                return Bitrate.BR_8_MBPS;
-        }
-    }
-
-    /**
-     * This method is responsible for exporting a movie
-     *
-     * @param filePath The output file path
-     * @param projectDir The output project directory
-     * @param height The height of clip
-     * @param bitrate The bitrate at which the movie should be exported
-     * @param mediaItemsList The media items list
-     * @param mediaTransitionList The transitions list
-     * @param mediaBGMList The background track list
-     * @param listener The ExportProgressListener
-     *
-     */
-    void export(String filePath, String projectDir, int height, int bitrate,
-            List<MediaItem> mediaItemsList, List<Transition> mediaTransitionList,
-            List<AudioTrack> mediaBGMList, ExportProgressListener listener) {
-
-        int outBitrate = 0;
-        mExportFilename = filePath;
-        previewStoryBoard(mediaItemsList, mediaTransitionList, mediaBGMList,null);
-        mExportProgressListener = listener;
-        int outVideoProfile = 0;
-        int outVideoLevel = 0;
-
-        /** Check the platform specific maximum export resolution */
-        VideoEditorProfile veProfile = VideoEditorProfile.get();
-        if (veProfile == null) {
-            throw new RuntimeException("Can't get the video editor profile");
-        }
-        final int maxOutputHeight = veProfile.maxOutputVideoFrameHeight;
-        final int maxOutputWidth = veProfile.maxOutputVideoFrameWidth;
-        if (height > maxOutputHeight) {
-            throw new IllegalArgumentException(
-                    "Unsupported export resolution. Supported maximum width:" +
-                    maxOutputWidth + " height:" + maxOutputHeight +
-                    " current height:" + height);
-        }
-        outVideoProfile = VideoEditorProfile.getExportProfile(mExportVideoCodec);
-        outVideoLevel = VideoEditorProfile.getExportLevel(mExportVideoCodec);
-
-        mProgressToApp = 0;
-
-        switch (bitrate) {
-            case MediaProperties.BITRATE_28K:
-                outBitrate = Bitrate.BR_32_KBPS;
-                break;
-            case MediaProperties.BITRATE_40K:
-                outBitrate = Bitrate.BR_48_KBPS;
-                break;
-            case MediaProperties.BITRATE_64K:
-                outBitrate = Bitrate.BR_64_KBPS;
-                break;
-            case MediaProperties.BITRATE_96K:
-                outBitrate = Bitrate.BR_96_KBPS;
-                break;
-            case MediaProperties.BITRATE_128K:
-                outBitrate = Bitrate.BR_128_KBPS;
-                break;
-            case MediaProperties.BITRATE_192K:
-                outBitrate = Bitrate.BR_192_KBPS;
-                break;
-            case MediaProperties.BITRATE_256K:
-                outBitrate = Bitrate.BR_256_KBPS;
-                break;
-            case MediaProperties.BITRATE_384K:
-                outBitrate = Bitrate.BR_384_KBPS;
-                break;
-            case MediaProperties.BITRATE_512K:
-                outBitrate = Bitrate.BR_512_KBPS;
-                break;
-            case MediaProperties.BITRATE_800K:
-                outBitrate = Bitrate.BR_800_KBPS;
-                break;
-            case MediaProperties.BITRATE_2M:
-                outBitrate = Bitrate.BR_2_MBPS;
-                break;
-            case MediaProperties.BITRATE_5M:
-                outBitrate = Bitrate.BR_5_MBPS;
-                break;
-            case MediaProperties.BITRATE_8M:
-                outBitrate = Bitrate.BR_8_MBPS;
-                break;
-
-            default:
-                throw new IllegalArgumentException("Argument Bitrate incorrect");
-        }
-        mPreviewEditSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
-        mPreviewEditSettings.outputFile = mOutputFilename = filePath;
-
-        int aspectRatio = mVideoEditor.getAspectRatio();
-        mPreviewEditSettings.videoFrameSize = findVideoResolution(aspectRatio, height);
-        mPreviewEditSettings.videoFormat = mExportVideoCodec;
-        mPreviewEditSettings.audioFormat = mExportAudioCodec;
-        mPreviewEditSettings.videoProfile = outVideoProfile;
-        mPreviewEditSettings.videoLevel = outVideoLevel;
-        mPreviewEditSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
-        mPreviewEditSettings.maxFileSize = 0;
-        mPreviewEditSettings.audioChannels = 2;
-        mPreviewEditSettings.videoBitrate = outBitrate;
-        mPreviewEditSettings.audioBitrate = Bitrate.BR_96_KBPS;
-
-        mPreviewEditSettings.transitionSettingsArray = new TransitionSettings[mTotalClips - 1];
-        for (int index = 0; index < mTotalClips - 1; index++) {
-            mPreviewEditSettings.transitionSettingsArray[index] = new TransitionSettings();
-            mPreviewEditSettings.transitionSettingsArray[index].videoTransitionType =
-                VideoTransition.NONE;
-            mPreviewEditSettings.transitionSettingsArray[index].audioTransitionType =
-                AudioTransition.NONE;
-        }
-
-        for (int clipCnt = 0; clipCnt < mPreviewEditSettings.clipSettingsArray.length; clipCnt++) {
-            if (mPreviewEditSettings.clipSettingsArray[clipCnt].fileType == FileType.JPG) {
-                mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath =
-                mPreviewEditSettings.clipSettingsArray[clipCnt].clipOriginalPath;
-            }
-        }
-        nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
-
-        int err = 0;
-        try {
-            mProcessingState  = PROCESSING_EXPORT;
-            mProcessingObject = null;
-            err = generateClip(mPreviewEditSettings);
-            mProcessingState  = PROCESSING_NONE;
-        } catch (IllegalArgumentException ex) {
-            Log.e(TAG, "IllegalArgument for generateClip");
-            throw ex;
-        } catch (IllegalStateException ex) {
-            Log.e(TAG, "IllegalStateExceptiont for generateClip");
-            throw ex;
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "RuntimeException for generateClip");
-            throw ex;
-        }
-
-        if (err != 0) {
-            Log.e(TAG, "RuntimeException for generateClip");
-            throw new RuntimeException("generateClip failed with error=" + err);
-        }
-
-        mExportProgressListener = null;
-    }
-
-    /**
-     * This methods takes care of stopping the Export process
-     *
-     * @param The input file name for which export has to be stopped
-     */
-    void stop(String filename) {
-        try {
-            stopEncoding();
-            new File(mExportFilename).delete();
-        } catch (IllegalStateException ex) {
-            Log.e(TAG, "Illegal state exception in unload settings");
-            throw ex;
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "Runtime exception in unload settings");
-            throw ex;
-        }
-    }
-
-    /**
-     * This method extracts a frame from the input file
-     * and returns the frame as a bitmap. See getPixelsList() for more information.
-     */
-    Bitmap getPixels(String filename, int width, int height, long timeMs,
-            int videoRotation) {
-        final Bitmap result[] = new Bitmap[1];
-        getPixelsList(filename, width, height, timeMs, timeMs, 1, new int[] {0},
-                new MediaItem.GetThumbnailListCallback() {
-            public void onThumbnail(Bitmap bitmap, int index) {
-                result[0] = bitmap;
-            }
-        }, videoRotation);
-        return result[0];
-    }
-
-    /**
-     * This method extracts a list of frame from the
-     * input file and returns the frame in bitmap array
-     *
-     * @param filename The input file name
-     * @param width The width of the output frame, before rotation
-     * @param height The height of the output frame, before rotation
-     * @param startMs The starting time in ms
-     * @param endMs The end time in ms
-     * @param thumbnailCount The number of frames to be extracted
-     * @param indices The indices of thumbnails wanted
-     * @param callback The callback used to pass back the bitmaps
-     * @param videoRotation The rotation degree need to be done for the bitmap
-     *
-     * @return The frames as bitmaps in bitmap array
-     **/
-    void getPixelsList(String filename, final int width, final int height,
-            long startMs, long endMs, int thumbnailCount, int[] indices,
-            final MediaItem.GetThumbnailListCallback callback,
-            final int videoRotation) {
-
-        // The decoder needs output width and height as even
-        final int decWidth = (width + 1) & 0xFFFFFFFE;
-        final int decHeight = (height + 1) & 0xFFFFFFFE;
-        final int thumbnailSize = decWidth * decHeight;
-
-        // We convert the decoder output (in int[]) to a bitmap by first
-        // copy it into an IntBuffer, then use Bitmap.copyPixelsFromBuffer to
-        // copy it to the bitmap.
-        final int[] decArray = new int[thumbnailSize];
-        final IntBuffer decBuffer = IntBuffer.allocate(thumbnailSize);
-
-        // If we need to resize and/or rotate the decoder output, we need a
-        // temporary bitmap to hold the decoded output.
-        final boolean needToMassage =
-                (decWidth != width || decHeight != height || videoRotation != 0);
-        final Bitmap tmpBitmap = needToMassage
-                ? Bitmap.createBitmap(decWidth, decHeight, Bitmap.Config.ARGB_8888)
-                : null;
-
-        // The final output bitmap width/height may swap because of rotation.
-        final boolean needToSwapWH = (videoRotation == 90 || videoRotation == 270);
-        final int outWidth = needToSwapWH ? height : width;
-        final int outHeight = needToSwapWH ? width : height;
-
-        nativeGetPixelsList(filename, decArray, decWidth, decHeight,
-                thumbnailCount, startMs, endMs, indices,
-                new NativeGetPixelsListCallback() {
-            public void onThumbnail(int index) {
-                // This is the bitmap we will output to the client
-                Bitmap outBitmap = Bitmap.createBitmap(
-                        outWidth, outHeight, Bitmap.Config.ARGB_8888);
-
-                // Copy int[] to IntBuffer
-                decBuffer.rewind();
-                decBuffer.put(decArray, 0, thumbnailSize);
-                decBuffer.rewind();
-
-                if (!needToMassage) {
-                    // We can directly read the decoded result to output bitmap
-                    outBitmap.copyPixelsFromBuffer(decBuffer);
-                } else {
-                    // Copy the decoded result to an intermediate bitmap first
-                    tmpBitmap.copyPixelsFromBuffer(decBuffer);
-
-                    // Create a canvas to resize/rotate the bitmap
-                    // First scale the decoded bitmap to (0,0)-(1,1), rotate it
-                    // with (0.5, 0.5) as center, then scale it to
-                    // (outWidth, outHeight).
-                    final Canvas canvas = new Canvas(outBitmap);
-                    Matrix m = new Matrix();
-                    float sx = 1f / decWidth;
-                    float sy = 1f / decHeight;
-                    m.postScale(sx, sy);
-                    m.postRotate(videoRotation, 0.5f, 0.5f);
-                    m.postScale(outWidth, outHeight);
-                    canvas.drawBitmap(tmpBitmap, m, sResizePaint);
-                }
-                callback.onThumbnail(outBitmap, index);
-            }
-        });
-
-        if (tmpBitmap != null) {
-            tmpBitmap.recycle();
-        }
-    }
-
-    interface NativeGetPixelsListCallback {
-        public void onThumbnail(int index);
-    }
-
-    /**
-     * This method generates the audio graph
-     *
-     * @param uniqueId The unique id
-     * @param inFileName The inputFile
-     * @param OutAudiGraphFileName output filename
-     * @param frameDuration The each frame duration
-     * @param audioChannels The number of audio channels
-     * @param samplesCount Total number of samples count
-     * @param listener ExtractAudioWaveformProgressListener reference
-     * @param isVideo The flag to indicate if the file is video file or not
-     *
-     **/
-    void generateAudioGraph(String uniqueId, String inFileName, String OutAudiGraphFileName,
-            int frameDuration, int audioChannels, int samplesCount,
-            ExtractAudioWaveformProgressListener listener, boolean isVideo) {
-        String tempPCMFileName;
-
-        mExtractAudioWaveformProgressListener = listener;
-
-        /**
-         * In case of Video, first call will generate the PCM file to make the
-         * audio graph
-         */
-        if (isVideo) {
-            tempPCMFileName = String.format(mProjectPath + "/" + uniqueId + ".pcm");
-        } else {
-            tempPCMFileName = mAudioTrackPCMFilePath;
-        }
-
-        /**
-         * For Video item, generate the PCM
-         */
-        if (isVideo) {
-            nativeGenerateRawAudio(inFileName, tempPCMFileName);
-        }
-
-        nativeGenerateAudioGraph(tempPCMFileName, OutAudiGraphFileName, frameDuration,
-                audioChannels, samplesCount);
-
-        /**
-         * Once the audio graph file is generated, delete the pcm file
-         */
-        if (isVideo) {
-            new File(tempPCMFileName).delete();
-        }
-    }
-
-    void clearPreviewSurface(Surface surface) {
-        nativeClearSurface(surface);
-    }
-
-    /**
-     * Grab the semaphore which arbitrates access to the editor
-     *
-     * @throws InterruptedException
-     */
-    private void lock() throws InterruptedException {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "lock: grabbing semaphore", new Throwable());
-        }
-        mLock.acquire();
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "lock: grabbed semaphore");
-        }
-    }
-
-    /**
-     * Release the semaphore which arbitrates access to the editor
-     */
-    private void unlock() {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "unlock: releasing semaphore");
-        }
-        mLock.release();
-    }
-
-    /**     Native Methods        */
-    native Properties getMediaProperties(String file) throws IllegalArgumentException,
-            IllegalStateException, RuntimeException, Exception;
-
-    /**
-     * Get the version of ManualEdit.
-     *
-     * @return version of ManualEdit
-     * @throws RuntimeException if an error occurred
-     * @see Version
-     */
-    private static native Version getVersion() throws RuntimeException;
-
-    /**
-     * Returns the video thumbnail in an array of integers. Output format is
-     * ARGB8888.
-     *
-     * @param pixelArray the array that receives the pixel values
-     * @param width width of the video thumbnail
-     * @param height height of the video thumbnail
-     * @param timeMS desired time of the thumbnail in ms
-     * @return actual time in ms of the thumbnail generated
-     * @throws IllegalStateException if the class has not been initialized
-     * @throws IllegalArgumentException if the pixelArray is not available or
-     *             one of the dimensions is negative or zero or the time is
-     *             negative
-     * @throws RuntimeException on runtime errors in native code
-     */
-    private native int nativeGetPixels(String fileName, int[] pixelArray, int width, int height,
-            long timeMS);
-
-    private native int nativeGetPixelsList(String fileName, int[] pixelArray,
-            int width, int height, int nosofTN, long startTimeMs,
-            long endTimeMs, int[] indices, NativeGetPixelsListCallback callback);
-
-    /**
-     * Releases the JNI and cleans up the core native module.. Should be called
-     * only after init( )
-     *
-     * @throws IllegalStateException if the method could not be called
-     */
-    private native void release() throws IllegalStateException, RuntimeException;
-
-    /*
-     * Clear the preview surface
-     */
-    private native void nativeClearSurface(Surface surface);
-
-    /**
-     * Stops the encoding. This method should only be called after encoding has
-     * started using method <code> startEncoding</code>
-     *
-     * @throws IllegalStateException if the method could not be called
-     */
-    private native void stopEncoding() throws IllegalStateException, RuntimeException;
-
-
-    private native void _init(String tempPath, String libraryPath)
-            throws IllegalArgumentException, IllegalStateException, RuntimeException;
-
-    private native void nativeStartPreview(Surface mSurface, long fromMs, long toMs,
-            int callbackAfterFrameCount, boolean loop) throws IllegalArgumentException,
-            IllegalStateException, RuntimeException;
-
-    private native void nativePopulateSettings(EditSettings editSettings,
-            PreviewClipProperties mProperties, AudioSettings mAudioSettings)
-    throws IllegalArgumentException, IllegalStateException, RuntimeException;
-
-    private native int nativeRenderPreviewFrame(Surface mSurface, long timeMs,
-                                                 int surfaceWidth, int surfaceHeight)
-                                                 throws IllegalArgumentException,
-                                                 IllegalStateException, RuntimeException;
-
-    private native int nativeRenderMediaItemPreviewFrame(Surface mSurface, String filepath,
-            int framewidth, int frameheight, int surfacewidth, int surfaceheight, long timeMs)
-    throws IllegalArgumentException, IllegalStateException, RuntimeException;
-
-    private native int nativeStopPreview();
-
-    private native int nativeGenerateAudioGraph(String pcmFilePath, String outGraphPath,
-            int frameDuration, int channels, int sampleCount);
-
-    private native int nativeGenerateRawAudio(String InFileName, String PCMFileName);
-
-    private native int nativeGenerateClip(EditSettings editSettings)
-    throws IllegalArgumentException, IllegalStateException, RuntimeException;
-
-}
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
deleted file mode 100644
index 590b4ae..0000000
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ /dev/null
@@ -1,1021 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import java.util.ArrayList;
-import android.media.videoeditor.MediaArtistNativeHelper.ClipSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.EditSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.FileType;
-import android.media.videoeditor.MediaArtistNativeHelper.Properties;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.lang.Math;
-import java.util.List;
-
-/**
- * This class represents an image item on the storyboard. Note that images are
- * scaled down to the maximum supported resolution by preserving the native
- * aspect ratio. To learn the scaled image dimensions use
- * {@link #getScaledWidth()} and {@link #getScaledHeight()} respectively.
- *
- * {@hide}
- */
-public class MediaImageItem extends MediaItem {
-    /**
-     *  Logging
-     */
-    private static final String TAG = "MediaImageItem";
-
-    /**
-     *  The resize paint
-     */
-    private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
-
-    /**
-     *  Instance variables
-     */
-    private final int mWidth;
-    private final int mHeight;
-    private final int mAspectRatio;
-    private long mDurationMs;
-    private int mScaledWidth, mScaledHeight;
-    private String mScaledFilename;
-    private final VideoEditorImpl mVideoEditor;
-    private String mDecodedFilename;
-    private int mGeneratedClipHeight;
-    private int mGeneratedClipWidth;
-    private String mFileName;
-
-    private final MediaArtistNativeHelper mMANativeHelper;
-
-    /**
-     * This class cannot be instantiated by using the default constructor
-     */
-    @SuppressWarnings("unused")
-    private MediaImageItem() throws IOException {
-        this(null, null, null, 0, RENDERING_MODE_BLACK_BORDER);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param editor The video editor reference
-     * @param mediaItemId The media item id
-     * @param filename The image file name
-     * @param durationMs The duration of the image on the storyboard
-     * @param renderingMode The rendering mode
-     *
-     * @throws IOException
-     */
-    public MediaImageItem(VideoEditor editor, String mediaItemId, String filename, long durationMs,
-        int renderingMode) throws IOException {
-
-        super(editor, mediaItemId, filename, renderingMode);
-
-        mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
-        mVideoEditor = ((VideoEditorImpl)editor);
-        try {
-            final Properties properties = mMANativeHelper.getMediaProperties(filename);
-
-            switch (mMANativeHelper.getFileType(properties.fileType)) {
-                case MediaProperties.FILE_JPEG:
-                case MediaProperties.FILE_PNG: {
-                    break;
-                }
-
-                default: {
-                    throw new IllegalArgumentException("Unsupported Input File Type");
-                }
-            }
-        } catch (Exception e) {
-            throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
-        }
-        mFileName = filename;
-        /**
-         *  Determine the dimensions of the image
-         */
-        final BitmapFactory.Options dbo = new BitmapFactory.Options();
-        dbo.inJustDecodeBounds = true;
-        BitmapFactory.decodeFile(filename, dbo);
-
-        mWidth = dbo.outWidth;
-        mHeight = dbo.outHeight;
-        mDurationMs = durationMs;
-        mDecodedFilename = String.format(mMANativeHelper.getProjectPath() +
-                "/" + "decoded" + getId()+ ".rgb");
-
-        try {
-            mAspectRatio = mMANativeHelper.getAspectRatio(mWidth, mHeight);
-        } catch(IllegalArgumentException e) {
-            throw new IllegalArgumentException ("Null width and height");
-        }
-
-        mGeneratedClipHeight = 0;
-        mGeneratedClipWidth = 0;
-
-        /**
-         *  Images are stored in memory scaled to the maximum resolution to
-         *  save memory.
-         */
-        final Pair<Integer, Integer>[] resolutions =
-            MediaProperties.getSupportedResolutions(mAspectRatio);
-
-        /**
-         *  Get the highest resolution
-         */
-        final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1];
-
-        final Bitmap imageBitmap;
-
-        if (mWidth > maxResolution.first || mHeight > maxResolution.second) {
-            /**
-             *  We need to scale the image
-             */
-            imageBitmap = scaleImage(filename, maxResolution.first,
-                                                         maxResolution.second);
-            mScaledFilename = String.format(mMANativeHelper.getProjectPath() +
-                    "/" + "scaled" + getId()+ ".JPG");
-            if (!((new File(mScaledFilename)).exists())) {
-                super.mRegenerateClip = true;
-                final FileOutputStream f1 = new FileOutputStream(mScaledFilename);
-                imageBitmap.compress(Bitmap.CompressFormat.JPEG, 50,f1);
-                f1.close();
-            }
-            mScaledWidth =  (imageBitmap.getWidth() >> 1) << 1;
-            mScaledHeight = (imageBitmap.getHeight() >> 1) << 1;
-        } else {
-            mScaledFilename = filename;
-            mScaledWidth =  (mWidth >> 1) << 1;
-            mScaledHeight = (mHeight >> 1) << 1;
-            imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
-        }
-        int newWidth = mScaledWidth;
-        int newHeight = mScaledHeight;
-        if (!((new File(mDecodedFilename)).exists())) {
-            final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
-            final DataOutputStream dos = new DataOutputStream(fl);
-            final int [] framingBuffer = new int[newWidth];
-            final ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
-            IntBuffer intBuffer;
-            final byte[] array = byteBuffer.array();
-            int tmp = 0;
-            while (tmp < newHeight) {
-                imageBitmap.getPixels(framingBuffer, 0, mScaledWidth, 0,
-                                                        tmp, newWidth, 1);
-                intBuffer = byteBuffer.asIntBuffer();
-                intBuffer.put(framingBuffer, 0, newWidth);
-                dos.write(array);
-                tmp += 1;
-            }
-            fl.close();
-        }
-        imageBitmap.recycle();
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int getFileType() {
-        if (mFilename.endsWith(".jpg") || mFilename.endsWith(".jpeg")
-                || mFilename.endsWith(".JPG") || mFilename.endsWith(".JPEG")) {
-            return MediaProperties.FILE_JPEG;
-        } else if (mFilename.endsWith(".png") || mFilename.endsWith(".PNG")) {
-            return MediaProperties.FILE_PNG;
-        } else {
-            return MediaProperties.FILE_UNSUPPORTED;
-        }
-    }
-
-    /**
-     * @return The scaled image file name
-     */
-    String getScaledImageFileName() {
-        return mScaledFilename;
-    }
-
-    /**
-     * @return The generated Kenburns clip height.
-     */
-    int getGeneratedClipHeight() {
-        return mGeneratedClipHeight;
-    }
-
-    /**
-     * @return The generated Kenburns clip width.
-     */
-    int getGeneratedClipWidth() {
-        return mGeneratedClipWidth;
-    }
-
-    /**
-     * @return The file name of image which is decoded and stored
-     * in RGB format
-     */
-    String getDecodedImageFileName() {
-        return mDecodedFilename;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int getWidth() {
-        return mWidth;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int getHeight() {
-        return mHeight;
-    }
-
-    /**
-     * @return The scaled width of the image.
-     */
-    public int getScaledWidth() {
-        return mScaledWidth;
-    }
-
-    /**
-     * @return The scaled height of the image.
-     */
-    public int getScaledHeight() {
-        return mScaledHeight;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int getAspectRatio() {
-        return mAspectRatio;
-    }
-
-    /**
-     * This method will adjust the duration of bounding transitions, effects
-     * and overlays if the current duration of the transactions become greater
-     * than the maximum allowable duration.
-     *
-     * @param durationMs The duration of the image in the storyboard timeline
-     */
-    public void setDuration(long durationMs) {
-        if (durationMs == mDurationMs) {
-            return;
-        }
-
-        mMANativeHelper.setGeneratePreview(true);
-
-        /**
-         * Invalidate the end transitions if necessary.
-         * This invalidation is necessary for the case in which an effect or
-         * an overlay is overlapping with the end transition
-         * (before the duration is changed) and it no longer overlaps with the
-         * transition after the duration is increased.
-         *
-         * The beginning transition does not need to be invalidated at this time
-         * because an effect or an overlay overlaps with the beginning
-         * transition, the begin transition is unaffected by a media item
-         * duration change.
-         */
-        invalidateEndTransition();
-
-        mDurationMs = durationMs;
-
-        adjustTransitions();
-        final List<Overlay> adjustedOverlays = adjustOverlays();
-        final List<Effect> adjustedEffects = adjustEffects();
-
-        /**
-         * Invalidate the beginning and end transitions after adjustments.
-         * This invalidation is necessary for the case in which an effect or
-         * an overlay was not overlapping with the beginning or end transitions
-         * before the setDuration reduces the duration of the media item and
-         * causes an overlap of the beginning and/or end transition with the
-         * effect.
-         */
-        invalidateBeginTransition(adjustedEffects, adjustedOverlays);
-        invalidateEndTransition();
-        if (getGeneratedImageClip() != null) {
-            /*
-             *  Delete the file
-             */
-            new File(getGeneratedImageClip()).delete();
-            /*
-             *  Invalidate the filename
-             */
-            setGeneratedImageClip(null);
-            super.setRegenerateClip(true);
-        }
-        mVideoEditor.updateTimelineDuration();
-    }
-
-    /**
-     * Invalidate the begin transition if any effects and overlays overlap
-     * with the begin transition.
-     *
-     * @param effects List of effects to check for transition overlap
-     * @param overlays List of overlays to check for transition overlap
-     */
-    private void invalidateBeginTransition(List<Effect> effects, List<Overlay> overlays) {
-        if (mBeginTransition != null && mBeginTransition.isGenerated()) {
-            final long transitionDurationMs = mBeginTransition.getDuration();
-
-            /**
-             *  The begin transition must be invalidated if it overlaps with
-             *  an effect.
-             */
-            for (Effect effect : effects) {
-                /**
-                 *  Check if the effect overlaps with the begin transition
-                 */
-                if (effect.getStartTime() < transitionDurationMs) {
-                    mBeginTransition.invalidate();
-                    break;
-                }
-            }
-
-            if (mBeginTransition.isGenerated()) {
-                /**
-                 *  The end transition must be invalidated if it overlaps with
-                 *  an overlay.
-                 */
-                for (Overlay overlay : overlays) {
-                    /**
-                     *  Check if the overlay overlaps with the end transition
-                     */
-                    if (overlay.getStartTime() < transitionDurationMs) {
-                        mBeginTransition.invalidate();
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Invalidate the end transition if any effects and overlays overlap
-     * with the end transition.
-     */
-    private void invalidateEndTransition() {
-        if (mEndTransition != null && mEndTransition.isGenerated()) {
-            final long transitionDurationMs = mEndTransition.getDuration();
-
-            /**
-             *  The end transition must be invalidated if it overlaps with
-             *  an effect.
-             */
-            final List<Effect> effects = getAllEffects();
-            for (Effect effect : effects) {
-                /**
-                 *  Check if the effect overlaps with the end transition
-                 */
-                if (effect.getStartTime() + effect.getDuration() >
-                    mDurationMs - transitionDurationMs) {
-                    mEndTransition.invalidate();
-                    break;
-                }
-            }
-
-            if (mEndTransition.isGenerated()) {
-                /**
-                 *  The end transition must be invalidated if it overlaps with
-                 *  an overlay.
-                 */
-                final List<Overlay> overlays = getAllOverlays();
-                for (Overlay overlay : overlays) {
-                    /**
-                     *  Check if the overlay overlaps with the end transition
-                     */
-                    if (overlay.getStartTime() + overlay.getDuration() >
-                        mDurationMs - transitionDurationMs) {
-                        mEndTransition.invalidate();
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Adjust the start time and/or duration of effects.
-     *
-     * @return The list of effects which were adjusted
-     */
-    private List<Effect> adjustEffects() {
-        final List<Effect> adjustedEffects = new ArrayList<Effect>();
-        final List<Effect> effects = getAllEffects();
-        for (Effect effect : effects) {
-            /**
-             *  Adjust the start time if necessary
-             */
-            final long effectStartTimeMs;
-            if (effect.getStartTime() > getDuration()) {
-                effectStartTimeMs = 0;
-            } else {
-                effectStartTimeMs = effect.getStartTime();
-            }
-
-            /**
-             *  Adjust the duration if necessary
-             */
-            final long effectDurationMs;
-            if (effectStartTimeMs + effect.getDuration() > getDuration()) {
-                effectDurationMs = getDuration() - effectStartTimeMs;
-            } else {
-                effectDurationMs = effect.getDuration();
-            }
-
-            if (effectStartTimeMs != effect.getStartTime() ||
-                    effectDurationMs != effect.getDuration()) {
-                effect.setStartTimeAndDuration(effectStartTimeMs, effectDurationMs);
-                adjustedEffects.add(effect);
-            }
-        }
-
-        return adjustedEffects;
-    }
-
-    /**
-     * Adjust the start time and/or duration of overlays.
-     *
-     * @return The list of overlays which were adjusted
-     */
-    private List<Overlay> adjustOverlays() {
-        final List<Overlay> adjustedOverlays = new ArrayList<Overlay>();
-        final List<Overlay> overlays = getAllOverlays();
-        for (Overlay overlay : overlays) {
-            /**
-             *  Adjust the start time if necessary
-             */
-            final long overlayStartTimeMs;
-            if (overlay.getStartTime() > getDuration()) {
-                overlayStartTimeMs = 0;
-            } else {
-                overlayStartTimeMs = overlay.getStartTime();
-            }
-
-            /**
-             *  Adjust the duration if necessary
-             */
-            final long overlayDurationMs;
-            if (overlayStartTimeMs + overlay.getDuration() > getDuration()) {
-                overlayDurationMs = getDuration() - overlayStartTimeMs;
-            } else {
-                overlayDurationMs = overlay.getDuration();
-            }
-
-            if (overlayStartTimeMs != overlay.getStartTime() ||
-                    overlayDurationMs != overlay.getDuration()) {
-                overlay.setStartTimeAndDuration(overlayStartTimeMs, overlayDurationMs);
-                adjustedOverlays.add(overlay);
-            }
-        }
-
-        return adjustedOverlays;
-    }
-    /**
-     * This function get the proper width by given aspect ratio
-     * and height.
-     *
-     * @param aspectRatio  Given aspect ratio
-     * @param height  Given height
-     */
-    private int getWidthByAspectRatioAndHeight(int aspectRatio, int height) {
-        int width = 0;
-
-        switch (aspectRatio) {
-            case MediaProperties.ASPECT_RATIO_3_2:
-                if (height == MediaProperties.HEIGHT_480)
-                    width = 720;
-                else if (height == MediaProperties.HEIGHT_720)
-                    width = 1080;
-                break;
-
-            case MediaProperties.ASPECT_RATIO_16_9:
-                if (height == MediaProperties.HEIGHT_360)
-                    width = 640;
-                else if (height == MediaProperties.HEIGHT_480)
-                    width = 854;
-                else if (height == MediaProperties.HEIGHT_720)
-                    width = 1280;
-                else if (height == MediaProperties.HEIGHT_1080)
-                    width = 1920;
-                break;
-
-            case MediaProperties.ASPECT_RATIO_4_3:
-                if (height == MediaProperties.HEIGHT_480)
-                    width = 640;
-                if (height == MediaProperties.HEIGHT_720)
-                    width = 960;
-                break;
-
-            case MediaProperties.ASPECT_RATIO_5_3:
-                if (height == MediaProperties.HEIGHT_480)
-                    width = 800;
-                break;
-
-            case MediaProperties.ASPECT_RATIO_11_9:
-                if (height == MediaProperties.HEIGHT_144)
-                    width = 176;
-                break;
-
-            default : {
-                throw new IllegalArgumentException(
-                    "Illegal arguments for aspectRatio");
-            }
-        }
-
-        return width;
-    }
-
-    /**
-     * This function sets the Ken Burn effect generated clip
-     * name.
-     *
-     * @param generatedFilePath The name of the generated clip
-     */
-    @Override
-    void setGeneratedImageClip(String generatedFilePath) {
-        super.setGeneratedImageClip(generatedFilePath);
-
-        // set the Kenburns clip width and height
-        mGeneratedClipHeight = getScaledHeight();
-        mGeneratedClipWidth = getWidthByAspectRatioAndHeight(
-                mVideoEditor.getAspectRatio(), mGeneratedClipHeight);
-    }
-
-    /**
-     * @return The name of the image clip
-     * generated with ken burns effect.
-     */
-    @Override
-    String getGeneratedImageClip() {
-        return super.getGeneratedImageClip();
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public long getDuration() {
-        return mDurationMs;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public long getTimelineDuration() {
-        return mDurationMs;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public Bitmap getThumbnail(int width, int height, long timeMs) throws IOException {
-        if (getGeneratedImageClip() != null) {
-            return mMANativeHelper.getPixels(getGeneratedImageClip(),
-                width, height, timeMs, 0);
-        } else {
-            return scaleImage(mFilename, width, height);
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void getThumbnailList(int width, int height,
-                                 long startMs, long endMs,
-                                 int thumbnailCount,
-                                 int[] indices,
-                                 GetThumbnailListCallback callback)
-                                 throws IOException {
-        //KenBurns was not applied on this.
-        if (getGeneratedImageClip() == null) {
-            final Bitmap thumbnail = scaleImage(mFilename, width, height);
-            for (int i = 0; i < indices.length; i++) {
-                callback.onThumbnail(thumbnail, indices[i]);
-            }
-        } else {
-            if (startMs > endMs) {
-                throw new IllegalArgumentException("Start time is greater than end time");
-            }
-
-            if (endMs > mDurationMs) {
-                throw new IllegalArgumentException("End time is greater than file duration");
-            }
-
-            mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
-                height, startMs, endMs, thumbnailCount, indices, callback, 0);
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    void invalidateTransitions(long startTimeMs, long durationMs) {
-        /**
-         *  Check if the item overlaps with the beginning and end transitions
-         */
-        if (mBeginTransition != null) {
-            if (isOverlapping(startTimeMs, durationMs, 0, mBeginTransition.getDuration())) {
-                mBeginTransition.invalidate();
-            }
-        }
-
-        if (mEndTransition != null) {
-            final long transitionDurationMs = mEndTransition.getDuration();
-            if (isOverlapping(startTimeMs, durationMs,
-                    getDuration() - transitionDurationMs, transitionDurationMs)) {
-                mEndTransition.invalidate();
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
-            long newDurationMs) {
-        /**
-         *  Check if the item overlaps with the beginning and end transitions
-         */
-        if (mBeginTransition != null) {
-            final long transitionDurationMs = mBeginTransition.getDuration();
-            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs, 0,
-                    transitionDurationMs);
-            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs, 0,
-                    transitionDurationMs);
-            /**
-             * Invalidate transition if:
-             *
-             * 1. New item overlaps the transition, the old one did not
-             * 2. New item does not overlap the transition, the old one did
-             * 3. New and old item overlap the transition if begin or end
-             * time changed
-             */
-            if (newOverlap != oldOverlap) { // Overlap has changed
-                mBeginTransition.invalidate();
-            } else if (newOverlap) { // Both old and new overlap
-                if ((oldStartTimeMs != newStartTimeMs) ||
-                        !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
-                        newStartTimeMs + newDurationMs > transitionDurationMs)) {
-                    mBeginTransition.invalidate();
-                }
-            }
-        }
-
-        if (mEndTransition != null) {
-            final long transitionDurationMs = mEndTransition.getDuration();
-            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
-                    mDurationMs - transitionDurationMs, transitionDurationMs);
-            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
-                    mDurationMs - transitionDurationMs, transitionDurationMs);
-            /**
-             * Invalidate transition if:
-             *
-             * 1. New item overlaps the transition, the old one did not
-             * 2. New item does not overlap the transition, the old one did
-             * 3. New and old item overlap the transition if begin or end
-             * time changed
-             */
-            if (newOverlap != oldOverlap) { // Overlap has changed
-                mEndTransition.invalidate();
-            } else if (newOverlap) { // Both old and new overlap
-                if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
-                        ((oldStartTimeMs > mDurationMs - transitionDurationMs) ||
-                        newStartTimeMs > mDurationMs - transitionDurationMs)) {
-                    mEndTransition.invalidate();
-                }
-            }
-        }
-    }
-
-    /**
-     * This function invalidates the rgb image clip,ken burns effect clip,
-     * and scaled image clip
-     */
-    void invalidate() {
-        if (getGeneratedImageClip() != null) {
-            new File(getGeneratedImageClip()).delete();
-            setGeneratedImageClip(null);
-            setRegenerateClip(true);
-        }
-
-        if (mScaledFilename != null) {
-            if(mFileName != mScaledFilename) {
-                new File(mScaledFilename).delete();
-            }
-            mScaledFilename = null;
-        }
-
-        if (mDecodedFilename != null) {
-            new File(mDecodedFilename).delete();
-            mDecodedFilename = null;
-        }
-    }
-
-    /**
-     * @param KenBurnEffect object.
-     * @return an Object of {@link ClipSettings} with Ken Burn settings
-     * needed to generate the clip
-     */
-    private ClipSettings getKenBurns(EffectKenBurns effectKB) {
-        int PanZoomXa;
-        int PanZoomXb;
-        int width = 0, height = 0;
-        Rect start = new Rect();
-        Rect end = new Rect();
-        ClipSettings clipSettings = null;
-        clipSettings = new ClipSettings();
-        /**
-         *  image:
-        ---------------------------------------
-       |    Xa                                  |
-       | Ya ---------------                     |
-       |    |                |                  |
-       |    |                |                  |
-       |     ---------------    Xb       ratioB |
-       |        ratioA           -------        |
-       |                  Yb    |        |      |
-       |                        |        |      |
-       |                         -------        |
-        ---------------------------------------
-         */
-
-        effectKB.getKenBurnsSettings(start, end);
-        width = getWidth();
-        height = getHeight();
-        if ((start.left < 0) || (start.left > width) || (start.right < 0) || (start.right > width)
-                || (start.top < 0) || (start.top > height) || (start.bottom < 0)
-                || (start.bottom > height) || (end.left < 0) || (end.left > width)
-                || (end.right < 0) || (end.right > width) || (end.top < 0) || (end.top > height)
-                || (end.bottom < 0) || (end.bottom > height)) {
-            throw new IllegalArgumentException("Illegal arguments for KebBurns");
-        }
-
-        if (((width - (start.right - start.left) == 0) || (height - (start.bottom - start.top) == 0))
-                && ((width - (end.right - end.left) == 0) || (height - (end.bottom - end.top) == 0))) {
-            setRegenerateClip(false);
-            clipSettings.clipPath = getDecodedImageFileName();
-            clipSettings.fileType = FileType.JPG;
-            clipSettings.beginCutTime = 0;
-            clipSettings.endCutTime = (int)getTimelineDuration();
-            clipSettings.beginCutPercent = 0;
-            clipSettings.endCutPercent = 0;
-            clipSettings.panZoomEnabled = false;
-            clipSettings.panZoomPercentStart = 0;
-            clipSettings.panZoomTopLeftXStart = 0;
-            clipSettings.panZoomTopLeftYStart = 0;
-            clipSettings.panZoomPercentEnd = 0;
-            clipSettings.panZoomTopLeftXEnd = 0;
-            clipSettings.panZoomTopLeftYEnd = 0;
-            clipSettings.mediaRendering = mMANativeHelper
-            .getMediaItemRenderingMode(getRenderingMode());
-
-            clipSettings.rgbWidth = getScaledWidth();
-            clipSettings.rgbHeight = getScaledHeight();
-
-            return clipSettings;
-        }
-
-        PanZoomXa = (1000 * start.width()) / width;
-        PanZoomXb = (1000 * end.width()) / width;
-
-        clipSettings.clipPath = getDecodedImageFileName();
-        clipSettings.fileType = mMANativeHelper.getMediaItemFileType(getFileType());
-        clipSettings.beginCutTime = 0;
-        clipSettings.endCutTime = (int)getTimelineDuration();
-        clipSettings.beginCutPercent = 0;
-        clipSettings.endCutPercent = 0;
-        clipSettings.panZoomEnabled = true;
-        clipSettings.panZoomPercentStart = PanZoomXa;
-        clipSettings.panZoomTopLeftXStart = (start.left * 1000) / width;
-        clipSettings.panZoomTopLeftYStart = (start.top * 1000) / height;
-        clipSettings.panZoomPercentEnd = PanZoomXb;
-        clipSettings.panZoomTopLeftXEnd = (end.left * 1000) / width;
-        clipSettings.panZoomTopLeftYEnd = (end.top * 1000) / height;
-        clipSettings.mediaRendering
-            = mMANativeHelper.getMediaItemRenderingMode(getRenderingMode());
-
-        clipSettings.rgbWidth = getScaledWidth();
-        clipSettings.rgbHeight = getScaledHeight();
-
-        return clipSettings;
-    }
-
-
-    /**
-     * @param KenBurnEffect object.
-     * @return an Object of {@link ClipSettings} with Ken Burns
-     * generated clip name
-     */
-    ClipSettings generateKenburnsClip(EffectKenBurns effectKB) {
-        EditSettings editSettings = new EditSettings();
-        editSettings.clipSettingsArray = new ClipSettings[1];
-        String output = null;
-        ClipSettings clipSettings = new ClipSettings();
-        initClipSettings(clipSettings);
-        editSettings.clipSettingsArray[0] = getKenBurns(effectKB);
-        if ((getGeneratedImageClip() == null) && (getRegenerateClip())) {
-            output = mMANativeHelper.generateKenBurnsClip(editSettings, this);
-            setGeneratedImageClip(output);
-            setRegenerateClip(false);
-            clipSettings.clipPath = output;
-            clipSettings.fileType = FileType.THREE_GPP;
-
-            mGeneratedClipHeight = getScaledHeight();
-            mGeneratedClipWidth = getWidthByAspectRatioAndHeight(
-                    mVideoEditor.getAspectRatio(), mGeneratedClipHeight);
-        } else {
-            if (getGeneratedImageClip() == null) {
-                clipSettings.clipPath = getDecodedImageFileName();
-                clipSettings.fileType = FileType.JPG;
-
-                clipSettings.rgbWidth = getScaledWidth();
-                clipSettings.rgbHeight = getScaledHeight();
-
-            } else {
-                clipSettings.clipPath = getGeneratedImageClip();
-                clipSettings.fileType = FileType.THREE_GPP;
-            }
-        }
-        clipSettings.mediaRendering = mMANativeHelper.getMediaItemRenderingMode(getRenderingMode());
-        clipSettings.beginCutTime = 0;
-        clipSettings.endCutTime = (int)getTimelineDuration();
-
-        return clipSettings;
-    }
-
-    /**
-     * @return an Object of {@link ClipSettings} with Image Clip
-     * properties data populated.If the image has Ken Burns effect applied,
-     * then file path contains generated image clip name with Ken Burns effect
-     */
-    ClipSettings getImageClipProperties() {
-        ClipSettings clipSettings = new ClipSettings();
-        List<Effect> effects = null;
-        EffectKenBurns effectKB = null;
-        boolean effectKBPresent = false;
-
-        effects = getAllEffects();
-        for (Effect effect : effects) {
-            if (effect instanceof EffectKenBurns) {
-                effectKB = (EffectKenBurns)effect;
-                effectKBPresent = true;
-                break;
-            }
-        }
-
-        if (effectKBPresent) {
-            clipSettings = generateKenburnsClip(effectKB);
-        } else {
-            /**
-             * Init the clip settings object
-             */
-            initClipSettings(clipSettings);
-            clipSettings.clipPath = getDecodedImageFileName();
-            clipSettings.fileType = FileType.JPG;
-            clipSettings.beginCutTime = 0;
-            clipSettings.endCutTime = (int)getTimelineDuration();
-            clipSettings.mediaRendering = mMANativeHelper
-                .getMediaItemRenderingMode(getRenderingMode());
-            clipSettings.rgbWidth = getScaledWidth();
-            clipSettings.rgbHeight = getScaledHeight();
-
-        }
-        return clipSettings;
-    }
-
-    /**
-     * Resize a bitmap to the specified width and height
-     *
-     * @param filename The filename
-     * @param width The thumbnail width
-     * @param height The thumbnail height
-     *
-     * @return The resized bitmap
-     */
-    private Bitmap scaleImage(String filename, int width, int height)
-    throws IOException {
-        final BitmapFactory.Options dbo = new BitmapFactory.Options();
-        dbo.inJustDecodeBounds = true;
-        BitmapFactory.decodeFile(filename, dbo);
-
-        final int nativeWidth = dbo.outWidth;
-        final int nativeHeight = dbo.outHeight;
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "generateThumbnail: Input: " + nativeWidth + "x" + nativeHeight
-                    + ", resize to: " + width + "x" + height);
-        }
-
-        final Bitmap srcBitmap;
-        float bitmapWidth, bitmapHeight;
-        if (nativeWidth > width || nativeHeight > height) {
-            float dx = ((float)nativeWidth) / ((float)width);
-            float dy = ((float)nativeHeight) / ((float)height);
-
-            if (dx > dy) {
-                bitmapWidth = width;
-
-                if (((float)nativeHeight / dx) < (float)height) {
-                    bitmapHeight = (float)Math.ceil(nativeHeight / dx);
-                } else { // value equals the requested height
-                    bitmapHeight = (float)Math.floor(nativeHeight / dx);
-                }
-
-            } else {
-                if (((float)nativeWidth / dy) > (float)width) {
-                    bitmapWidth = (float)Math.floor(nativeWidth / dy);
-                } else { // value equals the requested width
-                    bitmapWidth = (float)Math.ceil(nativeWidth / dy);
-                }
-
-                bitmapHeight = height;
-            }
-
-            /**
-             *  Create the bitmap from file
-             */
-            int sampleSize = (int) Math.ceil(Math.max(
-                    (float) nativeWidth / bitmapWidth,
-                    (float) nativeHeight / bitmapHeight));
-            sampleSize = nextPowerOf2(sampleSize);
-            final BitmapFactory.Options options = new BitmapFactory.Options();
-            options.inSampleSize = sampleSize;
-            srcBitmap = BitmapFactory.decodeFile(filename, options);
-        } else {
-            bitmapWidth = width;
-            bitmapHeight = height;
-            srcBitmap = BitmapFactory.decodeFile(filename);
-
-        }
-
-        if (srcBitmap == null) {
-            Log.e(TAG, "generateThumbnail: Cannot decode image bytes");
-            throw new IOException("Cannot decode file: " + mFilename);
-        }
-
-        /**
-         *  Create the canvas bitmap
-         */
-        final Bitmap bitmap = Bitmap.createBitmap((int)bitmapWidth,
-                                                  (int)bitmapHeight,
-                                                  Bitmap.Config.ARGB_8888);
-        final Canvas canvas = new Canvas(bitmap);
-        canvas.drawBitmap(srcBitmap, new Rect(0, 0, srcBitmap.getWidth(),
-                                              srcBitmap.getHeight()),
-                                              new Rect(0, 0, (int)bitmapWidth,
-                                              (int)bitmapHeight), sResizePaint);
-        canvas.setBitmap(null);
-        /**
-         *  Release the source bitmap
-         */
-        srcBitmap.recycle();
-        return bitmap;
-    }
-
-    public static int nextPowerOf2(int n) {
-        n -= 1;
-        n |= n >>> 16;
-        n |= n >>> 8;
-        n |= n >>> 4;
-        n |= n >>> 2;
-        n |= n >>> 1;
-        return n + 1;
-    }
-}
diff --git a/media/java/android/media/videoeditor/MediaItem.java b/media/java/android/media/videoeditor/MediaItem.java
deleted file mode 100644
index 4e9ea75..0000000
--- a/media/java/android/media/videoeditor/MediaItem.java
+++ /dev/null
@@ -1,814 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import java.io.DataOutputStream;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-
-import android.graphics.Bitmap;
-import android.media.videoeditor.MediaArtistNativeHelper.ClipSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.FileType;
-import android.media.videoeditor.MediaArtistNativeHelper.MediaRendering;
-
-/**
- * This abstract class describes the base class for any MediaItem. Objects are
- * defined with a file path as a source data.
- * {@hide}
- */
-public abstract class MediaItem {
-    /**
-     *  A constant which can be used to specify the end of the file (instead of
-     *  providing the actual duration of the media item).
-     */
-    public final static int END_OF_FILE = -1;
-
-    /**
-     *  Rendering modes
-     */
-    /**
-     * When using the RENDERING_MODE_BLACK_BORDER rendering mode video frames
-     * are resized by preserving the aspect ratio until the movie matches one of
-     * the dimensions of the output movie. The areas outside the resized video
-     * clip are rendered black.
-     */
-    public static final int RENDERING_MODE_BLACK_BORDER = 0;
-
-    /**
-     * When using the RENDERING_MODE_STRETCH rendering mode video frames are
-     * stretched horizontally or vertically to match the current aspect ratio of
-     * the video editor.
-     */
-    public static final int RENDERING_MODE_STRETCH = 1;
-
-    /**
-     * When using the RENDERING_MODE_CROPPING rendering mode video frames are
-     * scaled horizontally or vertically by preserving the original aspect ratio
-     * of the media item.
-     */
-    public static final int RENDERING_MODE_CROPPING = 2;
-
-    /**
-     *  The unique id of the MediaItem
-     */
-    private final String mUniqueId;
-
-    /**
-     *  The name of the file associated with the MediaItem
-     */
-    protected final String mFilename;
-
-    /**
-     *  List of effects
-     */
-    private final List<Effect> mEffects;
-
-    /**
-     *  List of overlays
-     */
-    private final List<Overlay> mOverlays;
-
-    /**
-     *  The rendering mode
-     */
-    private int mRenderingMode;
-
-    private final MediaArtistNativeHelper mMANativeHelper;
-
-    private final String mProjectPath;
-
-    /**
-     *  Beginning and end transitions
-     */
-    protected Transition mBeginTransition;
-
-    protected Transition mEndTransition;
-
-    protected String mGeneratedImageClip;
-
-    protected boolean mRegenerateClip;
-
-    private boolean mBlankFrameGenerated = false;
-
-    private String mBlankFrameFilename = null;
-
-    /**
-     * Constructor
-     *
-     * @param editor The video editor reference
-     * @param mediaItemId The MediaItem id
-     * @param filename name of the media file.
-     * @param renderingMode The rendering mode
-     * @throws IOException if file is not found
-     * @throws IllegalArgumentException if a capability such as file format is
-     *             not supported the exception object contains the unsupported
-     *             capability
-     */
-    protected MediaItem(VideoEditor editor, String mediaItemId, String filename,
-                        int renderingMode) throws IOException {
-        if (filename == null) {
-            throw new IllegalArgumentException("MediaItem : filename is null");
-        }
-        File file = new File(filename);
-        if (!file.exists()) {
-            throw new IOException(filename + " not found ! ");
-        }
-
-        /*Compare file_size with 2GB*/
-        if (VideoEditor.MAX_SUPPORTED_FILE_SIZE <= file.length()) {
-            throw new IllegalArgumentException("File size is more than 2GB");
-        }
-        mUniqueId = mediaItemId;
-        mFilename = filename;
-        mRenderingMode = renderingMode;
-        mEffects = new ArrayList<Effect>();
-        mOverlays = new ArrayList<Overlay>();
-        mBeginTransition = null;
-        mEndTransition = null;
-        mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
-        mProjectPath = editor.getPath();
-        mRegenerateClip = false;
-        mGeneratedImageClip = null;
-    }
-
-    /**
-     * @return The id of the media item
-     */
-    public String getId() {
-        return mUniqueId;
-    }
-
-    /**
-     * @return The media source file name
-     */
-    public String getFilename() {
-        return mFilename;
-    }
-
-    /**
-     * If aspect ratio of the MediaItem is different from the aspect ratio of
-     * the editor then this API controls the rendering mode.
-     *
-     * @param renderingMode rendering mode. It is one of:
-     *            {@link #RENDERING_MODE_BLACK_BORDER},
-     *            {@link #RENDERING_MODE_STRETCH}
-     */
-    public void setRenderingMode(int renderingMode) {
-        switch (renderingMode) {
-            case RENDERING_MODE_BLACK_BORDER:
-            case RENDERING_MODE_STRETCH:
-            case RENDERING_MODE_CROPPING:
-                break;
-
-            default:
-                throw new IllegalArgumentException("Invalid Rendering Mode");
-        }
-
-        mMANativeHelper.setGeneratePreview(true);
-
-        mRenderingMode = renderingMode;
-        if (mBeginTransition != null) {
-            mBeginTransition.invalidate();
-        }
-
-        if (mEndTransition != null) {
-            mEndTransition.invalidate();
-        }
-
-        for (Overlay overlay : mOverlays) {
-            ((OverlayFrame)overlay).invalidateGeneratedFiles();
-        }
-    }
-
-    /**
-     * @return The rendering mode
-     */
-    public int getRenderingMode() {
-        return mRenderingMode;
-    }
-
-    /**
-     * @param transition The beginning transition
-     */
-    void setBeginTransition(Transition transition) {
-        mBeginTransition = transition;
-    }
-
-    /**
-     * @return The begin transition
-     */
-    public Transition getBeginTransition() {
-        return mBeginTransition;
-    }
-
-    /**
-     * @param transition The end transition
-     */
-    void setEndTransition(Transition transition) {
-        mEndTransition = transition;
-    }
-
-    /**
-     * @return The end transition
-     */
-    public Transition getEndTransition() {
-        return mEndTransition;
-    }
-
-    /**
-     * @return The timeline duration. This is the actual duration in the
-     *         timeline (trimmed duration)
-     */
-    public abstract long getTimelineDuration();
-
-    /**
-     * @return The is the full duration of the media item (not trimmed)
-     */
-    public abstract long getDuration();
-
-    /**
-     * @return The source file type
-     */
-    public abstract int getFileType();
-
-    /**
-     * @return Get the native width of the media item
-     */
-    public abstract int getWidth();
-
-    /**
-     * @return Get the native height of the media item
-     */
-    public abstract int getHeight();
-
-    /**
-     * Get aspect ratio of the source media item.
-     *
-     * @return the aspect ratio as described in MediaProperties.
-     *         MediaProperties.ASPECT_RATIO_UNDEFINED if aspect ratio is not
-     *         supported as in MediaProperties
-     */
-    public abstract int getAspectRatio();
-
-    /**
-     * Add the specified effect to this media item.
-     *
-     * Note that certain types of effects cannot be applied to video and to
-     * image media items. For example in certain implementation a Ken Burns
-     * implementation cannot be applied to video media item.
-     *
-     * This method invalidates transition video clips if the
-     * effect overlaps with the beginning and/or the end transition.
-     *
-     * @param effect The effect to apply
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if the effect start and/or duration are
-     *      invalid or if the effect cannot be applied to this type of media
-     *      item or if the effect id is not unique across all the Effects
-     *      added.
-     */
-    public void addEffect(Effect effect) {
-
-        if (effect == null) {
-            throw new IllegalArgumentException("NULL effect cannot be applied");
-        }
-
-        if (effect.getMediaItem() != this) {
-            throw new IllegalArgumentException("Media item mismatch");
-        }
-
-        if (mEffects.contains(effect)) {
-            throw new IllegalArgumentException("Effect already exists: " + effect.getId());
-        }
-
-        if (effect.getStartTime() + effect.getDuration() > getDuration()) {
-            throw new IllegalArgumentException(
-            "Effect start time + effect duration > media clip duration");
-        }
-
-        mMANativeHelper.setGeneratePreview(true);
-
-        mEffects.add(effect);
-
-        invalidateTransitions(effect.getStartTime(), effect.getDuration());
-
-        if (effect instanceof EffectKenBurns) {
-            mRegenerateClip = true;
-        }
-    }
-
-    /**
-     * Remove the effect with the specified id.
-     *
-     * This method invalidates a transition video clip if the effect overlaps
-     * with a transition.
-     *
-     * @param effectId The id of the effect to be removed
-     *
-     * @return The effect that was removed
-     * @throws IllegalStateException if a preview or an export is in progress
-     */
-    public Effect removeEffect(String effectId) {
-        for (Effect effect : mEffects) {
-            if (effect.getId().equals(effectId)) {
-                mMANativeHelper.setGeneratePreview(true);
-
-                mEffects.remove(effect);
-
-                invalidateTransitions(effect.getStartTime(), effect.getDuration());
-                if (effect instanceof EffectKenBurns) {
-                    if (mGeneratedImageClip != null) {
-                        /**
-                         *  Delete the file
-                         */
-                        new File(mGeneratedImageClip).delete();
-                        /**
-                         *  Invalidate the filename
-                         */
-                        mGeneratedImageClip = null;
-                    }
-                    mRegenerateClip = false;
-                }
-                return effect;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Set the filepath of the generated image clip when the effect is added.
-     *
-     * @param The filepath of the generated image clip.
-     */
-    void setGeneratedImageClip(String generatedFilePath) {
-        mGeneratedImageClip = generatedFilePath;
-    }
-
-    /**
-     * Get the filepath of the generated image clip when the effect is added.
-     *
-     * @return The filepath of the generated image clip (null if it does not
-     *         exist)
-     */
-    String getGeneratedImageClip() {
-        return mGeneratedImageClip;
-    }
-
-    /**
-     * Find the effect with the specified id
-     *
-     * @param effectId The effect id
-     * @return The effect with the specified id (null if it does not exist)
-     */
-    public Effect getEffect(String effectId) {
-        for (Effect effect : mEffects) {
-            if (effect.getId().equals(effectId)) {
-                return effect;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get the list of effects.
-     *
-     * @return the effects list. If no effects exist an empty list will be
-     *         returned.
-     */
-    public List<Effect> getAllEffects() {
-        return mEffects;
-    }
-
-    /**
-     * Add an overlay to the storyboard. This method invalidates a transition
-     * video clip if the overlay overlaps with a transition.
-     *
-     * @param overlay The overlay to add
-     * @throws IllegalStateException if a preview or an export is in progress or
-     *             if the overlay id is not unique across all the overlays added
-     *             or if the bitmap is not specified or if the dimensions of the
-     *             bitmap do not match the dimensions of the media item
-     * @throws FileNotFoundException, IOException if overlay could not be saved
-     *             to project path
-     */
-    public void addOverlay(Overlay overlay) throws FileNotFoundException, IOException {
-        if (overlay == null) {
-            throw new IllegalArgumentException("NULL Overlay cannot be applied");
-        }
-
-        if (overlay.getMediaItem() != this) {
-            throw new IllegalArgumentException("Media item mismatch");
-        }
-
-        if (mOverlays.contains(overlay)) {
-            throw new IllegalArgumentException("Overlay already exists: " + overlay.getId());
-        }
-
-        if (overlay.getStartTime() + overlay.getDuration() > getDuration()) {
-            throw new IllegalArgumentException(
-            "Overlay start time + overlay duration > media clip duration");
-        }
-
-        if (overlay instanceof OverlayFrame) {
-            final OverlayFrame frame = (OverlayFrame)overlay;
-            final Bitmap bitmap = frame.getBitmap();
-            if (bitmap == null) {
-                throw new IllegalArgumentException("Overlay bitmap not specified");
-            }
-
-            final int scaledWidth, scaledHeight;
-            if (this instanceof MediaVideoItem) {
-                scaledWidth = getWidth();
-                scaledHeight = getHeight();
-            } else {
-                scaledWidth = ((MediaImageItem)this).getScaledWidth();
-                scaledHeight = ((MediaImageItem)this).getScaledHeight();
-            }
-
-            /**
-             * The dimensions of the overlay bitmap must be the same as the
-             * media item dimensions
-             */
-            if (bitmap.getWidth() != scaledWidth || bitmap.getHeight() != scaledHeight) {
-                throw new IllegalArgumentException(
-                "Bitmap dimensions must match media item dimensions");
-            }
-
-            mMANativeHelper.setGeneratePreview(true);
-            ((OverlayFrame)overlay).save(mProjectPath);
-
-            mOverlays.add(overlay);
-            invalidateTransitions(overlay.getStartTime(), overlay.getDuration());
-
-        } else {
-            throw new IllegalArgumentException("Overlay not supported");
-        }
-    }
-
-    /**
-     * @param flag The flag to indicate if regeneration of clip is true or
-     *            false.
-     */
-    void setRegenerateClip(boolean flag) {
-        mRegenerateClip = flag;
-    }
-
-    /**
-     * @return flag The flag to indicate if regeneration of clip is true or
-     *         false.
-     */
-    boolean getRegenerateClip() {
-        return mRegenerateClip;
-    }
-
-    /**
-     * Remove the overlay with the specified id.
-     *
-     * This method invalidates a transition video clip if the overlay overlaps
-     * with a transition.
-     *
-     * @param overlayId The id of the overlay to be removed
-     *
-     * @return The overlay that was removed
-     * @throws IllegalStateException if a preview or an export is in progress
-     */
-    public Overlay removeOverlay(String overlayId) {
-        for (Overlay overlay : mOverlays) {
-            if (overlay.getId().equals(overlayId)) {
-                mMANativeHelper.setGeneratePreview(true);
-
-                mOverlays.remove(overlay);
-                if (overlay instanceof OverlayFrame) {
-                    ((OverlayFrame)overlay).invalidate();
-                }
-                invalidateTransitions(overlay.getStartTime(), overlay.getDuration());
-                return overlay;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Find the overlay with the specified id
-     *
-     * @param overlayId The overlay id
-     *
-     * @return The overlay with the specified id (null if it does not exist)
-     */
-    public Overlay getOverlay(String overlayId) {
-        for (Overlay overlay : mOverlays) {
-            if (overlay.getId().equals(overlayId)) {
-                return overlay;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the list of overlays associated with this media item
-     *
-     * Note that if any overlay source files are not accessible anymore,
-     * this method will still provide the full list of overlays.
-     *
-     * @return The list of overlays. If no overlays exist an empty list will
-     *         be returned.
-     */
-    public List<Overlay> getAllOverlays() {
-        return mOverlays;
-    }
-
-    /**
-     * Create a thumbnail at specified time in a video stream in Bitmap format
-     *
-     * @param width width of the thumbnail in pixels
-     * @param height height of the thumbnail in pixels
-     * @param timeMs The time in the source video file at which the thumbnail is
-     *            requested (even if trimmed).
-     *
-     * @return The thumbnail as a Bitmap.
-     *
-     * @throws IOException if a file error occurs
-     * @throws IllegalArgumentException if time is out of video duration
-     */
-    public abstract Bitmap getThumbnail(int width, int height, long timeMs)
-                                        throws IOException;
-
-    /**
-     * Get the array of Bitmap thumbnails between start and end.
-     *
-     * @param width width of the thumbnail in pixels
-     * @param height height of the thumbnail in pixels
-     * @param startMs The start of time range in milliseconds
-     * @param endMs The end of the time range in milliseconds
-     * @param thumbnailCount The thumbnail count
-     * @param indices The indices of the thumbnails wanted
-     * @param callback The callback used to pass back the bitmaps
-     *
-     * @throws IOException if a file error occurs
-     */
-    public abstract void getThumbnailList(int width, int height,
-                                          long startMs, long endMs,
-                                          int thumbnailCount,
-                                          int[] indices,
-                                          GetThumbnailListCallback callback)
-                                          throws IOException;
-
-    public interface GetThumbnailListCallback {
-        public void onThumbnail(Bitmap bitmap, int index);
-    }
-
-    // This is for compatibility, only used in tests.
-    public Bitmap[] getThumbnailList(int width, int height,
-                                     long startMs, long endMs,
-                                     int thumbnailCount)
-                                     throws IOException {
-        final Bitmap[] bitmaps = new Bitmap[thumbnailCount];
-        int[] indices = new int[thumbnailCount];
-        for (int i = 0; i < thumbnailCount; i++) {
-            indices[i] = i;
-        }
-        getThumbnailList(width, height, startMs, endMs,
-                thumbnailCount, indices, new GetThumbnailListCallback() {
-            public void onThumbnail(Bitmap bitmap, int index) {
-                bitmaps[index] = bitmap;
-            }
-        });
-
-        return bitmaps;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (!(object instanceof MediaItem)) {
-            return false;
-        }
-        return mUniqueId.equals(((MediaItem)object).mUniqueId);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int hashCode() {
-        return mUniqueId.hashCode();
-    }
-
-    /**
-     * Invalidate the start and end transitions if necessary
-     *
-     * @param startTimeMs The start time of the effect or overlay
-     * @param durationMs The duration of the effect or overlay
-     */
-    abstract void invalidateTransitions(long startTimeMs, long durationMs);
-
-    /**
-     * Invalidate the start and end transitions if necessary. This method is
-     * typically called when the start time and/or duration of an overlay or
-     * effect is changing.
-     *
-     * @param oldStartTimeMs The old start time of the effect or overlay
-     * @param oldDurationMs The old duration of the effect or overlay
-     * @param newStartTimeMs The new start time of the effect or overlay
-     * @param newDurationMs The new duration of the effect or overlay
-     */
-    abstract void invalidateTransitions(long oldStartTimeMs, long oldDurationMs,
-            long newStartTimeMs, long newDurationMs);
-
-    /**
-     * Check if two items overlap in time
-     *
-     * @param startTimeMs1 Item 1 start time
-     * @param durationMs1 Item 1 duration
-     * @param startTimeMs2 Item 2 start time
-     * @param durationMs2 Item 2 end time
-     * @return true if the two items overlap
-     */
-    protected boolean isOverlapping(long startTimeMs1, long durationMs1,
-                                    long startTimeMs2, long durationMs2) {
-        if (startTimeMs1 + durationMs1 <= startTimeMs2) {
-            return false;
-        } else if (startTimeMs1 >= startTimeMs2 + durationMs2) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Adjust the duration transitions.
-     */
-    protected void adjustTransitions() {
-        /**
-         *  Check if the duration of transitions need to be adjusted
-         */
-        if (mBeginTransition != null) {
-            final long maxDurationMs = mBeginTransition.getMaximumDuration();
-            if (mBeginTransition.getDuration() > maxDurationMs) {
-                mBeginTransition.setDuration(maxDurationMs);
-            }
-        }
-
-        if (mEndTransition != null) {
-            final long maxDurationMs = mEndTransition.getMaximumDuration();
-            if (mEndTransition.getDuration() > maxDurationMs) {
-                mEndTransition.setDuration(maxDurationMs);
-            }
-        }
-    }
-
-    /**
-     * @return MediaArtistNativeHleper context
-     */
-    MediaArtistNativeHelper getNativeContext() {
-        return mMANativeHelper;
-    }
-
-    /**
-     * Initialises ClipSettings fields to default value
-     *
-     * @param ClipSettings object
-     *{@link android.media.videoeditor.MediaArtistNativeHelper.ClipSettings}
-     */
-    void initClipSettings(ClipSettings clipSettings) {
-        clipSettings.clipPath = null;
-        clipSettings.clipDecodedPath = null;
-        clipSettings.clipOriginalPath = null;
-        clipSettings.fileType = 0;
-        clipSettings.endCutTime = 0;
-        clipSettings.beginCutTime = 0;
-        clipSettings.beginCutPercent = 0;
-        clipSettings.endCutPercent = 0;
-        clipSettings.panZoomEnabled = false;
-        clipSettings.panZoomPercentStart = 0;
-        clipSettings.panZoomTopLeftXStart = 0;
-        clipSettings.panZoomTopLeftYStart = 0;
-        clipSettings.panZoomPercentEnd = 0;
-        clipSettings.panZoomTopLeftXEnd = 0;
-        clipSettings.panZoomTopLeftYEnd = 0;
-        clipSettings.mediaRendering = 0;
-        clipSettings.rgbWidth = 0;
-        clipSettings.rgbHeight = 0;
-    }
-
-    /**
-     * @return ClipSettings object with populated data
-     *{@link android.media.videoeditor.MediaArtistNativeHelper.ClipSettings}
-     */
-    ClipSettings getClipSettings() {
-        MediaVideoItem mVI = null;
-        MediaImageItem mII = null;
-        ClipSettings clipSettings = new ClipSettings();
-        initClipSettings(clipSettings);
-        if (this instanceof MediaVideoItem) {
-            mVI = (MediaVideoItem)this;
-            clipSettings.clipPath = mVI.getFilename();
-            clipSettings.fileType = mMANativeHelper.getMediaItemFileType(mVI.
-                                                                 getFileType());
-            clipSettings.beginCutTime = (int)mVI.getBoundaryBeginTime();
-            clipSettings.endCutTime = (int)mVI.getBoundaryEndTime();
-            clipSettings.mediaRendering = mMANativeHelper.
-                                          getMediaItemRenderingMode(mVI
-                                          .getRenderingMode());
-        } else if (this instanceof MediaImageItem) {
-            mII = (MediaImageItem)this;
-            clipSettings = mII.getImageClipProperties();
-        }
-        return clipSettings;
-    }
-
-    /**
-     * Generates a black frame to be used for generating
-     * begin transition at first media item in storyboard
-     * or end transition at last media item in storyboard
-     *
-     * @param ClipSettings object
-     *{@link android.media.videoeditor.MediaArtistNativeHelper.ClipSettings}
-     */
-    void generateBlankFrame(ClipSettings clipSettings) {
-        if (!mBlankFrameGenerated) {
-            int mWidth = 64;
-            int mHeight = 64;
-            mBlankFrameFilename = String.format(mProjectPath + "/" + "ghost.rgb");
-            FileOutputStream fl = null;
-            try {
-                 fl = new FileOutputStream(mBlankFrameFilename);
-            } catch (IOException e) {
-                /* catch IO exception */
-            }
-            final DataOutputStream dos = new DataOutputStream(fl);
-
-            final int [] framingBuffer = new int[mWidth];
-
-            ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
-            IntBuffer intBuffer;
-
-            byte[] array = byteBuffer.array();
-            int tmp = 0;
-            while(tmp < mHeight) {
-                intBuffer = byteBuffer.asIntBuffer();
-                intBuffer.put(framingBuffer,0,mWidth);
-                try {
-                    dos.write(array);
-                } catch (IOException e) {
-                    /* catch file write error */
-                }
-                tmp += 1;
-            }
-
-            try {
-                fl.close();
-            } catch (IOException e) {
-                /* file close error */
-            }
-            mBlankFrameGenerated = true;
-        }
-
-        clipSettings.clipPath = mBlankFrameFilename;
-        clipSettings.fileType = FileType.JPG;
-        clipSettings.beginCutTime = 0;
-        clipSettings.endCutTime = 0;
-        clipSettings.mediaRendering = MediaRendering.RESIZING;
-
-        clipSettings.rgbWidth = 64;
-        clipSettings.rgbHeight = 64;
-    }
-
-    /**
-     * Invalidates the blank frame generated
-     */
-    void invalidateBlankFrame() {
-        if (mBlankFrameFilename != null) {
-            if (new File(mBlankFrameFilename).exists()) {
-                new File(mBlankFrameFilename).delete();
-                mBlankFrameFilename = null;
-            }
-        }
-    }
-
-}
diff --git a/media/java/android/media/videoeditor/MediaProperties.java b/media/java/android/media/videoeditor/MediaProperties.java
deleted file mode 100644
index cf518a5..0000000
--- a/media/java/android/media/videoeditor/MediaProperties.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import android.media.videoeditor.VideoEditorProfile;
-import android.util.Pair;
-import java.lang.System;
-/**
- * This class defines all properties of a media file such as supported height,
- * aspect ratio, bitrate for export function.
- * {@hide}
- */
-public class MediaProperties {
-    /**
-     *  Supported heights
-     */
-    public static final int HEIGHT_144 = 144;
-    public static final int HEIGHT_288 = 288;
-    public static final int HEIGHT_360 = 360;
-    public static final int HEIGHT_480 = 480;
-    public static final int HEIGHT_720 = 720;
-    public static final int HEIGHT_1080 = 1080;
-
-    /**
-     *  Supported aspect ratios
-     */
-    public static final int ASPECT_RATIO_UNDEFINED = 0;
-    public static final int ASPECT_RATIO_3_2 = 1;
-    public static final int ASPECT_RATIO_16_9 = 2;
-    public static final int ASPECT_RATIO_4_3 = 3;
-    public static final int ASPECT_RATIO_5_3 = 4;
-    public static final int ASPECT_RATIO_11_9 = 5;
-
-    /**
-     *  The array of supported aspect ratios
-     */
-    private static final int[] ASPECT_RATIOS = new int[] {
-        ASPECT_RATIO_3_2,
-        ASPECT_RATIO_16_9,
-        ASPECT_RATIO_4_3,
-        ASPECT_RATIO_5_3,
-        ASPECT_RATIO_11_9
-    };
-
-    /**
-     *  Supported resolutions for specific aspect ratios
-     */
-    @SuppressWarnings({"unchecked"})
-    private static final Pair<Integer, Integer>[] ASPECT_RATIO_3_2_RESOLUTIONS =
-        new Pair[] {
-        new Pair<Integer, Integer>(720, HEIGHT_480),
-        new Pair<Integer, Integer>(1080, HEIGHT_720)
-    };
-
-    @SuppressWarnings({"unchecked"})
-    private static final Pair<Integer, Integer>[] ASPECT_RATIO_4_3_RESOLUTIONS =
-        new Pair[] {
-        new Pair<Integer, Integer>(640, HEIGHT_480),
-        new Pair<Integer, Integer>(960, HEIGHT_720)
-    };
-
-    @SuppressWarnings({"unchecked"})
-    private static final Pair<Integer, Integer>[] ASPECT_RATIO_5_3_RESOLUTIONS =
-        new Pair[] {
-        new Pair<Integer, Integer>(800, HEIGHT_480)
-    };
-
-    @SuppressWarnings({"unchecked"})
-    private static final Pair<Integer, Integer>[] ASPECT_RATIO_11_9_RESOLUTIONS =
-        new Pair[] {
-        new Pair<Integer, Integer>(176, HEIGHT_144),
-        new Pair<Integer, Integer>(352, HEIGHT_288)
-    };
-
-    @SuppressWarnings({"unchecked"})
-    private static final Pair<Integer, Integer>[] ASPECT_RATIO_16_9_RESOLUTIONS =
-        new Pair[] {
-        new Pair<Integer, Integer>(848, HEIGHT_480),
-        new Pair<Integer, Integer>(1280, HEIGHT_720),
-        new Pair<Integer, Integer>(1920, HEIGHT_1080),
-    };
-
-    /**
-     *  Bitrate values (in bits per second)
-     */
-    public static final int BITRATE_28K = 28000;
-    public static final int BITRATE_40K = 40000;
-    public static final int BITRATE_64K = 64000;
-    public static final int BITRATE_96K = 96000;
-    public static final int BITRATE_128K = 128000;
-    public static final int BITRATE_192K = 192000;
-    public static final int BITRATE_256K = 256000;
-    public static final int BITRATE_384K = 384000;
-    public static final int BITRATE_512K = 512000;
-    public static final int BITRATE_800K = 800000;
-    public static final int BITRATE_2M = 2000000;
-    public static final int BITRATE_5M = 5000000;
-    public static final int BITRATE_8M = 8000000;
-
-    /**
-     *  The array of supported bitrates
-     */
-    private static final int[] SUPPORTED_BITRATES = new int[] {
-        BITRATE_28K,
-        BITRATE_40K,
-        BITRATE_64K,
-        BITRATE_96K,
-        BITRATE_128K,
-        BITRATE_192K,
-        BITRATE_256K,
-        BITRATE_384K,
-        BITRATE_512K,
-        BITRATE_800K,
-        BITRATE_2M,
-        BITRATE_5M,
-        BITRATE_8M
-    };
-
-    /**
-     *  Video codec types
-     */
-    public static final int VCODEC_H263 = 1;
-    public static final int VCODEC_H264 = 2;
-    public static final int VCODEC_MPEG4 = 3;
-
-    /**
-     *  The array of supported video codecs
-     */
-    private static final int[] SUPPORTED_VCODECS = new int[] {
-        VCODEC_H264,
-        VCODEC_H263,
-        VCODEC_MPEG4,
-    };
-
-    /**
-     *  The H264 profile, the values are same as the one in OMX_Video.h
-     */
-    public final class H264Profile {
-        public static final int H264ProfileBaseline = 0x01; /**< Baseline profile */
-        public static final int H264ProfileMain     = 0x02; /**< Main profile */
-        public static final int H264ProfileExtended = 0x04; /**< Extended profile */
-        public static final int H264ProfileHigh     = 0x08; /**< High profile */
-        public static final int H264ProfileHigh10   = 0x10; /**< High 10 profile */
-        public static final int H264ProfileHigh422  = 0x20; /**< High 4:2:2 profile */
-        public static final int H264ProfileHigh444  = 0x40; /**< High 4:4:4 profile */
-        public static final int H264ProfileUnknown  = 0x7FFFFFFF;
-   }
-    /**
-     *  The H264 level, the values are same as the one in OMX_Video.h
-     */
-    public final class H264Level {
-        public static final int H264Level1   = 0x01; /**< Level 1 */
-        public static final int H264Level1b  = 0x02; /**< Level 1b */
-        public static final int H264Level11  = 0x04; /**< Level 1.1 */
-        public static final int H264Level12  = 0x08; /**< Level 1.2 */
-        public static final int H264Level13  = 0x10; /**< Level 1.3 */
-        public static final int H264Level2   = 0x20; /**< Level 2 */
-        public static final int H264Level21  = 0x40; /**< Level 2.1 */
-        public static final int H264Level22  = 0x80; /**< Level 2.2 */
-        public static final int H264Level3   = 0x100; /**< Level 3 */
-        public static final int H264Level31  = 0x200; /**< Level 3.1 */
-        public static final int H264Level32  = 0x400; /**< Level 3.2 */
-        public static final int H264Level4   = 0x800; /**< Level 4 */
-        public static final int H264Level41  = 0x1000; /**< Level 4.1 */
-        public static final int H264Level42  = 0x2000; /**< Level 4.2 */
-        public static final int H264Level5   = 0x4000; /**< Level 5 */
-        public static final int H264Level51  = 0x8000; /**< Level 5.1 */
-        public static final int H264LevelUnknown = 0x7FFFFFFF;
-    }
-    /**
-     *  The H263 profile, the values are same as the one in OMX_Video.h
-     */
-    public final class H263Profile {
-        public static final int H263ProfileBaseline            = 0x01;
-        public static final int H263ProfileH320Coding          = 0x02;
-        public static final int H263ProfileBackwardCompatible  = 0x04;
-        public static final int H263ProfileISWV2               = 0x08;
-        public static final int H263ProfileISWV3               = 0x10;
-        public static final int H263ProfileHighCompression     = 0x20;
-        public static final int H263ProfileInternet            = 0x40;
-        public static final int H263ProfileInterlace           = 0x80;
-        public static final int H263ProfileHighLatency       = 0x100;
-        public static final int H263ProfileUnknown          = 0x7FFFFFFF;
-    }
-    /**
-     *  The H263 level, the values are same as the one in OMX_Video.h
-     */
-    public final class H263Level {
-        public static final int H263Level10  = 0x01;
-        public static final int H263Level20  = 0x02;
-        public static final int H263Level30  = 0x04;
-        public static final int H263Level40  = 0x08;
-        public static final int H263Level45  = 0x10;
-        public static final int H263Level50  = 0x20;
-        public static final int H263Level60  = 0x40;
-        public static final int H263Level70  = 0x80;
-        public static final int H263LevelUnknown = 0x7FFFFFFF;
-    }
-    /**
-     *  The mpeg4 profile, the values are same as the one in OMX_Video.h
-     */
-    public final class MPEG4Profile {
-        public static final int MPEG4ProfileSimple           = 0x01;
-        public static final int MPEG4ProfileSimpleScalable   = 0x02;
-        public static final int MPEG4ProfileCore             = 0x04;
-        public static final int MPEG4ProfileMain             = 0x08;
-        public static final int MPEG4ProfileNbit             = 0x10;
-        public static final int MPEG4ProfileScalableTexture  = 0x20;
-        public static final int MPEG4ProfileSimpleFace       = 0x40;
-        public static final int MPEG4ProfileSimpleFBA        = 0x80;
-        public static final int MPEG4ProfileBasicAnimated    = 0x100;
-        public static final int MPEG4ProfileHybrid           = 0x200;
-        public static final int MPEG4ProfileAdvancedRealTime = 0x400;
-        public static final int MPEG4ProfileCoreScalable     = 0x800;
-        public static final int MPEG4ProfileAdvancedCoding   = 0x1000;
-        public static final int MPEG4ProfileAdvancedCore     = 0x2000;
-        public static final int MPEG4ProfileAdvancedScalable = 0x4000;
-        public static final int MPEG4ProfileAdvancedSimple   = 0x8000;
-        public static final int MPEG4ProfileUnknown          = 0x7FFFFFFF;
-    }
-    /**
-     *  The mpeg4 level, the values are same as the one in OMX_Video.h
-     */
-    public final class MPEG4Level {
-        public static final int MPEG4Level0  = 0x01; /**< Level 0 */
-        public static final int MPEG4Level0b = 0x02; /**< Level 0b */
-        public static final int MPEG4Level1  = 0x04; /**< Level 1 */
-        public static final int MPEG4Level2  = 0x08; /**< Level 2 */
-        public static final int MPEG4Level3  = 0x10; /**< Level 3 */
-        public static final int MPEG4Level4  = 0x20; /**< Level 4 */
-        public static final int MPEG4Level4a = 0x40; /**< Level 4a */
-        public static final int MPEG4Level5  = 0x80; /**< Level 5 */
-        public static final int MPEG4LevelUnknown = 0x7FFFFFFF;
-    }
-    /**
-     *  Audio codec types
-     */
-    public static final int ACODEC_NO_AUDIO = 0;
-    public static final int ACODEC_AMRNB = 1;
-    public static final int ACODEC_AAC_LC = 2;
-    public static final int ACODEC_AAC_PLUS = 3;
-    public static final int ACODEC_ENHANCED_AAC_PLUS = 4;
-    public static final int ACODEC_MP3 = 5;
-    public static final int ACODEC_EVRC = 6;
-    // 7 value is used for PCM
-    public static final int ACODEC_AMRWB = 8;
-    public static final int ACODEC_OGG = 9;
-
-    /**
-     *  The array of supported audio codecs
-     */
-    private static final int[] SUPPORTED_ACODECS = new int[] {
-        ACODEC_AAC_LC,
-        ACODEC_AMRNB,
-        ACODEC_AMRWB
-    };
-
-    /**
-     *  Samples per frame for each audio codec
-     */
-    public static final int SAMPLES_PER_FRAME_AAC = 1024;
-    public static final int SAMPLES_PER_FRAME_MP3 = 1152;
-    public static final int SAMPLES_PER_FRAME_AMRNB = 160;
-    public static final int SAMPLES_PER_FRAME_AMRWB = 320;
-
-    public static final int DEFAULT_SAMPLING_FREQUENCY = 32000;
-    public static final int DEFAULT_CHANNEL_COUNT = 2;
-
-    /**
-     *  File format types
-     */
-    public static final int FILE_3GP = 0;
-    public static final int FILE_MP4 = 1;
-    public static final int FILE_AMR = 2;
-    public static final int FILE_MP3 = 3;
-    // 4 is for PCM
-    public static final int FILE_JPEG = 5;
-    // 6 is for BMP
-    // 7 is for GIF
-    public static final int FILE_PNG = 8;
-    // 9 is for ARGB8888
-    public static final int FILE_M4V = 10;
-    public static final int FILE_UNSUPPORTED = 255;
-
-    /**
-     * Undefined video codec profiles
-     */
-    public static final int UNDEFINED_VIDEO_PROFILE = 255;
-
-    /**
-     * The array of the supported file formats
-     */
-    private static final int[] SUPPORTED_VIDEO_FILE_FORMATS = new int[] {
-        FILE_3GP,
-        FILE_MP4,
-        FILE_M4V
-    };
-
-    /**
-     * The maximum count of audio tracks supported
-     */
-    public static final int AUDIO_MAX_TRACK_COUNT = 1;
-
-    /** The maximum volume supported (100 means that no amplification is
-     * supported, i.e. attenuation only)
-     */
-    public static final int AUDIO_MAX_VOLUME_PERCENT = 100;
-
-    /**
-     * This class cannot be instantiated
-     */
-    private MediaProperties() {
-    }
-
-    /**
-     * @return The array of supported aspect ratios
-     */
-    public static int[] getAllSupportedAspectRatios() {
-        return ASPECT_RATIOS;
-    }
-
-    /**
-     * Get the supported resolutions for the specified aspect ratio.
-     *
-     * @param aspectRatio The aspect ratio for which the resolutions are
-     *        requested
-     * @return The array of width and height pairs
-     */
-    public static Pair<Integer, Integer>[] getSupportedResolutions(int aspectRatio) {
-        final Pair<Integer, Integer>[] resolutions;
-        switch (aspectRatio) {
-            case ASPECT_RATIO_3_2: {
-                resolutions = ASPECT_RATIO_3_2_RESOLUTIONS;
-                break;
-            }
-
-            case ASPECT_RATIO_4_3: {
-                resolutions = ASPECT_RATIO_4_3_RESOLUTIONS;
-                break;
-            }
-
-            case ASPECT_RATIO_5_3: {
-                resolutions = ASPECT_RATIO_5_3_RESOLUTIONS;
-                break;
-            }
-
-            case ASPECT_RATIO_11_9: {
-                resolutions = ASPECT_RATIO_11_9_RESOLUTIONS;
-                break;
-            }
-
-            case ASPECT_RATIO_16_9: {
-                resolutions = ASPECT_RATIO_16_9_RESOLUTIONS;
-                break;
-            }
-
-            default: {
-                throw new IllegalArgumentException("Unknown aspect ratio: " + aspectRatio);
-            }
-        }
-
-        /** Check the platform specific maximum export resolution */
-        VideoEditorProfile veProfile = VideoEditorProfile.get();
-        if (veProfile == null) {
-            throw new RuntimeException("Can't get the video editor profile");
-        }
-        final int maxWidth = veProfile.maxOutputVideoFrameWidth;
-        final int maxHeight = veProfile.maxOutputVideoFrameHeight;
-        Pair<Integer, Integer>[] tmpResolutions = new Pair[resolutions.length];
-        int numSupportedResolution = 0;
-        int i = 0;
-
-        /** Get supported resolution list */
-        for (i = 0; i < resolutions.length; i++) {
-            if ((resolutions[i].first <= maxWidth) &&
-                (resolutions[i].second <= maxHeight)) {
-                tmpResolutions[numSupportedResolution] = resolutions[i];
-                numSupportedResolution++;
-            }
-        }
-        final Pair<Integer, Integer>[] supportedResolutions =
-            new Pair[numSupportedResolution];
-        System.arraycopy(tmpResolutions, 0,
-            supportedResolutions, 0, numSupportedResolution);
-
-        return supportedResolutions;
-    }
-
-    /**
-     * @return The array of supported video codecs
-     */
-    public static int[] getSupportedVideoCodecs() {
-        return SUPPORTED_VCODECS;
-    }
-
-    /**
-     * @return The array of supported audio codecs
-     */
-    public static int[] getSupportedAudioCodecs() {
-        return SUPPORTED_ACODECS;
-    }
-
-    /**
-     * @return The array of supported file formats
-     */
-    public static int[] getSupportedVideoFileFormat() {
-        return SUPPORTED_VIDEO_FILE_FORMATS;
-    }
-
-    /**
-     * @return The array of supported video bitrates
-     */
-    public static int[] getSupportedVideoBitrates() {
-        return SUPPORTED_BITRATES;
-    }
-
-    /**
-     * @return The maximum value for the audio volume
-     */
-    public static int getSupportedMaxVolume() {
-        return MediaProperties.AUDIO_MAX_VOLUME_PERCENT;
-    }
-
-    /**
-     * @return The maximum number of audio tracks supported
-     */
-    public static int getSupportedAudioTrackCount() {
-        return MediaProperties.AUDIO_MAX_TRACK_COUNT;
-    }
-}
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
deleted file mode 100644
index bbcdf57..0000000
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.ref.SoftReference;
-import android.graphics.Bitmap;
-import android.media.videoeditor.MediaArtistNativeHelper.ClipSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.Properties;
-import android.media.videoeditor.VideoEditorProfile;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-
-/**
- * This class represents a video clip item on the storyboard
- * {@hide}
- */
-public class MediaVideoItem extends MediaItem {
-
-    /**
-     *  Instance variables
-     */
-    private final int mWidth;
-    private final int mHeight;
-    private final int mAspectRatio;
-    private final int mFileType;
-    private final int mVideoType;
-    private final int mVideoProfile;
-    private final int mVideoLevel;
-    private final int mVideoBitrate;
-    private final long mDurationMs;
-    private final int mAudioBitrate;
-    private final int mFps;
-    private final int mAudioType;
-    private final int mAudioChannels;
-    private final int mAudioSamplingFrequency;
-    private long mBeginBoundaryTimeMs;
-    private long mEndBoundaryTimeMs;
-    private int mVolumePercentage;
-    private boolean mMuted;
-    private String mAudioWaveformFilename;
-    private MediaArtistNativeHelper mMANativeHelper;
-    private VideoEditorImpl mVideoEditor;
-    private final int mVideoRotationDegree;
-    /**
-     *  The audio waveform data
-     */
-    private SoftReference<WaveformData> mWaveformData;
-
-    /**
-     * An object of this type cannot be instantiated with a default constructor
-     */
-    @SuppressWarnings("unused")
-    private MediaVideoItem() throws IOException {
-        this(null, null, null, RENDERING_MODE_BLACK_BORDER);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param editor The video editor reference
-     * @param mediaItemId The MediaItem id
-     * @param filename The image file name
-     * @param renderingMode The rendering mode
-     *
-     * @throws IOException if the file cannot be opened for reading
-     */
-    public MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
-            int renderingMode) throws IOException {
-        this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param editor The video editor reference
-     * @param mediaItemId The MediaItem id
-     * @param filename The image file name
-     * @param renderingMode The rendering mode
-     * @param beginMs Start time in milliseconds. Set to 0 to extract from the
-     *           beginning
-     * @param endMs End time in milliseconds. Set to {@link #END_OF_FILE} to
-     *           extract until the end
-     * @param volumePercent in %/. 100% means no change; 50% means half value, 200%
-     *            means double, 0% means silent.
-     * @param muted true if the audio is muted
-     * @param audioWaveformFilename The name of the audio waveform file
-     *
-     * @throws IOException if the file cannot be opened for reading
-     */
-    MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
-            int renderingMode, long beginMs, long endMs, int volumePercent, boolean muted,
-            String audioWaveformFilename)  throws IOException {
-        super(editor, mediaItemId, filename, renderingMode);
-
-        if (editor instanceof VideoEditorImpl) {
-            mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
-            mVideoEditor = ((VideoEditorImpl)editor);
-        }
-
-        final Properties properties;
-        try {
-             properties = mMANativeHelper.getMediaProperties(filename);
-        } catch ( Exception e) {
-            throw new IllegalArgumentException(e.getMessage() + " : " + filename);
-        }
-
-        /** Check the platform specific maximum import resolution */
-        VideoEditorProfile veProfile = VideoEditorProfile.get();
-        if (veProfile == null) {
-            throw new RuntimeException("Can't get the video editor profile");
-        }
-        final int maxInputWidth = veProfile.maxInputVideoFrameWidth;
-        final int maxInputHeight = veProfile.maxInputVideoFrameHeight;
-        if ((properties.width > maxInputWidth) ||
-            (properties.height > maxInputHeight)) {
-            throw new IllegalArgumentException(
-                "Unsupported import resolution. Supported maximum width:" +
-                maxInputWidth + " height:" + maxInputHeight +
-                ", current width:" + properties.width +
-                " height:" + properties.height);
-        }
-        /** Check the platform specific maximum video profile and level */
-        if (!properties.profileSupported) {
-            throw new IllegalArgumentException(
-                "Unsupported video profile " + properties.profile);
-        }
-        if (!properties.levelSupported) {
-            throw new IllegalArgumentException(
-                "Unsupported video level " + properties.level);
-        }
-        switch (mMANativeHelper.getFileType(properties.fileType)) {
-            case MediaProperties.FILE_3GP:
-            case MediaProperties.FILE_MP4:
-            case MediaProperties.FILE_M4V:
-                break;
-
-            default:
-                throw new IllegalArgumentException("Unsupported Input File Type");
-        }
-
-        switch (mMANativeHelper.getVideoCodecType(properties.videoFormat)) {
-            case MediaProperties.VCODEC_H263:
-            case MediaProperties.VCODEC_H264:
-            case MediaProperties.VCODEC_MPEG4:
-                break;
-
-            default:
-                throw new IllegalArgumentException("Unsupported Video Codec Format in Input File");
-        }
-
-        mWidth = properties.width;
-        mHeight = properties.height;
-        mAspectRatio = mMANativeHelper.getAspectRatio(properties.width,
-                properties.height);
-        mFileType = mMANativeHelper.getFileType(properties.fileType);
-        mVideoType = mMANativeHelper.getVideoCodecType(properties.videoFormat);
-        mVideoProfile = properties.profile;
-        mVideoLevel = properties.level;
-        mDurationMs = properties.videoDuration;
-        mVideoBitrate = properties.videoBitrate;
-        mAudioBitrate = properties.audioBitrate;
-        mFps = (int)properties.averageFrameRate;
-        mAudioType = mMANativeHelper.getAudioCodecType(properties.audioFormat);
-        mAudioChannels = properties.audioChannels;
-        mAudioSamplingFrequency =  properties.audioSamplingFrequency;
-        mBeginBoundaryTimeMs = beginMs;
-        mEndBoundaryTimeMs = endMs == END_OF_FILE ? mDurationMs : endMs;
-        mVolumePercentage = volumePercent;
-        mMuted = muted;
-        mAudioWaveformFilename = audioWaveformFilename;
-        if (audioWaveformFilename != null) {
-            mWaveformData = new SoftReference<WaveformData>(
-                        new WaveformData(audioWaveformFilename));
-        } else {
-            mWaveformData = null;
-        }
-        mVideoRotationDegree = properties.videoRotation;
-    }
-
-    /**
-     * Sets the start and end marks for trimming a video media item.
-     * This method will adjust the duration of bounding transitions, effects
-     * and overlays if the current duration of the transactions become greater
-     * than the maximum allowable duration.
-     *
-     * @param beginMs Start time in milliseconds. Set to 0 to extract from the
-     *           beginning
-     * @param endMs End time in milliseconds. Set to {@link #END_OF_FILE} to
-     *           extract until the end
-     *
-     * @throws IllegalArgumentException if the start time is greater or equal than
-     *           end time, the end time is beyond the file duration, the start time
-     *           is negative
-     */
-    public void setExtractBoundaries(long beginMs, long endMs) {
-        if (beginMs > mDurationMs) {
-            throw new IllegalArgumentException("setExtractBoundaries: Invalid start time");
-        }
-
-        if (endMs > mDurationMs) {
-            throw new IllegalArgumentException("setExtractBoundaries: Invalid end time");
-        }
-
-        if ((endMs != -1) && (beginMs >= endMs) ) {
-            throw new IllegalArgumentException("setExtractBoundaries: Start time is greater than end time");
-        }
-
-        if ((beginMs < 0) || ((endMs != -1) && (endMs < 0))) {
-            throw new IllegalArgumentException("setExtractBoundaries: Start time or end time is negative");
-        }
-
-        mMANativeHelper.setGeneratePreview(true);
-
-        if (beginMs != mBeginBoundaryTimeMs) {
-            if (mBeginTransition != null) {
-                mBeginTransition.invalidate();
-            }
-        }
-
-        if (endMs != mEndBoundaryTimeMs) {
-            if (mEndTransition != null) {
-                mEndTransition.invalidate();
-            }
-        }
-
-        mBeginBoundaryTimeMs = beginMs;
-        mEndBoundaryTimeMs = endMs;
-        adjustTransitions();
-        mVideoEditor.updateTimelineDuration();
-        /**
-         *  Note that the start and duration of any effects and overlays are
-         *  not adjusted nor are they automatically removed if they fall
-         *  outside the new boundaries.
-         */
-    }
-
-    /**
-     * @return The boundary begin time
-     */
-    public long getBoundaryBeginTime() {
-        return mBeginBoundaryTimeMs;
-    }
-
-    /**
-     * @return The boundary end time
-     */
-    public long getBoundaryEndTime() {
-        return mEndBoundaryTimeMs;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void addEffect(Effect effect) {
-        if (effect instanceof EffectKenBurns) {
-            throw new IllegalArgumentException("Ken Burns effects cannot be applied to MediaVideoItem");
-        }
-        super.addEffect(effect);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public Bitmap getThumbnail(int width, int height, long timeMs) {
-        if (timeMs > mDurationMs) {
-            throw new IllegalArgumentException("Time Exceeds duration");
-        }
-
-        if (timeMs < 0) {
-            throw new IllegalArgumentException("Invalid Time duration");
-        }
-
-        if ((width <= 0) || (height <= 0)) {
-            throw new IllegalArgumentException("Invalid Dimensions");
-        }
-
-        if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
-            int temp = width;
-            width = height;
-            height = temp;
-        }
-
-        return mMANativeHelper.getPixels(
-                getFilename(), width, height, timeMs, mVideoRotationDegree);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void getThumbnailList(int width, int height,
-                                 long startMs, long endMs,
-                                 int thumbnailCount,
-                                 int[] indices,
-                                 GetThumbnailListCallback callback)
-                                 throws IOException {
-        if (startMs > endMs) {
-            throw new IllegalArgumentException("Start time is greater than end time");
-        }
-
-        if (endMs > mDurationMs) {
-            throw new IllegalArgumentException("End time is greater than file duration");
-        }
-
-        if ((height <= 0) || (width <= 0)) {
-            throw new IllegalArgumentException("Invalid dimension");
-        }
-
-        if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
-            int temp = width;
-            width = height;
-            height = temp;
-        }
-
-        mMANativeHelper.getPixelsList(getFilename(), width, height,
-                startMs, endMs, thumbnailCount, indices, callback,
-                mVideoRotationDegree);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    void invalidateTransitions(long startTimeMs, long durationMs) {
-        /**
-         *  Check if the item overlaps with the beginning and end transitions
-         */
-        if (mBeginTransition != null) {
-            if (isOverlapping(startTimeMs, durationMs,
-                    mBeginBoundaryTimeMs, mBeginTransition.getDuration())) {
-                mBeginTransition.invalidate();
-            }
-        }
-
-        if (mEndTransition != null) {
-            final long transitionDurationMs = mEndTransition.getDuration();
-            if (isOverlapping(startTimeMs, durationMs,
-                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs)) {
-                mEndTransition.invalidate();
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
-            long newDurationMs) {
-        /**
-         *  Check if the item overlaps with the beginning and end transitions
-         */
-        if (mBeginTransition != null) {
-            final long transitionDurationMs = mBeginTransition.getDuration();
-            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
-                    mBeginBoundaryTimeMs, transitionDurationMs);
-            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
-                    mBeginBoundaryTimeMs, transitionDurationMs);
-            /**
-             * Invalidate transition if:
-             *
-             * 1. New item overlaps the transition, the old one did not
-             * 2. New item does not overlap the transition, the old one did
-             * 3. New and old item overlap the transition if begin or end
-             * time changed
-             */
-            if (newOverlap != oldOverlap) { // Overlap has changed
-                mBeginTransition.invalidate();
-            } else if (newOverlap) { // Both old and new overlap
-                if ((oldStartTimeMs != newStartTimeMs) ||
-                        !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
-                        newStartTimeMs + newDurationMs > transitionDurationMs)) {
-                    mBeginTransition.invalidate();
-                }
-            }
-        }
-
-        if (mEndTransition != null) {
-            final long transitionDurationMs = mEndTransition.getDuration();
-            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
-                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
-            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
-                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
-            /**
-             * Invalidate transition if:
-             *
-             * 1. New item overlaps the transition, the old one did not
-             * 2. New item does not overlap the transition, the old one did
-             * 3. New and old item overlap the transition if begin or end
-             * time changed
-             */
-            if (newOverlap != oldOverlap) { // Overlap has changed
-                mEndTransition.invalidate();
-            } else if (newOverlap) { // Both old and new overlap
-                if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
-                        ((oldStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs) ||
-                        newStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs)) {
-                    mEndTransition.invalidate();
-                }
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int getAspectRatio() {
-        return mAspectRatio;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int getFileType() {
-        return mFileType;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int getWidth() {
-        if (mVideoRotationDegree == 90 ||
-             mVideoRotationDegree == 270) {
-            return mHeight;
-        } else {
-            return mWidth;
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int getHeight() {
-        if (mVideoRotationDegree == 90 ||
-             mVideoRotationDegree == 270) {
-            return mWidth;
-        } else {
-            return mHeight;
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public long getDuration() {
-        return mDurationMs;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public long getTimelineDuration() {
-        return mEndBoundaryTimeMs - mBeginBoundaryTimeMs;
-    }
-
-    /**
-     * Render a frame according to the playback (in the native aspect ratio) for
-     * the specified media item. All effects and overlays applied to the media
-     * item are ignored. The extract boundaries are also ignored. This method
-     * can be used to playback frames when implementing trimming functionality.
-     *
-     * @param surfaceHolder SurfaceHolder used by the application
-     * @param timeMs time corresponding to the frame to display (relative to the
-     *            the beginning of the media item).
-     * @return The accurate time stamp of the frame that is rendered .
-     * @throws IllegalStateException if a playback, preview or an export is
-     *             already in progress
-     * @throws IllegalArgumentException if time is negative or greater than the
-     *             media item duration
-     */
-    public long renderFrame(SurfaceHolder surfaceHolder, long timeMs) {
-        if (surfaceHolder == null) {
-            throw new IllegalArgumentException("Surface Holder is null");
-        }
-
-        if (timeMs > mDurationMs || timeMs < 0) {
-            throw new IllegalArgumentException("requested time not correct");
-        }
-
-        final Surface surface = surfaceHolder.getSurface();
-        if (surface == null) {
-            throw new RuntimeException("Surface could not be retrieved from Surface holder");
-        }
-
-        if (mFilename != null) {
-            return mMANativeHelper.renderMediaItemPreviewFrame(surface,
-                    mFilename,timeMs,mWidth,mHeight);
-        } else {
-            return 0;
-        }
-    }
-
-
-    /**
-     * This API allows to generate a file containing the sample volume levels of
-     * the Audio track of this media item. This function may take significant
-     * time and is blocking. The file can be retrieved using
-     * getAudioWaveformFilename().
-     *
-     * @param listener The progress listener
-     *
-     * @throws IOException if the output file cannot be created
-     * @throws IllegalArgumentException if the mediaItem does not have a valid
-     *             Audio track
-     */
-    public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener)
-        throws IOException {
-        int frameDuration = 0;
-        int sampleCount = 0;
-        final String projectPath = mMANativeHelper.getProjectPath();
-        /**
-         *  Waveform file does not exist
-         */
-        if (mAudioWaveformFilename == null ) {
-            /**
-             * Since audioWaveformFilename will not be supplied,it is  generated
-             */
-            String mAudioWaveFileName = null;
-
-            mAudioWaveFileName =
-                String.format(projectPath + "/" + "audioWaveformFile-"+ getId() + ".dat");
-            /**
-             * Logic to get frame duration = (no. of frames per sample * 1000)/
-             * sampling frequency
-             */
-            if (mMANativeHelper.getAudioCodecType(mAudioType) ==
-                MediaProperties.ACODEC_AMRNB ) {
-                frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRNB*1000)/
-                MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
-                sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRNB;
-            } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
-                MediaProperties.ACODEC_AMRWB ) {
-                frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRWB * 1000)/
-                MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
-                sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRWB;
-            } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
-                MediaProperties.ACODEC_AAC_LC ) {
-                frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AAC * 1000)/
-                MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
-                sampleCount = MediaProperties.SAMPLES_PER_FRAME_AAC;
-            }
-
-            mMANativeHelper.generateAudioGraph( getId(),
-                    mFilename,
-                    mAudioWaveFileName,
-                    frameDuration,
-                    MediaProperties.DEFAULT_CHANNEL_COUNT,
-                    sampleCount,
-                    listener,
-                    true);
-            /**
-             * Record the generated file name
-             */
-            mAudioWaveformFilename = mAudioWaveFileName;
-        }
-        mWaveformData =
-            new SoftReference<WaveformData>(new WaveformData(mAudioWaveformFilename));
-    }
-
-    /**
-     * Get the audio waveform file name if {@link #extractAudioWaveform()} was
-     * successful. The file format is as following:
-     * <ul>
-     *  <li>first 4 bytes provide the number of samples for each value, as big-endian signed</li>
-     *  <li>4 following bytes is the total number of values in the file, as big-endian signed</li>
-     *  <li>all values follow as bytes Name is unique.</li>
-     *</ul>
-     * @return the name of the file, null if the file has not been computed or
-     *         if there is no Audio track in the mediaItem
-     */
-    String getAudioWaveformFilename() {
-        return mAudioWaveformFilename;
-    }
-
-    /**
-     * Invalidate the AudioWaveform File
-     */
-    void invalidate() {
-        if (mAudioWaveformFilename != null) {
-            new File(mAudioWaveformFilename).delete();
-            mAudioWaveformFilename = null;
-        }
-    }
-
-    /**
-     * @return The waveform data
-     */
-    public WaveformData getWaveformData() throws IOException {
-        if (mWaveformData == null) {
-            return null;
-        }
-
-        WaveformData waveformData = mWaveformData.get();
-        if (waveformData != null) {
-            return waveformData;
-        } else if (mAudioWaveformFilename != null) {
-            try {
-                waveformData = new WaveformData(mAudioWaveformFilename);
-            } catch(IOException e) {
-                throw e;
-            }
-            mWaveformData = new SoftReference<WaveformData>(waveformData);
-            return waveformData;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Set volume of the Audio track of this mediaItem
-     *
-     * @param volumePercent in %/. 100% means no change; 50% means half value, 200%
-     *            means double, 0% means silent.
-     * @throws UsupportedOperationException if volume value is not supported
-     */
-    public void setVolume(int volumePercent) {
-        if ((volumePercent <0) || (volumePercent >100)) {
-            throw new IllegalArgumentException("Invalid volume");
-        }
-
-        mVolumePercentage = volumePercent;
-    }
-
-    /**
-     * Get the volume value of the audio track as percentage. Call of this
-     * method before calling setVolume will always return 100%
-     *
-     * @return the volume in percentage
-     */
-    public int getVolume() {
-        return mVolumePercentage;
-    }
-
-    /**
-     * @param muted true to mute the media item
-     */
-    public void setMute(boolean muted) {
-        mMANativeHelper.setGeneratePreview(true);
-        mMuted = muted;
-        if (mBeginTransition != null) {
-            mBeginTransition.invalidate();
-        }
-        if (mEndTransition != null) {
-            mEndTransition.invalidate();
-        }
-    }
-
-    /**
-     * @return true if the media item is muted
-     */
-    public boolean isMuted() {
-        return mMuted;
-    }
-
-    /**
-     * @return The video type
-     */
-    public int getVideoType() {
-        return mVideoType;
-    }
-
-    /**
-     * @return The video profile
-     */
-    public int getVideoProfile() {
-        return mVideoProfile;
-    }
-
-    /**
-     * @return The video profile
-     */
-    public int getVideoLevel() {
-        return mVideoLevel;
-    }
-
-    /**
-     * @return The video bitrate
-     */
-    public int getVideoBitrate() {
-        return mVideoBitrate;
-    }
-
-    /**
-     * @return The audio bitrate
-     */
-    public int getAudioBitrate() {
-        return mAudioBitrate;
-    }
-
-    /**
-     * @return The number of frames per second
-     */
-    public int getFps() {
-        return mFps;
-    }
-
-    /**
-     * @return The audio codec
-     */
-    public int getAudioType() {
-        return mAudioType;
-    }
-
-    /**
-     * @return The number of audio channels
-     */
-    public int getAudioChannels() {
-        return mAudioChannels;
-    }
-
-    /**
-     * @return The audio sample frequency
-     */
-    public int getAudioSamplingFrequency() {
-        return mAudioSamplingFrequency;
-    }
-
-    /**
-     * @return The Video media item properties in ClipSettings class object
-     * {@link android.media.videoeditor.MediaArtistNativeHelper.ClipSettings}
-     */
-    ClipSettings getVideoClipProperties() {
-        ClipSettings clipSettings = new ClipSettings();
-        clipSettings.clipPath = getFilename();
-        clipSettings.fileType = mMANativeHelper.getMediaItemFileType(getFileType());
-        clipSettings.beginCutTime = (int)getBoundaryBeginTime();
-        clipSettings.endCutTime = (int)getBoundaryEndTime();
-        clipSettings.mediaRendering = mMANativeHelper.getMediaItemRenderingMode(getRenderingMode());
-        clipSettings.rotationDegree = mVideoRotationDegree;
-
-        return clipSettings;
-    }
-}
diff --git a/media/java/android/media/videoeditor/Overlay.java b/media/java/android/media/videoeditor/Overlay.java
deleted file mode 100644
index a070eb4..0000000
--- a/media/java/android/media/videoeditor/Overlay.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * This is the super class for all Overlay classes.
- * {@hide}
- */
-public abstract class Overlay {
-    /**
-     *  Instance variables
-     */
-    private final String mUniqueId;
-    /**
-     *  The overlay owner
-     */
-    private final MediaItem mMediaItem;
-    /**
-     *  user attributes
-     */
-    private final Map<String, String> mUserAttributes;
-
-    protected long mStartTimeMs;
-    protected long mDurationMs;
-
-    /**
-     * Default constructor
-     */
-    @SuppressWarnings("unused")
-    private Overlay() {
-        this(null, null, 0, 0);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param mediaItem The media item owner
-     * @param overlayId The overlay id
-     * @param startTimeMs The start time relative to the media item start time
-     * @param durationMs The duration
-     *
-     * @throws IllegalArgumentException if the file type is not PNG or the
-     *      startTimeMs and durationMs are incorrect.
-     */
-    public Overlay(MediaItem mediaItem, String overlayId, long startTimeMs,
-           long durationMs) {
-        if (mediaItem == null) {
-            throw new IllegalArgumentException("Media item cannot be null");
-        }
-
-        if ((startTimeMs<0) || (durationMs<0) ) {
-            throw new IllegalArgumentException("Invalid start time and/OR duration");
-        }
-
-        if (startTimeMs + durationMs > mediaItem.getDuration()) {
-            throw new IllegalArgumentException("Invalid start time and duration");
-        }
-
-        mMediaItem = mediaItem;
-        mUniqueId = overlayId;
-        mStartTimeMs = startTimeMs;
-        mDurationMs = durationMs;
-        mUserAttributes = new HashMap<String, String>();
-    }
-
-    /**
-     * Get the overlay ID.
-     *
-     * @return The of the overlay
-     */
-    public String getId() {
-        return mUniqueId;
-    }
-
-    /**
-     * Get the duration of overlay.
-     *
-     * @return The duration of the overlay effect
-     */
-    public long getDuration() {
-        return mDurationMs;
-    }
-
-    /**
-     * If a preview or export is in progress, then this change is effective for
-     * next preview or export session.
-     *
-     * @param durationMs The duration in milliseconds
-     */
-    public void setDuration(long durationMs) {
-        if (durationMs < 0) {
-            throw new IllegalArgumentException("Invalid duration");
-        }
-
-        if (mStartTimeMs + durationMs > mMediaItem.getDuration()) {
-            throw new IllegalArgumentException("Duration is too large");
-        }
-
-        getMediaItem().getNativeContext().setGeneratePreview(true);
-
-        final long oldDurationMs = mDurationMs;
-        mDurationMs = durationMs;
-
-        mMediaItem.invalidateTransitions(mStartTimeMs, oldDurationMs, mStartTimeMs, mDurationMs);
-    }
-
-    /**
-     * Get the start time of overlay.
-     *
-     * @return the start time of the overlay
-     */
-    public long getStartTime() {
-        return mStartTimeMs;
-    }
-
-    /**
-     * Set the start time for the overlay. If a preview or export is in
-     * progress, then this change is effective for next preview or export
-     * session.
-     *
-     * @param startTimeMs start time in milliseconds
-     */
-    public void setStartTime(long startTimeMs) {
-        if (startTimeMs + mDurationMs > mMediaItem.getDuration()) {
-            throw new IllegalArgumentException("Start time is too large");
-        }
-
-        getMediaItem().getNativeContext().setGeneratePreview(true);
-
-        final long oldStartTimeMs = mStartTimeMs;
-        mStartTimeMs = startTimeMs;
-
-        mMediaItem.invalidateTransitions(oldStartTimeMs, mDurationMs, mStartTimeMs, mDurationMs);
-    }
-
-    /**
-     * Set the start time and duration
-     *
-     * @param startTimeMs start time in milliseconds
-     * @param durationMs The duration in milliseconds
-     */
-    public void setStartTimeAndDuration(long startTimeMs, long durationMs) {
-        if (startTimeMs + durationMs > mMediaItem.getDuration()) {
-            throw new IllegalArgumentException("Invalid start time or duration");
-        }
-
-        getMediaItem().getNativeContext().setGeneratePreview(true);
-
-        final long oldStartTimeMs = mStartTimeMs;
-        final long oldDurationMs = mDurationMs;
-
-        mStartTimeMs = startTimeMs;
-        mDurationMs = durationMs;
-
-        mMediaItem.invalidateTransitions(oldStartTimeMs, oldDurationMs, mStartTimeMs, mDurationMs);
-    }
-
-    /**
-     * Get the media item owner.
-     *
-     * @return The media item owner.
-     */
-    public MediaItem getMediaItem() {
-        return mMediaItem;
-    }
-
-    /**
-     * Set a user attribute
-     *
-     * @param name The attribute name
-     * @param value The attribute value
-     */
-    public void setUserAttribute(String name, String value) {
-        mUserAttributes.put(name, value);
-    }
-
-    /**
-     * Get the current user attributes set.
-     *
-     * @return The user attributes
-     */
-    public Map<String, String> getUserAttributes() {
-        return mUserAttributes;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (!(object instanceof Overlay)) {
-            return false;
-        }
-        return mUniqueId.equals(((Overlay)object).mUniqueId);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int hashCode() {
-        return mUniqueId.hashCode();
-    }
-}
diff --git a/media/java/android/media/videoeditor/OverlayFrame.java b/media/java/android/media/videoeditor/OverlayFrame.java
deleted file mode 100644
index d159df2..0000000
--- a/media/java/android/media/videoeditor/OverlayFrame.java
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.DataOutputStream;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap.CompressFormat;
-import android.util.Pair;
-
-
-/**
- * This class is used to overlay an image on top of a media item.
- * {@hide}
- */
-public class OverlayFrame extends Overlay {
-    /**
-     *  Instance variables
-     */
-    private Bitmap mBitmap;
-    private String mFilename;
-    private String mBitmapFileName;
-
-    private int mOFWidth;
-    private int mOFHeight;
-
-    /**
-     * resized RGB Image dimensions
-     */
-    private int mResizedRGBWidth;
-    private int mResizedRGBHeight;
-
-    /**
-     *  The resize paint
-     */
-    private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
-
-    /**
-     * An object of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private OverlayFrame() {
-        this(null, null, (String)null, 0, 0);
-    }
-
-    /**
-     * Constructor for an OverlayFrame
-     *
-     * @param mediaItem The media item owner
-     * @param overlayId The overlay id
-     * @param bitmap The bitmap to be used as an overlay. The size of the
-     *      bitmap must equal to the size of the media item to which it is
-     *      added. The bitmap is typically a decoded PNG file.
-     * @param startTimeMs The overlay start time in milliseconds
-     * @param durationMs The overlay duration in milliseconds
-     *
-     * @throws IllegalArgumentException if the file type is not PNG or the
-     *      startTimeMs and durationMs are incorrect.
-     */
-    public OverlayFrame(MediaItem mediaItem, String overlayId, Bitmap bitmap,
-                        long startTimeMs,long durationMs) {
-        super(mediaItem, overlayId, startTimeMs, durationMs);
-        mBitmap = bitmap;
-        mFilename = null;
-        mBitmapFileName = null;
-        mResizedRGBWidth = 0;
-        mResizedRGBHeight = 0;
-    }
-
-    /**
-     * Constructor for an OverlayFrame. This constructor can be used to
-     * restore the overlay after it was saved internally by the video editor.
-     *
-     * @param mediaItem The media item owner
-     * @param overlayId The overlay id
-     * @param filename The file name that contains the overlay.
-     * @param startTimeMs The overlay start time in milliseconds
-     * @param durationMs The overlay duration in milliseconds
-     *
-     * @throws IllegalArgumentException if the file type is not PNG or the
-     *      startTimeMs and durationMs are incorrect.
-     */
-    OverlayFrame(MediaItem mediaItem, String overlayId, String filename,
-                 long startTimeMs,long durationMs) {
-        super(mediaItem, overlayId, startTimeMs, durationMs);
-        mBitmapFileName = filename;
-        mBitmap = BitmapFactory.decodeFile(mBitmapFileName);
-        mFilename = null;
-        mResizedRGBWidth = 0;
-        mResizedRGBHeight = 0;
-    }
-
-    /**
-     * Get the overlay bitmap.
-     *
-     * @return Get the overlay bitmap
-     */
-    public Bitmap getBitmap() {
-        return mBitmap;
-    }
-
-    /**
-     * Get the overlay bitmap.
-     *
-     * @return Get the overlay bitmap as png file.
-     */
-    String getBitmapImageFileName() {
-        return mBitmapFileName;
-    }
-    /**
-     * Set the overlay bitmap.
-     *
-     * @param bitmap The overlay bitmap.
-     */
-    public void setBitmap(Bitmap bitmap) {
-        getMediaItem().getNativeContext().setGeneratePreview(true);
-
-        invalidate();
-
-        mBitmap = bitmap;
-        if (mFilename != null) {
-            /**
-             *  Delete the file
-             */
-            new File(mFilename).delete();
-            /**
-             *  Invalidate the filename
-             */
-            mFilename = null;
-        }
-
-        /**
-         *  Invalidate the transitions if necessary
-         */
-        getMediaItem().invalidateTransitions(mStartTimeMs, mDurationMs);
-    }
-
-    /**
-     * Get the file name of this overlay
-     */
-    String getFilename() {
-        return mFilename;
-    }
-
-    /*
-     * Set the file name of this overlay
-     */
-    void setFilename(String filename) {
-        mFilename = filename;
-    }
-    /**
-     * Save the overlay to the project folder
-     *
-     * @param path The path where the overlay will be saved
-     *
-     * @return The filename
-     * @throws FileNotFoundException if the bitmap cannot be saved
-     * @throws IOException if the bitmap file cannot be saved
-     */
-    String save(String path) throws FileNotFoundException, IOException {
-        if (mFilename != null) {
-            return mFilename;
-        }
-
-        // Create the compressed PNG file
-        mBitmapFileName = path + "/" + "Overlay" + getId() + ".png";
-        if (!(new File(mBitmapFileName).exists())) {
-            final FileOutputStream out = new FileOutputStream (mBitmapFileName);
-            mBitmap.compress(CompressFormat.PNG, 100, out);
-            out.flush();
-            out.close();
-        }
-
-        mOFWidth = mBitmap.getWidth();
-        mOFHeight = mBitmap.getHeight();
-
-        mFilename = path + "/" + "Overlay" + getId() + ".rgb";
-
-        /* resize and save rgb as per project aspect ratio */
-        MediaArtistNativeHelper nativeHelper = (super.getMediaItem()).getNativeContext();
-
-        /* get height and width for story board aspect ratio */
-        final Pair<Integer, Integer> maxResolution;
-        final Pair<Integer, Integer>[] resolutions;
-        resolutions = MediaProperties.getSupportedResolutions(nativeHelper.nativeHelperGetAspectRatio());
-
-        // Get the highest resolution
-        maxResolution = resolutions[resolutions.length - 1];
-
-        /* Generate the rgb file with rendering mode */
-        generateOverlayWithRenderingMode (super.getMediaItem(), this,
-                maxResolution.second /* max Height */ ,
-                maxResolution.first /* max Width */);
-
-        return mFilename;
-    }
-
-    /**
-     * Get the OverlayFrame Height
-     */
-     int getOverlayFrameHeight() {
-         return mOFHeight;
-     }
-
-     /**
-     * Get the OverlayFrame Width
-     */
-     int getOverlayFrameWidth() {
-         return mOFWidth;
-     }
-
-    /*
-     * Set the OverlayFrame Height
-     */
-     void setOverlayFrameHeight(int height) {
-         mOFHeight = height;
-     }
-
-    /*
-     * Set the OverlayFrame Width
-     */
-     void setOverlayFrameWidth(int width) {
-         mOFWidth = width;
-     }
-
-    /*
-     * Set the resized RGB widht and height
-     */
-     void setResizedRGBSize(int width, int height) {
-        mResizedRGBWidth = width;
-        mResizedRGBHeight = height;
-     }
-
-    /*
-     * Get the resized RGB Height
-     */
-     int getResizedRGBSizeHeight() {
-         return mResizedRGBHeight;
-     }
-
-    /*
-     * Get the resized RGB Width
-     */
-     int getResizedRGBSizeWidth() {
-         return mResizedRGBWidth;
-     }
-
-
-    /**
-     * Delete the overlay files
-     */
-    void invalidate() {
-        if (mBitmap != null) {
-            mBitmap.recycle();
-            mBitmap = null;
-        }
-
-        if (mFilename != null) {
-            new File(mFilename).delete();
-            mFilename = null;
-        }
-
-        if (mBitmapFileName != null) {
-            new File(mBitmapFileName).delete();
-            mBitmapFileName = null;
-        }
-    }
-
-     /**
-     * Delete the overlay related files
-     */
-    void invalidateGeneratedFiles() {
-        if (mFilename != null) {
-            new File(mFilename).delete();
-            mFilename = null;
-        }
-
-        if (mBitmapFileName != null) {
-            new File(mBitmapFileName).delete();
-            mBitmapFileName = null;
-        }
-    }
-
-    void generateOverlayWithRenderingMode (MediaItem mediaItemsList, OverlayFrame overlay, int height , int width)
-        throws FileNotFoundException, IOException {
-
-        final MediaItem t = mediaItemsList;
-
-        /* get the rendering mode */
-        int renderMode = t.getRenderingMode();
-
-        Bitmap overlayBitmap = ((OverlayFrame)overlay).getBitmap();
-
-        /*
-         * Check if the resize of Overlay is needed with rendering mode applied
-         * because of change in export dimensions
-         */
-        int resizedRGBFileHeight = ((OverlayFrame)overlay).getResizedRGBSizeHeight();
-        int resizedRGBFileWidth = ((OverlayFrame)overlay).getResizedRGBSizeWidth();
-
-        /* Get original bitmap width if it is not resized */
-        if(resizedRGBFileWidth == 0) {
-            resizedRGBFileWidth = overlayBitmap.getWidth();
-        }
-        /* Get original bitmap height if it is not resized */
-        if(resizedRGBFileHeight == 0) {
-            resizedRGBFileHeight = overlayBitmap.getHeight();
-        }
-
-        if (resizedRGBFileWidth != width || resizedRGBFileHeight != height
-            || (!(new File(((OverlayFrame)overlay).getFilename()).exists()))) {
-            /*
-             *  Create the canvas bitmap
-             */
-            final Bitmap destBitmap = Bitmap.createBitmap((int)width,
-                                                      (int)height,
-                                                      Bitmap.Config.ARGB_8888);
-            final Canvas overlayCanvas = new Canvas(destBitmap);
-            final Rect destRect;
-            final Rect srcRect;
-
-            switch (renderMode) {
-                case MediaItem.RENDERING_MODE_STRETCH: {
-                    destRect = new Rect(0, 0, overlayCanvas.getWidth(),
-                                             overlayCanvas.getHeight());
-                    srcRect = new Rect(0, 0, overlayBitmap.getWidth(),
-                                             overlayBitmap.getHeight());
-                    break;
-                }
-
-                case MediaItem.RENDERING_MODE_BLACK_BORDER: {
-                    int left, right, top, bottom;
-                    float aROverlayImage, aRCanvas;
-                    aROverlayImage = (float)(overlayBitmap.getWidth()) /
-                                     (float)(overlayBitmap.getHeight());
-
-                    aRCanvas = (float)(overlayCanvas.getWidth()) /
-                                     (float)(overlayCanvas.getHeight());
-
-                    if (aROverlayImage > aRCanvas) {
-                        int newHeight = ((overlayCanvas.getWidth() * overlayBitmap.getHeight())
-                                         / overlayBitmap.getWidth());
-                        left = 0;
-                        top  = (overlayCanvas.getHeight() - newHeight) / 2;
-                        right = overlayCanvas.getWidth();
-                        bottom = top + newHeight;
-                    } else {
-                        int newWidth = ((overlayCanvas.getHeight() * overlayBitmap.getWidth())
-                                            / overlayBitmap.getHeight());
-                        left = (overlayCanvas.getWidth() - newWidth) / 2;
-                        top  = 0;
-                        right = left + newWidth;
-                        bottom = overlayCanvas.getHeight();
-                    }
-
-                    destRect = new Rect(left, top, right, bottom);
-                    srcRect = new Rect(0, 0, overlayBitmap.getWidth(), overlayBitmap.getHeight());
-                    break;
-                }
-
-                case MediaItem.RENDERING_MODE_CROPPING: {
-                    // Calculate the source rect
-                    int left, right, top, bottom;
-                    float aROverlayImage, aRCanvas;
-                    aROverlayImage = (float)(overlayBitmap.getWidth()) /
-                                     (float)(overlayBitmap.getHeight());
-                    aRCanvas = (float)(overlayCanvas.getWidth()) /
-                                    (float)(overlayCanvas.getHeight());
-                    if (aROverlayImage < aRCanvas) {
-                        int newHeight = ((overlayBitmap.getWidth() * overlayCanvas.getHeight())
-                                   / overlayCanvas.getWidth());
-
-                        left = 0;
-                        top  = (overlayBitmap.getHeight() - newHeight) / 2;
-                        right = overlayBitmap.getWidth();
-                        bottom = top + newHeight;
-                    } else {
-                        int newWidth = ((overlayBitmap.getHeight() * overlayCanvas.getWidth())
-                                    / overlayCanvas.getHeight());
-                        left = (overlayBitmap.getWidth() - newWidth) / 2;
-                        top  = 0;
-                        right = left + newWidth;
-                        bottom = overlayBitmap.getHeight();
-                    }
-
-                    srcRect = new Rect(left, top, right, bottom);
-                    destRect = new Rect(0, 0, overlayCanvas.getWidth(), overlayCanvas.getHeight());
-                    break;
-                }
-
-                default: {
-                    throw new IllegalStateException("Rendering mode: " + renderMode);
-                }
-            }
-
-            overlayCanvas.drawBitmap(overlayBitmap, srcRect, destRect, sResizePaint);
-            overlayCanvas.setBitmap(null);
-
-            /*
-             * Write to the dest file
-             */
-            String outFileName = ((OverlayFrame)overlay).getFilename();
-
-            /*
-             * Save the image to same rgb file
-             */
-            if (outFileName != null) {
-                new File(outFileName).delete();
-            }
-
-            final FileOutputStream fl = new FileOutputStream(outFileName);
-            final DataOutputStream dos = new DataOutputStream(fl);
-
-            /*
-             * Populate the rgb file with bitmap data
-             */
-            final int [] framingBuffer = new int[width];
-            ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
-            IntBuffer intBuffer;
-
-            byte[] array = byteBuffer.array();
-            int tmp = 0;
-            while(tmp < height) {
-                destBitmap.getPixels(framingBuffer,0,width,0,tmp,width,1);
-                intBuffer = byteBuffer.asIntBuffer();
-                intBuffer.put(framingBuffer,0,width);
-                dos.write(array);
-                tmp += 1;
-            }
-            fl.flush();
-            fl.close();
-
-            /*
-             * Set the resized RGB width and height
-             */
-            ((OverlayFrame)overlay).setResizedRGBSize(width, height);
-        }
-    }
-}
diff --git a/media/java/android/media/videoeditor/Transition.java b/media/java/android/media/videoeditor/Transition.java
deleted file mode 100644
index fa9d26d..0000000
--- a/media/java/android/media/videoeditor/Transition.java
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import android.media.videoeditor.MediaArtistNativeHelper.AlphaMagicSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.AudioTransition;
-import android.media.videoeditor.MediaArtistNativeHelper.ClipSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.EditSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.EffectSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.SlideTransitionSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.TransitionSettings;
-import android.media.videoeditor.MediaArtistNativeHelper.VideoTransition;
-
-/**
- * This class is super class for all transitions. Transitions (with the
- * exception of TransitionAtStart and TransitioAtEnd) can only be inserted
- * between media items.
- *
- * Adding a transition between MediaItems makes the
- * duration of the storyboard shorter by the duration of the Transition itself.
- * As a result, if the duration of the transition is larger than the smaller
- * duration of the two MediaItems associated with the Transition, an exception
- * will be thrown.
- *
- * During a transition, the audio track are cross-fading
- * automatically. {@hide}
- */
-public abstract class Transition {
-    /**
-     *  The transition behavior
-     */
-    private static final int BEHAVIOR_MIN_VALUE = 0;
-
-    /** The transition starts slowly and speed up */
-    public static final int BEHAVIOR_SPEED_UP = 0;
-    /** The transition start fast and speed down */
-    public static final int BEHAVIOR_SPEED_DOWN = 1;
-    /** The transition speed is constant */
-    public static final int BEHAVIOR_LINEAR = 2;
-    /** The transition starts fast and ends fast with a slow middle */
-    public static final int BEHAVIOR_MIDDLE_SLOW = 3;
-    /** The transition starts slowly and ends slowly with a fast middle */
-    public static final int BEHAVIOR_MIDDLE_FAST = 4;
-
-    private static final int BEHAVIOR_MAX_VALUE = 4;
-
-    /**
-     *  The unique id of the transition
-     */
-    private final String mUniqueId;
-
-    /**
-     *  The transition is applied at the end of this media item
-     */
-    private final MediaItem mAfterMediaItem;
-    /**
-     *  The transition is applied at the beginning of this media item
-     */
-    private final MediaItem mBeforeMediaItem;
-
-    /**
-     *  The transition behavior
-     */
-    protected final int mBehavior;
-
-    /**
-     *  The transition duration
-     */
-    protected long mDurationMs;
-
-    /**
-     *  The transition filename
-     */
-    protected String mFilename;
-
-    protected MediaArtistNativeHelper mNativeHelper;
-    /**
-     * An object of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private Transition() {
-        this(null, null, null, 0, 0);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param transitionId The transition id
-     * @param afterMediaItem The transition is applied to the end of this
-     *      media item
-     * @param beforeMediaItem The transition is applied to the beginning of
-     *      this media item
-     * @param durationMs The duration of the transition in milliseconds
-     * @param behavior The transition behavior
-     */
-    protected Transition(String transitionId, MediaItem afterMediaItem,
-                         MediaItem beforeMediaItem,long durationMs,
-                         int behavior) {
-        if (behavior < BEHAVIOR_MIN_VALUE || behavior > BEHAVIOR_MAX_VALUE) {
-            throw new IllegalArgumentException("Invalid behavior: " + behavior);
-        }
-        if ((afterMediaItem == null) && (beforeMediaItem == null)) {
-            throw new IllegalArgumentException("Null media items");
-        }
-        mUniqueId = transitionId;
-        mAfterMediaItem = afterMediaItem;
-        mBeforeMediaItem = beforeMediaItem;
-        mDurationMs = durationMs;
-        mBehavior = behavior;
-        mNativeHelper = null;
-        if (durationMs > getMaximumDuration()) {
-            throw new IllegalArgumentException("The duration is too large");
-        }
-        if (afterMediaItem != null) {
-            mNativeHelper = afterMediaItem.getNativeContext();
-        }else {
-            mNativeHelper = beforeMediaItem.getNativeContext();
-        }
-    }
-
-    /**
-     * Get the ID of the transition.
-     *
-     * @return The ID of the transition
-     */
-    public String getId() {
-        return mUniqueId;
-    }
-
-    /**
-     * Get the media item at the end of which the transition is applied.
-     *
-     * @return The media item at the end of which the transition is applied
-     */
-    public MediaItem getAfterMediaItem() {
-        return mAfterMediaItem;
-    }
-
-    /**
-     * Get the media item at the beginning of which the transition is applied.
-     *
-     * @return The media item at the beginning of which the transition is
-     *      applied
-     */
-    public MediaItem getBeforeMediaItem() {
-        return mBeforeMediaItem;
-    }
-
-    /**
-     * Set the duration of the transition.
-     *
-     * @param durationMs the duration of the transition in milliseconds
-     */
-    public void setDuration(long durationMs) {
-        if (durationMs > getMaximumDuration()) {
-            throw new IllegalArgumentException("The duration is too large");
-        }
-
-        mDurationMs = durationMs;
-        invalidate();
-        mNativeHelper.setGeneratePreview(true);
-    }
-
-    /**
-     * Get the duration of the transition.
-     *
-     * @return the duration of the transition in milliseconds
-     */
-    public long getDuration() {
-        return mDurationMs;
-    }
-
-    /**
-     * The duration of a transition cannot be greater than half of the minimum
-     * duration of the bounding media items.
-     *
-     * @return The maximum duration of this transition
-     */
-    public long getMaximumDuration() {
-        if (mAfterMediaItem == null) {
-            return mBeforeMediaItem.getTimelineDuration() / 2;
-        } else if (mBeforeMediaItem == null) {
-            return mAfterMediaItem.getTimelineDuration() / 2;
-        } else {
-            return (Math.min(mAfterMediaItem.getTimelineDuration(),
-                    mBeforeMediaItem.getTimelineDuration()) / 2);
-        }
-    }
-
-    /**
-     * Get the behavior of the transition.
-     *
-     * @return The behavior
-     */
-    public int getBehavior() {
-        return mBehavior;
-    }
-
-    /**
-     * Get the transition data.
-     *
-     * @return The transition data in TransitionSettings object
-     * {@link android.media.videoeditor.MediaArtistNativeHelper.TransitionSettings}
-     */
-    TransitionSettings getTransitionSettings() {
-        TransitionAlpha transitionAlpha = null;
-        TransitionSliding transitionSliding = null;
-        TransitionCrossfade transitionCrossfade = null;
-        TransitionFadeBlack transitionFadeBlack = null;
-        TransitionSettings transitionSetting = null;
-        transitionSetting = new TransitionSettings();
-        transitionSetting.duration = (int)getDuration();
-        if (this instanceof TransitionAlpha) {
-            transitionAlpha = (TransitionAlpha)this;
-            transitionSetting.videoTransitionType = VideoTransition.ALPHA_MAGIC;
-            transitionSetting.audioTransitionType = AudioTransition.CROSS_FADE;
-            transitionSetting.transitionBehaviour = mNativeHelper
-            .getVideoTransitionBehaviour(transitionAlpha.getBehavior());
-            transitionSetting.alphaSettings = new AlphaMagicSettings();
-            transitionSetting.slideSettings = null;
-            transitionSetting.alphaSettings.file = transitionAlpha.getPNGMaskFilename();
-            transitionSetting.alphaSettings.blendingPercent = transitionAlpha.getBlendingPercent();
-            transitionSetting.alphaSettings.invertRotation = transitionAlpha.isInvert();
-            transitionSetting.alphaSettings.rgbWidth = transitionAlpha.getRGBFileWidth();
-            transitionSetting.alphaSettings.rgbHeight = transitionAlpha.getRGBFileHeight();
-
-        } else if (this instanceof TransitionSliding) {
-            transitionSliding = (TransitionSliding)this;
-            transitionSetting.videoTransitionType = VideoTransition.SLIDE_TRANSITION;
-            transitionSetting.audioTransitionType = AudioTransition.CROSS_FADE;
-            transitionSetting.transitionBehaviour = mNativeHelper
-            .getVideoTransitionBehaviour(transitionSliding.getBehavior());
-            transitionSetting.alphaSettings = null;
-            transitionSetting.slideSettings = new SlideTransitionSettings();
-            transitionSetting.slideSettings.direction = mNativeHelper
-            .getSlideSettingsDirection(transitionSliding.getDirection());
-        } else if (this instanceof TransitionCrossfade) {
-            transitionCrossfade = (TransitionCrossfade)this;
-            transitionSetting.videoTransitionType = VideoTransition.CROSS_FADE;
-            transitionSetting.audioTransitionType = AudioTransition.CROSS_FADE;
-            transitionSetting.transitionBehaviour = mNativeHelper
-            .getVideoTransitionBehaviour(transitionCrossfade.getBehavior());
-            transitionSetting.alphaSettings = null;
-            transitionSetting.slideSettings = null;
-        } else if (this instanceof TransitionFadeBlack) {
-            transitionFadeBlack = (TransitionFadeBlack)this;
-            transitionSetting.videoTransitionType = VideoTransition.FADE_BLACK;
-            transitionSetting.audioTransitionType = AudioTransition.CROSS_FADE;
-            transitionSetting.transitionBehaviour = mNativeHelper
-            .getVideoTransitionBehaviour(transitionFadeBlack.getBehavior());
-            transitionSetting.alphaSettings = null;
-            transitionSetting.slideSettings = null;
-        }
-
-        return transitionSetting;
-    }
-
-    /**
-     * Checks if the effect and overlay applied on a media item
-     * overlaps with the transition on media item.
-     *
-     * @param m The media item
-     * @param clipSettings The ClipSettings object
-     * @param clipNo The clip no.(out of the two media items
-     * associated with current transition)for which the effect
-     * clip should be generated
-     * @return List of effects that overlap with the transition
-     */
-
-    List<EffectSettings>  isEffectandOverlayOverlapping(MediaItem m, ClipSettings clipSettings,
-                                         int clipNo) {
-        List<Effect> effects;
-        List<Overlay> overlays;
-        List<EffectSettings> effectSettings = new ArrayList<EffectSettings>();
-        EffectSettings tmpEffectSettings;
-
-        overlays = m.getAllOverlays();
-        for (Overlay overlay : overlays) {
-            tmpEffectSettings = mNativeHelper.getOverlaySettings((OverlayFrame)overlay);
-            mNativeHelper.adjustEffectsStartTimeAndDuration(tmpEffectSettings,
-                    clipSettings.beginCutTime, clipSettings.endCutTime);
-            if (tmpEffectSettings.duration != 0) {
-                effectSettings.add(tmpEffectSettings);
-            }
-        }
-
-        effects = m.getAllEffects();
-        for (Effect effect : effects) {
-            if (effect instanceof EffectColor) {
-                tmpEffectSettings = mNativeHelper.getEffectSettings((EffectColor)effect);
-                mNativeHelper.adjustEffectsStartTimeAndDuration(tmpEffectSettings,
-                        clipSettings.beginCutTime, clipSettings.endCutTime);
-                if (tmpEffectSettings.duration != 0) {
-                    if (m instanceof MediaVideoItem) {
-                        tmpEffectSettings.fiftiesFrameRate = mNativeHelper
-                        .GetClosestVideoFrameRate(((MediaVideoItem)m).getFps());
-                    }
-                    effectSettings.add(tmpEffectSettings);
-                }
-            }
-        }
-
-         return effectSettings;
-    }
-
-    /**
-     * Generate the video clip for the specified transition. This method may
-     * block for a significant amount of time. Before the method completes
-     * execution it sets the mFilename to the name of the newly generated
-     * transition video clip file.
-     */
-    void generate() {
-        MediaItem m1 = this.getAfterMediaItem();
-        MediaItem m2 = this.getBeforeMediaItem();
-        ClipSettings clipSettings1 = new ClipSettings();
-        ClipSettings clipSettings2 = new ClipSettings();
-        TransitionSettings transitionSetting = null;
-        EditSettings editSettings = new EditSettings();
-        List<EffectSettings> effectSettings_clip1;
-        List<EffectSettings> effectSettings_clip2;
-
-        String output = null;
-
-        if (mNativeHelper == null) {
-            if (m1 != null)
-                mNativeHelper = m1.getNativeContext();
-            else if (m2 != null)
-                mNativeHelper = m2.getNativeContext();
-        }
-        transitionSetting = getTransitionSettings();
-        if (m1 != null && m2 != null) {
-            /* transition between media items */
-            clipSettings1 = m1.getClipSettings();
-            clipSettings2 = m2.getClipSettings();
-            clipSettings1.beginCutTime = (int)(clipSettings1.endCutTime -
-                                                              this.mDurationMs);
-            clipSettings2.endCutTime = (int)(clipSettings2.beginCutTime +
-                                                              this.mDurationMs);
-            /*
-             * Check how many effects and overlays overlap with transition and
-             * generate effect clip first if there is any overlap
-             */
-            effectSettings_clip1 = isEffectandOverlayOverlapping(m1, clipSettings1,1);
-            effectSettings_clip2 = isEffectandOverlayOverlapping(m2, clipSettings2,2);
-            for (int index = 0; index < effectSettings_clip2.size(); index++ ) {
-                effectSettings_clip2.get(index).startTime += this.mDurationMs;
-            }
-            editSettings.effectSettingsArray =
-                                              new EffectSettings[effectSettings_clip1.size()
-                                                 + effectSettings_clip2.size()];
-            int i=0,j=0;
-            while (i < effectSettings_clip1.size()) {
-                editSettings.effectSettingsArray[j] = effectSettings_clip1.get(i);
-                i++;
-                j++;
-            }
-            i=0;
-            while (i < effectSettings_clip2.size()) {
-                editSettings.effectSettingsArray[j] = effectSettings_clip2.get(i);
-                i++;
-                j++;
-            }
-        } else if (m1 == null && m2 != null) {
-            /* begin transition at first media item */
-            m2.generateBlankFrame(clipSettings1);
-            clipSettings2 = m2.getClipSettings();
-            clipSettings1.endCutTime = (int)(this.mDurationMs + 50);
-            clipSettings2.endCutTime = (int)(clipSettings2.beginCutTime +
-                                                              this.mDurationMs);
-            /*
-             * Check how many effects and overlays overlap with transition and
-             * generate effect clip first if there is any overlap
-             */
-            effectSettings_clip2 = isEffectandOverlayOverlapping(m2, clipSettings2,2);
-            for (int index = 0; index < effectSettings_clip2.size(); index++ ) {
-                effectSettings_clip2.get(index).startTime += this.mDurationMs;
-            }
-            editSettings.effectSettingsArray = new EffectSettings[effectSettings_clip2.size()];
-            int i=0, j=0;
-            while (i < effectSettings_clip2.size()) {
-                editSettings.effectSettingsArray[j] = effectSettings_clip2.get(i);
-                i++;
-                j++;
-            }
-        } else if (m1 != null && m2 == null) {
-            /* end transition at last media item */
-            clipSettings1 = m1.getClipSettings();
-            m1.generateBlankFrame(clipSettings2);
-            clipSettings1.beginCutTime = (int)(clipSettings1.endCutTime -
-                                                              this.mDurationMs);
-            clipSettings2.endCutTime = (int)(this.mDurationMs + 50);
-            /*
-             * Check how many effects and overlays overlap with transition and
-             * generate effect clip first if there is any overlap
-             */
-            effectSettings_clip1 = isEffectandOverlayOverlapping(m1, clipSettings1,1);
-            editSettings.effectSettingsArray = new EffectSettings[effectSettings_clip1.size()];
-            int i=0,j=0;
-            while (i < effectSettings_clip1.size()) {
-                editSettings.effectSettingsArray[j] = effectSettings_clip1.get(i);
-                i++;
-                j++;
-            }
-        }
-
-        editSettings.clipSettingsArray = new ClipSettings[2];
-        editSettings.clipSettingsArray[0] = clipSettings1;
-        editSettings.clipSettingsArray[1] = clipSettings2;
-        editSettings.backgroundMusicSettings = null;
-        editSettings.transitionSettingsArray = new TransitionSettings[1];
-        editSettings.transitionSettingsArray[0] = transitionSetting;
-        output = mNativeHelper.generateTransitionClip(editSettings, mUniqueId,
-                                                      m1, m2,this);
-        setFilename(output);
-    }
-
-
-    /**
-     * Set the transition filename.
-     */
-    void setFilename(String filename) {
-        mFilename = filename;
-    }
-
-    /**
-     * Get the transition filename.
-     */
-    String getFilename() {
-        return mFilename;
-    }
-
-    /**
-     * Remove any resources associated with this transition
-     */
-    void invalidate() {
-        if (mFilename != null) {
-            new File(mFilename).delete();
-            mFilename = null;
-        }
-    }
-
-    /**
-     * Check if the transition is generated.
-     *
-     * @return true if the transition is generated
-     */
-    boolean isGenerated() {
-        return (mFilename != null);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (!(object instanceof Transition)) {
-            return false;
-        }
-        return mUniqueId.equals(((Transition)object).mUniqueId);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public int hashCode() {
-        return mUniqueId.hashCode();
-    }
-}
diff --git a/media/java/android/media/videoeditor/TransitionAlpha.java b/media/java/android/media/videoeditor/TransitionAlpha.java
deleted file mode 100644
index 22788d4..0000000
--- a/media/java/android/media/videoeditor/TransitionAlpha.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.videoeditor;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-
-/**
- * This class allows to render an "alpha blending" transition according to a
- * bitmap mask. The mask shows the shape of the transition all along the
- * duration of the transition: just before the transition, video 1 is fully
- * displayed. When the transition starts, as the time goes on, pixels of video 2
- * replace pixels of video 1 according to the gray scale pixel value of the
- * mask.
- * {@hide}
- */
-public class TransitionAlpha extends Transition {
-    /** This is the input JPEG file for the mask */
-    private final String mMaskFilename;
-
-    /**
-     * This is percentage (between 0 and 100) of blending between video 1 and
-     * video 2 if this value equals 0, then the mask is strictly applied if this
-     * value equals 100, then the mask is not at all applied (no transition
-     * effect)
-     */
-    private final int mBlendingPercent;
-
-    /**
-     * If true, this value inverts the direction of the mask: white pixels of
-     * the mask show video 2 pixels first black pixels of the mask show video 2
-     * pixels last.
-     */
-    private final boolean mIsInvert;
-
-
-    private int mWidth;
-    private int mHeight;
-    private String mRGBMaskFile;
-
-    /**
-     * An object of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private TransitionAlpha() {
-        this(null, null, null, 0, 0, null, 0, false);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param transitionId The transition id
-     * @param afterMediaItem The transition is applied to the end of this media
-     *            item
-     * @param beforeMediaItem The transition is applied to the beginning of this
-     *            media item
-     * @param durationMs duration of the transition in milliseconds
-     * @param behavior behavior is one of the behavior defined in Transition
-     *            class
-     * @param maskFilename JPEG file name. The dimension of the image
-     *           corresponds to 720p (16:9 aspect ratio). Mask files are
-     *           shared between video editors and can be created in the
-     *           projects folder (the parent folder for all projects).
-     * @param blendingPercent The blending percent applied
-     * @param invert true to invert the direction of the alpha blending
-     * @throws IllegalArgumentException if behavior is not supported, or if
-     *             direction are not supported.
-     */
-    public TransitionAlpha(String transitionId, MediaItem afterMediaItem,
-            MediaItem beforeMediaItem, long durationMs, int behavior,
-            String maskFilename, int blendingPercent, boolean invert) {
-        super(transitionId, afterMediaItem, beforeMediaItem, durationMs, behavior);
-
-        /**
-         * Generate a RGB file for the supplied mask file
-         */
-        final BitmapFactory.Options dbo = new BitmapFactory.Options();
-        dbo.inJustDecodeBounds = true;
-        if (!new File(maskFilename).exists())
-            throw new IllegalArgumentException("File not Found " + maskFilename);
-        BitmapFactory.decodeFile(maskFilename, dbo);
-
-        mWidth = dbo.outWidth;
-        mHeight = dbo.outHeight;
-
-        mRGBMaskFile = String.format(mNativeHelper.getProjectPath() +
-                "/" + "mask" + transitionId+ ".rgb");
-
-
-        FileOutputStream fl = null;
-
-        try{
-             fl = new FileOutputStream(mRGBMaskFile);
-        } catch (IOException e) {
-            /* catch IO exception */
-        }
-        final DataOutputStream dos = new DataOutputStream(fl);
-
-        if (fl != null) {
-            /**
-             * Write to rgb file
-             */
-            Bitmap imageBitmap = BitmapFactory.decodeFile(maskFilename);
-            final int [] framingBuffer = new int[mWidth];
-            ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
-            IntBuffer intBuffer;
-
-            byte[] array = byteBuffer.array();
-            int tmp = 0;
-            while (tmp < mHeight) {
-                imageBitmap.getPixels(framingBuffer, 0, mWidth, 0, tmp,mWidth, 1);
-                intBuffer = byteBuffer.asIntBuffer();
-                intBuffer.put(framingBuffer,0,mWidth);
-                try {
-                    dos.write(array);
-                } catch (IOException e) {
-                    /* catch file write error */
-                }
-                tmp += 1;
-            }
-
-            imageBitmap.recycle();
-            try{
-                fl.close();
-            }catch (IOException e) {
-                /* file close error */
-            }
-        }
-
-        /**
-         * Capture the details
-         */
-        mMaskFilename = maskFilename;
-        mBlendingPercent = blendingPercent;
-        mIsInvert = invert;
-    }
-
-    public int getRGBFileWidth() {
-        return mWidth;
-    }
-
-    public int getRGBFileHeight() {
-        return mHeight;
-    }
-
-    public String getPNGMaskFilename() {
-        return mRGBMaskFile;
-    }
-
-    /**
-     * Get the blending percentage
-     *
-     * @return The blending percentage
-     */
-    public int getBlendingPercent() {
-        return mBlendingPercent;
-    }
-
-    /**
-     * Get the filename of the mask.
-     *
-     * @return The mask filename
-     */
-    public String getMaskFilename() {
-        return mMaskFilename;
-    }
-
-    /**
-     * Check if the alpha blending direction is inverted.
-     *
-     * @return true if the direction of the alpha blending is inverted
-     */
-    public boolean isInvert() {
-        return mIsInvert;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void generate() {
-        super.generate();
-    }
-}
diff --git a/media/java/android/media/videoeditor/TransitionCrossfade.java b/media/java/android/media/videoeditor/TransitionCrossfade.java
deleted file mode 100644
index 417c64e..0000000
--- a/media/java/android/media/videoeditor/TransitionCrossfade.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-
-/**
- * This class allows to render a crossfade (dissolve) effect transition between
- * two videos
- * {@hide}
- */
-public class TransitionCrossfade extends Transition {
-    /**
-     * An object of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private TransitionCrossfade() {
-        this(null, null, null, 0, 0);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param transitionId The transition id
-     * @param afterMediaItem The transition is applied to the end of this
-     *      media item
-     * @param beforeMediaItem The transition is applied to the beginning of
-     *      this media item
-     * @param durationMs duration of the transition in milliseconds
-     * @param behavior behavior is one of the behavior defined in Transition
-     *      class
-     *
-     * @throws IllegalArgumentException if behavior is not supported.
-     */
-    public TransitionCrossfade(String transitionId, MediaItem afterMediaItem,
-            MediaItem beforeMediaItem, long durationMs, int behavior) {
-        super(transitionId, afterMediaItem, beforeMediaItem, durationMs, behavior);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    void generate() {
-        super.generate();
-    }
-}
diff --git a/media/java/android/media/videoeditor/TransitionFadeBlack.java b/media/java/android/media/videoeditor/TransitionFadeBlack.java
deleted file mode 100644
index da07cf0..0000000
--- a/media/java/android/media/videoeditor/TransitionFadeBlack.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-
-/**
- * This class is used to render a fade to black and fade from black transition
- * between two media items.
- * {@hide}
- */
-public class TransitionFadeBlack extends Transition {
-    /**
-     * An object of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private TransitionFadeBlack() {
-        this(null, null, null, 0, 0);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param transitionId The transition id
-     * @param afterMediaItem The transition is applied to the end of this
-     *      media item
-     * @param beforeMediaItem The transition is applied to the beginning of
-     *      this media item
-     * @param durationMs duration of the transition
-     * @param behavior behavior is one of the behavior defined in Transition
-     *      class
-     *
-     * @throws IllegalArgumentException if behavior is not supported.
-     */
-    public TransitionFadeBlack(String transitionId, MediaItem afterMediaItem,
-            MediaItem beforeMediaItem, long durationMs, int behavior) {
-        super(transitionId, afterMediaItem, beforeMediaItem, durationMs, behavior);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    void generate() {
-        super.generate();
-    }
-}
diff --git a/media/java/android/media/videoeditor/TransitionSliding.java b/media/java/android/media/videoeditor/TransitionSliding.java
deleted file mode 100644
index 57610ab..0000000
--- a/media/java/android/media/videoeditor/TransitionSliding.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.videoeditor;
-
-/**
- * This class allows to create sliding transitions
- * {@hide}
- */
-public class TransitionSliding extends Transition {
-
-    /** Video 1 is pushed to the right while video 2 is coming from left */
-    public final static int DIRECTION_RIGHT_OUT_LEFT_IN = 0;
-    /** Video 1 is pushed to the left while video 2 is coming from right */
-    public static final int DIRECTION_LEFT_OUT_RIGHT_IN = 1;
-    /** Video 1 is pushed to the top while video 2 is coming from bottom */
-    public static final int DIRECTION_TOP_OUT_BOTTOM_IN = 2;
-    /** Video 1 is pushed to the bottom while video 2 is coming from top */
-    public static final int DIRECTION_BOTTOM_OUT_TOP_IN = 3;
-
-    // The sliding transitions
-    private final int mSlidingDirection;
-
-    /**
-     * An object of this type cannot be instantiated by using the default
-     * constructor
-     */
-    @SuppressWarnings("unused")
-    private TransitionSliding() {
-        this(null, null, null, 0, 0, 0);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param transitionId The transition id
-     * @param afterMediaItem The transition is applied to the end of this
-     *      media item
-     * @param beforeMediaItem The transition is applied to the beginning of
-     *      this media item
-     * @param durationMs duration of the transition in milliseconds
-     * @param behavior behavior is one of the behavior defined in Transition
-     *            class
-     * @param direction direction shall be one of the supported directions like
-     *            RIGHT_OUT_LEFT_IN
-     *
-     * @throws IllegalArgumentException if behavior is not supported.
-     */
-    public TransitionSliding(String transitionId, MediaItem afterMediaItem,
-            MediaItem beforeMediaItem, long durationMs, int behavior,
-            int direction) {
-        super(transitionId, afterMediaItem, beforeMediaItem, durationMs, behavior);
-        switch (direction) {
-            case DIRECTION_RIGHT_OUT_LEFT_IN:
-            case DIRECTION_LEFT_OUT_RIGHT_IN:
-            case DIRECTION_TOP_OUT_BOTTOM_IN:
-            case DIRECTION_BOTTOM_OUT_TOP_IN:
-                break;
-
-            default:
-                throw new IllegalArgumentException("Invalid direction");
-        }
-        mSlidingDirection = direction;
-    }
-
-    /**
-     * Get the sliding direction.
-     *
-     * @return The sliding direction
-     */
-    public int getDirection() {
-        return mSlidingDirection;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    void generate() {
-        super.generate();
-    }
-}
diff --git a/media/java/android/media/videoeditor/VideoEditor.java b/media/java/android/media/videoeditor/VideoEditor.java
deleted file mode 100644
index 08d27d4..0000000
--- a/media/java/android/media/videoeditor/VideoEditor.java
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.CancellationException;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.view.SurfaceHolder;
-
-/**
- * This is the interface implemented by classes which provide video editing
- * functionality. The VideoEditor implementation class manages all input and
- * output files. Unless specifically mentioned, methods are blocking. A typical
- * editing session may consist of the following sequence of operations:
- *
- * <ul>
- *  <li>Add a set of MediaItems</li>
- *  <li>Apply a set of Transitions between MediaItems</li>
- *  <li>Add Effects and Overlays to media items</li>
- *  <li>Preview the movie at any time</li>
- *  <li>Save the VideoEditor implementation class internal state</li>
- *  <li>Release the VideoEditor implementation class instance by invoking
- * {@link #release()}
- * </ul>
- * The internal VideoEditor state consists of the following elements:
- * <ul>
- *  <li>Ordered & trimmed MediaItems</li>
- *  <li>Transition video clips</li>
- *  <li>Overlays</li>
- *  <li>Effects</li>
- *  <li>Audio waveform for the background audio and MediaItems</li>
- *  <li>Project thumbnail</li>
- *  <li>Last exported movie.</li>
- *  <li>Other project specific data such as the current aspect ratio.</li>
- * </ul>
- * {@hide}
- */
-public interface VideoEditor {
-    /**
-     *  The file name of the project thumbnail
-     */
-    public static final String THUMBNAIL_FILENAME = "thumbnail.jpg";
-
-    /**
-     *  Use this value instead of the specific end of the storyboard timeline
-     *  value.
-     */
-    public final static int DURATION_OF_STORYBOARD = -1;
-
-    /**
-     *  Maximum supported file size
-     */
-    public static final long MAX_SUPPORTED_FILE_SIZE = 2147483648L;
-
-    /**
-     * This listener interface is used by the VideoEditor to emit preview
-     * progress notifications. This callback should be invoked after the number
-     * of frames specified by
-     * {@link #startPreview(SurfaceHolder surfaceHolder, long fromMs,
-     *           int callbackAfterFrameCount, PreviewProgressListener listener)}
-     */
-    public interface PreviewProgressListener {
-        /**
-         * This method notifies the listener of the current time position while
-         * previewing a project.
-         *
-         * @param videoEditor The VideoEditor instance
-         * @param timeMs The current preview position (expressed in milliseconds
-         *        since the beginning of the storyboard timeline).
-         * @param overlayData The overlay data (null if the overlay data
-         *      is unchanged)
-         */
-        public void onProgress(VideoEditor videoEditor, long timeMs,
-                               OverlayData overlayData);
-        /**
-         * This method notifies the listener when the preview is started
-         * previewing a project.
-         *
-         * @param videoEditor The VideoEditor instance
-         */
-        public void onStart(VideoEditor videoEditor);
-
-        /**
-         * This method notifies the listener when the preview is stopped
-         * previewing a project.
-         *
-         * @param videoEditor The VideoEditor instance
-         */
-        public void onStop(VideoEditor videoEditor);
-
-        /**
-         * This method notifies the listener when error has occurred during
-         * previewing a project.
-         *
-         * @param videoEditor The VideoEditor instance
-         * @param error The error that has occurred
-         * FIXME: We should pass well-defined error code to the application;
-         * but for now, we just pass whatever error code reported by the native layer.
-         */
-        public void onError(VideoEditor videoEditor, int error);
-    }
-
-    /**
-     * This listener interface is used by the VideoEditor to emit export status
-     * notifications.
-     * {@link #export(String filename, ExportProgressListener listener,
-     *                int height, int bitrate)}
-     */
-    public interface ExportProgressListener {
-        /**
-         * This method notifies the listener of the progress status of a export
-         * operation.
-         *
-         * @param videoEditor The VideoEditor instance
-         * @param filename The name of the file which is in the process of being
-         *        exported.
-         * @param progress The progress in %. At the beginning of the export,
-         *        this value is set to 0; at the end, the value is set to 100.
-         */
-        public void onProgress(VideoEditor videoEditor, String filename,
-                              int progress);
-    }
-
-    public interface MediaProcessingProgressListener {
-        /**
-         *  Values used for the action parameter
-         */
-        public static final int ACTION_ENCODE = 1;
-        public static final int ACTION_DECODE = 2;
-
-        /**
-         * This method notifies the listener of the progress status of
-         * processing a media object such as a Transition, AudioTrack & Kenburns
-         * This method may be called maximum 100 times for one operation.
-         *
-         * @param object The object that is being processed such as a Transition
-         *               or AudioTrack
-         * @param action The type of processing being performed
-         * @param progress The progress in %. At the beginning of the operation,
-         *          this value is set to 0; at the end, the value is set to 100.
-         */
-        public void onProgress(Object item, int action, int progress);
-    }
-
-    /**
-     * The overlay data
-     */
-    public static final class OverlayData {
-        // Instance variables
-        private Bitmap mOverlayBitmap;
-        private int mRenderingMode;
-        private boolean mClear;
-        private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
-
-        /**
-         * Default constructor
-         */
-        public OverlayData() {
-            mOverlayBitmap = null;
-            mRenderingMode = MediaArtistNativeHelper.MediaRendering.BLACK_BORDERS;
-            mClear = false;
-        }
-
-        /**
-         * Releases the bitmap
-         */
-        public void release() {
-            if (mOverlayBitmap != null) {
-                mOverlayBitmap.recycle();
-                mOverlayBitmap = null;
-            }
-        }
-
-        /**
-         * Check if the overlay needs to be rendered
-         *
-         * @return true if rendering is needed
-         */
-        public boolean needsRendering() {
-            return (mClear || mOverlayBitmap != null);
-        }
-
-        /**
-         * Store the overlay data
-         *
-         * @param overlayBitmap The overlay bitmap
-         * @param renderingMode The rendering mode
-         */
-        void set(Bitmap overlayBitmap, int renderingMode) {
-            mOverlayBitmap = overlayBitmap;
-            mRenderingMode = renderingMode;
-            mClear = false;
-        }
-
-        /**
-         * Clear the overlay
-         */
-        void setClear() {
-            mClear = true;
-        }
-
-        /**
-        * Render the overlay by either clearing it or by
-        * rendering the overlay bitmap with the specified
-        * rendering mode
-        *
-        * @param destBitmap The destination bitmap
-        */
-        public void renderOverlay(Bitmap destBitmap) {
-            if (mClear) {
-                destBitmap.eraseColor(Color.TRANSPARENT);
-            } else if (mOverlayBitmap != null) {
-                final Canvas overlayCanvas = new Canvas(destBitmap);
-                final Rect destRect;
-                final Rect srcRect;
-                switch (mRenderingMode) {
-                    case MediaArtistNativeHelper.MediaRendering.RESIZING: {
-                        destRect = new Rect(0, 0, overlayCanvas.getWidth(),
-                                                 overlayCanvas.getHeight());
-                        srcRect = new Rect(0, 0, mOverlayBitmap.getWidth(),
-                                                 mOverlayBitmap.getHeight());
-                        break;
-                    }
-
-                    case MediaArtistNativeHelper.MediaRendering.BLACK_BORDERS: {
-                        int left, right, top, bottom;
-                        float aROverlayImage, aRCanvas;
-                        aROverlayImage = (float)(mOverlayBitmap.getWidth()) /
-                                         (float)(mOverlayBitmap.getHeight());
-
-                        aRCanvas = (float)(overlayCanvas.getWidth()) /
-                                         (float)(overlayCanvas.getHeight());
-
-                        if (aROverlayImage > aRCanvas) {
-                            int newHeight = ((overlayCanvas.getWidth() * mOverlayBitmap.getHeight())
-                                             / mOverlayBitmap.getWidth());
-                            left = 0;
-                            top  = (overlayCanvas.getHeight() - newHeight) / 2;
-                            right = overlayCanvas.getWidth();
-                            bottom = top + newHeight;
-                        } else {
-                            int newWidth = ((overlayCanvas.getHeight() * mOverlayBitmap.getWidth())
-                                                / mOverlayBitmap.getHeight());
-                            left = (overlayCanvas.getWidth() - newWidth) / 2;
-                            top  = 0;
-                            right = left + newWidth;
-                            bottom = overlayCanvas.getHeight();
-                        }
-
-                        destRect = new Rect(left, top, right, bottom);
-                        srcRect = new Rect(0, 0, mOverlayBitmap.getWidth(), mOverlayBitmap.getHeight());
-                        break;
-                    }
-
-                    case MediaArtistNativeHelper.MediaRendering.CROPPING: {
-                        // Calculate the source rect
-                        int left, right, top, bottom;
-                        float aROverlayImage, aRCanvas;
-                        aROverlayImage = (float)(mOverlayBitmap.getWidth()) /
-                                         (float)(mOverlayBitmap.getHeight());
-                        aRCanvas = (float)(overlayCanvas.getWidth()) /
-                                        (float)(overlayCanvas.getHeight());
-                        if (aROverlayImage < aRCanvas) {
-                            int newHeight = ((mOverlayBitmap.getWidth() * overlayCanvas.getHeight())
-                                       / overlayCanvas.getWidth());
-
-                            left = 0;
-                            top  = (mOverlayBitmap.getHeight() - newHeight) / 2;
-                            right = mOverlayBitmap.getWidth();
-                            bottom = top + newHeight;
-                        } else {
-                            int newWidth = ((mOverlayBitmap.getHeight() * overlayCanvas.getWidth())
-                                        / overlayCanvas.getHeight());
-                            left = (mOverlayBitmap.getWidth() - newWidth) / 2;
-                            top  = 0;
-                            right = left + newWidth;
-                            bottom = mOverlayBitmap.getHeight();
-                        }
-
-                        srcRect = new Rect(left, top, right, bottom);
-                        destRect = new Rect(0, 0, overlayCanvas.getWidth(), overlayCanvas.getHeight());
-                        break;
-                    }
-
-                    default: {
-                        throw new IllegalStateException("Rendering mode: " + mRenderingMode);
-                    }
-                }
-
-                destBitmap.eraseColor(Color.TRANSPARENT);
-                overlayCanvas.drawBitmap(mOverlayBitmap, srcRect, destRect, sResizePaint);
-
-                mOverlayBitmap.recycle();
-            }
-        }
-    }
-
-    /**
-     * @return The path where the VideoEditor stores all files related to the
-     *         project
-     */
-    public String getPath();
-
-    /**
-     * This method releases all in-memory resources used by the VideoEditor
-     * instance. All pending operations such as preview, export and extract
-     * audio waveform must be canceled.
-     */
-    public void release();
-
-    /**
-     * Persist the current internal state of VideoEditor to the project path.
-     * The VideoEditor state may be restored by invoking the
-     * {@link VideoEditorFactory#load(String)} method. This method does not
-     * release the internal in-memory state of the VideoEditor. To release
-     * the in-memory state of the VideoEditor the {@link #release()} method
-     * must be invoked.
-     *
-     * Pending transition generations must be allowed to complete before the
-     * state is saved.
-     * Pending audio waveform generations must be allowed to complete.
-     * Pending export operations must be allowed to continue.
-     *
-     * @throws IOException if the internal state cannot be saved to project file
-     */
-    public void save() throws IOException;
-
-    /**
-     * Create the output movie based on all media items added and the applied
-     * storyboard items. This method can take a long time to execute and is
-     * blocking. The application will receive progress notifications via the
-     * ExportProgressListener. Specific implementations may not support multiple
-     * simultaneous export operations. Note that invoking methods which would
-     * change the contents of the output movie throw an IllegalStateException
-     * while an export operation is pending.
-     *
-     * The audio and video codecs are automatically selected by the underlying
-     * implementation.
-     *
-     * @param filename The output file name (including the full path)
-     * @param height The height of the output video file. The supported values
-     *        for height are described in the MediaProperties class, for
-     *        example: HEIGHT_480. The width will be automatically computed
-     *        according to the aspect ratio provided by
-     *        {@link #setAspectRatio(int)}
-     * @param bitrate The bitrate of the output video file. This is approximate
-     *        value for the output movie. Supported bitrate values are
-     *        described in the MediaProperties class for example: BITRATE_384K
-     * @param listener The listener for progress notifications. Use null if
-     *        export progress notifications are not needed.
-     *
-     * @throws IllegalArgumentException if height or bitrate are not supported
-     *        or if the audio or video codecs are not supported
-     * @throws IOException if output file cannot be created
-     * @throws IllegalStateException if a preview or an export is in progress or
-     *        if no MediaItem has been added
-     * @throws CancellationException if export is canceled by calling
-     *        {@link #cancelExport()}
-     * @throws UnsupportOperationException if multiple simultaneous export() are
-     *        not allowed
-     */
-    public void export(String filename, int height, int bitrate,
-                       ExportProgressListener listener)
-                       throws IOException;
-
-    /**
-     * Create the output movie based on all media items added and the applied
-     * storyboard items. This method can take a long time to execute and is
-     * blocking. The application will receive progress notifications via the
-     * ExportProgressListener. Specific implementations may not support multiple
-     * simultaneous export operations. Note that invoking methods which would
-     * change the contents of the output movie throw an IllegalStateException
-     * while an export operation is pending.
-     *
-     * @param filename The output file name (including the full path)
-     * @param height The height of the output video file. The supported values
-     *        for height are described in the MediaProperties class, for
-     *        example: HEIGHT_480. The width will be automatically computed
-     *        according to the aspect ratio provided by
-     *        {@link #setAspectRatio(int)}
-     * @param bitrate The bitrate of the output video file. This is approximate
-     *        value for the output movie. Supported bitrate values are
-     *        described in the MediaProperties class for example: BITRATE_384K
-     * @param audioCodec The audio codec to be used for the export. The audio
-     *        codec values are defined in the MediaProperties class (e.g.
-     *        ACODEC_AAC_LC). Note that not all audio codec types are
-     *        supported for export purposes.
-     * @param videoCodec The video codec to be used for the export. The video
-     *        codec values are defined in the MediaProperties class (e.g.
-     *        VCODEC_H264). Note that not all video codec types are
-     *        supported for export purposes.
-     * @param listener The listener for progress notifications. Use null if
-     *        export progress notifications are not needed.
-     *
-     * @throws IllegalArgumentException if height or bitrate are not supported
-     *        or if the audio or video codecs are not supported
-     * @throws IOException if output file cannot be created
-     * @throws IllegalStateException if a preview or an export is in progress or
-     *        if no MediaItem has been added
-     * @throws CancellationException if export is cancelled by calling
-     *        {@link #cancelExport()}
-     * @throws UnsupportOperationException if multiple simultaneous export() are
-     *        not allowed
-     */
-    public void export(String filename, int height, int bitrate, int audioCodec,
-                       int videoCodec, ExportProgressListener listener)
-                       throws IOException;
-
-    /**
-     * Cancel the running export operation. This method blocks until the export
-     * is cancelled and the exported file (if any) is deleted. If the export
-     * completed by the time this method is invoked, the export file will be
-     * deleted.
-     *
-     * @param filename The filename which identifies the export operation to be
-     *            canceled.
-     **/
-    public void cancelExport(String filename);
-
-    /**
-     * Add a media item at the end of the storyboard.
-     *
-     * @param mediaItem The media item object to add
-     *
-     * @throws IllegalStateException if a preview or an export is in progress or
-     *        if the media item id is not unique across all the media items
-     *        added.
-     */
-    public void addMediaItem(MediaItem mediaItem);
-
-    /**
-     * Insert a media item after the media item with the specified id.
-     *
-     * @param mediaItem The media item object to insert
-     * @param afterMediaItemId Insert the mediaItem after the media item
-     *        identified by this id. If this parameter is null, the media
-     *        item is inserted at the beginning of the timeline.
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if media item with the specified id does
-     *        not exist (null is a valid value) or if the media item id is
-     *        not unique across all the media items added.
-     */
-    public void insertMediaItem(MediaItem mediaItem, String afterMediaItemId);
-
-    /**
-     * Move a media item after the media item with the specified id.
-     *
-     * Note: The project thumbnail is regenerated if the media item is or
-     * becomes the first media item in the storyboard timeline.
-     *
-     * @param mediaItemId The id of the media item to move
-     * @param afterMediaItemId Move the media item identified by mediaItemId
-     *        after the media item identified by this parameter. If this
-     *        parameter is null, the media item is moved at the beginning of
-     *        the timeline.
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if one of media item ids is invalid
-     *        (null is a valid value)
-     */
-    public void moveMediaItem(String mediaItemId, String afterMediaItemId);
-
-    /**
-     * Remove the media item with the specified id. If there are transitions
-     * before or after this media item, then this/these transition(s) are
-     * removed from the storyboard. If the extraction of the audio waveform is
-     * in progress, the extraction is canceled and the file is deleted.
-     *
-     * Effects and overlays associated with the media item will also be removed.
-     *
-     * Note: The project thumbnail is regenerated if the media item which is
-     * removed is the first media item in the storyboard or if the media item is
-     * the only one in the storyboard. If the media item is the only one in the
-     * storyboard, the project thumbnail will be set to a black frame and the
-     * aspect ratio will revert to the default aspect ratio and this method is
-     * equivalent to removeAllMediaItems() in this case.
-     *
-     * @param mediaItemId The unique id of the media item to be removed
-     *
-     * @return The media item that was removed
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if media item with the specified id does
-     *        not exist
-     */
-    public MediaItem removeMediaItem(String mediaItemId);
-
-    /**
-     * Remove all media items in the storyboard. All effects, overlays and all
-     * transitions are also removed.
-     *
-     * Note: The project thumbnail will be set to a black frame and the aspect
-     * ratio will revert to the default aspect ratio.
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     */
-    public void removeAllMediaItems();
-
-    /**
-     * Get the list of media items in the order in which it they appear in the
-     * storyboard timeline.
-     *
-     * Note that if any media item source files are no longer
-     * accessible, this method will still provide the full list of media items.
-     *
-     * @return The list of media items. If no media item exist an empty list
-     *        will be returned.
-     */
-    public List<MediaItem> getAllMediaItems();
-
-    /**
-     * Find the media item with the specified id
-     *
-     * @param mediaItemId The media item id
-     *
-     * @return The media item with the specified id (null if it does not exist)
-     */
-    public MediaItem getMediaItem(String mediaItemId);
-
-    /**
-     * Add a transition between the media items specified by the transition.
-     * If a transition existed at the same position it is invalidated and then
-     * the transition is replaced. Note that the new transition video clip is
-     * not automatically generated by this method. The
-     * {@link Transition#generate()} method must be invoked to generate
-     * the transition video clip.
-     *
-     * Note that the TransitionAtEnd and TransitionAtStart are special kinds
-     * that can not be applied between two media items.
-     *
-     * A crossfade audio transition will be automatically applied regardless of
-     * the video transition.
-     *
-     * @param transition The transition to apply
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if the transition duration is larger
-     *        than the smallest duration of the two media item files or if
-     *        the two media items specified in the transition are not
-     *        adjacent
-     */
-    public void addTransition(Transition transition);
-
-    /**
-     * Remove the transition with the specified id.
-     *
-     * @param transitionId The id of the transition to be removed
-     *
-     * @return The transition that was removed
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if transition with the specified id does
-     *        not exist
-     */
-    public Transition removeTransition(String transitionId);
-
-    /**
-     * Get the list of transitions
-     *
-     * @return The list of transitions. If no transitions exist an empty list
-     *        will be returned.
-     */
-    public List<Transition> getAllTransitions();
-
-    /**
-     * Find the transition with the specified transition id.
-     *
-     * @param transitionId The transition id
-     *
-     * @return The transition
-     */
-    public Transition getTransition(String transitionId);
-
-    /**
-     * Add the specified AudioTrack to the storyboard. Note: Specific
-     * implementations may support a limited number of audio tracks (e.g. only
-     * one audio track)
-     *
-     * @param audioTrack The AudioTrack to add
-     *
-     * @throws UnsupportedOperationException if the implementation supports a
-     *        limited number of audio tracks.
-     * @throws IllegalArgumentException if media item is not unique across all
-     *        the audio tracks already added.
-     */
-    public void addAudioTrack(AudioTrack audioTrack);
-
-    /**
-     * Insert an audio track after the audio track with the specified id. Use
-     * addAudioTrack to add an audio track at the end of the storyboard
-     * timeline.
-     *
-     * @param audioTrack The audio track object to insert
-     * @param afterAudioTrackId Insert the audio track after the audio track
-     *        identified by this parameter. If this parameter is null the
-     *        audio track is added at the beginning of the timeline.
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if media item with the specified id does
-     *        not exist (null is a valid value). if media item is not unique
-     *        across all the audio tracks already added.
-     * @throws UnsupportedOperationException if the implementation supports a
-     *        limited number of audio tracks
-     */
-    public void insertAudioTrack(AudioTrack audioTrack, String afterAudioTrackId);
-
-    /**
-     * Move an AudioTrack after the AudioTrack with the specified id.
-     *
-     * @param audioTrackId The id of the AudioTrack to move
-     * @param afterAudioTrackId Move the AudioTrack identified by audioTrackId
-     *        after the AudioTrack identified by this parameter. If this
-     *        parameter is null the audio track is added at the beginning of
-     *        the timeline.
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if one of media item ids is invalid
-     *        (null is a valid value)
-     */
-    public void moveAudioTrack(String audioTrackId, String afterAudioTrackId);
-
-    /**
-     * Remove the audio track with the specified id. If the extraction of the
-     * audio waveform is in progress, the extraction is canceled and the file is
-     * deleted.
-     *
-     * @param audioTrackId The id of the audio track to be removed
-     *
-     * @return The audio track that was removed
-     * @throws IllegalStateException if a preview or an export is in progress
-     */
-    public AudioTrack removeAudioTrack(String audioTrackId);
-
-    /**
-     * Get the list of AudioTracks in order in which they appear in the
-     * storyboard.
-     *
-     * Note that if any AudioTrack source files are not accessible anymore,
-     * this method will still provide the full list of audio tracks.
-     *
-     * @return The list of AudioTracks. If no audio tracks exist an empty list
-     *        will be returned.
-     */
-    public List<AudioTrack> getAllAudioTracks();
-
-    /**
-     * Find the AudioTrack with the specified id
-     *
-     * @param audioTrackId The AudioTrack id
-     *
-     * @return The AudioTrack with the specified id (null if it does not exist)
-     */
-    public AudioTrack getAudioTrack(String audioTrackId);
-
-    /**
-     * Set the aspect ratio used in the preview and the export movie.
-     *
-     * The default aspect ratio is ASPECTRATIO_16_9 (16:9).
-     *
-     * @param aspectRatio to apply. If aspectRatio is the same as the current
-     *        aspect ratio, then this function just returns. The supported
-     *        aspect ratio are defined in the MediaProperties class for
-     *        example: ASPECTRATIO_16_9
-     *
-     * @throws IllegalStateException if a preview or an export is in progress
-     * @throws IllegalArgumentException if aspect ratio is not supported
-     */
-    public void setAspectRatio(int aspectRatio);
-
-    /**
-     * Get current aspect ratio.
-     *
-     * @return The aspect ratio as described in MediaProperties
-     */
-    public int getAspectRatio();
-
-    /**
-     * Get the preview (and output movie) duration.
-     *
-     * @return The duration of the preview (and output movie)
-     */
-    public long getDuration();
-
-    /**
-     * Render a frame according to the preview aspect ratio and activating all
-     * storyboard items relative to the specified time.
-     *
-     * @param surfaceHolder SurfaceHolder used by the application
-     * @param timeMs time corresponding to the frame to display
-     * @param overlayData The overlay data
-     *
-     * @return The accurate time stamp of the frame that is rendered.
-     *
-     * @throws IllegalStateException if a preview or an export is already in
-     *        progress
-     * @throws IllegalArgumentException if time is negative or beyond the
-     *        preview duration
-     */
-    public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs,
-            OverlayData overlayData);
-
-    /**
-     * This method must be called after any changes made to the storyboard
-     * and before startPreview is called. Note that this method may block for an
-     * extensive period of time.
-     */
-    public void generatePreview(MediaProcessingProgressListener listener);
-
-    /**
-     * Start the preview of all the storyboard items applied on all MediaItems
-     * This method does not block (does not wait for the preview to complete).
-     * The PreviewProgressListener allows to track the progress at the time
-     * interval determined by the callbackAfterFrameCount parameter. The
-     * SurfaceHolder has to be created and ready for use before calling this
-     * method. The method is a no-op if there are no MediaItems in the
-     * storyboard.
-     *
-     * @param surfaceHolder SurfaceHolder where the preview is rendered.
-     * @param fromMs The time (relative to the timeline) at which the preview
-     *        will start
-     * @param toMs The time (relative to the timeline) at which the preview will
-     *        stop. Use -1 to play to the end of the timeline
-     * @param loop true if the preview should be looped once it reaches the end
-     * @param callbackAfterFrameCount The listener interface should be invoked
-     *        after the number of frames specified by this parameter.
-     * @param listener The listener which will be notified of the preview
-     *        progress
-     *
-     * @throws IllegalArgumentException if fromMs is beyond the preview duration
-     * @throws IllegalStateException if a preview or an export is already in
-     *        progress
-     */
-    public void startPreview(SurfaceHolder surfaceHolder, long fromMs, long toMs,
-                             boolean loop,int callbackAfterFrameCount,
-                             PreviewProgressListener listener);
-
-    /**
-     * Stop the current preview. This method blocks until ongoing preview is
-     * stopped. Ignored if there is no preview running.
-     *
-     * @return The accurate current time when stop is effective expressed in
-     *        milliseconds
-     */
-    public long stopPreview();
-
-    /**
-     * Clears the preview surface
-     *
-     * @param surfaceHolder SurfaceHolder where the preview is rendered
-     * and needs to be cleared.
-     */
-    public void clearSurface(SurfaceHolder surfaceHolder);
-}
diff --git a/media/java/android/media/videoeditor/VideoEditorFactory.java b/media/java/android/media/videoeditor/VideoEditorFactory.java
deleted file mode 100644
index 85c329f..0000000
--- a/media/java/android/media/videoeditor/VideoEditorFactory.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
-
-/**
- * The VideoEditorFactory class must be used to instantiate VideoEditor objects
- * by creating a new project {@link #create(String)} or by loading an
- * existing project {@link #load(String)}.
- * {@hide}
- */
-public class VideoEditorFactory {
-    /**
-     * This is the factory method for creating a new VideoEditor instance.
-     *
-     * @param projectPath The path where all VideoEditor internal
-     *            files are stored. When a project is deleted the application is
-     *            responsible for deleting the path and its contents.
-     *
-     * @return The VideoEditor instance
-     *
-     * @throws IOException if path does not exist or if the path can
-     *             not be accessed in read/write mode
-     */
-    public static VideoEditor create(String projectPath) throws IOException {
-        /*
-         *  If the project path does not exist create it
-         */
-        final File dir = new File(projectPath);
-        if (!dir.exists()) {
-            if (!dir.mkdirs()) {
-                throw new FileNotFoundException("Cannot create project path: "
-                                                                 + projectPath);
-            } else {
-                /*
-                 * Create the file which hides the media files
-                 * from the media scanner
-                 */
-                if (!new File(dir, ".nomedia").createNewFile()) {
-                    throw new FileNotFoundException("Cannot create file .nomedia");
-                }
-            }
-        }
-
-        return new VideoEditorImpl(projectPath);
-    }
-
-    /**
-     * This is the factory method for instantiating a VideoEditor from the
-     * internal state previously saved with the
-     * {@link VideoEditor#save(String)} method.
-     *
-     * @param projectPath The path where all VideoEditor internal files
-     *            are stored. When a project is deleted the application is
-     *            responsible for deleting the path and its contents.
-     * @param generatePreview if set to true the
-     *      {@link MediaEditor#generatePreview(MediaProcessingProgressListener
-     *             listener)}
-     *      will be called internally to generate any needed transitions.
-     *
-     * @return The VideoEditor instance
-     *
-     * @throws IOException if path does not exist or if the path can
-     *             not be accessed in read/write mode or if one of the resource
-     *             media files cannot be retrieved
-     */
-    public static VideoEditor load(String projectPath, boolean generatePreview)
-        throws IOException {
-        final VideoEditor videoEditor = new VideoEditorImpl(projectPath);
-        if (generatePreview) {
-            videoEditor.generatePreview(null);
-        }
-        return videoEditor;
-    }
-}
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
deleted file mode 100644
index fbf2eab..0000000
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ /dev/null
@@ -1,1978 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.MediaMetadataRetriever;
-import android.util.Log;
-import android.util.Xml;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.os.Debug;
-import android.os.SystemProperties;
-import android.os.Environment;
-
-import libcore.io.IoUtils;
-
-/**
- * The VideoEditor implementation {@hide}
- */
-public class VideoEditorImpl implements VideoEditor {
-    /*
-     *  Logging
-     */
-    private static final String TAG = "VideoEditorImpl";
-
-    /*
-     *  The project filename
-     */
-    private static final String PROJECT_FILENAME = "videoeditor.xml";
-
-    /*
-     *  XML tags
-     */
-    private static final String TAG_PROJECT = "project";
-    private static final String TAG_MEDIA_ITEMS = "media_items";
-    private static final String TAG_MEDIA_ITEM = "media_item";
-    private static final String TAG_TRANSITIONS = "transitions";
-    private static final String TAG_TRANSITION = "transition";
-    private static final String TAG_OVERLAYS = "overlays";
-    private static final String TAG_OVERLAY = "overlay";
-    private static final String TAG_OVERLAY_USER_ATTRIBUTES = "overlay_user_attributes";
-    private static final String TAG_EFFECTS = "effects";
-    private static final String TAG_EFFECT = "effect";
-    private static final String TAG_AUDIO_TRACKS = "audio_tracks";
-    private static final String TAG_AUDIO_TRACK = "audio_track";
-
-    private static final String ATTR_ID = "id";
-    private static final String ATTR_FILENAME = "filename";
-    private static final String ATTR_AUDIO_WAVEFORM_FILENAME = "waveform";
-    private static final String ATTR_RENDERING_MODE = "rendering_mode";
-    private static final String ATTR_ASPECT_RATIO = "aspect_ratio";
-    private static final String ATTR_REGENERATE_PCM = "regeneratePCMFlag";
-    private static final String ATTR_TYPE = "type";
-    private static final String ATTR_DURATION = "duration";
-    private static final String ATTR_START_TIME = "start_time";
-    private static final String ATTR_BEGIN_TIME = "begin_time";
-    private static final String ATTR_END_TIME = "end_time";
-    private static final String ATTR_VOLUME = "volume";
-    private static final String ATTR_BEHAVIOR = "behavior";
-    private static final String ATTR_DIRECTION = "direction";
-    private static final String ATTR_BLENDING = "blending";
-    private static final String ATTR_INVERT = "invert";
-    private static final String ATTR_MASK = "mask";
-    private static final String ATTR_BEFORE_MEDIA_ITEM_ID = "before_media_item";
-    private static final String ATTR_AFTER_MEDIA_ITEM_ID = "after_media_item";
-    private static final String ATTR_COLOR_EFFECT_TYPE = "color_type";
-    private static final String ATTR_COLOR_EFFECT_VALUE = "color_value";
-    private static final String ATTR_START_RECT_LEFT = "start_l";
-    private static final String ATTR_START_RECT_TOP = "start_t";
-    private static final String ATTR_START_RECT_RIGHT = "start_r";
-    private static final String ATTR_START_RECT_BOTTOM = "start_b";
-    private static final String ATTR_END_RECT_LEFT = "end_l";
-    private static final String ATTR_END_RECT_TOP = "end_t";
-    private static final String ATTR_END_RECT_RIGHT = "end_r";
-    private static final String ATTR_END_RECT_BOTTOM = "end_b";
-    private static final String ATTR_LOOP = "loop";
-    private static final String ATTR_MUTED = "muted";
-    private static final String ATTR_DUCK_ENABLED = "ducking_enabled";
-    private static final String ATTR_DUCK_THRESHOLD = "ducking_threshold";
-    private static final String ATTR_DUCKED_TRACK_VOLUME = "ducking_volume";
-    private static final String ATTR_GENERATED_IMAGE_CLIP = "generated_image_clip";
-    private static final String ATTR_IS_IMAGE_CLIP_GENERATED = "is_image_clip_generated";
-    private static final String ATTR_GENERATED_TRANSITION_CLIP = "generated_transition_clip";
-    private static final String ATTR_IS_TRANSITION_GENERATED = "is_transition_generated";
-    private static final String ATTR_OVERLAY_RGB_FILENAME = "overlay_rgb_filename";
-    private static final String ATTR_OVERLAY_FRAME_WIDTH = "overlay_frame_width";
-    private static final String ATTR_OVERLAY_FRAME_HEIGHT = "overlay_frame_height";
-    private static final String ATTR_OVERLAY_RESIZED_RGB_FRAME_WIDTH = "resized_RGBframe_width";
-    private static final String ATTR_OVERLAY_RESIZED_RGB_FRAME_HEIGHT = "resized_RGBframe_height";
-    private static final int ENGINE_ACCESS_MAX_TIMEOUT_MS = 500;
-    /*
-     *  Instance variables
-     */
-    private final Semaphore mLock;
-    private final String mProjectPath;
-    private final List<MediaItem> mMediaItems = new ArrayList<MediaItem>();
-    private final List<AudioTrack> mAudioTracks = new ArrayList<AudioTrack>();
-    private final List<Transition> mTransitions = new ArrayList<Transition>();
-    private long mDurationMs;
-    private int mAspectRatio;
-
-    /*
-     * Private Object for calling native Methods via MediaArtistNativeHelper
-     */
-    private MediaArtistNativeHelper mMANativeHelper;
-    private boolean mPreviewInProgress = false;
-    private final boolean mMallocDebug;
-
-    /**
-     * Constructor
-     *
-     * @param projectPath - The path where the VideoEditor stores all files
-     *        related to the project
-     */
-    public VideoEditorImpl(String projectPath) throws IOException {
-        String s;
-        s = SystemProperties.get("libc.debug.malloc");
-        if (s.equals("1")) {
-            mMallocDebug = true;
-            try {
-                dumpHeap("HeapAtStart");
-            } catch (Exception ex) {
-                Log.e(TAG, "dumpHeap returned error in constructor");
-            }
-        } else {
-            mMallocDebug = false;
-        }
-        mLock = new Semaphore(1, true);
-        mMANativeHelper = new MediaArtistNativeHelper(projectPath, mLock, this);
-        mProjectPath = projectPath;
-        final File projectXml = new File(projectPath, PROJECT_FILENAME);
-        if (projectXml.exists()) {
-            try {
-                load();
-            } catch (Exception ex) {
-                ex.printStackTrace();
-                throw new IOException(ex.toString());
-            }
-        } else {
-            mAspectRatio = MediaProperties.ASPECT_RATIO_16_9;
-            mDurationMs = 0;
-        }
-    }
-
-    /*
-     * @return The MediaArtistNativeHelper object
-     */
-    MediaArtistNativeHelper getNativeContext() {
-        return mMANativeHelper;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized void addAudioTrack(AudioTrack audioTrack) {
-        if (audioTrack == null) {
-            throw new IllegalArgumentException("Audio Track is null");
-        }
-
-        if (mAudioTracks.size() == 1) {
-            throw new IllegalArgumentException("No more tracks can be added");
-        }
-
-        mMANativeHelper.setGeneratePreview(true);
-
-        /*
-         * Add the audio track to AudioTrack list
-         */
-        mAudioTracks.add(audioTrack);
-
-        /*
-         * Form the audio PCM file path
-         */
-        final String audioTrackPCMFilePath = String.format(mProjectPath + "/"
-                    + "AudioPcm" + audioTrack.getId() + ".pcm");
-
-        /*
-         * Create PCM only if not generated in previous session
-         */
-        if (new File(audioTrackPCMFilePath).exists()) {
-            mMANativeHelper.setAudioflag(false);
-        }
-
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized void addMediaItem(MediaItem mediaItem) {
-        /*
-         * Validate Media Item
-         */
-        if (mediaItem == null) {
-            throw new IllegalArgumentException("Media item is null");
-        }
-        /*
-         * Add the Media item to MediaItem list
-         */
-        if (mMediaItems.contains(mediaItem)) {
-            throw new IllegalArgumentException("Media item already exists: " + mediaItem.getId());
-        }
-
-        mMANativeHelper.setGeneratePreview(true);
-
-        /*
-         *  Invalidate the end transition if necessary
-         */
-        final int mediaItemsCount = mMediaItems.size();
-        if (mediaItemsCount > 0) {
-            removeTransitionAfter(mediaItemsCount - 1);
-        }
-
-        /*
-         *  Add the new media item
-         */
-        mMediaItems.add(mediaItem);
-
-        computeTimelineDuration();
-
-        /*
-         *  Generate project thumbnail only from first media Item on storyboard
-         */
-        if (mMediaItems.size() == 1) {
-            generateProjectThumbnail();
-        }
-    }
-
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized void addTransition(Transition transition) {
-        if (transition == null) {
-            throw new IllegalArgumentException("Null Transition");
-        }
-
-        final MediaItem beforeMediaItem = transition.getBeforeMediaItem();
-        final MediaItem afterMediaItem = transition.getAfterMediaItem();
-        /*
-         * Check if the MediaItems are in sequence
-         */
-        if (mMediaItems == null) {
-            throw new IllegalArgumentException("No media items are added");
-        }
-
-        if ((afterMediaItem != null) &&  (beforeMediaItem != null)) {
-            final int afterMediaItemIndex = mMediaItems.indexOf(afterMediaItem);
-            final int beforeMediaItemIndex = mMediaItems.indexOf(beforeMediaItem);
-
-            if ((afterMediaItemIndex == -1) || (beforeMediaItemIndex == -1)) {
-                throw new IllegalArgumentException
-                    ("Either of the mediaItem is not found in the list");
-            }
-
-            if (afterMediaItemIndex != (beforeMediaItemIndex - 1) ) {
-                throw new IllegalArgumentException("MediaItems are not in sequence");
-            }
-        }
-
-        mMANativeHelper.setGeneratePreview(true);
-
-        mTransitions.add(transition);
-        /*
-         *  Cross reference the transitions
-         */
-        if (afterMediaItem != null) {
-            /*
-             *  If a transition already exists at the specified position then
-             *  invalidate it.
-             */
-            if (afterMediaItem.getEndTransition() != null) {
-                afterMediaItem.getEndTransition().invalidate();
-                mTransitions.remove(afterMediaItem.getEndTransition());
-            }
-            afterMediaItem.setEndTransition(transition);
-        }
-
-        if (beforeMediaItem != null) {
-            /*
-             *  If a transition already exists at the specified position then
-             *  invalidate it.
-             */
-            if (beforeMediaItem.getBeginTransition() != null) {
-                beforeMediaItem.getBeginTransition().invalidate();
-                mTransitions.remove(beforeMediaItem.getBeginTransition());
-            }
-            beforeMediaItem.setBeginTransition(transition);
-        }
-
-        computeTimelineDuration();
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public void cancelExport(String filename) {
-        if (mMANativeHelper != null && filename != null) {
-            mMANativeHelper.stop(filename);
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public void export(String filename, int height, int bitrate,
-                       int audioCodec, int videoCodec,
-                       ExportProgressListener listener)
-                       throws IOException {
-        int audcodec = 0;
-        int vidcodec = 0;
-        if (filename == null) {
-            throw new IllegalArgumentException("export: filename is null");
-        }
-
-        final File tempPathFile = new File(filename);
-        if (tempPathFile == null) {
-            throw new IOException(filename + "can not be created");
-        }
-
-        if (mMediaItems.size() == 0) {
-            throw new IllegalStateException("No MediaItems added");
-        }
-
-        switch (height) {
-            case MediaProperties.HEIGHT_144:
-                break;
-            case MediaProperties.HEIGHT_288:
-                break;
-            case MediaProperties.HEIGHT_360:
-                break;
-            case MediaProperties.HEIGHT_480:
-                break;
-            case MediaProperties.HEIGHT_720:
-                break;
-            case MediaProperties.HEIGHT_1080:
-                break;
-
-            default: {
-                String message = "Unsupported height value " + height;
-                throw new IllegalArgumentException(message);
-            }
-        }
-
-        switch (bitrate) {
-            case MediaProperties.BITRATE_28K:
-                break;
-            case MediaProperties.BITRATE_40K:
-                break;
-            case MediaProperties.BITRATE_64K:
-                break;
-            case MediaProperties.BITRATE_96K:
-                break;
-            case MediaProperties.BITRATE_128K:
-                break;
-            case MediaProperties.BITRATE_192K:
-                break;
-            case MediaProperties.BITRATE_256K:
-                break;
-            case MediaProperties.BITRATE_384K:
-                break;
-            case MediaProperties.BITRATE_512K:
-                break;
-            case MediaProperties.BITRATE_800K:
-                break;
-            case MediaProperties.BITRATE_2M:
-                break;
-            case MediaProperties.BITRATE_5M:
-                break;
-            case MediaProperties.BITRATE_8M:
-                break;
-
-            default: {
-                final String message = "Unsupported bitrate value " + bitrate;
-                throw new IllegalArgumentException(message);
-            }
-        }
-        computeTimelineDuration();
-        final long audioBitrate = MediaArtistNativeHelper.Bitrate.BR_96_KBPS;
-        final long fileSize = (mDurationMs * (bitrate + audioBitrate)) / 8000;
-        if (MAX_SUPPORTED_FILE_SIZE <= fileSize) {
-            throw new IllegalStateException("Export Size is more than 2GB");
-        }
-        switch (audioCodec) {
-            case MediaProperties.ACODEC_AAC_LC:
-                audcodec = MediaArtistNativeHelper.AudioFormat.AAC;
-                break;
-            case MediaProperties.ACODEC_AMRNB:
-                audcodec = MediaArtistNativeHelper.AudioFormat.AMR_NB;
-                break;
-
-            default: {
-                String message = "Unsupported audio codec type " + audioCodec;
-                throw new IllegalArgumentException(message);
-            }
-        }
-
-        switch (videoCodec) {
-            case MediaProperties.VCODEC_H263:
-                vidcodec = MediaArtistNativeHelper.VideoFormat.H263;
-                break;
-            case MediaProperties.VCODEC_H264:
-                vidcodec = MediaArtistNativeHelper.VideoFormat.H264;
-                break;
-            case MediaProperties.VCODEC_MPEG4:
-                vidcodec = MediaArtistNativeHelper.VideoFormat.MPEG4;
-                break;
-
-            default: {
-                String message = "Unsupported video codec type " + videoCodec;
-                throw new IllegalArgumentException(message);
-            }
-        }
-
-        boolean semAcquireDone = false;
-        try {
-            lock();
-            semAcquireDone = true;
-
-            if (mMANativeHelper == null) {
-                throw new IllegalStateException("The video editor is not initialized");
-            }
-            mMANativeHelper.setAudioCodec(audcodec);
-            mMANativeHelper.setVideoCodec(vidcodec);
-            mMANativeHelper.export(filename, mProjectPath, height,bitrate,
-                               mMediaItems, mTransitions, mAudioTracks, listener);
-        } catch (InterruptedException  ex) {
-            Log.e(TAG, "Sem acquire NOT successful in export");
-        } finally {
-            if (semAcquireDone) {
-                unlock();
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public void export(String filename, int height, int bitrate,
-                       ExportProgressListener listener)
-                       throws IOException {
-        int defaultAudiocodec = MediaArtistNativeHelper.AudioFormat.AAC;
-        int defaultVideocodec = MediaArtistNativeHelper.VideoFormat.H264;
-
-        export(filename, height, bitrate, defaultAudiocodec,
-                defaultVideocodec, listener);
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public void generatePreview(MediaProcessingProgressListener listener) {
-        boolean semAcquireDone = false;
-        try {
-            lock();
-            semAcquireDone = true;
-
-            if (mMANativeHelper == null) {
-                throw new IllegalStateException("The video editor is not initialized");
-            }
-
-            if ((mMediaItems.size() > 0) || (mAudioTracks.size() > 0)) {
-                mMANativeHelper.previewStoryBoard(mMediaItems, mTransitions, mAudioTracks,
-                        listener);
-            }
-        } catch (InterruptedException  ex) {
-            Log.e(TAG, "Sem acquire NOT successful in previewStoryBoard");
-        } finally {
-            if (semAcquireDone) {
-                unlock();
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public List<AudioTrack> getAllAudioTracks() {
-        return mAudioTracks;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public List<MediaItem> getAllMediaItems() {
-        return mMediaItems;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public List<Transition> getAllTransitions() {
-        return mTransitions;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public int getAspectRatio() {
-        return mAspectRatio;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public AudioTrack getAudioTrack(String audioTrackId) {
-        for (AudioTrack at : mAudioTracks) {
-            if (at.getId().equals(audioTrackId)) {
-                return at;
-            }
-        }
-        return null;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public long getDuration() {
-        /**
-         *  Since MediaImageItem can change duration we need to compute the
-         *  duration here
-         */
-        computeTimelineDuration();
-        return mDurationMs;
-    }
-
-    /*
-     * Force updates the timeline duration
-     */
-    void updateTimelineDuration() {
-        computeTimelineDuration();
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized MediaItem getMediaItem(String mediaItemId) {
-        for (MediaItem mediaItem : mMediaItems) {
-            if (mediaItem.getId().equals(mediaItemId)) {
-                return mediaItem;
-            }
-        }
-        return null;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public String getPath() {
-        return mProjectPath;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public Transition getTransition(String transitionId) {
-        for (Transition transition : mTransitions) {
-            if (transition.getId().equals(transitionId)) {
-                return transition;
-            }
-        }
-        return null;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized void insertAudioTrack(AudioTrack audioTrack,
-                                              String afterAudioTrackId) {
-        if (mAudioTracks.size() == 1) {
-            throw new IllegalArgumentException("No more tracks can be added");
-        }
-
-        if (afterAudioTrackId == null) {
-            mMANativeHelper.setGeneratePreview(true);
-            mAudioTracks.add(0, audioTrack);
-        } else {
-            final int audioTrackCount = mAudioTracks.size();
-            for (int i = 0; i < audioTrackCount; i++) {
-                AudioTrack at = mAudioTracks.get(i);
-                if (at.getId().equals(afterAudioTrackId)) {
-                    mMANativeHelper.setGeneratePreview(true);
-                    mAudioTracks.add(i + 1, audioTrack);
-                    return;
-                }
-            }
-
-            throw new IllegalArgumentException("AudioTrack not found: " + afterAudioTrackId);
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized void insertMediaItem(MediaItem mediaItem, String afterMediaItemId) {
-        if (mMediaItems.contains(mediaItem)) {
-            throw new IllegalArgumentException("Media item already exists: " + mediaItem.getId());
-        }
-
-        if (afterMediaItemId == null) {
-            mMANativeHelper.setGeneratePreview(true);
-            if (mMediaItems.size() > 0) {
-                /**
-                 *  Invalidate the transition at the beginning of the timeline
-                 */
-                removeTransitionBefore(0);
-            }
-
-            mMediaItems.add(0, mediaItem);
-            computeTimelineDuration();
-            generateProjectThumbnail();
-        } else {
-            final int mediaItemCount = mMediaItems.size();
-            for (int i = 0; i < mediaItemCount; i++) {
-                final MediaItem mi = mMediaItems.get(i);
-                if (mi.getId().equals(afterMediaItemId)) {
-                    mMANativeHelper.setGeneratePreview(true);
-                    /**
-                     *  Invalidate the transition at this position
-                     */
-                    removeTransitionAfter(i);
-                    /**
-                     *  Insert the new media item
-                     */
-                    mMediaItems.add(i + 1, mediaItem);
-                    computeTimelineDuration();
-                    return;
-                }
-            }
-
-            throw new IllegalArgumentException("MediaItem not found: " + afterMediaItemId);
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized void moveAudioTrack(String audioTrackId, String afterAudioTrackId) {
-        throw new IllegalStateException("Not supported");
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized void moveMediaItem(String mediaItemId, String afterMediaItemId) {
-        final MediaItem moveMediaItem = removeMediaItem(mediaItemId,true);
-        if (moveMediaItem == null) {
-            throw new IllegalArgumentException("Target MediaItem not found: " + mediaItemId);
-        }
-
-        if (afterMediaItemId == null) {
-            if (mMediaItems.size() > 0) {
-                mMANativeHelper.setGeneratePreview(true);
-
-                /**
-                 *  Invalidate adjacent transitions at the insertion point
-                 */
-                removeTransitionBefore(0);
-
-                /**
-                 *  Insert the media item at the new position
-                 */
-                mMediaItems.add(0, moveMediaItem);
-                computeTimelineDuration();
-
-                generateProjectThumbnail();
-            } else {
-                throw new IllegalStateException("Cannot move media item (it is the only item)");
-            }
-        } else {
-            final int mediaItemCount = mMediaItems.size();
-            for (int i = 0; i < mediaItemCount; i++) {
-                final MediaItem mi = mMediaItems.get(i);
-                if (mi.getId().equals(afterMediaItemId)) {
-                    mMANativeHelper.setGeneratePreview(true);
-                    /**
-                     *  Invalidate adjacent transitions at the insertion point
-                     */
-                    removeTransitionAfter(i);
-                    /**
-                     *  Insert the media item at the new position
-                     */
-                    mMediaItems.add(i + 1, moveMediaItem);
-                    computeTimelineDuration();
-                    return;
-                }
-            }
-
-            throw new IllegalArgumentException("MediaItem not found: " + afterMediaItemId);
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public void release() {
-        stopPreview();
-
-        boolean semAcquireDone = false;
-        try {
-            lock();
-            semAcquireDone = true;
-
-            if (mMANativeHelper != null) {
-                mMediaItems.clear();
-                mAudioTracks.clear();
-                mTransitions.clear();
-                mMANativeHelper.releaseNativeHelper();
-                mMANativeHelper = null;
-            }
-        } catch (Exception  ex) {
-            Log.e(TAG, "Sem acquire NOT successful in export", ex);
-        } finally {
-            if (semAcquireDone) {
-                unlock();
-            }
-        }
-        if (mMallocDebug) {
-            try {
-                dumpHeap("HeapAtEnd");
-            } catch (Exception ex) {
-                Log.e(TAG, "dumpHeap returned error in release");
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized void removeAllMediaItems() {
-        mMANativeHelper.setGeneratePreview(true);
-
-        mMediaItems.clear();
-
-        /**
-         *  Invalidate all transitions
-         */
-        for (Transition transition : mTransitions) {
-            transition.invalidate();
-        }
-        mTransitions.clear();
-
-        mDurationMs = 0;
-        /**
-         * If a thumbnail already exists, then delete it
-         */
-        if ((new File(mProjectPath + "/" + THUMBNAIL_FILENAME)).exists()) {
-            (new File(mProjectPath + "/" + THUMBNAIL_FILENAME)).delete();
-        }
-
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized AudioTrack removeAudioTrack(String audioTrackId) {
-        final AudioTrack audioTrack = getAudioTrack(audioTrackId);
-        if (audioTrack != null) {
-            mMANativeHelper.setGeneratePreview(true);
-            mAudioTracks.remove(audioTrack);
-            audioTrack.invalidate();
-            mMANativeHelper.invalidatePcmFile();
-            mMANativeHelper.setAudioflag(true);
-        } else {
-            throw new IllegalArgumentException(" No more audio tracks");
-        }
-        return audioTrack;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized MediaItem removeMediaItem(String mediaItemId) {
-        final String firstItemString = mMediaItems.get(0).getId();
-        final MediaItem mediaItem = getMediaItem(mediaItemId);
-        if (mediaItem != null) {
-            mMANativeHelper.setGeneratePreview(true);
-            /**
-             *  Remove the media item
-             */
-            mMediaItems.remove(mediaItem);
-            if (mediaItem instanceof MediaImageItem) {
-                ((MediaImageItem)mediaItem).invalidate();
-            }
-            final List<Overlay> overlays = mediaItem.getAllOverlays();
-            if (overlays.size() > 0) {
-                for (Overlay overlay : overlays) {
-                    if (overlay instanceof OverlayFrame) {
-                        final OverlayFrame overlayFrame = (OverlayFrame)overlay;
-                        overlayFrame.invalidate();
-                    }
-                }
-            }
-
-            /**
-             *  Remove the adjacent transitions
-             */
-            removeAdjacentTransitions(mediaItem);
-            computeTimelineDuration();
-        }
-
-        /**
-         * If string equals first mediaItem, then
-         * generate Project thumbnail
-         */
-        if (firstItemString.equals(mediaItemId)) {
-            generateProjectThumbnail();
-        }
-
-        if (mediaItem instanceof MediaVideoItem) {
-            /**
-             * Delete the graph file
-             */
-            ((MediaVideoItem)mediaItem).invalidate();
-        }
-        return mediaItem;
-    }
-
-    private synchronized MediaItem removeMediaItem(String mediaItemId, boolean flag) {
-        final String firstItemString = mMediaItems.get(0).getId();
-
-        final MediaItem mediaItem = getMediaItem(mediaItemId);
-        if (mediaItem != null) {
-            mMANativeHelper.setGeneratePreview(true);
-            /**
-             *  Remove the media item
-             */
-            mMediaItems.remove(mediaItem);
-            /**
-             *  Remove the adjacent transitions
-             */
-            removeAdjacentTransitions(mediaItem);
-            computeTimelineDuration();
-        }
-
-        /**
-         * If string equals first mediaItem, then
-         * generate Project thumbail
-         */
-        if (firstItemString.equals(mediaItemId)) {
-            generateProjectThumbnail();
-        }
-        return mediaItem;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public synchronized Transition removeTransition(String transitionId) {
-        final Transition transition = getTransition(transitionId);
-        if (transition == null) {
-            throw new IllegalStateException("Transition not found: " + transitionId);
-        }
-
-        mMANativeHelper.setGeneratePreview(true);
-
-        /**
-         *  Remove the transition references
-         */
-        final MediaItem afterMediaItem = transition.getAfterMediaItem();
-        if (afterMediaItem != null) {
-            afterMediaItem.setEndTransition(null);
-        }
-
-        final MediaItem beforeMediaItem = transition.getBeforeMediaItem();
-        if (beforeMediaItem != null) {
-            beforeMediaItem.setBeginTransition(null);
-        }
-
-        mTransitions.remove(transition);
-        transition.invalidate();
-        computeTimelineDuration();
-        return transition;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs,
-                                    OverlayData overlayData) {
-        if (surfaceHolder == null) {
-            throw new IllegalArgumentException("Surface Holder is null");
-        }
-
-        final Surface surface = surfaceHolder.getSurface();
-        if (surface == null) {
-            throw new IllegalArgumentException("Surface could not be retrieved from Surface holder");
-        }
-
-        if (surface.isValid() == false) {
-            throw new IllegalStateException("Surface is not valid");
-        }
-
-        if (timeMs < 0) {
-            throw new IllegalArgumentException("requested time not correct");
-        } else if (timeMs > mDurationMs) {
-            throw new IllegalArgumentException("requested time more than duration");
-        }
-        long result = 0;
-
-        boolean semAcquireDone = false;
-        try {
-            semAcquireDone = lock(ENGINE_ACCESS_MAX_TIMEOUT_MS);
-            if (semAcquireDone == false) {
-                throw new IllegalStateException("Timeout waiting for semaphore");
-            }
-
-            if (mMANativeHelper == null) {
-                throw new IllegalStateException("The video editor is not initialized");
-            }
-
-            if (mMediaItems.size() > 0) {
-                final Rect frame = surfaceHolder.getSurfaceFrame();
-                result = mMANativeHelper.renderPreviewFrame(surface,
-                        timeMs, frame.width(), frame.height(), overlayData);
-            } else {
-                result = 0;
-            }
-        } catch (InterruptedException ex) {
-            Log.w(TAG, "The thread was interrupted", new Throwable());
-            throw new IllegalStateException("The thread was interrupted");
-        } finally {
-            if (semAcquireDone) {
-                unlock();
-            }
-        }
-        return result;
-    }
-
-    /**
-     *  the project form XML
-     */
-    private void load() throws FileNotFoundException, XmlPullParserException, IOException {
-        final File file = new File(mProjectPath, PROJECT_FILENAME);
-        /**
-         *  Load the metadata
-         */
-        final FileInputStream fis = new FileInputStream(file);
-        try {
-            final List<String> ignoredMediaItems = new ArrayList<String>();
-
-            final XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(fis, "UTF-8");
-            int eventType = parser.getEventType();
-            String name;
-            MediaItem currentMediaItem = null;
-            Overlay currentOverlay = null;
-            boolean regenerateProjectThumbnail = false;
-            while (eventType != XmlPullParser.END_DOCUMENT) {
-                switch (eventType) {
-                    case XmlPullParser.START_TAG: {
-                        name = parser.getName();
-                        if (TAG_PROJECT.equals(name)) {
-                            mAspectRatio = Integer.parseInt(parser.getAttributeValue("",
-                                   ATTR_ASPECT_RATIO));
-
-                            final boolean mRegenPCM =
-                                Boolean.parseBoolean(parser.getAttributeValue("",
-                                    ATTR_REGENERATE_PCM));
-                            mMANativeHelper.setAudioflag(mRegenPCM);
-                        } else if (TAG_MEDIA_ITEM.equals(name)) {
-                            final String mediaItemId = parser.getAttributeValue("", ATTR_ID);
-                            try {
-                                currentMediaItem = parseMediaItem(parser);
-                                mMediaItems.add(currentMediaItem);
-                            } catch (Exception ex) {
-                                Log.w(TAG, "Cannot load media item: " + mediaItemId, ex);
-                                currentMediaItem = null;
-
-                                // First media item is invalid, mark for project thumbnail removal
-                                if (mMediaItems.size() == 0) {
-                                    regenerateProjectThumbnail = true;
-                                }
-                                // Ignore the media item
-                                ignoredMediaItems.add(mediaItemId);
-                            }
-                        } else if (TAG_TRANSITION.equals(name)) {
-                            try {
-                                final Transition transition = parseTransition(parser,
-                                        ignoredMediaItems);
-                                // The transition will be null if the bounding
-                                // media items are ignored
-                                if (transition != null) {
-                                    mTransitions.add(transition);
-                                }
-                            } catch (Exception ex) {
-                                Log.w(TAG, "Cannot load transition", ex);
-                            }
-                        } else if (TAG_OVERLAY.equals(name)) {
-                            if (currentMediaItem != null) {
-                                try {
-                                    currentOverlay = parseOverlay(parser, currentMediaItem);
-                                    currentMediaItem.addOverlay(currentOverlay);
-                                } catch (Exception ex) {
-                                    Log.w(TAG, "Cannot load overlay", ex);
-                                }
-                            }
-                        } else if (TAG_OVERLAY_USER_ATTRIBUTES.equals(name)) {
-                            if (currentOverlay != null) {
-                                final int attributesCount = parser.getAttributeCount();
-                                for (int i = 0; i < attributesCount; i++) {
-                                    currentOverlay.setUserAttribute(parser.getAttributeName(i),
-                                            parser.getAttributeValue(i));
-                                }
-                            }
-                        } else if (TAG_EFFECT.equals(name)) {
-                            if (currentMediaItem != null) {
-                                try {
-                                    final Effect effect = parseEffect(parser, currentMediaItem);
-                                    currentMediaItem.addEffect(effect);
-
-                                    if (effect instanceof EffectKenBurns) {
-                                        final boolean isImageClipGenerated =
-                                               Boolean.parseBoolean(parser.getAttributeValue("",
-                                                                  ATTR_IS_IMAGE_CLIP_GENERATED));
-                                        if(isImageClipGenerated) {
-                                            final String filename = parser.getAttributeValue("",
-                                                                  ATTR_GENERATED_IMAGE_CLIP);
-                                            if (new File(filename).exists() == true) {
-                                                ((MediaImageItem)currentMediaItem).
-                                                            setGeneratedImageClip(filename);
-                                                ((MediaImageItem)currentMediaItem).
-                                                             setRegenerateClip(false);
-                                             } else {
-                                               ((MediaImageItem)currentMediaItem).
-                                                             setGeneratedImageClip(null);
-                                               ((MediaImageItem)currentMediaItem).
-                                                             setRegenerateClip(true);
-                                             }
-                                        } else {
-                                            ((MediaImageItem)currentMediaItem).
-                                                             setGeneratedImageClip(null);
-                                            ((MediaImageItem)currentMediaItem).
-                                                            setRegenerateClip(true);
-                                        }
-                                    }
-                                } catch (Exception ex) {
-                                    Log.w(TAG, "Cannot load effect", ex);
-                                }
-                            }
-                        } else if (TAG_AUDIO_TRACK.equals(name)) {
-                            try {
-                                final AudioTrack audioTrack = parseAudioTrack(parser);
-                                addAudioTrack(audioTrack);
-                            } catch (Exception ex) {
-                                Log.w(TAG, "Cannot load audio track", ex);
-                            }
-                        }
-                        break;
-                    }
-
-                    case XmlPullParser.END_TAG: {
-                        name = parser.getName();
-                        if (TAG_MEDIA_ITEM.equals(name)) {
-                            currentMediaItem = null;
-                        } else if (TAG_OVERLAY.equals(name)) {
-                            currentOverlay = null;
-                        }
-                        break;
-                    }
-
-                    default: {
-                        break;
-                    }
-                }
-                eventType = parser.next();
-            }
-            computeTimelineDuration();
-            // Regenerate project thumbnail
-            if (regenerateProjectThumbnail) {
-                generateProjectThumbnail();
-                regenerateProjectThumbnail = false;
-            }
-        } finally {
-            if (fis != null) {
-                fis.close();
-            }
-        }
-    }
-
-    /**
-     * Parse the media item
-     *
-     * @param parser The parser
-     * @return The media item
-     */
-    private MediaItem parseMediaItem(XmlPullParser parser) throws IOException {
-        final String mediaItemId = parser.getAttributeValue("", ATTR_ID);
-        final String type = parser.getAttributeValue("", ATTR_TYPE);
-        final String filename = parser.getAttributeValue("", ATTR_FILENAME);
-        final int renderingMode = Integer.parseInt(parser.getAttributeValue("",
-                ATTR_RENDERING_MODE));
-
-        final MediaItem currentMediaItem;
-        if (MediaImageItem.class.getSimpleName().equals(type)) {
-            final long durationMs = Long.parseLong(parser.getAttributeValue("", ATTR_DURATION));
-            currentMediaItem = new MediaImageItem(this, mediaItemId, filename,
-                    durationMs, renderingMode);
-        } else if (MediaVideoItem.class.getSimpleName().equals(type)) {
-            final long beginMs = Long.parseLong(parser.getAttributeValue("", ATTR_BEGIN_TIME));
-            final long endMs = Long.parseLong(parser.getAttributeValue("", ATTR_END_TIME));
-            final int volume = Integer.parseInt(parser.getAttributeValue("", ATTR_VOLUME));
-            final boolean muted = Boolean.parseBoolean(parser.getAttributeValue("", ATTR_MUTED));
-            final String audioWaveformFilename = parser.getAttributeValue("",
-                    ATTR_AUDIO_WAVEFORM_FILENAME);
-            currentMediaItem = new MediaVideoItem(this, mediaItemId, filename,
-                    renderingMode, beginMs, endMs, volume, muted, audioWaveformFilename);
-
-            final long beginTimeMs = Long.parseLong(parser.getAttributeValue("", ATTR_BEGIN_TIME));
-            final long endTimeMs = Long.parseLong(parser.getAttributeValue("", ATTR_END_TIME));
-            ((MediaVideoItem)currentMediaItem).setExtractBoundaries(beginTimeMs, endTimeMs);
-
-            final int volumePercent = Integer.parseInt(parser.getAttributeValue("", ATTR_VOLUME));
-            ((MediaVideoItem)currentMediaItem).setVolume(volumePercent);
-        } else {
-            throw new IllegalArgumentException("Unknown media item type: " + type);
-        }
-
-        return currentMediaItem;
-    }
-
-    /**
-     * Parse the transition
-     *
-     * @param parser The parser
-     * @param ignoredMediaItems The list of ignored media items
-     *
-     * @return The transition
-     */
-    private Transition parseTransition(XmlPullParser parser, List<String> ignoredMediaItems) {
-        final String transitionId = parser.getAttributeValue("", ATTR_ID);
-        final String type = parser.getAttributeValue("", ATTR_TYPE);
-        final long durationMs = Long.parseLong(parser.getAttributeValue("", ATTR_DURATION));
-        final int behavior = Integer.parseInt(parser.getAttributeValue("", ATTR_BEHAVIOR));
-
-        final String beforeMediaItemId = parser.getAttributeValue("", ATTR_BEFORE_MEDIA_ITEM_ID);
-        final MediaItem beforeMediaItem;
-        if (beforeMediaItemId != null) {
-            if (ignoredMediaItems.contains(beforeMediaItemId)) {
-                // This transition is ignored
-                return null;
-            }
-
-            beforeMediaItem = getMediaItem(beforeMediaItemId);
-        } else {
-            beforeMediaItem = null;
-        }
-
-        final String afterMediaItemId = parser.getAttributeValue("", ATTR_AFTER_MEDIA_ITEM_ID);
-        final MediaItem afterMediaItem;
-        if (afterMediaItemId != null) {
-            if (ignoredMediaItems.contains(afterMediaItemId)) {
-                // This transition is ignored
-                return null;
-            }
-
-            afterMediaItem = getMediaItem(afterMediaItemId);
-        } else {
-            afterMediaItem = null;
-        }
-
-        final Transition transition;
-        if (TransitionAlpha.class.getSimpleName().equals(type)) {
-            final int blending = Integer.parseInt(parser.getAttributeValue("", ATTR_BLENDING));
-            final String maskFilename = parser.getAttributeValue("", ATTR_MASK);
-            final boolean invert = Boolean.getBoolean(parser.getAttributeValue("", ATTR_INVERT));
-            transition = new TransitionAlpha(transitionId, afterMediaItem, beforeMediaItem,
-                    durationMs, behavior, maskFilename, blending, invert);
-        } else if (TransitionCrossfade.class.getSimpleName().equals(type)) {
-            transition = new TransitionCrossfade(transitionId, afterMediaItem, beforeMediaItem,
-                    durationMs, behavior);
-        } else if (TransitionSliding.class.getSimpleName().equals(type)) {
-            final int direction = Integer.parseInt(parser.getAttributeValue("", ATTR_DIRECTION));
-            transition = new TransitionSliding(transitionId, afterMediaItem, beforeMediaItem,
-                    durationMs, behavior, direction);
-        } else if (TransitionFadeBlack.class.getSimpleName().equals(type)) {
-            transition = new TransitionFadeBlack(transitionId, afterMediaItem, beforeMediaItem,
-                    durationMs, behavior);
-        } else {
-            throw new IllegalArgumentException("Invalid transition type: " + type);
-        }
-
-        final boolean isTransitionGenerated = Boolean.parseBoolean(parser.getAttributeValue("",
-                                                 ATTR_IS_TRANSITION_GENERATED));
-        if (isTransitionGenerated == true) {
-            final String transitionFile = parser.getAttributeValue("",
-                                                ATTR_GENERATED_TRANSITION_CLIP);
-
-            if (new File(transitionFile).exists()) {
-                transition.setFilename(transitionFile);
-            } else {
-                transition.setFilename(null);
-            }
-        }
-
-        // Use the transition
-        if (beforeMediaItem != null) {
-            beforeMediaItem.setBeginTransition(transition);
-        }
-
-        if (afterMediaItem != null) {
-            afterMediaItem.setEndTransition(transition);
-        }
-
-        return transition;
-    }
-
-    /**
-     * Parse the overlay
-     *
-     * @param parser The parser
-     * @param mediaItem The media item owner
-     *
-     * @return The overlay
-     */
-    private Overlay parseOverlay(XmlPullParser parser, MediaItem mediaItem) {
-        final String overlayId = parser.getAttributeValue("", ATTR_ID);
-        final String type = parser.getAttributeValue("", ATTR_TYPE);
-        final long durationMs = Long.parseLong(parser.getAttributeValue("", ATTR_DURATION));
-        final long startTimeMs = Long.parseLong(parser.getAttributeValue("", ATTR_BEGIN_TIME));
-
-        final Overlay overlay;
-        if (OverlayFrame.class.getSimpleName().equals(type)) {
-            final String filename = parser.getAttributeValue("", ATTR_FILENAME);
-            overlay = new OverlayFrame(mediaItem, overlayId, filename, startTimeMs, durationMs);
-        } else {
-            throw new IllegalArgumentException("Invalid overlay type: " + type);
-        }
-
-        final String overlayRgbFileName = parser.getAttributeValue("", ATTR_OVERLAY_RGB_FILENAME);
-        if (overlayRgbFileName != null) {
-            ((OverlayFrame)overlay).setFilename(overlayRgbFileName);
-
-            final int overlayFrameWidth = Integer.parseInt(parser.getAttributeValue("",
-                                   ATTR_OVERLAY_FRAME_WIDTH));
-            final int overlayFrameHeight = Integer.parseInt(parser.getAttributeValue("",
-                                   ATTR_OVERLAY_FRAME_HEIGHT));
-
-            ((OverlayFrame)overlay).setOverlayFrameWidth(overlayFrameWidth);
-            ((OverlayFrame)overlay).setOverlayFrameHeight(overlayFrameHeight);
-
-            final int resizedRGBFrameWidth = Integer.parseInt(parser.getAttributeValue("",
-                                   ATTR_OVERLAY_RESIZED_RGB_FRAME_WIDTH));
-            final int resizedRGBFrameHeight = Integer.parseInt(parser.getAttributeValue("",
-                                   ATTR_OVERLAY_RESIZED_RGB_FRAME_HEIGHT));
-
-            ((OverlayFrame)overlay).setResizedRGBSize(resizedRGBFrameWidth, resizedRGBFrameHeight);
-        }
-
-        return overlay;
-    }
-
-    /**
-     * Parse the effect
-     *
-     * @param parser The parser
-     * @param mediaItem The media item owner
-     *
-     * @return The effect
-     */
-    private Effect parseEffect(XmlPullParser parser, MediaItem mediaItem) {
-        final String effectId = parser.getAttributeValue("", ATTR_ID);
-        final String type = parser.getAttributeValue("", ATTR_TYPE);
-        final long durationMs = Long.parseLong(parser.getAttributeValue("", ATTR_DURATION));
-        final long startTimeMs = Long.parseLong(parser.getAttributeValue("", ATTR_BEGIN_TIME));
-
-        final Effect effect;
-        if (EffectColor.class.getSimpleName().equals(type)) {
-            final int colorEffectType = Integer.parseInt(parser.getAttributeValue("",
-                                                       ATTR_COLOR_EFFECT_TYPE));
-            final int color;
-            if (colorEffectType == EffectColor.TYPE_COLOR
-                    || colorEffectType == EffectColor.TYPE_GRADIENT) {
-                color = Integer.parseInt(parser.getAttributeValue("", ATTR_COLOR_EFFECT_VALUE));
-            } else {
-                color = 0;
-            }
-            effect = new EffectColor(mediaItem, effectId, startTimeMs,
-                    durationMs, colorEffectType, color);
-        } else if (EffectKenBurns.class.getSimpleName().equals(type)) {
-            final Rect startRect = new Rect(
-                    Integer.parseInt(parser.getAttributeValue("", ATTR_START_RECT_LEFT)),
-                    Integer.parseInt(parser.getAttributeValue("", ATTR_START_RECT_TOP)),
-                    Integer.parseInt(parser.getAttributeValue("", ATTR_START_RECT_RIGHT)),
-                    Integer.parseInt(parser.getAttributeValue("", ATTR_START_RECT_BOTTOM)));
-            final Rect endRect = new Rect(
-                    Integer.parseInt(parser.getAttributeValue("", ATTR_END_RECT_LEFT)),
-                    Integer.parseInt(parser.getAttributeValue("", ATTR_END_RECT_TOP)),
-                    Integer.parseInt(parser.getAttributeValue("", ATTR_END_RECT_RIGHT)),
-                    Integer.parseInt(parser.getAttributeValue("", ATTR_END_RECT_BOTTOM)));
-            effect = new EffectKenBurns(mediaItem, effectId, startRect, endRect,
-                                        startTimeMs, durationMs);
-        } else {
-            throw new IllegalArgumentException("Invalid effect type: " + type);
-        }
-
-        return effect;
-    }
-
-    /**
-     * Parse the audio track
-     *
-     * @param parser The parser
-     *
-     * @return The audio track
-     */
-    private AudioTrack parseAudioTrack(XmlPullParser parser) throws IOException {
-        final String audioTrackId = parser.getAttributeValue("", ATTR_ID);
-        final String filename = parser.getAttributeValue("", ATTR_FILENAME);
-        final long startTimeMs = Long.parseLong(parser.getAttributeValue("", ATTR_START_TIME));
-        final long beginMs = Long.parseLong(parser.getAttributeValue("", ATTR_BEGIN_TIME));
-        final long endMs = Long.parseLong(parser.getAttributeValue("", ATTR_END_TIME));
-        final int volume = Integer.parseInt(parser.getAttributeValue("", ATTR_VOLUME));
-        final boolean muted = Boolean.parseBoolean(parser.getAttributeValue("", ATTR_MUTED));
-        final boolean loop = Boolean.parseBoolean(parser.getAttributeValue("", ATTR_LOOP));
-        final boolean duckingEnabled = Boolean.parseBoolean(
-                parser.getAttributeValue("", ATTR_DUCK_ENABLED));
-        final int duckThreshold = Integer.parseInt(
-                parser.getAttributeValue("", ATTR_DUCK_THRESHOLD));
-        final int duckedTrackVolume = Integer.parseInt(parser.getAttributeValue("",
-                                                     ATTR_DUCKED_TRACK_VOLUME));
-
-        final String waveformFilename = parser.getAttributeValue("", ATTR_AUDIO_WAVEFORM_FILENAME);
-        final AudioTrack audioTrack = new AudioTrack(this, audioTrackId,
-                                                     filename, startTimeMs,
-                                                     beginMs, endMs, loop,
-                                                     volume, muted,
-                                                     duckingEnabled,
-                                                     duckThreshold,
-                                                     duckedTrackVolume,
-                                                     waveformFilename);
-
-        return audioTrack;
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public void save() throws IOException {
-        final XmlSerializer serializer = Xml.newSerializer();
-        final StringWriter writer = new StringWriter();
-        serializer.setOutput(writer);
-        serializer.startDocument("UTF-8", true);
-        serializer.startTag("", TAG_PROJECT);
-        serializer.attribute("",
-                             ATTR_ASPECT_RATIO, Integer.toString(mAspectRatio));
-
-        serializer.attribute("", ATTR_REGENERATE_PCM,
-                        Boolean.toString(mMANativeHelper.getAudioflag()));
-
-        serializer.startTag("", TAG_MEDIA_ITEMS);
-        for (MediaItem mediaItem : mMediaItems) {
-            serializer.startTag("", TAG_MEDIA_ITEM);
-            serializer.attribute("", ATTR_ID, mediaItem.getId());
-            serializer.attribute("", ATTR_TYPE,
-                                          mediaItem.getClass().getSimpleName());
-            serializer.attribute("", ATTR_FILENAME, mediaItem.getFilename());
-            serializer.attribute("", ATTR_RENDERING_MODE, Integer.toString(
-                    mediaItem.getRenderingMode()));
-            if (mediaItem instanceof MediaVideoItem) {
-                final MediaVideoItem mvi = (MediaVideoItem)mediaItem;
-                serializer
-                .attribute("", ATTR_BEGIN_TIME,
-                                     Long.toString(mvi.getBoundaryBeginTime()));
-                serializer.attribute("", ATTR_END_TIME,
-                                       Long.toString(mvi.getBoundaryEndTime()));
-                serializer.attribute("", ATTR_VOLUME,
-                                             Integer.toString(mvi.getVolume()));
-                serializer.attribute("", ATTR_MUTED,
-                                               Boolean.toString(mvi.isMuted()));
-                if (mvi.getAudioWaveformFilename() != null) {
-                    serializer.attribute("", ATTR_AUDIO_WAVEFORM_FILENAME,
-                            mvi.getAudioWaveformFilename());
-                }
-            } else if (mediaItem instanceof MediaImageItem) {
-                serializer.attribute("", ATTR_DURATION,
-                        Long.toString(mediaItem.getTimelineDuration()));
-            }
-
-            final List<Overlay> overlays = mediaItem.getAllOverlays();
-            if (overlays.size() > 0) {
-                serializer.startTag("", TAG_OVERLAYS);
-                for (Overlay overlay : overlays) {
-                    serializer.startTag("", TAG_OVERLAY);
-                    serializer.attribute("", ATTR_ID, overlay.getId());
-                    serializer.attribute("",
-                                 ATTR_TYPE, overlay.getClass().getSimpleName());
-                    serializer.attribute("", ATTR_BEGIN_TIME,
-                                         Long.toString(overlay.getStartTime()));
-                    serializer.attribute("", ATTR_DURATION,
-                                          Long.toString(overlay.getDuration()));
-                    if (overlay instanceof OverlayFrame) {
-                        final OverlayFrame overlayFrame = (OverlayFrame)overlay;
-                        overlayFrame.save(getPath());
-                        if (overlayFrame.getBitmapImageFileName() != null) {
-                            serializer.attribute("", ATTR_FILENAME,
-                                         overlayFrame.getBitmapImageFileName());
-                        }
-
-                        if (overlayFrame.getFilename() != null) {
-                            serializer.attribute("",
-                                                 ATTR_OVERLAY_RGB_FILENAME,
-                                                 overlayFrame.getFilename());
-                            serializer.attribute("", ATTR_OVERLAY_FRAME_WIDTH,
-                                                 Integer.toString(overlayFrame.getOverlayFrameWidth()));
-                            serializer.attribute("", ATTR_OVERLAY_FRAME_HEIGHT,
-                                                 Integer.toString(overlayFrame.getOverlayFrameHeight()));
-                            serializer.attribute("", ATTR_OVERLAY_RESIZED_RGB_FRAME_WIDTH,
-                                                 Integer.toString(overlayFrame.getResizedRGBSizeWidth()));
-                            serializer.attribute("", ATTR_OVERLAY_RESIZED_RGB_FRAME_HEIGHT,
-                                                 Integer.toString(overlayFrame.getResizedRGBSizeHeight()));
-
-                        }
-
-                    }
-
-                    /**
-                     *  Save the user attributes
-                     */
-                    serializer.startTag("", TAG_OVERLAY_USER_ATTRIBUTES);
-                    final Map<String, String> userAttributes = overlay.getUserAttributes();
-                    for (String name : userAttributes.keySet()) {
-                        final String value = userAttributes.get(name);
-                        if (value != null) {
-                            serializer.attribute("", name, value);
-                        }
-                    }
-                    serializer.endTag("", TAG_OVERLAY_USER_ATTRIBUTES);
-
-                    serializer.endTag("", TAG_OVERLAY);
-                }
-                serializer.endTag("", TAG_OVERLAYS);
-            }
-
-            final List<Effect> effects = mediaItem.getAllEffects();
-            if (effects.size() > 0) {
-                serializer.startTag("", TAG_EFFECTS);
-                for (Effect effect : effects) {
-                    serializer.startTag("", TAG_EFFECT);
-                    serializer.attribute("", ATTR_ID, effect.getId());
-                    serializer.attribute("",
-                                  ATTR_TYPE, effect.getClass().getSimpleName());
-                    serializer.attribute("", ATTR_BEGIN_TIME,
-                            Long.toString(effect.getStartTime()));
-                    serializer.attribute("", ATTR_DURATION,
-                                           Long.toString(effect.getDuration()));
-                    if (effect instanceof EffectColor) {
-                        final EffectColor colorEffect = (EffectColor)effect;
-                        serializer.attribute("", ATTR_COLOR_EFFECT_TYPE,
-                                Integer.toString(colorEffect.getType()));
-                        if (colorEffect.getType() == EffectColor.TYPE_COLOR ||
-                                colorEffect.getType() == EffectColor.TYPE_GRADIENT) {
-                            serializer.attribute("", ATTR_COLOR_EFFECT_VALUE,
-                                    Integer.toString(colorEffect.getColor()));
-                        }
-                    } else if (effect instanceof EffectKenBurns) {
-                        final Rect startRect = ((EffectKenBurns)effect).getStartRect();
-                        serializer.attribute("", ATTR_START_RECT_LEFT,
-                                Integer.toString(startRect.left));
-                        serializer.attribute("", ATTR_START_RECT_TOP,
-                                Integer.toString(startRect.top));
-                        serializer.attribute("", ATTR_START_RECT_RIGHT,
-                                Integer.toString(startRect.right));
-                        serializer.attribute("", ATTR_START_RECT_BOTTOM,
-                                Integer.toString(startRect.bottom));
-
-                        final Rect endRect = ((EffectKenBurns)effect).getEndRect();
-                        serializer.attribute("", ATTR_END_RECT_LEFT,
-                                                Integer.toString(endRect.left));
-                        serializer.attribute("", ATTR_END_RECT_TOP,
-                                                 Integer.toString(endRect.top));
-                        serializer.attribute("", ATTR_END_RECT_RIGHT,
-                                               Integer.toString(endRect.right));
-                        serializer.attribute("", ATTR_END_RECT_BOTTOM,
-                                Integer.toString(endRect.bottom));
-                        final MediaItem mItem = effect.getMediaItem();
-                           if(((MediaImageItem)mItem).getGeneratedImageClip() != null) {
-                               serializer.attribute("", ATTR_IS_IMAGE_CLIP_GENERATED,
-                                       Boolean.toString(true));
-                               serializer.attribute("", ATTR_GENERATED_IMAGE_CLIP,
-                                     ((MediaImageItem)mItem).getGeneratedImageClip());
-                            } else {
-                                serializer.attribute("", ATTR_IS_IMAGE_CLIP_GENERATED,
-                                     Boolean.toString(false));
-                         }
-                    }
-
-                    serializer.endTag("", TAG_EFFECT);
-                }
-                serializer.endTag("", TAG_EFFECTS);
-            }
-
-            serializer.endTag("", TAG_MEDIA_ITEM);
-        }
-        serializer.endTag("", TAG_MEDIA_ITEMS);
-
-        serializer.startTag("", TAG_TRANSITIONS);
-
-        for (Transition transition : mTransitions) {
-            serializer.startTag("", TAG_TRANSITION);
-            serializer.attribute("", ATTR_ID, transition.getId());
-            serializer.attribute("", ATTR_TYPE, transition.getClass().getSimpleName());
-            serializer.attribute("", ATTR_DURATION, Long.toString(transition.getDuration()));
-            serializer.attribute("", ATTR_BEHAVIOR, Integer.toString(transition.getBehavior()));
-            serializer.attribute("", ATTR_IS_TRANSITION_GENERATED,
-                                    Boolean.toString(transition.isGenerated()));
-            if (transition.isGenerated() == true) {
-                serializer.attribute("", ATTR_GENERATED_TRANSITION_CLIP, transition.mFilename);
-            }
-            final MediaItem afterMediaItem = transition.getAfterMediaItem();
-            if (afterMediaItem != null) {
-                serializer.attribute("", ATTR_AFTER_MEDIA_ITEM_ID, afterMediaItem.getId());
-            }
-
-            final MediaItem beforeMediaItem = transition.getBeforeMediaItem();
-            if (beforeMediaItem != null) {
-                serializer.attribute("", ATTR_BEFORE_MEDIA_ITEM_ID, beforeMediaItem.getId());
-            }
-
-            if (transition instanceof TransitionSliding) {
-                serializer.attribute("", ATTR_DIRECTION,
-                        Integer.toString(((TransitionSliding)transition).getDirection()));
-            } else if (transition instanceof TransitionAlpha) {
-                TransitionAlpha ta = (TransitionAlpha)transition;
-                serializer.attribute("", ATTR_BLENDING,
-                                     Integer.toString(ta.getBlendingPercent()));
-                serializer.attribute("", ATTR_INVERT,
-                                               Boolean.toString(ta.isInvert()));
-                if (ta.getMaskFilename() != null) {
-                    serializer.attribute("", ATTR_MASK, ta.getMaskFilename());
-                }
-            }
-            serializer.endTag("", TAG_TRANSITION);
-        }
-        serializer.endTag("", TAG_TRANSITIONS);
-        serializer.startTag("", TAG_AUDIO_TRACKS);
-        for (AudioTrack at : mAudioTracks) {
-            serializer.startTag("", TAG_AUDIO_TRACK);
-            serializer.attribute("", ATTR_ID, at.getId());
-            serializer.attribute("", ATTR_FILENAME, at.getFilename());
-            serializer.attribute("", ATTR_START_TIME, Long.toString(at.getStartTime()));
-            serializer.attribute("", ATTR_BEGIN_TIME, Long.toString(at.getBoundaryBeginTime()));
-            serializer.attribute("", ATTR_END_TIME, Long.toString(at.getBoundaryEndTime()));
-            serializer.attribute("", ATTR_VOLUME, Integer.toString(at.getVolume()));
-            serializer.attribute("", ATTR_DUCK_ENABLED,
-                                       Boolean.toString(at.isDuckingEnabled()));
-            serializer.attribute("", ATTR_DUCKED_TRACK_VOLUME,
-                                   Integer.toString(at.getDuckedTrackVolume()));
-            serializer.attribute("", ATTR_DUCK_THRESHOLD,
-                                   Integer.toString(at.getDuckingThreshhold()));
-            serializer.attribute("", ATTR_MUTED, Boolean.toString(at.isMuted()));
-            serializer.attribute("", ATTR_LOOP, Boolean.toString(at.isLooping()));
-            if (at.getAudioWaveformFilename() != null) {
-                serializer.attribute("", ATTR_AUDIO_WAVEFORM_FILENAME,
-                        at.getAudioWaveformFilename());
-            }
-
-            serializer.endTag("", TAG_AUDIO_TRACK);
-        }
-        serializer.endTag("", TAG_AUDIO_TRACKS);
-
-        serializer.endTag("", TAG_PROJECT);
-        serializer.endDocument();
-
-        /**
-         *  Save the metadata XML file
-         */
-        final FileOutputStream out = new FileOutputStream(new File(getPath(),
-                                                          PROJECT_FILENAME));
-        out.write(writer.toString().getBytes());
-        out.flush();
-        out.close();
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public void setAspectRatio(int aspectRatio) {
-        mAspectRatio = aspectRatio;
-        /**
-         *  Invalidate all transitions
-         */
-        mMANativeHelper.setGeneratePreview(true);
-
-        for (Transition transition : mTransitions) {
-            transition.invalidate();
-        }
-
-        final Iterator<MediaItem> it = mMediaItems.iterator();
-
-        while (it.hasNext()) {
-            final MediaItem t = it.next();
-            List<Overlay> overlayList = t.getAllOverlays();
-            for (Overlay overlay : overlayList) {
-
-                ((OverlayFrame)overlay).invalidateGeneratedFiles();
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public void startPreview(SurfaceHolder surfaceHolder, long fromMs, long toMs,
-                             boolean loop, int callbackAfterFrameCount,
-                             PreviewProgressListener listener) {
-
-        if (surfaceHolder == null) {
-            throw new IllegalArgumentException();
-        }
-
-        final Surface surface = surfaceHolder.getSurface();
-        if (surface == null) {
-            throw new IllegalArgumentException("Surface could not be retrieved from surface holder");
-        }
-
-        if (surface.isValid() == false) {
-            throw new IllegalStateException("Surface is not valid");
-        }
-
-        if (listener == null) {
-            throw new IllegalArgumentException();
-        }
-
-        if (fromMs >= mDurationMs) {
-            throw new IllegalArgumentException("Requested time not correct");
-        }
-
-        if (fromMs < 0) {
-            throw new IllegalArgumentException("Requested time not correct");
-        }
-
-        boolean semAcquireDone = false;
-        if (!mPreviewInProgress) {
-            try{
-                semAcquireDone = lock(ENGINE_ACCESS_MAX_TIMEOUT_MS);
-                if (semAcquireDone == false) {
-                    throw new IllegalStateException("Timeout waiting for semaphore");
-                }
-
-                if (mMANativeHelper == null) {
-                    throw new IllegalStateException("The video editor is not initialized");
-                }
-
-                if (mMediaItems.size() > 0) {
-                    mPreviewInProgress = true;
-                    mMANativeHelper.previewStoryBoard(mMediaItems, mTransitions,
-                                                      mAudioTracks, null);
-                    mMANativeHelper.doPreview(surface, fromMs, toMs, loop,
-                                     callbackAfterFrameCount, listener);
-                }
-                /**
-                 *  Release The lock on complete by calling stopPreview
-                 */
-            } catch (InterruptedException ex) {
-                Log.w(TAG, "The thread was interrupted", new Throwable());
-                throw new IllegalStateException("The thread was interrupted");
-            }
-         } else {
-            throw new IllegalStateException("Preview already in progress");
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    public long stopPreview() {
-        long result = 0;
-        if (mPreviewInProgress) {
-            try {
-                result = mMANativeHelper.stopPreview();
-                /**
-                 *  release on complete by calling stopPreview
-                 */
-                } finally {
-                    mPreviewInProgress = false;
-                    unlock();
-                }
-            return result;
-        }
-        else {
-            return 0;
-        }
-    }
-
-    /*
-     * Remove transitions associated with the specified media item
-     *
-     * @param mediaItem The media item
-     */
-    private void removeAdjacentTransitions(MediaItem mediaItem) {
-        final Transition beginTransition = mediaItem.getBeginTransition();
-        if (beginTransition != null) {
-            if (beginTransition.getAfterMediaItem() != null) {
-                beginTransition.getAfterMediaItem().setEndTransition(null);
-            }
-            beginTransition.invalidate();
-            mTransitions.remove(beginTransition);
-        }
-
-        final Transition endTransition = mediaItem.getEndTransition();
-        if (endTransition != null) {
-            if (endTransition.getBeforeMediaItem() != null) {
-                endTransition.getBeforeMediaItem().setBeginTransition(null);
-            }
-            endTransition.invalidate();
-            mTransitions.remove(endTransition);
-        }
-
-        mediaItem.setBeginTransition(null);
-        mediaItem.setEndTransition(null);
-    }
-
-    /**
-     * Remove the transition before this media item
-     *
-     * @param index The media item index
-     */
-    private void removeTransitionBefore(int index) {
-        final MediaItem mediaItem = mMediaItems.get(index);
-        final Iterator<Transition> it = mTransitions.iterator();
-        while (it.hasNext()) {
-            Transition t = it.next();
-            if (t.getBeforeMediaItem() == mediaItem) {
-                mMANativeHelper.setGeneratePreview(true);
-                it.remove();
-                t.invalidate();
-                mediaItem.setBeginTransition(null);
-                if (index > 0) {
-                    mMediaItems.get(index - 1).setEndTransition(null);
-                }
-                break;
-            }
-        }
-    }
-
-    /**
-     * Remove the transition after this media item
-     *
-     * @param mediaItem The media item
-     */
-    private void removeTransitionAfter(int index) {
-        final MediaItem mediaItem = mMediaItems.get(index);
-        final Iterator<Transition> it = mTransitions.iterator();
-        while (it.hasNext()) {
-            Transition t = it.next();
-            if (t.getAfterMediaItem() == mediaItem) {
-                mMANativeHelper.setGeneratePreview(true);
-                it.remove();
-                t.invalidate();
-                mediaItem.setEndTransition(null);
-                /**
-                 *  Invalidate the reference in the next media item
-                 */
-                if (index < mMediaItems.size() - 1) {
-                    mMediaItems.get(index + 1).setBeginTransition(null);
-                }
-                break;
-            }
-        }
-    }
-
-    /**
-     * Compute the duration
-     */
-    private void computeTimelineDuration() {
-        mDurationMs = 0;
-        final int mediaItemsCount = mMediaItems.size();
-        for (int i = 0; i < mediaItemsCount; i++) {
-            final MediaItem mediaItem = mMediaItems.get(i);
-            mDurationMs += mediaItem.getTimelineDuration();
-            if (mediaItem.getEndTransition() != null) {
-                if (i < mediaItemsCount - 1) {
-                    mDurationMs -= mediaItem.getEndTransition().getDuration();
-                }
-            }
-        }
-    }
-
-    /*
-     * Generate the project thumbnail
-     */
-    private void generateProjectThumbnail() {
-        /*
-         * If a thumbnail already exists, then delete it first
-         */
-        if ((new File(mProjectPath + "/" + THUMBNAIL_FILENAME)).exists()) {
-            (new File(mProjectPath + "/" + THUMBNAIL_FILENAME)).delete();
-        }
-        /*
-         * Generate a new thumbnail for the project from first media Item
-         */
-        if (mMediaItems.size() > 0) {
-            MediaItem mI = mMediaItems.get(0);
-            /*
-             * Keep aspect ratio of the image
-             */
-            int height = 480;
-            int width = mI.getWidth() * height / mI.getHeight();
-
-            Bitmap projectBitmap = null;
-            String filename = mI.getFilename();
-            if (mI instanceof MediaVideoItem) {
-                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
-                retriever.setDataSource(filename);
-                Bitmap bitmap = retriever.getFrameAtTime();
-                retriever.release();
-                retriever = null;
-                if (bitmap == null) {
-                    String msg = "Thumbnail extraction from " +
-                                    filename + " failed";
-                    throw new IllegalArgumentException(msg);
-                }
-                // Resize the thumbnail to the target size
-                projectBitmap =
-                    Bitmap.createScaledBitmap(bitmap, width, height, true);
-            } else {
-                try {
-                    projectBitmap = mI.getThumbnail(width, height, 500);
-                } catch (IllegalArgumentException e) {
-                    String msg = "Project thumbnail extraction from " +
-                                    filename + " failed";
-                    throw new IllegalArgumentException(msg);
-                } catch (IOException e) {
-                    String msg = "IO Error creating project thumbnail";
-                    throw new IllegalArgumentException(msg);
-                }
-            }
-
-            FileOutputStream stream = null;
-            try {
-                stream = new FileOutputStream(mProjectPath + "/" + THUMBNAIL_FILENAME);
-                projectBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
-                stream.flush();
-            } catch (IOException e) {
-                throw new IllegalArgumentException ("Error creating project thumbnail");
-            } finally {
-                IoUtils.closeQuietly(stream);
-                projectBitmap.recycle();
-            }
-        }
-    }
-
-    /**
-     * Clears the preview surface
-     *
-     * @param surfaceHolder SurfaceHolder where the preview is rendered
-     * and needs to be cleared.
-     */
-    public void clearSurface(SurfaceHolder surfaceHolder) {
-        if (surfaceHolder == null) {
-            throw new IllegalArgumentException("Invalid surface holder");
-        }
-
-        final Surface surface = surfaceHolder.getSurface();
-        if (surface == null) {
-            throw new IllegalArgumentException("Surface could not be retrieved from surface holder");
-        }
-
-        if (surface.isValid() == false) {
-            throw new IllegalStateException("Surface is not valid");
-        }
-
-        if (mMANativeHelper != null) {
-            mMANativeHelper.clearPreviewSurface(surface);
-        } else {
-            Log.w(TAG, "Native helper was not ready!");
-        }
-    }
-
-    /**
-     * Grab the semaphore which arbitrates access to the editor
-     *
-     * @throws InterruptedException
-     */
-    private void lock() throws InterruptedException {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "lock: grabbing semaphore", new Throwable());
-        }
-        mLock.acquire();
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "lock: grabbed semaphore");
-        }
-    }
-
-    /**
-     * Tries to grab the semaphore with a specified time out which arbitrates access to the editor
-     *
-     * @param timeoutMs time out in ms.
-     *
-     * @return true if the semaphore is acquired, false otherwise
-     * @throws InterruptedException
-     */
-    private boolean lock(long timeoutMs) throws InterruptedException {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "lock: grabbing semaphore with timeout " + timeoutMs, new Throwable());
-        }
-
-        boolean acquireSem = mLock.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS);
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "lock: grabbed semaphore status " + acquireSem);
-        }
-
-        return acquireSem;
-    }
-
-    /**
-     * Release the semaphore which arbitrates access to the editor
-     */
-    private void unlock() {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "unlock: releasing semaphore");
-        }
-        mLock.release();
-    }
-
-    /**
-     * Dumps the heap memory usage information to file
-     */
-    private static void dumpHeap (String filename) throws Exception {
-        /* Cleanup as much as possible before dump
-         */
-        System.gc();
-        System.runFinalization();
-        Thread.sleep(1000);
-        String state = Environment.getExternalStorageState();
-        if (Environment.MEDIA_MOUNTED.equals(state)) {
-            String extDir =
-             Environment.getExternalStorageDirectory().toString();
-
-            /* If dump file already exists, then delete it first
-            */
-            if ((new File(extDir + "/" + filename + ".dump")).exists()) {
-                (new File(extDir + "/" + filename + ".dump")).delete();
-            }
-            /* Dump native heap
-            */
-            FileOutputStream ost =
-             new FileOutputStream(extDir + "/" + filename + ".dump");
-            Debug.dumpNativeHeap(ost.getFD());
-            ost.close();
-        }
-    }
-}
diff --git a/media/java/android/media/videoeditor/VideoEditorProfile.java b/media/java/android/media/videoeditor/VideoEditorProfile.java
deleted file mode 100644
index 202a2df..0000000
--- a/media/java/android/media/videoeditor/VideoEditorProfile.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.videoeditor;
-
-/**
- * The VideoEditorProfile class is used to retrieve the
- * predefined videoeditor profile settings for videoeditor applications.
- * These settings are read-only.
- *
- * <p>The videoeditor profile specifies the following set of parameters:
- * <ul>
- * <li> max input video frame width
- * <li> max input video frame height
- * <li> max output video frame width
- * <li> max output video frame height
- * </ul>
- * {@hide}
- */
-public class VideoEditorProfile
-{
-    static {
-        System.loadLibrary("media_jni");
-        native_init();
-    }
-    /**
-     * The max input video frame width
-     */
-    public int maxInputVideoFrameWidth;
-
-    /**
-     * The max input video frame height
-     */
-    public int maxInputVideoFrameHeight;
-
-    /**
-     * The max ouput video frame width
-     */
-    public int maxOutputVideoFrameWidth;
-
-    /**
-     * The max ouput video frame height
-     */
-    public int maxOutputVideoFrameHeight;
-
-    /**
-     * Returns the videoeditor profile
-     */
-    public static VideoEditorProfile get() {
-        return native_get_videoeditor_profile();
-    }
-
-    /**
-     * Returns the supported profile by given video codec
-     */
-    public static int getExportProfile(int vidCodec) {
-        int profile = -1;
-
-        switch (vidCodec) {
-            case MediaProperties.VCODEC_H263:
-            case MediaProperties.VCODEC_H264:
-            case MediaProperties.VCODEC_MPEG4:
-                 profile = native_get_videoeditor_export_profile(vidCodec);
-                 break;
-            default :
-               throw new IllegalArgumentException("Unsupported video codec" + vidCodec);
-        }
-
-        return profile;
-    }
-
-    /**
-     * Returns the supported level by given video codec
-     */
-    public static int getExportLevel(int vidCodec) {
-        int level = -1;
-
-        switch (vidCodec) {
-            case MediaProperties.VCODEC_H263:
-            case MediaProperties.VCODEC_H264:
-            case MediaProperties.VCODEC_MPEG4:
-                 level = native_get_videoeditor_export_level(vidCodec);
-                 break;
-            default :
-               throw new IllegalArgumentException("Unsupported video codec" + vidCodec);
-        }
-
-        return level;
-    }
-
-    // Private constructor called by JNI
-    private VideoEditorProfile(int inputWidth,
-                             int inputHeight,
-                             int outputWidth,
-                             int outputHeight) {
-
-        this.maxInputVideoFrameWidth = inputWidth;
-        this.maxInputVideoFrameHeight = inputHeight;
-        this.maxOutputVideoFrameWidth = outputWidth;
-        this.maxOutputVideoFrameHeight = outputHeight;
-    }
-
-    // Methods implemented by JNI
-    private static native final void native_init();
-    private static native final VideoEditorProfile
-        native_get_videoeditor_profile();
-    private static native final int native_get_videoeditor_export_profile(int codec);
-    private static native final int native_get_videoeditor_export_level(int level);
-
-}
diff --git a/media/java/android/media/videoeditor/WaveformData.java b/media/java/android/media/videoeditor/WaveformData.java
deleted file mode 100644
index 6c10e3c..0000000
--- a/media/java/android/media/videoeditor/WaveformData.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.media.videoeditor;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/**
- * Class which describes the waveform data of an audio track. The gain values
- * represent the average gain for an audio frame. For audio codecs which do not
- * operate on a per frame bases (eg. ALAW, ULAW) a reasonable audio frame
- * duration will be assumed (eg. 50ms).
- * {@hide}
- */
-public class WaveformData {
-    /*
-     *  Instance variables
-     */
-    private final int mFrameDurationMs;
-    private final int mFramesCount;
-    private final short[] mGains;
-
-    /*
-     * This constructor shall not be used
-     */
-    @SuppressWarnings("unused")
-    private WaveformData() throws IOException {
-        mFrameDurationMs = 0;
-        mFramesCount = 0;
-        mGains = null;
-    }
-
-    /*
-     * Constructor
-     *
-     * @param audioWaveformFilename The name of the audio waveform file
-     *
-     * The file format is as following:
-     * <ul>
-     *  <li>first 4 bytes provide the number of samples for each value, as
-     *  big-endian signed</li>
-     *  <li>4 following bytes is the total number of values in the file, as
-     *  big-endian signed</li>
-     *  <li>then, all values follow as bytes</li>
-     * </ul>
-     *
-     * @throws IOException on failure of file input stream operations
-     * @throws IllegalArgumentException if audioWaveformFilename is null
-     */
-    WaveformData(String audioWaveformFilename) throws IOException {
-
-        if (audioWaveformFilename == null) {
-            throw new IllegalArgumentException("WaveformData : filename is null");
-        }
-
-        FileInputStream audioGraphFileReadHandle = null;
-
-        try {
-            final File audioGraphFileContext = new File(audioWaveformFilename);
-
-            audioGraphFileReadHandle = new FileInputStream(audioGraphFileContext);
-            /*
-             * Read frame duration
-             */
-            final byte tempFrameDuration[] = new byte[4];
-
-            audioGraphFileReadHandle.read(tempFrameDuration, 0, 4);
-
-            int tempFrameDurationMs = 0;
-            int tempFramesCounter = 0;
-            for (int i = 0; i < 4; i++) {
-                tempFrameDurationMs = (tempFrameDurationMs << 8);
-                tempFrameDurationMs = (tempFrameDurationMs | (tempFrameDuration[i] & 0xff));
-            }
-            mFrameDurationMs = tempFrameDurationMs;
-
-            /*
-             * Read count
-             */
-            final byte tempFramesCount[] = new byte[4];
-
-            audioGraphFileReadHandle.read(tempFramesCount, 0, 4);
-            for (int i = 0; i < 4; i++) {
-                tempFramesCounter = (tempFramesCounter << 8);
-                tempFramesCounter = (tempFramesCounter | (tempFramesCount[i] & 0xff));
-            }
-            mFramesCount = tempFramesCounter;
-
-            /*
-             *  Capture the graph values
-             */
-            mGains = new short[mFramesCount];
-
-            for (int i = 0; i < mFramesCount; i++) {
-                mGains[i] = (short)audioGraphFileReadHandle.read();
-            }
-        } finally {
-            if (audioGraphFileReadHandle != null) {
-                audioGraphFileReadHandle.close();
-            }
-        }
-    }
-
-    /**
-     * @return The duration of a frame in milliseconds
-     */
-    public int getFrameDuration() {
-        return mFrameDurationMs;
-    }
-
-    /**
-     * @return The number of frames within the waveform data
-     */
-    public int getFramesCount() {
-        return mFramesCount;
-    }
-
-    /**
-     * @return The array of frame gains. The size of the array is the frames
-     *         count. The values of the frame gains range from 0 to 255.
-     */
-    public short[] getFrameGains() {
-        return mGains;
-    }
-}
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index 48a9132..1e5c700 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -290,75 +290,6 @@
     }
     return static_cast<jint>(levels[index]);
 }
-static jobject
-android_media_MediaProfiles_native_get_videoeditor_profile(JNIEnv *env, jobject thiz)
-{
-    ALOGV("native_get_videoeditor_profile");
-
-    int maxInputFrameWidth =
-            sProfiles->getVideoEditorCapParamByName("videoeditor.input.width.max");
-    int maxInputFrameHeight =
-            sProfiles->getVideoEditorCapParamByName("videoeditor.input.height.max");
-    int maxOutputFrameWidth =
-            sProfiles->getVideoEditorCapParamByName("videoeditor.output.width.max");
-    int maxOutputFrameHeight =
-            sProfiles->getVideoEditorCapParamByName("videoeditor.output.height.max");
-
-    // Check on the values retrieved
-    if (maxInputFrameWidth == -1 || maxInputFrameHeight == -1 ||
-        maxOutputFrameWidth == -1 || maxOutputFrameHeight == -1) {
-
-        jniThrowException(env, "java/lang/RuntimeException",\
-            "Error retrieving videoeditor profile params");
-        return NULL;
-    }
-    ALOGV("native_get_videoeditor_profile \
-        inWidth:%d inHeight:%d,outWidth:%d, outHeight:%d",\
-        maxInputFrameWidth,maxInputFrameHeight,\
-        maxOutputFrameWidth,maxOutputFrameHeight);
-
-    jclass VideoEditorProfileClazz =
-        env->FindClass("android/media/videoeditor/VideoEditorProfile");
-    jmethodID VideoEditorProfileConstructorMethodID =
-        env->GetMethodID(VideoEditorProfileClazz, "<init>", "(IIII)V");
-    return env->NewObject(VideoEditorProfileClazz,
-                          VideoEditorProfileConstructorMethodID,
-                          maxInputFrameWidth,
-                          maxInputFrameHeight,
-                          maxOutputFrameWidth,
-                          maxOutputFrameHeight);
-}
-static jint
-android_media_MediaProfiles_native_get_videoeditor_export_profile(
-    JNIEnv *env, jobject thiz, jint codec)
-{
-    ALOGV("android_media_MediaProfiles_native_get_export_profile index ");
-    int profile =0;
-    profile = sProfiles->getVideoEditorExportParamByName("videoeditor.export.profile", codec);
-    // Check the values retrieved
-    if (profile == -1) {
-        jniThrowException(env, "java/lang/RuntimeException",\
-            "Error retrieving videoeditor export profile params");
-        return -1;
-    }
-    return static_cast<jint>(profile);
-}
-
-static jint
-android_media_MediaProfiles_native_get_videoeditor_export_level(
-    JNIEnv *env, jobject thiz, jint codec)
-{
-    ALOGV("android_media_MediaProfiles_native_get_export_level");
-    int level =0;
-    level = sProfiles->getVideoEditorExportParamByName("videoeditor.export.level", codec);
-    // Check the values retrieved
-    if (level == -1) {
-        jniThrowException(env, "java/lang/RuntimeException",\
-            "Error retrieving videoeditor export level params");
-        return -1;
-    }
-    return static_cast<jint>(level);
-}
 static JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = {
     {"native_init",                            "()V",                    (void *)android_media_MediaProfiles_native_init},
     {"native_get_num_file_formats",            "()I",                    (void *)android_media_MediaProfiles_native_get_num_file_formats},
@@ -396,19 +327,10 @@
     {"native_get_image_encoding_quality_level","(II)I",                   (void *)android_media_MediaProfiles_native_get_image_encoding_quality_level},
 };
 
-static JNINativeMethod gMethodsForVideoEditorProfileClass[] = {
-    {"native_init",                            "()V",         (void *)android_media_MediaProfiles_native_init},
-    {"native_get_videoeditor_profile", "()Landroid/media/videoeditor/VideoEditorProfile;", (void *)android_media_MediaProfiles_native_get_videoeditor_profile},
-    {"native_get_videoeditor_export_profile", "(I)I", (void *)android_media_MediaProfiles_native_get_videoeditor_export_profile},
-    {"native_get_videoeditor_export_level", "(I)I", (void *)android_media_MediaProfiles_native_get_videoeditor_export_level},
-};
-
 static const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities";
 static const char* const kDecoderCapabilitiesClassPathName = "android/media/DecoderCapabilities";
 static const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile";
 static const char* const kCameraProfileClassPathName = "android/media/CameraProfile";
-static const char* const kVideoEditorProfileClassPathName =
-    "android/media/videoeditor/VideoEditorProfile";
 
 // This function only registers the native methods, and is called from
 // JNI_OnLoad in android_media_MediaPlayer.cpp
@@ -434,11 +356,6 @@
                gMethodsForCameraProfileClass,
                NELEM(gMethodsForCameraProfileClass));
 
-    int ret5 = AndroidRuntime::registerNativeMethods(env,
-               kVideoEditorProfileClassPathName,
-               gMethodsForVideoEditorProfileClass,
-               NELEM(gMethodsForVideoEditorProfileClass));
-
     // Success if all return values from above are 0
-    return (ret1 || ret2 || ret3 || ret4 || ret5);
+    return (ret1 || ret2 || ret3 || ret4);
 }
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
deleted file mode 100644
index 312c366..0000000
--- a/media/jni/mediaeditor/Android.mk
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    VideoEditorMain.cpp \
-    VideoEditorClasses.cpp \
-    VideoEditorOsal.cpp \
-    VideoEditorJava.cpp \
-    VideoEditorPropertiesMain.cpp \
-    VideoEditorThumbnailMain.cpp  \
-    VideoBrowserMain.c
-
-LOCAL_C_INCLUDES += \
-    $(TOP)/frameworks/base/core/jni \
-    $(TOP)/frameworks/base/include \
-    $(TOP)/frameworks/base/include/media \
-    $(TOP)/frameworks/base/media/libmediaplayerservice \
-    $(TOP)/frameworks/base/media/libstagefright \
-    $(TOP)/frameworks/base/media/libstagefright/include \
-    $(TOP)/frameworks/base/media/libstagefright/rtsp \
-    $(JNI_H_INCLUDE) \
-    $(TOP)/frameworks/native/include/media/editor \
-    $(TOP)/frameworks/base/core/jni/mediaeditor \
-    $(TOP)/frameworks/av/libvideoeditor/vss/inc \
-    $(TOP)/frameworks/av/libvideoeditor/vss/common/inc \
-    $(TOP)/frameworks/av/libvideoeditor/vss/mcs/inc \
-    $(TOP)/frameworks/av/libvideoeditor/vss/stagefrightshells/inc \
-    $(TOP)/frameworks/av/libvideoeditor/lvpp \
-    $(TOP)/frameworks/av/libvideoeditor/osal/inc \
-    $(TOP)/frameworks/native/include/media/openmax
-
-LOCAL_SHARED_LIBRARIES := \
-    libandroid_runtime \
-    libaudioutils \
-    libbinder \
-    libcutils \
-    liblog \
-    libdl \
-    libgui \
-    libmedia \
-    libnativehelper \
-    libstagefright \
-    libstagefright_foundation \
-    libstagefright_omx \
-    libutils \
-    libvideoeditor_core \
-    libvideoeditor_osal \
-    libvideoeditor_videofilters \
-    libvideoeditorplayer \
-
-
-LOCAL_CFLAGS += \
-    -DUSE_STAGEFRIGHT_CODECS \
-    -DUSE_STAGEFRIGHT_AUDIODEC \
-    -DUSE_STAGEFRIGHT_VIDEODEC \
-    -DUSE_STAGEFRIGHT_AUDIOENC \
-    -DUSE_STAGEFRIGHT_VIDEOENC \
-    -DUSE_STAGEFRIGHT_READERS \
-    -DUSE_STAGEFRIGHT_3GPP_READER
-
-LOCAL_MODULE:= libvideoeditor_jni
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/jni/mediaeditor/MODULE_LICENSE_APACHE2 b/media/jni/mediaeditor/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/jni/mediaeditor/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/jni/mediaeditor/NOTICE b/media/jni/mediaeditor/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/jni/mediaeditor/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/media/jni/mediaeditor/VideoBrowserInternal.h b/media/jni/mediaeditor/VideoBrowserInternal.h
deleted file mode 100644
index f4eaab8..0000000
--- a/media/jni/mediaeditor/VideoBrowserInternal.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef VIDEO_BROWSER_INTERNAL_H
-#define VIDEO_BROWSER_INTERNAL_H
-
-#include "VideoBrowserMain.h"
-
-#include "M4READER_Common.h"
-#include "M4DECODER_Common.h"
-
-
-#define VIDEO_BROWSER_BGR565
-
-/*---------------------------- MACROS ----------------------------*/
-#define CHECK_PTR(fct, p, err, errValue) \
-{ \
-    if (M4OSA_NULL == p) \
-    { \
-        err = errValue ; \
-        M4OSA_TRACE1_1("" #fct "(L%d): " #p " is NULL, returning " #errValue "", __LINE__) ; \
-        goto fct##_cleanUp; \
-    } \
-}
-
-#define CHECK_ERR(fct, err) \
-{ \
-    if (M4OSA_ERR_IS_ERROR(err)) \
-    { \
-        M4OSA_TRACE1_2("" #fct "(L%d): ERROR 0x%.8x returned", __LINE__,err) ; \
-        goto fct##_cleanUp; \
-    } \
-    else if (M4OSA_ERR_IS_WARNING(err)) \
-    { \
-        M4OSA_TRACE2_2("" #fct "(L%d): WARNING 0x%.8x returned", __LINE__,err) ; \
-    } \
-}
-
-#define CHECK_STATE(fct, state, pC) \
-{ \
-    if (state != pC->m_state) \
-    { \
-        M4OSA_TRACE1_1("" #fct " called in bad state %d", pC->m_state) ; \
-        err = M4ERR_STATE ; \
-        goto fct##_cleanUp; \
-    } \
-}
-
-#define SAFE_FREE(p) \
-{ \
-    if (M4OSA_NULL != p) \
-    { \
-        free(p) ; \
-        p = M4OSA_NULL ; \
-    } \
-}
-
-/*--- Video Browser state ---*/
-typedef enum
-{
-    VideoBrowser_kVBCreating,
-    VideoBrowser_kVBOpened,
-    VideoBrowser_kVBBrowsing
-} VideoBrowser_videoBrowerState;
-
-
-/*--- Video Browser execution context. ---*/
-typedef struct
-{
-    VideoBrowser_videoBrowerState       m_state ;
-    VideoBrowser_videoBrowerDrawMode    m_drawmode;
-
-    M4OSA_Context                       g_hbmp2;
-    M4OSA_Context                       dc;
-    M4OSA_Int16*                        g_bmPixels2;
-
-    /*--- Reader parameters ---*/
-    M4OSA_FileReadPointer               m_fileReadPtr;
-    M4READER_GlobalInterface*           m_3gpReader ;
-    M4READER_DataInterface*             m_3gpData ;
-    M4READER_MediaType                  m_mediaType ;
-    M4OSA_Context                       m_pReaderCtx ;
-
-    M4_StreamHandler*                   m_pStreamHandler ;
-    M4_AccessUnit                       m_accessUnit ;
-
-    /*--- Decoder parameters ---*/
-    M4DECODER_VideoInterface*           m_pDecoder ;
-    M4OSA_Context                       m_pDecoderCtx ;
-
-    /*--- Common display parameters ---*/
-    M4OSA_UInt32                        m_x ;
-    M4OSA_UInt32                        m_y ;
-    M4VIFI_ImagePlane                   m_outputPlane[3] ;
-
-    /*--- Current browsing time ---*/
-    M4OSA_UInt32                        m_currentCTS ;
-
-    /*--- Platform dependent display parameters ---*/
-    M4OSA_Context                       m_pCoreContext ;
-
-    /*--- Callback function settings ---*/
-    videoBrowser_Callback               m_pfCallback;
-    M4OSA_Void*                         m_pCallbackUserData;
-
-    /*--- Codec Loader core context ---*/
-    M4OSA_Context                       m_pCodecLoaderContext;
-
-    /*--- Required color type ---*/
-    VideoBrowser_VideoColorType         m_frameColorType;
-
-} VideoBrowserContext;
-
-#endif /* VIDEO_BROWSER_INTERNAL_H */
diff --git a/media/jni/mediaeditor/VideoBrowserMain.c b/media/jni/mediaeditor/VideoBrowserMain.c
deleted file mode 100644
index c6c6000..0000000
--- a/media/jni/mediaeditor/VideoBrowserMain.c
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "VideoEditorVideoDecoder.h"
-#include "VideoEditor3gpReader.h"
-
-#include <utils/Log.h>
-#include "VideoBrowserInternal.h"
-#include "LVOSA_FileReader_optim.h"
-
-//#define M4OSA_TRACE_LEVEL 1
-#if (M4OSA_TRACE_LEVEL >= 1)
-#undef M4OSA_TRACE1_0
-#undef M4OSA_TRACE1_1
-#undef M4OSA_TRACE1_2
-#undef M4OSA_TRACE1_3
-
-#define M4OSA_TRACE1_0(a)       __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a);
-#define M4OSA_TRACE1_1(a,b)     __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b);
-#define M4OSA_TRACE1_2(a,b,c)   __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c);
-#define M4OSA_TRACE1_3(a,b,c,d) __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c,d);
-#endif
-
-/******************************************************************************
- * M4OSA_ERR     videoBrowserSetWindow(
- *          M4OSA_Context pContext, M4OSA_UInt32 x,
- *          M4OSA_UInt32 y, M4OSA_UInt32 dx, M4OSA_UInt32 dy);
- * @brief        This function sets the size and the position of the display.
- * @param        pContext       (IN) : Video Browser context
- * @param        pPixelArray    (IN) : Array to hold the video frame.
- * @param        x              (IN) : Horizontal position of the top left
- *                                     corner
- * @param        y              (IN) : Vertical position of the top left corner
- * @param        dx             (IN) : Width of the display window
- * @param        dy             (IN) : Height of the video window
- * @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
- ******************************************************************************/
-M4OSA_ERR videoBrowserSetWindow(
-        M4OSA_Context pContext,
-        M4OSA_Int32 *pPixelArray,
-        M4OSA_UInt32 x, M4OSA_UInt32 y,
-        M4OSA_UInt32 dx, M4OSA_UInt32 dy)
-{
-    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
-    M4OSA_ERR err = M4NO_ERROR;
-
-    M4OSA_TRACE2_5("videoBrowserSetWindow: entering with 0x%x %d %d %d %d ",
-            pContext, x, y, dx, dy);
-
-    /*--- Sanity checks ---*/
-    CHECK_PTR(videoBrowserSetWindow, pContext, err, M4ERR_PARAMETER);
-    CHECK_PTR(videoBrowserSetWindow, pPixelArray, err, M4ERR_PARAMETER);
-    CHECK_STATE(videoBrowserSetWindow, VideoBrowser_kVBOpened, pC);
-
-    pC->m_outputPlane[0].u_topleft = 0;
-
-    pC->m_outputPlane[0].u_height = dy;
-    pC->m_outputPlane[0].u_width = dx;
-    pC->m_x = x;
-    pC->m_y = y;
-
-    if (pC->m_frameColorType == VideoBrowser_kGB565) {
-        pC->m_outputPlane[0].u_stride = pC->m_outputPlane[0].u_width << 1;
-        pC->m_outputPlane[0].pac_data = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(
-            pC->m_outputPlane[0].u_stride * pC->m_outputPlane[0].u_height,
-            VIDEOBROWSER, (M4OSA_Char *)"output plane");
-
-        CHECK_PTR(videoBrowserSetWindow,
-            pC->m_outputPlane[0].pac_data, err, M4ERR_ALLOC);
-    }
-    else if (pC->m_frameColorType == VideoBrowser_kYUV420) {
-        pC->m_outputPlane[0].u_stride = pC->m_outputPlane[0].u_width;
-        pC->m_outputPlane[1].u_height = pC->m_outputPlane[0].u_height >> 1;
-        pC->m_outputPlane[1].u_width = pC->m_outputPlane[0].u_width >> 1;
-        pC->m_outputPlane[1].u_topleft = 0;
-        pC->m_outputPlane[1].u_stride = pC->m_outputPlane[1].u_width;
-
-        pC->m_outputPlane[2].u_height = pC->m_outputPlane[0].u_height >> 1;
-        pC->m_outputPlane[2].u_width = pC->m_outputPlane[0].u_width >> 1;
-        pC->m_outputPlane[2].u_topleft = 0;
-        pC->m_outputPlane[2].u_stride = pC->m_outputPlane[2].u_width;
-
-        pC->m_outputPlane[0].pac_data = (M4OSA_UInt8*)pPixelArray;
-
-        CHECK_PTR(videoBrowserSetWindow,
-            pC->m_outputPlane[0].pac_data, err, M4ERR_ALLOC);
-
-        pC->m_outputPlane[1].pac_data =
-            pC->m_outputPlane[0].pac_data +
-            (pC->m_outputPlane[0].u_stride * pC->m_outputPlane[0].u_height);
-
-        pC->m_outputPlane[2].pac_data =
-            pC->m_outputPlane[1].pac_data +
-            (pC->m_outputPlane[1].u_stride * pC->m_outputPlane[1].u_height);
-    }
-
-
-    M4OSA_TRACE2_0("videoBrowserSetWindow returned NO ERROR");
-    return M4NO_ERROR;
-
-videoBrowserSetWindow_cleanUp:
-
-    M4OSA_TRACE2_1("videoBrowserSetWindow returned 0x%x", err);
-    return err;
-}
-
-/******************************************************************************
-* @brief  This function allocates the resources needed for browsing a video file
-* @param   ppContext     (OUT): Pointer on a context filled by this function.
-* @param   pURL          (IN) : Path of File to browse
-* @param   DrawMode      (IN) : Indicate which method is used to draw (Direct draw etc...)
-* @param   pfCallback    (IN) : Callback function to be called when a frame must be displayed
-* @param   pCallbackData (IN) : User defined data that will be passed as parameter of the callback
-* @param   clrType       (IN) : Required color type.
-* @return  M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
-******************************************************************************/
-M4OSA_ERR videoBrowserCreate(
-        M4OSA_Context* ppContext,
-        M4OSA_Char* pURL,
-        M4OSA_UInt32 DrawMode,
-        M4OSA_FileReadPointer* ptrF,
-        videoBrowser_Callback pfCallback,
-        M4OSA_Void* pCallbackData,
-        VideoBrowser_VideoColorType clrType)
-{
-    VideoBrowserContext* pContext = M4OSA_NULL;
-    M4READER_MediaFamily mediaFamily = M4READER_kMediaFamilyUnknown;
-    M4_StreamHandler* pStreamHandler = M4OSA_NULL;
-    M4_VideoStreamHandler* pVideoStreamHandler = M4OSA_NULL;
-    M4DECODER_VideoType decoderType;
-    M4DECODER_OutputFilter FilterOption;
-
-    M4OSA_Bool deb = M4OSA_TRUE;
-    M4OSA_ERR err = M4NO_ERROR;
-
-    M4OSA_TRACE1_2(
-        "videoBrowserCreate: entering with 0x%x 0x%x", ppContext, pURL);
-
-    /*--- Sanity checks ---*/
-    CHECK_PTR(videoBrowserCreate, ppContext, err, M4ERR_PARAMETER);
-    *ppContext = M4OSA_NULL ;
-    CHECK_PTR(videoBrowserCreate, pURL,  err, M4ERR_PARAMETER);
-
-    /*--- Create context ---*/
-    pContext = (VideoBrowserContext*)M4OSA_32bitAlignedMalloc(
-            sizeof(VideoBrowserContext),
-            VIDEOBROWSER, (M4OSA_Char*)"Video browser context");
-
-    CHECK_PTR(videoBrowserCreate, pContext,err, M4ERR_ALLOC);
-    memset((void *)pContext, 0,sizeof(VideoBrowserContext));
-
-    /*--- Initialize the context parameters ---*/
-    pContext->m_state = VideoBrowser_kVBCreating ;
-    pContext->m_frameColorType = clrType;
-
-    /*--- Copy the file reader functions ---*/
-    memcpy((void *)&pContext->m_fileReadPtr,
-                 (void *)ptrF,
-                 sizeof(M4OSA_FileReadPointer)) ;
-
-    /* PR#SP00013 DGR bug 13 : first frame is not visible */
-    pContext->m_drawmode = DrawMode;
-
-
-    /* Retrieve the 3gp reader interface */
-    VideoEditor3gpReader_getInterface(&pContext->m_mediaType,
-        &pContext->m_3gpReader, &pContext->m_3gpData);
-
-    CHECK_PTR(videoBrowserCreate, pContext->m_3gpReader,  err, M4ERR_ALLOC);
-    CHECK_PTR(videoBrowserCreate, pContext->m_3gpData,    err, M4ERR_ALLOC);
-
-    /*--- Create the file reader ---*/
-    err = pContext->m_3gpReader->m_pFctCreate(&pContext->m_pReaderCtx);
-    CHECK_ERR(videoBrowserCreate, err);
-    CHECK_PTR(videoBrowserCreate, pContext->m_pReaderCtx, err, M4ERR_ALLOC);
-    pContext->m_3gpData->m_readerContext = pContext->m_pReaderCtx;
-
-    /*--- Set the OSAL file reader functions ---*/
-    err = pContext->m_3gpReader->m_pFctSetOption(
-            pContext->m_pReaderCtx,
-            M4READER_kOptionID_SetOsaFileReaderFctsPtr,
-            (M4OSA_DataOption)(&pContext->m_fileReadPtr));
-
-    CHECK_ERR(videoBrowserCreate, err) ;
-
-    /*--- Open the file ---*/
-    err = pContext->m_3gpReader->m_pFctOpen(pContext->m_pReaderCtx, pURL);
-    CHECK_ERR(videoBrowserCreate, err) ;
-
-    /*--- Try to find a video stream ---*/
-    while (err == M4NO_ERROR)
-    {
-        err = pContext->m_3gpReader->m_pFctGetNextStream(
-                pContext->m_pReaderCtx, &mediaFamily, &pStreamHandler);
-
-        /*in case we found a bifs stream or something else...*/
-        if ((err == (M4OSA_UInt32)M4ERR_READER_UNKNOWN_STREAM_TYPE) ||
-            (err == (M4OSA_UInt32)M4WAR_TOO_MUCH_STREAMS))
-        {
-            err = M4NO_ERROR;
-            continue;
-        }
-
-        if (err != M4WAR_NO_MORE_STREAM)
-        {
-            if (M4READER_kMediaFamilyVideo != mediaFamily)
-            {
-                err = M4NO_ERROR;
-                continue;
-            }
-
-            pContext->m_pStreamHandler = pStreamHandler;
-
-            err = pContext->m_3gpReader->m_pFctReset(
-                    pContext->m_pReaderCtx, pContext->m_pStreamHandler);
-
-            CHECK_ERR(videoBrowserCreate, err);
-
-            err = pContext->m_3gpReader->m_pFctFillAuStruct(
-                    pContext->m_pReaderCtx,
-                    pContext->m_pStreamHandler,
-                    &pContext->m_accessUnit);
-
-            CHECK_ERR(videoBrowserCreate, err);
-
-            pVideoStreamHandler =
-                (M4_VideoStreamHandler*)pContext->m_pStreamHandler;
-
-            switch (pContext->m_pStreamHandler->m_streamType)
-            {
-                case M4DA_StreamTypeVideoMpeg4:
-                case M4DA_StreamTypeVideoH263:
-                {
-                    pContext->m_pCodecLoaderContext = M4OSA_NULL;
-                    decoderType = M4DECODER_kVideoTypeMPEG4;
-
-#ifdef USE_SOFTWARE_DECODER
-                        err = VideoEditorVideoDecoder_getSoftwareInterface_MPEG4(
-                            &decoderType, &pContext->m_pDecoder);
-#else
-                        err = VideoEditorVideoDecoder_getInterface_MPEG4(
-                            &decoderType, (void **)&pContext->m_pDecoder);
-#endif
-                    CHECK_ERR(videoBrowserCreate, err) ;
-
-                    err = pContext->m_pDecoder->m_pFctCreate(
-                            &pContext->m_pDecoderCtx,
-                            pContext->m_pStreamHandler,
-                            pContext->m_3gpReader,
-                            pContext->m_3gpData,
-                            &pContext->m_accessUnit,
-                            pContext->m_pCodecLoaderContext) ;
-
-                    CHECK_ERR(videoBrowserCreate, err) ;
-                }
-                break;
-
-                case M4DA_StreamTypeVideoMpeg4Avc:
-                {
-                    pContext->m_pCodecLoaderContext = M4OSA_NULL;
-
-                    decoderType = M4DECODER_kVideoTypeAVC;
-
-#ifdef USE_SOFTWARE_DECODER
-                        err = VideoEditorVideoDecoder_getSoftwareInterface_H264(
-                            &decoderType, &pContext->m_pDecoder);
-#else
-                        err = VideoEditorVideoDecoder_getInterface_H264(
-                            &decoderType, (void **)&pContext->m_pDecoder);
-#endif
-                   CHECK_ERR(videoBrowserCreate, err) ;
-
-                    err = pContext->m_pDecoder->m_pFctCreate(
-                            &pContext->m_pDecoderCtx,
-                            pContext->m_pStreamHandler,
-                            pContext->m_3gpReader,
-                            pContext->m_3gpData,
-                            &pContext->m_accessUnit,
-                            pContext->m_pCodecLoaderContext) ;
-
-                    CHECK_ERR(videoBrowserCreate, err) ;
-                }
-                break;
-
-                default:
-                    err = M4ERR_VB_MEDIATYPE_NOT_SUPPORTED;
-                    goto videoBrowserCreate_cleanUp;
-            }
-        }
-    }
-
-    if (err == M4WAR_NO_MORE_STREAM)
-    {
-        err = M4NO_ERROR ;
-    }
-
-    if (M4OSA_NULL == pContext->m_pStreamHandler)
-    {
-        err = M4ERR_VB_NO_VIDEO ;
-        goto videoBrowserCreate_cleanUp ;
-    }
-
-    err = pContext->m_pDecoder->m_pFctSetOption(
-            pContext->m_pDecoderCtx,
-            M4DECODER_kOptionID_DeblockingFilter,
-            (M4OSA_DataOption)&deb);
-
-    if (err == M4WAR_DEBLOCKING_FILTER_NOT_IMPLEMENTED)
-    {
-        err = M4NO_ERROR;
-    }
-    CHECK_ERR(videoBrowserCreate, err);
-
-    FilterOption.m_pFilterUserData = M4OSA_NULL;
-
-
-    if (pContext->m_frameColorType == VideoBrowser_kGB565) {
-        FilterOption.m_pFilterFunction =
-            (M4OSA_Void*)M4VIFI_ResizeBilinearYUV420toBGR565;
-    }
-    else if (pContext->m_frameColorType == VideoBrowser_kYUV420) {
-        FilterOption.m_pFilterFunction =
-            (M4OSA_Void*)M4VIFI_ResizeBilinearYUV420toYUV420;
-    }
-    else {
-        err = M4ERR_PARAMETER;
-        goto videoBrowserCreate_cleanUp;
-    }
-
-    err = pContext->m_pDecoder->m_pFctSetOption(
-            pContext->m_pDecoderCtx,
-            M4DECODER_kOptionID_OutputFilter,
-            (M4OSA_DataOption)&FilterOption);
-
-    CHECK_ERR(videoBrowserCreate, err);
-
-    /* store the callback details */
-    pContext->m_pfCallback = pfCallback;
-    pContext->m_pCallbackUserData = pCallbackData;
-    /* store the callback details */
-
-    pContext->m_state = VideoBrowser_kVBOpened;
-    *ppContext = pContext;
-
-    M4OSA_TRACE1_0("videoBrowserCreate returned NO ERROR");
-    return M4NO_ERROR;
-
-videoBrowserCreate_cleanUp:
-
-    if (M4OSA_NULL != pContext)
-    {
-        if (M4OSA_NULL != pContext->m_pDecoderCtx)
-        {
-            pContext->m_pDecoder->m_pFctDestroy(pContext->m_pDecoderCtx);
-            pContext->m_pDecoderCtx = M4OSA_NULL;
-        }
-
-        if (M4OSA_NULL != pContext->m_pReaderCtx)
-        {
-            pContext->m_3gpReader->m_pFctClose(pContext->m_pReaderCtx);
-            pContext->m_3gpReader->m_pFctDestroy(pContext->m_pReaderCtx);
-            pContext->m_pReaderCtx = M4OSA_NULL;
-        }
-        SAFE_FREE(pContext->m_pDecoder);
-        SAFE_FREE(pContext->m_3gpReader);
-        SAFE_FREE(pContext->m_3gpData);
-        SAFE_FREE(pContext);
-    }
-
-    M4OSA_TRACE2_1("videoBrowserCreate returned 0x%x", err);
-    return err;
-}
-
-/******************************************************************************
-* M4OSA_ERR     videoBrowserCleanUp(M4OSA_Context pContext);
-* @brief        This function frees the resources needed for browsing a
-*               video file.
-* @param        pContext     (IN) : Video browser context
-* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE
-******************************************************************************/
-M4OSA_ERR videoBrowserCleanUp(M4OSA_Context pContext)
-{
-    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
-    M4OSA_ERR err = M4NO_ERROR;
-
-    M4OSA_TRACE2_1("videoBrowserCleanUp: entering with 0x%x", pContext);
-
-    /*--- Sanity checks ---*/
-    CHECK_PTR(videoBrowserCleanUp, pContext, err, M4ERR_PARAMETER);
-
-    if (M4OSA_NULL != pC->m_pDecoderCtx)
-    {
-        pC->m_pDecoder->m_pFctDestroy(pC->m_pDecoderCtx);
-        pC->m_pDecoderCtx = M4OSA_NULL ;
-    }
-
-    if (M4OSA_NULL != pC->m_pReaderCtx)
-    {
-        pC->m_3gpReader->m_pFctClose(pC->m_pReaderCtx) ;
-        pC->m_3gpReader->m_pFctDestroy(pC->m_pReaderCtx);
-        pC->m_pReaderCtx = M4OSA_NULL;
-    }
-
-    SAFE_FREE(pC->m_pDecoder);
-    SAFE_FREE(pC->m_3gpReader);
-    SAFE_FREE(pC->m_3gpData);
-
-    if (pC->m_frameColorType != VideoBrowser_kYUV420) {
-        SAFE_FREE(pC->m_outputPlane[0].pac_data);
-    }
-    SAFE_FREE(pC);
-
-    M4OSA_TRACE2_0("videoBrowserCleanUp returned NO ERROR");
-    return M4NO_ERROR;
-
-videoBrowserCleanUp_cleanUp:
-
-    M4OSA_TRACE2_1("videoBrowserCleanUp returned 0x%x", err);
-    return err;
-}
-/******************************************************************************
-* M4OSA_ERR     videoBrowserPrepareFrame(
-*       M4OSA_Context pContext, M4OSA_UInt32* pTime);
-* @brief        This function prepares the frame.
-* @param        pContext     (IN) : Video browser context
-* @param        pTime        (IN/OUT) : Pointer on the time to reach. Updated
-*                                       by this function with the reached time
-* @param        tolerance    (IN) :  We may decode an earlier frame within the tolerance.
-*                                    The time difference is specified in milliseconds.
-* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
-******************************************************************************/
-M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime,
-    M4OSA_UInt32 tolerance)
-{
-    VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
-    M4OSA_ERR err = M4NO_ERROR;
-    M4OSA_UInt32 targetTime = 0;
-    M4_MediaTime timeMS = 0;
-    M4OSA_Bool bJumpNeeded = M4OSA_FALSE;
-
-    /*--- Sanity checks ---*/
-    CHECK_PTR(videoBrowserPrepareFrame, pContext, err, M4ERR_PARAMETER);
-    CHECK_PTR(videoBrowserPrepareFrame, pTime,  err, M4ERR_PARAMETER);
-
-    targetTime = *pTime ;
-
-    /*--- Check the state, if this is the first call to this function
-          we move to the state "browsing" ---*/
-    if (VideoBrowser_kVBOpened == pC->m_state)
-    {
-        pC->m_state = VideoBrowser_kVBBrowsing;
-    }
-    else if (VideoBrowser_kVBBrowsing != pC->m_state)
-    {
-        err = M4ERR_STATE ;
-        goto videoBrowserPrepareFrame_cleanUp;
-    }
-
-    // If we jump backward or forward to a time greater than current position by
-    // 85ms (~ 2 frames), we want to jump.
-    if (pC->m_currentCTS == 0 ||
-        targetTime < pC->m_currentCTS ||
-        targetTime > (pC->m_currentCTS + 85))
-    {
-        bJumpNeeded = M4OSA_TRUE;
-    }
-
-    timeMS = (M4_MediaTime)targetTime;
-    err = pC->m_pDecoder->m_pFctDecode(
-        pC->m_pDecoderCtx, &timeMS, bJumpNeeded, tolerance);
-
-    if ((err != M4NO_ERROR) && (err != M4WAR_NO_MORE_AU))
-    {
-        return err;
-    }
-
-    err = pC->m_pDecoder->m_pFctRender(
-        pC->m_pDecoderCtx, &timeMS, pC->m_outputPlane, M4OSA_TRUE);
-
-    if (M4WAR_VIDEORENDERER_NO_NEW_FRAME == err)
-    {
-        return err;
-    }
-    CHECK_ERR(videoBrowserPrepareFrame, err) ;
-
-    pC->m_currentCTS = (M4OSA_UInt32)timeMS;
-
-    *pTime = pC->m_currentCTS;
-
-    return M4NO_ERROR;
-
-videoBrowserPrepareFrame_cleanUp:
-
-    if ((M4WAR_INVALID_TIME == err) || (M4WAR_NO_MORE_AU == err))
-    {
-        err = M4NO_ERROR;
-    }
-    else if (M4OSA_NULL != pC)
-    {
-        pC->m_currentCTS = 0;
-    }
-
-    M4OSA_TRACE2_1("videoBrowserPrepareFrame returned 0x%x", err);
-    return err;
-}
-
-/******************************************************************************
-* M4OSA_ERR     videoBrowserDisplayCurrentFrame(M4OSA_Context pContext);
-* @brief        This function displays the current frame.
-* @param        pContext     (IN) : Video browser context
-* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
-******************************************************************************/
-M4OSA_ERR videoBrowserDisplayCurrentFrame(M4OSA_Context pContext)
-{
-    VideoBrowserContext* pC = (VideoBrowserContext*)pContext ;
-    M4OSA_ERR err = M4NO_ERROR ;
-
-    /*--- Sanity checks ---*/
-    CHECK_PTR(videoBrowserDisplayCurrentFrame, pContext, err, M4ERR_PARAMETER);
-
-    // Request display of the frame
-    pC->m_pfCallback((M4OSA_Context) pC,             // VB context
-        VIDEOBROWSER_DISPLAY_FRAME,                  // action requested
-        M4NO_ERROR,                                  // error code
-        (M4OSA_Void*) &(pC->m_outputPlane[0]),       // image to be displayed
-        (M4OSA_Void*) pC->m_pCallbackUserData);      // user-provided data
-
-#ifdef DUMPTOFILE
-    {
-        M4OSA_Context fileContext;
-        M4OSA_Char* fileName = "/sdcard/textBuffer_RGB565.rgb";
-        M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,
-            M4OSA_kFileWrite | M4OSA_kFileCreate);
-
-        M4OSA_fileWriteData(fileContext,
-            (M4OSA_MemAddr8) pC->m_outputPlane[0].pac_data,
-            pC->m_outputPlane[0].u_height*pC->m_outputPlane[0].u_width*2);
-
-        M4OSA_fileWriteClose(fileContext);
-    }
-#endif
-
-    M4OSA_TRACE2_0("videoBrowserDisplayCurrentFrame returned NO ERROR") ;
-    return M4NO_ERROR;
-
-videoBrowserDisplayCurrentFrame_cleanUp:
-
-    M4OSA_TRACE2_1("videoBrowserDisplayCurrentFrame returned 0x%x", err) ;
-    return err;
-}
diff --git a/media/jni/mediaeditor/VideoBrowserMain.h b/media/jni/mediaeditor/VideoBrowserMain.h
deleted file mode 100644
index 00b5e05..0000000
--- a/media/jni/mediaeditor/VideoBrowserMain.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef VIDEO_BROWSER_MAIN_H
-#define VIDEO_BROWSER_MAIN_H
-
-/**
- ************************************************************************
- * @file    VideoBrowserMain.h
- * @brief   Video browser Interface functions
- ************************************************************************
-*/
-
-#define VIDEOBROWSER    0x423
-
-#include "M4OSA_Memory.h"
-#include "M4OSA_CharStar.h"
-#include "M4OSA_OptionID.h"
-#include "M4OSA_Debug.h"
-#include "M4VIFI_FiltersAPI.h"
-#include "M4OSA_FileReader.h"
-
-
-/**
- ************************************************************************
- * @brief    Error codes definition.
- * @note    These value are the Browser engine specific error codes.
- ************************************************************************
-*/
-#define M4ERR_VB_MEDIATYPE_NOT_SUPPORTED    M4OSA_ERR_CREATE(M4_ERR, VIDEOBROWSER, 0x01)
-#define M4ERR_VB_NO_VIDEO                   M4OSA_ERR_CREATE(M4_ERR, VIDEOBROWSER, 0x02)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- *  Video Browser draw mode, extension for angle based bliting can be done
- */
-typedef enum
-{
-    VideoBrowser_kVBNormalBliting
-} VideoBrowser_videoBrowerDrawMode;
-
-
-/*--- Video Browser output frame color type ---*/
-typedef enum
-{
-    VideoBrowser_kYUV420,
-    VideoBrowser_kGB565
-} VideoBrowser_VideoColorType;
-
-/**
- ************************************************************************
- * enumeration  VideoBrowser_Notification
- * @brief       Video Browser notification type.
- * @note        This callback mechanism must be used to wait the completion of an asynchronous
- * operation, before calling another API function.
- ************************************************************************
-*/
-typedef enum
-{
-    /**
-     * A frame is ready to be displayed, it should be displayed in the callback function
-     * pCbData type = M4VIFI_ImagePlane*
-     */
-    VIDEOBROWSER_DISPLAY_FRAME            = 0x00000001,
-    VIDEOBROWSER_NOTIFICATION_NONE        = 0xffffffff
-}VideoBrowser_Notification;
-
-
-/**
- ************************************************************************
- * @brief    videoBrowser_Callback type definition
- * @param    pInstance          (IN) Video Browser context.
- * @param    notificationID     (IN) Id of the callback which generated the error
- * @param    errCode            (IN) Error code from the core
- * @param    pCbData            (IN) pointer to data associated wit the callback.
- * @param    pCbUserData        (IN) pointer to application user data passed in init.
- * @note    This callback mechanism is used to request display of an image
- ************************************************************************
-*/
-typedef M4OSA_Void (*videoBrowser_Callback) (M4OSA_Context pInstance,
-                                        VideoBrowser_Notification notificationID,
-                                        M4OSA_ERR errCode,
-                                        M4OSA_Void* pCbData,
-                                        M4OSA_Void* pCallbackUserData);
-
-
-/******************************************************************************
-* @brief   This function allocates the resources needed for browsing a video file.
-* @param   ppContext     (OUT): Pointer on a context filled by this function.
-* @param   pURL          (IN) : Path of File to browse
-* @param   DrawMode      (IN) : Indicate which method is used to draw (Direct draw etc...)
-* @param   pfCallback    (IN) : Callback function to be called when a frame must be displayed
-* @param   pCallbackData (IN)  : User defined data that will be passed as parameter of the callback
-* @param   clrType       (IN) : Required color type.
-* @return  M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
-******************************************************************************/
-M4OSA_ERR videoBrowserCreate(M4OSA_Context* ppContext, M4OSA_Char* pURL,
-                                        M4OSA_UInt32 DrawMode,
-                                        M4OSA_FileReadPointer* ptrF,
-                                        videoBrowser_Callback pfCallback,
-                                        M4OSA_Void* pCallbackData,
-                                        VideoBrowser_VideoColorType clrType);
-
-/******************************************************************************
-* @brief        This function frees the resources needed for browsing a video file.
-* @param        pContext     (IN) : Video browser context
-* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE
-******************************************************************************/
-M4OSA_ERR videoBrowserCleanUp(M4OSA_Context pContext) ;
-
-
-/******************************************************************************
-* @brief        This function allocates the resources needed for browsing a video file.
-* @param        pContext  (IN)      : Video browser context
-* @param        pTime     (IN/OUT)  : Pointer on the time to reach. Updated by
-*                                     this function with the reached time
-* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
-******************************************************************************/
-M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime,
-        M4OSA_UInt32 tolerance);
-
-/******************************************************************************
-* @brief        This function sets the size and the position of the display.
-* @param        pContext     (IN) : Video Browser context
-* @param        pixelArray   (IN) : Array to hold the video frame.
-* @param        x            (IN) : Horizontal position of the top left corner
-* @param        y            (IN) : Vertical position of the top left corner
-* @param        dx           (IN) : Width of the display window
-* @param        dy           (IN) : Height of the video window
-* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
-******************************************************************************/
-M4OSA_ERR videoBrowserSetWindow(M4OSA_Context pContext, M4OSA_Int32* pixelArray,
-                                M4OSA_UInt32 x, M4OSA_UInt32 y,
-                                M4OSA_UInt32 dx, M4OSA_UInt32 dy);
-
-/******************************************************************************
-* @brief        This function displays the current frame.
-* @param        pContext     (IN) : Video browser context
-* @return       M4NO_ERROR / M4ERR_PARAMETER / M4ERR_STATE / M4ERR_ALLOC
-******************************************************************************/
-M4OSA_ERR videoBrowserDisplayCurrentFrame(M4OSA_Context pContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* VIDEO_BROWSER_MAIN_H */
diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp
deleted file mode 100644
index d29fad3..0000000
--- a/media/jni/mediaeditor/VideoEditorClasses.cpp
+++ /dev/null
@@ -1,3146 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VideoEditorClasses"
-
-#include <VideoEditorClasses.h>
-#include <VideoEditorJava.h>
-#include <VideoEditorLogging.h>
-#include <VideoEditorOsal.h>
-
-extern "C" {
-#include <M4OSA_Clock.h>
-#include <M4OSA_CharStar.h>
-#include <M4OSA_FileCommon.h>
-#include <M4OSA_FileReader.h>
-#include <M4OSA_FileWriter.h>
-#include <M4OSA_Memory.h>
-#include <M4OSA_Debug.h>
-#include <M4OSA_Thread.h>
-#include <M4VSS3GPP_API.h>
-#include <M4xVSS_API.h>
-#include <M4VSS3GPP_ErrorCodes.h>
-#include <M4MCS_ErrorCodes.h>
-#include <M4READER_Common.h>
-#include <M4WRITER_common.h>
-#include <M4DECODER_Common.h>
-};
-
-#define VIDEOEDIT_PROP_JAVA_RESULT_STRING_MAX                     (128)
-
-#define VIDEOEDIT_JAVA__RESULT_STRING_MAX                     (128)
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(AudioEffect)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NONE",     M4VSS3GPP_kAudioEffectType_None),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_IN",  M4VSS3GPP_kAudioEffectType_FadeIn),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_OUT", M4VSS3GPP_kAudioEffectType_FadeOut)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(AudioEffect, AUDIO_EFFECT_CLASS_NAME, M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(AudioFormat)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NO_AUDIO",          M4VIDEOEDITING_kNoneAudio),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("AMR_NB",            M4VIDEOEDITING_kAMR_NB),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("AAC",               M4VIDEOEDITING_kAAC),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("AAC_PLUS",          M4VIDEOEDITING_kAACplus),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ENHANCED_AAC_PLUS", M4VIDEOEDITING_keAACplus),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("MP3",               M4VIDEOEDITING_kMP3),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("EVRC",              M4VIDEOEDITING_kEVRC),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("PCM",               M4VIDEOEDITING_kPCM),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NULL_AUDIO",        M4VIDEOEDITING_kNullAudio),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("UNSUPPORTED_AUDIO", M4VIDEOEDITING_kUnsupportedAudio)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(AudioFormat, AUDIO_FORMAT_CLASS_NAME, M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(AudioSamplingFrequency)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_DEFAULT", M4VIDEOEDITING_kDefault_ASF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_8000",    M4VIDEOEDITING_k8000_ASF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_16000",   M4VIDEOEDITING_k16000_ASF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_22050",   M4VIDEOEDITING_k22050_ASF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_24000",   M4VIDEOEDITING_k24000_ASF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_32000",   M4VIDEOEDITING_k32000_ASF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_44100",   M4VIDEOEDITING_k44100_ASF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FREQ_48000",   M4VIDEOEDITING_k48000_ASF)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(AudioSamplingFrequency,AUDIO_SAMPLING_FREQUENCY_CLASS_NAME,
-                                     M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(AudioTransition)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NONE",       M4VSS3GPP_kAudioTransitionType_None),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("CROSS_FADE", M4VSS3GPP_kAudioTransitionType_CrossFade)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(AudioTransition, AUDIO_TRANSITION_CLASS_NAME, M4OSA_NULL,
-                                     M4OSA_NULL)
-
-
-static const char*
-videoEditClasses_getUnknownBitrateString(int bitrate)
-{
-    static char string[VIDEOEDIT_JAVA__RESULT_STRING_MAX] = "";
-
-    M4OSA_chrSPrintf((M4OSA_Char *)string, sizeof(string) - 1, (M4OSA_Char*)"%d", bitrate);
-
-    // Return the bitrate string.
-    return(string);
-}
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(Bitrate)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("VARIABLE",     M4VIDEOEDITING_kVARIABLE_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("UNDEFINED",    M4VIDEOEDITING_kUndefinedBitrate),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_9_2_KBPS",  M4VIDEOEDITING_k9_2_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_12_2_KBPS", M4VIDEOEDITING_k12_2_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_16_KBPS",   M4VIDEOEDITING_k16_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_24_KBPS",   M4VIDEOEDITING_k24_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_32_KBPS",   M4VIDEOEDITING_k32_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_48_KBPS",   M4VIDEOEDITING_k48_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_64_KBPS",   M4VIDEOEDITING_k64_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_96_KBPS",   M4VIDEOEDITING_k96_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_128_KBPS",  M4VIDEOEDITING_k128_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_192_KBPS",  M4VIDEOEDITING_k192_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_256_KBPS",  M4VIDEOEDITING_k256_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_288_KBPS",  M4VIDEOEDITING_k288_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_384_KBPS",  M4VIDEOEDITING_k384_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_512_KBPS",  M4VIDEOEDITING_k512_KBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_800_KBPS",  M4VIDEOEDITING_k800_KBPS),
-/*+ New Encoder bitrates */
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_2_MBPS",  M4VIDEOEDITING_k2_MBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_5_MBPS",  M4VIDEOEDITING_k5_MBPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BR_8_MBPS",  M4VIDEOEDITING_k8_MBPS)
-/*- New Encoder bitrates */
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(Bitrate, BITRATE_CLASS_NAME,
- videoEditClasses_getUnknownBitrateString, videoEditClasses_getUnknownBitrateString)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(ClipType)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("THREE_GPP",   M4VIDEOEDITING_kFileType_3GPP),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("MP4",         M4VIDEOEDITING_kFileType_MP4),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("AMR",         M4VIDEOEDITING_kFileType_AMR),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("MP3",         M4VIDEOEDITING_kFileType_MP3),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("PCM",         M4VIDEOEDITING_kFileType_PCM),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("JPG",         M4VIDEOEDITING_kFileType_JPG),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("PNG",         M4VIDEOEDITING_kFileType_PNG),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("M4V",         M4VIDEOEDITING_kFileType_M4V),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("UNSUPPORTED", M4VIDEOEDITING_kFileType_Unsupported)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(ClipType, FILE_TYPE_CLASS_NAME, M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(Engine)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("TASK_LOADING_SETTINGS",    TASK_LOADING_SETTINGS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("TASK_ENCODING",            TASK_ENCODING)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(Engine, MANUAL_EDIT_ENGINE_CLASS_NAME, M4OSA_NULL,
-                                     M4OSA_NULL)
-
-
-static const char*
-videoEditClasses_getUnknownErrorName(int error)
-{
-    static char string[VIDEOEDIT_JAVA__RESULT_STRING_MAX] = "ERR_INTERNAL";
-
-    // Format the unknown error string.
-    M4OSA_chrSPrintf((M4OSA_Char *)string, sizeof(string) - 1, (M4OSA_Char*)"ERR_INTERNAL(%s)",
-                    videoEditOsal_getResultString(error));
-
-    // Return the error string.
-    return(string);
-}
-
-static const char*
-videoEditClasses_getUnknownErrorString(int error)
-{
-    // Return the result string.
-    return(videoEditOsal_getResultString(error));
-}
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(Error)
-{
-    // M4OSA_Clock.h
-    VIDEOEDIT_JAVA_CONSTANT_INIT("WAR_TIMESCALE_TOO_BIG",                   \
-          M4WAR_TIMESCALE_TOO_BIG                               ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_CLOCK_BAD_REF_YEAR",                  \
-          M4ERR_CLOCK_BAD_REF_YEAR                              ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_FILE_NOT_FOUND",                      \
-          M4ERR_FILE_NOT_FOUND                                  ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("WAR_TRANSCODING_NECESSARY",               \
-          M4VSS3GPP_WAR_TRANSCODING_NECESSARY                   ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("WAR_MAX_OUTPUT_SIZE_EXCEEDED",            \
-          M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED                   ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_BUFFER_OUT_TOO_SMALL",                \
-          M4xVSSWAR_BUFFER_OUT_TOO_SMALL                        ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_NOMORE_SPACE_FOR_FILE",               \
-          M4xVSSERR_NO_MORE_SPACE                               ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_FILE_TYPE",                   \
-          M4VSS3GPP_ERR_INVALID_FILE_TYPE                       ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_EFFECT_KIND",                 \
-          M4VSS3GPP_ERR_INVALID_EFFECT_KIND                     ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_VIDEO_EFFECT_TYPE",           \
-          M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE               ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_AUDIO_EFFECT_TYPE",           \
-          M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE               ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_VIDEO_TRANSITION_TYPE",       \
-          M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE           ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_AUDIO_TRANSITION_TYPE",       \
-          M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE           ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_VIDEO_ENCODING_FRAME_RATE",   \
-          M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE       ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EXTERNAL_EFFECT_NULL",                \
-          M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL                    ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EXTERNAL_TRANSITION_NULL",            \
-          M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL                ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_BEGIN_CUT_LARGER_THAN_DURATION",      \
-          M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION          ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_BEGIN_CUT_LARGER_THAN_END_CUT",       \
-          M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT           ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_OVERLAPPING_TRANSITIONS",             \
-         M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS                  ),
-#ifdef M4VSS3GPP_ERR_ANALYSIS_DATA_SIZE_TOO_SMALL
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ANALYSIS_DATA_SIZE_TOO_SMALL",        \
-          M4VSS3GPP_ERR_ANALYSIS_DATA_SIZE_TOO_SMALL            ),
-#endif
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_3GPP_FILE",                     \
-        M4VSS3GPP_ERR_INVALID_3GPP_FILE                         ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT",        \
-        M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT            ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT",        \
-        M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT            ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_AMR_EDITING_UNSUPPORTED",               \
-        M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED                   ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INPUT_VIDEO_AU_TOO_LARGE",              \
-        M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE                  ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INPUT_AUDIO_AU_TOO_LARGE",              \
-        M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE                  ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INPUT_AUDIO_CORRUPTED_AU",              \
-        M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU                  ),
-#ifdef M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INPUT_AUDIO_CORRUPTED_AU",              \
-        M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU              ),
-#endif
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ENCODER_ACCES_UNIT_ERROR",              \
-        M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR                  ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT",      \
-        M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT          ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_H263_PROFILE",      \
-        M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE          ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE",     \
-        M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE         ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_MPEG4_RVLC",        \
-        M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC            ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT",      \
-        M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT          ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE",   \
-        M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE       ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE",\
-     M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_CLIP_ANALYSIS_VERSION",        \
-         M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION            ),
-#ifdef M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_PLATFORM
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INVALID_CLIP_ANALYSIS_PLATFORM",       \
-        M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_PLATFORM            ),
-#endif
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INCOMPATIBLE_VIDEO_FORMAT",            \
-         M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT                ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE",        \
-         M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE            ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INCOMPATIBLE_VIDEO_TIME_SCALE",        \
-         M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE            ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING", \
-         M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING     ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNSUPPORTED_MP3_ASSEMBLY",             \
-         M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY                 ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_NO_SUPPORTED_STREAM_IN_FILE",          \
-         M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE              ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ADDVOLUME_EQUALS_ZERO",                \
-         M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO                    ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION",    \
-         M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION        ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT",    \
-         M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT        ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_UNSUPPORTED_ADDED_AUDIO_STREAM",       \
-         M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM           ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_AUDIO_MIXING_UNSUPPORTED",             \
-         M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED                 ),
-#ifdef M4VSS3GPP_ERR_AUDIO_MIXING_MP3_UNSUPPORTED
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_AUDIO_MIXING_MP3_UNSUPPORTED",         \
-          M4VSS3GPP_ERR_AUDIO_MIXING_MP3_UNSUPPORTED            ),
-#endif
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK", \
-      M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK        ),
-#ifdef M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AAC
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_FEATURE_UNSUPPORTED_WITH_AAC",         \
-       M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AAC               ),
-#endif
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_AUDIO_CANNOT_BE_MIXED",                \
-        M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED                     ),
-#ifdef M4VSS3GPP_ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED",        \
-         M4VSS3GPP_ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED            ),
-#endif
-#ifdef M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_EVRC
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_FEATURE_UNSUPPORTED_WITH_EVRC",        \
-          M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_EVRC           ),
-#endif
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_H263_PROFILE_NOT_SUPPORTED",           \
-          M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED              ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE",    \
-          M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE       ),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ERR_INTERNAL",                             \
-          M4NO_ERROR                                            ),
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(Error, ERROR_CLASS_NAME,
- videoEditClasses_getUnknownErrorName, videoEditClasses_getUnknownErrorString)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(FileType)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("THREE_GPP",   VideoEditClasses_kFileType_3GPP),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("MP4",         VideoEditClasses_kFileType_MP4),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("AMR",         VideoEditClasses_kFileType_AMR),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("MP3",         VideoEditClasses_kFileType_MP3),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("PCM",         VideoEditClasses_kFileType_PCM),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("JPG",         VideoEditClasses_kFileType_JPG),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("GIF",         VideoEditClasses_kFileType_GIF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("PNG",         VideoEditClasses_kFileType_PNG),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("M4V",         VideoEditClasses_kFileType_M4V),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("UNSUPPORTED", VideoEditClasses_kFileType_Unsupported)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(FileType, FILE_TYPE_CLASS_NAME, M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(MediaRendering)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("RESIZING",      M4xVSS_kResizing),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("CROPPING",      M4xVSS_kCropping),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BLACK_BORDERS", M4xVSS_kBlackBorders)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(MediaRendering, MEDIA_RENDERING_CLASS_NAME,
- M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(SlideDirection)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("RIGHT_OUT_LEFT_IN", M4xVSS_SlideTransition_RightOutLeftIn),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("LEFT_OUT_RIGTH_IN", M4xVSS_SlideTransition_LeftOutRightIn),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("TOP_OUT_BOTTOM_IN", M4xVSS_SlideTransition_TopOutBottomIn),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BOTTOM_OUT_TOP_IN", M4xVSS_SlideTransition_BottomOutTopIn)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(SlideDirection, SLIDE_DIRECTION_CLASS_NAME,
- M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(TransitionBehaviour)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("SPEED_UP",    M4VSS3GPP_TransitionBehaviour_SpeedUp),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("LINEAR",      M4VSS3GPP_TransitionBehaviour_Linear),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("SPEED_DOWN",  M4VSS3GPP_TransitionBehaviour_SpeedDown),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("SLOW_MIDDLE", M4VSS3GPP_TransitionBehaviour_SlowMiddle),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FAST_MIDDLE", M4VSS3GPP_TransitionBehaviour_FastMiddle)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(TransitionBehaviour, TRANSITION_BEHAVIOUR_CLASS_NAME,
- M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoEffect)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NONE",            M4VSS3GPP_kVideoEffectType_None),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_FROM_BLACK", M4VSS3GPP_kVideoEffectType_FadeFromBlack),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_TO_BLACK",   M4VSS3GPP_kVideoEffectType_FadeToBlack),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("EXTERNAL",        M4VSS3GPP_kVideoEffectType_External),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("BLACK_AND_WHITE", M4xVSS_kVideoEffectType_BlackAndWhite),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("PINK",            M4xVSS_kVideoEffectType_Pink),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("GREEN",           M4xVSS_kVideoEffectType_Green),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("SEPIA",           M4xVSS_kVideoEffectType_Sepia),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NEGATIVE",        M4xVSS_kVideoEffectType_Negative),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FRAMING",         M4xVSS_kVideoEffectType_Framing),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("TEXT",            M4xVSS_kVideoEffectType_Text),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ZOOM_IN",         M4xVSS_kVideoEffectType_ZoomIn),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ZOOM_OUT",        M4xVSS_kVideoEffectType_ZoomOut),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FIFTIES",         M4xVSS_kVideoEffectType_Fifties),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("COLORRGB16",      M4xVSS_kVideoEffectType_ColorRGB16),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("GRADIENT",        M4xVSS_kVideoEffectType_Gradient),
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoEffect, VIDEO_EFFECT_CLASS_NAME, M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoFormat)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NO_VIDEO",    M4VIDEOEDITING_kNoneVideo),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("H263",        M4VIDEOEDITING_kH263),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("MPEG4",       M4VIDEOEDITING_kMPEG4),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("H264",        M4VIDEOEDITING_kH264),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NULL_VIDEO",  M4VIDEOEDITING_kNullVideo),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("UNSUPPORTED", M4VIDEOEDITING_kUnsupportedVideo),
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoFormat, VIDEO_FORMAT_CLASS_NAME, M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoFrameRate)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FR_5_FPS",    M4VIDEOEDITING_k5_FPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FR_7_5_FPS",  M4VIDEOEDITING_k7_5_FPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FR_10_FPS",   M4VIDEOEDITING_k10_FPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FR_12_5_FPS", M4VIDEOEDITING_k12_5_FPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FR_15_FPS",   M4VIDEOEDITING_k15_FPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FR_20_FPS",   M4VIDEOEDITING_k20_FPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FR_25_FPS",   M4VIDEOEDITING_k25_FPS),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FR_30_FPS",   M4VIDEOEDITING_k30_FPS)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoFrameRate, VIDEO_FRAME_RATE_CLASS_NAME,
- M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoFrameSize)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("SQCIF", M4VIDEOEDITING_kSQCIF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("QQVGA", M4VIDEOEDITING_kQQVGA),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("QCIF",  M4VIDEOEDITING_kQCIF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("QVGA",  M4VIDEOEDITING_kQVGA),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("CIF",   M4VIDEOEDITING_kCIF),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("VGA",   M4VIDEOEDITING_kVGA),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("WVGA", M4VIDEOEDITING_kWVGA),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NTSC", M4VIDEOEDITING_kNTSC),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("nHD", M4VIDEOEDITING_k640_360),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("WVGA16x9", M4VIDEOEDITING_k854_480),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("V720p", M4VIDEOEDITING_k1280_720),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("W720p", M4VIDEOEDITING_k1080_720),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("S720p", M4VIDEOEDITING_k960_720),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("V1080p", M4VIDEOEDITING_k1920_1080)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoFrameSize, VIDEO_FRAME_SIZE_CLASS_NAME,
- M4OSA_NULL, M4OSA_NULL)
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoTransition)
-{
-    VIDEOEDIT_JAVA_CONSTANT_INIT("NONE",             M4VSS3GPP_kVideoTransitionType_None),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("CROSS_FADE",       M4VSS3GPP_kVideoTransitionType_CrossFade),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("EXTERNAL",         M4VSS3GPP_kVideoTransitionType_External),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("ALPHA_MAGIC",      M4xVSS_kVideoTransitionType_AlphaMagic),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("SLIDE_TRANSITION", M4xVSS_kVideoTransitionType_SlideTransition),
-    VIDEOEDIT_JAVA_CONSTANT_INIT("FADE_BLACK",       M4xVSS_kVideoTransitionType_FadeBlack)
-};
-
-VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoTransition, VIDEO_TRANSITION_CLASS_NAME,
-                                     M4OSA_NULL, M4OSA_NULL)
-
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(AlphaMagic)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("file",            "Ljava/lang/String;"),
-    VIDEOEDIT_JAVA_FIELD_INIT("blendingPercent", "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("invertRotation",  "Z"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("rgbWidth",  "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("rgbHeight",  "I"                 )
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(AlphaMagic, ALPHA_MAGIC_SETTINGS_CLASS_NAME)
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(Properties)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("duration",               "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("fileType",               "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoFormat",            "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoDuration",          "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoBitrate",           "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("width",                  "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("height",                 "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("averageFrameRate",       "F"),
-    VIDEOEDIT_JAVA_FIELD_INIT("profile",                "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("level",                  "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("profileSupported",       "Z"),
-    VIDEOEDIT_JAVA_FIELD_INIT("levelSupported",         "Z"),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioFormat",            "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioDuration",          "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioBitrate",           "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioChannels",          "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioSamplingFrequency", "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoRotation",          "I")
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(Properties, PROPERTIES_CLASS_NAME)
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(BackgroundMusic)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("file",          "Ljava/lang/String;"),
-    VIDEOEDIT_JAVA_FIELD_INIT("fileType",      "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("insertionTime", "J"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("volumePercent", "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("beginLoop",     "J"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("endLoop",       "J"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("enableDucking",   "Z"               ),
-    VIDEOEDIT_JAVA_FIELD_INIT("duckingThreshold","I"               ),
-    VIDEOEDIT_JAVA_FIELD_INIT("lowVolume",         "I"             ),
-    VIDEOEDIT_JAVA_FIELD_INIT("isLooping",         "Z"             )
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(BackgroundMusic, BACKGROUND_MUSIC_SETTINGS_CLASS_NAME)
-
-/*
-VIDEOEDIT_JAVA_DEFINE_FIELDS(BestEditSettings)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("videoFormat",    "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoFrameSize", "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioFormat",    "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioChannels",  "I")
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(BestEditSettings, BEST_EDIT_SETTINGS_CLASS_NAME)
-*/
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(ClipSettings)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("clipPath",             "Ljava/lang/String;"),
-    VIDEOEDIT_JAVA_FIELD_INIT("fileType",             "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("beginCutTime",         "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("endCutTime",           "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("beginCutPercent",      "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("endCutPercent",        "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("panZoomEnabled",       "Z"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("panZoomPercentStart",  "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("panZoomTopLeftXStart", "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("panZoomTopLeftYStart", "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("panZoomPercentEnd",    "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("panZoomTopLeftXEnd",   "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("panZoomTopLeftYEnd",   "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("mediaRendering",       "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("rgbWidth",           "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("rgbHeight",          "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("rotationDegree",     "I"                 )
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(ClipSettings, CLIP_SETTINGS_CLASS_NAME)
-
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(EditSettings)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("clipSettingsArray",       "[L"CLIP_SETTINGS_CLASS_NAME";"         ),
-    VIDEOEDIT_JAVA_FIELD_INIT("transitionSettingsArray", "[L"TRANSITION_SETTINGS_CLASS_NAME";"   ),
-    VIDEOEDIT_JAVA_FIELD_INIT("effectSettingsArray",     "[L"EFFECT_SETTINGS_CLASS_NAME";"       ),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoFrameRate",          "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("outputFile",              "Ljava/lang/String;"                    ),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoFrameSize",          "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoFormat",             "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoProfile",            "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoLevel",              "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioFormat",             "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioSamplingFreq",       "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("maxFileSize",             "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioChannels",           "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoBitrate",            "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioBitrate",            "I"                                     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("backgroundMusicSettings",\
-    "L"BACKGROUND_MUSIC_SETTINGS_CLASS_NAME";"),
-    VIDEOEDIT_JAVA_FIELD_INIT("primaryTrackVolume",            "I"                               )
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(EditSettings, EDIT_SETTINGS_CLASS_NAME)
-
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(EffectSettings)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("startTime",                       "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("duration",                        "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoEffectType",                 "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioEffectType",                 "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("startPercent",                    "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("durationPercent",                 "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("framingFile",                     "Ljava/lang/String;"),
-    VIDEOEDIT_JAVA_FIELD_INIT("framingBuffer",                   "[I"                ),
-    VIDEOEDIT_JAVA_FIELD_INIT("bitmapType",                      "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("width",                           "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("height",                          "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("topLeftX",                        "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("topLeftY",                        "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("framingResize",                   "Z"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("framingScaledSize",               "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("text",                            "Ljava/lang/String;"),
-    VIDEOEDIT_JAVA_FIELD_INIT("textRenderingData",               "Ljava/lang/String;"),
-    VIDEOEDIT_JAVA_FIELD_INIT("textBufferWidth",                 "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("textBufferHeight",                "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("fiftiesFrameRate",                "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("rgb16InputColor",                 "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingStartPercent",       "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingMiddlePercent",      "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingEndPercent",         "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingFadeInTimePercent",  "I"                 ),
-    VIDEOEDIT_JAVA_FIELD_INIT("alphaBlendingFadeOutTimePercent", "I"                 )
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(EffectSettings, EFFECT_SETTINGS_CLASS_NAME)
-
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(Engine)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("mManualEditContext", "J")
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(Engine, MANUAL_EDIT_ENGINE_CLASS_NAME)
-
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(SlideTransitionSettings)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("direction", "I")
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(SlideTransitionSettings, SLIDE_TRANSITION_SETTINGS_CLASS_NAME)
-
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(TransitionSettings)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("duration",            "I"                                       ),
-    VIDEOEDIT_JAVA_FIELD_INIT("videoTransitionType", "I"                                       ),
-    VIDEOEDIT_JAVA_FIELD_INIT("audioTransitionType", "I"                                       ),
-    VIDEOEDIT_JAVA_FIELD_INIT("transitionBehaviour", "I"                                       ),
-    VIDEOEDIT_JAVA_FIELD_INIT("alphaSettings",       "L"ALPHA_MAGIC_SETTINGS_CLASS_NAME";"     ),
-    VIDEOEDIT_JAVA_FIELD_INIT("slideSettings",       "L"SLIDE_TRANSITION_SETTINGS_CLASS_NAME";")
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(TransitionSettings, TRANSITION_SETTINGS_CLASS_NAME)
-
-
-VIDEOEDIT_JAVA_DEFINE_FIELDS(Version)
-{
-    VIDEOEDIT_JAVA_FIELD_INIT("major",    "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("minor",    "I"),
-    VIDEOEDIT_JAVA_FIELD_INIT("revision", "I")
-};
-
-VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(Version, VERSION_CLASS_NAME)
-
-
-VIDEOEDIT_JAVA_DEFINE_METHODS(Engine)
-{
-    VIDEOEDIT_JAVA_METHOD_INIT("onProgressUpdate", "(II)V")
-};
-
-VIDEOEDIT_JAVA_DEFINE_METHOD_CLASS(Engine, MANUAL_EDIT_ENGINE_CLASS_NAME)
-
-
-static const char*
-videoEditClasses_getBrandString(M4OSA_UInt32 brand)
-{
-    static char         brandString[11] = "0x00000000";
-           const char*  pBrandString    = M4OSA_NULL;
-           M4OSA_UInt8* pBrand          = (M4OSA_UInt8*)&brand;
-           M4OSA_UInt32 brandHost       = 0;
-
-    // Convert the brand from big endian to host.
-    brandHost =  pBrand[0];
-    brandHost =  brandHost << 8;
-    brandHost += pBrand[1];
-    brandHost =  brandHost << 8;
-    brandHost += pBrand[2];
-    brandHost =  brandHost << 8;
-    brandHost += pBrand[3];
-
-    switch (brandHost)
-    {
-    case M4VIDEOEDITING_BRAND_0000:
-        pBrandString = "0000";
-        break;
-    case M4VIDEOEDITING_BRAND_3G2A:
-        pBrandString = "3G2A";
-        break;
-    case M4VIDEOEDITING_BRAND_3GP4:
-        pBrandString = "3GP4";
-        break;
-    case M4VIDEOEDITING_BRAND_3GP5:
-        pBrandString = "3GP5";
-        break;
-    case M4VIDEOEDITING_BRAND_3GP6:
-        pBrandString = "3GP6";
-        break;
-    case M4VIDEOEDITING_BRAND_AVC1:
-        pBrandString = "AVC1";
-        break;
-    case M4VIDEOEDITING_BRAND_EMP:
-        pBrandString = "EMP";
-        break;
-    case M4VIDEOEDITING_BRAND_ISOM:
-        pBrandString = "ISOM";
-        break;
-    case M4VIDEOEDITING_BRAND_MP41:
-        pBrandString = "MP41";
-        break;
-    case M4VIDEOEDITING_BRAND_MP42:
-        pBrandString = "MP42";
-        break;
-    case M4VIDEOEDITING_BRAND_VFJ1:
-        pBrandString = "VFJ1";
-        break;
-    default:
-        M4OSA_chrSPrintf((M4OSA_Char *)brandString,
-                         sizeof(brandString) - 1,
-                         (M4OSA_Char*)"0x%08X", brandHost);
-        pBrandString = brandString;
-        break;
-    }
-
-    // Return the brand string.
-    return(pBrandString);
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-static void
-videoEditClasses_logFtypBox(
-                M4VIDEOEDITING_FtypBox*             pBox,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the FtypBox.
-    if (M4OSA_NULL != pBox)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "%*c major_brand:        %s",    indentation, ' ',
-                 videoEditClasses_getBrandString(pBox->major_brand));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "%*c minor_version:      %08X",  indentation, ' ',
-                (unsigned int)pBox->minor_version);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "%*c nbCompatibleBrands: %u",    indentation, ' ',
-                (unsigned int)pBox->nbCompatibleBrands);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "%*c compatible_brands:", indentation, ' ');
-                indentation += VIDEOEDIT_LOG_INDENTATION;
-        for (int i = 0; (i < (int)pBox->nbCompatibleBrands) &&\
-         (i < M4VIDEOEDITING_MAX_COMPATIBLE_BRANDS); i++)
-        {
-            VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                    "%*c compatible_brand[%d]: %s",    indentation, ' ',
-                    i, videoEditClasses_getBrandString(pBox->compatible_brands[i]));
-        }
-        indentation -= VIDEOEDIT_LOG_INDENTATION;
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c <null>",
-                 indentation, ' ');
-    }
-}
-#endif
-
-
-void
-videoEditClasses_init(
-                bool*                               pResult,
-                JNIEnv*                             pEnv)
-{
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",\
-        "videoEditClasses_init()");
-
-        // Initialize the constants.
-        videoEditJava_initAudioEffectConstants(pResult, pEnv);
-        videoEditJava_initAudioFormatConstants(pResult, pEnv);
-        videoEditJava_initAudioSamplingFrequencyConstants(pResult, pEnv);
-        videoEditJava_initAudioTransitionConstants(pResult, pEnv);
-        videoEditJava_initBitrateConstants(pResult, pEnv);
-        videoEditJava_initClipTypeConstants(pResult, pEnv);
-        videoEditJava_initEngineConstants(pResult, pEnv);
-        videoEditJava_initErrorConstants(pResult, pEnv);
-        videoEditJava_initFileTypeConstants(pResult, pEnv);
-        videoEditJava_initMediaRenderingConstants(pResult, pEnv);
-        videoEditJava_initSlideDirectionConstants(pResult, pEnv);
-        videoEditJava_initTransitionBehaviourConstants(pResult, pEnv);
-        videoEditJava_initVideoEffectConstants(pResult, pEnv);
-        videoEditJava_initVideoFormatConstants(pResult, pEnv);
-        videoEditJava_initVideoFrameRateConstants(pResult, pEnv);
-        videoEditJava_initVideoFrameSizeConstants(pResult, pEnv);
-        videoEditJava_initVideoTransitionConstants(pResult, pEnv);
-
-        // Initialize the fields.
-        videoEditJava_initAlphaMagicFields(pResult, pEnv);
-        videoEditJava_initBackgroundMusicFields(pResult, pEnv);
-        videoEditJava_initClipSettingsFields(pResult, pEnv);
-        videoEditJava_initEditSettingsFields(pResult, pEnv);
-        videoEditJava_initEffectSettingsFields(pResult, pEnv);
-        videoEditJava_initEngineFields(pResult, pEnv);
-        videoEditJava_initSlideTransitionSettingsFields(pResult, pEnv);
-        videoEditJava_initTransitionSettingsFields(pResult, pEnv);
-        videoEditJava_initVersionFields(pResult, pEnv);
-        // Initialize the methods.
-        videoEditJava_initEngineMethods(pResult, pEnv);
-    }
-}
-
-void
-videoEditPropClass_init(
-                bool*                               pResult,
-                JNIEnv*                             pEnv)
-{
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",\
-            "videoEditPropClass_init()");
-
-        // Initialize the constants.
-        videoEditJava_initAudioFormatConstants(pResult, pEnv);
-        videoEditJava_initErrorConstants(pResult, pEnv);
-        videoEditJava_initFileTypeConstants(pResult, pEnv);
-        videoEditJava_initVideoFormatConstants(pResult, pEnv);
-
-        // Initialize the fields.
-        videoEditJava_initPropertiesFields(pResult, pEnv);
-    }
-}
-
-void
-videoEditClasses_getAlphaMagicSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4xVSS_AlphaMagicSettings**         ppSettings)
-{
-    VideoEditJava_AlphaMagicFieldIds fieldIds;
-    M4xVSS_AlphaMagicSettings* pSettings = M4OSA_NULL;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_AlphaMagicFieldIds));
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                   "videoEditClasses_getAlphaMagicSettings()");
-
-        // Retrieve the field ids.
-        videoEditJava_getAlphaMagicFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only validate the AlphaMagicSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Check if the clip is set.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                                                    (NULL == object),
-                                                    "alphaSettings is null");
-    }
-
-    // Only retrieve the AlphaMagicSettings if the fields could be located and validated.
-    if (*pResult)
-    {
-        // Allocate memory for the AlphaMagicSettings.
-        pSettings = (M4xVSS_AlphaMagicSettings*)videoEditOsal_alloc(pResult, pEnv,
-                sizeof(M4xVSS_AlphaMagicSettings), "AlphaMagicSettings");
-
-        // Check if memory could be allocated for the AlphaMagicSettings.
-        if (*pResult)
-        {
-            // Set the alpha magic file path (JPG file).
-            pSettings->pAlphaFilePath = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, object,
-                    fieldIds.file, M4OSA_NULL);
-
-            // Check if the alpha magic file path is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                    (M4OSA_NULL == pSettings->pAlphaFilePath), "alphaSettings.file is null");
-        }
-
-        // Check if the alpha file path could be retrieved.
-        if (*pResult)
-        {
-            // Set the blending percentage between 0 and 100.
-            pSettings->blendingPercent = (M4OSA_UInt8)pEnv->GetIntField(object,
-                    fieldIds.blendingPercent);
-
-            // Set the direct effect or reverse.
-            pSettings->isreverse = (M4OSA_Bool)pEnv->GetBooleanField(object,
-                    fieldIds.invertRotation);
-
-            // Get the rgb width
-            pSettings->width = (M4OSA_UInt32) pEnv->GetIntField(object, fieldIds.rgbWidth );
-
-            pSettings->height = (M4OSA_UInt32) pEnv->GetIntField(object, fieldIds.rgbHeight );
-
-             VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                    "((((((((((path %s", pSettings->pAlphaFilePath);
-
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                    "------- getAlphaMagicSettings width %d", pEnv->GetIntField(object,
-                    fieldIds.rgbWidth ));
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                   "-------- getAlphaMagicSettings Height %d",
-                   pEnv->GetIntField(object, fieldIds.rgbHeight ));
-        }
-
-        // Check if settings could be set.
-        if (*pResult)
-        {
-            // Return the settings.
-            (*ppSettings) = pSettings;
-        }
-        else
-        {
-            // Free the settings.
-            videoEditClasses_freeAlphaMagicSettings(&pSettings);
-        }
-    }
-}
-
-void
-videoEditClasses_freeAlphaMagicSettings(
-                M4xVSS_AlphaMagicSettings**         ppSettings)
-{
-    // Check if memory was allocated for the AlphaMagicSettings.
-    if (M4OSA_NULL != (*ppSettings))
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                  "videoEditClasses_freeAlphaMagicSettings()");
-
-        // Free the alpha file path.
-        videoEditOsal_free((*ppSettings)->pAlphaFilePath);
-        (*ppSettings)->pAlphaFilePath = M4OSA_NULL;
-
-        // Free the settings structure.
-        videoEditOsal_free((*ppSettings));
-        (*ppSettings) = M4OSA_NULL;
-    }
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logAlphaMagicSettings(
-                M4xVSS_AlphaMagicSettings*          pSettings,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the AlphaMagicSettings.
-    if (M4OSA_NULL != pSettings)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-             "%*c pAlphaFilePath:  %s",    indentation, ' ',
-            (M4OSA_NULL != pSettings->pAlphaFilePath) ? \
-            (char *)pSettings->pAlphaFilePath : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-             "%*c blendingPercent: %u %%", indentation, ' ',
-            (unsigned int)pSettings->blendingPercent);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c isreverse:       %s",    indentation, ' ',
-            pSettings->isreverse ? "true" : "false");
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c <null>", indentation, ' ');
-    }
-}
-#endif
-
-
-void
-videoEditClasses_getBackgroundMusicSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4xVSS_BGMSettings**                ppSettings)
-{
-    VideoEditJava_BackgroundMusicFieldIds fieldIds;
-    M4xVSS_BGMSettings*           pSettings = M4OSA_NULL;
-    bool                          converted = true;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_BackgroundMusicFieldIds));
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-               "videoEditClasses_getBackgroundMusicSettings()");
-
-        // Retrieve the field ids.
-        videoEditJava_getBackgroundMusicFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only retrieve the BackgroundMusicSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Check if the object is valid.
-        if (NULL != object)
-        {
-            // Allocate memory for the BackgroundMusicSettings.
-            pSettings = (M4xVSS_BGMSettings*)videoEditOsal_alloc(pResult, pEnv,
-                sizeof(M4xVSS_BGMSettings), "BackgroundMusicSettings");
-
-            // Check if memory could be allocated for the BackgroundMusicSettings.
-            if (*pResult)
-            {
-                // Set the input file path.
-                pSettings->pFile = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, object,
-                        fieldIds.file, M4OSA_NULL);
-
-                // Check if the input file path is valid.
-                videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                        (M4OSA_NULL == pSettings->pFile), "backgroundMusicSettings.file is null");
-            }
-
-            // Check if the input file path could be retrieved.
-            if (*pResult)
-            {
-                // Set the file type .3gp, .amr, .mp3.
-                pSettings->FileType = M4VIDEOEDITING_kFileType_PCM;
-                /*(M4VIDEOEDITING_FileType)videoEditJava_getClipTypeJavaToC(
-                 &converted, pEnv->GetIntField(object, fieldIds.fileType));*/
-
-                // Check if the file type is valid.
-                videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                        !converted, "backgroundMusicSettings.fileType is invalid");
-            }
-
-            // Check if the file type could be retrieved.
-            if (*pResult)
-            {
-                // Set the time, in milliseconds, at which the added audio track is inserted.
-                pSettings->uiAddCts = (M4OSA_UInt32)pEnv->GetLongField(object,
-                        fieldIds.insertionTime);
-
-                // Set the volume, in percentage (0..100), of the added audio track.
-                pSettings->uiAddVolume = (M4OSA_UInt32)pEnv->GetIntField(object,
-                        fieldIds.volumePercent);
-
-                // Set the start time of the loop in milli seconds.
-                pSettings->uiBeginLoop = (M4OSA_UInt32)pEnv->GetLongField(object,
-                        fieldIds.beginLoop);
-
-                // Set the end time of the loop in milli seconds.
-                pSettings->uiEndLoop = (M4OSA_UInt32)pEnv->GetLongField(object,
-                        fieldIds.endLoop);
-                // Set the end time of the loop in milli seconds.
-                pSettings->b_DuckingNeedeed =
-                        (M4OSA_Bool)pEnv->GetBooleanField(object, fieldIds.enableDucking);
-
-                // Set the end time of the loop in milli seconds.
-                pSettings->InDucking_threshold =
-                        (M4OSA_Int32)pEnv->GetIntField(object, fieldIds.duckingThreshold);
-
-                // Set the end time of the loop in milli seconds.
-                pSettings->lowVolume =
-                        (M4OSA_Float)(((M4OSA_Float)pEnv->GetIntField(object, fieldIds.lowVolume)));
-
-                // Set the end time of the loop in milli seconds.
-                pSettings->bLoop = (M4OSA_Bool)pEnv->GetBooleanField(object, fieldIds.isLooping);
-
-                // Set sampling freq and channels
-                pSettings->uiSamplingFrequency = M4VIDEOEDITING_k32000_ASF;
-                pSettings->uiNumChannels = 2;
-            }
-
-            // Check if settings could be set.
-            if (*pResult)
-            {
-                // Return the settings.
-                (*ppSettings) = pSettings;
-            }
-            else
-            {
-                // Free the settings.
-                videoEditClasses_freeBackgroundMusicSettings(&pSettings);
-            }
-        }
-    }
-}
-
-void
-videoEditClasses_freeBackgroundMusicSettings(
-                M4xVSS_BGMSettings**                ppSettings)
-{
-    // Check if memory was allocated for the BackgroundMusicSettings.
-    if (M4OSA_NULL != (*ppSettings))
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-         "videoEditClasses_freeBackgroundMusicSettings()");
-
-        // Free the input file path.
-        videoEditOsal_free((*ppSettings)->pFile);
-        (*ppSettings)->pFile = M4OSA_NULL;
-
-        // Free the settings structure.
-        videoEditOsal_free((*ppSettings));
-        (*ppSettings) = M4OSA_NULL;
-    }
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logBackgroundMusicSettings(
-                M4xVSS_BGMSettings*                 pSettings,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the BackgroundMusicSettings.
-    if (M4OSA_NULL != pSettings)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c pFile:       %s",
-            indentation, ' ',
-            (M4OSA_NULL != pSettings->pFile) ? (char *)pSettings->pFile : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c FileType:    %s",    indentation, ' ',
-            videoEditJava_getClipTypeString(pSettings->FileType));
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c uiAddCts:    %u ms",
-            indentation, ' ', (unsigned int)pSettings->uiAddCts);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c uiAddVolume: %u %%",
-            indentation, ' ', (unsigned int)pSettings->uiAddVolume);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c uiBeginLoop: %u ms",
-            indentation, ' ', (unsigned int)pSettings->uiBeginLoop);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c uiEndLoop:   %u ms",
-            indentation, ' ', (unsigned int)pSettings->uiEndLoop);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c b_DuckingNeedeed:\
-            %u ", indentation, ' ', (bool)pSettings->b_DuckingNeedeed);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c InDucking_threshold: \
-            %u ms", indentation, ' ', (unsigned int)pSettings->InDucking_threshold);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c lowVolume:   %2.2f ",\
-            indentation, ' ', (float)pSettings->lowVolume);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c bLoop:   %u ms",\
-            indentation, ' ', (bool)pSettings->bLoop);
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c <null>",
-            indentation, ' ');
-    }
-}
-#endif
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logClipProperties(
-                M4VIDEOEDITING_ClipProperties*      pProperties,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the ClipProperties.
-    if (M4OSA_NULL != pProperties)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bAnalysed:                        %s",       indentation, ' ',
-            pProperties->bAnalysed ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c Version:                          %d.%d.%d", indentation, ' ',
-            pProperties->Version[0], pProperties->Version[1], pProperties->Version[2]);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiClipDuration:                   %u",       indentation, ' ',
-            (unsigned int)pProperties->uiClipDuration);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c FileType:                         %s",       indentation, ' ',
-            videoEditJava_getClipTypeString(pProperties->FileType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c ftyp:",
-                                              indentation, ' ');
-        videoEditClasses_logFtypBox(&pProperties->ftyp, indentation + VIDEOEDIT_LOG_INDENTATION);
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c VideoStreamType:                  %s",       indentation, ' ',
-            videoEditJava_getVideoFormatString(pProperties->VideoStreamType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiClipVideoDuration:              %u",       indentation, ' ',
-            (unsigned int)pProperties->uiClipVideoDuration);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiVideoBitrate:                   %s",       indentation, ' ',
-            videoEditJava_getBitrateString(pProperties->uiVideoBitrate));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiVideoMaxAuSize:                 %u",       indentation, ' ',
-            (unsigned int)pProperties->uiVideoMaxAuSize);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiVideoWidth:                     %u",       indentation, ' ',
-            (unsigned int)pProperties->uiVideoWidth);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiVideoHeight:                    %u",       indentation, ' ',
-            (unsigned int)(unsigned int)pProperties->uiVideoHeight);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiVideoTimeScale:                 %u",       indentation, ' ',
-            (unsigned int)pProperties->uiVideoTimeScale);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c fAverageFrameRate:                %.3f",     indentation, ' ',
-            pProperties->fAverageFrameRate);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bMPEG4dataPartition:              %s",       indentation, ' ',
-            pProperties->bMPEG4dataPartition ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bMPEG4rvlc:                       %s",       indentation, ' ',
-            pProperties->bMPEG4rvlc ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bMPEG4resynchMarker:              %s",       indentation, ' ',
-            pProperties->bMPEG4resynchMarker ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c AudioStreamType:                  %s",       indentation, ' ',
-            videoEditJava_getAudioFormatString(pProperties->AudioStreamType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiClipAudioDuration:              %u",       indentation, ' ',
-            (unsigned int)pProperties->uiClipAudioDuration);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiAudioBitrate:                   %s",       indentation, ' ',
-            videoEditJava_getBitrateString(pProperties->uiAudioBitrate));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiAudioMaxAuSize:                 %u",       indentation, ' ',
-            (unsigned int)pProperties->uiAudioMaxAuSize);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiNbChannels:                     %u",       indentation, ' ',
-            (unsigned int)pProperties->uiNbChannels);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiSamplingFrequency:              %u",       indentation, ' ',
-            (unsigned int)pProperties->uiSamplingFrequency);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiExtendedSamplingFrequency:      %u",       indentation, ' ',
-            (unsigned int)pProperties->uiExtendedSamplingFrequency);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiDecodedPcmSize:                 %u",       indentation, ' ',
-            (unsigned int)pProperties->uiDecodedPcmSize);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bVideoIsEditable:                 %s",       indentation, ' ',
-            pProperties->bVideoIsEditable ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bAudioIsEditable:                 %s",       indentation, ' ',
-            pProperties->bAudioIsEditable ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bVideoIsCompatibleWithMasterClip: %s",       indentation, ' ',
-            pProperties->bVideoIsCompatibleWithMasterClip ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bAudioIsCompatibleWithMasterClip: %s",       indentation, ' ',
-            pProperties->bAudioIsCompatibleWithMasterClip ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiClipAudioVolumePercentage:      %d",       indentation, ' ',
-                        pProperties->uiClipAudioVolumePercentage);
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES", "%*c <null>",
-            indentation, ' ');
-    }
-}
-#endif
-
-void
-videoEditClasses_getClipSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4VSS3GPP_ClipSettings**            ppSettings)
-{
-
-    VideoEditJava_ClipSettingsFieldIds fieldIds;
-    M4VSS3GPP_ClipSettings*    pSettings = M4OSA_NULL;
-    M4OSA_ERR                  result    = M4NO_ERROR;
-    bool                       converted = true;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_ClipSettingsFieldIds));
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "videoEditClasses_getClipSettings()");
-
-        // Retrieve the field ids.
-        videoEditJava_getClipSettingsFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only validate the ClipSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Check if the clip is set.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                                                    (NULL == object),
-                                                    "clip is null");
-    }
-
-    // Only retrieve the ClipSettings if the fields could be located and validated.
-    if (*pResult)
-    {
-        // Allocate memory for the ClipSettings.
-        pSettings = (M4VSS3GPP_ClipSettings *)videoEditOsal_alloc(pResult, pEnv,
-            sizeof(M4VSS3GPP_ClipSettings), "ClipSettings");
-
-        // Check if memory could be allocated for the ClipSettings.
-        if (*pResult)
-        {
-            // Log the API call.
-            VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4xVSS_CreateClipSettings()");
-
-            // Initialize the ClipSettings.
-            result = M4xVSS_CreateClipSettings(pSettings, NULL, 0, 0);
-
-            // Log the result.
-            VIDEOEDIT_LOG_RESULT(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                videoEditOsal_getResultString(result));
-
-            // Check if the initialization succeeded.
-            videoEditJava_checkAndThrowRuntimeException(pResult, pEnv,
-                (M4NO_ERROR != result), result);
-        }
-
-        // Check if the allocation and initialization succeeded
-        //(required because pSettings is dereferenced).
-        if (*pResult)
-        {
-            // Set the input file path.
-            pSettings->pFile = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, object,
-                fieldIds.clipPath, &pSettings->filePathSize);
-
-            // Check if the file path is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                    (M4OSA_NULL == pSettings->pFile), "clip.clipPath is null");
-        }
-
-        // Check if the input file could be retrieved.
-        if (*pResult)
-        {
-            // Set the file type .3gp, .amr, .mp3.
-            pSettings->FileType = (M4VIDEOEDITING_FileType)videoEditJava_getClipTypeJavaToC(
-                                        &converted, pEnv->GetIntField(object, fieldIds.fileType));
-
-            if (( pSettings->FileType == M4VIDEOEDITING_kFileType_JPG) ||
-                 ( pSettings->FileType == M4VIDEOEDITING_kFileType_PNG)) {
-                 pSettings->FileType = M4VIDEOEDITING_kFileType_ARGB8888;
-            }
-
-            // Check if the file type is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                    !converted, "clip.fileType is invalid");
-        }
-
-        // Check if the file type could be retrieved.
-        if (*pResult)
-        {
-            // Set the begin cut time, in milliseconds.
-            pSettings->uiBeginCutTime =
-                (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.beginCutTime);
-
-            // Set the end cut time, in milliseconds.
-            pSettings->uiEndCutTime = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.endCutTime);
-
-            // Set the begin cut time, in percent of clip duration (only for 3GPP clip !).
-            pSettings->xVSS.uiBeginCutPercent =
-                (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.beginCutPercent);
-
-            // Set the end cut time, in percent of clip duration (only for 3GPP clip !).
-            pSettings->xVSS.uiEndCutPercent =
-                (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.endCutPercent);
-
-            // Set the duration of the clip, if different from 0,
-            // has priority on uiEndCutTime or uiEndCutPercent.
-            pSettings->xVSS.uiDuration = 0;
-
-            // Set whether or not the pan and zoom mode is enabled.
-            pSettings->xVSS.isPanZoom =
-                (M4OSA_Bool)pEnv->GetBooleanField(object, fieldIds.panZoomEnabled);
-
-            // Set the pan and zoom start zoom percentage.
-            pSettings->xVSS.PanZoomXa        =
-                (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomPercentStart);
-
-            // Set the pan and zoom start x.
-            pSettings->xVSS.PanZoomTopleftXa =
-                (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomTopLeftXStart);
-
-            // Set the pan and zoom start y.
-            pSettings->xVSS.PanZoomTopleftYa =
-                (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomTopLeftYStart);
-
-            // Set the pan and zoom end zoom percentage.
-            pSettings->xVSS.PanZoomXb        =
-                (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomPercentEnd);
-
-            // Set the pan and zoom end x.
-            pSettings->xVSS.PanZoomTopleftXb =
-                (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomTopLeftXEnd);
-
-            // Set the pan and zoom end y.
-            pSettings->xVSS.PanZoomTopleftYb =
-                (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.panZoomTopLeftYEnd);
-
-            // Set the media rendering mode, only used with JPEG to crop, resize,
-            // or render black borders.
-            pSettings->xVSS.MediaRendering =
-                (M4xVSS_MediaRendering)videoEditJava_getMediaRenderingJavaToC(
-                    &converted, pEnv->GetIntField(object,fieldIds.mediaRendering));
-
-            // Check if the media rendering is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, !converted,
-                "clip.mediaRendering is invalid");
-
-             // Capture the rgb file width and height
-            pSettings->ClipProperties.uiStillPicWidth =
-                (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.rgbFileWidth);
-            pSettings->ClipProperties.uiStillPicHeight  =
-                (M4OSA_UInt16)pEnv->GetIntField(object, fieldIds.rgbFileHeight);
-
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", \
-                "getClipSettings-- rgbFileWidth %d ",
-                pSettings->ClipProperties.uiStillPicWidth);
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", \
-                "getClipSettings-- rgbFileHeight %d ",
-                pSettings->ClipProperties.uiStillPicHeight);
-
-            // Set the video rotation degree
-            pSettings->ClipProperties.videoRotationDegrees =
-                (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.rotationDegree);
-        }
-
-        // Check if settings could be set.
-        if (*pResult)
-        {
-            // Return the settings.
-            (*ppSettings) = pSettings;
-        }
-        else
-        {
-            // Free the settings.
-            videoEditClasses_freeClipSettings(&pSettings);
-        }
-    }
-}
-
-void
-videoEditClasses_createClipSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                M4VSS3GPP_ClipSettings*             pSettings,
-                jobject*                            pObject)
-{
-    VideoEditJava_ClipSettingsFieldIds fieldIds;
-    jclass                     clazz    = NULL;
-    jobject                    object   = NULL;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_ClipSettingsFieldIds));
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "videoEditClasses_createClipSettings()");
-
-        // Retrieve the class.
-        videoEditJava_getClipSettingsClass(pResult, pEnv, &clazz);
-
-        // Retrieve the field ids.
-        videoEditJava_getClipSettingsFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only create an object if the class and fields could be located.
-    if (*pResult)
-    {
-        // Allocate a new object.
-        object = pEnv->AllocObject(clazz);
-        if (NULL != object)
-        {
-            // Set the clipPath field.
-            pEnv->SetObjectField(object, fieldIds.clipPath, NULL);
-
-            // Set the fileType field.
-            pEnv->SetIntField(object, fieldIds.fileType, videoEditJava_getClipTypeCToJava(
-                                                                    pSettings->FileType));
-
-            // Set the beginCutTime field.
-            pEnv->SetIntField(object, fieldIds.beginCutTime, pSettings->uiBeginCutTime);
-
-            // Set the endCutTime field.
-            pEnv->SetIntField(object, fieldIds.endCutTime, pSettings->uiEndCutTime);
-
-            // Set the beginCutPercent field.
-            pEnv->SetIntField(object, fieldIds.beginCutPercent, pSettings->xVSS.uiBeginCutPercent);
-
-            // Set the endCutPercent field.
-            pEnv->SetIntField(object, fieldIds.endCutPercent, pSettings->xVSS.uiEndCutPercent);
-
-            // Set the panZoomEnabled field.
-            pEnv->SetBooleanField(object, fieldIds.panZoomEnabled, pSettings->xVSS.isPanZoom);
-
-            // Set the panZoomPercentStart field.
-            pEnv->SetIntField(object, fieldIds.panZoomPercentStart,
-                (1000 - pSettings->xVSS.PanZoomXa));
-
-            // Set the panZoomTopLeftXStart field.
-            pEnv->SetIntField(object, fieldIds.panZoomTopLeftXStart,
-                pSettings->xVSS.PanZoomTopleftXa);
-
-            // Set the panZoomTopLeftYStart field.
-            pEnv->SetIntField(object, fieldIds.panZoomTopLeftYStart,
-                pSettings->xVSS.PanZoomTopleftYa);
-
-            // Set the panZoomPercentEnd field.
-            pEnv->SetIntField(object, fieldIds.panZoomPercentEnd,
-                (1000 - pSettings->xVSS.PanZoomXb));
-
-            // Set the panZoomTopLeftXEnd field.
-            pEnv->SetIntField(object, fieldIds.panZoomTopLeftXEnd,
-                pSettings->xVSS.PanZoomTopleftXb);
-
-            // Set the panZoomTopLeftYEnd field.
-            pEnv->SetIntField(object, fieldIds.panZoomTopLeftYEnd,
-                pSettings->xVSS.PanZoomTopleftYb);
-
-            // Set the mediaRendering field.
-            pEnv->SetIntField(object, fieldIds.mediaRendering,
-                videoEditJava_getMediaRenderingCToJava(pSettings->xVSS.MediaRendering));
-
-            // Set the rgb file width and height
-            pEnv->SetIntField(object, fieldIds.rgbFileWidth,
-                pSettings->ClipProperties.uiStillPicWidth );
-
-            pEnv->SetIntField(object, fieldIds.rgbFileHeight,
-                pSettings->ClipProperties.uiStillPicHeight );
-
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "rgbFileWeight %d rgbFileHeight %d ",
-                pSettings->ClipProperties.uiStillPicWidth ,
-                pSettings->ClipProperties.uiStillPicHeight);
-
-            // Set the video rotation
-            pEnv->SetIntField(object, fieldIds.rotationDegree,
-                pSettings->ClipProperties.videoRotationDegrees);
-
-            // Return the object.
-            (*pObject) = object;
-        }
-    }
-}
-void
-videoEditPropClass_createProperties(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                VideoEditPropClass_Properties*      pProperties,
-                jobject*                            pObject)
-{
-    VideoEditJava_PropertiesFieldIds fieldIds;
-    jclass                   clazz    = NULL;
-    jobject                  object   = NULL;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_PropertiesFieldIds));
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-                "videoEditPropClass_createProperties()");
-
-        // Retrieve the class.
-        videoEditJava_getPropertiesClass(pResult, pEnv, &clazz);
-
-        // Retrieve the field ids.
-        videoEditJava_getPropertiesFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only create an object if the class and fields could be located.
-    if (*pResult)
-    {
-        // Allocate a new object.
-        object = pEnv->AllocObject(clazz);
-        if (NULL != object)
-        {
-            // Set the duration field.
-            pEnv->SetIntField(object, fieldIds.duration, pProperties->uiClipDuration);
-
-            // Set the fileType field.
-            pEnv->SetIntField(object, fieldIds.fileType,
-                videoEditJava_getFileTypeCToJava(pProperties->FileType));
-
-            // Set the videoFormat field.
-            pEnv->SetIntField(object, fieldIds.videoFormat,
-                videoEditJava_getVideoFormatCToJava(pProperties->VideoStreamType));
-
-            // Set the videoDuration field.
-            pEnv->SetIntField(object, fieldIds.videoDuration, pProperties->uiClipVideoDuration);
-
-            // Set the videoBitrate field.
-            pEnv->SetIntField(object, fieldIds.videoBitrate, pProperties->uiVideoBitrate);
-
-            // Set the width field.
-            pEnv->SetIntField(object, fieldIds.width, pProperties->uiVideoWidth);
-
-            // Set the height field.
-            pEnv->SetIntField(object, fieldIds.height, pProperties->uiVideoHeight);
-
-            // Set the averageFrameRate field.
-            pEnv->SetFloatField(object, fieldIds.averageFrameRate, pProperties->fAverageFrameRate);
-
-            // Set the profile field.
-            pEnv->SetIntField(object, fieldIds.profile,
-                pProperties->uiVideoProfile);
-
-            // Set the level field.
-            pEnv->SetIntField(object, fieldIds.level,
-                pProperties->uiVideoLevel);
-
-            // Set whether profile supported
-            pEnv->SetBooleanField(object, fieldIds.profileSupported,
-                pProperties->bProfileSupported);
-
-            // Set whether level supported
-            pEnv->SetBooleanField(object, fieldIds.levelSupported,
-                pProperties->bLevelSupported);
-
-            // Set the audioFormat field.
-            pEnv->SetIntField(object, fieldIds.audioFormat,
-                videoEditJava_getAudioFormatCToJava(pProperties->AudioStreamType));
-
-            // Set the audioDuration field.
-            pEnv->SetIntField(object, fieldIds.audioDuration, pProperties->uiClipAudioDuration);
-
-            // Set the audioBitrate field.
-            pEnv->SetIntField(object, fieldIds.audioBitrate, pProperties->uiAudioBitrate);
-
-            // Set the audioChannels field.
-            pEnv->SetIntField(object, fieldIds.audioChannels, pProperties->uiNbChannels);
-
-            // Set the audioSamplingFrequency field.
-            pEnv->SetIntField(object, fieldIds.audioSamplingFrequency,
-                pProperties->uiSamplingFrequency);
-
-            // Set the video rotation field.
-            pEnv->SetIntField(object, fieldIds.videoRotation, pProperties->uiRotation);
-
-            // Return the object.
-            (*pObject) = object;
-        }
-    }
-}
-
-void
-videoEditClasses_freeClipSettings(
-                M4VSS3GPP_ClipSettings**            ppSettings)
-{
-    // Check if memory was allocated for the ClipSettings.
-    if (M4OSA_NULL != (*ppSettings))
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "videoEditClasses_freeClipSettings()");
-
-        // Free the input file path.
-        videoEditOsal_free((*ppSettings)->pFile);
-        (*ppSettings)->pFile = M4OSA_NULL;
-        (*ppSettings)->filePathSize = 0;
-
-        // Free the clip settings.
-        M4xVSS_FreeClipSettings((*ppSettings));
-
-        // Free the settings structure.
-        videoEditOsal_free((*ppSettings));
-        (*ppSettings) = M4OSA_NULL;
-    }
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logClipSettings(
-                M4VSS3GPP_ClipSettings*             pSettings,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the ClipSettings.
-    if (M4OSA_NULL != pSettings)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pFile:           %s", indentation, ' ',
-            (M4OSA_NULL != pSettings->pFile) ? (char*)pSettings->pFile : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c FileType:        %s", indentation, ' ',
-            videoEditJava_getClipTypeString(pSettings->FileType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c filePathSize:    %u", indentation, ' ',
-            (unsigned int)pSettings->filePathSize);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c ClipProperties:",  indentation, ' ');
-        videoEditClasses_logClipProperties(&pSettings->ClipProperties,
-            indentation + VIDEOEDIT_LOG_INDENTATION);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiBeginCutTime:    %u ms", indentation, ' ',
-            (unsigned int)pSettings->uiBeginCutTime);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiEndCutTime:      %u ms", indentation, ' ',
-            (unsigned int)pSettings->uiEndCutTime);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiBeginCutPercent: %u %%", indentation, ' ',
-            (unsigned int)pSettings->xVSS.uiBeginCutPercent);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiEndCutPercent:   %u %%", indentation, ' ',
-            (unsigned int)pSettings->xVSS.uiEndCutPercent);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiDuration:        %u ms", indentation, ' ',
-            (unsigned int)pSettings->xVSS.uiDuration);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c isPanZoom:         %s",    indentation, ' ',
-            pSettings->xVSS.isPanZoom ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c PanZoomXa:         %d ms", indentation, ' ',
-            pSettings->xVSS.PanZoomXa);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c PanZoomTopleftXa:  %d ms", indentation, ' ',
-            pSettings->xVSS.PanZoomTopleftXa);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c PanZoomTopleftYa:  %d ms", indentation, ' ',
-            pSettings->xVSS.PanZoomTopleftYa);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c PanZoomXb:         %d ms", indentation, ' ',
-            pSettings->xVSS.PanZoomXb);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c PanZoomTopleftXb:  %d ms", indentation, ' ',
-            pSettings->xVSS.PanZoomTopleftXb);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c PanZoomTopleftYb:  %d ms", indentation, ' ',
-            pSettings->xVSS.PanZoomTopleftYb);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c MediaRendering:    %s",    indentation, ' ',
-            videoEditJava_getMediaRenderingString(pSettings->xVSS.MediaRendering));
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c <null>", indentation, ' ');
-    }
-}
-#endif
-
-
-void
-videoEditClasses_getEditSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4VSS3GPP_EditSettings**            ppSettings,
-                bool                                flag)
-{
-    VideoEditJava_EditSettingsFieldIds fieldIds;
-    jobjectArray               clipSettingsArray           = NULL;
-    jsize                      clipSettingsArraySize       = 0;
-    jobject                    clipSettings                = NULL;
-    jobjectArray               transitionSettingsArray     = NULL;
-    jsize                      transitionSettingsArraySize = 0;
-    jobject                    transitionSettings          = NULL;
-    jobjectArray               effectSettingsArray         = NULL;
-    jsize                      effectSettingsArraySize     = 0;
-    jobject                    effectSettings              = NULL;
-    jobject                    backgroundMusicSettings     = NULL;
-    int                        audioChannels               = 0;
-    M4VSS3GPP_EditSettings*    pSettings                   = M4OSA_NULL;
-    bool                       converted                   = true;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_EditSettingsFieldIds));
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "videoEditClasses_getEditSettings()");
-
-        // Retrieve the field ids.
-        videoEditJava_getEditSettingsFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only retrieve the EditSettings if the previous action succeeded.
-    if (*pResult)
-    {
-        // Check if the object is valid.
-        if (NULL != object)
-        {
-            // Retrieve the clipSettingsArray.
-            videoEditJava_getArray(pResult, pEnv, object,
-                           fieldIds.clipSettingsArray,
-                           &clipSettingsArray,
-                           &clipSettingsArraySize);
-
-            // Retrieve the transitionSettingsArray.
-            videoEditJava_getArray(pResult, pEnv, object,
-                           fieldIds.transitionSettingsArray,
-                           &transitionSettingsArray,
-                           &transitionSettingsArraySize);
-
-            // Retrieve the effectSettingsArray.
-            videoEditJava_getArray(pResult, pEnv, object,
-                           fieldIds.effectSettingsArray,
-                           &effectSettingsArray,
-                           &effectSettingsArraySize);
-
-            // Retrieve the backgroundMusicSettings.
-            videoEditJava_getObject(pResult, pEnv, object, fieldIds.backgroundMusicSettings,
-                    &backgroundMusicSettings);
-
-            // Check if the arrays and background music settings object could be retrieved.
-            if (*pResult)
-            {
-                // Retrieve the number of channels.
-                audioChannels = pEnv->GetIntField(object, fieldIds.audioChannels);
-            }
-        }
-    }
-
-    // Only validate the EditSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Check if there is at least one clip.
-        //videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-         //                                          (clipSettingsArraySize < 1),
-         //                                          "there should be at least one clip");
-        if(clipSettingsArraySize < 1) {
-            return;
-        }
-        if(flag)
-        {
-            // Check if there are clips.
-            if ((clipSettingsArraySize != 0) || (transitionSettingsArraySize != 0))
-            {
-                // The number of transitions must be equal to the number of clips - 1.
-                videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                         (clipSettingsArraySize != (transitionSettingsArraySize + 1)),
-                         "the number of transitions should be equal to the number of clips - 1");
-            }
-        }
-    }
-
-    // Only retrieve the EditSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Check if the object is valid.
-        if (NULL != object)
-        {
-            // Allocate memory for the EditSettings.
-            pSettings = (M4VSS3GPP_EditSettings*)videoEditOsal_alloc(pResult, pEnv,
-                    sizeof(M4VSS3GPP_EditSettings), "EditSettings");
-
-            // Check if memory could be allocated for the EditSettings.
-            if (*pResult)
-            {
-                // Set the number of clips that will be edited.
-                pSettings->uiClipNumber = clipSettingsArraySize;
-
-                // Check if the clip settings array contains items.
-                if (clipSettingsArraySize > 0)
-                {
-                    // Allocate memory for the clip settings array.
-                    pSettings->pClipList = (M4VSS3GPP_ClipSettings **)videoEditOsal_alloc(pResult,
-                                pEnv,
-                                clipSettingsArraySize * sizeof(M4VSS3GPP_ClipSettings *),
-                                "ClipSettingsArray");
-                    if (*pResult)
-                    {
-                        // Loop over all clip settings objects.
-                        for (int i = 0; ((*pResult) && (i < clipSettingsArraySize)); i++)
-                        {
-                            // Get the clip settings object.
-                            clipSettings = pEnv->GetObjectArrayElement(clipSettingsArray, i);
-
-                            // Get the clip settings.
-                            videoEditClasses_getClipSettings(pResult, pEnv, clipSettings,
-                                &pSettings->pClipList[i]);
-
-                            // Free the local references to avoid memory leaks
-                            pEnv->DeleteLocalRef(clipSettings);
-                        }
-                    }
-                }
-
-                // Check if the transition settings array contains items.
-                if (transitionSettingsArraySize > 0)
-                {
-                    // Allocate memory for the transition settings array.
-                    pSettings->pTransitionList =
-                            (M4VSS3GPP_TransitionSettings **)videoEditOsal_alloc(pResult,
-                                pEnv, transitionSettingsArraySize * sizeof(M4VSS3GPP_TransitionSettings *),
-                                "TransitionSettingsArray");
-                    if (*pResult)
-                    {
-                        // Loop over all transition settings objects.
-                        for (int i = 0; ((*pResult) && (i < transitionSettingsArraySize)); i++)
-                        {
-                            // Get the transition settings object.
-                            transitionSettings =
-                                    pEnv->GetObjectArrayElement(transitionSettingsArray, i);
-
-                            // Get the transition settings.
-                            videoEditClasses_getTransitionSettings(pResult, pEnv,
-                                    transitionSettings, &pSettings->pTransitionList[i]);
-
-                            // Free the local references to avoid memory leaks
-                            pEnv->DeleteLocalRef(transitionSettings);
-                        }
-                    }
-                }
-
-                // Check if the effect settings array contains items.
-                if (effectSettingsArraySize > 0)
-                {
-                    // Allocate memory for the effect settings array.
-                    pSettings->Effects = (M4VSS3GPP_EffectSettings*)videoEditOsal_alloc(pResult,
-                                pEnv,
-                                effectSettingsArraySize * sizeof(M4VSS3GPP_EffectSettings),
-                                "EffectSettingsArray");
-                    if (*pResult)
-                    {
-                        // Loop over all effect settings objects.
-                        for (int i = 0; ((*pResult) && (i < effectSettingsArraySize)); i++)
-                        {
-                            // Get the effect settings object.
-                            effectSettings = pEnv->GetObjectArrayElement(effectSettingsArray, i);
-
-                            // Get the effect settings.
-                            videoEditClasses_getEffectSettings(pResult, pEnv, effectSettings,
-                                    &pSettings->Effects[i]);
-
-                            // Free the local references to avoid memory leaks
-                            pEnv->DeleteLocalRef(effectSettings);
-                        }
-                    }
-                }
-
-                // Check if the clips, transitions and effects could be set.
-                if (*pResult)
-                {
-                    // Set the number of effects in the clip.
-                    pSettings->nbEffects = (M4OSA_UInt8)effectSettingsArraySize;
-
-                    // Set the frame rate of the output video.
-                    pSettings->videoFrameRate =
-                        (M4VIDEOEDITING_VideoFramerate)videoEditJava_getVideoFrameRateJavaToC(
-                             &converted, pEnv->GetIntField(object, fieldIds.videoFrameRate));
-
-                    // Check if the frame rate is valid.
-                    videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                        !converted, "editSettings.videoFrameRate is invalid");
-                }
-
-                // Check if the frame rate could be set.
-                if (*pResult)
-                {
-                    // Set the path of the output file.
-                    pSettings->pOutputFile = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv,
-                        object, fieldIds.outputFile, &pSettings->uiOutputPathSize);
-                }
-
-                // Check if path of the output file could be set.
-                if (*pResult)
-                {
-                    // Set the path of the temporary file produced when using
-                    // the constant memory 3gp writer.
-                    pSettings->pTemporaryFile = M4OSA_NULL;
-
-                    // Set the output video size.
-                    pSettings->xVSS.outputVideoSize =
-                        (M4VIDEOEDITING_VideoFrameSize)videoEditJava_getVideoFrameSizeJavaToC(
-                                &converted, pEnv->GetIntField(object, fieldIds.videoFrameSize));
-
-                    // Check if the output video size is valid.
-                    videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                        !converted, "editSettings.videoFrameSize is invalid");
-                }
-
-                // Check if the output video size could be set.
-                if (*pResult)
-                {
-                    // Set the output video format.
-                    pSettings->xVSS.outputVideoFormat =
-                        (M4VIDEOEDITING_VideoFormat)videoEditJava_getVideoFormatJavaToC(
-                               &converted, pEnv->GetIntField(object, fieldIds.videoFormat));
-
-                    // Check if the output video format is valid.
-                    videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                        !converted, "editSettings.videoFormat is invalid");
-                }
-
-                // Check if the output video format could be set.
-                if (*pResult)
-                {
-                    // Set the output audio format.
-                    pSettings->xVSS.outputAudioFormat =
-                            (M4VIDEOEDITING_AudioFormat)videoEditJava_getAudioFormatJavaToC(
-                                  &converted, pEnv->GetIntField(object, fieldIds.audioFormat));
-
-                    // Check if the output audio format is valid.
-                    videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                            !converted, "editSettings.audioFormat is invalid");
-                }
-
-                // Check if the output audio format could be set.
-                if (*pResult)
-                {
-                    // Set the output audio sampling frequency when not replacing the audio,
-                    // or replacing it with MP3 audio.
-                    pSettings->xVSS.outputAudioSamplFreq =
-                        (M4VIDEOEDITING_AudioSamplingFrequency)\
-                            videoEditJava_getAudioSamplingFrequencyJavaToC(
-                                &converted, pEnv->GetIntField(object, fieldIds.audioSamplingFreq));
-
-                    // Check if the output audio sampling frequency is valid.
-                    videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                            !converted, "editSettings.audioSamplingFreq is invalid");
-                }
-
-                // Check if the output audio sampling frequency could be set.
-                if (*pResult)
-                {
-                    // Check if the number of audio channels is valid.
-                    videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                        ((0 != audioChannels ) ||
-                        ((M4VIDEOEDITING_kNoneAudio != pSettings->xVSS.outputAudioFormat) &&
-                        (M4VIDEOEDITING_kNullAudio != pSettings->xVSS.outputAudioFormat) ) ) &&
-                        (1 != audioChannels ) &&
-                        (2 != audioChannels ),
-                        "editSettings.audioChannels must be set to 0, 1 or 2");
-                }
-
-                // Check if the number of audio channels is valid.
-                if (*pResult)
-                {
-                    // Set the maximum output file size (MMS usecase).
-                    pSettings->xVSS.outputFileSize = (M4OSA_UInt32)pEnv->GetIntField(object,
-                            fieldIds.maxFileSize);
-
-                    // Whether or not the audio is mono, only valid for AAC.
-                    pSettings->xVSS.bAudioMono = (M4OSA_Bool)(1 == audioChannels);
-
-                    // Set the output video bitrate.
-                    pSettings->xVSS.outputVideoBitrate = (M4OSA_UInt32)pEnv->GetIntField(object,
-                            fieldIds.videoBitrate);
-
-                    // Set the output video profile.
-                    pSettings->xVSS.outputVideoProfile = (M4OSA_UInt32)pEnv->GetIntField(object,
-                            fieldIds.videoProfile);
-
-                    // Set the output video level.
-                    pSettings->xVSS.outputVideoLevel = (M4OSA_UInt32)pEnv->GetIntField(object,
-                            fieldIds.videoLevel);
-
-                    // Set the output audio bitrate.
-                    pSettings->xVSS.outputAudioBitrate = (M4OSA_UInt32)pEnv->GetIntField(object,
-                            fieldIds.audioBitrate);
-
-                    // Set the background music settings.
-                    videoEditClasses_getBackgroundMusicSettings(pResult, pEnv,
-                            backgroundMusicSettings, &pSettings->xVSS.pBGMtrack);
-
-                    // Set the text rendering function (will be set elsewhere).
-                    pSettings->xVSS.pTextRenderingFct = M4OSA_NULL;
-                    pSettings->PTVolLevel =
-                            (M4OSA_Float)pEnv->GetIntField(object, fieldIds.primaryTrackVolume);
-                }
-            }
-
-            // Check if settings could be set.
-            if (*pResult)
-            {
-                // Return the settings.
-                (*ppSettings) = pSettings;
-            }
-            else
-            {
-                // Free the settings.
-                videoEditClasses_freeEditSettings(&pSettings);
-            }
-        }
-    }
-}
-
-void
-videoEditClasses_freeEditSettings(
-                M4VSS3GPP_EditSettings**            ppSettings)
-{
-    // Check if memory was allocated for the EditSettings.
-    if (M4OSA_NULL != (*ppSettings))
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "videoEditClasses_freeEditSettings()");
-
-        // Free the background music settings.
-        videoEditClasses_freeBackgroundMusicSettings(&(*ppSettings)->xVSS.pBGMtrack);
-
-        // Free the path of the output file.
-        videoEditOsal_free((*ppSettings)->pOutputFile);
-        (*ppSettings)->pOutputFile = M4OSA_NULL;
-        (*ppSettings)->uiOutputPathSize = 0;
-
-        // Check if the EffectSettings should be freed.
-        if (M4OSA_NULL != (*ppSettings)->Effects)
-        {
-            // Loop over all effect settings.
-            for (int i = 0; i < (*ppSettings)->nbEffects; i++)
-            {
-                // Free the effect settings.
-                videoEditClasses_freeEffectSettings(&(*ppSettings)->Effects[i]);
-            }
-
-            // Free the memory for the effect settings array.
-            videoEditOsal_free((*ppSettings)->Effects);
-            (*ppSettings)->Effects = M4OSA_NULL;
-        }
-
-        // Reset the number of effects in the clip.
-        (*ppSettings)->nbEffects = 0;
-
-        // Check if there are clips.
-        if (0 < (*ppSettings)->uiClipNumber)
-        {
-            // Check if the TransitionSettings should be freed.
-            if (M4OSA_NULL != (*ppSettings)->pTransitionList)
-            {
-                // Loop over all transition settings.
-                for (int i = 0; i < ((*ppSettings)->uiClipNumber - 1); i++)
-                {
-                    // Free the transition settings.
-                    videoEditClasses_freeTransitionSettings(&(*ppSettings)->pTransitionList[i]);
-                }
-
-                // Free the memory for the transition settings array.
-                videoEditOsal_free((*ppSettings)->pTransitionList);
-                (*ppSettings)->pTransitionList = M4OSA_NULL;
-            }
-
-            // Check if the ClipSettings should be freed.
-            if (M4OSA_NULL != (*ppSettings)->pClipList)
-            {
-                // Loop over all clip settings.
-                for (int i = 0; i < (*ppSettings)->uiClipNumber; i++)
-                {
-                    // Free the clip settings.
-                    videoEditClasses_freeClipSettings(&(*ppSettings)->pClipList[i]);
-                }
-
-                // Free the memory for the clip settings array.
-                videoEditOsal_free((*ppSettings)->pClipList);
-                (*ppSettings)->pClipList = M4OSA_NULL;
-            }
-        }
-
-        // Reset the number of clips.
-        (*ppSettings)->uiClipNumber = 0;
-
-        // Free the settings structure.
-        videoEditOsal_free((*ppSettings));
-        (*ppSettings) = M4OSA_NULL;
-    }
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logEditSettings(
-                M4VSS3GPP_EditSettings*             pSettings,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the EditSettings.
-    if (M4OSA_NULL != pSettings)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiClipNumber:         %d", indentation, ' ',
-            pSettings->uiClipNumber);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiMasterClip:         %d", indentation, ' ',
-            pSettings->uiMasterClip);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pClipList:            %s", indentation, ' ',
-            (M4OSA_NULL != pSettings->pClipList) ? " " : "<null>");
-        if (M4OSA_NULL != pSettings->pClipList)
-        {
-            indentation += VIDEOEDIT_LOG_INDENTATION;
-            for (int i = 0; i < pSettings->uiClipNumber; i++)
-            {
-                VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                    "%*c pClipList[%d]:", indentation, ' ',
-                    i);
-                videoEditClasses_logClipSettings(pSettings->pClipList[i],
-                    indentation + VIDEOEDIT_LOG_INDENTATION);
-            }
-            indentation -= VIDEOEDIT_LOG_INDENTATION;
-        }
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pTransitionList:      %s", indentation, ' ',
-            (M4OSA_NULL != pSettings->pTransitionList) ? " " : "<null>");
-        if (M4OSA_NULL != pSettings->pTransitionList)
-        {
-            indentation += VIDEOEDIT_LOG_INDENTATION;
-            for (int i = 0; i < (pSettings->uiClipNumber - 1); i++)
-            {
-                VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                    "%*c pTransitionList[%d]:", indentation, ' ', i);
-                videoEditClasses_logTransitionSettings(pSettings->pTransitionList[i],
-                    indentation + VIDEOEDIT_LOG_INDENTATION);
-            }
-            indentation -= VIDEOEDIT_LOG_INDENTATION;
-        }
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c Effects:              %s", indentation, ' ',
-            (M4OSA_NULL != pSettings->Effects)   ? " " : "<null>");
-        if (M4OSA_NULL != pSettings->Effects)
-        {
-            indentation += VIDEOEDIT_LOG_INDENTATION;
-            for (int i = 0; i < pSettings->nbEffects; i++)
-            {
-                VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                    "%*c Effects[%d]:", indentation, ' ',  i);
-                videoEditClasses_logEffectSettings(&pSettings->Effects[i],
-                    indentation + VIDEOEDIT_LOG_INDENTATION);
-            }
-            indentation -= VIDEOEDIT_LOG_INDENTATION;
-        }
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c nbEffects:            %d", indentation, ' ',
-            pSettings->nbEffects);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c videoFrameRate:       %s", indentation, ' ',
-            videoEditJava_getVideoFrameRateString(pSettings->videoFrameRate));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pOutputFile:          %s", indentation, ' ',
-            (M4OSA_NULL != pSettings->pOutputFile) ? (char*)pSettings->pOutputFile : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiOutputPathSize:     %u", indentation, ' ',
-            (unsigned int)pSettings->uiOutputPathSize);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pTemporaryFile:       %s", indentation, ' ',
-            (M4OSA_NULL != pSettings->pTemporaryFile) ?\
-             (char*)pSettings->pTemporaryFile : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputVideoSize:      %s", indentation, ' ',
-            videoEditJava_getVideoFrameSizeString(pSettings->xVSS.outputVideoSize));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputVideoFormat:    %s", indentation, ' ',
-            videoEditJava_getVideoFormatString(pSettings->xVSS.outputVideoFormat));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputVideoProfile:    %u", indentation, ' ',
-            videoEditJava_getVideoFormatString(pSettings->xVSS.outputVideoProfile));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputVideoLevel:    %u", indentation, ' ',
-            videoEditJava_getVideoFormatString(pSettings->xVSS.outputVideoLevel));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputAudioFormat:    %s", indentation, ' ',
-            videoEditJava_getAudioFormatString(pSettings->xVSS.outputAudioFormat));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputAudioSamplFreq: %s", indentation, ' ',
-            videoEditJava_getAudioSamplingFrequencyString(pSettings->xVSS.outputAudioSamplFreq));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputFileSize:       %u", indentation, ' ',
-            (unsigned int)pSettings->xVSS.outputFileSize);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bAudioMono:           %s", indentation, ' ',
-            pSettings->xVSS.bAudioMono ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputVideoBitrate:   %s", indentation, ' ',
-            videoEditJava_getBitrateString(pSettings->xVSS.outputVideoBitrate));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c outputAudioBitrate:   %s", indentation, ' ',
-            videoEditJava_getBitrateString(pSettings->xVSS.outputAudioBitrate));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pBGMtrack:",               indentation, ' ');
-        videoEditClasses_logBackgroundMusicSettings(pSettings->xVSS.pBGMtrack,
-            indentation + VIDEOEDIT_LOG_INDENTATION);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pTextRenderingFct:    %s", indentation, ' ',
-            (M4OSA_NULL != pSettings->xVSS.pTextRenderingFct) ? "set" : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c PTVolLevel:       %u", indentation, ' ',
-            (unsigned int)pSettings->PTVolLevel);
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c <null>", indentation, ' ');
-    }
-}
-#endif
-
-
-void
-videoEditClasses_getEffectSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4VSS3GPP_EffectSettings*           pSettings)
-{
-
-    VideoEditJava_EffectSettingsFieldIds fieldIds;
-    bool                         converted = true;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_EffectSettingsFieldIds));
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-         "videoEditClasses_getEffectSettings()");
-
-        // Retrieve the field ids.
-        videoEditJava_getEffectSettingsFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only validate the EffectSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Check if the effect is set.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                                                    (NULL == object),
-                                                    "effect is null");
-    }
-
-    // Only retrieve the EffectSettings if the fields could be located and validated.
-    if (*pResult)
-    {
-        // Set the start time in milliseconds.
-        pSettings->uiStartTime = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.startTime);
-
-        // Set the duration in milliseconds.
-        pSettings->uiDuration = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.duration);
-
-        // Set the video effect type, None, FadeIn, FadeOut, etc.
-        pSettings->VideoEffectType =
-                (M4VSS3GPP_VideoEffectType)videoEditJava_getVideoEffectJavaToC(
-                              &converted, pEnv->GetIntField(object, fieldIds.videoEffectType));
-
-        // Check if the video effect type is valid.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                !converted, "effect.videoEffectType is invalid");
-    }
-
-    // Check if the video effect type could be set.
-    if (*pResult)
-    {
-        // Set the external effect function.
-        pSettings->ExtVideoEffectFct = M4OSA_NULL;
-
-        // Set the context given to the external effect function.
-        pSettings->pExtVideoEffectFctCtxt = M4OSA_NULL;
-
-        // Set the audio effect type, None, FadeIn, FadeOut.
-        pSettings->AudioEffectType =
-                (M4VSS3GPP_AudioEffectType)videoEditJava_getAudioEffectJavaToC(
-                        &converted, pEnv->GetIntField(object, fieldIds.audioEffectType));
-
-        // Check if the audio effect type is valid.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                !converted, "effect.audioEffectType is invalid");
-    }
-
-    // Check if the audio effect type could be set.
-    if (*pResult)
-    {
-        // Set the start in percentage of the cut clip duration.
-        pSettings->xVSS.uiStartPercent = (M4OSA_UInt32)pEnv->GetIntField(object,
-                fieldIds.startPercent);
-
-        // Set the duration in percentage of the ((clip duration) - (effect starttime)).
-        pSettings->xVSS.uiDurationPercent = (M4OSA_UInt32)pEnv->GetIntField(object,
-                fieldIds.durationPercent);
-
-        // Set the framing file path (GIF/PNG file).
-        pSettings->xVSS.pFramingFilePath = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv,
-                object, fieldIds.framingFile, M4OSA_NULL);
-
-        // Check if this is a framing effect.
-        if (M4xVSS_kVideoEffectType_Framing == (M4xVSS_VideoEffectType)pSettings->VideoEffectType)
-        {
-            // Check if the framing file path is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                    (M4OSA_NULL == pSettings->xVSS.pFramingFilePath), "effect.framingFile is null");
-        }
-    }
-
-    // Check if the framing file path could be retrieved.
-    if (*pResult)
-    {
-        // Set the Framing RGB565 buffer.
-        pSettings->xVSS.pFramingBuffer = M4OSA_NULL;
-
-        // Set the top-left X coordinate in the output picture
-        // where the added frame will be displayed.
-        pSettings->xVSS.topleft_x = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.topLeftX);
-
-        // Set the top-left Y coordinate in the output picture
-        // where the added frame will be displayed.
-        pSettings->xVSS.topleft_y = (M4OSA_UInt32)pEnv->GetIntField(object, fieldIds.topLeftY);
-
-        // Set whether or not the framing image is resized to output video size.
-        pSettings->xVSS.bResize =
-                (M4OSA_Bool)pEnv->GetBooleanField(object, fieldIds.framingResize);
-
-        // Set the new size to which framing buffer needs to be resized to
-        pSettings->xVSS.framingScaledSize =
-                (M4VIDEOEDITING_VideoFrameSize)pEnv->GetIntField(object, fieldIds.framingScaledSize);
-
-        // Set the text buffer.
-        pSettings->xVSS.pTextBuffer = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv, object,
-                fieldIds.text, &pSettings->xVSS.textBufferSize);
-    }
-
-    // Check if the text buffer could be retrieved.
-    if (*pResult)
-    {
-        // Set the data used by the font engine (size, color...).
-        pSettings->xVSS.pRenderingData = (M4OSA_Char*)videoEditJava_getString(pResult, pEnv,
-                object, fieldIds.textRenderingData, M4OSA_NULL);
-    }
-
-    // Check if the text rendering data could be retrieved.
-    if (*pResult)
-    {
-        // Set the text plane width.
-        pSettings->xVSS.uiTextBufferWidth = (M4OSA_UInt32)pEnv->GetIntField(object,
-                fieldIds.textBufferWidth);
-
-        // Set the text plane height.
-        pSettings->xVSS.uiTextBufferHeight = (M4OSA_UInt32)pEnv->GetIntField(object,
-                fieldIds.textBufferHeight);
-
-        // Set the processing rate of the effect added when using the Fifties effect.
-        pSettings->xVSS.uiFiftiesOutFrameRate = (M4OSA_UInt32)pEnv->GetIntField(object,
-                fieldIds.fiftiesFrameRate);
-
-        // Set the RGB16 input color of the effect added when using the rgb16 color effect.
-        pSettings->xVSS.uiRgb16InputColor = (M4OSA_UInt16)pEnv->GetIntField(object,
-                fieldIds.rgb16InputColor);
-
-        // Set the start percentage of Alpha blending.
-        pSettings->xVSS.uialphaBlendingStart = (M4OSA_UInt8)pEnv->GetIntField(object,
-                fieldIds.alphaBlendingStartPercent);
-
-        // Set the middle percentage of Alpha blending.
-        pSettings->xVSS.uialphaBlendingMiddle = (M4OSA_UInt8)pEnv->GetIntField(object,
-                fieldIds.alphaBlendingMiddlePercent);
-
-        // Set the end percentage of Alpha blending.
-        pSettings->xVSS.uialphaBlendingEnd = (M4OSA_UInt8)pEnv->GetIntField(object,
-                fieldIds.alphaBlendingEndPercent);
-
-        // Set the duration, in percentage of effect duration, of the FadeIn phase.
-        pSettings->xVSS.uialphaBlendingFadeInTime = (M4OSA_UInt8)pEnv->GetIntField(object,
-                fieldIds.alphaBlendingFadeInTimePercent);
-
-        // Set the duration, in percentage of effect duration, of the FadeOut phase.
-        pSettings->xVSS.uialphaBlendingFadeOutTime = (M4OSA_UInt8)pEnv->GetIntField(object,
-                fieldIds.alphaBlendingFadeOutTimePercent);
-
-        if (pSettings->xVSS.pFramingFilePath != M4OSA_NULL)
-        {
-            pSettings->xVSS.pFramingBuffer =
-                (M4VIFI_ImagePlane *)M4OSA_32bitAlignedMalloc(sizeof(M4VIFI_ImagePlane),
-                0x00,(M4OSA_Char *)"framing buffer");
-        }
-
-        if (pSettings->xVSS.pFramingBuffer != M4OSA_NULL)
-        {
-             // OverFrame height and width
-            pSettings->xVSS.pFramingBuffer->u_width = pEnv->GetIntField(object,
-             fieldIds.width);
-
-            pSettings->xVSS.pFramingBuffer->u_height = pEnv->GetIntField(object,
-             fieldIds.height);
-
-            pSettings->xVSS.width = pSettings->xVSS.pFramingBuffer->u_width;
-            pSettings->xVSS.height = pSettings->xVSS.pFramingBuffer->u_height;
-            pSettings->xVSS.rgbType = M4VSS3GPP_kRGB565;
-
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                    "pFramingBuffer u_width %d ", pSettings->xVSS.pFramingBuffer->u_width);
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                    "pFramingBuffer u_height %d", pSettings->xVSS.pFramingBuffer->u_height);
-
-        }
-
-        // Check if settings could be set.
-        if (!(*pResult))
-        {
-            // Free the settings.
-            videoEditClasses_freeEffectSettings(pSettings);
-        }
-    }
-}
-
-void
-videoEditClasses_freeEffectSettings(
-                M4VSS3GPP_EffectSettings*           pSettings)
-{
-    // Check if memory was allocated for the EffectSettings.
-    if (M4OSA_NULL != pSettings)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "videoEditClasses_freeEffectSettings()");
-
-        // Free the data used by the font engine (size, color...).
-        videoEditOsal_free(pSettings->xVSS.pRenderingData);
-        pSettings->xVSS.pRenderingData = M4OSA_NULL;
-
-        // Free the text buffer.
-        videoEditOsal_free(pSettings->xVSS.pTextBuffer);
-        pSettings->xVSS.pTextBuffer = M4OSA_NULL;
-        pSettings->xVSS.textBufferSize = 0;
-
-        // Free the framing file path.
-        videoEditOsal_free(pSettings->xVSS.pFramingFilePath);
-        pSettings->xVSS.pFramingFilePath = M4OSA_NULL;
-    }
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logEffectSettings(
-                M4VSS3GPP_EffectSettings*           pSettings,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the EffectSettings.
-    if (M4OSA_NULL != pSettings)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiStartTime:                %u ms", indentation, ' ',
-            (unsigned int)pSettings->uiStartTime);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiDuration:                 %u ms", indentation, ' ',
-            (unsigned int)pSettings->uiDuration);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c VideoEffectType:            %s",    indentation, ' ',
-            videoEditJava_getVideoEffectString(pSettings->VideoEffectType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-             "%*c ExtVideoEffectFct:          %s",    indentation, ' ',
-            (M4OSA_NULL != pSettings->ExtVideoEffectFct) ? "set" : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pExtVideoEffectFctCtxt:     %s",    indentation, ' ',
-            (M4OSA_NULL != pSettings->pExtVideoEffectFctCtxt) ? "set" : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c AudioEffectType:            %s",    indentation, ' ',
-            videoEditJava_getAudioEffectString(pSettings->AudioEffectType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiStartPercent:             %u %%", indentation, ' ',
-            (unsigned int)pSettings->xVSS.uiStartPercent);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiDurationPercent:          %u %%", indentation, ' ',
-            (unsigned int)pSettings->xVSS.uiDurationPercent);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pFramingFilePath:           %s",    indentation, ' ',
-            (M4OSA_NULL != pSettings->xVSS.pFramingFilePath) ?\
-             (char*)pSettings->xVSS.pFramingFilePath : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pFramingBuffer:             %s",    indentation, ' ',
-            (M4OSA_NULL != pSettings->xVSS.pFramingBuffer) ? "set" : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c topleft_x:                  %u",    indentation, ' ',
-            (unsigned int)pSettings->xVSS.topleft_x);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c topleft_y:                  %u",    indentation, ' ',
-            (unsigned int)pSettings->xVSS.topleft_y);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c bResize:                    %s",    indentation, ' ',
-            pSettings->xVSS.bResize ? "true" : "false");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pTextBuffer:                %s",    indentation, ' ',
-            (M4OSA_NULL != pSettings->xVSS.pTextBuffer) ?\
-             (char*)pSettings->xVSS.pTextBuffer : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c textBufferSize:             %u",    indentation, ' ',
-            (unsigned int)pSettings->xVSS.textBufferSize);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c pRenderingData:             %s",    indentation, ' ',
-            (M4OSA_NULL != pSettings->xVSS.pRenderingData) ?\
-             (char*)pSettings->xVSS.pRenderingData : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiTextBufferWidth:          %u",    indentation, ' ',
-            (unsigned int)pSettings->xVSS.uiTextBufferWidth);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-             "%*c uiTextBufferHeight:         %u",    indentation, ' ',
-            (unsigned int)pSettings->xVSS.uiTextBufferHeight);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiFiftiesOutFrameRate:      %u",    indentation, ' ',
-            (unsigned int)pSettings->xVSS.uiFiftiesOutFrameRate);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uiRgb16InputColor:          %d",    indentation, ' ',
-            pSettings->xVSS.uiRgb16InputColor);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uialphaBlendingStart:       %d %%", indentation, ' ',
-            pSettings->xVSS.uialphaBlendingStart);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uialphaBlendingMiddle:      %d %%", indentation, ' ',
-            pSettings->xVSS.uialphaBlendingMiddle);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uialphaBlendingEnd:         %d %%", indentation, ' ',
-            pSettings->xVSS.uialphaBlendingEnd);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uialphaBlendingFadeInTime:  %d %%", indentation, ' ',
-            pSettings->xVSS.uialphaBlendingFadeInTime);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c uialphaBlendingFadeOutTime: %d %%", indentation, ' ',
-            pSettings->xVSS.uialphaBlendingFadeOutTime);
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c <null>", indentation, ' ');
-    }
-}
-#endif
-
-
-void
-videoEditClasses_getSlideTransitionSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4xVSS_SlideTransitionSettings**    ppSettings)
-{
-    VideoEditJava_SlideTransitionSettingsFieldIds fieldIds  = {NULL};
-    M4xVSS_SlideTransitionSettings*       pSettings = M4OSA_NULL;
-    bool                                  converted = true;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "videoEditClasses_getSlideTransitionSettings()");
-
-        // Retrieve the field ids.
-        videoEditJava_getSlideTransitionSettingsFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-
-    // Only validate the SlideTransitionSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Check if the clip is set.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                                                    (NULL == object),
-                                                    "slideSettings is null");
-    }
-
-    // Only retrieve the SlideTransitionSettings if the fields could be located and validated.
-    if (*pResult)
-    {
-        // Allocate memory for the SlideTransitionSettings.
-        pSettings = (M4xVSS_SlideTransitionSettings*)videoEditOsal_alloc(pResult, pEnv,
-                sizeof(M4xVSS_SlideTransitionSettings), "SlideTransitionSettings");
-
-        // Check if memory could be allocated for the SlideTransitionSettings.
-        if (*pResult)
-        {
-            // Set the direction of the slide.
-            pSettings->direction =
-                    (M4xVSS_SlideTransition_Direction)videoEditJava_getSlideDirectionJavaToC(
-                            &converted, pEnv->GetIntField(object, fieldIds.direction));
-
-            // Check if the direction is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                    !converted, "slideSettings.direction is invalid");
-        }
-
-        // Check if settings could be set.
-        if (*pResult)
-        {
-            // Return the settings.
-            (*ppSettings) = pSettings;
-        }
-        else
-        {
-            // Free the settings.
-            videoEditClasses_freeSlideTransitionSettings(&pSettings);
-        }
-    }
-}
-
-void
-videoEditClasses_freeSlideTransitionSettings(
-                M4xVSS_SlideTransitionSettings**    ppSettings)
-{
-    // Check if memory was allocated for the SlideTransitionSettings.
-    if (M4OSA_NULL != (*ppSettings))
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                "videoEditClasses_freeSlideTransitionSettings()");
-
-        // Free the settings structure.
-        videoEditOsal_free((*ppSettings));
-        (*ppSettings) = M4OSA_NULL;
-    }
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logSlideTransitionSettings(
-                M4xVSS_SlideTransitionSettings*     pSettings,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the SlideTransitionSettings.
-    if (M4OSA_NULL != pSettings)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c direction: %s", indentation, ' ',
-            videoEditJava_getSlideDirectionString(pSettings->direction));
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-            "%*c <null>", indentation, ' ');
-    }
-}
-#endif
-
-
-void
-videoEditClasses_getTransitionSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4VSS3GPP_TransitionSettings**      ppSettings)
-{
-
-    VideoEditJava_TransitionSettingsFieldIds fieldIds;
-    jobject                          alphaSettings = NULL;
-    jobject                          slideSettings = NULL;
-    M4VSS3GPP_TransitionSettings*    pSettings     = M4OSA_NULL;
-    bool                             converted     = true;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_TransitionSettingsFieldIds));
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-               "videoEditClasses_getTransitionSettings()");
-
-        // Retrieve the field ids.
-        videoEditJava_getTransitionSettingsFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only validate the TransitionSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Check if the transition is set.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                                                    (NULL == object),
-                                                    "transition is null");
-    }
-
-    // Check if the field ids could be located and validated.
-    if (*pResult)
-    {
-        // Retrieve the alphaSettings.
-        videoEditJava_getObject(pResult, pEnv, object, fieldIds.alphaSettings, &alphaSettings);
-
-        // Retrieve the slideSettings.
-        videoEditJava_getObject(pResult, pEnv, object, fieldIds.slideSettings, &slideSettings);
-    }
-
-    // Only retrieve the TransitionSettings if the fields could be located.
-    if (*pResult)
-    {
-        // Allocate memory for the TransitionSettings.
-        pSettings = (M4VSS3GPP_TransitionSettings*)videoEditOsal_alloc(pResult,
-                pEnv, sizeof(M4VSS3GPP_TransitionSettings), "TransitionSettings");
-
-        // Check if memory could be allocated for the TransitionSettings.
-        if (*pResult)
-        {
-            // Set the duration of the transition, in milliseconds (set to 0 to get no transition).
-            pSettings->uiTransitionDuration = (M4OSA_UInt32)pEnv->GetIntField(object,
-                    fieldIds.duration);
-
-            // Set the type of the video transition.
-            pSettings->VideoTransitionType =
-                    (M4VSS3GPP_VideoTransitionType)videoEditJava_getVideoTransitionJavaToC(
-                             &converted, pEnv->GetIntField(object, fieldIds.videoTransitionType));
-
-            // Check if the video transition type is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, !converted,
-                            "transition.videoTransitionType is invalid");
-        }
-
-        // Check if the video transition type could be set.
-        if (*pResult)
-        {
-            // Set the external transition video effect function.
-            pSettings->ExtVideoTransitionFct = M4OSA_NULL;
-
-            // Set the context of the external transition video effect function.
-            pSettings->pExtVideoTransitionFctCtxt = M4OSA_NULL;
-
-            // Set the type of the audio transition.
-            pSettings->AudioTransitionType =
-                    (M4VSS3GPP_AudioTransitionType)videoEditJava_getAudioTransitionJavaToC(
-                            &converted, pEnv->GetIntField(object, fieldIds.audioTransitionType));
-
-            // Check if the audio transition type is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, !converted,
-                             "transition.audioTransitionType is invalid");
-        }
-
-        // Check if the audio transition type could be set.
-        if (*pResult)
-        {
-            // Set the transition behaviour.
-            pSettings->TransitionBehaviour =
-                    (M4VSS3GPP_TransitionBehaviour)videoEditJava_getTransitionBehaviourJavaToC(
-                            &converted, pEnv->GetIntField(object, fieldIds.transitionBehaviour));
-
-            // Check if the transition behaviour is valid.
-            videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, !converted,
-                                                    "transition.transitionBehaviour is invalid");
-        }
-
-        // Check if the audio transition behaviour could be set.
-        if (*pResult)
-        {
-            // Check if a slide transition or alpha magic setting object is expected.
-            if ((int)pSettings->VideoTransitionType == M4xVSS_kVideoTransitionType_SlideTransition)
-            {
-                // Set the slide transition settings.
-                videoEditClasses_getSlideTransitionSettings(pResult, pEnv, slideSettings,
-                                     &pSettings->xVSS.transitionSpecific.pSlideTransitionSettings);
-            }
-            else if ((int)pSettings->VideoTransitionType == M4xVSS_kVideoTransitionType_AlphaMagic)
-            {
-                // Set the alpha magic settings.
-                videoEditClasses_getAlphaMagicSettings(pResult, pEnv, alphaSettings,
-                                  &pSettings->xVSS.transitionSpecific.pAlphaMagicSettings);
-            }
-        }
-
-        // Check if settings could be set.
-        if (*pResult)
-        {
-            // Return the settings.
-            (*ppSettings) = pSettings;
-        }
-        else
-        {
-            // Free the settings.
-            videoEditClasses_freeTransitionSettings(&pSettings);
-        }
-    }
-}
-
-void
-videoEditClasses_freeTransitionSettings(
-                M4VSS3GPP_TransitionSettings**      ppSettings)
-{
-    // Check if memory was allocated for the TransitionSettings.
-    if (M4OSA_NULL != (*ppSettings))
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                               "videoEditClasses_freeTransitionSettings()");
-
-        // Check if a slide transition or alpha magic setting structure is expected.
-        if ((int)(*ppSettings)->VideoTransitionType == M4xVSS_kVideoTransitionType_SlideTransition)
-        {
-            // Free the slide transition settings.
-            videoEditClasses_freeSlideTransitionSettings(
-                               &(*ppSettings)->xVSS.transitionSpecific.pSlideTransitionSettings);
-        }
-        else
-        {
-            // Free the alpha magic settings.
-            videoEditClasses_freeAlphaMagicSettings(
-                              &(*ppSettings)->xVSS.transitionSpecific.pAlphaMagicSettings);
-        }
-
-        // Free the settings structure.
-        videoEditOsal_free((*ppSettings));
-        (*ppSettings) = M4OSA_NULL;
-    }
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logTransitionSettings(
-                M4VSS3GPP_TransitionSettings*       pSettings,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the TransitionSettings.
-    if (M4OSA_NULL != pSettings)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                               "%*c uiTransitionDuration:       %u ms", indentation, ' ',
-                                  (unsigned int)pSettings->uiTransitionDuration);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                           "%*c VideoTransitionType:        %s",    indentation, ' ',
-                           videoEditJava_getVideoTransitionString(pSettings->VideoTransitionType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                              "%*c ExtVideoTransitionFct:      %s",    indentation, ' ',
-                              (M4OSA_NULL != pSettings->ExtVideoTransitionFct) ? "set" : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                         "%*c pExtVideoTransitionFctCtxt: %s",    indentation, ' ',
-                         (M4OSA_NULL != pSettings->pExtVideoTransitionFctCtxt) ? "set" : "<null>");
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                         "%*c AudioTransitionType:        %s",    indentation, ' ',
-                          videoEditJava_getAudioTransitionString(pSettings->AudioTransitionType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                      "%*c TransitionBehaviour:        %s",    indentation, ' ',
-                      videoEditJava_getTransitionBehaviourString(pSettings->TransitionBehaviour));
-
-        // Check if a slide transition or alpha magic setting structure is expected.
-        if ((int)pSettings->VideoTransitionType == M4xVSS_kVideoTransitionType_SlideTransition)
-        {
-            // Log the slide transition settings.
-            VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                                   "%*c pSlideTransitionSettings:", indentation, ' ');
-            videoEditClasses_logSlideTransitionSettings\
-            (pSettings->xVSS.transitionSpecific.pSlideTransitionSettings,
-            indentation + VIDEOEDIT_LOG_INDENTATION);
-        }
-        else
-        {
-            // Log the alpha magic settings.
-            VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                                   "%*c pAlphaMagicSettings:", indentation, ' ');
-            videoEditClasses_logAlphaMagicSettings\
-            (pSettings->xVSS.transitionSpecific.pAlphaMagicSettings,
-            indentation + VIDEOEDIT_LOG_INDENTATION);
-        }
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                               "%*c <null>", indentation, ' ');
-    }
-}
-#endif
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditPropClass_logProperties(
-                VideoEditPropClass_Properties*                   pProperties,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the Properties.
-    if (M4OSA_NULL != pProperties)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c uiClipDuration:                   %u",       indentation, ' ',
-            (unsigned int)pProperties->uiClipDuration);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c FileType:                         %s",       indentation, ' ',
-            videoEditJava_getFileTypeString(pProperties->FileType));
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c VideoStreamType:                  %s",       indentation, ' ',
-            videoEditJava_getVideoFormatString(pProperties->VideoStreamType));
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c uiClipVideoDuration:              %u",       indentation, ' ',
-            (unsigned int)pProperties->uiClipVideoDuration);
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c uiVideoBitrate:                   %s",       indentation, ' ',
-            videoEditJava_getBitrateString(pProperties->uiVideoBitrate));
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c uiVideoWidth:                     %u",       indentation, ' ',
-            (unsigned int)pProperties->uiVideoWidth);
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c uiVideoHeight:                    %u",       indentation, ' ',
-            (unsigned int)(unsigned int)pProperties->uiVideoHeight);
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c fAverageFrameRate:                %.3f",     indentation, ' ',
-            pProperties->fAverageFrameRate);
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c AudioStreamType:                  %s",       indentation, ' ',
-            videoEditJava_getAudioFormatString(pProperties->AudioStreamType));
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c uiClipAudioDuration:              %u",       indentation, ' ',
-            (unsigned int)pProperties->uiClipAudioDuration);
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c uiAudioBitrate:                   %s",       indentation, ' ',
-            videoEditJava_getBitrateString(pProperties->uiAudioBitrate));
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c uiNbChannels:                     %u",       indentation, ' ',
-            (unsigned int)pProperties->uiNbChannels);
-
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-             "%*c uiSamplingFrequency:              %u",       indentation, ' ',
-            (unsigned int)pProperties->uiSamplingFrequency);
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_PROP_CLASSES",
-            "%*c <null>", indentation, ' ');
-    }
-}
-#endif
-
-
-void
-videoEditClasses_createVersion(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                M4_VersionInfo*                     pVersionInfo,
-                jobject*                            pObject)
-{
-
-    VideoEditJava_VersionFieldIds fieldIds;
-    jclass                clazz    = NULL;
-    jobject               object   = NULL;
-    memset(&fieldIds, 0, sizeof(VideoEditJava_VersionFieldIds));
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                               "videoEditClasses_createVersion()");
-
-        // Retrieve the class.
-        videoEditJava_getVersionClass(pResult, pEnv, &clazz);
-
-        // Retrieve the field ids.
-        videoEditJava_getVersionFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Only create an object if the class and fields could be located.
-    if (*pResult)
-    {
-        // Allocate a new object.
-        object = pEnv->AllocObject(clazz);
-
-        // check if alloc is done
-        videoEditJava_checkAndThrowRuntimeException(pResult, pEnv,
-                                                    (NULL == object),
-                                                    M4ERR_ALLOC);
-        if (NULL != object)
-        {
-            // Set the major field.
-            pEnv->SetIntField(object, fieldIds.major, pVersionInfo->m_major);
-
-            // Set the minor field.
-            pEnv->SetIntField(object, fieldIds.minor, pVersionInfo->m_minor);
-
-            // Set the revision field.
-            pEnv->SetIntField(object, fieldIds.revision, pVersionInfo->m_revision);
-
-            // Return the object.
-            (*pObject) = object;
-        }
-    }
-}
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-void
-videoEditClasses_logVersion(
-                M4_VersionInfo*                     pVersionInfo,
-                int                                 indentation)
-{
-    // Check if memory was allocated for the Version.
-    if (M4OSA_NULL != pVersionInfo)
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                             "%*c major:    %u ms", indentation, ' ',
-                             (unsigned int)pVersionInfo->m_major);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                              "%*c minor:    %u",    indentation, ' ',
-                              (unsigned int)pVersionInfo->m_minor);
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                             "%*c revision: %u",    indentation, ' ',
-                             (unsigned int)pVersionInfo->m_revision);
-    }
-    else
-    {
-        VIDEOEDIT_LOG_SETTING(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                              "%*c <null>", indentation, ' ');
-    }
-}
-#endif
-
-
-void*
-videoEditClasses_getContext(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object)
-{
-    void*                pContext = M4OSA_NULL;
-    jclass               clazz    = NULL;
-    VideoEditJava_EngineFieldIds fieldIds = {NULL};
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                               "videoEditClasses_getContext()");
-
-        // Retrieve the class.
-        videoEditJava_getEngineClass(pResult, pEnv, &clazz);
-
-        // Retrieve the field ids.
-        videoEditJava_getEngineFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Check if the class and field ids could be located.
-    if (*pResult)
-    {
-        // Retrieve the context pointer.
-        pContext = (void *)pEnv->GetLongField(object, fieldIds.context);
-    }
-
-    // Return the context pointer.
-    return(pContext);
-}
-
-void
-videoEditClasses_setContext(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                void*                               pContext)
-{
-    jclass               clazz    = NULL;
-    VideoEditJava_EngineFieldIds fieldIds = {NULL};
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                               "videoEditClasses_setContext()");
-
-        // Retrieve the class.
-        videoEditJava_getEngineClass(pResult, pEnv, &clazz);
-
-        // Retrieve the field ids.
-        videoEditJava_getEngineFieldIds(pResult, pEnv, &fieldIds);
-    }
-
-    // Check if the class and field ids could be located.
-    if (*pResult)
-    {
-        // Set the context field.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                        "The context value from JAVA before setting is = %p",
-                        (void *)pEnv->GetLongField(object, fieldIds.context));
-
-        pEnv->SetLongField(object, fieldIds.context, (jlong)pContext);
-        M4OSA_TRACE1_1("The context value in JNI is = %p",pContext);
-
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
-                         "The context value from JAVA after setting is = %p",
-                         (void *)pEnv->GetLongField(object, fieldIds.context));
-    }
-}
-
diff --git a/media/jni/mediaeditor/VideoEditorClasses.h b/media/jni/mediaeditor/VideoEditorClasses.h
deleted file mode 100644
index a4c82a8..0000000
--- a/media/jni/mediaeditor/VideoEditorClasses.h
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VIDEO_EDITOR_CLASSES_H
-#define VIDEO_EDITOR_CLASSES_H
-
-#include <VideoEditorJava.h>
-#include <VideoEditorClasses.h>
-/**
- ************************************************************************
- * @file        VideoEditorClasses.h
- * @brief       Interface for JNI methods/defines that have specific
- *              access to class, objects and method Ids defined in Java layer
- ************************************************************************
-*/
-
-
-extern "C" {
-#include <M4xVSS_API.h>
-#include <M4VSS3GPP_API.h>
-#include <M4VSS3GPP_ErrorCodes.h>
-#include <M4MCS_ErrorCodes.h>
-#include <M4READER_Common.h>
-#include <M4WRITER_common.h>
-};
-
-/*
- * Java layer class/object name strings
- */
-#define PACKAGE_NAME                           "android/media/videoeditor"
-
-#define MANUAL_EDIT_ENGINE_CLASS_NAME          PACKAGE_NAME"/MediaArtistNativeHelper"
-#define MEDIA_PROPERTIES_ENGINE_CLASS_NAME     PACKAGE_NAME"/MediaArtistNativeHelper"
-
-#define AUDIO_FORMAT_CLASS_NAME                MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioFormat"
-#define RESULTS_CLASS_NAME                     MANUAL_EDIT_ENGINE_CLASS_NAME"$Results"
-#define VERSION_CLASS_NAME                     MANUAL_EDIT_ENGINE_CLASS_NAME"$Version"
-#define AUDIO_SAMPLING_FREQUENCY_CLASS_NAME    MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioSamplingFrequency"
-#define BITRATE_CLASS_NAME                     MANUAL_EDIT_ENGINE_CLASS_NAME"$Bitrate"
-#define ERROR_CLASS_NAME                       MANUAL_EDIT_ENGINE_CLASS_NAME"$Result"
-#define FILE_TYPE_CLASS_NAME                   MANUAL_EDIT_ENGINE_CLASS_NAME"$FileType"
-#define MEDIA_RENDERING_CLASS_NAME             MANUAL_EDIT_ENGINE_CLASS_NAME"$MediaRendering"
-#define VIDEO_FORMAT_CLASS_NAME                MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoFormat"
-#define VIDEO_FRAME_RATE_CLASS_NAME            MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoFrameRate"
-#define VIDEO_FRAME_SIZE_CLASS_NAME            MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoFrameSize"
-#define VIDEO_PROFILE_CLASS_NAME               MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoProfile"
-#define ALPHA_MAGIC_SETTINGS_CLASS_NAME        MANUAL_EDIT_ENGINE_CLASS_NAME"$AlphaMagicSettings"
-#define AUDIO_EFFECT_CLASS_NAME                MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioEffect"
-#define AUDIO_TRANSITION_CLASS_NAME            MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioTransition"
-#define BACKGROUND_MUSIC_SETTINGS_CLASS_NAME   MANUAL_EDIT_ENGINE_CLASS_NAME"$BackgroundMusicSettings"
-#define CLIP_SETTINGS_CLASS_NAME               MANUAL_EDIT_ENGINE_CLASS_NAME"$ClipSettings"
-#define EDIT_SETTINGS_CLASS_NAME               MANUAL_EDIT_ENGINE_CLASS_NAME"$EditSettings"
-#define EFFECT_SETTINGS_CLASS_NAME             MANUAL_EDIT_ENGINE_CLASS_NAME"$EffectSettings"
-#define SLIDE_DIRECTION_CLASS_NAME             MANUAL_EDIT_ENGINE_CLASS_NAME"$SlideDirection"
-#define SLIDE_TRANSITION_SETTINGS_CLASS_NAME   MANUAL_EDIT_ENGINE_CLASS_NAME"$SlideTransitionSettings"
-#define TRANSITION_BEHAVIOUR_CLASS_NAME        MANUAL_EDIT_ENGINE_CLASS_NAME"$TransitionBehaviour"
-#define TRANSITION_SETTINGS_CLASS_NAME         MANUAL_EDIT_ENGINE_CLASS_NAME"$TransitionSettings"
-#define VIDEO_EFFECT_CLASS_NAME                MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoEffect"
-#define VIDEO_TRANSITION_CLASS_NAME            MANUAL_EDIT_ENGINE_CLASS_NAME"$VideoTransition"
-#define PREVIEW_CLIPS_CLASS_NAME               MANUAL_EDIT_ENGINE_CLASS_NAME"$PreviewClips"
-#define PREVIEW_SETTING_CLASS_NAME             MANUAL_EDIT_ENGINE_CLASS_NAME"$PreviewSettings"
-#define PREVIEW_PROPERTIES_CLASS_NAME          MANUAL_EDIT_ENGINE_CLASS_NAME"$PreviewClipProperties"
-#define AUDIO_SETTINGS_CLASS_NAME              MANUAL_EDIT_ENGINE_CLASS_NAME"$AudioSettings"
-#define PROPERTIES_CLASS_NAME                  MANUAL_EDIT_ENGINE_CLASS_NAME"$Properties"
-
-#define TASK_IDLE                                   0
-#define TASK_LOADING_SETTINGS                       1
-#define TASK_ENCODING                               2
-
-/*
- * File type enum
- */
-typedef enum
-{
-    VideoEditClasses_kFileType_3GPP,
-    VideoEditClasses_kFileType_MP4,
-    VideoEditClasses_kFileType_AMR,
-    VideoEditClasses_kFileType_MP3,
-    VideoEditClasses_kFileType_PCM,
-    VideoEditClasses_kFileType_JPG,
-    VideoEditClasses_kFileType_BMP,
-    VideoEditClasses_kFileType_GIF,
-    VideoEditClasses_kFileType_PNG,
-    VideoEditClasses_kFileType_ARGB8888,
-    VideoEditClasses_kFileType_M4V,
-    VideoEditClasses_kFileType_Unsupported
-} VideoEditClasses_FileType;
-
-/*
- * Alpha magic transition structure
- */
-typedef struct
-{
-    jfieldID file;
-    jfieldID blendingPercent;
-    jfieldID invertRotation;
-    jfieldID rgbWidth;
-    jfieldID rgbHeight;
-} VideoEditJava_AlphaMagicFieldIds;
-
-typedef struct
-{
-    jfieldID file;
-    jfieldID fileType;
-    jfieldID insertionTime;
-    jfieldID volumePercent;
-    jfieldID beginLoop;
-    jfieldID endLoop;
-    jfieldID enableDucking;
-    jfieldID duckingThreshold;
-    jfieldID lowVolume;
-    jfieldID isLooping;
-} VideoEditJava_BackgroundMusicFieldIds;
-/*
- * Structure to hold media properties from native layer
- */
-typedef struct {
-    M4OSA_UInt32 uiClipDuration;
-    VideoEditClasses_FileType  FileType;
-    M4VIDEOEDITING_VideoFormat VideoStreamType;
-    M4OSA_UInt32 uiClipVideoDuration;
-    M4OSA_UInt32 uiVideoBitrate;
-    M4OSA_UInt32 uiVideoWidth;
-    M4OSA_UInt32 uiVideoHeight;
-    M4OSA_Float  fAverageFrameRate;
-    M4OSA_UInt32 uiVideoProfile; /**< H263 or MPEG-4 or H264 profile(from core decoder) */
-    M4OSA_UInt32 uiVideoLevel;   /**< H263 or MPEG-4 or H264 level*/
-    M4OSA_Bool bProfileSupported;
-    M4OSA_Bool bLevelSupported;
-    M4VIDEOEDITING_AudioFormat AudioStreamType;
-    M4OSA_UInt32 uiClipAudioDuration;
-    M4OSA_UInt32 uiAudioBitrate;
-    M4OSA_UInt32 uiNbChannels;
-    M4OSA_UInt32 uiSamplingFrequency;
-    M4OSA_UInt32 uiRotation;
-} VideoEditPropClass_Properties;
-
-typedef struct
-{
-    jfieldID duration;
-    jfieldID fileType;
-    jfieldID videoFormat;
-    jfieldID videoDuration;
-    jfieldID videoBitrate;
-    jfieldID width;
-    jfieldID height;
-    jfieldID averageFrameRate;
-    jfieldID profile;
-    jfieldID level;
-    jfieldID profileSupported;
-    jfieldID levelSupported;
-    jfieldID audioFormat;
-    jfieldID audioDuration;
-    jfieldID audioBitrate;
-    jfieldID audioChannels;
-    jfieldID audioSamplingFrequency;
-    jfieldID videoRotation;
-} VideoEditJava_PropertiesFieldIds;
-
-
-typedef struct
-{
-    jfieldID clipPath;
-    jfieldID fileType;
-    jfieldID beginCutTime;
-    jfieldID endCutTime;
-    jfieldID beginCutPercent;
-    jfieldID endCutPercent;
-    jfieldID panZoomEnabled;
-    jfieldID panZoomPercentStart;
-    jfieldID panZoomTopLeftXStart;
-    jfieldID panZoomTopLeftYStart;
-    jfieldID panZoomPercentEnd;
-    jfieldID panZoomTopLeftXEnd;
-    jfieldID panZoomTopLeftYEnd;
-    jfieldID mediaRendering;
-    jfieldID rgbFileWidth;
-    jfieldID rgbFileHeight;
-    jfieldID rotationDegree;
-} VideoEditJava_ClipSettingsFieldIds;
-
-typedef struct
-{
-    jfieldID clipSettingsArray;
-    jfieldID transitionSettingsArray;
-    jfieldID effectSettingsArray;
-    jfieldID videoFrameRate;
-    jfieldID outputFile;
-    jfieldID videoFrameSize;
-    jfieldID videoFormat;
-    jfieldID videoProfile;
-    jfieldID videoLevel;
-    jfieldID audioFormat;
-    jfieldID audioSamplingFreq;
-    jfieldID maxFileSize;
-    jfieldID audioChannels;
-    jfieldID videoBitrate;
-    jfieldID audioBitrate;
-    jfieldID backgroundMusicSettings;
-    jfieldID primaryTrackVolume;
-} VideoEditJava_EditSettingsFieldIds;
-
-
-typedef struct
-{
-    jfieldID startTime;
-    jfieldID duration;
-    jfieldID videoEffectType;
-    jfieldID audioEffectType;
-    jfieldID startPercent;
-    jfieldID durationPercent;
-    jfieldID framingFile;
-    jfieldID framingBuffer;
-    jfieldID bitmapType;
-    jfieldID width;
-    jfieldID height;
-    jfieldID topLeftX;
-    jfieldID topLeftY;
-    jfieldID framingResize;
-    jfieldID framingScaledSize;
-    jfieldID text;
-    jfieldID textRenderingData;
-    jfieldID textBufferWidth;
-    jfieldID textBufferHeight;
-    jfieldID fiftiesFrameRate;
-    jfieldID rgb16InputColor;
-    jfieldID alphaBlendingStartPercent;
-    jfieldID alphaBlendingMiddlePercent;
-    jfieldID alphaBlendingEndPercent;
-    jfieldID alphaBlendingFadeInTimePercent;
-    jfieldID alphaBlendingFadeOutTimePercent;
-} VideoEditJava_EffectSettingsFieldIds;
-
-typedef struct
-{
-    jfieldID context;
-} VideoEditJava_EngineFieldIds;
-
-typedef struct
-{
-    jfieldID direction;
-} VideoEditJava_SlideTransitionSettingsFieldIds;
-
-typedef struct
-{
-    jfieldID duration;
-    jfieldID videoTransitionType;
-    jfieldID audioTransitionType;
-    jfieldID transitionBehaviour;
-    jfieldID alphaSettings;
-    jfieldID slideSettings;
-} VideoEditJava_TransitionSettingsFieldIds;
-
-typedef struct
-{
-    jfieldID major;
-    jfieldID minor;
-    jfieldID revision;
-} VideoEditJava_VersionFieldIds;
-
-
-typedef struct
-{
-    jmethodID onProgressUpdate;
-} VideoEditJava_EngineMethodIds;
-
-
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(AudioEffect           )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(AudioFormat           )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(AudioSamplingFrequency)
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(AudioTransition       )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(Bitrate               )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(Engine                )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(Error                 )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(FileType              )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(MediaRendering        )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(SlideDirection        )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(TransitionBehaviour   )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoEffect           )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoFormat           )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoFrameRate        )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoFrameSize        )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoProfile          )
-VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(VideoTransition       )
-
-
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(AlphaMagic               )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(BackgroundMusic          )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(ClipSettings             )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(ClipSettings             )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(EditSettings             )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(EffectSettings           )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(Engine                   )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(SlideTransitionSettings  )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(TransitionSettings       )
-VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(Version                  )
-
-VIDEOEDIT_JAVA_DECLARE_METHOD_CLASS(Engine                  )
-
-/*
- * Init all Edit settings related structures
- */
-void
-videoEditClasses_init(
-                bool*                               pResult,
-                JNIEnv*                             pEnv);
-/**
- ************************************************************************
- * @brief    Media Properties init function.
- * @param    pResult    (OUT) Pointer to hold result
- * @param    pEnv       (IN)  JVM Interface pointer
- ************************************************************************
-*/
-void
-videoEditPropClass_init(
-                bool*                               pResult,
-                JNIEnv*                             pEnv);
-/**
- ************************************************************************
- * @brief    Interface to populate Media Properties.
- * @param    pResult        (IN/OUT)    Pointer to hold result
- * @param    pEnv           (IN)        JVM Interface pointer
- * @param    pProperties    (IN)        Media propeties structure pointer
- * @param    pObject        (OUT)       Java object to hold media
- *                                      properties for java layer.
- ************************************************************************
-*/
-void
-videoEditPropClass_createProperties(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                VideoEditPropClass_Properties*      pProperties,
-                jobject*                            pObject);
-
-/**
- ************************************************************************
- * @brief    Interface to log/display media properties.
- * @param    pProperties    (IN) Pointer holding media properties
- * @param    indentation    (IN) Indentation to follow in display
- ************************************************************************
-*/
-void
-videoEditPropClass_logProperties(
-                VideoEditPropClass_Properties*      pProperties,
-                int                                 indentation);
-
-/*
- * Get alpha magic transition settings
- */
-void
-videoEditClasses_getAlphaMagicSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4xVSS_AlphaMagicSettings**         ppSettings);
-
-/*
- * Free alpha magic transition settings structure
- */
-void
-videoEditClasses_freeAlphaMagicSettings(
-                M4xVSS_AlphaMagicSettings**         ppSettings);
-
-/*
- * Log alpha magic transition settings
- */
-void
-videoEditClasses_logAlphaMagicSettings(
-                M4xVSS_AlphaMagicSettings*          pSettings,
-                int                                 indentation);
-
-/*
- * Get Background Track settings
- */
-void
-videoEditClasses_getBackgroundMusicSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4xVSS_BGMSettings**                ppSettings);
-
-/*
- * Free Background Track settings structure
- */
-void
-videoEditClasses_freeBackgroundMusicSettings(
-                M4xVSS_BGMSettings**                ppSettings);
-
-/*
- * Log Background Track settings
- */
-void
-videoEditClasses_logBackgroundMusicSettings(
-                M4xVSS_BGMSettings*                 pSettings,
-                int                                 indentation);
-
-/*
- * Log clip properties
- */
-void
-videoEditClasses_logClipProperties(
-                M4VIDEOEDITING_ClipProperties*      pProperties,
-                int                                 indentation);
-
-/*
- * Get clip settings from Java
- */
-void
-videoEditClasses_getClipSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4VSS3GPP_ClipSettings**            ppSettings);
-/**
- ************************************************************************
- * @brief   Interface function to retrieve media properties for a given
- *          file.
- * @param   pEnv    (IN)    Pointer holding media properties
- * @param   thiz    (IN)    Indentation to follow in display
- * @param   file    (IN)    File path for which media properties has
- *                          to be retrieved.
- ************************************************************************
-*/
-jobject
-videoEditProp_getProperties(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jstring                             file);
-
-/*
- * Create/Set the clip settings to java Object
- */
-void
-videoEditClasses_createClipSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                M4VSS3GPP_ClipSettings*             pSettings,
-                jobject*                            pObject);
-
-/*
- * Free clip settings structure
- */
-void
-videoEditClasses_freeClipSettings(
-                M4VSS3GPP_ClipSettings**            ppSettings);
-
-/*
- * Log clip settings structure
- */
-void
-videoEditClasses_logClipSettings(
-                M4VSS3GPP_ClipSettings*             pSettings,
-                int                                 indentation);
-
-/*
- * Get Edit settings from Java
- */
-void
-videoEditClasses_getEditSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4VSS3GPP_EditSettings**            ppSettings,
-                bool                                flag);
-
-/*
- * Free Edit Settings structure
- */
-void
-videoEditClasses_freeEditSettings(
-                M4VSS3GPP_EditSettings**            ppSettings);
-
-/*
- * Log Edit settings structure
- */
-void
-videoEditClasses_logEditSettings(
-                M4VSS3GPP_EditSettings*             pSettings,
-                int                                 indentation);
-
-/*
- * Get Effect settings from Java
- */
-void
-videoEditClasses_getEffectSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4VSS3GPP_EffectSettings*           pSettings);
-
-/*
- * Free Effect settings structure
- */
-void
-videoEditClasses_freeEffectSettings(
-                M4VSS3GPP_EffectSettings*           pSettings);
-
-/*
- * Log Effect settings
- */
-void
-videoEditClasses_logEffectSettings(
-                M4VSS3GPP_EffectSettings*           pSettings,
-                int                                 indentation);
-
-/*
- * Get Transition-Sliding settings from Java
- */
-void
-videoEditClasses_getSlideTransitionSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4xVSS_SlideTransitionSettings**    ppSettings);
-
-/*
- * Free Transition-Sliding structure
- */
-void
-videoEditClasses_freeSlideTransitionSettings(
-                M4xVSS_SlideTransitionSettings**    ppSettings);
-
-/*
- * Free Transition-Sliding structure
- */
-void
-videoEditClasses_logSlideTransitionSettings(
-                M4xVSS_SlideTransitionSettings*     pSettings,
-                int                                 indentation);
-
-/*
- * Get Transition settings from Java
- */
-void
-videoEditClasses_getTransitionSettings(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                M4VSS3GPP_TransitionSettings**      ppSettings);
-
-/*
- * Free Transition settings structure
- */
-void
-videoEditClasses_freeTransitionSettings(
-                M4VSS3GPP_TransitionSettings**      ppSettings);
-
-/*
- * Log Transition settings
- */
-void
-videoEditClasses_logTransitionSettings(
-                M4VSS3GPP_TransitionSettings*       pSettings,
-                int                                 indentation);
-
-/*
- * Set version information to Java object
- */
-void
-videoEditClasses_createVersion(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                M4_VersionInfo*                     pVersionInfo,
-                jobject*                            pObject);
-
-/*
- * Log Version information
- */
-void
-videoEditClasses_logVersion(
-                M4_VersionInfo*                     pVersionInfo,
-                int                                 indentation);
-
-
-void*
-videoEditClasses_getContext(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object);
-
-void
-videoEditClasses_setContext(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                void*                               pContext);
-
-
-#endif // VIDEO_EDITOR_CLASSES_H
-
diff --git a/media/jni/mediaeditor/VideoEditorJava.cpp b/media/jni/mediaeditor/VideoEditorJava.cpp
deleted file mode 100644
index fde0fb5..0000000
--- a/media/jni/mediaeditor/VideoEditorJava.cpp
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VideoEditorJava"
-
-#include <VideoEditorClasses.h>
-#include <VideoEditorJava.h>
-#include <VideoEditorLogging.h>
-#include <VideoEditorOsal.h>
-
-extern "C" {
-#include <M4OSA_CharStar.h>
-};
-
-
-void
-videoEditJava_checkAndThrowIllegalArgumentExceptionFunc(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                bool                                condition,
-                const char*                         pMessage,
-                const char*                         pFile,
-                int                                 lineNo)
-{
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Check if the condition is true.
-        if (condition)
-        {
-            // Log the exception.
-            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",\
-                    "videoEditJava_checkAndThrowIllegalArgumentException, %s (%s:%d)",
-                    pMessage, pFile, lineNo);
-
-            // Reset the result flag.
-            (*pResult) = false;
-
-            // Throw an exception.
-            jniThrowException(pEnv, "java/lang/IllegalArgumentException", pMessage);
-        }
-    }
-}
-
-void
-videoEditJava_checkAndThrowRuntimeExceptionFunc(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                bool                                condition,
-                M4OSA_ERR                           result,
-                const char*                         pFile,
-                int                                 lineNo
-                )
-{
-    const char* pMessage = NULL;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Check if the condition is true.
-        if (condition)
-        {
-            // Get the error string.
-            pMessage = videoEditJava_getErrorName(result);
-
-            // Log the exception.
-            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
-                    "videoEditJava_checkAndThrowRuntimeException, %s (%s:%d)",
-                    pMessage, pFile, lineNo);
-
-            // Reset the result flag.
-            (*pResult) = false;
-
-            // Throw an exception.
-            jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
-        }
-    }
-}
-
-void
-videoEditJava_checkAndThrowIllegalStateExceptionFunc(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                bool                                condition,
-                const char*                         pMessage,
-                const char*                         pFile,
-                int                                 lineNo
-                )
-{
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Check if the condition is true.
-        if (condition)
-        {
-            // Log the exception.
-            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
-                    "videoEditJava_checkAndThrowIllegalStateException, %s (%s:%d)",
-                    pMessage, pFile, lineNo);
-
-            // Reset the result flag.
-            (*pResult) = false;
-
-            // Throw an exception.
-            jniThrowException(pEnv, "java/lang/IllegalStateException", pMessage);
-        }
-    }
-}
-
-void
-videoEditJava_getClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                const char*                         pName,
-                jclass*                             pClazz)
-{
-    // Only look for the class if locating the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-                "videoEditJava_getClass(%s)", pName);
-
-        // Look up the class.
-        jclass clazz = pEnv->FindClass(pName);
-
-        // Clear any resulting exceptions.
-        pEnv->ExceptionClear();
-
-        // Check if the class could be located.
-        if (NULL != clazz)
-        {
-            // Return the class.
-            (*pClazz) = clazz;
-        }
-        else
-        {
-            // Reset the result flag.
-            (*pResult) = false;
-
-            // Log the error.
-            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
-                    "videoEditJava_getClass, error: unable to locate class %s", pName);
-
-            // Throw an exception.
-            jniThrowException(pEnv, "java/lang/ClassNotFoundException",
-                    "unable to locate class");
-        }
-    }
-}
-
-void
-videoEditJava_getMethodId(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jclass                              clazz,
-                const char*                         pName,
-                const char*                         pType,
-                jmethodID*                          pMethodId)
-{
-    // Only look for the class if locating the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-                "videoEditJava_getMethodId(%s,%s)", pName, pType);
-
-        // Look up the method id.
-        jmethodID methodId = pEnv->GetMethodID(clazz, pName, pType);
-
-        // Clear any resulting exceptions.
-        pEnv->ExceptionClear();
-
-        // Check if the method could be located.
-        if (NULL != methodId)
-        {
-            // Return the method id.
-            (*pMethodId) = methodId;
-        }
-        else
-        {
-            // Reset the result flag.
-            (*pResult) = false;
-
-            // Log the error.
-            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
-                    "videoEditJava_getMethodId, error: unable to locate method %s with type %s",
-                    pName, pType);
-
-            // Throw an exception.
-            jniThrowException(pEnv, "java/lang/NoSuchMethodException", "unable to locate method");
-        }
-    }
-}
-
-void
-videoEditJava_getFieldId(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jclass                              clazz,
-                const char*                         pName,
-                const char*                         pType,
-                jfieldID*                           pFieldId)
-{
-    // Only look for the class if locating the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-                "videoEditJava_getFieldId(%s,%s)", pName, pType);
-
-        // Look up the field id.
-        jfieldID fieldId = pEnv->GetFieldID(clazz, pName, pType);
-
-        // Clear any resulting exceptions.
-        pEnv->ExceptionClear();
-
-        // Check if the field could be located.
-        if (NULL != fieldId)
-        {
-            // Return the field id.
-            (*pFieldId) = fieldId;
-        }
-        else
-        {
-            // Reset the result flag.
-            (*pResult) = false;
-
-            // Log the error.
-            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
-                    "videoEditJava_getFieldId, error: unable to locate field %s with type %s",
-                    pName, pType);
-
-            // Throw an exception.
-            jniThrowException(pEnv, "java/lang/NoSuchFieldException", "unable to locate field");
-        }
-    }
-}
-
-void
-videoEditJava_getObject(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                jfieldID                            objectFieldId,
-                jobject*                            pObject)
-{
-    // Only retrieve the array object and size if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-            "videoEditJava_getObject()");
-
-        // Retrieve the object.
-        (*pObject) = pEnv->GetObjectField(object, objectFieldId);
-
-        // Clear any resulting exceptions.
-        pEnv->ExceptionClear();
-    }
-}
-
-void
-videoEditJava_getArray(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                jfieldID                            arrayFieldId,
-                jobjectArray*                       pArray,
-                jsize*                              pArraySize)
-{
-    // Only retrieve the array object and size if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", "videoEditJava_getArray()");
-
-        // Retrieve the array object.
-        jobjectArray array     = (jobjectArray)pEnv->GetObjectField(object, arrayFieldId);
-        jsize        arraySize = 0;
-
-        // Clear any resulting exceptions.
-        pEnv->ExceptionClear();
-
-        // Check if the array could be retrieved.
-        if (NULL != array)
-        {
-            // Retrieve the array size.
-            arraySize = pEnv->GetArrayLength(array);
-        }
-
-        // Return the array and its size.
-        (*pArray)     = array;
-        (*pArraySize) = arraySize;
-    }
-}
-
-void*
-videoEditJava_getString(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                jfieldID                            stringFieldId,
-                M4OSA_UInt32*                       pLength)
-{
-    void*        pString = M4OSA_NULL;
-    jstring      string  = NULL;
-    M4OSA_UInt32 length  = 0;
-    M4OSA_Char*  pLocal  = M4OSA_NULL;
-    M4OSA_ERR    result  = M4NO_ERROR;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA", "videoEditJava_getString()");
-
-        // Check if an object containing a string was specified.
-        if (NULL != stringFieldId)
-        {
-            // Retrieve the string object.
-            string = (jstring)pEnv->GetObjectField(object, stringFieldId);
-
-            // Clear any resulting exceptions.
-            pEnv->ExceptionClear();
-        }
-        else
-        {
-            // The string itself was specified.
-            string = (jstring)object;
-        }
-
-        // Check if the string could be retrieved.
-        if (NULL != string)
-        {
-            // Get a local copy of the string.
-            pLocal = (M4OSA_Char*)pEnv->GetStringUTFChars(string, M4OSA_NULL);
-            if (M4OSA_NULL != pLocal)
-            {
-                // Determine the length of the path
-                // (add one extra character for the zero terminator).
-                length = strlen((const char *)pLocal) + 1;
-
-                // Allocate memory for the string.
-                pString = videoEditOsal_alloc(pResult, pEnv, length, "String");
-                if (*pResult)
-                {
-                    // Copy the string.
-                    result = M4OSA_chrNCopy((M4OSA_Char*)pString, pLocal, length);
-
-                    // Check if the copy succeeded.
-                    videoEditJava_checkAndThrowRuntimeException(pResult, pEnv,
-                     (M4NO_ERROR != result), result);
-
-                    // Check if the string could not be copied.
-                    if (!(*pResult))
-                    {
-                        // Free the allocated memory.
-                        videoEditOsal_free(pString);
-                        pString = M4OSA_NULL;
-                    }
-                }
-
-                // Release the local copy of the string.
-                pEnv->ReleaseStringUTFChars(string, (const char *)pLocal);
-            }
-        }
-
-        // Check if the string was empty or could be copied.
-        if (*pResult)
-        {
-            // Check if the length was requested.
-            if (M4OSA_NULL != pLength)
-            {
-                // Return the length.
-                (*pLength) = length;
-            }
-        }
-
-        // Delete local references to avoid memory leaks
-        pEnv->DeleteLocalRef(string);
-    }
-
-    // Return the string.
-    return(pString);
-}
-
-void
-videoEditJava_getStaticIntField(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jclass                              clazz,
-                const char*                         pName,
-                int*                                pValue)
-{
-    // Only look for the class if locating the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-                "videoEditJava_getStaticIntField(%s)", pName);
-
-        // Look up the field id.
-        jfieldID fieldId = pEnv->GetStaticFieldID(clazz, pName, "I");
-
-        // Clear any resulting exceptions.
-        pEnv->ExceptionClear();
-
-        // Check if the field could be located.
-        if (NULL != fieldId)
-        {
-            // Retrieve the field value.
-            (*pValue) = pEnv->GetStaticIntField(clazz, fieldId);
-
-            // Log the value.
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-                    "videoEditJava_getStaticIntField, %s = %d", pName, (*pValue));
-        }
-        else
-        {
-            // Reset the result flag.
-            (*pResult) = false;
-
-            // Log the error.
-            VIDEOEDIT_LOG_EXCEPTION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_JAVA",
-                    "videoEditJava_getStaticIntField, error: unable to locate field %s", pName);
-
-            // Throw an exception.
-            jniThrowException(pEnv, "java/lang/NoSuchFieldException",
-                    "unable to locate static field");
-        }
-    }
-}
-
-void
-videoEditJava_initConstantClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                VideoEditJava_ConstantsClass*               pClass)
-{
-    bool   gotten = true;
-    jclass clazz  = NULL;
-    int    index  = 0;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-                "videoEditJava_initConstantClass(%s)", pClass->pName);
-
-        // Only initialize the class once.
-        if (!pClass->initialized)
-        {
-            // Look up the class.
-            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);
-
-            // Loop over the constants.
-            for (index = 0; index < pClass->count; index++)
-            {
-                // Look up the constant.
-                videoEditJava_getStaticIntField(pResult, pEnv, clazz,
-                                        pClass->pConstants[index].pName,
-                                        &pClass->pConstants[index].java);
-            }
-
-            // Check if all constants could be located.
-            if (*pResult)
-            {
-                // Set the initialized flag.
-                pClass->initialized = true;
-            }
-        }
-    }
-}
-
-const char*
-videoEditJava_getConstantClassName(
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value,
-                VideoEditJava_UnknownConstant               unknown)
-{
-    const char* pName = M4OSA_NULL;
-    int         index = 0;
-
-    // Loop over the list with constants.
-    for (index = 0;
-         ((M4OSA_NULL == pName) && (index < pClass->count));
-         index++)
-    {
-        // Check if the specified value matches the c value of the constant.
-        if (value == pClass->pConstants[index].c)
-        {
-            // Set the name.
-            pName = pClass->pConstants[index].pName;
-        }
-    }
-
-    // Check if no constant was found.
-    if (M4OSA_NULL == pName)
-    {
-        // Check if a function was specified to handle this case.
-        if (M4OSA_NULL != unknown)
-        {
-            // Pass the constant to the specified unknown function.
-            pName = unknown(value);
-        }
-        else
-        {
-            // Set the description to a default value.
-            pName = "<unknown>";
-        }
-    }
-
-    // Return the result.
-    return(pName);
-}
-
-const char*
-videoEditJava_getConstantClassString(
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value,
-                VideoEditJava_UnknownConstant               unknown)
-{
-    const char* pString = M4OSA_NULL;
-    int         index   = 0;
-
-    // Loop over the list with constants.
-    for (index = 0;
-         ((M4OSA_NULL == pString) && (index < pClass->count));
-         index++)
-    {
-        // Check if the specified value matches the c value of the constant.
-        if (value == pClass->pConstants[index].c)
-        {
-            // Set the description.
-            pString = pClass->pConstants[index].pDescription;
-        }
-    }
-
-    // Check if no constant was found.
-    if (M4OSA_NULL == pString)
-    {
-        // Check if a function was specified to handle this case.
-        if (M4OSA_NULL != unknown)
-        {
-            // Pass the constant to the specified unknown function.
-            pString = unknown(value);
-        }
-        else
-        {
-            // Set the description to a default value.
-            pString = "<unknown>";
-        }
-    }
-
-    // Return the result.
-    return(pString);
-}
-
-int
-videoEditJava_getConstantClassJavaToC(
-                bool*                               pResult,
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value)
-{
-    bool gotten = false;
-    int  index  = 0;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Loop over the list with constants.
-        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
-        {
-            // Check if the specified value matches the java value of the constant.
-            if (value == pClass->pConstants[index].java)
-            {
-                // Set the value to the c value.
-                value = pClass->pConstants[index].c;
-
-                // Set the gotten flag.
-                gotten = true;
-            }
-        }
-
-        // Check if the value was not found.
-        if (!gotten)
-        {
-            (*pResult) = false;
-        }
-    }
-
-    // Return the translated value.
-    return(value);
-}
-
-int
-videoEditJava_getConstantClassJavaToC(
-                bool*                               pResult,
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value,
-                int                                 unknown)
-{
-    bool gotten = false;
-    int  index  = 0;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Loop over the list with constants.
-        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
-        {
-            // Check if the specified value matches the java value of the constant.
-            if (value == pClass->pConstants[index].java)
-            {
-                // Set the value to the c value.
-                value = pClass->pConstants[index].c;
-
-                // Set the gotten flag.
-                gotten = true;
-            }
-        }
-
-        // If the constant was not found, look for the specified unknown.
-        if (!gotten)
-        {
-            // Set the value to the c value.
-            value = unknown;
-        }
-    }
-
-    // Return the translated value.
-    return(value);
-}
-
-int
-videoEditJava_getConstantClassCToJava(
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value)
-{
-    bool gotten = false;
-    int  index  = 0;
-
-    // Loop over the list with constants.
-    for (index = 0; ((!gotten) && (index < pClass->count)); index++)
-    {
-        // Check if the specified value matches the c value of the constant.
-        if (value == pClass->pConstants[index].c)
-        {
-            // Set the value to the java value.
-            value = pClass->pConstants[index].java;
-
-            // Set the gotten flag.
-            gotten = true;
-        }
-    }
-
-    // Return the translated value.
-    return(value);
-}
-
-int
-videoEditJava_getConstantClassCToJava(
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value,
-                int                                 unknown)
-{
-    bool gotten = false;
-    int  index  = 0;
-
-    // Loop over the list with constants.
-    for (index = 0; ((!gotten) && (index < pClass->count)); index++)
-    {
-        // Check if the specified value matches the c value of the constant.
-        if (value == pClass->pConstants[index].c)
-        {
-            // Set the value to the java value.
-            value = pClass->pConstants[index].java;
-
-            // Set the gotten flag.
-            gotten = true;
-        }
-    }
-
-    // If the constant was not found, look for the specified unknown.
-    if (!gotten)
-    {
-        // Loop over the list with constants.
-        for (index = 0; ((!gotten) && (index < pClass->count)); index++)
-        {
-            // Check if the specified value matches the java value of the constant.
-            if (unknown == pClass->pConstants[index].c)
-            {
-                // Set the value to the c value.
-                value = pClass->pConstants[index].java;
-
-                // Set the gotten flag.
-                gotten = true;
-            }
-        }
-    }
-
-    // Return the translated value.
-    return(value);
-}
-
-void
-videoEditJava_initFieldClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                VideoEditJava_FieldsClass*                  pClass)
-{
-    bool   gotten = true;
-    jclass clazz  = NULL;
-    int    index  = 0;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-                "videoEditJava_initFieldClass(%s)", pClass->pName);
-
-        // Only initialize the class once.
-        if (!pClass->initialized)
-        {
-            // Look up the class.
-            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);
-
-            // Loop over the fields.
-            for (index = 0; index < pClass->count; index++)
-            {
-                // Look up the field id.
-                videoEditJava_getFieldId(
-                        pResult,
-                        pEnv,
-                        clazz,
-                        pClass->pFields[index].pName,
-                        pClass->pFields[index].pType,
-                        &pClass->pFields[index].fieldId);
-            }
-
-            // Check if all fields could be located.
-            if (*pResult)
-            {
-                // Set the initialized flag.
-                pClass->initialized = true;
-            }
-        }
-    }
-}
-
-void
-videoEditJava_fieldClassClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                const VideoEditJava_FieldsClass*            pClass,
-                jclass*                             pClazz)
-{
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Check if the class is initialized.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
-                "field class not initialized");
-
-        // Get the class.
-        videoEditJava_getClass(pResult, pEnv, pClass->pName, pClazz);
-    }
-}
-
-void
-videoEditJava_fieldClassFieldIds(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                const VideoEditJava_FieldsClass*            pClass,
-                int                                 count,
-                VideoEditJava_FieldIds*                     pIds)
-{
-    int index = 0;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Check if the class is initialized.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
-                "field class not initialized");
-
-        // Check if the number of fields matches.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,
-                (pClass->count != count),
-                "field class type mismatch");
-
-        // Check if the class and object are valid.
-        if (*pResult)
-        {
-            // Loop over the class fields.
-            for (index = 0; index < count; index++)
-            {
-                // Copy the field ids.
-                pIds->fieldIds[index] = pClass->pFields[index].fieldId;
-            }
-        }
-    }
-}
-
-void
-videoEditJava_initMethodClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                VideoEditJava_MethodsClass*                 pClass)
-{
-    bool   gotten = true;
-    jclass clazz  = NULL;
-    int    index  = 0;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Log the function call.
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_JAVA",
-                "videoEditJava_initMethodClass(%s)", pClass->pName);
-
-        // Only initialize the class once.
-        if (!pClass->initialized)
-        {
-            // Look up the class.
-            videoEditJava_getClass(pResult, pEnv, pClass->pName, &clazz);
-
-            // Loop over the methods.
-            for (index = 0; index < pClass->count; index++)
-            {
-                // Look up the method id.
-                videoEditJava_getMethodId(
-                        pResult,
-                        pEnv,
-                        clazz,
-                        pClass->pMethods[index].pName,
-                        pClass->pMethods[index].pType,
-                        &pClass->pMethods[index].methodId);
-            }
-
-            // Check if all methods could be located.
-            if (*pResult)
-            {
-                // Set the initialized flag.
-                pClass->initialized = true;
-            }
-        }
-    }
-}
-
-void
-videoEditJava_methodClassMethodIds(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                const VideoEditJava_MethodsClass*   pClass,
-                int                                 count,
-                VideoEditJava_MethodIds*            pIds)
-{
-    int index = 0;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Check if the class is initialized.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv, (!pClass->initialized),
-                    "method class not initialized");
-
-        // Check if the number of methods matches.
-        videoEditJava_checkAndThrowIllegalArgumentException(pResult, pEnv,\
-                    (pClass->count != count),
-                    "method class type mismatch");
-
-        // Check if the class and object are valid.
-        if (*pResult)
-        {
-            // Loop over the class methods.
-            for (index = 0; index < count; index++)
-            {
-                // Copy the method ids.
-                pIds->methodIds[index] = pClass->pMethods[index].methodId;
-            }
-        }
-    }
-}
-
diff --git a/media/jni/mediaeditor/VideoEditorJava.h b/media/jni/mediaeditor/VideoEditorJava.h
deleted file mode 100644
index 0a2db08..0000000
--- a/media/jni/mediaeditor/VideoEditorJava.h
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VIDEO_EDiTOR_JAVA_H
-#define VIDEO_EDiTOR_JAVA_H
-
-#include <jni.h>
-#include <JNIHelp.h>
-
-/**
- ************************************************************************
- * @file        VideoEditorJava.h
- * @brief       Interface for JNI methods that have specific access to
- *              class, objects and method Ids defined in Java layer
- ************************************************************************
-*/
-
-extern "C" {
-#include <M4OSA_Types.h>
-#include <M4OSA_Error.h>
-}
-
-#define VIDEOEDIT_JAVA_CONSTANT_INIT(m_name, m_c)                           \
-            { m_name,                                                       \
-              0,                                                            \
-              m_c,                                                          \
-              #m_c }
-
-#define VIDEOEDIT_JAVA_DEFINE_CONSTANTS(m_class)                            \
-static                                                                      \
-VideoEditJava_Constant g##m_class##Constants [] =
-
-#define VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(                               \
-                m_class,                                                    \
-                m_name,                                                     \
-                m_unknownName,                                              \
-                m_unknownString)                                            \
-                                                                            \
-static VideoEditJava_ConstantsClass g##m_class##ConstantsClass =            \
-{       m_name,                                                             \
-        &g##m_class##Constants[0],                                          \
-        (sizeof(g##m_class##Constants) / sizeof(VideoEditJava_Constant)),   \
-        false                                                               \
-};                                                                          \
-                                                                            \
-                                                                            \
-void videoEditJava_init##m_class##Constants(                                \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv)                   \
-{                                                                           \
-    videoEditJava_initConstantClass(                                        \
-                pResult,                                                    \
-                pEnv,                                                       \
-                &g##m_class##ConstantsClass);                               \
-}                                                                           \
-                                                                            \
-const char* videoEditJava_get##m_class##Name(                               \
-                int                                 value)                  \
-{                                                                           \
-    return(videoEditJava_getConstantClassName(                              \
-                &g##m_class##ConstantsClass,                                \
-                value,                                                      \
-                m_unknownName));                                            \
-}                                                                           \
-                                                                            \
-const char* videoEditJava_get##m_class##String(                             \
-                int                                 value)                  \
-{                                                                           \
-    return(videoEditJava_getConstantClassString(                            \
-                &g##m_class##ConstantsClass,                                \
-                value,                                                      \
-                m_unknownString));                                          \
-}                                                                           \
-                                                                            \
-int                                                                         \
-videoEditJava_get##m_class##JavaToC(                                        \
-                bool*                               pResult,                \
-                int                                 value)                  \
-{                                                                           \
-    return(videoEditJava_getConstantClassJavaToC(                           \
-                pResult,                                                    \
-                &g##m_class##ConstantsClass,                                \
-                value));                                                    \
-}                                                                           \
-                                                                            \
-int                                                                         \
-videoEditJava_get##m_class##JavaToC(                                        \
-                bool*                               pResult,                \
-                int                                 value,                  \
-                int                                 unknown)                \
-{                                                                           \
-    return(videoEditJava_getConstantClassJavaToC(                           \
-                pResult,                                                    \
-                &g##m_class##ConstantsClass,                                \
-                value,                                                      \
-                unknown));                                                  \
-}                                                                           \
-                                                                            \
-int                                                                         \
-videoEditJava_get##m_class##CToJava(                                        \
-                        int                                 value)          \
-{                                                                           \
-    return(videoEditJava_getConstantClassCToJava(                           \
-                &g##m_class##ConstantsClass,                                \
-                value));                                                    \
-}                                                                           \
-                                                                            \
-int                                                                         \
-videoEditJava_get##m_class##CToJava(                                        \
-                int                                 value,                  \
-                int                                 unknown)                \
-{                                                                           \
-    return(videoEditJava_getConstantClassCToJava(                           \
-                &g##m_class##ConstantsClass,                                \
-                value,                                                      \
-                unknown));                                                  \
-}
-
-
-#define VIDEOEDIT_JAVA_DECLARE_CONSTANT_CLASS(m_class)                       \
-void                                                                        \
-videoEditJava_init##m_class##Constants(                                     \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv);                  \
-                                                                            \
-const char*                                                                 \
-videoEditJava_get##m_class##Name(                                           \
-                int                                 value);                 \
-                                                                            \
-const char*                                                                 \
-videoEditJava_get##m_class##String(                                         \
-                int                                 value);                 \
-                                                                            \
-int                                                                         \
-videoEditJava_get##m_class##JavaToC(                                        \
-                bool*                               pResult,                \
-                int                                 value,                  \
-                int                                 unknown);               \
-                                                                            \
-int                                                                         \
-videoEditJava_get##m_class##JavaToC(                                        \
-                bool*                               pResult,                \
-                int                                 value);                 \
-                                                                            \
-int                                                                         \
-videoEditJava_get##m_class##CToJava(                                        \
-                int                                 value);                 \
-                                                                            \
-int                                                                         \
-videoEditJava_get##m_class##CToJava(                                        \
-                int                                 value,                  \
-                int                                 unknown);
-
-#define VIDEOEDIT_JAVA_FIELD_INIT(m_name, m_type)                           \
-    { m_name,                                                               \
-      m_type,                                                               \
-      NULL }
-
-#define VIDEOEDIT_JAVA_DEFINE_FIELDS(m_class)                               \
-static                                                                      \
-VideoEditJava_Field g##m_class##Fields [] =
-
-#define VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(m_class, m_name)                  \
-static VideoEditJava_FieldsClass g##m_class##FieldsClass =                  \
-    { m_name,                                                               \
-      &g##m_class##Fields[0],                                               \
-      (sizeof(g##m_class##Fields) / sizeof(VideoEditJava_Field)),           \
-      false };                                                              \
-                                                                            \
-void                                                                        \
-videoEditJava_init##m_class##Fields(                                        \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv)                   \
-{                                                                           \
-    videoEditJava_initFieldClass(                                           \
-                pResult,                                                    \
-                pEnv,                                                       \
-                &g##m_class##FieldsClass);                                  \
-}                                                                           \
-                                                                            \
-void                                                                        \
-videoEditJava_get##m_class##Class(                                          \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv,                   \
-                jclass*                             pClazz)                 \
-{                                                                           \
-    videoEditJava_fieldClassClass(                                          \
-                pResult,                                                    \
-                pEnv,                                                       \
-                &g##m_class##FieldsClass,                                   \
-                pClazz);                                                    \
-}                                                                           \
-                                                                            \
-void                                                                        \
-videoEditJava_get##m_class##FieldIds(                                       \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv,                   \
-                VideoEditJava_##m_class##FieldIds*          pIds)           \
-{                                                                           \
-    videoEditJava_fieldClassFieldIds(                                       \
-                pResult,                                                    \
-                pEnv,                                                       \
-                &g##m_class##FieldsClass,                                   \
-                (sizeof(VideoEditJava_##m_class##FieldIds) /                \
-                 sizeof(jfieldID)),                                         \
-                (VideoEditJava_FieldIds*)pIds);                             \
-}
-
-#define VIDEOEDIT_JAVA_DECLARE_FIELD_CLASS(m_class)                         \
-void                                                                        \
-videoEditJava_init##m_class##Fields(                                        \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv);                  \
-                                                                            \
-void                                                                        \
-videoEditJava_get##m_class##Class(                                          \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv,                   \
-                jclass*                             pClazz);                \
-                                                                            \
-void                                                                        \
-videoEditJava_get##m_class##FieldIds(                                       \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv,                   \
-                VideoEditJava_##m_class##FieldIds*          pIds);
-
-
-#define VIDEOEDIT_JAVA_METHOD_INIT(m_name, m_type)                          \
-    { m_name,                                                               \
-      m_type,                                                               \
-      NULL }
-
-#define VIDEOEDIT_JAVA_DEFINE_METHODS(m_class)                              \
-static                                                                      \
-VideoEditJava_Method g##m_class##Methods [] =
-
-#define VIDEOEDIT_JAVA_DEFINE_METHOD_CLASS(m_class, m_name)                 \
-static VideoEditJava_MethodsClass g##m_class##MethodsClass =                \
-    { m_name,                                                               \
-      &g##m_class##Methods[0],                                              \
-      (sizeof(g##m_class##Methods) / sizeof(VideoEditJava_Method)),         \
-      false };                                                              \
-                                                                            \
-void                                                                        \
-videoEditJava_init##m_class##Methods(                                       \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv)                   \
-{                                                                           \
-    videoEditJava_initMethodClass(                                          \
-                pResult,                                                    \
-                pEnv,                                                       \
-                &g##m_class##MethodsClass);                                 \
-}                                                                           \
-                                                                            \
-void                                                                        \
-videoEditJava_get##m_class##MethodIds(                                      \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv,                   \
-                VideoEditJava_##m_class##MethodIds*         pIds)           \
-{                                                                           \
-    videoEditJava_methodClassMethodIds(                                     \
-                pResult,                                                    \
-                pEnv,                                                       \
-                &g##m_class##MethodsClass,                                  \
-                (sizeof(VideoEditJava_##m_class##MethodIds) /               \
-                 sizeof(jmethodID)),                                        \
-                (VideoEditJava_MethodIds*)pIds);                            \
-}
-
-#define VIDEOEDIT_JAVA_DECLARE_METHOD_CLASS(m_class)                        \
-void                                                                        \
-videoEditJava_init##m_class##Methods(                                       \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv);                  \
-                                                                            \
-void                                                                        \
-videoEditJava_get##m_class##MethodIds(                                      \
-                bool*                               pResult,                \
-                JNIEnv*                             pEnv,                   \
-                VideoEditJava_##m_class##MethodIds*         pIds);
-
-
-typedef struct
-{
-    const char*     pName;
-    int             java;
-    int             c;
-    const char*     pDescription;
-} VideoEditJava_Constant;
-
-typedef struct
-{
-    const char*             pName;
-    VideoEditJava_Constant* pConstants;
-    int                     count;
-    bool                    initialized;
-} VideoEditJava_ConstantsClass;
-
-typedef const char* (*VideoEditJava_UnknownConstant)(int constant);
-
-typedef struct
-{
-    const char*             pName;
-    const char*             pType;
-    jfieldID                fieldId;
-} VideoEditJava_Field;
-
-typedef struct
-{
-    const char*             pName;
-    VideoEditJava_Field*    pFields;
-    int                     count;
-    bool                    initialized;
-} VideoEditJava_FieldsClass;
-
-typedef struct
-{
-    jfieldID fieldIds[];
-} VideoEditJava_FieldIds;
-
-typedef struct
-{
-    const char*             pName;
-    const char*             pType;
-    jmethodID               methodId;
-} VideoEditJava_Method;
-
-typedef struct
-{
-    const char*             pName;
-    VideoEditJava_Method*   pMethods;
-    int                     count;
-    bool                    initialized;
-} VideoEditJava_MethodsClass;
-
-typedef struct
-{
-    jmethodID methodIds[];
-} VideoEditJava_MethodIds;
-
-#define videoEditJava_checkAndThrowIllegalArgumentException(\
-    a, b, c, d) videoEditJava_checkAndThrowIllegalArgumentExceptionFunc(\
-    a, b, c, d, __FILE__, __LINE__)
-
-#define videoEditJava_checkAndThrowRuntimeException(\
-    a, b, c, d) videoEditJava_checkAndThrowRuntimeExceptionFunc(\
-    a, b, c, d, __FILE__, __LINE__)
-
-#define videoEditJava_checkAndThrowIllegalStateException(\
-    a, b, c, d) videoEditJava_checkAndThrowIllegalStateExceptionFunc(\
-    a, b, c, d, __FILE__, __LINE__)
-
-void
-videoEditJava_checkAndThrowIllegalArgumentExceptionFunc(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                bool                                condition,
-                const char*                         pMessage,
-                const char*                         pFile,
-                int                                 lineNo
-                );
-
-void
-videoEditJava_checkAndThrowRuntimeExceptionFunc(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                bool                                condition,
-                M4OSA_ERR                           result,
-                const char*                         pFile,
-                int                                 lineNo
-                );
-
-void
-videoEditJava_checkAndThrowIllegalStateExceptionFunc(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                bool                                condition,
-                const char*                         pMessage,
-                const char*                         pFile,
-                int                                 lineNo
-                );
-
-void
-videoEditJava_getClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                const char*                         pName,
-                jclass*                             pClazz);
-
-void
-videoEditJava_getMethodId(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jclass                              clazz,
-                const char*                         pName,
-                const char*                         pType,
-                jmethodID*                          pMethodId);
-
-void videoEditJava_getFieldId(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jclass                              clazz,
-                const char*                         pName,
-                const char*                         pType,
-                jfieldID*                           pFieldId);
-
-void videoEditJava_getObject(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                jfieldID                            objectFieldId,
-                jobject*                            pObject);
-
-void videoEditJava_getArray(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                jfieldID                            arrayFieldId,
-                jobjectArray*                       pArray,
-                jsize*                              pArraySize);
-
-void* videoEditJava_getString(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                jobject                             object,
-                jfieldID                            stringFieldId,
-                M4OSA_UInt32*                       pLength);
-
-void videoEditJava_getStaticIntField(
-                bool*                               pResult,
-                JNIEnv*                             env,
-                jclass                              clazz,
-                const char*                         pName,
-                int*                                pValue);
-
-void
-videoEditJava_initConstantClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                VideoEditJava_ConstantsClass*               pClass);
-
-const char*
-videoEditJava_getConstantClassName(
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value,
-                VideoEditJava_UnknownConstant               unknown);
-
-const char*
-videoEditJava_getConstantClassString(
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value,
-                VideoEditJava_UnknownConstant               unknown);
-
-int
-videoEditJava_getConstantClassJavaToC(
-                bool*                               pResult,
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value);
-
-int
-videoEditJava_getConstantClassJavaToC(
-                bool*                               pResult,
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value,
-                int                                 unknown);
-
-int
-videoEditJava_getConstantClassCToJava(
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value);
-
-int
-videoEditJava_getConstantClassCToJava(
-                const VideoEditJava_ConstantsClass*         pClass,
-                int                                 value,
-                int                                 unknown);
-
-void
-videoEditJava_initFieldClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                VideoEditJava_FieldsClass*                  pClass);
-
-void
-videoEditJava_fieldClassClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                const VideoEditJava_FieldsClass*            pClass,
-                jclass*                             pClazz);
-
-void
-videoEditJava_fieldClassFieldIds(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                const VideoEditJava_FieldsClass*            pClass,
-                int                                 count,
-                VideoEditJava_FieldIds*                     pIds);
-
-void
-videoEditJava_initMethodClass(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                VideoEditJava_MethodsClass*                 pClass);
-
-void
-videoEditJava_methodClassMethodIds(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                const VideoEditJava_MethodsClass*           pClass,
-                int                                 count,
-                VideoEditJava_MethodIds*                    pIds);
-
-#endif // VIDEO_EDiTOR_JAVA_H
-
diff --git a/media/jni/mediaeditor/VideoEditorLogging.h b/media/jni/mediaeditor/VideoEditorLogging.h
deleted file mode 100644
index 1f1228a..0000000
--- a/media/jni/mediaeditor/VideoEditorLogging.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VIDEO_EDITOR_LOGGING_H
-#define VIDEO_EDITOR_LOGGING_H
-
-#ifndef LOG_TAG
-#error "No LOG_TAG defined!"
-#endif
-
-/*
- * This file is used as a proxy for cutils/log.h.  Include cutils/log.h here to
- * avoid relying on import ordering.
- */
-#include <cutils/log.h>
-
-//#define VIDEOEDIT_LOGGING_ENABLED
-
-#define VIDEOEDIT_LOG_INDENTATION                       (3)
-
-#define VIDEOEDIT_LOG_ERROR                             __android_log_print
-#define VIDEOEDIT_LOG_EXCEPTION                         __android_log_print
-
-#ifdef VIDEOEDIT_LOGGING_ENABLED
-
-#define VIDEOEDIT_LOG_ALLOCATION                        __android_log_print
-#define VIDEOEDIT_LOG_API                               __android_log_print
-#define VIDEOEDIT_LOG_FUNCTION                          __android_log_print
-#define VIDEOEDIT_LOG_RESULT(x,y, ...)                     ALOGI(y, __VA_ARGS__ )
-#define VIDEOEDIT_LOG_SETTING                           __android_log_print
-#define VIDEOEDIT_LOG_EDIT_SETTINGS(m_settings)         videoEditClasses_logEditSettings\
-                                               (m_settings, VIDEOEDIT_LOG_INDENTATION)
-#define VIDEOEDIT_PROP_LOG_PROPERTIES(m_properties)          videoEditPropClass_logProperties\
-                                                  (m_properties, VIDEOEDIT_LOG_INDENTATION)
-#define VIDEOEDIT_PROP_LOG_RESULT                            __android_log_print
-
-#else
-
-#define VIDEOEDIT_LOG_ALLOCATION                        (void)
-#define VIDEOEDIT_LOG_API                               (void)
-#define VIDEOEDIT_LOG_FUNCTION                          (void)
-#define VIDEOEDIT_LOG_RESULT                            (void)
-#define VIDEOEDIT_LOG_SETTING                           (void)
-#define VIDEOEDIT_LOG_EDIT_SETTINGS(m_settings)         (void)m_settings
-#define VIDEOEDIT_PROP_LOG_PROPERTIES(m_properties)          (void)m_properties
-#define VIDEOEDIT_PROP_LOG_RESULT                            (void)
-
-#endif
-
-#endif // VIDEO_EDITOR_LOGGING_H
-
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
deleted file mode 100644
index 0894d74..0000000
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ /dev/null
@@ -1,3639 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define LOG_NDEBUG 1
-#define LOG_TAG "VideoEditorMain"
-#include <dlfcn.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <VideoEditorClasses.h>
-#include <VideoEditorJava.h>
-#include <VideoEditorOsal.h>
-#include <VideoEditorLogging.h>
-#include <VideoEditorClasses.h>
-#include <VideoEditorThumbnailMain.h>
-#include <M4OSA_Debug.h>
-#include <M4xVSS_Internal.h>
-#include <gui/Surface.h>
-#include "VideoEditorPreviewController.h"
-
-#include "VideoEditorMain.h"
-
-#include <android_runtime/android_view_Surface.h>
-
-extern "C" {
-#include <M4OSA_Clock.h>
-#include <M4OSA_CharStar.h>
-#include <M4OSA_Error.h>
-#include <M4OSA_FileCommon.h>
-#include <M4OSA_FileReader.h>
-#include <M4OSA_FileWriter.h>
-#include <M4OSA_Memory.h>
-#include <M4OSA_Thread.h>
-#include <M4xVSS_API.h>
-#include <M4VSS3GPP_ErrorCodes.h>
-#include <M4MCS_API.h>
-#include <M4MCS_ErrorCodes.h>
-#include <M4READER_Common.h>
-#include <M4WRITER_common.h>
-};
-
-
-using namespace android;
-
-#define THREAD_STACK_SIZE       (65536)
-
-#define VIDEOEDITOR_VERSION_MAJOR     0
-#define VIDEOEDITOR_VERSION_MINOR     0
-#define VIDEOEDITOR_VERSION_REVISION  1
-
-
-typedef enum
-{
-    ManualEditState_NOT_INITIALIZED,
-    ManualEditState_INITIALIZED,
-    ManualEditState_ANALYZING,
-    ManualEditState_ANALYZING_ERROR,
-    ManualEditState_OPENED,
-    ManualEditState_SAVING,
-    ManualEditState_SAVING_ERROR,
-    ManualEditState_SAVED,
-    ManualEditState_STOPPING
-} ManualEditState;
-
-typedef struct
-{
-    JavaVM*                        pVM;
-    jobject                        engine;
-    jmethodID                      onCompletionMethodId;
-    jmethodID                      onErrorMethodId;
-    jmethodID                      onWarningMethodId;
-    jmethodID                      onProgressUpdateMethodId;
-    jmethodID                      onPreviewProgressUpdateMethodId;
-    jmethodID                      previewFrameEditInfoId;
-    M4xVSS_InitParams              initParams;
-    void*                          pTextRendererHandle;
-    M4xVSS_getTextRgbBufferFct     pTextRendererFunction;
-    M4OSA_Context                  engineContext;
-    ManualEditState                state;
-    M4VSS3GPP_EditSettings*        pEditSettings;
-    M4OSA_Context                  threadContext;
-    M4OSA_ERR                      threadResult;
-    M4OSA_UInt8                    threadProgress;
-    VideoEditorPreviewController   *mPreviewController;
-    M4xVSS_AudioMixingSettings     *mAudioSettings;
-    /* Audio Graph changes */
-    M4OSA_Context                   pAudioGraphMCSCtx;
-    M4OSA_Bool                      bSkipState;
-    jmethodID                       onAudioGraphProgressUpdateMethodId;
-    Mutex                           mLock;
-    bool                            mIsUpdateOverlay;
-    char                            *mOverlayFileName;
-    int                             mOverlayRenderingMode;
-    M4DECODER_VideoDecoders* decoders;
-} ManualEditContext;
-
-extern "C" M4OSA_ERR M4MCS_open_normalMode(
-                M4MCS_Context                       pContext,
-                M4OSA_Void*                         pFileIn,
-                M4VIDEOEDITING_FileType             InputFileType,
-                M4OSA_Void*                         pFileOut,
-                M4OSA_Void*                         pTempFile);
-
-static M4OSA_ERR videoEditor_toUTF8Fct(
-                M4OSA_Void*                         pBufferIn,
-                M4OSA_UInt8*                        pBufferOut,
-                M4OSA_UInt32*                       bufferOutSize);
-
-static M4OSA_ERR videoEditor_fromUTF8Fct(
-                M4OSA_UInt8*                        pBufferIn,
-                M4OSA_Void*                         pBufferOut,
-                M4OSA_UInt32*                       bufferOutSize);
-
-static M4OSA_ERR videoEditor_getTextRgbBufferFct(
-                M4OSA_Void*                         pRenderingData,
-                M4OSA_Void*                         pTextBuffer,
-                M4OSA_UInt32                        textBufferSize,
-                M4VIFI_ImagePlane**                 pOutputPlane);
-
-static void videoEditor_callOnProgressUpdate(
-                ManualEditContext*                  pContext,
-                int                                 task,
-                int                                 progress);
-
-static void videoEditor_freeContext(
-                JNIEnv*                             pEnv,
-                ManualEditContext**                 ppContext);
-
-static M4OSA_ERR videoEditor_threadProc(
-                M4OSA_Void*                         param);
-
-static jobject videoEditor_getVersion(
-                JNIEnv*                             pEnv,
-                jobject                             thiz);
-
-static void videoEditor_init(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jstring                             tempPath,
-                jstring                             textRendererPath);
-
-static void videoEditor_loadSettings(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jobject                             settings);
-
-static void videoEditor_unloadSettings(
-                JNIEnv*                             pEnv,
-                jobject                             thiz);
-
-
-static void videoEditor_stopEncoding(
-                JNIEnv*                             pEnv,
-                jobject                             thiz);
-
-static void videoEditor_release(
-                JNIEnv*                             pEnv,
-                jobject                             thiz);
-static jint videoEditor_getPixels(
-                                 JNIEnv*                  env,
-                                 jobject                  thiz,
-                                 jstring                  path,
-                                 jintArray                pixelArray,
-                                 M4OSA_UInt32             width,
-                                 M4OSA_UInt32             height,
-                                 M4OSA_UInt32             timeMS);
-static jint videoEditor_getPixelsList(
-                                     JNIEnv*                  env,
-                                     jobject                  thiz,
-                                     jstring                  path,
-                                     jintArray                pixelArray,
-                                     M4OSA_UInt32             width,
-                                     M4OSA_UInt32             height,
-                                     M4OSA_UInt32             noOfThumbnails,
-                                     jlong                    startTime,
-                                     jlong                    endTime,
-                                     jintArray                indexArray,
-                                     jobject                  callback);
-
-static void
-videoEditor_startPreview(
-                JNIEnv*                 pEnv,
-                jobject                 thiz,
-                jobject                 mSurface,
-                jlong                   fromMs,
-                jlong                   toMs,
-                jint                    callbackInterval,
-                jboolean                loop);
-
-static void
-videoEditor_populateSettings(
-                JNIEnv*                 pEnv,
-                jobject                 thiz,
-                jobject                 settings,
-                jobject                 object,
-                jobject                 audioSettingObject);
-
-static jint videoEditor_stopPreview(JNIEnv*  pEnv,
-                              jobject  thiz);
-
-static jobject
-videoEditor_getProperties(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jstring                             file);
-
-static jint videoEditor_renderPreviewFrame(JNIEnv* pEnv,
-                                    jobject thiz,
-                                    jobject    mSurface,
-                                    jlong fromMs,
-                                    jint  surfaceWidth,
-                                    jint  surfaceHeight);
-
-static int videoEditor_registerManualEditMethods(
-                JNIEnv*                             pEnv);
-
-static void jniPreviewProgressCallback(void* cookie, M4OSA_UInt32 msgType,
-                                        void *argc);
-
-static jint videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv,
-                                                    jobject thiz,
-                                                    jobject mSurface,
-                                                    jstring filePath,
-                                                    jint frameWidth,
-                                                    jint frameHeight,
-                                                    jint surfaceWidth,
-                                                    jint surfaceHeight,
-                                                    jlong fromMs);
-
-static jint videoEditor_generateAudioWaveFormSync ( JNIEnv*     pEnv,
-                                                  jobject     thiz,
-                                                  jstring     pcmfilePath,
-                                                  jstring     outGraphfilePath,
-                                                  jint        frameDuration,
-                                                  jint        channels,
-                                                  jint        samplesCount);
-
-static int videoEditor_generateAudioRawFile(JNIEnv* pEnv,
-                                    jobject thiz,
-                                    jstring infilePath,
-                                    jstring pcmfilePath );
-
-M4OSA_ERR videoEditor_generateAudio(JNIEnv* pEnv,ManualEditContext* pContext,
-                                    M4OSA_Char* infilePath,
-                                    M4OSA_Char* pcmfilePath );
-
-static jint
-videoEditor_generateClip(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jobject                             settings);
-
-static void videoEditor_clearSurface(JNIEnv* pEnv,
-                                    jobject thiz,
-                                    jobject surface);
-
-static JNINativeMethod gManualEditMethods[] = {
-    {"getVersion",               "()L"VERSION_CLASS_NAME";",
-                                (void *)videoEditor_getVersion      },
-    {"_init",                    "(Ljava/lang/String;Ljava/lang/String;)V",
-                                (void *)videoEditor_init    },
-    {"nativeStartPreview",       "(Landroid/view/Surface;JJIZ)V",
-                                (void *)videoEditor_startPreview    },
-    {"nativePopulateSettings",
-            "(L"EDIT_SETTINGS_CLASS_NAME";L"PREVIEW_PROPERTIES_CLASS_NAME";L"
-            AUDIO_SETTINGS_CLASS_NAME";)V",
-                                (void *)videoEditor_populateSettings    },
-    {"nativeRenderPreviewFrame", "(Landroid/view/Surface;JII)I",
-                                (int *)videoEditor_renderPreviewFrame     },
-    {"nativeRenderMediaItemPreviewFrame",
-    "(Landroid/view/Surface;Ljava/lang/String;IIIIJ)I",
-                        (int *)videoEditor_renderMediaItemPreviewFrame     },
-    {"nativeStopPreview",       "()I",
-                                (int *)videoEditor_stopPreview    },
-    {"stopEncoding",            "()V",
-                                (void *)videoEditor_stopEncoding         },
-    {"release",                 "()V",
-                                (void *)videoEditor_release            },
-    {"nativeGetPixels",         "(Ljava/lang/String;[IIIJ)I",
-                                (void*)videoEditor_getPixels               },
-    {"nativeGetPixelsList",     "(Ljava/lang/String;[IIIIJJ[ILandroid/media/videoeditor/MediaArtistNativeHelper$NativeGetPixelsListCallback;)I",
-                                (void*)videoEditor_getPixelsList           },
-    {"getMediaProperties",
-    "(Ljava/lang/String;)Landroid/media/videoeditor/MediaArtistNativeHelper$Properties;",
-                                (void *)videoEditor_getProperties          },
-    {"nativeGenerateAudioGraph","(Ljava/lang/String;Ljava/lang/String;III)I",
-                                (int *)videoEditor_generateAudioWaveFormSync },
-    {"nativeGenerateRawAudio",  "(Ljava/lang/String;Ljava/lang/String;)I",
-                                (int *)videoEditor_generateAudioRawFile      },
-    {"nativeGenerateClip",      "(L"EDIT_SETTINGS_CLASS_NAME";)I",
-                                (void *)videoEditor_generateClip  },
-    {"nativeClearSurface",       "(Landroid/view/Surface;)V",
-                                (void *)videoEditor_clearSurface  },
-};
-
-// temp file name of VSS out file
-#define TEMP_MCS_OUT_FILE_PATH "tmpOut.3gp"
-
-void
-getClipSetting(
-                JNIEnv*                                       pEnv,
-                jobject                                       object,
-                M4VSS3GPP_ClipSettings*                       pSettings)
-{
-
-    jfieldID fid;
-    int field = 0;
-    bool needToBeLoaded = true;
-    jclass clazz = pEnv->FindClass(PROPERTIES_CLASS_NAME);
-
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == clazz),
-                                             "not initialized");
-
-    fid = pEnv->GetFieldID(clazz,"duration","I");
-    pSettings->ClipProperties.uiClipDuration = pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("duration = %d",pSettings->ClipProperties.uiClipDuration);
-
-    fid = pEnv->GetFieldID(clazz,"videoFormat","I");
-    pSettings->ClipProperties.VideoStreamType =
-        (M4VIDEOEDITING_VideoFormat)pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("videoFormat = %d",pSettings->ClipProperties.VideoStreamType);
-
-    fid = pEnv->GetFieldID(clazz,"videoDuration","I");
-    pSettings->ClipProperties.uiClipVideoDuration = pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("videoDuration = %d",
-                    pSettings->ClipProperties.uiClipVideoDuration);
-
-    fid = pEnv->GetFieldID(clazz,"width","I");
-    pSettings->ClipProperties.uiVideoWidth = pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("width = %d",pSettings->ClipProperties.uiVideoWidth);
-
-    fid = pEnv->GetFieldID(clazz,"height","I");
-    pSettings->ClipProperties.uiVideoHeight = pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("height = %d",pSettings->ClipProperties.uiVideoHeight);
-
-    fid = pEnv->GetFieldID(clazz,"audioFormat","I");
-    pSettings->ClipProperties.AudioStreamType =
-        (M4VIDEOEDITING_AudioFormat)pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("audioFormat = %d",pSettings->ClipProperties.AudioStreamType);
-
-    fid = pEnv->GetFieldID(clazz,"audioDuration","I");
-    pSettings->ClipProperties.uiClipAudioDuration = pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("audioDuration = %d",
-                    pSettings->ClipProperties.uiClipAudioDuration);
-
-    fid = pEnv->GetFieldID(clazz,"audioBitrate","I");
-    pSettings->ClipProperties.uiAudioBitrate = pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("audioBitrate = %d",pSettings->ClipProperties.uiAudioBitrate);
-
-    fid = pEnv->GetFieldID(clazz,"audioChannels","I");
-    pSettings->ClipProperties.uiNbChannels = pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("audioChannels = %d",pSettings->ClipProperties.uiNbChannels);
-
-    fid = pEnv->GetFieldID(clazz,"audioSamplingFrequency","I");
-    pSettings->ClipProperties.uiSamplingFrequency = pEnv->GetIntField(object,fid);
-    M4OSA_TRACE1_1("audioSamplingFrequency = %d",
-                    pSettings->ClipProperties.uiSamplingFrequency);
-
-   fid = pEnv->GetFieldID(clazz,"audioVolumeValue","I");
-   pSettings->ClipProperties.uiClipAudioVolumePercentage =
-                    pEnv->GetIntField(object,fid);
-   M4OSA_TRACE1_1("audioVolumeValue = %d",
-                    pSettings->ClipProperties.uiClipAudioVolumePercentage);
-
-   fid = pEnv->GetFieldID(clazz,"videoRotation","I");
-   pSettings->ClipProperties.videoRotationDegrees =
-                    pEnv->GetIntField(object,fid);
-   M4OSA_TRACE1_1("videoRotation = %d",
-                    pSettings->ClipProperties.videoRotationDegrees);
-
-   // Free the local references to avoid memory leaks
-   pEnv->DeleteLocalRef(clazz);
-}
-
-static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType,
-                                        void *argc)
-{
-    ManualEditContext *pContext = (ManualEditContext *)cookie;
-    JNIEnv*     pEnv = NULL;
-    bool        isFinished = false;
-    int         currentMs = 0;
-    int         error = M4NO_ERROR;
-    bool        isUpdateOverlay = false;
-    int         overlayEffectIndex;
-    char        *extPos;
-    bool        isSendProgress = true;
-    jstring     tmpFileName;
-    VideoEditorCurretEditInfo *pCurrEditInfo;
-
-    // Attach the current thread.
-    pContext->pVM->AttachCurrentThread(&pEnv, NULL);
-    switch(msgType)
-    {
-        case MSG_TYPE_PROGRESS_INDICATION:
-            currentMs = *(int*)argc;
-            break;
-        case MSG_TYPE_PLAYER_ERROR:
-            currentMs = -1;
-            error = *(int*)argc;
-            break;
-        case MSG_TYPE_PREVIEW_END:
-            isFinished = true;
-            break;
-        case MSG_TYPE_OVERLAY_UPDATE:
-        {
-            int overlayFileNameLen = 0;
-            isSendProgress = false;
-            pContext->mIsUpdateOverlay = true;
-            pCurrEditInfo = (VideoEditorCurretEditInfo*)argc;
-            overlayEffectIndex = pCurrEditInfo->overlaySettingsIndex;
-            ALOGV("MSG_TYPE_OVERLAY_UPDATE");
-
-            if (pContext->mOverlayFileName != NULL) {
-                free(pContext->mOverlayFileName);
-                pContext->mOverlayFileName = NULL;
-            }
-
-            overlayFileNameLen =
-                strlen((const char*)pContext->pEditSettings->Effects[overlayEffectIndex].xVSS.pFramingFilePath);
-
-            pContext->mOverlayFileName =
-                (char*)M4OSA_32bitAlignedMalloc(overlayFileNameLen+1,
-                                    M4VS, (M4OSA_Char*)"videoEdito JNI overlayFile");
-            if (pContext->mOverlayFileName != NULL) {
-                strncpy (pContext->mOverlayFileName,
-                    (const char*)pContext->pEditSettings->
-                    Effects[overlayEffectIndex].xVSS.pFramingFilePath, overlayFileNameLen);
-                //Change the name to png file
-                extPos = strstr(pContext->mOverlayFileName, ".rgb");
-                if (extPos != NULL) {
-                    *extPos = '\0';
-                } else {
-                    ALOGE("ERROR the overlay file is incorrect");
-                }
-
-                strcat(pContext->mOverlayFileName, ".png");
-                ALOGV("Conv string is %s", pContext->mOverlayFileName);
-                ALOGV("Current Clip index = %d", pCurrEditInfo->clipIndex);
-
-                pContext->mOverlayRenderingMode = pContext->pEditSettings->\
-                         pClipList[pCurrEditInfo->clipIndex]->xVSS.MediaRendering;
-                ALOGV("rendering mode %d ", pContext->mOverlayRenderingMode);
-
-            }
-
-            break;
-        }
-
-        case MSG_TYPE_OVERLAY_CLEAR:
-            isSendProgress = false;
-            if (pContext->mOverlayFileName != NULL) {
-                free(pContext->mOverlayFileName);
-                pContext->mOverlayFileName = NULL;
-            }
-
-            ALOGV("MSG_TYPE_OVERLAY_CLEAR");
-            //argc is not used
-            pContext->mIsUpdateOverlay = true;
-            break;
-        default:
-            break;
-    }
-
-    if (isSendProgress) {
-        tmpFileName  = pEnv->NewStringUTF(pContext->mOverlayFileName);
-        pEnv->CallVoidMethod(pContext->engine,
-                pContext->onPreviewProgressUpdateMethodId,
-                currentMs,isFinished, pContext->mIsUpdateOverlay,
-                tmpFileName, pContext->mOverlayRenderingMode, error);
-
-        if (pContext->mIsUpdateOverlay) {
-            pContext->mIsUpdateOverlay = false;
-        }
-
-        if (tmpFileName) {
-            pEnv->DeleteLocalRef(tmpFileName);
-        }
-    }
-
-    // Detach the current thread.
-    pContext->pVM->DetachCurrentThread();
-
-}
-static M4OSA_ERR checkClipVideoProfileAndLevel(M4DECODER_VideoDecoders *pDecoders,
-    M4OSA_Int32 format, M4OSA_UInt32 profile, M4OSA_UInt32 level){
-
-    M4OSA_Int32 codec = 0;
-    M4OSA_Bool foundCodec = M4OSA_FALSE;
-    M4OSA_ERR  result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE;
-    M4OSA_Bool foundProfile = M4OSA_FALSE;
-    ALOGV("checkClipVideoProfileAndLevel format %d profile;%d level:0x%x",
-       format, profile, level);
-
-    switch (format) {
-        case M4VIDEOEDITING_kH263:
-            codec = M4DA_StreamTypeVideoH263;
-            break;
-        case M4VIDEOEDITING_kH264:
-             codec = M4DA_StreamTypeVideoMpeg4Avc;
-            break;
-        case M4VIDEOEDITING_kMPEG4:
-             codec = M4DA_StreamTypeVideoMpeg4;
-            break;
-        case M4VIDEOEDITING_kNoneVideo:
-        case M4VIDEOEDITING_kNullVideo:
-        case M4VIDEOEDITING_kUnsupportedVideo:
-             // For these case we do not check the profile and level
-             return M4NO_ERROR;
-        default :
-            ALOGE("checkClipVideoProfileAndLevel unsupport Video format %ld", format);
-            break;
-    }
-
-    if (pDecoders != M4OSA_NULL && pDecoders->decoderNumber > 0) {
-        VideoDecoder *pVideoDecoder = pDecoders->decoder;
-        for(size_t k =0; k < pDecoders->decoderNumber; k++) {
-            if (pVideoDecoder != M4OSA_NULL) {
-                if (pVideoDecoder->codec == codec) {
-                    foundCodec = M4OSA_TRUE;
-                    break;
-                }
-            }
-            pVideoDecoder++;
-        }
-
-        if (foundCodec) {
-            VideoComponentCapabilities* pComponent = pVideoDecoder->component;
-            for (size_t i = 0; i < pVideoDecoder->componentNumber; i++) {
-                if (pComponent != M4OSA_NULL) {
-                    VideoProfileLevel *pProfileLevel = pComponent->profileLevel;
-                    for (size_t j =0; j < pComponent->profileNumber; j++) {
-                        // Check the profile and level
-                        if (pProfileLevel != M4OSA_NULL) {
-                            if (profile == pProfileLevel->mProfile) {
-                                foundProfile = M4OSA_TRUE;
-
-                                if (level <= pProfileLevel->mLevel) {
-                                    return M4NO_ERROR;
-                                }
-                            } else {
-                                foundProfile = M4OSA_FALSE;
-                            }
-                        }
-                        pProfileLevel++;
-                    }
-                }
-                pComponent++;
-            }
-        }
-    }
-
-    if (foundProfile) {
-        result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_LEVEL;
-    } else {
-        result = M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE;
-    }
-
-    return result;
-}
-static jint videoEditor_stopPreview(JNIEnv*  pEnv,
-                              jobject  thiz)
-{
-    ManualEditContext* pContext = M4OSA_NULL;
-    bool needToBeLoaded = true;
-    M4OSA_UInt32 lastProgressTimeMs = 0;
-
-    // Get the context.
-    pContext =
-            (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-    lastProgressTimeMs = pContext->mPreviewController->stopPreview();
-
-    if (pContext->mOverlayFileName != NULL) {
-        free(pContext->mOverlayFileName);
-        pContext->mOverlayFileName = NULL;
-    }
-
-    return (jint)lastProgressTimeMs;
-}
-
-static void videoEditor_clearSurface(JNIEnv* pEnv,
-                                    jobject thiz,
-                                    jobject surface)
-{
-    bool needToBeLoaded = true;
-    M4OSA_ERR result = M4NO_ERROR;
-    VideoEditor_renderPreviewFrameStr frameStr;
-    const char* pMessage = NULL;
-    // Let the size be QVGA
-    int width = 320;
-    int height = 240;
-    ManualEditContext* pContext = M4OSA_NULL;
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
-                                "VIDEO_EDITOR","pContext = 0x%x",pContext);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                 (M4OSA_NULL == pContext->mPreviewController),
-                                 "not initialized");
-
-    // Validate the surface parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
-                                                (NULL == surface),
-                                                "surface is null");
-
-    sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, surface);
-
-    // Validate the mSurface's mNativeSurface field
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                                (NULL == previewSurface.get()),
-                                                "mNativeSurface is null");
-
-    frameStr.pBuffer = M4OSA_NULL;
-    frameStr.timeMs = 0;
-    frameStr.uiSurfaceWidth = width;
-    frameStr.uiSurfaceHeight = height;
-    frameStr.uiFrameWidth = width;
-    frameStr.uiFrameHeight = height;
-    frameStr.bApplyEffect = M4OSA_FALSE;
-    frameStr.clipBeginCutTime = 0;
-    frameStr.clipEndCutTime = 0;
-
-    result = pContext->mPreviewController->clearSurface(previewSurface,
-                                                              &frameStr);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-            (M4NO_ERROR != result), result);
-
-  }
-
-static jint videoEditor_renderPreviewFrame(JNIEnv* pEnv,
-                                    jobject thiz,
-                                    jobject    mSurface,
-                                    jlong fromMs,
-                                    jint surfaceWidth,
-                                    jint surfaceHeight )
-{
-    bool needToBeLoaded = true;
-    M4OSA_ERR result = M4NO_ERROR;
-    M4OSA_UInt32 timeMs = (M4OSA_UInt32)fromMs;
-    M4OSA_UInt32 i=0,tnTimeMs = 0, framesizeYuv =0;
-    M4VIFI_UInt8 *pixelArray = M4OSA_NULL;
-    M4OSA_UInt32    iCurrentClipIndex = 0, uiNumberOfClipsInStoryBoard =0,
-                    uiClipDuration = 0, uiTotalClipDuration = 0,
-                    iIncrementedDuration = 0;
-    VideoEditor_renderPreviewFrameStr frameStr;
-    M4OSA_Context tnContext = M4OSA_NULL;
-    const char* pMessage = NULL;
-    M4VIFI_ImagePlane *yuvPlane = NULL;
-    VideoEditorCurretEditInfo  currEditInfo;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
-        "VIDEO_EDITOR", "surfaceWidth = %d",surfaceWidth);
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
-        "VIDEO_EDITOR", "surfaceHeight = %d",surfaceHeight);
-    ManualEditContext* pContext = M4OSA_NULL;
-    // Get the context.
-    pContext =
-            (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
-                                "VIDEO_EDITOR","pContext = 0x%x",pContext);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                 (M4OSA_NULL == pContext->mPreviewController),
-                                 "not initialized");
-
-    // Validate the mSurface parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
-                                                (NULL == mSurface),
-                                                "mSurface is null");
-
-    sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface);
-
-    // Validate the mSurface's mNativeSurface field
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                                (NULL == previewSurface.get()),
-                                                "mNativeSurface is null");
-
-    /* Determine the total number of clips, total duration*/
-    uiNumberOfClipsInStoryBoard = pContext->pEditSettings->uiClipNumber;
-
-    for (i = 0; i < uiNumberOfClipsInStoryBoard; i++) {
-        uiClipDuration = pContext->pEditSettings->pClipList[i]->uiEndCutTime -
-            pContext->pEditSettings->pClipList[i]->uiBeginCutTime;
-        uiTotalClipDuration += uiClipDuration;
-    }
-
-    /* determine the clip whose thumbnail needs to be rendered*/
-    if (timeMs == 0) {
-        iCurrentClipIndex = 0;
-        i=0;
-    } else {
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "videoEditor_renderPreviewFrame() timeMs=%d", timeMs);
-
-        if (timeMs > uiTotalClipDuration) {
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                "videoEditor_renderPreviewFrame() timeMs > uiTotalClipDuration");
-            pMessage = videoEditJava_getErrorName(M4ERR_PARAMETER);
-            jniThrowException(pEnv, "java/lang/IllegalArgumentException", pMessage);
-            return -1;
-        }
-
-        for (i = 0; i < uiNumberOfClipsInStoryBoard; i++) {
-            if (timeMs <= (iIncrementedDuration +
-                          (pContext->pEditSettings->pClipList[i]->uiEndCutTime -
-                           pContext->pEditSettings->pClipList[i]->uiBeginCutTime)))
-            {
-                iCurrentClipIndex = i;
-                VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                    "videoEditor_renderPreviewFrame() iCurrentClipIndex=%d for timeMs=%d",
-                    iCurrentClipIndex, timeMs);
-                break;
-            }
-            else {
-                iIncrementedDuration = iIncrementedDuration +
-                    (pContext->pEditSettings->pClipList[i]->uiEndCutTime -
-                    pContext->pEditSettings->pClipList[i]->uiBeginCutTime);
-            }
-        }
-    }
-    /* If timestamp is beyond story board duration, return*/
-    if (i >= uiNumberOfClipsInStoryBoard) {
-        if (timeMs == iIncrementedDuration) {
-            iCurrentClipIndex = i-1;
-        } else {
-           return -1;
-        }
-    }
-
-    /*+ Handle the image files here */
-      if (pContext->pEditSettings->pClipList[iCurrentClipIndex]->FileType ==
-          /*M4VIDEOEDITING_kFileType_JPG*/ M4VIDEOEDITING_kFileType_ARGB8888 ) {
-          VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", " iCurrentClipIndex %d ", iCurrentClipIndex);
-          VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                "  Height = %d",
-                pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoHeight);
-
-          VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                "  Width = %d",
-                pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoWidth);
-
-          LvGetImageThumbNail((const char *)pContext->pEditSettings->\
-          pClipList[iCurrentClipIndex]->pFile,
-            pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoHeight,
-            pContext->pEditSettings->pClipList[iCurrentClipIndex]->ClipProperties.uiVideoWidth,
-            (M4OSA_Void **)&frameStr.pBuffer);
-            tnTimeMs = (M4OSA_UInt32)timeMs;
-
-          frameStr.videoRotationDegree = 0;
-    } else {
-        /* Handle 3gp/mp4 Clips here */
-        /* get thumbnail*/
-        result = ThumbnailOpen(&tnContext,
-            (const M4OSA_Char*)pContext->pEditSettings->\
-            pClipList[iCurrentClipIndex]->pFile, M4OSA_TRUE);
-        if (result != M4NO_ERROR || tnContext  == M4OSA_NULL) {
-            return -1;
-        }
-
-        /* timeMs is relative to storyboard; in this api it shud be relative to this clip */
-        if ((i >= uiNumberOfClipsInStoryBoard) &&
-            (timeMs == iIncrementedDuration)) {
-            tnTimeMs = pContext->pEditSettings->\
-            pClipList[iCurrentClipIndex]->uiEndCutTime;
-        } else {
-            tnTimeMs = pContext->pEditSettings->\
-            pClipList[iCurrentClipIndex]->uiBeginCutTime
-            + (timeMs - iIncrementedDuration);
-        }
-
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "video width = %d",pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-            ClipProperties.uiVideoWidth);
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "video height = %d",pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-            ClipProperties.uiVideoHeight);
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "current clip index = %d",iCurrentClipIndex);
-
-        M4OSA_UInt32 width = pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-            ClipProperties.uiVideoWidth;
-        M4OSA_UInt32 height = pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-            ClipProperties.uiVideoHeight;
-
-        framesizeYuv = width * height * 1.5;
-
-        pixelArray = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(framesizeYuv, M4VS,
-            (M4OSA_Char*)"videoEditor pixelArray");
-        if (pixelArray == M4OSA_NULL) {
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                "videoEditor_renderPreviewFrame() malloc error");
-            ThumbnailClose(tnContext);
-            pMessage = videoEditJava_getErrorName(M4ERR_ALLOC);
-            jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
-            return -1;
-        }
-
-        result = ThumbnailGetPixels16(tnContext, (M4OSA_Int16 *)pixelArray,
-            pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-            ClipProperties.uiVideoWidth,
-            pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-            ClipProperties.uiVideoHeight,
-            &tnTimeMs, 0);
-        if (result != M4NO_ERROR) {
-            free(pixelArray);
-            ThumbnailClose(tnContext);
-            return -1;
-        }
-
-        ThumbnailClose(tnContext);
-        tnContext = M4OSA_NULL;
-
-#ifdef DUMPTOFILE
-        {
-            M4OSA_Context fileContext;
-            M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/FirstRGB565.raw";
-            remove((const char *)fileName);
-            M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\
-                M4OSA_kFileWrite|M4OSA_kFileCreate);
-            M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) pixelArray,
-                framesizeYuv);
-            M4OSA_fileWriteClose(fileContext);
-        }
-#endif
-
-        /**
-        * Allocate output YUV planes
-        */
-        yuvPlane = (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc(3*sizeof(M4VIFI_ImagePlane), M4VS,
-            (M4OSA_Char*)"videoEditor_renderPreviewFrame Output plane YUV");
-        if (yuvPlane == M4OSA_NULL) {
-            VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                "videoEditor_renderPreviewFrame() malloc error for yuv plane");
-            free(pixelArray);
-            pMessage = videoEditJava_getErrorName(M4ERR_ALLOC);
-            jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
-            return -1;
-        }
-
-        yuvPlane[0].u_width = width;
-        yuvPlane[0].u_height = height;
-        yuvPlane[0].u_topleft = 0;
-        yuvPlane[0].u_stride = width;
-        yuvPlane[0].pac_data = (M4VIFI_UInt8*)pixelArray;
-
-        yuvPlane[1].u_width = width>>1;
-        yuvPlane[1].u_height = height>>1;
-        yuvPlane[1].u_topleft = 0;
-        yuvPlane[1].u_stride = width>>1;
-        yuvPlane[1].pac_data = yuvPlane[0].pac_data
-                    + yuvPlane[0].u_width * yuvPlane[0].u_height;
-        yuvPlane[2].u_width = (width)>>1;
-        yuvPlane[2].u_height = (height)>>1;
-        yuvPlane[2].u_topleft = 0;
-        yuvPlane[2].u_stride = (width)>>1;
-        yuvPlane[2].pac_data = yuvPlane[1].pac_data
-                    + yuvPlane[1].u_width * yuvPlane[1].u_height;
-
-#ifdef DUMPTOFILE
-        {
-            M4OSA_Context fileContext;
-            M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/ConvertedYuv.yuv";
-            remove((const char *)fileName);
-            M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\
-                M4OSA_kFileWrite|M4OSA_kFileCreate);
-            M4OSA_fileWriteData(fileContext,
-                (M4OSA_MemAddr8) yuvPlane[0].pac_data, framesizeYuv);
-            M4OSA_fileWriteClose(fileContext);
-        }
-#endif
-
-        /* Fill up the render structure*/
-        frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data;
-
-        frameStr.videoRotationDegree = pContext->pEditSettings->\
-            pClipList[iCurrentClipIndex]->ClipProperties.videoRotationDegrees;
-    }
-
-    frameStr.timeMs = timeMs;    /* timestamp on storyboard*/
-    frameStr.uiSurfaceWidth =
-        pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-        ClipProperties.uiVideoWidth;
-    frameStr.uiSurfaceHeight =
-        pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-        ClipProperties.uiVideoHeight;
-    frameStr.uiFrameWidth =
-        pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-        ClipProperties.uiVideoWidth;
-    frameStr.uiFrameHeight =
-        pContext->pEditSettings->pClipList[iCurrentClipIndex]->\
-        ClipProperties.uiVideoHeight;
-    if (pContext->pEditSettings->nbEffects > 0) {
-        frameStr.bApplyEffect = M4OSA_TRUE;
-    } else {
-        frameStr.bApplyEffect = M4OSA_FALSE;
-    }
-    frameStr.clipBeginCutTime = iIncrementedDuration;
-    frameStr.clipEndCutTime =
-        iIncrementedDuration +
-        (pContext->pEditSettings->pClipList[iCurrentClipIndex]->uiEndCutTime -\
-        pContext->pEditSettings->pClipList[iCurrentClipIndex]->uiBeginCutTime);
-
-    pContext->mPreviewController->setPreviewFrameRenderingMode(
-        pContext->pEditSettings->\
-        pClipList[iCurrentClipIndex]->xVSS.MediaRendering,
-        pContext->pEditSettings->xVSS.outputVideoSize);
-    result = pContext->mPreviewController->renderPreviewFrame(previewSurface,
-                                                              &frameStr, &currEditInfo);
-
-    if (currEditInfo.overlaySettingsIndex != -1) {
-        char tmpOverlayFilename[100];
-        char *extPos = NULL;
-        jstring tmpOverlayString;
-        int tmpRenderingMode = 0;
-
-        strncpy (tmpOverlayFilename,
-                (const char*)pContext->pEditSettings->Effects[currEditInfo.overlaySettingsIndex].xVSS.pFramingFilePath, 99);
-
-        //Change the name to png file
-        extPos = strstr(tmpOverlayFilename, ".rgb");
-        if (extPos != NULL) {
-            *extPos = '\0';
-        } else {
-            ALOGE("ERROR the overlay file is incorrect");
-        }
-
-        strcat(tmpOverlayFilename, ".png");
-
-        tmpRenderingMode = pContext->pEditSettings->pClipList[iCurrentClipIndex]->xVSS.MediaRendering;
-        tmpOverlayString = pEnv->NewStringUTF(tmpOverlayFilename);
-        pEnv->CallVoidMethod(pContext->engine,
-            pContext->previewFrameEditInfoId,
-            tmpOverlayString, tmpRenderingMode);
-
-    }
-
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-            (M4NO_ERROR != result), result);
-
-    free(frameStr.pBuffer);
-    if (pContext->pEditSettings->pClipList[iCurrentClipIndex]->FileType !=
-            M4VIDEOEDITING_kFileType_ARGB8888) {
-        free(yuvPlane);
-    }
-
-    return (jint)tnTimeMs;
-}
-
-static jint videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv,
-                                                    jobject thiz,
-                                                    jobject mSurface,
-                                                    jstring filePath,
-                                                    jint    frameWidth,
-                                                    jint    frameHeight,
-                                                    jint    surfaceWidth,
-                                                    jint    surfaceHeight,
-                                                    jlong   fromMs)
-{
-    bool needToBeLoaded = true;
-    M4OSA_ERR result = M4NO_ERROR;
-    M4OSA_UInt32 timeMs = (M4OSA_UInt32)fromMs;
-    M4OSA_UInt32 framesizeYuv =0;
-    M4VIFI_UInt8 *pixelArray = M4OSA_NULL;
-    VideoEditor_renderPreviewFrameStr frameStr;
-    M4OSA_Context tnContext = M4OSA_NULL;
-    const char* pMessage = NULL;
-    M4VIFI_ImagePlane yuvPlane[3], rgbPlane;
-
-    ManualEditContext* pContext = M4OSA_NULL;
-    // Get the context.
-    pContext =
-            (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded,
-                                                      pEnv, thiz);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                 (M4OSA_NULL == pContext->mPreviewController),
-                                 "not initialized");
-
-    // Validate the mSurface parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
-                                                (NULL == mSurface),
-                                                "mSurface is null");
-
-    sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface);
-
-    const char *pString = pEnv->GetStringUTFChars(filePath, NULL);
-    if (pString == M4OSA_NULL) {
-        if (pEnv != NULL) {
-            jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null");
-        }
-    }
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-        "videoEditor_renderMediaItemPreviewFrame() timeMs=%d", timeMs);
-    /* get thumbnail*/
-    result = ThumbnailOpen(&tnContext,(const M4OSA_Char*)pString, M4OSA_TRUE);
-    if (result != M4NO_ERROR || tnContext  == M4OSA_NULL) {
-        return (jint)timeMs;
-    }
-
-    framesizeYuv = ((frameWidth)*(frameHeight)*1.5);
-
-    pixelArray = (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(framesizeYuv, M4VS,\
-        (M4OSA_Char*)"videoEditor pixelArray");
-    if (pixelArray == M4OSA_NULL) {
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "videoEditor_renderPreviewFrame() malloc error");
-        ThumbnailClose(tnContext);
-        pMessage = videoEditJava_getErrorName(M4ERR_ALLOC);
-        jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
-        return (jint)timeMs;
-    }
-
-    result = ThumbnailGetPixels16(tnContext, (M4OSA_Int16 *)pixelArray,
-                                                frameWidth,
-                                                frameHeight, &timeMs, 0);
-    if (result != M4NO_ERROR) {
-        free(pixelArray);
-        ThumbnailClose(tnContext);
-        return (jint)fromMs;
-    }
-
-#ifdef DUMPTOFILESYSTEM
-    {
-        M4OSA_Context fileContext;
-        M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/FirstRGB565.rgb";
-        M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\
-            M4OSA_kFileWrite|M4OSA_kFileCreate);
-        M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) pixelArray,
-                            framesizeRgb);
-        M4OSA_fileWriteClose(fileContext);
-    }
-#endif
-
-    yuvPlane[0].pac_data = (M4VIFI_UInt8*)pixelArray;
-    yuvPlane[0].u_height = frameHeight;
-    yuvPlane[0].u_width = frameWidth;
-    yuvPlane[0].u_stride = yuvPlane[0].u_width;
-    yuvPlane[0].u_topleft = 0;
-
-    yuvPlane[1].u_height = frameHeight/2;
-    yuvPlane[1].u_width = frameWidth/2;
-    yuvPlane[1].u_stride = yuvPlane[1].u_width;
-    yuvPlane[1].u_topleft = 0;
-    yuvPlane[1].pac_data = yuvPlane[0].pac_data
-                + yuvPlane[0].u_width*yuvPlane[0].u_height;
-
-    yuvPlane[2].u_height = frameHeight/2;
-    yuvPlane[2].u_width = frameWidth/2;
-    yuvPlane[2].u_stride = yuvPlane[2].u_width;
-    yuvPlane[2].u_topleft = 0;
-    yuvPlane[2].pac_data = yuvPlane[0].pac_data
-        + yuvPlane[0].u_width*yuvPlane[0].u_height + \
-        (yuvPlane[0].u_width/2)*(yuvPlane[0].u_height/2);
-#ifdef DUMPTOFILESYSTEM
-    {
-        M4OSA_Context fileContext;
-        M4OSA_Char* fileName = (M4OSA_Char*)"/mnt/sdcard/ConvertedYuv.yuv";
-        M4OSA_fileWriteOpen(&fileContext, (M4OSA_Void*) fileName,\
-            M4OSA_kFileWrite|M4OSA_kFileCreate);
-        M4OSA_fileWriteData(fileContext, (M4OSA_MemAddr8) yuvPlane[0].pac_data,
-                            framesizeYuv);
-        M4OSA_fileWriteClose(fileContext);
-    }
-#endif
-
-    /* Fill up the render structure*/
-    frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data;
-    frameStr.timeMs = timeMs;    /* timestamp on storyboard*/
-    frameStr.uiSurfaceWidth = frameWidth;
-    frameStr.uiSurfaceHeight = frameHeight;
-    frameStr.uiFrameWidth = frameWidth;
-    frameStr.uiFrameHeight = frameHeight;
-    frameStr.bApplyEffect = M4OSA_FALSE;
-    // clip begin cuttime and end cuttime set to 0
-    // as its only required when effect needs to be applied while rendering
-    frameStr.clipBeginCutTime = 0;
-    frameStr.clipEndCutTime = 0;
-
-    /*  pContext->mPreviewController->setPreviewFrameRenderingMode(M4xVSS_kBlackBorders,
-    (M4VIDEOEDITING_VideoFrameSize)(M4VIDEOEDITING_kHD960+1));*/
-    result
-    = pContext->mPreviewController->renderPreviewFrame(previewSurface,&frameStr, NULL);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                                                (M4NO_ERROR != result), result);
-
-    /* free the pixelArray and yuvPlane[0].pac_data */
-    free(yuvPlane[0].pac_data);
-
-    ThumbnailClose(tnContext);
-
-    if (pString != NULL) {
-        pEnv->ReleaseStringUTFChars(filePath, pString);
-    }
-
-    return (jint)timeMs;
-}
-
-jint videoEditor_generateAudioRawFile(  JNIEnv*     pEnv,
-                                        jobject     thiz,
-                                        jstring     infilePath,
-                                        jstring     pcmfilePath)
-{
-    M4OSA_ERR result = M4NO_ERROR;
-    bool               loaded   = true;
-    ManualEditContext* pContext = M4OSA_NULL;
-
-
-
-    const char *pInputFile = pEnv->GetStringUTFChars(infilePath, NULL);
-    if (pInputFile == M4OSA_NULL) {
-        if (pEnv != NULL) {
-            jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null");
-        }
-    }
-
-    const char *pStringOutPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL);
-    if (pStringOutPCMFilePath == M4OSA_NULL) {
-        if (pEnv != NULL) {
-            jniThrowException(pEnv, "java/lang/RuntimeException", "Input string null");
-        }
-    }
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
-        "VIDEO_EDITOR", "videoEditor_generateAudioRawFile infilePath %s",
-        pInputFile);
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
-        "VIDEO_EDITOR", "videoEditor_generateAudioRawFile pcmfilePath %s",
-        pStringOutPCMFilePath);
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz);
-
-    result = videoEditor_generateAudio( pEnv, pContext, (M4OSA_Char*)pInputFile,
-        (M4OSA_Char*)pStringOutPCMFilePath);
-
-    if (pInputFile != NULL) {
-        pEnv->ReleaseStringUTFChars(infilePath, pInputFile);
-    }
-    if (pStringOutPCMFilePath != NULL) {
-        pEnv->ReleaseStringUTFChars(pcmfilePath, pStringOutPCMFilePath);
-    }
-
-    return (jint)result;
-}
-
-M4OSA_ERR videoEditor_generateAudio(JNIEnv* pEnv,ManualEditContext* pContext,
-                                    M4OSA_Char* infilePath,
-                                    M4OSA_Char* pcmfilePath )
-{
-    bool                            needToBeLoaded = true;
-    M4OSA_ERR                       result = M4NO_ERROR;
-    M4MCS_Context                   mcsContext = M4OSA_NULL;
-    M4OSA_Char*                     pInputFile = M4OSA_NULL;
-    M4OSA_Char*                     pOutputFile = M4OSA_NULL;
-    M4OSA_Char*                     pTempPath = M4OSA_NULL;
-    M4MCS_OutputParams*             pOutputParams = M4OSA_NULL;
-    M4MCS_EncodingParams*           pEncodingParams = M4OSA_NULL;
-    M4OSA_Int32                     pInputFileType = 0;
-    M4OSA_UInt8                     threadProgress = 0;
-    M4OSA_Char*                     pTemp3gpFilePath = M4OSA_NULL;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_generateAudio()");
-
-    videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
-        (NULL == pContext),
-        "ManualEditContext is null");
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_init()");
-
-    pOutputParams = (M4MCS_OutputParams *)M4OSA_32bitAlignedMalloc(
-        sizeof(M4MCS_OutputParams),0x00,
-        (M4OSA_Char *)"M4MCS_OutputParams");
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-        (M4OSA_NULL == pOutputParams),
-        "not initialized");
-    if (needToBeLoaded == false) {
-        return M4ERR_ALLOC;
-    }
-
-    pEncodingParams = (M4MCS_EncodingParams *)M4OSA_32bitAlignedMalloc(
-        sizeof(M4MCS_EncodingParams),0x00,
-        (M4OSA_Char *)"M4MCS_EncodingParams");
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-        (M4OSA_NULL == pEncodingParams),
-        "not initialized");
-    if (needToBeLoaded == false) {
-        free(pEncodingParams);
-        pEncodingParams = M4OSA_NULL;
-        return M4ERR_ALLOC;
-    }
-
-    // Initialize the MCS library.
-    result = M4MCS_init(&mcsContext, pContext->initParams.pFileReadPtr,
-        pContext->initParams.pFileWritePtr);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,\
-        (M4NO_ERROR != result), result);
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-        (M4OSA_NULL == mcsContext),
-        "not initialized");
-     if(needToBeLoaded == false) {
-         free(pOutputParams);
-         pOutputParams = M4OSA_NULL;
-         free(pEncodingParams);
-         pEncodingParams = M4OSA_NULL;
-         return result;
-     }
-
-    // generate the path for temp 3gp output file
-    pTemp3gpFilePath = (M4OSA_Char*) M4OSA_32bitAlignedMalloc (
-        (strlen((const char*)pContext->initParams.pTempPath)
-        + strlen((const char*)TEMP_MCS_OUT_FILE_PATH)) + 1 /* for null termination */ , 0x0,
-        (M4OSA_Char*)"Malloc for temp 3gp file");
-    if (pTemp3gpFilePath != M4OSA_NULL)
-    {
-        memset((void *)pTemp3gpFilePath  ,0,
-            strlen((const char*)pContext->initParams.pTempPath)
-            + strlen((const char*)TEMP_MCS_OUT_FILE_PATH) + 1);
-        strncat((char *)pTemp3gpFilePath,
-            (const char *)pContext->initParams.pTempPath  ,
-            (size_t) ((M4OSA_Char*)pContext->initParams.pTempPath));
-        strncat((char *)pTemp3gpFilePath , (const char *)TEMP_MCS_OUT_FILE_PATH,
-            (size_t)strlen ((const char*)TEMP_MCS_OUT_FILE_PATH));
-    }
-    else {
-         M4MCS_abort(mcsContext);
-         free(pOutputParams);
-         pOutputParams = M4OSA_NULL;
-         free(pEncodingParams);
-         pEncodingParams = M4OSA_NULL;
-         return M4ERR_ALLOC;
-    }
-
-    pInputFile = (M4OSA_Char *) infilePath; //pContext->mAudioSettings->pFile;
-    //Delete this file later
-    pOutputFile = (M4OSA_Char *) pTemp3gpFilePath;
-    // Temp folder path for VSS use = ProjectPath
-    pTempPath = (M4OSA_Char *) pContext->initParams.pTempPath;
-    pInputFileType = (M4VIDEOEDITING_FileType)pContext->mAudioSettings->fileType;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "TEMP_MCS_OUT_FILE_PATH len %d",
-        strlen ((const char*)TEMP_MCS_OUT_FILE_PATH));
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pTemp3gpFilePath %s",
-        pOutputFile);
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_open()");
-
-    result = M4MCS_open(mcsContext, pInputFile,
-        (M4VIDEOEDITING_FileType)pInputFileType,
-        pOutputFile, pTempPath);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-        (M4NO_ERROR != result), result);
-    if(needToBeLoaded == false) {
-         free(pTemp3gpFilePath);
-         pTemp3gpFilePath = M4OSA_NULL;
-         M4MCS_abort(mcsContext);
-         free(pOutputParams);
-         pOutputParams = M4OSA_NULL;
-         free(pEncodingParams);
-         pEncodingParams = M4OSA_NULL;
-         return result;
-    }
-
-    pOutputParams->OutputFileType
-        = (M4VIDEOEDITING_FileType)M4VIDEOEDITING_kFileType_3GPP;
-    // Set the video format.
-    pOutputParams->OutputVideoFormat =
-        (M4VIDEOEDITING_VideoFormat)M4VIDEOEDITING_kNoneVideo;//M4VIDEOEDITING_kNoneVideo;
-    pOutputParams->outputVideoProfile = 1;
-    pOutputParams->outputVideoLevel = 1;
-    // Set the frame size.
-    pOutputParams->OutputVideoFrameSize
-        = (M4VIDEOEDITING_VideoFrameSize)M4VIDEOEDITING_kQCIF;
-    // Set the frame rate.
-    pOutputParams->OutputVideoFrameRate
-        = (M4VIDEOEDITING_VideoFramerate)M4VIDEOEDITING_k5_FPS;
-
-    // Set the audio format.
-    pOutputParams->OutputAudioFormat
-        = (M4VIDEOEDITING_AudioFormat)M4VIDEOEDITING_kAAC;
-    // Set the audio sampling frequency.
-    pOutputParams->OutputAudioSamplingFrequency =
-        (M4VIDEOEDITING_AudioSamplingFrequency)M4VIDEOEDITING_k32000_ASF;
-    // Set the audio mono.
-    pOutputParams->bAudioMono = false;
-    // Set the pcm file; null for now.
-    pOutputParams->pOutputPCMfile = (M4OSA_Char *)pcmfilePath;
-    //(M4OSA_Char *)"/sdcard/Output/AudioPcm.pcm";
-    // Set the audio sampling frequency.
-    pOutputParams->MediaRendering = (M4MCS_MediaRendering)M4MCS_kCropping;
-    // new params after integrating MCS 2.0
-    // Set the number of audio effects; 0 for now.
-    pOutputParams->nbEffects = 0;
-    // Set the audio effect; null for now.
-    pOutputParams->pEffects = NULL;
-    // Set the audio effect; null for now.
-    pOutputParams->bDiscardExif = M4OSA_FALSE;
-    // Set the audio effect; null for now.
-    pOutputParams->bAdjustOrientation = M4OSA_FALSE;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_setOutputParams()");
-    result = M4MCS_setOutputParams(mcsContext, pOutputParams);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                                        (M4NO_ERROR != result), result);
-    if (needToBeLoaded == false) {
-         free(pTemp3gpFilePath);
-         pTemp3gpFilePath = M4OSA_NULL;
-         M4MCS_abort(mcsContext);
-         free(pOutputParams);
-         pOutputParams = M4OSA_NULL;
-         free(pEncodingParams);
-         pEncodingParams = M4OSA_NULL;
-        return result;
-    }
-    // Set the video bitrate.
-    pEncodingParams->OutputVideoBitrate =
-    (M4VIDEOEDITING_Bitrate)M4VIDEOEDITING_kUndefinedBitrate;
-    // Set the audio bitrate.
-    pEncodingParams->OutputAudioBitrate
-        = (M4VIDEOEDITING_Bitrate)M4VIDEOEDITING_k128_KBPS;
-    // Set the end cut time in milliseconds.
-    pEncodingParams->BeginCutTime = 0;
-    // Set the end cut time in milliseconds.
-    pEncodingParams->EndCutTime = 0;
-    // Set the output file size in bytes.
-    pEncodingParams->OutputFileSize = 0;
-    // Set video time scale.
-    pEncodingParams->OutputVideoTimescale = 0;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                            "M4MCS_setEncodingParams()");
-    result = M4MCS_setEncodingParams(mcsContext, pEncodingParams);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-        (M4NO_ERROR != result), result);
-    if (needToBeLoaded == false) {
-         free(pTemp3gpFilePath);
-         pTemp3gpFilePath = M4OSA_NULL;
-         M4MCS_abort(mcsContext);
-         free(pOutputParams);
-         pOutputParams = M4OSA_NULL;
-         free(pEncodingParams);
-         pEncodingParams = M4OSA_NULL;
-         return result;
-    }
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                            "M4MCS_checkParamsAndStart()");
-    result = M4MCS_checkParamsAndStart(mcsContext);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-        (M4NO_ERROR != result), result);
-    if (needToBeLoaded == false) {
-         free(pTemp3gpFilePath);
-         pTemp3gpFilePath = M4OSA_NULL;
-         M4MCS_abort(mcsContext);
-         free(pOutputParams);
-         pOutputParams = M4OSA_NULL;
-         free(pEncodingParams);
-         pEncodingParams = M4OSA_NULL;
-        return result;
-    }
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_step()");
-
-    /*+ PROGRESS CB */
-    M4OSA_UInt8 curProgress = 0;
-    int         lastProgress = 0;
-
-    ALOGV("LVME_generateAudio Current progress is =%d", curProgress);
-    pEnv->CallVoidMethod(pContext->engine,
-            pContext->onProgressUpdateMethodId, 1/*task status*/,
-            curProgress/*progress*/);
-    do {
-        result = M4MCS_step(mcsContext, &curProgress);
-
-        if (result != M4NO_ERROR) {
-            ALOGV("LVME_generateAudio M4MCS_step returned 0x%x",result);
-
-            if (result == M4MCS_WAR_TRANSCODING_DONE) {
-                ALOGV("LVME_generateAudio MCS process ended");
-
-                // Send a progress notification.
-                curProgress = 100;
-                pEnv->CallVoidMethod(pContext->engine,
-                    pContext->onProgressUpdateMethodId, 1/*task status*/,
-                    curProgress);
-                ALOGV("LVME_generateAudio Current progress is =%d", curProgress);
-            }
-        } else {
-            // Send a progress notification if needed
-            if (curProgress != lastProgress) {
-                lastProgress = curProgress;
-                pEnv->CallVoidMethod(pContext->engine,
-                    pContext->onProgressUpdateMethodId, 0/*task status*/,
-                    curProgress/*progress*/);
-                ALOGV("LVME_generateAudio Current progress is =%d",curProgress);
-            }
-        }
-    } while (result == M4NO_ERROR);
-    /*- PROGRESS CB */
-
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-        (M4MCS_WAR_TRANSCODING_DONE != result), result);
-    if (needToBeLoaded == false) {
-         free(pTemp3gpFilePath);
-         pTemp3gpFilePath = M4OSA_NULL;
-         M4MCS_abort(mcsContext);
-         free(pOutputParams);
-         pOutputParams = M4OSA_NULL;
-         free(pEncodingParams);
-         pEncodingParams = M4OSA_NULL;
-        return result;
-    }
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4MCS_abort()");
-    result = M4MCS_abort(mcsContext);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-        (M4NO_ERROR != result), result);
-
-    //pContext->mAudioSettings->pFile = pOutputParams->pOutputPCMfile;
-    remove((const char *) pTemp3gpFilePath);
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_generateAudio() EXIT ");
-
-    if (pTemp3gpFilePath != M4OSA_NULL) {
-        free(pTemp3gpFilePath);
-    }
-    if (pOutputParams != M4OSA_NULL) {
-       free(pOutputParams);
-    }
-    if(pEncodingParams != M4OSA_NULL) {
-       free(pEncodingParams);
-    }
-    return result;
-}
-
-static int removeAlphafromRGB8888 (
-                        M4OSA_Char* pFramingFilePath,
-                        M4xVSS_FramingStruct *pFramingCtx)
-{
-    M4OSA_UInt32 frameSize_argb = (pFramingCtx->width * pFramingCtx->height * 4); // aRGB data
-    M4OSA_Context lImageFileFp  = M4OSA_NULL;
-    M4OSA_ERR err = M4NO_ERROR;
-
-    ALOGV("removeAlphafromRGB8888: width %d", pFramingCtx->width);
-
-    M4OSA_UInt8 *pTmpData = (M4OSA_UInt8*) M4OSA_32bitAlignedMalloc(frameSize_argb, M4VS, (M4OSA_Char*)"Image argb data");
-    if (pTmpData == M4OSA_NULL) {
-        ALOGE("Failed to allocate memory for Image clip");
-        return M4ERR_ALLOC;
-    }
-
-       /** Read the argb data from the passed file. */
-    M4OSA_ERR lerr = M4OSA_fileReadOpen(&lImageFileFp, (M4OSA_Void *) pFramingFilePath, M4OSA_kFileRead);
-
-
-    if ((lerr != M4NO_ERROR) || (lImageFileFp == M4OSA_NULL))
-    {
-        ALOGE("removeAlphafromRGB8888: Can not open the file ");
-        free(pTmpData);
-        return M4ERR_FILE_NOT_FOUND;
-    }
-
-
-    lerr = M4OSA_fileReadData(lImageFileFp, (M4OSA_MemAddr8)pTmpData, &frameSize_argb);
-    if (lerr != M4NO_ERROR)
-    {
-        ALOGE("removeAlphafromRGB8888: can not read the data ");
-        M4OSA_fileReadClose(lImageFileFp);
-        free(pTmpData);
-        return lerr;
-    }
-    M4OSA_fileReadClose(lImageFileFp);
-
-    M4OSA_UInt32 frameSize = (pFramingCtx->width * pFramingCtx->height * 3); //Size of RGB 888 data.
-
-    pFramingCtx->FramingRgb = (M4VIFI_ImagePlane*)M4OSA_32bitAlignedMalloc(
-             sizeof(M4VIFI_ImagePlane), M4VS, (M4OSA_Char*)"Image clip RGB888 data");
-    pFramingCtx->FramingRgb->pac_data = (M4VIFI_UInt8*)M4OSA_32bitAlignedMalloc(
-             frameSize, M4VS, (M4OSA_Char*)"Image clip RGB888 data");
-
-    if (pFramingCtx->FramingRgb == M4OSA_NULL)
-    {
-        ALOGE("Failed to allocate memory for Image clip");
-        free(pTmpData);
-        return M4ERR_ALLOC;
-    }
-
-    /** Remove the alpha channel */
-    for (size_t i = 0, j = 0; i < frameSize_argb; i++) {
-        if ((i % 4) == 0) continue;
-        pFramingCtx->FramingRgb->pac_data[j] = pTmpData[i];
-        j++;
-    }
-    free(pTmpData);
-    return M4NO_ERROR;
-}
-
-static void
-videoEditor_populateSettings(
-                JNIEnv*                 pEnv,
-                jobject                 thiz,
-                jobject                 settings,
-                jobject                 object,
-                jobject                 audioSettingObject)
-{
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "videoEditor_populateSettings()");
-
-    bool                needToBeLoaded  = true;
-    ManualEditContext*  pContext        = M4OSA_NULL;
-    M4OSA_ERR           result          = M4NO_ERROR;
-    jstring             strPath         = M4OSA_NULL;
-    jstring             strPCMPath      = M4OSA_NULL;
-    jobjectArray        propertiesClipsArray           = M4OSA_NULL;
-    jobject             properties      = M4OSA_NULL;
-    jint*               bitmapArray     =  M4OSA_NULL;
-    jobjectArray        effectSettingsArray = M4OSA_NULL;
-    jobject             effectSettings  = M4OSA_NULL;
-    jintArray           pixelArray      = M4OSA_NULL;
-    int width = 0;
-    int height = 0;
-    int nbOverlays = 0;
-    int i,j = 0;
-    int *pOverlayIndex = M4OSA_NULL;
-    M4OSA_Char* pTempChar = M4OSA_NULL;
-
-    // Validate the settings parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
-                                                (NULL == settings),
-                                                "settings is null");
-    // Get the context.
-    pContext =
-            (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                 (M4OSA_NULL == pContext->mPreviewController),
-                                 "not initialized");
-    jclass mPreviewClipPropClazz = pEnv->FindClass(PREVIEW_PROPERTIES_CLASS_NAME);
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                     (M4OSA_NULL == mPreviewClipPropClazz),
-                                     "not initialized");
-
-    jfieldID fid = pEnv->GetFieldID(mPreviewClipPropClazz,"clipProperties",
-            "[L"PROPERTIES_CLASS_NAME";"  );
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                     (M4OSA_NULL == fid),
-                                     "not initialized");
-
-    propertiesClipsArray = (jobjectArray)pEnv->GetObjectField(object, fid);
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                     (M4OSA_NULL == propertiesClipsArray),
-                                     "not initialized");
-
-    jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME);
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                     (M4OSA_NULL == engineClass),
-                                     "not initialized");
-
-    pContext->onPreviewProgressUpdateMethodId = pEnv->GetMethodID(engineClass,
-            "onPreviewProgressUpdate",     "(IZZLjava/lang/String;II)V");
-    // Check if the context is valid (required because the context is dereferenced).
-    if (needToBeLoaded) {
-        // Make sure that we are in a correct state.
-        videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                             (pContext->state != ManualEditState_INITIALIZED),
-                             "settings already loaded");
-        if (needToBeLoaded) {
-            // Retrieve the edit settings.
-            if (pContext->pEditSettings != M4OSA_NULL) {
-                videoEditClasses_freeEditSettings(&pContext->pEditSettings);
-                pContext->pEditSettings = M4OSA_NULL;
-            }
-            videoEditClasses_getEditSettings(&needToBeLoaded, pEnv,
-                settings, &pContext->pEditSettings,false);
-        }
-    }
-
-    if (needToBeLoaded == false) {
-        j = 0;
-        while (j < pContext->pEditSettings->nbEffects)
-        {
-            if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL) {
-                if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer != M4OSA_NULL) {
-                    free(pContext->pEditSettings->\
-                    Effects[j].xVSS.pFramingBuffer);
-                    pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer = M4OSA_NULL;
-                }
-            }
-          j++;
-        }
-        return;
-    }
-
-    M4OSA_TRACE1_0("videoEditorC_getEditSettings done");
-
-    pContext->previewFrameEditInfoId = pEnv->GetMethodID(engineClass,
-        "previewFrameEditInfo", "(Ljava/lang/String;I)V");
-
-    if ( pContext->pEditSettings != NULL )
-    {
-        // Check if the edit settings could be retrieved.
-        jclass mEditClazz = pEnv->FindClass(EDIT_SETTINGS_CLASS_NAME);
-        if(mEditClazz == M4OSA_NULL)
-        {
-            M4OSA_TRACE1_0("cannot find object field for mEditClazz");
-            goto videoEditor_populateSettings_cleanup;
-        }
-        jclass mEffectsClazz = pEnv->FindClass(EFFECT_SETTINGS_CLASS_NAME);
-        if(mEffectsClazz == M4OSA_NULL)
-        {
-            M4OSA_TRACE1_0("cannot find object field for mEffectsClazz");
-            goto videoEditor_populateSettings_cleanup;
-        }
-        fid = pEnv->GetFieldID(mEditClazz,"effectSettingsArray", "[L"EFFECT_SETTINGS_CLASS_NAME";"  );
-        if(fid == M4OSA_NULL)
-        {
-            M4OSA_TRACE1_0("cannot find field for effectSettingsArray Array");
-            goto videoEditor_populateSettings_cleanup;
-        }
-        effectSettingsArray = (jobjectArray)pEnv->GetObjectField(settings, fid);
-        if(effectSettingsArray == M4OSA_NULL)
-        {
-            M4OSA_TRACE1_0("cannot find object field for effectSettingsArray");
-            goto videoEditor_populateSettings_cleanup;
-        }
-
-        //int overlayIndex[pContext->pEditSettings->nbEffects];
-        if (pContext->pEditSettings->nbEffects > 0)
-        {
-            pOverlayIndex
-            = (int*) M4OSA_32bitAlignedMalloc(pContext->pEditSettings->nbEffects * sizeof(int), 0,
-                (M4OSA_Char*)"pOverlayIndex");
-            if (pOverlayIndex == M4OSA_NULL) {
-                videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                    M4OSA_TRUE, M4ERR_ALLOC);
-                goto videoEditor_populateSettings_cleanup;
-            }
-        }
-
-        i = 0;
-        j = 0;
-        M4OSA_TRACE1_1("no of effects = %d",pContext->pEditSettings->nbEffects);
-        while (j < pContext->pEditSettings->nbEffects)
-        {
-            if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL)
-            {
-                pOverlayIndex[nbOverlays] = j;
-
-                M4xVSS_FramingStruct *aFramingCtx = M4OSA_NULL;
-                aFramingCtx
-                = (M4xVSS_FramingStruct*)M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_FramingStruct), M4VS,
-                  (M4OSA_Char*)"M4xVSS_internalDecodeGIF: Context of the framing effect");
-                if (aFramingCtx == M4OSA_NULL)
-                {
-                    M4OSA_TRACE1_0("Allocation error in videoEditor_populateSettings");
-                    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                        M4OSA_TRUE, M4ERR_ALLOC);
-                    goto videoEditor_populateSettings_cleanup;
-                }
-
-                aFramingCtx->pCurrent = M4OSA_NULL; /* Only used by the first element of the chain */
-                aFramingCtx->previousClipTime = -1;
-                aFramingCtx->FramingYuv = M4OSA_NULL;
-                aFramingCtx->FramingRgb = M4OSA_NULL;
-                aFramingCtx->topleft_x
-                    = pContext->pEditSettings->Effects[j].xVSS.topleft_x;
-                aFramingCtx->topleft_y
-                    = pContext->pEditSettings->Effects[j].xVSS.topleft_y;
-
-
-                 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF u_width %d",
-                                        pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width);
-                 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF u_height() %d",
-                                        pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height);
-                 VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "OF rgbType() %d",
-                                        pContext->pEditSettings->Effects[j].xVSS.rgbType);
-
-                 aFramingCtx->width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width;
-                 aFramingCtx->height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height;
-
-                result = M4xVSS_internalConvertARGB888toYUV420_FrammingEffect(pContext->engineContext,
-                    &(pContext->pEditSettings->Effects[j]),aFramingCtx,
-                pContext->pEditSettings->Effects[j].xVSS.framingScaledSize);
-                videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                                            (M4NO_ERROR != result), result);
-                if (needToBeLoaded == false) {
-                    M4OSA_TRACE1_1("M4xVSS_internalConvertARGB888toYUV420_FrammingEffect returned 0x%x", result);
-                    if (aFramingCtx != M4OSA_NULL) {
-                        free(aFramingCtx);
-                        aFramingCtx = M4OSA_NULL;
-                    }
-                    goto videoEditor_populateSettings_cleanup;
-                }
-
-                //framing buffers are resized to fit the output video resolution.
-                pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width =
-                    aFramingCtx->FramingRgb->u_width;
-                pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height =
-                    aFramingCtx->FramingRgb->u_height;
-
-                VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "A framing Context aFramingCtx->width = %d",
-                    aFramingCtx->FramingRgb->u_width);
-
-                VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "A framing Context aFramingCtx->height = %d",
-                    aFramingCtx->FramingRgb->u_height);
-
-
-                width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width;
-                height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height;
-
-                //RGB 565
-                pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_stride = width * 2;
-
-                //for RGB565
-                pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_topleft = 0;
-                pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->pac_data =
-                            (M4VIFI_UInt8 *)M4OSA_32bitAlignedMalloc(width*height*2,
-                            0x00,(M4OSA_Char *)"pac_data buffer");
-
-                if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->pac_data == M4OSA_NULL) {
-                    M4OSA_TRACE1_0("Failed to allocate memory for framing buffer");
-                    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                                            M4OSA_TRUE, M4ERR_ALLOC);
-                    goto videoEditor_populateSettings_cleanup;
-                }
-
-                memcpy((void *)&pContext->pEditSettings->\
-                    Effects[j].xVSS.pFramingBuffer->\
-                    pac_data[0],(void *)&aFramingCtx->FramingRgb->pac_data[0],(width*height*2));
-
-                //As of now rgb type is 565
-                pContext->pEditSettings->Effects[j].xVSS.rgbType =
-                    (M4VSS3GPP_RGBType) M4VSS3GPP_kRGB565;
-
-                if (aFramingCtx->FramingYuv != M4OSA_NULL )
-                {
-                    if (aFramingCtx->FramingYuv[0].pac_data != M4OSA_NULL) {
-                        free(aFramingCtx->FramingYuv[0].pac_data);
-                        aFramingCtx->FramingYuv[0].pac_data = M4OSA_NULL;
-                    }
-                    if (aFramingCtx->FramingYuv[1].pac_data != M4OSA_NULL) {
-                        free(aFramingCtx->FramingYuv[1].pac_data);
-                        aFramingCtx->FramingYuv[1].pac_data = M4OSA_NULL;
-                    }
-                    if (aFramingCtx->FramingYuv[2].pac_data != M4OSA_NULL) {
-                        free(aFramingCtx->FramingYuv[2].pac_data);
-                        aFramingCtx->FramingYuv[2].pac_data = M4OSA_NULL;
-                    }
-
-                    free(aFramingCtx->FramingYuv);
-                    aFramingCtx->FramingYuv = M4OSA_NULL;
-                }
-                if (aFramingCtx->FramingRgb->pac_data != M4OSA_NULL) {
-                    free(aFramingCtx->FramingRgb->pac_data);
-                    aFramingCtx->FramingRgb->pac_data = M4OSA_NULL;
-                }
-                if (aFramingCtx->FramingRgb != M4OSA_NULL) {
-                    free(aFramingCtx->FramingRgb);
-                    aFramingCtx->FramingRgb = M4OSA_NULL;
-                }
-                if (aFramingCtx != M4OSA_NULL) {
-                    free(aFramingCtx);
-                    aFramingCtx = M4OSA_NULL;
-                }
-                nbOverlays++;
-            }
-            j++;
-        }
-
-        // Check if the edit settings could be retrieved.
-        M4OSA_TRACE1_1("total clips are = %d",pContext->pEditSettings->uiClipNumber);
-        for (i = 0; i < pContext->pEditSettings->uiClipNumber; i++) {
-            M4OSA_TRACE1_1("clip no = %d",i);
-            properties = pEnv->GetObjectArrayElement(propertiesClipsArray, i);
-            videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                (M4OSA_NULL == properties),
-                "not initialized");
-            if (needToBeLoaded) {
-                getClipSetting(pEnv,properties, pContext->pEditSettings->pClipList[i]);
-                pEnv->DeleteLocalRef(properties);
-            } else {
-                pEnv->DeleteLocalRef(properties);
-                goto videoEditor_populateSettings_cleanup;
-            }
-        }
-
-        if (needToBeLoaded) {
-            // Log the edit settings.
-            VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings);
-        }
-    }
-    /* free previous allocations , if any */
-    if (pContext->mAudioSettings != M4OSA_NULL) {
-        if (pContext->mAudioSettings->pFile != NULL) {
-            free(pContext->mAudioSettings->pFile);
-            pContext->mAudioSettings->pFile = M4OSA_NULL;
-        }
-        if (pContext->mAudioSettings->pPCMFilePath != NULL) {
-            free(pContext->mAudioSettings->pPCMFilePath);
-            pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
-        }
-    }
-
-    if (audioSettingObject != M4OSA_NULL) {
-        jclass audioSettingClazz = pEnv->FindClass(AUDIO_SETTINGS_CLASS_NAME);
-        videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                         (M4OSA_NULL == audioSettingClazz),
-                                         "not initialized");
-
-        videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                     (M4OSA_NULL == pContext->mAudioSettings),
-                                     "not initialized");
-
-        if (needToBeLoaded == false) {
-            goto videoEditor_populateSettings_cleanup;
-        }
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"bRemoveOriginal","Z");
-        pContext->mAudioSettings->bRemoveOriginal =
-            pEnv->GetBooleanField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("bRemoveOriginal = %d",pContext->mAudioSettings->bRemoveOriginal);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"channels","I");
-        pContext->mAudioSettings->uiNbChannels = pEnv->GetIntField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("uiNbChannels = %d",pContext->mAudioSettings->uiNbChannels);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"Fs","I");
-        pContext->mAudioSettings->uiSamplingFrequency = pEnv->GetIntField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("uiSamplingFrequency = %d",pContext->mAudioSettings->uiSamplingFrequency);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"ExtendedFs","I");
-        pContext->mAudioSettings->uiExtendedSamplingFrequency =
-         pEnv->GetIntField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("uiExtendedSamplingFrequency = %d",
-        pContext->mAudioSettings->uiExtendedSamplingFrequency);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"startMs","J");
-        pContext->mAudioSettings->uiAddCts
-            = pEnv->GetLongField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("uiAddCts = %d",pContext->mAudioSettings->uiAddCts);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"volume","I");
-        pContext->mAudioSettings->uiAddVolume
-            = pEnv->GetIntField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("uiAddVolume = %d",pContext->mAudioSettings->uiAddVolume);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"loop","Z");
-        pContext->mAudioSettings->bLoop
-            = pEnv->GetBooleanField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("bLoop = %d",pContext->mAudioSettings->bLoop);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"beginCutTime","J");
-        pContext->mAudioSettings->beginCutMs
-            = pEnv->GetLongField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("begin cut time = %d",pContext->mAudioSettings->beginCutMs);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"endCutTime","J");
-        pContext->mAudioSettings->endCutMs
-            = pEnv->GetLongField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("end cut time = %d",pContext->mAudioSettings->endCutMs);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"fileType","I");
-        pContext->mAudioSettings->fileType
-            = pEnv->GetIntField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("fileType = %d",pContext->mAudioSettings->fileType);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"pFile","Ljava/lang/String;");
-        strPath = (jstring)pEnv->GetObjectField(audioSettingObject,fid);
-        pTempChar = (M4OSA_Char*)pEnv->GetStringUTFChars(strPath, M4OSA_NULL);
-        if (pTempChar != NULL) {
-            pContext->mAudioSettings->pFile = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(
-                (M4OSA_UInt32)(strlen((const char*)pTempChar))+1 /* +1 for NULL termination */, 0,
-                (M4OSA_Char*)"strPath allocation " );
-            if (pContext->mAudioSettings->pFile != M4OSA_NULL) {
-                memcpy((void *)pContext->mAudioSettings->pFile ,
-                    (void *)pTempChar , strlen((const char*)pTempChar));
-                ((M4OSA_Int8 *)(pContext->mAudioSettings->pFile))[strlen((const char*)pTempChar)] = '\0';
-                pEnv->ReleaseStringUTFChars(strPath,(const char *)pTempChar);
-            } else {
-                pEnv->ReleaseStringUTFChars(strPath,(const char *)pTempChar);
-                VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                    "regenerateAudio() Malloc failed for pContext->mAudioSettings->pFile ");
-                videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                    M4OSA_TRUE, M4ERR_ALLOC);
-                goto videoEditor_populateSettings_cleanup;
-            }
-        }
-        M4OSA_TRACE1_1("file name = %s",pContext->mAudioSettings->pFile);
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio() file name = %s",\
-        pContext->mAudioSettings->pFile);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"pcmFilePath","Ljava/lang/String;");
-        strPCMPath = (jstring)pEnv->GetObjectField(audioSettingObject,fid);
-        pTempChar = (M4OSA_Char*)pEnv->GetStringUTFChars(strPCMPath, M4OSA_NULL);
-        if (pTempChar != NULL) {
-            pContext->mAudioSettings->pPCMFilePath = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(
-                (M4OSA_UInt32)(strlen((const char*)pTempChar))+1 /* +1 for NULL termination */, 0,
-                (M4OSA_Char*)"strPCMPath allocation " );
-            if (pContext->mAudioSettings->pPCMFilePath != M4OSA_NULL) {
-                memcpy((void *)pContext->mAudioSettings->pPCMFilePath ,
-                    (void *)pTempChar , strlen((const char*)pTempChar));
-                ((M4OSA_Int8 *)(pContext->mAudioSettings->pPCMFilePath))[strlen((const char*)pTempChar)] = '\0';
-                pEnv->ReleaseStringUTFChars(strPCMPath,(const char *)pTempChar);
-            } else {
-                pEnv->ReleaseStringUTFChars(strPCMPath,(const char *)pTempChar);
-                VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-                    "regenerateAudio() Malloc failed for pContext->mAudioSettings->pPCMFilePath ");
-                videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                    M4OSA_TRUE, M4ERR_ALLOC);
-                goto videoEditor_populateSettings_cleanup;
-            }
-        }
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "pPCMFilePath -- %s ",\
-        pContext->mAudioSettings->pPCMFilePath);
-
-        fid = pEnv->GetFieldID(engineClass,"mRegenerateAudio","Z");
-        bool regenerateAudio = pEnv->GetBooleanField(thiz,fid);
-
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEOEDITOR", "regenerateAudio -- %d ",\
-        regenerateAudio);
-
-        if (regenerateAudio) {
-            M4OSA_TRACE1_0("Calling Generate Audio now");
-            result = videoEditor_generateAudio(pEnv,
-                        pContext,
-                        (M4OSA_Char*)pContext->mAudioSettings->pFile,
-                        (M4OSA_Char*)pContext->mAudioSettings->pPCMFilePath);
-
-            videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                (M4NO_ERROR != result), result);
-            if (needToBeLoaded == false) {
-                goto videoEditor_populateSettings_cleanup;
-            }
-
-            regenerateAudio = false;
-            pEnv->SetBooleanField(thiz,fid,regenerateAudio);
-        }
-
-        /* Audio mix and duck */
-        fid = pEnv->GetFieldID(audioSettingClazz,"ducking_threshold","I");
-        pContext->mAudioSettings->uiInDucking_threshold
-            = pEnv->GetIntField(audioSettingObject,fid);
-
-        M4OSA_TRACE1_1("ducking threshold = %d",
-            pContext->mAudioSettings->uiInDucking_threshold);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"ducking_lowVolume","I");
-        pContext->mAudioSettings->uiInDucking_lowVolume
-            = pEnv->GetIntField(audioSettingObject,fid);
-
-        M4OSA_TRACE1_1("ducking lowVolume = %d",
-            pContext->mAudioSettings->uiInDucking_lowVolume);
-
-        fid = pEnv->GetFieldID(audioSettingClazz,"bInDucking_enable","Z");
-        pContext->mAudioSettings->bInDucking_enable
-            = pEnv->GetBooleanField(audioSettingObject,fid);
-        M4OSA_TRACE1_1("ducking lowVolume = %d",
-            pContext->mAudioSettings->bInDucking_enable);
-
-    } else {
-        if (pContext->mAudioSettings != M4OSA_NULL) {
-            pContext->mAudioSettings->pFile = M4OSA_NULL;
-            pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
-            pContext->mAudioSettings->bRemoveOriginal = 0;
-            pContext->mAudioSettings->uiNbChannels = 0;
-            pContext->mAudioSettings->uiSamplingFrequency = 0;
-            pContext->mAudioSettings->uiExtendedSamplingFrequency = 0;
-            pContext->mAudioSettings->uiAddCts = 0;
-            pContext->mAudioSettings->uiAddVolume = 0;
-            pContext->mAudioSettings->beginCutMs = 0;
-            pContext->mAudioSettings->endCutMs = 0;
-            pContext->mAudioSettings->fileType = 0;
-            pContext->mAudioSettings->bLoop = 0;
-            pContext->mAudioSettings->uiInDucking_lowVolume  = 0;
-            pContext->mAudioSettings->bInDucking_enable  = 0;
-            pContext->mAudioSettings->uiBTChannelCount  = 0;
-            pContext->mAudioSettings->uiInDucking_threshold = 0;
-
-            fid = pEnv->GetFieldID(engineClass,"mRegenerateAudio","Z");
-            bool regenerateAudio = pEnv->GetBooleanField(thiz,fid);
-            if (!regenerateAudio) {
-                regenerateAudio = true;
-                pEnv->SetBooleanField(thiz,fid,regenerateAudio);
-            }
-        }
-    }
-
-    if (pContext->pEditSettings != NULL)
-    {
-        result = pContext->mPreviewController->loadEditSettings(pContext->pEditSettings,
-            pContext->mAudioSettings);
-        videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-                                            (M4NO_ERROR != result), result);
-
-        if (needToBeLoaded) {
-            pContext->mPreviewController->setJniCallback((void*)pContext,
-            (jni_progress_callback_fct)jniPreviewProgressCallback);
-        }
-    }
-
-videoEditor_populateSettings_cleanup:
-        j = 0;
-        while (j < nbOverlays)
-        {
-            if (pContext->pEditSettings->Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data != \
-                M4OSA_NULL) {
-                free(pContext->pEditSettings->\
-                Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data);
-                pContext->pEditSettings->\
-                Effects[pOverlayIndex[j]].xVSS.pFramingBuffer->pac_data = M4OSA_NULL;
-            }
-            j++;
-        }
-
-        j = 0;
-        while (j < pContext->pEditSettings->nbEffects)
-        {
-            if (pContext->pEditSettings->Effects[j].xVSS.pFramingFilePath != M4OSA_NULL) {
-                if (pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer != M4OSA_NULL) {
-                    free(pContext->pEditSettings->\
-                    Effects[j].xVSS.pFramingBuffer);
-                    pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer = M4OSA_NULL;
-                }
-            }
-          j++;
-        }
-
-    if (pOverlayIndex != M4OSA_NULL)
-    {
-        free(pOverlayIndex);
-        pOverlayIndex = M4OSA_NULL;
-    }
-    return;
-}
-
-static void
-videoEditor_startPreview(
-                JNIEnv*                 pEnv,
-                jobject                 thiz,
-                jobject                 mSurface,
-                jlong                   fromMs,
-                jlong                   toMs,
-                jint                    callbackInterval,
-                jboolean                loop)
-{
-    bool needToBeLoaded = true;
-    M4OSA_ERR result = M4NO_ERROR;
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_startPreview()");
-
-    ManualEditContext* pContext = M4OSA_NULL;
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                     (M4OSA_NULL == pContext->mAudioSettings),
-                                     "not initialized");
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                 (M4OSA_NULL == pContext->mPreviewController),
-                                 "not initialized");
-
-    // Validate the mSurface parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
-                                                (NULL == mSurface),
-                                                "mSurface is null");
-
-    sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface);
-
-    // Validate the mSurface's mNativeSurface field
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                                (NULL == previewSurface.get()),
-                                                "mNativeSurface is null");
-
-    result =  pContext->mPreviewController->setSurface(previewSurface);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
-        (M4NO_ERROR != result), result);
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "fromMs=%ld, toMs=%ld",
-        (M4OSA_UInt32)fromMs, (M4OSA_Int32)toMs);
-
-    result = pContext->mPreviewController->startPreview((M4OSA_UInt32)fromMs,
-                                                (M4OSA_Int32)toMs,
-                                                (M4OSA_UInt16)callbackInterval,
-                                                (M4OSA_Bool)loop);
-    videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, (M4NO_ERROR != result), result);
-}
-
-
-static jobject
-videoEditor_getProperties(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jstring                             file)
-{
-    jobject object = M4OSA_NULL;
-    jclass clazz = pEnv->FindClass(PROPERTIES_CLASS_NAME);
-    jfieldID fid;
-    bool needToBeLoaded = true;
-    ManualEditContext* pContext = M4OSA_NULL;
-    M4OSA_ERR          result   = M4NO_ERROR;
-    int profile = 0;
-    int level = 0;
-    int videoFormat = 0;
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
-
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == clazz),
-                                             "not initialized");
-
-    object = videoEditProp_getProperties(pEnv,thiz,file);
-
-    if (object != M4OSA_NULL) {
-        fid = pEnv->GetFieldID(clazz,"profile","I");
-        profile = pEnv->GetIntField(object,fid);
-        fid = pEnv->GetFieldID(clazz,"level","I");
-        level = pEnv->GetIntField(object,fid);
-        fid = pEnv->GetFieldID(clazz,"videoFormat","I");
-        videoFormat = pEnv->GetIntField(object,fid);
-
-        result = checkClipVideoProfileAndLevel(pContext->decoders, videoFormat, profile, level);
-
-        fid = pEnv->GetFieldID(clazz,"profileSupported","Z");
-        if (M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_PROFILE == result) {
-            pEnv->SetBooleanField(object,fid,false);
-        }
-
-        fid = pEnv->GetFieldID(clazz,"levelSupported","Z");
-        if (M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_LEVEL == result) {
-            pEnv->SetBooleanField(object,fid,false);
-        }
-    }
-    return object;
-
-}
-static jint videoEditor_getPixels(
-                    JNIEnv*                     env,
-                    jobject                     thiz,
-                    jstring                     path,
-                    jintArray                   pixelArray,
-                    M4OSA_UInt32                width,
-                    M4OSA_UInt32                height,
-                    M4OSA_UInt32                timeMS)
-{
-
-    M4OSA_ERR       err = M4NO_ERROR;
-    M4OSA_Context   mContext = M4OSA_NULL;
-    jint*           m_dst32 = M4OSA_NULL;
-
-    const char *pString = env->GetStringUTFChars(path, NULL);
-    if (pString == M4OSA_NULL) {
-        if (env != NULL) {
-            jniThrowException(env, "java/lang/RuntimeException", "Input string null");
-        }
-        return M4ERR_ALLOC;
-    }
-
-    err = ThumbnailOpen(&mContext,(const M4OSA_Char*)pString, M4OSA_FALSE);
-    if (err != M4NO_ERROR || mContext == M4OSA_NULL) {
-        if (pString != NULL) {
-            env->ReleaseStringUTFChars(path, pString);
-        }
-        if (env != NULL) {
-            jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed");
-        }
-    }
-
-    m_dst32 = env->GetIntArrayElements(pixelArray, NULL);
-
-    err = ThumbnailGetPixels32(mContext, (M4OSA_Int32 *)m_dst32, width,height,&timeMS,0);
-    if (err != M4NO_ERROR ) {
-        if (env != NULL) {
-            jniThrowException(env, "java/lang/RuntimeException",\
-                "ThumbnailGetPixels32 failed");
-        }
-    }
-    env->ReleaseIntArrayElements(pixelArray, m_dst32, 0);
-
-    ThumbnailClose(mContext);
-    if (pString != NULL) {
-        env->ReleaseStringUTFChars(path, pString);
-    }
-
-    return (jint)timeMS;
-}
-
-static jint videoEditor_getPixelsList(
-                JNIEnv*                 env,
-                jobject                 thiz,
-                jstring                 path,
-                jintArray               pixelArray,
-                M4OSA_UInt32            width,
-                M4OSA_UInt32            height,
-                M4OSA_UInt32            noOfThumbnails,
-                jlong                   startTime,
-                jlong                   endTime,
-                jintArray               indexArray,
-                jobject                 callback)
-{
-
-    M4OSA_ERR           err = M4NO_ERROR;
-    M4OSA_Context       mContext = M4OSA_NULL;
-
-    const char *pString = env->GetStringUTFChars(path, NULL);
-    if (pString == M4OSA_NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Input string null");
-        return (jint)M4ERR_ALLOC;
-    }
-
-    err = ThumbnailOpen(&mContext,(const M4OSA_Char*)pString, M4OSA_FALSE);
-    if (err != M4NO_ERROR || mContext == M4OSA_NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed");
-        if (pString != NULL) {
-            env->ReleaseStringUTFChars(path, pString);
-        }
-        return (jint)err;
-    }
-
-    jlong duration = (endTime - startTime);
-    M4OSA_UInt32 tolerance = duration / (2 * noOfThumbnails);
-    jint* m_dst32 = env->GetIntArrayElements(pixelArray, NULL);
-    jint* indices = env->GetIntArrayElements(indexArray, NULL);
-    jsize len = env->GetArrayLength(indexArray);
-
-    jclass cls = env->GetObjectClass(callback);
-    jmethodID mid = env->GetMethodID(cls, "onThumbnail", "(I)V");
-
-    for (int i = 0; i < len; i++) {
-        int k = indices[i];
-        M4OSA_UInt32 timeMS = startTime;
-        timeMS += (2 * k + 1) * duration / (2 * noOfThumbnails);
-        err = ThumbnailGetPixels32(mContext, ((M4OSA_Int32 *)m_dst32),
-            width, height, &timeMS, tolerance);
-        if (err != M4NO_ERROR) {
-            break;
-        }
-        env->CallVoidMethod(callback, mid, (jint)k);
-        if (env->ExceptionCheck()) {
-            err = M4ERR_ALLOC;
-            break;
-        }
-    }
-
-    env->ReleaseIntArrayElements(pixelArray, m_dst32, 0);
-    env->ReleaseIntArrayElements(indexArray, indices, 0);
-
-    ThumbnailClose(mContext);
-    if (pString != NULL) {
-        env->ReleaseStringUTFChars(path, pString);
-    }
-
-    if (err != M4NO_ERROR && !env->ExceptionCheck()) {
-        jniThrowException(env, "java/lang/RuntimeException",\
-                "ThumbnailGetPixels32 failed");
-    }
-
-    return (jint)err;
-}
-
-static M4OSA_ERR
-videoEditor_toUTF8Fct(
-                M4OSA_Void*                         pBufferIn,
-                M4OSA_UInt8*                        pBufferOut,
-                M4OSA_UInt32*                       bufferOutSize)
-{
-    M4OSA_ERR    result = M4NO_ERROR;
-    M4OSA_UInt32 length = 0;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_toUTF8Fct()");
-
-    // Determine the length of the input buffer.
-    if (M4OSA_NULL != pBufferIn)
-    {
-        length = strlen((const char *)pBufferIn);
-    }
-
-    // Check if the output buffer is large enough to hold the input buffer.
-    if ((*bufferOutSize) > length)
-    {
-        // Check if the input buffer is not M4OSA_NULL.
-        if (M4OSA_NULL != pBufferIn)
-        {
-            // Copy the temp path, ignore the result.
-            M4OSA_chrNCopy((M4OSA_Char *)pBufferOut, (M4OSA_Char *)pBufferIn, length);
-        }
-        else
-        {
-            // Set the output buffer to an empty string.
-            (*(M4OSA_Char *)pBufferOut) = 0;
-        }
-    }
-    else
-    {
-        // The buffer is too small.
-        result = M4xVSSWAR_BUFFER_OUT_TOO_SMALL;
-    }
-
-    // Return the buffer output size.
-    (*bufferOutSize) = length + 1;
-
-    // Return the result.
-    return(result);
-}
-
-static M4OSA_ERR
-videoEditor_fromUTF8Fct(
-                M4OSA_UInt8*                        pBufferIn,
-                M4OSA_Void*                         pBufferOut,
-                M4OSA_UInt32*                       bufferOutSize)
-{
-    M4OSA_ERR    result = M4NO_ERROR;
-    M4OSA_UInt32 length = 0;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_fromUTF8Fct()");
-
-    // Determine the length of the input buffer.
-    if (M4OSA_NULL != pBufferIn)
-    {
-        length = strlen((const char *)pBufferIn);
-    }
-
-    // Check if the output buffer is large enough to hold the input buffer.
-    if ((*bufferOutSize) > length)
-    {
-        // Check if the input buffer is not M4OSA_NULL.
-        if (M4OSA_NULL != pBufferIn)
-        {
-            // Copy the temp path, ignore the result.
-            M4OSA_chrNCopy((M4OSA_Char *)pBufferOut, (M4OSA_Char *)pBufferIn, length);
-        }
-        else
-        {
-            // Set the output buffer to an empty string.
-            (*(M4OSA_Char *)pBufferOut) = 0;
-        }
-    }
-    else
-    {
-        // The buffer is too small.
-        result = M4xVSSWAR_BUFFER_OUT_TOO_SMALL;
-    }
-
-    // Return the buffer output size.
-    (*bufferOutSize) = length + 1;
-
-    // Return the result.
-    return(result);
-}
-
-static M4OSA_ERR
-videoEditor_getTextRgbBufferFct(
-                M4OSA_Void*                         pRenderingData,
-                M4OSA_Void*                         pTextBuffer,
-                M4OSA_UInt32                        textBufferSize,
-                M4VIFI_ImagePlane**                 pOutputPlane)
-{
-    M4OSA_ERR result = M4NO_ERROR;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getTextRgbBufferFct()");
-
-    // Return the result.
-    return(result);
-}
-
-static void
-videoEditor_callOnProgressUpdate(
-                ManualEditContext*                  pContext,
-                int                                 task,
-                int                                 progress)
-{
-    JNIEnv* pEnv = NULL;
-
-
-    // Attach the current thread.
-    pContext->pVM->AttachCurrentThread(&pEnv, NULL);
-
-
-    // Call the on completion callback.
-    pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId,
-     videoEditJava_getEngineCToJava(task), progress);
-
-
-    // Detach the current thread.
-    pContext->pVM->DetachCurrentThread();
-}
-
-static void
-videoEditor_freeContext(
-                JNIEnv*                             pEnv,
-                ManualEditContext**                 ppContext)
-{
-    ManualEditContext* pContext = M4OSA_NULL;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_freeContext");
-
-    // Set the context pointer.
-    pContext = (*ppContext);
-
-    // Check if the context was set.
-    if (M4OSA_NULL != pContext)
-    {
-        // Check if a global reference to the engine object was set.
-        if (NULL != pContext->engine)
-        {
-            // Free the global reference.
-            pEnv->DeleteGlobalRef(pContext->engine);
-            pContext->engine = NULL;
-        }
-
-        // Check if the temp path was set.
-        if (M4OSA_NULL != pContext->initParams.pTempPath)
-        {
-            // Free the memory allocated for the temp path.
-            videoEditOsal_free(pContext->initParams.pTempPath);
-            pContext->initParams.pTempPath = M4OSA_NULL;
-        }
-
-        // Check if the file writer was set.
-        if (M4OSA_NULL != pContext->initParams.pFileWritePtr)
-        {
-            // Free the memory allocated for the file writer.
-            videoEditOsal_free(pContext->initParams.pFileWritePtr);
-            pContext->initParams.pFileWritePtr = M4OSA_NULL;
-        }
-
-        // Check if the file reader was set.
-        if (M4OSA_NULL != pContext->initParams.pFileReadPtr)
-        {
-            // Free the memory allocated for the file reader.
-            videoEditOsal_free(pContext->initParams.pFileReadPtr);
-            pContext->initParams.pFileReadPtr = M4OSA_NULL;
-        }
-
-        // Free the memory allocated for the context.
-        videoEditOsal_free(pContext);
-        pContext = M4OSA_NULL;
-
-        // Reset the context pointer.
-        (*ppContext) = M4OSA_NULL;
-    }
-}
-
-static jobject
-videoEditor_getVersion(
-                JNIEnv*                             pEnv,
-                jobject                             thiz)
-{
-    bool           isSuccessful          = true;
-    jobject        version         = NULL;
-    M4_VersionInfo versionInfo     = {0, 0, 0, 0};
-    M4OSA_ERR      result          = M4NO_ERROR;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getVersion()");
-
-    versionInfo.m_structSize = sizeof(versionInfo);
-    versionInfo.m_major = VIDEOEDITOR_VERSION_MAJOR;
-    versionInfo.m_minor = VIDEOEDITOR_VERSION_MINOR;
-    versionInfo.m_revision = VIDEOEDITOR_VERSION_REVISION;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_getVersion() major %d,\
-     minor %d, revision %d", versionInfo.m_major, versionInfo.m_minor, versionInfo.m_revision);
-
-    // Create a version object.
-    videoEditClasses_createVersion(&isSuccessful, pEnv, &versionInfo, &version);
-
-    // Return the version object.
-    return(version);
-}
-
-static void
-videoEditor_init(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jstring                             tempPath,
-                jstring                             libraryPath)
-{
-    bool                  initialized            = true;
-    ManualEditContext*    pContext               = M4OSA_NULL;
-    VideoEditJava_EngineMethodIds methodIds              = {NULL};
-    M4OSA_Char*           pLibraryPath           = M4OSA_NULL;
-    M4OSA_Char*           pTextRendererPath      = M4OSA_NULL;
-    M4OSA_UInt32          textRendererPathLength = 0;
-    M4OSA_ERR             result                 = M4NO_ERROR;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_init()");
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&initialized, pEnv, thiz);
-
-    // Get the engine method ids.
-    videoEditJava_getEngineMethodIds(&initialized, pEnv, &methodIds);
-
-    // Validate the tempPath parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(&initialized, pEnv,
-                                                (NULL == tempPath),
-                                                "tempPath is null");
-
-    // Make sure that the context was not set already.
-    videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv,
-                                             (M4OSA_NULL != pContext),
-                                             "already initialized");
-
-    // Check if the initialization succeeded (required because of dereferencing of psContext,
-    // and freeing when initialization fails).
-    if (initialized)
-    {
-        // Allocate a new context.
-        pContext = new ManualEditContext;
-
-        // Check if the initialization succeeded (required because of dereferencing of psContext).
-        //if (initialized)
-        if (pContext != NULL)
-        {
-            // Set the state to not initialized.
-            pContext->state = ManualEditState_NOT_INITIALIZED;
-
-            // Allocate a file read pointer structure.
-            pContext->initParams.pFileReadPtr =
-             (M4OSA_FileReadPointer*)videoEditOsal_alloc(&initialized, pEnv,
-              sizeof(M4OSA_FileReadPointer), "FileReadPointer");
-
-            // Allocate a file write pointer structure.
-            pContext->initParams.pFileWritePtr =
-             (M4OSA_FileWriterPointer*)videoEditOsal_alloc(&initialized, pEnv,
-              sizeof(M4OSA_FileWriterPointer), "FileWriterPointer");
-
-            // Get the temp path.
-            M4OSA_Char* tmpString =
-                (M4OSA_Char *)videoEditJava_getString(&initialized, pEnv, tempPath,
-                NULL, M4OSA_NULL);
-            M4OSA_UInt32 length = strlen((const char *)tmpString);
-            // Malloc additional 2 bytes for beginning and tail separator.
-            M4OSA_UInt32 pathLength = length + 2;
-
-            pContext->initParams.pTempPath = (M4OSA_Char *)
-                 M4OSA_32bitAlignedMalloc(pathLength, 0x0, (M4OSA_Char *)"tempPath");
-
-            //initialize the first char. so that strcat works.
-            M4OSA_Char *ptmpChar = (M4OSA_Char*)pContext->initParams.pTempPath;
-            ptmpChar[0] = 0x00;
-            strncat((char *)pContext->initParams.pTempPath, (const char *)tmpString,
-                length);
-            strncat((char *)pContext->initParams.pTempPath, (const char *)"/", (size_t)1);
-            free(tmpString);
-            tmpString = NULL;
-            pContext->mIsUpdateOverlay = false;
-            pContext->mOverlayFileName = NULL;
-            pContext->decoders = NULL;
-        }
-
-        // Check if the initialization succeeded
-        // (required because of dereferencing of pContext, pFileReadPtr and pFileWritePtr).
-        if (initialized)
-        {
-
-            // Initialize the OSAL file system function pointers.
-            videoEditOsal_getFilePointers(pContext->initParams.pFileReadPtr ,
-                                          pContext->initParams.pFileWritePtr);
-
-            // Set the UTF8 conversion functions.
-            pContext->initParams.pConvToUTF8Fct   = videoEditor_toUTF8Fct;
-            pContext->initParams.pConvFromUTF8Fct = videoEditor_fromUTF8Fct;
-
-            // Set the callback method ids.
-            pContext->onProgressUpdateMethodId = methodIds.onProgressUpdate;
-
-            // Set the virtual machine.
-            pEnv->GetJavaVM(&(pContext->pVM));
-
-            // Create a global reference to the engine object.
-            pContext->engine = pEnv->NewGlobalRef(thiz);
-
-            // Check if the global reference could be created.
-            videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv,
-             (NULL == pContext->engine), M4NO_ERROR);
-        }
-
-        // Check if the initialization succeeded (required because of dereferencing of pContext).
-        if (initialized)
-        {
-            // Log the API call.
-            VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "M4xVSS_Init()");
-
-            // Initialize the visual studio library.
-            result = M4xVSS_Init(&pContext->engineContext, &pContext->initParams);
-
-            // Log the result.
-            VIDEOEDIT_LOG_RESULT(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-             videoEditOsal_getResultString(result));
-
-            // Check if the library could be initialized.
-            videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv,
-             (M4NO_ERROR != result), result);
-
-            // Get platform video decoder capablities.
-            result = M4xVSS_getVideoDecoderCapabilities(&pContext->decoders);
-
-            videoEditJava_checkAndThrowRuntimeException(&initialized, pEnv,
-             (M4NO_ERROR != result), result);
-        }
-
-        if(initialized)
-        {
-            pContext->mPreviewController = new VideoEditorPreviewController();
-            videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv,
-                                 (M4OSA_NULL == pContext->mPreviewController),
-                                 "not initialized");
-            pContext->mAudioSettings =
-             (M4xVSS_AudioMixingSettings *)
-             M4OSA_32bitAlignedMalloc(sizeof(M4xVSS_AudioMixingSettings),0x0,
-             (M4OSA_Char *)"mAudioSettings");
-            videoEditJava_checkAndThrowIllegalStateException(&initialized, pEnv,
-                                     (M4OSA_NULL == pContext->mAudioSettings),
-                                     "not initialized");
-            pContext->mAudioSettings->pFile = M4OSA_NULL;
-            pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
-            pContext->mAudioSettings->bRemoveOriginal = 0;
-            pContext->mAudioSettings->uiNbChannels = 0;
-            pContext->mAudioSettings->uiSamplingFrequency = 0;
-            pContext->mAudioSettings->uiExtendedSamplingFrequency = 0;
-            pContext->mAudioSettings->uiAddCts = 0;
-            pContext->mAudioSettings->uiAddVolume = 0;
-            pContext->mAudioSettings->beginCutMs = 0;
-            pContext->mAudioSettings->endCutMs = 0;
-            pContext->mAudioSettings->fileType = 0;
-            pContext->mAudioSettings->bLoop = 0;
-            pContext->mAudioSettings->uiInDucking_lowVolume  = 0;
-            pContext->mAudioSettings->bInDucking_enable  = 0;
-            pContext->mAudioSettings->uiBTChannelCount  = 0;
-            pContext->mAudioSettings->uiInDucking_threshold = 0;
-        }
-        // Check if the library could be initialized.
-        if (initialized)
-        {
-            // Set the state to initialized.
-            pContext->state = ManualEditState_INITIALIZED;
-        }
-
-        // Set the context.
-        videoEditClasses_setContext(&initialized, pEnv, thiz, (void* )pContext);
-        pLibraryPath = M4OSA_NULL;
-
-        pContext->pEditSettings = M4OSA_NULL;
-        // Cleanup if anything went wrong during initialization.
-        if (!initialized)
-        {
-            // Free the context.
-            videoEditor_freeContext(pEnv, &pContext);
-        }
-    }
-}
-
-/*+ PROGRESS CB */
-static
-M4OSA_ERR videoEditor_processClip(
-                            JNIEnv*  pEnv,
-                            jobject  thiz,
-                            int      unuseditemID) {
-
-    bool               loaded           = true;
-    ManualEditContext* pContext         = NULL;
-    M4OSA_UInt8        progress         = 0;
-    M4OSA_UInt8        progressBase     = 0;
-    M4OSA_UInt8        lastProgress     = 0;
-    M4OSA_ERR          result           = M4NO_ERROR;
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    // We start in Analyzing state
-    pContext->state = ManualEditState_INITIALIZED;
-    M4OSA_ERR          completionResult = M4VSS3GPP_WAR_ANALYZING_DONE;
-    ManualEditState    completionState  = ManualEditState_OPENED;
-    ManualEditState    errorState       = ManualEditState_ANALYZING_ERROR;
-
-    // While analyzing progress goes from 0 to 10 (except Kenburn clip
-    // generation, which goes from 0 to 50)
-    progressBase     = 0;
-
-    // Set the text rendering function.
-    if (M4OSA_NULL != pContext->pTextRendererFunction)
-    {
-        // Use the text renderer function in the library.
-        pContext->pEditSettings->xVSS.pTextRenderingFct = pContext->pTextRendererFunction;
-    }
-    else
-    {
-        // Use the internal text renderer function.
-        pContext->pEditSettings->xVSS.pTextRenderingFct = videoEditor_getTextRgbBufferFct;
-    }
-
-    // Send the command.
-    ALOGV("videoEditor_processClip ITEM %d Calling M4xVSS_SendCommand()", unuseditemID);
-    result = M4xVSS_SendCommand(pContext->engineContext, pContext->pEditSettings);
-    ALOGV("videoEditor_processClip ITEM %d M4xVSS_SendCommand() returned 0x%x",
-        unuseditemID, (unsigned int) result);
-
-    // Remove warnings indications (we only care about errors here)
-    if ((result == M4VSS3GPP_WAR_TRANSCODING_NECESSARY)
-        || (result == M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED)) {
-        result = M4NO_ERROR;
-    }
-
-    // Send the first progress indication (=0)
-    ALOGV("VERY FIRST PROGRESS videoEditor_processClip ITEM %d Progress indication %d",
-        unuseditemID, progress);
-    pEnv->CallVoidMethod(pContext->engine, pContext->onProgressUpdateMethodId,
-        unuseditemID, progress);
-
-    // Check if a task is being performed.
-    // ??? ADD STOPPING MECHANISM
-    ALOGV("videoEditor_processClip Entering processing loop");
-    M4OSA_UInt8 prevReportedProgress = 0;
-    while((result == M4NO_ERROR)
-        &&(pContext->state!=ManualEditState_SAVED)
-        &&(pContext->state!=ManualEditState_STOPPING)) {
-
-            // Perform the next processing step.
-            //ALOGV("LVME_processClip Entering M4xVSS_Step()");
-            result = M4xVSS_Step(pContext->engineContext, &progress);
-
-            if (progress != prevReportedProgress) {
-                prevReportedProgress = progress;
-                // Log the 1 % .. 100 % progress after processing.
-                if (M4OSA_TRUE ==
-                    pContext->pEditSettings->pClipList[0]->xVSS.isPanZoom) {
-                    // For KenBurn clip generation, return 0 to 50
-                    // for Analysis phase and 50 to 100 for Saving phase
-                    progress = progressBase + progress/2;
-                } else {
-                    // For export/transition clips, 0 to 10 for Analysis phase
-                    // and 10 to 100 for Saving phase
-                    if (ManualEditState_INITIALIZED == pContext->state) {
-                        progress = 0.1*progress;
-                    } else {
-                        progress = progressBase + 0.9*progress;
-                    }
-                }
-
-                if (progress > lastProgress)
-                {
-                    // Send a progress notification.
-                    ALOGV("videoEditor_processClip ITEM %d Progress indication %d",
-                        unuseditemID, progress);
-                    pEnv->CallVoidMethod(pContext->engine,
-                        pContext->onProgressUpdateMethodId,
-                        unuseditemID, progress);
-                    lastProgress = progress;
-                }
-            }
-
-            // Check if processing has been completed.
-            if (result == completionResult)
-            {
-                // Set the state to the completions state.
-                pContext->state = completionState;
-                ALOGV("videoEditor_processClip ITEM %d STATE changed to %d",
-                    unuseditemID, pContext->state);
-
-                // Reset progress indication, as we switch to next state
-                lastProgress = 0;
-
-                // Reset error code, as we start a new round of processing
-                result = M4NO_ERROR;
-
-                // Check if we are analyzing input
-                if (pContext->state == ManualEditState_OPENED) {
-                    // File is opened, we must start saving it
-                    ALOGV("videoEditor_processClip Calling M4xVSS_SaveStart()");
-                    result = M4xVSS_SaveStart(pContext->engineContext,
-                        (M4OSA_Char*)pContext->pEditSettings->pOutputFile,
-                        (M4OSA_UInt32)pContext->pEditSettings->uiOutputPathSize);
-                    ALOGV("videoEditor_processClip ITEM %d SaveStart() returned 0x%x",
-                        unuseditemID, (unsigned int) result);
-
-                    // Set the state to saving.
-                    pContext->state  = ManualEditState_SAVING;
-                    completionState  = ManualEditState_SAVED;
-                    completionResult = M4VSS3GPP_WAR_SAVING_DONE;
-                    errorState       = ManualEditState_SAVING_ERROR;
-
-                    // While saving, progress goes from 10 to 100
-                    // except for Kenburn clip which goes from 50 to 100
-                    if (M4OSA_TRUE ==
-                            pContext->pEditSettings->pClipList[0]->xVSS.isPanZoom) {
-                        progressBase = 50;
-                    } else {
-                        progressBase     = 10;
-                    }
-                }
-                // Check if we encoding is ongoing
-                else if (pContext->state == ManualEditState_SAVED) {
-
-                    // Send a progress notification.
-                    progress = 100;
-                    ALOGV("videoEditor_processClip ITEM %d Last progress indication %d",
-                        unuseditemID, progress);
-                    pEnv->CallVoidMethod(pContext->engine,
-                        pContext->onProgressUpdateMethodId,
-                        unuseditemID, progress);
-
-
-                    // Stop the encoding.
-                    ALOGV("videoEditor_processClip Calling M4xVSS_SaveStop()");
-                    result = M4xVSS_SaveStop(pContext->engineContext);
-                    ALOGV("videoEditor_processClip M4xVSS_SaveStop() returned 0x%x", result);
-                }
-                // Other states are unexpected
-                else {
-                    result = M4ERR_STATE;
-                    ALOGE("videoEditor_processClip ITEM %d State ERROR 0x%x",
-                        unuseditemID, (unsigned int) result);
-                }
-            }
-
-            // Check if an error occurred.
-            if (result != M4NO_ERROR)
-            {
-                // Set the state to the error state.
-                pContext->state = errorState;
-
-                // Log the result.
-                ALOGE("videoEditor_processClip ITEM %d Processing ERROR 0x%x",
-                    unuseditemID, (unsigned int) result);
-            }
-    }
-
-    // Return the error result
-    ALOGE("videoEditor_processClip ITEM %d END 0x%x", unuseditemID, (unsigned int) result);
-    return result;
-}
-/*+ PROGRESS CB */
-
-static jint
-videoEditor_generateClip(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jobject                             settings) {
-    bool               loaded   = true;
-    ManualEditContext* pContext = M4OSA_NULL;
-    M4OSA_ERR          result   = M4NO_ERROR;
-
-    ALOGV("videoEditor_generateClip START");
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&loaded, pEnv, thiz);
-
-    Mutex::Autolock autoLock(pContext->mLock);
-
-    // Validate the settings parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(&loaded, pEnv,
-                                                (NULL == settings),
-                                                "settings is null");
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&loaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    // Load the clip settings
-    ALOGV("videoEditor_generateClip Calling videoEditor_loadSettings");
-    videoEditor_loadSettings(pEnv, thiz, settings);
-    ALOGV("videoEditor_generateClip videoEditor_loadSettings returned");
-
-    // Generate the clip
-    ALOGV("videoEditor_generateClip Calling LVME_processClip");
-    result = videoEditor_processClip(pEnv, thiz, 0 /*item id is unused*/);
-    ALOGV("videoEditor_generateClip videoEditor_processClip returned 0x%x", result);
-
-    if (pContext->state != ManualEditState_INITIALIZED) {
-        // Free up memory (whatever the result)
-        videoEditor_unloadSettings(pEnv, thiz);
-    }
-
-    ALOGV("videoEditor_generateClip END 0x%x", (unsigned int) result);
-    return (jint)result;
-}
-
-static void
-videoEditor_loadSettings(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jobject                             settings)
-{
-    bool               needToBeLoaded   = true;
-    ManualEditContext* pContext = M4OSA_NULL;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_loadSettings()");
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded,
-                                                                pEnv, thiz);
-
-    // Validate the settings parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv,
-                                                (NULL == settings),
-                                                "settings is null");
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    // Check if the context is valid (required because the context is dereferenced).
-    if (needToBeLoaded)
-    {
-        // Make sure that we are in a correct state.
-        videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
-                             (pContext->state != ManualEditState_INITIALIZED),
-                             "settings already loaded");
-
-        // Retrieve the edit settings.
-        if(pContext->pEditSettings != M4OSA_NULL) {
-            videoEditClasses_freeEditSettings(&pContext->pEditSettings);
-            pContext->pEditSettings = M4OSA_NULL;
-        }
-        videoEditClasses_getEditSettings(&needToBeLoaded, pEnv, settings,
-            &pContext->pEditSettings,true);
-    }
-
-    // Check if the edit settings could be retrieved.
-    if (needToBeLoaded)
-    {
-        // Log the edit settings.
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "inside load settings");
-        VIDEOEDIT_LOG_EDIT_SETTINGS(pContext->pEditSettings);
-    }
-    ALOGV("videoEditor_loadSettings END");
-}
-
-
-
-static void
-videoEditor_unloadSettings(
-                JNIEnv*                             pEnv,
-                jobject                             thiz)
-{
-    bool               needToBeUnLoaded = true;
-    ManualEditContext* pContext = M4OSA_NULL;
-    M4OSA_ERR          result   = M4NO_ERROR;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_unloadSettings()");
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeUnLoaded, pEnv, thiz);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    // Check if the context is valid (required because the context is dereferenced).
-    if (needToBeUnLoaded)
-    {
-        ALOGV("videoEditor_unloadSettings state %d", pContext->state);
-        // Make sure that we are in a correct state.
-        videoEditJava_checkAndThrowIllegalStateException(&needToBeUnLoaded, pEnv,
-                     ((pContext->state != ManualEditState_ANALYZING      ) &&
-                      (pContext->state != ManualEditState_ANALYZING_ERROR) &&
-                      (pContext->state != ManualEditState_OPENED         ) &&
-                      (pContext->state != ManualEditState_SAVING_ERROR   ) &&
-                      (pContext->state != ManualEditState_SAVED          ) &&
-                      (pContext->state != ManualEditState_STOPPING       ) ),
-                     "videoEditor_unloadSettings no load settings in progress");
-    }
-
-    // Check if we are in a correct state.
-    if (needToBeUnLoaded)
-    {
-        // Check if the thread could be stopped.
-        if (needToBeUnLoaded)
-        {
-            // Close the command.
-            ALOGV("videoEditor_unloadSettings Calling M4xVSS_CloseCommand()");
-            result = M4xVSS_CloseCommand(pContext->engineContext);
-            ALOGV("videoEditor_unloadSettings M4xVSS_CloseCommand() returned 0x%x",
-                (unsigned int)result);
-
-            // Check if the command could be closed.
-            videoEditJava_checkAndThrowRuntimeException(&needToBeUnLoaded, pEnv,
-             (M4NO_ERROR != result), result);
-        }
-
-        // Check if the command could be closed.
-        if (needToBeUnLoaded)
-        {
-            // Free the edit settings.
-            //videoEditClasses_freeEditSettings(&pContext->pEditSettings);
-
-            // Reset the thread result.
-            pContext->threadResult = M4NO_ERROR;
-
-            // Reset the thread progress.
-            pContext->threadProgress = 0;
-
-            // Set the state to initialized.
-            pContext->state = ManualEditState_INITIALIZED;
-        }
-    }
-}
-
-static void
-videoEditor_stopEncoding(
-                JNIEnv*                             pEnv,
-                jobject                             thiz)
-{
-    bool               stopped  = true;
-    ManualEditContext* pContext = M4OSA_NULL;
-    M4OSA_ERR          result   = M4NO_ERROR;
-
-    ALOGV("videoEditor_stopEncoding START");
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&stopped, pEnv, thiz);
-
-    // Change state and get Lock
-    // This will ensure the generateClip function exits
-    pContext->state = ManualEditState_STOPPING;
-    Mutex::Autolock autoLock(pContext->mLock);
-
-    // Make sure that the context was set.
-    videoEditJava_checkAndThrowIllegalStateException(&stopped, pEnv,
-                                             (M4OSA_NULL == pContext),
-                                             "not initialized");
-
-    if (stopped) {
-
-        // Check if the command should be closed.
-        if (pContext->state != ManualEditState_INITIALIZED)
-        {
-            // Close the command.
-            ALOGV("videoEditor_stopEncoding Calling M4xVSS_CloseCommand()");
-            result = M4xVSS_CloseCommand(pContext->engineContext);
-            ALOGV("videoEditor_stopEncoding M4xVSS_CloseCommand() returned 0x%x",
-                (unsigned int)result);
-        }
-
-        // Check if the command could be closed.
-        videoEditJava_checkAndThrowRuntimeException(&stopped, pEnv,
-            (M4NO_ERROR != result), result);
-
-        // Free the edit settings.
-        videoEditClasses_freeEditSettings(&pContext->pEditSettings);
-
-        // Set the state to initialized.
-        pContext->state = ManualEditState_INITIALIZED;
-    }
-
-}
-
-static void
-videoEditor_release(
-                JNIEnv*                             pEnv,
-                jobject                             thiz)
-{
-    bool               released = true;
-    ManualEditContext* pContext = M4OSA_NULL;
-    M4OSA_ERR          result   = M4NO_ERROR;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "videoEditor_release()");
-
-    // Get the context.
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&released, pEnv, thiz);
-
-    // If context is not set, return (we consider release already happened)
-    if (pContext == NULL) {
-        ALOGV("videoEditor_release Nothing to do, context is aleady NULL");
-        return;
-    }
-
-
-    // Check if the context is valid (required because the context is dereferenced).
-    if (released)
-    {
-        if (pContext->state != ManualEditState_INITIALIZED)
-        {
-            // Change state and get Lock
-            // This will ensure the generateClip function exits if it is running
-            pContext->state = ManualEditState_STOPPING;
-            Mutex::Autolock autoLock(pContext->mLock);
-        }
-
-        // Reset the context.
-        videoEditClasses_setContext(&released, pEnv, thiz, (void *)M4OSA_NULL);
-
-        // Check if the command should be closed.
-        if (pContext->state != ManualEditState_INITIALIZED)
-        {
-            // Close the command.
-            ALOGV("videoEditor_release Calling M4xVSS_CloseCommand() state =%d",
-                pContext->state);
-            result = M4xVSS_CloseCommand(pContext->engineContext);
-            ALOGV("videoEditor_release M4xVSS_CloseCommand() returned 0x%x",
-                (unsigned int)result);
-
-            // Check if the command could be closed.
-            videoEditJava_checkAndThrowRuntimeException(&released, pEnv,
-                (M4NO_ERROR != result), result);
-        }
-
-        // Cleanup the engine.
-        ALOGV("videoEditor_release Calling M4xVSS_CleanUp()");
-        result = M4xVSS_CleanUp(pContext->engineContext);
-        ALOGV("videoEditor_release M4xVSS_CleanUp() returned 0x%x", (unsigned int)result);
-
-        // Check if the cleanup succeeded.
-        videoEditJava_checkAndThrowRuntimeException(&released, pEnv,
-            (M4NO_ERROR != result), result);
-
-        // Free the edit settings.
-        videoEditClasses_freeEditSettings(&pContext->pEditSettings);
-        pContext->pEditSettings = M4OSA_NULL;
-
-
-        if(pContext->mPreviewController != M4OSA_NULL)
-        {
-            delete pContext->mPreviewController;
-            pContext->mPreviewController = M4OSA_NULL;
-        }
-
-        // Free the mAudioSettings context.
-        if(pContext->mAudioSettings != M4OSA_NULL)
-        {
-            if (pContext->mAudioSettings->pFile != NULL) {
-                free(pContext->mAudioSettings->pFile);
-                pContext->mAudioSettings->pFile = M4OSA_NULL;
-            }
-            if (pContext->mAudioSettings->pPCMFilePath != NULL) {
-                free(pContext->mAudioSettings->pPCMFilePath);
-                pContext->mAudioSettings->pPCMFilePath = M4OSA_NULL;
-            }
-
-            free(pContext->mAudioSettings);
-            pContext->mAudioSettings = M4OSA_NULL;
-        }
-        // Free video Decoders capabilities
-        if (pContext->decoders != M4OSA_NULL) {
-            VideoDecoder *pDecoder = NULL;
-            VideoComponentCapabilities *pComponents = NULL;
-            int32_t decoderNumber = pContext->decoders->decoderNumber;
-            if (pContext->decoders->decoder != NULL &&
-                decoderNumber > 0) {
-                pDecoder = pContext->decoders->decoder;
-                for (int32_t k = 0; k < decoderNumber; k++) {
-                    // free each component
-                    ALOGV("decoder index :%d",k);
-                    if (pDecoder != NULL &&
-                        pDecoder->component != NULL &&
-                        pDecoder->componentNumber > 0) {
-                        ALOGV("component number %d",pDecoder->componentNumber);
-                        int32_t componentNumber =
-                           pDecoder->componentNumber;
-
-                        pComponents = pDecoder->component;
-                        for (int32_t i = 0; i< componentNumber; i++) {
-                            ALOGV("component index :%d",i);
-                            if (pComponents != NULL &&
-                                pComponents->profileLevel != NULL) {
-                                free(pComponents->profileLevel);
-                                pComponents->profileLevel = NULL;
-                            }
-                            pComponents++;
-                        }
-                        free(pDecoder->component);
-                        pDecoder->component = NULL;
-                    }
-
-                    pDecoder++;
-                }
-                free(pContext->decoders->decoder);
-                pContext->decoders->decoder = NULL;
-            }
-            free(pContext->decoders);
-            pContext->decoders = NULL;
-        }
-
-        videoEditor_freeContext(pEnv, &pContext);
-    }
-}
-
-static int
-videoEditor_registerManualEditMethods(
-                JNIEnv*                             pEnv)
-{
-    int result = -1;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-     "videoEditor_registerManualEditMethods()");
-
-    // Look up the engine class
-    jclass engineClazz = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME);
-
-    // Clear any resulting exceptions.
-    pEnv->ExceptionClear();
-
-    // Check if the engine class was found.
-    if (NULL != engineClazz)
-    {
-        // Register all the methods.
-        if (pEnv->RegisterNatives(engineClazz, gManualEditMethods,
-                sizeof(gManualEditMethods) / sizeof(gManualEditMethods[0])) == JNI_OK)
-        {
-            // Success.
-            result = 0;
-        }
-    }
-
-    // Return the result.
-    return(result);
-}
-
-/*******Audio Graph*******/
-
-static M4OSA_UInt32 getDecibelSound(M4OSA_UInt32 value)
-{
-    int dbSound = 1;
-
-    if (value == 0) return 0;
-
-    if (value > 0x4000 && value <= 0x8000) // 32768
-        dbSound = 90;
-    else if (value > 0x2000 && value <= 0x4000) // 16384
-        dbSound = 84;
-    else if (value > 0x1000 && value <= 0x2000) // 8192
-        dbSound = 78;
-    else if (value > 0x0800 && value <= 0x1000) // 4028
-        dbSound = 72;
-    else if (value > 0x0400 && value <= 0x0800) // 2048
-        dbSound = 66;
-    else if (value > 0x0200 && value <= 0x0400) // 1024
-        dbSound = 60;
-    else if (value > 0x0100 && value <= 0x0200) // 512
-        dbSound = 54;
-    else if (value > 0x0080 && value <= 0x0100) // 256
-        dbSound = 48;
-    else if (value > 0x0040 && value <= 0x0080) // 128
-        dbSound = 42;
-    else if (value > 0x0020 && value <= 0x0040) // 64
-        dbSound = 36;
-    else if (value > 0x0010 && value <= 0x0020) // 32
-        dbSound = 30;
-    else if (value > 0x0008 && value <= 0x0010) //16
-        dbSound = 24;
-    else if (value > 0x0007 && value <= 0x0008) //8
-        dbSound = 24;
-    else if (value > 0x0003 && value <= 0x0007) // 4
-        dbSound = 18;
-    else if (value > 0x0001 && value <= 0x0003) //2
-        dbSound = 12;
-    else if (value > 0x000 && value == 0x0001) // 1
-        dbSound = 6;
-    else
-        dbSound = 0;
-
-    return dbSound;
-}
-
-typedef struct
-{
-    M4OSA_UInt8      *m_dataAddress;
-    M4OSA_UInt32    m_bufferSize;
-} M4AM_Buffer;
-
-
-M4OSA_UInt8 logLookUp[256] = {
-0,120,137,146,154,159,163,167,171,173,176,178,181,182,184,186,188,189,190,192,193,
-194,195,196,198,199,199,200,201,202,203,204,205,205,206,207,207,208,209,209,210,
-211,211,212,212,213,213,214,215,215,216,216,216,217,217,218,218,219,219,220,220,
-220,221,221,222,222,222,223,223,223,224,224,224,225,225,225,226,226,226,227,227,
-227,228,228,228,229,229,229,229,230,230,230,230,231,231,231,232,232,232,232,233,
-233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236,236,237,237,237,
-237,237,238,238,238,238,238,239,239,239,239,239,240,240,240,240,240,240,241,241,
-241,241,241,241,242,242,242,242,242,242,243,243,243,243,243,243,244,244,244,244,
-244,244,245,245,245,245,245,245,245,246,246,246,246,246,246,246,247,247,247,247,
-247,247,247,247,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,250,
-250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,252,252,252,252,
-252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,
-254,254,254,254,255,255,255,255,255,255,255,255,255,255,255};
-
-M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL,
-                     M4OSA_Char* pOutFileURL,
-                     M4OSA_UInt32 samplesPerValue,
-                     M4OSA_UInt32 channels,
-                     M4OSA_UInt32 frameDuration,
-                     ManualEditContext* pContext)
-{
-    M4OSA_ERR           err;
-    M4OSA_Context       outFileHandle = M4OSA_NULL;
-    M4OSA_Context       inputFileHandle = M4OSA_NULL;
-    M4AM_Buffer         bufferIn = {0, 0};
-    M4OSA_UInt32        peakVolumeDbValue = 0;
-    M4OSA_UInt32        samplesCountInBytes= 0 , numBytesToRead = 0, index = 0;
-    M4OSA_UInt32        writeCount = 0, samplesCountBigEndian = 0, volumeValuesCount = 0;
-    M4OSA_Int32         seekPos = 0;
-    M4OSA_UInt32        fileSize = 0;
-    M4OSA_UInt32        totalBytesRead = 0;
-    M4OSA_UInt32        prevProgress = 0;
-    bool                threadStarted = true;
-
-    int dbValue = 0;
-    M4OSA_Int16 *ptr16 ;
-
-    jclass engineClass = pEnv->FindClass(MANUAL_EDIT_ENGINE_CLASS_NAME);
-    videoEditJava_checkAndThrowIllegalStateException(&threadStarted, pEnv,
-                                             (M4OSA_NULL == engineClass),
-                                             "not initialized");
-
-    /* register the call back function pointer */
-    pContext->onAudioGraphProgressUpdateMethodId =
-            pEnv->GetMethodID(engineClass, "onAudioGraphExtractProgressUpdate", "(IZ)V");
-
-
-    /* ENTER */
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "ENTER - M4MA_generateAudioGraphFile");
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "Audio Graph samplesPerValue %d channels %d", samplesPerValue, channels);
-
-    /******************************************************************************
-        OPEN INPUT AND OUTPUT FILES
-    *******************************************************************************/
-    err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead);
-    if (inputFileHandle == M4OSA_NULL) {
-        VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "M4MA_generateAudioGraphFile: Cannot open input file 0x%" PRIx32, err);
-        return err;
-    }
-
-    /* get the file size for progress */
-    err = M4OSA_fileReadGetOption(inputFileHandle, M4OSA_kFileReadGetFileSize,
-                                (M4OSA_Void**)&fileSize);
-    if ( err != M4NO_ERROR) {
-        //LVMEL_LOG_ERROR("M4MA_generateAudioGraphFile : File write failed \n");
-        jniThrowException(pEnv, "java/lang/IOException", "file size get option failed");
-        //return -1;
-    }
-
-    err = M4OSA_fileWriteOpen (&outFileHandle,(M4OSA_Char*) pOutFileURL,
-        M4OSA_kFileCreate | M4OSA_kFileWrite);
-    if (outFileHandle == M4OSA_NULL) {
-        if (inputFileHandle != NULL)
-        {
-            M4OSA_fileReadClose(inputFileHandle);
-        }
-        return err;
-    }
-
-    /******************************************************************************
-        PROCESS THE SAMPLES
-    *******************************************************************************/
-    samplesCountInBytes = (samplesPerValue * sizeof(M4OSA_UInt16) * channels);
-
-    bufferIn.m_dataAddress = (M4OSA_UInt8*)M4OSA_32bitAlignedMalloc(samplesCountInBytes*sizeof(M4OSA_UInt16), 0,
-    (M4OSA_Char*)"AudioGraph" );
-    if ( bufferIn.m_dataAddress != M4OSA_NULL) {
-        bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16);
-    } else {
-        VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%" PRIx32,
-            M4ERR_ALLOC);
-        return M4ERR_ALLOC;
-    }
-    /* sample to be converted to BIG endian ; store the frame duration */
-    samplesCountBigEndian = ((frameDuration>>24)&0xff) | // move byte 3 to byte 0
-                    ((frameDuration<<8)&0xff0000) | // move byte 1 to byte 2
-                    ((frameDuration>>8)&0xff00) | // move byte 2 to byte 1
-                    ((frameDuration<<24)&0xff000000); // byte 0 to byte 3
-
-    /* write the samples per value supplied to out file */
-    err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian,
-        sizeof(M4OSA_UInt32) );
-    if (err != M4NO_ERROR) {
-        jniThrowException(pEnv, "java/lang/IOException", "file write failed");
-    }
-
-
-    /* write UIn32 value 0 for no of values as place holder */
-    samplesCountBigEndian = 0; /* reusing local var */
-    err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&samplesCountBigEndian,
-        sizeof(M4OSA_UInt32) );
-    if (err != M4NO_ERROR) {
-        jniThrowException(pEnv, "java/lang/IOException", "file write failed");
-    }
-
-    /* loop until EOF */
-    do
-    {
-        memset((void *)bufferIn.m_dataAddress,0,bufferIn.m_bufferSize);
-
-        numBytesToRead = samplesCountInBytes;
-
-        err =  M4OSA_fileReadData(  inputFileHandle,
-                                    (M4OSA_MemAddr8)bufferIn.m_dataAddress,
-                                    &numBytesToRead );
-
-        if (err != M4NO_ERROR) {
-            // if out value of bytes-read is 0, break
-            if ( numBytesToRead == 0) {
-                VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%" PRIx32,
-                numBytesToRead);
-                break; /* stop if file is empty or EOF */
-            }
-        }
-
-        ptr16 = (M4OSA_Int16*)bufferIn.m_dataAddress;
-
-        peakVolumeDbValue = 0;
-        index = 0;
-
-        // loop through half the lenght frame bytes read 'cause its 16 bits samples
-        while (index < (numBytesToRead / 2)) {
-            /* absolute values of 16 bit sample */
-            if (ptr16[index] < 0) {
-                ptr16[index] = -(ptr16[index]);
-            }
-            peakVolumeDbValue = (peakVolumeDbValue > (M4OSA_UInt32)ptr16[index] ?\
-             peakVolumeDbValue : (M4OSA_UInt32)ptr16[index]);
-            index++;
-        }
-
-        // move 7 bits , ignore sign bit
-        dbValue = (peakVolumeDbValue >> 7);
-        dbValue = logLookUp[(M4OSA_UInt8)dbValue];
-
-        err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&dbValue, sizeof(M4OSA_UInt8) );
-        if (err != M4NO_ERROR) {
-            VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-             "M4MA_generateAudioGraphFile : File write failed");
-            break;
-        }
-
-        volumeValuesCount ++;
-        totalBytesRead += numBytesToRead;
-
-        if ((((totalBytesRead*100)/fileSize)) != prevProgress) {
-            if ( (pContext->threadProgress != prevProgress) && (prevProgress != 0 )) {
-                //pContext->threadProgress = prevProgress;
-                //onWveformProgressUpdateMethodId(prevProgress, 0);
-                //LVME_callAudioGraphOnProgressUpdate(pContext, 0, prevProgress);
-            pEnv->CallVoidMethod(pContext->engine,
-                                 pContext->onAudioGraphProgressUpdateMethodId,
-                                 prevProgress, 0);
-            VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "pContext->threadProgress %d",
-                             prevProgress);
-            }
-        }
-        prevProgress = (((totalBytesRead*100)/fileSize));
-
-    } while (numBytesToRead != 0);
-
-    VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%" PRIx32, volumeValuesCount);
-
-    /* if some error occured in fwrite */
-    if (numBytesToRead != 0) {
-        //err = -1;
-        jniThrowException(pEnv, "java/lang/IOException", "numBytesToRead != 0 ; file write failed");
-    }
-
-    /* write the count in place holder after seek */
-    seekPos = sizeof(M4OSA_UInt32);
-    err = M4OSA_fileWriteSeek(outFileHandle, M4OSA_kFileSeekBeginning,
-            &seekPos /* after samples per value */);
-    if ( err != M4NO_ERROR) {
-        jniThrowException(pEnv, "java/lang/IOException", "file seek failed");
-    } else {
-        volumeValuesCount = ((volumeValuesCount>>24)&0xff) | // move byte 3 to byte 0
-                    ((volumeValuesCount<<8)&0xff0000) | // move byte 1 to byte 2
-                    ((volumeValuesCount>>8)&0xff00) |  // move byte 2 to byte 1
-                    ((volumeValuesCount<<24)&0xff000000); // byte 0 to byte 3
-
-        err = M4OSA_fileWriteData (outFileHandle, (M4OSA_MemAddr8)&volumeValuesCount,
-                                    sizeof(M4OSA_UInt32) );
-        if ( err != M4NO_ERROR) {
-            jniThrowException(pEnv, "java/lang/IOException", "file write failed");
-        }
-    }
-
-    /******************************************************************************
-    CLOSE AND FREE ALLOCATIONS
-    *******************************************************************************/
-    free(bufferIn.m_dataAddress);
-    M4OSA_fileReadClose(inputFileHandle);
-    M4OSA_fileWriteClose(outFileHandle);
-    /* final finish callback */
-    pEnv->CallVoidMethod(pContext->engine, pContext->onAudioGraphProgressUpdateMethodId, 100, 0);
-
-    /* EXIT */
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR", "EXIT - M4MA_generateAudioGraphFile");
-
-    return err;
-}
-
-static jint videoEditor_generateAudioWaveFormSync (JNIEnv*  pEnv, jobject thiz,
-                                                  jstring pcmfilePath,
-                                                  jstring outGraphfilePath,
-                                                  jint frameDuration, jint channels,
-                                                  jint samplesCount)
-{
-    M4OSA_ERR result = M4NO_ERROR;
-    ManualEditContext* pContext = M4OSA_NULL;
-    bool needToBeLoaded = true;
-    const char *pPCMFilePath, *pStringOutAudioGraphFile;
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-        "videoEditor_generateAudioWaveFormSync() ");
-
-    /* Get the context. */
-    pContext = (ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
-    if (pContext == M4OSA_NULL) {
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "videoEditor_generateAudioWaveFormSync() - pContext is NULL ");
-    }
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-        "videoEditor_generateAudioWaveFormSync Retrieving pStringOutAudioGraphFile");
-
-    pPCMFilePath = pEnv->GetStringUTFChars(pcmfilePath, NULL);
-    if (pPCMFilePath == M4OSA_NULL) {
-        jniThrowException(pEnv, "java/lang/RuntimeException",
-            "Input string PCMFilePath is null");
-        result = M4ERR_PARAMETER;
-        goto out;
-    }
-
-    pStringOutAudioGraphFile = pEnv->GetStringUTFChars(outGraphfilePath, NULL);
-    if (pStringOutAudioGraphFile == M4OSA_NULL) {
-        jniThrowException(pEnv, "java/lang/RuntimeException",
-            "Input string outGraphfilePath is null");
-        result = M4ERR_PARAMETER;
-        goto out2;
-    }
-
-    VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-        "videoEditor_generateAudioWaveFormSync Generate the waveform data %s %d %d %d",
-        pStringOutAudioGraphFile, frameDuration, channels, samplesCount);
-
-    /* Generate the waveform */
-    result = M4MA_generateAudioGraphFile(pEnv, (M4OSA_Char*) pPCMFilePath,
-        (M4OSA_Char*) pStringOutAudioGraphFile,
-        (M4OSA_UInt32) samplesCount,
-        (M4OSA_UInt32) channels,
-        (M4OSA_UInt32)frameDuration,
-        pContext);
-
-    pEnv->ReleaseStringUTFChars(outGraphfilePath, pStringOutAudioGraphFile);
-
-out2:
-    if (pPCMFilePath != NULL) {
-        pEnv->ReleaseStringUTFChars(pcmfilePath, pPCMFilePath);
-    }
-
-out:
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-        "videoEditor_generateAudioWaveFormSync pContext->bSkipState ");
-
-    return (jint)result;
-}
-
-/******** End Audio Graph *******/
-jint JNI_OnLoad(
-                JavaVM*                             pVm,
-                void*                               pReserved)
-{
-    void* pEnv         = NULL;
-    bool  needToBeInitialized = true;
-    jint  result      = -1;
-
-    VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", "JNI_OnLoad()");
-
-    // Check the JNI version.
-    if (pVm->GetEnv(&pEnv, JNI_VERSION_1_4) == JNI_OK)
-    {
-        // Register the manual edit JNI methods.
-        if (videoEditor_registerManualEditMethods((JNIEnv*)pEnv) == 0)
-        {
-            // Initialize the classes.
-            videoEditClasses_init(&needToBeInitialized, (JNIEnv*)pEnv);
-            if (needToBeInitialized)
-            {
-                // Success, return valid version number.
-                result = JNI_VERSION_1_4;
-            }
-        }
-    }
-
-    // Return the result.
-    return(result);
-}
-
diff --git a/media/jni/mediaeditor/VideoEditorOsal.cpp b/media/jni/mediaeditor/VideoEditorOsal.cpp
deleted file mode 100644
index c12b1f5..0000000
--- a/media/jni/mediaeditor/VideoEditorOsal.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VideoEditorOsal"
-
-#include <VideoEditorJava.h>
-#include <VideoEditorLogging.h>
-#include <VideoEditorOsal.h>
-
-extern "C" {
-#include <M4OSA_Clock.h>
-#include <M4OSA_CharStar.h>
-#include <M4OSA_FileCommon.h>
-#include <M4OSA_FileReader.h>
-#include <M4OSA_FileWriter.h>
-#include <M4OSA_Memory.h>
-#include <M4OSA_Thread.h>
-#include <M4xVSS_API.h>
-#include <M4VSS3GPP_ErrorCodes.h>
-#include <M4MCS_ErrorCodes.h>
-#include <M4READER_Common.h>
-#include <M4WRITER_common.h>
-#include <M4VSS3GPP_API.h>
-#include <M4DECODER_Common.h>
-};
-
-
-#define VIDEOEDIT_OSAL_RESULT_STRING_MAX     (32)
-
-#define VIDEOEDIT_OSAL_RESULT_INIT(m_result) { m_result, #m_result }
-
-
-typedef struct
-{
-    M4OSA_ERR   result;
-    const char* pName;
-} VideoEdit_Osal_Result;
-
-static const VideoEdit_Osal_Result gkRESULTS[] =
-{
-    // M4OSA_Clock.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_TIMESCALE_TOO_BIG                                ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_CLOCK_BAD_REF_YEAR                               ),
-
-    // M4OSA_Error.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4NO_ERROR                                             ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_PARAMETER                                        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_STATE                                            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_ALLOC                                            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_BAD_CONTEXT                                      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_CONTEXT_FAILED                                   ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_BAD_STREAM_ID                                    ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_BAD_OPTION_ID                                    ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_WRITE_ONLY                                       ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_READ_ONLY                                        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_NOT_IMPLEMENTED                                  ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_UNSUPPORTED_MEDIA_TYPE                           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_NO_DATA_YET                                      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_NO_MORE_STREAM                                   ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_INVALID_TIME                                     ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_NO_MORE_AU                                       ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_TIME_OUT                                         ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_BUFFER_FULL                                      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_REDIRECT                                         ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_TOO_MUCH_STREAMS                                 ),
-
-    // M4OSA_FileCommon.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_FILE_NOT_FOUND                                   ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_FILE_LOCKED                                      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_FILE_BAD_MODE_ACCESS                             ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_FILE_INVALID_POSITION                            ),
-
-    // M4OSA_Thread.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_THREAD_NOT_STARTED                               ),
-
-    // M4xVSS_API.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_ANALYZING_DONE                           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_PREVIEW_READY                            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_SAVING_DONE                              ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_TRANSCODING_NECESSARY                    ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_OUTPUTFILESIZE_EXCEED                    ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_JPG_TOO_BIG                              ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4xVSSWAR_BUFFER_OUT_TOO_SMALL                         ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4xVSSERR_NO_MORE_SPACE                                ),
-
-    // M4VSS3GPP_ErrorCodes.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_FILE_TYPE                        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_EFFECT_KIND                      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_VIDEO_EFFECT_TYPE                ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_AUDIO_EFFECT_TYPE                ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_VIDEO_TRANSITION_TYPE            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_AUDIO_TRANSITION_TYPE            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_VIDEO_ENCODING_FRAME_RATE        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EXTERNAL_EFFECT_NULL                     ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EXTERNAL_TRANSITION_NULL                 ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_DURATION           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_BEGIN_CUT_LARGER_THAN_END_CUT            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_OVERLAPPING_TRANSITIONS                  ),
-#ifdef M4VSS3GPP_ERR_ANALYSIS_DATA_SIZE_TOO_SMALL
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ANALYSIS_DATA_SIZE_TOO_SMALL             ),
-#endif
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_3GPP_FILE                        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNSUPPORTED_INPUT_VIDEO_FORMAT           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNSUPPORTED_INPUT_AUDIO_FORMAT           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AMR_EDITING_UNSUPPORTED                  ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_VIDEO_AU_TOO_LARGE                 ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_AUDIO_AU_TOO_LARGE                 ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AU                 ),
-#ifdef M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_AUDIO_CORRUPTED_AMR_AU             ),
-#endif
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ENCODER_ACCES_UNIT_ERROR                 ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_VIDEO_FORMAT         ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_H263_PROFILE         ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_PROFILE        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_MPEG4_RVLC           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_UNSUPPORTED_AUDIO_FORMAT         ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_STREAM_IN_FILE      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_EDITING_NO_SUPPORTED_VIDEO_STREAM_IN_FILE),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_VERSION            ),
-#ifdef M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_PLATFORM
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INVALID_CLIP_ANALYSIS_PLATFORM           ),
-#endif
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FORMAT                ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_FRAME_SIZE            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_TIME_SCALE            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INCOMPATIBLE_VIDEO_DATA_PARTITIONING     ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNSUPPORTED_MP3_ASSEMBLY                 ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_STREAM_TYPE           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_NB_OF_CHANNELS        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_WAR_INCOMPATIBLE_AUDIO_SAMPLING_FREQUENCY    ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_NO_SUPPORTED_STREAM_IN_FILE              ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ADDVOLUME_EQUALS_ZERO                    ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ADDCTS_HIGHER_THAN_VIDEO_DURATION        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNDEFINED_AUDIO_TRACK_FILE_FORMAT        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_UNSUPPORTED_ADDED_AUDIO_STREAM           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_MIXING_UNSUPPORTED                 ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AUDIO_TRACK     ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_CANNOT_BE_MIXED                    ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INPUT_CLIP_IS_NOT_A_3GPP                 ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_BEGINLOOP_HIGHER_ENDLOOP                 ),
-#ifdef M4VSS3GPP_ERR_AUDIO_MIXING_MP3_UNSUPPORTED
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_MIXING_MP3_UNSUPPORTED             ),
-#endif
-#ifdef M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AAC
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_AAC             ),
-#endif
-#ifdef M4VSS3GPP_ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_ONLY_AMRNB_INPUT_CAN_BE_MIXED            ),
-#endif
-#ifdef M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_EVRC
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_FEATURE_UNSUPPORTED_WITH_EVRC            ),
-#endif
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_H263_PROFILE_NOT_SUPPORTED               ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_NO_SUPPORTED_VIDEO_STREAM_IN_FILE        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_INTERNAL_STATE                           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_LUMA_FILTER_ERROR                        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_TRANSITION_FILTER_ERROR                  ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_DECODER_INIT_FAILED                ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_AUDIO_DECODED_PCM_SIZE_ISSUE             ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4VSS3GPP_ERR_OUTPUT_FILE_TYPE_ERROR                   ),
-
-    // M4MCS_ErrorCodes.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_WAR_TRANSCODING_DONE                             ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_WAR_MEDIATYPE_NOT_SUPPORTED                      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INPUT_FILE_CONTAINS_NO_SUPPORTED_STREAM      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INVALID_INPUT_FILE                           ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FORMAT                ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_SIZE            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_UNDEFINED_OUTPUT_VIDEO_FRAME_RATE            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_UNDEFINED_OUTPUT_AUDIO_FORMAT                ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INVALID_VIDEO_FRAME_SIZE_FOR_H263            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INVALID_VIDEO_FRAME_RATE_FOR_H263            ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_DURATION_IS_NULL                             ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_H263_FORBIDDEN_IN_MP4_FILE                   ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_H263_PROFILE_NOT_SUPPORTED                   ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_INVALID_AAC_SAMPLING_FREQUENCY               ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_AUDIO_CONVERSION_FAILED                      ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_BEGIN_CUT_LARGER_THAN_DURATION               ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_BEGIN_CUT_EQUALS_END_CUT                     ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_END_CUT_SMALLER_THAN_BEGIN_CUT               ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_MAXFILESIZE_TOO_SMALL                        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_VIDEOBITRATE_TOO_LOW                         ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_AUDIOBITRATE_TOO_LOW                         ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_VIDEOBITRATE_TOO_HIGH                        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_AUDIOBITRATE_TOO_HIGH                        ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_OUTPUT_FILE_SIZE_TOO_SMALL                   ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_NOMORE_SPACE                                 ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4MCS_ERR_FILE_DRM_PROTECTED                           ),
-
-    // M4READER_Common.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_READER_UNKNOWN_STREAM_TYPE                       ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_READER_NO_METADATA                               ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_READER_INFORMATION_NOT_PRESENT                   ),
-
-    // M4WRITER_Common.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_WRITER_STOP_REQ                                  ),
-    // M4DECODER_Common.h
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_VIDEORENDERER_NO_NEW_FRAME                       ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4WAR_DEBLOCKING_FILTER_NOT_IMPLEMENTED                ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_DECODER_H263_PROFILE_NOT_SUPPORTED               ),
-    VIDEOEDIT_OSAL_RESULT_INIT(M4ERR_DECODER_H263_NOT_BASELINE                        )
-};
-
-static const int gkRESULTS_COUNT = (sizeof(gkRESULTS) / sizeof(VideoEdit_Osal_Result));
-
-#ifdef OSAL_MEM_LEAK_DEBUG
-static int gAllocatedBlockCount = 0;
-#endif
-
-const char*
-videoEditOsal_getResultString(
-                M4OSA_ERR                           result)
-{
-    static char string[VIDEOEDIT_OSAL_RESULT_STRING_MAX] = "";
-    const char* pString                         = M4OSA_NULL;
-    int         index                           = 0;
-
-    // Loop over the list with constants.
-    for (index = 0;
-         ((M4OSA_NULL == pString) && (index < gkRESULTS_COUNT));
-         index++)
-    {
-        // Check if the specified result matches.
-        if (result == gkRESULTS[index].result)
-        {
-            // Set the description.
-            pString = gkRESULTS[index].pName;
-        }
-    }
-
-    // Check if no result was found.
-    if (M4OSA_NULL == pString)
-    {
-        // Set the description to a default value.
-        M4OSA_chrSPrintf((M4OSA_Char *)string, sizeof(string) - 1,
-         (M4OSA_Char*)"<unknown(0x%08X)>", result);
-        pString = string;
-    }
-
-    // Return the result.
-    return(pString);
-}
-
-void *
-videoEditOsal_alloc(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                size_t                              size,
-                const char*                         pDescription)
-{
-    void *pData = M4OSA_NULL;
-
-    // Check if the previous action succeeded.
-    if (*pResult)
-    {
-        // Allocate memory for the settings.
-        pData = (M4VSS3GPP_EditSettings*)M4OSA_32bitAlignedMalloc(size, 0, (M4OSA_Char*)pDescription);
-        if (M4OSA_NULL != pData)
-        {
-            // Reset the allocated memory.
-            memset((void *)pData, 0,size);
-#ifdef OSAL_MEM_LEAK_DEBUG
-            // Update the allocated block count.
-            gAllocatedBlockCount++;
-#endif
-        }
-        else
-        {
-            // Reset the result flag.
-            (*pResult) = false;
-
-            // Log the error.
-            VIDEOEDIT_LOG_ERROR(ANDROID_LOG_ERROR, "VIDEO_EDITOR_OSAL", "videoEditOsal_alloc,\
-             error: unable to allocate memory for %s", pDescription);
-
-            // Throw an exception.
-            jniThrowException(pEnv, "java/lang/OutOfMemoryError", "unable to allocate memory");
-        }
-    }
-
-    // Return the allocated memory.
-    return(pData);
-}
-
-void
-videoEditOsal_free(
-                void*                               pData)
-{
-    // Check if memory was allocated.
-    if (M4OSA_NULL != pData)
-    {
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_OSAL", "videoEditOsal_free()");
-
-        // Log the API call.
-        VIDEOEDIT_LOG_API(ANDROID_LOG_INFO, "VIDEO_EDITOR_OSAL", "free");
-
-        // Free the memory.
-        free(pData);
-#ifdef OSAL_MEM_LEAK_DEBUG
-        // Update the allocated block count.
-        gAllocatedBlockCount--;
-
-        // Log the number of allocated blocks.
-        VIDEOEDIT_LOG_ALLOCATION(ANDROID_LOG_ERROR, "VIDEO_EDITOR_OSAL", "allocated, %d blocks",\
-         gAllocatedBlockCount);
-#endif
-    }
-}
-
-
-void
-videoEditOsal_getFilePointers ( M4OSA_FileReadPointer *pOsaFileReadPtr,
-                                M4OSA_FileWriterPointer *pOsaFileWritePtr)
-{
-    if (pOsaFileReadPtr != M4OSA_NULL)
-    {
-        // Initialize the filereader function pointers.
-        pOsaFileReadPtr->openRead  = M4OSA_fileReadOpen;
-        pOsaFileReadPtr->readData  = M4OSA_fileReadData;
-        pOsaFileReadPtr->seek      = M4OSA_fileReadSeek;
-        pOsaFileReadPtr->closeRead = M4OSA_fileReadClose;
-        pOsaFileReadPtr->setOption = M4OSA_fileReadSetOption;
-        pOsaFileReadPtr->getOption = M4OSA_fileReadGetOption;
-    }
-
-    if (pOsaFileWritePtr != M4OSA_NULL)
-    {
-        // Initialize the filewriter function pointers.
-        pOsaFileWritePtr->openWrite  = M4OSA_fileWriteOpen;
-        pOsaFileWritePtr->writeData  = M4OSA_fileWriteData;
-        pOsaFileWritePtr->seek       = M4OSA_fileWriteSeek;
-        pOsaFileWritePtr->Flush      = M4OSA_fileWriteFlush;
-        pOsaFileWritePtr->closeWrite = M4OSA_fileWriteClose;
-        pOsaFileWritePtr->setOption  = M4OSA_fileWriteSetOption;
-        pOsaFileWritePtr->getOption  = M4OSA_fileWriteGetOption;
-    }
-}
-
diff --git a/media/jni/mediaeditor/VideoEditorOsal.h b/media/jni/mediaeditor/VideoEditorOsal.h
deleted file mode 100644
index 7a6f5ea..0000000
--- a/media/jni/mediaeditor/VideoEditorOsal.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VIDEO_EDITOR_OSAL_H
-#define VIDEO_EDITOR_OSAL_H
-
-#include <jni.h>
-#include <JNIHelp.h>
-
-extern "C" {
-#include <M4OSA_Error.h>
-#include <M4OSA_Thread.h>
-#include <M4OSA_FileReader.h>
-#include <M4OSA_FileWriter.h>
-};
-
-const char*
-videoEditOsal_getResultString(
-                M4OSA_ERR                           result);
-
-void*
-videoEditOsal_alloc(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                size_t                              size,
-                const char*                         pDescription);
-
-void
-videoEditOsal_free(
-                void*                               pData);
-
-void
-videoEditOsal_startThread(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                int                                 stackSize,
-                M4OSA_ThreadDoIt                    callback,
-                M4OSA_Context*                      pContext,
-                void*                               pParam);
-
-void
-videoEditOsal_stopThread(
-                bool*                               pResult,
-                JNIEnv*                             pEnv,
-                M4OSA_Context*                      pContext);
-
-void
-videoEditOsal_getFilePointers ( M4OSA_FileReadPointer *pOsaFileReadPtr,
-                                M4OSA_FileWriterPointer *pOsaFileWritePtr);
-
-#endif // VIDEO_EDITOR_OSAL_H
-
diff --git a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
deleted file mode 100644
index ae1a80e..0000000
--- a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VideoEditorPropertiesMain"
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <VideoEditorClasses.h>
-#include <VideoEditorJava.h>
-#include <VideoEditorOsal.h>
-#include <VideoEditorLogging.h>
-#include <VideoEditorOsal.h>
-
-extern "C" {
-#include <M4OSA_Clock.h>
-#include <M4OSA_CharStar.h>
-#include <M4OSA_Error.h>
-#include <M4OSA_FileCommon.h>
-#include <M4OSA_FileReader.h>
-#include <M4OSA_FileWriter.h>
-#include <M4OSA_Memory.h>
-#include <M4OSA_Thread.h>
-#include <M4VSS3GPP_API.h>
-#include <M4VSS3GPP_ErrorCodes.h>
-#include <M4MCS_API.h>
-#include <M4MCS_ErrorCodes.h>
-#include <M4READER_Common.h>
-#include <M4WRITER_common.h>
-#include <M4DECODER_Common.h>
-#include <M4AD_Common.h>
-};
-
-extern "C" M4OSA_ERR M4MCS_open_normalMode(
-                M4MCS_Context                       pContext,
-                M4OSA_Void*                         pFileIn,
-                M4VIDEOEDITING_FileType             InputFileType,
-                M4OSA_Void*                         pFileOut,
-                M4OSA_Void*                         pTempFile);
-
-jobject videoEditProp_getProperties(
-                JNIEnv*                             pEnv,
-                jobject                             thiz,
-                jstring                             file);
-
-static void
-getFileAndMediaTypeFromExtension (
-                M4OSA_Char* pExtension,
-                VideoEditClasses_FileType   *pFileType,
-                M4VIDEOEDITING_FileType       *pClipType);
-
-static M4OSA_ERR
-getClipProperties(  JNIEnv*                         pEnv,
-                    jobject                         thiz,
-                    M4OSA_Char*                     pFile,
-                    M4VIDEOEDITING_FileType         clipType,
-                    M4VIDEOEDITING_ClipProperties*  pClipProperties);
-
-M4OSA_UInt32
-VideoEdit_chrCompare(M4OSA_Char* pStrIn1,
-                     M4OSA_Char* pStrIn2,
-                     M4OSA_Int32* pCmpResult);
-
-jobject videoEditProp_getProperties(
-        JNIEnv* pEnv,
-        jobject thiz,
-        jstring file)
-{
-    bool                           gotten          = true;
-    M4OSA_Char*                    pFile           = M4OSA_NULL;
-    M4OSA_Char*                    pExtension      = M4OSA_NULL;
-    M4OSA_UInt32                   index           = 0;
-    M4OSA_Int32                    cmpResult       = 0;
-    VideoEditPropClass_Properties* pProperties     = M4OSA_NULL;
-    M4VIDEOEDITING_ClipProperties* pClipProperties = M4OSA_NULL;
-    M4OSA_ERR                      result          = M4NO_ERROR;
-    M4MCS_Context                  context         = M4OSA_NULL;
-    M4OSA_FilePosition             size            = 0;
-    M4OSA_UInt32                   width           = 0;
-    M4OSA_UInt32                   height          = 0;
-    jobject                        properties      = NULL;
-    M4OSA_Context                  pOMXContext     = M4OSA_NULL;
-    M4DECODER_VideoInterface*      pOMXVidDecoderInterface = M4OSA_NULL;
-    M4AD_Interface*                pOMXAudDecoderInterface = M4OSA_NULL;
-
-    bool  initialized = true;
-    VideoEditClasses_FileType fileType = VideoEditClasses_kFileType_Unsupported;
-    M4VIDEOEDITING_FileType clipType = M4VIDEOEDITING_kFileType_Unsupported;
-
-    VIDEOEDIT_LOG_API(
-            ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
-            "videoEditProp_getProperties()");
-
-    // Initialize the classes.
-    videoEditPropClass_init(&initialized, (JNIEnv*)pEnv);
-
-    // Validate the tempPath parameter.
-    videoEditJava_checkAndThrowIllegalArgumentException(
-            &gotten, pEnv, (NULL == file), "file is null");
-
-    // Get the file path.
-    pFile = (M4OSA_Char *)videoEditJava_getString(
-            &gotten, pEnv, file, NULL, M4OSA_NULL);
-
-    result = M4OSA_fileReadOpen(&context, (M4OSA_Void*)pFile, M4OSA_kFileRead);
-
-    if(M4NO_ERROR != result) {
-        // Free the file path.
-        videoEditOsal_free(pFile);
-        pFile = M4OSA_NULL;
-    }
-
-    videoEditJava_checkAndThrowIllegalArgumentException(&gotten, pEnv,
-        (M4NO_ERROR != result), "file not found");
-
-    // Close the file and free the file context
-    if (context != NULL) {
-        result = M4OSA_fileReadClose(context);
-        context = M4OSA_NULL;
-    }
-
-    // Return if Error
-    if (M4NO_ERROR != result) {
-        return (properties); // NULL
-    }
-
-    // Check if the file path is valid.
-    if (gotten)
-    {
-        // Retrieve the extension.
-        pExtension = (M4OSA_Char *)strrchr((const char *)pFile, (int)'.');
-        if (M4OSA_NULL != pExtension)
-        {
-            // Skip the dot.
-            pExtension++;
-
-            // Get the file type and Media type from extension
-            getFileAndMediaTypeFromExtension(
-                    pExtension ,&fileType, &clipType);
-        }
-    }
-
-    // Check if the file type could be determined.
-    videoEditJava_checkAndThrowIllegalArgumentException(
-            &gotten, pEnv,
-            (VideoEditClasses_kFileType_Unsupported == fileType),
-            "file type is not supported");
-
-    // Allocate a new properties structure.
-    pProperties = (VideoEditPropClass_Properties*)videoEditOsal_alloc(
-            &gotten, pEnv,
-            sizeof(VideoEditPropClass_Properties), "Properties");
-
-    // Check if the context is valid and allocation succeeded
-    // (required because of dereferencing of pProperties).
-    if (gotten)
-    {
-        // Check if this type of file needs to be analyzed using MCS.
-        if ((VideoEditClasses_kFileType_MP3  == fileType) ||
-            (VideoEditClasses_kFileType_MP4  == fileType) ||
-            (VideoEditClasses_kFileType_3GPP == fileType) ||
-            (VideoEditClasses_kFileType_AMR  == fileType) ||
-            (VideoEditClasses_kFileType_PCM  == fileType) ||
-            (VideoEditClasses_kFileType_M4V  == fileType))
-        {
-            // Allocate a new clip properties structure.
-            pClipProperties =
-                (M4VIDEOEDITING_ClipProperties*)videoEditOsal_alloc(
-                    &gotten, pEnv,
-                    sizeof(M4VIDEOEDITING_ClipProperties), "ClipProperties");
-
-            // Check if allocation succeeded (required because of
-            // dereferencing of pClipProperties).
-            if (gotten)
-            {
-                // Log the API call.
-                VIDEOEDIT_LOG_API(
-                        ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
-                        "getClipProperties");
-
-                // Get Video clip properties
-                result = getClipProperties(
-                        pEnv, thiz, pFile, clipType, pClipProperties);
-
-                if (M4MCS_ERR_FILE_DRM_PROTECTED == result) {
-                    // Check if the creation succeeded.
-                    videoEditJava_checkAndThrowIllegalArgumentException(
-                            &gotten, pEnv,(M4NO_ERROR != result),
-                            "Invalid File - DRM Protected ");
-                } else {
-                    // Check if the creation succeeded.
-                    videoEditJava_checkAndThrowIllegalArgumentException(
-                            &gotten, pEnv,(M4NO_ERROR != result),
-                            "Invalid File or File not found ");
-                }
-
-#ifdef USE_SOFTWARE_DECODER
-                /**
-                 * Input clip with non-multiples of 16 is not supported.
-                 */
-                if ( (pClipProperties->uiVideoWidth %16)
-                    || (pClipProperties->uiVideoHeight %16) )
-                {
-                    result = M4MCS_ERR_INPUT_VIDEO_SIZE_NON_X16;
-                    videoEditJava_checkAndThrowIllegalArgumentException(
-                            &gotten, pEnv, (M4NO_ERROR != result),
-                            "non x16 input video frame size is not supported");
-                }
-#endif /* USE_SOFTWARE_DECODER */
-            }
-
-            // Check if the properties could be retrieved.
-            if (gotten)
-            {
-                // Set the properties.
-                pProperties->uiClipDuration = pClipProperties->uiClipDuration;
-                if (M4VIDEOEDITING_kFileType_Unsupported == pClipProperties->FileType)
-                {
-                    pProperties->FileType        = VideoEditClasses_kFileType_Unsupported;
-                }
-                else
-                {
-                    pProperties->FileType        = fileType;
-                }
-                pProperties->VideoStreamType     = pClipProperties->VideoStreamType;
-                pProperties->uiClipVideoDuration = pClipProperties->uiClipVideoDuration;
-                pProperties->uiVideoBitrate      = pClipProperties->uiVideoBitrate;
-                pProperties->uiVideoWidth        = pClipProperties->uiVideoWidth;
-                pProperties->uiVideoHeight       = pClipProperties->uiVideoHeight;
-                pProperties->fAverageFrameRate   = pClipProperties->fAverageFrameRate;
-                pProperties->uiVideoProfile      = pClipProperties->uiVideoProfile;
-                pProperties->uiVideoLevel        = pClipProperties->uiVideoLevel;
-                // Set profile and level support to TRUE, pending check
-                pProperties->bProfileSupported   = M4OSA_TRUE;
-                pProperties->bLevelSupported     = M4OSA_TRUE;
-                pProperties->AudioStreamType     = pClipProperties->AudioStreamType;
-                pProperties->uiClipAudioDuration = pClipProperties->uiClipAudioDuration;
-                pProperties->uiAudioBitrate      = pClipProperties->uiAudioBitrate;
-                pProperties->uiNbChannels        = pClipProperties->uiNbChannels;
-                pProperties->uiSamplingFrequency = pClipProperties->uiSamplingFrequency;
-                pProperties->uiRotation          = pClipProperties->videoRotationDegrees;
-
-            }
-
-            // Free the clip properties.
-            videoEditOsal_free(pClipProperties);
-            pClipProperties = M4OSA_NULL;
-        }
-        else if ((VideoEditClasses_kFileType_JPG == fileType) ||
-            (VideoEditClasses_kFileType_GIF == fileType) ||
-            (VideoEditClasses_kFileType_PNG == fileType))
-        {
-            pProperties->uiClipDuration      = 0;
-            pProperties->FileType            = fileType;
-            pProperties->VideoStreamType     = M4VIDEOEDITING_kNoneVideo;
-            pProperties->uiClipVideoDuration = 0;
-            pProperties->uiVideoBitrate      = 0;
-            pProperties->uiVideoWidth        = width;
-            pProperties->uiVideoHeight       = height;
-            pProperties->fAverageFrameRate   = 0.0f;
-            pProperties->uiVideoProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
-            pProperties->uiVideoLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
-            pProperties->AudioStreamType     = M4VIDEOEDITING_kNoneAudio;
-            pProperties->uiClipAudioDuration = 0;
-            pProperties->uiAudioBitrate      = 0;
-            pProperties->uiNbChannels        = 0;
-            pProperties->uiSamplingFrequency = 0;
-
-            // Added for Handling invalid paths and non existent image files
-            // Open the file for reading.
-            result = M4OSA_fileReadOpen(&context, (M4OSA_Void*)pFile, M4OSA_kFileRead);
-            if (M4NO_ERROR != result)
-            {
-                pProperties->FileType = VideoEditClasses_kFileType_Unsupported;
-            }
-            result = M4OSA_fileReadClose(context);
-            context = M4OSA_NULL;
-        }
-    }
-
-    if (M4NO_ERROR == result) {
-        // Create a properties object.
-        videoEditPropClass_createProperties(&gotten, pEnv, pProperties, &properties);
-
-        // Log the properties.
-        VIDEOEDIT_PROP_LOG_PROPERTIES(pProperties);
-    }
-
-    // Free the properties.
-    videoEditOsal_free(pProperties);
-    pProperties = M4OSA_NULL;
-
-    // Free the file path.
-    videoEditOsal_free(pFile);
-    pFile = M4OSA_NULL;
-
-    // Return the Properties object.
-    return(properties);
-}
-
-static void getFileAndMediaTypeFromExtension (
-        M4OSA_Char *pExtension,
-        VideoEditClasses_FileType *pFileType,
-        M4VIDEOEDITING_FileType *pClipType)
-{
-    M4OSA_Char extension[5] = {0, 0, 0, 0, 0};
-    VideoEditClasses_FileType fileType =
-            VideoEditClasses_kFileType_Unsupported;
-
-    M4VIDEOEDITING_FileType clipType =
-            M4VIDEOEDITING_kFileType_Unsupported;
-
-    M4OSA_UInt32 index = 0;
-    M4OSA_ERR result = M4NO_ERROR;
-    M4OSA_Int32 cmpResult = 0;
-    M4OSA_UInt32  extLength = strlen((const char *)pExtension);
-
-    // Assign default
-    *pFileType = VideoEditClasses_kFileType_Unsupported;
-    *pClipType = M4VIDEOEDITING_kFileType_Unsupported;
-
-    // Check if the length of the extension is valid.
-    if ((3 == extLength) || (4 == extLength))
-    {
-        // Convert the extension to lowercase.
-        for (index = 0; index < extLength ; index++)
-        {
-            extension[index] = tolower((int)pExtension[index]);
-        }
-
-        // Check if the extension is ".mp3".
-        if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"mp3", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_MP3;
-            *pClipType = M4VIDEOEDITING_kFileType_MP3;
-        }
-        // Check if the extension is ".mp4".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"mp4", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_MP4;
-            *pClipType = M4VIDEOEDITING_kFileType_MP4;
-        }
-        // Check if the extension is ".3gp".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"3gp", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_3GPP;
-            *pClipType = M4VIDEOEDITING_kFileType_3GPP;
-        }
-        // Check if the extension is ".m4a".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"m4a", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_3GPP;
-            *pClipType = M4VIDEOEDITING_kFileType_3GPP;
-        }
-        // Check if the extension is ".3gpp".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"3gpp", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_3GPP;
-            *pClipType = M4VIDEOEDITING_kFileType_3GPP;
-        }
-        // Check if the extension is ".amr".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"amr", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_AMR;
-            *pClipType = M4VIDEOEDITING_kFileType_AMR;
-        }
-        // Check if the extension is ".pcm".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"pcm", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_PCM;
-            *pClipType = M4VIDEOEDITING_kFileType_PCM;
-        }
-        // Check if the extension is ".jpg".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"jpg", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_JPG;
-        }
-        // Check if the extension is ".jpeg".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"jpeg", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_JPG;
-        }
-        // Check if the extension is ".gif".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"gif", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_GIF;
-        }
-        // Check if the extension is ".png".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"png", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_PNG;
-        }
-        // Check if the extension is ".m4v".
-        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"m4v", &cmpResult)))
-        {
-            *pFileType = VideoEditClasses_kFileType_M4V;
-            *pClipType = M4VIDEOEDITING_kFileType_M4V;
-        }
-    }
-}
-
-static M4OSA_ERR getClipProperties(
-        JNIEnv* pEnv,
-        jobject thiz,
-        M4OSA_Char* pFile,
-        M4VIDEOEDITING_FileType clipType,
-        M4VIDEOEDITING_ClipProperties* pClipProperties)
-{
-    bool                      gotten          = true;
-    M4OSA_ERR                 result          = M4NO_ERROR;
-    M4OSA_ERR                 resultAbort     = M4NO_ERROR;
-    M4MCS_Context             context         = M4OSA_NULL;
-
-    M4OSA_FileReadPointer fileReadPtr =
-            { M4OSA_NULL, M4OSA_NULL, M4OSA_NULL,
-              M4OSA_NULL, M4OSA_NULL, M4OSA_NULL };
-
-    M4OSA_FileWriterPointer fileWritePtr =
-            { M4OSA_NULL, M4OSA_NULL, M4OSA_NULL,
-              M4OSA_NULL, M4OSA_NULL, M4OSA_NULL, M4OSA_NULL };
-
-    // Initialize the OSAL file system function pointers.
-    videoEditOsal_getFilePointers(&fileReadPtr , &fileWritePtr);
-
-    // Log the API call.
-    VIDEOEDIT_LOG_API(
-            ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",\
-            "getClipProperties - M4MCS_init()");
-
-    // Initialize the MCS context.
-    result = M4MCS_init(&context, &fileReadPtr, &fileWritePtr);
-
-    // Log the result.
-    VIDEOEDIT_PROP_LOG_RESULT(
-            ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s",
-            videoEditOsal_getResultString(result));
-
-    // Check if the creation succeeded.
-    videoEditJava_checkAndThrowRuntimeException(
-            &gotten, pEnv, (M4NO_ERROR != result), result);
-
-    // Check if opening the MCS context succeeded.
-    if (gotten)
-    {
-        // Log the API call.
-        VIDEOEDIT_LOG_API(
-                ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
-                "getClipProperties - M4MCS_open_normalMode()");
-
-        // Open the MCS in the normal opening mode to
-        // retrieve the exact duration
-        result = M4MCS_open_normalMode(
-                context, pFile, clipType, M4OSA_NULL, M4OSA_NULL);
-
-        // Log the result.
-        VIDEOEDIT_PROP_LOG_RESULT(
-                ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s",
-                videoEditOsal_getResultString(result));
-
-        // Check if the creation succeeded.
-        videoEditJava_checkAndThrowRuntimeException(
-                &gotten, pEnv, (M4NO_ERROR != result), result);
-
-        // Check if the MCS could be opened.
-        if (gotten)
-        {
-            // Log the API call.
-            VIDEOEDIT_LOG_API(
-                    ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
-                    "getClipProperties - M4MCS_getInputFileProperties()");
-
-            // Get the properties.
-            result = M4MCS_getInputFileProperties(context, pClipProperties);
-
-            // Log the result.
-            VIDEOEDIT_PROP_LOG_RESULT(
-                    ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s",
-                    videoEditOsal_getResultString(result));
-
-            // Check if the creation succeeded.
-            videoEditJava_checkAndThrowRuntimeException(
-                    &gotten, pEnv, (M4NO_ERROR != result), result);
-        }
-
-        // Log the API call.
-        VIDEOEDIT_LOG_API(
-                ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
-                "getClipProperties - M4MCS_abort()");
-
-        // Close the MCS session.
-        resultAbort = M4MCS_abort(context);
-
-       if (result == M4NO_ERROR) {
-            // Log the result.
-            VIDEOEDIT_PROP_LOG_RESULT(
-                    ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s",
-                    videoEditOsal_getResultString(resultAbort));
-
-            // Check if the abort succeeded.
-            videoEditJava_checkAndThrowRuntimeException(
-                    &gotten, pEnv, (M4NO_ERROR != resultAbort), resultAbort);
-            result = resultAbort;
-        }
-    }
-
-    return result;
-}
-
-M4OSA_UInt32
-VideoEdit_chrCompare(M4OSA_Char* pStrIn1,
-                     M4OSA_Char* pStrIn2,
-                      M4OSA_Int32* pCmpResult)
-{
-    *pCmpResult = strcmp((const char *)pStrIn1, (const char *)pStrIn2);
-    return *pCmpResult;
-}
-
-
diff --git a/media/jni/mediaeditor/VideoEditorThumbnailMain.cpp b/media/jni/mediaeditor/VideoEditorThumbnailMain.cpp
deleted file mode 100644
index 1508246..0000000
--- a/media/jni/mediaeditor/VideoEditorThumbnailMain.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <jni.h>
-#include <JNIHelp.h>
-#include <utils/Log.h>
-#include "VideoBrowserMain.h"
-#include "VideoBrowserInternal.h"
-
-#if (M4OSA_TRACE_LEVEL >= 1)
-#undef M4OSA_TRACE1_0
-#undef M4OSA_TRACE1_1
-#undef M4OSA_TRACE1_2
-#undef M4OSA_TRACE1_3
-
-#define M4OSA_TRACE1_0(a)       __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a);
-#define M4OSA_TRACE1_1(a,b)     __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b);
-#define M4OSA_TRACE1_2(a,b,c)   __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c);
-#define M4OSA_TRACE1_3(a,b,c,d) __android_log_print(ANDROID_LOG_INFO, "Thumbnail", a,b,c,d);
-#endif
-
-/*
- * Memory format of 'ARGB8888' in skia is RGBA, so ABGR in 32bit little-endian packed format
- * bitmap format is rgb565
- */
-//                                RED                 GREEN               BLUE            ALPHA
-#define RGB565toSKCOLOR(c) ( (((c)&0xF800)>>8) | (((c)&0x7E0)<<5) | (((c)&0x1F)<<19) | 0xFF000000)
-
-#define GetIntField(env, obj, name) env->GetIntField(obj,\
-env->GetFieldID(env->GetObjectClass(obj), name, "I"))
-
-extern "C" M4OSA_ERR NXPSW_FileReaderOptim_init(M4OSA_Void *lowLevel_functionPointers,
-        M4OSA_Void *optimized_functionPointers);
-
-/*
- * Video Browser execution context.
- * Based on request for RGB565 or RGB888, m_dst16 or m_dst32
- * will be initialized and used
- */
-typedef struct
-{
-    M4OSA_Context       m_pVideoBrowser;
-    M4OSA_UInt32        m_previousTime;
-    M4OSA_Int32*        m_dst32;
-    M4OSA_Int16*        m_dst16;
-    unsigned int        m_width;
-    unsigned int        m_height;
-    M4OSA_Bool          m_bRender;
-} ThumbnailContext;
-
-/**
- ************************************************************************
- * @brief    Interface to retrieve the thumbnail pixels
- * @param    pContext   (IN)    Thumbnail Context.
- * @param    width      (IN)    Width of thumbnail
- * @param    height     (IN)    Height of thumbnail
- * @param    pTimeMS    (IN/OUT)Time stamp at which thumbnail is retrieved.
- ************************************************************************
-*/
-M4OSA_ERR ThumbnailGetPixels(const M4OSA_Context pContext,
-                             M4OSA_Int32* pixelArray,
-                             M4OSA_UInt32 width, M4OSA_UInt32 height,
-                             M4OSA_UInt32* pTimeMS, M4OSA_UInt32 tolerance);
-
-
-/**
- ************************************************************************
- * @brief    Video browser callback, called when a frame must be displayed
- * @param    pInstance          (IN) Thumbnail context.
- * @param    notificationID     (IN) Id of the callback which generated the error
- * @param    errCode            (IN) Error code from the Core
- * @param    pCbData            (IN) pointer to data associated wit the callback.
- * @param    pCbUserData        (IN) pointer to application user data passed in init.
- * @note     This callback mechanism is used to request display of an image
- ************************************************************************
-*/
-M4OSA_Void VBcallback(  M4OSA_Context  pInstance,
-                        VideoBrowser_Notification notificationID,
-                        M4OSA_ERR errCode, M4OSA_Void* pCbData,
-                        M4OSA_Void* pCallbackUserData)
-{
-    M4OSA_UInt32 i, j;
-    M4OSA_ERR err;
-
-    M4OSA_TRACE3_0("inside VBcallback");
-    M4VIFI_ImagePlane* pPlane=NULL;
-    M4OSA_UInt16* src=NULL;
-    ThumbnailContext* pC = NULL;
-
-    CHECK_PTR(VBcallback, pCbData, err, M4ERR_PARAMETER);
-    CHECK_PTR(VBcallback, pInstance,err, M4ERR_PARAMETER);
-
-    pC = (ThumbnailContext*)pCallbackUserData ;
-    CHECK_PTR(VBcallback, pC->m_pVideoBrowser, err, M4ERR_PARAMETER);
-
-    pPlane = (M4VIFI_ImagePlane*)pCbData;
-    src = (M4OSA_UInt16*)pPlane->pac_data;
-
-    if (pC->m_dst32 != NULL)
-    {
-        M4OSA_Int32* dst = pC->m_dst32;
-
-        for (j = 0; j < pPlane->u_height; j++)
-        {
-            for (i = 0; i < pPlane->u_width; i++)
-            {
-                dst[i] = RGB565toSKCOLOR(src[i]);
-            }
-            for (i = pPlane->u_width; i < pC->m_width; i++)
-            {
-                dst[i] = 0;
-            }
-            src = (M4OSA_UInt16*)((M4OSA_UInt8*)src + pPlane->u_stride);
-            dst += pC->m_width;
-        }
-    }
-    else if (pC->m_dst16 != NULL)
-    {
-        M4OSA_Int16* dst = pC->m_dst16;
-
-        for (j = 0; j < pPlane->u_height; j++)
-        {
-            memcpy((void * )dst, (void * )src, pPlane->u_stride);
-            for (i = pPlane->u_width; i < pC->m_width; i++)
-            {
-                dst[i] = 0;
-            }
-            src = (M4OSA_UInt16*)((M4OSA_UInt8*)src + pPlane->u_stride);
-            dst += pC->m_width;
-        }
-    }
-    else
-    {
-        CHECK_PTR(VBcallback, NULL, err, M4ERR_PARAMETER);
-    }
-
-VBcallback_cleanUp:
-
-    return;
-}
-
-M4OSA_ERR ThumbnailOpen(M4OSA_Context *pPContext,
-                  const M4OSA_Char *pString,
-                  M4OSA_Bool bRender)
-{
-
-    M4OSA_ERR err;
-    ThumbnailContext *pContext = M4OSA_NULL;
-    VideoBrowser_VideoColorType vbColorType;
-
-    CHECK_PTR(ThumbnailOpen, pString, err, M4ERR_BAD_CONTEXT);
-
-    /*--- Create context ---*/
-    pContext = (ThumbnailContext*)M4OSA_32bitAlignedMalloc(sizeof(ThumbnailContext), VIDEOBROWSER,
-        (M4OSA_Char*)"Thumbnail context") ;
-    M4OSA_TRACE3_1("context value is = %d",pContext);
-    CHECK_PTR(ThumbnailOpen, pContext, err, M4ERR_ALLOC);
-
-    memset((void *)pContext, 0,sizeof(ThumbnailContext));
-
-    M4OSA_FileReadPointer optFP;
-    M4OSA_FileReadPointer llFP;
-
-    NXPSW_FileReaderOptim_init(&llFP, &optFP);
-    M4OSA_TRACE1_2("ThumbnailOpen: entering videoBrowserCreate with 0x%x %s",
-        &pContext->m_pVideoBrowser, pString) ;
-
-    pContext->m_bRender = bRender;
-    if (bRender == M4OSA_TRUE) {
-        //Open is called for rendering the frame.
-        //So set YUV420 as the output color format.
-        vbColorType = VideoBrowser_kYUV420;
-    } else {
-        //Open is called for thumbnail Extraction
-        //So set BGR565 as the output.
-        vbColorType = VideoBrowser_kGB565;
-    }
-
-    err = videoBrowserCreate(&pContext->m_pVideoBrowser, (M4OSA_Char*)pString,
-        VideoBrowser_kVBNormalBliting, &optFP, VBcallback, pContext, vbColorType);
-
-    M4OSA_TRACE1_1("err value is = 0x%x",err);
-    CHECK_ERR(ThumbnailOpen, err);
-    CHECK_PTR(ThumbnailOpen, pContext->m_pVideoBrowser, err, M4ERR_ALLOC);
-
-    *pPContext = pContext;
-    M4OSA_TRACE1_1("context value is = %d",*pPContext);
-
-    return M4NO_ERROR;
-
-ThumbnailOpen_cleanUp:
-
-    M4OSA_TRACE1_0("i am inside cleanUP");
-    if (M4OSA_NULL != pContext)
-    {
-        if (M4OSA_NULL != pContext->m_pVideoBrowser)
-        {
-            videoBrowserCleanUp(pContext->m_pVideoBrowser) ;
-        }
-        free(pContext) ;
-    }
-    return err;
-}
-
-M4OSA_ERR ThumbnailGetPixels(const M4OSA_Context pContext,
-                             M4OSA_Int32* pixelArray,
-                             M4OSA_UInt32 width, M4OSA_UInt32 height,
-                             M4OSA_UInt32* pTimeMS, M4OSA_UInt32 tolerance)
-{
-    M4OSA_ERR err;
-
-    ThumbnailContext* pC = (ThumbnailContext*)pContext;
-
-    if ((pC->m_width != width) || (pC->m_height != height))
-    {
-        err = videoBrowserSetWindow(pC->m_pVideoBrowser, pixelArray,
-                                      0, 0, width, height);
-        CHECK_ERR(ThumbnailGetPixels, err);
-        pC->m_width  = width;
-        pC->m_height = height;
-    }
-
-    // Alter the pTimeMS to a valid value at which a frame is found
-    // m_currentCTS has the actual frame time stamp just ahead of the
-    // pTimeMS supplied.
-    if ((((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS != 0) &&
-        (*pTimeMS >= pC->m_previousTime) &&
-        (*pTimeMS < ((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS))
-    {
-        pC->m_previousTime = *pTimeMS;
-        *pTimeMS = ((VideoBrowserContext*)pC->m_pVideoBrowser)->m_currentCTS;
-    }
-    else
-    {
-        pC->m_previousTime = *pTimeMS;
-    }
-
-    err = videoBrowserPrepareFrame(pC->m_pVideoBrowser, pTimeMS, tolerance);
-    CHECK_ERR(ThumbnailGetPixels, err);
-
-    if (pC->m_bRender != M4OSA_TRUE) {
-        err = videoBrowserDisplayCurrentFrame(pC->m_pVideoBrowser);
-        CHECK_ERR(ThumbnailGetPixels, err);
-    }
-
-ThumbnailGetPixels_cleanUp:
-
-    return err;
-}
-
-M4OSA_ERR ThumbnailGetPixels32(const M4OSA_Context pContext,
-                         M4OSA_Int32* pixelArray, M4OSA_UInt32 width,
-                         M4OSA_UInt32 height, M4OSA_UInt32* timeMS,
-                         M4OSA_UInt32 tolerance)
-{
-
-    M4OSA_ERR err = M4NO_ERROR;
-
-    ThumbnailContext* pC = (ThumbnailContext*)pContext;
-
-    CHECK_PTR(ThumbnailGetPixels32, pC->m_pVideoBrowser, err, M4ERR_ALLOC) ;
-    CHECK_PTR(ThumbnailGetPixels32, pixelArray, err, M4ERR_ALLOC) ;
-
-    pC->m_dst16 = NULL;
-    pC->m_dst32 = pixelArray;
-
-    err = ThumbnailGetPixels(pContext, pixelArray, width, height, timeMS, tolerance);
-
-ThumbnailGetPixels32_cleanUp:
-
-    return err;
-}
-
-M4OSA_ERR ThumbnailGetPixels16(const M4OSA_Context pContext,
-                         M4OSA_Int16* pixelArray, M4OSA_UInt32 width,
-                         M4OSA_UInt32 height, M4OSA_UInt32* timeMS,
-                         M4OSA_UInt32 tolerance)
-{
-    M4OSA_ERR err = M4NO_ERROR;
-
-    ThumbnailContext* pC = (ThumbnailContext*)pContext;
-
-    CHECK_PTR(ThumbnailGetPixels16, pC->m_pVideoBrowser, err, M4ERR_ALLOC);
-    CHECK_PTR(ThumbnailGetPixels16, pixelArray, err, M4ERR_ALLOC);
-
-    pC->m_dst16 = pixelArray;
-    pC->m_dst32 = NULL;
-
-    err = ThumbnailGetPixels(pContext, (M4OSA_Int32*)pixelArray, width, height,
-            timeMS, tolerance);
-
-ThumbnailGetPixels16_cleanUp:
-
-    return err;
-}
-
-
-void ThumbnailClose(const M4OSA_Context pContext)
-{
-    M4OSA_ERR err;
-
-    ThumbnailContext* pC = (ThumbnailContext*)pContext;
-
-    CHECK_PTR(ThumbnailClose, pC, err, M4ERR_ALLOC);
-
-    if (M4OSA_NULL != pC)
-    {
-        if (M4OSA_NULL != pC->m_pVideoBrowser)
-        {
-            videoBrowserCleanUp(pC->m_pVideoBrowser);
-        }
-        free(pC);
-    }
-
-ThumbnailClose_cleanUp:
-
-    return;
-}
-
diff --git a/media/jni/mediaeditor/VideoEditorThumbnailMain.h b/media/jni/mediaeditor/VideoEditorThumbnailMain.h
deleted file mode 100644
index 0b3b0c8..0000000
--- a/media/jni/mediaeditor/VideoEditorThumbnailMain.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VIDEOEDITOR_THUMBNAIL_MAIN_H
-#define VIDEOEDITOR_THUMBNAIL_MAIN_H
-
-/**
- ************************************************************************
- * @file        VideoEditorThumbnailMain.h
- * @brief       Thumbnail extract interface.
- ************************************************************************
-*/
-
-/**
- ************************************************************************
- * @brief    Interface to open a Thumbnail session.
- * @param    pContext   (OUT)   Thumbnail Context.
- * @param    pString    (IN)    File path from which thumbnail will be
- *                              retrieved
- * @param    M4OSA_Bool (IN)    true if this is for rendering at native layer.
- ************************************************************************
-*/
-M4OSA_ERR ThumbnailOpen(M4OSA_Context *pPContext,
-                  const M4OSA_Char *pString,
-                  M4OSA_Bool bRender);
-
-/**
- ************************************************************************
- * @brief    Interface to retrieve a RGB888 format thumbnail pixels
- * @param    pContext   (IN)    Thumbnail Context.
- * @param    pixelArray (OUT)   Pointer to array in which pixels data to return
- * @param    width      (IN)    Width of thumbnail
- * @param    height     (IN)    Height of thumbnail
- * @param    pTimeMS    (IN/OUT)Time stamp at which thumbnail is retrieved.
- ************************************************************************
-*/
-M4OSA_ERR ThumbnailGetPixels32(const M4OSA_Context pContext,
-                             M4OSA_Int32* pixelArray, M4OSA_UInt32 width,
-                             M4OSA_UInt32 height, M4OSA_UInt32 *timeMS,
-                             M4OSA_UInt32 tolerance);
-
-/**
- ************************************************************************
- * @brief    Interface to retrieve a RGB565 format thumbnail pixels
- * @param    pContext   (IN)    Thumbnail Context.
- * @param    pixelArray (OUT)   Pointer to array in which pixcel data to return
- * @param    width      (IN)    Width of thumbnail
- * @param    height     (IN)    Height of thumbnail
- * @param    pTimeMS    (IN/OUT)Time stamp at which thumbnail is retrieved.
- ************************************************************************
-*/
-M4OSA_ERR ThumbnailGetPixels16(const M4OSA_Context pContext,
-                             M4OSA_Int16* pixelArray, M4OSA_UInt32 width,
-                             M4OSA_UInt32 height, M4OSA_UInt32 *timeMS,
-                             M4OSA_UInt32 tolerance);
-
-/**
- ************************************************************************
- * @brief    Interface to close the Thumbnail session.
- * @param    pContext   (IN)    Thumbnail Context.
- ************************************************************************
-*/
-void ThumbnailClose(const M4OSA_Context pContext);
-
-#endif // VIDEOEDITOR_THUMBNAIL_MAIN_H
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
index 3d5905d..cfc0881 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
@@ -17,8 +17,6 @@
 package com.android.mediaframeworktest;
 
 import com.android.mediaframeworktest.performance.MediaPlayerPerformance;
-/*Video Editor performance Test cases*/
-import com.android.mediaframeworktest.performance.VideoEditorPerformance;
 import junit.framework.TestSuite;
 
 import android.os.Bundle;
@@ -44,8 +42,6 @@
     public TestSuite getAllTests() {
         TestSuite suite = new InstrumentationTestSuite(this);
         suite.addTestSuite(MediaPlayerPerformance.class);
-        /* Video Editor performance Test cases */
-        suite.addTestSuite(VideoEditorPerformance.class);
         return suite;
     }
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
index cbb6642..a9dc886 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
@@ -32,11 +32,6 @@
 import com.android.mediaframeworktest.functional.audio.MediaPresetReverbTest;
 import com.android.mediaframeworktest.functional.audio.MediaVirtualizerTest;
 import com.android.mediaframeworktest.functional.audio.MediaVisualizerTest;
-import com.android.mediaframeworktest.functional.videoeditor.MediaItemThumbnailTest;
-import com.android.mediaframeworktest.functional.videoeditor.MediaPropertiesTest;
-import com.android.mediaframeworktest.functional.videoeditor.VideoEditorAPITest;
-import com.android.mediaframeworktest.functional.videoeditor.VideoEditorExportTest;
-import com.android.mediaframeworktest.functional.videoeditor.VideoEditorPreviewTest;
 import junit.framework.TestSuite;
 
 import android.os.Bundle;
@@ -76,12 +71,6 @@
         suite.addTestSuite(MediaPresetReverbTest.class);
         suite.addTestSuite(MediaVirtualizerTest.class);
         suite.addTestSuite(MediaVisualizerTest.class);
-        /*Test for Video Editor*/
-        suite.addTestSuite(MediaItemThumbnailTest.class);
-        suite.addTestSuite(MediaPropertiesTest.class);
-        suite.addTestSuite(VideoEditorAPITest.class);
-        suite.addTestSuite(VideoEditorExportTest.class);
-        suite.addTestSuite(VideoEditorPreviewTest.class);
         return suite;
     }
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
index 0cd784c..5438061 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
@@ -19,8 +19,6 @@
 import android.test.InstrumentationTestRunner;
 import android.test.InstrumentationTestSuite;
 import com.android.mediaframeworktest.stress.MediaPlayerStressTest;
-/** Import for Video Editor Stress Test cases*/
-import com.android.mediaframeworktest.stress.VideoEditorStressTest;
 
 import junit.framework.TestSuite;
 
@@ -30,8 +28,6 @@
     public TestSuite getAllTests() {
         TestSuite suite = new InstrumentationTestSuite(this);
         suite.addTestSuite(MediaPlayerStressTest.class);
-        /** Video Editor Stress Test cases*/
-        suite.addTestSuite(VideoEditorStressTest.class);
         return suite;
     }
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/VideoEditorHelper.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/VideoEditorHelper.java
deleted file mode 100644
index dd7c4c6..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/VideoEditorHelper.java
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaframeworktest;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Random;
-
-import junit.framework.Assert;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.media.videoeditor.AudioTrack;
-import android.media.videoeditor.EffectColor;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.videoeditor.MediaVideoItem;
-import android.media.videoeditor.OverlayFrame;
-import android.media.videoeditor.TransitionAlpha;
-import android.media.videoeditor.TransitionCrossfade;
-import android.media.videoeditor.TransitionFadeBlack;
-import android.media.videoeditor.TransitionSliding;
-import android.media.videoeditor.VideoEditor;
-import android.media.videoeditor.VideoEditorFactory;
-import android.util.Log;
-import android.os.Environment;
-
-/**
- * This class has the names of the all the activity name and variables in the
- * instrumentation test.
- */
-public class VideoEditorHelper extends Assert {
-
-    private final String TAG = "VideoEditorMediaNames";
-
-    public VideoEditorHelper() {
-
-    }
-
-    public static final String PROJECT_LOCATION_COMMON =
-        Environment.getExternalStorageDirectory().toString() + "/";
-
-    public static final String INPUT_FILE_PATH_COMMON = PROJECT_LOCATION_COMMON +
-        "media_api/videoeditor/";
-
-    // -----------------------------------------------------------------
-    // HELPER METHODS
-    // -----------------------------------------------------------------
-
-    /**
-     * This method creates an object of VideoEditor
-     *
-     * @param projectPath the directory where all files related to project will
-     *            be stored
-     * @param className The class which implements the VideoEditor Class
-     * @return the object of VideoEditor
-     */
-    public VideoEditor createVideoEditor(String projectPath) {
-        VideoEditor mVideoEditor = null;
-        try {
-            mVideoEditor = VideoEditorFactory.create(projectPath);
-            assertNotNull("VideoEditor", mVideoEditor);
-        } catch (Exception e) {
-            fail("Unable to create Video Editor");
-        }
-        return mVideoEditor;
-    }
-
-    /**
-     *This method deletes the VideoEditor object created using
-     * createVideoEditor method
-     *
-     * @param videoEditor the VideoEditor object which needs to be cleaned up
-     */
-    public void destroyVideoEditor(VideoEditor videoEditor) {
-        // Release VideoEditor
-        if (videoEditor != null) {
-            try {
-                videoEditor.release();
-            } catch (Exception e) {
-                fail("Unable to destory Video Editor");
-            }
-        }
-    }
-
-    /**
-     *This Method checks the Range in "RangePercent" (say 10)
-     *
-     * @param int Expected data
-     * @param actual data
-     * @return boolean flag which confirms the range matching
-     */
-    public boolean checkRange(long expected, long actual, long rangePercent) {
-        long range = 0;
-        range = (100 * actual) / expected;
-
-        Log.i("checkRange", "Range = " + range);
-        if ((range > (100 - rangePercent)) && (range < (100 + rangePercent))) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     *This Method Creates a Bitmap with the given input file
-     *
-     * @param file the Input whose Bitmap has top be extracted
-     * @return an Object of EffectColor
-     */
-    public Bitmap getBitmap(String file, int width, int height) throws IOException {
-        assertNotNull("Bitmap File is Null", file);
-        FileInputStream inputStream = null;
-        Bitmap overlayBmp = null;
-        if (!new File(file).exists())
-            throw new IOException("File not Found " + file);
-        try {
-            final BitmapFactory.Options dbo = new BitmapFactory.Options();
-            dbo.inJustDecodeBounds = true;
-            dbo.outWidth = width;
-            dbo.outHeight = height;
-            File flPtr = new File(file);
-            inputStream = new FileInputStream(flPtr);
-            final Bitmap srcBitmap = BitmapFactory.decodeStream(inputStream);
-            overlayBmp = Bitmap.createBitmap(srcBitmap);
-            assertNotNull("Bitmap 1", srcBitmap);
-            assertNotNull("Bitmap 2", overlayBmp);
-            inputStream.close();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return overlayBmp;
-    }
-
-    /**
-     *This Method Create a Media Video Item with the specified params
-     *
-     * @return an Object of MediaVideoItem
-     */
-    public MediaVideoItem createMediaItem(VideoEditor videoEditor,
-        String MediaId, String filename, int renderingMode) {
-        MediaVideoItem mvi = null;
-        try {
-            mvi = new MediaVideoItem(videoEditor, MediaId, filename,
-                renderingMode);
-            assertNotNull("Can not create an object of MediaVideoItem", mvi);
-        } catch (IllegalArgumentException e) {
-            throw new IllegalArgumentException
-                ("Can not create an object of Media Video Item with file name = "
-                    + filename + " Issue = " + e.toString());
-        } catch (IOException e) {
-            assertTrue
-                ("Can not create an object of Media Video Item with file name = "
-                    + filename + " Issue = " + e.toString(), false);
-        }
-        return mvi;
-    }
-
-    /**
-     *This Method Create a Media Image Item with the specified params
-     *
-     * @return an Object of MediaImageItem
-     */
-    public MediaImageItem createMediaItem(VideoEditor videoEditor,
-        String MediaId, String filename, long duration, int renderingMode) {
-        MediaImageItem mii = null;
-        try {
-            mii = new MediaImageItem(videoEditor, MediaId, filename, duration,
-                renderingMode);
-            assertNotNull("Can not create an object of MediaImageItem", mii);
-
-        } catch (IllegalArgumentException e) {
-            assertTrue("Can not create an object of Media Image with file name = "
-                + filename + " Issue = " + e.toString(), false);
-        } catch (IOException e) {
-            assertTrue("Can not create an object of Media Image with file name = "
-                + filename + " Issue = " + e.toString(), false);
-        }
-        return mii;
-    }
-
-    /**
-     *This Method Create a Effect with the specified params
-     *
-     * @return an Object of EffectColor
-     */
-    public EffectColor createEffectItem(MediaItem mediaItem, String effectId,
-        long startTime, long duration, int effectType, int colorType) {
-        EffectColor effectonMVI = null;
-        effectonMVI = new EffectColor(mediaItem, effectId, startTime,
-            duration, effectType, colorType);
-        return effectonMVI;
-    }
-
-    /**
-     *This Method creates object of Type Transition Cross fade
-     *
-     * @return TransitionCrossfade object
-     */
-    public TransitionCrossfade createTCrossFade(String transitionId,
-        MediaItem afterMediaItem, MediaItem beforeMediaItem, long durationMs,
-        int behavior) {
-        Log.i("TransitionCrossfade Details === ", "Transid ID = " + transitionId +
-            " Duration= " + durationMs + " Behaviour " + behavior);
-
-        TransitionCrossfade transitionCF = null;
-            transitionCF = new TransitionCrossfade(transitionId, afterMediaItem,
-                beforeMediaItem, durationMs, behavior);
-        return transitionCF;
-    }
-
-    /**
-     *This Method creates object of Type TransitionFadeBlack
-     *
-     * @return TransitionFadeBlack object
-     */
-    public TransitionFadeBlack createTFadeBlack(String transitionId,
-        MediaItem afterMediaItem, MediaItem beforeMediaItem, long durationMs,
-        int behavior) {
-        TransitionFadeBlack transitionFB = null;
-
-        transitionFB = new TransitionFadeBlack(transitionId, afterMediaItem,
-            beforeMediaItem, durationMs, behavior);
-        return transitionFB;
-    }
-
-    /**
-     *This Method creates object of Type TransitionSliding
-     *
-     * @return TransitionSliding object
-     */
-    public TransitionSliding createTSliding(String transitionId,
-        MediaItem afterMediaItem, MediaItem beforeMediaItem, long durationMs,
-        int behavior, int direction) {
-        TransitionSliding transSlide = null;
-            transSlide = new TransitionSliding(transitionId, afterMediaItem,
-                beforeMediaItem, durationMs, behavior, direction);
-        return transSlide;
-    }
-
-    /**
-     *This Method creates object of Type TranistionAlpha
-     *
-     * @return TranistionAlpha object
-     */
-
-    public TransitionAlpha createTAlpha(String transitionId,
-        MediaItem afterMediaItem, MediaItem beforeMediaItem, long durationMs,
-        int behavior, String maskFilename, int blendingPercent, boolean invert) {
-        TransitionAlpha transA = null;
-            transA = new TransitionAlpha(transitionId, afterMediaItem,
-                beforeMediaItem, durationMs, behavior, maskFilename,
-                blendingPercent, invert);
-        return transA;
-    }
-
-    /**
-     *This Method creates object of Type OverlayFrame
-     *
-     * @return OverlayFrame object
-     */
-
-    public OverlayFrame createOverlay(MediaItem mediaItem, String overlayId,
-        Bitmap bitmap, long startTimeMs, long durationMs) {
-        OverlayFrame overLayFrame = null;
-        overLayFrame = new OverlayFrame(mediaItem, overlayId, bitmap,
-                startTimeMs, durationMs);
-        return overLayFrame;
-    }
-
-    /**
-     *This Method creates object of Type AudioTrack
-     *
-     * @return OverlayFrame object
-     */
-    public AudioTrack createAudio(VideoEditor videoEditor, String audioTrackId,
-        String filename) {
-        AudioTrack audio = null;
-        try {
-            audio = new AudioTrack(videoEditor, audioTrackId, filename);
-            assertNotNull("Cant not create an object of an  AudioTrack " +
-                audioTrackId, audio);
-        } catch (IllegalArgumentException e) {
-            assertTrue("Can not create object of an AudioTrack " +
-                audioTrackId + " Issue = " + e.toString(), false);
-        } catch (IOException e) {
-            assertTrue("Can not create object of an AudioTrack " +
-                audioTrackId + " Issue = " + e.toString(), false);
-        }
-        return audio;
-    }
-
-    /**
-     *This Method validates the Exported Movie,as per the specified params
-     * during Export
-     */
-
-    public void validateExport(VideoEditor videoEditor, String fileName,
-        int export_height, int startTime, long endTime, int vCodec, int aCodec) {
-        File tempFile = new File(fileName);
-        assertEquals("Exported FileName", tempFile.exists(), true);
-        final MediaVideoItem mvi = createMediaItem(videoEditor, "m1", fileName,
-            MediaItem.RENDERING_MODE_BLACK_BORDER);
-
-        Log.i(TAG, "VideoCodec for file = " + fileName +
-            "\tExpected Video Codec = " + vCodec + "\tActual Video Codec = " +
-            mvi.getVideoType());
-        assertEquals("Export: Video Codec Mismatch for file = " + fileName +
-            "\t<expected> " + vCodec + "\t<actual> " + mvi.getVideoType(),
-            vCodec, mvi.getVideoType());
-
-        Log.i(TAG, "Height for file = " + fileName + "\tExpected Height = " +
-            export_height + "\tActual VideoHeight = " + mvi.getHeight());
-        assertEquals("Export height Mismatch for file " + fileName +
-            "\t<expected> " + export_height + "\t<actual> " + mvi.getHeight(),
-             export_height, mvi.getHeight());
-        if (startTime == 0) {
-            if (endTime != 0) {
-                Log.i(TAG, "TimeLine Expected = " + (startTime + endTime) +
-                    "\t VideoTime= " + mvi.getTimelineDuration());
-                assertTrue("Timeline Duration Mismatch for file " + fileName +
-                    "<expected> " + (startTime + endTime) + "\t<actual> " +
-                    mvi.getTimelineDuration(), checkRange((startTime +
-                        endTime), mvi.getTimelineDuration(), 10));
-            }
-        } else {
-            Log.i(TAG, "TimeLine Expected = " + (endTime - startTime) +
-                "\t VideoTime= " + mvi.getTimelineDuration());
-            assertTrue("Timeline Duration Mismatch for file " + fileName +
-                "<expected> " + (endTime - startTime) + "\t<actual> " +
-                mvi.getTimelineDuration(), checkRange((endTime -
-                    startTime), (int)mvi.getTimelineDuration(), 10));
-        }
-    }
-
-    /**
-     * @param videoEditor
-     * @param fileName
-     * @param export_bitrate
-     * @param export_height
-     * @param startTime
-     * @param endTime
-     * @param vCodec
-     * @param aCodec
-     */
-    public void validateExport(VideoEditor videoEditor, String fileName,
-        int export_height, int startTime, int endTime, int vCodec, int aCodec) {
-        File tempFile = new File(fileName);
-        assertEquals("Exported FileName", tempFile.exists(), true);
-        final MediaVideoItem mvi = createMediaItem(videoEditor, "m1", fileName,
-            MediaItem.RENDERING_MODE_BLACK_BORDER);
-        Log.i(TAG, "VideoCodec for file = " + fileName +
-            "\tExpected Video Codec = " + vCodec + "\tActual Video Codec = " +
-            mvi.getVideoType());
-        assertEquals("Export: Video Codec Mismatch for file = " + fileName +
-            "\t<expected> " + vCodec + "\t<actual> " + mvi.getVideoType(),
-            vCodec, mvi.getVideoType());
-
-        Log.i(TAG, "AudioCodec for file = " + fileName +
-            "\tExpected Audio Codec = " + aCodec + "\tActual Audio Codec = " +
-            mvi.getAudioType());
-        assertEquals("Export: Audio Codec Mismatch for file = " + fileName +
-            "\t<expected> " + aCodec + "\t<actual> " + mvi.getAudioType(),
-            aCodec, mvi.getAudioType());
-
-        Log.i(TAG, "Height for file = " + fileName + "\tExpected Height = " +
-            export_height + "\tActual VideoHeight = " + mvi.getHeight());
-        assertEquals("Export: height Mismatch for file " + fileName +
-            "\t<expected> " + export_height + "\t<actual> " + mvi.getHeight(),
-            export_height, mvi.getHeight());
-        if (startTime == 0) {
-            if (endTime != 0) {
-                Log.i(TAG, "TimeLine Expected = " + (startTime + endTime) +
-                    "\t VideoTime= " + mvi.getTimelineDuration());
-                assertTrue("Export :Timeline Duration Mismatch for file " +
-                    fileName + "<expected> " + (startTime + endTime) +
-                    "\t<actual> " + mvi.getTimelineDuration(),
-                    checkRange((startTime + endTime), mvi.getTimelineDuration(), 10));
-            }
-        } else {
-            Log.i(TAG, "TimeLine Expected = " + (endTime-startTime) +
-                "\t VideoTime= " + mvi.getTimelineDuration());
-            assertTrue("Timeline Duration Mismatch for file " + fileName +
-                "<expected> " + (endTime - startTime) + "\t<actual> " +
-                mvi.getTimelineDuration(), checkRange((endTime -
-                    startTime), mvi.getTimelineDuration(), 10));
-        }
-    }
-
-    /**
-     * Check file and deletes it.
-     *
-     * @param filename
-     */
-    public void checkDeleteExistingFile(String filename) {
-        Log.i(TAG, ">>>>>>>>>>>>>>>>>>checkDeleteExistingFile  = " + filename);
-        if (filename != null) {
-            File temp = new File(filename);
-            if (temp != null && temp.exists()) {
-                temp.delete();
-            }
-        }
-    }
-
-    /**
-     * This method creates a Directory and filename
-     *
-     * @param location This is path where the file is to be created
-     *            "/sdcard/Output/"
-     * @return Path in form of /sdcard/Output/200910100000
-     */
-    public String createRandomFile(String location) {
-        Random randomGenerator = new Random();
-        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssS");
-        Date date = new Date();
-        final String filePath = location + dateFormat.format(date) +
-            randomGenerator.nextInt(10);
-        Log.i(TAG, ">>>>>>>>>>>>>>>>createRandomFile  Location= " + location +
-            "\t FilePath = " + filePath);
-        return filePath;
-    }
-
-    /**
-     * This method recursively deletes all the file and directory
-     *
-     * @param directory where the files are located Example = "/sdcard/Input"
-     * @return boolean True if deletion is successful else False
-     */
-    public boolean deleteProject(File directory) {
-        Log.i(TAG, ">>>>>>>>>>>>>>>>>>>>>>>>deleteProject  directory= " +
-            directory.toString());
-        if (directory.isDirectory()) {
-            String[] filesInDirecory = directory.list();
-            for (int i = 0; i < filesInDirecory.length; i++) {
-                boolean success = deleteProject(new File(directory,
-                    filesInDirecory[i]));
-                if (!success) {
-                    return false;
-                }
-            }
-        }
-        return directory.delete();
-    }
-
-    /**
-     * This method compares the array of Integer from 0 - 100
-     *
-     * @param data set of integer values received as progress
-     * @return true if sucess else false
-     */
-    public boolean checkProgressCBValues(int[] data) {
-        boolean retFlag = false;
-        for (int i = 0; i < 100; i++) {
-            if (data[i] == 100) {
-                retFlag = true;
-                break;
-            } else {
-                retFlag = false;
-            }
-        }
-        return retFlag;
-    }
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/MediaItemThumbnailTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/MediaItemThumbnailTest.java
deleted file mode 100644
index 7dfab7d..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/MediaItemThumbnailTest.java
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.mediaframeworktest.functional.videoeditor;
-
-import java.io.File;
-import java.io.IOException;
-
-import android.graphics.Bitmap;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.videoeditor.MediaVideoItem;
-import android.media.videoeditor.VideoEditor;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.VideoEditorHelper;
-
-public class MediaItemThumbnailTest extends
-    ActivityInstrumentationTestCase<MediaFrameworkTest> {
-    private final String TAG = "MediaItemThumbailTest";
-
-    private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
-
-    private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
-
-    private VideoEditor mVideoEditor;
-
-    private VideoEditorHelper mVideoEditorHelper;
-
-    public MediaItemThumbnailTest() {
-        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        // setup for each test case.
-        super.setUp();
-        mVideoEditorHelper = new VideoEditorHelper();
-        // Create a random String which will be used as project path, where all
-        // project related files will be stored.
-        final String projectPath = mVideoEditorHelper.
-            createRandomFile(PROJECT_LOCATION);
-        mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
-        // Clean the directory created as project path
-        mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
-        System.gc();
-        super.tearDown();
-    }
-
-    protected void validateThumbnail(Bitmap thumbNailBmp, int outWidth,
-        int outHeight) throws Exception {
-        assertNotNull("Thumbnail Retrived is Null", thumbNailBmp);
-        assertEquals("Thumbnail Height", outHeight, thumbNailBmp.getHeight());
-        assertEquals("Thumbnail Width", outWidth, thumbNailBmp.getWidth());
-        thumbNailBmp.recycle();
-    }
-
-    // -----------------------------------------------------------------
-    // THUMBNAIL
-    // -----------------------------------------------------------------
-    /**
-     * To test thumbnail / frame extraction on H.263 QCIF.
-     */
-    @LargeTest
-    public void testThumbnailForH263QCIF() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final int atTime = 0;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        final int outWidth = (mediaVideoItem.getWidth() / 2);
-        final int outHeight = mediaVideoItem.getHeight();
-
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on MPEG4 VGA .
-     */
-    @LargeTest
-    public void testThumbnailForMPEG4VGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_30fps_512Kbps_0_23.3gp";
-        final int atTime = 0;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = (mediaVideoItem.getWidth() / 2);
-        final int outHeight = mediaVideoItem.getHeight();
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on MPEG4 NTSC.
-     */
-    @LargeTest
-    public void testThumbnailForMPEG4NTSC() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-        final int atTime = 0;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = mediaVideoItem.getWidth() / 2;
-        final int outHeight = mediaVideoItem.getHeight() / 2;
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on MPEG4 WVGA.
-     */
-    @LargeTest
-    public void testThumbnailForMPEG4WVGA() throws Exception {
-
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_800x480_515kbps_15fps_AMR_NB_8KHz_12.2kbps_m_0_26.mp4";
-        final int atTime = 0;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = mediaVideoItem.getWidth() * 2;
-        final int outHeight = mediaVideoItem.getHeight();
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on MPEG4 QCIF.
-     */
-    @LargeTest
-    public void testThumbnailForMPEG4QCIF() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        final int atTime = 0;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = mediaVideoItem.getWidth();
-        final int outHeight = mediaVideoItem.getHeight() * 2;
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on H264 QCIF.
-     */
-    @LargeTest
-    public void testThumbnailForH264QCIF() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H264_BP_176x144_15fps_144kbps_AMRNB_8kHz_12.2kbps_m_1_17.3gp";
-
-        final int atTime = 0;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = mediaVideoItem.getWidth() * 2;
-        final int outHeight = mediaVideoItem.getHeight() * 2;
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on H264 VGA.
-     */
-    @LargeTest
-    public void testThumbnailForH264VGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final int outWidth = 32;
-        final int outHeight = 32;
-        final int atTime = 0;
-
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-    /**
-     * To test thumbnail / frame extraction on H264 WVGA.
-     */
-    @LargeTest
-    public void testThumbnailForH264WVGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4";
-        final int outWidth = 64;
-        final int outHeight = 64;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final long atTime = mediaVideoItem.getDuration() / 2;
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on H264 854x480.
-     */
-    @LargeTest
-    public void testThumbnailForH264854_480() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_854x480_15fps_256kbps_AACLC_16khz_48kbps_s_0_26.mp4";
-        final int outWidth = 128;
-        final int outHeight = 128;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        MediaVideoItem mediaVideoItem = null;
-        mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final long atTime = mediaVideoItem.getDuration() - 1000;
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on H264 960x720.
-     */
-    @LargeTest
-    public void testThumbnailForH264HD960() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_960x720_25fps_800kbps_AACLC_48Khz_192Kbps_s_1_17.mp4";
-        final int outWidth = 75;
-        final int outHeight = 75;
-
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final long atTime = mediaVideoItem.getDuration() - 1000;
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on H264 1080x720 .
-     */
-    @LargeTest
-    public void testThumbnailForH264HD1080() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = mediaVideoItem.getWidth() / 2;
-        final int outHeight = mediaVideoItem.getHeight() / 2;
-        final long atTime = mediaVideoItem.getDuration() / 4;
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * Check the thumbnail / frame extraction precision at 0,100 and 200 ms
-     */
-    @LargeTest
-    public void testThumbnailForH264VGADifferentDuration() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final int atTime = 0;
-        final int atTime1 = 100;
-        final int atTime2 = 200;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = mediaVideoItem.getWidth();
-        final int outHeight = mediaVideoItem.getHeight();
-
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-
-        // get Thumbnail @ 100ms
-        final Bitmap thumbNailBmpAt100 =
-            mediaVideoItem.getThumbnail(outWidth, outHeight, atTime1);
-        validateThumbnail(thumbNailBmpAt100, outWidth, outHeight);
-
-        // get Thumbnail @ 200ms
-        final Bitmap thumbNailBmpAt200 = mediaVideoItem.getThumbnail(
-            outWidth, outHeight, atTime2);
-        validateThumbnail(thumbNailBmpAt200, outWidth, outHeight);
-    }
-
-    /**
-     *Check the thumbnail / frame extraction precision at
-     * FileDuration,FileDuration/2 + 100 andFileDuration/2 + 200 ms
-     */
-    @LargeTest
-    public void testThumbnailForMP4VGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_256kbps_0_30.mp4";
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, MediaItem.RENDERING_MODE_BLACK_BORDER);
-
-        final int outWidth = mediaVideoItem.getWidth();
-        final int outHeight = mediaVideoItem.getHeight();
-        final long atTime = mediaVideoItem.getDuration() / 2;
-        final long atTime1 = atTime + 100;
-        final long atTime2 = atTime + 200;
-
-        // get Thumbnail @ duration/2
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-
-        // get Thumbnail @ duration/2 + 100ms
-        final Bitmap thumbNailBmpAt100 = mediaVideoItem.getThumbnail(
-            outWidth, outHeight, atTime1);
-        validateThumbnail(thumbNailBmpAt100, outWidth, outHeight);
-
-        // get Thumbnail @ duration/2 + 200ms
-        final Bitmap thumbNailBmpAt200 = mediaVideoItem.getThumbnail(
-            outWidth, outHeight, atTime2);
-        validateThumbnail(thumbNailBmpAt200, outWidth, outHeight);
-    }
-
-    /**
-     * Check the thumbnail / frame extraction on JPEG file
-     */
-    @LargeTest
-    public void testThumbnailForImage() throws Exception {
-        final String imageItemFilename = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int mediaDuration = 1000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        int outWidth = 0;
-        int outHeight = 0;
-
-        final MediaImageItem mii = mVideoEditorHelper.createMediaItem(
-            mVideoEditor, "m1", imageItemFilename, mediaDuration, renderingMode);
-        assertNotNull("Media Image Item is Null",  mii);
-        outWidth =  mii.getWidth() / 2;
-        outHeight =  mii.getHeight() / 2;
-
-        final Bitmap thumbNailBmp = mii.getThumbnail(outWidth,
-            outHeight, mediaDuration);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-    /**
-     *To test ThumbnailList for H263 QCIF
-     */
-    @LargeTest
-    public void testThumbnailListH263QCIF() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_1_17.3gp";
-        final int startTime = 0;
-        final int tnCount = 10;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        final int outWidth = mediaVideoItem.getWidth() / 4;
-        final int outHeight = mediaVideoItem.getHeight() / 4;
-        final long endTime = mediaVideoItem.getDuration() / 2;
-
-        final Bitmap thumbNailBmp[] = mediaVideoItem.getThumbnailList(
-            outWidth, outHeight, startTime, endTime, tnCount);
-        assertNotNull("Thumbnail Retrived is Null", thumbNailBmp);
-        assertEquals("Thumbnail Count", tnCount, thumbNailBmp.length);
-
-        for (int i = 0; i < thumbNailBmp.length; i++) {
-            validateThumbnail(thumbNailBmp[i], outWidth, outHeight);
-            thumbNailBmp[i] = null;
-        }
-    }
-
-    /**
-     *To test ThumbnailList for MPEG4 QCIF
-     */
-    @LargeTest
-    public void testThumbnailListMPEG4QCIF() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        final int tnCount = 10;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        final int outWidth = mediaVideoItem.getWidth() / 2;
-        final int outHeight = mediaVideoItem.getHeight() / 2;
-        final long startTime = mediaVideoItem.getDuration() / 2;
-        final long endTime = mediaVideoItem.getDuration();
-
-        final Bitmap thumbNailBmp[] = mediaVideoItem.getThumbnailList(
-            outWidth, outHeight, startTime, endTime, tnCount);
-
-        assertNotNull("Thumbnail Retrived is Null", thumbNailBmp);
-        assertEquals("Thumbnail Count", tnCount, thumbNailBmp.length);
-        for (int i = 0; i < thumbNailBmp.length; i++) {
-            validateThumbnail(thumbNailBmp[i], outWidth, outHeight);
-            thumbNailBmp[i] = null;
-        }
-    }
-
-    /**
-     *To test ThumbnailList for H264 VGA
-     */
-    @LargeTest
-    public void testThumbnailListH264VGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final int tnCount = 10;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        final int outWidth = mediaVideoItem.getWidth() / 2;
-        final int outHeight = mediaVideoItem.getHeight() / 2;
-        final long startTime = mediaVideoItem.getDuration() / 3;
-        final long endTime = mediaVideoItem.getDuration() / 2;
-
-        final Bitmap thumbNailBmp[] = mediaVideoItem.getThumbnailList(
-            outWidth, outHeight, startTime, endTime, tnCount);
-        assertNotNull("Thumbnail Retrived is Null", thumbNailBmp);
-        assertEquals("Thumbnail Count", tnCount, thumbNailBmp.length);
-        for (int i = 0; i < thumbNailBmp.length; i++) {
-            validateThumbnail(thumbNailBmp[i], outWidth, outHeight);
-            thumbNailBmp[i] = null;
-        }
-    }
-
-    /**
-     *To test ThumbnailList for H264 WVGA
-     */
-    @LargeTest
-    public void testThumbnailListH264WVGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4";
-        final int tnCount = 10;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        final int outWidth = mediaVideoItem.getWidth() / 2;
-        final int outHeight = mediaVideoItem.getHeight() / 2;
-        final long startTime = mediaVideoItem.getDuration() / 3;
-        final long endTime = mediaVideoItem.getDuration() / 2;
-
-        final Bitmap thumbNailBmp[] = mediaVideoItem.getThumbnailList(
-            outWidth, outHeight, startTime, endTime, tnCount);
-        assertNotNull("Thumbnail Retrived is Null", thumbNailBmp);
-        assertEquals("Thumbnail Count", tnCount, thumbNailBmp.length);
-        for (int i = 0; i < thumbNailBmp.length; i++) {
-            validateThumbnail(thumbNailBmp[i], outWidth, outHeight);
-            thumbNailBmp[i] = null;
-        }
-    }
-
-    /**
-     *To test ThumbnailList for H264 VGA ,Time exceeding file duration
-     */
-    @LargeTest
-    public void testThumbnailH264VGAExceedingFileDuration() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        boolean flagForException = false;
-        int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        try {
-            final MediaVideoItem mediaVideoItem =
-                mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                    videoItemFilename, renderingMode);
-            final int outWidth = mediaVideoItem.getWidth() / 2;
-            final int outHeight = mediaVideoItem.getHeight() / 2;
-            final long atTime = mediaVideoItem.getDuration() + 2000;
-            mediaVideoItem.getThumbnail(outWidth, outHeight, atTime);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Exception in Extracting thumbanil with Invalid Time",
-            flagForException);
-    }
-
-    /**
-     *To test ThumbnailList for VGA Image
-     */
-    @LargeTest
-    public void testThumbnailListVGAImage() throws Exception {
-        final String imageItemFilename = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int imageItemDuration = 10000;
-        final int startTime = 0;
-        final int endTime = 0;
-        final int tnCount = 10;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                imageItemFilename, imageItemDuration, renderingMode);
-        final int outWidth = mediaImageItem.getWidth() / 2;
-        final int outHeight = mediaImageItem.getHeight() / 2;
-
-        final Bitmap thumbNailBmp[] = mediaImageItem.getThumbnailList
-            (outWidth, outHeight, startTime, endTime, tnCount);
-        assertNotNull("Thumbnail Retrived is Null", thumbNailBmp);
-        assertEquals("Thumbnail Count", tnCount, thumbNailBmp.length);
-        for (int i = 0; i < thumbNailBmp.length; i++) {
-            validateThumbnail(thumbNailBmp[i], outWidth, outHeight);
-            thumbNailBmp[i] = null;
-        }
-    }
-
-    /**
-     *To test ThumbnailList for Invalid file path
-     */
-    @LargeTest
-    public void testThumbnailForInvalidFilePath() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "/sdcard/abc.jpg";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        try{
-        final MediaImageItem mii = new MediaImageItem(mVideoEditor, "m1",
-            imageItemFileName, 3000, renderingMode);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        } catch (IOException e) {
-            flagForException = true;
-        }
-        assertTrue(" Invalid File Path", flagForException);
-    }
-
-    /**
-     * To test thumbnail / frame extraction with setBoundaries
-     */
-    @LargeTest
-    public void testThumbnailForMPEG4WVGAWithSetBoundaries() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "MPEG4_SP_800x480_515kbps_15fps_AMR_NB_8KHz_12.2kbps_m_0_26.mp4";
-        final int atTime = 10000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        mediaVideoItem.setExtractBoundaries(1000,
-            (mediaVideoItem.getDuration() - 21000));
-
-        final int outWidth = (mediaVideoItem.getWidth() / 2);
-        final int outHeight = (mediaVideoItem.getHeight() / 2);
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail(outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     *To test ThumbnailList for H264 WVGA with setExtractboundaries
-     */
-    @LargeTest
-    public void testThumbnailListForH264WVGAWithSetBoundaries() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_1_17.mp4";
-        final int thumbNailStartTime = 10000;
-        final int thumbNailEndTime = 12000;
-        final int tnCount = 10;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        final int outWidth = (mediaVideoItem.getWidth() / 2);
-        final int outHeight = (mediaVideoItem.getHeight() / 2);
-
-        mediaVideoItem.setExtractBoundaries(10000, 12000);
-
-        final Bitmap thumbNailBmp[] = mediaVideoItem.getThumbnailList
-            (outWidth, outHeight, thumbNailStartTime, thumbNailEndTime,
-             tnCount);
-        assertNotNull("Thumbnail Retrived is Null", thumbNailBmp);
-        assertTrue("Thumbnail Size", (thumbNailBmp.length > 0) ? true : false);
-        for (int i = 0; i < thumbNailBmp.length; i++) {
-            validateThumbnail(thumbNailBmp[i], outWidth, outHeight);
-            thumbNailBmp[i] = null;
-        }
-    }
-
-    /**
-     *To test ThumbnailList for H264 WVGA with count > frame available
-     */
-    @LargeTest
-    public void testThumbnailListForH264WVGAWithCount() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4";
-        final int tnCount = 70;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-
-        final int outWidth = (mediaVideoItem.getWidth() / 2);
-        final int outHeight = (mediaVideoItem.getHeight() / 2);
-        final long thumbNailStartTime = mediaVideoItem.getDuration() / 2;
-        final long thumbNailEndTime = thumbNailStartTime + 4000;
-        Bitmap thumbNailBmp[] = null;
-        boolean flagForException = false;
-        try{
-            thumbNailBmp = mediaVideoItem.getThumbnailList(outWidth, outHeight,
-                thumbNailStartTime, thumbNailEndTime, tnCount);
-        }catch (Exception e){
-            assertTrue("Unable to get Thumbnail list", flagForException);
-        }
-        if (thumbNailBmp.length <= tnCount) {
-            flagForException = true;
-        }
-        assertTrue("Thumbnail count more than asked", flagForException);
-    }
-
-    /**
-     *To test ThumbnailList for H264 WVGA with startTime > End Time
-     */
-    @LargeTest
-    public void testThumbnailListH264WVGAWithStartGreaterEnd() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int tnCount = 10;
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = (mediaVideoItem.getWidth() / 2);
-        final int outHeight = (mediaVideoItem.getHeight() / 2);
-        final long thumbNailStartTime = mediaVideoItem.getDuration() / 2;
-        final long thumbNailEndTime = thumbNailStartTime - 1000;
-        try{
-            mediaVideoItem.getThumbnailList(outWidth, outHeight,
-                thumbNailStartTime, thumbNailEndTime, tnCount);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Thumbnail Extraction where start time > end time",
-            flagForException);
-    }
-
-    /**
-     *To test ThumbnailList for H264 WVGA with startTime = End Time
-     */
-    @LargeTest
-    public void testThumbnailListH264WVGAWithStartEqualEnd() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4";
-        final int tnCount = 1;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = (mediaVideoItem.getWidth() / 2);
-        final int outHeight = (mediaVideoItem.getHeight() / 2);
-        final long thumbNailStartTime = mediaVideoItem.getDuration() / 2;
-        final long thumbNailEndTime = thumbNailStartTime;
-        final Bitmap thumbNailBmp[] = mediaVideoItem.getThumbnailList(outWidth,
-            outHeight, thumbNailStartTime, thumbNailEndTime, tnCount);
-        assertNotNull("Thumbnail Retrived is Null", thumbNailBmp);
-        assertEquals("Thumbnail Count", tnCount, thumbNailBmp.length);
-        for (int i = 0; i < thumbNailBmp.length; i++) {
-            validateThumbnail(thumbNailBmp[i], outWidth, outHeight);
-            thumbNailBmp[i] = null;
-        }
-    }
-
-    /**
-     *To test ThumbnailList for file where video duration is less
-     * than file duration.
-     */
-    @LargeTest
-    public void testThumbnailForVideoDurationLessFileDuration() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_64kps_m_0_27.3gp";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-            final MediaVideoItem mediaVideoItem =
-                mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                    videoItemFilename, renderingMode);
-            final int outWidth = (mediaVideoItem.getWidth() / 2);
-            final int outHeight = (mediaVideoItem.getHeight() / 2);
-            final long atTime = mediaVideoItem.getDuration() - 2000;
-            final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail (outWidth,
-                outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-
-    }
-
-    /**
-     *To test ThumbnailList for file which has video part corrupted
-     */
-    @LargeTest
-    public void testThumbnailWithCorruptedVideoPart() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "corrupted_H264_BP_640x480_12.5fps_256kbps_AACLC_16khz_24kbps_s_0_26.mp4";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-
-        try {
-            final MediaVideoItem mediaVideoItem =
-                 mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                    videoItemFilename, renderingMode);
-            final int outWidth = mediaVideoItem.getWidth();
-            final int outHeight = mediaVideoItem.getHeight() * 2;
-            final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail
-                (outWidth, outHeight, mediaVideoItem.getDuration()/2);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Corrupted File cannot be read", flagForException);
-    }
-
-    /**
-     * Check the thumbnail / frame list extraction for Height as Negative Value
-     */
-    @LargeTest
-    public void testThumbnailWithNegativeHeight() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        final int tnCount = 10;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        try {
-            final MediaVideoItem mediaVideoItem =
-                mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                    videoItemFilename, renderingMode);
-            final int outWidth = (mediaVideoItem.getWidth() / 2);
-            final int outHeight = -1;
-            final long thumbNailStartTime =
-                mediaVideoItem.getBoundaryBeginTime()/2;
-            final long thumbNailEndTime = mediaVideoItem.getBoundaryEndTime();
-            mediaVideoItem.getThumbnailList(outWidth, outHeight,
-                thumbNailStartTime, thumbNailEndTime, tnCount);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Thumbnail List with negative Height", flagForException);
-    }
-
-    /**
-     * Check the thumbnail for Height as Zero
-     */
-    @LargeTest
-    public void testThumbnailWithHeightAsZero() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        final int atTime = 100;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        try {
-            final MediaVideoItem mediaVideoItem =
-                mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                    videoItemFilename, renderingMode);
-            final int outWidth = (mediaVideoItem.getWidth() / 2);
-            final int outHeight = -1;
-            mediaVideoItem.getThumbnail(outWidth, outHeight, atTime);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Thumbnail List with Zero Height", flagForException);
-    }
-
-    /**
-     * Check the thumbnail for Height = 10
-     */
-    @LargeTest
-    public void testThumbnailWithHeight() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        final int atTime = 1000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-            final MediaVideoItem mediaVideoItem =
-                mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                    videoItemFilename, renderingMode);
-            final int outWidth = (mediaVideoItem.getWidth() / 2);
-            final int outHeight = 10;
-            final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail (outWidth,
-                outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * Check the thumbnail / frame list extraction for Width as Negative Value
-     */
-    @LargeTest
-    public void testThumbnailWithNegativeWidth() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        final int tnCount = 10;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        try {
-            final MediaVideoItem mediaVideoItem =
-                mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                    videoItemFilename, renderingMode);
-            final int outWidth = -1;
-            final int outHeight = mediaVideoItem.getHeight();
-            final long thumbNailStartTime =
-                mediaVideoItem.getBoundaryBeginTime()/2;
-            final long thumbNailEndTime = mediaVideoItem.getBoundaryEndTime();
-            mediaVideoItem.getThumbnailList(outWidth, outHeight, thumbNailStartTime,
-                thumbNailEndTime, tnCount);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Thumbnail List with negative Height", flagForException);
-    }
-
-    /**
-     * Check the thumbnail / frame list extraction for Width zero
-     */
-    @LargeTest
-    public void testThumbnailWithWidthAsZero() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        final int atTime = 1000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        try {
-            final MediaVideoItem mediaVideoItem =
-                mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                    videoItemFilename, renderingMode);
-            final int outWidth = 0;
-            final int outHeight = mediaVideoItem.getHeight() / 2;
-            mediaVideoItem.getThumbnail(outWidth, outHeight, atTime);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Thumbnail List with Zero Width", flagForException);
-    }
-
-    /**
-     * Check the thumbnail for Width = 10
-     */
-    @LargeTest
-    public void testThumbnailWithWidth() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        final int atTime = 1000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth = 10;
-        final int outHeight = mediaVideoItem.getHeight();
-        final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail (outWidth,
-            outHeight, atTime);
-        validateThumbnail(thumbNailBmp, outWidth, outHeight);
-    }
-
-    /**
-     * To test thumbnail / frame extraction on MPEG4 (time beyond file duration).
-     */
-    @LargeTest
-    public void testThumbnailMPEG4withMorethanFileDuration() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_30fps_256kbps_AACLC_44.1kHz_96kbps_s_1_17.3gp";
-        boolean flagForException = false;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename, renderingMode);
-        final int outWidth =  mediaVideoItem.getWidth()/2;
-        final int outHeight =  mediaVideoItem.getHeight()/2;
-        final long atTime = mediaVideoItem.getDuration() + 100;
-        try{
-            final Bitmap thumbNailBmp = mediaVideoItem.getThumbnail (outWidth,
-            outHeight, atTime);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Thumbnail duration is more than file duration",
-            flagForException);
-    }
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/MediaPropertiesTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/MediaPropertiesTest.java
deleted file mode 100644
index 34cf9f0..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/MediaPropertiesTest.java
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaframeworktest.functional.videoeditor;
-
-import java.io.File;
-import java.io.IOException;
-
-import android.media.videoeditor.AudioTrack;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.videoeditor.MediaProperties;
-import android.media.videoeditor.MediaVideoItem;
-import android.media.videoeditor.VideoEditor;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.VideoEditorHelper;
-import com.android.mediaframeworktest.MediaProfileReader;
-
-public class MediaPropertiesTest extends
-    ActivityInstrumentationTestCase<MediaFrameworkTest> {
-    private final String TAG = "MediaPropertiesTest";
-
-    private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
-
-    private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
-
-    private VideoEditor mVideoEditor;
-
-    private VideoEditorHelper mVideoEditorHelper;
-
-    public MediaPropertiesTest() {
-        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        // setup for each test case.
-        super.setUp();
-        mVideoEditorHelper = new VideoEditorHelper();
-        // Create a random String which will be used as project path,
-        // where all project related files will be stored.
-        final String projectPath = mVideoEditorHelper.
-            createRandomFile(PROJECT_LOCATION);
-        mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
-        // Clean the directory created as project path
-        mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
-        System.gc();
-        super.tearDown();
-    }
-
-    protected void validateVideoProperties(int aspectRatio, int fileType,
-        int videoCodecType, int duration, int videoBitrate, int fps,
-        int videoProfile, int videoLevel, int width, int height, int audioCodecType,
-        int audioSamplingFrequency, int audioChannel, int audioBitrate,
-        MediaVideoItem mvi) throws Exception {
-        assertEquals("Aspect Ratio Mismatch", aspectRatio, mvi.getAspectRatio());
-        assertEquals("File Type Mismatch", fileType, mvi.getFileType());
-        assertEquals("VideoCodec Mismatch", videoCodecType, mvi.getVideoType());
-
-        assertTrue("Video duration Mismatch", mVideoEditorHelper.checkRange (
-            duration, mvi.getDuration(), 10));
-        assertEquals("Video Profile " + mvi.getVideoProfile(), videoProfile,
-            mvi.getVideoProfile());
-        assertEquals("Video Level " + mvi.getVideoLevel(), videoLevel,
-            mvi.getVideoLevel());
-        assertEquals("Video height " + mvi.getHeight(), height, mvi.getHeight());
-        assertEquals("Video width " + mvi.getWidth(), width, mvi.getWidth());
-        /** Check FPS with 10% range */
-        assertTrue("fps Mismatch" + mvi.getFps(),
-            mVideoEditorHelper.checkRange(fps, mvi.getFps(), 10));
-
-        assertEquals("AudioType Mismatch ", audioCodecType, mvi.getAudioType());
-        assertEquals("Audio Sampling " + mvi.getAudioSamplingFrequency(),
-            audioSamplingFrequency, mvi.getAudioSamplingFrequency());
-        // PV SW AAC codec always returns number of channels as Stereo.
-        // So we do not assert for number of audio channels for AAC_LC
-        if ( audioCodecType != MediaProperties.ACODEC_AAC_LC ) {
-            assertEquals("Audio Channels " + mvi.getAudioChannels(), audioChannel,
-                mvi.getAudioChannels());
-        }
-    }
-
-    protected void validateAudioProperties(int audioCodecType, int duration,
-        int audioSamplingFrequency, int audioChannel, int audioBitrate,
-        AudioTrack aT) throws Exception {
-        assertEquals("AudioType Mismatch ", audioCodecType, aT.getAudioType());
-        assertTrue("Video duration Mismatch", mVideoEditorHelper.checkRange (
-            duration, aT.getDuration(), 10));
-        assertEquals("Audio Sampling " + aT.getAudioSamplingFrequency(),
-            audioSamplingFrequency, aT.getAudioSamplingFrequency());
-        // PV SW AAC codec always returns number of channels as Stereo.
-        // So we do not assert for number of audio channels for AAC_LC
-        if ( audioCodecType != MediaProperties.ACODEC_AAC_LC ) {
-            assertEquals("Audio Channels " + aT.getAudioChannels(), audioChannel,
-                aT.getAudioChannels());
-        }
-    }
-
-    protected void validateImageProperties(int aspectRatio, int fileType,
-        int width, int height, MediaImageItem mii)
-        throws Exception {
-        assertEquals("Aspect Ratio Mismatch", aspectRatio, mii.getAspectRatio());
-        assertEquals("File Type Mismatch", fileType, mii.getFileType());
-        assertEquals("Image height " + mii.getHeight(), height, mii.getHeight());
-        assertEquals("Image width " + mii.getWidth(), width, mii.getWidth());
-    }
-
-
-    /**
-     *To test Media Properties for file MPEG4 854 x 480
-     */
-    @LargeTest
-    public void testPropertiesMPEG4854_480() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_854x480_15fps_256kbps_AACLC_16khz_48kbps_s_0_26.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_16_9;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_MPEG4;
-        final int duration = 26933;
-        final int videoBitrate = 319000;
-        final int audioBitrate = 48000;
-        final int fps = 15;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 16000;
-        final int audioChannel = 2;
-        final int videoProfile = MediaProperties.MPEG4Profile.MPEG4ProfileSimple;
-        final int videoLevel = MediaProperties.MPEG4Level.MPEG4Level1;
-        final int width = 854;
-        final int height = MediaProperties.HEIGHT_480;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename,
-            MediaItem.RENDERING_MODE_BLACK_BORDER);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-
-    /**
-     *To test Media Properties for file MPEG4 WVGA
-     */
-    @LargeTest
-    public void testPropertiesMPEGWVGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_800x480_515kbps_15fps_AMR_NB_8KHz_12.2kbps_m_0_26.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_5_3;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_MPEG4;
-        final int duration = 26933;
-        final int videoBitrate = 384000;
-        final int audioBitrate = 12800;
-        final int fps = 15;
-        final int audioCodecType = MediaProperties.ACODEC_AMRNB;
-        final int audioSamplingFrequency = 8000;
-        final int audioChannel = 1;
-        final int videoProfile = MediaProperties.MPEG4Profile.MPEG4ProfileSimple;
-        final int videoLevel = MediaProperties.MPEG4Level.MPEG4Level1;
-        final int width = 800;
-        final int height = MediaProperties.HEIGHT_480;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test media properties for MPEG4 720x480 (NTSC) + AAC file.
-     */
-    @LargeTest
-    public void testPropertiesMPEGNTSC() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_MPEG4;
-        final int duration = 26866;
-        final int videoBitrate = 403000;
-        final int audioBitrate = 160000;
-        final int fps = 30;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 48000;
-        final int audioChannel = 2;
-        final int videoProfile = MediaProperties.MPEG4Profile.MPEG4ProfileSimple;
-        final int videoLevel = MediaProperties.MPEG4Level.MPEG4Level1;
-        final int width = 720;
-        final int height = MediaProperties.HEIGHT_480;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test Media Properties for file MPEG4 VGA
-     */
-    @LargeTest
-    public void testPropertiesMPEGVGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_4_3;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_MPEG4;
-        final int duration = 26933;
-        final int videoBitrate = 533000;
-        final int audioBitrate = 128000;
-        final int fps = 15;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 48000;
-        final int audioChannel = 2;
-        final int videoProfile = MediaProperties.MPEG4Profile.MPEG4ProfileSimple;
-        final int videoLevel = MediaProperties.MPEG4Level.MPEG4Level1;
-        final int width = 640;
-        final int height = MediaProperties.HEIGHT_480;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test Media Properties for file MPEG4 QCIF
-     */
-    @LargeTest
-    public void testPropertiesMPEGQCIF() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "MPEG4_SP_176x144_12fps_92kbps_AMRNB_8KHz_12.2kbps_m_0_27.3gp";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_11_9;
-        final int fileType = MediaProperties.FILE_3GP;
-        final int videoCodecType = MediaProperties.VCODEC_MPEG4;
-        final int duration = 27000;
-        final int videoBitrate = 384000;
-        final int audioBitrate = 12200;
-        final int fps = 12;
-        final int audioCodecType = MediaProperties.ACODEC_AMRNB;
-        final int audioSamplingFrequency = 8000;
-        final int audioChannel = 1;
-        final int videoProfile = MediaProperties.MPEG4Profile.MPEG4ProfileSimple;
-        final int videoLevel = MediaProperties.MPEG4Level.MPEG4Level1;
-        final int width = 176;
-        final int height = MediaProperties.HEIGHT_144;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To To test media properties for H263 176x144 (QCIF) + AAC (mono) file.
-     */
-    @LargeTest
-    public void testPropertiesH263QCIF() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_16kHz_32kbps_m_0_26.3gp";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_11_9;
-        final int fileType = MediaProperties.FILE_3GP;
-        final int videoCodecType = MediaProperties.VCODEC_H263;
-        final int duration = 26933;
-        final int videoBitrate = 384000;
-        final int audioBitrate = 64000;
-        final int fps = 15;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 16000;
-        final int audioChannel = 1;
-        final int videoProfile = MediaProperties.H263Profile.H263ProfileBaseline;
-        final int videoLevel = MediaProperties.H263Level.H263Level10;
-        final int width = 176;
-        final int height = MediaProperties.HEIGHT_144;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test Media Properties for file H264 VGA
-     */
-    @LargeTest
-    public void testPropertiesH264VGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_64kps_m_0_27.3gp";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_4_3;
-        final int fileType = MediaProperties.FILE_3GP;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int duration = 77600;
-        final int videoBitrate = 745000;
-        final int audioBitrate = 64000;
-        final int fps = 15;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 48000;
-        final int audioChannel = 2;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileBaseline;
-        final int videoLevel = MediaProperties.H264Level.H264Level13;
-        final int width = 640;
-        final int height = MediaProperties.HEIGHT_480;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test Media Properties for file H264 NTSC
-     */
-    @LargeTest
-    public void testPropertiesH264NTSC() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H264_BP_720x480_25fps_256kbps_AMRNB_8khz_12.2kbps_m_0_26.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int duration = 26880;
-        final int videoBitrate = 244000;
-        final int audioBitrate = 12200;
-        final int fps = 25;
-        final int audioCodecType = MediaProperties.ACODEC_AMRNB;
-        final int audioSamplingFrequency = 8000;
-        final int audioChannel = 1;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileBaseline;
-        final int videoLevel = MediaProperties.H264Level.H264Level13;
-        final int width = 720;
-        final int height = MediaProperties.HEIGHT_480;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test media properties for H264 800x480 (WVGA) + AAC file.
-     */
-    @LargeTest
-    public void testPropertiesH264WVGA() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-              "H264_BP_800x480_15fps_512kbps_AACLC_24KHz_38Kbps_s_1_17.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_5_3;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int duration = 77466;
-        final int videoBitrate = 528000;
-        final int audioBitrate = 38000;
-        final int fps = 15;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 24000;
-        final int audioChannel = 2;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileBaseline;
-        final int videoLevel = MediaProperties.H264Level.H264Level13;
-        final int width = 800;
-        final int height = MediaProperties.HEIGHT_480;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test Media Properties for file H264 HD1280
-     */
-    @LargeTest
-    public void testPropertiesH264HD1280() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H264_BP_1280x720_15fps_512kbps_AACLC_16khz_48kbps_s_1_17.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_16_9;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int duration = 77600;
-        final int videoBitrate = 606000;
-        final int audioBitrate = 48000;
-        final int fps = 15;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 16000;
-        final int audioChannel = 2;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileBaseline;
-        final int videoLevel = MediaProperties.H264Level.H264Level13;
-        final int width = 1280;
-        final int height = MediaProperties.HEIGHT_720;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test media properties for H264 1080x720 + AAC file
-     */
-    @LargeTest
-    public void testPropertiesH264HD1080WithAudio() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H264_BP_1080x720_30fps_12Mbps_AACLC_44.1khz_64kbps_s_1_17.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int duration = 77500;
-        final int videoBitrate = 1190000;
-        final int audioBitrate = 64000;
-        final int fps = 10;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 44100;
-        final int audioChannel = 2;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileBaseline;
-        final int videoLevel = MediaProperties.H264Level.H264Level13;
-        final int width = 1080;
-        final int height = MediaProperties.HEIGHT_720;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test Media Properties for file WMV - Unsupported type
-     */
-    @LargeTest
-    public void testPropertiesWMVFile() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "WMV_V7_640x480_15fps_512Kbps_wma_V9_44khz_48Kbps_s_1_30.wmv";
-        boolean flagForException = false;
-        if (MediaProfileReader.getWMVEnable() == false) {
-            flagForException = true;
-        } else {
-            try {
-                new MediaVideoItem(mVideoEditor, "m1", videoItemFilename,
-                    MediaItem.RENDERING_MODE_BLACK_BORDER);
-            } catch (IllegalArgumentException e) {
-                flagForException = true;
-            } catch (IOException e) {
-                flagForException = true;
-            }
-        }
-        assertTrue("Media Properties for a WMV File -- Unsupported file type",
-            flagForException);
-    }
-
-    /**
-     *To test media properties for H.264 Main/Advanced profile.
-     */
-    @LargeTest
-    public void testPropertiesH264MainLineProfile() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH
-            + "H264_MP_960x720_25fps_800kbps_AACLC_48Khz_192Kbps_s_1_17.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_4_3;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int duration = 77500;
-        final int videoBitrate = 800000;
-        final int audioBitrate = 192000;
-        final int fps = 25;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 48000;
-        final int audioChannel = 2;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileMain;
-        final int videoLevel = MediaProperties.H264Level.H264Level31;
-        final int width = 960;
-        final int height = MediaProperties.HEIGHT_720;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-
-    }
-
-    /**
-     *To test Media Properties for non existing file.
-     */
-    @LargeTest
-    public void testPropertiesForNonExsitingFile() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH + "abc.3gp";
-        boolean flagForException = false;
-
-        try {
-            new MediaVideoItem(mVideoEditor, "m1", videoItemFilename,
-                MediaItem.RENDERING_MODE_BLACK_BORDER);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        } catch (IOException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Properties for non exsisting file", flagForException);
-     }
-
-    /**
-     *To test Media Properties for file H264 HD1080
-     */
-    @LargeTest
-    public void testPropertiesH264HD1080WithoutAudio() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int duration = 77366;
-        final int videoBitrate = 859000;
-        final int audioBitrate = 0;
-        final int fps = 30;
-        final int audioCodecType = -1;
-        final int audioSamplingFrequency = 0;
-        final int audioChannel = 0;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileBaseline;
-        final int videoLevel = MediaProperties.H264Level.H264Level13;
-        final int width = 1080;
-        final int height = MediaProperties.HEIGHT_720;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mvi = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", videoItemFilename, renderingMode);
-
-        validateVideoProperties(aspectRatio, fileType, videoCodecType, duration,
-            videoBitrate, fps, videoProfile, videoLevel, width, height, audioCodecType,
-            audioSamplingFrequency, audioChannel, audioBitrate, mvi);
-    }
-
-    /**
-     *To test Media Properties for Image file of JPEG Type
-     */
-    @LargeTest
-    public void testPropertiesVGAImage() throws Exception {
-        final String imageItemFilename = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int imageItemDuration = 10000;
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_4_3;
-        final int fileType = MediaProperties.FILE_JPEG;
-        final int width = 640;
-        final int height = MediaProperties.HEIGHT_480;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaImageItem mii = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", imageItemFilename, imageItemDuration,
-            renderingMode);
-        validateImageProperties(aspectRatio, fileType, width, height, mii);
-    }
-
-    /**
-     *To test Media Properties for Image file of PNG Type
-     */
-    @LargeTest
-    public void testPropertiesPNG() throws Exception {
-        final String imageItemFilename = INPUT_FILE_PATH + "IMG_640x480.png";
-        final int imageItemDuration = 10000;
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_4_3;
-        final int fileType = MediaProperties.FILE_PNG;
-        final int width = 640;
-        final int height = 480;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaImageItem mii = mVideoEditorHelper.createMediaItem
-            (mVideoEditor, "m1", imageItemFilename, imageItemDuration,
-            renderingMode);
-        validateImageProperties(aspectRatio, fileType, width, height, mii);
-    }
-
-    /**
-     *To test Media Properties for file GIF - Unsupported type
-     */
-    @LargeTest
-    public void testPropertiesGIFFile() throws Exception {
-
-        final String imageItemFilename = INPUT_FILE_PATH + "IMG_640x480.gif";
-        final int imageItemDuration = 10000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        try {
-            new MediaImageItem(mVideoEditor, "m1", imageItemFilename,
-                imageItemDuration, renderingMode);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Properties for a GIF File -- Unsupported file type",
-            flagForException);
-    }
-
-    /**
-     *To test Media Properties for file Text file named as 3GP
-     */
-    @LargeTest
-    public void testPropertiesofDirtyFile() throws Exception {
-
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "Text_FileRenamedTo3gp.3gp";
-        boolean flagForException = false;
-
-        try {
-            new MediaVideoItem(mVideoEditor, "m1", videoItemFilename,
-                MediaItem.RENDERING_MODE_BLACK_BORDER);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Properties for a Dirty  File ",
-            flagForException);
-    }
-
-    /**
-     *To test Media Properties for file name as NULL
-     */
-    @LargeTest
-    public void testPropertieNULLFile() throws Exception {
-        final String videoItemFilename = null;
-        boolean flagForException = false;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        try {
-            new MediaVideoItem(mVideoEditor, "m1", videoItemFilename,
-                renderingMode);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Properties for NULL  File ",
-            flagForException);
-    }
-
-    /**
-     *To test Media Properties for file which is of type MPEG2
-     */
-    @LargeTest
-    public void testPropertiesMPEG2File() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "MPEG2_640x480_30fps_192kbps_1_5.mp4";
-        boolean flagForException = false;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        try {
-            new MediaVideoItem(mVideoEditor, "m1", videoItemFilename,
-                renderingMode);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Properties for a MPEG2 File --Unsupported file type",
-            flagForException);
-    }
-
-    /**
-     *To test Media Properties for file without Video only Audio
-     */
-    @LargeTest
-    public void testProperties3GPWithoutVideoMediaItem() throws Exception {
-        final String audioFilename = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        boolean flagForException = false;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        try {
-            new MediaVideoItem(mVideoEditor, "m1", audioFilename,
-                renderingMode);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Exception in Creaing Media Video item object without video",
-            flagForException);
-    }
-
-    /**
-     *To test media properties for Audio Track file. (No Video, AAC Audio)
-     */
-    @LargeTest
-    public void testProperties3GPWithoutVideoAudioTrack() throws Exception {
-
-        final String audioFilename = INPUT_FILE_PATH +
-            "AACLC_44.1kHz_256kbps_s_1_17.mp4";
-        final int duration = 77554;
-        final int audioBitrate = 384000;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 44100;
-        final int audioChannel = 2;
-
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio
-            (mVideoEditor, "a1", audioFilename);
-
-        validateAudioProperties(audioCodecType, duration, audioSamplingFrequency,
-            audioChannel, audioBitrate, audioTrack);
-    }
-
-        /**
-     *To test media properties for Audio Track file. MP3 file
-     */
-    @LargeTest
-    public void testPropertiesMP3AudioTrack() throws Exception {
-
-        final String audioFilename = INPUT_FILE_PATH +
-            "MP3_48KHz_128kbps_s_1_17.mp3";
-        final int duration = 77640;
-        final int audioBitrate = 128000;
-        final int audioCodecType = MediaProperties.ACODEC_MP3;
-        final int audioSamplingFrequency = 48000;
-        final int audioChannel = 2;
-
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio
-            (mVideoEditor, "a1", audioFilename);
-
-        validateAudioProperties(audioCodecType, duration, audioSamplingFrequency,
-            audioChannel, audioBitrate, audioTrack);
-    }
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorAPITest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorAPITest.java
deleted file mode 100644
index 6e520c3..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorAPITest.java
+++ /dev/null
@@ -1,2751 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaframeworktest.functional.videoeditor;
-
-import java.io.File;
-import java.util.List;
-
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.media.videoeditor.AudioTrack;
-import android.media.videoeditor.EffectColor;
-import android.media.videoeditor.EffectKenBurns;
-import android.media.videoeditor.ExtractAudioWaveformProgressListener;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.videoeditor.MediaProperties;
-import android.media.videoeditor.MediaVideoItem;
-import android.media.videoeditor.OverlayFrame;
-import android.media.videoeditor.Transition;
-import android.media.videoeditor.TransitionAlpha;
-import android.media.videoeditor.TransitionCrossfade;
-import android.media.videoeditor.TransitionFadeBlack;
-import android.media.videoeditor.TransitionSliding;
-import android.media.videoeditor.VideoEditor;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase;
-import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
-
-import android.util.Log;
-import java.lang.annotation.Annotation;
-
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import com.android.mediaframeworktest.VideoEditorHelper;
-
-public class VideoEditorAPITest extends
-        ActivityInstrumentationTestCase<MediaFrameworkTest> {
-    private final String TAG = "VideoEditorTest";
-
-    private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
-
-    private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
-
-    private final String PROJECT_CLASS_NAME =
-        "android.media.videoeditor.VideoEditorImpl";
-    private VideoEditor mVideoEditor;
-    private VideoEditorHelper mVideoEditorHelper;
-
-    public VideoEditorAPITest() {
-        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        // setup for each test case.
-        super.setUp();
-        mVideoEditorHelper = new VideoEditorHelper();
-        // Create a random String which will be used as project path, where all
-        // project related files will be stored.
-        final String projectPath = mVideoEditorHelper.
-            createRandomFile(PROJECT_LOCATION);
-        mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
-        // Clean the directory created as project path
-        mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
-        System.gc();
-        super.tearDown();
-    }
-
-    /**
-     * To Test Creation of Media Video Item.
-     */
-    @LargeTest
-    public void testMediaVideoItem() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final int videoItemRenderingMode =
-            MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-
-        assertTrue("Media Video ID",
-            mediaVideoItem1.getId().equals("mediaVideoItem1"));
-        assertTrue("Media Video Filename",
-            mediaVideoItem1.getFilename().equals(videoItemFileName));
-        assertEquals("Media Video Rendering Mode",
-            videoItemRenderingMode, mediaVideoItem1.getRenderingMode());
-        assertEquals("Media Video Item Duration", mediaVideoItem1.getDuration(),
-            mediaVideoItem1.getTimelineDuration());
-        assertEquals("Media Video Overlay", 0,
-            mediaVideoItem1.getAllOverlays().size());
-        assertEquals("Media Video Effect", 0,
-            mediaVideoItem1.getAllEffects().size());
-        assertNull("Media Video Begin transition",
-            mediaVideoItem1.getBeginTransition());
-        assertNull("Media Video End transition",
-            mediaVideoItem1.getEndTransition());
-        mediaVideoItem1.setExtractBoundaries(1000,11000);
-        boolean flagForException = false;
-        if (mediaVideoItem1.getDuration() !=
-            mediaVideoItem1.getTimelineDuration()) {
-            flagForException = true;
-        }
-        assertTrue("Media Video Item Duration & Timeline are same",
-            flagForException );
-    }
-
-    /**
-     * To test creation of Media Video Item with Set Extract Boundaries With Get
-     * the Begin and End Time.
-     */
-    @LargeTest
-    public void testMediaVideoItemExtractBoundaries() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final int videoItemRenderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        mediaVideoItem1.setExtractBoundaries(1000, 11000);
-        assertEquals("Media Item Duration = StoryBoard Duration",
-            mediaVideoItem1.getTimelineDuration(), mVideoEditor.getDuration());
-        try {
-            mediaVideoItem1.setExtractBoundaries(0, 100000000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Set Extract with Invalid Values endTime > FileDuration",
-            flagForException);
-
-        flagForException = false;
-        try {
-            mediaVideoItem1.setExtractBoundaries(100000000, 11000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Set Extract with Invalid Values startTime > endTime",
-            flagForException);
-
-        flagForException = false;
-        try {
-            mediaVideoItem1.setExtractBoundaries(0, 0);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Set Extract with Invalid Values startTime = endTime",
-            flagForException);
-
-        mediaVideoItem1.setExtractBoundaries(1000, 10000);
-        assertTrue("Media Item Duration is still the same",
-            (mediaVideoItem1.getTimelineDuration() ==
-            (mediaVideoItem1.getBoundaryEndTime()-
-            mediaVideoItem1.getBoundaryBeginTime())) ? true : false);
-
-        mediaVideoItem1.setExtractBoundaries(1,mediaVideoItem1.getDuration()-1);
-        assertEquals("Media Item Start Time", 1,
-            mediaVideoItem1.getBoundaryBeginTime());
-        assertEquals("Media Item End Time", (mediaVideoItem1.getDuration() - 1),
-            mediaVideoItem1.getBoundaryEndTime());
-
-        mediaVideoItem1.setExtractBoundaries(1, mediaVideoItem1.getDuration());
-        assertEquals("Media Item Duration = StoryBoard Duration",
-            mediaVideoItem1.getTimelineDuration(), mVideoEditor.getDuration());
-
-        mediaVideoItem1.setExtractBoundaries(0,mediaVideoItem1.getDuration()/2);
-        assertEquals("Media Item Duration = StoryBoard Duration",
-            mediaVideoItem1.getTimelineDuration(), mVideoEditor.getDuration());
-
-        mediaVideoItem1.setExtractBoundaries(0, -1);
-        assertEquals("Media Item Duration = StoryBoard Duration",
-            mediaVideoItem1.getTimelineDuration(), mVideoEditor.getDuration());
-    }
-
-    /**
-     * To test creation of Media Video Item with Set and Get rendering Mode
-     */
-    @LargeTest
-    public void testMediaVideoItemRenderingModes() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final int videoItemRenderingMode= MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-        mediaVideoItem1.setRenderingMode(MediaItem.RENDERING_MODE_CROPPING);
-        assertEquals("MediaVideo Item rendering Mode",
-            MediaItem.RENDERING_MODE_CROPPING,
-            mediaVideoItem1.getRenderingMode());
-        try {
-            mediaVideoItem1.setRenderingMode(
-                MediaItem.RENDERING_MODE_CROPPING + 911);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Item Invalid rendering Mode", flagForException);
-        flagForException = false;
-        try {
-            mediaVideoItem1.setRenderingMode(
-                MediaItem.RENDERING_MODE_BLACK_BORDER - 11);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Item Invalid rendering Mode", flagForException);
-        assertEquals("MediaVideo Item rendering Mode",
-            MediaItem.RENDERING_MODE_CROPPING,
-            mediaVideoItem1.getRenderingMode());
-        mediaVideoItem1.setRenderingMode(MediaItem.RENDERING_MODE_STRETCH);
-        assertEquals("MediaVideo Item rendering Mode",
-            MediaItem.RENDERING_MODE_STRETCH,
-            mediaVideoItem1.getRenderingMode());
-    }
-
-
-    /**
-     * To Test the Media Video API : Set Audio Volume, Get Audio Volume and Mute
-     */
-    @LargeTest
-    public void testMediaVideoItemAudioFeatures() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final int videoItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-        mediaVideoItem1.setVolume(77);
-        assertEquals("Updated Volume is 77", 77, mediaVideoItem1.getVolume());
-
-        mediaVideoItem1.setMute(true);
-        assertTrue("Audio must be Muted", mediaVideoItem1.isMuted());
-
-        mediaVideoItem1.setVolume(78);
-        assertEquals("Updated Volume is 78", 78, mediaVideoItem1.getVolume());
-        assertTrue("Audio must be Muted", mediaVideoItem1.isMuted());
-
-        try {
-            mediaVideoItem1.setVolume(1000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Invalid Set Volume", flagForException);
-
-        mediaVideoItem1.setMute(false);
-        assertFalse("Audio must be Un-Muted", mediaVideoItem1.isMuted());
-
-        mediaVideoItem1.setVolume(0);
-        assertFalse("Audio must be Un-Muted", mediaVideoItem1.isMuted());
-
-        flagForException = false;
-        try {
-            mediaVideoItem1.setVolume(-1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Invalid Set Volume", flagForException);
-
-        mediaVideoItem1.setVolume(100);
-        assertEquals("MediaItem Volume", 100, mediaVideoItem1.getVolume());
-        try {
-            mediaVideoItem1.setVolume(101);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Invalid Set Volume", flagForException);
-        assertEquals("MediaItem Volume", 100, mediaVideoItem1.getVolume());
-    }
-
-    /**
-     * To Test the Media Video API : GetWaveFormData and
-     * extractAudioWaveFormData
-     */
-
-    @LargeTest
-    public void testMediaVideoItemGetWaveformData() throws Exception {
-
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final int videoItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        assertNull("WaveForm data", mediaVideoItem1.getWaveformData());
-        final int[] progressWaveform = new int[105];
-
-        mediaVideoItem1.extractAudioWaveform(new
-            ExtractAudioWaveformProgressListener() {
-                int i = 0;
-                public void onProgress(int progress) {
-                    Log.i("WaveformData","progress=" +progress);
-                    progressWaveform[i++] = progress;
-                }
-            });
-        assertTrue("Progress of WaveForm data", mVideoEditorHelper
-            .checkProgressCBValues(progressWaveform));
-        assertNotNull("WaveForm data", mediaVideoItem1.getWaveformData());
-        assertTrue("WaveForm Frame Duration",
-            (mediaVideoItem1.getWaveformData().getFrameDuration() > 0?
-            true : false));
-        assertTrue("WaveForm Frame Count",
-            (mediaVideoItem1.getWaveformData().getFramesCount() > 0 ?
-            true : false));
-        assertTrue("WaveForm Gain",
-            (mediaVideoItem1.getWaveformData().getFrameGains().length > 0 ?
-            true : false));
-
-    }
-
-    /**
-     * To Test the Media Video API : Get Effect, GetAllEffects, remove Effect
-     */
-
-    @LargeTest
-    public void testMediaVideoItemEffect() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final int videoItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem1 = mVideoEditorHelper.
-            createMediaItem(mVideoEditor, "mediaVideoItem1", videoItemFileName,
-            videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        assertTrue("Effect List Size",
-            (mediaVideoItem1.getAllEffects().size() == 0) ? true : false);
-        assertNull("Effect Item by ID", mediaVideoItem1.getEffect("xyx"));
-
-        final EffectColor effectColor = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "Effecton MVi1", 0, 4000, EffectColor.TYPE_GRADIENT,
-            EffectColor.GRAY);
-        mediaVideoItem1.addEffect(effectColor);
-
-        assertTrue("Effect List Size", (mediaVideoItem1.
-            getAllEffects().size() == 1) ? true : false);
-        assertEquals("Effect Item by Valid ID", effectColor,
-            mediaVideoItem1.getEffect(effectColor.getId()));
-        assertNull("Effect Item by Invalid ID",
-            mediaVideoItem1.getEffect("xyz"));
-        assertNull("Effect Item by Invalid ID",
-            mediaVideoItem1.removeEffect("effectId"));
-        assertTrue("Effect List Size",
-            (mediaVideoItem1.getAllEffects().size() == 1) ? true : false);
-        assertEquals("Effect Removed", effectColor,
-            mediaVideoItem1.removeEffect(effectColor.getId()));
-        assertTrue("Effect List Size",
-            (mediaVideoItem1.getAllEffects().size() == 0) ? true : false);
-        assertNull("Effect Item by ID", mediaVideoItem1.getEffect("effectId"));
-    }
-
-    /**
-     * To Test the Media Video API : Get Before and after transition
-     */
-
-    @LargeTest
-    public void testMediaVideoItemTransitions() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final int videoItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-        assertNull("Begin Transition", mediaVideoItem1.getBeginTransition());
-        assertNull("End Transition", mediaVideoItem1.getEndTransition());
-
-        TransitionFadeBlack transition1 =
-            mVideoEditorHelper.createTFadeBlack("transition1", mediaVideoItem1,
-            null, 0, Transition.BEHAVIOR_SPEED_UP);
-        mVideoEditor.addTransition(transition1);
-        assertEquals("Begin transition", transition1,
-            mediaVideoItem1.getEndTransition());
-
-        assertNotNull("End Transition", mediaVideoItem1.getEndTransition());
-        assertTrue(mediaVideoItem1.
-            getEndTransition().getId().equals(transition1.getId()));
-        assertTrue(mediaVideoItem1.getEndTransition().getDuration() ==
-            transition1.getDuration() ? true : false);
-        assertTrue(mediaVideoItem1.getEndTransition().getBehavior() ==
-            transition1.getBehavior() ? true : false);
-
-        TransitionFadeBlack transition2 = mVideoEditorHelper.createTFadeBlack(
-            "transition2", null,mediaVideoItem1, 0, Transition.BEHAVIOR_LINEAR);
-        mVideoEditor.addTransition(transition2);
-        assertNotNull("Begin transition", mediaVideoItem1.getBeginTransition());
-        assertEquals("End Transition", transition2,
-            mediaVideoItem1.getBeginTransition());
-        assertTrue(mediaVideoItem1.
-            getBeginTransition().getId().equals(transition2.getId()));
-        assertTrue(mediaVideoItem1. getBeginTransition().getDuration() ==
-            transition2.getDuration() ? true : false);
-        assertTrue(mediaVideoItem1.getBeginTransition().getBehavior() ==
-            transition2.getBehavior() ? true : false);
-    }
-
-    /**
-     * To Test the Media Video API : Get All Overlay, Get Overlay and remove Overlay
-     *
-     */
-
-    @LargeTest
-    public void testMediaVideoItemOverlays() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final String overlayItemFileName = INPUT_FILE_PATH +
-            "IMG_176x144_Overlay1.png";
-        final int videoItemRenderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        assertTrue("Overlay List Size",
-            (mediaVideoItem1.getAllOverlays().size() == 0) ? true : false);
-        assertNull("Overlay Item by ID", mediaVideoItem1.getOverlay("xyz"));
-
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayItemFileName,
-            176, 144);
-        final OverlayFrame overlayFrame = mVideoEditorHelper.createOverlay(
-            mediaVideoItem1, "overlayId", mBitmap, 5000, 5000);
-        mediaVideoItem1.addOverlay(overlayFrame);
-
-        assertTrue("Overlay List Size",
-            (mediaVideoItem1.getAllOverlays().size() == 1) ? true : false);
-        assertEquals("Overlay Item by Valid ID", overlayFrame, mediaVideoItem1
-            .getOverlay(overlayFrame.getId()));
-        assertNull("Overlay Item by Invalid ID",
-            mediaVideoItem1.getOverlay("xyz"));
-        assertNull("Overlay Item by Invalid ID",
-            mediaVideoItem1.removeOverlay("xyz"));
-        assertTrue("Overlay List Size",
-            (mediaVideoItem1.getAllOverlays().size() == 1) ? true : false);
-        assertEquals("Overlay Removed", overlayFrame,
-            mediaVideoItem1.removeOverlay(overlayFrame.getId()));
-        assertTrue("Overlay List Size",
-            (mediaVideoItem1.getAllOverlays().size() == 0) ? true : false);
-        assertNull("Overlay Item by ID",mediaVideoItem1.getOverlay("effectId"));
-    }
-
-    /**
-     * To Test Creation of Media Image Item.
-     */
-    @LargeTest
-    public void testMediaImageItem() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-                imageItemFileName, 5000, imageItemRenderingMode);
-        assertTrue("Media Image ID",
-            mediaImageItem1.getId().equals("mediaImageItem1"));
-        assertTrue("Media IMage Filename",
-            mediaImageItem1.getFilename().equals(imageItemFileName));
-        assertEquals("Media Image Rendering Mode",
-            imageItemRenderingMode, mediaImageItem1.getRenderingMode());
-        assertEquals("Media Image Item Duration", mediaImageItem1.getDuration(),
-            mediaImageItem1.getTimelineDuration());
-        assertEquals("Media Image Overlay", 0,
-            mediaImageItem1.getAllOverlays().size());
-        assertEquals("Media Image Effect", 0,
-            mediaImageItem1.getAllEffects().size());
-        assertNull("Media Image Begin transition",
-            mediaImageItem1.getBeginTransition());
-        assertNull("Media Image End transition",
-            mediaImageItem1.getEndTransition());
-        assertEquals("Media Image Scaled Height", MediaProperties.HEIGHT_720,
-            mediaImageItem1.getScaledHeight());
-        assertEquals("Media Image Scaled Width", 960,
-            mediaImageItem1.getScaledWidth());
-        assertEquals("Media Image Aspect Ratio", MediaProperties.ASPECT_RATIO_4_3,
-            mediaImageItem1.getAspectRatio());
-        assertNotNull("Media Image Thumbnail",
-            mediaImageItem1.getThumbnail(960, MediaProperties.HEIGHT_720, 2000));
-    }
-
-    /**
-     * To Test the Media Image API : Get and Set rendering Mode
-     */
-    @LargeTest
-    public void testMediaImageItemRenderingModes() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final int imageItemRenderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-            imageItemFileName, imageItemRenderingMode, 5000);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        mediaImageItem1.setRenderingMode(MediaItem.RENDERING_MODE_CROPPING);
-        assertEquals("MediaVideo Item rendering Mode",
-            MediaItem.RENDERING_MODE_CROPPING, mediaImageItem1.getRenderingMode());
-        try {
-            mediaImageItem1.setRenderingMode(
-                MediaItem.RENDERING_MODE_CROPPING + 911);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Item Invalid rendering Mode", flagForException);
-
-        flagForException = false;
-        try {
-            mediaImageItem1.setRenderingMode(
-                MediaItem.RENDERING_MODE_BLACK_BORDER - 11);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Media Item Invalid rendering Mode", flagForException);
-
-        assertEquals("MediaVideo Item rendering Mode",
-            MediaItem.RENDERING_MODE_CROPPING,
-            mediaImageItem1.getRenderingMode());
-        mediaImageItem1.setRenderingMode(MediaItem.RENDERING_MODE_STRETCH);
-        assertEquals("MediaVideo Item rendering Mode",
-            MediaItem.RENDERING_MODE_STRETCH,
-            mediaImageItem1.getRenderingMode());
-    }
-
-    /**
-     * To Test the Media Image API : GetHeight and GetWidth
-     */
-    @LargeTest
-    public void testMediaImageItemHeightWidth() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-            imageItemFileName, imageItemRenderingMode, 5000);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        assertEquals("Image Height = Image Scaled Height",
-            mediaImageItem1.getScaledHeight(), mediaImageItem1.getHeight());
-        assertEquals("Image Width = Image Scaled Width",
-            mediaImageItem1.getScaledWidth(), mediaImageItem1.getWidth());
-    }
-
-
-
-/**    This Test Case can be removed as this is already checked in TC 010 */
-    /**
-     * To Test the Media Image API : Scaled Height and Scaled GetWidth
-     */
-    @LargeTest
-    public void testMediaImageItemScaledHeightWidth() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-            imageItemFileName, imageItemRenderingMode, 5000);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        assertNotSame("Image Height = Image Scaled Height",
-            mediaImageItem1.getScaledHeight(), mediaImageItem1.getHeight());
-        assertNotSame("Image Width = Image Scaled Width",
-            mediaImageItem1.getScaledWidth(), mediaImageItem1.getWidth());
-    }
-
-    /**
-     * To Test the Media Image API : Get Effect, GetAllEffects, remove Effect
-     */
-
-    @LargeTest
-    public void testMediaImageItemEffect() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-            imageItemFileName, 5000, imageItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        assertTrue("Effect List Size",
-            (mediaImageItem1.getAllEffects().size() == 0) ? true : false);
-        assertNull("Effect Item by ID", mediaImageItem1.getEffect("xyx"));
-
-        final EffectColor effectColor =
-            mVideoEditorHelper.createEffectItem(mediaImageItem1,
-            "Effecton MVi1", 0, 4000, EffectColor.TYPE_GRADIENT, EffectColor.GRAY);
-        mediaImageItem1.addEffect(effectColor);
-
-        assertTrue("Effect List Size",
-            (mediaImageItem1.getAllEffects().size() == 1) ? true : false);
-        assertEquals("Effect Item by Valid ID",
-            effectColor, mediaImageItem1.getEffect(effectColor.getId()));
-        assertNull("Effect Item by Invalid ID",
-            mediaImageItem1.getEffect("xyz"));
-        assertNull("Effect Item by Invalid ID",
-            mediaImageItem1.removeEffect("effectId"));
-        assertTrue("Effect List Size",
-            (mediaImageItem1.getAllEffects().size() == 1) ? true : false);
-        assertEquals("Effect Removed", effectColor,
-            mediaImageItem1.removeEffect(effectColor.getId()));
-        assertTrue("Effect List Size",
-            (mediaImageItem1.getAllEffects().size() == 0) ? true : false);
-        assertNull("Effect Item by ID", mediaImageItem1.getEffect("effectId"));
-    }
-
-    /**
-     * To Test the Media Image API : Get Before and after transition
-     */
-
-    @LargeTest
-    public void testMediaImageItemTransitions() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-            imageItemFileName, 5000, imageItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        assertNull("Begin Transition", mediaImageItem1.getBeginTransition());
-        assertNull("End Transition", mediaImageItem1.getEndTransition());
-
-        TransitionFadeBlack transition1 =
-            mVideoEditorHelper.createTFadeBlack("transition1", mediaImageItem1,
-            null, 0, Transition.BEHAVIOR_SPEED_UP);
-        mVideoEditor.addTransition(transition1);
-
-        assertEquals("Begin transition", transition1,
-            mediaImageItem1.getEndTransition());
-        assertNotNull("End Transition", mediaImageItem1.getEndTransition());
-        assertTrue(mediaImageItem1.getEndTransition().getId().equals
-            (transition1.getId()));
-        assertTrue(mediaImageItem1.getEndTransition().getDuration() ==
-            transition1.getDuration() ? true : false);
-        assertTrue(mediaImageItem1.getEndTransition().getBehavior() ==
-            transition1.getBehavior() ? true : false);
-
-        TransitionFadeBlack transition2 = mVideoEditorHelper.createTFadeBlack(
-            "transition2",null, mediaImageItem1, 0, Transition.BEHAVIOR_SPEED_UP);
-        mVideoEditor.addTransition(transition2);
-
-        assertNotNull("Begin transition", mediaImageItem1.getBeginTransition());
-        assertEquals("End Transition", transition2,
-            mediaImageItem1.getBeginTransition());
-        assertTrue(mediaImageItem1.getBeginTransition().getId().equals(
-            transition2.getId()));
-        assertTrue(mediaImageItem1.getBeginTransition().getDuration() ==
-            transition2.getDuration() ? true : false);
-        assertTrue(mediaImageItem1.getBeginTransition().getBehavior() ==
-            transition2.getBehavior() ? true : false);
-    }
-
-    /**
-     * To Test the Media Image API : Get All Overlay, Get Overlay and remove
-     * Overlay
-     */
-
-    @LargeTest
-    public void testMediaImageItemOverlays() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String overlayItemFileName = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay1.png";
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-            imageItemFileName, 12000, imageItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        assertTrue("Overlay List Size",
-            (mediaImageItem1.getAllOverlays().size() == 0) ? true : false);
-        assertNull("Overlay Item by ID", mediaImageItem1.getOverlay("xyz"));
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayItemFileName,
-            640, 480);
-        final OverlayFrame overlayFrame =
-            mVideoEditorHelper.createOverlay(mediaImageItem1, "overlayId",
-            mBitmap, 5000, 5000);
-        mediaImageItem1.addOverlay(overlayFrame);
-
-        assertTrue("Overlay List Size",
-            (mediaImageItem1.getAllOverlays().size() == 1) ? true : false);
-        assertEquals("Overlay Item by Valid ID", overlayFrame, mediaImageItem1
-            .getOverlay(overlayFrame.getId()));
-        assertNull("Overlay Item by Invalid ID",
-            mediaImageItem1.getOverlay("xyz"));
-        assertNull("Remove Overlay Item by Invalid ID",
-            mediaImageItem1.removeOverlay("xyz"));
-        assertTrue("Overlay List Size",
-            (mediaImageItem1.getAllOverlays().size() == 1) ? true : false);
-        assertEquals("Overlay Removed",
-            overlayFrame, mediaImageItem1.removeOverlay(overlayFrame.getId()));
-        assertTrue("Overlay List Size",
-            (mediaImageItem1.getAllOverlays().size() == 0) ? true : false);
-        assertNull("Overlay Item by ID",
-            mediaImageItem1.getOverlay("effectId"));
-    }
-
-    /**
-     * To test creation of Audio Track
-     */
-
-    @LargeTest
-    public void testAudioTrack() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        assertEquals("Audio Track Item Duration", audioTrack.getDuration(),
-            audioTrack.getTimelineDuration());
-        assertEquals("Audio Track Start Time", 0, audioTrack.getStartTime());
-        assertFalse("Audio Track is Looping", audioTrack.isLooping());
-        audioTrack.getVolume();
-        assertFalse("Audio Track Ducking is Disabled",
-            audioTrack.isDuckingEnabled());
-        assertTrue("Audio Track Filename",
-            audioTrack.getFilename().equals(audioFileName));
-         assertEquals("Audio Ducking Threshold", 0,
-            audioTrack.getDuckingThreshhold());
-         assertFalse("Audio Track Mute", audioTrack.isMuted());
-         audioTrack.getDuckedTrackVolume();
-    }
-
-    /**
-     * To test creation of Audio Track with set extract boundaries
-     */
-    @LargeTest
-    public void testAudioTrackExtractBoundaries() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        boolean flagForException = false;
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        audioTrack.setExtractBoundaries(1000, 5000);
-        assertEquals("Audio Track Start time", 1000,
-            audioTrack.getBoundaryBeginTime());
-        assertEquals("Audio Track End time", 5000,
-            audioTrack.getBoundaryEndTime());
-        try {
-            audioTrack.setExtractBoundaries(0, 100000000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Audio Track With endTime > FileDuration", flagForException);
-        flagForException = false;
-        try {
-            audioTrack.setExtractBoundaries(100000000, 5000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Audio Track With startTime > FileDuration",
-            flagForException);
-        flagForException = false;
-        try {
-            audioTrack.setExtractBoundaries(0, 0);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        /* This is under discussion.  Hence, checked for False */
-        assertFalse("Audio Track With startTime = endTime", flagForException);
-        assertEquals("Audio Track Start time", 0,
-            audioTrack.getBoundaryBeginTime());
-        assertEquals("Audio Track End time", 0,
-            audioTrack.getBoundaryEndTime());
-        assertEquals("Audio Track Start time",0,
-            audioTrack.getBoundaryBeginTime());
-        assertEquals("Audio Track End time", (audioTrack.getTimelineDuration()),
-            audioTrack.getBoundaryEndTime());
-        audioTrack.setExtractBoundaries(0, audioTrack.getDuration() / 2);
-        assertEquals("Audio Track Start time",0,
-            audioTrack.getBoundaryBeginTime());
-        assertEquals("Audio Track End time", (audioTrack.getDuration() / 2),
-            audioTrack.getBoundaryEndTime());
-        audioTrack.setExtractBoundaries(1, audioTrack.getDuration() - 1);
-        assertEquals("Audio Track Start time", 1,
-            audioTrack.getBoundaryBeginTime());
-        assertEquals("Audio Track End time", (audioTrack.getDuration() - 1),
-            audioTrack.getBoundaryEndTime());
-
-        flagForException = false;
-        try {
-                audioTrack.setExtractBoundaries(0, -1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue ("Audio Track end time < 0",flagForException);
-    }
-
-    /**
-     * To test creation of Audio Track with set Start Time and Get Time
-     */
-    @LargeTest
-    public void testAudioTrackSetGetTime() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        boolean flagForException = false;
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        mVideoEditor.addAudioTrack(audioTrack);
-        /** set StartTime API is removed and start time is always 0 */
-        assertEquals("Audio Track Start Time", 0, audioTrack.getStartTime());
-    }
-
-    /**
-     * To Test the Audio Track API: Enable Ducking
-     */
-    @LargeTest
-    public void testAudioTrackEnableDucking() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        boolean flagForException = false;
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        assertFalse("Audio Ducking Disabled by default",
-            audioTrack.isDuckingEnabled());
-        audioTrack.enableDucking(45, 70);
-        assertTrue("Audio Ducking Enabled", audioTrack.isDuckingEnabled());
-        assertEquals("Audio Ducking Threshold", 45,
-            audioTrack.getDuckingThreshhold());
-        assertEquals("Audio Ducking Volume", 70,
-            audioTrack.getDuckedTrackVolume());
-        audioTrack.enableDucking(85, 70);
-        assertEquals("Audio Ducking Threshold", 85,
-            audioTrack.getDuckingThreshhold());
-        assertEquals("Audio Ducking Volume", 70,
-            audioTrack.getDuckedTrackVolume());
-        try {
-            audioTrack.enableDucking(91, 70);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Enable ducking threshold > 90", flagForException);
-        flagForException = false;
-        try {
-            audioTrack.enableDucking(90, 101);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Enable ducking volume > 100", flagForException);
-        flagForException = false;
-        try {
-            audioTrack.enableDucking(91, 101);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Enable ducking volume > 100 and threshold > 91",
-            flagForException);
-        flagForException = false;
-        try {
-            audioTrack.enableDucking(-1, 100);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Enable ducking threshold < 0", flagForException);
-        flagForException = false;
-        try {
-            audioTrack.enableDucking(1, -1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Enable ducking lowVolume < 0", flagForException);
-        flagForException = false;
-        try {
-            audioTrack.enableDucking(0, 50);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertFalse("Enable ducking threshold = 0", flagForException);
-    }
-
-    /**
-     * To Test the Audio Track API: Looping
-     */
-    @LargeTest
-    public void testAudioTrackLooping() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        mVideoEditor.addAudioTrack(audioTrack);
-        assertFalse("Audio Looping", audioTrack.isLooping());
-        audioTrack.enableLoop();
-        assertTrue("Audio Looping", audioTrack.isLooping());
-        audioTrack.disableLoop();
-        assertFalse("Audio Looping", audioTrack.isLooping());
-    }
-
-    /**
-     * To Test the Audio Track API:Extract waveform data
-     */
-
-    @LargeTest
-    public void testAudioTrackWaveFormData() throws Exception {
-        /** Image item is added as dummy as Audio track cannot be added without
-         * a media item in the story board
-         */
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-            imageItemFileName, 5000, imageItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem);
-
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-
-        mVideoEditor.addAudioTrack(audioTrack);
-        assertNull("WaveForm data", audioTrack.getWaveformData());
-
-        final int[] progressUpdate = new int[105];
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            int i = 0;
-            public void onProgress(Object item, int action, int progress) {
-                progressUpdate[i++] = progress;
-            }
-        });
-
-        final int[] progressWaveform = new int[105];
-
-        audioTrack.extractAudioWaveform(
-            new ExtractAudioWaveformProgressListener() {
-                int i = 0;
-                public void onProgress(int progress) {
-                    Log.i("AudioWaveformData","progress=" +progress);
-                    progressWaveform[i++] = progress;
-            }
-        });
-        assertTrue("Progress of WaveForm data", mVideoEditorHelper
-            .checkProgressCBValues(progressWaveform));
-        assertNotNull("WaveForm data", audioTrack.getWaveformData());
-        assertTrue("WaveForm Frame Duration",
-            (audioTrack.getWaveformData().getFrameDuration() > 0 ?
-            true : false));
-        assertTrue("WaveForm Frame Count",
-            (audioTrack.getWaveformData().getFramesCount() > 0 ? true : false));
-        assertTrue("WaveForm Gain",
-            (audioTrack.getWaveformData().getFrameGains().length > 0 ?
-            true : false));
-    }
-
-    /**
-     * To Test the Audio Track API: Mute
-     */
-    @LargeTest
-    public void testAudioTrackMute() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        assertFalse("Audio Track UnMute", audioTrack.isMuted());
-        audioTrack.setMute(true);
-        assertTrue("Audio Track Mute", audioTrack.isMuted());
-        audioTrack.setMute(false);
-        assertFalse("Audio Track UnMute", audioTrack.isMuted());
-    }
-
-    /**
-     * To Test the Audio Track API: Get Volume and Set Volume
-     */
-    @LargeTest
-    public void testAudioTrackGetSetVolume() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        boolean flagForException = false;
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        audioTrack.setVolume(0);
-        assertEquals("Audio Volume", 0, audioTrack.getVolume());
-        assertFalse("Audio Track UnMute", audioTrack.isMuted());
-        audioTrack.setVolume(45);
-        assertEquals("Audio Volume", 45, audioTrack.getVolume());
-        assertFalse("Audio Track UnMute", audioTrack.isMuted());
-        try {
-            audioTrack.setVolume(-1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Volume = -1", flagForException);
-        assertEquals("Audio Volume", 45, audioTrack.getVolume());
-        flagForException = false;
-        try {
-            audioTrack.setVolume(101);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Volume = 101", flagForException);
-        flagForException = false;
-        try {
-            audioTrack.setVolume(1000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Volume = 10000", flagForException);
-        assertEquals("Audio Volume", 45, audioTrack.getVolume());
-    }
-
-    /**
-     * To test Effect Color.
-     */
-    @LargeTest
-    public void testAllEffects() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_30fps_512Kbps_0_27.mp4";
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final EffectColor effectColor1 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect1", 1000, 1000, EffectColor.TYPE_COLOR,
-            EffectColor.PINK);
-        mediaVideoItem1.addEffect(effectColor1);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor1.getMediaItem());
-        assertTrue("Effect Id", effectColor1.getId().equals("effect1"));
-        assertEquals("Effect StartTime", 1000, effectColor1.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor1.getDuration());
-        assertEquals("Effect Type", EffectColor.TYPE_COLOR,
-            effectColor1.getType());
-        assertEquals("Effect Color", EffectColor.PINK, effectColor1.getColor());
-
-        final EffectColor effectColor2 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect2", 2000, 1000, EffectColor.TYPE_COLOR,
-            EffectColor.GRAY);
-        mediaVideoItem1.addEffect(effectColor2);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor2.getMediaItem());
-        assertTrue("Effect Id", effectColor2.getId().equals("effect2"));
-        assertEquals("Effect StartTime", 2000, effectColor2.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor2.getDuration());
-        assertEquals("Effect Type", EffectColor.TYPE_COLOR,
-            effectColor2.getType());
-        assertEquals("Effect Color", EffectColor.GRAY, effectColor2.getColor());
-
-        final EffectColor effectColor3 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect3", 3000, 1000, EffectColor.TYPE_COLOR,
-            EffectColor.GREEN);
-        mediaVideoItem1.addEffect(effectColor3);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor3.getMediaItem());
-        assertTrue("Effect Id", effectColor3.getId().equals("effect3"));
-        assertEquals("Effect StartTime", 3000, effectColor3.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor3.getDuration());
-        assertEquals("Effect Type", EffectColor.TYPE_COLOR,
-            effectColor3.getType());
-        assertEquals("Effect Color", EffectColor.GREEN, effectColor3.getColor());
-
-        final EffectColor effectColor4 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect4", 4000, 1000, EffectColor.TYPE_GRADIENT,
-            EffectColor.PINK);
-        mediaVideoItem1.addEffect(effectColor4);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor4.getMediaItem());
-        assertTrue("Effect Id", effectColor4.getId().equals("effect4"));
-        assertEquals("Effect StartTime", 4000, effectColor4.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor4.getDuration());
-        assertEquals("Effect Type", EffectColor.TYPE_GRADIENT,
-            effectColor4.getType());
-        assertEquals("Effect Color", EffectColor.PINK, effectColor4.getColor());
-
-        final EffectColor effectColor5 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect5", 5000, 1000,
-            EffectColor.TYPE_GRADIENT, EffectColor.GRAY);
-        mediaVideoItem1.addEffect(effectColor5);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor5.getMediaItem());
-        assertTrue("Effect Id", effectColor5.getId().equals("effect5"));
-        assertEquals("Effect StartTime", 5000, effectColor5.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor5.getDuration());
-        assertEquals("Effect Type", EffectColor.TYPE_GRADIENT,
-            effectColor5.getType());
-        assertEquals("Effect Color", EffectColor.GRAY, effectColor5.getColor());
-
-        final EffectColor effectColor6 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect6", 6000, 1000,
-            EffectColor.TYPE_GRADIENT, EffectColor.GREEN);
-        mediaVideoItem1.addEffect(effectColor6);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor6.getMediaItem());
-        assertTrue("Effect Id", effectColor6.getId().equals("effect6"));
-        assertEquals("Effect StartTime", 6000, effectColor6.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor6.getDuration());
-        assertEquals("Effect Type",
-            EffectColor.TYPE_GRADIENT, effectColor6.getType());
-        assertEquals("Effect Color",
-            EffectColor.GREEN, effectColor6.getColor());
-
-        final EffectColor effectColor7 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect7", 7000, 1000,
-            EffectColor.TYPE_FIFTIES, 0);
-        mediaVideoItem1.addEffect(effectColor7);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor7.getMediaItem());
-        assertTrue("Effect Id", effectColor7.getId().equals("effect7"));
-        assertEquals("Effect StartTime", 7000, effectColor7.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor7.getDuration());
-        assertEquals("Effect Type", EffectColor.TYPE_FIFTIES,
-            effectColor7.getType());
-        assertEquals("Effect Color", -1, effectColor7.getColor());
-
-        final EffectColor effectColor8 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect8", 8000, 1000, EffectColor.TYPE_SEPIA, 0);
-        mediaVideoItem1.addEffect(effectColor8);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor8.getMediaItem());
-        assertTrue("Effect Id", effectColor8.getId().equals("effect8"));
-        assertEquals("Effect StartTime", 8000, effectColor8.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor8.getDuration());
-        assertEquals("Effect Type", EffectColor.TYPE_SEPIA,
-            effectColor8.getType());
-        assertEquals("Effect Color", -1, effectColor8.getColor());
-
-        final EffectColor effectColor9 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect9", 9000, 1000,
-            EffectColor.TYPE_NEGATIVE, 0);
-        mediaVideoItem1.addEffect(effectColor9);
-
-        assertEquals("Associated Media Item", mediaVideoItem1,
-            effectColor9.getMediaItem());
-        assertTrue("Effect Id", effectColor9.getId().equals("effect9"));
-        assertEquals("Effect StartTime", 9000, effectColor9.getStartTime());
-        assertEquals("Effect EndTime", 1000, effectColor9.getDuration());
-        assertEquals("Effect Type", EffectColor.TYPE_NEGATIVE,
-            effectColor9.getType());
-        assertEquals("Effect Color", -1, effectColor9.getColor());
-        try {
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effect9",
-                9000, 1000, EffectColor.TYPE_COLOR - 1, 0);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect type Invalid", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effect9",
-                9000, 1000, EffectColor.TYPE_FIFTIES + 1, 0);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect type Invalid", flagForException);
-        try {
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effect10",
-                10000, 1000, EffectColor.TYPE_FIFTIES +
-                EffectColor.TYPE_GRADIENT, 0);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect type Invalid", flagForException);
-    }
-
-    /**
-     * To test Effect Color : Set duration and Get Duration
-     */
-    @LargeTest
-    public void testEffectSetgetDuration() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_30fps_512Kbps_0_27.mp4";
-        final int videoItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final EffectColor effectColor1 = mVideoEditorHelper.createEffectItem(
-            mediaVideoItem1, "effect1", 1000, 2000,
-            EffectColor.TYPE_COLOR, EffectColor.PINK);
-        mediaVideoItem1.addEffect(effectColor1);
-
-        effectColor1.setDuration(5000);
-        assertEquals("Updated Effect Duration", 5000,
-            effectColor1.getDuration());
-        try {
-            effectColor1.setDuration(mediaVideoItem1.getDuration() + 1000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect Color duration > mediaVideoItemDuration",
-            flagForException);
-        assertEquals("Effect Duration", 5000, effectColor1.getDuration());
-        flagForException = false;
-        try {
-            effectColor1.setDuration(-1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect Color duration = -1", flagForException);
-    }
-
-    /**
-     * To test Effect Color : UNDEFINED color param value
-     */
-    @LargeTest
-    public void testEffectUndefinedColorParam() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_30fps_512Kbps_0_27.mp4";
-        final int videoItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-        try{
-        mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effect1", 1000,
-            2000, EffectColor.TYPE_COLOR, 0xabcdabcd);
-        }catch (IllegalArgumentException e){
-            flagForException = true;
-        }
-        assertTrue("Invalid Effect added",flagForException);
-    }
-
-    /**
-     * To test Effect Color : with Invalid StartTime and Duration
-     */
-    @LargeTest
-    public void testEffectInvalidStartTimeAndDuration() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_32kbps_m_1_17.3gp";
-        final int videoItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-            videoItemFileName, videoItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        try {
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effect1",
-                400000000, 2000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect with invalid StartTime", flagForException);
-
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effect1", -1,
-                2000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect with invalid StartTime", flagForException);
-
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effect1",
-                2000, -1, EffectColor.TYPE_COLOR, EffectColor.GREEN);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect with invalid Duration", flagForException);
-    }
-
-
-    /** Test cases 29, 30, 31, 32 and 33 are removed */
-
-
-    /**
-     * To test Effect : with NULL Media Item
-     */
-    @LargeTest
-    public void testEffectNullMediaItem() throws Exception {
-        boolean flagForException = false;
-        try {
-            mVideoEditorHelper.createEffectItem(null, "effect1", 1000, 4000,
-                EffectColor.TYPE_COLOR, EffectColor.GREEN);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Effect with null MediaItem", flagForException);
-    }
-
-    /**
-     * To test Effect : KenBurn Effect
-     */
-    @LargeTest
-    public void testEffectKenBurn() throws Exception {
-        // Test ken burn effect using a JPEG file.
-        testEffectKenBurn(INPUT_FILE_PATH + "IMG_640x480.jpg",
-         "mediaImageItem1");
-
-        // Test ken burn effect using a PNG file
-        testEffectKenBurn(INPUT_FILE_PATH + "IMG_640x480.png",
-         "mediaImageItem2");
-    }
-
-    private void testEffectKenBurn(final String imageItemFileName,
-     final String MediaId) throws Exception {
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, MediaId,
-            imageItemFileName, 5000, imageItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem);
-
-        final Rect startRect = new Rect((mediaImageItem.getHeight() / 3),
-            (mediaImageItem.getWidth() / 3), (mediaImageItem.getHeight() / 2),
-            (mediaImageItem.getWidth() / 2));
-        final Rect endRect = new Rect(0, 0, mediaImageItem.getWidth(),
-            mediaImageItem.getHeight());
-
-        final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
-            mediaImageItem, "KBOnM2", startRect, endRect, 500, 3000);
-
-        assertNotNull("EffectKenBurns: " + imageItemFileName,
-            kbEffectOnMediaItem);
-
-        mediaImageItem.addEffect(kbEffectOnMediaItem);
-        assertEquals("KenBurn Start Rect: " + imageItemFileName, startRect,
-            kbEffectOnMediaItem.getStartRect());
-
-        assertEquals("KenBurn End Rect: " + imageItemFileName, endRect,
-            kbEffectOnMediaItem.getEndRect());
-    }
-
-    /**
-     * To test KenBurnEffect : Set StartRect and EndRect
-     */
-
-    @LargeTest
-    public void testEffectKenBurnSet() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int imageItemRenderingMode =MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-            imageItemFileName, 5000, imageItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem);
-
-        final Rect startRect = new Rect((mediaImageItem.getHeight() / 3),
-            (mediaImageItem.getWidth() / 3), (mediaImageItem.getHeight() / 2),
-            (mediaImageItem.getWidth() / 2));
-        final Rect endRect = new Rect(0, 0, mediaImageItem.getWidth(),
-            mediaImageItem.getHeight());
-
-        EffectKenBurns kbEffectOnMediaItem=null;
-        kbEffectOnMediaItem = new EffectKenBurns(mediaImageItem, "KBOnM2",
-            startRect, endRect, 500, 3000);
-
-        assertNotNull("EffectKenBurns", kbEffectOnMediaItem);
-        mediaImageItem.addEffect(kbEffectOnMediaItem);
-        assertEquals("KenBurn Start Rect", startRect,
-            kbEffectOnMediaItem.getStartRect());
-        assertEquals("KenBurn End Rect", endRect,
-            kbEffectOnMediaItem.getEndRect());
-
-        final Rect startRect1 = new Rect((mediaImageItem.getHeight() / 5),
-            (mediaImageItem.getWidth() / 5), (mediaImageItem.getHeight() / 4),
-            (mediaImageItem.getWidth() / 4));
-        final Rect endRect1 = new Rect(10, 10, mediaImageItem.getWidth() / 4,
-            mediaImageItem.getHeight() / 4);
-
-        /* Added newly to take care of removal set APIs */
-        kbEffectOnMediaItem = new EffectKenBurns(mediaImageItem, "KBOnM2_changed",
-            startRect1, endRect1, 500, 3000);
-
-        assertEquals("KenBurn Start Rect", startRect1,
-            kbEffectOnMediaItem.getStartRect());
-        assertEquals("KenBurn End Rect", endRect1,
-            kbEffectOnMediaItem.getEndRect());
-
-        final Rect zeroRect = new Rect(0, 0, 0, 0);
-        try {
-            kbEffectOnMediaItem = new EffectKenBurns(mediaImageItem, "KBOnM2_zeroStart",
-                zeroRect, endRect, 500, 3000);
-
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Invalid Start Rect", flagForException);
-
-        flagForException = false;
-        try {
-            kbEffectOnMediaItem = new EffectKenBurns(mediaImageItem, "KBOnM2_zeroEnd",
-                startRect, zeroRect, 500, 3000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Invalid End Rect", flagForException);
-    }
-
-    /**
-     * To test Transition : Fade To Black with all behavior
-     * SPEED_UP/SPEED_DOWN/LINEAR/MIDDLE_SLOW/MIDDLE_FAST
-     */
-
-    @LargeTest
-    public void testTransitionFadeBlack() throws Exception {
-
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String videoItemFilename2 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_15fps_128kbps_1_35.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String videoItemFilename3 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final String videoItemFilename4 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_256kbps_0_30.mp4";
-        final String videoItemFilename5 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_10fps_96kbps_0_25.3gp";
-        boolean flagForException = false;
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-            videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-            videoItemFilename2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem2.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final TransitionFadeBlack transition1And2 = mVideoEditorHelper
-            .createTFadeBlack("transition1And2", mediaVideoItem1,
-            mediaVideoItem2, 3000, Transition.BEHAVIOR_SPEED_UP);
-        mVideoEditor.addTransition(transition1And2);
-
-        assertTrue("Transition ID",
-            transition1And2.getId().equals("transition1And2"));
-        assertEquals("Transtion After Media item",
-            mediaVideoItem1, transition1And2.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem2,
-            transition1And2.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 3000, transition1And2.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_SPEED_UP,
-            transition1And2.getBehavior());
-
-        final MediaImageItem mediaImageItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                imageItemFilename1, 15000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem3);
-
-        final TransitionFadeBlack transition2And3 =
-            mVideoEditorHelper.createTFadeBlack("transition2And3", mediaVideoItem2,
-                mediaImageItem3, 1000, Transition.BEHAVIOR_SPEED_DOWN);
-        mVideoEditor.addTransition(transition2And3);
-
-        assertTrue("Transition ID",
-            transition2And3.getId().equals("transition2And3"));
-        assertEquals("Transtion After Media item", mediaVideoItem2,
-            transition2And3.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaImageItem3,
-            transition2And3.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 1000, transition2And3.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_SPEED_DOWN,
-            transition2And3.getBehavior());
-
-        final MediaVideoItem mediaVideoItem4 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                videoItemFilename3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem4.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaVideoItem4);
-
-        final TransitionFadeBlack transition3And4 =
-            mVideoEditorHelper.createTFadeBlack("transition3And4", mediaImageItem3,
-                mediaVideoItem4, 5000, Transition.BEHAVIOR_LINEAR);
-        mVideoEditor.addTransition(transition3And4);
-
-        assertTrue("Transition ID",
-            transition3And4.getId().equals("transition3And4"));
-        assertEquals("Transtion After Media item", mediaImageItem3,
-            transition3And4.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem4,
-            transition3And4.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 5000, transition3And4.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_LINEAR,
-            transition3And4.getBehavior());
-
-        final MediaVideoItem mediaVideoItem5 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                videoItemFilename4, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem5);
-
-        final TransitionFadeBlack transition4And5 =
-            mVideoEditorHelper.createTFadeBlack("transition4And5", mediaVideoItem4,
-                mediaVideoItem5, 8000, Transition.BEHAVIOR_MIDDLE_FAST);
-        mVideoEditor.addTransition(transition4And5);
-
-        assertTrue("Transition ID",
-            transition4And5.getId().equals("transition4And5"));
-        assertEquals("Transtion After Media item", mediaVideoItem4,
-            transition4And5.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem5,
-            transition4And5.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 8000, transition4And5.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_MIDDLE_FAST,
-            transition4And5.getBehavior());
-
-        final MediaVideoItem mediaVideoItem6 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m6",
-                videoItemFilename5, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem6.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaVideoItem6);
-
-        final TransitionFadeBlack transition5And6 =
-            mVideoEditorHelper.createTFadeBlack("transition5And6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_SLOW);
-        mVideoEditor.addTransition(transition5And6);
-
-        assertTrue("Transition ID",
-            transition5And6.getId().equals("transition5And6"));
-        assertEquals("Transtion After Media item", mediaVideoItem5,
-            transition5And6.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem6,
-            transition5And6.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 2000, transition5And6.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_MIDDLE_SLOW,
-            transition5And6.getBehavior());
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTFadeBlack("transitiond6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_SPEED_UP - 1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition FadeBlack with Invalid behavior", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTFadeBlack("transitiond6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_FAST + 1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition FadeBlack with Invalid behavior", flagForException);
-    }
-
-    /**
-     * To test Transition : CrossFade with all behavior
-     * SPEED_UP/SPEED_DOWN/LINEAR/MIDDLE_SLOW/MIDDLE_FAST
-     */
-
-    @LargeTest
-    public void testTransitionCrossFade() throws Exception {
-
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String videoItemFilename2 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_15fps_128kbps_1_35.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String videoItemFilename3 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final String videoItemFilename4 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_256kbps_0_30.mp4";
-        final String videoItemFilename5 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_10fps_96kbps_0_25.3gp";
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                videoItemFilename2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem2.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final TransitionCrossfade transition1And2 =
-            mVideoEditorHelper.createTCrossFade("transition1And2", mediaVideoItem1,
-                mediaVideoItem2, 3000, Transition.BEHAVIOR_SPEED_UP);
-        mVideoEditor.addTransition(transition1And2);
-
-        assertTrue("Transition ID",
-            transition1And2.getId().equals("transition1And2"));
-        assertEquals("Transtion After Media item", mediaVideoItem1,
-            transition1And2.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem2,
-            transition1And2.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 3000, transition1And2.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_SPEED_UP,
-            transition1And2.getBehavior());
-
-        final MediaImageItem mediaImageItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                imageItemFilename1, 15000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem3);
-
-        final TransitionCrossfade transition2And3 =
-            mVideoEditorHelper.createTCrossFade("transition2And3", mediaVideoItem2,
-                mediaImageItem3, 1000, Transition.BEHAVIOR_SPEED_DOWN);
-        mVideoEditor.addTransition(transition2And3);
-
-        assertTrue("Transition ID",
-            transition2And3.getId().equals("transition2And3"));
-        assertEquals("Transtion After Media item", mediaVideoItem2,
-            transition2And3.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaImageItem3,
-            transition2And3.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 1000, transition2And3.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_SPEED_DOWN,
-            transition2And3.getBehavior());
-
-        final MediaVideoItem mediaVideoItem4 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                videoItemFilename3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem4.setExtractBoundaries(0, 18000);
-        mVideoEditor.addMediaItem(mediaVideoItem4);
-
-        final TransitionCrossfade transition3And4 =
-            mVideoEditorHelper.createTCrossFade("transition3And4", mediaImageItem3,
-                mediaVideoItem4, 5000, Transition.BEHAVIOR_LINEAR);
-        mVideoEditor.addTransition(transition3And4);
-
-        assertTrue("Transition ID",
-            transition3And4.getId().equals("transition3And4"));
-        assertEquals("Transtion After Media item", mediaImageItem3,
-            transition3And4.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem4,
-            transition3And4.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 5000, transition3And4.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_LINEAR,
-            transition3And4.getBehavior());
-
-        final MediaVideoItem mediaVideoItem5 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                videoItemFilename4, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem5);
-
-        final TransitionCrossfade transition4And5 =
-            mVideoEditorHelper.createTCrossFade("transition4And5", mediaVideoItem4,
-                mediaVideoItem5, 8000, Transition.BEHAVIOR_MIDDLE_FAST);
-        mVideoEditor.addTransition(transition4And5);
-
-        assertTrue("Transition ID",
-            transition4And5.getId().equals("transition4And5"));
-        assertEquals("Transtion After Media item", mediaVideoItem4,
-            transition4And5.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem5,
-            transition4And5.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 8000, transition4And5.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_MIDDLE_FAST,
-            transition4And5.getBehavior());
-
-        final MediaVideoItem mediaVideoItem6 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m6",
-                videoItemFilename5, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem6.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaVideoItem6);
-
-        final TransitionCrossfade transition5And6 =
-            mVideoEditorHelper.createTCrossFade("transition5And6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_SLOW);
-        mVideoEditor.addTransition(transition5And6);
-
-        assertTrue("Transition ID",
-            transition5And6.getId().equals("transition5And6"));
-        assertEquals("Transtion After Media item", mediaVideoItem5,
-            transition5And6.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem6,
-            transition5And6.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 2000, transition5And6.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_MIDDLE_SLOW,
-            transition5And6.getBehavior());
-
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTCrossFade("transitiond6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_SPEED_UP - 1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition FadeBlack with Invalid behavior", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTCrossFade("transitiond6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_FAST + 1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition FadeBlack with Invalid behavior", flagForException);
-    }
-
-    /**
-     * To test Transition : Sliding with all behavior
-     * SPEED_UP/SPEED_DOWN/LINEAR/MIDDLE_SLOW/MIDDLE_FAST and Direction =
-     * DIRECTION_RIGHT_OUT_LEFT_IN
-     * ,DIRECTION_LEFT_OUT_RIGHT_IN,DIRECTION_TOP_OUT_BOTTOM_IN
-     * ,DIRECTION_BOTTOM_OUT_TOP_IN
-     */
-
-    @LargeTest
-    public void testTransitionSliding() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String videoItemFilename2 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_15fps_128kbps_1_35.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH +
-            "IMG_1600x1200.jpg";
-        final String videoItemFilename3 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final String videoItemFilename4 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_256kbps_0_30.mp4";
-        final String videoItemFilename5 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_10fps_96kbps_0_25.3gp";
-        boolean flagForException = false;
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                videoItemFilename2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem2.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final TransitionSliding transition1And2 =
-            mVideoEditorHelper.createTSliding("transition1And2", mediaVideoItem1,
-                mediaVideoItem2, 3000, Transition.BEHAVIOR_SPEED_UP,
-                TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
-        mVideoEditor.addTransition(transition1And2);
-
-        assertTrue("Transition ID",
-            transition1And2.getId().equals("transition1And2"));
-        assertEquals("Transtion After Media item", mediaVideoItem1,
-            transition1And2.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem2,
-            transition1And2.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 3000, transition1And2.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_SPEED_UP,
-            transition1And2.getBehavior());
-        assertEquals("Transition Sliding",
-            TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN,
-            transition1And2.getDirection());
-
-        final MediaImageItem mediaImageItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                imageItemFilename1, 15000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem3);
-
-        final TransitionSliding transition2And3 =
-            mVideoEditorHelper.createTSliding("transition2And3",
-                mediaVideoItem2, mediaImageItem3, 1000,
-                Transition.BEHAVIOR_SPEED_DOWN,
-                TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN);
-        mVideoEditor.addTransition(transition2And3);
-
-        assertTrue("Transition ID",
-            transition2And3.getId().equals("transition2And3"));
-        assertEquals("Transtion After Media item", mediaVideoItem2,
-            transition2And3.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaImageItem3,
-            transition2And3.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 1000, transition2And3.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_SPEED_DOWN,
-            transition2And3.getBehavior());
-        assertEquals("Transition Sliding",
-            TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN,
-            transition2And3.getDirection());
-
-        final MediaVideoItem mediaVideoItem4 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                videoItemFilename3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem4.setExtractBoundaries(0, 18000);
-        mVideoEditor.addMediaItem(mediaVideoItem4);
-
-        final TransitionSliding transition3And4 =
-            mVideoEditorHelper.createTSliding("transition3And4", mediaImageItem3,
-                mediaVideoItem4, 5000, Transition.BEHAVIOR_LINEAR,
-                TransitionSliding.DIRECTION_TOP_OUT_BOTTOM_IN);
-        mVideoEditor.addTransition(transition3And4);
-
-        assertTrue("Transition ID",
-            transition3And4.getId().equals("transition3And4"));
-        assertEquals("Transtion After Media item", mediaImageItem3,
-            transition3And4.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem4,
-            transition3And4.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 5000, transition3And4.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_LINEAR,
-            transition3And4.getBehavior());
-        assertEquals("Transition Sliding",
-            TransitionSliding.DIRECTION_TOP_OUT_BOTTOM_IN,
-            transition3And4.getDirection());
-
-        final MediaVideoItem mediaVideoItem5 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                videoItemFilename4, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem5);
-
-        final TransitionSliding transition4And5 =
-            mVideoEditorHelper.createTSliding("transition4And5", mediaVideoItem4,
-                mediaVideoItem5, 8000, Transition.BEHAVIOR_MIDDLE_FAST,
-                TransitionSliding.DIRECTION_BOTTOM_OUT_TOP_IN);
-        mVideoEditor.addTransition(transition4And5);
-
-        assertTrue("Transition ID",
-            transition4And5.getId().equals("transition4And5"));
-        assertEquals("Transtion After Media item", mediaVideoItem4,
-            transition4And5.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem5,
-            transition4And5.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 8000, transition4And5.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_MIDDLE_FAST,
-            transition4And5.getBehavior());
-        assertEquals("Transition Sliding",
-            TransitionSliding.DIRECTION_BOTTOM_OUT_TOP_IN,
-            transition4And5.getDirection());
-
-        final MediaVideoItem mediaVideoItem6 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m6",
-                videoItemFilename5, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem6.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaVideoItem6);
-
-        final TransitionSliding transition5And6 =
-            mVideoEditorHelper.createTSliding("transition5And6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_SLOW,
-                TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
-        mVideoEditor.addTransition(transition5And6);
-
-        assertTrue("Transition ID",
-            transition5And6.getId().equals("transition5And6"));
-        assertEquals("Transtion After Media item", mediaVideoItem5,
-            transition5And6.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem6,
-            transition5And6.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 2000, transition5And6.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_MIDDLE_SLOW,
-            transition5And6.getBehavior());
-        assertEquals("Transition Sliding",
-            TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN,
-            transition5And6.getDirection());
-
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTSliding("transitiond6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_SLOW,
-                TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN - 1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition Sliding with Invalid Direction", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTSliding("transitiond6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_FAST + 1,
-                TransitionSliding.DIRECTION_BOTTOM_OUT_TOP_IN + 1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition Sliding with Invalid behavior", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTSliding("transitiond6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_SPEED_UP - 1,
-                TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition Sliding with Invalid behavior", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTSliding("transitiond6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_FAST + 1,
-                TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition Sliding with Invalid behavior", flagForException);
-    }
-
-    /**
-     * To test Transition : Alpha with all behavior
-     * SPEED_UP/SPEED_DOWN/LINEAR/MIDDLE_SLOW/MIDDLE_FAST
-     */
-
-    @LargeTest
-    public void testTransitionAlpha() throws Exception {
-
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String videoItemFilename2 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_15fps_128kbps_1_35.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH +
-            "IMG_640x480.jpg";
-        final String videoItemFilename3 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final String videoItemFilename4 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_256kbps_0_30.mp4";
-        final String videoItemFilename5 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_10fps_96kbps_0_25.3gp";
-        final String maskFilename = INPUT_FILE_PATH +
-            "TransitionSpiral_QVGA.jpg";
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                videoItemFilename2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem2.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final TransitionAlpha transition1And2 =
-            mVideoEditorHelper.createTAlpha("transition1And2", mediaVideoItem1,
-            mediaVideoItem2, 3000, Transition.BEHAVIOR_SPEED_UP, maskFilename,
-            10, false);
-        mVideoEditor.addTransition(transition1And2);
-
-        assertTrue("Transition ID",
-            transition1And2.getId().equals("transition1And2"));
-        assertEquals("Transtion After Media item", mediaVideoItem1,
-            transition1And2.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem2,
-            transition1And2.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 3000, transition1And2.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_SPEED_UP,
-            transition1And2.getBehavior());
-        assertTrue("Transition maskFile",
-            transition1And2.getMaskFilename().equals(maskFilename));
-        assertEquals("Transition BlendingPercent", 10,
-            transition1And2.getBlendingPercent());
-        assertFalse("Transition Invert", transition1And2.isInvert());
-
-        final MediaImageItem mediaImageItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                imageItemFilename1, 15000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem3);
-
-        final TransitionAlpha transition2And3 =
-            mVideoEditorHelper.createTAlpha("transition2And3", mediaVideoItem2,
-                mediaImageItem3, 1000, Transition.BEHAVIOR_SPEED_DOWN,
-                maskFilename, 30, false);
-        mVideoEditor.addTransition(transition2And3);
-
-        assertTrue("Transition ID",
-            transition2And3.getId().equals("transition2And3"));
-        assertEquals("Transtion After Media item", mediaVideoItem2,
-            transition2And3.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaImageItem3,
-            transition2And3.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 1000, transition2And3.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_SPEED_DOWN,
-            transition2And3.getBehavior());
-        assertTrue("Transition maskFile",
-            transition2And3.getMaskFilename().equals(maskFilename));
-        assertEquals("Transition BlendingPercent", 30,
-            transition2And3.getBlendingPercent());
-        assertFalse("Transition Invert", transition2And3.isInvert());
-
-        final MediaVideoItem mediaVideoItem4 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                videoItemFilename3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem4.setExtractBoundaries(0, 18000);
-        mVideoEditor.addMediaItem(mediaVideoItem4);
-
-        final TransitionAlpha transition3And4 =
-            mVideoEditorHelper.createTAlpha("transition3And4", mediaImageItem3,
-            mediaVideoItem4, 5000, Transition.BEHAVIOR_LINEAR, maskFilename,
-            50, false);
-        mVideoEditor.addTransition(transition3And4);
-
-        assertTrue("Transition ID",
-            transition3And4.getId().equals("transition3And4"));
-        assertEquals("Transtion After Media item", mediaImageItem3,
-            transition3And4.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem4,
-            transition3And4.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 5000, transition3And4.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_LINEAR,
-            transition3And4.getBehavior());
-        assertTrue("Transition maskFile",
-            transition3And4.getMaskFilename().equals(maskFilename));
-        assertEquals("Transition BlendingPercent", 50,
-            transition3And4.getBlendingPercent());
-        assertFalse("Transition Invert", transition3And4.isInvert());
-
-        final MediaVideoItem mediaVideoItem5 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                videoItemFilename4, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem5);
-
-        final TransitionAlpha transition4And5 =
-            mVideoEditorHelper.createTAlpha("transition4And5", mediaVideoItem4,
-            mediaVideoItem5, 8000, Transition.BEHAVIOR_MIDDLE_FAST,
-            maskFilename, 70, true);
-        mVideoEditor.addTransition(transition4And5);
-
-        assertTrue("Transition ID",
-            transition4And5.getId().equals("transition4And5"));
-        assertEquals("Transtion After Media item", mediaVideoItem4,
-            transition4And5.getAfterMediaItem());
-        assertEquals("Transtion Before Media item", mediaVideoItem5,
-            transition4And5.getBeforeMediaItem());
-        assertEquals("Transtion Duration", 8000, transition4And5.getDuration());
-        assertEquals("Transtion Behavior", Transition.BEHAVIOR_MIDDLE_FAST,
-            transition4And5.getBehavior());
-        assertTrue("Transition maskFile",
-            transition4And5.getMaskFilename().equals(maskFilename));
-        assertEquals("Transition BlendingPercent", 70,
-            transition4And5.getBlendingPercent());
-        assertTrue("Transition Invert", transition4And5.isInvert());
-
-        final MediaVideoItem mediaVideoItem6 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m6",
-                videoItemFilename5, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem6.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaVideoItem6);
-
-        try {
-            mVideoEditorHelper.createTAlpha("transition5And6", mediaVideoItem5,
-                mediaVideoItem6, 2000, Transition.BEHAVIOR_MIDDLE_SLOW,
-                INPUT_FILE_PATH + "imDummyFile.jpg", 70,
-                true);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("MaskFile is not exsisting", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTAlpha("transition5And6", null, null, 2000,
-                Transition.BEHAVIOR_MIDDLE_SLOW, maskFilename, 101, true);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Invalid Blending Percent", flagForException);
-
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTAlpha("transitiond6", mediaVideoItem4,
-                mediaVideoItem5, 2000, Transition.BEHAVIOR_SPEED_UP - 1,
-                maskFilename, 30, false);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition FadeBlack with Invalid behavior", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditorHelper.createTAlpha("transitiond6", mediaVideoItem4,
-                mediaVideoItem5, 2000, Transition.BEHAVIOR_MIDDLE_FAST + 1,
-                maskFilename, 30, false);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Transition FadeBlack with Invalid behavior", flagForException);
-    }
-
-    /**
-     * To test Frame Overlay for Media Video Item
-     */
-
-    @LargeTest
-    public void testFrameOverlayVideoItem() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_10fps_256kbps_0_25.3gp";
-        final String overlayFile1 = INPUT_FILE_PATH +  "IMG_176x144_Overlay1.png";
-        final String overlayFile2 = INPUT_FILE_PATH +  "IMG_176x144_Overlay2.png";
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final Bitmap mBitmap1 =  mVideoEditorHelper.getBitmap(overlayFile1,
-            176, 144);
-        final OverlayFrame overlayFrame1 = mVideoEditorHelper.createOverlay(
-            mediaVideoItem1, "overlayId1", mBitmap1, 5000, 5000);
-        mediaVideoItem1.addOverlay(overlayFrame1);
-
-        assertEquals("Overlay : Media Item", mediaVideoItem1,
-            overlayFrame1.getMediaItem());
-        assertTrue("Overlay Id", overlayFrame1.getId().equals("overlayId1"));
-        assertEquals("Overlay Bitmap", mBitmap1, overlayFrame1.getBitmap());
-        assertEquals("Overlay Start Time", 5000, overlayFrame1.getStartTime());
-        assertEquals("Overlay Duration", 5000, overlayFrame1.getDuration());
-
-        Bitmap upddateBmp = mVideoEditorHelper.getBitmap(overlayFile2, 176, 144);
-        overlayFrame1.setBitmap(upddateBmp);
-        assertEquals("Overlay Update Bitmap", upddateBmp, overlayFrame1.getBitmap());
-        upddateBmp.recycle();
-    }
-
-    /**
-     * To test Frame Overlay for Media Video Item : Set duration and Get
-     * Duration
-     */
-
-    @LargeTest
-    public void testFrameOverlaySetAndGet() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_30fps_512Kbps_0_27.mp4";
-        final String overlayFile1 = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-        boolean flagForException = false;
-
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1,
-            640, 480);
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-            videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final OverlayFrame overlayFrame1 = mVideoEditorHelper.createOverlay(
-            mediaVideoItem1, "overlayId1", mBitmap, 5000, 5000);
-        mediaVideoItem1.addOverlay(overlayFrame1);
-        overlayFrame1.setDuration(5000);
-
-        assertEquals("Overlay Duration", 5000, overlayFrame1.getDuration());
-        try {
-            overlayFrame1.setDuration(mediaVideoItem1.getDuration() + 10000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay Duration > MediaVideo Item Duration",
-            flagForException);
-
-        assertEquals("Overlay Duration", 5000, overlayFrame1.getDuration());
-        flagForException = false;
-
-        try {
-            overlayFrame1.setDuration(-1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay Duration = -1", flagForException);
-    }
-
-    /**
-     * To test Frame Overlay for Media Video Item : Set duration and Get
-     * Duration
-     */
-
-    @LargeTest
-    public void testFrameOverlayInvalidTime() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
-        final String overlayFile1 = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-        boolean flagForException = false;
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        try {
-            final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1,
-                640, 480);
-            mVideoEditorHelper.createOverlay(mediaVideoItem1, "overlayId1",
-                mBitmap, 400000000, 2000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay With Invalid Start Time", flagForException);
-
-        flagForException = false;
-        try {
-            final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1,
-                640, 480);
-            mVideoEditorHelper.createOverlay(mediaVideoItem1, "overlayId2",
-                mBitmap, -1, 2000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay With Invalid Start Time", flagForException);
-
-        flagForException = false;
-        try {
-            final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1,
-            640, 480);
-            mVideoEditorHelper.createOverlay(mediaVideoItem1, "overlayId3",
-                mBitmap, 2000, -1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay With Invalid Start Time", flagForException);
-    }
-
-    /**
-     * To test Frame Overlay for Media Image Item
-     */
-    @LargeTest
-    public void testFrameOverlayImageItem() throws Exception {
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String overlayFile1 = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-        final String overlayFile2 = INPUT_FILE_PATH + "IMG_640x480_Overlay2.png";
-
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                imageItemFilename1, 10000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1, 640,
-            480);
-        final OverlayFrame overlayFrame1 = mVideoEditorHelper.createOverlay(
-            mediaImageItem1, "overlayId1", mBitmap, 5000, 5000);
-        mediaImageItem1.addOverlay(overlayFrame1);
-
-        assertEquals("Overlay : Media Item", mediaImageItem1,
-            overlayFrame1.getMediaItem());
-        assertTrue("Overlay Id", overlayFrame1.getId().equals("overlayId1"));
-        assertEquals("Overlay Bitmap",mBitmap ,overlayFrame1.getBitmap());
-        assertEquals("Overlay Start Time", 5000, overlayFrame1.getStartTime());
-        assertEquals("Overlay Duration", 5000, overlayFrame1.getDuration());
-        Bitmap upddateBmp = mVideoEditorHelper.getBitmap(overlayFile2, 640, 480);
-
-        overlayFrame1.setBitmap(upddateBmp);
-        assertEquals("Overlay Update Bitmap", upddateBmp, overlayFrame1.getBitmap());
-        upddateBmp.recycle();
-    }
-
-    /**
-     * To test Frame Overlay for Media Image Item : Set duration and Get
-     * Duration
-     */
-
-    @LargeTest
-    public void testFrameOverlaySetAndGetImage() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String overlayFile1 = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-        boolean flagForException = false;
-
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, 10000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1,
-            640, 480);
-        final OverlayFrame overlayFrame1 = mVideoEditorHelper.createOverlay(
-            mediaImageItem1, "overlayId1", mBitmap, 5000, 5000);
-        mediaImageItem1.addOverlay(overlayFrame1);
-
-        overlayFrame1.setDuration(5000);
-        assertEquals("Overlay Duration", 5000, overlayFrame1.getDuration());
-
-        try {
-            overlayFrame1.setDuration(mediaImageItem1.getDuration() + 10000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay Duration > Media Item Duration", flagForException);
-        assertEquals("Overlay Duration", 5000, overlayFrame1.getDuration());
-
-        flagForException = false;
-        try {
-            overlayFrame1.setDuration(-1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay Duration = -1", flagForException);
-    }
-
-    /**
-     * To test  Frame Overlay for  Media Image Item :Invalid StartTime and
-     * Duration
-     */
-
-    @LargeTest
-    public void testFrameOverlayInvalidTimeImage() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String overlayFile1 = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-        boolean flagForException = false;
-
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, 10000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        try {
-            final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1,
-                640, 480);
-            mVideoEditorHelper.createOverlay(mediaImageItem1, "overlayId1",
-                mBitmap, 400000000, 2000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay With Invalid Start Time", flagForException);
-
-        flagForException = false;
-        try {
-            final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1,
-                640, 480);
-            mVideoEditorHelper.createOverlay(mediaImageItem1, "overlayId2",
-                mBitmap, -1, 2000);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay With Invalid Start Time", flagForException);
-
-        flagForException = false;
-        try {
-            final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1,
-                640, 480);
-            mVideoEditorHelper.createOverlay(mediaImageItem1, "overlayId3",
-                mBitmap, 2000, -1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Overlay With Invalid Start Time", flagForException);
-    }
-
-    /**
-     * To Test Frame Overlay Media Image Item :JPG File
-     */
-
-    @LargeTest
-    public void testFrameOverlayJPGImage() throws Exception {
-
-        final String imageItemFilename = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String overlayFile1 = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-        boolean flagForException = false;
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                imageItemFilename, 10000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile1, 640,
-            480);
-        mVideoEditorHelper.createOverlay(mediaImageItem1, "overlayId1",
-            mBitmap, 5000, 5000);
-    }
-
-    /**
-     * To test Video Editor API
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testVideoEditorAPI() throws Exception {
-
-        final String videoItemFileName1 = INPUT_FILE_PATH
-            + "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-        final String videoItemFileName2 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
-        final String videoItemFileName3 = INPUT_FILE_PATH
-            + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final String imageItemFileName1 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String imageItemFileName2 = INPUT_FILE_PATH + "IMG_176x144.jpg";
-        final String audioFilename1 = INPUT_FILE_PATH +
-            "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
-        final String audioFilename2 = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        TransitionCrossfade transition2And4;
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName1, renderingMode);
-        mediaVideoItem1.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                videoItemFileName2, renderingMode);
-        mediaVideoItem2.setExtractBoundaries(mediaVideoItem2.getDuration() / 4,
-            mediaVideoItem2.getDuration() / 2);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final MediaVideoItem mediaVideoItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                videoItemFileName3, renderingMode);
-        mediaVideoItem3.setExtractBoundaries(mediaVideoItem3.getDuration() / 2,
-            mediaVideoItem3.getDuration());
-        mVideoEditor.addMediaItem(mediaVideoItem3);
-
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                imageItemFileName1, 5000, renderingMode);
-
-        final MediaImageItem mediaImageItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                imageItemFileName2, 5000, renderingMode);
-
-        List<MediaItem> mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item List Size", 3, mediaList.size());
-
-        mVideoEditor.insertMediaItem(mediaImageItem1, mediaVideoItem2.getId());
-        mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item List Size", 4, mediaList.size());
-        assertEquals("Media item 1", mediaVideoItem1, mediaList.get(0));
-        assertEquals("Media item 2", mediaVideoItem2, mediaList.get(1));
-        assertEquals("Media item 4", mediaImageItem1, mediaList.get(2));
-        assertEquals("Media item 3", mediaVideoItem3, mediaList.get(3));
-
-        mVideoEditor.insertMediaItem(mediaImageItem2, mediaImageItem1.getId());
-        mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item List Size", 5, mediaList.size());
-        assertEquals("Media item 1", mediaVideoItem1, mediaList.get(0));
-        assertEquals("Media item 2", mediaVideoItem2, mediaList.get(1));
-        assertEquals("Media item 4", mediaImageItem1, mediaList.get(2));
-        assertEquals("Media item 5", mediaImageItem2, mediaList.get(3));
-        assertEquals("Media item 3", mediaVideoItem3, mediaList.get(4));
-
-        mVideoEditor.moveMediaItem(mediaVideoItem1.getId(), mediaImageItem2.getId());
-        mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item List Size", 5, mediaList.size());
-        assertEquals("Media item 2", mediaVideoItem2, mediaList.get(0));
-        assertEquals("Media item 4", mediaImageItem1, mediaList.get(1));
-        assertEquals("Media item 5", mediaImageItem2, mediaList.get(2));
-        assertEquals("Media item 1", mediaVideoItem1, mediaList.get(3));
-        assertEquals("Media item 3", mediaVideoItem3, mediaList.get(4));
-
-        assertEquals("Media Item 1", mediaVideoItem1,
-            mVideoEditor.getMediaItem(mediaVideoItem1.getId()));
-
-        flagForException = false;
-        transition2And4 = null;
-        try{
-            transition2And4 = mVideoEditorHelper.createTCrossFade(
-                "transition2And4", mediaVideoItem2, mediaImageItem1, 2000,
-                Transition.BEHAVIOR_MIDDLE_FAST);
-            mVideoEditor.addTransition(transition2And4);
-        }
-        catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertFalse("Transition2and4 cannot be created", flagForException);
-
-
-        TransitionCrossfade transition1And3 = null;
-        flagForException = false;
-        try{
-            transition1And3 = mVideoEditorHelper.createTCrossFade(
-                "transition1And3", mediaVideoItem1, mediaVideoItem2, 5000,
-                Transition.BEHAVIOR_MIDDLE_FAST);
-                mVideoEditor.addTransition(transition1And3);
-            }catch (IllegalArgumentException e) {
-                flagForException = true;
-            }
-        assertTrue("Transition1and3 cannot be created", flagForException);
-
-        List<Transition> transitionList = mVideoEditor.getAllTransitions();
-        assertEquals("Transition List", 1, transitionList.size());
-
-        assertEquals("Transition 2", transition2And4,
-            mVideoEditor.getTransition(transition2And4.getId()));
-
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFilename1);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        List<AudioTrack> audioList = mVideoEditor.getAllAudioTracks();
-        assertEquals("Audio List", 1, audioList.size());
-
-        final AudioTrack audioTrack1 = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack1", audioFilename2);
-        flagForException = false;
-        try {
-            mVideoEditor.addAudioTrack(audioTrack1);
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Audio Track support is 1 ", flagForException);
-
-        flagForException = false;
-        try {
-            mVideoEditor.insertAudioTrack(audioTrack1,"audioTrack");
-        } catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Audio Track supports is 1 ", flagForException);
-
-        assertEquals("Removing AudioTrack", audioTrack,
-            mVideoEditor.removeAudioTrack(audioTrack.getId()));
-
-        assertEquals("Removing transition", transition2And4,
-            mVideoEditor.removeTransition(transition2And4.getId()));
-
-        assertEquals("Removing Media Item", mediaVideoItem2,
-            mVideoEditor.removeMediaItem(mediaVideoItem2.getId()));
-
-        mVideoEditor.setAspectRatio(MediaProperties.ASPECT_RATIO_16_9);
-        assertEquals("Check Aspect Ratio", MediaProperties.ASPECT_RATIO_16_9,
-            mVideoEditor.getAspectRatio());
-
-        long storyBoardDuration = mediaVideoItem1.getTimelineDuration()
-            + mediaVideoItem3.getTimelineDuration()
-            + mediaImageItem1.getDuration()
-            + mediaImageItem2.getDuration();
-        assertEquals("Story Board Duration", storyBoardDuration,
-            mVideoEditor.getDuration());
-    }
-
-    /**
-     * To add Audio Track Greater than MediaItem Duration
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testVideoLessThanAudio() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH
-            + "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-        final String audioTrackFilename = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName1, renderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrackId", audioTrackFilename);
-        mVideoEditor.addAudioTrack(audioTrack);
-        assertEquals("Storyboard = mediaItem Duration",
-            mediaVideoItem1.getDuration(), mVideoEditor.getDuration());
-        assertTrue("Audio Duration > mediaItem Duration",
-            (audioTrack.getDuration() > mediaVideoItem1.getDuration() ?
-            true : false));
-    }
-
-    /**
-     * To test Video Editor API with 1080 P
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testVideoContentHD() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH
-            + "H264_BP_1920x1080_30fps_1200Kbps_1_10.mp4";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final MediaVideoItem mediaVideoItem1;
-        // 1080p resolution is supported on some devices
-        // but not on other devices.
-        // So this test case is not generic and
-        // hence we always assert true
-        boolean flagForException = true;
-        try {
-            mediaVideoItem1 = mVideoEditorHelper.createMediaItem(mVideoEditor,
-                "m1", videoItemFileName1, renderingMode);
-        } catch (IllegalArgumentException e) {
-        }
-        assertTrue("VideoContent 1920x1080", flagForException);
-    }
-
-
-    /**
-     * To test: Remove audio track
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testRemoveAudioTrack() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        boolean flagForException = false;
-
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack1", audioFileName);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        assertEquals("Audio Track Item Duration", audioTrack.getDuration(),
-            audioTrack.getTimelineDuration());
-        assertTrue("Audio Track ID", audioTrack.getId().equals("audioTrack1"));
-        assertNotNull("Remove Audio Track",
-            mVideoEditor.removeAudioTrack("audioTrack1"));
-        try{
-            mVideoEditor.removeAudioTrack("audioTrack1");
-        }catch (IllegalArgumentException e){
-            flagForException = true;
-        }
-        assertTrue("Remove Audio Track not possible", flagForException);
-    }
-
-      /**
-     * To test: Disable ducking
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testAudioDuckingDisable() throws Exception {
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        audioTrack.disableDucking();
-        assertFalse("Audio Track Ducking is Disabled",
-            audioTrack.isDuckingEnabled());
-    }
-
-
-
-      /**
-     * To test: Need a basic test case for the get value for TransitionAlpha
-     *  ( ie. getBlendingPercent, getMaskFilename, isInvert)
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testTransitionAlphaBasic() throws Exception {
-
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String maskFilename = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-        boolean flagForException = false;
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 15000);
-
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2", maskFilename,
-                10000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaImageItem.setDuration(15000);
-
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-        mVideoEditor.addMediaItem(mediaImageItem);
-        final TransitionAlpha transition1And2 =
-            mVideoEditorHelper.createTAlpha("transition1And2", mediaVideoItem1,
-                mediaImageItem, 3000, Transition.BEHAVIOR_SPEED_UP,
-                maskFilename, 10, false);
-        mVideoEditor.addTransition(transition1And2);
-        assertTrue("Transition maskFile",
-            transition1And2.getMaskFilename().equals(maskFilename));
-        assertEquals("Transition BlendingPercent", 10,
-            transition1And2.getBlendingPercent());
-        assertFalse("Transition Invert", transition1And2.isInvert());
-    }
-
-    /**
-     * To test: NULL arguments to the Video Editor APIs
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testNullAPIs() throws Exception {
-
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String maskFilename = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay1.png";
-        final String audioFileName = INPUT_FILE_PATH +
-            "AACLC_48KHz_256Kbps_s_1_17.3gp";
-        boolean flagForException = false;
-
-        try {
-            mVideoEditor.addAudioTrack(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Video Editor with null Audio Track", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditor.addMediaItem(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Video Editor with NULL Image Item ", flagForException);
-        flagForException = false;
-        try {
-            mVideoEditor.addMediaItem(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Video Editor with NULL Video Item ", flagForException);
-
-        MediaVideoItem mediaVideoItem1 = null;
-        try {
-            mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        } catch (IllegalArgumentException e) {
-            assertTrue("Cannot Create Video Item", false);
-        }
-        mediaVideoItem1.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-        flagForException = false;
-        try {
-            mediaVideoItem1.addEffect(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Video with null effect ", flagForException);
-        flagForException = false;
-        try {
-            mediaVideoItem1.addOverlay(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Video with null overlay ", flagForException);
-
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2", maskFilename,
-                10000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaImageItem.setDuration(15000);
-        mVideoEditor.addMediaItem(mediaImageItem);
-        flagForException = false;
-        try {
-            mediaImageItem.addEffect(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Image with null effect ", flagForException);
-        flagForException = false;
-        try {
-            mediaImageItem.addOverlay(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Image with null overlay ", flagForException);
-
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioFileName);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        flagForException = false;
-        try {
-            mVideoEditor.addTransition(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Added null transition ", flagForException);
-
-        flagForException = false;
-        try {
-            mVideoEditor.addTransition(null);
-        } catch(IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Added null transition ", flagForException);
-
-    }
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorExportTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorExportTest.java
deleted file mode 100644
index 69ecf0d..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorExportTest.java
+++ /dev/null
@@ -1,812 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaframeworktest.functional.videoeditor;
-
-import java.io.File;
-
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.media.videoeditor.AudioTrack;
-import android.media.videoeditor.EffectColor;
-import android.media.videoeditor.EffectKenBurns;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.videoeditor.MediaProperties;
-import android.media.videoeditor.MediaVideoItem;
-import android.media.videoeditor.OverlayFrame;
-import android.media.videoeditor.Transition;
-import android.media.videoeditor.TransitionAlpha;
-import android.media.videoeditor.TransitionCrossfade;
-import android.media.videoeditor.TransitionFadeBlack;
-import android.media.videoeditor.TransitionSliding;
-import android.media.videoeditor.VideoEditor;
-import android.media.videoeditor.VideoEditor.ExportProgressListener;
-import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase;
-
-
-import android.util.Log;
-
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
-import com.android.mediaframeworktest.VideoEditorHelper;
-
-public class VideoEditorExportTest extends
-    ActivityInstrumentationTestCase<MediaFrameworkTest> {
-    private final String TAG = "TransitionTest";
-
-    private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
-
-    private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
-
-    private VideoEditor mVideoEditor;
-
-    private VideoEditorHelper mVideoEditorHelper;
-
-    // Declares the annotation for Preview Test Cases
-    public @interface TransitionTests {
-    }
-
-    public VideoEditorExportTest() {
-        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        // setup for each test case.
-        super.setUp();
-        mVideoEditorHelper = new VideoEditorHelper();
-        // Create a random String which will be used as project path, where all
-        // project related files will be stored.
-        final String projectPath =
-            mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
-        mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
-        // Clean the directory created as project path
-        mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
-        System.gc();
-        super.tearDown();
-    }
-
-    /**
-     * To Test export : Merge and Trim different types of Video and Image files
-     */
-    @LargeTest
-    public void testExportMergeTrim() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String videoItemFilename2 = INPUT_FILE_PATH
-            + "H264_BP_640x480_12.5fps_256kbps_AACLC_16khz_24kbps_s_0_26.mp4";
-        final String videoItemFilename3 = INPUT_FILE_PATH
-            + "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-        final String imageItemFilename2 = INPUT_FILE_PATH + "IMG_176x144.jpg";
-        final String imageItemFilename3 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/")
-            + ".3gp";
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(2000, 7000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaImageItem mediaImageItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFilename1, 3000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem2);
-
-        final MediaVideoItem mediaVideoItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                videoItemFilename2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem3.setExtractBoundaries(0, 2000);
-        mVideoEditor.addMediaItem(mediaVideoItem3);
-
-        final MediaVideoItem mediaVideoItem4 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                videoItemFilename3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem4.setExtractBoundaries(mediaVideoItem4.getDuration()-5000,
-            mediaVideoItem4.getDuration());
-        mVideoEditor.addMediaItem(mediaVideoItem4);
-
-        final MediaImageItem mediaImageItem5 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                imageItemFilename2, 4000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem5);
-
-        final MediaImageItem mediaImageItem6 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m6",
-                imageItemFilename3, 2000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem6);
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_720,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (Exception e) {
-            assertTrue("Error in Export" + e.toString(), false);
-        }
-        final long storyBoardDuration = mediaVideoItem1.getTimelineDuration()
-            + mediaImageItem2.getDuration() + mediaVideoItem3.getTimelineDuration()
-            + mediaVideoItem4.getTimelineDuration() + mediaImageItem5.getDuration()
-            + mediaImageItem6.getDuration();
-        mVideoEditorHelper.validateExport(mVideoEditor, outFilename,
-            MediaProperties.HEIGHT_720, 0, storyBoardDuration,
-            MediaProperties.VCODEC_H264, MediaProperties.ACODEC_AAC_LC);
-        mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-    }
-
-    /**
-     *To Test export : With Effect and Overlays on Different Media Items
-     */
-    @LargeTest
-    public void testExportEffectOverlay() throws Exception {
-          final String videoItemFilename1 = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String videoItemFilename2 = INPUT_FILE_PATH
-              + "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_64kps_m_0_27.3gp";
-        final String videoItemFilename3 = INPUT_FILE_PATH
-            + "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-        final String imageItemFilename2 = INPUT_FILE_PATH + "IMG_176x144.jpg";
-        final String imageItemFilename3 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
-
-        final String overlayFile = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(2000, 7000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final EffectColor effectPink =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effectPink",
-                0, 2000, EffectColor.TYPE_COLOR, EffectColor.PINK);
-        mediaVideoItem1.addEffect(effectPink);
-
-        final EffectColor effectNegative =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effectNegative",
-                3000, 4000, EffectColor.TYPE_NEGATIVE, 0);
-        mediaVideoItem1.addEffect(effectNegative);
-
-        final MediaImageItem mediaImageItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFilename1, 3000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem2);
-
-        final EffectColor effectFifties =
-            mVideoEditorHelper.createEffectItem(mediaImageItem2, "effectFifties",
-                0, 3000, EffectColor.TYPE_FIFTIES, 0);
-        mediaImageItem2.addEffect(effectFifties);
-
-        final MediaVideoItem mediaVideoItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                videoItemFilename2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem3);
-        mediaVideoItem3.setExtractBoundaries(0, 8000);
-
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile,
-            640, 480);
-        final OverlayFrame overlayFrame =
-            mVideoEditorHelper.createOverlay(mediaVideoItem3, "overlay",
-                mBitmap, 2000, 5000);
-        mediaVideoItem3.addOverlay(overlayFrame);
-
-        final EffectColor effectGreen =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem3, "effectGreen",
-                0, 2000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
-        mediaVideoItem3.addEffect(effectGreen);
-
-        final MediaVideoItem mediaVideoItem4 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                videoItemFilename3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem4.setExtractBoundaries(mediaVideoItem4.getDuration()-5000,
-            mediaVideoItem4.getDuration());
-        mVideoEditor.addMediaItem(mediaVideoItem4);
-
-        final EffectColor effectSepia =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem4, "effectSepia",
-                0, 2000, EffectColor.TYPE_SEPIA, 0);
-        mediaVideoItem4.addEffect(effectSepia);
-
-        final MediaImageItem mediaImageItem5 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                imageItemFilename2, 4000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem5);
-
-        final EffectColor effectGray =
-            mVideoEditorHelper.createEffectItem(mediaImageItem5, "effectGray",
-                0, 2000, EffectColor.TYPE_COLOR, EffectColor.GRAY);
-        mediaImageItem5.addEffect(effectGray);
-
-        final MediaImageItem mediaImageItem6 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m6",
-                imageItemFilename3, 2000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem6);
-
-        final EffectColor effectGradient =
-            mVideoEditorHelper.createEffectItem(mediaImageItem6,
-                "effectGradient", 0, 2000, EffectColor.TYPE_GRADIENT,
-                EffectColor.PINK);
-        mediaImageItem6.addEffect(effectGradient);
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_720,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (Exception e) {
-            assertTrue("Error in Export" + e.toString(), false);
-        }
-        final long storyBoardDuration = mediaVideoItem1.getTimelineDuration()
-            + mediaImageItem2.getDuration()
-            + mediaVideoItem3.getTimelineDuration()
-            + mediaVideoItem4.getTimelineDuration()
-            + mediaImageItem5.getDuration()
-            + mediaImageItem6.getDuration();
-        mVideoEditorHelper.validateExport(mVideoEditor, outFilename,
-            MediaProperties.HEIGHT_720, 0, storyBoardDuration,
-            MediaProperties.VCODEC_H264, MediaProperties.ACODEC_AAC_LC);
-        mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-    }
-
-    /**
-     * To test export : with Image with KenBurnEffect
-     */
-    @LargeTest
-    public void testExportEffectKenBurn() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int imageItemRenderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
-
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaImageItem1",
-                imageItemFileName, 5000, imageItemRenderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem);
-
-        final Rect startRect = new Rect((mediaImageItem.getHeight() / 3),
-            (mediaImageItem.getWidth() / 3), (mediaImageItem.getHeight() / 2),
-            (mediaImageItem.getWidth() / 2));
-
-        final Rect endRect = new Rect(0, 0, mediaImageItem.getWidth(),
-            mediaImageItem.getHeight());
-
-        final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
-            mediaImageItem, "KBOnM2", startRect, endRect, 500, 3000);
-        assertNotNull("EffectKenBurns", kbEffectOnMediaItem);
-        mediaImageItem.addEffect(kbEffectOnMediaItem);
-
-        assertEquals("KenBurn Start Rect", startRect,
-            kbEffectOnMediaItem.getStartRect());
-        assertEquals("KenBurn End Rect", endRect,
-            kbEffectOnMediaItem.getEndRect());
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_720,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (Exception e) {
-            assertTrue("Error in Export" + e.toString(), false);
-        }
-        mVideoEditorHelper.validateExport(mVideoEditor, outFilename,
-            MediaProperties.HEIGHT_720, 0, mediaImageItem.getDuration(),
-            MediaProperties.VCODEC_H264, MediaProperties.ACODEC_AAC_LC);
-        mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-    }
-
-    /**
-     * To Test Export : With Video and Image and An Audio BackGround Track
-     */
-    @LargeTest
-    public void testExportAudio() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
-        final String audioTrackFilename = INPUT_FILE_PATH +
-            "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFileName, 5000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem);
-
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "a1", audioTrackFilename);
-        audioTrack.setExtractBoundaries(2000, 5000);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        audioTrack.disableDucking();
-        audioTrack.enableLoop();
-        audioTrack.setVolume(75);
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_720,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (Exception e) {
-            assertTrue("Error in Export" + e.toString(), false);
-        }
-        mVideoEditorHelper.validateExport(mVideoEditor, outFilename,
-            MediaProperties.HEIGHT_720, 0, (mediaVideoItem.getTimelineDuration() +
-            mediaImageItem.getDuration()),
-            MediaProperties.VCODEC_H264, MediaProperties.ACODEC_AAC_LC);
-
-        mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-    }
-
-    /**
-     *To Test export : With Transition on Different Media Items
-     */
-    @LargeTest
-    public void testExportTransition() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String videoItemFilename2 = INPUT_FILE_PATH
-            + "H264_BP_640x480_12.5fps_256kbps_AACLC_16khz_24kbps_s_0_26.mp4";
-        final String videoItemFilename3 = INPUT_FILE_PATH +
-            "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-
-        final String imageItemFilename2 = INPUT_FILE_PATH + "IMG_176x144.jpg";
-        final String imageItemFilename3 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
-        final String maskFilename = INPUT_FILE_PATH +
-            "TransitionSpiral_QVGA.jpg";
-
-        final MediaVideoItem mediaItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaItem1.setExtractBoundaries(2000, 7000);
-        mVideoEditor.addMediaItem(mediaItem1);
-
-        final TransitionAlpha transition1 =
-            mVideoEditorHelper.createTAlpha("transition1", null, mediaItem1,
-                2000, Transition.BEHAVIOR_LINEAR, maskFilename, 50, true);
-        mVideoEditor.addTransition(transition1);
-
-        final MediaImageItem mediaItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFilename1, 8000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaItem2);
-
-        final MediaVideoItem mediaItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                videoItemFilename2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaItem3.setExtractBoundaries(0, 8000);
-        mVideoEditor.addMediaItem(mediaItem3);
-
-        final TransitionSliding transition2And3 =
-            mVideoEditorHelper.createTSliding("transition2", mediaItem2,
-                mediaItem3, 4000, Transition.BEHAVIOR_MIDDLE_FAST,
-                TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
-        mVideoEditor.addTransition(transition2And3);
-
-        final MediaVideoItem mediaItem4 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                videoItemFilename3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaItem4);
-        mediaItem4.setExtractBoundaries(0, 8000);
-
-        final TransitionCrossfade transition3And4 =
-            mVideoEditorHelper.createTCrossFade("transition3", mediaItem3,
-                mediaItem4, 3500, Transition.BEHAVIOR_MIDDLE_SLOW);
-        mVideoEditor.addTransition(transition3And4);
-
-        final MediaImageItem mediaItem5 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                imageItemFilename2, 7000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaItem5);
-
-        final TransitionFadeBlack transition4And5 =
-            mVideoEditorHelper.createTFadeBlack("transition4", mediaItem4,
-                mediaItem5, 3500, Transition.BEHAVIOR_SPEED_DOWN);
-        mVideoEditor.addTransition(transition4And5);
-
-        final MediaImageItem mediaItem6 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m6",
-                imageItemFilename3, 3000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaItem6);
-
-        final TransitionSliding transition5And6 =
-            mVideoEditorHelper.createTSliding("transition5", mediaItem5,
-                mediaItem6, 1000/*4000*/, Transition.BEHAVIOR_SPEED_UP,
-                TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN);
-        mVideoEditor.addTransition(transition5And6);
-
-        final TransitionSliding transition6 =
-            mVideoEditorHelper.createTSliding("transition6", mediaItem6, null,
-                1000 /*4000*/, Transition.BEHAVIOR_SPEED_UP,
-                TransitionSliding.DIRECTION_TOP_OUT_BOTTOM_IN);
-        mVideoEditor.addTransition(transition6);
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_720,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (Exception e) {
-            assertTrue("Error in Export" + e.toString(), false);
-        }
-        final long storyBoardDuration = mediaItem1.getTimelineDuration()
-            + mediaItem2.getTimelineDuration()
-            + mediaItem3.getTimelineDuration() - transition2And3.getDuration()
-            + mediaItem4.getTimelineDuration() - transition3And4.getDuration()
-            + mediaItem5.getTimelineDuration() - transition4And5.getDuration()
-            + mediaItem6.getTimelineDuration() - transition5And6.getDuration();
-        mVideoEditorHelper.validateExport(mVideoEditor, outFilename,
-            MediaProperties.HEIGHT_720, 0, storyBoardDuration,
-            MediaProperties.VCODEC_H264, MediaProperties.ACODEC_AAC_LC);
-        mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-    }
-
-    /**
-     * To Test Export : Without any Media Items in the story Board
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testExportWithoutMediaItems() throws Exception {
-        boolean flagForException = false;
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export("/sdcard/Test.3gp", MediaProperties.HEIGHT_720,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (IllegalStateException e) {
-            flagForException = true;
-        }
-        assertTrue("Export without any MediaItems", flagForException);
-    }
-
-    /**
-     * To Test Export : With Media Items add and removed in the story Board
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testExportWithoutMediaItemsAddRemove() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_1_17.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String maskFilename = INPUT_FILE_PATH + "TransitionSpiral_QVGA.jpg";
-        boolean flagForException = false;
-
-        final MediaVideoItem mediaItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaItem1.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaItem1);
-
-        final MediaImageItem mediaItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFilename1, 15000,
-                MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaItem2);
-
-        final TransitionAlpha transition1 =
-            mVideoEditorHelper.createTAlpha("transition1", mediaItem1, mediaItem2,
-                3000, Transition.BEHAVIOR_LINEAR, maskFilename, 50, false);
-        mVideoEditor.addTransition(transition1);
-
-        final EffectColor effectColor =
-            mVideoEditorHelper.createEffectItem(mediaItem2, "effect", 12000,
-                3000, EffectColor.TYPE_COLOR, EffectColor.PINK);
-        mediaItem2.addEffect(effectColor);
-
-        mVideoEditor.removeMediaItem(mediaItem1.getId());
-        mVideoEditor.removeMediaItem(mediaItem2.getId());
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export("/sdcard/Test.3gp", MediaProperties.HEIGHT_720,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (IllegalStateException e) {
-            flagForException = true;
-        }
-        assertTrue("Export with MediaItem added and removed", flagForException);
-    }
-
-    /**
-     * To Test Export : With Video and Image : MMS use case
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testExportMMS() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_1_17.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String videoItemFilename2 = INPUT_FILE_PATH
-            + "H264_BP_640x480_12.5fps_256kbps_AACLC_16khz_24kbps_s_0_26.mp4";
-        final String maskFilename = INPUT_FILE_PATH + "TransitionSpiral_QVGA.jpg";
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
-
-        final MediaVideoItem mediaItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaItem1.setExtractBoundaries(2000, 7000);
-        mVideoEditor.addMediaItem(mediaItem1);
-
-        final TransitionAlpha transition1 =
-            mVideoEditorHelper.createTAlpha("transition1", null, mediaItem1,
-                2000, Transition.BEHAVIOR_LINEAR, maskFilename, 50, true);
-        mVideoEditor.addTransition(transition1);
-
-        final MediaImageItem mediaItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFilename1, 8000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaItem2);
-
-        final MediaVideoItem mediaItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                videoItemFilename2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaItem3.setExtractBoundaries(0, 8000);
-        mVideoEditor.addMediaItem(mediaItem3);
-
-        final TransitionSliding transition2And3 =
-            mVideoEditorHelper.createTSliding("transition2", mediaItem2,
-                mediaItem3, 4000, Transition.BEHAVIOR_MIDDLE_FAST,
-                TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
-        mVideoEditor.addTransition(transition2And3);
-
-        final TransitionCrossfade transition3 =
-            mVideoEditorHelper.createTCrossFade("transition3", mediaItem3, null,
-                3500, Transition.BEHAVIOR_MIDDLE_SLOW);
-        mVideoEditor.addTransition(transition3);
-
-        final EffectColor effectColor =
-            mVideoEditorHelper.createEffectItem(mediaItem2, "effect", 0,
-                3000, EffectColor.TYPE_COLOR, EffectColor.PINK);
-        mediaItem2.addEffect(effectColor);
-
-        mVideoEditor.setAspectRatio(MediaProperties.ASPECT_RATIO_11_9);
-
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (Exception e) {
-            assertTrue("Error in Export" + e.toString(), false);
-        }
-        final long storyBoardDuration = mediaItem1.getTimelineDuration()
-            + mediaItem2.getTimelineDuration() + mediaItem3.getTimelineDuration()
-            - transition2And3.getDuration();
-
-        mVideoEditorHelper.validateExport(mVideoEditor, outFilename,
-            MediaProperties.HEIGHT_144, 0, storyBoardDuration,
-            MediaProperties.VCODEC_H264, MediaProperties.ACODEC_AAC_LC);
-         mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-    }
-
-    /**
-     * To Test Export :Media Item having duration of 1 Hour
-     *
-     * @throws Exception
-     */
-    @Suppress
-    @LargeTest
-    public void testExportDuration1Hour() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_15fps_384kbps_60_0.mp4";
-        final String outFilename = mVideoEditorHelper.createRandomFile(
-            mVideoEditor.getPath() + "/") + ".3gp";
-
-        final MediaVideoItem mediaItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaItem1);
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        }catch (Exception e) {
-            assertTrue("Error in Export" + e.toString(), false);
-        }
-        mVideoEditorHelper.validateExport(mVideoEditor, outFilename,
-            MediaProperties.HEIGHT_720, 0, mediaItem1.getDuration(),
-            MediaProperties.VCODEC_H264, MediaProperties.ACODEC_AAC_LC);
-        mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-    }
-
-    /**
-     * To Test Export : Storage location having very less space (Less than 100
-     * KB)
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testExportWithStorageFull() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH
-            + "H264_BP_640x480_12.5fps_256kbps_AACLC_16khz_24kbps_s_0_26.mp4";
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
-        boolean flagForException = false;
-
-        mVideoEditorHelper.createMediaItem(mVideoEditor, "m1", videoItemFilename1,
-            MediaItem.RENDERING_MODE_BLACK_BORDER);
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (Exception e) {
-            flagForException = true;
-        }
-        assertTrue("Error in exporting file due to lack of storage space",
-            flagForException);
-    }
-
-     /**
-     * To Test Export :Two Media Items added
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testExportTwoVideos() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_1_17.3gp";
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_12.5fps_256kbps_AACLC_16khz_24kbps_s_0_26.mp4";
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                videoItemFileName1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        try {
-            final int[] progressUpdate = new int[100];
-            mVideoEditor.export(outFilename, MediaProperties.HEIGHT_720,
-                MediaProperties.BITRATE_800K, new ExportProgressListener() {
-                    int i = 0;
-                    public void onProgress(VideoEditor ve, String outFileName,
-                        int progress) {
-                            progressUpdate[i++] = progress;
-                    }
-                });
-            mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        } catch (Exception e) {
-            assertTrue("Error in Export" + e.toString(), false);
-        }
-        mVideoEditorHelper.validateExport(mVideoEditor, outFilename,
-            MediaProperties.HEIGHT_720, 0,
-            (mediaVideoItem.getDuration()+ mediaVideoItem1.getDuration()),
-            MediaProperties.VCODEC_H264, MediaProperties.ACODEC_AAC_LC);
-        mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-    }
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorPreviewTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorPreviewTest.java
deleted file mode 100644
index 7965b0a..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorPreviewTest.java
+++ /dev/null
@@ -1,1156 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaframeworktest.functional.videoeditor;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.Semaphore;
-
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.media.videoeditor.AudioTrack;
-import android.media.videoeditor.Effect;
-import android.media.videoeditor.EffectColor;
-import android.media.videoeditor.EffectKenBurns;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.videoeditor.MediaProperties;
-import android.media.videoeditor.MediaVideoItem;
-import android.media.videoeditor.Overlay;
-import android.media.videoeditor.OverlayFrame;
-import android.media.videoeditor.Transition;
-import android.media.videoeditor.TransitionAlpha;
-import android.media.videoeditor.TransitionCrossfade;
-import android.media.videoeditor.TransitionFadeBlack;
-import android.media.videoeditor.TransitionSliding;
-import android.media.videoeditor.VideoEditor;
-import android.media.videoeditor.VideoEditor.ExportProgressListener;
-import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
-import android.media.videoeditor.VideoEditor.PreviewProgressListener;
-import android.media.videoeditor.VideoEditor.OverlayData;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase;
-import android.view.SurfaceHolder;
-
-
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import com.android.mediaframeworktest.VideoEditorHelper;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-
-import java.util.concurrent.TimeUnit;
-
-import android.util.Log;
-
-public class VideoEditorPreviewTest extends
-    ActivityInstrumentationTestCase<MediaFrameworkTest> {
-    private final String TAG = "VideoEditorTest";
-
-    private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
-
-    private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
-
-    private final String PROJECT_CLASS_NAME =
-        "android.media.videoeditor.VideoEditorImpl";
-
-    private VideoEditor mVideoEditor;
-
-    private VideoEditorHelper mVideoEditorHelper;
-
-    private class EventHandler extends Handler {
-        public EventHandler( Looper lp)
-        {
-            super(lp);
-        }
-        public void handleMessage(Message msg)
-        {
-            switch (msg.what)
-            {
-                default:
-                MediaFrameworkTest.testInvalidateOverlay();
-            }
-        }
-    }
-    private EventHandler mEventHandler;
-
-    private boolean previewStart;
-    private boolean previewStop;
-    private boolean previewError;
-
-    /* Minimum waiting time for Semaphore to wait for release */
-    private final long minWaitingTime = 3000;
-
-    // Declares the annotation for Preview Test Cases
-    public @interface Preview {
-    }
-
-    public VideoEditorPreviewTest() {
-        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-
-        Looper looper;
-        if ((looper = Looper.myLooper()) != null) {
-            mEventHandler = new EventHandler(looper);
-
-        } else {
-            //Handle error when looper can not be created.
-            ;
-        }
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        // setup for each test case.
-        super.setUp();
-        mVideoEditorHelper = new VideoEditorHelper();
-        // Create a random String which will be used as project path, where all
-        // project related files will be stored.
-        final String projectPath =
-            mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
-        mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
-        // Clean the directory created as project path
-        mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
-        System.gc();
-        super.tearDown();
-    }
-
-    protected void setPreviewStart() {
-        previewStart = true;
-    }
-    protected void setPreviewStop() {
-        previewStop = true;
-    }
-    protected void setPreviewError() {
-        previewError = true;
-    }
-    protected void validatePreviewProgress(int startMs, int endMs,
-        boolean loop, long duration) throws Exception {
-
-        final int[] progressUpdate = new int[100];
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-        previewStart = false;
-        previewStop = false;
-        previewError = false;
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            int i = 0;
-            public void onProgress(Object item, int action, int progress) {
-                progressUpdate[i++] = progress;
-            }
-        });
-        mVideoEditorHelper.checkProgressCBValues(progressUpdate);
-        final SurfaceHolder surfaceHolder =
-            MediaFrameworkTest.mSurfaceView.getHolder();
-
-        long waitingTime = minWaitingTime;
-        if (endMs == -1) {
-            waitingTime += duration;
-        }
-        else {
-            waitingTime += (endMs - startMs);
-        }
-        blockTillPreviewCompletes.acquire();
-        try {
-        mVideoEditor.startPreview(surfaceHolder, startMs, endMs, loop, 1,
-            new PreviewProgressListener() {
-                public void onProgress(VideoEditor videoEditor, long timeMs,
-                    OverlayData overlayData) {
-
-                        if ( overlayData != null) {
-                            if(overlayData.needsRendering()) {
-                                overlayData.renderOverlay(MediaFrameworkTest.mDestBitmap);
-                                mEventHandler.sendMessage(mEventHandler.obtainMessage(1, 2, 3));
-                            }
-                        }
-                }
-                public void onStart(VideoEditor videoEditor) {
-                    setPreviewStart();
-                }
-                public void onStop(VideoEditor videoEditor) {
-                    setPreviewStop();
-                    blockTillPreviewCompletes.release();
-                }
-                public void onError(VideoEditor videoEditor, int error) {
-                    setPreviewError();
-                    blockTillPreviewCompletes.release();
-                }
-        });
-        } catch (Exception e) {
-            blockTillPreviewCompletes.release();
-        }
-        blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
-
-        mVideoEditor.stopPreview();
-        assertTrue("Preview Failed to start", previewStart);
-        assertTrue("Preview Failed to stop", previewStop);
-        assertFalse("Preview Error occurred", previewError);
-
-        blockTillPreviewCompletes.release();
-    }
-
-    // -----------------------------------------------------------------
-    // Preview
-    // -----------------------------------------------------------------
-
-    /**
-     *To test Preview : FULL Preview of current work (beginning till end)
-     */
-    @LargeTest
-    public void testPreviewTheStoryBoard() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH
-            + "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-        final String videoItemFileName2 = INPUT_FILE_PATH
-            + "MPEG4_SP_640x480_15fps_256kbps_0_30.mp4";
-        final String videoItemFileName3 = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_1_17.3gp";
-        previewStart = false;
-        previewStop = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-                videoItemFileName1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem2",
-                videoItemFileName2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-        mediaVideoItem2.setExtractBoundaries(0, 10000);
-
-        final MediaVideoItem mediaVideoItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem3",
-                videoItemFileName3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem3.setExtractBoundaries(0, 10000);
-
-        mVideoEditor.insertMediaItem(mediaVideoItem3, mediaVideoItem1.getId());
-        List<MediaItem> mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item 1", mediaVideoItem1, mediaList.get(0));
-        assertEquals("Media Item 3", mediaVideoItem3, mediaList.get(1));
-        assertEquals("Media Item 2", mediaVideoItem2, mediaList.get(2));
-
-        mediaVideoItem1.setRenderingMode(MediaItem.RENDERING_MODE_BLACK_BORDER);
-        assertEquals("Media Item 1 Rendering Mode",
-            MediaItem.RENDERING_MODE_BLACK_BORDER,
-            mediaVideoItem1.getRenderingMode());
-
-        mediaVideoItem2.setRenderingMode(MediaItem.RENDERING_MODE_BLACK_BORDER);
-        assertEquals("Media Item 2 Rendering Mode",
-            MediaItem.RENDERING_MODE_BLACK_BORDER,
-            mediaVideoItem2.getRenderingMode());
-
-        mediaVideoItem3.setRenderingMode(MediaItem.RENDERING_MODE_STRETCH);
-        assertEquals("Media Item 3 Rendering Mode",
-            MediaItem.RENDERING_MODE_STRETCH,
-            mediaVideoItem3.getRenderingMode());
-
-        mVideoEditor.setAspectRatio(MediaProperties.ASPECT_RATIO_5_3);
-        assertEquals("Aspect Ratio", MediaProperties.ASPECT_RATIO_5_3,
-            mVideoEditor.getAspectRatio());
-
-        validatePreviewProgress(0, -1, false, mVideoEditor.getDuration());
-    }
-
-    /**
-     * To test Preview : Preview of start + 10 sec till end of story board
-     */
-    @LargeTest
-    public void testPreviewTheStoryBoardFromDuration() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH
-            + "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-        final String videoItemFileName2 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_256kbps_0_30.mp4";
-        final String videoItemFileName3 = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_1_17.3gp";
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-        previewStart = false;
-        previewStop = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-                videoItemFileName1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem2",
-                videoItemFileName2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem2.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final MediaVideoItem mediaVideoItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem3",
-                videoItemFileName3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem3.setExtractBoundaries(0, 10000);
-
-        mVideoEditor.insertMediaItem(mediaVideoItem3, mediaVideoItem1.getId());
-
-        List<MediaItem> mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item 1", mediaVideoItem1, mediaList.get(0));
-        assertEquals("Media Item 3", mediaVideoItem3, mediaList.get(1));
-        assertEquals("Media Item 2", mediaVideoItem2, mediaList.get(2));
-        mediaVideoItem1.setRenderingMode(MediaItem.RENDERING_MODE_BLACK_BORDER);
-
-        assertEquals("Media Item 1 Rendering Mode",
-            MediaItem.RENDERING_MODE_BLACK_BORDER,
-            mediaVideoItem1.getRenderingMode());
-        mediaVideoItem2.setRenderingMode(MediaItem.RENDERING_MODE_BLACK_BORDER);
-
-        assertEquals("Media Item 2 Rendering Mode",
-            MediaItem.RENDERING_MODE_BLACK_BORDER,
-            mediaVideoItem2.getRenderingMode());
-        mediaVideoItem3.setRenderingMode(MediaItem.RENDERING_MODE_STRETCH);
-
-        assertEquals("Media Item 3 Rendering Mode",
-            MediaItem.RENDERING_MODE_STRETCH,
-            mediaVideoItem3.getRenderingMode());
-
-        mVideoEditor.setAspectRatio(MediaProperties.ASPECT_RATIO_5_3);
-        assertEquals("Aspect Ratio", MediaProperties.ASPECT_RATIO_5_3,
-            mVideoEditor.getAspectRatio());
-
-        validatePreviewProgress(10000, -1, false, mVideoEditor.getDuration());
-    }
-
-    /**
-     * To test Preview : Preview of current Effects applied
-     */
-    @LargeTest
-    public void testPreviewOfEffects() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-        previewStart = false;
-        previewStop = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "mediaVideoItem1",
-                videoItemFileName1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final EffectColor effectNegative =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1,
-                "effectNegative", 0, 2000, EffectColor.TYPE_NEGATIVE, 0);
-        mediaVideoItem1.addEffect(effectNegative);
-
-        final EffectColor effectGreen =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "effectGreen",
-                2000, 3000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
-        mediaVideoItem1.addEffect(effectGreen);
-
-        final EffectColor effectFifties =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1,
-                "effectFifties", 5000, 4000, EffectColor.TYPE_FIFTIES, 0);
-        mediaVideoItem1.addEffect(effectFifties);
-
-        List<Effect> effectList = mediaVideoItem1.getAllEffects();
-        assertEquals("Effect List Size", 3, effectList.size());
-        assertEquals("Effect negative", effectNegative, effectList.get(0));
-        assertEquals("Effect Green", effectGreen, effectList.get(1));
-        assertEquals("Effect Fifties", effectFifties, effectList.get(2));
-
-        mVideoEditor.setAspectRatio(MediaProperties.ASPECT_RATIO_4_3);
-        assertEquals("Aspect Ratio", MediaProperties.ASPECT_RATIO_4_3,
-            mVideoEditor.getAspectRatio());
-
-        final long storyboardDuration = mVideoEditor.getDuration() ;
-        validatePreviewProgress(0, (int)(storyboardDuration/2), false, (storyboardDuration/2));
-
-        assertEquals("Removing Effect : Negative", effectNegative,
-            mediaVideoItem1.removeEffect(effectNegative.getId()));
-
-        effectList = mediaVideoItem1.getAllEffects();
-
-        assertEquals("Effect List Size", 2, effectList.size());
-        assertEquals("Effect Green", effectGreen, effectList.get(0));
-        assertEquals("Effect Fifties", effectFifties, effectList.get(1));
-
-        validatePreviewProgress(0, -1, false, mVideoEditor.getDuration());
-    }
-
-    /**
-     *To test Preview : Preview of current Transitions applied (with multiple
-     * generatePreview)
-     */
-    @LargeTest
-    public void testPreviewWithTransition() throws Exception {
-
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_10fps_96kbps_0_25.3gp";
-        final String imageItemFileName1 = INPUT_FILE_PATH +
-            "IMG_1600x1200.jpg";
-        final String videoItemFileName2 = INPUT_FILE_PATH +
-            "MPEG4_SP_800x480_515kbps_15fps_AMR_NB_8KHz_12.2kbps_m_0_26.mp4";
-        final String maskFilename = INPUT_FILE_PATH +
-            "TransitionSpiral_QVGA.jpg";
-        previewStart = false;
-        previewStop = false;
-        previewError = false;
-
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFileName1, 10000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                videoItemFileName2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem2.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final TransitionCrossfade transition1And2CrossFade =
-            mVideoEditorHelper.createTCrossFade("transition_1_2_CF",
-                mediaVideoItem1, mediaImageItem1, 2000,
-                Transition.BEHAVIOR_MIDDLE_FAST);
-        mVideoEditor.addTransition(transition1And2CrossFade);
-
-        final TransitionAlpha transition2And3Alpha =
-            mVideoEditorHelper.createTAlpha("transition_2_3", mediaImageItem1,
-                mediaVideoItem2, 4000, Transition.BEHAVIOR_SPEED_UP,
-                maskFilename, 50, true);
-        mVideoEditor.addTransition(transition2And3Alpha);
-
-        final TransitionFadeBlack transition1FadeBlack =
-            mVideoEditorHelper.createTFadeBlack("transition_1FB", null,
-                mediaVideoItem1, 2000, Transition.BEHAVIOR_MIDDLE_FAST);
-        mVideoEditor.addTransition(transition1FadeBlack);
-
-        List<Transition> transitionList = mVideoEditor.getAllTransitions();
-        assertEquals("Transition List Size", 3, transitionList.size());
-        assertEquals("Transition 1", transition1And2CrossFade,
-            transitionList.get(0));
-        assertEquals("Transition 2", transition2And3Alpha, transitionList.get(1));
-        assertEquals("Transition 3", transition1FadeBlack, transitionList.get(2));
-
-        mVideoEditor.setAspectRatio(MediaProperties.ASPECT_RATIO_3_2);
-
-        final int[] progressValues = new int[300];
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            int i = 0;
-
-            public void onProgress(Object item, int action, int progress) {
-                if (item instanceof TransitionCrossfade) {
-                    progressValues[i] = progress;
-                    assertEquals("Object", item, transition1And2CrossFade);
-                    assertEquals("Action", action,
-                        MediaProcessingProgressListener.ACTION_ENCODE);
-                } else if (item instanceof TransitionAlpha) {
-                    progressValues[i] = progress;
-                    assertEquals("Object", item, transition2And3Alpha);
-                    assertEquals("Action", action,
-                        MediaProcessingProgressListener.ACTION_ENCODE);
-                } else if (item instanceof TransitionFadeBlack) {
-                    progressValues[i] = progress;
-                    assertEquals("Object", item, transition1FadeBlack);
-                    assertEquals("Action", action,
-                        MediaProcessingProgressListener.ACTION_ENCODE);
-                }
-                i++;
-            }
-        });
-
-        mVideoEditorHelper.checkProgressCBValues(progressValues);
-        final SurfaceHolder surfaceHolder =
-            MediaFrameworkTest.mSurfaceView.getHolder();
-        /* As transition takes more time buffer of 10 sec is added */
-        long waitingTime = minWaitingTime + 10000 + 10000;
-
-        blockTillPreviewCompletes.acquire();
-        try {
-        mVideoEditor.startPreview(surfaceHolder, 0, 10000, false, 1,
-            new PreviewProgressListener() {
-            public void onProgress(VideoEditor videoEditor, long timeMs,
-                OverlayData overlayData) {
-                }
-                public void onStart(VideoEditor videoEditor) {
-                    setPreviewStart();
-                }
-                public void onStop(VideoEditor videoEditor) {
-                    setPreviewStop();
-                    blockTillPreviewCompletes.release();
-                }
-                public void onError(VideoEditor videoEditor, int error) {
-                    setPreviewError();
-                    blockTillPreviewCompletes.release();
-                }
-        });
-        } catch (Exception e) {
-            blockTillPreviewCompletes.release();
-        }
-        blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
-        mVideoEditor.stopPreview();
-        blockTillPreviewCompletes.release();
-        assertTrue("Preview Failed to start", previewStart);
-        assertTrue("Preview Failed to stop", previewStop);
-        assertFalse("Preview Error occurred", previewError);
-
-        assertEquals("Removing Transition " + transition1And2CrossFade.getId(),
-            transition1And2CrossFade,
-            mVideoEditor.removeTransition(transition1And2CrossFade.getId()));
-        transitionList = mVideoEditor.getAllTransitions();
-        assertEquals("Transition List Size", 2, transitionList.size());
-        assertEquals("Transition 1", transition2And3Alpha, transitionList.get(0));
-        assertEquals("Transition 2", transition1FadeBlack, transitionList.get(1));
-
-        validatePreviewProgress(0, -1, false, mVideoEditor.getDuration());
-
-
-        final TransitionSliding transition1And2Sliding =
-            mVideoEditorHelper.createTSliding("transition_1_2Sliding",
-                mediaVideoItem1, mediaImageItem1, 4000,
-                Transition.BEHAVIOR_MIDDLE_FAST,
-                TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN);
-        mVideoEditor.addTransition(transition1And2Sliding);
-
-        transitionList = mVideoEditor.getAllTransitions();
-        assertEquals("Transition List Size", 3, transitionList.size());
-        assertEquals("Transition 1", transition2And3Alpha, transitionList.get(0));
-        assertEquals("Transition 2", transition1FadeBlack, transitionList.get(1));
-        assertEquals("Transition 3", transition1And2Sliding,
-            transitionList.get(2));
-
-        validatePreviewProgress(5000, -1, false, (mVideoEditor.getDuration()));
-
-    }
-
-    /**
-     * To test Preview : Preview of current Overlay applied
-     */
-    @LargeTest
-    public void testPreviewWithOverlay() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
-        final String overlayFilename1 = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay1.png";
-        final String overlayFilename2 = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay2.png";
-        final int previewFrom = 5000;
-        final int previewTo = 10000;
-        final boolean previewLoop = false;
-        final int previewCallbackFrameCount = 1;
-        final int setAspectRatio = MediaProperties.ASPECT_RATIO_4_3;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-        previewStart = false;
-        previewStop = false;
-        boolean flagForException = false;
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName, renderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-        mediaVideoItem.setExtractBoundaries(0, 10000);
-
-        final Bitmap mBitmap1 =  mVideoEditorHelper.getBitmap(overlayFilename1,
-            640, 480);
-        final OverlayFrame overlayOnMvi1 =
-            mVideoEditorHelper.createOverlay(mediaVideoItem, "OverlayOnMvi1",
-                mBitmap1, 0, 5000);
-        mediaVideoItem.addOverlay(overlayOnMvi1);
-
-        final Bitmap mBitmap2 =  mVideoEditorHelper.getBitmap(overlayFilename2,
-            640, 480);
-        final OverlayFrame overlayOnMvi2 =
-            mVideoEditorHelper.createOverlay(mediaVideoItem, "OverlayOnMvi2",
-                mBitmap2, 5000, 9000);
-        mediaVideoItem.addOverlay(overlayOnMvi2);
-
-        List<Overlay> overlayList = mediaVideoItem.getAllOverlays();
-        assertEquals("Overlay Size", 2, overlayList.size());
-        assertEquals("Overlay 1", overlayOnMvi1, overlayList.get(0));
-        assertEquals("Overlay 2", overlayOnMvi2, overlayList.get(1));
-
-        mVideoEditor.setAspectRatio(setAspectRatio);
-
-        validatePreviewProgress(0 /* previewFrom */, -1, previewLoop,
-            mVideoEditor.getDuration());
-    }
-
-    /**
-     * To test Preview : Preview of current Trim applied (with default aspect
-     * ratio)
-     */
-    @LargeTest
-    public void testPreviewWithTrim() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName, MediaItem.RENDERING_MODE_CROPPING);
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-        boolean flagForException = false;
-        previewStart = false;
-        previewStop = false;
-        mediaVideoItem.setExtractBoundaries(mediaVideoItem.getDuration() / 2,
-            mediaVideoItem.getDuration());
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        validatePreviewProgress(1000, -1, false, mVideoEditor.getDuration());
-    }
-
-    /**
-     * To test Preview : Preview of current work having Overlay and Effect
-     * applied
-     */
-
-    @LargeTest
-    public void testPreviewWithOverlayEffectKenBurn() throws Exception {
-
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final String overlayFilename = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay1.png";
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-        previewStart = false;
-        previewStop = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaImageItem mediaImageItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFileName, 10000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem2);
-
-        final MediaVideoItem mediaVideoItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                videoItemFileName1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem3);
-
-        final EffectColor effectColor =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem1, "Effect1",
-                1000, 3000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
-        mediaVideoItem1.addEffect(effectColor);
-
-        final Rect startRect = new Rect((mediaImageItem2.getHeight() / 3),
-            (mediaImageItem2.getWidth() / 3), (mediaImageItem2.getHeight() / 2),
-            (mediaImageItem2.getWidth() / 2));
-        final Rect endRect = new Rect(0, 0, mediaImageItem2.getWidth(),
-            mediaImageItem2.getHeight());
-
-        final EffectKenBurns kbeffectOnMI2 = new EffectKenBurns(mediaImageItem2,
-            "KBOnM2", startRect, endRect, 0, 10000);
-        assertNotNull("EffectKenBurns", kbeffectOnMI2);
-        mediaImageItem2.addEffect(kbeffectOnMI2);
-
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFilename,
-            640, 480);
-        final OverlayFrame overlayFrame =
-            mVideoEditorHelper.createOverlay(mediaVideoItem3, "OverlayID",
-                mBitmap, (mediaImageItem2.getDuration() / 4),
-                (mediaVideoItem3.getDuration() / 3));
-        mediaVideoItem3.addOverlay(overlayFrame);
-
-        validatePreviewProgress(5000, -1, false, mVideoEditor.getDuration());
-    }
-
-    /**
-     *To test Preview : Export during preview
-     */
-    @LargeTest
-    public void testPreviewDuringExport() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-        previewStart = false;
-        previewStop = false;
-        previewError = false;
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        long waitingTime = minWaitingTime + mVideoEditor.getDuration();
-
-
-        blockTillPreviewCompletes.acquire();
-                    final String fileName = mVideoEditor.getPath() + "/test.3gp";
-                    final int height = MediaProperties.HEIGHT_480;
-                    final int bitrate = MediaProperties.BITRATE_512K;
-
-            try {
-                mVideoEditor.export(fileName, height, bitrate,
-                    new ExportProgressListener() {
-                        public void onProgress(VideoEditor ve,
-                            String outFileName,int progress) {
-
-                        }
-                    });
-            } catch (IOException e) {
-                assertTrue("UnExpected Error in Export" +
-                    e.toString(), false);
-            }
-
-        final SurfaceHolder surfaceHolder =
-            MediaFrameworkTest.mSurfaceView.getHolder();
-        try {
-
-            mVideoEditor.startPreview(surfaceHolder, 5000, -1, false, 1,
-                new PreviewProgressListener() {
-
-                    public void onProgress(VideoEditor videoEditor, long timeMs,
-                        OverlayData overlayData) {
-                    }
-                public void onStart(VideoEditor videoEditor) {
-                    setPreviewStart();
-                }
-                public void onStop(VideoEditor videoEditor) {
-                    setPreviewStop();
-                    blockTillPreviewCompletes.release();
-                }
-                public void onError(VideoEditor videoEditor, int error) {
-                    setPreviewError();
-                    blockTillPreviewCompletes.release();
-                }
-            });
-
-        } catch (Exception e) {
-            blockTillPreviewCompletes.release();
-        }
-        blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
-        mVideoEditor.stopPreview();
-        assertTrue("Preview Failed to start", previewStart);
-        assertTrue("Preview Failed to stop", previewStop);
-        assertFalse("Preview Error occurred", previewError);
-
-        blockTillPreviewCompletes.release();
-    }
-
-    /**
-     * To test Preview : Preview of current Effects applied (with from time >
-     * total duration)
-     */
-    @LargeTest
-    public void testPreviewWithDurationGreaterThanMediaDuration()
-        throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_192kbps_1_5.mp4";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        boolean flagForException = false;
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName, renderingMode);
-        try {
-            mediaVideoItem1.setExtractBoundaries(0, 20000);
-        } catch (Exception e) {
-            assertTrue("Exception during setExtract Boundaries", false);
-        }
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-        final SurfaceHolder surfaceHolder =
-            MediaFrameworkTest.mSurfaceView.getHolder();
-        long waitingTime = minWaitingTime + (mVideoEditor.getDuration() - 30000);
-        if(waitingTime < 0)
-        {
-            waitingTime = minWaitingTime;
-        }
-
-        blockTillPreviewCompletes.acquire();
-        try {
-            mVideoEditor.startPreview(surfaceHolder, 30000, -1, true, 1,
-            new PreviewProgressListener() {
-                public void onProgress(VideoEditor videoEditor, long timeMs,
-                    OverlayData overlayData) {
-            }
-                public void onStart(VideoEditor videoEditor) {
-                    setPreviewStart();
-                }
-                public void onStop(VideoEditor videoEditor) {
-                    setPreviewStop();
-                    blockTillPreviewCompletes.release();
-                }
-                public void onError(VideoEditor videoEditor, int error) {
-                    setPreviewError();
-                    blockTillPreviewCompletes.release();
-                }
-        });
-
-        } catch (IllegalArgumentException e) {
-            blockTillPreviewCompletes.release();
-            flagForException = true;
-        }
-        blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
-        assertTrue("Expected Error in Preview", flagForException);
-        mVideoEditor.stopPreview();
-        blockTillPreviewCompletes.release();
-    }
-
-    /**
-     * To test Preview : Preview of current Effects applied (with Render Preview
-     * Frame)
-     */
-    @LargeTest
-    public void testPreviewWithRenderPreviewFrame() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final Semaphore blockTillPreviewCompletes = new Semaphore(1);
-        boolean flagForException = false;
-        OverlayData overlayData1 = new OverlayData();
-        previewStart = false;
-        previewStop = false;
-
-        final String overlayFilename1 = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay1.png";
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor,
-            "m1", videoItemFileName, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final EffectColor effectPink =
-            mVideoEditorHelper.createEffectItem(mediaVideoItem,
-                "effectNegativeOnMvi", 1000, 3000, EffectColor.TYPE_COLOR,
-                 EffectColor.PINK);
-        mediaVideoItem.addEffect(effectPink);
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-        final SurfaceHolder surfaceHolder =
-            MediaFrameworkTest.mSurfaceView.getHolder();
-
-        assertEquals("Render preview Frame at 5 Sec", 5000,
-            mVideoEditor.renderPreviewFrame(surfaceHolder, 5000,
-            overlayData1));
-
-        assertEquals("Render preview Frame at 7 Sec", 7000,
-            mVideoEditor.renderPreviewFrame(surfaceHolder, 7000,
-            overlayData1));
-
-        validatePreviewProgress(5000, -1, false, mVideoEditor.getDuration());
-    }
-
-    /**
-     * To test Preview : Preview of current work from selected jump location
-     * till end with Audio Track
-     */
-    @LargeTest
-    public void testPreviewWithEndAudioTrack() throws Exception {
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String imageItemFilename2 = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final String audioFilename = INPUT_FILE_PATH +
-            "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
-
-        boolean flagForException = false;
-        previewStart = false;
-        previewStop = false;
-        final MediaImageItem mediaImageItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                imageItemFilename1, 7000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem1);
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                videoItemFileName, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem.setExtractBoundaries(1000, 8000);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final MediaImageItem mediaImageItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                imageItemFilename2, 7000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem2);
-
-        final AudioTrack audioTrack =
-            mVideoEditorHelper.createAudio(mVideoEditor, "a1", audioFilename);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        List<AudioTrack> audioList = mVideoEditor.getAllAudioTracks();
-        assertEquals("Audio Track List size", 1, audioList.size());
-        assertEquals("Audio Track", audioTrack, audioList.get(0));
-        mVideoEditor.setAspectRatio(MediaProperties.ASPECT_RATIO_4_3);
-
-        validatePreviewProgress(10000, -1, false, mVideoEditor.getDuration());
-    }
-
-    /**
-     * To test render Preview Frame
-     */
-    @LargeTest
-    public void testRenderPreviewFrame() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH
-            + "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String videoItemFileName2 = INPUT_FILE_PATH
-            + "MPEG4_SP_800x480_515kbps_15fps_AMR_NB_8KHz_12.2kbps_m_0_26.mp4";
-        final String videoItemFileName3 = INPUT_FILE_PATH
-            + "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String imageItemFilename1 = INPUT_FILE_PATH
-            + "IMG_1600x1200.jpg";
-        final String imageItemFilename2 = INPUT_FILE_PATH
-            + "IMG_176x144.jpg";
-        final String audioFilename = INPUT_FILE_PATH
-            + "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
-        OverlayData overlayData1 = new OverlayData();
-        previewStart = false;
-        previewStop = false;
-        final MediaVideoItem mediaVideoItem1 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFileName1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                videoItemFileName2, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(mediaVideoItem2.getDuration() / 4,
-            mediaVideoItem2.getDuration() / 2);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final MediaVideoItem mediaVideoItem3 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m3",
-                videoItemFileName3, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem1.setExtractBoundaries(mediaVideoItem2.getDuration() / 2,
-            mediaVideoItem2.getDuration());
-        mVideoEditor.addMediaItem(mediaVideoItem3);
-
-        final MediaImageItem mediaImageItem4 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m4",
-                imageItemFilename1, 5000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-
-        final MediaImageItem mediaImageItem5 =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m5",
-                imageItemFilename2, 5000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-
-        List<MediaItem> mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item List Size", 3, mediaList.size());
-
-        mVideoEditor.insertMediaItem(mediaImageItem4, mediaVideoItem2.getId());
-        mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item List Size", 4, mediaList.size());
-        assertEquals("Media item 1", mediaVideoItem1, mediaList.get(0));
-        assertEquals("Media item 2", mediaVideoItem2, mediaList.get(1));
-        assertEquals("Media item 4", mediaImageItem4, mediaList.get(2));
-        assertEquals("Media item 3", mediaVideoItem3, mediaList.get(3));
-
-        mVideoEditor.insertMediaItem(mediaImageItem5, mediaImageItem4.getId());
-        mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item List Size", 5, mediaList.size());
-        assertEquals("Media item 1", mediaVideoItem1, mediaList.get(0));
-        assertEquals("Media item 2", mediaVideoItem2, mediaList.get(1));
-        assertEquals("Media item 4", mediaImageItem4, mediaList.get(2));
-        assertEquals("Media item 5", mediaImageItem5, mediaList.get(3));
-        assertEquals("Media item 3", mediaVideoItem3, mediaList.get(4));
-
-        mVideoEditor.moveMediaItem(mediaVideoItem1.getId(),
-            mediaImageItem5.getId());
-        mediaList = mVideoEditor.getAllMediaItems();
-        assertEquals("Media Item List Size", 5, mediaList.size());
-        assertEquals("Media item 2", mediaVideoItem2, mediaList.get(0));
-        assertEquals("Media item 4", mediaImageItem4, mediaList.get(1));
-        assertEquals("Media item 5", mediaImageItem5, mediaList.get(2));
-        assertEquals("Media item 1", mediaVideoItem1, mediaList.get(3));
-        assertEquals("Media item 3", mediaVideoItem3, mediaList.get(4));
-
-        final TransitionCrossfade transition2And4CrossFade =
-            mVideoEditorHelper.createTCrossFade("transition2And4CrossFade",
-                mediaVideoItem2, mediaImageItem4, 2000,
-                Transition.BEHAVIOR_MIDDLE_FAST);
-        mVideoEditor.addTransition(transition2And4CrossFade);
-
-        final TransitionCrossfade transition1And3CrossFade =
-            mVideoEditorHelper.createTCrossFade("transition1And3CrossFade",
-                mediaVideoItem1, mediaVideoItem3, 5000,
-                Transition.BEHAVIOR_MIDDLE_FAST);
-        mVideoEditor.addTransition(transition1And3CrossFade);
-
-        final AudioTrack audioTrack =
-            mVideoEditorHelper.createAudio(mVideoEditor, "a1", audioFilename);
-        audioTrack.setExtractBoundaries(0, 2000);
-        mVideoEditor.addAudioTrack(audioTrack);
-
-        audioTrack.enableLoop();
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        final SurfaceHolder surfaceHolder =
-            MediaFrameworkTest.mSurfaceView.getHolder();
-
-        mVideoEditor.renderPreviewFrame(surfaceHolder, mVideoEditor.getDuration()/4, overlayData1);
-        Thread.sleep(1000);
-        mVideoEditor.renderPreviewFrame(surfaceHolder, mVideoEditor.getDuration()/2, overlayData1);
-        Thread.sleep(1000);
-        mVideoEditor.renderPreviewFrame(surfaceHolder, mVideoEditor.getDuration(), overlayData1);
-
-    }
-
-    /**
-     * To Test Preview : Without any Media Items in the story Board
-     */
-    @LargeTest
-    public void testStartPreviewWithoutMediaItems() throws Exception {
-        boolean flagForException = false;
-
-        final SurfaceHolder surfaceHolder =
-            MediaFrameworkTest.mSurfaceView.getHolder();
-        try{
-            mVideoEditor.startPreview(surfaceHolder, 0, -1, false, 1,
-                new PreviewProgressListener() {
-                    public void onProgress(VideoEditor videoEditor, long timeMs,
-                        OverlayData overlayData) {
-                    }
-                    public void onStart(VideoEditor videoEditor) {
-                        setPreviewStart();
-                    }
-                    public void onStop(VideoEditor videoEditor) {
-                        setPreviewStop();
-                    }
-                    public void onError(VideoEditor videoEditor, int error) {
-                        setPreviewError();
-                    }
-            });
-        }catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Preview without Media Items", flagForException);
-    }
-
-    /**
-     * To Test Preview : Add Media and Remove Media Item (Without any Media
-     * Items in the story Board)
-     */
-    @LargeTest
-    public void testStartPreviewAddRemoveMediaItems() throws Exception {
-        final String videoItemFilename1 = INPUT_FILE_PATH
-            + "H263_profile0_176x144_15fps_256kbps_AACLC_32kHz_128kbps_s_0_26.3gp";
-        final String imageItemFilename1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String alphaFilename = INPUT_FILE_PATH +
-            "TransitionSpiral_QVGA.jpg";
-        boolean flagForException = false;
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
-                videoItemFilename1, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mediaVideoItem.setExtractBoundaries(0, 15000);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final MediaImageItem mediaImageItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor, "m2",
-                imageItemFilename1, 15000, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaImageItem);
-
-        final TransitionAlpha transition1And2 =
-            mVideoEditorHelper.createTAlpha("transition", mediaVideoItem,
-                mediaImageItem, 3000, Transition.BEHAVIOR_SPEED_UP,
-                alphaFilename, 10, false);
-        mVideoEditor.addTransition(transition1And2);
-
-        final EffectColor effectColor =
-            mVideoEditorHelper.createEffectItem(mediaImageItem, "effect", 5000,
-                3000, EffectColor.TYPE_COLOR, EffectColor.PINK);
-        mediaImageItem.addEffect(effectColor);
-
-        assertEquals("removing Media item 1", mediaVideoItem,
-            mVideoEditor.removeMediaItem(mediaVideoItem.getId()));
-        assertEquals("removing Media item 2", mediaImageItem,
-            mVideoEditor.removeMediaItem(mediaImageItem.getId()));
-
-        try{
-            mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-                public void onProgress(Object item, int action, int progress) {
-                }
-            });
-            final SurfaceHolder surfaceHolder =
-                MediaFrameworkTest.mSurfaceView.getHolder();
-            mVideoEditor.startPreview(surfaceHolder, 0, -1, false, 1,
-                new PreviewProgressListener() {
-                    public void onProgress(VideoEditor videoEditor, long timeMs,
-                        OverlayData overlayData) {
-                    }
-                    public void onStart(VideoEditor videoEditor) {
-                        setPreviewStart();
-                    }
-                    public void onStop(VideoEditor videoEditor) {
-                        setPreviewStop();
-                    }
-                    public void onError(VideoEditor videoEditor, int error) {
-                        setPreviewError();
-                    }
-            });
-        }catch (IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue("Preview with removed Media Items", flagForException);
-
-    }
-
-    /**
-     * To test Preview : Preview of current Effects applied (with Render Preview
-     * Frame)
-     */
-    @LargeTest
-    public void testPreviewWithRenderPreviewFrameWithoutGenerate() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        boolean flagForException = false;
-        long duration = 0;
-        OverlayData overlayData1 = new OverlayData();
-
-        final MediaVideoItem mediaVideoItem =
-            mVideoEditorHelper.createMediaItem(mVideoEditor,
-            "m1", videoItemFileName, MediaItem.RENDERING_MODE_BLACK_BORDER);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final SurfaceHolder surfaceHolder =
-            MediaFrameworkTest.mSurfaceView.getHolder();
-        duration = mVideoEditor.getDuration();
-        /* RenderPreviewFrame returns -1 to indicate last frame */
-        try {
-            mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
-            overlayData1);
-        } catch ( IllegalStateException e) {
-            flagForException = true;
-        }
-        assertTrue (" Render Preview Frame without generate", flagForException);
-        duration = mVideoEditor.getDuration() + 1000;
-        try {
-            mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
-            overlayData1);
-        } catch ( IllegalArgumentException e) {
-            flagForException = true;
-        }
-        assertTrue (" Preview time greater than duration", flagForException);
-    }
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
deleted file mode 100644
index d15a535..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
+++ /dev/null
@@ -1,1073 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.mediaframeworktest.performance;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.Writer;
-
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.media.videoeditor.AudioTrack;
-import android.media.videoeditor.EffectColor;
-import android.media.videoeditor.EffectKenBurns;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.videoeditor.MediaProperties;
-import android.media.videoeditor.MediaVideoItem;
-import android.media.videoeditor.OverlayFrame;
-import android.media.videoeditor.Transition;
-import android.media.videoeditor.TransitionCrossfade;
-import android.media.videoeditor.TransitionAlpha;
-import android.media.videoeditor.TransitionFadeBlack;
-import android.media.videoeditor.TransitionSliding;
-import android.media.videoeditor.VideoEditor;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase;
-import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase;
-import android.media.videoeditor.VideoEditor.ExportProgressListener;
-
-import android.util.Log;
-
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import com.android.mediaframeworktest.VideoEditorHelper;
-
-/**
- * Junit / Instrumentation - performance measurement for media player and
- * recorder
- */
-public class VideoEditorPerformance extends
-    ActivityInstrumentationTestCase<MediaFrameworkTest> {
-
-    private final String TAG = "VideoEditorPerformance";
-
-    private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
-
-    private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
-
-    private final String VIDEOEDITOR_OUTPUT = PROJECT_LOCATION +
-        "VideoEditorPerformance.txt";
-
-    public VideoEditorPerformance() {
-        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-    }
-
-    private final String PROJECT_CLASS_NAME =
-        "android.media.videoeditor.VideoEditorImpl";
-    private VideoEditor mVideoEditor;
-    private VideoEditorHelper mVideoEditorHelper;
-
-    @Override
-    protected void setUp() throws Exception {
-        // setup for each test case.
-        super.setUp();
-        mVideoEditorHelper = new VideoEditorHelper();
-        // Create a random String which will be used as project path, where all
-        // project related files will be stored.
-        final String projectPath =
-            mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
-        mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
-        // Clean the directory created as project path
-        mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
-        System.gc();
-        super.tearDown();
-    }
-
-    private void writeTimingInfo(String testCaseName, String[] information)
-        throws Exception {
-        File outFile = new File(VIDEOEDITOR_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(outFile, true));
-        output.write(testCaseName + "\n\t");
-        for (int i = 0; i < information.length; i++) {
-            output.write(information[i]);
-        }
-        output.write("\n\n");
-        output.close();
-    }
-
-    private final int NUM_OF_ITERATIONS=20;
-
-    private int calculateTimeTaken(long beginTime, int numIterations)
-        throws Exception {
-        final long duration2 = SystemClock.uptimeMillis();
-        final long durationToCreateMediaItem = (duration2 - beginTime);
-        final int timeTaken1 = (int)(durationToCreateMediaItem / numIterations);
-        return (timeTaken1);
-    }
-
-    private void createVideoItems(MediaVideoItem[] mediaVideoItem,
-        String videoItemFileName, int renderingMode, int startTime, int endTime) throws Exception {
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            try {
-                mediaVideoItem[i] = new MediaVideoItem(mVideoEditor, "m" + i,
-                    videoItemFileName, renderingMode);
-                mediaVideoItem[i].setExtractBoundaries(startTime, endTime);
-            } catch (Exception e1) {
-                assertTrue(
-                    "Can not create an object of Video Item with file name = "
-                    + videoItemFileName + "------ID:m" + i + "       Issue = "
-                    + e1.toString(), false);
-            }
-        }
-    }
-
-    private void addVideoItems(MediaVideoItem[] mediaVideoItem) throws Exception {
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            try {
-                mVideoEditor.addMediaItem(mediaVideoItem[i]);
-            } catch (Exception e1) {
-                assertTrue(
-                    "Can not add an object of Video Item with ID:m" + i +
-                    "    Issue = " + e1.toString(), false);
-            }
-        }
-    }
-
-    private void removeVideoItems(MediaVideoItem[] mediaVideoItem) throws Exception {
-            for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            try {
-            mVideoEditor.removeMediaItem(mediaVideoItem[i].getId());
-            } catch (Exception e1) {
-                assertTrue(
-                    "Can not Remove an object of Video Item with ID:m" + i +
-                    "    Issue = " + e1.toString(), false);
-            }
-        }
-    }
-
-    private void createImageItems(MediaImageItem[] mIi,
-        String imageItemFileName, int renderingMode, int duration) throws Exception {
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            try {
-                mIi[i] = new MediaImageItem(mVideoEditor, "m" + i,
-                    imageItemFileName, duration, renderingMode);
-            } catch (Exception e1) {
-                assertTrue( " Cannot create Image Item", false);
-            }
-        }
-    }
-
-    private void addImageItems(MediaImageItem[] mIi) throws Exception {
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            try {
-                mVideoEditor.addMediaItem(mIi[i]);
-            } catch (Exception e1) {
-                assertTrue("Cannot add Image item", false);
-            }
-        }
-    }
-
-    private void removeImageItems(MediaImageItem[] mIi) throws Exception {
-            for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            try {
-            mVideoEditor.removeMediaItem(mIi[i].getId());
-            } catch (Exception e1) {
-                assertTrue("Cannot remove image item", false);
-            }
-        }
-    }
-    /**
-     * To test the performance of adding and removing the video media item
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceAddRemoveVideoItem() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final int videoItemStartTime = 0;
-        final int videoItemEndTime = 5000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String[] loggingInfo = new String[3];
-        final MediaVideoItem[] mediaVideoItem =
-            new MediaVideoItem[NUM_OF_ITERATIONS];
-        int timeTaken = 0;
-        long startTime = 0;
-
-        /** Time Take for creation of Media Video Item */
-        startTime = SystemClock.uptimeMillis();
-        createVideoItems(mediaVideoItem, videoItemFileName, renderingMode,
-            videoItemStartTime, videoItemEndTime);
-
-        timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Time taken to Create Media Video Item :" +
-            timeTaken;
-
-        /** Time Take for Addition of Media Video Item */
-        startTime = SystemClock.uptimeMillis();
-        addVideoItems(mediaVideoItem);
-        timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
-        loggingInfo[1] = "\n\tTime taken to Add  Media Video Item :"
-            + timeTaken;
-
-        /** Time Take for Removal of Media Video Item */
-        startTime = SystemClock.uptimeMillis();
-        removeVideoItems(mediaVideoItem);
-        timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
-        loggingInfo[2] = "\n\tTime taken to remove  Media Video Item :"
-            + timeTaken;
-
-        writeTimingInfo("testPerformanceAddRemoveVideoItem (in mSec)", loggingInfo);
-    }
-
-    /**
-     * To test the performance of adding and removing the image media item
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceAddRemoveImageItem() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final int imageItemDuration = 0;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String[] loggingInfo = new String[3];
-        final MediaImageItem[] mediaImageItem =
-            new MediaImageItem[NUM_OF_ITERATIONS];
-        int timeTaken = 0;
-
-        long beginTime = SystemClock.uptimeMillis();
-        createImageItems(mediaImageItem, imageItemFileName, renderingMode,
-            imageItemDuration);
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Time taken to Create  Media Image Item :" +
-            timeTaken;
-
-        beginTime = SystemClock.uptimeMillis();
-        addImageItems(mediaImageItem);
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[1] = "\n\tTime taken to add  Media Image Item :" +
-            timeTaken;
-
-        beginTime = SystemClock.uptimeMillis();
-        removeImageItems(mediaImageItem);
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[2] = "\n\tTime taken to remove  Media Image Item :"
-            + timeTaken;
-
-        writeTimingInfo("testPerformanceAddRemoveImageItem (in mSec)",
-            loggingInfo);
-    }
-
-    /**
-     * To test the performance of adding and removing the transition
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceAddRemoveTransition() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-        "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final int videoItemStartTime1 = 0;
-        final int videoItemEndTime1 = 20000;
-        final String videoItemFileName2 = INPUT_FILE_PATH
-            + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final int videoItemStartTime2 = 0;
-        final int videoItemEndTime2 = 20000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int transitionDuration = 5000;
-        final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
-        final String[] loggingInfo = new String[3];
-        int timeTaken = 0;
-
-        final MediaVideoItem[] mediaVideoItem =
-            new MediaVideoItem[(NUM_OF_ITERATIONS *10) + 1];
-
-        for (int i = 0; i < (NUM_OF_ITERATIONS *10); i+=2) {
-            try {
-                mediaVideoItem[i] = new MediaVideoItem(mVideoEditor, "m" + i,
-                    videoItemFileName1, renderingMode);
-                mediaVideoItem[i+1] = new MediaVideoItem(mVideoEditor,
-                    "m" + (i+1), videoItemFileName2, renderingMode);
-                mediaVideoItem[i].setExtractBoundaries(videoItemStartTime1,
-                    videoItemEndTime1);
-                mediaVideoItem[i+1].setExtractBoundaries(videoItemStartTime2,
-                    videoItemEndTime2);
-            } catch (Exception e1) {
-                assertTrue("Can not create Video Object Item with file name = "
-                    + e1.toString(), false);
-            }
-            mVideoEditor.addMediaItem(mediaVideoItem[i]);
-            mVideoEditor.addMediaItem(mediaVideoItem[i+1]);
-        }
-        mediaVideoItem[(NUM_OF_ITERATIONS *10)] = new MediaVideoItem(mVideoEditor,
-            "m" + (NUM_OF_ITERATIONS *10), videoItemFileName1, renderingMode);
-        mediaVideoItem[(NUM_OF_ITERATIONS *10)].setExtractBoundaries(
-            videoItemStartTime1, videoItemEndTime1);
-        mVideoEditor.addMediaItem(mediaVideoItem[(NUM_OF_ITERATIONS *10)]);
-        final TransitionCrossfade tranCrossfade[] =
-            new TransitionCrossfade[(NUM_OF_ITERATIONS *10)];
-
-        long beginTime = SystemClock.uptimeMillis();
-        for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
-            tranCrossfade[i] = new TransitionCrossfade("transition" + i,
-                mediaVideoItem[i], mediaVideoItem[i+1], transitionDuration,
-                transitionBehavior);
-        }
-        timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
-        loggingInfo[0] = "Time taken to Create CrossFade Transition :" +
-            timeTaken;
-
-        beginTime = SystemClock.uptimeMillis();
-        for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
-            mVideoEditor.addTransition(tranCrossfade[i]);
-        }
-        timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
-        loggingInfo[1] = "\n\tTime taken to add CrossFade Transition :" +
-            timeTaken;
-
-        beginTime = SystemClock.uptimeMillis();
-        for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
-            assertEquals("Removing Transitions", tranCrossfade[i], mVideoEditor
-                .removeTransition(tranCrossfade[i].getId()));
-        }
-        timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
-        loggingInfo[2] = "\n\tTime taken to remove CrossFade Transition :" +
-            timeTaken;
-
-        writeTimingInfo("testPerformanceAddRemoveTransition (in mSec)", loggingInfo);
-    }
-
-    /**
-     * To test performance of Export
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceExport() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int outHeight = MediaProperties.HEIGHT_480;
-        final int outBitrate = MediaProperties.BITRATE_256K;
-        final int outVcodec = MediaProperties.VCODEC_H264;
-        final String[] loggingInfo = new String[1];
-        final String outFilename = mVideoEditorHelper
-            .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_12Mbps_AACLC_44.1khz_64kbps_s_1_17.mp4";
-        final String imageItemFileName1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
-        final String videoItemFileName2 = INPUT_FILE_PATH +
-            "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_32kbps_m_1_17.3gp";
-        final String imageItemFileName2 = INPUT_FILE_PATH + "IMG_176x144.jpg";
-        final String videoItemFileName3 = INPUT_FILE_PATH +
-            "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
-        final String overlayFile = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
-        final String audioTrackFilename = INPUT_FILE_PATH +
-            "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
-        final String maskFilename = INPUT_FILE_PATH +
-            "TransitionSpiral_QVGA.jpg";
-
-        final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-            "m1", videoItemFileName1, renderingMode);
-        mediaItem1.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaItem1);
-
-        final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
-            "m2", imageItemFileName1, 10000, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem2);
-
-        final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
-            "m3", videoItemFileName2, renderingMode);
-        mediaItem3.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaItem3);
-
-        final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
-            "m4", imageItemFileName2, 10000, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem4);
-
-        final MediaVideoItem mediaItem5 = new MediaVideoItem(mVideoEditor,
-            "m5", videoItemFileName3, renderingMode);
-        mediaItem5.setExtractBoundaries(0, 20000);
-        mVideoEditor.addMediaItem(mediaItem5);
-        /**
-         * 7.Add TransitionAlpha, Apply this  Transition as Begin for Media Item 1
-         *  with duration = 2 sec behavior = BEHAVIOR_LINEAR, mask file name =
-         * TransitionSpiral_QVGA.jpg , blending percent = 50%, invert = true;
-         * */
-        final TransitionAlpha transition1 =
-            mVideoEditorHelper.createTAlpha("transition1", null, mediaItem1,
-                2000, Transition.BEHAVIOR_LINEAR, maskFilename, 50, true);
-        mVideoEditor.addTransition(transition1);
-
-        /**
-         * 8.Add Transition Sliding between MediaItem 2 and 3 ,
-         *  Sliding Direction  = DIRECTION_RIGHT_OUT_LEFT_IN,
-         *  behavior  = BEHAVIOR_MIDDLE_FAST and duration = 4sec
-         * */
-        final TransitionSliding transition2And3 =
-            mVideoEditorHelper.createTSliding("transition2", mediaItem2,
-                mediaItem3, 4000, Transition.BEHAVIOR_MIDDLE_FAST,
-                TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
-        mVideoEditor.addTransition(transition2And3);
-
-        /**
-         * 9.Add Transition Crossfade between  Media Item 3 and 4,
-         *  behavior = BEHAVIOR_MIDDLE_SLOW, duration = 3.5 sec
-         * */
-        final TransitionCrossfade transition3And4 =
-            mVideoEditorHelper.createTCrossFade("transition3", mediaItem3,
-                mediaItem4, 3500, Transition.BEHAVIOR_MIDDLE_SLOW);
-        mVideoEditor.addTransition(transition3And4);
-
-        /**
-         * 10.Add Transition Fadeblack between  Media Item 4 and 5,
-         *  behavior = BEHAVIOR_SPEED_DOWN, duration = 3.5 sec
-         * */
-        final TransitionFadeBlack transition4And5 =
-            mVideoEditorHelper.createTFadeBlack("transition4", mediaItem4,
-                mediaItem5, 3500, Transition.BEHAVIOR_SPEED_DOWN);
-        mVideoEditor.addTransition(transition4And5);
-
-        /**
-         * 11.Add Effect 1 type="TYPE_SEPIA" to the MediaItem 1,
-         *  start time=1sec and duration =4secs
-         * */
-        final EffectColor effectColor1 = mVideoEditorHelper.createEffectItem(
-            mediaItem1, "effect1", 1000, 4000, EffectColor.TYPE_SEPIA, 0);
-        mediaItem1.addEffect(effectColor1);
-
-        /**
-         * 12.Add Overlay 1  to the MediaItem 3: Frame Overlay with start time = 1 sec
-         * duration = 4 sec with item  = IMG_640x480_Overlay1.png
-         * */
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFile, 640,
-            480);
-        final OverlayFrame overlayFrame =
-            mVideoEditorHelper.createOverlay(mediaItem3, "overlay",
-                mBitmap, 1000, 4000);
-        mediaItem3.addOverlay(overlayFrame);
-        /**
-         * 13.Add Effect 2 type="TYPE_NEGATIVE" to the MediaItem 2,
-         *  start time=8sec and duration =2secs
-         * */
-        final EffectColor effectColor2 = mVideoEditorHelper.createEffectItem(
-            mediaItem2, "effect2", 8000, 2000, EffectColor.TYPE_NEGATIVE, 0);
-        mediaItem2.addEffect(effectColor2);
-        /**
-         * 14.Add Effect 3 type="TYPE_COLOR" to the MediaItem 3, color param = "PINK",
-         *  start time=5 sec and duration =3secs
-         * */
-        final EffectColor effectColor3 = mVideoEditorHelper.createEffectItem(
-            mediaItem3, "effect3", 5000, 3000, EffectColor.TYPE_COLOR,
-            EffectColor.PINK);
-        mediaItem3.addEffect(effectColor3);
-        /**
-         * 15.Add Effect 4 type="TYPE_FIFTIES" to the MediaItem 4,
-         *  start time=2 sec and duration =1secs
-        * */
-        final EffectColor effectColor4 = mVideoEditorHelper.createEffectItem(
-            mediaItem4, "effect4", 2000, 1000, EffectColor.TYPE_FIFTIES, 0);
-        mediaItem4.addEffect(effectColor4);
-        /**
-         * 16.Add KenBurnsEffect for MediaItem 4 with
-         *  duration = 3 sec and startTime = 4 sec
-         *  StartRect
-         *  left = org_height/3  ;  top = org_width/3
-         *  bottom = org_width/2  ;  right = org_height/2
-         *  EndRect
-         *  left = 0  ;  top = 0
-         *  bottom =  org_height;  right =  org_width
-         * */
-
-        final Rect startRect = new Rect((mediaItem4.getHeight() / 3),
-            (mediaItem4.getWidth() / 3), (mediaItem4.getHeight() / 2),
-            (mediaItem4.getWidth() / 2));
-        final Rect endRect = new Rect(0, 0, mediaItem4.getWidth(),
-            mediaItem4.getHeight());
-        final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
-            mediaItem4, "KBOnM2", startRect, endRect,4000 , 3000);
-        mediaItem4.addEffect(kbEffectOnMediaItem);
-
-        /** 17.Add Audio Track,Set extract boundaries o to 10 sec.
-         * */
-        final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
-            mVideoEditor, "audioTrack", audioTrackFilename);
-        mVideoEditor.addAudioTrack(audioTrack);
-        /** 18.Enable Looping for Audio Track.
-         * */
-        audioTrack.enableLoop();
-        int timeTaken = 0;
-        final long beginTime = SystemClock.uptimeMillis();
-            try {
-                mVideoEditor.export(outFilename, outHeight, outBitrate,
-                    new ExportProgressListener() {
-                        public void onProgress(VideoEditor ve,
-                            String outFileName, int progress) {
-                        }
-                    });
-            } catch (Exception e) {
-                assertTrue("Error in Export" + e.toString(), false);
-            }
-        mVideoEditorHelper.checkDeleteExistingFile(outFilename);
-
-        timeTaken = calculateTimeTaken(beginTime, 1);
-        loggingInfo[0] = "Time taken to do ONE export of storyboard duration "
-            + mVideoEditor.getDuration() + " is :" + timeTaken;
-
-        writeTimingInfo("testPerformanceExport (in mSec)", loggingInfo);
-        mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
-    }
-
-
-    /**
-     * To test the performance of thumbnail extraction
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceThumbnailVideoItem() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-            + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final int videoItemStartTime = 0;
-        final int videoItemEndTime = 20000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String[] loggingInfo = new String[1];
-
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "m1", videoItemFileName, renderingMode);
-        mediaVideoItem.setExtractBoundaries(videoItemStartTime,
-            videoItemEndTime);
-
-        int timeTaken = 0;
-        long beginTime = SystemClock.uptimeMillis();
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            mediaVideoItem.getThumbnail(mediaVideoItem.getWidth() / 2,
-                mediaVideoItem.getHeight() / 2, i);
-        }
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Duration taken to get Video Thumbnails :" +
-            timeTaken;
-
-        writeTimingInfo("testPerformanceThumbnailVideoItem (in mSec)", loggingInfo);
-    }
-
-    /**
-     * To test the performance of adding and removing the overlay to media item
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceOverlayVideoItem() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final int videoItemStartTime1 = 0;
-        final int videoItemEndTime1 = 10000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String overlayFilename = INPUT_FILE_PATH
-            + "IMG_640x480_Overlay1.png";
-        final int overlayStartTime = 1000;
-        final int overlayDuration = 5000;
-
-        final String[] loggingInfo = new String[2];
-        MediaVideoItem mediaVideoItem = null;
-
-        try {
-            mediaVideoItem = new MediaVideoItem(mVideoEditor, "m0",
-                videoItemFileName1, renderingMode);
-            mediaVideoItem.setExtractBoundaries(videoItemStartTime1,
-                videoItemEndTime1);
-        } catch (Exception e1) {
-            assertTrue("Can not create Video Item with file name = "
-                + e1.toString(), false);
-        }
-        final OverlayFrame overlayFrame[] = new OverlayFrame[NUM_OF_ITERATIONS];
-        final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(overlayFilename,
-            640, 480);
-        int timeTaken = 0;
-        long beginTime = SystemClock.uptimeMillis();
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            overlayFrame[i] = new OverlayFrame(mediaVideoItem, "overlay" + i,
-            mBitmap, overlayStartTime, overlayDuration);
-            mediaVideoItem.addOverlay(overlayFrame[i]);
-        }
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Time taken to add & create Overlay :" + timeTaken;
-
-        beginTime = SystemClock.uptimeMillis();
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            assertEquals("Removing Overlays", overlayFrame[i],
-                mediaVideoItem.removeOverlay((overlayFrame[i].getId())));
-        }
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[1] = "\n\tTime taken to remove  Overlay :" +
-            timeTaken;
-
-        writeTimingInfo("testPerformanceOverlayVideoItem (in mSec)", loggingInfo);
-    }
-
-    /**
-     * To test the performance of get properties of a Video media item
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceVideoItemProperties() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final int videoItemStartTime1 = 0;
-        final int videoItemEndTime1 = 10100;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
-        final int fileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int duration = 77366;
-        final int videoBitrate = 3169971;
-        final int fps = 30;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileBaseline;
-        final int videoLevel = MediaProperties.H264Level.H264Level13;
-        final int width = 1080;
-        final int height = MediaProperties.HEIGHT_720;
-        int timeTaken = 0;
-        final String[] loggingInfo = new String[1];
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "m0", videoItemFileName1, renderingMode);
-        mediaVideoItem.setExtractBoundaries(videoItemStartTime1,
-            videoItemEndTime1);
-        long beginTime = SystemClock.uptimeMillis();
-        for (int i = 0; i < (NUM_OF_ITERATIONS*10); i++) {
-            try {
-                assertEquals("Aspect Ratio Mismatch",
-                    aspectRatio, mediaVideoItem.getAspectRatio());
-                assertEquals("File Type Mismatch",
-                    fileType, mediaVideoItem.getFileType());
-                assertEquals("VideoCodec Mismatch",
-                    videoCodecType, mediaVideoItem.getVideoType());
-                assertEquals("duration Mismatch",
-                    duration, mediaVideoItem.getDuration());
-                assertEquals("Video Profile ",
-                    videoProfile, mediaVideoItem.getVideoProfile());
-                assertEquals("Video Level ",
-                    videoLevel, mediaVideoItem.getVideoLevel());
-                assertEquals("Video height ",
-                    height, mediaVideoItem.getHeight());
-                assertEquals("Video width ",
-                    width, mediaVideoItem.getWidth());
-            } catch (Exception e1) {
-                assertTrue("Can not create Video Item with file name = "
-                    + e1.toString(), false);
-            }
-        }
-        timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS*10));
-        loggingInfo[0] = "Time taken to get Media Properties :"
-            + timeTaken;
-        writeTimingInfo("testPerformanceVideoItemProperties:", loggingInfo);
-    }
-
-    /**
-     * To test the performance of generatePreview : with Transitions
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceGeneratePreviewWithTransitions()
-        throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String imageItemFileName = INPUT_FILE_PATH +
-            "IMG_1600x1200.jpg";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
-        long averageTime = 0;
-        final String[] loggingInfo = new String[1];
-
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "mediaItem1", videoItemFileName, renderingMode);
-        mediaVideoItem.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
-            "mediaItem2", imageItemFileName, 10000, renderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem);
-
-        final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
-            "transitionCrossFade", mediaVideoItem, mediaImageItem,
-            5000, transitionBehavior);
-        mVideoEditor.addTransition(transitionCrossFade);
-
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            final long duration1 = SystemClock.uptimeMillis();
-            mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-                public void onProgress(Object item, int action, int progress) {
-                }
-            });
-            final long duration2 = SystemClock.uptimeMillis();
-            mVideoEditor.removeTransition(transitionCrossFade.getId());
-            mVideoEditor.addTransition(transitionCrossFade);
-            averageTime += (duration2 - duration1);
-        }
-        final long durationToAddObjects = averageTime;
-        final float timeTaken = (float)durationToAddObjects *
-            1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken to Generate Preview with transition :"
-            + timeTaken;
-        writeTimingInfo("testPerformanceGeneratePreviewWithTransitions:",
-            loggingInfo);
-    }
-
-    /**
-     * To test the performance of generatePreview : with KenBurn
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceWithKenBurn() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String imageItemFileName = INPUT_FILE_PATH +
-            "IMG_1600x1200.jpg";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        long averageTime = 0;
-        final String[] loggingInfo = new String[1];
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "mediaItem1", videoItemFileName, renderingMode);
-        mediaVideoItem.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
-            "mediaItem2", imageItemFileName, 10000, renderingMode);
-        mVideoEditor.addMediaItem(mediaImageItem);
-
-        final Rect startRect = new Rect((mediaImageItem.getHeight() / 3),
-            (mediaImageItem.getWidth() / 3), (mediaImageItem.getHeight() / 2),
-            (mediaImageItem.getWidth() / 2));
-        final Rect endRect = new Rect(0, 0, mediaImageItem.getWidth(),
-            mediaImageItem.getHeight());
-        final EffectKenBurns kbEffectOnMediaItem =
-            new EffectKenBurns(mediaImageItem, "KBOnM2", startRect, endRect,
-                500, 3000);
-        mediaImageItem.addEffect(kbEffectOnMediaItem);
-
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            final long duration1 = SystemClock.uptimeMillis();
-            mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-                public void onProgress(Object item, int action, int progress) {
-                }
-            });
-            final long duration2 = SystemClock.uptimeMillis();
-            mediaImageItem.removeEffect(kbEffectOnMediaItem.getId());
-            mediaImageItem.addEffect(kbEffectOnMediaItem);
-            averageTime += duration2 - duration1;
-        }
-
-        final long durationToAddObjects = (averageTime);
-        final float timeTaken = (float)durationToAddObjects *
-            1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken to Generate KenBurn Effect :"
-            + timeTaken;
-        writeTimingInfo("testPerformanceWithKenBurn", loggingInfo);
-    }
-
-    /**
-     * To test the performance of generatePreview : with Transitions and
-     * Effect,Overlapping scenario
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceEffectOverlappingTransition() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String videoItemFileName2 = INPUT_FILE_PATH
-            + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final int videoStartTime1 = 0;
-        final int videoEndTime1 = 10000;
-        final int videoStartTime2 = 0;
-        final int videoEndTime2 = 10000;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int transitionDuration = 5000;
-        final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
-        final int effectItemStartTime = 5000;
-        final int effectItemDurationTime = 5000;
-        final int effectType = EffectColor.TYPE_COLOR;
-        final int effectColorType = EffectColor.GREEN;
-        long averageDuration = 0;
-
-        final String[] loggingInfo = new String[1];
-        final MediaVideoItem mediaVideoItem1 = new MediaVideoItem(mVideoEditor,
-            "mediaItem1", videoItemFileName1, renderingMode);
-        mediaVideoItem1.setExtractBoundaries(videoStartTime1, videoEndTime1);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 = new MediaVideoItem(mVideoEditor,
-            "mediaItem2", videoItemFileName2, renderingMode);
-        mediaVideoItem2.setExtractBoundaries(videoStartTime2, videoEndTime2);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
-            "transitionCrossFade", mediaVideoItem1, mediaVideoItem2,
-            transitionDuration, transitionBehavior);
-        mVideoEditor.addTransition(transitionCrossFade);
-
-        final EffectColor effectColor = new EffectColor(mediaVideoItem1,
-            "effect", effectItemStartTime, effectItemDurationTime, effectType,
-             effectColorType);
-        mediaVideoItem1.addEffect(effectColor);
-
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            final long duration1 = SystemClock.uptimeMillis();
-            mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-                public void onProgress(Object item, int action, int progress) {
-                }
-            });
-            final long duration2 = SystemClock.uptimeMillis();
-            mVideoEditor.removeTransition(transitionCrossFade.getId());
-            mVideoEditor.addTransition(transitionCrossFade);
-            averageDuration += (duration2 - duration1);
-        }
-        SystemClock.uptimeMillis();
-        final long durationToAddObjects = (averageDuration);
-        final float timeTaken = (float)durationToAddObjects *
-            1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] =
-            "Time taken to testPerformanceEffectOverlappingTransition :"
-            + timeTaken;
-        writeTimingInfo("testPerformanceEffectOverlappingTransition:",
-            loggingInfo);
-    }
-
-    /**
-     * To test creation of story board with Transition and Two Effects, Effect
-     * overlapping transitions
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceTransitionWithEffectOverlapping() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String videoItemFileName2 = INPUT_FILE_PATH
-            + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int transitionDuration = 5000;
-        final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
-        final int effectItemStartTime1 = 5000;
-        final int effectItemDurationTime1 = 5000;
-        final int effectType1 = EffectColor.TYPE_COLOR;
-        final int effectColorType1 = EffectColor.GREEN;
-        final int effectItemStartTime2 = 5000;
-        final int effectItemDurationTime2 = 5000;
-        final int effectType2 = EffectColor.TYPE_COLOR;
-        final int effectColorType2 = EffectColor.GREEN;
-        int averageTime = 0;
-        final String[] loggingInfo = new String[1];
-
-        final MediaVideoItem mediaVideoItem1 = new MediaVideoItem(mVideoEditor,
-            "mediaItem1", videoItemFileName1, renderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem1);
-
-        final MediaVideoItem mediaVideoItem2 = new MediaVideoItem(mVideoEditor,
-            "mediaItem2", videoItemFileName2, renderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem2);
-
-        final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
-            "transitionCrossFade", mediaVideoItem1, mediaVideoItem2,
-            transitionDuration, transitionBehavior);
-        mVideoEditor.addTransition(transitionCrossFade);
-
-        final EffectColor effectColor1 = new EffectColor(mediaVideoItem1,
-            "effect1", effectItemStartTime1, effectItemDurationTime1,
-            effectType1, effectColorType1);
-        mediaVideoItem1.addEffect(effectColor1);
-
-        final EffectColor effectColor2 = new EffectColor(mediaVideoItem2,
-            "effect2", effectItemStartTime2, effectItemDurationTime2,
-            effectType2, effectColorType2);
-        mediaVideoItem2.addEffect(effectColor2);
-
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            final long duration1 = SystemClock.uptimeMillis();
-            mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-                public void onProgress(Object item, int action, int progress) {
-                }
-            });
-            final long duration2 = SystemClock.uptimeMillis();
-            mVideoEditor.removeTransition(transitionCrossFade.getId());
-            mVideoEditor.addTransition(transitionCrossFade);
-            averageTime += duration2 - duration1;
-        }
-        final long durationToAddObjects = (averageTime);
-        final float timeTaken = (float)durationToAddObjects *
-            1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken to TransitionWithEffectOverlapping :"
-            + timeTaken;
-        writeTimingInfo("testPerformanceTransitionWithEffectOverlapping",
-            loggingInfo);
-    }
-
-    /**
-     *To test ThumbnailList for H264
-     */
-    @LargeTest
-    public void testThumbnailH264NonIFrame() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final int outWidth = 1080;
-        final int outHeight = 720;
-        final int atTime = 2400;
-        long durationToAddObjects = 0;
-        int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String[] loggingInfo = new String[1];
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "m1", videoItemFilename, renderingMode);
-        assertNotNull("MediaVideoItem", mediaVideoItem);
-
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            final long duration1 = SystemClock.uptimeMillis();
-            mediaVideoItem.getThumbnail(outWidth, outHeight, atTime + i);
-            final long duration2 = SystemClock.uptimeMillis();
-            durationToAddObjects += (duration2 - duration1);
-        }
-        final float timeTaken = (float)durationToAddObjects *
-            1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken for Thumbnail generation :"
-            + timeTaken;
-        writeTimingInfo("testThumbnailH264NonIFrame", loggingInfo);
-    }
-
-    /**
-     *To test ThumbnailList for H264
-     */
-    @LargeTest
-    public void testThumbnailH264AnIFrame() throws Exception {
-        final String videoItemFilename = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final int outWidth = 1080;
-        final int outHeight = 720;
-        final int atTime = 3000;
-        int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String[] loggingInfo = new String[1];
-        long durationToAddObjects = 0;
-
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "m1", videoItemFilename, renderingMode);
-        assertNotNull("MediaVideoItem", mediaVideoItem);
-
-        for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
-            final long duration1 = SystemClock.uptimeMillis();
-            mediaVideoItem.getThumbnail(outWidth, outHeight, atTime + i);
-            final long duration2 = SystemClock.uptimeMillis();
-            durationToAddObjects += (duration2 - duration1);
-        }
-        final float timeTaken = (float)durationToAddObjects *
-            1.0f/(float)NUM_OF_ITERATIONS;
-        loggingInfo[0] = "Time taken Thumbnail generation :"
-            + timeTaken;
-        writeTimingInfo("testThumbnailH264AnIFrame", loggingInfo);
-    }
-
-    /**
-     * To test the performance : With an audio track
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceWithAudioTrack() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String audioFilename1 = INPUT_FILE_PATH +
-            "AACLC_44.1kHz_256kbps_s_1_17.mp4";
-        final String audioFilename2 = INPUT_FILE_PATH +
-            "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int audioVolume = 50;
-        final String[] loggingInfo = new String[2];
-        int timeTaken = 0;
-
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "mediaItem1", videoItemFileName1, renderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
-            "Audio Track1", audioFilename1);
-        audioTrack1.disableDucking();
-        audioTrack1.setVolume(audioVolume);
-        mVideoEditor.addAudioTrack(audioTrack1);
-
-        long beginTime = SystemClock.uptimeMillis();
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-        timeTaken = calculateTimeTaken(beginTime, 1);
-        loggingInfo[0] = "Time taken for 1st Audio Track (AACLC) :"
-            + timeTaken;
-
-        final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
-            "Audio Track2", audioFilename2);
-        audioTrack2.enableLoop();
-
-        beginTime = SystemClock.uptimeMillis();
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-        timeTaken = calculateTimeTaken(beginTime, 1);
-        loggingInfo[1] = "\n\tTime taken for 2nd Audio Track(AMRNB) :"
-            + timeTaken;
-
-        writeTimingInfo("testPerformanceWithAudioTrack", loggingInfo);
-    }
-
-    /**
-     * To test the performance of adding and removing the
-     * image media item with 640 x 480
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testPerformanceAddRemoveImageItem640x480() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int imageItemDuration = 0;
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String[] loggingInfo = new String[3];
-
-        int timeTaken = 0;
-
-        final MediaImageItem[] mediaImageItem =
-            new MediaImageItem[NUM_OF_ITERATIONS];
-        long beginTime = SystemClock.uptimeMillis();
-        createImageItems(mediaImageItem, imageItemFileName, renderingMode,
-            imageItemDuration);
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[0] = "Time taken to Create  Media Image Item (640x480) :"
-            + timeTaken;
-
-        beginTime = SystemClock.uptimeMillis();
-        addImageItems(mediaImageItem);
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[1] = "\n\tTime taken to add  Media Image Item (640x480) :"
-            + timeTaken;
-
-        beginTime = SystemClock.uptimeMillis();
-        removeImageItems(mediaImageItem);
-        timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
-        loggingInfo[2] = "\n\tTime taken to remove  Media Image Item (640x480) :"
-            + timeTaken;
-        writeTimingInfo("testPerformanceAddRemoveImageItem640x480 (in mSec)", loggingInfo);
-    }
-
-
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
deleted file mode 100644
index 7784c7b..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
+++ /dev/null
@@ -1,1309 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaframeworktest.stress;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.Writer;
-import java.util.List;
-
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.media.videoeditor.AudioTrack;
-import android.media.videoeditor.EffectColor;
-import android.media.videoeditor.EffectKenBurns;
-import android.media.videoeditor.MediaImageItem;
-import android.media.videoeditor.MediaItem;
-import android.media.videoeditor.MediaProperties;
-import android.media.videoeditor.MediaVideoItem;
-import android.media.videoeditor.OverlayFrame;
-import android.media.videoeditor.Transition;
-import android.media.videoeditor.TransitionCrossfade;
-import android.media.videoeditor.TransitionAlpha;
-import android.media.videoeditor.TransitionFadeBlack;
-import android.media.videoeditor.TransitionSliding;
-import android.media.videoeditor.VideoEditor;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase;
-import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase;
-import android.media.videoeditor.VideoEditor.ExportProgressListener;
-import android.media.videoeditor.VideoEditorFactory;
-import android.media.videoeditor.ExtractAudioWaveformProgressListener;
-
-import android.os.Debug;
-import android.util.Log;
-import com.android.mediaframeworktest.MediaFrameworkPerfTestRunner;
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import com.android.mediaframeworktest.VideoEditorHelper;
-import com.android.mediaframeworktest.MediaTestUtil;
-
-/**
- * Junit / Instrumentation - performance measurement for media player and
- * recorder
- */
-public class VideoEditorStressTest
-        extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
-
-    private final String TAG = "VideoEditorStressTest";
-
-    private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
-
-    private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
-
-    private final String VIDEOEDITOR_OUTPUT = PROJECT_LOCATION +
-        "VideoEditorStressMemOutput.txt";
-
-    private long BeginJavaMemory;
-    private long AfterJavaMemory;
-
-    private long BeginNativeMemory;
-    private long AfterNativeMemory;
-
-    public VideoEditorStressTest() {
-        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-        new File(VIDEOEDITOR_OUTPUT).delete();
-    }
-
-    private final String PROJECT_CLASS_NAME =
-        "android.media.videoeditor.VideoEditorImpl";
-    private VideoEditor mVideoEditor;
-    private MediaTestUtil mMediaTestUtil;
-    private VideoEditorHelper mVideoEditorHelper;
-
-    @Override
-    protected void setUp() throws Exception {
-        // setup for each test case.
-        super.setUp();
-        getActivity();
-        mMediaTestUtil = new MediaTestUtil(
-            "/sdcard/VideoEditorMediaServerMemoryLog.txt",
-             this.getName(), "mediaserver");
-        mVideoEditorHelper = new VideoEditorHelper();
-        // Create a random String which will be used as project path, where all
-        // project related files will be stored.
-        final String projectPath =
-            mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
-        mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        final String[] loggingInfo = new String[1];
-        mMediaTestUtil.getMemorySummary();
-        loggingInfo[0] = "\n" +this.getName();
-        writeTimingInfo(loggingInfo);
-        loggingInfo[0] = " diff :  " + (AfterNativeMemory - BeginNativeMemory);
-        writeTimingInfo(loggingInfo);
-        mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
-        // Clean the directory created as project path
-        mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
-        System.gc();
-        super.tearDown();
-    }
-
-    private void writeTimingInfo(String[] information)
-        throws Exception {
-        File outFile = new File(VIDEOEDITOR_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(outFile, true));
-        for (int i = 0; i < information.length; i++) {
-            output.write(information[i]);
-        }
-        output.close();
-    }
-
-    private void writeTestCaseHeader(String testCaseName)
-        throws Exception {
-        File outFile = new File(VIDEOEDITOR_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(outFile, true));
-        output.write("\n\n" + testCaseName + "\n");
-        output.close();
-    }
-
-    private void getBeginMemory() throws Exception {
-        System.gc();
-        Thread.sleep(2500);
-        BeginNativeMemory = Debug.getNativeHeapAllocatedSize();
-        mMediaTestUtil.getStartMemoryLog();
-    }
-    private void getAfterMemory_updateLog(String[] loggingInfo, boolean when,
-        int iteration)
-        throws Exception {
-        System.gc();
-        Thread.sleep(2500);
-        AfterNativeMemory = Debug.getNativeHeapAllocatedSize();
-        if(when == false){
-            loggingInfo[0] = "\n Before Remove: iteration No.= " + iteration +
-                "\t " + (AfterNativeMemory - BeginNativeMemory);
-        } else {
-            loggingInfo[0] = "\n After Remove: iteration No.= " + iteration +
-                "\t " + (AfterNativeMemory - BeginNativeMemory);
-        }
-        writeTimingInfo(loggingInfo);
-        mMediaTestUtil.getMemoryLog();
-    }
-
-    /**
-     * To stress test MediaItem(Video Item) adding functionality
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressAddRemoveVideoItem() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_176x144_15fps_144kbps_AMRNB_8kHz_12.2kbps_m_1_17.3gp";
-        final String videoItemFileName2 = INPUT_FILE_PATH +
-            "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
-        final String videoItemFileName3 = INPUT_FILE_PATH +
-            "H263_profile0_176x144_15fps_128kbps_1_35.3gp";
-        final String videoItemFileName4 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
-        final String[] loggingInfo = new String[1];
-        writeTestCaseHeader("testStressAddRemoveVideoItem");
-        int i = 0;
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            if (i % 4 == 0) {
-                final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-                    "m1" + i, videoItemFileName1, renderingMode);
-                mediaItem1.setExtractBoundaries(0, 5000);
-                mVideoEditor.addMediaItem(mediaItem1);
-            }
-            if (i % 4 == 1) {
-                final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
-                    "m2" + i, videoItemFileName2, renderingMode);
-                mediaItem2.setExtractBoundaries(0, 10000);
-                mVideoEditor.addMediaItem(mediaItem2);
-            }
-            if (i % 4 == 2) {
-                final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
-                    "m3" + i, videoItemFileName3, renderingMode);
-                mediaItem3.setExtractBoundaries(30000, 45000);
-                mVideoEditor.addMediaItem(mediaItem3);
-            }
-            if (i % 4 == 3) {
-                final MediaVideoItem mediaItem4 = new MediaVideoItem(mVideoEditor,
-                    "m4" + i, videoItemFileName4, renderingMode);
-                mediaItem4.setExtractBoundaries(10000, 30000);
-                mVideoEditor.addMediaItem(mediaItem4);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        for ( i = 0; i < 50; i++) {
-            if (i % 4 == 0) {
-                mVideoEditor.removeMediaItem("m1" + i);
-            }
-            if (i % 4 == 1) {
-                mVideoEditor.removeMediaItem("m2" + i);
-            }
-            if (i % 4 == 2) {
-                mVideoEditor.removeMediaItem("m3" + i);
-            }
-            if (i % 4 == 3) {
-                mVideoEditor.removeMediaItem("m4" + i);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, true, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * To stress test MediaItem(Image Item) adding functionality
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressAddRemoveImageItem() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String ImageItemFileName1 = INPUT_FILE_PATH +
-            "IMG_1600x1200.jpg";
-        final String ImageItemFileName2 = INPUT_FILE_PATH +
-            "IMG_640x480.jpg";
-        final String ImageItemFileName3 = INPUT_FILE_PATH +
-            "IMG_320x240.jpg";
-        final String ImageItemFileName4 = INPUT_FILE_PATH +
-            "IMG_176x144.jpg";
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        writeTestCaseHeader("testStressAddRemoveImageItem");
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            if (i % 4 == 0) {
-                final MediaImageItem mediaItem1 = new MediaImageItem(mVideoEditor,
-                    "m1"+ i, ImageItemFileName1, 5000, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem1);
-            }
-            if (i % 4 == 1) {
-                final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
-                    "m2"+ i, ImageItemFileName2, 10000, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem2);
-            }
-            if (i % 4 == 2) {
-                final MediaImageItem mediaItem3 = new MediaImageItem(mVideoEditor,
-                    "m3"+ i, ImageItemFileName3, 15000, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem3);
-            }
-            if (i % 4 == 3) {
-                final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
-                    "m4"+ i, ImageItemFileName4, 20000, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem4);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        for ( i = 0; i < 50; i++) {
-            if (i % 4 == 0) {
-                mVideoEditor.removeMediaItem("m1"+i);
-            }
-            if (i % 4 == 1) {
-                mVideoEditor.removeMediaItem("m2"+i);
-            }
-            if (i % 4 == 2) {
-                mVideoEditor.removeMediaItem("m3"+i);
-            }
-            if (i % 4 == 3) {
-                mVideoEditor.removeMediaItem("m4"+i);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, true, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * To stress test transition
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressAddRemoveTransition() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String VideoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_1_17.mp4";
-        final String ImageItemFileName2 = INPUT_FILE_PATH +
-            "IMG_1600x1200.jpg";
-        final String VideoItemFileName3 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final String maskFilename = INPUT_FILE_PATH +
-            "TransitionSpiral_QVGA.jpg";
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        writeTestCaseHeader("testStressAddRemoveTransition");
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            if (i % 4 == 0) {
-                final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-                    "m1"+i, VideoItemFileName1, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem1);
-                mediaItem1.setExtractBoundaries(0, 10000);
-                final TransitionCrossfade tranCrossfade =
-                    new TransitionCrossfade("transCF" + i, null,
-                        mediaItem1, 5000, Transition.BEHAVIOR_MIDDLE_FAST);
-                mVideoEditor.addTransition(tranCrossfade);
-            }
-            if (i % 4 == 1) {
-                final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-                    "m1"+i, VideoItemFileName1, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem1);
-                mediaItem1.setExtractBoundaries(0, 10000);
-
-                final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
-                    "m2" +i, ImageItemFileName2, 10000, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem2);
-
-                final TransitionAlpha transitionAlpha =
-                    mVideoEditorHelper.createTAlpha("transAlpha" + i, mediaItem1,
-                        mediaItem2, 5000, Transition.BEHAVIOR_SPEED_UP,
-                        maskFilename, 10, false);
-                transitionAlpha.setDuration(4000);
-                mVideoEditor.addTransition(transitionAlpha);
-            }
-            if (i % 4 == 2) {
-                final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
-                    "m2" + i, ImageItemFileName2, 10000, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem2);
-
-                final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
-                    "m3" + i, VideoItemFileName3, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem3);
-
-                mediaItem3.setExtractBoundaries(0, 10000);
-                final TransitionAlpha transitionAlpha =
-                    mVideoEditorHelper.createTAlpha("transAlpha" + i, mediaItem2,
-                        mediaItem3, 5000, Transition.BEHAVIOR_SPEED_UP,
-                        maskFilename, 10, false);
-                transitionAlpha.setDuration(4000);
-                mVideoEditor.addTransition(transitionAlpha);
-
-                mediaItem3.setExtractBoundaries(0, 6000);
-
-                final TransitionSliding transition2And3 =
-                    mVideoEditorHelper.createTSliding("transSlide" +i, mediaItem2,
-                        mediaItem3, 3000, Transition.BEHAVIOR_MIDDLE_FAST,
-                        TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN);
-                mVideoEditor.addTransition(transition2And3);
-            }
-            if (i % 4 == 3) {
-                final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
-                    "m3" + i, VideoItemFileName3, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem3);
-                mediaItem3.setExtractBoundaries(0, 5000);
-
-                final TransitionFadeBlack transition3 =
-                    mVideoEditorHelper.createTFadeBlack("transFB" +i, mediaItem3,
-                        null, 2500, Transition.BEHAVIOR_SPEED_UP);
-                transition3.setDuration(500);
-                mVideoEditor.addTransition(transition3);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        for ( i = 0; i < 50; i++) {
-            if (i % 4 == 0) {
-                mVideoEditor.removeTransition("transCF" + i);
-                mVideoEditor.removeMediaItem("m1" + i);
-            }
-            if (i % 4 == 1) {
-                mVideoEditor.removeTransition("transAlpha" + i);
-                mVideoEditor.removeMediaItem("m1" + i);
-                mVideoEditor.removeMediaItem("m2" + i);
-            }
-            if (i % 4 == 2) {
-                mVideoEditor.removeTransition("transSlide" +i);
-                mVideoEditor.removeMediaItem("m2" + i);
-                mVideoEditor.removeMediaItem("m3" + i);
-            }
-            if (i % 4 == 3) {
-                mVideoEditor.removeMediaItem("m3" + i);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, true, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * To stress test overlay
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressAddRemoveOverlay() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String VideoItemFileName1 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final String ImageItemFileName2 = INPUT_FILE_PATH +
-            "IMG_640x480.jpg";
-        final String OverlayFile3 = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay1.png";
-        final String OverlayFile4 = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay2.png";
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-            "m1", VideoItemFileName1, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem1);
-
-        final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
-            "m2", ImageItemFileName2, 10000, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem2);
-        writeTestCaseHeader("testStressAddRemoveOverlay");
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            if (i % 3 == 0) {
-                mediaItem1.setExtractBoundaries(0, 10000);
-                final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(
-                    OverlayFile3, 640, 480);
-                final OverlayFrame overlayFrame =
-                    mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
-                        mBitmap, 1000, 5000);
-                mediaItem1.addOverlay(overlayFrame);
-                mediaItem1.removeOverlay("overlay"+i);
-            }
-            if (i % 3 == 1) {
-                final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(
-                    OverlayFile4, 640, 480);
-                final OverlayFrame overlayFrame =
-                    mVideoEditorHelper.createOverlay(mediaItem2, "overlay" + i,
-                        mBitmap, 1000, 5000);
-                mediaItem2.addOverlay(overlayFrame);
-                mediaItem2.removeOverlay("overlay"+i);
-            }
-            if (i % 3 == 2) {
-                mediaItem1.setExtractBoundaries(0, 10000);
-                final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(
-                    OverlayFile4, 640, 480);
-                final OverlayFrame overlayFrame =
-                    mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
-                        mBitmap, 0, mediaItem1.getDuration());
-                mediaItem1.addOverlay(overlayFrame);
-                mediaItem1.removeOverlay("overlay"+i);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-    }
-
-    /**
-     * To stress test Effects
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressAddRemoveEffects() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String VideoItemFileName1 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
-        final String ImageItemFileName2 = INPUT_FILE_PATH +
-            "IMG_1600x1200.jpg";
-        final String[] loggingInfo = new String[1];
-        final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-            "m1", VideoItemFileName1, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem1);
-        final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
-            "m2", ImageItemFileName2, 10000, renderingMode);
-        int i = 0;
-        mVideoEditor.addMediaItem(mediaItem2);
-        writeTestCaseHeader("testStressAddRemoveEffects");
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            if (i % 5 == 0) {
-                mediaItem1.setExtractBoundaries(10000, 30000);
-                final EffectColor effectColor1 =
-                    mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
-                        10000, (mediaItem1.getTimelineDuration()-1000),
-                        EffectColor.TYPE_COLOR, EffectColor.GREEN);
-                mediaItem1.addEffect(effectColor1);
-            }
-            if (i % 5 == 1) {
-                mediaItem2.setDuration(20000);
-                final EffectColor effectColor1 =
-                    mVideoEditorHelper.createEffectItem(mediaItem2, "effect1"+i,
-                        0, 4000, EffectColor.TYPE_GRADIENT, EffectColor.GRAY);
-                mediaItem2.addEffect(effectColor1);
-            }
-            if (i % 5 == 2) {
-                mediaItem1.setExtractBoundaries(10000, 30000);
-                final EffectColor effectColor1 =
-                    mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
-                        (mediaItem1.getTimelineDuration() - 4000), 4000,
-                        EffectColor.TYPE_SEPIA, 0);
-                mediaItem1.addEffect(effectColor1);
-            }
-            if (i % 5 == 3) {
-                mediaItem2.setDuration(20000);
-                final EffectColor effectColor1 =
-                    mVideoEditorHelper.createEffectItem(mediaItem2, "effect1"+i,
-                        10000, 4000, EffectColor.TYPE_NEGATIVE, 0);
-                mediaItem2.addEffect(effectColor1);
-            }
-            if (i % 5 == 4) {
-                mediaItem2.setDuration(20000);
-                final Rect startRect = new Rect((mediaItem2.getHeight() / 3),
-                    (mediaItem2.getWidth() / 3), (mediaItem2.getHeight() / 2),
-                    (mediaItem2.getWidth() / 2));
-                final Rect endRect = new Rect(0, 0, mediaItem2.getWidth(),
-                    mediaItem2.getHeight());
-                final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
-                    mediaItem2, "KBOnM2" + i, startRect, endRect, 500,
-                    (mediaItem2.getDuration() - 500));
-                mediaItem2.addEffect(kbEffectOnMediaItem);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        for ( i = 0; i < 50; i++) {
-            if (i % 5 == 0) {
-                mediaItem1.removeEffect("effect1"+i);
-            }
-            if (i % 5 == 1) {
-                mediaItem1.removeEffect("effect1"+i);
-            }
-            if (i % 5 == 2) {
-                mediaItem1.removeEffect("effect1"+i);
-            }
-            if (i % 5 == 3) {
-                mediaItem1.removeEffect("effect1"+i);
-            }
-            if (i % 5 == 4) {
-                mediaItem1.removeEffect("KBOnM2"+i);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, true, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * This method will test thumbnail list extraction in a loop = 200 for Video
-     * Item
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressThumbnailVideoItem() throws Exception {
-        final String videoItemFileName = INPUT_FILE_PATH
-                + "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_64kps_m_0_27.3gp";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "m1", videoItemFileName, renderingMode);
-        writeTestCaseHeader("testStressThumbnailVideoItem");
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            if (i % 4 == 0) {
-                final Bitmap[] thumbNails =
-                    mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*3,
-                        mediaVideoItem.getHeight()/2, i, 5000, 2);
-                // Recycle this Bitmap array
-                for (int i1 = 0; i1 < thumbNails.length; i1++) {
-                    thumbNails[i1].recycle();
-                }
-            }
-            if (i % 4 == 1) {
-                final Bitmap[] thumbNails =
-                    mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()/2,
-                        mediaVideoItem.getHeight() * 3, i, 5000, 2);
-                // Recycle this Bitmap array
-                for (int i1 = 0; i1 < thumbNails.length; i1++) {
-                    thumbNails[i1].recycle();
-                }
-            }
-            if (i % 4 == 2) {
-                final Bitmap[] thumbNails =
-                    mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*2,
-                        mediaVideoItem.getHeight() / 3, i, 5000, 2);
-                // Recycle this Bitmap array
-                for (int i1 = 0; i1 < thumbNails.length; i1++) {
-                    thumbNails[i1].recycle();
-                }
-            }
-            if (i % 4 == 3) {
-                final Bitmap[] thumbNails =
-                    mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth(),
-                        mediaVideoItem.getHeight(), i, 5000, 2);
-                // Recycle this Bitmap array
-                for (int i1 = 0; i1 < thumbNails.length; i1++) {
-                    thumbNails[i1].recycle();
-                }
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-    }
-
-    /**
-     * To stress test media properties
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressMediaProperties() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String VideoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String ImageItemFileName2 = INPUT_FILE_PATH +
-            "IMG_640x480.jpg";
-        final String AudioItemFileName3 = INPUT_FILE_PATH +
-            "AACLC_44.1kHz_256kbps_s_1_17.mp4";
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        final int videoAspectRatio = MediaProperties.ASPECT_RATIO_3_2;
-        final int videoFileType = MediaProperties.FILE_MP4;
-        final int videoCodecType = MediaProperties.VCODEC_H264;
-        final int videoDuration = 77366;
-        final int videoProfile = MediaProperties.H264Profile.H264ProfileBaseline;
-        final int videoLevel = MediaProperties.H264Level.H264Level13;
-        final int videoHeight = MediaProperties.HEIGHT_720;
-        final int videoWidth = 1080;
-
-        final int imageAspectRatio = MediaProperties.ASPECT_RATIO_4_3;
-        final int imageFileType = MediaProperties.FILE_JPEG;
-        final int imageWidth = 640;
-        final int imageHeight = MediaProperties.HEIGHT_480;
-
-        final int audioDuration = 77554;
-        final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
-        final int audioSamplingFrequency = 44100;
-        final int audioChannel = 2;
-        writeTestCaseHeader("testStressMediaProperties");
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            if (i % 3 == 0) {
-                final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-                    "m1" + i, VideoItemFileName1, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem1);
-                mediaItem1.setExtractBoundaries(0, 20000);
-                assertEquals("Aspect Ratio Mismatch",
-                    videoAspectRatio, mediaItem1.getAspectRatio());
-                assertEquals("File Type Mismatch",
-                    videoFileType, mediaItem1.getFileType());
-                assertEquals("VideoCodec Mismatch",
-                    videoCodecType, mediaItem1.getVideoType());
-                assertEquals("duration Mismatch",
-                    videoDuration, mediaItem1.getDuration());
-                assertEquals("Video Profile ",
-                    videoProfile, mediaItem1.getVideoProfile());
-                assertEquals("Video Level ",
-                    videoLevel, mediaItem1.getVideoLevel());
-                assertEquals("Video height ",
-                    videoHeight, mediaItem1.getHeight());
-                assertEquals("Video width ",
-                    videoWidth, mediaItem1.getWidth());
-                mVideoEditor.removeMediaItem("m1" + i);
-            }
-            if (i % 3 == 1) {
-                final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
-                    "m2" + i, ImageItemFileName2, 10000, renderingMode);
-                mVideoEditor.addMediaItem(mediaItem2);
-                assertEquals("Aspect Ratio Mismatch",
-                    imageAspectRatio, mediaItem2.getAspectRatio());
-                assertEquals("File Type Mismatch",
-                    imageFileType, mediaItem2.getFileType());
-                assertEquals("Image height",
-                    imageHeight, mediaItem2.getHeight());
-                assertEquals("Image width",
-                    imageWidth, mediaItem2.getWidth());
-                mVideoEditor.removeMediaItem("m2" + i);
-            }
-            if (i % 3 == 2) {
-                final AudioTrack mediaItem3 = new AudioTrack(mVideoEditor,
-                    "m3" + i, AudioItemFileName3);
-                mVideoEditor.addAudioTrack(mediaItem3);
-                assertEquals("AudioType Mismatch", audioCodecType,
-                    mediaItem3.getAudioType());
-                assertEquals("Audio Sampling", audioSamplingFrequency,
-                    mediaItem3.getAudioSamplingFrequency());
-                assertEquals("Audio Channels",
-                    audioChannel, mediaItem3.getAudioChannels());
-                assertEquals("duration Mismatch", audioDuration,
-                    mediaItem3.getDuration());
-                mVideoEditor.removeAudioTrack("m3" + i);
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-    }
-
-    /**
-     * To stress test insert and move of mediaitems
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressInsertMovieItems() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String VideoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String VideoItemFileName2 = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_1_17.mp4";
-        final String VideoItemFileName3 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        writeTestCaseHeader("testStressInsertMovieItems");
-
-        final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-            "m1", VideoItemFileName1, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem1);
-        mediaItem1.setExtractBoundaries(0, 10000);
-
-        final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
-            "m2", VideoItemFileName2, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem2);
-        mediaItem2.setExtractBoundaries(0, 15000);
-
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
-                "m3" + i, VideoItemFileName3, renderingMode);
-            mediaItem3.setExtractBoundaries(0, 15000);
-            mVideoEditor.insertMediaItem(mediaItem3, "m1");
-            mVideoEditor.moveMediaItem("m2", "m3" + i);
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        for ( i = 0; i < 50; i++) {
-            mVideoEditor.removeMediaItem("m3" + i);
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, true, i);
-            }
-        }
-        mVideoEditor.removeMediaItem("m2");
-        mVideoEditor.removeMediaItem("m1");
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * To stress test : load and save
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressLoadAndSave() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String VideoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String VideoItemFileName2 = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_1_17.mp4";
-        final String VideoItemFileName3 = INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
-        final String ImageItemFileName4 = INPUT_FILE_PATH +
-            "IMG_640x480.jpg";
-        final String ImageItemFileName5 = INPUT_FILE_PATH +
-            "IMG_176x144.jpg";
-        final String OverlayFile6 = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay1.png";
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        final String[] projectPath = new String[10];
-        writeTestCaseHeader("testStressLoadAndSave");
-        getBeginMemory();
-        for( i=0; i < 10; i++){
-
-            projectPath[i] =
-                mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
-            final VideoEditor mVideoEditor1 =
-                mVideoEditorHelper.createVideoEditor(projectPath[i]);
-
-            final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor1,
-                "m1", VideoItemFileName1, renderingMode);
-            mVideoEditor1.addMediaItem(mediaItem1);
-            mediaItem1.setExtractBoundaries(0, 10000);
-
-            final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor1,
-                "m2", VideoItemFileName2, renderingMode);
-            mVideoEditor1.addMediaItem(mediaItem2);
-            mediaItem2.setExtractBoundaries(mediaItem2.getDuration()/4,
-                mediaItem2.getDuration()/2);
-
-            final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor1,
-                "m3", VideoItemFileName3, renderingMode);
-            mVideoEditor1.addMediaItem(mediaItem3);
-            mediaItem3.setExtractBoundaries(mediaItem3.getDuration()/2,
-                mediaItem3.getDuration());
-
-            final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor1,
-                "m4", ImageItemFileName4, 5000, renderingMode);
-            mVideoEditor1.addMediaItem(mediaItem4);
-
-            final MediaImageItem mediaItem5 = new MediaImageItem(mVideoEditor1,
-                "m5", ImageItemFileName5, 5000, renderingMode);
-            mVideoEditor1.addMediaItem(mediaItem5);
-
-            final EffectColor effectColor1 =
-                mVideoEditorHelper.createEffectItem(mediaItem3, "effect1",
-                    10000, 2000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
-            mediaItem3.addEffect(effectColor1);
-
-            final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(OverlayFile6,
-                640, 480);
-            final OverlayFrame overlayFrame =
-                mVideoEditorHelper.createOverlay(mediaItem4, "overlay",
-                    mBitmap, 4000, 1000);
-            mediaItem4.addOverlay(overlayFrame);
-
-            final TransitionCrossfade tranCrossfade =
-                new TransitionCrossfade("transCF", mediaItem1,
-                    mediaItem2, 5000, Transition.BEHAVIOR_MIDDLE_FAST);
-            mVideoEditor1.addTransition(tranCrossfade);
-
-            final EffectColor effectColor2 =
-                mVideoEditorHelper.createEffectItem(mediaItem4, "effect2", 0,
-                    mediaItem4.getDuration(), EffectColor.TYPE_COLOR,
-                    EffectColor.PINK);
-            mediaItem4.addEffect(effectColor2);
-
-            mVideoEditor1.generatePreview(new MediaProcessingProgressListener() {
-                public void onProgress(Object item, int action, int progress) {
-                }
-            });
-
-            mVideoEditor1.save();
-            mVideoEditor1.release();
-
-            getAfterMemory_updateLog(loggingInfo, false, i);
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        for( i=0; i<10; i++){
-            final VideoEditor mVideoEditor1b =
-                VideoEditorFactory.load(projectPath[i], true);
-            List<MediaItem> mediaList = mVideoEditor1b.getAllMediaItems();
-            assertEquals("Media Item List Size", 5, mediaList.size());
-
-            mediaList.get(3).removeEffect("effect1");
-            mediaList.get(3).removeEffect("effect2");
-            mediaList.get(2).removeOverlay("overlay");
-            mVideoEditor1b.removeTransition("transCF");
-            mVideoEditor1b.removeMediaItem("m5");
-            mVideoEditor1b.removeMediaItem("m4");
-            mVideoEditor1b.removeMediaItem("m3");
-            mVideoEditor1b.removeMediaItem("m2");
-            mVideoEditor1b.removeMediaItem("m1");
-            mVideoEditor1b.release();
-            getAfterMemory_updateLog(loggingInfo, true, i);
-        }
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * To stress test : Multiple Export
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressMultipleExport() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String VideoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String VideoItemFileName2 = INPUT_FILE_PATH +
-            "H264_BP_800x480_15fps_512kbps_1_17.mp4";
-        final String[] loggingInfo = new String[1];
-        final String outFilename = mVideoEditorHelper.createRandomFile(
-            mVideoEditor.getPath() + "/") + ".3gp";
-        int i = 0;
-        writeTestCaseHeader("testStressMultipleExport");
-        getBeginMemory();
-        final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-            "m1", VideoItemFileName1, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem1);
-        mediaItem1.setExtractBoundaries(0, 10000);
-
-        final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
-            "m2", VideoItemFileName2, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem2);
-        mediaItem2.setExtractBoundaries(0, 15000);
-
-        for ( i = 0; i < 50; i++) {
-            if(i%4 ==0){
-                final int aspectRatio = MediaProperties.ASPECT_RATIO_11_9;
-                mVideoEditor.setAspectRatio(aspectRatio);
-                mVideoEditor.export(outFilename, MediaProperties.HEIGHT_288,
-                    MediaProperties.BITRATE_256K,MediaProperties.ACODEC_AAC_LC,
-                        MediaProperties.VCODEC_H263,
-                        new ExportProgressListener() {
-                        public void onProgress(VideoEditor ve, String outFileName,
-                            int progress) {
-                        }
-                    });
-            }
-            if(i%4 ==1){
-                final int aspectRatio = MediaProperties.ASPECT_RATIO_5_3;
-                mVideoEditor.setAspectRatio(aspectRatio);
-                mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
-                    MediaProperties.BITRATE_384K,MediaProperties.ACODEC_AAC_LC,
-                        MediaProperties.VCODEC_MPEG4,
-                        new ExportProgressListener() {
-                        public void onProgress(VideoEditor ve, String outFileName,
-                            int progress) {
-                        }
-                    });
-            }
-            if(i%4 ==2){
-                final int aspectRatio = MediaProperties.ASPECT_RATIO_11_9;
-                mVideoEditor.setAspectRatio(aspectRatio);
-                mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
-                    MediaProperties.BITRATE_512K,MediaProperties.ACODEC_AAC_LC,
-                        MediaProperties.VCODEC_H264,
-                        new ExportProgressListener() {
-                        public void onProgress(VideoEditor ve, String outFileName,
-                            int progress) {
-                        }
-                    });
-            }
-            if(i%4 ==3){
-                final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
-                mVideoEditor.setAspectRatio(aspectRatio);
-                mVideoEditor.export(outFilename, MediaProperties.HEIGHT_480,
-                    MediaProperties.BITRATE_800K,MediaProperties.ACODEC_AAC_LC,
-                        MediaProperties.VCODEC_H264,
-                        new ExportProgressListener() {
-                        public void onProgress(VideoEditor ve, String outFileName,
-                            int progress) {
-                        }
-                    });
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        mVideoEditor.removeMediaItem("m2");
-        mVideoEditor.removeMediaItem("m1");
-
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * To stress test Media Item,Overlays,Transitions and Ken Burn
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressOverlayTransKenBurn() throws Exception {
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String VideoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_640x480_30fps_256kbps_1_17.mp4";
-        final String ImageItemFileName2 = INPUT_FILE_PATH +
-            "IMG_640x480.jpg";
-        final String OverlayFile3 = INPUT_FILE_PATH +
-            "IMG_640x480_Overlay1.png";
-        final String audioFilename4 = INPUT_FILE_PATH +
-            "AACLC_44.1kHz_256kbps_s_1_17.mp4";
-        int i = 0;
-        final String[] loggingInfo = new String[1];
-        writeTestCaseHeader("testStressOverlayTransKenBurn");
-        getBeginMemory();
-        for ( i = 0; i < 10; i++) {
-            final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-                "m1" + i, VideoItemFileName1, renderingMode);
-            mVideoEditor.addMediaItem(mediaItem1);
-            mediaItem1.setExtractBoundaries(0, 10000);
-
-            final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
-                "m2" + i, ImageItemFileName2, 10000, renderingMode);
-            mVideoEditor.addMediaItem(mediaItem2);
-
-            final EffectColor effectColor1 =
-                mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
-                    (mediaItem1.getDuration() - 4000), 4000,
-                    EffectColor.TYPE_SEPIA, 0);
-            mediaItem1.addEffect(effectColor1);
-
-            final TransitionCrossfade tranCrossfade =
-                new TransitionCrossfade("transCF" + i, mediaItem1,
-                    mediaItem2, 4000, Transition.BEHAVIOR_MIDDLE_FAST);
-            mVideoEditor.addTransition(tranCrossfade);
-
-            final Bitmap mBitmap =  mVideoEditorHelper.getBitmap(OverlayFile3,
-                640, 480);
-            final OverlayFrame overlayFrame =
-                mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
-                    mBitmap, 1000, 5000);
-            mediaItem1.addOverlay(overlayFrame);
-
-            final Rect startRect = new Rect((mediaItem2.getHeight() / 3),
-                (mediaItem2.getWidth() / 3), (mediaItem2.getHeight() / 2),
-                (mediaItem2.getWidth() / 2));
-            final Rect endRect = new Rect(0, 0, mediaItem2.getWidth(),
-                mediaItem2.getHeight());
-
-            final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
-                mediaItem2, "KBOnM2" + i, startRect, endRect, 500,
-                (mediaItem2.getDuration()-500));
-            mediaItem2.addEffect(kbEffectOnMediaItem);
-
-            if(i == 5) {
-                final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
-                    "Audio Track1", audioFilename4);
-                mVideoEditor.addAudioTrack(audioTrack1);
-            }
-            getAfterMemory_updateLog(loggingInfo, false, i);
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        for ( i = 0; i < 10; i++) {
-            MediaImageItem m2 = (MediaImageItem)mVideoEditor.getMediaItem("m2"+i);
-            MediaVideoItem m1 = (MediaVideoItem)mVideoEditor.getMediaItem("m1"+i);
-            m2.removeEffect("KBOnM2" + i);
-            m1.removeOverlay("overlay" + i);
-            mVideoEditor.removeTransition("transCF" + i);
-            m1.removeEffect("effect1" + i);
-            mVideoEditor.removeMediaItem("m2" + i);
-            mVideoEditor.removeMediaItem("m1" + i);
-            if(i == 5) {
-                mVideoEditor.removeAudioTrack("Audio Track1");
-            }
-            getAfterMemory_updateLog(loggingInfo, true, i);
-        }
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * To test the performance : With an audio track with Video
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressAudioTrackVideo() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
-        final String audioFilename1 = INPUT_FILE_PATH +
-            "AACLC_44.1kHz_256kbps_s_1_17.mp4";
-        final String audioFilename2 = INPUT_FILE_PATH +
-            "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int audioVolume = 50;
-        final String[] loggingInfo = new String[1];
-        int i = 1;
-        writeTestCaseHeader("testStressAudioTrackVideo");
-        getBeginMemory();
-        final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
-            "mediaItem1", videoItemFileName1, renderingMode);
-        mVideoEditor.addMediaItem(mediaVideoItem);
-
-        final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
-            "Audio Track1", audioFilename1);
-        audioTrack1.disableDucking();
-        audioTrack1.setVolume(audioVolume);
-        mVideoEditor.addAudioTrack(audioTrack1);
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-
-        mVideoEditor.removeAudioTrack("Audio Track1");
-
-        final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
-            "Audio Track2", audioFilename2);
-        audioTrack2.enableLoop();
-
-        mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
-            public void onProgress(Object item, int action, int progress) {
-            }
-        });
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        mVideoEditor.removeMediaItem("mediaItem1");
-
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-    /**
-     * To Test Stress : Story Board creation with out preview or export
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressStoryBoard() throws Exception {
-        final String videoItemFileName1 = INPUT_FILE_PATH +
-            "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
-        final String videoItemFileName2 = INPUT_FILE_PATH +
-            "MPEG4_SP_854x480_15fps_256kbps_AACLC_16khz_48kbps_s_0_26.mp4";
-        final String videoItemFileName3= INPUT_FILE_PATH +
-            "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
-        final String imageItemFileName4 = INPUT_FILE_PATH +
-            "IMG_1600x1200.jpg";
-        final String imageItemFileName5 = INPUT_FILE_PATH +
-            "IMG_176x144.jpg";
-        final String audioFilename6 = INPUT_FILE_PATH +
-            "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
-        final String audioFilename7 = INPUT_FILE_PATH +
-            "AACLC_44.1kHz_256kbps_s_1_17.mp4";
-
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final int audioVolume = 50;
-        final String[] loggingInfo = new String[1];
-        int i = 1;
-
-        writeTestCaseHeader("testStressStoryBoard");
-        getBeginMemory();
-        final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
-            "m1", videoItemFileName1, renderingMode);
-        mediaItem1.setExtractBoundaries(0, 10000);
-        mVideoEditor.addMediaItem(mediaItem1);
-
-        final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
-            "m2", videoItemFileName2, renderingMode);
-        mediaItem2.setExtractBoundaries(mediaItem2.getDuration()/4,
-            mediaItem2.getDuration()/2);
-        mVideoEditor.addMediaItem(mediaItem2);
-
-        final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
-            "m3", videoItemFileName3, renderingMode);
-        mediaItem3.setExtractBoundaries(mediaItem3.getDuration()/2,
-            mediaItem3.getDuration());
-        mVideoEditor.addMediaItem(mediaItem3);
-
-        final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
-            "m4", imageItemFileName4, 5000, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem4);
-
-        final MediaImageItem mediaItem5 = new MediaImageItem(mVideoEditor,
-            "m5", imageItemFileName5, 5000, renderingMode);
-        mVideoEditor.addMediaItem(mediaItem5);
-
-        final TransitionCrossfade tranCrossfade =
-            new TransitionCrossfade("transCF", mediaItem2, mediaItem3, 2500,
-                Transition.BEHAVIOR_MIDDLE_FAST);
-        mVideoEditor.addTransition(tranCrossfade);
-
-        final TransitionCrossfade tranCrossfade1 =
-            new TransitionCrossfade("transCF1", mediaItem3, mediaItem4, 2500,
-                Transition.BEHAVIOR_MIDDLE_FAST);
-        mVideoEditor.addTransition(tranCrossfade1);
-
-        final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
-            "Audio Track1", audioFilename6);
-        mVideoEditor.addAudioTrack(audioTrack1);
-
-        mVideoEditor.removeAudioTrack("Audio Track1");
-        final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
-            "Audio Track2", audioFilename7);
-        mVideoEditor.addAudioTrack(audioTrack2);
-        audioTrack2.enableLoop();
-        getAfterMemory_updateLog(loggingInfo, false, i);
-
-        /** Remove items and check for memory leak if any */
-        getBeginMemory();
-        mVideoEditor.removeAudioTrack("Audio Track2");
-        mVideoEditor.removeTransition("transCF");
-        mVideoEditor.removeTransition("transCF1");
-        mVideoEditor.removeMediaItem("m5");
-        mVideoEditor.removeMediaItem("m4");
-        mVideoEditor.removeMediaItem("m3");
-        mVideoEditor.removeMediaItem("m2");
-        mVideoEditor.removeMediaItem("m1");
-
-        getAfterMemory_updateLog(loggingInfo, true, i);
-    }
-
-     /**
-     * To test the performance : With an audio track Only
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressAudioTrackOnly() throws Exception {
-
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String AudioItemFileName1 = INPUT_FILE_PATH +
-            "AACLC_44.1kHz_256kbps_s_1_17.mp4";
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        writeTestCaseHeader("testStressAudioTrackOnly");
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            final AudioTrack mediaItem1 = new AudioTrack(mVideoEditor,
-                "m1" + i, AudioItemFileName1);
-            mVideoEditor.addAudioTrack(mediaItem1);
-            mediaItem1.enableLoop();
-            mVideoEditor.removeAudioTrack("m1" + i);
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-    }
-
-    /**
-     * This method will test thumbnail list extraction in a loop = 200 for Image
-     * Item
-     *
-     * @throws Exception
-     */
-    @LargeTest
-    public void testStressThumbnailImageItem() throws Exception {
-        final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
-        final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
-        final String[] loggingInfo = new String[1];
-        int i = 0;
-        final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
-            "m1", imageItemFileName, 5000, renderingMode);
-        writeTestCaseHeader("testStressThumbnailImageItem");
-        getBeginMemory();
-        for ( i = 0; i < 50; i++) {
-            if (i % 4 == 0) {
-                final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
-                    mediaImageItem.getWidth() / 2 ,
-                    mediaImageItem.getHeight() / 2, i, 5000, 2);
-                // Recycle this Bitmap array
-                for (int i1 = 0; i1 < thumbNails.length; i1++) {
-                    thumbNails[i1].recycle();
-                }
-            }
-            if (i % 4 == 1) {
-                final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
-                    mediaImageItem.getWidth() / 2,
-                    mediaImageItem.getHeight() * 3, i, 5000, 2);
-                // Recycle this Bitmap array
-                for (int i1 = 0; i1 < thumbNails.length; i1++) {
-                    thumbNails[i1].recycle();
-                }
-            }
-            if (i % 4 == 2) {
-                final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
-                    mediaImageItem.getWidth() * 2,
-                    mediaImageItem.getHeight() / 3, i, 5000, 2);
-                // Recycle this Bitmap array
-                for (int i1 = 0; i1 < thumbNails.length; i1++) {
-                    thumbNails[i1].recycle();
-                }
-            }
-            if (i % 4 == 3) {
-                final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
-                    mediaImageItem.getWidth(),
-                    mediaImageItem.getHeight(), i, 5000, 2);
-                // Recycle this Bitmap array
-                for (int i1 = 0; i1 < thumbNails.length; i1++) {
-                    thumbNails[i1].recycle();
-                }
-            }
-            if (i % 10 == 0) {
-                getAfterMemory_updateLog(loggingInfo, false, i);
-            }
-        }
-        getAfterMemory_updateLog(loggingInfo, false, i);
-    }
-}
diff --git a/preloaded-classes b/preloaded-classes
index 35c52ad..4413cd3 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -601,8 +601,6 @@
 android.media.ResampleInputStream
 android.media.SoundPool
 android.media.ToneGenerator
-android.media.videoeditor.MediaArtistNativeHelper
-android.media.videoeditor.VideoEditorProfile
 android.mtp.MtpDatabase
 android.mtp.MtpDevice
 android.mtp.MtpDeviceInfo
