Remove size parameter in OnMediaEnd

Derive file size from media ranges instead.

Also fix subsegment range reporting for WebM (internal variable,
no output affected).

Change-Id: I5f8152dff4c2cd5fbae5550992b86a669e278f7b
This commit is contained in:
KongQun Yang 2017-07-18 12:23:42 -07:00
parent 8d2b87c773
commit 61c58724ec
20 changed files with 56 additions and 73 deletions

View File

@ -116,8 +116,7 @@ void HlsNotifyMuxerListener::OnMediaStart(const MuxerOptions& muxer_options,
void HlsNotifyMuxerListener::OnSampleDurationReady(uint32_t sample_duration) {} void HlsNotifyMuxerListener::OnSampleDurationReady(uint32_t sample_duration) {}
void HlsNotifyMuxerListener::OnMediaEnd(const MediaRanges& media_ranges, void HlsNotifyMuxerListener::OnMediaEnd(const MediaRanges& media_ranges,
float duration_seconds, float duration_seconds) {
uint64_t file_size) {
// TODO(kqyang): Should we just Flush here to avoid calling Flush explicitly? // TODO(kqyang): Should we just Flush here to avoid calling Flush explicitly?
// Don't flush the notifier here. Flushing here would write all the playlists // Don't flush the notifier here. Flushing here would write all the playlists
// before all Media Playlists are read. Which could cause problems // before all Media Playlists are read. Which could cause problems

View File

@ -54,8 +54,7 @@ class HlsNotifyMuxerListener : public MuxerListener {
ContainerType container_type) override; ContainerType container_type) override;
void OnSampleDurationReady(uint32_t sample_duration) override; void OnSampleDurationReady(uint32_t sample_duration) override;
void OnMediaEnd(const MediaRanges& media_ranges, void OnMediaEnd(const MediaRanges& media_ranges,
float duration_seconds, float duration_seconds) override;
uint64_t file_size) override;
void OnNewSegment(const std::string& file_name, void OnNewSegment(const std::string& file_name,
uint64_t start_time, uint64_t start_time,
uint64_t duration, uint64_t duration,

View File

@ -319,7 +319,7 @@ TEST_F(HlsNotifyMuxerListenerTest, OnSampleDurationReady) {
// Make sure it doesn't crash. // Make sure it doesn't crash.
TEST_F(HlsNotifyMuxerListenerTest, OnMediaEnd) { TEST_F(HlsNotifyMuxerListenerTest, OnMediaEnd) {
// None of these values matter, they are not used. // None of these values matter, they are not used.
listener_.OnMediaEnd(MuxerListener::MediaRanges(), 0, 0); listener_.OnMediaEnd(MuxerListener::MediaRanges(), 0);
} }
TEST_F(HlsNotifyMuxerListenerTest, OnNewSegment) { TEST_F(HlsNotifyMuxerListenerTest, OnNewSegment) {
@ -383,7 +383,7 @@ TEST_F(HlsNotifyMuxerListenerTest, NoSegmentTemplateOnMediaEnd) {
EXPECT_CALL(mock_notifier_, EXPECT_CALL(mock_notifier_,
NotifyNewSegment(_, StrEq("filename.mp4"), kStartTime, NotifyNewSegment(_, StrEq("filename.mp4"), kStartTime,
kDuration, kSegmentStartOffset, kFileSize)); kDuration, kSegmentStartOffset, kFileSize));
listener_.OnMediaEnd(ranges, 200000, 98234328); listener_.OnMediaEnd(ranges, 200000);
} }
// Verify that when there is a mismatch in the number of calls to // Verify that when there is a mismatch in the number of calls to
@ -435,7 +435,7 @@ TEST_F(HlsNotifyMuxerListenerTest,
EXPECT_CALL(mock_notifier_, EXPECT_CALL(mock_notifier_,
NotifyNewSegment(_, StrEq("filename.mp4"), kStartTime, NotifyNewSegment(_, StrEq("filename.mp4"), kStartTime,
kDuration, kSegmentStartOffset, kFileSize)); kDuration, kSegmentStartOffset, kFileSize));
listener_.OnMediaEnd(ranges, 200000, 98234328); listener_.OnMediaEnd(ranges, 200000);
} }
} // namespace media } // namespace media

View File

@ -13,8 +13,7 @@ MockMuxerListener::MockMuxerListener() {}
MockMuxerListener::~MockMuxerListener() {} MockMuxerListener::~MockMuxerListener() {}
void MockMuxerListener::OnMediaEnd(const MediaRanges& range, void MockMuxerListener::OnMediaEnd(const MediaRanges& range,
float duration_seconds, float duration_seconds) {
uint64_t file_size) {
const bool has_init_range = static_cast<bool>(range.init_range); const bool has_init_range = static_cast<bool>(range.init_range);
Range init_range = {}; Range init_range = {};
if (has_init_range) { if (has_init_range) {
@ -29,7 +28,7 @@ void MockMuxerListener::OnMediaEnd(const MediaRanges& range,
OnMediaEndMock(has_init_range, init_range.start, init_range.end, OnMediaEndMock(has_init_range, init_range.start, init_range.end,
has_index_range, index_range.start, index_range.end, has_index_range, index_range.start, index_range.end,
!range.subsegment_ranges.empty(), range.subsegment_ranges, !range.subsegment_ranges.empty(), range.subsegment_ranges,
duration_seconds, file_size); duration_seconds);
} }
} // namespace media } // namespace media

View File

@ -40,23 +40,21 @@ class MockMuxerListener : public MuxerListener {
MOCK_METHOD1(OnSampleDurationReady, void(uint32_t sample_duration)); MOCK_METHOD1(OnSampleDurationReady, void(uint32_t sample_duration));
MOCK_METHOD10(OnMediaEndMock, MOCK_METHOD9(OnMediaEndMock,
void(bool has_init_range, void(bool has_init_range,
uint64_t init_range_start, uint64_t init_range_start,
uint64_t init_range_end, uint64_t init_range_end,
bool has_index_range, bool has_index_range,
uint64_t index_range_start, uint64_t index_range_start,
uint64_t index_range_end, uint64_t index_range_end,
bool has_subsegment_ranges, bool has_subsegment_ranges,
const std::vector<Range> subsegment_ranges, const std::vector<Range> subsegment_ranges,
float duration_seconds, float duration_seconds));
uint64_t file_size));
// Windows 32 bit cannot mock MediaRanges because it has Optionals that use // Windows 32 bit cannot mock MediaRanges because it has Optionals that use
// memory alignment of 8 bytes. The compiler fails if it is mocked. // memory alignment of 8 bytes. The compiler fails if it is mocked.
void OnMediaEnd(const MediaRanges& range, void OnMediaEnd(const MediaRanges& range,
float duration_seconds, float duration_seconds) override;
uint64_t file_size) override;
MOCK_METHOD4(OnNewSegment, MOCK_METHOD4(OnNewSegment,
void(const std::string& segment_name, void(const std::string& segment_name,

View File

@ -110,8 +110,7 @@ void MpdNotifyMuxerListener::OnSampleDurationReady(
} }
void MpdNotifyMuxerListener::OnMediaEnd(const MediaRanges& media_ranges, void MpdNotifyMuxerListener::OnMediaEnd(const MediaRanges& media_ranges,
float duration_seconds, float duration_seconds) {
uint64_t file_size) {
if (mpd_notifier_->dash_profile() == DashProfile::kLive) { if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
DCHECK(subsegments_.empty()); DCHECK(subsegments_.empty());
// TODO(kqyang): Set mpd duration to |duration_seconds|, which is more // TODO(kqyang): Set mpd duration to |duration_seconds|, which is more
@ -122,7 +121,7 @@ void MpdNotifyMuxerListener::OnMediaEnd(const MediaRanges& media_ranges,
} }
DCHECK(media_info_); DCHECK(media_info_);
if (!internal::SetVodInformation(media_ranges, duration_seconds, file_size, if (!internal::SetVodInformation(media_ranges, duration_seconds,
media_info_.get())) { media_info_.get())) {
LOG(ERROR) << "Failed to generate VOD information from input."; LOG(ERROR) << "Failed to generate VOD information from input.";
return; return;

View File

@ -46,8 +46,7 @@ class MpdNotifyMuxerListener : public MuxerListener {
ContainerType container_type) override; ContainerType container_type) override;
void OnSampleDurationReady(uint32_t sample_duration) override; void OnSampleDurationReady(uint32_t sample_duration) override;
void OnMediaEnd(const MediaRanges& media_ranges, void OnMediaEnd(const MediaRanges& media_ranges,
float duration_seconds, float duration_seconds) override;
uint64_t file_size) override;
void OnNewSegment(const std::string& file_name, void OnNewSegment(const std::string& file_name,
uint64_t start_time, uint64_t start_time,
uint64_t duration, uint64_t duration,

View File

@ -83,8 +83,7 @@ class MpdNotifyMuxerListenerTest : public ::testing::TestWithParam<MpdType> {
void FireOnMediaEndWithParams(const OnMediaEndParameters& params) { void FireOnMediaEndWithParams(const OnMediaEndParameters& params) {
// On success, this writes the result to |temp_file_path_|. // On success, this writes the result to |temp_file_path_|.
listener_->OnMediaEnd(params.media_ranges, params.duration_seconds, listener_->OnMediaEnd(params.media_ranges, params.duration_seconds);
params.file_size);
} }
std::unique_ptr<MpdNotifyMuxerListener> listener_; std::unique_ptr<MpdNotifyMuxerListener> listener_;

View File

@ -105,12 +105,11 @@ class MuxerListener {
/// Called when all files are written out and the muxer object does not output /// Called when all files are written out and the muxer object does not output
/// any more files. /// any more files.
/// Note: This event might not be very interesting to MPEG DASH Live profile. /// Note: This event might not be very interesting to MPEG DASH Live profile.
/// @param media_ranges is the ranges of the media file. /// @param media_ranges is the ranges of the media file. It should have ranges
/// for the entire file, using which the file size can be calculated.
/// @param duration_seconds is the length of the media in seconds. /// @param duration_seconds is the length of the media in seconds.
/// @param file_size is the size of the file in bytes.
virtual void OnMediaEnd(const MediaRanges& media_ranges, virtual void OnMediaEnd(const MediaRanges& media_ranges,
float duration_seconds, float duration_seconds) = 0;
uint64_t file_size) = 0;
/// Called when a segment has been muxed and the file has been written. /// Called when a segment has been muxed and the file has been written.
/// Note: For some implementations, this is used to signal new subsegments. /// Note: For some implementations, this is used to signal new subsegments.

View File

@ -192,13 +192,8 @@ bool GenerateMediaInfo(const MuxerOptions& muxer_options,
bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges, bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges,
float duration_seconds, float duration_seconds,
uint64_t file_size,
MediaInfo* media_info) { MediaInfo* media_info) {
DCHECK(media_info); DCHECK(media_info);
if (file_size == 0) {
LOG(ERROR) << "File size not specified.";
return false;
}
if (duration_seconds <= 0.0f) { if (duration_seconds <= 0.0f) {
// Non positive second media must be invalid media. // Non positive second media must be invalid media.
@ -220,6 +215,17 @@ bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges,
media_info->set_media_duration_seconds(duration_seconds); media_info->set_media_duration_seconds(duration_seconds);
if (!media_info->has_bandwidth()) { if (!media_info->has_bandwidth()) {
// Calculate file size from media_ranges.
uint64_t file_size = 0;
if (media_ranges.init_range)
file_size = std::max(file_size, media_ranges.init_range->end + 1);
if (media_ranges.index_range)
file_size = std::max(file_size, media_ranges.index_range->end + 1);
if (!media_ranges.subsegment_ranges.empty()) {
file_size =
std::max(file_size, media_ranges.subsegment_ranges.back().end + 1);
}
media_info->set_bandwidth( media_info->set_bandwidth(
EstimateRequiredBandwidth(file_size, duration_seconds)); EstimateRequiredBandwidth(file_size, duration_seconds));
} }

View File

@ -37,7 +37,6 @@ bool GenerateMediaInfo(const MuxerOptions& muxer_options,
/// @return true on success, false otherwise. /// @return true on success, false otherwise.
bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges, bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges,
float duration_seconds, float duration_seconds,
uint64_t file_size,
MediaInfo* media_info); MediaInfo* media_info);
/// @param protection_scheme specifies the protection scheme: 'cenc', 'cens', /// @param protection_scheme specifies the protection scheme: 'cenc', 'cens',

View File

@ -64,8 +64,9 @@ OnMediaEndParameters GetDefaultOnMediaEndParams() {
const uint64_t kInitRangeEnd = kInitRangeStart + 120; const uint64_t kInitRangeEnd = kInitRangeStart + 120;
const uint64_t kIndexRangeStart = kInitRangeEnd + 1; const uint64_t kIndexRangeStart = kInitRangeEnd + 1;
const uint64_t kIndexRangeEnd = kIndexRangeStart + 100; const uint64_t kIndexRangeEnd = kIndexRangeStart + 100;
const uint64_t kMediaSegmentRangeStart = kIndexRangeEnd + 1;
const uint64_t kMediaSegmentRangeEnd = 9999;
const float kMediaDuration = 10.5f; const float kMediaDuration = 10.5f;
const uint64_t kFileSize = 10000;
MuxerListener::MediaRanges media_ranges; MuxerListener::MediaRanges media_ranges;
Range init_range; Range init_range;
init_range.start = kInitRangeStart; init_range.start = kInitRangeStart;
@ -76,7 +77,12 @@ OnMediaEndParameters GetDefaultOnMediaEndParams() {
index_range.end = kIndexRangeEnd; index_range.end = kIndexRangeEnd;
media_ranges.index_range =index_range; media_ranges.index_range =index_range;
OnMediaEndParameters param = {media_ranges, kMediaDuration, kFileSize}; Range media_segment_range;
media_segment_range.start = kMediaSegmentRangeStart;
media_segment_range.end = kMediaSegmentRangeEnd;
media_ranges.subsegment_ranges.push_back(media_segment_range);
OnMediaEndParameters param = {media_ranges, kMediaDuration};
return param; return param;
} }

View File

@ -76,7 +76,6 @@ struct VideoStreamInfoParameters {
struct OnMediaEndParameters { struct OnMediaEndParameters {
MuxerListener::MediaRanges media_ranges; MuxerListener::MediaRanges media_ranges;
float duration_seconds; float duration_seconds;
uint64_t file_size;
}; };
// Creates StreamInfo instance from VideoStreamInfoParameters. // Creates StreamInfo instance from VideoStreamInfoParameters.

View File

@ -73,10 +73,9 @@ void VodMediaInfoDumpMuxerListener::OnSampleDurationReady(
} }
void VodMediaInfoDumpMuxerListener::OnMediaEnd(const MediaRanges& media_ranges, void VodMediaInfoDumpMuxerListener::OnMediaEnd(const MediaRanges& media_ranges,
float duration_seconds, float duration_seconds) {
uint64_t file_size) {
DCHECK(media_info_); DCHECK(media_info_);
if (!internal::SetVodInformation(media_ranges, duration_seconds, file_size, if (!internal::SetVodInformation(media_ranges, duration_seconds,
media_info_.get())) { media_info_.get())) {
LOG(ERROR) << "Failed to generate VOD information from input."; LOG(ERROR) << "Failed to generate VOD information from input.";
return; return;

View File

@ -45,8 +45,7 @@ class VodMediaInfoDumpMuxerListener : public MuxerListener {
ContainerType container_type) override; ContainerType container_type) override;
void OnSampleDurationReady(uint32_t sample_duration) override; void OnSampleDurationReady(uint32_t sample_duration) override;
void OnMediaEnd(const MediaRanges& media_ranges, void OnMediaEnd(const MediaRanges& media_ranges,
float duration_seconds, float duration_seconds) override;
uint64_t file_size) override;
void OnNewSegment(const std::string& file_name, void OnNewSegment(const std::string& file_name,
uint64_t start_time, uint64_t start_time,
uint64_t duration, uint64_t duration,

View File

@ -95,9 +95,7 @@ class VodMediaInfoDumpMuxerListenerTest : public ::testing::Test {
void FireOnMediaEndWithParams(const OnMediaEndParameters& params) { void FireOnMediaEndWithParams(const OnMediaEndParameters& params) {
// On success, this writes the result to |temp_file_path_|. // On success, this writes the result to |temp_file_path_|.
listener_->OnMediaEnd(params.media_ranges, listener_->OnMediaEnd(params.media_ranges, params.duration_seconds);
params.duration_seconds,
params.file_size);
} }
void ExpectTempFileToEqual(const std::string& expected_protobuf) { void ExpectTempFileToEqual(const std::string& expected_protobuf) {

View File

@ -61,7 +61,7 @@ void TsMuxer::FireOnMediaEndEvent() {
// For now, there is no single file TS segmenter. So all the values passed // For now, there is no single file TS segmenter. So all the values passed
// here are left empty. // here are left empty.
MuxerListener::MediaRanges range; MuxerListener::MediaRanges range;
muxer_listener()->OnMediaEnd(range, 0, 0); muxer_listener()->OnMediaEnd(range, 0);
} }
} // namespace mp2t } // namespace mp2t

View File

@ -469,15 +469,7 @@ void MP4Muxer::FireOnMediaEndEvent() {
media_range.subsegment_ranges = segmenter_->GetSegmentRanges(); media_range.subsegment_ranges = segmenter_->GetSegmentRanges();
const float duration_seconds = static_cast<float>(segmenter_->GetDuration()); const float duration_seconds = static_cast<float>(segmenter_->GetDuration());
muxer_listener()->OnMediaEnd(media_range, duration_seconds);
const int64_t file_size =
File::GetFileSize(options().output_file_name.c_str());
if (file_size <= 0) {
LOG(ERROR) << "Invalid file size: " << file_size;
return;
}
muxer_listener()->OnMediaEnd(media_range, duration_seconds, file_size);
} }
uint64_t MP4Muxer::IsoTimeNow() { uint64_t MP4Muxer::IsoTimeNow() {

View File

@ -56,15 +56,17 @@ std::vector<Range> SingleSegmentSegmenter::GetSegmentRanges() {
for (int32_t i = 0; i < cues()->cue_entries_size() - 1; ++i) { for (int32_t i = 0; i < cues()->cue_entries_size() - 1; ++i) {
const mkvmuxer::CuePoint* cue_point = cues()->GetCueByIndex(i); const mkvmuxer::CuePoint* cue_point = cues()->GetCueByIndex(i);
Range r; Range r;
r.start = cue_point->cluster_pos(); // Cue point cluster position is relative to segment payload pos.
r.end = cues()->GetCueByIndex(i + 1)->cluster_pos() - 1; r.start = segment_payload_pos() + cue_point->cluster_pos();
r.end =
segment_payload_pos() + cues()->GetCueByIndex(i + 1)->cluster_pos() - 1;
ranges.push_back(r); ranges.push_back(r);
} }
Range last_range; Range last_range;
const mkvmuxer::CuePoint* last_cue_point = const mkvmuxer::CuePoint* last_cue_point =
cues()->GetCueByIndex(cues()->cue_entries_size() - 1); cues()->GetCueByIndex(cues()->cue_entries_size() - 1);
last_range.start = last_cue_point->cluster_pos(); last_range.start = segment_payload_pos() + last_cue_point->cluster_pos();
last_range.end = last_range.start + cluster()->Size() - 1; last_range.end = last_range.start + cluster()->Size() - 1;
ranges.push_back(last_range); ranges.push_back(last_range);
return ranges; return ranges;

View File

@ -122,15 +122,7 @@ void WebMMuxer::FireOnMediaEndEvent() {
media_range.subsegment_ranges = segmenter_->GetSegmentRanges(); media_range.subsegment_ranges = segmenter_->GetSegmentRanges();
const float duration_seconds = segmenter_->GetDurationInSeconds(); const float duration_seconds = segmenter_->GetDurationInSeconds();
muxer_listener()->OnMediaEnd(media_range, duration_seconds);
const int64_t file_size =
File::GetFileSize(options().output_file_name.c_str());
if (file_size <= 0) {
LOG(ERROR) << "Invalid file size: " << file_size;
return;
}
muxer_listener()->OnMediaEnd(media_range, duration_seconds, file_size);
} }
} // namespace webm } // namespace webm