From 404fced9bfa8fa423ee210a271ca051ffd1bec13 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Wed, 11 Jun 2014 14:45:31 -0700 Subject: refactor getTrackInfo() (this is in preparation for supporting other cc source) - split into two methods: getTrackCount() and getTrackInfo() - move track info parcelling to NuPlayer - parcel in the mime type of the subtitle format Bug: 15470448 Change-Id: If00724d8c3a2b2319cb9c5f29d3fe76347bfe947 --- .../nuplayer/HTTPLiveSource.cpp | 8 +- .../nuplayer/HTTPLiveSource.h | 3 +- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 103 ++++++++++++++++----- media/libmediaplayerservice/nuplayer/NuPlayer.h | 5 + .../nuplayer/NuPlayerSource.h | 8 +- media/libstagefright/MediaDefs.cpp | 1 + media/libstagefright/httplive/LiveSession.cpp | 8 +- media/libstagefright/httplive/LiveSession.h | 3 +- media/libstagefright/httplive/M3UParser.cpp | 77 ++++++++------- media/libstagefright/httplive/M3UParser.h | 3 +- 10 files changed, 154 insertions(+), 65 deletions(-) (limited to 'media') diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index cbedf5c..e8431e9 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -120,8 +120,12 @@ status_t NuPlayer::HTTPLiveSource::getDuration(int64_t *durationUs) { return mLiveSession->getDuration(durationUs); } -status_t NuPlayer::HTTPLiveSource::getTrackInfo(Parcel *reply) const { - return mLiveSession->getTrackInfo(reply); +size_t NuPlayer::HTTPLiveSource::getTrackCount() const { + return mLiveSession->getTrackCount(); +} + +sp NuPlayer::HTTPLiveSource::getTrackInfo(size_t trackIndex) const { + return mLiveSession->getTrackInfo(trackIndex); } status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select) { diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h index 4d7251f..6b5f6af 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h @@ -40,7 +40,8 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { virtual status_t feedMoreTSData(); virtual status_t getDuration(int64_t *durationUs); - virtual status_t getTrackInfo(Parcel *reply) const; + virtual size_t getTrackCount() const; + virtual sp getTrackInfo(size_t trackIndex) const; virtual status_t selectTrack(size_t trackIndex, bool select); virtual status_t seekTo(int64_t seekTimeUs); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 857e703..dc69f73 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -305,6 +305,34 @@ bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) { } } +void NuPlayer::writeTrackInfo( + Parcel* reply, const sp format) const { + int32_t trackType; + CHECK(format->findInt32("type", &trackType)); + + AString lang; + CHECK(format->findString("language", &lang)); + + reply->writeInt32(2); // write something non-zero + reply->writeInt32(trackType); + reply->writeString16(String16(lang.c_str())); + + if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) { + AString mime; + CHECK(format->findString("mime", &mime)); + + int32_t isAuto, isDefault, isForced; + CHECK(format->findInt32("auto", &isAuto)); + CHECK(format->findInt32("default", &isDefault)); + CHECK(format->findInt32("forced", &isForced)); + + reply->writeString16(String16(mime.c_str())); + reply->writeInt32(isAuto); + reply->writeInt32(isDefault); + reply->writeInt32(isForced); + } +} + void NuPlayer::onMessageReceived(const sp &msg) { switch (msg->what()) { case kWhatSetDataSource: @@ -339,16 +367,23 @@ void NuPlayer::onMessageReceived(const sp &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); - status_t err = INVALID_OPERATION; + Parcel* reply; + CHECK(msg->findPointer("reply", (void**)&reply)); + + size_t inbandTracks = 0; if (mSource != NULL) { - Parcel* reply; - CHECK(msg->findPointer("reply", (void**)&reply)); - err = mSource->getTrackInfo(reply); + inbandTracks = mSource->getTrackCount(); } - sp response = new AMessage; - response->setInt32("err", err); + // total track count + reply->writeInt32(inbandTracks); + + // write inband tracks + for (size_t i = 0; i < inbandTracks; ++i) { + writeTrackInfo(reply, mSource->getTrackInfo(i)); + } + sp response = new AMessage; response->postReply(replyID); break; } @@ -358,12 +393,19 @@ void NuPlayer::onMessageReceived(const sp &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); + size_t trackIndex; + int32_t select; + CHECK(msg->findSize("trackIndex", &trackIndex)); + CHECK(msg->findInt32("select", &select)); + status_t err = INVALID_OPERATION; + + size_t inbandTracks = 0; if (mSource != NULL) { - size_t trackIndex; - int32_t select; - CHECK(msg->findSize("trackIndex", &trackIndex)); - CHECK(msg->findInt32("select", &select)); + inbandTracks = mSource->getTrackCount(); + } + + if (trackIndex < inbandTracks) { err = mSource->selectTrack(trackIndex, select); } @@ -1187,6 +1229,14 @@ status_t NuPlayer::selectTrack(size_t trackIndex, bool select) { sp response; status_t err = msg->postAndAwaitResponse(&response); + if (err != OK) { + return err; + } + + if (!response->findInt32("err", &err)) { + err = OK; + } + return err; } @@ -1438,21 +1488,7 @@ void NuPlayer::onSourceNotify(const sp &msg) { sp buffer; CHECK(msg->findBuffer("buffer", &buffer)); - int32_t trackIndex; - int64_t timeUs, durationUs; - CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex)); - CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); - CHECK(buffer->meta()->findInt64("durationUs", &durationUs)); - - Parcel in; - in.writeInt32(trackIndex); - in.writeInt64(timeUs); - in.writeInt64(durationUs); - in.writeInt32(buffer->size()); - in.writeInt32(buffer->size()); - in.write(buffer->data(), buffer->size()); - - notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in); + sendSubtitleData(buffer, 0 /* baseIndex */); break; } @@ -1474,6 +1510,23 @@ void NuPlayer::onSourceNotify(const sp &msg) { } } +void NuPlayer::sendSubtitleData(const sp &buffer, int32_t baseIndex) { + int32_t trackIndex; + int64_t timeUs, durationUs; + CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex)); + CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); + CHECK(buffer->meta()->findInt64("durationUs", &durationUs)); + + Parcel in; + in.writeInt32(trackIndex + baseIndex); + in.writeInt64(timeUs); + in.writeInt64(durationUs); + in.writeInt32(buffer->size()); + in.writeInt32(buffer->size()); + in.write(buffer->data(), buffer->size()); + + notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in); +} //////////////////////////////////////////////////////////////////////////////// void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index f1d3d55..f95cc11 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -24,6 +24,7 @@ namespace android { +struct ABuffer; struct MetaData; struct NuPlayerDriver; @@ -189,6 +190,10 @@ private: void queueDecoderShutdown( bool audio, bool video, const sp &reply); + void sendSubtitleData(const sp &buffer, int32_t baseIndex); + + void writeTrackInfo(Parcel* reply, const sp format) const; + DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h index 11279fc..f5a1d6d 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h @@ -72,8 +72,12 @@ struct NuPlayer::Source : public AHandler { return INVALID_OPERATION; } - virtual status_t getTrackInfo(Parcel* /* reply */) const { - return INVALID_OPERATION; + virtual size_t getTrackCount() const { + return 0; + } + + virtual sp getTrackInfo(size_t /* trackIndex */) const { + return NULL; } virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */) { diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp index 8229e55..f38729e 100644 --- a/media/libstagefright/MediaDefs.cpp +++ b/media/libstagefright/MediaDefs.cpp @@ -58,5 +58,6 @@ const char *MEDIA_MIMETYPE_CONTAINER_WVM = "video/wvm"; const char *MEDIA_MIMETYPE_TEXT_3GPP = "text/3gpp-tt"; const char *MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip"; +const char *MEDIA_MIMETYPE_TEXT_VTT = "text/vtt"; } // namespace android diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index 08a146f..10cdde2 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -926,8 +926,12 @@ bool LiveSession::hasDynamicDuration() const { return false; } -status_t LiveSession::getTrackInfo(Parcel *reply) const { - return mPlaylist->getTrackInfo(reply); +size_t LiveSession::getTrackCount() const { + return mPlaylist->getTrackCount(); +} + +sp LiveSession::getTrackInfo(size_t trackIndex) const { + return mPlaylist->getTrackInfo(trackIndex); } status_t LiveSession::selectTrack(size_t index, bool select) { diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h index d7ed56f..ed3818f 100644 --- a/media/libstagefright/httplive/LiveSession.h +++ b/media/libstagefright/httplive/LiveSession.h @@ -70,7 +70,8 @@ struct LiveSession : public AHandler { status_t seekTo(int64_t timeUs); status_t getDuration(int64_t *durationUs) const; - status_t getTrackInfo(Parcel *reply) const; + size_t getTrackCount() const; + sp getTrackInfo(size_t trackIndex) const; status_t selectTrack(size_t index, bool select); bool isSeekable() const; diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp index 785c515..281e0da 100644 --- a/media/libstagefright/httplive/M3UParser.cpp +++ b/media/libstagefright/httplive/M3UParser.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -58,8 +59,8 @@ struct M3UParser::MediaGroup : public RefBase { void pickRandomMediaItems(); status_t selectTrack(size_t index, bool select); - void getTrackInfo(Parcel* reply) const; size_t countTracks() const; + sp getTrackInfo(size_t index) const; protected: virtual ~MediaGroup(); @@ -184,35 +185,42 @@ status_t M3UParser::MediaGroup::selectTrack(size_t index, bool select) { return OK; } -void M3UParser::MediaGroup::getTrackInfo(Parcel* reply) const { - for (size_t i = 0; i < mMediaItems.size(); ++i) { - reply->writeInt32(2); // 2 fields - - if (mType == TYPE_AUDIO) { - reply->writeInt32(MEDIA_TRACK_TYPE_AUDIO); - } else if (mType == TYPE_VIDEO) { - reply->writeInt32(MEDIA_TRACK_TYPE_VIDEO); - } else if (mType == TYPE_SUBS) { - reply->writeInt32(MEDIA_TRACK_TYPE_SUBTITLE); - } else { - reply->writeInt32(MEDIA_TRACK_TYPE_UNKNOWN); - } +size_t M3UParser::MediaGroup::countTracks() const { + return mMediaItems.size(); +} - const Media &item = mMediaItems.itemAt(i); - const char *lang = item.mLanguage.empty() ? "und" : item.mLanguage.c_str(); - reply->writeString16(String16(lang)); +sp M3UParser::MediaGroup::getTrackInfo(size_t index) const { + if (index >= mMediaItems.size()) { + return NULL; + } - if (mType == TYPE_SUBS) { - // TO-DO: pass in a MediaFormat instead - reply->writeInt32(!!(item.mFlags & MediaGroup::FLAG_AUTOSELECT)); - reply->writeInt32(!!(item.mFlags & MediaGroup::FLAG_DEFAULT)); - reply->writeInt32(!!(item.mFlags & MediaGroup::FLAG_FORCED)); - } + sp format = new AMessage(); + + int32_t trackType; + if (mType == TYPE_AUDIO) { + trackType = MEDIA_TRACK_TYPE_AUDIO; + } else if (mType == TYPE_VIDEO) { + trackType = MEDIA_TRACK_TYPE_VIDEO; + } else if (mType == TYPE_SUBS) { + trackType = MEDIA_TRACK_TYPE_SUBTITLE; + } else { + trackType = MEDIA_TRACK_TYPE_UNKNOWN; + } + format->setInt32("type", trackType); + + const Media &item = mMediaItems.itemAt(index); + const char *lang = item.mLanguage.empty() ? "und" : item.mLanguage.c_str(); + format->setString("language", lang); + + if (mType == TYPE_SUBS) { + // TO-DO: pass in a MediaFormat instead + format->setString("mime", MEDIA_MIMETYPE_TEXT_VTT); + format->setInt32("auto", !!(item.mFlags & MediaGroup::FLAG_AUTOSELECT)); + format->setInt32("default", !!(item.mFlags & MediaGroup::FLAG_DEFAULT)); + format->setInt32("forced", !!(item.mFlags & MediaGroup::FLAG_FORCED)); } -} -size_t M3UParser::MediaGroup::countTracks() const { - return mMediaItems.size(); + return format; } bool M3UParser::MediaGroup::getActiveURI(AString *uri) const { @@ -319,17 +327,24 @@ status_t M3UParser::selectTrack(size_t index, bool select) { return INVALID_OPERATION; } -status_t M3UParser::getTrackInfo(Parcel* reply) const { +size_t M3UParser::getTrackCount() const { size_t trackCount = 0; for (size_t i = 0; i < mMediaGroups.size(); ++i) { trackCount += mMediaGroups.valueAt(i)->countTracks(); } - reply->writeInt32(trackCount); + return trackCount; +} - for (size_t i = 0; i < mMediaGroups.size(); ++i) { - mMediaGroups.valueAt(i)->getTrackInfo(reply); +sp M3UParser::getTrackInfo(size_t index) const { + for (size_t i = 0, ii = index; i < mMediaGroups.size(); ++i) { + sp group = mMediaGroups.valueAt(i); + size_t tracks = group->countTracks(); + if (ii < tracks) { + return group->getTrackInfo(ii); + } + ii -= tracks; } - return OK; + return NULL; } ssize_t M3UParser::getSelectedIndex() const { diff --git a/media/libstagefright/httplive/M3UParser.h b/media/libstagefright/httplive/M3UParser.h index ccd6556..fe9fb9d 100644 --- a/media/libstagefright/httplive/M3UParser.h +++ b/media/libstagefright/httplive/M3UParser.h @@ -42,7 +42,8 @@ struct M3UParser : public RefBase { void pickRandomMediaItems(); status_t selectTrack(size_t index, bool select); - status_t getTrackInfo(Parcel* reply) const; + size_t getTrackCount() const; + sp getTrackInfo(size_t index) const; ssize_t getSelectedIndex() const; bool getTypeURI(size_t index, const char *key, AString *uri) const; -- cgit v1.1