Merge "Update MediaMetadateRetriever to use android graphic's C APIs."

This commit is contained in:
Derek Sollenberger
2019-11-11 17:08:59 +00:00
committed by Android (Google) Code Review
5 changed files with 92 additions and 64 deletions

View File

@@ -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");

View File

@@ -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();

View File

@@ -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 @@ 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);
}

View File

@@ -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

View File

@@ -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 @@ 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<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 @@ 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<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 @@ 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<IMemory> 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<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 @@ 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;