diff options
author | James Dong <jdong@google.com> | 2012-03-14 17:45:18 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-03-14 17:45:18 -0700 |
commit | cbcd6e869dd41158076e742a31c1ee410fc0c713 (patch) | |
tree | ca11dbcb2453661a440691a1e0e67e3cd1ddb92a /media | |
parent | 213744c53992ba183809b30980f57d25dc8bd967 (diff) | |
parent | f9d660a5e0196240add5daf0199f128d471e592c (diff) | |
download | frameworks_av-cbcd6e869dd41158076e742a31c1ee410fc0c713.zip frameworks_av-cbcd6e869dd41158076e742a31c1ee410fc0c713.tar.gz frameworks_av-cbcd6e869dd41158076e742a31c1ee410fc0c713.tar.bz2 |
Merge "Defines MediaPlayer APIs to support multiple audio/video/timedtext tracks."
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/StagefrightPlayer.cpp | 3 | ||||
-rw-r--r-- | media/libstagefright/AwesomePlayer.cpp | 145 | ||||
-rw-r--r-- | media/libstagefright/MediaDefs.cpp | 1 | ||||
-rw-r--r-- | media/libstagefright/include/AwesomePlayer.h | 5 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedText3GPPSource.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedText3GPPSource.h | 1 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextDriver.cpp | 136 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextPlayer.cpp | 47 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextPlayer.h | 4 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextSRTSource.cpp | 11 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextSRTSource.h | 2 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextSource.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextSource.h | 2 |
13 files changed, 229 insertions, 136 deletions
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp index 052ebf0..619c149 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.cpp +++ b/media/libmediaplayerservice/StagefrightPlayer.cpp @@ -166,7 +166,8 @@ player_type StagefrightPlayer::playerType() { } status_t StagefrightPlayer::invoke(const Parcel &request, Parcel *reply) { - return INVALID_OPERATION; + ALOGV("invoke()"); + return mPlayer->invoke(request, reply); } void StagefrightPlayer::setAudioSink(const sp<AudioSink> &audioSink) { diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 9e00bb3..b4cb1ab 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -1114,7 +1114,7 @@ status_t AwesomePlayer::pause_l(bool at_eos) { modifyFlags(AUDIO_RUNNING, CLEAR); } - if (mFlags & TEXTPLAYER_STARTED) { + if (mFlags & TEXTPLAYER_INITIALIZED) { mTextDriver->pause(); modifyFlags(TEXT_RUNNING, CLEAR); } @@ -1268,32 +1268,6 @@ status_t AwesomePlayer::seekTo(int64_t timeUs) { return OK; } -status_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) { - if (mTextDriver != NULL) { - if (index >= 0) { // to turn on a text track - status_t err = mTextDriver->setTimedTextTrackIndex(index); - if (err != OK) { - return err; - } - - modifyFlags(TEXT_RUNNING, SET); - modifyFlags(TEXTPLAYER_STARTED, SET); - return OK; - } else { // to turn off the text track display - if (mFlags & TEXT_RUNNING) { - modifyFlags(TEXT_RUNNING, CLEAR); - } - if (mFlags & TEXTPLAYER_STARTED) { - modifyFlags(TEXTPLAYER_STARTED, CLEAR); - } - - return mTextDriver->setTimedTextTrackIndex(index); - } - } else { - return INVALID_OPERATION; - } -} - status_t AwesomePlayer::seekTo_l(int64_t timeUs) { if (mFlags & CACHE_UNDERRUN) { modifyFlags(CACHE_UNDERRUN, CLEAR); @@ -1315,7 +1289,7 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) { seekAudioIfNecessary_l(); - if (mFlags & TEXTPLAYER_STARTED) { + if (mFlags & TEXTPLAYER_INITIALIZED) { mTextDriver->seekToAsync(mSeekTimeUs); } @@ -1691,8 +1665,8 @@ void AwesomePlayer::onVideoEvent() { } } - if ((mFlags & TEXTPLAYER_STARTED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) { - mTextDriver->resume(); + if ((mFlags & TEXTPLAYER_INITIALIZED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) { + mTextDriver->start(); modifyFlags(TEXT_RUNNING, SET); } @@ -2232,20 +2206,6 @@ void AwesomePlayer::postAudioSeekComplete() { status_t AwesomePlayer::setParameter(int key, const Parcel &request) { switch (key) { - case KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX: - { - Mutex::Autolock autoLock(mTimedTextLock); - return setTimedTextTrackIndex(request.readInt32()); - } - case KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE: - { - Mutex::Autolock autoLock(mTimedTextLock); - if (mTextDriver == NULL) { - mTextDriver = new TimedTextDriver(mListener); - } - - return mTextDriver->addOutOfBandTextSource(request); - } case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS: { return setCacheStatCollectFreq(request); @@ -2294,6 +2254,103 @@ status_t AwesomePlayer::getParameter(int key, Parcel *reply) { } } +status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { + if (NULL == reply) { + return android::BAD_VALUE; + } + int32_t methodId; + status_t ret = request.readInt32(&methodId); + if (ret != android::OK) { + return ret; + } + switch(methodId) { + case INVOKE_ID_GET_TRACK_INFO: + { + Mutex::Autolock autoLock(mTimedTextLock); + if (mTextDriver == NULL) { + return INVALID_OPERATION; + } + mTextDriver->getTrackInfo(reply); + return OK; + } + case INVOKE_ID_ADD_EXTERNAL_SOURCE: + { + Mutex::Autolock autoLock(mTimedTextLock); + if (mTextDriver == NULL) { + mTextDriver = new TimedTextDriver(mListener); + } + // String values written in Parcel are UTF-16 values. + String16 uri16 = request.readString16(); + const char *uri = NULL; + if (uri16 != NULL) { + uri = String8(uri16).string(); + } + String16 mimeType16 = request.readString16(); + const char *mimeType = NULL; + if (mimeType16 != NULL) { + mimeType = String8(mimeType16).string(); + } + return mTextDriver->addOutOfBandTextSource(uri, mimeType); + } + case INVOKE_ID_ADD_EXTERNAL_SOURCE_FD: + { + Mutex::Autolock autoLock(mTimedTextLock); + if (mTextDriver == NULL) { + mTextDriver = new TimedTextDriver(mListener); + } + int fd = request.readFileDescriptor(); + off64_t offset = request.readInt64(); + size_t length = request.readInt64(); + String16 mimeType16 = request.readString16(); + const char *mimeType = NULL; + if (mimeType16 != NULL) { + mimeType = String8(mimeType16).string(); + } + + return mTextDriver->addOutOfBandTextSource( + fd, offset, length, mimeType); + } + case INVOKE_ID_SELECT_TRACK: + { + Mutex::Autolock autoLock(mTimedTextLock); + if (mTextDriver == NULL) { + return INVALID_OPERATION; + } + + status_t err = mTextDriver->selectTrack( + request.readInt32()); + if (err == OK) { + modifyFlags(TEXTPLAYER_INITIALIZED, SET); + if (mFlags & PLAYING && !(mFlags & TEXT_RUNNING)) { + mTextDriver->start(); + modifyFlags(TEXT_RUNNING, SET); + } + } + return err; + } + case INVOKE_ID_UNSELECT_TRACK: + { + Mutex::Autolock autoLock(mTimedTextLock); + if (mTextDriver == NULL) { + return INVALID_OPERATION; + } + status_t err = mTextDriver->unselectTrack( + request.readInt32()); + if (err == OK) { + modifyFlags(TEXTPLAYER_INITIALIZED, CLEAR); + modifyFlags(TEXT_RUNNING, CLEAR); + } + return err; + } + default: + { + return ERROR_UNSUPPORTED; + } + } + // It will not reach here. + return OK; +} + bool AwesomePlayer::isStreamingHTTP() const { return mCachedSource != NULL || mWVMExtractor != NULL; } diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp index 444e823..2549de6 100644 --- a/media/libstagefright/MediaDefs.cpp +++ b/media/libstagefright/MediaDefs.cpp @@ -52,5 +52,6 @@ const char *MEDIA_MIMETYPE_CONTAINER_MPEG2PS = "video/mp2p"; 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"; } // namespace android diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 4c7bfa6..06e9468 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -90,6 +90,7 @@ struct AwesomePlayer { status_t setParameter(int key, const Parcel &request); status_t getParameter(int key, Parcel *reply); + status_t invoke(const Parcel &request, Parcel *reply); status_t setCacheStatCollectFreq(const Parcel &request); status_t seekTo(int64_t timeUs); @@ -100,8 +101,6 @@ struct AwesomePlayer { void postAudioEOS(int64_t delayUs = 0ll); void postAudioSeekComplete(); - status_t setTimedTextTrackIndex(int32_t index); - status_t dump(int fd, const Vector<String16> &args) const; private: @@ -136,7 +135,7 @@ private: INCOGNITO = 0x8000, TEXT_RUNNING = 0x10000, - TEXTPLAYER_STARTED = 0x20000, + TEXTPLAYER_INITIALIZED = 0x20000, SLOW_DECODER_HACK = 0x40000, }; diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.cpp b/media/libstagefright/timedtext/TimedText3GPPSource.cpp index 4a3bfd3..c423ef0 100644 --- a/media/libstagefright/timedtext/TimedText3GPPSource.cpp +++ b/media/libstagefright/timedtext/TimedText3GPPSource.cpp @@ -110,4 +110,8 @@ status_t TimedText3GPPSource::extractGlobalDescriptions(Parcel *parcel) { return OK; } +sp<MetaData> TimedText3GPPSource::getFormat() { + return mSource->getFormat(); +} + } // namespace android diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.h b/media/libstagefright/timedtext/TimedText3GPPSource.h index dfc6418..4ec3d8a 100644 --- a/media/libstagefright/timedtext/TimedText3GPPSource.h +++ b/media/libstagefright/timedtext/TimedText3GPPSource.h @@ -37,6 +37,7 @@ public: Parcel *parcel, const MediaSource::ReadOptions *options = NULL); virtual status_t extractGlobalDescriptions(Parcel *parcel); + virtual sp<MetaData> getFormat(); protected: virtual ~TimedText3GPPSource(); diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp index c70870e..ed83894 100644 --- a/media/libstagefright/timedtext/TimedTextDriver.cpp +++ b/media/libstagefright/timedtext/TimedTextDriver.cpp @@ -20,10 +20,13 @@ #include <binder/IPCThreadState.h> +#include <media/mediaplayer.h> #include <media/MediaPlayerInterface.h> +#include <media/stagefright/DataSource.h> +#include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MediaSource.h> -#include <media/stagefright/DataSource.h> +#include <media/stagefright/MetaData.h> #include <media/stagefright/Utils.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> @@ -47,24 +50,22 @@ TimedTextDriver::TimedTextDriver( } TimedTextDriver::~TimedTextDriver() { - mTextInBandVector.clear(); - mTextOutOfBandVector.clear(); + mTextSourceVector.clear(); mLooper->stop(); } -status_t TimedTextDriver::setTimedTextTrackIndex_l(int32_t index) { - if (index >= - (int)(mTextInBandVector.size() + mTextOutOfBandVector.size())) { +status_t TimedTextDriver::selectTrack_l(int32_t index) { + if (index >= (int)(mTextSourceVector.size())) { return BAD_VALUE; } sp<TimedTextSource> source; - if (index < mTextInBandVector.size()) { - source = mTextInBandVector.itemAt(index); - } else { - source = mTextOutOfBandVector.itemAt(index - mTextInBandVector.size()); - } + source = mTextSourceVector.itemAt(index); mPlayer->setDataSource(source); + if (mState == UNINITIALIZED) { + mState = PAUSED; + } + mCurrentTrackIndex = index; return OK; } @@ -73,13 +74,10 @@ status_t TimedTextDriver::start() { switch (mState) { case UNINITIALIZED: return INVALID_OPERATION; - case STOPPED: - mPlayer->start(); - break; case PLAYING: return OK; case PAUSED: - mPlayer->resume(); + mPlayer->start(); break; default: TRESPASS(); @@ -88,10 +86,6 @@ status_t TimedTextDriver::start() { return OK; } -status_t TimedTextDriver::stop() { - return pause(); -} - // TODO: Test if pause() works properly. // Scenario 1: start - pause - resume // Scenario 2: start - seek @@ -101,8 +95,6 @@ status_t TimedTextDriver::pause() { switch (mState) { case UNINITIALIZED: return INVALID_OPERATION; - case STOPPED: - return OK; case PLAYING: mPlayer->pause(); break; @@ -115,45 +107,17 @@ status_t TimedTextDriver::pause() { return OK; } -status_t TimedTextDriver::resume() { - return start(); -} - -status_t TimedTextDriver::seekToAsync(int64_t timeUs) { - mPlayer->seekToAsync(timeUs); - return OK; -} - -status_t TimedTextDriver::setTimedTextTrackIndex(int32_t index) { - // TODO: This is current implementation for MediaPlayer::disableTimedText(). - // Find better way for readability. - if (index < 0) { - mPlayer->pause(); - return OK; - } - +status_t TimedTextDriver::selectTrack(int32_t index) { status_t ret = OK; Mutex::Autolock autoLock(mLock); switch (mState) { case UNINITIALIZED: - ret = INVALID_OPERATION; - break; case PAUSED: - ret = setTimedTextTrackIndex_l(index); + ret = selectTrack_l(index); break; case PLAYING: mPlayer->pause(); - ret = setTimedTextTrackIndex_l(index); - if (ret != OK) { - break; - } - mPlayer->start(); - break; - case STOPPED: - // TODO: The only difference between STOPPED and PAUSED is this - // part. Revise the flow from "MediaPlayer::enableTimedText()" and - // remove one of the status, PAUSED and STOPPED, if possible. - ret = setTimedTextTrackIndex_l(index); + ret = selectTrack_l(index); if (ret != OK) { break; } @@ -165,6 +129,24 @@ status_t TimedTextDriver::setTimedTextTrackIndex(int32_t index) { return ret; } +status_t TimedTextDriver::unselectTrack(int32_t index) { + if (mCurrentTrackIndex != index) { + return INVALID_OPERATION; + } + status_t err = pause(); + if (err != OK) { + return err; + } + Mutex::Autolock autoLock(mLock); + mState = UNINITIALIZED; + return OK; +} + +status_t TimedTextDriver::seekToAsync(int64_t timeUs) { + mPlayer->seekToAsync(timeUs); + return OK; +} + status_t TimedTextDriver::addInBandTextSource( const sp<MediaSource>& mediaSource) { sp<TimedTextSource> source = @@ -173,25 +155,17 @@ status_t TimedTextDriver::addInBandTextSource( return ERROR_UNSUPPORTED; } Mutex::Autolock autoLock(mLock); - mTextInBandVector.add(source); - if (mState == UNINITIALIZED) { - mState = STOPPED; - } + mTextSourceVector.add(source); return OK; } status_t TimedTextDriver::addOutOfBandTextSource( - const Parcel &request) { + const char *uri, const char *mimeType) { // TODO: Define "TimedTextSource::CreateFromURI(uri)" // and move below lines there..? - // String values written in Parcel are UTF-16 values. - const String16 uri16 = request.readString16(); - String8 uri = String8(request.readString16()); - - uri.toLower(); // To support local subtitle file only for now - if (strncasecmp("file://", uri.string(), 7)) { + if (strncasecmp("file://", uri, 7)) { return ERROR_UNSUPPORTED; } sp<DataSource> dataSource = @@ -201,7 +175,7 @@ status_t TimedTextDriver::addOutOfBandTextSource( } sp<TimedTextSource> source; - if (uri.getPathExtension() == String8(".srt")) { + if (strcasecmp(mimeType, MEDIA_MIMETYPE_TEXT_SUBRIP)) { source = TimedTextSource::CreateTimedTextSource( dataSource, TimedTextSource::OUT_OF_BAND_FILE_SRT); } @@ -211,12 +185,38 @@ status_t TimedTextDriver::addOutOfBandTextSource( } Mutex::Autolock autoLock(mLock); + mTextSourceVector.add(source); + return OK; +} - mTextOutOfBandVector.add(source); - if (mState == UNINITIALIZED) { - mState = STOPPED; +status_t TimedTextDriver::addOutOfBandTextSource( + int fd, off64_t offset, size_t length, const char *mimeType) { + // Not supported yet. This requires DataSource::sniff to detect various text + // formats such as srt/smi/ttml. + return ERROR_UNSUPPORTED; +} + +void TimedTextDriver::getTrackInfo(Parcel *parcel) { + Mutex::Autolock autoLock(mLock); + Vector<sp<TimedTextSource> >::const_iterator iter; + parcel->writeInt32(mTextSourceVector.size()); + for (iter = mTextSourceVector.begin(); + iter != mTextSourceVector.end(); ++iter) { + sp<MetaData> meta = (*iter)->getFormat(); + if (meta != NULL) { + // There are two fields. + parcel->writeInt32(2); + + // track type. + parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT); + + const char *lang = "und"; + meta->findCString(kKeyMediaLanguage, &lang); + parcel->writeString16(String16(lang)); + } else { + parcel->writeInt32(0); + } } - return OK; } } // namespace android diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp index bda7b46..8717914 100644 --- a/media/libstagefright/timedtext/TimedTextPlayer.cpp +++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp @@ -56,10 +56,6 @@ void TimedTextPlayer::pause() { (new AMessage(kWhatPause, id()))->post(); } -void TimedTextPlayer::resume() { - start(); -} - void TimedTextPlayer::seekToAsync(int64_t timeUs) { sp<AMessage> msg = new AMessage(kWhatSeek, id()); msg->setInt64("seekTimeUs", timeUs); @@ -104,9 +100,9 @@ void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) { if (obj != NULL) { sp<ParcelEvent> parcelEvent; parcelEvent = static_cast<ParcelEvent*>(obj.get()); - notifyListener(MEDIA_TIMED_TEXT, &(parcelEvent->parcel)); + notifyListener(&(parcelEvent->parcel)); } else { - notifyListener(MEDIA_TIMED_TEXT); + notifyListener(); } doRead(); break; @@ -119,14 +115,18 @@ void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) { mSource->stop(); } mSource = static_cast<TimedTextSource*>(obj.get()); - mSource->start(); + status_t err = mSource->start(); + if (err != OK) { + notifyError(err); + break; + } Parcel parcel; - if (mSource->extractGlobalDescriptions(&parcel) == OK && - parcel.dataSize() > 0) { - notifyListener(MEDIA_TIMED_TEXT, &parcel); - } else { - notifyListener(MEDIA_TIMED_TEXT); + err = mSource->extractGlobalDescriptions(&parcel); + if (err != OK) { + notifyError(err); + break; } + notifyListener(&parcel); break; } } @@ -141,8 +141,12 @@ void TimedTextPlayer::doSeekAndRead(int64_t seekTimeUs) { void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) { int64_t timeUs = 0; sp<ParcelEvent> parcelEvent = new ParcelEvent(); - mSource->read(&timeUs, &(parcelEvent->parcel), options); - postTextEvent(parcelEvent, timeUs); + status_t err = mSource->read(&timeUs, &(parcelEvent->parcel), options); + if (err != OK) { + notifyError(err); + } else { + postTextEvent(parcelEvent, timeUs); + } } void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeUs) { @@ -151,7 +155,7 @@ void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeU int64_t positionUs, delayUs; int32_t positionMs = 0; listener->getCurrentPosition(&positionMs); - positionUs = positionMs * 1000; + positionUs = positionMs * 1000ll; if (timeUs <= positionUs + kAdjustmentProcessingTimeUs) { delayUs = 0; @@ -167,13 +171,20 @@ void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeU } } -void TimedTextPlayer::notifyListener(int msg, const Parcel *parcel) { +void TimedTextPlayer::notifyError(int error) { + sp<MediaPlayerBase> listener = mListener.promote(); + if (listener != NULL) { + listener->sendEvent(MEDIA_INFO, MEDIA_INFO_TIMED_TEXT_ERROR, error); + } +} + +void TimedTextPlayer::notifyListener(const Parcel *parcel) { sp<MediaPlayerBase> listener = mListener.promote(); if (listener != NULL) { if (parcel != NULL && (parcel->dataSize() > 0)) { - listener->sendEvent(msg, 0, 0, parcel); + listener->sendEvent(MEDIA_TIMED_TEXT, 0, 0, parcel); } else { // send an empty timed text to clear the screen - listener->sendEvent(msg); + listener->sendEvent(MEDIA_TIMED_TEXT); } } } diff --git a/media/libstagefright/timedtext/TimedTextPlayer.h b/media/libstagefright/timedtext/TimedTextPlayer.h index 837beeb..b869f18 100644 --- a/media/libstagefright/timedtext/TimedTextPlayer.h +++ b/media/libstagefright/timedtext/TimedTextPlayer.h @@ -40,7 +40,6 @@ public: void start(); void pause(); - void resume(); void seekToAsync(int64_t timeUs); void setDataSource(sp<TimedTextSource> source); @@ -68,7 +67,8 @@ private: void doRead(MediaSource::ReadOptions* options = NULL); void onTextEvent(); void postTextEvent(const sp<ParcelEvent>& parcel = NULL, int64_t timeUs = -1); - void notifyListener(int msg, const Parcel *parcel = NULL); + void notifyError(int error = 0); + void notifyListener(const Parcel *parcel = NULL); DISALLOW_EVIL_CONSTRUCTORS(TimedTextPlayer); }; diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.cpp b/media/libstagefright/timedtext/TimedTextSRTSource.cpp index 3752d34..c44a99b 100644 --- a/media/libstagefright/timedtext/TimedTextSRTSource.cpp +++ b/media/libstagefright/timedtext/TimedTextSRTSource.cpp @@ -21,8 +21,10 @@ #include <binder/Parcel.h> #include <media/stagefright/foundation/AString.h> #include <media/stagefright/DataSource.h> +#include <media/stagefright/MediaDefs.h> // for MEDIA_MIMETYPE_xxx #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MediaSource.h> +#include <media/stagefright/MetaData.h> #include "TimedTextSRTSource.h" #include "TextDescriptions.h" @@ -31,6 +33,7 @@ namespace android { TimedTextSRTSource::TimedTextSRTSource(const sp<DataSource>& dataSource) : mSource(dataSource), + mMetaData(new MetaData), mIndex(0) { } @@ -42,10 +45,14 @@ status_t TimedTextSRTSource::start() { if (err != OK) { reset(); } + // TODO: Need to detect the language, because SRT doesn't give language + // information explicitly. + mMetaData->setCString(kKeyMediaLanguage, ""); return err; } void TimedTextSRTSource::reset() { + mMetaData->clear(); mTextVector.clear(); mIndex = 0; } @@ -272,4 +279,8 @@ status_t TimedTextSRTSource::extractAndAppendLocalDescriptions( return OK; } +sp<MetaData> TimedTextSRTSource::getFormat() { + return mMetaData; +} + } // namespace android diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.h b/media/libstagefright/timedtext/TimedTextSRTSource.h index acc01f9..62710a0 100644 --- a/media/libstagefright/timedtext/TimedTextSRTSource.h +++ b/media/libstagefright/timedtext/TimedTextSRTSource.h @@ -39,12 +39,14 @@ public: int64_t *timeUs, Parcel *parcel, const MediaSource::ReadOptions *options = NULL); + virtual sp<MetaData> getFormat(); protected: virtual ~TimedTextSRTSource(); private: sp<DataSource> mSource; + sp<MetaData> mMetaData; struct TextInfo { int64_t endTimeUs; diff --git a/media/libstagefright/timedtext/TimedTextSource.cpp b/media/libstagefright/timedtext/TimedTextSource.cpp index ffbe1c3..953f7b5 100644 --- a/media/libstagefright/timedtext/TimedTextSource.cpp +++ b/media/libstagefright/timedtext/TimedTextSource.cpp @@ -59,4 +59,8 @@ sp<TimedTextSource> TimedTextSource::CreateTimedTextSource( return NULL; } +sp<MetaData> TimedTextSource::getFormat() { + return NULL; +} + } // namespace android diff --git a/media/libstagefright/timedtext/TimedTextSource.h b/media/libstagefright/timedtext/TimedTextSource.h index 06bae71..9349342 100644 --- a/media/libstagefright/timedtext/TimedTextSource.h +++ b/media/libstagefright/timedtext/TimedTextSource.h @@ -25,6 +25,7 @@ namespace android { class DataSource; +class MetaData; class Parcel; class TimedTextSource : public RefBase { @@ -48,6 +49,7 @@ class TimedTextSource : public RefBase { virtual status_t extractGlobalDescriptions(Parcel *parcel) { return INVALID_OPERATION; } + virtual sp<MetaData> getFormat(); protected: virtual ~TimedTextSource() { } |