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

Commit d2d62d04 authored by James Dong's avatar James Dong Committed by Android (Google) Code Review
Browse files

Merge "Support extracting thumbnail from rotated video tracks" into gingerbread

parents 08686b07 53ebc72f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ public:
    uint32_t mDisplayHeight;
    uint32_t mSize;            // Number of bytes in mData
    uint8_t* mData;            // Actual binary data
    int32_t  mRotationAngle;   // rotation angle, clockwise
};

}; // namespace android
+58 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ struct fields_t {
    jfieldID context;
    jclass bitmapClazz;
    jmethodID bitmapConstructor;
    jmethodID createBitmapMethod;
};

static fields_t fields;
@@ -174,6 +175,41 @@ static jobject android_media_MediaMetadataRetriever_captureFrame(JNIEnv *env, jo
        return NULL;
    }

    jobject matrix = NULL;
    if (videoFrame->mRotationAngle != 0) {
        LOGD("Create a rotation matrix: %d degrees", videoFrame->mRotationAngle);
        jclass matrixClazz = env->FindClass("android/graphics/Matrix");
        if (matrixClazz == NULL) {
            jniThrowException(env, "java/lang/RuntimeException",
                "Can't find android/graphics/Matrix");
            return NULL;
        }
        jmethodID matrixConstructor =
            env->GetMethodID(matrixClazz, "<init>", "()V");
        if (matrixConstructor == NULL) {
            jniThrowException(env, "java/lang/RuntimeException",
                "Can't find Matrix constructor");
            return NULL;
        }
        matrix =
            env->NewObject(matrixClazz, matrixConstructor);
        if (matrix == NULL) {
            LOGE("Could not create a Matrix object");
            return NULL;
        }

        LOGV("Rotate the matrix: %d degrees", videoFrame->mRotationAngle);
        jmethodID setRotateMethod =
                env->GetMethodID(matrixClazz, "setRotate", "(F)V");
        if (setRotateMethod == NULL) {
            jniThrowException(env, "java/lang/RuntimeException",
                "Can't find Matrix setRotate method");
            return NULL;
        }
        env->CallVoidMethod(matrix, setRotateMethod, 1.0 * videoFrame->mRotationAngle);
        env->DeleteLocalRef(matrixClazz);
    }

    // Create a SkBitmap to hold the pixels
    SkBitmap *bitmap = new SkBitmap();
    if (bitmap == NULL) {
@@ -191,7 +227,19 @@ static jobject android_media_MediaMetadataRetriever_captureFrame(JNIEnv *env, jo
    // Since internally SkBitmap uses reference count to manage the reference to
    // its pixels, it is important that the pixels (along with SkBitmap) be
    // available after creating the Bitmap is returned to Java app.
    return env->NewObject(fields.bitmapClazz, fields.bitmapConstructor, (int) bitmap, true, NULL, -1);
    jobject jSrcBitmap = env->NewObject(fields.bitmapClazz,
            fields.bitmapConstructor, (int) bitmap, true, NULL, -1);

    LOGV("Return a new bitmap constructed with the rotation matrix");
    return env->CallStaticObjectMethod(
                fields.bitmapClazz, fields.createBitmapMethod,
                jSrcBitmap,                     // source Bitmap
                0,                              // x
                0,                              // y
                videoFrame->mDisplayWidth,      // width
                videoFrame->mDisplayHeight,     // height
                matrix,                         // transform matrix
                false);                         // filter
}

static jbyteArray android_media_MediaMetadataRetriever_extractAlbumArt(JNIEnv *env, jobject thiz)
@@ -291,6 +339,15 @@ static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env)
        jniThrowException(env, "java/lang/RuntimeException", "Can't find Bitmap constructor");
        return;
    }
    fields.createBitmapMethod =
            env->GetStaticMethodID(fields.bitmapClazz, "createBitmap",
                    "(Landroid/graphics/Bitmap;IIIILandroid/graphics/Matrix;Z)"
                    "Landroid/graphics/Bitmap;");
    if (fields.createBitmapMethod == NULL) {
        jniThrowException(env, "java/lang/RuntimeException",
                "Can't find Bitmap.createBitmap method");
        return;
    }
}

static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobject thiz)
+2 −0
Original line number Diff line number Diff line
@@ -253,6 +253,8 @@ sp<IMemory> MetadataRetrieverClient::captureFrame()
    frameCopy->mDisplayWidth = frame->mDisplayWidth;
    frameCopy->mDisplayHeight = frame->mDisplayHeight;
    frameCopy->mSize = frame->mSize;
    frameCopy->mRotationAngle = frame->mRotationAngle;
    LOGV("rotation: %d", frameCopy->mRotationAngle);
    frameCopy->mData = (uint8_t *)frameCopy + sizeof(VideoFrame);
    memcpy(frameCopy->mData, frame->mData, frame->mSize);
    delete frame;  // Fix memory leakage
+6 −0
Original line number Diff line number Diff line
@@ -191,6 +191,11 @@ static VideoFrame *extractVideoFrameWithCodecFlags(
    CHECK(meta->findInt32(kKeyWidth, &width));
    CHECK(meta->findInt32(kKeyHeight, &height));

    int32_t rotationAngle;
    if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) {
        rotationAngle = 0;  // By default, no rotation
    }

    VideoFrame *frame = new VideoFrame;
    frame->mWidth = width;
    frame->mHeight = height;
@@ -198,6 +203,7 @@ static VideoFrame *extractVideoFrameWithCodecFlags(
    frame->mDisplayHeight = height;
    frame->mSize = width * height * 2;
    frame->mData = new uint8_t[frame->mSize];
    frame->mRotationAngle = rotationAngle;

    int32_t srcFormat;
    CHECK(meta->findInt32(kKeyColorFormat, &srcFormat));