diff --git a/packager/media/event/mpd_notify_muxer_listener.cc b/packager/media/event/mpd_notify_muxer_listener.cc index d647242c7b..7972deb54b 100644 --- a/packager/media/event/mpd_notify_muxer_listener.cc +++ b/packager/media/event/mpd_notify_muxer_listener.cc @@ -106,7 +106,10 @@ void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range, uint64_t index_range_end, float duration_seconds, uint64_t file_size) { - if (mpd_notifier_->dash_profile() == kLiveProfile) return; + if (mpd_notifier_->dash_profile() == kLiveProfile) { + DCHECK(subsegments_.empty()); + return; + } DCHECK(media_info_); if (!internal::SetVodInformation(has_init_range, @@ -122,21 +125,28 @@ void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range, return; } - uint32_t id; // Result unused. + uint32_t id; // TODO(kqyang): Check return result. mpd_notifier_->NotifyNewContainer(*media_info_, &id); + for (std::list::const_iterator it = subsegments_.begin(); + it != subsegments_.end(); ++it) { + mpd_notifier_->NotifyNewSegment(id, it->start_time, it->duration, + it->segment_file_size); + } + subsegments_.clear(); } void MpdNotifyMuxerListener::OnNewSegment(uint64_t start_time, uint64_t duration, uint64_t segment_file_size) { - // TODO(rkuriowa): MpdNotifier::NotifyNewSegment() should be called for VOD as - // well. The easiest way to do this is to save all the values and call it - // after NotifyNewContainer() in OnMediaEnd(). - if (mpd_notifier_->dash_profile() != kLiveProfile) return; - // TODO(kqyang): Check return result. - mpd_notifier_->NotifyNewSegment( - notification_id_, start_time, duration, segment_file_size); + if (mpd_notifier_->dash_profile() == kLiveProfile) { + // TODO(kqyang): Check return result. + mpd_notifier_->NotifyNewSegment( + notification_id_, start_time, duration, segment_file_size); + } else { + SubsegmentInfo subsegment = {start_time, duration, segment_file_size}; + subsegments_.push_back(subsegment); + } } } // namespace media diff --git a/packager/media/event/mpd_notify_muxer_listener.h b/packager/media/event/mpd_notify_muxer_listener.h index d580881b0b..89b2592aa4 100644 --- a/packager/media/event/mpd_notify_muxer_listener.h +++ b/packager/media/event/mpd_notify_muxer_listener.h @@ -9,6 +9,7 @@ #ifndef MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_ #define MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_ +#include #include #include "packager/base/compiler_specific.h" @@ -60,6 +61,13 @@ class MpdNotifyMuxerListener : public MuxerListener { /// @} private: + // This stores data passed into OnNewSegment() for VOD. + struct SubsegmentInfo { + uint64_t start_time; + uint64_t duration; + uint64_t segment_file_size; + }; + MpdNotifier* const mpd_notifier_; uint32_t notification_id_; scoped_ptr media_info_; @@ -72,6 +80,12 @@ class MpdNotifyMuxerListener : public MuxerListener { std::string default_key_id_; std::string pssh_; + // Saves all the subsegment information for VOD. This should be used to call + // MpdNotifier::NotifyNewSegment() after NotifyNewSegment() is called + // (in OnMediaEnd). This is not used for live because NotifyNewSegment() is + // called immediately in OnNewSegment(). + std::list subsegments_; + DISALLOW_COPY_AND_ASSIGN(MpdNotifyMuxerListener); }; diff --git a/packager/media/event/mpd_notify_muxer_listener_unittest.cc b/packager/media/event/mpd_notify_muxer_listener_unittest.cc index 5405585431..a67cc305b2 100644 --- a/packager/media/event/mpd_notify_muxer_listener_unittest.cc +++ b/packager/media/event/mpd_notify_muxer_listener_unittest.cc @@ -20,6 +20,7 @@ #include "packager/mpd/base/mpd_notifier.h" using ::testing::_; +using ::testing::InSequence; namespace edash_packager { @@ -223,6 +224,42 @@ TEST_F(MpdNotifyMuxerListenerTest, VodOnSampleDurationReady) { FireOnMediaEndWithParams(GetDefaultOnMediaEndParams()); } +// Verify that MpdNotifier::NotifyNewSegment() is called after +// NotifyNewContainer(), if OnNewSegment() is called. +TEST_F(MpdNotifyMuxerListenerTest, VodOnNewSegment) { + SetupForVod(); + MuxerOptions muxer_options; + SetDefaultMuxerOptionsValues(&muxer_options); + VideoStreamInfoParameters video_params = GetDefaultVideoStreamInfoParams(); + scoped_refptr video_stream_info = + CreateVideoStreamInfo(video_params); + + const uint64_t kStartTime1 = 0u; + const uint64_t kDuration1 = 1000u; + const uint64_t kSegmentFileSize1 = 29812u; + const uint64_t kStartTime2 = 1001u; + const uint64_t kDuration2 = 3787u; + const uint64_t kSegmentFileSize2 = 83743u; + + EXPECT_CALL(*notifier_, NotifyNewContainer(_, _)).Times(0); + EXPECT_CALL(*notifier_, NotifyNewSegment(_, _, _, _)).Times(0); + listener_->OnMediaStart(muxer_options, *video_stream_info, + kDefaultReferenceTimeScale, + MuxerListener::kContainerMp4); + listener_->OnNewSegment(kStartTime1, kDuration1, kSegmentFileSize1); + listener_->OnNewSegment(kStartTime2, kDuration2, kSegmentFileSize2); + ::testing::Mock::VerifyAndClearExpectations(notifier_.get()); + + InSequence s; + EXPECT_CALL(*notifier_, NotifyNewContainer( + ExpectMediaInfoEq(kExpectedDefaultMediaInfo), _)); + EXPECT_CALL(*notifier_, + NotifyNewSegment(_, kStartTime1, kDuration1, kSegmentFileSize1)); + EXPECT_CALL(*notifier_, + NotifyNewSegment(_, kStartTime2, kDuration2, kSegmentFileSize2)); + FireOnMediaEndWithParams(GetDefaultOnMediaEndParams()); +} + // TODO(rkuroiwa): Add tests for live. } // namespace media