Update MediaMetadateRetriever to use android graphic's C APIs.
This is part of the effort to stabilize the ABI of the android
graphics package so that it can be contained within an APEX module.
Test: CtsMediaTestCases
Bug: 137655431
Change-Id: Ifdd6083ad18a73df819fadc36823ddc3027b7049
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 11d321f..bc1cc09 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -158,6 +158,7 @@
static jclass gBitmapConfig_class;
static jfieldID gBitmapConfig_nativeInstanceID;
+static jmethodID gBitmapConfig_nativeToConfigMethodID;
static jclass gBitmapRegionDecoder_class;
static jmethodID gBitmapRegionDecoder_constructorMethodID;
@@ -345,6 +346,54 @@
bitmap::toBitmap(env, bitmap).getSkBitmap(outBitmap);
}
+AndroidBitmapFormat GraphicsJNI::getFormatFromConfig(JNIEnv* env, jobject jconfig) {
+ ALOG_ASSERT(env);
+ if (NULL == jconfig) {
+ return ANDROID_BITMAP_FORMAT_NONE;
+ }
+ ALOG_ASSERT(env->IsInstanceOf(jconfig, gBitmapConfig_class));
+ jint javaConfigId = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
+
+ const AndroidBitmapFormat config2BitmapFormat[] = {
+ ANDROID_BITMAP_FORMAT_NONE,
+ ANDROID_BITMAP_FORMAT_A_8,
+ ANDROID_BITMAP_FORMAT_NONE, // Previously Config.Index_8
+ ANDROID_BITMAP_FORMAT_RGB_565,
+ ANDROID_BITMAP_FORMAT_RGBA_4444,
+ ANDROID_BITMAP_FORMAT_RGBA_8888,
+ ANDROID_BITMAP_FORMAT_RGBA_F16,
+ ANDROID_BITMAP_FORMAT_NONE // Congfig.HARDWARE
+ };
+ return config2BitmapFormat[javaConfigId];
+}
+
+jobject GraphicsJNI::getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format) {
+ ALOG_ASSERT(env);
+ jint configId = kNo_LegacyBitmapConfig;
+ switch (format) {
+ case ANDROID_BITMAP_FORMAT_A_8:
+ configId = kA8_LegacyBitmapConfig;
+ break;
+ case ANDROID_BITMAP_FORMAT_RGB_565:
+ configId = kRGB_565_LegacyBitmapConfig;
+ break;
+ case ANDROID_BITMAP_FORMAT_RGBA_4444:
+ configId = kARGB_4444_LegacyBitmapConfig;
+ break;
+ case ANDROID_BITMAP_FORMAT_RGBA_8888:
+ configId = kARGB_8888_LegacyBitmapConfig;
+ break;
+ case ANDROID_BITMAP_FORMAT_RGBA_F16:
+ configId = kRGBA_16F_LegacyBitmapConfig;
+ break;
+ default:
+ break;
+ }
+
+ return env->CallStaticObjectMethod(gBitmapConfig_class,
+ gBitmapConfig_nativeToConfigMethodID, configId);
+}
+
SkColorType GraphicsJNI::getNativeBitmapColorType(JNIEnv* env, jobject jconfig) {
ALOG_ASSERT(env);
if (NULL == jconfig) {
@@ -634,6 +683,9 @@
gBitmapConfig_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Bitmap$Config"));
gBitmapConfig_nativeInstanceID = GetFieldIDOrDie(env, gBitmapConfig_class, "nativeInt", "I");
+ gBitmapConfig_nativeToConfigMethodID = GetStaticMethodIDOrDie(env, gBitmapConfig_class,
+ "nativeToConfig",
+ "(I)Landroid/graphics/Bitmap$Config;");
gCanvas_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Canvas"));
gCanvas_nativeInstanceID = GetFieldIDOrDie(env, gCanvas_class, "mNativeCanvasWrapper", "J");
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index f80651c..6e7d9e7 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -76,6 +76,8 @@
or kUnknown_SkColorType if the java object is null.
*/
static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig);
+ static AndroidBitmapFormat getFormatFromConfig(JNIEnv* env, jobject jconfig);
+ static jobject getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format);
static bool isHardwareConfig(JNIEnv* env, jobject jconfig);
static jint hardwareLegacyBitmapConfig();
diff --git a/core/jni/android/graphics/apex/android_bitmap.cpp b/core/jni/android/graphics/apex/android_bitmap.cpp
index 96cc5db..a328def 100644
--- a/core/jni/android/graphics/apex/android_bitmap.cpp
+++ b/core/jni/android/graphics/apex/android_bitmap.cpp
@@ -17,6 +17,7 @@
#include "android/graphics/bitmap.h"
#include "Bitmap.h"
#include "TypeCast.h"
+#include "GraphicsJNI.h"
#include <hwui/Bitmap.h>
@@ -104,3 +105,11 @@
}
return bitmap->pixels();
}
+
+AndroidBitmapFormat ABitmapConfig_getFormatFromConfig(JNIEnv* env, jobject bitmapConfigObj) {
+ return GraphicsJNI::getFormatFromConfig(env, bitmapConfigObj);
+}
+
+jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format) {
+ return GraphicsJNI::getConfigFromFormat(env, format);
+}
diff --git a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
index bfa4c8d..dea5517 100644
--- a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
+++ b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
@@ -38,6 +38,9 @@
void* ABitmap_getPixels(ABitmap* bitmap);
+AndroidBitmapFormat ABitmapConfig_getFormatFromConfig(JNIEnv* env, jobject bitmapConfigObj);
+jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format);
+
__END_DECLS
#ifdef __cplusplus
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index bc4bceb..a5c62cb 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -22,7 +22,7 @@
#include <assert.h>
#include <utils/Log.h>
#include <utils/threads.h>
-#include <SkBitmap.h>
+#include <android/graphics/bitmap.h>
#include <media/IMediaHTTPService.h>
#include <media/mediametadataretriever.h>
#include <media/mediascanner.h>
@@ -36,8 +36,6 @@
#include "android_media_Streams.h"
#include "android_util_Binder.h"
-#include "android/graphics/GraphicsJNI.h"
-
using namespace android;
struct fields_t {
@@ -45,8 +43,6 @@
jclass bitmapClazz; // Must be a global ref
jmethodID createBitmapMethod;
jmethodID createScaledBitmapMethod;
- jclass configClazz; // Must be a global ref
- jmethodID createConfigMethod;
jclass bitmapParamsClazz; // Must be a global ref
jfieldID inPreferredConfig;
jfieldID outActualConfig;
@@ -263,7 +259,7 @@
static jobject getBitmapFromVideoFrame(
JNIEnv *env, VideoFrame *videoFrame, jint dst_width, jint dst_height,
- SkColorType outColorType) {
+ AndroidBitmapFormat outColorType) {
ALOGV("getBitmapFromVideoFrame: dimension = %dx%d, displaySize = %dx%d, bytes = %d",
videoFrame->mWidth,
videoFrame->mHeight,
@@ -271,11 +267,7 @@
videoFrame->mDisplayHeight,
videoFrame->mSize);
- ScopedLocalRef<jobject> config(env,
- env->CallStaticObjectMethod(
- fields.configClazz,
- fields.createConfigMethod,
- GraphicsJNI::colorTypeToLegacyBitmapConfig(outColorType)));
+ ScopedLocalRef<jobject> config(env, ABitmapConfig_getConfigFromFormat(env, outColorType));
uint32_t width, height, displayWidth, displayHeight;
bool swapWidthAndHeight = false;
@@ -306,10 +298,9 @@
return NULL;
}
- SkBitmap bitmap;
- GraphicsJNI::getSkBitmap(env, jBitmap, &bitmap);
+ graphics::Bitmap bitmap(env, jBitmap);
- if (outColorType == kRGB_565_SkColorType) {
+ if (outColorType == ANDROID_BITMAP_FORMAT_RGB_565) {
rotate((uint16_t*)bitmap.getPixels(),
(uint16_t*)((char*)videoFrame + sizeof(VideoFrame)),
videoFrame->mWidth,
@@ -350,37 +341,26 @@
return jBitmap;
}
-static int getColorFormat(JNIEnv *env, jobject options,
- int defaultPreferred = HAL_PIXEL_FORMAT_RGBA_8888) {
+static AndroidBitmapFormat getColorFormat(JNIEnv *env, jobject options,
+ AndroidBitmapFormat defaultPreferred = ANDROID_BITMAP_FORMAT_RGBA_8888) {
if (options == NULL) {
return defaultPreferred;
}
ScopedLocalRef<jobject> inConfig(env, env->GetObjectField(options, fields.inPreferredConfig));
- SkColorType prefColorType = GraphicsJNI::getNativeBitmapColorType(env, inConfig.get());
+ AndroidBitmapFormat format = ABitmapConfig_getFormatFromConfig(env, inConfig.get());
- if (prefColorType == kRGB_565_SkColorType) {
- return HAL_PIXEL_FORMAT_RGB_565;
+ if (format == ANDROID_BITMAP_FORMAT_RGB_565) {
+ return ANDROID_BITMAP_FORMAT_RGB_565;
}
- return HAL_PIXEL_FORMAT_RGBA_8888;
+ return ANDROID_BITMAP_FORMAT_RGBA_8888;
}
-static SkColorType setOutColorType(JNIEnv *env, int colorFormat, jobject options) {
- SkColorType outColorType = kN32_SkColorType;
- if (colorFormat == HAL_PIXEL_FORMAT_RGB_565) {
- outColorType = kRGB_565_SkColorType;
- }
-
+static void setOutConfig(JNIEnv *env, jobject options, AndroidBitmapFormat colorFormat) {
if (options != NULL) {
- ScopedLocalRef<jobject> config(env,
- env->CallStaticObjectMethod(
- fields.configClazz,
- fields.createConfigMethod,
- GraphicsJNI::colorTypeToLegacyBitmapConfig(outColorType)));
-
+ ScopedLocalRef<jobject> config(env, ABitmapConfig_getConfigFromFormat(env, colorFormat));
env->SetObjectField(options, fields.outActualConfig, config.get());
}
- return outColorType;
}
static jobject android_media_MediaMetadataRetriever_getFrameAtTime(
@@ -394,9 +374,9 @@
jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
return NULL;
}
- // For getFrameAtTime family of calls, default to HAL_PIXEL_FORMAT_RGB_565
+ // For getFrameAtTime family of calls, default to ANDROID_BITMAP_FORMAT_RGB_565
// to keep the behavior consistent with older releases
- int colorFormat = getColorFormat(env, params, HAL_PIXEL_FORMAT_RGB_565);
+ AndroidBitmapFormat colorFormat = getColorFormat(env, params, ANDROID_BITMAP_FORMAT_RGB_565);
// Call native method to retrieve a video frame
VideoFrame *videoFrame = NULL;
@@ -413,9 +393,8 @@
return NULL;
}
- SkColorType outColorType = setOutColorType(env, colorFormat, params);
-
- return getBitmapFromVideoFrame(env, videoFrame, dst_width, dst_height, outColorType);
+ setOutConfig(env, params, colorFormat);
+ return getBitmapFromVideoFrame(env, videoFrame, dst_width, dst_height, colorFormat);
}
static jobject android_media_MediaMetadataRetriever_getImageAtIndex(
@@ -428,7 +407,7 @@
return NULL;
}
- int colorFormat = getColorFormat(env, params);
+ AndroidBitmapFormat colorFormat = getColorFormat(env, params);
// Call native method to retrieve an image
VideoFrame *videoFrame = NULL;
@@ -445,9 +424,8 @@
return NULL;
}
- SkColorType outColorType = setOutColorType(env, colorFormat, params);
-
- return getBitmapFromVideoFrame(env, videoFrame, -1, -1, outColorType);
+ setOutConfig(env, params, colorFormat);
+ return getBitmapFromVideoFrame(env, videoFrame, -1, -1, colorFormat);
}
static jobject android_media_MediaMetadataRetriever_getThumbnailImageAtIndex(
@@ -461,7 +439,7 @@
return NULL;
}
- int colorFormat = getColorFormat(env, params);
+ AndroidBitmapFormat colorFormat = getColorFormat(env, params);
jint dst_width = -1, dst_height = -1;
// Call native method to retrieve an image
@@ -508,9 +486,8 @@
// thumbnails extracted by BitmapFactory APIs.
videoFrame->mRotationAngle = 0;
- SkColorType outColorType = setOutColorType(env, colorFormat, params);
-
- return getBitmapFromVideoFrame(env, videoFrame, dst_width, dst_height, outColorType);
+ setOutConfig(env, params, colorFormat);
+ return getBitmapFromVideoFrame(env, videoFrame, dst_width, dst_height, colorFormat);
}
static jobject android_media_MediaMetadataRetriever_getFrameAtIndex(
@@ -532,8 +509,8 @@
return NULL;
}
- int colorFormat = getColorFormat(env, params);
- SkColorType outColorType = setOutColorType(env, colorFormat, params);
+ AndroidBitmapFormat colorFormat = getColorFormat(env, params);
+ setOutConfig(env, params, colorFormat);
size_t i = 0;
for (; i < numFrames; i++) {
sp<IMemory> frame = retriever->getFrameAtIndex(frameIndex + i, colorFormat);
@@ -546,7 +523,7 @@
// Either document why it is safe in this case or address the
// issue (e.g. by copying).
VideoFrame *videoFrame = static_cast<VideoFrame *>(frame->unsecurePointer());
- jobject bitmapObj = getBitmapFromVideoFrame(env, videoFrame, -1, -1, outColorType);
+ jobject bitmapObj = getBitmapFromVideoFrame(env, videoFrame, -1, -1, colorFormat);
env->CallBooleanMethod(arrayList, fields.arrayListAdd, bitmapObj);
env->DeleteLocalRef(bitmapObj);
}
@@ -671,21 +648,6 @@
return;
}
- clazz.reset(env->FindClass("android/graphics/Bitmap$Config"));
- if (clazz.get() == NULL) {
- return;
- }
- fields.configClazz = (jclass) env->NewGlobalRef(clazz.get());
- if (fields.configClazz == NULL) {
- return;
- }
- fields.createConfigMethod =
- env->GetStaticMethodID(fields.configClazz, "nativeToConfig",
- "(I)Landroid/graphics/Bitmap$Config;");
- if (fields.createConfigMethod == NULL) {
- return;
- }
-
clazz.reset(env->FindClass("android/media/MediaMetadataRetriever$BitmapParams"));
if (clazz.get() == NULL) {
return;