summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorChih-Chung Chang <chihchung@google.com>2011-09-08 05:52:44 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-09-08 05:52:44 -0700
commit70ad1c378bce097f9f2dbb79cb8d5d225d4c14d7 (patch)
treef9bca6d4a690a6a46463a15d40ed5c44dd5569cf /media
parent66b10a1cf77e1dd767508930a950b1584143ee9b (diff)
parent47a52158d2df0eb818bf7d589d8ff9fd5c0daaa3 (diff)
downloadframeworks_base-70ad1c378bce097f9f2dbb79cb8d5d225d4c14d7.zip
frameworks_base-70ad1c378bce097f9f2dbb79cb8d5d225d4c14d7.tar.gz
frameworks_base-70ad1c378bce097f9f2dbb79cb8d5d225d4c14d7.tar.bz2
Merge "Fix 5156702: rotate thumbnails"
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/videoeditor/MediaArtistNativeHelper.java163
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaImageItem.java2
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaVideoItem.java19
-rwxr-xr-xmedia/java/android/media/videoeditor/VideoEditorImpl.java21
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorMain.cpp4
5 files changed, 89 insertions, 120 deletions
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index aa0a2e9..d7b8eaa 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3758,65 +3758,33 @@ class MediaArtistNativeHelper {
/**
* This method extracts a frame from the input file
- * and returns the frame as a bitmap
- *
- * @param inputFile The inputFile
- * @param width The width of the output frame
- * @param height The height of the output frame
- * @param timeMS The time in ms at which the frame has to be extracted
- */
- Bitmap getPixels(String inputFile, int width, int height, long timeMS) {
- if (inputFile == null) {
- throw new IllegalArgumentException("Invalid input file");
- }
-
- /* Make width and height as even */
- final int newWidth = (width + 1) & 0xFFFFFFFE;
- final int newHeight = (height + 1) & 0xFFFFFFFE;
-
- /* Create a temp bitmap for resized thumbnails */
- Bitmap tempBitmap = null;
- if ((newWidth != width) || (newHeight != height)) {
- tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
- }
-
- IntBuffer rgb888 = IntBuffer.allocate(newWidth * newHeight * 4);
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- nativeGetPixels(inputFile, rgb888.array(), newWidth, newHeight, timeMS);
-
- if ((newWidth == width) && (newHeight == height)) {
- bitmap.copyPixelsFromBuffer(rgb888);
- } else {
- /* Create a temp bitmap to be used for resize */
- tempBitmap.copyPixelsFromBuffer(rgb888);
-
- /* Create a canvas to resize */
- final Canvas canvas = new Canvas(bitmap);
- canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
- new Rect(0, 0, width, height), sResizePaint);
- canvas.setBitmap(null);
- }
-
- if (tempBitmap != null) {
- tempBitmap.recycle();
- }
-
- return bitmap;
+ * 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 inputFile
- * @param width The width of the output frame
- * @param height The height of the output frame
+ * @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
- * from startMs to endMs
+ * @param videoRotation The rotation degree need to be done for the bitmap
*
* @return The frames as bitmaps in bitmap array
**/
@@ -3824,62 +3792,69 @@ class MediaArtistNativeHelper {
long startMs, long endMs, int thumbnailCount, int[] indices,
final MediaItem.GetThumbnailListCallback callback,
final int videoRotation) {
- /* Make width and height as even */
- final int newWidth = (width + 1) & 0xFFFFFFFE;
- final int newHeight = (height + 1) & 0xFFFFFFFE;
- final int thumbnailSize = newWidth * newHeight;
-
- /* Create a temp bitmap for resized thumbnails */
- final Bitmap tempBitmap =
- (newWidth != width || newHeight != height)
- ? Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888)
+
+ // 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;
- final int[] rgb888 = new int[thumbnailSize];
- final IntBuffer tmpBuffer = IntBuffer.allocate(thumbnailSize);
- nativeGetPixelsList(filename, rgb888, newWidth, newHeight,
- thumbnailCount, videoRotation, startMs, endMs, indices,
+ // 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) {
- Bitmap bitmap = Bitmap.createBitmap(
- width, height, Bitmap.Config.ARGB_8888);
- tmpBuffer.put(rgb888, 0, thumbnailSize);
- tmpBuffer.rewind();
+ // This is the bitmap we will output to the client
+ Bitmap outBitmap = Bitmap.createBitmap(
+ outWidth, outHeight, Bitmap.Config.ARGB_8888);
- if ((newWidth == width) && (newHeight == height)) {
- bitmap.copyPixelsFromBuffer(tmpBuffer);
- } else {
- /* Copy the out rgb buffer to temp bitmap */
- tempBitmap.copyPixelsFromBuffer(tmpBuffer);
+ // Copy int[] to IntBuffer
+ decBuffer.put(decArray, 0, thumbnailSize);
+ decBuffer.rewind();
- /* Create a canvas to resize */
- final Canvas canvas = new Canvas(bitmap);
- canvas.drawBitmap(tempBitmap,
- new Rect(0, 0, newWidth, newHeight),
- new Rect(0, 0, width, height), sResizePaint);
-
- canvas.setBitmap(null);
- }
-
- if (videoRotation == 0) {
- callback.onThumbnail(bitmap, index);
+ if (!needToMassage) {
+ // We can directly read the decoded result to output bitmap
+ outBitmap.copyPixelsFromBuffer(decBuffer);
} else {
- Matrix mtx = new Matrix();
- mtx.postRotate(videoRotation);
- Bitmap rotatedBmp =
- Bitmap.createBitmap(bitmap, 0, 0, width, height, mtx, false);
- callback.onThumbnail(rotatedBmp, index);
-
- if (bitmap != null) {
- bitmap.recycle();
- }
+ // 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 (tempBitmap != null) {
- tempBitmap.recycle();
+ if (tmpBitmap != null) {
+ tmpBitmap.recycle();
}
}
@@ -3996,7 +3971,7 @@ class MediaArtistNativeHelper {
long timeMS);
private native int nativeGetPixelsList(String fileName, int[] pixelArray,
- int width, int height, int nosofTN, int videoRotation, long startTimeMs,
+ int width, int height, int nosofTN, long startTimeMs,
long endTimeMs, int[] indices, NativeGetPixelsListCallback callback);
/**
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index 65a9e19..a862d00 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -606,7 +606,7 @@ public class MediaImageItem extends MediaItem {
public Bitmap getThumbnail(int width, int height, long timeMs) throws IOException {
if (getGeneratedImageClip() != null) {
return mMANativeHelper.getPixels(getGeneratedImageClip(),
- width, height,timeMs);
+ width, height, timeMs, 0);
} else {
return scaleImage(mFilename, width, height);
}
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index 2ce857c..bbcdf57 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -293,7 +293,14 @@ public class MediaVideoItem extends MediaItem {
throw new IllegalArgumentException("Invalid Dimensions");
}
- return mMANativeHelper.getPixels(super.getFilename(), width, height,timeMs);
+ if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
+ int temp = width;
+ width = height;
+ height = temp;
+ }
+
+ return mMANativeHelper.getPixels(
+ getFilename(), width, height, timeMs, mVideoRotationDegree);
}
/*
@@ -318,8 +325,14 @@ public class MediaVideoItem extends MediaItem {
throw new IllegalArgumentException("Invalid dimension");
}
- mMANativeHelper.getPixelsList(super.getFilename(), width,
- height, startMs, endMs, thumbnailCount, indices, callback,
+ if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
+ int temp = width;
+ width = height;
+ height = temp;
+ }
+
+ mMANativeHelper.getPixelsList(getFilename(), width, height,
+ startMs, endMs, thumbnailCount, indices, callback,
mVideoRotationDegree);
}
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index f18dd88..2446c2f 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -1825,27 +1825,10 @@ public class VideoEditorImpl implements VideoEditor {
if (mMediaItems.size() > 0) {
MediaItem mI = mMediaItems.get(0);
/*
- * Lets initialize the width for default aspect ratio i.e 16:9
+ * Keep aspect ratio of the image
*/
int height = 480;
- int width = 854;
- switch (mI.getAspectRatio()) {
- case MediaProperties.ASPECT_RATIO_3_2:
- width = 720;
- break;
- case MediaProperties.ASPECT_RATIO_4_3:
- width = 640;
- break;
- case MediaProperties.ASPECT_RATIO_5_3:
- width = 800;
- break;
- case MediaProperties.ASPECT_RATIO_11_9:
- width = 586;
- break;
- case MediaProperties.ASPECT_RATIO_16_9:
- case MediaProperties.ASPECT_RATIO_UNDEFINED:
- break;
- }
+ int width = mI.getWidth() * height / mI.getHeight();
Bitmap projectBitmap = null;
String filename = mI.getFilename();
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 4e73581..4e954fc 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -185,7 +185,6 @@ static int videoEditor_getPixelsList(
M4OSA_UInt32 width,
M4OSA_UInt32 height,
M4OSA_UInt32 noOfThumbnails,
- M4OSA_UInt32 videoRotation,
jlong startTime,
jlong endTime,
jintArray indexArray,
@@ -292,7 +291,7 @@ static JNINativeMethod gManualEditMethods[] = {
(void *)videoEditor_release },
{"nativeGetPixels", "(Ljava/lang/String;[IIIJ)I",
(void*)videoEditor_getPixels },
- {"nativeGetPixelsList", "(Ljava/lang/String;[IIIIIJJ[ILandroid/media/videoeditor/MediaArtistNativeHelper$NativeGetPixelsListCallback;)I",
+ {"nativeGetPixelsList", "(Ljava/lang/String;[IIIIJJ[ILandroid/media/videoeditor/MediaArtistNativeHelper$NativeGetPixelsListCallback;)I",
(void*)videoEditor_getPixelsList },
{"getMediaProperties",
"(Ljava/lang/String;)Landroid/media/videoeditor/MediaArtistNativeHelper$Properties;",
@@ -2286,7 +2285,6 @@ static int videoEditor_getPixelsList(
M4OSA_UInt32 width,
M4OSA_UInt32 height,
M4OSA_UInt32 noOfThumbnails,
- M4OSA_UInt32 videoRotation,
jlong startTime,
jlong endTime,
jintArray indexArray,