Bug 1341483 - MP4Metadata::ReadTrackIndex() now also returns a success/error code - r?kinetik
MozReview-Commit-ID: GO7kz1huaQl
--- a/dom/media/fmp4/MP4Demuxer.cpp
+++ b/dom/media/fmp4/MP4Demuxer.cpp
@@ -204,21 +204,20 @@ MP4Demuxer::Init()
RESULT_DETAIL("Invalid MP4 audio track (%s)",
info.Result().Description().get()));
}
continue;
} else if (NS_FAILED(info.Result()) && result == NS_OK) {
result = Move(info.Result());
}
FallibleTArray<mp4_demuxer::Index::Indice> indices;
- if (!metadata.ReadTrackIndex(indices, info.Ref()->mTrackId)) {
+ MediaResult rv = metadata.ReadTrackIndex(indices, info.Ref()->mTrackId);
+ if (NS_FAILED(rv)) {
if (result == NS_OK) {
- result =
- MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
- RESULT_DETAIL("Invalid MP4 audio track index list"));
+ result = rv;
}
continue;
}
mAudioDemuxers[i] = new MP4TrackDemuxer(this, Move(info.Ref()), indices);
}
}
if (videoTrackCount.Ref() != 0) {
@@ -239,21 +238,20 @@ MP4Demuxer::Init()
RESULT_DETAIL("Invalid MP4 video track (%s)",
info.Result().Description().get()));
}
continue;
} else if (NS_FAILED(info.Result()) && result == NS_OK) {
result = Move(info.Result());
}
FallibleTArray<mp4_demuxer::Index::Indice> indices;
- if (!metadata.ReadTrackIndex(indices, info.Ref()->mTrackId)) {
+ MediaResult rv = metadata.ReadTrackIndex(indices, info.Ref()->mTrackId);
+ if (NS_FAILED(rv)) {
if (result == NS_OK) {
- result =
- MediaResult(NS_ERROR_DOM_MEDIA_DEMUXER_ERR,
- RESULT_DETAIL("Invalid MP4 video track index list"));
+ result = rv;
}
continue;
}
mVideoDemuxers[i] = new MP4TrackDemuxer(this, Move(info.Ref()), indices);
}
}
mp4_demuxer::MP4Metadata::ResultAndCryptoFile cryptoFile =
--- a/media/libstagefright/binding/MP4Metadata.cpp
+++ b/media/libstagefright/binding/MP4Metadata.cpp
@@ -7,16 +7,17 @@
#include "media/stagefright/MediaDefs.h"
#include "media/stagefright/MediaSource.h"
#include "media/stagefright/MetaData.h"
#include "mozilla/Assertions.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/Logging.h"
#include "mozilla/RefPtr.h"
+#include "mozilla/SizePrintfMacros.h"
#include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "VideoUtils.h"
#include "mp4_demuxer/MoofParser.h"
#include "mp4_demuxer/MP4Metadata.h"
#include "mp4_demuxer/Stream.h"
#include "MediaPrefs.h"
#include "mp4parse.h"
@@ -84,17 +85,19 @@ public:
MP4Metadata::ResultAndTrackCount
GetNumberTracks(mozilla::TrackInfo::TrackType aType) const;
MP4Metadata::ResultAndTrackInfo GetTrackInfo(
mozilla::TrackInfo::TrackType aType, size_t aTrackNumber) const;
bool CanSeek() const;
MP4Metadata::ResultAndCryptoFile Crypto() const;
- bool ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID);
+ mozilla::MediaResult
+ ReadTrackIndex(FallibleTArray<Index::Indice>& aDest,
+ mozilla::TrackID aTrackID);
private:
int32_t GetTrackNumber(mozilla::TrackID aTrackID);
void UpdateCrypto(const stagefright::MetaData* aMetaData);
mozilla::UniquePtr<mozilla::TrackInfo> CheckTrack(const char* aMimeType,
stagefright::MetaData* aMetaData,
int32_t aIndex) const;
CryptoFile mCrypto;
@@ -133,17 +136,18 @@ public:
MP4Metadata::ResultAndTrackCount
GetNumberTracks(mozilla::TrackInfo::TrackType aType) const;
MP4Metadata::ResultAndTrackInfo GetTrackInfo(
mozilla::TrackInfo::TrackType aType, size_t aTrackNumber) const;
bool CanSeek() const;
MP4Metadata::ResultAndCryptoFile Crypto() const;
- bool ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID);
+ mozilla::MediaResult
+ ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID);
private:
void UpdateCrypto();
Maybe<uint32_t> TrackTypeToGlobalTrackIndex(mozilla::TrackInfo::TrackType aType, size_t aTrackNumber) const;
CryptoFile mCrypto;
RefPtr<Stream> mSource;
RustStreamAdaptor mRustSource;
@@ -455,65 +459,69 @@ MP4Metadata::Crypto() const
if (mPreferRust) {
return rustCrypto;
}
return crypto;
}
-bool
-MP4Metadata::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID)
+mozilla::MediaResult
+MP4Metadata::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest,
+ mozilla::TrackID aTrackID)
{
- bool ret = mStagefright->ReadTrackIndex(aDest, aTrackID);
+ mozilla::MediaResult ret =
+ mStagefright->ReadTrackIndex(aDest, aTrackID);
#ifndef RELEASE_OR_BETA
- if (mRustTestMode && ret && mRust) {
+ if (mRustTestMode && NS_SUCCEEDED(ret) && mRust) {
mp4parse_byte_data data = {};
- bool rustRet = mRust->ReadTrackIndice(&data, aTrackID);
- MOZ_DIAGNOSTIC_ASSERT(rustRet);
+ mozilla::MediaResult rustRet = mRust->ReadTrackIndice(&data, aTrackID);
+ MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(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);
}
}
#endif
return ret;
}
-static inline bool
+static inline mozilla::MediaResult
ConvertIndex(FallibleTArray<Index::Indice>& aDest,
const nsTArray<stagefright::MediaSource::Indice>& aIndex,
int64_t aMediaTime)
{
if (!aDest.SetCapacity(aIndex.Length(), mozilla::fallible)) {
- return false;
+ return MediaResult{NS_ERROR_OUT_OF_MEMORY,
+ RESULT_DETAIL("Could not resize to %" PRIuSIZE " indices",
+ aIndex.Length())};
}
for (size_t i = 0; i < aIndex.Length(); 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 - aMediaTime;
indice.end_composition = s_indice.end_composition - aMediaTime;
indice.start_decode = s_indice.start_decode;
indice.sync = s_indice.sync;
// FIXME: Make this infallible after bug 968520 is done.
MOZ_ALWAYS_TRUE(aDest.AppendElement(indice, mozilla::fallible));
MOZ_LOG(sLog, LogLevel::Debug, ("s_o: %" PRIu64 ", e_o: %" PRIu64 ", s_c: %" PRIu64 ", e_c: %" PRIu64 ", s_d: %" PRIu64 ", sync: %d\n",
indice.start_offset, indice.end_offset, indice.start_composition, indice.end_composition,
indice.start_decode, indice.sync));
}
- return true;
+ return NS_OK;
}
MP4MetadataStagefright::MP4MetadataStagefright(Stream* aSource)
: mSource(aSource)
, mMetadataExtractor(new MPEG4Extractor(new DataSourceAdapter(mSource)))
, mCanSeek(mMetadataExtractor->flags() & MediaExtractor::CAN_SEEK)
{
sp<MetaData> metaData = mMetadataExtractor->getMetaData();
@@ -676,36 +684,39 @@ MP4MetadataStagefright::UpdateCrypto(con
// 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
-MP4MetadataStagefright::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID)
+mozilla::MediaResult
+MP4MetadataStagefright::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest,
+ mozilla::TrackID aTrackID)
{
size_t numTracks = mMetadataExtractor->countTracks();
int32_t trackNumber = GetTrackNumber(aTrackID);
if (trackNumber < 0) {
- return false;
+ return MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
+ RESULT_DETAIL("Cannot find track id %d",
+ int(aTrackID)));
}
sp<MediaSource> track = mMetadataExtractor->getTrack(trackNumber);
if (!track.get()) {
- return false;
+ return MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
+ RESULT_DETAIL("Cannot access track id %d",
+ int(aTrackID)));
}
sp<MetaData> metadata = mMetadataExtractor->getTrackMetaData(trackNumber);
int64_t mediaTime;
if (!metadata->findInt64(kKeyMediaTime, &mediaTime)) {
mediaTime = 0;
}
- bool rv = ConvertIndex(aDest, track->exportIndex(), mediaTime);
-
- return rv;
+ return ConvertIndex(aDest, track->exportIndex(), mediaTime);
}
int32_t
MP4MetadataStagefright::GetTrackNumber(mozilla::TrackID aTrackID)
{
size_t numTracks = mMetadataExtractor->countTracks();
for (size_t i = 0; i < numTracks; i++) {
sp<MetaData> metaData = mMetadataExtractor->getTrackMetaData(i);
@@ -990,35 +1001,39 @@ MP4MetadataRust::CanSeek() const
}
MP4Metadata::ResultAndCryptoFile
MP4MetadataRust::Crypto() const
{
return {NS_OK, &mCrypto};
}
-bool
+mozilla::MediaResult
MP4MetadataRust::ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID)
{
uint8_t fragmented = false;
auto rv = mp4parse_is_fragmented(mRustParser.get(), aTrackID, &fragmented);
if (rv != MP4PARSE_OK) {
- return false;
+ return MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
+ RESULT_DETAIL("Cannot parse whether track id %d is fragmented",
+ int(aTrackID)));
}
if (fragmented) {
- return true;
+ return NS_OK;
}
rv = mp4parse_get_indice_table(mRustParser.get(), aTrackID, aIndices);
if (rv != MP4PARSE_OK) {
- return false;
+ return MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
+ RESULT_DETAIL("Cannot parse index table in track id %d",
+ int(aTrackID)));
}
- return true;
+ return NS_OK;
}
/*static*/ MP4Metadata::ResultAndByteBuffer
MP4MetadataRust::Metadata(Stream* aSource)
{
MOZ_ASSERT(false, "Not yet implemented");
return {NS_ERROR_NOT_IMPLEMENTED, nullptr};
}
--- a/media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/MP4Metadata.h
@@ -60,17 +60,19 @@ public:
ResultAndTrackInfo GetTrackInfo(mozilla::TrackInfo::TrackType aType,
size_t aTrackNumber) const;
bool CanSeek() const;
using ResultAndCryptoFile = ResultAndType<const CryptoFile*>;
ResultAndCryptoFile Crypto() const;
- bool ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID);
+ mozilla::MediaResult
+ ReadTrackIndex(FallibleTArray<Index::Indice>& aDest,
+ mozilla::TrackID aTrackID);
private:
UniquePtr<MP4MetadataStagefright> mStagefright;
UniquePtr<MP4MetadataRust> mRust;
mutable bool mPreferRust;
mutable bool mReportedAudioTrackTelemetry;
mutable bool mReportedVideoTrackTelemetry;
#ifndef RELEASE_OR_BETA
--- a/media/libstagefright/gtest/TestParser.cpp
+++ b/media/libstagefright/gtest/TestParser.cpp
@@ -235,17 +235,18 @@ TEST(stagefright_MPEG4Metadata, test_cas
const VideoInfo* videoInfo = trackInfo.Ref()->GetAsVideoInfo();
ASSERT_TRUE(!!videoInfo);
EXPECT_TRUE(videoInfo->IsValid());
EXPECT_TRUE(videoInfo->IsVideo());
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));
+ EXPECT_TRUE(
+ NS_SUCCEEDED(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);
}
}
trackInfo = metadata.GetTrackInfo(TrackInfo::kAudioTrack, 0);
if (testFiles[test].mNumberAudioTracks == 0) {
EXPECT_TRUE(!trackInfo.Ref());
@@ -253,17 +254,18 @@ TEST(stagefright_MPEG4Metadata, test_cas
ASSERT_TRUE(!!trackInfo.Ref());
const AudioInfo* audioInfo = trackInfo.Ref()->GetAsAudioInfo();
ASSERT_TRUE(!!audioInfo);
EXPECT_TRUE(audioInfo->IsValid());
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));
+ EXPECT_TRUE(
+ NS_SUCCEEDED(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);
}
}
EXPECT_FALSE(metadata.GetTrackInfo(TrackInfo::kTextTrack, 0).Ref());
// We can see anywhere in any MPEG4.
EXPECT_TRUE(metadata.CanSeek());