2014-02-14 23:21:05 +00:00
|
|
|
// Copyright 2014 Google Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file or at
|
|
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
|
2014-10-01 22:10:21 +00:00
|
|
|
#include "packager/mpd/util/mpd_writer.h"
|
2014-01-15 18:50:47 +00:00
|
|
|
|
2015-09-14 19:53:32 +00:00
|
|
|
#include <gflags/gflags.h>
|
2014-08-28 18:35:15 +00:00
|
|
|
#include <google/protobuf/text_format.h>
|
2014-09-30 23:52:58 +00:00
|
|
|
#include <stdint.h>
|
2014-08-28 18:35:15 +00:00
|
|
|
|
2015-09-14 19:53:32 +00:00
|
|
|
#include "packager/base/files/file_path.h"
|
2015-07-22 23:40:45 +00:00
|
|
|
#include "packager/base/files/file_util.h"
|
2014-10-01 22:10:21 +00:00
|
|
|
#include "packager/media/file/file.h"
|
2015-09-14 19:53:32 +00:00
|
|
|
#include "packager/mpd/base/dash_iop_mpd_notifier.h"
|
2014-10-01 22:10:21 +00:00
|
|
|
#include "packager/mpd/base/mpd_builder.h"
|
2015-09-14 19:53:32 +00:00
|
|
|
#include "packager/mpd/base/mpd_notifier.h"
|
2015-08-26 20:25:29 +00:00
|
|
|
#include "packager/mpd/base/mpd_utils.h"
|
2015-09-14 19:53:32 +00:00
|
|
|
#include "packager/mpd/base/simple_mpd_notifier.h"
|
|
|
|
|
|
|
|
DEFINE_bool(generate_dash_if_iop_compliant_mpd,
|
|
|
|
false,
|
|
|
|
"Try to generate DASH-IF IOPv3 compliant MPD. This is best effort "
|
|
|
|
"and does not guarantee compliance. Off by default until players "
|
|
|
|
"support IOP MPDs.");
|
2014-01-15 18:50:47 +00:00
|
|
|
|
2016-05-20 21:19:33 +00:00
|
|
|
namespace shaka {
|
2014-01-15 18:50:47 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2015-09-14 19:53:32 +00:00
|
|
|
// Factory that creates DashIopMpdNotifier instances.
|
|
|
|
class DashIopMpdNotifierFactory : public MpdNotifierFactory {
|
|
|
|
public:
|
|
|
|
DashIopMpdNotifierFactory() {}
|
2015-07-22 23:40:45 +00:00
|
|
|
~DashIopMpdNotifierFactory() override {}
|
2015-09-14 19:53:32 +00:00
|
|
|
|
2015-07-22 23:40:45 +00:00
|
|
|
scoped_ptr<MpdNotifier> Create(DashProfile dash_profile,
|
|
|
|
const MpdOptions& mpd_options,
|
|
|
|
const std::vector<std::string>& base_urls,
|
|
|
|
const std::string& output_path) override {
|
2015-09-14 19:53:32 +00:00
|
|
|
return scoped_ptr<MpdNotifier>(new DashIopMpdNotifier(
|
|
|
|
dash_profile, mpd_options, base_urls, output_path));
|
2015-02-02 17:26:09 +00:00
|
|
|
}
|
2015-09-14 19:53:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Factory that creates SimpleMpdNotifier instances.
|
|
|
|
class SimpleMpdNotifierFactory : public MpdNotifierFactory {
|
|
|
|
public:
|
|
|
|
SimpleMpdNotifierFactory() {}
|
2015-07-22 23:40:45 +00:00
|
|
|
~SimpleMpdNotifierFactory() override {}
|
2015-09-14 19:53:32 +00:00
|
|
|
|
2015-07-22 23:40:45 +00:00
|
|
|
scoped_ptr<MpdNotifier> Create(DashProfile dash_profile,
|
|
|
|
const MpdOptions& mpd_options,
|
|
|
|
const std::vector<std::string>& base_urls,
|
|
|
|
const std::string& output_path) override {
|
2015-09-14 19:53:32 +00:00
|
|
|
return scoped_ptr<MpdNotifier>(new SimpleMpdNotifier(
|
|
|
|
dash_profile, mpd_options, base_urls, output_path));
|
2014-01-15 18:50:47 +00:00
|
|
|
}
|
2015-09-14 19:53:32 +00:00
|
|
|
};
|
2014-01-15 18:50:47 +00:00
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2015-09-14 19:53:32 +00:00
|
|
|
MpdWriter::MpdWriter()
|
|
|
|
: notifier_factory_(FLAGS_generate_dash_if_iop_compliant_mpd
|
|
|
|
? static_cast<MpdNotifierFactory*>(
|
|
|
|
new DashIopMpdNotifierFactory())
|
|
|
|
: static_cast<MpdNotifierFactory*>(
|
|
|
|
new SimpleMpdNotifierFactory())) {}
|
2014-01-15 18:50:47 +00:00
|
|
|
MpdWriter::~MpdWriter() {}
|
|
|
|
|
2014-12-16 01:32:19 +00:00
|
|
|
bool MpdWriter::AddFile(const std::string& media_info_path,
|
|
|
|
const std::string& mpd_path) {
|
2014-01-15 18:50:47 +00:00
|
|
|
std::string file_content;
|
2014-12-16 01:32:19 +00:00
|
|
|
if (!media::File::ReadFileToString(media_info_path.c_str(),
|
|
|
|
&file_content)) {
|
|
|
|
LOG(ERROR) << "Failed to read " << media_info_path << " to string.";
|
2014-01-15 18:50:47 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MediaInfo media_info;
|
|
|
|
if (!::google::protobuf::TextFormat::ParseFromString(file_content,
|
|
|
|
&media_info)) {
|
|
|
|
LOG(ERROR) << "Failed to parse " << file_content << " to MediaInfo.";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-12-16 01:32:19 +00:00
|
|
|
MpdBuilder::MakePathsRelativeToMpd(mpd_path, &media_info);
|
2014-01-15 18:50:47 +00:00
|
|
|
media_infos_.push_back(media_info);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MpdWriter::AddBaseUrl(const std::string& base_url) {
|
|
|
|
base_urls_.push_back(base_url);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MpdWriter::WriteMpdToFile(const char* file_name) {
|
|
|
|
CHECK(file_name);
|
2015-09-14 19:53:32 +00:00
|
|
|
scoped_ptr<MpdNotifier> notifier = notifier_factory_->Create(
|
|
|
|
kOnDemandProfile, MpdOptions(), base_urls_, file_name);
|
|
|
|
if (!notifier->Init()) {
|
|
|
|
LOG(ERROR) << "failed to initialize MpdNotifier.";
|
2014-01-15 18:50:47 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-09-14 19:53:32 +00:00
|
|
|
for (std::list<MediaInfo>::const_iterator it = media_infos_.begin();
|
|
|
|
it != media_infos_.end();
|
|
|
|
++it) {
|
|
|
|
uint32_t unused_conatiner_id;
|
|
|
|
if (!notifier->NotifyNewContainer(*it, &unused_conatiner_id)) {
|
|
|
|
LOG(ERROR) << "Failed to add MediaInfo for media file: "
|
|
|
|
<< it->media_file_name();
|
2014-01-15 18:50:47 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-14 19:53:32 +00:00
|
|
|
if (!notifier->Flush()) {
|
|
|
|
LOG(ERROR) << "Failed to flush MPD notifier.";
|
2014-01-15 18:50:47 +00:00
|
|
|
return false;
|
|
|
|
}
|
2015-09-14 19:53:32 +00:00
|
|
|
return true;
|
|
|
|
}
|
2014-01-15 18:50:47 +00:00
|
|
|
|
2015-09-14 19:53:32 +00:00
|
|
|
void MpdWriter::SetMpdNotifierFactoryForTest(
|
|
|
|
scoped_ptr<MpdNotifierFactory> factory) {
|
|
|
|
notifier_factory_ = factory.Pass();
|
2014-01-15 18:50:47 +00:00
|
|
|
}
|
|
|
|
|
2016-05-20 21:19:33 +00:00
|
|
|
} // namespace shaka
|