diff options
Diffstat (limited to 'media/libstagefright')
-rw-r--r-- | media/libstagefright/MPEG4Extractor.cpp | 45 | ||||
-rw-r--r-- | media/libstagefright/include/MPEG4Extractor.h | 4 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedText3GPPSource.cpp | 14 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedText3GPPSource.h | 3 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextPlayer.cpp | 30 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextPlayer.h | 1 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextSRTSource.cpp | 12 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextSRTSource.h | 3 | ||||
-rw-r--r-- | media/libstagefright/timedtext/TimedTextSource.h | 3 |
9 files changed, 95 insertions, 20 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 6c95d4e..663f285 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -599,6 +599,7 @@ static void convertTimeToDate(int64_t time_1904, String8 *s) { } status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { + ALOGV("entering parseChunk %lld/%d", *offset, depth); uint32_t hdr[2]; if (mDataSource->readAt(*offset, hdr, 8) < 8) { return ERROR_IO; @@ -625,6 +626,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { char chunk[5]; MakeFourCCString(chunk_type, chunk); + ALOGV("chunk: %s @ %lld", chunk, *offset); #if 0 static const char kWhitespace[] = " "; @@ -1302,6 +1304,8 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { break; } + case FOURCC('m', 'e', 'a', 'n'): + case FOURCC('n', 'a', 'm', 'e'): case FOURCC('d', 'a', 't', 'a'): { if (mPath.size() == 6 && underMetaDataPath(mPath)) { @@ -1437,6 +1441,15 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { break; } + case FOURCC('-', '-', '-', '-'): + { + mLastCommentMean.clear(); + mLastCommentName.clear(); + mLastCommentData.clear(); + *offset += chunk_size; + break; + } + default: { *offset += chunk_size; @@ -1553,6 +1566,9 @@ status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { uint32_t flags = U32_AT(buffer); uint32_t metadataKey = 0; + char chunk[5]; + MakeFourCCString(mPath[4], chunk); + ALOGV("meta: %s @ %lld", chunk, offset); switch (mPath[4]) { case FOURCC(0xa9, 'a', 'l', 'b'): { @@ -1632,6 +1648,35 @@ status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { } break; } + case FOURCC('-', '-', '-', '-'): + { + buffer[size] = '\0'; + switch (mPath[5]) { + case FOURCC('m', 'e', 'a', 'n'): + mLastCommentMean.setTo((const char *)buffer + 4); + break; + case FOURCC('n', 'a', 'm', 'e'): + mLastCommentName.setTo((const char *)buffer + 4); + break; + case FOURCC('d', 'a', 't', 'a'): + mLastCommentData.setTo((const char *)buffer + 8); + break; + } + if (mLastCommentMean == "com.apple.iTunes" + && mLastCommentName == "iTunSMPB" + && mLastCommentData.length() != 0) { + int32_t delay, padding; + if (sscanf(mLastCommentData, + " %*x %x %x %*x", &delay, &padding) == 2) { + mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); + mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); + } + mLastCommentMean.clear(); + mLastCommentName.clear(); + mLastCommentData.clear(); + } + break; + } default: break; diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h index eae62c6..5c549e0 100644 --- a/media/libstagefright/include/MPEG4Extractor.h +++ b/media/libstagefright/include/MPEG4Extractor.h @@ -20,6 +20,7 @@ #include <media/stagefright/MediaExtractor.h> #include <utils/Vector.h> +#include <utils/String8.h> namespace android { @@ -64,6 +65,9 @@ private: sp<MetaData> mFileMetaData; Vector<uint32_t> mPath; + String8 mLastCommentMean; + String8 mLastCommentName; + String8 mLastCommentData; status_t readMetaData(); status_t parseChunk(off64_t *offset, int depth); diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.cpp b/media/libstagefright/timedtext/TimedText3GPPSource.cpp index c423ef0..4854121 100644 --- a/media/libstagefright/timedtext/TimedText3GPPSource.cpp +++ b/media/libstagefright/timedtext/TimedText3GPPSource.cpp @@ -39,19 +39,21 @@ TimedText3GPPSource::~TimedText3GPPSource() { } status_t TimedText3GPPSource::read( - int64_t *timeUs, Parcel *parcel, const MediaSource::ReadOptions *options) { + int64_t *startTimeUs, int64_t *endTimeUs, Parcel *parcel, + const MediaSource::ReadOptions *options) { MediaBuffer *textBuffer = NULL; status_t err = mSource->read(&textBuffer, options); if (err != OK) { return err; } CHECK(textBuffer != NULL); - textBuffer->meta_data()->findInt64(kKeyTime, timeUs); - // TODO: this is legacy code. when 'timeUs' can be <= 0? - if (*timeUs > 0) { - extractAndAppendLocalDescriptions(*timeUs, textBuffer, parcel); - } + textBuffer->meta_data()->findInt64(kKeyTime, startTimeUs); + CHECK_GE(*startTimeUs, 0); + extractAndAppendLocalDescriptions(*startTimeUs, textBuffer, parcel); textBuffer->release(); + // endTimeUs is a dummy parameter for 3gpp timed text format. + // Set a negative value to it to mark it is unavailable. + *endTimeUs = -1; return OK; } diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.h b/media/libstagefright/timedtext/TimedText3GPPSource.h index 4ec3d8a..4170940 100644 --- a/media/libstagefright/timedtext/TimedText3GPPSource.h +++ b/media/libstagefright/timedtext/TimedText3GPPSource.h @@ -33,7 +33,8 @@ public: virtual status_t start() { return mSource->start(); } virtual status_t stop() { return mSource->stop(); } virtual status_t read( - int64_t *timeUs, + int64_t *startTimeUs, + int64_t *endTimeUs, Parcel *parcel, const MediaSource::ReadOptions *options = NULL); virtual status_t extractGlobalDescriptions(Parcel *parcel); diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp index 8717914..917c62a 100644 --- a/media/libstagefright/timedtext/TimedTextPlayer.cpp +++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp @@ -31,6 +31,7 @@ namespace android { static const int64_t kAdjustmentProcessingTimeUs = 100000ll; +static const int64_t kWaitTimeUsToRetryRead = 100000ll; TimedTextPlayer::TimedTextPlayer(const wp<MediaPlayerBase> &listener) : mListener(listener), @@ -139,13 +140,25 @@ void TimedTextPlayer::doSeekAndRead(int64_t seekTimeUs) { } void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) { - int64_t timeUs = 0; + int64_t startTimeUs = 0; + int64_t endTimeUs = 0; sp<ParcelEvent> parcelEvent = new ParcelEvent(); - status_t err = mSource->read(&timeUs, &(parcelEvent->parcel), options); - if (err != OK) { + status_t err = mSource->read(&startTimeUs, &endTimeUs, + &(parcelEvent->parcel), options); + if (err == WOULD_BLOCK) { + postTextEventDelayUs(NULL, kWaitTimeUsToRetryRead); + return; + } else if (err != OK) { notifyError(err); - } else { - postTextEvent(parcelEvent, timeUs); + return; + } + + postTextEvent(parcelEvent, startTimeUs); + if (endTimeUs > 0) { + CHECK_GE(endTimeUs, startTimeUs); + // send an empty timed text to clear the subtitle when it reaches to the + // end time. + postTextEvent(NULL, endTimeUs); } } @@ -162,6 +175,13 @@ void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeU } else { delayUs = timeUs - positionUs - kAdjustmentProcessingTimeUs; } + postTextEventDelayUs(parcel, delayUs); + } +} + +void TimedTextPlayer::postTextEventDelayUs(const sp<ParcelEvent>& parcel, int64_t delayUs) { + sp<MediaPlayerBase> listener = mListener.promote(); + if (listener != NULL) { sp<AMessage> msg = new AMessage(kWhatSendSubtitle, id()); msg->setInt32("generation", mSendSubtitleGeneration); if (parcel != NULL) { diff --git a/media/libstagefright/timedtext/TimedTextPlayer.h b/media/libstagefright/timedtext/TimedTextPlayer.h index b869f18..47aff03 100644 --- a/media/libstagefright/timedtext/TimedTextPlayer.h +++ b/media/libstagefright/timedtext/TimedTextPlayer.h @@ -67,6 +67,7 @@ private: void doRead(MediaSource::ReadOptions* options = NULL); void onTextEvent(); void postTextEvent(const sp<ParcelEvent>& parcel = NULL, int64_t timeUs = -1); + void postTextEventDelayUs(const sp<ParcelEvent>& parcel = NULL, int64_t delayUs = -1); void notifyError(int error = 0); void notifyListener(const Parcel *parcel = NULL); diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.cpp b/media/libstagefright/timedtext/TimedTextSRTSource.cpp index c44a99b..7b1f7f6 100644 --- a/media/libstagefright/timedtext/TimedTextSRTSource.cpp +++ b/media/libstagefright/timedtext/TimedTextSRTSource.cpp @@ -19,6 +19,7 @@ #include <utils/Log.h> #include <binder/Parcel.h> +#include <media/stagefright/foundation/ADebug.h> // for CHECK_xx #include <media/stagefright/foundation/AString.h> #include <media/stagefright/DataSource.h> #include <media/stagefright/MediaDefs.h> // for MEDIA_MIMETYPE_xxx @@ -63,19 +64,18 @@ status_t TimedTextSRTSource::stop() { } status_t TimedTextSRTSource::read( - int64_t *timeUs, + int64_t *startTimeUs, + int64_t *endTimeUs, Parcel *parcel, const MediaSource::ReadOptions *options) { - int64_t endTimeUs; AString text; - status_t err = getText(options, &text, timeUs, &endTimeUs); + status_t err = getText(options, &text, startTimeUs, endTimeUs); if (err != OK) { return err; } - if (*timeUs > 0) { - extractAndAppendLocalDescriptions(*timeUs, text, parcel); - } + CHECK_GE(*startTimeUs, 0); + extractAndAppendLocalDescriptions(*startTimeUs, text, parcel); return OK; } diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.h b/media/libstagefright/timedtext/TimedTextSRTSource.h index 62710a0..e1371b8 100644 --- a/media/libstagefright/timedtext/TimedTextSRTSource.h +++ b/media/libstagefright/timedtext/TimedTextSRTSource.h @@ -36,7 +36,8 @@ public: virtual status_t start(); virtual status_t stop(); virtual status_t read( - int64_t *timeUs, + int64_t *startTimeUs, + int64_t *endTimeUs, Parcel *parcel, const MediaSource::ReadOptions *options = NULL); virtual sp<MetaData> getFormat(); diff --git a/media/libstagefright/timedtext/TimedTextSource.h b/media/libstagefright/timedtext/TimedTextSource.h index 9349342..756cc31 100644 --- a/media/libstagefright/timedtext/TimedTextSource.h +++ b/media/libstagefright/timedtext/TimedTextSource.h @@ -43,7 +43,8 @@ class TimedTextSource : public RefBase { virtual status_t stop() = 0; // Returns subtitle parcel and its start time. virtual status_t read( - int64_t *timeUs, + int64_t *startTimeUs, + int64_t *endTimeUs, Parcel *parcel, const MediaSource::ReadOptions *options = NULL) = 0; virtual status_t extractGlobalDescriptions(Parcel *parcel) { |