summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-03-21 10:25:44 -0700
committerAndreas Huber <andih@google.com>2011-03-21 11:13:59 -0700
commit5b7ced6a4ebcec34a36d0779773bc9e671732dbf (patch)
tree0489d59487f225e900896f1f5fd152dc2c498666
parentaffb58e727863fdc8d2c0ea444054b581eb41be5 (diff)
downloadframeworks_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.xml17
-rw-r--r--include/media/IMediaMetadataRetriever.h9
-rw-r--r--include/media/MediaMetadataRetrieverInterface.h6
-rw-r--r--include/media/mediametadataretriever.h6
-rw-r--r--media/java/android/media/MediaMetadataRetriever.java16
-rw-r--r--media/jni/android_media_MediaMetadataRetriever.cpp110
-rw-r--r--media/libmedia/IMediaMetadataRetriever.cpp29
-rw-r--r--media/libmedia/mediametadataretriever.cpp5
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.cpp5
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.h5
-rw-r--r--media/libmediaplayerservice/MidiMetadataRetriever.cpp6
-rw-r--r--media/libmediaplayerservice/MidiMetadataRetriever.h4
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp5
-rw-r--r--media/libstagefright/include/StagefrightMetadataRetriever.h5
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&lt;java.lang.String, java.lang.String&gt;">
+</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);