diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index 11d321f0b0382..bc1cc09506adf 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -158,6 +158,7 @@ static jfieldID gPointF_yFieldID; static jclass gBitmapConfig_class; static jfieldID gBitmapConfig_nativeInstanceID; +static jmethodID gBitmapConfig_nativeToConfigMethodID; static jclass gBitmapRegionDecoder_class; static jmethodID gBitmapRegionDecoder_constructorMethodID; @@ -345,6 +346,54 @@ void GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap, SkBitmap* outBitmap) 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 @@ int register_android_graphics_Graphics(JNIEnv* env) 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 f80651c30d64a..6e7d9e736c0a8 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -76,6 +76,8 @@ public: 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 96cc5db8a5a41..a328def879080 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 @@ -104,3 +105,11 @@ void* ABitmap_getPixels(ABitmap* bitmapHandle) { } 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 bfa4c8df407f8..dea55172b3bb2 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 @@ AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmap); 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 bc4bcebaf560d..a5c62cb720cf5 100644 --- a/media/jni/android_media_MediaMetadataRetriever.cpp +++ b/media/jni/android_media_MediaMetadataRetriever.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -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 @@ struct fields_t { 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 void rotate(T *dst, const T *src, size_t width, size_t height, int angle) 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 @@ static jobject getBitmapFromVideoFrame( videoFrame->mDisplayHeight, videoFrame->mSize); - ScopedLocalRef config(env, - env->CallStaticObjectMethod( - fields.configClazz, - fields.createConfigMethod, - GraphicsJNI::colorTypeToLegacyBitmapConfig(outColorType))); + ScopedLocalRef config(env, ABitmapConfig_getConfigFromFormat(env, outColorType)); uint32_t width, height, displayWidth, displayHeight; bool swapWidthAndHeight = false; @@ -306,10 +298,9 @@ static jobject getBitmapFromVideoFrame( 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 @@ static jobject getBitmapFromVideoFrame( 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 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 config(env, - env->CallStaticObjectMethod( - fields.configClazz, - fields.createConfigMethod, - GraphicsJNI::colorTypeToLegacyBitmapConfig(outColorType))); - + ScopedLocalRef 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 @@ static jobject android_media_MediaMetadataRetriever_getFrameAtTime( 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 @@ static jobject android_media_MediaMetadataRetriever_getFrameAtTime( 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 @@ static jobject android_media_MediaMetadataRetriever_getImageAtIndex( 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 @@ static jobject android_media_MediaMetadataRetriever_getImageAtIndex( 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 @@ static jobject android_media_MediaMetadataRetriever_getThumbnailImageAtIndex( 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 @@ static jobject android_media_MediaMetadataRetriever_getThumbnailImageAtIndex( // 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 @@ static jobject android_media_MediaMetadataRetriever_getFrameAtIndex( 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 frame = retriever->getFrameAtIndex(frameIndex + i, colorFormat); @@ -546,7 +523,7 @@ static jobject android_media_MediaMetadataRetriever_getFrameAtIndex( // Either document why it is safe in this case or address the // issue (e.g. by copying). VideoFrame *videoFrame = static_cast(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 @@ static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env) 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;