MpdBuilder should be able to write to File instance
Change interface of MpdBuilder so that it can write to a File instance directly. Change-Id: I4007deed4d0246a7c75fbc7c5aca3ece374c1224
This commit is contained in:
parent
05db9e02b9
commit
d04ae592cd
|
@ -15,6 +15,7 @@
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
|
#include "media/file/file.h"
|
||||||
#include "mpd/base/content_protection_element.h"
|
#include "mpd/base/content_protection_element.h"
|
||||||
#include "mpd/base/mpd_utils.h"
|
#include "mpd/base/mpd_utils.h"
|
||||||
#include "mpd/base/xml/xml_node.h"
|
#include "mpd/base/xml/xml_node.h"
|
||||||
|
@ -156,6 +157,29 @@ int SearchTimedOutRepeatIndex(uint64 timeshift_limit,
|
||||||
return (timeshift_limit - segment_info.start_time) / segment_info.duration;
|
return (timeshift_limit - segment_info.start_time) / segment_info.duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Overload this function to support different types of |output|.
|
||||||
|
// Note that this could be done by call MpdBuilder::ToString() and use the
|
||||||
|
// result to write to a file, it requires an extra copy.
|
||||||
|
bool WriteXmlCharArrayToOutput(xmlChar* doc,
|
||||||
|
int doc_size,
|
||||||
|
std::string* output) {
|
||||||
|
DCHECK(doc);
|
||||||
|
DCHECK(output);
|
||||||
|
output->assign(doc, doc + doc_size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteXmlCharArrayToOutput(xmlChar* doc,
|
||||||
|
int doc_size,
|
||||||
|
media::File* output) {
|
||||||
|
DCHECK(doc);
|
||||||
|
DCHECK(output);
|
||||||
|
if (output->Write(doc, doc_size) < doc_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return output->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MpdOptions::MpdOptions()
|
MpdOptions::MpdOptions()
|
||||||
|
@ -190,12 +214,20 @@ AdaptationSet* MpdBuilder::AddAdaptationSet() {
|
||||||
return adaptation_set.release();
|
return adaptation_set.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MpdBuilder::ToString(std::string* output) {
|
bool MpdBuilder::WriteMpdToFile(media::File* output_file) {
|
||||||
base::AutoLock scoped_lock(lock_);
|
base::AutoLock scoped_lock(lock_);
|
||||||
return ToStringImpl(output);
|
DCHECK(output_file);
|
||||||
|
return WriteMpdToOutput(output_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MpdBuilder::ToStringImpl(std::string* output) {
|
bool MpdBuilder::ToString(std::string* output) {
|
||||||
|
base::AutoLock scoped_lock(lock_);
|
||||||
|
DCHECK(output);
|
||||||
|
return WriteMpdToOutput(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputType>
|
||||||
|
bool MpdBuilder::WriteMpdToOutput(OutputType* output) {
|
||||||
xmlInitParser();
|
xmlInitParser();
|
||||||
xml::ScopedXmlPtr<xmlDoc>::type doc(GenerateMpd());
|
xml::ScopedXmlPtr<xmlDoc>::type doc(GenerateMpd());
|
||||||
if (!doc.get())
|
if (!doc.get())
|
||||||
|
@ -207,15 +239,13 @@ bool MpdBuilder::ToStringImpl(std::string* output) {
|
||||||
xmlDocDumpFormatMemoryEnc(
|
xmlDocDumpFormatMemoryEnc(
|
||||||
doc.get(), &doc_str, &doc_str_size, "UTF-8", kNiceFormat);
|
doc.get(), &doc_str, &doc_str_size, "UTF-8", kNiceFormat);
|
||||||
|
|
||||||
output->assign(doc_str, doc_str + doc_str_size);
|
bool result = WriteXmlCharArrayToOutput(doc_str, doc_str_size, output);
|
||||||
xmlFree(doc_str);
|
xmlFree(doc_str);
|
||||||
|
|
||||||
DLOG(INFO) << *output;
|
|
||||||
|
|
||||||
// Cleanup, free the doc then cleanup parser.
|
// Cleanup, free the doc then cleanup parser.
|
||||||
doc.reset();
|
doc.reset();
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
return true;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlDocPtr MpdBuilder::GenerateMpd() {
|
xmlDocPtr MpdBuilder::GenerateMpd() {
|
||||||
|
|
|
@ -25,6 +25,13 @@
|
||||||
#include "mpd/base/segment_info.h"
|
#include "mpd/base/segment_info.h"
|
||||||
#include "mpd/base/xml/scoped_xml_ptr.h"
|
#include "mpd/base/xml/scoped_xml_ptr.h"
|
||||||
|
|
||||||
|
namespace media {
|
||||||
|
class File;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(rkuroiwa): For classes with |id_|, consider removing the field and let
|
||||||
|
// the MPD (XML) generation functions take care of assigning an ID to each
|
||||||
|
// element.
|
||||||
namespace dash_packager {
|
namespace dash_packager {
|
||||||
|
|
||||||
class AdaptationSet;
|
class AdaptationSet;
|
||||||
|
@ -70,6 +77,12 @@ class MpdBuilder {
|
||||||
/// @return The new adaptation set, which is owned by this instance.
|
/// @return The new adaptation set, which is owned by this instance.
|
||||||
AdaptationSet* AddAdaptationSet();
|
AdaptationSet* AddAdaptationSet();
|
||||||
|
|
||||||
|
/// Write the MPD to specified file.
|
||||||
|
/// @param[out] output_file is MPD destination. output_file will be
|
||||||
|
/// flushed but not closed.
|
||||||
|
/// @return true on success, false otherwise.
|
||||||
|
bool WriteMpdToFile(media::File* output_file);
|
||||||
|
|
||||||
/// Writes the MPD to the given string.
|
/// Writes the MPD to the given string.
|
||||||
/// @param[out] output is an output string where the MPD gets written.
|
/// @param[out] output is an output string where the MPD gets written.
|
||||||
/// @return true on success, false otherwise.
|
/// @return true on success, false otherwise.
|
||||||
|
@ -85,6 +98,11 @@ class MpdBuilder {
|
||||||
|
|
||||||
bool ToStringImpl(std::string* output);
|
bool ToStringImpl(std::string* output);
|
||||||
|
|
||||||
|
// This is a helper method for writing out MPDs, called from WriteMpdToFile()
|
||||||
|
// and ToString().
|
||||||
|
template <typename OutputType>
|
||||||
|
bool WriteMpdToOutput(OutputType* output);
|
||||||
|
|
||||||
// Returns the document pointer to the MPD. This must be freed by the caller
|
// Returns the document pointer to the MPD. This must be freed by the caller
|
||||||
// using appropriate xmlDocPtr freeing function.
|
// using appropriate xmlDocPtr freeing function.
|
||||||
// On failure, this returns NULL.
|
// On failure, this returns NULL.
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/string_util.h"
|
#include "base/strings/string_util.h"
|
||||||
#include "base/strings/stringprintf.h"
|
#include "base/strings/stringprintf.h"
|
||||||
|
#include "media/file/file.h"
|
||||||
#include "mpd/base/mpd_builder.h"
|
#include "mpd/base/mpd_builder.h"
|
||||||
#include "mpd/base/mpd_utils.h"
|
#include "mpd/base/mpd_utils.h"
|
||||||
#include "mpd/test/mpd_builder_test_helper.h"
|
#include "mpd/test/mpd_builder_test_helper.h"
|
||||||
|
@ -362,6 +363,31 @@ TEST_F(StaticMpdBuilderTest, MediaInfoMissingBandwidth) {
|
||||||
ASSERT_FALSE(mpd_.ToString(&mpd_doc));
|
ASSERT_FALSE(mpd_.ToString(&mpd_doc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticMpdBuilderTest, WriteToFile) {
|
||||||
|
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
||||||
|
AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet();
|
||||||
|
ASSERT_TRUE(video_adaptation_set);
|
||||||
|
|
||||||
|
Representation* video_representation =
|
||||||
|
video_adaptation_set->AddRepresentation(video_media_info);
|
||||||
|
ASSERT_TRUE(video_representation);
|
||||||
|
|
||||||
|
base::FilePath file_path;
|
||||||
|
ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
|
||||||
|
media::File* file = media::File::Open(file_path.value().data(), "w");
|
||||||
|
ASSERT_TRUE(file);
|
||||||
|
ASSERT_TRUE(mpd_.WriteMpdToFile(file));
|
||||||
|
ASSERT_TRUE(file->Close());
|
||||||
|
|
||||||
|
std::string file_content;
|
||||||
|
ASSERT_TRUE(base::ReadFileToString(file_path, &file_content));
|
||||||
|
ASSERT_NO_FATAL_FAILURE(ExpectMpdToEqualExpectedOutputFile(
|
||||||
|
file_content, kFileNameExpectedMpdOutputVideo1));
|
||||||
|
|
||||||
|
const bool kNonRecursive = false;
|
||||||
|
EXPECT_TRUE(DeleteFile(file_path, kNonRecursive));
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether the attributes are set correctly for dynamic <MPD> element.
|
// Check whether the attributes are set correctly for dynamic <MPD> element.
|
||||||
TEST_F(DynamicMpdBuilderTest, CheckMpdAttributes) {
|
TEST_F(DynamicMpdBuilderTest, CheckMpdAttributes) {
|
||||||
static const char kExpectedOutput[] =
|
static const char kExpectedOutput[] =
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
],
|
],
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'../base/base.gyp:base',
|
'../base/base.gyp:base',
|
||||||
|
'../media/file/file.gyp:file',
|
||||||
'../third_party/libxml/libxml.gyp:libxml',
|
'../third_party/libxml/libxml.gyp:libxml',
|
||||||
'media_info_proto',
|
'media_info_proto',
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue