diff options
author | Andreas Huber <andih@google.com> | 2011-03-21 10:25:44 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2011-03-21 11:13:59 -0700 |
commit | 5b7ced6a4ebcec34a36d0779773bc9e671732dbf (patch) | |
tree | 0489d59487f225e900896f1f5fd152dc2c498666 | |
parent | affb58e727863fdc8d2c0ea444054b581eb41be5 (diff) | |
download | frameworks_base-5b7ced6a4ebcec34a36d0779773bc9e671732dbf.zip frameworks_base-5b7ced6a4ebcec34a36d0779773bc9e671732dbf.tar.gz frameworks_base-5b7ced6a4ebcec34a36d0779773bc9e671732dbf.tar.bz2 |
Support passing headers to MediaMetadataRetriever's setDataSource API
Change-Id: Ib1a5c08fc5034cac05034db27007a35c9b660b26
related-to-bug: 3506316
-rw-r--r-- | api/current.xml | 17 | ||||
-rw-r--r-- | include/media/IMediaMetadataRetriever.h | 9 | ||||
-rw-r--r-- | include/media/MediaMetadataRetrieverInterface.h | 6 | ||||
-rw-r--r-- | include/media/mediametadataretriever.h | 6 | ||||
-rw-r--r-- | media/java/android/media/MediaMetadataRetriever.java | 16 | ||||
-rw-r--r-- | media/jni/android_media_MediaMetadataRetriever.cpp | 110 | ||||
-rw-r--r-- | media/libmedia/IMediaMetadataRetriever.cpp | 29 | ||||
-rw-r--r-- | media/libmedia/mediametadataretriever.cpp | 5 | ||||
-rw-r--r-- | media/libmediaplayerservice/MetadataRetrieverClient.cpp | 5 | ||||
-rw-r--r-- | media/libmediaplayerservice/MetadataRetrieverClient.h | 5 | ||||
-rw-r--r-- | media/libmediaplayerservice/MidiMetadataRetriever.cpp | 6 | ||||
-rw-r--r-- | media/libmediaplayerservice/MidiMetadataRetriever.h | 4 | ||||
-rw-r--r-- | media/libstagefright/StagefrightMetadataRetriever.cpp | 5 | ||||
-rw-r--r-- | media/libstagefright/include/StagefrightMetadataRetriever.h | 5 |
14 files changed, 200 insertions, 28 deletions
diff --git a/api/current.xml b/api/current.xml index 70ea729..16ba6be 100644 --- a/api/current.xml +++ b/api/current.xml @@ -105715,6 +105715,23 @@ deprecated="not deprecated" visibility="public" > +<parameter name="uri" type="java.lang.String"> +</parameter> +<parameter name="headers" type="java.util.Map<java.lang.String, java.lang.String>"> +</parameter> +<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException"> +</exception> +</method> +<method name="setDataSource" + return="void" + abstract="false" + native="true" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> <parameter name="fd" type="java.io.FileDescriptor"> </parameter> <parameter name="offset" type="long"> diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h index 8e3cdbb..1c1c268 100644 --- a/include/media/IMediaMetadataRetriever.h +++ b/include/media/IMediaMetadataRetriever.h @@ -18,10 +18,11 @@ #ifndef ANDROID_IMEDIAMETADATARETRIEVER_H #define ANDROID_IMEDIAMETADATARETRIEVER_H -#include <utils/RefBase.h> #include <binder/IInterface.h> #include <binder/Parcel.h> #include <binder/IMemory.h> +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> namespace android { @@ -30,7 +31,11 @@ class IMediaMetadataRetriever: public IInterface public: DECLARE_META_INTERFACE(MediaMetadataRetriever); virtual void disconnect() = 0; - virtual status_t setDataSource(const char* srcUrl) = 0; + + virtual status_t setDataSource( + const char *srcUrl, + const KeyedVector<String8, String8> *headers = NULL) = 0; + virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option) = 0; virtual sp<IMemory> extractAlbumArt() = 0; diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h index 0449122..27b7e4d 100644 --- a/include/media/MediaMetadataRetrieverInterface.h +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -30,7 +30,11 @@ class MediaMetadataRetrieverBase : public RefBase public: MediaMetadataRetrieverBase() {} virtual ~MediaMetadataRetrieverBase() {} - virtual status_t setDataSource(const char *url) = 0; + + virtual status_t setDataSource( + const char *url, + const KeyedVector<String8, String8> *headers = NULL) = 0; + virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0; virtual MediaAlbumArt* extractAlbumArt() = 0; diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index a5cb949..3e343e0 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -62,7 +62,11 @@ public: MediaMetadataRetriever(); ~MediaMetadataRetriever(); void disconnect(); - status_t setDataSource(const char* dataSourceUrl); + + status_t setDataSource( + const char *dataSourceUrl, + const KeyedVector<String8, String8> *headers = NULL); + status_t setDataSource(int fd, int64_t offset, int64_t length); sp<IMemory> getFrameAtTime(int64_t timeUs, int option); sp<IMemory> extractAlbumArt(); diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index 13e1732..60085b5 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -26,6 +26,8 @@ import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.Map; + /** * MediaMetadataRetriever class provides a unified interface for retrieving * frame and meta data from an input media file. @@ -56,7 +58,19 @@ public class MediaMetadataRetriever * @throws IllegalArgumentException If the path is invalid. */ public native void setDataSource(String path) throws IllegalArgumentException; - + + /** + * Sets the data source (URI) to use. Call this + * method before the rest of the methods in this class. This method may be + * time-consuming. + * + * @param uri The URI of the input media. + * @param headers the headers to be sent together with the request for the data + * @throws IllegalArgumentException If the URI is invalid. + */ + public native void setDataSource(String uri, Map<String, String> headers) + throws IllegalArgumentException; + /** * Sets the data source (FileDescriptor) to use. It is the caller's * responsibility to close the file descriptor. It is safe to do so as soon diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp index 3d7dbf9..eaac9638c 100644 --- a/media/jni/android_media_MediaMetadataRetriever.cpp +++ b/media/jni/android_media_MediaMetadataRetriever.cpp @@ -76,32 +76,123 @@ static void setRetriever(JNIEnv* env, jobject thiz, int retriever) env->SetIntField(thiz, fields.context, retriever); } -static void android_media_MediaMetadataRetriever_setDataSource(JNIEnv *env, jobject thiz, jstring path) -{ +static void +android_media_MediaMetadataRetriever_setDataSourceAndHeaders( + JNIEnv *env, jobject thiz, jstring path, jobject headers) { LOGV("setDataSource"); MediaMetadataRetriever* retriever = getRetriever(env, thiz); if (retriever == 0) { - jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); + jniThrowException( + env, + "java/lang/IllegalStateException", "No retriever available"); + return; } + if (!path) { - jniThrowException(env, "java/lang/IllegalArgumentException", "Null pointer"); + jniThrowException( + env, "java/lang/IllegalArgumentException", "Null pointer"); + return; } - const char *pathStr = env->GetStringUTFChars(path, NULL); + const char *tmp = env->GetStringUTFChars(path, NULL); if (!pathStr) { // OutOfMemoryError exception already thrown return; } + String8 pathStr = tmp; + + env->ReleaseStringUTFChars(path, tmp); + tmp = NULL; + // Don't let somebody trick us in to reading some random block of memory - if (strncmp("mem://", pathStr, 6) == 0) { - jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid pathname"); + if (strncmp("mem://", pathStr.string(), 6) == 0) { + jniThrowException( + env, "java/lang/IllegalArgumentException", "Invalid pathname"); return; } - process_media_retriever_call(env, retriever->setDataSource(pathStr), "java/lang/RuntimeException", "setDataSource failed"); - env->ReleaseStringUTFChars(path, pathStr); + // headers is a Map<String, String>. + // We build a similar KeyedVector out of it. + KeyedVector<String8, String8> headersVector; + if (headers) { + // Get the Map's entry Set. + jclass mapClass = env->FindClass("java/util/Map"); + + jmethodID entrySet = + env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;"); + + jobject set = env->CallObjectMethod(headers, entrySet); + // Obtain an iterator over the Set + jclass setClass = env->FindClass("java/util/Set"); + + jmethodID iterator = + env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;"); + + jobject iter = env->CallObjectMethod(set, iterator); + // Get the Iterator method IDs + jclass iteratorClass = env->FindClass("java/util/Iterator"); + jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z"); + + jmethodID next = + env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;"); + + // Get the Entry class method IDs + jclass entryClass = env->FindClass("java/util/Map$Entry"); + + jmethodID getKey = + env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;"); + + jmethodID getValue = + env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;"); + + // Iterate over the entry Set + while (env->CallBooleanMethod(iter, hasNext)) { + jobject entry = env->CallObjectMethod(iter, next); + jstring key = (jstring) env->CallObjectMethod(entry, getKey); + jstring value = (jstring) env->CallObjectMethod(entry, getValue); + + const char* keyStr = env->GetStringUTFChars(key, NULL); + if (!keyStr) { // Out of memory + return; + } + + const char* valueStr = env->GetStringUTFChars(value, NULL); + if (!valueStr) { // Out of memory + return; + } + + headersVector.add(String8(keyStr), String8(valueStr)); + + env->DeleteLocalRef(entry); + env->ReleaseStringUTFChars(key, keyStr); + env->DeleteLocalRef(key); + env->ReleaseStringUTFChars(value, valueStr); + env->DeleteLocalRef(value); + } + + env->DeleteLocalRef(entryClass); + env->DeleteLocalRef(iteratorClass); + env->DeleteLocalRef(iter); + env->DeleteLocalRef(setClass); + env->DeleteLocalRef(set); + env->DeleteLocalRef(mapClass); + } + + process_media_retriever_call( + env, + retriever->setDataSource( + pathStr.string(), headers ? &headersVector : NULL), + + "java/lang/RuntimeException", + "setDataSource failed"); +} + +static void android_media_MediaMetadataRetriever_setDataSource( + JNIEnv *env, jobject thiz, jstring path) { + android_media_MediaMetadataRetriever_setDataSourceAndHeaders( + env, thiz, path, NULL); } static void android_media_MediaMetadataRetriever_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length) @@ -388,6 +479,7 @@ static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobje // JNI mapping between Java methods and native methods static JNINativeMethod nativeMethods[] = { {"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaMetadataRetriever_setDataSource}, + {"setDataSource", "(Ljava/lang/String;Ljava/util/Map;)V", (void *)android_media_MediaMetadataRetriever_setDataSourceAndHeaders}, {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD}, {"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime}, {"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata}, diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp index d5298c9..ebe821f 100644 --- a/media/libmedia/IMediaMetadataRetriever.cpp +++ b/media/libmedia/IMediaMetadataRetriever.cpp @@ -20,6 +20,7 @@ #include <binder/Parcel.h> #include <SkBitmap.h> #include <media/IMediaMetadataRetriever.h> +#include <utils/String8.h> // The binder is supposed to propagate the scheduler group across // the binder interface so that remote calls are executed with @@ -102,11 +103,24 @@ public: remote()->transact(DISCONNECT, data, &reply); } - status_t setDataSource(const char* srcUrl) + status_t setDataSource( + const char *srcUrl, const KeyedVector<String8, String8> *headers) { Parcel data, reply; data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); data.writeCString(srcUrl); + + if (headers == NULL) { + data.writeInt32(0); + } else { + // serialize the headers + data.writeInt32(headers->size()); + for (size_t i = 0; i < headers->size(); ++i) { + data.writeString8(headers->keyAt(i)); + data.writeString8(headers->valueAt(i)); + } + } + remote()->transact(SET_DATA_SOURCE_URL, data, &reply); return reply.readInt32(); } @@ -188,7 +202,18 @@ status_t BnMediaMetadataRetriever::onTransact( case SET_DATA_SOURCE_URL: { CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); const char* srcUrl = data.readCString(); - reply->writeInt32(setDataSource(srcUrl)); + + KeyedVector<String8, String8> headers; + int32_t numHeaders = data.readInt32(); + for (int i = 0; i < numHeaders; ++i) { + String8 key = data.readString8(); + String8 value = data.readString8(); + headers.add(key, value); + } + + reply->writeInt32( + setDataSource(srcUrl, numHeaders > 0 ? &headers : NULL)); + return NO_ERROR; } break; case SET_DATA_SOURCE_FD: { diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp index 8dfcb3b..cee06ab 100644 --- a/media/libmedia/mediametadataretriever.cpp +++ b/media/libmedia/mediametadataretriever.cpp @@ -92,7 +92,8 @@ void MediaMetadataRetriever::disconnect() } } -status_t MediaMetadataRetriever::setDataSource(const char* srcUrl) +status_t MediaMetadataRetriever::setDataSource( + const char *srcUrl, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource"); Mutex::Autolock _l(mLock); @@ -105,7 +106,7 @@ status_t MediaMetadataRetriever::setDataSource(const char* srcUrl) return UNKNOWN_ERROR; } LOGV("data source (%s)", srcUrl); - return mRetriever->setDataSource(srcUrl); + return mRetriever->setDataSource(srcUrl, headers); } status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index 5fcf2a7..8f776b4 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -120,7 +120,8 @@ static sp<MediaMetadataRetrieverBase> createRetriever(player_type playerType) return p; } -status_t MetadataRetrieverClient::setDataSource(const char *url) +status_t MetadataRetrieverClient::setDataSource( + const char *url, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource(%s)", url); Mutex::Autolock lock(mLock); @@ -131,7 +132,7 @@ status_t MetadataRetrieverClient::setDataSource(const char *url) LOGV("player type = %d", playerType); sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); if (p == NULL) return NO_INIT; - status_t ret = p->setDataSource(url); + status_t ret = p->setDataSource(url, headers); if (ret == NO_ERROR) mRetriever = p; return ret; } diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h index b834715..f08f933 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.h +++ b/media/libmediaplayerservice/MetadataRetrieverClient.h @@ -41,7 +41,10 @@ public: // Implements IMediaMetadataRetriever interface // These methods are called in IMediaMetadataRetriever.cpp? virtual void disconnect(); - virtual status_t setDataSource(const char *url); + + virtual status_t setDataSource( + const char *url, const KeyedVector<String8, String8> *headers); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option); virtual sp<IMemory> extractAlbumArt(); diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.cpp b/media/libmediaplayerservice/MidiMetadataRetriever.cpp index ad95fac..aaf2d18 100644 --- a/media/libmediaplayerservice/MidiMetadataRetriever.cpp +++ b/media/libmediaplayerservice/MidiMetadataRetriever.cpp @@ -35,7 +35,8 @@ void MidiMetadataRetriever::clearMetadataValues() mMetadataValues[0][0] = '\0'; } -status_t MidiMetadataRetriever::setDataSource(const char *url) +status_t MidiMetadataRetriever::setDataSource( + const char *url, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource: %s", url? url: "NULL pointer"); Mutex::Autolock lock(mLock); @@ -43,8 +44,7 @@ status_t MidiMetadataRetriever::setDataSource(const char *url) if (mMidiPlayer == 0) { mMidiPlayer = new MidiFile(); } - // TODO: support headers in MetadataRetriever interface! - return mMidiPlayer->setDataSource(url, NULL /* headers */); + return mMidiPlayer->setDataSource(url, headers); } status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.h b/media/libmediaplayerservice/MidiMetadataRetriever.h index 73ff347..4cee42d 100644 --- a/media/libmediaplayerservice/MidiMetadataRetriever.h +++ b/media/libmediaplayerservice/MidiMetadataRetriever.h @@ -31,7 +31,9 @@ public: MidiMetadataRetriever() {} ~MidiMetadataRetriever() {} - virtual status_t setDataSource(const char *url); + virtual status_t setDataSource( + const char *url, const KeyedVector<String8, String8> *headers); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual const char* extractMetadata(int keyCode); diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index c371cd0..f58726e 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -48,7 +48,8 @@ StagefrightMetadataRetriever::~StagefrightMetadataRetriever() { mClient.disconnect(); } -status_t StagefrightMetadataRetriever::setDataSource(const char *uri) { +status_t StagefrightMetadataRetriever::setDataSource( + const char *uri, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource(%s)", uri); mParsedMetaData = false; @@ -56,7 +57,7 @@ status_t StagefrightMetadataRetriever::setDataSource(const char *uri) { delete mAlbumArt; mAlbumArt = NULL; - mSource = DataSource::CreateFromURI(uri); + mSource = DataSource::CreateFromURI(uri, headers); if (mSource == NULL) { return UNKNOWN_ERROR; diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h index 07b1ec8..b02ed0e 100644 --- a/media/libstagefright/include/StagefrightMetadataRetriever.h +++ b/media/libstagefright/include/StagefrightMetadataRetriever.h @@ -32,7 +32,10 @@ struct StagefrightMetadataRetriever : public MediaMetadataRetrieverInterface { StagefrightMetadataRetriever(); virtual ~StagefrightMetadataRetriever(); - virtual status_t setDataSource(const char *url); + virtual status_t setDataSource( + const char *url, + const KeyedVector<String8, String8> *headers); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option); |