diff options
-rw-r--r-- | include/media/stagefright/AMRExtractor.h | 2 | ||||
-rw-r--r-- | include/media/stagefright/MP3Extractor.h | 2 | ||||
-rw-r--r-- | include/media/stagefright/MPEG4Extractor.h | 3 | ||||
-rw-r--r-- | include/media/stagefright/MediaExtractor.h | 7 | ||||
-rw-r--r-- | include/media/stagefright/MetaData.h | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightMetadataRetriever.cpp | 12 | ||||
-rw-r--r-- | media/libstagefright/AMRExtractor.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/MP3Extractor.cpp | 2 | ||||
-rw-r--r-- | media/libstagefright/MPEG4Extractor.cpp | 23 | ||||
-rw-r--r-- | media/libstagefright/OMXCodec.cpp | 18 | ||||
-rw-r--r-- | media/libstagefright/SampleTable.cpp | 47 | ||||
-rw-r--r-- | media/libstagefright/include/SampleTable.h | 2 |
12 files changed, 111 insertions, 10 deletions
diff --git a/include/media/stagefright/AMRExtractor.h b/include/media/stagefright/AMRExtractor.h index c8710d3..debf006 100644 --- a/include/media/stagefright/AMRExtractor.h +++ b/include/media/stagefright/AMRExtractor.h @@ -30,7 +30,7 @@ public: virtual size_t countTracks(); virtual sp<MediaSource> getTrack(size_t index); - virtual sp<MetaData> getTrackMetaData(size_t index); + virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags); static sp<MetaData> makeAMRFormat(bool isWide); diff --git a/include/media/stagefright/MP3Extractor.h b/include/media/stagefright/MP3Extractor.h index 11ba01d..074973b 100644 --- a/include/media/stagefright/MP3Extractor.h +++ b/include/media/stagefright/MP3Extractor.h @@ -32,7 +32,7 @@ public: virtual size_t countTracks(); virtual sp<MediaSource> getTrack(size_t index); - virtual sp<MetaData> getTrackMetaData(size_t index); + virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags); protected: virtual ~MP3Extractor(); diff --git a/include/media/stagefright/MPEG4Extractor.h b/include/media/stagefright/MPEG4Extractor.h index 932e30f..ce4736d 100644 --- a/include/media/stagefright/MPEG4Extractor.h +++ b/include/media/stagefright/MPEG4Extractor.h @@ -33,7 +33,7 @@ public: size_t countTracks(); sp<MediaSource> getTrack(size_t index); - sp<MetaData> getTrackMetaData(size_t index); + sp<MetaData> getTrackMetaData(size_t index, uint32_t flags); protected: virtual ~MPEG4Extractor(); @@ -44,6 +44,7 @@ private: sp<MetaData> meta; uint32_t timescale; sp<SampleTable> sampleTable; + bool includes_expensive_metadata; }; sp<DataSource> mDataSource; diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h index 67e45bd..4d6b989 100644 --- a/include/media/stagefright/MediaExtractor.h +++ b/include/media/stagefright/MediaExtractor.h @@ -33,7 +33,12 @@ public: virtual size_t countTracks() = 0; virtual sp<MediaSource> getTrack(size_t index) = 0; - virtual sp<MetaData> getTrackMetaData(size_t index) = 0; + + enum GetTrackMetaDataFlags { + kIncludeExtensiveMetaData = 1 + }; + virtual sp<MetaData> getTrackMetaData( + size_t index, uint32_t flags = 0) = 0; protected: MediaExtractor() {} diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index d48ea41..c2d8f98 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -46,6 +46,7 @@ enum { kKeyDecoderComponent = 'decC', // cstring kKeyBufferID = 'bfID', kKeyMaxInputSize = 'inpS', + kKeyThumbnailTime = 'thbT', // int64_t (usecs) }; enum { diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp index c069128..5ac59c8 100644 --- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp +++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp @@ -108,6 +108,9 @@ VideoFrame *StagefrightMetadataRetriever::captureFrame() { return NULL; } + sp<MetaData> trackMeta = mExtractor->getTrackMetaData( + i, MediaExtractor::kIncludeExtensiveMetaData); + sp<MediaSource> source = mExtractor->getTrack(i); if (source.get() == NULL) { @@ -132,6 +135,12 @@ VideoFrame *StagefrightMetadataRetriever::captureFrame() { // Read one output buffer, ignore format change notifications // and spurious empty buffers. + MediaSource::ReadOptions options; + int64_t thumbNailTime; + if (trackMeta->findInt64(kKeyThumbnailTime, &thumbNailTime)) { + options.setSeekTo(thumbNailTime); + } + MediaBuffer *buffer = NULL; status_t err; do { @@ -139,7 +148,8 @@ VideoFrame *StagefrightMetadataRetriever::captureFrame() { buffer->release(); buffer = NULL; } - err = decoder->read(&buffer); + err = decoder->read(&buffer, &options); + options.clearSeekTo(); } while (err == INFO_FORMAT_CHANGED || (buffer != NULL && buffer->range_length() == 0)); diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp index 1660351..74f055e 100644 --- a/media/libstagefright/AMRExtractor.cpp +++ b/media/libstagefright/AMRExtractor.cpp @@ -86,7 +86,7 @@ sp<MediaSource> AMRExtractor::getTrack(size_t index) { return new AMRSource(mDataSource, mIsWide); } -sp<MetaData> AMRExtractor::getTrackMetaData(size_t index) { +sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t flags) { if (mInitCheck != OK || index != 0) { return NULL; } diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp index b7dd9ba..78b8eb2 100644 --- a/media/libstagefright/MP3Extractor.cpp +++ b/media/libstagefright/MP3Extractor.cpp @@ -393,7 +393,7 @@ sp<MediaSource> MP3Extractor::getTrack(size_t index) { mMeta, mDataSource, mFirstFramePos, mFixedHeader); } -sp<MetaData> MP3Extractor::getTrackMetaData(size_t index) { +sp<MetaData> MP3Extractor::getTrackMetaData(size_t index, uint32_t flags) { if (mFirstFramePos < 0 || index != 0) { return NULL; } diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index da714f8..382133c 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -179,7 +179,8 @@ size_t MPEG4Extractor::countTracks() { return n; } -sp<MetaData> MPEG4Extractor::getTrackMetaData(size_t index) { +sp<MetaData> MPEG4Extractor::getTrackMetaData( + size_t index, uint32_t flags) { status_t err; if ((err = readMetaData()) != OK) { return NULL; @@ -199,6 +200,25 @@ sp<MetaData> MPEG4Extractor::getTrackMetaData(size_t index) { return NULL; } + if ((flags & kIncludeExtensiveMetaData) + && !track->includes_expensive_metadata) { + track->includes_expensive_metadata = true; + + const char *mime; + CHECK(track->meta->findCString(kKeyMIMEType, &mime)); + if (!strncasecmp("video/", mime, 6)) { + uint32_t sampleIndex; + uint32_t sampleTime; + if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK + && track->sampleTable->getDecodingTime( + sampleIndex, &sampleTime) == OK) { + track->meta->setInt64( + kKeyThumbnailTime, + ((int64_t)sampleTime * 1000000) / track->timescale); + } + } + } + return track->meta; } @@ -353,6 +373,7 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { mLastTrack = track; track->meta = new MetaData; + track->includes_expensive_metadata = false; track->timescale = 0; track->sampleTable = new SampleTable(mDataSource); track->meta->setCString(kKeyMIMEType, "application/octet-stream"); diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index ff001e8..f8c0bda 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1943,9 +1943,24 @@ status_t OMXCodec::read( return UNKNOWN_ERROR; } + bool seeking = false; + int64_t seekTimeUs; + if (options && options->getSeekTo(&seekTimeUs)) { + seeking = true; + } + if (mInitialBufferSubmit) { mInitialBufferSubmit = false; + if (seeking) { + CHECK(seekTimeUs >= 0); + mSeekTimeUs = seekTimeUs; + + // There's no reason to trigger the code below, there's + // nothing to flush yet. + seeking = false; + } + drainInputBuffers(); if (mState == EXECUTING) { @@ -1955,8 +1970,7 @@ status_t OMXCodec::read( } } - int64_t seekTimeUs; - if (options && options->getSeekTo(&seekTimeUs)) { + if (seeking) { CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); mSignalledEOS = false; diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index 5c5bb4d..3eed52a 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -575,5 +575,52 @@ status_t SampleTable::findClosestSyncSample( return OK; } +status_t SampleTable::findThumbnailSample(uint32_t *sample_index) { + if (mSyncSampleOffset < 0) { + // All samples are sync-samples. + *sample_index = 0; + return OK; + } + + uint32_t bestSampleIndex = 0; + size_t maxSampleSize = 0; + + static const size_t kMaxNumSyncSamplesToScan = 20; + + // Consider the first kMaxNumSyncSamplesToScan sync samples and + // pick the one with the largest (compressed) size as the thumbnail. + + size_t numSamplesToScan = mNumSyncSamples; + if (numSamplesToScan > kMaxNumSyncSamplesToScan) { + numSamplesToScan = kMaxNumSyncSamplesToScan; + } + + for (size_t i = 0; i < numSamplesToScan; ++i) { + uint32_t x; + if (mDataSource->read_at( + mSyncSampleOffset + 8 + i * 4, &x, 4) != 4) { + return ERROR_IO; + } + x = ntohl(x); + --x; + + // Now x is a sample index. + size_t sampleSize; + status_t err = getSampleSize(x, &sampleSize); + if (err != OK) { + return err; + } + + if (i == 0 || sampleSize > maxSampleSize) { + bestSampleIndex = x; + maxSampleSize = sampleSize; + } + } + + *sample_index = bestSampleIndex; + + return OK; +} + } // namespace android diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h index 34a0649..ead3431 100644 --- a/media/libstagefright/include/SampleTable.h +++ b/media/libstagefright/include/SampleTable.h @@ -75,6 +75,8 @@ public: status_t findClosestSyncSample( uint32_t start_sample_index, uint32_t *sample_index); + status_t findThumbnailSample(uint32_t *sample_index); + protected: ~SampleTable(); |