// 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 #include "base/file_util.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "mpd/base/mpd_builder.h" #include "mpd/test/mpd_builder_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/libxml/src/include/libxml/xmlstring.h" namespace dash_packager { namespace { // Get 'id' attribute from |node|, convert it to std::string and convert it to a // number. void ExpectXmlElementIdEqual(xmlNodePtr node, uint32 id) { const char kId[] = "id"; xml::ScopedXmlPtr::type id_attribute_xml_str( xmlGetProp(node, BAD_CAST kId)); ASSERT_TRUE(id_attribute_xml_str); unsigned id_attribute_unsigned = 0; std::string id_attribute_str = reinterpret_cast(id_attribute_xml_str.get()); ASSERT_TRUE(base::StringToUint(id_attribute_str, &id_attribute_unsigned)); ASSERT_EQ(id, id_attribute_unsigned); } // Using template to support both AdaptationSet and Representation. template void CheckIdEqual(uint32 expected_id, T* node) { ASSERT_EQ(expected_id, node->id()); // Also check if the XML generated by libxml2 has the correct id attribute. xml::ScopedXmlPtr::type node_xml(node->GetXml()); ASSERT_NO_FATAL_FAILURE(ExpectXmlElementIdEqual(node_xml.get(), expected_id)); } } // namespace TEST(AdaptationSetTest, CheckId) { base::AtomicSequenceNumber sequence_counter; const uint32 kAdaptationSetId = 42; AdaptationSet adaptation_set(kAdaptationSetId, &sequence_counter); ASSERT_NO_FATAL_FAILURE(CheckIdEqual(kAdaptationSetId, &adaptation_set)); } TEST(RepresentationTest, CheckId) { const MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1); const uint32 kRepresentationId = 1; Representation representation(video_media_info, kRepresentationId); EXPECT_TRUE(representation.Init()); ASSERT_NO_FATAL_FAILURE(CheckIdEqual(kRepresentationId, &representation)); } class StaticMpdBuilderTest : public ::testing::Test { public: StaticMpdBuilderTest() : mpd_(MpdBuilder::kStatic) {} virtual ~StaticMpdBuilderTest() {} void CheckMpd(const std::string& expected_output_file) { std::string mpd_doc; ASSERT_TRUE(mpd_.ToString(&mpd_doc)); ASSERT_TRUE(ValidateMpdSchema(mpd_doc)); ASSERT_NO_FATAL_FAILURE( ExpectMpdToEqualExpectedOutputFile(mpd_doc, expected_output_file)); } protected: MpdBuilder mpd_; private: DISALLOW_COPY_AND_ASSIGN(StaticMpdBuilderTest); }; TEST_F(StaticMpdBuilderTest, Video) { 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); EXPECT_NO_FATAL_FAILURE(CheckMpd(kFileNameExpectedMpdOutputVideo1)); } TEST_F(StaticMpdBuilderTest, VideoAndAudio) { MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1); MediaInfo audio_media_info = GetTestMediaInfo(kFileNameAudioMediaInfo1); // The order matters here to check against expected output. AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet(); ASSERT_TRUE(video_adaptation_set); AdaptationSet* audio_adaptation_set = mpd_.AddAdaptationSet(); ASSERT_TRUE(audio_adaptation_set); Representation* audio_representation = audio_adaptation_set->AddRepresentation(audio_media_info); ASSERT_TRUE(audio_representation); Representation* video_representation = video_adaptation_set->AddRepresentation(video_media_info); ASSERT_TRUE(video_representation); EXPECT_NO_FATAL_FAILURE(CheckMpd(kFileNameExpectedMpdOutputAudio1AndVideo1)); } // MPD schema has strict ordering. AudioChannelConfiguration must appear before // ContentProtection. TEST_F(StaticMpdBuilderTest, AudioChannelConfigurationWithContentProtection) { MediaInfo encrypted_audio_media_info = GetTestMediaInfo(kFileNameEncytpedAudioMediaInfo); AdaptationSet* audio_adaptation_set = mpd_.AddAdaptationSet(); ASSERT_TRUE(audio_adaptation_set); Representation* audio_representation = audio_adaptation_set->AddRepresentation(encrypted_audio_media_info); ASSERT_TRUE(audio_representation); EXPECT_NO_FATAL_FAILURE(CheckMpd(kFileNameExpectedMpdOutputEncryptedAudio)); } } // namespace dash_packager