diff options
Diffstat (limited to 'media')
8 files changed, 344 insertions, 87 deletions
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index b5bd988..c8cb7ed 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -204,6 +204,8 @@ const int32_t kAudioAttributesMarshallTagFlattenTags = 1; // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | content_type | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | source | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | flags | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | kAudioAttributesMarshallTagFlattenTags | // ignore tags if not found @@ -219,6 +221,7 @@ void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attribu { attributes->usage = (audio_usage_t) parcel.readInt32(); attributes->content_type = (audio_content_type_t) parcel.readInt32(); + attributes->source = (audio_source_t) parcel.readInt32(); attributes->flags = (audio_flags_mask_t) parcel.readInt32(); const bool hasFlattenedTag = (parcel.readInt32() == kAudioAttributesMarshallTagFlattenTags); if (hasFlattenedTag) { diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index f257ef3..8e1987a 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -32,6 +32,7 @@ #include <media/stagefright/MediaExtractor.h> #include <media/stagefright/MediaSource.h> #include <media/stagefright/MetaData.h> +#include <media/stagefright/Utils.h> #include "../../libstagefright/include/DRMExtractor.h" #include "../../libstagefright/include/NuCachedSource2.h" #include "../../libstagefright/include/WVMExtractor.h" @@ -318,7 +319,14 @@ void NuPlayer::GenericSource::onPrepareAsync() { } if (mVideoTrack.mSource != NULL) { - notifyVideoSizeChanged(getFormat(false /* audio */)); + sp<MetaData> meta = doGetFormatMeta(false /* audio */); + sp<AMessage> msg = new AMessage; + err = convertMetaDataToMessage(meta, &msg); + if(err != OK) { + notifyPreparedAndCleanup(err); + return; + } + notifyVideoSizeChanged(msg); } notifyFlagsChanged( @@ -422,7 +430,7 @@ void NuPlayer::GenericSource::start() { mAudioTrack.mPackets = new AnotherPacketSource(mAudioTrack.mSource->getFormat()); - readBuffer(MEDIA_TRACK_TYPE_AUDIO); + postReadBuffer(MEDIA_TRACK_TYPE_AUDIO); } if (mVideoTrack.mSource != NULL) { @@ -430,7 +438,7 @@ void NuPlayer::GenericSource::start() { mVideoTrack.mPackets = new AnotherPacketSource(mVideoTrack.mSource->getFormat()); - readBuffer(MEDIA_TRACK_TYPE_VIDEO); + postReadBuffer(MEDIA_TRACK_TYPE_VIDEO); } setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000); @@ -459,6 +467,8 @@ void NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, i if (mDecryptHandle != NULL) { mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position); } + mSubtitleTrack.mPackets = new AnotherPacketSource(NULL); + mTimedTextTrack.mPackets = new AnotherPacketSource(NULL); } status_t NuPlayer::GenericSource::feedMoreTSData() { @@ -615,6 +625,37 @@ void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) { } break; } + + case kWhatGetFormat: + { + onGetFormatMeta(msg); + break; + } + + case kWhatGetSelectedTrack: + { + onGetSelectedTrack(msg); + break; + } + + case kWhatSelectTrack: + { + onSelectTrack(msg); + break; + } + + case kWhatSeek: + { + onSeek(msg); + break; + } + + case kWhatReadBuffer: + { + onReadBuffer(msg); + break; + } + default: Source::onMessageReceived(msg); break; @@ -690,6 +731,34 @@ void NuPlayer::GenericSource::sendTextData( } sp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) { + sp<AMessage> msg = new AMessage(kWhatGetFormat, id()); + msg->setInt32("audio", audio); + + sp<AMessage> response; + void *format; + status_t err = msg->postAndAwaitResponse(&response); + if (err == OK && response != NULL) { + CHECK(response->findPointer("format", &format)); + return (MetaData *)format; + } else { + return NULL; + } +} + +void NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const { + int32_t audio; + CHECK(msg->findInt32("audio", &audio)); + + sp<AMessage> response = new AMessage; + sp<MetaData> format = doGetFormatMeta(audio); + response->setPointer("format", format.get()); + + uint32_t replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + response->postReply(replyID); +} + +sp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const { sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource; if (source == NULL) { @@ -709,7 +778,7 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit( if (mIsWidevine && !audio) { // try to read a buffer as we may not have been able to the last time - readBuffer(MEDIA_TRACK_TYPE_VIDEO, -1ll); + postReadBuffer(MEDIA_TRACK_TYPE_VIDEO); } status_t finalResult; @@ -720,18 +789,7 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit( status_t result = track->mPackets->dequeueAccessUnit(accessUnit); if (!track->mPackets->hasBufferAvailable(&finalResult)) { - readBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO, -1ll); - } - - if (mSubtitleTrack.mSource == NULL && mTimedTextTrack.mSource == NULL) { - return result; - } - - if (mSubtitleTrack.mSource != NULL) { - CHECK(mSubtitleTrack.mPackets != NULL); - } - if (mTimedTextTrack.mSource != NULL) { - CHECK(mTimedTextTrack.mPackets != NULL); + postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO); } if (result != OK) { @@ -825,6 +883,35 @@ sp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const { } ssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const { + sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id()); + msg->setInt32("type", type); + + sp<AMessage> response; + int32_t index; + status_t err = msg->postAndAwaitResponse(&response); + if (err == OK && response != NULL) { + CHECK(response->findInt32("index", &index)); + return index; + } else { + return -1; + } +} + +void NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const { + int32_t tmpType; + CHECK(msg->findInt32("type", &tmpType)); + media_track_type type = (media_track_type)tmpType; + + sp<AMessage> response = new AMessage; + ssize_t index = doGetSelectedTrack(type); + response->setInt32("index", index); + + uint32_t replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + response->postReply(replyID); +} + +ssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const { const Track *track = NULL; switch (type) { case MEDIA_TRACK_TYPE_VIDEO: @@ -852,6 +939,34 @@ ssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const { status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) { ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex); + sp<AMessage> msg = new AMessage(kWhatSelectTrack, id()); + msg->setInt32("trackIndex", trackIndex); + msg->setInt32("select", trackIndex); + + sp<AMessage> response; + status_t err = msg->postAndAwaitResponse(&response); + if (err == OK && response != NULL) { + CHECK(response->findInt32("err", &err)); + } + + return err; +} + +void NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) { + int32_t trackIndex, select; + CHECK(msg->findInt32("trackIndex", &trackIndex)); + CHECK(msg->findInt32("select", &select)); + + sp<AMessage> response = new AMessage; + status_t err = doSelectTrack(trackIndex, select); + response->setInt32("err", err); + + uint32_t replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + response->postReply(replyID); +} + +status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select) { if (trackIndex >= mSources.size()) { return BAD_INDEX; } @@ -922,6 +1037,32 @@ status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) { } status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) { + sp<AMessage> msg = new AMessage(kWhatSeek, id()); + msg->setInt64("seekTimeUs", seekTimeUs); + + sp<AMessage> response; + status_t err = msg->postAndAwaitResponse(&response); + if (err == OK && response != NULL) { + CHECK(response->findInt32("err", &err)); + } + + return err; +} + +void NuPlayer::GenericSource::onSeek(sp<AMessage> msg) { + int64_t seekTimeUs; + CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); + + sp<AMessage> response = new AMessage; + status_t err = doSeek(seekTimeUs); + response->setInt32("err", err); + + uint32_t replyID; + CHECK(msg->senderAwaitsResponse(&replyID)); + response->postReply(replyID); +} + +status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) { if (mVideoTrack.mSource != NULL) { int64_t actualTimeUs; readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs); @@ -1006,6 +1147,19 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( return ab; } +void NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) { + sp<AMessage> msg = new AMessage(kWhatReadBuffer, id()); + msg->setInt32("trackType", trackType); + msg->post(); +} + +void NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) { + int32_t tmpType; + CHECK(msg->findInt32("trackType", &tmpType)); + media_track_type trackType = (media_track_type)tmpType; + readBuffer(trackType); +} + void NuPlayer::GenericSource::readBuffer( media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) { Track *track; diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index 1f13120..50ff98a 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -84,6 +84,11 @@ private: kWhatSendTimedTextData, kWhatChangeAVSource, kWhatPollBuffering, + kWhatGetFormat, + kWhatGetSelectedTrack, + kWhatSelectTrack, + kWhatSeek, + kWhatReadBuffer, }; Vector<sp<MediaSource> > mSources; @@ -140,6 +145,18 @@ private: void notifyPreparedAndCleanup(status_t err); + void onGetFormatMeta(sp<AMessage> msg) const; + sp<MetaData> doGetFormatMeta(bool audio) const; + + void onGetSelectedTrack(sp<AMessage> msg) const; + ssize_t doGetSelectedTrack(media_track_type type) const; + + void onSelectTrack(sp<AMessage> msg); + status_t doSelectTrack(size_t trackIndex, bool select); + + void onSeek(sp<AMessage> msg); + status_t doSeek(int64_t seekTimeUs); + void onPrepareAsync(); void fetchTextData( @@ -155,6 +172,8 @@ private: media_track_type trackType, int64_t *actualTimeUs = NULL); + void postReadBuffer(media_track_type trackType); + void onReadBuffer(sp<AMessage> msg); void readBuffer( media_track_type trackType, int64_t seekTimeUs = -1ll, int64_t *actualTimeUs = NULL, bool formatChange = false); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index ae22123..4a5d18a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -541,7 +541,13 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { static_cast<NativeWindowWrapper *>(obj.get()))); if (obj != NULL) { - mDeferredActions.push_back(new SeekAction(mCurrentPositionUs)); + if (mStarted && mVideoDecoder != NULL) { + // Issue a seek to refresh the video screen only if started otherwise + // the extractor may not yet be started and will assert. + // If the video decoder is not set (perhaps audio only in this case) + // do not perform a seek as it is not needed. + mDeferredActions.push_back(new SeekAction(mCurrentPositionUs)); + } // If there is a new surface texture, instantiate decoders // again if possible. @@ -1540,6 +1546,10 @@ void NuPlayer::flushDecoder( ALOGE_IF(mFlushingVideo != NONE, "video flushDecoder() is called in state %d", mFlushingVideo); mFlushingVideo = newStatus; + + if (mCCDecoder != NULL) { + mCCDecoder->flush(); + } } } @@ -1665,6 +1675,14 @@ void NuPlayer::performSeek(int64_t seekTimeUs) { seekTimeUs, seekTimeUs / 1E6); + if (mSource == NULL) { + // This happens when reset occurs right before the loop mode + // asynchronously seeks to the start of the stream. + LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL, + "mSource is NULL and decoders not NULL audio(%p) video(%p)", + mAudioDecoder.get(), mVideoDecoder.get()); + return; + } mSource->seekTo(seekTimeUs); ++mTimedTextGeneration; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 5aaf48c..8ce7baf 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -716,72 +716,28 @@ bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetF return seamless; } -struct NuPlayer::CCDecoder::CCData { +struct CCData { CCData(uint8_t type, uint8_t data1, uint8_t data2) : mType(type), mData1(data1), mData2(data2) { } + bool getChannel(size_t *channel) const { + if (mData1 >= 0x10 && mData1 <= 0x1f) { + *channel = (mData1 >= 0x18 ? 1 : 0) + (mType ? 2 : 0); + return true; + } + return false; + } uint8_t mType; uint8_t mData1; uint8_t mData2; }; -NuPlayer::CCDecoder::CCDecoder(const sp<AMessage> ¬ify) - : mNotify(notify), - mTrackCount(0), - mSelectedTrack(-1) { -} - -size_t NuPlayer::CCDecoder::getTrackCount() const { - return mTrackCount; -} - -sp<AMessage> NuPlayer::CCDecoder::getTrackInfo(size_t index) const { - CHECK(index == 0); - - sp<AMessage> format = new AMessage(); - - format->setInt32("type", MEDIA_TRACK_TYPE_SUBTITLE); - format->setString("language", "und"); - format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_608); - format->setInt32("auto", 1); - format->setInt32("default", 1); - format->setInt32("forced", 0); - - return format; -} - -status_t NuPlayer::CCDecoder::selectTrack(size_t index, bool select) { - CHECK(index < mTrackCount); - - if (select) { - if (mSelectedTrack == (ssize_t)index) { - ALOGE("track %zu already selected", index); - return BAD_VALUE; - } - ALOGV("selected track %zu", index); - mSelectedTrack = index; - } else { - if (mSelectedTrack != (ssize_t)index) { - ALOGE("track %zu is not selected", index); - return BAD_VALUE; - } - ALOGV("unselected track %zu", index); - mSelectedTrack = -1; - } - - return OK; -} - -bool NuPlayer::CCDecoder::isSelected() const { - return mSelectedTrack >= 0 && mSelectedTrack < (int32_t)mTrackCount; -} - -bool NuPlayer::CCDecoder::isNullPad(CCData *cc) const { +static bool isNullPad(CCData *cc) { return cc->mData1 < 0x10 && cc->mData2 < 0x10; } -void NuPlayer::CCDecoder::dumpBytePair(const sp<ABuffer> &ccBuf) const { +static void dumpBytePair(const sp<ABuffer> &ccBuf) { size_t offset = 0; AString out; @@ -843,6 +799,78 @@ void NuPlayer::CCDecoder::dumpBytePair(const sp<ABuffer> &ccBuf) const { ALOGI("%s", out.c_str()); } +NuPlayer::CCDecoder::CCDecoder(const sp<AMessage> ¬ify) + : mNotify(notify), + mCurrentChannel(0), + mSelectedTrack(-1) { + for (size_t i = 0; i < sizeof(mTrackIndices)/sizeof(mTrackIndices[0]); ++i) { + mTrackIndices[i] = -1; + } +} + +size_t NuPlayer::CCDecoder::getTrackCount() const { + return mFoundChannels.size(); +} + +sp<AMessage> NuPlayer::CCDecoder::getTrackInfo(size_t index) const { + if (!isTrackValid(index)) { + return NULL; + } + + sp<AMessage> format = new AMessage(); + + format->setInt32("type", MEDIA_TRACK_TYPE_SUBTITLE); + format->setString("language", "und"); + format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_608); + //CC1, field 0 channel 0 + bool isDefaultAuto = (mFoundChannels[index] == 0); + format->setInt32("auto", isDefaultAuto); + format->setInt32("default", isDefaultAuto); + format->setInt32("forced", 0); + + return format; +} + +status_t NuPlayer::CCDecoder::selectTrack(size_t index, bool select) { + if (!isTrackValid(index)) { + return BAD_VALUE; + } + + if (select) { + if (mSelectedTrack == (ssize_t)index) { + ALOGE("track %zu already selected", index); + return BAD_VALUE; + } + ALOGV("selected track %zu", index); + mSelectedTrack = index; + } else { + if (mSelectedTrack != (ssize_t)index) { + ALOGE("track %zu is not selected", index); + return BAD_VALUE; + } + ALOGV("unselected track %zu", index); + mSelectedTrack = -1; + } + + return OK; +} + +bool NuPlayer::CCDecoder::isSelected() const { + return mSelectedTrack >= 0 && mSelectedTrack < (int32_t) getTrackCount(); +} + +bool NuPlayer::CCDecoder::isTrackValid(size_t index) const { + return index < getTrackCount(); +} + +int32_t NuPlayer::CCDecoder::getTrackIndex(size_t channel) const { + if (channel < sizeof(mTrackIndices)/sizeof(mTrackIndices[0])) { + return mTrackIndices[channel]; + } + return -1; +} + +// returns true if a new CC track is found bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { int64_t timeUs; CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); @@ -852,7 +880,7 @@ bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { return false; } - bool hasCC = false; + bool trackAdded = false; NALBitReader br(sei->data() + 1, sei->size() - 1); // sei_message() @@ -887,8 +915,6 @@ bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { && itu_t_t35_provider_code == 0x0031 && user_identifier == 'GA94' && user_data_type_code == 0x3) { - hasCC = true; - // MPEG_cc_data() // ATSC A/53 Part 4: 6.2.3.1 br.skipBits(1); //process_em_data_flag @@ -918,6 +944,12 @@ bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { && (cc_type == 0 || cc_type == 1)) { CCData cc(cc_type, cc_data_1, cc_data_2); if (!isNullPad(&cc)) { + size_t channel; + if (cc.getChannel(&channel) && getTrackIndex(channel) < 0) { + mTrackIndices[channel] = mFoundChannels.size(); + mFoundChannels.push_back(channel); + trackAdded = true; + } memcpy(ccBuf->data() + ccBuf->size(), (void *)&cc, sizeof(cc)); ccBuf->setRange(0, ccBuf->size() + sizeof(CCData)); @@ -940,13 +972,33 @@ bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { br.skipBits(payload_size * 8); } - return hasCC; + return trackAdded; } -void NuPlayer::CCDecoder::decode(const sp<ABuffer> &accessUnit) { - if (extractFromSEI(accessUnit) && mTrackCount == 0) { - mTrackCount++; +sp<ABuffer> NuPlayer::CCDecoder::filterCCBuf( + const sp<ABuffer> &ccBuf, size_t index) { + sp<ABuffer> filteredCCBuf = new ABuffer(ccBuf->size()); + filteredCCBuf->setRange(0, 0); + + size_t cc_count = ccBuf->size() / sizeof(CCData); + const CCData* cc_data = (const CCData*)ccBuf->data(); + for (size_t i = 0; i < cc_count; ++i) { + size_t channel; + if (cc_data[i].getChannel(&channel)) { + mCurrentChannel = channel; + } + if (mCurrentChannel == mFoundChannels[index]) { + memcpy(filteredCCBuf->data() + filteredCCBuf->size(), + (void *)&cc_data[i], sizeof(CCData)); + filteredCCBuf->setRange(0, filteredCCBuf->size() + sizeof(CCData)); + } + } + + return filteredCCBuf; +} +void NuPlayer::CCDecoder::decode(const sp<ABuffer> &accessUnit) { + if (extractFromSEI(accessUnit)) { ALOGI("Found CEA-608 track"); sp<AMessage> msg = mNotify->dup(); msg->setInt32("what", kWhatTrackAdded); @@ -956,13 +1008,18 @@ void NuPlayer::CCDecoder::decode(const sp<ABuffer> &accessUnit) { } void NuPlayer::CCDecoder::display(int64_t timeUs) { + if (!isTrackValid(mSelectedTrack)) { + ALOGE("Could not find current track(index=%d)", mSelectedTrack); + return; + } + ssize_t index = mCCMap.indexOfKey(timeUs); if (index < 0) { ALOGV("cc for timestamp %" PRId64 " not found", timeUs); return; } - sp<ABuffer> &ccBuf = mCCMap.editValueAt(index); + sp<ABuffer> ccBuf = filterCCBuf(mCCMap.valueAt(index), mSelectedTrack); if (ccBuf->size() > 0) { #if 0 @@ -983,5 +1040,9 @@ void NuPlayer::CCDecoder::display(int64_t timeUs) { mCCMap.removeItemsAt(0, index + 1); } +void NuPlayer::CCDecoder::flush() { + mCCMap.clear(); +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index 67bddb8..cc1bdff 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -126,18 +126,20 @@ struct NuPlayer::CCDecoder : public RefBase { bool isSelected() const; void decode(const sp<ABuffer> &accessUnit); void display(int64_t timeUs); + void flush(); private: - struct CCData; - sp<AMessage> mNotify; KeyedVector<int64_t, sp<ABuffer> > mCCMap; - size_t mTrackCount; + size_t mCurrentChannel; int32_t mSelectedTrack; + int32_t mTrackIndices[4]; + Vector<size_t> mFoundChannels; - bool isNullPad(CCData *cc) const; - void dumpBytePair(const sp<ABuffer> &ccBuf) const; + bool isTrackValid(size_t index) const; + int32_t getTrackIndex(size_t channel) const; bool extractFromSEI(const sp<ABuffer> &accessUnit); + sp<ABuffer> filterCCBuf(const sp<ABuffer> &ccBuf, size_t index); DISALLOW_EVIL_CONSTRUCTORS(CCDecoder); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 2423f5f..09324ae 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -626,7 +626,7 @@ void NuPlayerDriver::notifyListener_l( switch (msg) { case MEDIA_PLAYBACK_COMPLETE: { - if (mLooping) { + if (mLooping && mState != STATE_RESET_IN_PROGRESS) { mLock.unlock(); mPlayer->seekToAsync(0); mLock.lock(); diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp index 4d5d79e..82a4c39 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.cpp +++ b/media/libstagefright/httplive/PlaylistFetcher.cpp @@ -490,11 +490,11 @@ status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) { mStreamTypeMask = streamTypeMask; - mStartTimeUs = startTimeUs; mSegmentStartTimeUs = segmentStartTimeUs; mDiscontinuitySeq = startDiscontinuitySeq; - if (mStartTimeUs >= 0ll) { + if (startTimeUs >= 0) { + mStartTimeUs = startTimeUs; mSeqNumber = -1; mStartup = true; mPrepared = false; |