summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManikanta Kanamarlapudi <kmanikan@codeaurora.org>2013-12-26 12:16:10 +0530
committerMahesh Lanka <mlanka@codeaurora.org>2014-01-09 14:27:03 +0530
commitadefcc16d377253b5192d42d6c2e7dd4db2e5a25 (patch)
tree8e27ed102c4140eeea711c1c4ea200199b34340e
parent90d6183b25834e32ff3e316c9f122e204a385ee6 (diff)
downloadandroid_hardware_qcom_media-adefcc16d377253b5192d42d6c2e7dd4db2e5a25.tar.gz
android_hardware_qcom_media-adefcc16d377253b5192d42d6c2e7dd4db2e5a25.tar.bz2
android_hardware_qcom_media-adefcc16d377253b5192d42d6c2e7dd4db2e5a25.zip
dashplayer: DASH TSB support
- DASH TSB Support Change-Id: I1ba7897f2e497da4401ee6cd0aa3ddee5f2bf825
-rw-r--r--QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java12
-rw-r--r--dashplayer/DashPlayer.cpp153
-rw-r--r--dashplayer/DashPlayer.h10
-rw-r--r--dashplayer/DashPlayerDriver.cpp40
-rw-r--r--dashplayer/DashPlayerSource.h12
5 files changed, 198 insertions, 29 deletions
diff --git a/QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java b/QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java
index 7194de51..c5448a51 100644
--- a/QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java
+++ b/QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java
@@ -294,6 +294,18 @@ public class QCMediaPlayer extends MediaPlayer
QOEPeriodic
};*/
+
+ /**
+ * Key to query reposition range. Value needs to be same as defined in DashPlayer.h
+ */
+ public static final int KEY_DASH_REPOSITION_RANGE = 9000;
+
+ /**
+ * Keys for dash playback modes. Value needs to be same as defined in DashPlayer.h
+ */
+ public static final int KEY_DASH_SEEK_EVENT = 7001;
+ public static final int KEY_DASH_PAUSE_EVENT = 7002;
+
private class QCMediaEventHandler extends Handler
{
private QCMediaPlayer mQCMediaPlayer;
diff --git a/dashplayer/DashPlayer.cpp b/dashplayer/DashPlayer.cpp
index 63faa88d..264d5903 100644
--- a/dashplayer/DashPlayer.cpp
+++ b/dashplayer/DashPlayer.cpp
@@ -799,47 +799,54 @@ void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
case kWhatPause:
{
+ CHECK(mRenderer != NULL);
+ mRenderer->pause();
+
+ mPauseIndication = true;
+
#ifdef QCOM_WFD_SINK
if (mSourceType == kWfdSource) {
CHECK(mSource != NULL);
mSource->pause();
}
#endif //QCOM_WFD_SINK
- CHECK(mRenderer != NULL);
- mRenderer->pause();
- mPauseIndication = true;
if (mSourceType == kHttpDashSource) {
Mutex::Autolock autoLock(mLock);
if (mSource != NULL)
{
- mSource->pause();
+ status_t nRet = mSource->pause();
}
}
+
break;
}
case kWhatResume:
{
- CHECK(mRenderer != NULL);
- mRenderer->resume();
-
mPauseIndication = false;
if (mSourceType == kHttpDashSource) {
+ status_t nRet = UNKNOWN_ERROR;
Mutex::Autolock autoLock(mLock);
if (mSource != NULL) {
- mSource->resume();
+ nRet = mSource->resume();
}
+
if (mAudioDecoder == NULL || mVideoDecoder == NULL || mTextDecoder == NULL) {
mScanSourcesPending = false;
postScanSources();
}
- }else if (mSourceType == kWfdSource) {
+ }
+ else
+ {
+ CHECK(mRenderer != NULL);
+ mRenderer->resume();
+
+ if (mSourceType == kWfdSource) {
CHECK(mSource != NULL);
mSource->resume();
int count = 0;
-
//check if there are messages stored in the list, then repost them
while(!mDecoderMessageQueue.empty()) {
(*mDecoderMessageQueue.begin()).mMessageToBeConsumed->post(); //self post
@@ -853,6 +860,7 @@ void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
postScanSources();
}
}
+ }
break;
}
@@ -872,7 +880,10 @@ void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
ALOGE("Source is null when checking for prepare done\n");
break;
}
- if (mSource->isPrepareDone()) {
+
+ status_t err;
+ err = mSource->isPrepareDone();
+ if(err == OK) {
int64_t durationUs;
if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
sp<DashPlayerDriver> driver = mDriver.promote();
@@ -881,8 +892,11 @@ void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
}
}
notifyListener(MEDIA_PREPARED, 0, 0);
- } else {
+ } else if(err == -EWOULDBLOCK) {
msg->post(100000ll);
+ } else {
+ ALOGE("Prepareasync failed\n");
+ notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
}
break;
case kWhatSourceNotify:
@@ -909,14 +923,17 @@ void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
mSRid = (mSRid+1)%SRMax;
}
- if(msgFound) {
+ if(msgFound)
+ {
int32_t what;
CHECK(sourceRequest->findInt32("what", &what));
- sourceRequest->findInt64("track", &track);
- getTrackName((int)track,mTrackName);
if (what == kWhatBufferingStart) {
+
+ sourceRequest->findInt64("track", &track);
+ getTrackName((int)track,mTrackName);
ALOGE("Source Notified Buffering Start for %s ",mTrackName);
+
if (mBufferingNotification == false) {
if (track == kVideo && mNativeWindow == NULL)
{
@@ -935,6 +952,8 @@ void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
}
}
else if(what == kWhatBufferingEnd) {
+ sourceRequest->findInt64("track", &track);
+ getTrackName((int)track,mTrackName);
if (mBufferingNotification) {
ALOGE("Source Notified Buffering End for %s ",mTrackName);
mBufferingNotification = false;
@@ -948,10 +967,86 @@ void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
,mBufferingNotification);
}
}
- }
+ else if (what == kWhatSourceResumeStatus)
+ {
+ status_t status;
+ sourceRequest->findInt32("status", &status);
+ if (status == OK)
+ {
+ int32_t disc;
+ sourceRequest->findInt32("discontinuity", &disc);
+ if (disc == 1 && mSourceType == kHttpDashSource)
+ {
+ uint64_t nMin = 0, nMax = 0, nMaxDepth = 0;
+ status = mSource->getRepositionRange(&nMin, &nMax, &nMaxDepth);
+ if (status == OK)
+ {
+ int64_t seekTimeUs = (int64_t)nMin * 1000ll;
+
+ ALOGV("kWhatSeek seekTimeUs=%lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
+
+ status = mSource->seekTo(seekTimeUs);
+ if (status == OK)
+ {
+ // if seek success then flush the audio,video decoder and renderer
+ mTimeDiscontinuityPending = true;
+ bool audPresence = false;
+ bool vidPresence = false;
+ bool textPresence = false;
+ (void)mSource->getMediaPresence(audPresence,vidPresence,textPresence);
+ mRenderer->setMediaPresence(true,audPresence); // audio
+ mRenderer->setMediaPresence(false,vidPresence); // video
+ if( (mVideoDecoder != NULL) &&
+ (mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY) ) {
+ flushDecoder( false, true ); // flush video, shutdown
}
- else {
- ALOGE("kWhatSourceNotify - Source object does not exist anymore");
+
+ if( (mAudioDecoder != NULL) &&
+ (mFlushingAudio == NONE|| mFlushingAudio == AWAITING_DISCONTINUITY) )
+ {
+ flushDecoder( true, true ); // flush audio, shutdown
+ }
+ if( mAudioDecoder == NULL ) {
+ ALOGV("Audio is not there, set it to shutdown");
+ mFlushingAudio = SHUT_DOWN;
+ }
+ if( mVideoDecoder == NULL ) {
+ ALOGV("Video is not there, set it to shutdown");
+ mFlushingVideo = SHUT_DOWN;
+ }
+
+ if (mDriver != NULL)
+ {
+ sp<DashPlayerDriver> driver = mDriver.promote();
+ if (driver != NULL)
+ {
+ if( seekTimeUs >= 0 ) {
+ mRenderer->notifySeekPosition(seekTimeUs);
+ driver->notifyPosition( seekTimeUs );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (status == OK)
+ {
+ CHECK(mRenderer != NULL);
+ mRenderer->resume();
+ }
+ else
+ {
+ //Notify error?
+ ALOGE("kWhatSourceResumeStatus - Resume async failure");
+ notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, status);
+ }
+ }
+ }
+ }
+ else
+ {
+ ALOGE("kWhatSourceNotify - Source object does not exist anymore");
}
break;
}
@@ -1016,8 +1111,8 @@ void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
}
notifyListener(MEDIA_QOE,kWhatQOE,what,&notifyDataQOE);
}
- }
break;
+ }
default:
TRESPASS();
@@ -1629,6 +1724,25 @@ status_t DashPlayer::getParameter(int key, Parcel *reply)
ALOGE("Source is NULL in getParameter\n");
return UNKNOWN_ERROR;
}
+ if (key == KEY_DASH_REPOSITION_RANGE)
+ {
+ uint64_t nMin = 0, nMax = 0, nMaxDepth = 0;
+ err = mSource->getRepositionRange(&nMin, &nMax, &nMaxDepth);
+ if(err == OK)
+ {
+ reply->setDataPosition(0);
+ reply->writeInt64(nMin);
+ reply->writeInt64(nMax);
+ reply->writeInt64(nMaxDepth);
+ ALOGV("DashPlayer::getParameter KEY_DASH_REPOSITION_RANGE %lld, %lld", nMin, nMax);
+ }
+ else
+ {
+ ALOGE("DashPlayer::getParameter KEY_DASH_REPOSITION_RANGE err in NOT OK");
+ }
+ }
+ else
+ {
err = mSource->getParameter(key, &data_8, &data_8_Size);
if (key == KEY_DASH_QOE_PERIODIC_EVENT)
{
@@ -1688,6 +1802,7 @@ status_t DashPlayer::getParameter(int key, Parcel *reply)
err = reply->writeString16((char16_t *)data_16, data_8_Size);
free(data_16);
}
+ }
return err;
}
diff --git a/dashplayer/DashPlayer.h b/dashplayer/DashPlayer.h
index e8b99783..5005fea3 100644
--- a/dashplayer/DashPlayer.h
+++ b/dashplayer/DashPlayer.h
@@ -24,15 +24,22 @@
#include "DashPlayerStats.h"
#include <media/stagefright/foundation/ABuffer.h>
#include <cutils/properties.h>
+
+//Keys for playback modes
+#define KEY_DASH_SEEK_EVENT 7001
+#define KEY_DASH_PAUSE_EVENT 7002
+
// used for Get Adaptionset property (NonJB)and for both Get and set for JB
#define KEY_DASH_ADAPTION_PROPERTIES 8002
#define KEY_DASH_MPD_QUERY 8003
#define KEY_DASH_QOE_EVENT 8004
#define KEY_DASH_QOE_PERIODIC_EVENT 8008
-
#define KEY_DASH_GET_ADAPTION_PROPERTIES 8010
#define KEY_DASH_SET_ADAPTION_PROPERTIES 8011
+//Key to query reposition range
+#define KEY_DASH_REPOSITION_RANGE 9000
+
namespace android {
struct DashCodec;
@@ -152,6 +159,7 @@ private:
enum {
kWhatBufferingStart = 'bfst',
kWhatBufferingEnd = 'bfen',
+ kWhatSourceResumeStatus = 'srsm',
};
wp<DashPlayerDriver> mDriver;
diff --git a/dashplayer/DashPlayerDriver.cpp b/dashplayer/DashPlayerDriver.cpp
index 9b2c77e2..2aaa2435 100644
--- a/dashplayer/DashPlayerDriver.cpp
+++ b/dashplayer/DashPlayerDriver.cpp
@@ -150,9 +150,6 @@ status_t DashPlayerDriver::start() {
default:
{
CHECK_EQ((int)mState, (int)PAUSED);
- if (mAtEOS){
- seekTo(0);
- }
mPlayer->resume();
break;
}
@@ -317,6 +314,40 @@ status_t DashPlayerDriver::invoke(const Parcel &request, Parcel *reply) {
ret = getParameter(methodId,reply);
break;
+ case KEY_DASH_REPOSITION_RANGE:
+ ALOGV("calling KEY_DASH_REPOSITION_RANGE");
+ ret = getParameter(methodId,reply);
+ break;
+
+ case KEY_DASH_SEEK_EVENT:
+ {
+ ALOGV("calling KEY_DASH_SEEK_EVENT seekTo()");
+ int32_t msec;
+ ret = request.readInt32(&msec);
+ if (ret != OK)
+ {
+ ALOGE("Invoke: invalid seek value");
+ }
+ else
+ {
+ ret = seekTo(msec);
+ int32_t val = (ret == OK)? 1:0;
+ reply->setDataPosition(0);
+ reply->writeInt32(val);
+ }
+ break;
+ }
+
+ case KEY_DASH_PAUSE_EVENT:
+ {
+ ALOGV("calling KEY_DASH_PAUSE_EVENT pause()");
+ ret = pause();
+ int32_t val = (ret == OK)? 1:0;
+ reply->setDataPosition(0);
+ reply->writeInt32(val);
+ break;
+ }
+
case INVOKE_ID_GET_TRACK_INFO:
{
// Ignore the invoke call for INVOKE_ID_GET_TRACK_INFO with success return code
@@ -404,9 +435,6 @@ status_t DashPlayerDriver::dump(int fd, const Vector<String16> &args) const {
void DashPlayerDriver::notifyListener(int msg, int ext1, int ext2, const Parcel *obj) {
if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
mAtEOS = true;
- if(msg == MEDIA_PLAYBACK_COMPLETE){
- pause();
- }
}
sendEvent(msg, ext1, ext2, obj);
diff --git a/dashplayer/DashPlayerSource.h b/dashplayer/DashPlayerSource.h
index 9f968b24..a58be7ca 100644
--- a/dashplayer/DashPlayerSource.h
+++ b/dashplayer/DashPlayerSource.h
@@ -60,7 +60,7 @@ struct DashPlayer::Source : public RefBase {
return INVALID_OPERATION;
}
- virtual bool isPrepareDone() {
+ virtual status_t isPrepareDone() {
return INVALID_OPERATION;
}
@@ -84,16 +84,22 @@ struct DashPlayer::Source : public RefBase {
return INVALID_OPERATION;
}
- virtual void pause() {
+ virtual status_t pause() {
ALOGE("Pause called on Wrong DataSource.. Please check !!!");
+ return INVALID_OPERATION;
//CHECK(false);
}
- virtual void resume() {
+ virtual status_t resume() {
ALOGE("Resume called on Wrong DataSource.. Please check !!!");
+ return INVALID_OPERATION;
//CHECK(false);
}
+ virtual status_t getRepositionRange(uint64_t* pMin, uint64_t* pMax, uint64_t* pMaxDepth) {
+ return INVALID_OPERATION;
+ }
+
protected:
virtual ~Source() {}