MediaPlayer2: use DataSource to replace IDataSource.
Also fix deadlock by always posting notification to NuPlayer2Driver's
looper.
Test: MediaPlayer2 can play callback source.
Bug: 63934228
Change-Id: Ie27bc0038bcc07ffef5c610662db3fcb5df7aec4
diff --git a/media/libmedia/MediaPlayer2Manager.cpp b/media/libmedia/MediaPlayer2Manager.cpp
index c6ad99e..720c1e3 100644
--- a/media/libmedia/MediaPlayer2Manager.cpp
+++ b/media/libmedia/MediaPlayer2Manager.cpp
@@ -726,15 +726,14 @@
}
status_t MediaPlayer2Manager::Client::setDataSource(
- const sp<IDataSource> &source) {
- sp<DataSource> dataSource = CreateDataSourceFromIDataSource(source);
- player2_type playerType = MediaPlayer2Factory::getPlayerType(this, dataSource);
+ const sp<DataSource> &source) {
+ player2_type playerType = MediaPlayer2Factory::getPlayerType(this, source);
sp<MediaPlayer2Base> p = setDataSource_pre(playerType);
if (p == NULL) {
return NO_INIT;
}
// now set data source
- return mStatus = setDataSource_post(p, p->setDataSource(dataSource));
+ return mStatus = setDataSource_post(p, p->setDataSource(source));
}
void MediaPlayer2Manager::Client::disconnectNativeWindow_l() {
diff --git a/media/libmedia/MediaPlayer2Manager.h b/media/libmedia/MediaPlayer2Manager.h
index d3ee044..b42cbbb 100644
--- a/media/libmedia/MediaPlayer2Manager.h
+++ b/media/libmedia/MediaPlayer2Manager.h
@@ -39,7 +39,7 @@
struct AudioPlaybackRate;
class AudioTrack;
struct AVSyncSettings;
-class IDataSource;
+class DataSource;
struct MediaHTTPService;
class MediaPlayer2EngineClient;
@@ -297,7 +297,7 @@
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setDataSource(const sp<IStreamSource> &source);
- virtual status_t setDataSource(const sp<IDataSource> &source);
+ virtual status_t setDataSource(const sp<DataSource> &source);
sp<MediaPlayer2Base> setDataSource_pre(player2_type playerType);
diff --git a/media/libmedia/include/media/MediaPlayer2Engine.h b/media/libmedia/include/media/MediaPlayer2Engine.h
index 0b43923..00f5fb1 100644
--- a/media/libmedia/include/media/MediaPlayer2Engine.h
+++ b/media/libmedia/include/media/MediaPlayer2Engine.h
@@ -32,13 +32,13 @@
namespace android {
struct ANativeWindowWrapper;
-class Parcel;
-class IDataSource;
+struct AVSyncSettings;
+struct AudioPlaybackRate;
+struct BufferingSettings;
+class DataSource;
struct IStreamSource;
struct MediaHTTPService;
-struct AudioPlaybackRate;
-struct AVSyncSettings;
-struct BufferingSettings;
+class Parcel;
typedef MediaSource::ReadOptions::SeekMode MediaPlayer2SeekMode;
@@ -54,7 +54,7 @@
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
virtual status_t setDataSource(const sp<IStreamSource>& source) = 0;
- virtual status_t setDataSource(const sp<IDataSource>& source) = 0;
+ virtual status_t setDataSource(const sp<DataSource>& source) = 0;
virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) = 0;
virtual status_t getBufferingSettings(
BufferingSettings* buffering /* nonnull */) = 0;
diff --git a/media/libmedia/include/media/mediaplayer2.h b/media/libmedia/include/media/mediaplayer2.h
index 8327043..c96765f 100644
--- a/media/libmedia/include/media/mediaplayer2.h
+++ b/media/libmedia/include/media/mediaplayer2.h
@@ -35,6 +35,8 @@
struct AVSyncSettings;
struct ANativeWindowWrapper;
+class DataSource;
+struct MediaHTTPService;
enum media2_event_type {
MEDIA2_NOP = 0, // interface test message
@@ -193,8 +195,6 @@
virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
};
-struct MediaHTTPService;
-
class MediaPlayer2 : public MediaPlayer2EngineClient
{
public:
@@ -208,7 +208,7 @@
const KeyedVector<String8, String8> *headers);
status_t setDataSource(int fd, int64_t offset, int64_t length);
- status_t setDataSource(const sp<IDataSource> &source);
+ status_t setDataSource(const sp<DataSource> &source);
status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww);
status_t setListener(const sp<MediaPlayer2Listener>& listener);
status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */);
diff --git a/media/libmedia/mediaplayer2.cpp b/media/libmedia/mediaplayer2.cpp
index 5a52abf..5c34d4a 100644
--- a/media/libmedia/mediaplayer2.cpp
+++ b/media/libmedia/mediaplayer2.cpp
@@ -33,7 +33,7 @@
#include <media/AudioResamplerPublic.h>
#include <media/AudioSystem.h>
#include <media/AVSyncSettings.h>
-#include <media/IDataSource.h>
+#include <media/DataSource.h>
#include <media/MediaAnalyticsItem.h>
#include <media/NdkWrapper.h>
@@ -183,9 +183,9 @@
return err;
}
-status_t MediaPlayer2::setDataSource(const sp<IDataSource> &source)
+status_t MediaPlayer2::setDataSource(const sp<DataSource> &source)
{
- ALOGV("setDataSource(IDataSource)");
+ ALOGV("setDataSource(DataSource)");
status_t err = UNKNOWN_ERROR;
sp<MediaPlayer2Engine> player(MediaPlayer2Manager::get().create(this, mAudioSessionId));
if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
diff --git a/media/libmedia/nuplayer2/GenericSource.cpp b/media/libmedia/nuplayer2/GenericSource.cpp
index f8bc4f1..acd54a1 100644
--- a/media/libmedia/nuplayer2/GenericSource.cpp
+++ b/media/libmedia/nuplayer2/GenericSource.cpp
@@ -364,7 +364,9 @@
if (mLooper == NULL) {
mLooper = new ALooper;
mLooper->setName("generic");
- mLooper->start();
+ mLooper->start(false, /* runOnCallingThread */
+ true, /* canCallJava */
+ PRIORITY_DEFAULT);
mLooper->registerHandler(this);
}
diff --git a/media/libmedia/nuplayer2/NuPlayer2Driver.cpp b/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
index c4e42e7..629a7eb 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmedia/nuplayer2/NuPlayer2Driver.cpp
@@ -40,6 +40,42 @@
namespace android {
+struct ParcelWrapper : public RefBase {
+ static sp<ParcelWrapper> Create(const Parcel *p) {
+ if (p != NULL) {
+ sp<ParcelWrapper> pw = new ParcelWrapper();
+ if (pw->appendFrom(p) == OK) {
+ return pw;
+ }
+ }
+ return NULL;
+ }
+
+ const Parcel *getParcel() {
+ return mParcel;
+ }
+
+protected:
+ virtual ~ParcelWrapper() {
+ if (mParcel != NULL) {
+ delete mParcel;
+ }
+ }
+
+private:
+ ParcelWrapper()
+ : mParcel(NULL) { }
+
+ status_t appendFrom(const Parcel *p) {
+ if (mParcel == NULL) {
+ mParcel = new Parcel;
+ }
+ return mParcel->appendFrom(p, 0 /* start */, p->dataSize());
+ }
+
+ Parcel *mParcel;
+};
+
// key for media statistics
static const char *kKeyPlayer = "nuplayer2";
// attrs for media statistics
@@ -390,7 +426,7 @@
case STATE_PAUSED:
mState = STATE_STOPPED;
- sendNotifyOnLooper(MEDIA2_STOPPED);
+ notifyListener_l(MEDIA2_STOPPED);
break;
case STATE_PREPARED:
@@ -425,7 +461,7 @@
case STATE_RUNNING:
mState = STATE_PAUSED;
- sendNotifyOnLooper(MEDIA2_PAUSED);
+ notifyListener_l(MEDIA2_PAUSED);
mPlayer->pause();
break;
@@ -449,7 +485,7 @@
Mutex::Autolock autoLock(mLock);
if (rate.mSpeed == 0.f && mState == STATE_RUNNING) {
mState = STATE_PAUSED;
- sendNotifyOnLooper(MEDIA2_PAUSED);
+ notifyListener_l(MEDIA2_PAUSED);
} else if (rate.mSpeed != 0.f
&& (mState == STATE_PAUSED
|| mState == STATE_STOPPED_AND_PREPARED
@@ -487,7 +523,7 @@
mAtEOS = false;
mSeekInProgress = true;
// seeks can take a while, so we essentially paused
- sendNotifyOnLooper(MEDIA2_PAUSED);
+ notifyListener_l(MEDIA2_PAUSED);
mPlayer->seekToAsync(seekTimeUs, mode, true /* needNotify */);
break;
}
@@ -660,7 +696,7 @@
{
CHECK(mIsAsyncPrepare);
- sendNotifyOnLooper(MEDIA2_PREPARED);
+ notifyListener_l(MEDIA2_PREPARED);
break;
}
@@ -669,7 +705,7 @@
}
if (mState != STATE_STOPPED) {
- sendNotifyOnLooper(MEDIA2_STOPPED);
+ notifyListener_l(MEDIA2_STOPPED);
}
mState = STATE_RESET_IN_PROGRESS;
@@ -952,8 +988,17 @@
switch (msg->what()) {
case kWhatNotifyListener: {
int32_t msgId;
+ int32_t ext1 = 0;
+ int32_t ext2 = 0;
CHECK(msg->findInt32("messageId", &msgId));
- notifyListener(msgId);
+ msg->findInt32("ext1", &ext1);
+ msg->findInt32("ext2", &ext2);
+ sp<ParcelWrapper> in;
+ sp<RefBase> obj;
+ if (msg->findObject("parcel", &obj) && obj != NULL) {
+ in = static_cast<ParcelWrapper *>(obj.get());
+ }
+ sendEvent(msgId, ext1, ext2, (in == NULL ? NULL : in->getParcel()));
break;
}
default:
@@ -1025,15 +1070,12 @@
break;
}
- mLock.unlock();
- sendEvent(msg, ext1, ext2, in);
- mLock.lock();
-}
-
-void NuPlayer2Driver::sendNotifyOnLooper(int msgId) {
- sp<AMessage> msg = new AMessage(kWhatNotifyListener, this);
- msg->setInt32("messageId", msgId);
- msg->post();
+ sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
+ notify->setInt32("messageId", msg);
+ notify->setInt32("ext1", ext1);
+ notify->setInt32("ext2", ext2);
+ notify->setObject("parcel", ParcelWrapper::Create(in));
+ notify->post();
}
void NuPlayer2Driver::notifySetDataSourceCompleted(status_t err) {
diff --git a/media/libmedia/nuplayer2/NuPlayer2Driver.h b/media/libmedia/nuplayer2/NuPlayer2Driver.h
index 4451349..d393f9d 100644
--- a/media/libmedia/nuplayer2/NuPlayer2Driver.h
+++ b/media/libmedia/nuplayer2/NuPlayer2Driver.h
@@ -160,7 +160,6 @@
status_t prepare_l();
status_t start_l();
void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
- void sendNotifyOnLooper(int msgId);
DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2Driver);
};