Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b1967c7 authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

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

parents 4a9d5822 213dacab
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -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");
+2 −0
Original line number Diff line number Diff line
@@ -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();
+9 −0
Original line number Diff line number Diff line
@@ -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);
}
+3 −0
Original line number Diff line number Diff line
@@ -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
+26 −64
Original line number Diff line number Diff line
@@ -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;
    }
    return HAL_PIXEL_FORMAT_RGBA_8888;
    if (format == ANDROID_BITMAP_FORMAT_RGB_565) {
        return ANDROID_BITMAP_FORMAT_RGB_565;
    }

static SkColorType setOutColorType(JNIEnv *env, int colorFormat, jobject options) {
    SkColorType outColorType = kN32_SkColorType;
    if (colorFormat == HAL_PIXEL_FORMAT_RGB_565) {
        outColorType = kRGB_565_SkColorType;
    return ANDROID_BITMAP_FORMAT_RGBA_8888;
}

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;