static sp<MediaPlayer> newMediaPlayer(const char *file)
{
sp<MediaPlayer> mp = new MediaPlayer();
- if (mp->setDataSource(file) == NO_ERROR) {
+ if (mp->setDataSource(file, NULL /* headers */) == NO_ERROR) {
mp->setAudioStreamType(AudioSystem::ENFORCED_AUDIBLE);
mp->prepare();
} else {
private static final int ENDED = 201;
private static final int POSTER_FETCHED = 202;
+ private static final String COOKIE = "Cookie";
+
// Timer thread -> UI thread
private static final int TIMEUPDATE = 300;
mVideoView = new VideoView(proxy.getContext());
mVideoView.setWillNotDraw(false);
mVideoView.setMediaController(new MediaController(proxy.getContext()));
- mVideoView.setVideoURI(Uri.parse(url));
+
+ String cookieValue = CookieManager.getInstance().getCookie(url);
+ Map<String, String> headers = null;
+ if (cookieValue != null) {
+ headers = new HashMap<String, String>();
+ headers.put(COOKIE, cookieValue);
+ }
+
+ mVideoView.setVideoURI(Uri.parse(url), headers);
mVideoView.setOnCompletionListener(proxy);
mVideoView.setOnPreparedListener(proxy);
mVideoView.setOnErrorListener(proxy);
import android.widget.MediaController.*;
import java.io.IOException;
+import java.util.Map;
/**
* Displays a video file. The VideoView class
private String TAG = "VideoView";
// settable by the client
private Uri mUri;
+ private Map<String, String> mHeaders;
private int mDuration;
// all possible internal states
super(context);
initVideoView();
}
-
+
public VideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
initVideoView();
}
-
+
public VideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initVideoView();
//Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height);
setMeasuredDimension(width, height);
}
-
+
public int resolveAdjustedSize(int desiredSize, int measureSpec) {
int result = desiredSize;
int specMode = MeasureSpec.getMode(measureSpec);
break;
case MeasureSpec.AT_MOST:
- /* Parent says we can be as big as we want, up to specSize.
- * Don't be larger than specSize, and don't be larger than
+ /* Parent says we can be as big as we want, up to specSize.
+ * Don't be larger than specSize, and don't be larger than
* the max size imposed on ourselves.
*/
result = Math.min(desiredSize, specSize);
break;
-
+
case MeasureSpec.EXACTLY:
// No choice. Do what we are told.
result = specSize;
}
return result;
}
-
+
private void initVideoView() {
mVideoWidth = 0;
mVideoHeight = 0;
}
public void setVideoURI(Uri uri) {
+ setVideoURI(uri, null);
+ }
+
+ /**
+ * @hide
+ */
+ public void setVideoURI(Uri uri, Map<String, String> headers) {
mUri = uri;
+ mHeaders = headers;
mSeekWhenPrepared = 0;
openVideo();
requestLayout();
invalidate();
}
-
+
public void stopPlayback() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
// not ready for playback just yet, will try again later
return;
}
- // Tell the music playback service to pause
+ // Tell the music playback service to pause
// TODO: these constants need to be published somewhere in the framework.
Intent i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause");
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mCurrentBufferPercentage = 0;
- mMediaPlayer.setDataSource(mContext, mUri);
+ mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
return;
}
}
-
+
public void setMediaController(MediaController controller) {
if (mMediaController != null) {
mMediaController.hide();
mMediaController.setEnabled(isInPlaybackState());
}
}
-
+
MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
new MediaPlayer.OnVideoSizeChangedListener() {
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
}
}
};
-
+
MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mCurrentState = STATE_PREPARED;
}
return false;
}
-
+
@Override
public boolean onTrackballEvent(MotionEvent ev) {
if (isInPlaybackState() && mMediaController != null) {
}
return false;
}
-
+
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
mMediaController.hide();
}
return true;
- } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
+ } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
&& mMediaPlayer.isPlaying()) {
pause();
mMediaController.show();
}
private void toggleMediaControlsVisiblity() {
- if (mMediaController.isShowing()) {
+ if (mMediaController.isShowing()) {
mMediaController.hide();
} else {
mMediaController.show();
}
}
-
+
public void start() {
if (isInPlaybackState()) {
mMediaPlayer.start();
}
mTargetState = STATE_PLAYING;
}
-
+
public void pause() {
if (isInPlaybackState()) {
if (mMediaPlayer.isPlaying()) {
}
mTargetState = STATE_PAUSED;
}
-
+
// cache duration as mDuration for faster access
public int getDuration() {
if (isInPlaybackState()) {
mDuration = -1;
return mDuration;
}
-
+
public int getCurrentPosition() {
if (isInPlaybackState()) {
return mMediaPlayer.getCurrentPosition();
}
return 0;
}
-
+
public void seekTo(int msec) {
if (isInPlaybackState()) {
mMediaPlayer.seekTo(msec);
} else {
mSeekWhenPrepared = msec;
}
- }
-
+ }
+
public boolean isPlaying() {
return isInPlaybackState() && mMediaPlayer.isPlaying();
}
-
+
public int getBufferPercentage() {
if (mMediaPlayer != null) {
return mCurrentBufferPercentage;
#define ANDROID_IMEDIAPLAYERSERVICE_H
#include <utils/Errors.h> // for status_t
+#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
+#include <utils/String8.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;
virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) = 0;
+ virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, const KeyedVector<String8, String8> *headers = NULL) = 0;
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
#include <sys/types.h>
#include <ui/ISurface.h>
-#include <utils/RefBase.h>
#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/RefBase.h>
#include <media/mediaplayer.h>
#include <media/AudioSystem.h>
virtual ~MediaPlayerBase() {}
virtual status_t initCheck() = 0;
virtual bool hardwareOutput() = 0;
- 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 status_t setVideoSurface(const sp<ISurface>& surface) = 0;
virtual status_t prepare() = 0;
virtual ~PVPlayer();
virtual status_t initCheck();
- 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 status_t setVideoSurface(const sp<ISurface>& surface);
virtual status_t prepare();
#include <media/IMediaPlayer.h>
#include <media/IMediaDeathNotifier.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
namespace android {
enum media_event_type {
~MediaPlayer();
void died();
void disconnect();
- status_t setDataSource(const char *url);
+
+ status_t setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers);
+
status_t setDataSource(int fd, int64_t offset, int64_t length);
status_t setVideoSurface(const sp<Surface>& surface);
status_t setListener(const sp<MediaPlayerListener>& listener);
import java.io.FileDescriptor;
import java.io.IOException;
+import java.util.Map;
import java.util.Set;
import java.lang.ref.WeakReference;
*/
public void setDataSource(Context context, Uri uri)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+ setDataSource(context, uri, null);
+ }
+
+ /**
+ * Sets the data source as a content Uri.
+ *
+ * @param context the Context to use when resolving the Uri
+ * @param uri the Content URI of the data you want to play
+ * @param headers the headers to be sent together with the request for the data
+ * @throws IllegalStateException if it is called in an invalid state
+ * @hide pending API council
+ */
+ public void setDataSource(Context context, Uri uri, Map<String, String> headers)
+ throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
String scheme = uri.getScheme();
if(scheme == null || scheme.equals("file")) {
}
}
Log.d(TAG, "Couldn't open file on client side, trying server side");
- setDataSource(uri.toString());
+ setDataSource(uri.toString(), headers);
return;
}
public native void setDataSource(String path) throws IOException, IllegalArgumentException, IllegalStateException;
/**
+ * Sets the data source (file-path or http/rtsp URL) to use.
+ *
+ * @param path the path of the file, or the http/rtsp URL of the stream you want to play
+ * @param headers the headers associated with the http request for the stream you want to play
+ * @throws IllegalStateException if it is called in an invalid state
+ * @hide pending API council
+ */
+ public native void setDataSource(String path, Map<String, String> headers)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
* 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 as this call returns.
*
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "utils/Errors.h" // for status_t
+#include "utils/KeyedVector.h"
+#include "utils/String8.h"
#include "android_util_Binder.h"
#include <binder/Parcel.h>
}
static void
-android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path)
-{
+android_media_MediaPlayer_setDataSourceAndHeaders(
+ JNIEnv *env, jobject thiz, jstring path, jobject headers) {
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
if (mp == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
return;
}
+
+ // 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
+ jniThrowException(
+ env, "java/lang/RuntimeException", "Out of memory");
+ return;
+ }
+
+ const char* valueStr = env->GetStringUTFChars(value, NULL);
+ if (!valueStr) { // Out of memory
+ jniThrowException(
+ env, "java/lang/RuntimeException", "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);
+ }
+
LOGV("setDataSource: path %s", pathStr);
- status_t opStatus = mp->setDataSource(pathStr);
+ status_t opStatus =
+ mp->setDataSource(
+ String8(pathStr),
+ headers ? &headersVector : NULL);
// Make sure that local ref is released before a potential exception
env->ReleaseStringUTFChars(path, pathStr);
- process_media_player_call( env, thiz, opStatus, "java/io/IOException", "setDataSource failed." );
+
+ process_media_player_call(
+ env, thiz, opStatus, "java/io/IOException",
+ "setDataSource failed." );
+}
+
+static void
+android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path)
+{
+ android_media_MediaPlayer_setDataSourceAndHeaders(env, thiz, path, 0);
}
static void
static JNINativeMethod gMethods[] = {
{"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaPlayer_setDataSource},
+ {"setDataSource", "(Ljava/lang/String;Ljava/util/Map;)V",(void *)android_media_MediaPlayer_setDataSourceAndHeaders},
{"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
{"_setVideoSurface", "()V", (void *)android_media_MediaPlayer_setVideoSurface},
{"prepare", "()V", (void *)android_media_MediaPlayer_prepare},
return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
}
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url)
- {
+ virtual sp<IMediaPlayer> create(
+ pid_t pid, const sp<IMediaPlayerClient>& client,
+ const char* url, const KeyedVector<String8, String8> *headers) {
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
data.writeInt32(pid);
data.writeStrongBinder(client->asBinder());
data.writeCString(url);
+
+ 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(CREATE_URL, data, &reply);
return interface_cast<IMediaPlayer>(reply.readStrongBinder());
}
case CREATE_URL: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
pid_t pid = data.readInt32();
- sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
+ sp<IMediaPlayerClient> client =
+ interface_cast<IMediaPlayerClient>(data.readStrongBinder());
const char* url = data.readCString();
- sp<IMediaPlayer> player = create(pid, client, url);
+
+ 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);
+ }
+
+ sp<IMediaPlayer> player = create(
+ pid, client, url, numHeaders > 0 ? &headers : NULL);
+
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
} break;
#include <binder/MemoryBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
namespace android {
MediaPlayer::MediaPlayer()
return err;
}
-status_t MediaPlayer::setDataSource(const char *url)
+status_t MediaPlayer::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers)
{
LOGV("setDataSource(%s)", url);
status_t err = BAD_VALUE;
if (url != NULL) {
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
- sp<IMediaPlayer> player(service->create(getpid(), this, url));
+ sp<IMediaPlayer> player(
+ service->create(getpid(), this, url, headers));
err = setDataSource(player);
}
}
return retriever;
}
-sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url)
+sp<IMediaPlayer> MediaPlayerService::create(
+ pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
+ const KeyedVector<String8, String8> *headers)
{
int32_t connId = android_atomic_inc(&mNextConnId);
sp<Client> c = new Client(this, pid, connId, client);
LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);
- if (NO_ERROR != c->setDataSource(url))
+ if (NO_ERROR != c->setDataSource(url, headers))
{
c.clear();
return c;
return p;
}
-status_t MediaPlayerService::Client::setDataSource(const char *url)
+status_t MediaPlayerService::Client::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers)
{
LOGV("setDataSource(%s)", url);
if (url == NULL)
// now set data source
LOGV(" setDataSource");
- mStatus = p->setDataSource(url);
+ mStatus = p->setDataSource(url, headers);
if (mStatus == NO_ERROR) {
mPlayer = p;
} else {
#include <utils/List.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
+#include <utils/String8.h>
#include <utils/Vector.h>
#include <ui/SurfaceComposerClient.h>
virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid);
// House keeping for media player clients
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url);
+ virtual sp<IMediaPlayer> create(
+ pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
+ const KeyedVector<String8, String8> *headers);
+
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length);
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
Parcel *reply);
sp<MediaPlayerBase> createPlayer(player_type playerType);
- status_t setDataSource(const char *url);
+
+ status_t setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers);
+
status_t setDataSource(int fd, int64_t offset, int64_t length);
static void notify(void* cookie, int msg, int ext1, int ext2);
release();
}
-status_t MidiFile::setDataSource(const char* path)
-{
+status_t MidiFile::setDataSource(
+ const char* path, const KeyedVector<String8, String8> *) {
LOGV("MidiFile::setDataSource url=%s", path);
Mutex::Autolock lock(mMutex);
~MidiFile();
virtual status_t initCheck();
- virtual status_t setDataSource(const char* path);
+
+ virtual status_t setDataSource(
+ const char* path, const KeyedVector<String8, String8> *headers);
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setVideoSurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; }
virtual status_t prepare();
if (mMidiPlayer == 0) {
mMidiPlayer = new MidiFile();
}
- return mMidiPlayer->setDataSource(url);
+ // TODO: support headers in MetadataRetriever interface!
+ return mMidiPlayer->setDataSource(url, NULL /* headers */);
}
status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
return OK;
}
-status_t StagefrightPlayer::setDataSource(const char *url) {
- LOGV("setDataSource('%s')", url);
+status_t StagefrightPlayer::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *) {
+ LOGI("setDataSource('%s')", url);
return mPlayer->setDataSource(url);
}
virtual ~StagefrightPlayer();
virtual status_t initCheck();
- 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 status_t setVideoSurface(const sp<ISurface> &surface);
virtual status_t prepare();
// Load the dynamic library.
// Create the test player.
// Call setDataSource on the test player with the url in param.
-status_t TestPlayerStub::setDataSource(const char *url)
-{
+status_t TestPlayerStub::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers) {
if (!isTestUrl(url) || NULL != mHandle) {
return INVALID_OPERATION;
}
}
mPlayer = (*mNewPlayer)();
- return mPlayer->setDataSource(mContentUrl);
+ return mPlayer->setDataSource(mContentUrl, headers);
}
// Internal cleanup.
virtual status_t initCheck();
// @param url Should be a test url. See class comment.
- virtual status_t setDataSource(const char* url);
+ virtual status_t setDataSource(
+ const char* url, const KeyedVector<String8, String8> *headers);
// Test player for a file descriptor source is not supported.
virtual status_t setDataSource(int, int64_t, int64_t) {
if (mVorbisPlayer == 0) {
mVorbisPlayer = new VorbisPlayer();
}
- return mVorbisPlayer->setDataSource(url);
+ // TODO: support headers in MetadataRetriever interface!
+ return mVorbisPlayer->setDataSource(url, NULL /* headers */);
}
status_t VorbisMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
release();
}
-status_t VorbisPlayer::setDataSource(const char* path)
-{
- return setdatasource(path, -1, 0, 0x7ffffffffffffffLL); // intentionally less than LONG_MAX
+status_t VorbisPlayer::setDataSource(
+ const char *uri, const KeyedVector<String8, String8> *headers) {
+ return setdatasource(uri, -1, 0, 0x7ffffffffffffffLL); // intentionally less than LONG_MAX
}
status_t VorbisPlayer::setDataSource(int fd, int64_t offset, int64_t length)
virtual void onFirstRef();
virtual status_t initCheck();
- virtual status_t setDataSource(const char* path);
+
+ virtual status_t setDataSource(
+ const char *uri, const KeyedVector<String8, String8> *headers);
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setVideoSurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; }
virtual status_t prepare();
using android::player_type;
using android::sp;
using android::status_t;
+using android::String8;
+using android::KeyedVector;
// This file contains a test player that is loaded via the
// TestPlayerStub class. The player contains various implementation
virtual status_t initCheck() {return OK;}
virtual bool hardwareOutput() {return true;}
- virtual status_t setDataSource(const char *url) {
+ virtual status_t setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *) {
LOGV("setDataSource %s", url);
mTest = TEST_UNKNOWN;
if (strncmp(url, kPing, strlen(kPing)) == 0) {