Bug 1343461 - add a wrapper class to encapsulate rust/stagefright sample table. r=gerald

MozReview-Commit-ID: 4UgToySaEmb

--HG--
extra : rebase_source : b91481f844d94bd3a9f7e6bfeaa08391f117e967
This commit is contained in:
Alfredo.Yang 2017-03-01 10:53:49 +08:00
parent 3157303745
commit 48c54615b1
6 changed files with 167 additions and 43 deletions

View File

@ -37,7 +37,7 @@ class MP4TrackDemuxer : public MediaTrackDemuxer
public:
MP4TrackDemuxer(MP4Demuxer* aParent,
UniquePtr<TrackInfo>&& aInfo,
const nsTArray<mp4_demuxer::Index::Indice>& indices);
const mp4_demuxer::IndiceWrapper& aIndices);
UniquePtr<TrackInfo> GetInfo() const override;
@ -152,9 +152,10 @@ MP4Demuxer::Init()
UniquePtr<TrackInfo> info =
metadata.GetTrackInfo(TrackInfo::kAudioTrack, i);
if (info) {
FallibleTArray<mp4_demuxer::Index::Indice> indices;
if (metadata.ReadTrackIndex(indices, info->mTrackId)) {
mAudioDemuxers[i] = new MP4TrackDemuxer(this, Move(info), indices);
UniquePtr<mp4_demuxer::IndiceWrapper> indices =
metadata.GetTrackIndice(info->mTrackId);
if (indices) {
mAudioDemuxers[i] = new MP4TrackDemuxer(this, Move(info), *indices.get());
}
}
}
@ -166,9 +167,10 @@ MP4Demuxer::Init()
UniquePtr<TrackInfo> info =
metadata.GetTrackInfo(TrackInfo::kVideoTrack, i);
if (info) {
FallibleTArray<mp4_demuxer::Index::Indice> indices;
if (metadata.ReadTrackIndex(indices, info->mTrackId)) {
mVideoDemuxers[i] = new MP4TrackDemuxer(this, Move(info), indices);
UniquePtr<mp4_demuxer::IndiceWrapper> indices =
metadata.GetTrackIndice(info->mTrackId);
if (indices) {
mVideoDemuxers[i] = new MP4TrackDemuxer(this, Move(info), *indices.get());
}
}
}
@ -263,11 +265,11 @@ MP4Demuxer::GetCrypto()
MP4TrackDemuxer::MP4TrackDemuxer(MP4Demuxer* aParent,
UniquePtr<TrackInfo>&& aInfo,
const nsTArray<mp4_demuxer::Index::Indice>& indices)
const mp4_demuxer::IndiceWrapper& aIndices)
: mParent(aParent)
, mStream(new mp4_demuxer::ResourceStream(mParent->mResource))
, mInfo(Move(aInfo))
, mIndex(new mp4_demuxer::Index(indices,
, mIndex(new mp4_demuxer::Index(aIndices,
mStream,
mInfo->mTrackId,
mInfo->IsAudio()))

View File

@ -5,6 +5,7 @@
#include "mp4_demuxer/ByteReader.h"
#include "mp4_demuxer/Index.h"
#include "mp4_demuxer/Interval.h"
#include "mp4_demuxer/MP4Metadata.h"
#include "mp4_demuxer/SinfParser.h"
#include "nsAutoPtr.h"
#include "mozilla/RefPtr.h"
@ -297,17 +298,17 @@ SampleIterator::GetNextKeyframeTime()
return -1;
}
Index::Index(const nsTArray<Indice>& aIndex,
Index::Index(const IndiceWrapper& aIndices,
Stream* aSource,
uint32_t aTrackId,
bool aIsAudio)
: mSource(aSource)
, mIsAudio(aIsAudio)
{
if (aIndex.IsEmpty()) {
if (!aIndices.Length()) {
mMoofParser = new MoofParser(aSource, aTrackId, aIsAudio);
} else {
if (!mIndex.SetCapacity(aIndex.Length(), fallible)) {
if (!mIndex.SetCapacity(aIndices.Length(), fallible)) {
// OOM.
return;
}
@ -316,8 +317,12 @@ Index::Index(const nsTArray<Indice>& aIndex,
bool haveSync = false;
bool progressive = true;
int64_t lastOffset = 0;
for (size_t i = 0; i < aIndex.Length(); i++) {
const Indice& indice = aIndex[i];
for (size_t i = 0; i < aIndices.Length(); i++) {
Indice indice;
if (!aIndices.GetIndice(i, indice)) {
// Out of index?
return;
}
if (indice.sync || mIsAudio) {
haveSync = true;
}
@ -364,8 +369,12 @@ Index::Index(const nsTArray<Indice>& aIndex,
}
if (mDataOffset.Length() && progressive) {
Indice indice;
if (!aIndices.GetIndice(aIndices.Length() - 1, indice)) {
return;
}
auto& last = mDataOffset.LastElement();
last.mEndOffset = aIndex.LastElement().end_offset;
last.mEndOffset = indice.end_offset;
last.mTime = Interval<int64_t>(intervalTime.GetStart(), intervalTime.GetEnd());
} else {
mDataOffset.Clear();

View File

@ -146,6 +146,87 @@ private:
mozilla::UniquePtr<mp4parse_parser, FreeMP4Parser> mRustParser;
};
class IndiceWrapperStagefright : public IndiceWrapper {
public:
size_t Length() const override;
bool GetIndice(size_t aIndex, Index::Indice& aIndice) const override;
explicit IndiceWrapperStagefright(FallibleTArray<Index::Indice>& aIndice);
protected:
FallibleTArray<Index::Indice> mIndice;
};
IndiceWrapperStagefright::IndiceWrapperStagefright(FallibleTArray<Index::Indice>& aIndice)
{
mIndice.SwapElements(aIndice);
}
size_t
IndiceWrapperStagefright::Length() const
{
return mIndice.Length();
}
bool
IndiceWrapperStagefright::GetIndice(size_t aIndex, Index::Indice& aIndice) const
{
if (aIndex >= mIndice.Length()) {
MOZ_LOG(sLog, LogLevel::Error, ("Index overflow in indice"));
return false;
}
aIndice = mIndice[aIndex];
return true;
}
// the owner of mIndice is rust mp4 paser, so lifetime of this class
// SHOULD NOT longer than rust parser.
class IndiceWrapperRust : public IndiceWrapper
{
public:
size_t Length() const override;
bool GetIndice(size_t aIndex, Index::Indice& aIndice) const override;
explicit IndiceWrapperRust(mp4parse_byte_data& aRustIndice);
protected:
UniquePtr<mp4parse_byte_data> mIndice;
};
IndiceWrapperRust::IndiceWrapperRust(mp4parse_byte_data& aRustIndice)
: mIndice(mozilla::MakeUnique<mp4parse_byte_data>())
{
mIndice->length = aRustIndice.length;
mIndice->indices = aRustIndice.indices;
}
size_t
IndiceWrapperRust::Length() const
{
return mIndice->length;
}
bool
IndiceWrapperRust::GetIndice(size_t aIndex, Index::Indice& aIndice) const
{
if (aIndex >= mIndice->length) {
MOZ_LOG(sLog, LogLevel::Error, ("Index overflow in indice"));
return false;
}
const mp4parse_indice* indice = &mIndice->indices[aIndex];
aIndice.start_offset = indice->start_offset;
aIndice.end_offset = indice->end_offset;
aIndice.start_composition = indice->start_composition;
aIndice.end_composition = indice->end_composition;
aIndice.start_decode = indice->start_decode;
aIndice.sync = indice->sync;
return true;
}
MP4Metadata::MP4Metadata(Stream* aSource)
: mStagefright(MakeUnique<MP4MetadataStagefright>(aSource))
, mRust(MakeUnique<MP4MetadataRust>(aSource))
@ -334,29 +415,42 @@ MP4Metadata::Crypto() const
return crypto;
}
bool
MP4Metadata::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID)
mozilla::UniquePtr<IndiceWrapper>
MP4Metadata::GetTrackIndice(mozilla::TrackID aTrackID)
{
bool ret = mStagefright->ReadTrackIndex(aDest, aTrackID);
FallibleTArray<Index::Indice> indiceSF;
if(!mStagefright->ReadTrackIndex(indiceSF, aTrackID)) {
return nullptr;
}
mp4parse_byte_data indiceRust = {};
if ((mPreferRust || mRustTestMode) &&
!mRust->ReadTrackIndice(&indiceRust, aTrackID)) {
return nullptr;
}
#ifndef RELEASE_OR_BETA
if (mRustTestMode && ret && mRust) {
mp4parse_byte_data data = {};
bool rustRet = mRust->ReadTrackIndice(&data, aTrackID);
MOZ_DIAGNOSTIC_ASSERT(rustRet);
MOZ_DIAGNOSTIC_ASSERT(data.length == aDest.Length());
for (uint32_t i = 0; i < data.length; i++) {
MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_offset == aDest[i].start_offset);
MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_offset == aDest[i].end_offset);
MOZ_DIAGNOSTIC_ASSERT(llabs(data.indices[i].start_composition - int64_t(aDest[i].start_composition)) <= 1);
MOZ_DIAGNOSTIC_ASSERT(llabs(data.indices[i].end_composition - int64_t(aDest[i].end_composition)) <= 1);
MOZ_DIAGNOSTIC_ASSERT(llabs(data.indices[i].start_decode - int64_t(aDest[i].start_decode)) <= 1);
MOZ_DIAGNOSTIC_ASSERT(data.indices[i].sync == aDest[i].sync);
if (mRustTestMode) {
MOZ_DIAGNOSTIC_ASSERT(indiceRust.length == indiceSF.Length());
for (uint32_t i = 0; i < indiceRust.length; i++) {
MOZ_DIAGNOSTIC_ASSERT(indiceRust.indices[i].start_offset == indiceSF[i].start_offset);
MOZ_DIAGNOSTIC_ASSERT(indiceRust.indices[i].end_offset == indiceSF[i].end_offset);
MOZ_DIAGNOSTIC_ASSERT(llabs(indiceRust.indices[i].start_composition - int64_t(indiceSF[i].start_composition)) <= 1);
MOZ_DIAGNOSTIC_ASSERT(llabs(indiceRust.indices[i].end_composition - int64_t(indiceSF[i].end_composition)) <= 1);
MOZ_DIAGNOSTIC_ASSERT(llabs(indiceRust.indices[i].start_decode - int64_t(indiceSF[i].start_decode)) <= 1);
MOZ_DIAGNOSTIC_ASSERT(indiceRust.indices[i].sync == indiceSF[i].sync);
}
}
#endif
return ret;
UniquePtr<IndiceWrapper> indice;
if (mPreferRust) {
indice = mozilla::MakeUnique<IndiceWrapperRust>(indiceRust);
} else {
indice = mozilla::MakeUnique<IndiceWrapperStagefright>(indiceSF);
}
return indice;
}
static inline bool

View File

@ -19,6 +19,7 @@ namespace mp4_demuxer
{
class Index;
class IndiceWrapper;
typedef int64_t Microseconds;
@ -92,7 +93,7 @@ public:
Interval<Microseconds> mTime;
};
Index(const nsTArray<Indice>& aIndex,
Index(const IndiceWrapper& aIndices,
Stream* aSource,
uint32_t aTrackId,
bool aIsAudio);

View File

@ -11,6 +11,7 @@
#include "MediaData.h"
#include "MediaInfo.h"
#include "Stream.h"
#include "mp4parse.h"
namespace mp4_demuxer
{
@ -18,6 +19,17 @@ namespace mp4_demuxer
class MP4MetadataStagefright;
class MP4MetadataRust;
class IndiceWrapper {
public:
virtual size_t Length() const = 0;
// TODO: Index::Indice is from stagefright, we should use another struct once
// stagefrigth is removed.
virtual bool GetIndice(size_t aIndex, Index::Indice& aIndice) const = 0;
virtual ~IndiceWrapper() {}
};
class MP4Metadata
{
public:
@ -32,7 +44,7 @@ public:
const CryptoFile& Crypto() const;
bool ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID);
mozilla::UniquePtr<IndiceWrapper> GetTrackIndice(mozilla::TrackID aTrackID);
private:
UniquePtr<MP4MetadataStagefright> mStagefright;

View File

@ -236,11 +236,14 @@ TEST(stagefright_MPEG4Metadata, test_case_mp4)
EXPECT_EQ(testFiles[test].mVideoDuration, videoInfo->mDuration);
EXPECT_EQ(testFiles[test].mWidth, videoInfo->mDisplay.width);
EXPECT_EQ(testFiles[test].mHeight, videoInfo->mDisplay.height);
FallibleTArray<mp4_demuxer::Index::Indice> indices;
EXPECT_TRUE(metadata.ReadTrackIndex(indices, videoInfo->mTrackId));
for (const mp4_demuxer::Index::Indice& indice : indices) {
EXPECT_TRUE(indice.start_offset <= indice.end_offset);
EXPECT_TRUE(indice.start_composition <= indice.end_composition);
UniquePtr<IndiceWrapper> indices = metadata.GetTrackIndice(videoInfo->mTrackId);
EXPECT_TRUE(!!indices);
for (size_t i = 0; i < indices->Length(); i++) {
Index::Indice data;
EXPECT_TRUE(indices->GetIndice(i, data));
EXPECT_TRUE(data.start_offset <= data.end_offset);
EXPECT_TRUE(data.start_composition <= data.end_composition);
}
}
trackInfo = metadata.GetTrackInfo(TrackInfo::kAudioTrack, 0);
@ -254,11 +257,14 @@ TEST(stagefright_MPEG4Metadata, test_case_mp4)
EXPECT_TRUE(audioInfo->IsAudio());
EXPECT_EQ(testFiles[test].mAudioDuration, audioInfo->mDuration);
EXPECT_EQ(testFiles[test].mAudioProfile, audioInfo->mProfile);
FallibleTArray<mp4_demuxer::Index::Indice> indices;
EXPECT_TRUE(metadata.ReadTrackIndex(indices, audioInfo->mTrackId));
for (const mp4_demuxer::Index::Indice& indice : indices) {
EXPECT_TRUE(indice.start_offset <= indice.end_offset);
EXPECT_TRUE(indice.start_composition <= indice.end_composition);
UniquePtr<IndiceWrapper> indices = metadata.GetTrackIndice(audioInfo->mTrackId);
EXPECT_TRUE(!!indices);
for (size_t i = 0; i < indices->Length(); i++) {
Index::Indice data;
EXPECT_TRUE(indices->GetIndice(i, data));
EXPECT_TRUE(data.start_offset <= data.end_offset);
EXPECT_TRUE(data.start_composition <= data.end_composition);
}
}
EXPECT_FALSE(metadata.GetTrackInfo(TrackInfo::kTextTrack, 0));