Call MpdNotifier::NotifyNewSegment for VOD

- Call NotifyNewSegment() in MpdNotifyMuxerListener::OnMediaEnd() to
  notify subsegments.
- This is necessary for MpdBuilder to calculate subsegmentAlignment.

Change-Id: I9359c408da4f616e543a6d9e568b010a90c90185
This commit is contained in:
Rintaro Kuroiwa 2015-08-04 14:23:16 -07:00
parent ab8f64ea2c
commit 48ff2fbe6a
3 changed files with 70 additions and 9 deletions

View File

@ -106,7 +106,10 @@ void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range,
uint64_t index_range_end, uint64_t index_range_end,
float duration_seconds, float duration_seconds,
uint64_t file_size) { uint64_t file_size) {
if (mpd_notifier_->dash_profile() == kLiveProfile) return; if (mpd_notifier_->dash_profile() == kLiveProfile) {
DCHECK(subsegments_.empty());
return;
}
DCHECK(media_info_); DCHECK(media_info_);
if (!internal::SetVodInformation(has_init_range, if (!internal::SetVodInformation(has_init_range,
@ -122,21 +125,28 @@ void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range,
return; return;
} }
uint32_t id; // Result unused. uint32_t id;
// TODO(kqyang): Check return result. // TODO(kqyang): Check return result.
mpd_notifier_->NotifyNewContainer(*media_info_, &id); mpd_notifier_->NotifyNewContainer(*media_info_, &id);
for (std::list<SubsegmentInfo>::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, void MpdNotifyMuxerListener::OnNewSegment(uint64_t start_time,
uint64_t duration, uint64_t duration,
uint64_t segment_file_size) { uint64_t segment_file_size) {
// TODO(rkuriowa): MpdNotifier::NotifyNewSegment() should be called for VOD as if (mpd_notifier_->dash_profile() == kLiveProfile) {
// 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. // TODO(kqyang): Check return result.
mpd_notifier_->NotifyNewSegment( mpd_notifier_->NotifyNewSegment(
notification_id_, start_time, duration, segment_file_size); notification_id_, start_time, duration, segment_file_size);
} else {
SubsegmentInfo subsegment = {start_time, duration, segment_file_size};
subsegments_.push_back(subsegment);
}
} }
} // namespace media } // namespace media

View File

@ -9,6 +9,7 @@
#ifndef MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_ #ifndef MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_
#define MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_ #define MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_
#include <list>
#include <vector> #include <vector>
#include "packager/base/compiler_specific.h" #include "packager/base/compiler_specific.h"
@ -60,6 +61,13 @@ class MpdNotifyMuxerListener : public MuxerListener {
/// @} /// @}
private: 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_; MpdNotifier* const mpd_notifier_;
uint32_t notification_id_; uint32_t notification_id_;
scoped_ptr<MediaInfo> media_info_; scoped_ptr<MediaInfo> media_info_;
@ -72,6 +80,12 @@ class MpdNotifyMuxerListener : public MuxerListener {
std::string default_key_id_; std::string default_key_id_;
std::string pssh_; 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<SubsegmentInfo> subsegments_;
DISALLOW_COPY_AND_ASSIGN(MpdNotifyMuxerListener); DISALLOW_COPY_AND_ASSIGN(MpdNotifyMuxerListener);
}; };

View File

@ -20,6 +20,7 @@
#include "packager/mpd/base/mpd_notifier.h" #include "packager/mpd/base/mpd_notifier.h"
using ::testing::_; using ::testing::_;
using ::testing::InSequence;
namespace edash_packager { namespace edash_packager {
@ -223,6 +224,42 @@ TEST_F(MpdNotifyMuxerListenerTest, VodOnSampleDurationReady) {
FireOnMediaEndWithParams(GetDefaultOnMediaEndParams()); 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<StreamInfo> 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. // TODO(rkuroiwa): Add tests for live.
} // namespace media } // namespace media