Merge "Unhide the android.media.[Media]DataSource interface."

This commit is contained in:
Chris Watkins
2015-04-16 17:06:37 +00:00
committed by Android (Google) Code Review
14 changed files with 377 additions and 120 deletions

View File

@@ -15564,6 +15564,11 @@ package android.media {
ctor public MediaCryptoException(java.lang.String);
}
public abstract interface MediaDataSource implements java.io.Closeable {
method public abstract long getSize();
method public abstract int readAt(long, byte[], int);
}
public class MediaDescription implements android.os.Parcelable {
method public int describeContents();
method public java.lang.CharSequence getDescription();
@@ -15699,6 +15704,7 @@ package android.media {
method public final void release();
method public void seekTo(long, int);
method public void selectTrack(int);
method public final void setDataSource(android.media.MediaDataSource) throws java.io.IOException, java.lang.IllegalArgumentException;
method public final void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
method public final void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
method public final void setDataSource(java.lang.String) throws java.io.IOException;
@@ -15878,6 +15884,7 @@ package android.media {
method public void setDataSource(java.io.FileDescriptor, long, long) throws java.lang.IllegalArgumentException;
method public void setDataSource(java.io.FileDescriptor) throws java.lang.IllegalArgumentException;
method public void setDataSource(android.content.Context, android.net.Uri) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException;
field public static final int METADATA_KEY_ALBUM = 1; // 0x1
field public static final int METADATA_KEY_ALBUMARTIST = 13; // 0xd
field public static final int METADATA_KEY_ARTIST = 2; // 0x2
@@ -15962,6 +15969,7 @@ package android.media {
method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDisplay(android.view.SurfaceHolder);
method public void setLooping(boolean);
method public void setNextMediaPlayer(android.media.MediaPlayer);

View File

@@ -16776,6 +16776,11 @@ package android.media {
ctor public MediaCryptoException(java.lang.String);
}
public abstract interface MediaDataSource implements java.io.Closeable {
method public abstract long getSize();
method public abstract int readAt(long, byte[], int);
}
public class MediaDescription implements android.os.Parcelable {
method public int describeContents();
method public java.lang.CharSequence getDescription();
@@ -16912,6 +16917,7 @@ package android.media {
method public final void release();
method public void seekTo(long, int);
method public void selectTrack(int);
method public final void setDataSource(android.media.MediaDataSource) throws java.io.IOException, java.lang.IllegalArgumentException;
method public final void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
method public final void setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException;
method public final void setDataSource(java.lang.String) throws java.io.IOException;
@@ -17091,6 +17097,7 @@ package android.media {
method public void setDataSource(java.io.FileDescriptor, long, long) throws java.lang.IllegalArgumentException;
method public void setDataSource(java.io.FileDescriptor) throws java.lang.IllegalArgumentException;
method public void setDataSource(android.content.Context, android.net.Uri) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException;
field public static final int METADATA_KEY_ALBUM = 1; // 0x1
field public static final int METADATA_KEY_ALBUMARTIST = 13; // 0xd
field public static final int METADATA_KEY_ARTIST = 2; // 0x2
@@ -17175,6 +17182,7 @@ package android.media {
method public void setDataSource(java.lang.String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDataSource(android.media.MediaDataSource) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setDisplay(android.view.SurfaceHolder);
method public void setLooping(boolean);
method public void setNextMediaPlayer(android.media.MediaPlayer);

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.media;
import java.io.Closeable;
/**
* An abstraction for a media data source, e.g. a file or an http stream
* {@hide}
*/
public interface DataSource extends Closeable {
/**
* Reads data from the data source at the requested position
*
* @param offset where in the source to read
* @param buffer the buffer to read the data into
* @param size how many bytes to read
* @return the number of bytes read, or -1 if there was an error
*/
public int readAt(long offset, byte[] buffer, int size);
/**
* Gets the size of the data source.
*
* @return size of data source, or -1 if the length is unknown
*/
public long getSize();
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.media;
import java.io.Closeable;
/**
* For supplying media data to the framework. Implement this if your app has
* special requirements for the way media data is obtained.
*
* <p class="note">Methods of this interface may be called on multiple different
* threads. There will be a thread synchronization point between each call to ensure that
* modifications to the state of your MediaDataSource are visible to future calls. This means
* you don't need to do your own synchronization unless you're modifying the
* MediaDataSource from another thread while it's being used by the framework.</p>
*/
public interface MediaDataSource extends Closeable {
/**
* Called to request data from the given position.
*
* Implementations should should write up to {@code size} bytes into
* {@code buffer}, and return the number of bytes written.
*
* Return {@code 0} to indicate that {@code position} is at, or beyond, the
* end of the source.
*
* Return {@code -1} to indicate that a fatal error occurred. The failed
* read will not be retried, so transient errors should be handled
* internally.
*
* Throwing an exception from this method will have the same effect as
* returning {@code -1}.
*
* @param position the position in the data source to read from.
* @param buffer the buffer to read the data into.
* @param size the number of bytes to read.
* @return the number of bytes read, or -1 if there was an error.
*/
public int readAt(long position, byte[] buffer, int size);
/**
* Called to get the size of the data source.
*
* @return the size of data source in bytes, or -1 if the size is unknown.
*/
public long getSize();
}

View File

@@ -66,10 +66,11 @@ final public class MediaExtractor {
}
/**
* Sets the DataSource object to be used as the data source for this extractor
* {@hide}
* Sets the data source (MediaDataSource) to use.
*
* @param dataSource the MediaDataSource for the media you want to extract from
*/
public native final void setDataSource(DataSource source) throws IOException;
public native final void setDataSource(MediaDataSource dataSource) throws IllegalArgumentException, IOException;
/**
* Sets the data source as a content Uri.

View File

@@ -203,7 +203,20 @@ public class MediaMetadataRetriever
}
/**
* Call this method after setDataSource(). This method retrieves the
* Sets the data source (MediaDataSource) to use.
*
* @param dataSource the MediaDataSource for the media you want to play
*/
public void setDataSource(MediaDataSource dataSource)
throws IllegalArgumentException {
_setDataSource(dataSource);
}
private native void _setDataSource(MediaDataSource dataSource)
throws IllegalArgumentException;
/**
* Call this method after setDataSource(). This method retrieves the
* meta data value associated with the keyCode.
*
* The keyCode currently supported is listed below as METADATA_XXX

View File

@@ -181,7 +181,8 @@ import java.lang.ref.WeakReference;
* {@link #setDataSource(FileDescriptor)}, or
* {@link #setDataSource(String)}, or
* {@link #setDataSource(Context, Uri)}, or
* {@link #setDataSource(FileDescriptor, long, long)} transfers a
* {@link #setDataSource(FileDescriptor, long, long)}, or
* {@link #setDataSource(MediaDataSource)} transfers a
* MediaPlayer object in the <em>Idle</em> state to the
* <em>Initialized</em> state.
* <ul>
@@ -1126,6 +1127,20 @@ public class MediaPlayer implements SubtitleController.Listener
private native void _setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException;
/**
* Sets the data source (MediaDataSource) to use.
*
* @param dataSource the MediaDataSource for the media you want to play
* @throws IllegalStateException if it is called in an invalid state
*/
public void setDataSource(MediaDataSource dataSource)
throws IllegalArgumentException, IllegalStateException {
_setDataSource(dataSource);
}
private native void _setDataSource(MediaDataSource dataSource)
throws IllegalArgumentException, IllegalStateException;
/**
* Prepares the player for playback, synchronously.
*

View File

@@ -7,6 +7,7 @@ LOCAL_SRC_FILES:= \
android_media_MediaCrypto.cpp \
android_media_MediaCodec.cpp \
android_media_MediaCodecList.cpp \
android_media_MediaDataSource.cpp \
android_media_MediaDrm.cpp \
android_media_MediaExtractor.cpp \
android_media_MediaHTTPConnection.cpp \

View File

@@ -0,0 +1,148 @@
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "JMediaDataSource-JNI"
#include <utils/Log.h>
#include "android_media_MediaDataSource.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "jni.h"
#include "JNIHelp.h"
#include <binder/MemoryDealer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <nativehelper/ScopedLocalRef.h>
namespace android {
JMediaDataSource::JMediaDataSource(JNIEnv* env, jobject source)
: mJavaObjStatus(OK), mSizeIsCached(false), mCachedSize(0), mMemory(NULL) {
mMediaDataSourceObj = env->NewGlobalRef(source);
CHECK(mMediaDataSourceObj != NULL);
ScopedLocalRef<jclass> mediaDataSourceClass(env, env->GetObjectClass(mMediaDataSourceObj));
CHECK(mediaDataSourceClass.get() != NULL);
mReadMethod = env->GetMethodID(mediaDataSourceClass.get(), "readAt", "(J[BI)I");
CHECK(mReadMethod != NULL);
mGetSizeMethod = env->GetMethodID(mediaDataSourceClass.get(), "getSize", "()J");
CHECK(mGetSizeMethod != NULL);
mCloseMethod = env->GetMethodID(mediaDataSourceClass.get(), "close", "()V");
CHECK(mCloseMethod != NULL);
ScopedLocalRef<jbyteArray> tmp(env, env->NewByteArray(kBufferSize));
mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
CHECK(mByteArrayObj != NULL);
sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "JMediaDataSource");
mMemory = memoryDealer->allocate(kBufferSize);
if (mMemory == NULL) {
ALOGE("Failed to allocate memory!");
}
}
JMediaDataSource::~JMediaDataSource() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->DeleteGlobalRef(mMediaDataSourceObj);
env->DeleteGlobalRef(mByteArrayObj);
}
sp<IMemory> JMediaDataSource::getIMemory() {
Mutex::Autolock lock(mLock);
return mMemory;
}
ssize_t JMediaDataSource::readAt(off64_t offset, size_t size) {
Mutex::Autolock lock(mLock);
if (mJavaObjStatus != OK || mMemory == NULL) {
return -1;
}
if (size > kBufferSize) {
size = kBufferSize;
}
JNIEnv* env = AndroidRuntime::getJNIEnv();
jint numread = env->CallIntMethod(mMediaDataSourceObj, mReadMethod,
(jlong)offset, mByteArrayObj, (jint)size);
if (env->ExceptionCheck()) {
ALOGW("An exception occurred in readAt()");
LOGW_EX(env);
env->ExceptionClear();
mJavaObjStatus = UNKNOWN_ERROR;
return -1;
}
if (numread < 0) {
ALOGW("An error occurred in readAt()");
mJavaObjStatus = UNKNOWN_ERROR;
return -1;
}
if ((size_t)numread > size) {
ALOGE("readAt read too many bytes.");
mJavaObjStatus = UNKNOWN_ERROR;
return -1;
}
ALOGV("readAt %lld / %zu => %d.", (long long)offset, size, numread);
env->GetByteArrayRegion(mByteArrayObj, 0, numread, (jbyte*)mMemory->pointer());
return numread;
}
status_t JMediaDataSource::getSize(off64_t* size) {
Mutex::Autolock lock(mLock);
if (mJavaObjStatus != OK) {
return UNKNOWN_ERROR;
}
if (mSizeIsCached) {
return mCachedSize;
}
JNIEnv* env = AndroidRuntime::getJNIEnv();
*size = env->CallLongMethod(mMediaDataSourceObj, mGetSizeMethod);
if (env->ExceptionCheck()) {
ALOGW("An exception occurred in getSize()");
LOGW_EX(env);
env->ExceptionClear();
// After returning an error, size shouldn't be used by callers.
*size = UNKNOWN_ERROR;
mJavaObjStatus = UNKNOWN_ERROR;
return UNKNOWN_ERROR;
}
// The minimum size should be -1, which indicates unknown size.
if (*size < 0) {
*size = -1;
}
mCachedSize = *size;
mSizeIsCached = true;
return OK;
}
void JMediaDataSource::close() {
Mutex::Autolock lock(mLock);
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->CallVoidMethod(mMediaDataSourceObj, mCloseMethod);
// The closed state is effectively the same as an error state.
mJavaObjStatus = UNKNOWN_ERROR;
}
} // namespace android

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ANDROID_MEDIA_MEDIADATASOURCE_H_
#define _ANDROID_MEDIA_MEDIADATASOURCE_H_
#include "jni.h"
#include <media/IDataSource.h>
#include <media/stagefright/foundation/ABase.h>
#include <utils/Errors.h>
#include <utils/Mutex.h>
namespace android {
// The native counterpart to a Java android.media.MediaDataSource. It inherits from
// IDataSource so that it can be accessed remotely.
//
// If the java DataSource returns an error or throws an exception it
// will be considered to be in a broken state, and the only further call this
// will make is to close().
class JMediaDataSource : public BnDataSource {
public:
enum {
kBufferSize = 64 * 1024,
};
JMediaDataSource(JNIEnv *env, jobject source);
virtual ~JMediaDataSource();
virtual sp<IMemory> getIMemory();
virtual ssize_t readAt(off64_t offset, size_t size);
virtual status_t getSize(off64_t* size);
virtual void close();
private:
// Protect all member variables with mLock because this object will be
// accessed on different binder worker threads.
Mutex mLock;
// The status of the java DataSource. Set to OK unless an error occurred or
// close() was called.
status_t mJavaObjStatus;
// Only call the java getSize() once so the app can't change the size on us.
bool mSizeIsCached;
off64_t mCachedSize;
sp<IMemory> mMemory;
jobject mMediaDataSourceObj;
jmethodID mReadMethod;
jmethodID mGetSizeMethod;
jmethodID mCloseMethod;
jbyteArray mByteArrayObj;
DISALLOW_EVIL_CONSTRUCTORS(JMediaDataSource);
};
} // namespace android
#endif // _ANDROID_MEDIA_MEDIADATASOURCE_H_

View File

@@ -25,6 +25,7 @@
#include "android_runtime/Log.h"
#include "jni.h"
#include "JNIHelp.h"
#include "android_media_MediaDataSource.h"
#include <media/IMediaHTTPService.h>
#include <media/hardware/CryptoAPI.h>
@@ -50,74 +51,6 @@ struct fields_t {
static fields_t gFields;
class JavaDataSourceBridge : public DataSource {
jmethodID mReadMethod;
jmethodID mGetSizeMethod;
jmethodID mCloseMethod;
jobject mDataSource;
public:
JavaDataSourceBridge(JNIEnv *env, jobject source) {
mDataSource = env->NewGlobalRef(source);
jclass datasourceclass = env->GetObjectClass(mDataSource);
CHECK(datasourceclass != NULL);
mReadMethod = env->GetMethodID(datasourceclass, "readAt", "(J[BI)I");
CHECK(mReadMethod != NULL);
mGetSizeMethod = env->GetMethodID(datasourceclass, "getSize", "()J");
CHECK(mGetSizeMethod != NULL);
mCloseMethod = env->GetMethodID(datasourceclass, "close", "()V");
CHECK(mCloseMethod != NULL);
}
~JavaDataSourceBridge() {
JNIEnv *env = AndroidRuntime::getJNIEnv();
env->CallVoidMethod(mDataSource, mCloseMethod);
env->DeleteGlobalRef(mDataSource);
}
virtual status_t initCheck() const {
return OK;
}
virtual ssize_t readAt(off64_t offset, void* buffer, size_t size) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
// XXX could optimize this by reusing the same array
jbyteArray byteArrayObj = env->NewByteArray(size);
env->DeleteLocalRef(env->GetObjectClass(mDataSource));
env->DeleteLocalRef(env->GetObjectClass(byteArrayObj));
ssize_t numread = env->CallIntMethod(mDataSource, mReadMethod, offset, byteArrayObj, (jint)size);
env->GetByteArrayRegion(byteArrayObj, 0, size, (jbyte*) buffer);
env->DeleteLocalRef(byteArrayObj);
if (env->ExceptionCheck()) {
ALOGW("Exception occurred while reading %zu at %lld", size, (long long)offset);
LOGW_EX(env);
env->ExceptionClear();
return -1;
}
return numread;
}
virtual status_t getSize(off64_t *size) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
CHECK(size != NULL);
int64_t len = env->CallLongMethod(mDataSource, mGetSizeMethod);
if (len < 0) {
*size = ERROR_UNSUPPORTED;
} else {
*size = len;
}
return OK;
}
};
////////////////////////////////////////////////////////////////////////////////
JMediaExtractor::JMediaExtractor(JNIEnv *env, jobject thiz)
: mClass(NULL),
mObject(NULL) {
@@ -777,7 +710,8 @@ static void android_media_MediaExtractor_setDataSourceCallback(
return;
}
sp<JavaDataSourceBridge> bridge = new JavaDataSourceBridge(env, callbackObj);
sp<DataSource> bridge =
DataSource::CreateFromIDataSource(new JMediaDataSource(env, callbackObj));
status_t err = extractor->setDataSource(bridge);
if (err != OK) {
@@ -881,7 +815,7 @@ static JNINativeMethod gMethods[] = {
{ "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
(void *)android_media_MediaExtractor_setDataSourceFd },
{ "setDataSource", "(Landroid/media/DataSource;)V",
{ "setDataSource", "(Landroid/media/MediaDataSource;)V",
(void *)android_media_MediaExtractor_setDataSourceCallback },
{ "getCachedDuration", "()J",

View File

@@ -134,7 +134,6 @@ static jobject android_media_MediaHTTPConnection_native_getIMemory(
static jint android_media_MediaHTTPConnection_native_readAt(
JNIEnv *env, jobject thiz, jlong offset, jint size) {
sp<JMediaHTTPConnection> conn = getObject(env, thiz);
if (size > JMediaHTTPConnection::kBufferSize) {
size = JMediaHTTPConnection::kBufferSize;
}

View File

@@ -30,6 +30,7 @@
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_media_MediaDataSource.h"
#include "android_media_Utils.h"
#include "android_util_Binder.h"
@@ -171,6 +172,23 @@ static void android_media_MediaMetadataRetriever_setDataSourceFD(JNIEnv *env, jo
process_media_retriever_call(env, retriever->setDataSource(fd, offset, length), "java/lang/RuntimeException", "setDataSource failed");
}
static void android_media_MediaMetadataRetriever_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
{
ALOGV("setDataSourceCallback");
MediaMetadataRetriever* retriever = getRetriever(env, thiz);
if (retriever == 0) {
jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
return;
}
if (dataSource == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
}
sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
process_media_retriever_call(env, retriever->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed");
}
template<typename T>
static void rotate0(T* dst, const T* src, size_t width, size_t height)
{
@@ -457,6 +475,7 @@ static JNINativeMethod nativeMethods[] = {
},
{"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaMetadataRetriever_setDataSourceFD},
{"_setDataSource", "(Landroid/media/MediaDataSource;)V", (void *)android_media_MediaMetadataRetriever_setDataSourceCallback},
{"_getFrameAtTime", "(JI)Landroid/graphics/Bitmap;", (void *)android_media_MediaMetadataRetriever_getFrameAtTime},
{"extractMetadata", "(I)Ljava/lang/String;", (void *)android_media_MediaMetadataRetriever_extractMetadata},
{"getEmbeddedPicture", "(I)[B", (void *)android_media_MediaMetadataRetriever_getEmbeddedPicture},

View File

@@ -36,6 +36,7 @@
#include "utils/Errors.h" // for status_t
#include "utils/KeyedVector.h"
#include "utils/String8.h"
#include "android_media_MediaDataSource.h"
#include "android_media_Utils.h"
#include "android_os_Parcel.h"
@@ -251,6 +252,23 @@ android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fil
process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
}
static void
android_media_MediaPlayer_setDataSourceCallback(JNIEnv *env, jobject thiz, jobject dataSource)
{
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
if (mp == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
if (dataSource == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
}
sp<IDataSource> callbackDataSource = new JMediaDataSource(env, dataSource);
process_media_player_call(env, thiz, mp->setDataSource(callbackDataSource), "java/lang/RuntimeException", "setDataSourceCallback failed." );
}
static sp<IGraphicBufferProducer>
getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
IGraphicBufferProducer * const p = (IGraphicBufferProducer*)env->GetLongField(thiz, fields.surface_texture);
@@ -871,7 +889,8 @@ static JNINativeMethod gMethods[] = {
(void *)android_media_MediaPlayer_setDataSourceAndHeaders
},
{"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
{"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
{"_setDataSource", "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
{"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
{"_prepare", "()V", (void *)android_media_MediaPlayer_prepare},
{"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},