From 9b3ed17a9648300d93240b3ff6dc70fb57d44a2d Mon Sep 17 00:00:00 2001 From: Rintaro Kuroiwa Date: Tue, 14 Jan 2014 00:50:48 -0800 Subject: [PATCH] Delegate MediaInfo generation for VOD Info from muxer is delegated to a function in internal namespace to create MediaInfo protobuf structure. Change-Id: I7c00ce02c9ab23f022cf485e582d771ce61107cf --- media/event/vod_mpd_notify_muxer_listener.cc | 159 +++--------------- media/event/vod_mpd_notify_muxer_listener.h | 17 +- media/event/vod_muxer_listener_internal.cc | 168 +++++++++++++++++++ media/event/vod_muxer_listener_internal.h | 35 ++++ 4 files changed, 231 insertions(+), 148 deletions(-) create mode 100644 media/event/vod_muxer_listener_internal.cc create mode 100644 media/event/vod_muxer_listener_internal.h diff --git a/media/event/vod_mpd_notify_muxer_listener.cc b/media/event/vod_mpd_notify_muxer_listener.cc index 6493dd3c6d..a0112b9854 100644 --- a/media/event/vod_mpd_notify_muxer_listener.cc +++ b/media/event/vod_mpd_notify_muxer_listener.cc @@ -1,4 +1,3 @@ - #include "media/event/vod_mpd_notify_muxer_listener.h" #include @@ -6,121 +5,13 @@ #include "base/logging.h" #include "media/base/audio_stream_info.h" #include "media/base/video_stream_info.h" +#include "media/event/vod_muxer_listener_internal.h" #include "mpd/base/media_info.pb.h" #include "mpd/base/mpd_notifier.h" namespace media { namespace event { -namespace { - -using dash_packager::MediaInfo; -using dash_packager::MediaInfo_AudioInfo; -using dash_packager::MediaInfo_VideoInfo; -using dash_packager::Range; - -// This will return a positive value, given that |file_size| and -// |duration_seconds| are positive. -uint32 EstimateRequiredBandwidth(uint64 file_size, float duration_seconds) { - const uint32 file_size_bits = file_size * 8; - const float bits_per_second = file_size_bits / duration_seconds; - - // Note that casting |bits_per_second| to an integer might make it 0. Take the - // ceiling and make sure that it returns a positive value. - return static_cast(ceil(bits_per_second)); -} - -void SetRange(uint32 begin, uint32 end, Range* range) { - DCHECK(range); - range->set_begin(begin); - range->set_end(end); -} - -void SetMediaInfoCommonInfo(bool has_init_range, - uint32 init_range_start, - uint32 init_range_end, - bool has_index_range, - uint32 index_range_start, - uint32 index_range_end, - float duration_seconds, - uint64 file_size, - MediaInfo* media_info) { - DCHECK(media_info); - DCHECK_GT(file_size, 0); - DCHECK_GT(duration_seconds, 0.0f); - - media_info->set_media_duration_seconds(duration_seconds); - media_info->set_bandwidth( - EstimateRequiredBandwidth(file_size, duration_seconds)); - - if (has_init_range) { - SetRange( - init_range_start, init_range_end, media_info->mutable_init_range()); - } - - if (has_index_range) { - SetRange( - index_range_start, index_range_end, media_info->mutable_index_range()); - } -} - -void AddVideoInfo(const VideoStreamInfo* video_stream_info, - MediaInfo* media_info) { - DCHECK(video_stream_info); - DCHECK(media_info); - MediaInfo_VideoInfo* video_info = media_info->add_video_info(); - video_info->set_codec(video_stream_info->codec_string()); - video_info->set_width(video_stream_info->width()); - video_info->set_height(video_stream_info->height()); - video_info->set_time_scale(video_stream_info->time_scale()); - - const std::vector& extra_data = video_stream_info->extra_data(); - if (!extra_data.empty()) { - video_info->set_decoder_config(&extra_data[0], extra_data.size()); - } - // TODO(rkuroiwa): Get frame duration. -} - -void AddAudioInfo(const AudioStreamInfo* audio_stream_info, - MediaInfo* media_info) { - DCHECK(audio_stream_info); - DCHECK(media_info); - MediaInfo_AudioInfo* audio_info = media_info->add_audio_info(); - audio_info->set_codec(audio_stream_info->codec_string()); - audio_info->set_sampling_frequency(audio_stream_info->sampling_frequency()); - audio_info->set_time_scale(audio_stream_info->time_scale()); - audio_info->set_num_channels(audio_stream_info->num_channels()); - audio_info->set_language(audio_stream_info->language()); - - const std::vector& extra_data = audio_stream_info->extra_data(); - if (!extra_data.empty()) { - audio_info->set_decoder_config(&extra_data[0], extra_data.size()); - } -} - -void SetMediaInfoStreamInfo(const std::list& stream_info_list, - MediaInfo* media_info) { - typedef std::list::const_iterator StreamInfoIterator; - for (StreamInfoIterator it = stream_info_list.begin(); - it != stream_info_list.end(); - ++it) { - const StreamInfo* stream_info = *it; - if (!stream_info) - continue; - - if (stream_info->stream_type() == kStreamAudio) { - AddAudioInfo(static_cast(stream_info), - media_info); - } else { - DCHECK_EQ(stream_info->stream_type(), kStreamVideo); - AddVideoInfo(static_cast(stream_info), - media_info); - } - } -} - -} // namespace - VodMpdNotifyMuxerListener::VodMpdNotifyMuxerListener( dash_packager::MpdNotifier* mpd_notifier) : mpd_notifier_(mpd_notifier) { @@ -131,38 +22,32 @@ VodMpdNotifyMuxerListener::~VodMpdNotifyMuxerListener() {} void VodMpdNotifyMuxerListener::OnMediaStart( const MuxerOptions& muxer_options, - const std::list& stream_info_list) {} + const std::vector& stream_infos) {} void VodMpdNotifyMuxerListener::OnMediaEnd( - const std::list& stream_info_list, + const std::vector& stream_infos, bool has_init_range, - uint32 init_range_start, - uint32 init_range_end, + uint64 init_range_start, + uint64 init_range_end, bool has_index_range, - uint32 index_range_start, - uint32 index_range_end, + uint64 index_range_start, + uint64 index_range_end, float duration_seconds, uint64 file_size) { - if (file_size == 0) { - // TODO(rkurowia); bandwidth is a required field for MPD. But without the - // file size, AFAIK there's not much I can do. Fail silently? - LOG(ERROR) << "File size not specified"; - return; - } - - if (duration_seconds <= 0.0f) { - // Non positive second media must be invalid media. - LOG(ERROR) << "Duration is not positive: " << duration_seconds; - return; - } - dash_packager::MediaInfo media_info; - SetMediaInfoCommonInfo(has_init_range, init_range_start, init_range_end, - has_index_range, index_range_start, index_range_end, - duration_seconds, - file_size, - &media_info); - SetMediaInfoStreamInfo(stream_info_list, &media_info); + if (!internal::GenerateMediaInfo(stream_infos, + has_init_range, + init_range_start, + init_range_end, + has_index_range, + index_range_start, + index_range_end, + duration_seconds, + file_size, + &media_info)) { + LOG(ERROR) << "Failed to generate MediaInfo from input."; + return; + } uint32 id; // Result unused. mpd_notifier_->NotifyNewContainer(media_info, &id); @@ -171,9 +56,7 @@ void VodMpdNotifyMuxerListener::OnMediaEnd( void VodMpdNotifyMuxerListener::OnNewSegment(uint32 time_scale, uint64 start_time, uint64 duration, - uint64 segment_file_size) { - NOTIMPLEMENTED(); -} + uint64 segment_file_size) {} } // namespace event } // namespace media diff --git a/media/event/vod_mpd_notify_muxer_listener.h b/media/event/vod_mpd_notify_muxer_listener.h index 146671cfde..420f7dfe2a 100644 --- a/media/event/vod_mpd_notify_muxer_listener.h +++ b/media/event/vod_mpd_notify_muxer_listener.h @@ -2,7 +2,7 @@ #ifndef MEDIA_EVENT_VOD_MPD_NOTIFY_MUXER_LISTENER_H_ #define MEDIA_EVENT_VOD_MPD_NOTIFY_MUXER_LISTENER_H_ -#include +#include #include "base/compiler_specific.h" #include "media/event/muxer_listener.h" @@ -12,9 +12,6 @@ class MpdNotifier; } // namespace dash_packager namespace media { - -class StreamInfo; - namespace event { class VodMpdNotifyMuxerListener : public MuxerListener { @@ -27,15 +24,15 @@ class VodMpdNotifyMuxerListener : public MuxerListener { // MuxerListener implementation. virtual void OnMediaStart( const MuxerOptions& muxer_options, - const std::list& stream_info_list) OVERRIDE; + const std::vector& stream_infos) OVERRIDE; - virtual void OnMediaEnd(const std::list& stream_info_list, + virtual void OnMediaEnd(const std::vector& stream_infos, bool has_init_range, - uint32 init_range_start, - uint32 init_range_end, + uint64 init_range_start, + uint64 init_range_end, bool has_index_range, - uint32 index_range_start, - uint32 index_range_end, + uint64 index_range_start, + uint64 index_range_end, float duration_seconds, uint64 file_size) OVERRIDE; diff --git a/media/event/vod_muxer_listener_internal.cc b/media/event/vod_muxer_listener_internal.cc new file mode 100644 index 0000000000..bec8037551 --- /dev/null +++ b/media/event/vod_muxer_listener_internal.cc @@ -0,0 +1,168 @@ +#include "media/event/vod_muxer_listener_internal.h" + +#include + +#include "base/logging.h" +#include "media/base/audio_stream_info.h" +#include "media/base/video_stream_info.h" +#include "mpd/base/media_info.pb.h" +#include "mpd/base/mpd_notifier.h" + +namespace media { +namespace event { +namespace internal { + +using dash_packager::MediaInfo; +using dash_packager::MediaInfo_AudioInfo; +using dash_packager::MediaInfo_VideoInfo; +using dash_packager::Range; + +namespace { + +// This will return a positive value, given that |file_size| and +// |duration_seconds| are positive. +uint32 EstimateRequiredBandwidth(uint64 file_size, float duration_seconds) { + const uint64 file_size_bits = file_size * 8; + const float bits_per_second = file_size_bits / duration_seconds; + + // Note that casting |bits_per_second| to an integer might make it 0. Take the + // ceiling and make sure that it returns a positive value. + return static_cast(ceil(bits_per_second)); +} + +void SetRange(uint64 begin, uint64 end, Range* range) { + DCHECK(range); + range->set_begin(begin); + range->set_end(end); +} + +void SetMediaInfoCommonInfo(bool has_init_range, + uint64 init_range_start, + uint64 init_range_end, + bool has_index_range, + uint64 index_range_start, + uint64 index_range_end, + float duration_seconds, + uint64 file_size, + MediaInfo* media_info) { + DCHECK(media_info); + DCHECK_GT(file_size, 0); + DCHECK_GT(duration_seconds, 0.0f); + + media_info->set_media_duration_seconds(duration_seconds); + media_info->set_bandwidth( + EstimateRequiredBandwidth(file_size, duration_seconds)); + + if (has_init_range) { + SetRange( + init_range_start, init_range_end, media_info->mutable_init_range()); + } + + if (has_index_range) { + SetRange( + index_range_start, index_range_end, media_info->mutable_index_range()); + } +} + +void AddVideoInfo(const VideoStreamInfo* video_stream_info, + MediaInfo* media_info) { + DCHECK(video_stream_info); + DCHECK(media_info); + MediaInfo_VideoInfo* video_info = media_info->add_video_info(); + video_info->set_codec(video_stream_info->codec_string()); + video_info->set_width(video_stream_info->width()); + video_info->set_height(video_stream_info->height()); + video_info->set_time_scale(video_stream_info->time_scale()); + + const std::vector& extra_data = video_stream_info->extra_data(); + if (!extra_data.empty()) { + video_info->set_decoder_config(&extra_data[0], extra_data.size()); + } + // TODO(rkuroiwa): Get frame duration. +} + +void AddAudioInfo(const AudioStreamInfo* audio_stream_info, + MediaInfo* media_info) { + DCHECK(audio_stream_info); + DCHECK(media_info); + MediaInfo_AudioInfo* audio_info = media_info->add_audio_info(); + audio_info->set_codec(audio_stream_info->codec_string()); + audio_info->set_sampling_frequency(audio_stream_info->sampling_frequency()); + audio_info->set_time_scale(audio_stream_info->time_scale()); + audio_info->set_num_channels(audio_stream_info->num_channels()); + + const std::string& language = audio_stream_info->language(); + // ISO-639-2/T defines language "und" which we also want to ignore. + if (!language.empty() && language != "und") { + audio_info->set_language(language); + } + + const std::vector& extra_data = audio_stream_info->extra_data(); + if (!extra_data.empty()) { + audio_info->set_decoder_config(&extra_data[0], extra_data.size()); + } +} + +void SetMediaInfoStreamInfo(const std::vector& stream_infos, + MediaInfo* media_info) { + typedef std::vector::const_iterator StreamInfoIterator; + for (StreamInfoIterator it = stream_infos.begin(); + it != stream_infos.end(); + ++it) { + const StreamInfo* stream_info = *it; + if (!stream_info) + continue; + + if (stream_info->stream_type() == kStreamAudio) { + AddAudioInfo(static_cast(stream_info), + media_info); + } else { + DCHECK_EQ(stream_info->stream_type(), kStreamVideo); + AddVideoInfo(static_cast(stream_info), + media_info); + } + } +} + +} // namespace + +bool GenerateMediaInfo(const std::vector& stream_infos, + bool has_init_range, + uint64 init_range_start, + uint64 init_range_end, + bool has_index_range, + uint64 index_range_start, + uint64 index_range_end, + float duration_seconds, + uint64 file_size, + MediaInfo* media_info) { + DCHECK(media_info); + if (file_size == 0) { + // TODO(rkurowia); bandwidth is a required field for MPD. But without the + // file size, AFAIK there's not much I can do. Fail silently? + LOG(ERROR) << "File size not specified."; + return false; + } + + if (duration_seconds <= 0.0f) { + // Non positive second media must be invalid media. + LOG(ERROR) << "Duration is not positive: " << duration_seconds; + return false;; + } + + SetMediaInfoCommonInfo(has_init_range, + init_range_start, + init_range_end, + has_index_range, + index_range_start, + index_range_end, + duration_seconds, + file_size, + media_info); + SetMediaInfoStreamInfo(stream_infos, media_info); + return true; +}; + +} // namespace internal +} // namespace event +} // namespace media diff --git a/media/event/vod_muxer_listener_internal.h b/media/event/vod_muxer_listener_internal.h new file mode 100644 index 0000000000..dc6ec49e38 --- /dev/null +++ b/media/event/vod_muxer_listener_internal.h @@ -0,0 +1,35 @@ +#ifndef MEDIA_EVENT_VOD_MUXER_LISTENER_INTERNAL_H_ +#define MEDIA_EVENT_VOD_MUXER_LISTENER_INTERNAL_H_ + +#include + +#include "base/basictypes.h" + +namespace dash_packager { +class MediaInfo; +} // namespace dash_packager + +namespace media { + +class StreamInfo; + +namespace event { +namespace internal { + +// On success fill |media_info| with input data and return true, otherwise +// return false. +bool GenerateMediaInfo(const std::vector& stream_infos, + bool has_init_range, + uint64 init_range_start, + uint64 init_range_end, + bool has_index_range, + uint64 index_range_start, + uint64 index_range_end, + float duration_seconds, + uint64 file_size, + dash_packager::MediaInfo* media_info); + +} // namespace internal +} // namespace event +} // namespace media +#endif // MEDIA_EVENT_VOD_MUXER_LISTENER_INTERNAL_H_