Bug 1243234 - Move mp4parse-rust code into MP4MetadataRust impl. r=giles

Most of the interface is stubbed with asserts and only GetNumberTracks() is
called on both libstagefright and mp4parse-rust variants.

This also moves the libstagefright vs mp4parse-rust comparisons up into
MP4Metadata.
This commit is contained in:
Matthew Gregan 2016-01-27 17:49:02 +13:00
parent 486dfd0798
commit 6e493e6d61
2 changed files with 183 additions and 80 deletions

View File

@ -100,14 +100,39 @@ private:
nsAutoPtr<StageFrightPrivate> mPrivate;
CryptoFile mCrypto;
RefPtr<Stream> mSource;
};
#ifdef MOZ_RUST_MP4PARSE
class MP4MetadataRust
{
public:
explicit MP4MetadataRust(Stream* aSource);
~MP4MetadataRust();
static bool HasCompleteMetadata(Stream* aSource);
static already_AddRefed<mozilla::MediaByteBuffer> Metadata(Stream* aSource);
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;
bool ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID);
private:
CryptoFile mCrypto;
RefPtr<Stream> mSource;
mutable mozilla::UniquePtr<mp4parse_state, FreeMP4ParseState> mRustState;
#endif
};
#endif
MP4Metadata::MP4Metadata(Stream* aSource)
: mStagefright(MakeUnique<MP4MetadataStagefright>(aSource))
#ifdef MOZ_RUST_MP4PARSE
, mRust(MakeUnique<MP4MetadataRust>(aSource))
#endif
{
}
@ -130,7 +155,40 @@ MP4Metadata::Metadata(Stream* aSource)
uint32_t
MP4Metadata::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const
{
return mStagefright->GetNumberTracks(aType);
static LazyLogModule sLog("MP4Metadata");
uint32_t numTracks = mStagefright->GetNumberTracks(aType);
#ifdef MOZ_RUST_MP4PARSE
if (!mRust) {
return numTracks;
}
uint32_t numTracksRust = mRust->GetNumberTracks(aType);
bool numTracksMatch = numTracks == numTracksRust;
const char* trackType = "unknown";
switch (aType) {
case mozilla::TrackInfo::kAudioTrack:
trackType = "audio";
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_TRACK_MATCH_AUDIO,
numTracksMatch);
break;
case mozilla::TrackInfo::kVideoTrack:
trackType = "video";
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_TRACK_MATCH_VIDEO,
numTracksMatch);
break;
default:
break;
}
MOZ_LOG(sLog, LogLevel::Info, ("%s tracks found: stagefright=%u rust=%u",
trackType, numTracks, numTracksRust));
#endif
return numTracks;
}
mozilla::UniquePtr<mozilla::TrackInfo>
@ -200,47 +258,9 @@ MP4MetadataStagefright::~MP4MetadataStagefright()
{
}
#ifdef MOZ_RUST_MP4PARSE
// Helper to test the rust parser on a data source.
static int32_t try_rust(const UniquePtr<mp4parse_state, FreeMP4ParseState>& aRustState, RefPtr<Stream> aSource)
{
static LazyLogModule sLog("MP4Metadata");
int64_t length;
if (!aSource->Length(&length) || length <= 0) {
MOZ_LOG(sLog, LogLevel::Warning, ("Couldn't get source length"));
return false;
}
MOZ_LOG(sLog, LogLevel::Debug,
("Source length %d bytes\n", (long long int)length));
size_t bytes_read = 0;
auto buffer = std::vector<uint8_t>(length);
bool rv = aSource->ReadAt(0, buffer.data(), length, &bytes_read);
if (!rv || bytes_read != size_t(length)) {
MOZ_LOG(sLog, LogLevel::Warning, ("Error copying mp4 data"));
return false;
}
return mp4parse_read(aRustState.get(), buffer.data(), bytes_read);
}
#endif
uint32_t
MP4MetadataStagefright::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const
{
#ifdef MOZ_RUST_MP4PARSE
static LazyLogModule sLog("MP4Metadata");
// Try in rust first.
mRustState.reset(mp4parse_new());
int32_t rust_mp4parse_success = try_rust(mRustState, mSource);
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_SUCCESS,
rust_mp4parse_success == MP4PARSE_OK);
if (rust_mp4parse_success != MP4PARSE_OK) {
MOZ_ASSERT(rust_mp4parse_success > 0);
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_ERROR_CODE,
rust_mp4parse_success);
}
uint32_t rust_tracks = mp4parse_get_track_count(mRustState.get());
MOZ_LOG(sLog, LogLevel::Info, ("rust parser found %u tracks", rust_tracks));
#endif
size_t tracks = mPrivate->mMetadataExtractor->countTracks();
uint32_t total = 0;
for (size_t i = 0; i < tracks; i++) {
@ -267,46 +287,6 @@ MP4MetadataStagefright::GetNumberTracks(mozilla::TrackInfo::TrackType aType) con
break;
}
}
#ifdef MOZ_RUST_MP4PARSE
uint32_t rust_total = 0;
const char* rust_track_type = nullptr;
if (rust_mp4parse_success == MP4PARSE_OK && rust_tracks > 0) {
for (uint32_t i = 0; i < rust_tracks; ++i) {
mp4parse_track_info track_info;
int32_t r = mp4parse_get_track_info(mRustState.get(), i, &track_info);
switch (aType) {
case mozilla::TrackInfo::kAudioTrack:
rust_track_type = "audio";
if (r == 0 && track_info.track_type == MP4PARSE_TRACK_TYPE_AAC) {
rust_total += 1;
}
break;
case mozilla::TrackInfo::kVideoTrack:
rust_track_type = "video";
if (r == 0 && track_info.track_type == MP4PARSE_TRACK_TYPE_H264) {
rust_total += 1;
}
break;
default:
break;
}
}
}
MOZ_LOG(sLog, LogLevel::Info, ("%s tracks found: stagefright=%u rust=%u",
rust_track_type, total, rust_total));
switch (aType) {
case mozilla::TrackInfo::kAudioTrack:
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_TRACK_MATCH_AUDIO,
rust_total == total);
break;
case mozilla::TrackInfo::kVideoTrack:
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_TRACK_MATCH_VIDEO,
rust_total == total);
break;
default:
break;
}
#endif
return total;
}
@ -478,4 +458,123 @@ MP4MetadataStagefright::Metadata(Stream* aSource)
return parser->Metadata();
}
#ifdef MOZ_RUST_MP4PARSE
MP4MetadataRust::MP4MetadataRust(Stream* aSource)
: mSource(aSource)
{
}
MP4MetadataRust::~MP4MetadataRust()
{
}
// Helper to test the rust parser on a data source.
static int32_t try_rust(const UniquePtr<mp4parse_state, FreeMP4ParseState>& aRustState, RefPtr<Stream> aSource)
{
static LazyLogModule sLog("MP4Metadata");
int64_t length;
if (!aSource->Length(&length) || length <= 0) {
MOZ_LOG(sLog, LogLevel::Warning, ("Couldn't get source length"));
return false;
}
MOZ_LOG(sLog, LogLevel::Debug,
("Source length %d bytes\n", (long long int)length));
size_t bytes_read = 0;
auto buffer = std::vector<uint8_t>(length);
bool rv = aSource->ReadAt(0, buffer.data(), length, &bytes_read);
if (!rv || bytes_read != size_t(length)) {
MOZ_LOG(sLog, LogLevel::Warning, ("Error copying mp4 data"));
return false;
}
return mp4parse_read(aRustState.get(), buffer.data(), bytes_read);
}
uint32_t
MP4MetadataRust::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const
{
static LazyLogModule sLog("MP4Metadata");
mRustState.reset(mp4parse_new());
int32_t rv = try_rust(mRustState, mSource);
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_SUCCESS,
rv == MP4PARSE_OK);
if (rv != MP4PARSE_OK) {
MOZ_ASSERT(rv > 0);
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_ERROR_CODE,
rv);
}
uint32_t tracks = mp4parse_get_track_count(mRustState.get());
MOZ_LOG(sLog, LogLevel::Info, ("rust parser found %u tracks", tracks));
uint32_t total = 0;
for (uint32_t i = 0; i < tracks; ++i) {
mp4parse_track_info track_info;
int32_t rv = mp4parse_get_track_info(mRustState.get(), i, &track_info);
if (rv != MP4PARSE_OK) {
continue;
}
switch (aType) {
case mozilla::TrackInfo::kAudioTrack:
if (track_info.track_type == MP4PARSE_TRACK_TYPE_AAC) {
total += 1;
}
break;
case mozilla::TrackInfo::kVideoTrack:
if (track_info.track_type == MP4PARSE_TRACK_TYPE_H264) {
total += 1;
}
break;
default:
break;
}
}
return total;
}
mozilla::UniquePtr<mozilla::TrackInfo>
MP4MetadataRust::GetTrackInfo(mozilla::TrackInfo::TrackType aType,
size_t aTrackNumber) const
{
MOZ_ASSERT(false, "Not yet implemented");
return nullptr;
}
bool
MP4MetadataRust::CanSeek() const
{
MOZ_ASSERT(false, "Not yet implemented");
return false;
}
const CryptoFile&
MP4MetadataRust::Crypto() const
{
MOZ_ASSERT(false, "Not yet implemented");
return mCrypto;
}
bool
MP4MetadataRust::ReadTrackIndex(FallibleTArray<Index::Indice>& aDest, mozilla::TrackID aTrackID)
{
MOZ_ASSERT(false, "Not yet implemented");
return false;
}
/*static*/ bool
MP4MetadataRust::HasCompleteMetadata(Stream* aSource)
{
MOZ_ASSERT(false, "Not yet implemented");
return false;
}
/*static*/ already_AddRefed<mozilla::MediaByteBuffer>
MP4MetadataRust::Metadata(Stream* aSource)
{
MOZ_ASSERT(false, "Not yet implemented");
return nullptr;
}
#endif
} // namespace mp4_demuxer

View File

@ -16,6 +16,7 @@ namespace mp4_demuxer
{
class MP4MetadataStagefright;
class MP4MetadataRust;
class MP4Metadata
{
@ -36,6 +37,9 @@ public:
private:
UniquePtr<MP4MetadataStagefright> mStagefright;
#ifdef MOZ_RUST_MP4PARSE
UniquePtr<MP4MetadataRust> mRust;
#endif
};
} // namespace mp4_demuxer