From 90dae2716cdb0869df583dc092dcbbf05b8a27af Mon Sep 17 00:00:00 2001 From: Rintaro Kuroiwa Date: Tue, 14 Jan 2014 00:50:48 -0800 Subject: [PATCH] Convert info from muxer to MediaInfo and dump to file A MuxerListener implementation. MediaInfo protobuf is dumped out to a file as human readable string. Change-Id: I1b1d52b4d11d969efc07b413ff25cb26fb1aa2b4 --- media/event/muxer_listener.h | 2 + .../vod_media_info_dump_muxer_listener.cc | 109 ++++++++++++++++++ .../vod_media_info_dump_muxer_listener.h | 66 +++++++++++ media/event/vod_mpd_notify_muxer_listener.cc | 6 +- media/event/vod_mpd_notify_muxer_listener.h | 10 +- packager.gyp | 19 +++ 6 files changed, 204 insertions(+), 8 deletions(-) create mode 100644 media/event/vod_media_info_dump_muxer_listener.cc create mode 100644 media/event/vod_media_info_dump_muxer_listener.h diff --git a/media/event/muxer_listener.h b/media/event/muxer_listener.h index a82d7c7cbe..0abfaeb1b2 100644 --- a/media/event/muxer_listener.h +++ b/media/event/muxer_listener.h @@ -13,6 +13,8 @@ class StreamInfo; namespace event { +// TODO(rkuroiwa): Need a solution to report a problem to the user. One idea is +// to add GetStatus() method somewhere (maybe in MuxerListener, maybe not). class MuxerListener { public: MuxerListener() {}; diff --git a/media/event/vod_media_info_dump_muxer_listener.cc b/media/event/vod_media_info_dump_muxer_listener.cc new file mode 100644 index 0000000000..504121c7e2 --- /dev/null +++ b/media/event/vod_media_info_dump_muxer_listener.cc @@ -0,0 +1,109 @@ +#include "media/event/vod_media_info_dump_muxer_listener.h" + +#include "base/logging.h" +#include "media/base/stream_info.h" +#include "media/event/vod_muxer_listener_internal.h" +#include "media/file/file.h" +#include "mpd/base/media_info.pb.h" +#include "third_party/protobuf/src/google/protobuf/text_format.h" + +namespace media { +namespace event { + +using dash_packager::MediaInfo; + +namespace { +bool IsAnyStreamEncrypted(const std::vector& stream_infos) { + typedef std::vector::const_iterator Iterator; + for (Iterator it = stream_infos.begin(); it != stream_infos.end(); ++it) { + if ((*it)->is_encrypted()) + return true; + } + + return false; +} +} // namespace + +VodMediaInfoDumpMuxerListener::VodMediaInfoDumpMuxerListener(File* output_file) + : file_(output_file) {} + +VodMediaInfoDumpMuxerListener::~VodMediaInfoDumpMuxerListener() {} + +void VodMediaInfoDumpMuxerListener::SetContentProtectionSchemeIdUri( + const std::string& scheme_id_uri) { + scheme_id_uri_ = scheme_id_uri; +} + +void VodMediaInfoDumpMuxerListener::OnMediaStart( + const MuxerOptions& muxer_options, + const std::vector& stream_infos, + uint32 time_scale) { + DLOG(INFO) + << "VodMediaInfoDumpMuxerListener does not care about OnMediaStart."; +} + +void VodMediaInfoDumpMuxerListener::OnMediaEnd( + 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; + 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; + } + + if (IsAnyStreamEncrypted(stream_infos)) { + if (scheme_id_uri_.empty()) { + LOG(ERROR) << "The stream is encrypted but no schemeIdUri specified for " + "ContentProtection."; + return; + } + + MediaInfo::ContentProtectionXml* content_protection = + media_info.add_content_protections(); + content_protection->set_scheme_id_uri(scheme_id_uri_); + } + + SerializeMediaInfoToFile(media_info); +} + +void VodMediaInfoDumpMuxerListener::OnNewSegment(uint64 start_time, + uint64 duration, + uint64 segment_file_size) { + NOTIMPLEMENTED(); +} + +void VodMediaInfoDumpMuxerListener::SerializeMediaInfoToFile( + const MediaInfo& media_info) { + std::string output_string; + if (!google::protobuf::TextFormat::PrintToString(media_info, + &output_string)) { + LOG(ERROR) << "Failed to serialize MediaInfo to string."; + return; + } + + if (file_->Write(output_string.data(), output_string.size()) <= 0) { + LOG(ERROR) << "Failed to write MediaInfo to file."; + return; + } + + file_->Flush(); +} + +} // namespace event +} // namespace media diff --git a/media/event/vod_media_info_dump_muxer_listener.h b/media/event/vod_media_info_dump_muxer_listener.h new file mode 100644 index 0000000000..d5206e92f8 --- /dev/null +++ b/media/event/vod_media_info_dump_muxer_listener.h @@ -0,0 +1,66 @@ +// Implementation of MuxerListener that converts the info to a MediaInfo +// protobuf and dumps it to a file. +// This is specifically for VOD. +#ifndef MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_ +#define MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_ + +#include +#include + +#include "base/compiler_specific.h" +#include "media/event/muxer_listener.h" + +namespace dash_packager { +class MediaInfo; +} // namespace dash_packager + +namespace media { + +class File; +class MuxerOptions; + +namespace event { + +class VodMediaInfoDumpMuxerListener : public MuxerListener { + // This object does not own |output_file|. The file has to be open and be + // ready for Write(). This will Flush() the file on write but it does not + // Close() the file. + VodMediaInfoDumpMuxerListener(File* output_file); + virtual ~VodMediaInfoDumpMuxerListener(); + + // If the stream is encrypted use this as 'schemeIdUri' attribute for + // ContentProtection element. + void SetContentProtectionSchemeIdUri(const std::string& scheme_id_uri); + + // MuxerListener implementation. + virtual void OnMediaStart(const MuxerOptions& muxer_options, + const std::vector& stream_infos, + uint32 time_scale) OVERRIDE; + + virtual void OnMediaEnd(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) OVERRIDE; + + virtual void OnNewSegment(uint64 start_time, + uint64 duration, + uint64 segment_file_size) OVERRIDE; + private: + // Write |media_info| to |file_|. + void SerializeMediaInfoToFile(const dash_packager::MediaInfo& media_info); + + File* file_; + std::string scheme_id_uri_; + + DISALLOW_COPY_AND_ASSIGN(VodMediaInfoDumpMuxerListener); +}; + +} // namespace event +} // namespace media + +#endif // MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_ diff --git a/media/event/vod_mpd_notify_muxer_listener.cc b/media/event/vod_mpd_notify_muxer_listener.cc index a0112b9854..490842fb45 100644 --- a/media/event/vod_mpd_notify_muxer_listener.cc +++ b/media/event/vod_mpd_notify_muxer_listener.cc @@ -22,7 +22,8 @@ VodMpdNotifyMuxerListener::~VodMpdNotifyMuxerListener() {} void VodMpdNotifyMuxerListener::OnMediaStart( const MuxerOptions& muxer_options, - const std::vector& stream_infos) {} + const std::vector& stream_infos, + uint32 time_scale) {} void VodMpdNotifyMuxerListener::OnMediaEnd( const std::vector& stream_infos, @@ -53,8 +54,7 @@ void VodMpdNotifyMuxerListener::OnMediaEnd( mpd_notifier_->NotifyNewContainer(media_info, &id); } -void VodMpdNotifyMuxerListener::OnNewSegment(uint32 time_scale, - uint64 start_time, +void VodMpdNotifyMuxerListener::OnNewSegment(uint64 start_time, uint64 duration, uint64 segment_file_size) {} diff --git a/media/event/vod_mpd_notify_muxer_listener.h b/media/event/vod_mpd_notify_muxer_listener.h index 420f7dfe2a..34b68beee3 100644 --- a/media/event/vod_mpd_notify_muxer_listener.h +++ b/media/event/vod_mpd_notify_muxer_listener.h @@ -22,9 +22,9 @@ class VodMpdNotifyMuxerListener : public MuxerListener { virtual ~VodMpdNotifyMuxerListener(); // MuxerListener implementation. - virtual void OnMediaStart( - const MuxerOptions& muxer_options, - const std::vector& stream_infos) OVERRIDE; + virtual void OnMediaStart(const MuxerOptions& muxer_options, + const std::vector& stream_infos, + uint32 time_scale) OVERRIDE; virtual void OnMediaEnd(const std::vector& stream_infos, bool has_init_range, @@ -36,10 +36,10 @@ class VodMpdNotifyMuxerListener : public MuxerListener { float duration_seconds, uint64 file_size) OVERRIDE; - virtual void OnNewSegment(uint32 time_scale, - uint64 start_time, + virtual void OnNewSegment(uint64 start_time, uint64 duration, uint64 segment_file_size) OVERRIDE; + private: dash_packager::MpdNotifier* const mpd_notifier_; diff --git a/packager.gyp b/packager.gyp index 4731106bc4..e5c9212c7b 100644 --- a/packager.gyp +++ b/packager.gyp @@ -191,6 +191,25 @@ 'media_base', ], }, + { + 'target_name': 'media_event', + 'type': 'static_library', + 'sources': [ + 'media/event/muxer_listener.h', + 'media/event/vod_media_info_dump_muxer_listener.cc', + 'media/event/vod_media_info_dump_muxer_listener.h', + 'media/event/vod_mpd_notify_muxer_listener.cc', + 'media/event/vod_mpd_notify_muxer_listener.h', + 'media/event/vod_muxer_listener_internal.cc', + 'media/event/vod_muxer_listener_internal.h', + ], + 'dependencies': [ + 'media_base', + 'mpd/mpd.gyp:media_info_proto', + # Depends on full protobuf to read/write with TextFormat. + 'third_party/protobuf/protobuf.gyp:protobuf_full_do_not_use', + ], + }, { 'target_name': 'mp4_unittest', 'type': 'executable',