summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorChih-Chung Chang <chihchung@google.com>2011-08-15 20:15:14 +0800
committerChih-Chung Chang <chihchung@google.com>2011-08-16 16:48:43 +0800
commit1f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0 (patch)
tree77c4ad2ab7fce3ab6efff68bf0887631b54f2f01 /media
parent0a2f9664737f112e7a15d8b28e053469845a5a80 (diff)
downloadframeworks_base-1f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0.zip
frameworks_base-1f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0.tar.gz
frameworks_base-1f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0.tar.bz2
Display thumbnails one by one and cache them.
Change-Id: I10808f5bca475aea924817bf532dc5916438563a
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/videoeditor/MediaArtistNativeHelper.java93
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaImageItem.java26
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaItem.java38
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaVideoItem.java18
-rwxr-xr-xmedia/jni/mediaeditor/VideoBrowserInternal.h3
-rwxr-xr-xmedia/jni/mediaeditor/VideoBrowserMain.c19
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorMain.cpp86
7 files changed, 139 insertions, 144 deletions
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 5bfdcdb..8caa04c 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3781,72 +3781,62 @@ class MediaArtistNativeHelper {
* @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
*
* @return The frames as bitmaps in bitmap array
**/
- Bitmap[] getPixelsList(String filename, int width, int height, long startMs, long endMs,
- int thumbnailCount) {
- int[] rgb888 = null;
- int thumbnailSize = 0;
- Bitmap tempBitmap = null;
-
+ void getPixelsList(String filename, final int width, final int height,
+ long startMs, long endMs, int thumbnailCount, int[] indices,
+ final MediaItem.GetThumbnailListCallback callback) {
/* Make width and height as even */
final int newWidth = (width + 1) & 0xFFFFFFFE;
final int newHeight = (height + 1) & 0xFFFFFFFE;
- thumbnailSize = newWidth * newHeight * 4;
+ final int thumbnailSize = newWidth * newHeight;
/* Create a temp bitmap for resized thumbnails */
- if ((newWidth != width) || (newHeight != height)) {
- tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
- }
- int i = 0;
- int deltaTime = (int)(endMs - startMs) / thumbnailCount;
- Bitmap[] bitmaps = null;
-
- try {
- // This may result in out of Memory Error
- rgb888 = new int[thumbnailSize * thumbnailCount];
- bitmaps = new Bitmap[thumbnailCount];
- } catch (Throwable e) {
- // Allocating to new size with Fixed count
- try {
- rgb888 = new int[thumbnailSize * MAX_THUMBNAIL_PERMITTED];
- bitmaps = new Bitmap[MAX_THUMBNAIL_PERMITTED];
- thumbnailCount = MAX_THUMBNAIL_PERMITTED;
- } catch (Throwable ex) {
- throw new RuntimeException("Memory allocation fails, thumbnail count too large: "
- + thumbnailCount);
- }
- }
- IntBuffer tmpBuffer = IntBuffer.allocate(thumbnailSize);
- nativeGetPixelsList(filename, rgb888, newWidth, newHeight, deltaTime, thumbnailCount,
- startMs, endMs);
+ final Bitmap tempBitmap =
+ (newWidth != width || newHeight != height)
+ ? Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888)
+ : null;
+
+ final int[] rgb888 = new int[thumbnailSize];
+ final IntBuffer tmpBuffer = IntBuffer.allocate(thumbnailSize);
+ nativeGetPixelsList(filename, rgb888, newWidth, newHeight,
+ 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();
+
+ if ((newWidth == width) && (newHeight == height)) {
+ bitmap.copyPixelsFromBuffer(tmpBuffer);
+ } else {
+ /* Copy the out rgb buffer to temp bitmap */
+ tempBitmap.copyPixelsFromBuffer(tmpBuffer);
- for (; i < thumbnailCount; i++) {
- bitmaps[i] = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- tmpBuffer.put(rgb888, (i * thumbnailSize), thumbnailSize);
- tmpBuffer.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);
- if ((newWidth == width) && (newHeight == height)) {
- bitmaps[i].copyPixelsFromBuffer(tmpBuffer);
- } else {
- /* Copy the out rgb buffer to temp bitmap */
- tempBitmap.copyPixelsFromBuffer(tmpBuffer);
-
- /* Create a canvas to resize */
- final Canvas canvas = new Canvas(bitmaps[i]);
- canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
- new Rect(0, 0, width, height), sResizePaint);
- canvas.setBitmap(null);
+ canvas.setBitmap(null);
+ }
+ callback.onThumbnail(bitmap, index);
}
- }
+ });
if (tempBitmap != null) {
tempBitmap.recycle();
}
+ }
- return bitmaps;
+ interface NativeGetPixelsListCallback {
+ public void onThumbnail(int index);
}
/**
@@ -3957,8 +3947,9 @@ class MediaArtistNativeHelper {
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 timeMS, int nosofTN, long startTimeMs, long endTimeMs);
+ 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
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index f0cc1fe..4ca6fad 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -616,17 +616,18 @@ public class MediaImageItem extends MediaItem {
* {@inheritDoc}
*/
@Override
- public Bitmap[] getThumbnailList(int width, int height, long startMs, long endMs,
- int thumbnailCount) throws IOException {
+ 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);
- final Bitmap[] thumbnailArray = new Bitmap[thumbnailCount];
- for (int i = 0; i < thumbnailCount; i++) {
- thumbnailArray[i] = thumbnail;
+ for (int i = 0; i < indices.length; i++) {
+ callback.onThumbnail(thumbnail, i);
}
-
- return thumbnailArray;
} else {
if (startMs > endMs) {
throw new IllegalArgumentException("Start time is greater than end time");
@@ -636,15 +637,8 @@ public class MediaImageItem extends MediaItem {
throw new IllegalArgumentException("End time is greater than file duration");
}
- if (startMs == endMs) {
- Bitmap[] bitmap = new Bitmap[1];
- bitmap[0] = mMANativeHelper.getPixels(getGeneratedImageClip(),
- width, height,startMs);
- return bitmap;
- }
-
- return mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
- height,startMs,endMs,thumbnailCount);
+ mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
+ height, startMs, endMs, thumbnailCount, indices, callback);
}
}
diff --git a/media/java/android/media/videoeditor/MediaItem.java b/media/java/android/media/videoeditor/MediaItem.java
index 8c4841f..4e9ea75 100755
--- a/media/java/android/media/videoeditor/MediaItem.java
+++ b/media/java/android/media/videoeditor/MediaItem.java
@@ -564,15 +564,41 @@ public abstract class MediaItem {
* @param startMs The start of time range in milliseconds
* @param endMs The end of the time range in milliseconds
* @param thumbnailCount The thumbnail count
- *
- * @return The array of Bitmaps
+ * @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 Bitmap[] getThumbnailList(int width, int height,
- long startMs, long endMs,
- int thumbnailCount)
- throws IOException;
+ 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}
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index 6248651..0ac354b 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -293,8 +293,12 @@ public class MediaVideoItem extends MediaItem {
* {@inheritDoc}
*/
@Override
- public Bitmap[] getThumbnailList(int width, int height, long startMs,
- long endMs, int thumbnailCount) throws IOException {
+ 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");
}
@@ -307,14 +311,8 @@ public class MediaVideoItem extends MediaItem {
throw new IllegalArgumentException("Invalid dimension");
}
- if (startMs == endMs) {
- final Bitmap[] bitmap = new Bitmap[1];
- bitmap[0] = mMANativeHelper.getPixels(super.getFilename(), width, height,startMs);
- return bitmap;
- }
-
- return mMANativeHelper.getPixelsList(super.getFilename(), width,
- height,startMs,endMs,thumbnailCount);
+ mMANativeHelper.getPixelsList(super.getFilename(), width,
+ height, startMs, endMs, thumbnailCount, indices, callback);
}
/*
diff --git a/media/jni/mediaeditor/VideoBrowserInternal.h b/media/jni/mediaeditor/VideoBrowserInternal.h
index 3cfb6b9..f4eaab8 100755
--- a/media/jni/mediaeditor/VideoBrowserInternal.h
+++ b/media/jni/mediaeditor/VideoBrowserInternal.h
@@ -26,9 +26,6 @@
#define VIDEO_BROWSER_BGR565
-
-#define VIDEO_BROWSER_PREDECODE_TIME 2000 /* In miliseconds */
-
/*---------------------------- MACROS ----------------------------*/
#define CHECK_PTR(fct, p, err, errValue) \
{ \
diff --git a/media/jni/mediaeditor/VideoBrowserMain.c b/media/jni/mediaeditor/VideoBrowserMain.c
index 2de55e3..c6c6000 100755
--- a/media/jni/mediaeditor/VideoBrowserMain.c
+++ b/media/jni/mediaeditor/VideoBrowserMain.c
@@ -447,13 +447,9 @@ M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime,
VideoBrowserContext* pC = (VideoBrowserContext*)pContext;
M4OSA_ERR err = M4NO_ERROR;
M4OSA_UInt32 targetTime = 0;
- M4OSA_UInt32 jumpTime = 0;
M4_MediaTime timeMS = 0;
- M4OSA_Int32 rapTime = 0;
- M4OSA_Bool isBackward = M4OSA_FALSE;
M4OSA_Bool bJumpNeeded = M4OSA_FALSE;
-
/*--- Sanity checks ---*/
CHECK_PTR(videoBrowserPrepareFrame, pContext, err, M4ERR_PARAMETER);
CHECK_PTR(videoBrowserPrepareFrame, pTime, err, M4ERR_PARAMETER);
@@ -472,16 +468,11 @@ M4OSA_ERR videoBrowserPrepareFrame(M4OSA_Context pContext, M4OSA_UInt32* pTime,
goto videoBrowserPrepareFrame_cleanUp;
}
- /*--- Check the duration ---*/
- /*--- If we jump backward, we need to jump ---*/
- if (targetTime < pC->m_currentCTS)
- {
- isBackward = M4OSA_TRUE;
- bJumpNeeded = M4OSA_TRUE;
- }
- /*--- If we jumpt to a time greater than "currentTime" + "predecodeTime"
- we need to jump ---*/
- else if (targetTime > (pC->m_currentCTS + VIDEO_BROWSER_PREDECODE_TIME))
+ // 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;
}
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 14972a2..7d0f56f 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -182,10 +182,11 @@ static int videoEditor_getPixelsList(
jintArray pixelArray,
M4OSA_UInt32 width,
M4OSA_UInt32 height,
- M4OSA_UInt32 deltatimeMS,
M4OSA_UInt32 noOfThumbnails,
- M4OSA_UInt32 startTime,
- M4OSA_UInt32 endTime);
+ jlong startTime,
+ jlong endTime,
+ jintArray indexArray,
+ jobject callback);
static void
videoEditor_startPreview(
@@ -288,7 +289,7 @@ static JNINativeMethod gManualEditMethods[] = {
(void *)videoEditor_release },
{"nativeGetPixels", "(Ljava/lang/String;[IIIJ)I",
(void*)videoEditor_getPixels },
- {"nativeGetPixelsList", "(Ljava/lang/String;[IIIIIJJ)I",
+ {"nativeGetPixelsList", "(Ljava/lang/String;[IIIIJJ[ILandroid/media/videoeditor/MediaArtistNativeHelper$NativeGetPixelsListCallback;)I",
(void*)videoEditor_getPixelsList },
{"getMediaProperties",
"(Ljava/lang/String;)Landroid/media/videoeditor/MediaArtistNativeHelper$Properties;",
@@ -2150,75 +2151,72 @@ static int videoEditor_getPixels(
}
static int videoEditor_getPixelsList(
- JNIEnv* env,
- jobject thiz,
- jstring path,
- jintArray pixelArray,
- M4OSA_UInt32 width,
- M4OSA_UInt32 height,
- M4OSA_UInt32 deltatimeMS,
+ JNIEnv* env,
+ jobject thiz,
+ jstring path,
+ jintArray pixelArray,
+ M4OSA_UInt32 width,
+ M4OSA_UInt32 height,
M4OSA_UInt32 noOfThumbnails,
- M4OSA_UInt32 startTime,
- M4OSA_UInt32 endTime)
+ jlong startTime,
+ jlong endTime,
+ jintArray indexArray,
+ jobject callback)
{
- M4OSA_ERR err;
+ M4OSA_ERR err = M4NO_ERROR;
M4OSA_Context mContext = M4OSA_NULL;
- jint* m_dst32;
- M4OSA_UInt32 timeMS = startTime;
- int arrayOffset = 0;
-
-
-
- // Add a text marker (the condition must always be true).
- ADD_TEXT_MARKER_FUN(NULL != env)
const char *pString = env->GetStringUTFChars(path, NULL);
if (pString == M4OSA_NULL) {
- if (env != NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "Input string 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 (env != NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed");
- }
+ jniThrowException(env, "java/lang/RuntimeException", "ThumbnailOpen failed");
if (pString != NULL) {
env->ReleaseStringUTFChars(path, pString);
}
return err;
}
- m_dst32 = env->GetIntArrayElements(pixelArray, NULL);
+ 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);
- M4OSA_UInt32 tolerance = deltatimeMS / 2;
- do {
- err = ThumbnailGetPixels32(mContext, ((M4OSA_Int32 *)m_dst32 + arrayOffset),
- width,height,&timeMS, tolerance);
- if (err != M4NO_ERROR ) {
- if (env != NULL) {
- jniThrowException(env, "java/lang/RuntimeException",\
- "ThumbnailGetPixels32 failed");
- }
- return err;
+ 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;
}
- timeMS += deltatimeMS;
- arrayOffset += (width * height * 4);
- noOfThumbnails--;
- } while(noOfThumbnails > 0);
+ env->CallVoidMethod(callback, mid, (jint)k);
+ }
env->ReleaseIntArrayElements(pixelArray, m_dst32, 0);
+ env->ReleaseIntArrayElements(indexArray, indices, 0);
ThumbnailClose(mContext);
if (pString != NULL) {
env->ReleaseStringUTFChars(path, pString);
}
- return err;
+ if (err != M4NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException",\
+ "ThumbnailGetPixels32 failed");
+ }
+ return err;
}
static M4OSA_ERR