author | Jean-Yves Avenard <jyavenard@mozilla.com> |
Fri, 01 May 2015 15:26:50 +1000 | |
changeset 241975 | e6a5d030152c399a96a2cb3a545afbf429422afe |
parent 241974 | 4b6149e01e96fc44ada6695359e2a0189f160684 |
child 241976 | cfb189bc93684ce7bbf40b39f24f2af6dfef697b |
push id | 28672 |
push user | ryanvm@gmail.com |
push date | Fri, 01 May 2015 16:57:20 +0000 |
treeherder | mozilla-central@e70555ac58d8 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kentuckyfriedtakahe |
bugs | 1156689 |
milestone | 40.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/media/libstagefright/binding/MP4Metadata.cpp @@ -0,0 +1,267 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "include/MPEG4Extractor.h" +#include "media/stagefright/DataSource.h" +#include "media/stagefright/MediaDefs.h" +#include "media/stagefright/MediaSource.h" +#include "media/stagefright/MetaData.h" +#include "mozilla/Monitor.h" +#include "mp4_demuxer/MP4Metadata.h" + +#include <limits> +#include <stdint.h> + +using namespace stagefright; + +namespace mp4_demuxer +{ + +struct StageFrightPrivate +{ + StageFrightPrivate() + : mCanSeek(false) {} + sp<MediaExtractor> mMetadataExtractor; + + bool mCanSeek; +}; + +class DataSourceAdapter : public DataSource +{ +public: + explicit DataSourceAdapter(Stream* aSource) : mSource(aSource) {} + + ~DataSourceAdapter() {} + + virtual status_t initCheck() const { return NO_ERROR; } + + virtual ssize_t readAt(off64_t offset, void* data, size_t size) + { + MOZ_ASSERT(((ssize_t)size) >= 0); + size_t bytesRead; + if (!mSource->ReadAt(offset, data, size, &bytesRead)) + return ERROR_IO; + + if (bytesRead == 0) + return ERROR_END_OF_STREAM; + + MOZ_ASSERT(((ssize_t)bytesRead) > 0); + return bytesRead; + } + + virtual status_t getSize(off64_t* size) + { + if (!mSource->Length(size)) + return ERROR_UNSUPPORTED; + return NO_ERROR; + } + + virtual uint32_t flags() { return kWantsPrefetching | kIsHTTPBasedSource; } + + virtual status_t reconnectAtOffset(off64_t offset) { return NO_ERROR; } + +private: + nsRefPtr<Stream> mSource; +}; + +static inline void +ConvertIndex(nsTArray<Index::Indice>& aDest, + const stagefright::Vector<stagefright::MediaSource::Indice>& aIndex) +{ + for (size_t i = 0; i < aIndex.size(); i++) { + Index::Indice indice; + const stagefright::MediaSource::Indice& s_indice = aIndex[i]; + indice.start_offset = s_indice.start_offset; + indice.end_offset = s_indice.end_offset; + indice.start_composition = s_indice.start_composition; + indice.end_composition = s_indice.end_composition; + indice.sync = s_indice.sync; + aDest.AppendElement(indice); + } +} + +MP4Metadata::MP4Metadata(Stream* aSource) + : mPrivate(new StageFrightPrivate) + , mSource(aSource) +{ + mPrivate->mMetadataExtractor = + new MPEG4Extractor(new DataSourceAdapter(mSource)); + mPrivate->mCanSeek = + mPrivate->mMetadataExtractor->flags() & MediaExtractor::CAN_SEEK; + sp<MetaData> metaData = mPrivate->mMetadataExtractor->getMetaData(); + + UpdateCrypto(metaData.get()); +} + +MP4Metadata::~MP4Metadata() +{ +} + +uint32_t +MP4Metadata::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const +{ + size_t tracks = mPrivate->mMetadataExtractor->countTracks(); + uint32_t total = 0; + for (size_t i = 0; i < tracks; i++) { + sp<MetaData> metaData = mPrivate->mMetadataExtractor->getTrackMetaData(i); + + const char* mimeType; + if (metaData == nullptr || !metaData->findCString(kKeyMIMEType, &mimeType)) { + continue; + } + switch (aType) { + case mozilla::TrackInfo::kAudioTrack: + if (!strncmp(mimeType, "audio/", 6)) { + total++; + } + break; + case mozilla::TrackInfo::kVideoTrack: + if (!strncmp(mimeType, "video/", 6)) { + total++; + } + break; + default: + break; + } + } + return total; +} + +mozilla::UniquePtr<mozilla::TrackInfo> +MP4Metadata::GetTrackInfo(mozilla::TrackInfo::TrackType aType, + size_t aTrackNumber) const +{ + size_t tracks = mPrivate->mMetadataExtractor->countTracks(); + if (!tracks) { + return nullptr; + } + int32_t index = -1; + const char* mimeType; + sp<MetaData> metaData; + + size_t i = 0; + while (i < tracks) { + metaData = mPrivate->mMetadataExtractor->getTrackMetaData(i); + + if (metaData == nullptr || !metaData->findCString(kKeyMIMEType, &mimeType)) { + continue; + } + switch (aType) { + case mozilla::TrackInfo::kAudioTrack: + if (!strncmp(mimeType, "audio/", 6)) { + index++; + } + break; + case mozilla::TrackInfo::kVideoTrack: + if (!strncmp(mimeType, "video/", 6)) { + index++; + } + break; + default: + break; + } + if (index == aTrackNumber) { + break; + } + i++; + } + if (index < 0) { + return nullptr; + } + + sp<MediaSource> track = mPrivate->mMetadataExtractor->getTrack(index); + if (!track.get() || track->start() != OK) { + return nullptr; + } + + UniquePtr<mozilla::TrackInfo> e; + + switch (aType) { + case mozilla::TrackInfo::kAudioTrack: + { + auto info = mozilla::MakeUnique<MP4AudioInfo>(); + info->Update(metaData.get(), mimeType); + e = Move(info); + } + break; + case mozilla::TrackInfo::kVideoTrack: + { + auto info = mozilla::MakeUnique<MP4VideoInfo>(); + info->Update(metaData.get(), mimeType); + e = Move(info); + } + break; + default: + break; + } + + track->stop(); + if (e) { + metaData = mPrivate->mMetadataExtractor->getMetaData(); + int64_t movieDuration; + if (!e->mDuration && + metaData->findInt64(kKeyMovieDuration, &movieDuration)) { + // No duration in track, use movie extend header box one. + e->mDuration = movieDuration; + } + } + + return e; +} + +bool +MP4Metadata::CanSeek() const +{ + return mPrivate->mCanSeek; +} + +void +MP4Metadata::UpdateCrypto(const MetaData* aMetaData) +{ + const void* data; + size_t size; + uint32_t type; + + // There's no point in checking that the type matches anything because it + // isn't set consistently in the MPEG4Extractor. + if (!aMetaData->findData(kKeyPssh, &type, &data, &size)) { + return; + } + mCrypto.Update(reinterpret_cast<const uint8_t*>(data), size); +} + +bool +MP4Metadata::ReadTrackIndex(nsTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID) +{ + size_t numTracks = mPrivate->mMetadataExtractor->countTracks(); + int32_t trackNumber = GetTrackNumber(aTrackID); + if (trackNumber < 0) { + return false; + } + sp<MediaSource> track = mPrivate->mMetadataExtractor->getTrack(trackNumber); + if (!track.get() || track->start() != OK) { + return false; + } + ConvertIndex(aDest, track->exportIndex()); + + track->stop(); + + return true; +} + +int32_t +MP4Metadata::GetTrackNumber(mozilla::TrackID aTrackID) +{ + size_t numTracks = mPrivate->mMetadataExtractor->countTracks(); + for (size_t i = 0; i < numTracks; i++) { + sp<MetaData> metaData = mPrivate->mMetadataExtractor->getTrackMetaData(i); + int32_t value; + if (metaData->findInt32(kKeyTrackID, &value) && value == aTrackID) { + return i; + } + } + return -1; +} + +} // namespace mp4_demuxer
new file mode 100644 --- /dev/null +++ b/media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MP4METADATA_H_ +#define MP4METADATA_H_ + +#include "mozilla/Monitor.h" +#include "mozilla/UniquePtr.h" +#include "mp4_demuxer/Index.h" +#include "mp4_demuxer/DecoderData.h" +#include "nsAutoPtr.h" +#include "nsTArray.h" +#include "MediaInfo.h" + +namespace mozilla { class MediaByteRange; } + +namespace stagefright { class MetaData; } + +namespace mp4_demuxer +{ + +struct StageFrightPrivate; + +class MP4Metadata +{ +public: + explicit MP4Metadata(Stream* aSource); + ~MP4Metadata(); + + uint32_t GetNumberTracks(mozilla::TrackInfo::TrackType aType) const; + mozilla::UniquePtr<mozilla::TrackInfo> GetTrackInfo(mozilla::TrackInfo::TrackType aType, + size_t aTrackNumber) const; + bool CanSeek() const; + + const CryptoFile& Crypto() const + { + return mCrypto; + } + + bool ReadTrackIndex(nsTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID); + +private: + int32_t GetTrackNumber(mozilla::TrackID aTrackID); + void UpdateCrypto(const stagefright::MetaData* aMetaData); + nsAutoPtr<StageFrightPrivate> mPrivate; + CryptoFile mCrypto; + nsRefPtr<Stream> mSource; +}; + +} // namespace mp4_demuxer + +#endif // MP4METADATA_H_
--- a/media/libstagefright/binding/include/mp4_demuxer/mp4_demuxer.h +++ b/media/libstagefright/binding/include/mp4_demuxer/mp4_demuxer.h @@ -1,30 +1,31 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MP4_DEMUXER_H_ #define MP4_DEMUXER_H_ -#include "nsAutoPtr.h" -#include "nsTArray.h" +#include "MediaInfo.h" +#include "MediaResource.h" +#include "mozilla/Monitor.h" +#include "mozilla/UniquePtr.h" #include "mp4_demuxer/DecoderData.h" #include "mp4_demuxer/Interval.h" #include "mp4_demuxer/Stream.h" #include "nsISupportsImpl.h" -#include "mozilla/Monitor.h" - -namespace mozilla { class MediaByteRange; } +#include "nsTArray.h" namespace mp4_demuxer { - +class Index; +class MP4Metadata; +class SampleIterator; using mozilla::Monitor; -struct StageFrightPrivate; typedef int64_t Microseconds; class MP4Demuxer { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MP4Demuxer) explicit MP4Demuxer(Stream* aSource, Monitor* aMonitor); @@ -39,19 +40,19 @@ public: void SeekAudio(Microseconds aTime); void SeekVideo(Microseconds aTime); // DemuxAudioSample and DemuxVideoSample functions // return nullptr on end of stream or error. already_AddRefed<mozilla::MediaRawData> DemuxAudioSample(); already_AddRefed<mozilla::MediaRawData> DemuxVideoSample(); - const CryptoFile& Crypto() { return mCrypto; } - const mozilla::AudioInfo& AudioConfig() { return mAudioConfig; } - const mozilla::VideoInfo& VideoConfig() { return mVideoConfig; } + const CryptoFile& Crypto() const; + const mozilla::AudioInfo& AudioConfig() const { return *mAudioConfig->GetAsAudioInfo(); } + const mozilla::VideoInfo& VideoConfig() const { return *mVideoConfig->GetAsVideoInfo(); } void UpdateIndex(const nsTArray<mozilla::MediaByteRange>& aByteRanges); void ConvertByteRangesToTime( const nsTArray<mozilla::MediaByteRange>& aByteRanges, nsTArray<Interval<Microseconds>>* aIntervals); int64_t GetEvictionOffset(Microseconds aTime); @@ -59,24 +60,25 @@ public: // Returns timestamp of next keyframe, or -1 if demuxer can't // report this. Microseconds GetNextKeyframeTime(); protected: ~MP4Demuxer(); private: - void UpdateCrypto(const stagefright::MetaData* aMetaData); - MP4AudioInfo mAudioConfig; - MP4VideoInfo mVideoConfig; - CryptoFile mCrypto; + mozilla::UniquePtr<mozilla::TrackInfo> mAudioConfig; + mozilla::UniquePtr<mozilla::TrackInfo> mVideoConfig; - nsAutoPtr<StageFrightPrivate> mPrivate; nsRefPtr<Stream> mSource; nsTArray<mozilla::MediaByteRange> mCachedByteRanges; nsTArray<Interval<Microseconds>> mCachedTimeRanges; Monitor* mMonitor; Microseconds mNextKeyframeTime; + mozilla::UniquePtr<MP4Metadata> mMetadata; + mozilla::UniquePtr<SampleIterator> mAudioIterator; + mozilla::UniquePtr<SampleIterator> mVideoIterator; + nsTArray<nsRefPtr<Index>> mIndexes; }; -} // namespace mozilla +} // namespace mp4_demuxer #endif // MP4_DEMUXER_H_
--- a/media/libstagefright/binding/mp4_demuxer.cpp +++ b/media/libstagefright/binding/mp4_demuxer.cpp @@ -1,326 +1,203 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "include/MPEG4Extractor.h" -#include "media/stagefright/DataSource.h" -#include "media/stagefright/MediaDefs.h" -#include "media/stagefright/MediaSource.h" -#include "media/stagefright/MetaData.h" +#include "mp4_demuxer/Index.h" +#include "mp4_demuxer/MP4Metadata.h" #include "mp4_demuxer/mp4_demuxer.h" -#include "mp4_demuxer/Index.h" -#include "MediaResource.h" #include <stdint.h> #include <algorithm> #include <limits> -using namespace stagefright; - namespace mp4_demuxer { -struct StageFrightPrivate -{ - StageFrightPrivate() : mCanSeek(false) {} - sp<MediaSource> mAudio; - nsAutoPtr<SampleIterator> mAudioIterator; - - sp<MediaSource> mVideo; - nsAutoPtr<SampleIterator> mVideoIterator; - - nsTArray<nsRefPtr<Index>> mIndexes; - - bool mCanSeek; -}; - -class DataSourceAdapter : public DataSource -{ -public: - explicit DataSourceAdapter(Stream* aSource) : mSource(aSource) {} - - ~DataSourceAdapter() {} - - virtual status_t initCheck() const { return NO_ERROR; } - - virtual ssize_t readAt(off64_t offset, void* data, size_t size) - { - MOZ_ASSERT(((ssize_t)size) >= 0); - size_t bytesRead; - if (!mSource->ReadAt(offset, data, size, &bytesRead)) - return ERROR_IO; - - if (bytesRead == 0) - return ERROR_END_OF_STREAM; - - MOZ_ASSERT(((ssize_t)bytesRead) > 0); - return bytesRead; - } - - virtual status_t getSize(off64_t* size) - { - if (!mSource->Length(size)) - return ERROR_UNSUPPORTED; - return NO_ERROR; - } - - virtual uint32_t flags() { return kWantsPrefetching | kIsHTTPBasedSource; } - - virtual status_t reconnectAtOffset(off64_t offset) { return NO_ERROR; } - -private: - nsRefPtr<Stream> mSource; -}; - MP4Demuxer::MP4Demuxer(Stream* source, Monitor* aMonitor) - : mPrivate(new StageFrightPrivate()) - , mSource(source) + : mSource(source) , mMonitor(aMonitor) , mNextKeyframeTime(-1) { } MP4Demuxer::~MP4Demuxer() { - if (mPrivate->mAudio.get()) { - mPrivate->mAudio->stop(); - } - if (mPrivate->mVideo.get()) { - mPrivate->mVideo->stop(); - } -} - -static void -ConvertIndex(nsTArray<Index::Indice>& aDest, - const stagefright::Vector<stagefright::MediaSource::Indice>& aIndex) -{ - for (size_t i = 0; i < aIndex.size(); i++) { - Index::Indice indice; - const stagefright::MediaSource::Indice& s_indice = aIndex[i]; - indice.start_offset = s_indice.start_offset; - indice.end_offset = s_indice.end_offset; - indice.start_composition = s_indice.start_composition; - indice.end_composition = s_indice.end_composition; - indice.sync = s_indice.sync; - aDest.AppendElement(indice); - } } bool MP4Demuxer::Init() { mMonitor->AssertCurrentThreadOwns(); - sp<MediaExtractor> e = new MPEG4Extractor(new DataSourceAdapter(mSource)); + + mMetadata = mozilla::MakeUnique<MP4Metadata>(mSource); // Read the number of tracks. If we can't find any, make sure to bail now before // attempting any new reads to make the retry system work. - size_t trackCount = e->countTracks(); - if (trackCount == 0) { + if (!mMetadata->GetNumberTracks(mozilla::TrackInfo::kAudioTrack) && + !mMetadata->GetNumberTracks(mozilla::TrackInfo::kVideoTrack)) { return false; } - for (size_t i = 0; i < trackCount; i++) { - sp<MetaData> metaData = e->getTrackMetaData(i); + auto audioInfo = mMetadata->GetTrackInfo(mozilla::TrackInfo::kAudioTrack, 0); + if (audioInfo) { + mAudioConfig = mozilla::Move(audioInfo); + nsTArray<Index::Indice> indices; + if (!mMetadata->ReadTrackIndex(indices, mAudioConfig->mTrackId)) { + return false; + } + nsRefPtr<Index> index = + new Index(indices, + mSource, + mAudioConfig->mTrackId, + /* aIsAudio = */ true, + mMonitor); + mIndexes.AppendElement(index); + mAudioIterator = mozilla::MakeUnique<SampleIterator>(index); + } - const char* mimeType; - if (metaData == nullptr || !metaData->findCString(kKeyMIMEType, &mimeType)) { - continue; + auto videoInfo = mMetadata->GetTrackInfo(mozilla::TrackInfo::kVideoTrack, 0); + if (videoInfo) { + mVideoConfig = mozilla::Move(videoInfo); + nsTArray<Index::Indice> indices; + if (!mMetadata->ReadTrackIndex(indices, mVideoConfig->mTrackId)) { + return false; } - if (!mPrivate->mAudio.get() && !strncmp(mimeType, "audio/", 6)) { - sp<MediaSource> track = e->getTrack(i); - if (track->start() != OK) { - return false; - } - mPrivate->mAudio = track; - mAudioConfig.Update(metaData.get(), mimeType); - - nsTArray<Index::Indice> indices; - ConvertIndex(indices, mPrivate->mAudio->exportIndex()); - nsRefPtr<Index> index = - new Index(indices, - mSource, - mAudioConfig.mTrackId, - /* aIsAudio = */ true, - mMonitor); - mPrivate->mIndexes.AppendElement(index); - mPrivate->mAudioIterator = new SampleIterator(index); - } else if (!mPrivate->mVideo.get() && !strncmp(mimeType, "video/", 6)) { - sp<MediaSource> track = e->getTrack(i); - if (track->start() != OK) { - return false; - } - mPrivate->mVideo = track; - mVideoConfig.Update(metaData.get(), mimeType); - - nsTArray<Index::Indice> indices; - ConvertIndex(indices, mPrivate->mVideo->exportIndex()); + nsRefPtr<Index> index = + new Index(indices, + mSource, + mVideoConfig->mTrackId, + /* aIsAudio = */ false, + mMonitor); + mIndexes.AppendElement(index); + mVideoIterator = mozilla::MakeUnique<SampleIterator>(index); + } - nsRefPtr<Index> index = - new Index(indices, - mSource, - mVideoConfig.mTrackId, - /* aIsAudio = */ false, - mMonitor); - mPrivate->mIndexes.AppendElement(index); - mPrivate->mVideoIterator = new SampleIterator(index); - } - } - sp<MetaData> metaData = e->getMetaData(); - UpdateCrypto(metaData.get()); - - int64_t movieDuration; - if (!mVideoConfig.mDuration && !mAudioConfig.mDuration && - metaData->findInt64(kKeyMovieDuration, &movieDuration)) { - // No duration were found in either tracks, use movie extend header box one. - mVideoConfig.mDuration = mAudioConfig.mDuration = movieDuration; - } - mPrivate->mCanSeek = e->flags() & MediaExtractor::CAN_SEEK; - - return mPrivate->mAudio.get() || mPrivate->mVideo.get(); -} - -void -MP4Demuxer::UpdateCrypto(const MetaData* aMetaData) -{ - const void* data; - size_t size; - uint32_t type; - - // There's no point in checking that the type matches anything because it - // isn't set consistently in the MPEG4Extractor. - if (!aMetaData->findData(kKeyPssh, &type, &data, &size)) { - return; - } - mCrypto.Update(reinterpret_cast<const uint8_t*>(data), size); + return mAudioIterator || mVideoIterator; } bool MP4Demuxer::HasValidAudio() { mMonitor->AssertCurrentThreadOwns(); - return mPrivate->mAudio.get() && mAudioConfig.IsValid(); + return mAudioIterator && mAudioConfig && mAudioConfig->IsValid(); } bool MP4Demuxer::HasValidVideo() { mMonitor->AssertCurrentThreadOwns(); - return mPrivate->mVideo.get() && mVideoConfig.IsValid(); + return mVideoIterator && mVideoConfig && mVideoConfig->IsValid(); } Microseconds MP4Demuxer::Duration() { mMonitor->AssertCurrentThreadOwns(); - return std::max(mVideoConfig.mDuration, mAudioConfig.mDuration); + int64_t videoDuration = mVideoConfig ? mVideoConfig->mDuration : 0; + int64_t audioDuration = mAudioConfig ? mAudioConfig->mDuration : 0; + return std::max(videoDuration, audioDuration); } bool MP4Demuxer::CanSeek() { mMonitor->AssertCurrentThreadOwns(); - return mPrivate->mCanSeek; + return mMetadata->CanSeek(); } void MP4Demuxer::SeekAudio(Microseconds aTime) { mMonitor->AssertCurrentThreadOwns(); - if (mPrivate->mAudioIterator) { - mPrivate->mAudioIterator->Seek(aTime); - } + MOZ_ASSERT(mAudioIterator); + mAudioIterator->Seek(aTime); } void MP4Demuxer::SeekVideo(Microseconds aTime) { mMonitor->AssertCurrentThreadOwns(); - if (mPrivate->mVideoIterator) { - mPrivate->mVideoIterator->Seek(aTime); - } + MOZ_ASSERT(mVideoIterator); + mVideoIterator->Seek(aTime); } already_AddRefed<mozilla::MediaRawData> MP4Demuxer::DemuxAudioSample() { mMonitor->AssertCurrentThreadOwns(); - if (!mPrivate->mAudioIterator) { - return nullptr; - } - nsRefPtr<mozilla::MediaRawData> sample(mPrivate->mAudioIterator->GetNext()); + MOZ_ASSERT(mAudioIterator); + nsRefPtr<mozilla::MediaRawData> sample(mAudioIterator->GetNext()); if (sample) { if (sample->mCrypto.mValid) { nsAutoPtr<MediaRawDataWriter> writer(sample->CreateWriter()); - writer->mCrypto.mMode = mAudioConfig.mCrypto.mMode; - writer->mCrypto.mIVSize = mAudioConfig.mCrypto.mIVSize; - writer->mCrypto.mKeyId.AppendElements(mAudioConfig.mCrypto.mKeyId); + writer->mCrypto.mMode = mAudioConfig->mCrypto.mMode; + writer->mCrypto.mIVSize = mAudioConfig->mCrypto.mIVSize; + writer->mCrypto.mKeyId.AppendElements(mAudioConfig->mCrypto.mKeyId); } } return sample.forget(); } already_AddRefed<MediaRawData> MP4Demuxer::DemuxVideoSample() { mMonitor->AssertCurrentThreadOwns(); - if (!mPrivate->mVideoIterator) { - return nullptr; - } - nsRefPtr<mozilla::MediaRawData> sample(mPrivate->mVideoIterator->GetNext()); + MOZ_ASSERT(mVideoIterator); + nsRefPtr<mozilla::MediaRawData> sample(mVideoIterator->GetNext()); if (sample) { - sample->mExtraData = mVideoConfig.mExtraData; + sample->mExtraData = mVideoConfig->GetAsVideoInfo()->mExtraData; if (sample->mCrypto.mValid) { nsAutoPtr<MediaRawDataWriter> writer(sample->CreateWriter()); - writer->mCrypto.mMode = mVideoConfig.mCrypto.mMode; - writer->mCrypto.mKeyId.AppendElements(mVideoConfig.mCrypto.mKeyId); + writer->mCrypto.mMode = mVideoConfig->mCrypto.mMode; + writer->mCrypto.mKeyId.AppendElements(mVideoConfig->mCrypto.mKeyId); } if (sample->mTime >= mNextKeyframeTime) { - mNextKeyframeTime = mPrivate->mVideoIterator->GetNextKeyframeTime(); + mNextKeyframeTime = mVideoIterator->GetNextKeyframeTime(); } } return sample.forget(); } void MP4Demuxer::UpdateIndex(const nsTArray<mozilla::MediaByteRange>& aByteRanges) { mMonitor->AssertCurrentThreadOwns(); - for (int i = 0; i < mPrivate->mIndexes.Length(); i++) { - mPrivate->mIndexes[i]->UpdateMoofIndex(aByteRanges); + for (int i = 0; i < mIndexes.Length(); i++) { + mIndexes[i]->UpdateMoofIndex(aByteRanges); } } void MP4Demuxer::ConvertByteRangesToTime( const nsTArray<mozilla::MediaByteRange>& aByteRanges, nsTArray<Interval<Microseconds>>* aIntervals) { mMonitor->AssertCurrentThreadOwns(); - if (mPrivate->mIndexes.IsEmpty()) { + if (mIndexes.IsEmpty()) { return; } Microseconds lastComposition = 0; nsTArray<Microseconds> endCompositions; - for (int i = 0; i < mPrivate->mIndexes.Length(); i++) { + for (int i = 0; i < mIndexes.Length(); i++) { Microseconds endComposition = - mPrivate->mIndexes[i]->GetEndCompositionIfBuffered(aByteRanges); + mIndexes[i]->GetEndCompositionIfBuffered(aByteRanges); endCompositions.AppendElement(endComposition); lastComposition = std::max(lastComposition, endComposition); } if (aByteRanges != mCachedByteRanges) { mCachedByteRanges = aByteRanges; mCachedTimeRanges.Clear(); - for (int i = 0; i < mPrivate->mIndexes.Length(); i++) { + for (int i = 0; i < mIndexes.Length(); i++) { nsTArray<Interval<Microseconds>> ranges; - mPrivate->mIndexes[i]->ConvertByteRangesToTimeRanges(aByteRanges, &ranges); + mIndexes[i]->ConvertByteRangesToTimeRanges(aByteRanges, &ranges); if (lastComposition && endCompositions[i]) { Interval<Microseconds>::SemiNormalAppend( ranges, Interval<Microseconds>(endCompositions[i], lastComposition)); } if (i) { nsTArray<Interval<Microseconds>> intersection; Interval<Microseconds>::Intersection(mCachedTimeRanges, ranges, &intersection); @@ -332,30 +209,33 @@ MP4Demuxer::ConvertByteRangesToTime( } aIntervals->AppendElements(mCachedTimeRanges); } int64_t MP4Demuxer::GetEvictionOffset(Microseconds aTime) { mMonitor->AssertCurrentThreadOwns(); - if (mPrivate->mIndexes.IsEmpty()) { + if (mIndexes.IsEmpty()) { return 0; } uint64_t offset = std::numeric_limits<uint64_t>::max(); - for (int i = 0; i < mPrivate->mIndexes.Length(); i++) { - offset = std::min(offset, mPrivate->mIndexes[i]->GetEvictionOffset(aTime)); + for (int i = 0; i < mIndexes.Length(); i++) { + offset = std::min(offset, mIndexes[i]->GetEvictionOffset(aTime)); } return offset == std::numeric_limits<uint64_t>::max() ? 0 : offset; } Microseconds MP4Demuxer::GetNextKeyframeTime() { mMonitor->AssertCurrentThreadOwns(); - if (!mPrivate->mVideoIterator) { - return -1; - } return mNextKeyframeTime; } +const CryptoFile& +MP4Demuxer::Crypto() const +{ + return mMetadata->Crypto(); +} + } // namespace mp4_demuxer
--- a/media/libstagefright/moz.build +++ b/media/libstagefright/moz.build @@ -56,16 +56,17 @@ EXPORTS.mp4_demuxer += [ 'binding/include/mp4_demuxer/ByteReader.h', 'binding/include/mp4_demuxer/ByteWriter.h', 'binding/include/mp4_demuxer/DecoderData.h', 'binding/include/mp4_demuxer/H264.h', 'binding/include/mp4_demuxer/Index.h', 'binding/include/mp4_demuxer/Interval.h', 'binding/include/mp4_demuxer/MoofParser.h', 'binding/include/mp4_demuxer/mp4_demuxer.h', + 'binding/include/mp4_demuxer/MP4Metadata.h', 'binding/include/mp4_demuxer/MP4TrackDemuxer.h', 'binding/include/mp4_demuxer/SinfParser.h', 'binding/include/mp4_demuxer/Stream.h', ] EXPORTS.demuxer += [ 'binding/include/demuxer/TrackDemuxer.h', ] @@ -84,16 +85,17 @@ UNIFIED_SOURCES += [ 'binding/AnnexB.cpp', 'binding/Box.cpp', 'binding/BufferStream.cpp', 'binding/DecoderData.cpp', 'binding/H264.cpp', 'binding/Index.cpp', 'binding/MoofParser.cpp', 'binding/mp4_demuxer.cpp', + 'binding/MP4Metadata.cpp', 'binding/MP4TrackDemuxer.cpp', 'binding/SinfParser.cpp', 'frameworks/av/media/libstagefright/DataSource.cpp', 'frameworks/av/media/libstagefright/ESDS.cpp', 'frameworks/av/media/libstagefright/foundation/AAtomizer.cpp', 'frameworks/av/media/libstagefright/foundation/ABitReader.cpp', 'frameworks/av/media/libstagefright/foundation/ABuffer.cpp', 'frameworks/av/media/libstagefright/foundation/AString.cpp',