Loading include/media/stagefright/timedtext/TimedTextDriver.h +20 −10 Original line number Diff line number Diff line Loading @@ -40,18 +40,24 @@ public: status_t start(); status_t pause(); status_t selectTrack(int32_t index); status_t unselectTrack(int32_t index); status_t selectTrack(size_t index); status_t unselectTrack(size_t index); status_t seekToAsync(int64_t timeUs); status_t addInBandTextSource(const sp<MediaSource>& source); status_t addOutOfBandTextSource(const char *uri, const char *mimeType); status_t addInBandTextSource( size_t trackIndex, const sp<MediaSource>& source); status_t addOutOfBandTextSource( size_t trackIndex, const char *uri, const char *mimeType); // Caller owns the file desriptor and caller is responsible for closing it. status_t addOutOfBandTextSource( int fd, off64_t offset, off64_t length, const char *mimeType); size_t trackIndex, int fd, off64_t offset, off64_t length, const char *mimeType); void getTrackInfo(Parcel *parcel); void getExternalTrackInfo(Parcel *parcel); size_t countExternalTracks() const; private: Mutex mLock; Loading @@ -68,13 +74,17 @@ private: // Variables to be guarded by mLock. State mState; int32_t mCurrentTrackIndex; Vector<sp<TimedTextSource> > mTextSourceVector; size_t mCurrentTrackIndex; KeyedVector<size_t, sp<TimedTextSource> > mTextSourceVector; Vector<bool> mTextSourceTypeVector; // -- End of variables to be guarded by mLock status_t selectTrack_l(int32_t index); status_t selectTrack_l(size_t index); status_t createOutOfBandTextSource( const char *mimeType, const sp<DataSource>& dataSource); size_t trackIndex, const char* mimeType, const sp<DataSource>& dataSource); DISALLOW_EVIL_CONSTRUCTORS(TimedTextDriver); }; Loading media/libstagefright/AwesomePlayer.cpp +102 −37 Original line number Diff line number Diff line Loading @@ -356,6 +356,7 @@ status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) { int64_t totalBitRate = 0; mExtractor = extractor; for (size_t i = 0; i < extractor->countTracks(); ++i) { sp<MetaData> meta = extractor->getTrackMetaData(i); Loading Loading @@ -443,7 +444,7 @@ status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) { } } } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) { addTextSource(extractor->getTrack(i)); addTextSource(i, extractor->getTrack(i)); } } Loading Loading @@ -507,6 +508,7 @@ void AwesomePlayer::reset_l() { mCachedSource.clear(); mAudioTrack.clear(); mVideoTrack.clear(); mExtractor.clear(); // Shutdown audio first, so that the respone to the reset request // appears to happen instantaneously as far as the user is concerned Loading Loading @@ -1331,7 +1333,7 @@ void AwesomePlayer::setAudioSource(sp<MediaSource> source) { mAudioTrack = source; } void AwesomePlayer::addTextSource(const sp<MediaSource>& source) { void AwesomePlayer::addTextSource(size_t trackIndex, const sp<MediaSource>& source) { Mutex::Autolock autoLock(mTimedTextLock); CHECK(source != NULL); Loading @@ -1339,7 +1341,7 @@ void AwesomePlayer::addTextSource(const sp<MediaSource>& source) { mTextDriver = new TimedTextDriver(mListener); } mTextDriver->addInBandTextSource(source); mTextDriver->addInBandTextSource(trackIndex, source); } status_t AwesomePlayer::initAudioDecoder() { Loading Loading @@ -2254,6 +2256,94 @@ status_t AwesomePlayer::getParameter(int key, Parcel *reply) { } } status_t AwesomePlayer::getTrackInfo(Parcel *reply) const { Mutex::Autolock autoLock(mTimedTextLock); if (mTextDriver == NULL) { return INVALID_OPERATION; } reply->writeInt32(mTextDriver->countExternalTracks() + mExtractor->countTracks()); for (size_t i = 0; i < mExtractor->countTracks(); ++i) { sp<MetaData> meta = mExtractor->getTrackMetaData(i); const char *_mime; CHECK(meta->findCString(kKeyMIMEType, &_mime)); String8 mime = String8(_mime); reply->writeInt32(2); // 2 fields if (!strncasecmp(mime.string(), "video/", 6)) { reply->writeInt32(MEDIA_TRACK_TYPE_VIDEO); } else if (!strncasecmp(mime.string(), "audio/", 6)) { reply->writeInt32(MEDIA_TRACK_TYPE_AUDIO); } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) { reply->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT); } else { reply->writeInt32(MEDIA_TRACK_TYPE_UNKNOWN); } const char *lang; if (meta->findCString(kKeyMediaLanguage, &lang)) { reply->writeString16(String16(lang)); } else { reply->writeString16(String16("")); } } mTextDriver->getExternalTrackInfo(reply); return OK; } // FIXME: // At present, only timed text track is able to be selected or unselected. status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) { Mutex::Autolock autoLock(mTimedTextLock); if (mTextDriver == NULL) { return INVALID_OPERATION; } if (trackIndex >= mExtractor->countTracks() + mTextDriver->countExternalTracks()) { return BAD_VALUE; } if (trackIndex < mExtractor->countTracks()) { sp<MetaData> meta = mExtractor->getTrackMetaData(trackIndex); const char *_mime; CHECK(meta->findCString(kKeyMIMEType, &_mime)); String8 mime = String8(_mime); if (strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) { return ERROR_UNSUPPORTED; } } status_t err = OK; if (select) { err = mTextDriver->selectTrack(trackIndex); if (err == OK) { modifyFlags(TEXTPLAYER_INITIALIZED, SET); if (mFlags & PLAYING && !(mFlags & TEXT_RUNNING)) { mTextDriver->start(); modifyFlags(TEXT_RUNNING, SET); } } } else { err = mTextDriver->unselectTrack(trackIndex); if (err == OK) { modifyFlags(TEXTPLAYER_INITIALIZED, CLEAR); modifyFlags(TEXT_RUNNING, CLEAR); } } return err; } size_t AwesomePlayer::countTracks() const { return mExtractor->countTracks() + mTextDriver->countExternalTracks(); } status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { if (NULL == reply) { return android::BAD_VALUE; Loading @@ -2266,12 +2356,7 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { switch(methodId) { case INVOKE_ID_GET_TRACK_INFO: { Mutex::Autolock autoLock(mTimedTextLock); if (mTextDriver == NULL) { return INVALID_OPERATION; } mTextDriver->getTrackInfo(reply); return OK; return getTrackInfo(reply); } case INVOKE_ID_ADD_EXTERNAL_SOURCE: { Loading @@ -2282,7 +2367,8 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { // String values written in Parcel are UTF-16 values. String8 uri(request.readString16()); String8 mimeType(request.readString16()); return mTextDriver->addOutOfBandTextSource(uri, mimeType); size_t nTracks = countTracks(); return mTextDriver->addOutOfBandTextSource(nTracks, uri, mimeType); } case INVOKE_ID_ADD_EXTERNAL_SOURCE_FD: { Loading @@ -2294,40 +2380,19 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { off64_t offset = request.readInt64(); off64_t length = request.readInt64(); String8 mimeType(request.readString16()); size_t nTracks = countTracks(); return mTextDriver->addOutOfBandTextSource( fd, offset, length, mimeType); nTracks, 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; int trackIndex = request.readInt32(); return selectTrack(trackIndex, true); } 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; int trackIndex = request.readInt32(); return selectTrack(trackIndex, false); } default: { Loading media/libstagefright/include/AwesomePlayer.h +10 −1 Original line number Diff line number Diff line Loading @@ -235,6 +235,7 @@ private: mutable Mutex mTimedTextLock; sp<WVMExtractor> mWVMExtractor; sp<MediaExtractor> mExtractor; status_t setDataSource_l( const char *uri, Loading @@ -257,7 +258,7 @@ private: void setVideoSource(sp<MediaSource> source); status_t initVideoDecoder(uint32_t flags = 0); void addTextSource(const sp<MediaSource>& source); void addTextSource(size_t trackIndex, const sp<MediaSource>& source); void onStreamDone(); Loading Loading @@ -318,6 +319,14 @@ private: Vector<TrackStat> mTracks; } mStats; status_t getTrackInfo(Parcel* reply) const; // when select is true, the given track is selected. // otherwise, the given track is unselected. status_t selectTrack(size_t trackIndex, bool select); size_t countTracks() const; AwesomePlayer(const AwesomePlayer &); AwesomePlayer &operator=(const AwesomePlayer &); }; Loading media/libstagefright/timedtext/TimedTextDriver.cpp +36 −23 Original line number Diff line number Diff line Loading @@ -52,16 +52,13 @@ TimedTextDriver::TimedTextDriver( TimedTextDriver::~TimedTextDriver() { mTextSourceVector.clear(); mTextSourceTypeVector.clear(); mLooper->stop(); } status_t TimedTextDriver::selectTrack_l(int32_t index) { if (index >= (int)(mTextSourceVector.size())) { return BAD_VALUE; } status_t TimedTextDriver::selectTrack_l(size_t index) { sp<TimedTextSource> source; source = mTextSourceVector.itemAt(index); source = mTextSourceVector.valueFor(index); mPlayer->setDataSource(source); if (mState == UNINITIALIZED) { mState = PAUSED; Loading Loading @@ -108,7 +105,7 @@ status_t TimedTextDriver::pause() { return OK; } status_t TimedTextDriver::selectTrack(int32_t index) { status_t TimedTextDriver::selectTrack(size_t index) { status_t ret = OK; Mutex::Autolock autoLock(mLock); switch (mState) { Loading @@ -130,7 +127,7 @@ status_t TimedTextDriver::selectTrack(int32_t index) { return ret; } status_t TimedTextDriver::unselectTrack(int32_t index) { status_t TimedTextDriver::unselectTrack(size_t index) { if (mCurrentTrackIndex != index) { return INVALID_OPERATION; } Loading @@ -149,19 +146,21 @@ status_t TimedTextDriver::seekToAsync(int64_t timeUs) { } status_t TimedTextDriver::addInBandTextSource( const sp<MediaSource>& mediaSource) { size_t trackIndex, const sp<MediaSource>& mediaSource) { sp<TimedTextSource> source = TimedTextSource::CreateTimedTextSource(mediaSource); if (source == NULL) { return ERROR_UNSUPPORTED; } Mutex::Autolock autoLock(mLock); mTextSourceVector.add(source); mTextSourceVector.add(trackIndex, source); mTextSourceTypeVector.add(true); return OK; } status_t TimedTextDriver::addOutOfBandTextSource( const char *uri, const char *mimeType) { size_t trackIndex, const char *uri, const char *mimeType) { // To support local subtitle file only for now if (strncasecmp("file://", uri, 7)) { ALOGE("uri('%s') is not a file", uri); Loading @@ -170,11 +169,11 @@ status_t TimedTextDriver::addOutOfBandTextSource( sp<DataSource> dataSource = DataSource::CreateFromURI(uri); return createOutOfBandTextSource(mimeType, dataSource); return createOutOfBandTextSource(trackIndex, mimeType, dataSource); } status_t TimedTextDriver::addOutOfBandTextSource( int fd, off64_t offset, off64_t length, const char *mimeType) { size_t trackIndex, int fd, off64_t offset, off64_t length, const char *mimeType) { if (fd < 0) { ALOGE("Invalid file descriptor: %d", fd); Loading @@ -182,11 +181,13 @@ status_t TimedTextDriver::addOutOfBandTextSource( } sp<DataSource> dataSource = new FileSource(dup(fd), offset, length); return createOutOfBandTextSource(mimeType, dataSource); return createOutOfBandTextSource(trackIndex, mimeType, dataSource); } status_t TimedTextDriver::createOutOfBandTextSource( const char *mimeType, const sp<DataSource>& dataSource) { size_t trackIndex, const char *mimeType, const sp<DataSource>& dataSource) { if (dataSource == NULL) { return ERROR_UNSUPPORTED; Loading @@ -199,28 +200,40 @@ status_t TimedTextDriver::createOutOfBandTextSource( } if (source == NULL) { ALOGE("Failed to create timed text source"); return ERROR_UNSUPPORTED; } Mutex::Autolock autoLock(mLock); mTextSourceVector.add(source); mTextSourceVector.add(trackIndex, source); mTextSourceTypeVector.add(false); return OK; } void TimedTextDriver::getTrackInfo(Parcel *parcel) { size_t TimedTextDriver::countExternalTracks() const { size_t nTracks = 0; for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) { if (!mTextSourceTypeVector[i]) { ++nTracks; } } return nTracks; } void TimedTextDriver::getExternalTrackInfo(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(); for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) { if (mTextSourceTypeVector[i]) { continue; } sp<MetaData> meta = mTextSourceVector.valueAt(i)->getFormat(); // There are two fields. parcel->writeInt32(2); // track type. parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT); const char *lang = "und"; if (meta != NULL) { meta->findCString(kKeyMediaLanguage, &lang); Loading Loading
include/media/stagefright/timedtext/TimedTextDriver.h +20 −10 Original line number Diff line number Diff line Loading @@ -40,18 +40,24 @@ public: status_t start(); status_t pause(); status_t selectTrack(int32_t index); status_t unselectTrack(int32_t index); status_t selectTrack(size_t index); status_t unselectTrack(size_t index); status_t seekToAsync(int64_t timeUs); status_t addInBandTextSource(const sp<MediaSource>& source); status_t addOutOfBandTextSource(const char *uri, const char *mimeType); status_t addInBandTextSource( size_t trackIndex, const sp<MediaSource>& source); status_t addOutOfBandTextSource( size_t trackIndex, const char *uri, const char *mimeType); // Caller owns the file desriptor and caller is responsible for closing it. status_t addOutOfBandTextSource( int fd, off64_t offset, off64_t length, const char *mimeType); size_t trackIndex, int fd, off64_t offset, off64_t length, const char *mimeType); void getTrackInfo(Parcel *parcel); void getExternalTrackInfo(Parcel *parcel); size_t countExternalTracks() const; private: Mutex mLock; Loading @@ -68,13 +74,17 @@ private: // Variables to be guarded by mLock. State mState; int32_t mCurrentTrackIndex; Vector<sp<TimedTextSource> > mTextSourceVector; size_t mCurrentTrackIndex; KeyedVector<size_t, sp<TimedTextSource> > mTextSourceVector; Vector<bool> mTextSourceTypeVector; // -- End of variables to be guarded by mLock status_t selectTrack_l(int32_t index); status_t selectTrack_l(size_t index); status_t createOutOfBandTextSource( const char *mimeType, const sp<DataSource>& dataSource); size_t trackIndex, const char* mimeType, const sp<DataSource>& dataSource); DISALLOW_EVIL_CONSTRUCTORS(TimedTextDriver); }; Loading
media/libstagefright/AwesomePlayer.cpp +102 −37 Original line number Diff line number Diff line Loading @@ -356,6 +356,7 @@ status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) { int64_t totalBitRate = 0; mExtractor = extractor; for (size_t i = 0; i < extractor->countTracks(); ++i) { sp<MetaData> meta = extractor->getTrackMetaData(i); Loading Loading @@ -443,7 +444,7 @@ status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) { } } } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) { addTextSource(extractor->getTrack(i)); addTextSource(i, extractor->getTrack(i)); } } Loading Loading @@ -507,6 +508,7 @@ void AwesomePlayer::reset_l() { mCachedSource.clear(); mAudioTrack.clear(); mVideoTrack.clear(); mExtractor.clear(); // Shutdown audio first, so that the respone to the reset request // appears to happen instantaneously as far as the user is concerned Loading Loading @@ -1331,7 +1333,7 @@ void AwesomePlayer::setAudioSource(sp<MediaSource> source) { mAudioTrack = source; } void AwesomePlayer::addTextSource(const sp<MediaSource>& source) { void AwesomePlayer::addTextSource(size_t trackIndex, const sp<MediaSource>& source) { Mutex::Autolock autoLock(mTimedTextLock); CHECK(source != NULL); Loading @@ -1339,7 +1341,7 @@ void AwesomePlayer::addTextSource(const sp<MediaSource>& source) { mTextDriver = new TimedTextDriver(mListener); } mTextDriver->addInBandTextSource(source); mTextDriver->addInBandTextSource(trackIndex, source); } status_t AwesomePlayer::initAudioDecoder() { Loading Loading @@ -2254,6 +2256,94 @@ status_t AwesomePlayer::getParameter(int key, Parcel *reply) { } } status_t AwesomePlayer::getTrackInfo(Parcel *reply) const { Mutex::Autolock autoLock(mTimedTextLock); if (mTextDriver == NULL) { return INVALID_OPERATION; } reply->writeInt32(mTextDriver->countExternalTracks() + mExtractor->countTracks()); for (size_t i = 0; i < mExtractor->countTracks(); ++i) { sp<MetaData> meta = mExtractor->getTrackMetaData(i); const char *_mime; CHECK(meta->findCString(kKeyMIMEType, &_mime)); String8 mime = String8(_mime); reply->writeInt32(2); // 2 fields if (!strncasecmp(mime.string(), "video/", 6)) { reply->writeInt32(MEDIA_TRACK_TYPE_VIDEO); } else if (!strncasecmp(mime.string(), "audio/", 6)) { reply->writeInt32(MEDIA_TRACK_TYPE_AUDIO); } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) { reply->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT); } else { reply->writeInt32(MEDIA_TRACK_TYPE_UNKNOWN); } const char *lang; if (meta->findCString(kKeyMediaLanguage, &lang)) { reply->writeString16(String16(lang)); } else { reply->writeString16(String16("")); } } mTextDriver->getExternalTrackInfo(reply); return OK; } // FIXME: // At present, only timed text track is able to be selected or unselected. status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) { Mutex::Autolock autoLock(mTimedTextLock); if (mTextDriver == NULL) { return INVALID_OPERATION; } if (trackIndex >= mExtractor->countTracks() + mTextDriver->countExternalTracks()) { return BAD_VALUE; } if (trackIndex < mExtractor->countTracks()) { sp<MetaData> meta = mExtractor->getTrackMetaData(trackIndex); const char *_mime; CHECK(meta->findCString(kKeyMIMEType, &_mime)); String8 mime = String8(_mime); if (strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) { return ERROR_UNSUPPORTED; } } status_t err = OK; if (select) { err = mTextDriver->selectTrack(trackIndex); if (err == OK) { modifyFlags(TEXTPLAYER_INITIALIZED, SET); if (mFlags & PLAYING && !(mFlags & TEXT_RUNNING)) { mTextDriver->start(); modifyFlags(TEXT_RUNNING, SET); } } } else { err = mTextDriver->unselectTrack(trackIndex); if (err == OK) { modifyFlags(TEXTPLAYER_INITIALIZED, CLEAR); modifyFlags(TEXT_RUNNING, CLEAR); } } return err; } size_t AwesomePlayer::countTracks() const { return mExtractor->countTracks() + mTextDriver->countExternalTracks(); } status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { if (NULL == reply) { return android::BAD_VALUE; Loading @@ -2266,12 +2356,7 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { switch(methodId) { case INVOKE_ID_GET_TRACK_INFO: { Mutex::Autolock autoLock(mTimedTextLock); if (mTextDriver == NULL) { return INVALID_OPERATION; } mTextDriver->getTrackInfo(reply); return OK; return getTrackInfo(reply); } case INVOKE_ID_ADD_EXTERNAL_SOURCE: { Loading @@ -2282,7 +2367,8 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { // String values written in Parcel are UTF-16 values. String8 uri(request.readString16()); String8 mimeType(request.readString16()); return mTextDriver->addOutOfBandTextSource(uri, mimeType); size_t nTracks = countTracks(); return mTextDriver->addOutOfBandTextSource(nTracks, uri, mimeType); } case INVOKE_ID_ADD_EXTERNAL_SOURCE_FD: { Loading @@ -2294,40 +2380,19 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { off64_t offset = request.readInt64(); off64_t length = request.readInt64(); String8 mimeType(request.readString16()); size_t nTracks = countTracks(); return mTextDriver->addOutOfBandTextSource( fd, offset, length, mimeType); nTracks, 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; int trackIndex = request.readInt32(); return selectTrack(trackIndex, true); } 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; int trackIndex = request.readInt32(); return selectTrack(trackIndex, false); } default: { Loading
media/libstagefright/include/AwesomePlayer.h +10 −1 Original line number Diff line number Diff line Loading @@ -235,6 +235,7 @@ private: mutable Mutex mTimedTextLock; sp<WVMExtractor> mWVMExtractor; sp<MediaExtractor> mExtractor; status_t setDataSource_l( const char *uri, Loading @@ -257,7 +258,7 @@ private: void setVideoSource(sp<MediaSource> source); status_t initVideoDecoder(uint32_t flags = 0); void addTextSource(const sp<MediaSource>& source); void addTextSource(size_t trackIndex, const sp<MediaSource>& source); void onStreamDone(); Loading Loading @@ -318,6 +319,14 @@ private: Vector<TrackStat> mTracks; } mStats; status_t getTrackInfo(Parcel* reply) const; // when select is true, the given track is selected. // otherwise, the given track is unselected. status_t selectTrack(size_t trackIndex, bool select); size_t countTracks() const; AwesomePlayer(const AwesomePlayer &); AwesomePlayer &operator=(const AwesomePlayer &); }; Loading
media/libstagefright/timedtext/TimedTextDriver.cpp +36 −23 Original line number Diff line number Diff line Loading @@ -52,16 +52,13 @@ TimedTextDriver::TimedTextDriver( TimedTextDriver::~TimedTextDriver() { mTextSourceVector.clear(); mTextSourceTypeVector.clear(); mLooper->stop(); } status_t TimedTextDriver::selectTrack_l(int32_t index) { if (index >= (int)(mTextSourceVector.size())) { return BAD_VALUE; } status_t TimedTextDriver::selectTrack_l(size_t index) { sp<TimedTextSource> source; source = mTextSourceVector.itemAt(index); source = mTextSourceVector.valueFor(index); mPlayer->setDataSource(source); if (mState == UNINITIALIZED) { mState = PAUSED; Loading Loading @@ -108,7 +105,7 @@ status_t TimedTextDriver::pause() { return OK; } status_t TimedTextDriver::selectTrack(int32_t index) { status_t TimedTextDriver::selectTrack(size_t index) { status_t ret = OK; Mutex::Autolock autoLock(mLock); switch (mState) { Loading @@ -130,7 +127,7 @@ status_t TimedTextDriver::selectTrack(int32_t index) { return ret; } status_t TimedTextDriver::unselectTrack(int32_t index) { status_t TimedTextDriver::unselectTrack(size_t index) { if (mCurrentTrackIndex != index) { return INVALID_OPERATION; } Loading @@ -149,19 +146,21 @@ status_t TimedTextDriver::seekToAsync(int64_t timeUs) { } status_t TimedTextDriver::addInBandTextSource( const sp<MediaSource>& mediaSource) { size_t trackIndex, const sp<MediaSource>& mediaSource) { sp<TimedTextSource> source = TimedTextSource::CreateTimedTextSource(mediaSource); if (source == NULL) { return ERROR_UNSUPPORTED; } Mutex::Autolock autoLock(mLock); mTextSourceVector.add(source); mTextSourceVector.add(trackIndex, source); mTextSourceTypeVector.add(true); return OK; } status_t TimedTextDriver::addOutOfBandTextSource( const char *uri, const char *mimeType) { size_t trackIndex, const char *uri, const char *mimeType) { // To support local subtitle file only for now if (strncasecmp("file://", uri, 7)) { ALOGE("uri('%s') is not a file", uri); Loading @@ -170,11 +169,11 @@ status_t TimedTextDriver::addOutOfBandTextSource( sp<DataSource> dataSource = DataSource::CreateFromURI(uri); return createOutOfBandTextSource(mimeType, dataSource); return createOutOfBandTextSource(trackIndex, mimeType, dataSource); } status_t TimedTextDriver::addOutOfBandTextSource( int fd, off64_t offset, off64_t length, const char *mimeType) { size_t trackIndex, int fd, off64_t offset, off64_t length, const char *mimeType) { if (fd < 0) { ALOGE("Invalid file descriptor: %d", fd); Loading @@ -182,11 +181,13 @@ status_t TimedTextDriver::addOutOfBandTextSource( } sp<DataSource> dataSource = new FileSource(dup(fd), offset, length); return createOutOfBandTextSource(mimeType, dataSource); return createOutOfBandTextSource(trackIndex, mimeType, dataSource); } status_t TimedTextDriver::createOutOfBandTextSource( const char *mimeType, const sp<DataSource>& dataSource) { size_t trackIndex, const char *mimeType, const sp<DataSource>& dataSource) { if (dataSource == NULL) { return ERROR_UNSUPPORTED; Loading @@ -199,28 +200,40 @@ status_t TimedTextDriver::createOutOfBandTextSource( } if (source == NULL) { ALOGE("Failed to create timed text source"); return ERROR_UNSUPPORTED; } Mutex::Autolock autoLock(mLock); mTextSourceVector.add(source); mTextSourceVector.add(trackIndex, source); mTextSourceTypeVector.add(false); return OK; } void TimedTextDriver::getTrackInfo(Parcel *parcel) { size_t TimedTextDriver::countExternalTracks() const { size_t nTracks = 0; for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) { if (!mTextSourceTypeVector[i]) { ++nTracks; } } return nTracks; } void TimedTextDriver::getExternalTrackInfo(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(); for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) { if (mTextSourceTypeVector[i]) { continue; } sp<MetaData> meta = mTextSourceVector.valueAt(i)->getFormat(); // There are two fields. parcel->writeInt32(2); // track type. parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT); const char *lang = "und"; if (meta != NULL) { meta->findCString(kKeyMediaLanguage, &lang); Loading