uint32_t MP4MetadataStagefright::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const { size_t tracks = mMetadataExtractor->countTracks(); uint32_t total = 0; for (size_t i = 0; i < tracks; i++) { sp<MetaData> metaData = 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) && CheckTrack(mimeType, metaData.get(), i)) { total++; } break; case mozilla::TrackInfo::kVideoTrack: if (!strncmp(mimeType, "video/", 6) && CheckTrack(mimeType, metaData.get(), i)) { 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) && CheckTrack(mimeType, metaData.get(), i)) { index++; } break; case mozilla::TrackInfo::kVideoTrack: if (!strncmp(mimeType, "video/", 6) && CheckTrack(mimeType, metaData.get(), i)) { index++; } break; default: break; } if (index == aTrackNumber) { break; } i++; } if (index < 0) { return nullptr; } UniquePtr<mozilla::TrackInfo> e = CheckTrack(mimeType, metaData.get(), index); 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; }
uint32_t MP4Metadata::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const { #ifdef MOZ_RUST_MP4PARSE // Try in rust first. mRustState.reset(mp4parse_new()); int32_t rust_tracks = 0; bool rust_mp4parse_success = try_rust(mRustState, mSource, &rust_tracks); Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_SUCCESS, rust_mp4parse_success); #endif 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) && CheckTrack(mimeType, metaData.get(), i)) { total++; } break; case mozilla::TrackInfo::kVideoTrack: if (!strncmp(mimeType, "video/", 6) && CheckTrack(mimeType, metaData.get(), i)) { total++; } break; default: break; } } #ifdef MOZ_RUST_MP4PARSE uint32_t rust_total = 0; const char* rust_track_type = nullptr; if (rust_mp4parse_success && rust_tracks > 0) { for (int32_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; } } } static LazyLogModule sLog("MP4Metadata"); MOZ_LOG(sLog, LogLevel::Info, ("%s tracks found: stagefright=%u rust=%u", rust_track_type, total, rust_total)); #endif return total; }