android_media_MediaMetadataRetriever.cpp revision ae12a50a35c0d8425430d0e934c022ecb9cd4936
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2008, The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "MediaMetadataRetrieverJNI" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <core/SkBitmap.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/mediametadataretriever.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <private/media/VideoFrame.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h" 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct fields_t { 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID context; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass bitmapClazz; 380e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jfieldID nativeBitmap; 3953ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong jmethodID createBitmapMethod; 400e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jclass configClazz; 410e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jmethodID createConfigMethod; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic fields_t fields; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic Mutex sLock; 464935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissenstatic const char* const kClassPathName = "android/media/MediaMetadataRetriever"; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void process_media_retriever_call(JNIEnv *env, status_t opStatus, const char* exception, const char *message) 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (opStatus == (status_t) INVALID_OPERATION) { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", NULL); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (opStatus != (status_t) OK) { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strlen(message) > 230) { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the message is too long, don't bother displaying the status code. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException( env, exception, message); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char msg[256]; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Append the status code to the message. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(msg, "%s: status = 0x%X", message, opStatus); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException( env, exception, msg); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic MediaMetadataRetriever* getRetriever(JNIEnv* env, jobject thiz) 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // No lock is needed, since it is called internally by other methods that are protected 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever* retriever = (MediaMetadataRetriever*) env->GetIntField(thiz, fields.context); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retriever; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void setRetriever(JNIEnv* env, jobject thiz, int retriever) 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // No lock is needed, since it is called internally by other methods that are protected 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever *old = (MediaMetadataRetriever*) env->GetIntField(thiz, fields.context); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetIntField(thiz, fields.context, retriever); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_MediaMetadataRetriever_setDataSource(JNIEnv *env, jobject thiz, jstring path) 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("setDataSource"); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever* retriever = getRetriever(env, thiz); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retriever == 0) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!path) { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalArgumentException", "Null pointer"); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char *pathStr = env->GetStringUTFChars(path, NULL); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!pathStr) { // OutOfMemoryError exception already thrown 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't let somebody trick us in to reading some random block of memory 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strncmp("mem://", pathStr, 6) == 0) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid pathname"); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project process_media_retriever_call(env, retriever->setDataSource(pathStr), "java/lang/RuntimeException", "setDataSource failed"); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringUTFChars(path, pathStr); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_MediaMetadataRetriever_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length) 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("setDataSource"); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever* retriever = getRetriever(env, thiz); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retriever == 0) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!fileDescriptor) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd = getParcelFileDescriptorFD(env, fileDescriptor); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset < 0 || length < 0 || fd < 0) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset < 0) { 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("negative offset (%lld)", offset); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length < 0) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("negative length (%lld)", length); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd < 0) { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("invalid file descriptor"); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project process_media_retriever_call(env, retriever->setDataSource(fd, offset, length), "java/lang/RuntimeException", "setDataSource failed"); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 136ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirotemplate<typename T> 137ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirostatic void rotate0(T* dst, const T* src, size_t width, size_t height) 138ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro{ 139ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro memcpy(dst, src, width * height * sizeof(T)); 140ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro} 141ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro 142ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirotemplate<typename T> 143ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirostatic void rotate90(T* dst, const T* src, size_t width, size_t height) 144ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro{ 145ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro for (size_t i = 0; i < height; ++i) { 146ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro for (size_t j = 0; j < width; ++j) { 147ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro dst[j * height + height - 1 - i] = src[i * width + j]; 148ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } 149ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } 150ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro} 151ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro 152ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirotemplate<typename T> 153ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirostatic void rotate180(T* dst, const T* src, size_t width, size_t height) 154ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro{ 155ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro for (size_t i = 0; i < height; ++i) { 156ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro for (size_t j = 0; j < width; ++j) { 157ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro dst[(height - 1 - i) * width + width - 1 - j] = src[i * width + j]; 158ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } 159ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } 160ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro} 161ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro 162ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirotemplate<typename T> 163ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirostatic void rotate270(T* dst, const T* src, size_t width, size_t height) 164ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro{ 165ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro for (size_t i = 0; i < height; ++i) { 166ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro for (size_t j = 0; j < width; ++j) { 167ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro dst[(width - 1 - j) * height + i] = src[i * width + j]; 168ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } 169ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } 170ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro} 171ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro 172ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirotemplate<typename T> 173ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapirostatic void rotate(T *dst, const T *src, size_t width, size_t height, int angle) 174ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro{ 175ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro switch (angle) { 176ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro case 0: 177ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro rotate0(dst, src, width, height); 178ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro break; 179ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro case 90: 180ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro rotate90(dst, src, width, height); 181ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro break; 182ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro case 180: 183ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro rotate180(dst, src, width, height); 184ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro break; 185ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro case 270: 186ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro rotate270(dst, src, width, height); 187ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro break; 188ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } 189ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro} 190ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro 191faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dongstatic jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option) 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 193faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong LOGV("getFrameAtTime: %lld us option: %d", timeUs, option); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever* retriever = getRetriever(env, thiz); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retriever == 0) { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Call native method to retrieve a video frame 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VideoFrame *videoFrame = NULL; 202faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong sp<IMemory> frameMemory = retriever->getFrameAtTime(timeUs, option); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (frameMemory != 0) { // cast the shared structure to a VideoFrame object 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project videoFrame = static_cast<VideoFrame *>(frameMemory->pointer()); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (videoFrame == NULL) { 207faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong LOGE("getFrameAtTime: videoFrame is a NULL pointer"); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2110e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong LOGV("Dimension = %dx%d and bytes = %d", 2120e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong videoFrame->mDisplayWidth, 2130e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong videoFrame->mDisplayHeight, 2140e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong videoFrame->mSize); 2150e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong 2160e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jobject config = env->CallStaticObjectMethod( 2170e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.configClazz, 2180e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.createConfigMethod, 2190e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong SkBitmap::kRGB_565_Config); 2200e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong 221ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro size_t width, height; 222ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro if (videoFrame->mRotationAngle == 90 || videoFrame->mRotationAngle == 270) { 223ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro width = videoFrame->mDisplayHeight; 224ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro height = videoFrame->mDisplayWidth; 225ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } else { 226ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro width = videoFrame->mDisplayWidth; 227ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro height = videoFrame->mDisplayHeight; 228ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro } 229ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro 2300e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jobject jBitmap = env->CallStaticObjectMethod( 2310e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.bitmapClazz, 2320e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.createBitmapMethod, 233ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro width, 234ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro height, 2350e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong config); 236ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro 2370e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong SkBitmap *bitmap = 2380e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong (SkBitmap *) env->GetIntField(jBitmap, fields.nativeBitmap); 2390e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong 2400e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong bitmap->lockPixels(); 241ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro rotate((uint16_t*)bitmap->getPixels(), 242ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro (uint16_t*)((char*)videoFrame + sizeof(VideoFrame)), 243ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro videoFrame->mDisplayWidth, 244ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro videoFrame->mDisplayHeight, 245ae12a50a35c0d8425430d0e934c022ecb9cd4936Carl Shapiro videoFrame->mRotationAngle); 2460e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong bitmap->unlockPixels(); 2470e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong 2480e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong return jBitmap; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 251df9b349b960fff95dff4fcf8b2661899e33059daJames Dongstatic jbyteArray android_media_MediaMetadataRetriever_getEmbeddedPicture( 252df9b349b960fff95dff4fcf8b2661899e33059daJames Dong JNIEnv *env, jobject thiz, jint pictureType) 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 254df9b349b960fff95dff4fcf8b2661899e33059daJames Dong LOGV("getEmbeddedPicture: %d", pictureType); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever* retriever = getRetriever(env, thiz); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retriever == 0) { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaAlbumArt* mediaAlbumArt = NULL; 261df9b349b960fff95dff4fcf8b2661899e33059daJames Dong 262df9b349b960fff95dff4fcf8b2661899e33059daJames Dong // FIXME: 263df9b349b960fff95dff4fcf8b2661899e33059daJames Dong // Use pictureType to retrieve the intended embedded picture and also change 264df9b349b960fff95dff4fcf8b2661899e33059daJames Dong // the method name to getEmbeddedPicture(). 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemory> albumArtMemory = retriever->extractAlbumArt(); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (albumArtMemory != 0) { // cast the shared structure to a MediaAlbumArt object 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mediaAlbumArt = static_cast<MediaAlbumArt *>(albumArtMemory->pointer()); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mediaAlbumArt == NULL) { 270df9b349b960fff95dff4fcf8b2661899e33059daJames Dong LOGE("getEmbeddedPicture: Call to getEmbeddedPicture failed."); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned int len = mediaAlbumArt->mSize; 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* data = (char*) mediaAlbumArt + sizeof(MediaAlbumArt); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray array = env->NewByteArray(len); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!array) { // OutOfMemoryError exception has already been thrown. 278df9b349b960fff95dff4fcf8b2661899e33059daJames Dong LOGE("getEmbeddedPicture: OutOfMemoryError is thrown."); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyte* bytes = env->GetByteArrayElements(array, NULL); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bytes != NULL) { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(bytes, data, len); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseByteArrayElements(array, bytes, 0); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // No need to delete mediaAlbumArt here 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return array; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject android_media_MediaMetadataRetriever_extractMetadata(JNIEnv *env, jobject thiz, jint keyCode) 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("extractMetadata"); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever* retriever = getRetriever(env, thiz); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retriever == 0) { 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* value = retriever->extractMetadata(keyCode); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!value) { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("extractMetadata: Metadata is not found"); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("extractMetadata: value (%s) for keyCode(%d)", value, keyCode); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return env->NewStringUTF(value); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_MediaMetadataRetriever_release(JNIEnv *env, jobject thiz) 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("release"); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(sLock); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever* retriever = getRetriever(env, thiz); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete retriever; 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRetriever(env, thiz, 0); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_MediaMetadataRetriever_native_finalize(JNIEnv *env, jobject thiz) 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("native_finalize"); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // No lock is needed, since android_media_MediaMetadataRetriever_release() is protected 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_media_MediaMetadataRetriever_release(env, thiz); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3244935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen// This function gets a field ID, which in turn causes class initialization. 3254935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen// It is called from a static block in MediaMetadataRetriever, which won't run until the 3264935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen// first time an instance of this class is used. 3274935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissenstatic void android_media_MediaMetadataRetriever_native_init(JNIEnv *env) 3284935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen{ 3294935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen jclass clazz = env->FindClass(kClassPathName); 3304935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen if (clazz == NULL) { 3314935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaMetadataRetriever"); 3324935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen return; 3334935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen } 3344935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen 3354935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); 3364935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen if (fields.context == NULL) { 3374935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaMetadataRetriever.mNativeContext"); 3384935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen return; 3394935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen } 3404935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen 3414935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen fields.bitmapClazz = env->FindClass("android/graphics/Bitmap"); 3424935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen if (fields.bitmapClazz == NULL) { 3434935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen jniThrowException(env, "java/lang/RuntimeException", "Can't find android/graphics/Bitmap"); 3444935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen return; 3454935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen } 3460e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong#if USE_PRIVATE_NATIVE_BITMAP_CONSTUCTOR 34788b77412286115b158d906369b62515d773f21bcJames Dong fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(I[BZ[BI)V"); 3484935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen if (fields.bitmapConstructor == NULL) { 3494935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen jniThrowException(env, "java/lang/RuntimeException", "Can't find Bitmap constructor"); 3504935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen return; 3514935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen } 3520e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.createBitmapRotationMethod = 35353ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong env->GetStaticMethodID(fields.bitmapClazz, "createBitmap", 35453ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong "(Landroid/graphics/Bitmap;IIIILandroid/graphics/Matrix;Z)" 35553ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong "Landroid/graphics/Bitmap;"); 3560e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong if (fields.createBitmapRotationMethod == NULL) { 35753ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong jniThrowException(env, "java/lang/RuntimeException", 35853ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong "Can't find Bitmap.createBitmap method"); 35953ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong return; 36053ebc72fd83f83bb5536d5917390aae03b7f5cadJames Dong } 3610e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong#else 3620e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.createBitmapMethod = 3630e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong env->GetStaticMethodID(fields.bitmapClazz, "createBitmap", 3640e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong "(IILandroid/graphics/Bitmap$Config;)" 3650e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong "Landroid/graphics/Bitmap;"); 3660e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong if (fields.createBitmapMethod == NULL) { 3670e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jniThrowException(env, "java/lang/RuntimeException", 3680e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong "Can't find Bitmap.createBitmap(int, int, Config) method"); 3690e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong return; 3700e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong } 3710e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.nativeBitmap = env->GetFieldID(fields.bitmapClazz, "mNativeBitmap", "I"); 3720e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong if (fields.nativeBitmap == NULL) { 3730e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jniThrowException(env, "java/lang/RuntimeException", 3740e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong "Can't find Bitmap.mNativeBitmap field"); 3750e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong } 3760e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong 3770e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.configClazz = env->FindClass("android/graphics/Bitmap$Config"); 3780e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong if (fields.configClazz == NULL) { 3790e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jniThrowException(env, "java/lang/RuntimeException", 3800e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong "Can't find Bitmap$Config class"); 3810e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong return; 3820e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong } 3830e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong fields.createConfigMethod = 3840e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong env->GetStaticMethodID(fields.configClazz, "nativeToConfig", 3850e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong "(I)Landroid/graphics/Bitmap$Config;"); 3860e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong if (fields.createConfigMethod == NULL) { 3870e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong jniThrowException(env, "java/lang/RuntimeException", 3880e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong "Can't find Bitmap$Config.nativeToConfig(int) method"); 3890e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong return; 3900e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong } 3910e4b535b439f2c8bd4f7ba820f81bf74336bae76James Dong#endif 3924935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen} 3934935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobject thiz) 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("native_setup"); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever* retriever = new MediaMetadataRetriever(); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retriever == 0) { 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRetriever(env, thiz, (int)retriever); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// JNI mapping between Java methods and native methods 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod nativeMethods[] = { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaMetadataRetriever_setDataSource}, 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD}, 409faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong {"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime}, 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata}, 411df9b349b960fff95dff4fcf8b2661899e33059daJames Dong {"getEmbeddedPicture", "(I)[B", (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture}, 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"release", "()V", (void *)android_media_MediaMetadataRetriever_release}, 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_finalize", "()V", (void *)android_media_MediaMetadataRetriever_native_finalize}, 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project {"native_setup", "()V", (void *)android_media_MediaMetadataRetriever_native_setup}, 4154935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen {"native_init", "()V", (void *)android_media_MediaMetadataRetriever_native_init}, 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4184935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen// This function only registers the native methods, and is called from 4194935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen// JNI_OnLoad in android_media_MediaPlayer.cpp 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_media_MediaMetadataRetriever(JNIEnv *env) 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AndroidRuntime::registerNativeMethods 4234935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen (env, kClassPathName, nativeMethods, NELEM(nativeMethods)); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 425