Bug 1141785 - Force all audio samples to be keyframes. r=k17e

This commit is contained in:
Bobby Holley 2015-03-12 20:26:08 -07:00
parent c628b9ad38
commit 3bf0414956
6 changed files with 21 additions and 17 deletions

View File

@ -293,7 +293,7 @@ public:
// consumers of ParseStartAndEndTimestamps to add their timestamp offset
// manually. This allows the ContainerParser to be shared across different
// timestampOffsets.
mParser = new mp4_demuxer::MoofParser(mStream, 0, &mMonitor);
mParser = new mp4_demuxer::MoofParser(mStream, 0, /* aIsAudio = */ false, &mMonitor);
mInitData = new LargeDataBuffer();
} else if (!mStream || !mParser) {
return false;

View File

@ -228,12 +228,12 @@ SampleIterator::GetNextKeyframeTime()
}
Index::Index(const stagefright::Vector<MediaSource::Indice>& aIndex,
Stream* aSource, uint32_t aTrackId, Monitor* aMonitor)
Stream* aSource, uint32_t aTrackId, bool aIsAudio, Monitor* aMonitor)
: mSource(aSource)
, mMonitor(aMonitor)
{
if (aIndex.isEmpty()) {
mMoofParser = new MoofParser(aSource, aTrackId, aMonitor);
mMoofParser = new MoofParser(aSource, aTrackId, aIsAudio, aMonitor);
} else {
for (size_t i = 0; i < aIndex.size(); i++) {
const MediaSource::Indice& indice = aIndex[i];

View File

@ -29,7 +29,7 @@ MoofParser::RebuildFragmentedIndex(BoxContext& aContext)
mInitRange = MediaByteRange(0, box.Range().mEnd);
ParseMoov(box);
} else if (box.IsType("moof")) {
Moof moof(box, mTrex, mMdhd, mEdts, mSinf);
Moof moof(box, mTrex, mMdhd, mEdts, mSinf, mIsAudio);
if (!mMoofs.IsEmpty()) {
// Stitch time ranges together in the case of a (hopefully small) time
@ -214,13 +214,13 @@ MoofParser::ParseEncrypted(Box& aBox)
}
}
Moof::Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf)
Moof::Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, bool aIsAudio)
: mRange(aBox.Range())
, mMaxRoundingError(0)
{
for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
if (box.IsType("traf")) {
ParseTraf(box, aTrex, aMdhd, aEdts, aSinf);
ParseTraf(box, aTrex, aMdhd, aEdts, aSinf, aIsAudio);
}
}
ProcessCenc();
@ -291,7 +291,7 @@ Moof::ProcessCenc()
}
void
Moof::ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf)
Moof::ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, bool aIsAudio)
{
Tfhd tfhd(aTrex);
Tfdt tfdt;
@ -314,7 +314,7 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf)
// Now search for TRUN box.
for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
if (box.IsType("trun")) {
ParseTrun(box, tfhd, tfdt, aMdhd, aEdts);
ParseTrun(box, tfhd, tfdt, aMdhd, aEdts, aIsAudio);
if (IsValid()) {
break;
}
@ -345,7 +345,7 @@ public:
};
void
Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts)
Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts, bool aIsAudio)
{
if (!aTfhd.IsValid() || !aTfdt.IsValid() ||
!aMdhd.IsValid() || !aEdts.IsValid()) {
@ -416,7 +416,9 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts)
aMdhd.ToMicroseconds((int64_t)decodeTime + ctsOffset + sampleDuration - aEdts.mMediaStart));
decodeTime += sampleDuration;
sample.mSync = !(sampleFlags & 0x1010000);
// Sometimes audio streams don't properly mark their samples as keyframes,
// because every audio sample is a keyframe.
sample.mSync = !(sampleFlags & 0x1010000) || aIsAudio;
mIndex.AppendElement(sample);

View File

@ -38,7 +38,7 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Index)
Index(const stagefright::Vector<stagefright::MediaSource::Indice>& aIndex,
Stream* aSource, uint32_t aTrackId, Monitor* aMonitor);
Stream* aSource, uint32_t aTrackId, bool aIsAudio, Monitor* aMonitor);
void UpdateMoofIndex(const nsTArray<mozilla::MediaByteRange>& aByteRanges);
Microseconds GetEndCompositionIfBuffered(

View File

@ -168,7 +168,7 @@ private:
class Moof : public Atom
{
public:
Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf);
Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, bool aIsAudio);
bool GetAuxInfo(AtomType aType, nsTArray<MediaByteRange>* aByteRanges);
void FixRounding(const Moof& aMoof);
@ -181,8 +181,8 @@ public:
nsTArray<Saio> mSaios;
private:
void ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf);
void ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts);
void ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts, Sinf& aSinf, bool aIsAudio);
void ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts, bool aIsAudio);
void ParseSaiz(Box& aBox);
void ParseSaio(Box& aBox);
bool ProcessCenc();
@ -192,11 +192,12 @@ private:
class MoofParser
{
public:
MoofParser(Stream* aSource, uint32_t aTrackId, Monitor* aMonitor)
MoofParser(Stream* aSource, uint32_t aTrackId, bool aIsAudio, Monitor* aMonitor)
: mSource(aSource)
, mOffset(0)
, mTrex(aTrackId)
, mMonitor(aMonitor)
, mIsAudio(aIsAudio)
{
// Setting the mTrex.mTrackId to 0 is a nasty work around for calculating
// the composition range for MSE. We need an array of tracks.
@ -233,6 +234,7 @@ public:
nsTArray<Moof>& Moofs() { mMonitor->AssertCurrentThreadOwns(); return mMoofs; }
private:
nsTArray<Moof> mMoofs;
bool mIsAudio;
};
}

View File

@ -122,7 +122,7 @@ MP4Demuxer::Init()
mAudioConfig.Update(metaData, mimeType);
nsRefPtr<Index> index = new Index(mPrivate->mAudio->exportIndex(),
mSource, mAudioConfig.mTrackId,
mMonitor);
/* aIsAudio = */ true, mMonitor);
mPrivate->mIndexes.AppendElement(index);
mPrivate->mAudioIterator = new SampleIterator(index);
} else if (!mPrivate->mVideo.get() && !strncmp(mimeType, "video/", 6)) {
@ -134,7 +134,7 @@ MP4Demuxer::Init()
mVideoConfig.Update(metaData, mimeType);
nsRefPtr<Index> index = new Index(mPrivate->mVideo->exportIndex(),
mSource, mVideoConfig.mTrackId,
mMonitor);
/* aIsAudio = */ false, mMonitor);
mPrivate->mIndexes.AppendElement(index);
mPrivate->mVideoIterator = new SampleIterator(index);
}