blob: c2694f1fb9cb39a1ccd2ad8563364e7cac2aeadb [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2**
3** Copyright 2008, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18//#define LOG_NDEBUG 0
19#define LOG_TAG "MediaMetadataRetrieverJNI"
20
21#include <assert.h>
22#include <utils/Log.h>
23#include <utils/threads.h>
24#include <core/SkBitmap.h>
25#include <media/mediametadataretriever.h>
26#include <private/media/VideoFrame.h>
27
28#include "jni.h"
29#include "JNIHelp.h"
30#include "android_runtime/AndroidRuntime.h"
James Dong79f407c2011-05-05 12:50:04 -070031#include "android_media_Utils.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032
33
34using namespace android;
35
36struct fields_t {
37 jfieldID context;
James Dongc371a022011-04-06 12:16:07 -070038 jclass bitmapClazz; // Must be a global ref
James Dong0e4b5352010-12-19 13:05:33 -080039 jfieldID nativeBitmap;
James Dong53ebc722010-11-08 16:04:27 -080040 jmethodID createBitmapMethod;
James Dong9f2cde32011-03-18 17:55:06 -070041 jmethodID createScaledBitmapMethod;
James Dongc371a022011-04-06 12:16:07 -070042 jclass configClazz; // Must be a global ref
James Dong0e4b5352010-12-19 13:05:33 -080043 jmethodID createConfigMethod;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044};
45
46static fields_t fields;
47static Mutex sLock;
Marco Nelissen4935d052009-08-03 11:12:58 -070048static const char* const kClassPathName = "android/media/MediaMetadataRetriever";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049
50static void process_media_retriever_call(JNIEnv *env, status_t opStatus, const char* exception, const char *message)
51{
52 if (opStatus == (status_t) INVALID_OPERATION) {
53 jniThrowException(env, "java/lang/IllegalStateException", NULL);
54 } else if (opStatus != (status_t) OK) {
55 if (strlen(message) > 230) {
56 // If the message is too long, don't bother displaying the status code.
57 jniThrowException( env, exception, message);
58 } else {
59 char msg[256];
60 // Append the status code to the message.
61 sprintf(msg, "%s: status = 0x%X", message, opStatus);
62 jniThrowException( env, exception, msg);
63 }
64 }
65}
66
67static MediaMetadataRetriever* getRetriever(JNIEnv* env, jobject thiz)
68{
69 // No lock is needed, since it is called internally by other methods that are protected
Ashok Bhat075e9a12014-01-06 13:45:09 +000070 MediaMetadataRetriever* retriever = (MediaMetadataRetriever*) env->GetLongField(thiz, fields.context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 return retriever;
72}
73
Ashok Bhat075e9a12014-01-06 13:45:09 +000074static void setRetriever(JNIEnv* env, jobject thiz, MediaMetadataRetriever* retriever)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075{
76 // No lock is needed, since it is called internally by other methods that are protected
Ashok Bhat075e9a12014-01-06 13:45:09 +000077 MediaMetadataRetriever *old = (MediaMetadataRetriever*) env->GetLongField(thiz, fields.context);
78 env->SetLongField(thiz, fields.context, (jlong) retriever);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079}
80
Andreas Huber5b7ced62011-03-21 10:25:44 -070081static void
82android_media_MediaMetadataRetriever_setDataSourceAndHeaders(
James Dong17524dc2011-05-04 13:41:58 -070083 JNIEnv *env, jobject thiz, jstring path,
84 jobjectArray keys, jobjectArray values) {
85
Steve Block71f2cf12011-10-20 11:56:00 +010086 ALOGV("setDataSource");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 MediaMetadataRetriever* retriever = getRetriever(env, thiz);
88 if (retriever == 0) {
Andreas Huber5b7ced62011-03-21 10:25:44 -070089 jniThrowException(
90 env,
91 "java/lang/IllegalStateException", "No retriever available");
92
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 return;
94 }
95
Andreas Huber5b7ced62011-03-21 10:25:44 -070096 if (!path) {
97 jniThrowException(
98 env, "java/lang/IllegalArgumentException", "Null pointer");
99
100 return;
101 }
102
103 const char *tmp = env->GetStringUTFChars(path, NULL);
Andreas Huber5bb357f2011-03-21 11:55:01 -0700104 if (!tmp) { // OutOfMemoryError exception already thrown
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 return;
106 }
107
Andreas Huber5bb357f2011-03-21 11:55:01 -0700108 String8 pathStr(tmp);
Andreas Huber5b7ced62011-03-21 10:25:44 -0700109 env->ReleaseStringUTFChars(path, tmp);
110 tmp = NULL;
111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 // Don't let somebody trick us in to reading some random block of memory
Andreas Huber5b7ced62011-03-21 10:25:44 -0700113 if (strncmp("mem://", pathStr.string(), 6) == 0) {
114 jniThrowException(
115 env, "java/lang/IllegalArgumentException", "Invalid pathname");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 return;
117 }
118
Andreas Huber5b7ced62011-03-21 10:25:44 -0700119 // We build a similar KeyedVector out of it.
120 KeyedVector<String8, String8> headersVector;
James Dong79f407c2011-05-05 12:50:04 -0700121 if (!ConvertKeyValueArraysToKeyedVector(
122 env, keys, values, &headersVector)) {
123 return;
Andreas Huber5b7ced62011-03-21 10:25:44 -0700124 }
Andreas Huber5b7ced62011-03-21 10:25:44 -0700125 process_media_retriever_call(
126 env,
127 retriever->setDataSource(
James Dong79f407c2011-05-05 12:50:04 -0700128 pathStr.string(), headersVector.size() > 0 ? &headersVector : NULL),
Andreas Huber5b7ced62011-03-21 10:25:44 -0700129
130 "java/lang/RuntimeException",
131 "setDataSource failed");
132}
133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134static void android_media_MediaMetadataRetriever_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
135{
Steve Block71f2cf12011-10-20 11:56:00 +0100136 ALOGV("setDataSource");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 MediaMetadataRetriever* retriever = getRetriever(env, thiz);
138 if (retriever == 0) {
139 jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
140 return;
141 }
142 if (!fileDescriptor) {
143 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
144 return;
145 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700146 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 if (offset < 0 || length < 0 || fd < 0) {
148 if (offset < 0) {
Ashok Bhat075e9a12014-01-06 13:45:09 +0000149 ALOGE("negative offset (%lld)", (long long)offset);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 }
151 if (length < 0) {
Ashok Bhat075e9a12014-01-06 13:45:09 +0000152 ALOGE("negative length (%lld)", (long long)length);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 }
154 if (fd < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000155 ALOGE("invalid file descriptor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 }
157 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
158 return;
159 }
160 process_media_retriever_call(env, retriever->setDataSource(fd, offset, length), "java/lang/RuntimeException", "setDataSource failed");
161}
162
Carl Shapiroae12a502011-01-20 23:13:09 -0800163template<typename T>
164static void rotate0(T* dst, const T* src, size_t width, size_t height)
165{
166 memcpy(dst, src, width * height * sizeof(T));
167}
168
169template<typename T>
170static void rotate90(T* dst, const T* src, size_t width, size_t height)
171{
172 for (size_t i = 0; i < height; ++i) {
173 for (size_t j = 0; j < width; ++j) {
174 dst[j * height + height - 1 - i] = src[i * width + j];
175 }
176 }
177}
178
179template<typename T>
180static void rotate180(T* dst, const T* src, size_t width, size_t height)
181{
182 for (size_t i = 0; i < height; ++i) {
183 for (size_t j = 0; j < width; ++j) {
184 dst[(height - 1 - i) * width + width - 1 - j] = src[i * width + j];
185 }
186 }
187}
188
189template<typename T>
190static void rotate270(T* dst, const T* src, size_t width, size_t height)
191{
192 for (size_t i = 0; i < height; ++i) {
193 for (size_t j = 0; j < width; ++j) {
194 dst[(width - 1 - j) * height + i] = src[i * width + j];
195 }
196 }
197}
198
199template<typename T>
200static void rotate(T *dst, const T *src, size_t width, size_t height, int angle)
201{
202 switch (angle) {
203 case 0:
204 rotate0(dst, src, width, height);
205 break;
206 case 90:
207 rotate90(dst, src, width, height);
208 break;
209 case 180:
210 rotate180(dst, src, width, height);
211 break;
212 case 270:
213 rotate270(dst, src, width, height);
214 break;
215 }
216}
217
James Dongfaf09ba2010-12-02 17:42:08 -0800218static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219{
Steve Block71f2cf12011-10-20 11:56:00 +0100220 ALOGV("getFrameAtTime: %lld us option: %d", timeUs, option);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 MediaMetadataRetriever* retriever = getRetriever(env, thiz);
222 if (retriever == 0) {
223 jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
224 return NULL;
225 }
226
227 // Call native method to retrieve a video frame
228 VideoFrame *videoFrame = NULL;
James Dongfaf09ba2010-12-02 17:42:08 -0800229 sp<IMemory> frameMemory = retriever->getFrameAtTime(timeUs, option);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 if (frameMemory != 0) { // cast the shared structure to a VideoFrame object
231 videoFrame = static_cast<VideoFrame *>(frameMemory->pointer());
232 }
233 if (videoFrame == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000234 ALOGE("getFrameAtTime: videoFrame is a NULL pointer");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 return NULL;
236 }
237
Steve Block71f2cf12011-10-20 11:56:00 +0100238 ALOGV("Dimension = %dx%d and bytes = %d",
James Dong0e4b5352010-12-19 13:05:33 -0800239 videoFrame->mDisplayWidth,
240 videoFrame->mDisplayHeight,
241 videoFrame->mSize);
242
James Dong0e4b5352010-12-19 13:05:33 -0800243 jobject config = env->CallStaticObjectMethod(
244 fields.configClazz,
245 fields.createConfigMethod,
246 SkBitmap::kRGB_565_Config);
247
Ashok Bhat58fad0b2014-03-04 21:13:52 +0000248 uint32_t width, height;
James Dong9f2cde32011-03-18 17:55:06 -0700249 bool swapWidthAndHeight = false;
Carl Shapiroae12a502011-01-20 23:13:09 -0800250 if (videoFrame->mRotationAngle == 90 || videoFrame->mRotationAngle == 270) {
James Dong9f2cde32011-03-18 17:55:06 -0700251 width = videoFrame->mHeight;
252 height = videoFrame->mWidth;
253 swapWidthAndHeight = true;
Carl Shapiroae12a502011-01-20 23:13:09 -0800254 } else {
James Dong9f2cde32011-03-18 17:55:06 -0700255 width = videoFrame->mWidth;
256 height = videoFrame->mHeight;
Carl Shapiroae12a502011-01-20 23:13:09 -0800257 }
258
James Dong0e4b5352010-12-19 13:05:33 -0800259 jobject jBitmap = env->CallStaticObjectMethod(
260 fields.bitmapClazz,
261 fields.createBitmapMethod,
Carl Shapiroae12a502011-01-20 23:13:09 -0800262 width,
263 height,
James Dong0e4b5352010-12-19 13:05:33 -0800264 config);
wang, biaoc847a482012-10-30 15:35:01 +0800265 if (jBitmap == NULL) {
266 if (env->ExceptionCheck()) {
267 env->ExceptionClear();
268 }
269 ALOGE("getFrameAtTime: create Bitmap failed!");
270 return NULL;
271 }
Carl Shapiroae12a502011-01-20 23:13:09 -0800272
James Dong0e4b5352010-12-19 13:05:33 -0800273 SkBitmap *bitmap =
Ashok Bhata0398432014-01-20 20:08:01 +0000274 (SkBitmap *) env->GetLongField(jBitmap, fields.nativeBitmap);
James Dong0e4b5352010-12-19 13:05:33 -0800275
276 bitmap->lockPixels();
Carl Shapiroae12a502011-01-20 23:13:09 -0800277 rotate((uint16_t*)bitmap->getPixels(),
278 (uint16_t*)((char*)videoFrame + sizeof(VideoFrame)),
James Dong9f2cde32011-03-18 17:55:06 -0700279 videoFrame->mWidth,
280 videoFrame->mHeight,
Carl Shapiroae12a502011-01-20 23:13:09 -0800281 videoFrame->mRotationAngle);
James Dong0e4b5352010-12-19 13:05:33 -0800282 bitmap->unlockPixels();
283
James Dong9f2cde32011-03-18 17:55:06 -0700284 if (videoFrame->mDisplayWidth != videoFrame->mWidth ||
285 videoFrame->mDisplayHeight != videoFrame->mHeight) {
Ashok Bhat58fad0b2014-03-04 21:13:52 +0000286 uint32_t displayWidth = videoFrame->mDisplayWidth;
287 uint32_t displayHeight = videoFrame->mDisplayHeight;
James Dong9f2cde32011-03-18 17:55:06 -0700288 if (swapWidthAndHeight) {
289 displayWidth = videoFrame->mDisplayHeight;
290 displayHeight = videoFrame->mDisplayWidth;
291 }
Steve Block71f2cf12011-10-20 11:56:00 +0100292 ALOGV("Bitmap dimension is scaled from %dx%d to %dx%d",
James Dong9f2cde32011-03-18 17:55:06 -0700293 width, height, displayWidth, displayHeight);
294 jobject scaledBitmap = env->CallStaticObjectMethod(fields.bitmapClazz,
295 fields.createScaledBitmapMethod,
296 jBitmap,
297 displayWidth,
298 displayHeight,
299 true);
300 return scaledBitmap;
301 }
302
James Dong0e4b5352010-12-19 13:05:33 -0800303 return jBitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304}
305
James Dongdf9b3492011-01-04 15:03:48 -0800306static jbyteArray android_media_MediaMetadataRetriever_getEmbeddedPicture(
307 JNIEnv *env, jobject thiz, jint pictureType)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308{
Steve Block71f2cf12011-10-20 11:56:00 +0100309 ALOGV("getEmbeddedPicture: %d", pictureType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 MediaMetadataRetriever* retriever = getRetriever(env, thiz);
311 if (retriever == 0) {
312 jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
313 return NULL;
314 }
315 MediaAlbumArt* mediaAlbumArt = NULL;
James Dongdf9b3492011-01-04 15:03:48 -0800316
317 // FIXME:
318 // Use pictureType to retrieve the intended embedded picture and also change
319 // the method name to getEmbeddedPicture().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 sp<IMemory> albumArtMemory = retriever->extractAlbumArt();
321 if (albumArtMemory != 0) { // cast the shared structure to a MediaAlbumArt object
322 mediaAlbumArt = static_cast<MediaAlbumArt *>(albumArtMemory->pointer());
323 }
324 if (mediaAlbumArt == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000325 ALOGE("getEmbeddedPicture: Call to getEmbeddedPicture failed.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 return NULL;
327 }
328
329 unsigned int len = mediaAlbumArt->mSize;
330 char* data = (char*) mediaAlbumArt + sizeof(MediaAlbumArt);
331 jbyteArray array = env->NewByteArray(len);
332 if (!array) { // OutOfMemoryError exception has already been thrown.
Steve Block3762c312012-01-06 19:20:56 +0000333 ALOGE("getEmbeddedPicture: OutOfMemoryError is thrown.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 } else {
335 jbyte* bytes = env->GetByteArrayElements(array, NULL);
336 if (bytes != NULL) {
337 memcpy(bytes, data, len);
338 env->ReleaseByteArrayElements(array, bytes, 0);
339 }
340 }
341
342 // No need to delete mediaAlbumArt here
343 return array;
344}
345
346static jobject android_media_MediaMetadataRetriever_extractMetadata(JNIEnv *env, jobject thiz, jint keyCode)
347{
Steve Block71f2cf12011-10-20 11:56:00 +0100348 ALOGV("extractMetadata");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 MediaMetadataRetriever* retriever = getRetriever(env, thiz);
350 if (retriever == 0) {
351 jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
352 return NULL;
353 }
354 const char* value = retriever->extractMetadata(keyCode);
355 if (!value) {
Steve Block71f2cf12011-10-20 11:56:00 +0100356 ALOGV("extractMetadata: Metadata is not found");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 return NULL;
358 }
Steve Block71f2cf12011-10-20 11:56:00 +0100359 ALOGV("extractMetadata: value (%s) for keyCode(%d)", value, keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 return env->NewStringUTF(value);
361}
362
363static void android_media_MediaMetadataRetriever_release(JNIEnv *env, jobject thiz)
364{
Steve Block71f2cf12011-10-20 11:56:00 +0100365 ALOGV("release");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 Mutex::Autolock lock(sLock);
367 MediaMetadataRetriever* retriever = getRetriever(env, thiz);
368 delete retriever;
Ashok Bhat075e9a12014-01-06 13:45:09 +0000369 setRetriever(env, thiz, (MediaMetadataRetriever*) 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370}
371
372static void android_media_MediaMetadataRetriever_native_finalize(JNIEnv *env, jobject thiz)
373{
Steve Block71f2cf12011-10-20 11:56:00 +0100374 ALOGV("native_finalize");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 // No lock is needed, since android_media_MediaMetadataRetriever_release() is protected
376 android_media_MediaMetadataRetriever_release(env, thiz);
377}
378
Marco Nelissen4935d052009-08-03 11:12:58 -0700379// This function gets a field ID, which in turn causes class initialization.
380// It is called from a static block in MediaMetadataRetriever, which won't run until the
381// first time an instance of this class is used.
382static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env)
383{
384 jclass clazz = env->FindClass(kClassPathName);
385 if (clazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700386 return;
387 }
388
Ashok Bhat075e9a12014-01-06 13:45:09 +0000389 fields.context = env->GetFieldID(clazz, "mNativeContext", "J");
Marco Nelissen4935d052009-08-03 11:12:58 -0700390 if (fields.context == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700391 return;
392 }
393
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700394 jclass bitmapClazz = env->FindClass("android/graphics/Bitmap");
395 if (bitmapClazz == NULL) {
396 return;
397 }
398 fields.bitmapClazz = (jclass) env->NewGlobalRef(bitmapClazz);
Marco Nelissen4935d052009-08-03 11:12:58 -0700399 if (fields.bitmapClazz == NULL) {
Marco Nelissen4935d052009-08-03 11:12:58 -0700400 return;
401 }
James Dong0e4b5352010-12-19 13:05:33 -0800402 fields.createBitmapMethod =
403 env->GetStaticMethodID(fields.bitmapClazz, "createBitmap",
404 "(IILandroid/graphics/Bitmap$Config;)"
405 "Landroid/graphics/Bitmap;");
406 if (fields.createBitmapMethod == NULL) {
James Dong0e4b5352010-12-19 13:05:33 -0800407 return;
408 }
James Dong9f2cde32011-03-18 17:55:06 -0700409 fields.createScaledBitmapMethod =
410 env->GetStaticMethodID(fields.bitmapClazz, "createScaledBitmap",
411 "(Landroid/graphics/Bitmap;IIZ)"
412 "Landroid/graphics/Bitmap;");
413 if (fields.createScaledBitmapMethod == NULL) {
James Dong9f2cde32011-03-18 17:55:06 -0700414 return;
415 }
Ashok Bhata0398432014-01-20 20:08:01 +0000416 fields.nativeBitmap = env->GetFieldID(fields.bitmapClazz, "mNativeBitmap", "J");
James Dong0e4b5352010-12-19 13:05:33 -0800417 if (fields.nativeBitmap == NULL) {
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700418 return;
James Dong0e4b5352010-12-19 13:05:33 -0800419 }
420
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700421 jclass configClazz = env->FindClass("android/graphics/Bitmap$Config");
422 if (configClazz == NULL) {
423 return;
424 }
425 fields.configClazz = (jclass) env->NewGlobalRef(configClazz);
James Dong0e4b5352010-12-19 13:05:33 -0800426 if (fields.configClazz == NULL) {
James Dong0e4b5352010-12-19 13:05:33 -0800427 return;
428 }
429 fields.createConfigMethod =
430 env->GetStaticMethodID(fields.configClazz, "nativeToConfig",
431 "(I)Landroid/graphics/Bitmap$Config;");
432 if (fields.createConfigMethod == NULL) {
James Dong0e4b5352010-12-19 13:05:33 -0800433 return;
434 }
Marco Nelissen4935d052009-08-03 11:12:58 -0700435}
436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobject thiz)
438{
Steve Block71f2cf12011-10-20 11:56:00 +0100439 ALOGV("native_setup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 MediaMetadataRetriever* retriever = new MediaMetadataRetriever();
441 if (retriever == 0) {
442 jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
443 return;
444 }
Ashok Bhat075e9a12014-01-06 13:45:09 +0000445 setRetriever(env, thiz, retriever);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446}
447
448// JNI mapping between Java methods and native methods
449static JNINativeMethod nativeMethods[] = {
James Dong17524dc2011-05-04 13:41:58 -0700450 {
451 "_setDataSource",
452 "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
453 (void *)android_media_MediaMetadataRetriever_setDataSourceAndHeaders
454 },
455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD},
James Dongfaf09ba2010-12-02 17:42:08 -0800457 {"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 {"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata},
James Dongdf9b3492011-01-04 15:03:48 -0800459 {"getEmbeddedPicture", "(I)[B", (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 {"release", "()V", (void *)android_media_MediaMetadataRetriever_release},
461 {"native_finalize", "()V", (void *)android_media_MediaMetadataRetriever_native_finalize},
462 {"native_setup", "()V", (void *)android_media_MediaMetadataRetriever_native_setup},
Marco Nelissen4935d052009-08-03 11:12:58 -0700463 {"native_init", "()V", (void *)android_media_MediaMetadataRetriever_native_init},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464};
465
Marco Nelissen4935d052009-08-03 11:12:58 -0700466// This function only registers the native methods, and is called from
467// JNI_OnLoad in android_media_MediaPlayer.cpp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468int register_android_media_MediaMetadataRetriever(JNIEnv *env)
469{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 return AndroidRuntime::registerNativeMethods
Marco Nelissen4935d052009-08-03 11:12:58 -0700471 (env, kClassPathName, nativeMethods, NELEM(nativeMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472}