diff --git a/packager/live_packager_test.cc b/packager/live_packager_test.cc index b895da47f2..08a9357e8a 100644 --- a/packager/live_packager_test.cc +++ b/packager/live_packager_test.cc @@ -870,7 +870,7 @@ TEST_F(LivePackagerBaseTest, VerifyPrdDecryptReEncrypt) { } } -TEST_F(LivePackagerBaseTest, EditListAfterRepackage) { +TEST_F(LivePackagerBaseTest, MoovAfterRepackage) { std::vector init_segment_buffer = ReadTestDataFile("encrypted/prd_data/init.mp4"); ASSERT_FALSE(init_segment_buffer.empty()); @@ -900,6 +900,8 @@ TEST_F(LivePackagerBaseTest, EditListAfterRepackage) { const auto& act_track = act_moov.tracks[i]; EXPECT_EQ(exp_track.edit.list.edits, act_track.edit.list.edits); } + + EXPECT_EQ(exp_moov.extends.tracks, act_moov.extends.tracks); } TEST_F(LivePackagerBaseTest, EncryptionFailure) { diff --git a/packager/media/base/stream_info.h b/packager/media/base/stream_info.h index 3317dc6d78..7caf971dd3 100644 --- a/packager/media/base/stream_info.h +++ b/packager/media/base/stream_info.h @@ -107,6 +107,9 @@ class StreamInfo { return encryption_config_; } int64_t media_time() const { return media_time_; } + uint32_t get_default_sample_duration() const { + return default_sample_duration_; + } void set_duration(int64_t duration) { duration_ = duration; } void set_codec(Codec codec) { codec_ = codec; } @@ -125,6 +128,9 @@ class StreamInfo { encryption_config_ = encryption_config; } void set_media_time(int64_t media_time) { media_time_ = media_time; } + void set_default_sample_duration(uint32_t duration) { + default_sample_duration_ = duration; + } private: // Whether the stream is Audio or Video. @@ -148,9 +154,12 @@ class StreamInfo { // codebooks. std::vector codec_config_; - // Optional data required for preserving edit lists when repackaging an + // Optional data required for preserving media time when repackaging an // init segment alone. int64_t media_time_ = 0; + // Optional data required for preserving default sample duration when repackaging an + // init segment alone. + uint32_t default_sample_duration_ = 0; // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler // generated copy constructor and assignment operator. Since the extra data is diff --git a/packager/media/formats/mp4/mp4_media_parser.cc b/packager/media/formats/mp4/mp4_media_parser.cc index 1ebf126678..73c5ffe6a2 100644 --- a/packager/media/formats/mp4/mp4_media_parser.cc +++ b/packager/media/formats/mp4/mp4_media_parser.cc @@ -595,6 +595,13 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) { if (edit_list.edits.size() == 1u) { streams.back()->set_media_time(edit_list.edits.front().media_time); } + + for (const auto& trex : moov_->extends.tracks) { + if (trex.track_id == track->header.track_id) { + streams.back()->set_default_sample_duration(trex.default_sample_duration); + break; + } + } } if (samp_descr.type == kVideo) { @@ -768,6 +775,13 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) { video_stream_info->set_media_time(edit_list.edits.front().media_time); } + for (const auto& trex : moov_->extends.tracks) { + if (trex.track_id == track->header.track_id) { + video_stream_info->set_default_sample_duration(trex.default_sample_duration); + break; + } + } + streams.push_back(video_stream_info); } } diff --git a/packager/media/formats/mp4/mp4_muxer.cc b/packager/media/formats/mp4/mp4_muxer.cc index e5c61bff1d..7d58b1de0b 100644 --- a/packager/media/formats/mp4/mp4_muxer.cc +++ b/packager/media/formats/mp4/mp4_muxer.cc @@ -264,6 +264,9 @@ Status MP4Muxer::DelayInitializeMuxer() { TrackExtends& trex = moov->extends.tracks[i]; trex.track_id = trak.header.track_id; trex.default_sample_description_index = 1; + if (stream->get_default_sample_duration() != 0) { + trex.default_sample_duration = stream->get_default_sample_duration(); + } bool generate_trak_result = false; switch (stream->stream_type()) {