fix: Fix handling of non-interleaved multi track FMP4 files (#1214)

Do not assume that each fragment contains all tracks. 
Use track id instead of index to pick the correct timestamp.

Fixes #1213
This commit is contained in:
Prakash Duggaraju 2023-08-21 16:34:32 -07:00 committed by GitHub
parent cc9a691aef
commit dcf32258ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 14 additions and 4 deletions

View File

@ -35,4 +35,5 @@ Richard Eklycke <richard@eklycke.se>
Sanil Raut <sr1990003@gmail.com> Sanil Raut <sr1990003@gmail.com>
Sergio Ammirata <sergio@ammirata.net> Sergio Ammirata <sergio@ammirata.net>
The Chromium Authors <*@chromium.org> The Chromium Authors <*@chromium.org>
Prakash Duggaraju <duggaraju@gmail.com>
Dennis E. Mungai (Brainiarc7) <dmngaie@gmail.com> Dennis E. Mungai (Brainiarc7) <dmngaie@gmail.com>

View File

@ -52,4 +52,5 @@ Thomas Inskip <tinskip@google.com>
Tim Lansen <tim.lansen@gmail.com> Tim Lansen <tim.lansen@gmail.com>
Vincent Nguyen <nvincen@amazon.com> Vincent Nguyen <nvincen@amazon.com>
Weiguo Shao <weiguo.shao@dolby.com> Weiguo Shao <weiguo.shao@dolby.com>
Prakash Duggaraju <duggaraju@gmail.com>
Dennis E. Mungai (Brainiarc7) <dmngaie@gmail.com> Dennis E. Mungai (Brainiarc7) <dmngaie@gmail.com>

View File

@ -298,6 +298,13 @@ TEST_F(MP4MediaParserTest, CencWithDecryptionSourceAndSenc) {
EXPECT_EQ(82u, num_samples_); EXPECT_EQ(82u, num_samples_);
} }
TEST_F(MP4MediaParserTest, NonInterleavedFMP4) {
// Test small, non-interleaved fragment MP4 with one track per fragment.
EXPECT_TRUE(ParseMP4File("BigBuckBunny_10s.ismv", 512));
EXPECT_EQ(2u, num_streams_);
EXPECT_EQ(770u, num_samples_);
}
} // namespace mp4 } // namespace mp4
} // namespace media } // namespace media
} // namespace shaka } // namespace shaka

View File

@ -284,10 +284,11 @@ bool TrackRunIterator::Init() {
bool TrackRunIterator::Init(const MovieFragment& moof) { bool TrackRunIterator::Init(const MovieFragment& moof) {
runs_.clear(); runs_.clear();
next_fragment_start_dts_.resize(moof.tracks.size(), 0); const auto track_count = std::max(moof.tracks.size(), moov_->tracks.size());
next_fragment_start_dts_.resize(track_count, 0);
for (size_t i = 0; i < moof.tracks.size(); i++) { for (size_t i = 0; i < moof.tracks.size(); i++) {
const TrackFragment& traf = moof.tracks[i]; const TrackFragment& traf = moof.tracks[i];
const auto track_index = traf.header.track_id - 1;
const Track* trak = NULL; const Track* trak = NULL;
for (size_t t = 0; t < moov_->tracks.size(); t++) { for (size_t t = 0; t < moov_->tracks.size(); t++) {
if (moov_->tracks[t].header.track_id == traf.header.track_id) if (moov_->tracks[t].header.track_id == traf.header.track_id)
@ -351,7 +352,7 @@ bool TrackRunIterator::Init(const MovieFragment& moof) {
} }
int64_t run_start_dts = traf.decode_time_absent int64_t run_start_dts = traf.decode_time_absent
? next_fragment_start_dts_[i] ? next_fragment_start_dts_[track_index]
: traf.decode_time.decode_time; : traf.decode_time.decode_time;
// dts is directly adjusted, which then propagates to pts as pts is encoded // dts is directly adjusted, which then propagates to pts as pts is encoded
@ -426,7 +427,7 @@ bool TrackRunIterator::Init(const MovieFragment& moof) {
runs_.push_back(tri); runs_.push_back(tri);
sample_count_sum += trun.sample_count; sample_count_sum += trun.sample_count;
} }
next_fragment_start_dts_[i] = run_start_dts; next_fragment_start_dts_[track_index] = run_start_dts;
} }
std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset()); std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset());

Binary file not shown.