summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2012-04-26 17:11:28 -0700
committerJames Dong <jdong@google.com>2012-05-14 14:06:50 -0700
commitab7a2e544643edcb2e09ed5f204580afd763edc1 (patch)
tree8cc651013168e8d5d5373d74f2b73025f847bad9 /media
parent94f60e297b9e45fac387cf10b6ce1acc067cb4a1 (diff)
downloadframeworks_av-ab7a2e544643edcb2e09ed5f204580afd763edc1.zip
frameworks_av-ab7a2e544643edcb2e09ed5f204580afd763edc1.tar.gz
frameworks_av-ab7a2e544643edcb2e09ed5f204580afd763edc1.tar.bz2
Switch audio tracks at runtime
o The switching is not allowed if there is an audio seek operation ongoing. o related-to-bug: 6110705 Change-Id: Ib92a165f3984aa033d97800184d3d17319522db5
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/AwesomePlayer.cpp101
-rw-r--r--media/libstagefright/include/AwesomePlayer.h9
2 files changed, 100 insertions, 10 deletions
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 0aa73db..5a5a00e 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -425,6 +425,7 @@ status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
} else if (!haveAudio && !strncasecmp(mime.string(), "audio/", 6)) {
setAudioSource(extractor->getTrack(i));
haveAudio = true;
+ mActiveAudioTrackIndex = i;
{
Mutex::Autolock autoLock(mStatsLock);
@@ -467,6 +468,7 @@ void AwesomePlayer::reset() {
}
void AwesomePlayer::reset_l() {
+ mActiveAudioTrackIndex = -1;
mDisplayWidth = 0;
mDisplayHeight = 0;
@@ -880,9 +882,10 @@ status_t AwesomePlayer::play_l() {
bool allowDeepBuffering;
int64_t cachedDurationUs;
bool eos;
- if (mVideoSource == NULL && (mDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US ||
- getCachedDuration_l(&cachedDurationUs, &eos) &&
- cachedDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
+ if (mVideoSource == NULL
+ && (mDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US ||
+ (getCachedDuration_l(&cachedDurationUs, &eos) &&
+ cachedDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US))) {
allowDeepBuffering = true;
} else {
allowDeepBuffering = false;
@@ -2336,8 +2339,77 @@ status_t AwesomePlayer::getTrackInfo(Parcel *reply) const {
return OK;
}
-// FIXME:
-// At present, only timed text track is able to be selected or unselected.
+status_t AwesomePlayer::selectAudioTrack_l(
+ const sp<MediaSource>& source, size_t trackIndex) {
+
+ ALOGI("selectAudioTrack_l: trackIndex=%d, mFlags=0x%x", trackIndex, mFlags);
+
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ if ((ssize_t)trackIndex == mActiveAudioTrackIndex) {
+ ALOGI("Track %d is active. Does nothing.", trackIndex);
+ return OK;
+ }
+ //mStats.mFlags = mFlags;
+ }
+
+ if (mSeeking != NO_SEEK) {
+ ALOGE("Selecting a track while seeking is not supported");
+ return ERROR_UNSUPPORTED;
+ }
+
+ if ((mFlags & PREPARED) == 0) {
+ ALOGE("Data source has not finished preparation");
+ return ERROR_UNSUPPORTED;
+ }
+
+ CHECK(source != NULL);
+ bool wasPlaying = (mFlags & PLAYING) != 0;
+
+ pause_l();
+
+ int64_t curTimeUs;
+ CHECK_EQ(getPosition(&curTimeUs), (status_t)OK);
+
+ if ((mAudioPlayer == NULL || !(mFlags & AUDIOPLAYER_STARTED))
+ && mAudioSource != NULL) {
+ // If we had an audio player, it would have effectively
+ // taken possession of the audio source and stopped it when
+ // _it_ is stopped. Otherwise this is still our responsibility.
+ mAudioSource->stop();
+ }
+ mAudioSource.clear();
+
+ mTimeSource = NULL;
+
+ delete mAudioPlayer;
+ mAudioPlayer = NULL;
+
+ modifyFlags(AUDIOPLAYER_STARTED, CLEAR);
+
+ setAudioSource(source);
+
+ modifyFlags(AUDIO_AT_EOS, CLEAR);
+ modifyFlags(AT_EOS, CLEAR);
+
+ status_t err;
+ if ((err = initAudioDecoder()) != OK) {
+ ALOGE("Failed to init audio decoder: 0x%x", err);
+ return err;
+ }
+
+ mSeekNotificationSent = true;
+ seekTo_l(curTimeUs);
+
+ if (wasPlaying) {
+ play_l();
+ }
+
+ mActiveAudioTrackIndex = trackIndex;
+
+ return OK;
+}
+
status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) {
ATRACE_CALL();
ALOGV("selectTrack: trackIndex = %d and select=%d", trackIndex, select);
@@ -2346,21 +2418,30 @@ status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) {
if (mTextDriver != NULL) {
trackCount += mTextDriver->countExternalTracks();
}
-
if (trackIndex >= trackCount) {
ALOGE("Track index (%d) is out of range [0, %d)", trackIndex, trackCount);
return ERROR_OUT_OF_RANGE;
}
+ bool isAudioTrack = false;
if (trackIndex < mExtractor->countTracks()) {
sp<MetaData> meta = mExtractor->getTrackMetaData(trackIndex);
- const char *_mime;
- CHECK(meta->findCString(kKeyMIMEType, &_mime));
- String8 mime = String8(_mime);
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+ isAudioTrack = !strncasecmp(mime, "audio/", 6);
+
+ if (!isAudioTrack && !strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
+ ALOGE("Track %d is not either audio or timed text", trackIndex);
+ return ERROR_UNSUPPORTED;
+ }
+ }
- if (strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) {
+ if (isAudioTrack) {
+ if (!select) {
+ ALOGE("Deselect an audio track (%d) is not supported", trackIndex);
return ERROR_UNSUPPORTED;
}
+ return selectAudioTrack_l(mExtractor->getTrack(trackIndex), trackIndex);
}
// Timed text track handling
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 909654a..68380a8 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -168,6 +168,7 @@ private:
sp<AwesomeRenderer> mVideoRenderer;
bool mVideoRendererIsPreview;
+ ssize_t mActiveAudioTrackIndex;
sp<MediaSource> mAudioTrack;
sp<MediaSource> mAudioSource;
AudioPlayer *mAudioPlayer;
@@ -309,8 +310,14 @@ private:
int mFd;
String8 mURI;
int64_t mBitrate;
+
+ // FIXME:
+ // These two indices are just 0 or 1 for now
+ // They are not representing the actual track
+ // indices in the stream.
ssize_t mAudioTrackIndex;
ssize_t mVideoTrackIndex;
+
int64_t mNumVideoFramesDecoded;
int64_t mNumVideoFramesDropped;
int32_t mVideoWidth;
@@ -323,6 +330,8 @@ private:
status_t setVideoScalingMode_l(int32_t mode);
status_t getTrackInfo(Parcel* reply) const;
+ status_t selectAudioTrack_l(const sp<MediaSource>& source, size_t trackIndex);
+
// when select is true, the given track is selected.
// otherwise, the given track is unselected.
status_t selectTrack(size_t trackIndex, bool select);