MediaPlayer2: support start position of data source
Test: cts
Bug: 112549021
Change-Id: I4062fab27aff101223cfb3924841c8e7c3afa6ce
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 74ccf56..3b155c5 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -403,6 +403,15 @@
if (dsd == NULL) {
return BAD_VALUE;
}
+ // Microsecond is used in NuPlayer2.
+ if (dsd->mStartPositionMs > INT64_MAX / 1000) {
+ dsd->mStartPositionMs = INT64_MAX / 1000;
+ ALOGW("setDataSource, start poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
+ }
+ if (dsd->mEndPositionMs > INT64_MAX / 1000) {
+ dsd->mEndPositionMs = INT64_MAX / 1000;
+ ALOGW("setDataSource, end poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
+ }
ALOGV("setDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
sp<MediaPlayer2Interface> oldPlayer;
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
index 4ce1a88..bf76e3a 100644
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
@@ -335,7 +335,7 @@
resetDataSource();
}
-void NuPlayer2::GenericSource2::prepareAsync() {
+void NuPlayer2::GenericSource2::prepareAsync(int64_t startTimeUs) {
Mutex::Autolock _l(mLock);
ALOGV("prepareAsync: (looper: %d)", (mLooper != NULL));
@@ -350,10 +350,12 @@
}
sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
+ msg->setInt64("startTimeUs", startTimeUs);
+
msg->post();
}
-void NuPlayer2::GenericSource2::onPrepareAsync() {
+void NuPlayer2::GenericSource2::onPrepareAsync(int64_t startTimeUs) {
ALOGV("onPrepareAsync: mDataSource: %d", (mDataSource != NULL));
// delayed data source creation
@@ -429,6 +431,7 @@
FLAG_CAN_SEEK_FORWARD |
FLAG_CAN_SEEK);
+ doSeek(startTimeUs, MediaPlayer2SeekMode::SEEK_CLOSEST);
finishPrepareAsync();
ALOGV("onPrepareAsync: Done");
@@ -440,6 +443,7 @@
if (mIsStreaming) {
mCachedSource->resumeFetchingIfNecessary();
mPreparing = true;
+ ++mPollBufferingGeneration;
schedulePollBuffering();
} else {
notifyPrepared();
@@ -544,7 +548,9 @@
switch (msg->what()) {
case kWhatPrepareAsync:
{
- onPrepareAsync();
+ int64_t startTimeUs;
+ CHECK(msg->findInt64("startTimeUs", &startTimeUs));
+ onPrepareAsync(startTimeUs);
break;
}
case kWhatFetchSubtitleData:
@@ -1443,10 +1449,12 @@
}
void NuPlayer2::GenericSource2::schedulePollBuffering() {
- sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
- msg->setInt32("generation", mPollBufferingGeneration);
- // Enquires buffering status every second.
- msg->post(1000000ll);
+ if (mIsStreaming) {
+ sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
+ msg->setInt32("generation", mPollBufferingGeneration);
+ // Enquires buffering status every second.
+ msg->post(1000000ll);
+ }
}
void NuPlayer2::GenericSource2::onPollBuffering() {
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.h b/media/libmediaplayer2/nuplayer2/GenericSource2.h
index 9bc5182..3cac809 100644
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.h
+++ b/media/libmediaplayer2/nuplayer2/GenericSource2.h
@@ -62,7 +62,7 @@
BufferingSettings* buffering /* nonnull */) override;
virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
- virtual void prepareAsync();
+ virtual void prepareAsync(int64_t startTimeUs);
virtual void start();
virtual void stop();
@@ -194,7 +194,7 @@
void onSeek(const sp<AMessage>& msg);
status_t doSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode);
- void onPrepareAsync();
+ void onPrepareAsync(int64_t startTimeUs);
void fetchTextData(
uint32_t what, media_track_type type,
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
index a61cacd..175be53 100644
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
@@ -99,7 +99,8 @@
return OK;
}
-void NuPlayer2::HTTPLiveSource2::prepareAsync() {
+// TODO: fetch data starting from |startTimeUs|
+void NuPlayer2::HTTPLiveSource2::prepareAsync(int64_t /* startTimeUs */) {
if (mLiveLooper == NULL) {
mLiveLooper = new ALooper;
mLiveLooper->setName("http live");
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
index 97d3653..8fc71e2 100644
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
+++ b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
@@ -38,7 +38,7 @@
BufferingSettings* buffering /* nonnull */) override;
virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
- virtual void prepareAsync();
+ virtual void prepareAsync(int64_t startTimeUs);
virtual void start();
virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
index 5bd1674..83a10bf 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
@@ -212,7 +212,6 @@
: mPID(pid),
mUID(uid),
mMediaClock(mediaClock),
- mSourceFlags(0),
mOffloadAudio(false),
mAudioDecoderGeneration(0),
mVideoDecoderGeneration(0),
@@ -240,8 +239,7 @@
mPaused(false),
mPausedByClient(true),
mPausedForBuffering(false),
- mIsDrmProtected(false),
- mDataSourceType(DATA_SOURCE_TYPE_NONE) {
+ mIsDrmProtected(false) {
CHECK(mediaClock != NULL);
clearFlushComplete();
}
@@ -393,11 +391,13 @@
// Now, source != NULL.
*/
- mDataSourceType = dataSourceType;
+ mCurrentSourceInfo.mDataSourceType = dataSourceType;
sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
msg->setObject("source", source);
msg->setInt64("srcId", dsd->mId);
+ msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
+ msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
msg->post();
}
@@ -415,11 +415,13 @@
// Now, source != NULL.
*/
- mNextDataSourceType = dataSourceType;
+ mNextSourceInfo.mDataSourceType = dataSourceType;
sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
msg->setObject("source", source);
msg->setInt64("srcId", dsd->mId);
+ msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
+ msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
msg->post();
}
@@ -554,7 +556,7 @@
sp<Source> source;
{
Mutex::Autolock autoLock(mSourceLock);
- source = mSource;
+ source = mCurrentSourceInfo.mSource;
}
if (source != NULL) {
@@ -640,15 +642,17 @@
{
ALOGV("kWhatSetDataSource");
- CHECK(mSource == NULL);
+ CHECK(mCurrentSourceInfo.mSource == NULL);
status_t err = OK;
sp<RefBase> obj;
CHECK(msg->findObject("source", &obj));
if (obj != NULL) {
Mutex::Autolock autoLock(mSourceLock);
- CHECK(msg->findInt64("srcId", &mSrcId));
- mSource = static_cast<Source *>(obj.get());
+ CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
+ CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
+ CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
+ mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
} else {
err = UNKNOWN_ERROR;
ALOGE("kWhatSetDataSource, source should not be NULL");
@@ -657,7 +661,7 @@
CHECK(mDriver != NULL);
sp<NuPlayer2Driver> driver = mDriver.promote();
if (driver != NULL) {
- driver->notifySetDataSourceCompleted(mSrcId, err);
+ driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
}
break;
}
@@ -671,9 +675,11 @@
CHECK(msg->findObject("source", &obj));
if (obj != NULL) {
Mutex::Autolock autoLock(mSourceLock);
- CHECK(msg->findInt64("srcId", &mNextSrcId));
- mNextSource = static_cast<Source *>(obj.get());
- mNextSource->prepareAsync();
+ CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
+ CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
+ CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
+ mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
+ mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
} else {
err = UNKNOWN_ERROR;
}
@@ -686,7 +692,7 @@
ALOGV("kWhatPlayNextDataSource");
int64_t srcId;
CHECK(msg->findInt64("srcId", &srcId));
- if (srcId != mNextSrcId) {
+ if (srcId != mNextSourceInfo.mSrcId) {
notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
return;
}
@@ -715,8 +721,8 @@
ALOGV("kWhatGetBufferingSettings");
BufferingSettings buffering;
status_t err = OK;
- if (mSource != NULL) {
- err = mSource->getBufferingSettings(&buffering);
+ if (mCurrentSourceInfo.mSource != NULL) {
+ err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
} else {
err = INVALID_OPERATION;
}
@@ -738,8 +744,8 @@
BufferingSettings buffering;
readFromAMessage(msg, &buffering);
status_t err = OK;
- if (mSource != NULL) {
- err = mSource->setBufferingSettings(buffering);
+ if (mCurrentSourceInfo.mSource != NULL) {
+ err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
} else {
err = INVALID_OPERATION;
}
@@ -753,7 +759,7 @@
{
ALOGV("onMessageReceived kWhatPrepare");
- mSource->prepareAsync();
+ mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
break;
}
@@ -766,8 +772,8 @@
CHECK(msg->findPointer("reply", (void**)&reply));
size_t inbandTracks = 0;
- if (mSource != NULL) {
- inbandTracks = mSource->getTrackCount();
+ if (mCurrentSourceInfo.mSource != NULL) {
+ inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
}
size_t ccTracks = 0;
@@ -780,7 +786,7 @@
// write inband tracks
for (size_t i = 0; i < inbandTracks; ++i) {
- writeTrackInfo(reply, mSource->getTrackInfo(i));
+ writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
}
// write CC track
@@ -796,13 +802,13 @@
case kWhatGetSelectedTrack:
{
status_t err = INVALID_OPERATION;
- if (mSource != NULL) {
+ if (mCurrentSourceInfo.mSource != NULL) {
err = OK;
int32_t type32;
CHECK(msg->findInt32("type", (int32_t*)&type32));
media_track_type type = (media_track_type)type32;
- ssize_t selectedTrack = mSource->getSelectedTrack(type);
+ ssize_t selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
PlayerMessage* reply;
CHECK(msg->findPointer("reply", (void**)&reply));
@@ -833,8 +839,8 @@
status_t err = INVALID_OPERATION;
size_t inbandTracks = 0;
- if (mSource != NULL) {
- inbandTracks = mSource->getTrackCount();
+ if (mCurrentSourceInfo.mSource != NULL) {
+ inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
}
size_t ccTracks = 0;
if (mCCDecoder != NULL) {
@@ -842,11 +848,11 @@
}
if (trackIndex < inbandTracks) {
- err = mSource->selectTrack(trackIndex, select, timeUs);
+ err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
if (!select && err == OK) {
int32_t type;
- sp<AMessage> info = mSource->getTrackInfo(trackIndex);
+ sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
if (info != NULL
&& info->findInt32("type", &type)
&& type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
@@ -879,10 +885,10 @@
}
int64_t durationUs;
- if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
+ if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
sp<NuPlayer2Driver> driver = mDriver.promote();
if (driver != NULL) {
- driver->notifyDuration(mSrcId, durationUs);
+ driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
}
}
@@ -899,13 +905,15 @@
ALOGD("onSetVideoSurface(%p, %s video decoder)",
(nww == NULL ? NULL : nww->getANativeWindow()),
- (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL
+ (mCurrentSourceInfo.mSource != NULL && mStarted
+ && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
&& mVideoDecoder != NULL) ? "have" : "no");
- // Need to check mStarted before calling mSource->getFormat because NuPlayer2 might
- // be in preparing state and it could take long time.
- // When mStarted is true, mSource must have been set.
- if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL
+ // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
+ // because NuPlayer2 might be in preparing state and it could take long time.
+ // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
+ if (mCurrentSourceInfo.mSource == NULL || !mStarted
+ || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
// NOTE: mVideoDecoder's mNativeWindow is always non-null
|| (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
performSetSurface(nww);
@@ -972,7 +980,7 @@
onStart(true /* play */);
}
mPausedByClient = false;
- notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
break;
}
@@ -1130,21 +1138,22 @@
&& (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
// This is the first time we've found anything playable.
- if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
+ if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
schedulePollDuration();
}
}
status_t err;
- if ((err = mSource->feedMoreTSData()) != OK) {
+ if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
// We're not currently decoding anything (no audio or
// video tracks found) and we just ran out of input data.
if (err == ERROR_END_OF_STREAM) {
- notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
} else {
- notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+ notifyListener(
+ mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
}
}
break;
@@ -1226,10 +1235,10 @@
CHECK(msg->findMessage("format", &format));
sp<AMessage> inputFormat =
- mSource->getFormat(false /* audio */);
+ mCurrentSourceInfo.mSource->getFormat(false /* audio */);
setVideoScalingMode(mVideoScalingMode);
- updateVideoSize(mSrcId, inputFormat, format);
+ updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
} else if (what == DecoderBase::kWhatShutdownCompleted) {
ALOGV("%s shutdown completed", audio ? "audio" : "video");
if (audio) {
@@ -1296,28 +1305,39 @@
finishFlushIfPossible(); // Should not occur.
break; // Finish anyways.
}
- if (mSource != nullptr) {
+ if (mCurrentSourceInfo.mSource != nullptr) {
if (audio) {
- if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL
- || mNativeWindow == NULL || mNativeWindow->getANativeWindow() == NULL
+ if (mVideoDecoderError
+ || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
+ || mNativeWindow == NULL
+ || mNativeWindow->getANativeWindow() == NULL
|| mVideoDecoder == NULL) {
// When both audio and video have error, or this stream has only audio
// which has error, notify client of error.
- notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+ notifyListener(
+ mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
+ MEDIA2_ERROR_UNKNOWN, err);
} else {
// Only audio track has error. Video track could be still good to play.
- notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
+ notifyListener(
+ mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
+ MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
}
mAudioDecoderError = true;
} else {
- if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL
+ if (mAudioDecoderError
+ || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
|| mAudioSink == NULL || mAudioDecoder == NULL) {
// When both audio and video have error, or this stream has only video
// which has error, notify client of error.
- notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+ notifyListener(
+ mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
+ MEDIA2_ERROR_UNKNOWN, err);
} else {
// Only video track has error. Audio track could be still good to play.
- notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
+ notifyListener(
+ mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
+ MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
}
mVideoDecoderError = true;
}
@@ -1367,12 +1387,13 @@
audio ? "audio" : "video", finalResult);
notifyListener(
- mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, finalResult);
+ mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
+ MEDIA2_ERROR_UNKNOWN, finalResult);
}
if ((mAudioEOS || mAudioDecoder == NULL)
&& (mVideoEOS || mVideoDecoder == NULL)) {
- notifyListener(mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
}
} else if (what == Renderer::kWhatFlushComplete) {
int32_t audio;
@@ -1393,10 +1414,11 @@
handleFlushComplete(audio, false /* isDecoder */);
finishFlushIfPossible();
} else if (what == Renderer::kWhatVideoRenderingStart) {
- notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_VIDEO_RENDERING_START, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
+ MEDIA2_INFO_VIDEO_RENDERING_START, 0);
} else if (what == Renderer::kWhatMediaRenderingStart) {
ALOGV("media rendering started");
- notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
} else if (what == Renderer::kWhatAudioTearDown) {
int32_t reason;
CHECK(msg->findInt32("reason", &reason));
@@ -1449,7 +1471,7 @@
int64_t timerUs;
CHECK(msg->findInt64("timerUs", &timerUs));
- notifyListener(mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
break;
}
@@ -1468,20 +1490,20 @@
if (!mStarted) {
if (!mSourceStarted) {
mSourceStarted = true;
- mSource->start();
+ mCurrentSourceInfo.mSource->start();
}
if (seekTimeUs > 0) {
performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
}
if (needNotify) {
- notifyDriverSeekComplete(mSrcId);
+ notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
}
break;
}
// seeks can take a while, so we essentially paused
- notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
mDeferredActions.push_back(
new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
@@ -1506,7 +1528,7 @@
onStart(false /* play */);
}
onPause();
- notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
mPausedByClient = true;
break;
}
@@ -1559,8 +1581,8 @@
return;
}
mPaused = false;
- if (mSource != NULL) {
- mSource->resume();
+ if (mCurrentSourceInfo.mSource != NULL) {
+ mCurrentSourceInfo.mSource->resume();
} else {
ALOGW("resume called when source is gone or not set");
}
@@ -1583,7 +1605,7 @@
if (!mSourceStarted) {
mSourceStarted = true;
- mSource->start();
+ mCurrentSourceInfo.mSource->start();
}
mOffloadAudio = false;
@@ -1594,22 +1616,23 @@
uint32_t flags = 0;
- if (mSource->isRealTime()) {
+ if (mCurrentSourceInfo.mSource->isRealTime()) {
flags |= Renderer::FLAG_REAL_TIME;
}
- bool hasAudio = (mSource->getFormat(true /* audio */) != NULL);
- bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
+ bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
+ bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
if (!hasAudio && !hasVideo) {
ALOGE("no metadata for either audio or video source");
- mSource->stop();
+ mCurrentSourceInfo.mSource->stop();
mSourceStarted = false;
- notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
+ MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
return;
}
ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream
- sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
+ sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
if (mAudioSink != NULL) {
@@ -1617,7 +1640,7 @@
}
mOffloadAudio =
- canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType)
+ canOffloadStream(audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
&& (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
// Modular DRM: Disabling audio offload if the source is protected
@@ -1641,9 +1664,9 @@
status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
if (err != OK) {
- mSource->stop();
+ mCurrentSourceInfo.mSource->stop();
mSourceStarted = false;
- notifyListener(mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
return;
}
@@ -1665,7 +1688,7 @@
}
startPlaybackTimer("onstart");
- notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
postScanSources();
}
@@ -1691,7 +1714,7 @@
ALOGV("stopPlaybackTimer() log %20" PRId64 "", played);
if (played > 0) {
- driver->notifyMorePlayingTimeUs(mSrcId, (played+500)/1000);
+ driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
}
}
mLastStartedPlayingTimeNs = 0;
@@ -1709,7 +1732,8 @@
void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
Mutex::Autolock autoLock(mPlayingTimeLock);
- ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)", mLastStartedRebufferingTimeNs, exitingPlayback);
+ ALOGV("stopRebufferTimer() time %20" PRId64 " (exiting %d)",
+ mLastStartedRebufferingTimeNs, exitingPlayback);
if (mLastStartedRebufferingTimeNs != 0) {
sp<NuPlayer2Driver> driver = mDriver.promote();
@@ -1719,9 +1743,10 @@
ALOGV("stopRebufferingTimer() log %20" PRId64 "", rebuffered);
if (rebuffered > 0) {
- driver->notifyMoreRebufferingTimeUs(mSrcId, (rebuffered+500)/1000);
+ driver->notifyMoreRebufferingTimeUs(
+ mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
if (exitingPlayback) {
- driver->notifyRebufferingWhenExit(mSrcId, true);
+ driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
}
}
}
@@ -1737,8 +1762,8 @@
return;
}
mPaused = true;
- if (mSource != NULL) {
- mSource->pause();
+ if (mCurrentSourceInfo.mSource != NULL) {
+ mCurrentSourceInfo.mSource->pause();
} else {
ALOGW("pause called when source is gone or not set");
}
@@ -1828,7 +1853,7 @@
status_t err = mRenderer->openAudioSink(
format, true /* offloadOnly */, hasVideo,
- AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming());
+ AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
if (err != OK) {
// Any failure we turn off mOffloadAudio.
mOffloadAudio = false;
@@ -1881,7 +1906,7 @@
}
void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
- if (mSource == NULL || mAudioSink == NULL) {
+ if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
return;
}
@@ -1891,12 +1916,12 @@
return;
}
- sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
- sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
+ sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
+ sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
const bool hasVideo = (videoFormat != NULL);
bool canOffload = canOffloadStream(
- audioMeta, hasVideo, mSource->isStreaming(), streamType)
+ audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
&& (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
// Modular DRM: Disabling audio offload if the source is protected
@@ -1927,7 +1952,7 @@
return OK;
}
- sp<AMessage> format = mSource->getFormat(audio);
+ sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
if (format == NULL) {
return UNKNOWN_ERROR;
@@ -1949,11 +1974,11 @@
mCCDecoder = new CCDecoder(ccNotify);
}
- if (mSourceFlags & Source::FLAG_SECURE) {
+ if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
format->setInt32("secure", true);
}
- if (mSourceFlags & Source::FLAG_PROTECTED) {
+ if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
format->setInt32("protected", true);
}
@@ -1972,16 +1997,16 @@
determineAudioModeChange(format);
}
if (mOffloadAudio) {
- mSource->setOffloadAudio(true /* offload */);
+ mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
- const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
+ const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
format->setInt32("has-video", hasVideo);
- *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
+ *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo);
} else {
- mSource->setOffloadAudio(false /* offload */);
+ mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
- *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer);
+ *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
ALOGV("instantiateDecoder audio Decoder");
}
mAudioDecoderError = false;
@@ -1991,7 +2016,8 @@
notify->setInt32("generation", mVideoDecoderGeneration);
*decoder = new Decoder(
- notify, mSource, mPID, mUID, mRenderer, mNativeWindow, mCCDecoder);
+ notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
+ mCCDecoder);
mVideoDecoderError = false;
// enable FRC if high-quality AV sync is requested, even if not
@@ -2008,8 +2034,8 @@
// Modular DRM
if (mIsDrmProtected) {
format->setObject("crypto", mCrypto);
- ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d", mCrypto.get(),
- (mSourceFlags & Source::FLAG_SECURE) != 0);
+ ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
+ mCrypto.get(), (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
}
(*decoder)->configure(format);
@@ -2277,11 +2303,11 @@
}
sp<MetaData> NuPlayer2::getFileMeta() {
- return mSource->getFileFormatMeta();
+ return mCurrentSourceInfo.mSource->getFileFormatMeta();
}
float NuPlayer2::getFrameRate() {
- sp<MetaData> meta = mSource->getFormatMeta(false /* audio */);
+ sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
if (meta == NULL) {
return 0;
}
@@ -2339,16 +2365,16 @@
ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
(long long)seekTimeUs, seekTimeUs / 1E6, mode);
- if (mSource == NULL) {
+ if (mCurrentSourceInfo.mSource == NULL) {
// This happens when reset occurs right before the loop mode
// asynchronously seeks to the start of the stream.
LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
- "mSource is NULL and decoders not NULL audio(%p) video(%p)",
+ "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
mAudioDecoder.get(), mVideoDecoder.get());
return;
}
mPreviousSeekTimeUs = seekTimeUs;
- mSource->seekTo(seekTimeUs, mode);
+ mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
++mTimedTextGeneration;
// everything's flushed, continue playback.
@@ -2395,17 +2421,17 @@
mRenderer.clear();
++mRendererGeneration;
- if (mSource != NULL) {
- mSource->stop();
+ if (mCurrentSourceInfo.mSource != NULL) {
+ mCurrentSourceInfo.mSource->stop();
Mutex::Autolock autoLock(mSourceLock);
- mSource.clear();
+ mCurrentSourceInfo.mSource.clear();
}
if (mDriver != NULL) {
sp<NuPlayer2Driver> driver = mDriver.promote();
if (driver != NULL) {
- driver->notifyResetComplete(mSrcId);
+ driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
}
}
@@ -2440,25 +2466,26 @@
++mRendererGeneration;
- if (mSource != NULL) {
- mSource->stop();
+ if (mCurrentSourceInfo.mSource != NULL) {
+ mCurrentSourceInfo.mSource->stop();
}
long previousSrcId;
{
Mutex::Autolock autoLock(mSourceLock);
- mSource = mNextSource;
- mNextSource = NULL;
- previousSrcId = mSrcId;
- mSrcId = mNextSrcId;
- ++mNextSrcId; // to distinguish the two sources.
+ mCurrentSourceInfo.mSource = mNextSourceInfo.mSource;
+ mNextSourceInfo.mSource = NULL;
+ previousSrcId = mCurrentSourceInfo.mSrcId;
+ mCurrentSourceInfo.mSrcId = mNextSourceInfo.mSrcId;
+ ++mNextSourceInfo.mSrcId; // to distinguish the two sources.
}
if (mDriver != NULL) {
sp<NuPlayer2Driver> driver = mDriver.promote();
if (driver != NULL) {
notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
- notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
+ notifyListener(
+ mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
}
}
@@ -2482,7 +2509,7 @@
onStart(true /* play */);
mPausedByClient = false;
- notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
}
void NuPlayer2::performScanSources() {
@@ -2508,7 +2535,7 @@
if (mDriver != NULL) {
sp<NuPlayer2Driver> driver = mDriver.promote();
if (driver != NULL) {
- driver->notifySetSurfaceComplete(mSrcId);
+ driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
}
}
}
@@ -2540,7 +2567,7 @@
void NuPlayer2::finishResume() {
if (mResumePending) {
mResumePending = false;
- notifyDriverSeekComplete(mSrcId);
+ notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
}
}
@@ -2562,8 +2589,9 @@
switch (what) {
case Source::kWhatPrepared:
{
- ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p", mSource.get());
- if (mSource == NULL) {
+ ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p",
+ mCurrentSourceInfo.mSource.get());
+ if (mCurrentSourceInfo.mSource == NULL) {
// This is a stale notification from a source that was
// asynchronously preparing when the client called reset().
// We handled the reset, the source is gone.
@@ -2588,7 +2616,7 @@
// notify duration first, so that it's definitely set when
// the app received the "prepare complete" callback.
int64_t durationUs;
- if (mSource->getDuration(&durationUs) == OK) {
+ if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
driver->notifyDuration(srcId, durationUs);
}
driver->notifyPrepareCompleted(srcId, err);
@@ -2640,16 +2668,21 @@
driver->notifyFlagsChanged(srcId, flags);
}
- if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
- && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
- cancelPollDuration();
- } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
- && (flags & Source::FLAG_DYNAMIC_DURATION)
- && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
- schedulePollDuration();
- }
+ if (srcId == mCurrentSourceInfo.mSrcId) {
+ if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
+ && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
+ cancelPollDuration();
+ } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
+ && (flags & Source::FLAG_DYNAMIC_DURATION)
+ && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
+ schedulePollDuration();
+ }
- mSourceFlags = flags;
+ mCurrentSourceInfo.mSourceFlags = flags;
+ } else if (srcId == mNextSourceInfo.mSrcId) {
+ // TODO: handle duration polling for next source.
+ mNextSourceInfo.mSourceFlags = flags;
+ }
break;
}
@@ -2800,8 +2833,8 @@
CHECK(msg->findBuffer("buffer", &buffer));
size_t inbandTracks = 0;
- if (mSource != NULL) {
- inbandTracks = mSource->getTrackCount();
+ if (mCurrentSourceInfo.mSource != NULL) {
+ inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
}
sendSubtitleData(buffer, inbandTracks);
@@ -2810,7 +2843,7 @@
case NuPlayer2::CCDecoder::kWhatTrackAdded:
{
- notifyListener(mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
break;
}
@@ -2835,7 +2868,7 @@
playerMsg.add_values()->set_int64_value(durationUs);
playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
- notifyListener(mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
}
void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
@@ -2846,7 +2879,7 @@
playerMsg.add_values()->set_int64_value(timeUs);
playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
- notifyListener(mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
}
void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
@@ -2876,14 +2909,14 @@
}
if (playerMsg.values_size() > 0) {
- notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
} else { // send an empty timed text
- notifyListener(mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
+ notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
}
}
const char *NuPlayer2::getDataSourceType() {
- switch (mDataSourceType) {
+ switch (mCurrentSourceInfo.mDataSourceType) {
case DATA_SOURCE_TYPE_HTTP_LIVE:
return "HTTPLive";
@@ -2957,7 +2990,7 @@
ALOGD("onPrepareDrm ");
status_t status = INVALID_OPERATION;
- if (mSource == NULL) {
+ if (mCurrentSourceInfo.mSource == NULL) {
ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status);
return status;
}
@@ -2970,12 +3003,12 @@
status = OK;
sp<AMediaCryptoWrapper> crypto = NULL;
- status = mSource->prepareDrm(uuid, *drmSessionId, &crypto);
+ status = mCurrentSourceInfo.mSource->prepareDrm(uuid, *drmSessionId, &crypto);
if (crypto == NULL) {
- ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status);
+ ALOGE("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm failed. status: %d", status);
return status;
}
- ALOGV("onPrepareDrm: mSource->prepareDrm succeeded");
+ ALOGV("onPrepareDrm: mCurrentSourceInfo.mSource->prepareDrm succeeded");
if (mCrypto != NULL) {
ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p", mCrypto.get());
@@ -3004,8 +3037,8 @@
status_t status;
if (mCrypto != NULL) {
// notifying the source first before removing crypto from codec
- if (mSource != NULL) {
- mSource->releaseDrm();
+ if (mCurrentSourceInfo.mSource != NULL) {
+ mCurrentSourceInfo.mSource->releaseDrm();
}
status=OK;
@@ -3090,4 +3123,12 @@
TRESPASS();
}
+NuPlayer2::SourceInfo::SourceInfo()
+ : mDataSourceType(DATA_SOURCE_TYPE_NONE),
+ mSrcId(0),
+ mSourceFlags(0),
+ mStartTimeUs(0),
+ mEndTimeUs(INT64_MAX) {
+}
+
} // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.h b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
index e55cdbe..4db0cbf 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
@@ -156,17 +156,33 @@
kWhatReleaseDrm = 'rDrm',
};
+ typedef enum {
+ DATA_SOURCE_TYPE_NONE,
+ DATA_SOURCE_TYPE_HTTP_LIVE,
+ DATA_SOURCE_TYPE_RTSP,
+ DATA_SOURCE_TYPE_GENERIC_URL,
+ DATA_SOURCE_TYPE_GENERIC_FD,
+ DATA_SOURCE_TYPE_MEDIA,
+ } DATA_SOURCE_TYPE;
+
+ struct SourceInfo {
+ SourceInfo();
+
+ sp<Source> mSource;
+ std::atomic<DATA_SOURCE_TYPE> mDataSourceType;
+ int64_t mSrcId;
+ uint32_t mSourceFlags;
+ int64_t mStartTimeUs;
+ int64_t mEndTimeUs;
+ };
+
wp<NuPlayer2Driver> mDriver;
pid_t mPID;
uid_t mUID;
const sp<MediaClock> mMediaClock;
Mutex mSourceLock; // guard |mSource|.
- sp<Source> mSource;
- int64_t mSrcId;
- uint32_t mSourceFlags;
- sp<Source> mNextSource;
- int64_t mNextSrcId;
- uint32_t mNextSourceFlags;
+ SourceInfo mCurrentSourceInfo;
+ SourceInfo mNextSourceInfo;
sp<ANativeWindowWrapper> mNativeWindow;
sp<MediaPlayer2Interface::AudioSink> mAudioSink;
sp<DecoderBase> mVideoDecoder;
@@ -252,18 +268,6 @@
sp<AMediaCryptoWrapper> mCrypto;
bool mIsDrmProtected;
- typedef enum {
- DATA_SOURCE_TYPE_NONE,
- DATA_SOURCE_TYPE_HTTP_LIVE,
- DATA_SOURCE_TYPE_RTSP,
- DATA_SOURCE_TYPE_GENERIC_URL,
- DATA_SOURCE_TYPE_GENERIC_FD,
- DATA_SOURCE_TYPE_MEDIA,
- } DATA_SOURCE_TYPE;
-
- std::atomic<DATA_SOURCE_TYPE> mDataSourceType;
- std::atomic<DATA_SOURCE_TYPE> mNextDataSourceType;
-
inline const sp<DecoderBase> &getDecoder(bool audio) {
return audio ? mAudioDecoder : mVideoDecoder;
}
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
index 662235f..9298a99 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
@@ -69,7 +69,7 @@
BufferingSettings* buffering /* nonnull */) = 0;
virtual status_t setBufferingSettings(const BufferingSettings& buffering) = 0;
- virtual void prepareAsync() = 0;
+ virtual void prepareAsync(int64_t startTimeUs) = 0;
virtual void start() = 0;
virtual void stop() {}
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp b/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
index 1dfe383..53c66c0 100644
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
+++ b/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
@@ -96,7 +96,8 @@
return OK;
}
-void NuPlayer2::RTSPSource2::prepareAsync() {
+// TODO: fetch data starting from |startTimeUs|
+void NuPlayer2::RTSPSource2::prepareAsync(int64_t /* startTimeUs */) {
if (mIsSDP && mHTTPService == NULL) {
notifyPrepared(BAD_VALUE);
return;
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.h b/media/libmediaplayer2/nuplayer2/RTSPSource2.h
index 712c3e5..e5f1716 100644
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.h
+++ b/media/libmediaplayer2/nuplayer2/RTSPSource2.h
@@ -43,7 +43,7 @@
BufferingSettings* buffering /* nonnull */) override;
virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
- virtual void prepareAsync();
+ virtual void prepareAsync(int64_t startTimeUs);
virtual void start();
virtual void stop();