Loading media/java/android/media/videoeditor/MediaImageItem.java +68 −15 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.media.videoeditor; import java.io.IOException; import java.util.List; import android.graphics.Bitmap; import android.graphics.BitmapFactory; Loading @@ -24,9 +25,14 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.util.Log; import android.util.Pair; /** * This class represents an image item on the storyboard. * 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 { Loading @@ -41,6 +47,7 @@ public class MediaImageItem extends MediaItem { private final int mHeight; private final int mAspectRatio; private long mDurationMs; private int mScaledWidth, mScaledHeight; /** * This class cannot be instantiated by using the default constructor Loading @@ -53,7 +60,7 @@ public class MediaImageItem extends MediaItem { /** * Constructor * * @param mediaItemId The MediaItem id * @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 Loading @@ -64,7 +71,7 @@ public class MediaImageItem extends MediaItem { throws IOException { super(mediaItemId, filename, renderingMode); // Determine the size of the image // Determine the dimensions of the image final BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; BitmapFactory.decodeFile(filename, dbo); Loading @@ -75,6 +82,22 @@ public class MediaImageItem extends MediaItem { // TODO: Determine the aspect ratio from the width and height mAspectRatio = MediaProperties.ASPECT_RATIO_4_3; // 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]; if (mHeight > maxResolution.second) { // We need to scale the image scaleImage(filename, maxResolution.first, maxResolution.second); mScaledWidth = maxResolution.first; mScaledHeight = maxResolution.second; } else { mScaledWidth = mWidth; mScaledHeight = mHeight; } } /* Loading Loading @@ -107,6 +130,20 @@ public class MediaImageItem extends MediaItem { 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} */ Loading Loading @@ -140,15 +177,31 @@ public class MediaImageItem extends MediaItem { } } // TODO: Validate/modify the start and the end time of effects and overlays final List<Overlay> overlays = getAllOverlays(); for (Overlay overlay : overlays) { // Adjust the start time if necessary if (overlay.getStartTime() < getTimelineDuration()) { overlay.setStartTime(0); } /* * {@inheritDoc} */ @Override public long getDuration() { return mDurationMs; // Adjust the duration if necessary if (overlay.getStartTime() + overlay.getDuration() > getTimelineDuration()) { overlay.setDuration(getTimelineDuration() - overlay.getStartTime()); } } final List<Effect> effects = getAllEffects(); for (Effect effect : effects) { // Adjust the start time if necessary if (effect.getStartTime() < getTimelineDuration()) { effect.setStartTime(0); } // Adjust the duration if necessary if (effect.getStartTime() + effect.getDuration() > getTimelineDuration()) { effect.setDuration(getTimelineDuration() - effect.getStartTime()); } } } /* Loading @@ -164,7 +217,7 @@ public class MediaImageItem extends MediaItem { */ @Override public Bitmap getThumbnail(int width, int height, long timeMs) throws IOException { return generateImageThumbnail(mFilename, width, height); return scaleImage(mFilename, width, height); } /* Loading @@ -173,7 +226,7 @@ public class MediaImageItem extends MediaItem { @Override public Bitmap[] getThumbnailList(int width, int height, long startMs, long endMs, int thumbnailCount) throws IOException { final Bitmap thumbnail = generateImageThumbnail(mFilename, width, height); final Bitmap thumbnail = scaleImage(mFilename, width, height); final Bitmap[] thumbnailArray = new Bitmap[thumbnailCount]; for (int i = 0; i < thumbnailCount; i++) { thumbnailArray[i] = thumbnail; Loading @@ -182,7 +235,7 @@ public class MediaImageItem extends MediaItem { } /** * Resize a bitmap within an input stream * Resize a bitmap to the specified width and height * * @param filename The filename * @param width The thumbnail width Loading @@ -190,7 +243,7 @@ public class MediaImageItem extends MediaItem { * * @return The resized bitmap */ private Bitmap generateImageThumbnail(String filename, int width, int height) private Bitmap scaleImage(String filename, int width, int height) throws IOException { final BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; Loading media/java/android/media/videoeditor/MediaItem.java +14 −10 Original line number Diff line number Diff line Loading @@ -157,11 +157,6 @@ public abstract class MediaItem { return mEndTransition; } /** * @return The duration of the media item */ public abstract long getDuration(); /** * @return The timeline duration. This is the actual duration in the * timeline (trimmed duration) Loading Loading @@ -214,7 +209,7 @@ public abstract class MediaItem { throw new IllegalArgumentException("Effect already exists: " + effect.getId()); } if (effect.getStartTime() + effect.getDuration() > getDuration()) { if (effect.getStartTime() + effect.getDuration() > getTimelineDuration()) { throw new IllegalArgumentException( "Effect start time + effect duration > media clip duration"); } Loading Loading @@ -287,7 +282,7 @@ public abstract class MediaItem { throw new IllegalArgumentException("Overlay already exists: " + overlay.getId()); } if (overlay.getStartTime() + overlay.getDuration() > getDuration()) { if (overlay.getStartTime() + overlay.getDuration() > getTimelineDuration()) { throw new IllegalArgumentException( "Overlay start time + overlay duration > media clip duration"); } Loading @@ -299,9 +294,18 @@ public abstract class MediaItem { 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() != getWidth() || bitmap.getHeight() != getHeight()) { if (bitmap.getWidth() != scaledWidth || bitmap.getHeight() != scaledHeight) { throw new IllegalArgumentException( "Bitmap dimensions must match media item dimensions"); } Loading Loading @@ -433,7 +437,7 @@ public abstract class MediaItem { } if (mEndTransition != null) { if (effect.getStartTime() + effect.getDuration() > getDuration() if (effect.getStartTime() + effect.getDuration() > getTimelineDuration() - mEndTransition.getDuration()) { mEndTransition.invalidate(); } Loading @@ -454,7 +458,7 @@ public abstract class MediaItem { } if (mEndTransition != null) { if (overlay.getStartTime() + overlay.getDuration() > getDuration() if (overlay.getStartTime() + overlay.getDuration() > getTimelineDuration() - mEndTransition.getDuration()) { mEndTransition.invalidate(); } Loading media/java/android/media/videoeditor/MediaProperties.java +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ public class MediaProperties { 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; Loading media/java/android/media/videoeditor/MediaVideoItem.java +30 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.media.videoeditor; import java.io.IOException; import java.util.List; import android.graphics.Bitmap; import android.media.MediaRecorder; Loading Loading @@ -222,8 +223,8 @@ public class MediaVideoItem extends MediaItem { String audioWaveformFilename) throws IOException { super(mediaItemId, filename, renderingMode); // TODO: Set these variables correctly mWidth = 0; mHeight = 0; mWidth = 1080; mHeight = 720; mAspectRatio = MediaProperties.ASPECT_RATIO_3_2; mFileType = MediaProperties.FILE_MP4; mVideoType = MediaRecorder.VideoEncoder.H264; Loading Loading @@ -297,7 +298,31 @@ public class MediaVideoItem extends MediaItem { } } // TODO: Validate/modify the start and the end time of effects and overlays final List<Overlay> overlays = getAllOverlays(); for (Overlay overlay : overlays) { // Adjust the start time if necessary if (overlay.getStartTime() < mBeginBoundaryTimeMs) { overlay.setStartTime(mBeginBoundaryTimeMs); } // Adjust the duration if necessary if (overlay.getStartTime() + overlay.getDuration() > getTimelineDuration()) { overlay.setDuration(getTimelineDuration() - overlay.getStartTime()); } } final List<Effect> effects = getAllEffects(); for (Effect effect : effects) { // Adjust the start time if necessary if (effect.getStartTime() < mBeginBoundaryTimeMs) { effect.setStartTime(mBeginBoundaryTimeMs); } // Adjust the duration if necessary if (effect.getStartTime() + effect.getDuration() > getTimelineDuration()) { effect.setDuration(getTimelineDuration() - effect.getStartTime()); } } } /** Loading Loading @@ -374,10 +399,9 @@ public class MediaVideoItem extends MediaItem { return mHeight; } /* * {@inheritDoc} /** * @return The duration of the video clip */ @Override public long getDuration() { return mDurationMs; } Loading media/java/android/media/videoeditor/Transition.java +4 −3 Original line number Diff line number Diff line Loading @@ -147,11 +147,12 @@ public abstract class Transition { */ public long getMaximumDuration() { if (mAfterMediaItem == null) { return mBeforeMediaItem.getDuration() / 2; return mBeforeMediaItem.getTimelineDuration() / 2; } else if (mBeforeMediaItem == null) { return mAfterMediaItem.getDuration() / 2; return mAfterMediaItem.getTimelineDuration() / 2; } else { return (Math.min(mAfterMediaItem.getDuration(), mBeforeMediaItem.getDuration()) / 2); return (Math.min(mAfterMediaItem.getTimelineDuration(), mBeforeMediaItem.getTimelineDuration()) / 2); } } Loading Loading
media/java/android/media/videoeditor/MediaImageItem.java +68 −15 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.media.videoeditor; import java.io.IOException; import java.util.List; import android.graphics.Bitmap; import android.graphics.BitmapFactory; Loading @@ -24,9 +25,14 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.util.Log; import android.util.Pair; /** * This class represents an image item on the storyboard. * 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 { Loading @@ -41,6 +47,7 @@ public class MediaImageItem extends MediaItem { private final int mHeight; private final int mAspectRatio; private long mDurationMs; private int mScaledWidth, mScaledHeight; /** * This class cannot be instantiated by using the default constructor Loading @@ -53,7 +60,7 @@ public class MediaImageItem extends MediaItem { /** * Constructor * * @param mediaItemId The MediaItem id * @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 Loading @@ -64,7 +71,7 @@ public class MediaImageItem extends MediaItem { throws IOException { super(mediaItemId, filename, renderingMode); // Determine the size of the image // Determine the dimensions of the image final BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; BitmapFactory.decodeFile(filename, dbo); Loading @@ -75,6 +82,22 @@ public class MediaImageItem extends MediaItem { // TODO: Determine the aspect ratio from the width and height mAspectRatio = MediaProperties.ASPECT_RATIO_4_3; // 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]; if (mHeight > maxResolution.second) { // We need to scale the image scaleImage(filename, maxResolution.first, maxResolution.second); mScaledWidth = maxResolution.first; mScaledHeight = maxResolution.second; } else { mScaledWidth = mWidth; mScaledHeight = mHeight; } } /* Loading Loading @@ -107,6 +130,20 @@ public class MediaImageItem extends MediaItem { 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} */ Loading Loading @@ -140,15 +177,31 @@ public class MediaImageItem extends MediaItem { } } // TODO: Validate/modify the start and the end time of effects and overlays final List<Overlay> overlays = getAllOverlays(); for (Overlay overlay : overlays) { // Adjust the start time if necessary if (overlay.getStartTime() < getTimelineDuration()) { overlay.setStartTime(0); } /* * {@inheritDoc} */ @Override public long getDuration() { return mDurationMs; // Adjust the duration if necessary if (overlay.getStartTime() + overlay.getDuration() > getTimelineDuration()) { overlay.setDuration(getTimelineDuration() - overlay.getStartTime()); } } final List<Effect> effects = getAllEffects(); for (Effect effect : effects) { // Adjust the start time if necessary if (effect.getStartTime() < getTimelineDuration()) { effect.setStartTime(0); } // Adjust the duration if necessary if (effect.getStartTime() + effect.getDuration() > getTimelineDuration()) { effect.setDuration(getTimelineDuration() - effect.getStartTime()); } } } /* Loading @@ -164,7 +217,7 @@ public class MediaImageItem extends MediaItem { */ @Override public Bitmap getThumbnail(int width, int height, long timeMs) throws IOException { return generateImageThumbnail(mFilename, width, height); return scaleImage(mFilename, width, height); } /* Loading @@ -173,7 +226,7 @@ public class MediaImageItem extends MediaItem { @Override public Bitmap[] getThumbnailList(int width, int height, long startMs, long endMs, int thumbnailCount) throws IOException { final Bitmap thumbnail = generateImageThumbnail(mFilename, width, height); final Bitmap thumbnail = scaleImage(mFilename, width, height); final Bitmap[] thumbnailArray = new Bitmap[thumbnailCount]; for (int i = 0; i < thumbnailCount; i++) { thumbnailArray[i] = thumbnail; Loading @@ -182,7 +235,7 @@ public class MediaImageItem extends MediaItem { } /** * Resize a bitmap within an input stream * Resize a bitmap to the specified width and height * * @param filename The filename * @param width The thumbnail width Loading @@ -190,7 +243,7 @@ public class MediaImageItem extends MediaItem { * * @return The resized bitmap */ private Bitmap generateImageThumbnail(String filename, int width, int height) private Bitmap scaleImage(String filename, int width, int height) throws IOException { final BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; Loading
media/java/android/media/videoeditor/MediaItem.java +14 −10 Original line number Diff line number Diff line Loading @@ -157,11 +157,6 @@ public abstract class MediaItem { return mEndTransition; } /** * @return The duration of the media item */ public abstract long getDuration(); /** * @return The timeline duration. This is the actual duration in the * timeline (trimmed duration) Loading Loading @@ -214,7 +209,7 @@ public abstract class MediaItem { throw new IllegalArgumentException("Effect already exists: " + effect.getId()); } if (effect.getStartTime() + effect.getDuration() > getDuration()) { if (effect.getStartTime() + effect.getDuration() > getTimelineDuration()) { throw new IllegalArgumentException( "Effect start time + effect duration > media clip duration"); } Loading Loading @@ -287,7 +282,7 @@ public abstract class MediaItem { throw new IllegalArgumentException("Overlay already exists: " + overlay.getId()); } if (overlay.getStartTime() + overlay.getDuration() > getDuration()) { if (overlay.getStartTime() + overlay.getDuration() > getTimelineDuration()) { throw new IllegalArgumentException( "Overlay start time + overlay duration > media clip duration"); } Loading @@ -299,9 +294,18 @@ public abstract class MediaItem { 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() != getWidth() || bitmap.getHeight() != getHeight()) { if (bitmap.getWidth() != scaledWidth || bitmap.getHeight() != scaledHeight) { throw new IllegalArgumentException( "Bitmap dimensions must match media item dimensions"); } Loading Loading @@ -433,7 +437,7 @@ public abstract class MediaItem { } if (mEndTransition != null) { if (effect.getStartTime() + effect.getDuration() > getDuration() if (effect.getStartTime() + effect.getDuration() > getTimelineDuration() - mEndTransition.getDuration()) { mEndTransition.invalidate(); } Loading @@ -454,7 +458,7 @@ public abstract class MediaItem { } if (mEndTransition != null) { if (overlay.getStartTime() + overlay.getDuration() > getDuration() if (overlay.getStartTime() + overlay.getDuration() > getTimelineDuration() - mEndTransition.getDuration()) { mEndTransition.invalidate(); } Loading
media/java/android/media/videoeditor/MediaProperties.java +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ public class MediaProperties { 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; Loading
media/java/android/media/videoeditor/MediaVideoItem.java +30 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.media.videoeditor; import java.io.IOException; import java.util.List; import android.graphics.Bitmap; import android.media.MediaRecorder; Loading Loading @@ -222,8 +223,8 @@ public class MediaVideoItem extends MediaItem { String audioWaveformFilename) throws IOException { super(mediaItemId, filename, renderingMode); // TODO: Set these variables correctly mWidth = 0; mHeight = 0; mWidth = 1080; mHeight = 720; mAspectRatio = MediaProperties.ASPECT_RATIO_3_2; mFileType = MediaProperties.FILE_MP4; mVideoType = MediaRecorder.VideoEncoder.H264; Loading Loading @@ -297,7 +298,31 @@ public class MediaVideoItem extends MediaItem { } } // TODO: Validate/modify the start and the end time of effects and overlays final List<Overlay> overlays = getAllOverlays(); for (Overlay overlay : overlays) { // Adjust the start time if necessary if (overlay.getStartTime() < mBeginBoundaryTimeMs) { overlay.setStartTime(mBeginBoundaryTimeMs); } // Adjust the duration if necessary if (overlay.getStartTime() + overlay.getDuration() > getTimelineDuration()) { overlay.setDuration(getTimelineDuration() - overlay.getStartTime()); } } final List<Effect> effects = getAllEffects(); for (Effect effect : effects) { // Adjust the start time if necessary if (effect.getStartTime() < mBeginBoundaryTimeMs) { effect.setStartTime(mBeginBoundaryTimeMs); } // Adjust the duration if necessary if (effect.getStartTime() + effect.getDuration() > getTimelineDuration()) { effect.setDuration(getTimelineDuration() - effect.getStartTime()); } } } /** Loading Loading @@ -374,10 +399,9 @@ public class MediaVideoItem extends MediaItem { return mHeight; } /* * {@inheritDoc} /** * @return The duration of the video clip */ @Override public long getDuration() { return mDurationMs; } Loading
media/java/android/media/videoeditor/Transition.java +4 −3 Original line number Diff line number Diff line Loading @@ -147,11 +147,12 @@ public abstract class Transition { */ public long getMaximumDuration() { if (mAfterMediaItem == null) { return mBeforeMediaItem.getDuration() / 2; return mBeforeMediaItem.getTimelineDuration() / 2; } else if (mBeforeMediaItem == null) { return mAfterMediaItem.getDuration() / 2; return mAfterMediaItem.getTimelineDuration() / 2; } else { return (Math.min(mAfterMediaItem.getDuration(), mBeforeMediaItem.getDuration()) / 2); return (Math.min(mAfterMediaItem.getTimelineDuration(), mBeforeMediaItem.getTimelineDuration()) / 2); } } Loading