From 144cdc5e598ffae483244ce66aa76d7241b0c21f Mon Sep 17 00:00:00 2001 From: Jacob Trimble Date: Wed, 17 Feb 2016 14:03:43 -0800 Subject: [PATCH] Change to use ProtectionSystemSpecificInfo. * EncryptionKey now contains them rather than a PSSH box. * Outputs PSSH boxes for each entry. * Outputs a ContentProtection element for each entry. * Removed SystemName and UUID from KeySource. * Removed --scheme_id_uri packager argument. Issue #88 Change-Id: I2651784c3220fd64f5b1773fdcd70285690cf8c0 --- packager/app/mpd_flags.cc | 8 --- packager/app/mpd_flags.h | 1 - packager/app/packager_main.cc | 4 -- packager/media/base/key_source.cc | 66 +++++++------------ packager/media/base/key_source.h | 22 +------ .../base/protection_system_specific_info.h | 10 +-- ...rotection_system_specific_info_unittest.cc | 18 ++--- packager/media/base/widevine_key_source.cc | 15 +++-- packager/media/base/widevine_key_source.h | 1 - .../base/widevine_key_source_unittest.cc | 17 +++-- .../media/event/mpd_notify_muxer_listener.cc | 29 ++++---- .../media/event/mpd_notify_muxer_listener.h | 14 +--- .../mpd_notify_muxer_listener_unittest.cc | 35 ++++------ packager/media/event/muxer_listener.h | 12 +--- .../media/event/muxer_listener_internal.cc | 38 ++++++----- .../media/event/muxer_listener_internal.h | 14 ++-- .../media/event/muxer_listener_test_helper.cc | 14 ++++ .../media/event/muxer_listener_test_helper.h | 10 +++ .../vod_media_info_dump_muxer_listener.cc | 17 ++--- .../vod_media_info_dump_muxer_listener.h | 14 +--- ...media_info_dump_muxer_listener_unittest.cc | 28 ++------ .../formats/mp4/key_rotation_fragmenter.cc | 19 +++--- packager/media/formats/mp4/segmenter.cc | 21 +++--- .../webm/encrypted_segmenter_unittest.cc | 42 ++++++------ packager/media/formats/webm/encryptor.cc | 6 +- .../mpd/base/simple_mpd_notifier_unittest.cc | 2 +- 26 files changed, 202 insertions(+), 275 deletions(-) diff --git a/packager/app/mpd_flags.cc b/packager/app/mpd_flags.cc index a119394ab7..bfa3864518 100644 --- a/packager/app/mpd_flags.cc +++ b/packager/app/mpd_flags.cc @@ -17,14 +17,6 @@ DEFINE_bool(output_media_info, "'.media_info'. Exclusive with --mpd_output."); DEFINE_string(mpd_output, "", "MPD output file name. Exclusive with --output_media_info."); -DEFINE_string(scheme_id_uri, - "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed", - "This flag only applies if output_media_info is true. This value " - "will be set in MediaInfo if the stream is encrypted. " - "If the stream is encrypted, MPD requires a " - "element which requires the schemeIdUri attribute. " - "Default value is Widevine PSSH system ID, and it is valid only " - "for ISO BMFF."); DEFINE_string(base_urls, "", "Comma separated BaseURLs for the MPD. The values will be added " diff --git a/packager/app/mpd_flags.h b/packager/app/mpd_flags.h index 9f6ef3ec18..ff76e9b838 100644 --- a/packager/app/mpd_flags.h +++ b/packager/app/mpd_flags.h @@ -13,7 +13,6 @@ DECLARE_bool(output_media_info); DECLARE_string(mpd_output); -DECLARE_string(scheme_id_uri); DECLARE_string(base_urls); DECLARE_double(availability_time_offset); DECLARE_double(minimum_update_period); diff --git a/packager/app/packager_main.cc b/packager/app/packager_main.cc index 4de1e6b8d0..c7935b13aa 100644 --- a/packager/app/packager_main.cc +++ b/packager/app/packager_main.cc @@ -307,15 +307,11 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors, scoped_ptr vod_media_info_dump_muxer_listener( new VodMediaInfoDumpMuxerListener(output_media_info_file_name)); - vod_media_info_dump_muxer_listener->SetContentProtectionSchemeIdUri( - FLAGS_scheme_id_uri); muxer_listener = vod_media_info_dump_muxer_listener.Pass(); } if (mpd_notifier) { scoped_ptr mpd_notify_muxer_listener( new MpdNotifyMuxerListener(mpd_notifier)); - mpd_notify_muxer_listener->SetContentProtectionSchemeIdUri( - FLAGS_scheme_id_uri); muxer_listener = mpd_notify_muxer_listener.Pass(); } diff --git a/packager/media/base/key_source.cc b/packager/media/base/key_source.cc index c62111b72d..1f5e8f73f0 100644 --- a/packager/media/base/key_source.cc +++ b/packager/media/base/key_source.cc @@ -10,12 +10,6 @@ #include "packager/media/base/aes_encryptor.h" #include "packager/media/base/buffer_writer.h" -namespace { -// TODO(kqyang): Consider making it configurable. -const char kDefaultUUID[] = "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"; -const char kDefaultSystemName[] = ""; -} // namespace - namespace edash_packager { namespace media { @@ -81,24 +75,28 @@ Status KeySource::GetCryptoPeriodKey(uint32_t crypto_period_index, std::rotate(key->key.begin(), key->key.begin() + (crypto_period_index % key->key.size()), key->key.end()); - const size_t kPsshHeaderSize = 32u; - std::vector pssh_data(key->pssh.begin() + kPsshHeaderSize, - key->pssh.end()); + + std::vector pssh_data( + key->key_system_info[0].pssh_data().begin(), + key->key_system_info[0].pssh_data().end()); std::rotate(pssh_data.begin(), pssh_data.begin() + (crypto_period_index % pssh_data.size()), pssh_data.end()); - key->pssh = PsshBoxFromPsshData(pssh_data); + + // Since this should only be used for testing, use the Widevine system id. + // TODO(modmaker): Change to FixedKeySource + ProtectionSystemSpecificInfo info; + info.add_key_id(key->key_id); + info.set_system_id(kWidevineSystemId, arraysize(kWidevineSystemId)); + info.set_pssh_box_version(0); + info.set_pssh_data(pssh_data); + + key->key_system_info.clear(); + key->key_system_info.push_back(info); + return Status::OK; } -std::string KeySource::UUID() { - return kDefaultUUID; -} - -std::string KeySource::SystemName() { - return kDefaultSystemName; -} - scoped_ptr KeySource::CreateFromHexStrings( const std::string& key_id_hex, const std::string& key_hex, @@ -130,9 +128,15 @@ scoped_ptr KeySource::CreateFromHexStrings( } } - encryption_key->pssh = PsshBoxFromPsshData(pssh_data); - return scoped_ptr( - new KeySource(encryption_key.Pass())); + // TODO(modmaker): Change to FixedKeySource + ProtectionSystemSpecificInfo info; + info.add_key_id(encryption_key->key_id); + info.set_system_id(kWidevineSystemId, arraysize(kWidevineSystemId)); + info.set_pssh_box_version(0); + info.set_pssh_data(pssh_data); + + encryption_key->key_system_info.push_back(info); + return scoped_ptr(new KeySource(encryption_key.Pass())); } KeySource::TrackType KeySource::GetTrackTypeFromString( @@ -163,26 +167,6 @@ std::string KeySource::TrackTypeToString(TrackType track_type) { } } -std::vector KeySource::PsshBoxFromPsshData( - const std::vector& pssh_data) { - const uint8_t kPsshFourCC[] = {'p', 's', 's', 'h'}; - const uint32_t kVersionAndFlags = 0; - - const uint32_t pssh_data_size = pssh_data.size(); - const uint32_t total_size = - sizeof(total_size) + sizeof(kPsshFourCC) + sizeof(kVersionAndFlags) + - sizeof(kWidevineSystemId) + sizeof(pssh_data_size) + pssh_data_size; - - BufferWriter writer; - writer.AppendInt(total_size); - writer.AppendArray(kPsshFourCC, sizeof(kPsshFourCC)); - writer.AppendInt(kVersionAndFlags); - writer.AppendArray(kWidevineSystemId, sizeof(kWidevineSystemId)); - writer.AppendInt(pssh_data_size); - writer.AppendVector(pssh_data); - return std::vector(writer.Buffer(), writer.Buffer() + writer.Size()); -} - KeySource::KeySource() {} KeySource::KeySource(scoped_ptr encryption_key) : encryption_key_(encryption_key.Pass()) { diff --git a/packager/media/base/key_source.h b/packager/media/base/key_source.h index 48158590e4..727d407c0c 100644 --- a/packager/media/base/key_source.h +++ b/packager/media/base/key_source.h @@ -7,9 +7,11 @@ #ifndef MEDIA_BASE_KEY_SOURCE_H_ #define MEDIA_BASE_KEY_SOURCE_H_ +#include #include #include "packager/base/memory/scoped_ptr.h" +#include "packager/media/base/protection_system_specific_info.h" #include "packager/media/base/status.h" namespace edash_packager { @@ -23,9 +25,9 @@ struct EncryptionKey { EncryptionKey(); ~EncryptionKey(); + std::vector key_system_info; std::vector key_id; std::vector key; - std::vector pssh; std::vector iv; }; @@ -91,19 +93,6 @@ class KeySource { TrackType track_type, EncryptionKey* key); - /// Returns the UUID of the key source in human readable form. - /// UUIDs are listed here: - /// http://dashif.org/identifiers/protection/ - /// @return UUID of the key source, empty string if not specified. - virtual std::string UUID(); - - /// Returns the name, and possibly with a version number, of the key source. - /// (This would be the ContentProtection@value attribute in the MPD. DASH-IF- - /// IOP v3.0 recommends this to be the DRM system and version name in human - /// readable from.) - /// @return the name of the key source, empty string if not specified. - virtual std::string SystemName(); - /// Create KeySource object from hex strings. /// @param key_id_hex is the key id in hex string. /// @param key_hex is the key in hex string. @@ -127,11 +116,6 @@ class KeySource { protected: KeySource(); - /// @return the raw bytes of the pssh box with system ID and box header - /// included. - static std::vector PsshBoxFromPsshData( - const std::vector& pssh_data); - private: explicit KeySource(scoped_ptr encryption_key); diff --git a/packager/media/base/protection_system_specific_info.h b/packager/media/base/protection_system_specific_info.h index 97827be056..ab734341c9 100644 --- a/packager/media/base/protection_system_specific_info.h +++ b/packager/media/base/protection_system_specific_info.h @@ -36,18 +36,18 @@ class ProtectionSystemSpecificInfo { /// Creates a PSSH box for the current data. std::vector CreateBox() const; - uint8_t version() const { return version_; } + uint8_t pssh_box_version() const { return version_; } const std::vector& system_id() const { return system_id_; } const std::vector>& key_ids() const { return key_ids_; } const std::vector& pssh_data() const { return pssh_data_; } - void set_version(uint8_t version) { + void set_pssh_box_version(uint8_t version) { DCHECK_LT(version, 2); version_ = version; } - void set_system_id(const std::vector& system_id) { - DCHECK_EQ(16u, system_id.size()); - system_id_ = system_id; + void set_system_id(const uint8_t* system_id, size_t system_id_size) { + DCHECK_EQ(16u, system_id_size); + system_id_.assign(system_id, system_id + system_id_size); } void add_key_id(const std::vector& key_id) { DCHECK_EQ(16u, key_id.size()); diff --git a/packager/media/base/protection_system_specific_info_unittest.cc b/packager/media/base/protection_system_specific_info_unittest.cc index 6ce3154945..a47811acfb 100644 --- a/packager/media/base/protection_system_specific_info_unittest.cc +++ b/packager/media/base/protection_system_specific_info_unittest.cc @@ -72,7 +72,7 @@ TEST_F(PsshTest, ParseBoxes_SupportsV0) { ASSERT_EQ(0u, info[0].key_ids().size()); EXPECT_EQ(test_system_id_, info[0].system_id()); EXPECT_EQ(test_pssh_data_, info[0].pssh_data()); - EXPECT_EQ(0, info[0].version()); + EXPECT_EQ(0, info[0].pssh_box_version()); } TEST_F(PsshTest, ParseBoxes_SupportsV1) { @@ -85,7 +85,7 @@ TEST_F(PsshTest, ParseBoxes_SupportsV1) { EXPECT_EQ(test_system_id_, info[0].system_id()); EXPECT_EQ(test_key_id_, info[0].key_ids()[0]); EXPECT_EQ(test_pssh_data_, info[0].pssh_data()); - EXPECT_EQ(1, info[0].version()); + EXPECT_EQ(1, info[0].pssh_box_version()); } TEST_F(PsshTest, ParseBoxes_SupportsConcatenatedBoxes) { @@ -103,25 +103,25 @@ TEST_F(PsshTest, ParseBoxes_SupportsConcatenatedBoxes) { EXPECT_EQ(test_system_id_, info[0].system_id()); EXPECT_EQ(test_key_id_, info[0].key_ids()[0]); EXPECT_EQ(test_pssh_data_, info[0].pssh_data()); - EXPECT_EQ(1, info[0].version()); + EXPECT_EQ(1, info[0].pssh_box_version()); ASSERT_EQ(0u, info[1].key_ids().size()); EXPECT_EQ(test_system_id_, info[1].system_id()); EXPECT_EQ(test_pssh_data_, info[1].pssh_data()); - EXPECT_EQ(0, info[1].version()); + EXPECT_EQ(0, info[1].pssh_box_version()); ASSERT_EQ(1u, info[2].key_ids().size()); EXPECT_EQ(test_system_id_, info[2].system_id()); EXPECT_EQ(test_key_id_, info[2].key_ids()[0]); EXPECT_EQ(test_pssh_data_, info[2].pssh_data()); - EXPECT_EQ(1, info[2].version()); + EXPECT_EQ(1, info[2].pssh_box_version()); } TEST_F(PsshTest, CreateBox_MakesV0Boxes) { ProtectionSystemSpecificInfo info; - info.set_system_id(test_system_id_); + info.set_system_id(kTestSystemIdArray, arraysize(kTestSystemIdArray)); info.set_pssh_data(test_pssh_data_); - info.set_version(0); + info.set_pssh_box_version(0); EXPECT_EQ(v0_box_, info.CreateBox()); } @@ -129,9 +129,9 @@ TEST_F(PsshTest, CreateBox_MakesV0Boxes) { TEST_F(PsshTest, CreateBox_MakesV1Boxes) { ProtectionSystemSpecificInfo info; info.add_key_id(test_key_id_); - info.set_system_id(test_system_id_); + info.set_system_id(kTestSystemIdArray, arraysize(kTestSystemIdArray)); info.set_pssh_data(test_pssh_data_); - info.set_version(1); + info.set_pssh_box_version(1); EXPECT_EQ(v1_box_, info.CreateBox()); } diff --git a/packager/media/base/widevine_key_source.cc b/packager/media/base/widevine_key_source.cc index d84f8d7617..ae5b75a09e 100644 --- a/packager/media/base/widevine_key_source.cc +++ b/packager/media/base/widevine_key_source.cc @@ -279,10 +279,6 @@ Status WidevineKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index, return GetKeyInternal(crypto_period_index, track_type, key); } -std::string WidevineKeySource::UUID() { - return "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"; -} - void WidevineKeySource::set_signer(scoped_ptr signer) { signer_ = signer.Pass(); } @@ -557,14 +553,23 @@ bool WidevineKeySource::ExtractEncryptionKey( if (!GetKeyIdFromTrack(*track_dict, &encryption_key->key_id)) return false; + ProtectionSystemSpecificInfo info; + info.add_key_id(encryption_key->key_id); + info.set_system_id(kWidevineSystemId, arraysize(kWidevineSystemId)); + info.set_pssh_box_version(0); + std::vector pssh_data; if (!GetPsshDataFromTrack(*track_dict, &pssh_data)) return false; - encryption_key->pssh = PsshBoxFromPsshData(pssh_data); + info.set_pssh_data(pssh_data); + + encryption_key->key_system_info.push_back(info); } encryption_key_map[track_type] = encryption_key.release(); } + // NOTE: To support version 1 pssh, update ProtectionSystemSpecificInfo to + // include all key IDs in |encryption_key_map|. DCHECK(!encryption_key_map.empty()); if (!enable_key_rotation) { encryption_key_map_ = encryption_key_map; diff --git a/packager/media/base/widevine_key_source.h b/packager/media/base/widevine_key_source.h index 3afdc75914..8e8b4c4d30 100644 --- a/packager/media/base/widevine_key_source.h +++ b/packager/media/base/widevine_key_source.h @@ -44,7 +44,6 @@ class WidevineKeySource : public KeySource { Status GetCryptoPeriodKey(uint32_t crypto_period_index, TrackType track_type, EncryptionKey* key) override; - std::string UUID() override; /// @} /// Set signer for the key source. diff --git a/packager/media/base/widevine_key_source_unittest.cc b/packager/media/base/widevine_key_source_unittest.cc index e402813bf0..b6d0c4a9d3 100644 --- a/packager/media/base/widevine_key_source_unittest.cc +++ b/packager/media/base/widevine_key_source_unittest.cc @@ -81,7 +81,10 @@ std::string ToString(const std::vector v) { } std::string GetMockKeyId(const std::string& track_type) { - return "MockKeyId" + track_type; + // Key ID must be 16 characters. + std::string key_id = "MockKeyId" + track_type; + key_id.resize(16, '~'); + return key_id; } std::string GetMockKey(const std::string& track_type) { @@ -122,12 +125,6 @@ std::string GenerateMockClassicLicenseResponse() { return base::StringPrintf(kLicenseResponseFormat, "OK", tracks.c_str()); } -std::string GetPsshDataFromPsshBox(const std::string& pssh_box) { - const size_t kPsshDataOffset = 32u; - DCHECK_LT(kPsshDataOffset, pssh_box.size()); - return pssh_box.substr(kPsshDataOffset); -} - } // namespace namespace media { @@ -186,10 +183,11 @@ class WidevineKeySourceTest : public ::testing::Test { &encryption_key)); EXPECT_EQ(GetMockKey(kTrackTypes[i]), ToString(encryption_key.key)); if (!classic) { + ASSERT_EQ(1u, encryption_key.key_system_info.size()); EXPECT_EQ(GetMockKeyId(kTrackTypes[i]), ToString(encryption_key.key_id)); EXPECT_EQ(GetMockPsshData(kTrackTypes[i]), - GetPsshDataFromPsshBox(ToString(encryption_key.pssh))); + ToString(encryption_key.key_system_info[0].pssh_data())); } } } @@ -395,7 +393,7 @@ const char kCryptoPeriodRequestMessageFormat[] = "\"tracks\":[{\"type\":\"SD\"},{\"type\":\"HD\"},{\"type\":\"AUDIO\"}]}"; const char kCryptoPeriodTrackFormat[] = - "{\"type\":\"%s\",\"key_id\":\"\",\"key\":" + "{\"type\":\"%s\",\"key_id\":\"%s\",\"key\":" "\"%s\",\"pssh\":[{\"drm_type\":\"WIDEVINE\",\"data\":\"\"}], " "\"crypto_period_index\":%u}"; @@ -417,6 +415,7 @@ std::string GenerateMockKeyRotationLicenseResponse( tracks += base::StringPrintf( kCryptoPeriodTrackFormat, kTrackTypes[i].c_str(), + Base64Encode(GetMockKeyId(kTrackTypes[i])).c_str(), Base64Encode(GetMockKey(kTrackTypes[i], index)).c_str(), index); } diff --git a/packager/media/event/mpd_notify_muxer_listener.cc b/packager/media/event/mpd_notify_muxer_listener.cc index af96d6956c..705f2e2dd4 100644 --- a/packager/media/event/mpd_notify_muxer_listener.cc +++ b/packager/media/event/mpd_notify_muxer_listener.cc @@ -11,6 +11,7 @@ #include "packager/base/logging.h" #include "packager/media/base/audio_stream_info.h" #include "packager/media/base/video_stream_info.h" +#include "packager/media/base/protection_system_specific_info.h" #include "packager/media/event/muxer_listener_internal.h" #include "packager/mpd/base/media_info.pb.h" #include "packager/mpd/base/mpd_notifier.h" @@ -27,31 +28,26 @@ MpdNotifyMuxerListener::MpdNotifyMuxerListener(MpdNotifier* mpd_notifier) MpdNotifyMuxerListener::~MpdNotifyMuxerListener() {} -void MpdNotifyMuxerListener::SetContentProtectionSchemeIdUri( - const std::string& scheme_id_uri) { - scheme_id_uri_ = scheme_id_uri; -} - void MpdNotifyMuxerListener::OnEncryptionInfoReady( bool is_initial_encryption_info, - const std::string& content_protection_uuid, - const std::string& content_protection_name_version, const std::vector& key_id, - const std::vector& pssh) { + const std::vector& key_system_info) { if (is_initial_encryption_info) { LOG_IF(WARNING, is_encrypted_) << "Updating initial encryption information."; - content_protection_uuid_ = content_protection_uuid; - content_protection_name_version_ = content_protection_name_version; default_key_id_.assign(key_id.begin(), key_id.end()); - pssh_.assign(pssh.begin(), pssh.end()); + key_system_info_ = key_system_info; is_encrypted_ = true; return; } - bool updated = mpd_notifier_->NotifyEncryptionUpdate( - notification_id_, content_protection_uuid, key_id, pssh); - LOG_IF(WARNING, !updated) << "Failed to update encryption info."; + for (const ProtectionSystemSpecificInfo& info : key_system_info) { + std::string drm_uuid = internal::CreateUUIDString(info.system_id()); + std::vector new_pssh = info.CreateBox(); + bool updated = mpd_notifier_->NotifyEncryptionUpdate( + notification_id_, drm_uuid, key_id, new_pssh); + LOG_IF(WARNING, !updated) << "Failed to update encryption info."; + } } void MpdNotifyMuxerListener::OnMediaStart( @@ -70,9 +66,8 @@ void MpdNotifyMuxerListener::OnMediaStart( } if (is_encrypted_) { - internal::SetContentProtectionFields( - content_protection_uuid_, content_protection_name_version_, - default_key_id_, pssh_, media_info.get()); + internal::SetContentProtectionFields(default_key_id_, key_system_info_, + media_info.get()); } if (mpd_notifier_->dash_profile() == kLiveProfile) { diff --git a/packager/media/event/mpd_notify_muxer_listener.h b/packager/media/event/mpd_notify_muxer_listener.h index 14b8cb4b1f..8e84cf372a 100644 --- a/packager/media/event/mpd_notify_muxer_listener.h +++ b/packager/media/event/mpd_notify_muxer_listener.h @@ -31,17 +31,12 @@ class MpdNotifyMuxerListener : public MuxerListener { explicit MpdNotifyMuxerListener(MpdNotifier* mpd_notifier); ~MpdNotifyMuxerListener() override; - /// If the stream is encrypted use this as 'schemeIdUri' attribute for - /// ContentProtection element. - void SetContentProtectionSchemeIdUri(const std::string& scheme_id_uri); - /// @name MuxerListener implementation overrides. /// @{ void OnEncryptionInfoReady(bool is_initial_encryption_info, - const std::string& content_protection_uuid, - const std::string& content_protection_name_version, const std::vector& key_id, - const std::vector& pssh) override; + const std::vector& + key_system_info) override; void OnMediaStart(const MuxerOptions& muxer_options, const StreamInfo& stream_info, uint32_t time_scale, @@ -71,14 +66,11 @@ class MpdNotifyMuxerListener : public MuxerListener { MpdNotifier* const mpd_notifier_; uint32_t notification_id_; scoped_ptr media_info_; - std::string scheme_id_uri_; bool is_encrypted_; // Storage for values passed to OnEncryptionInfoReady(). - std::string content_protection_uuid_; - std::string content_protection_name_version_; std::string default_key_id_; - std::string pssh_; + std::vector key_system_info_; // Saves all the subsegment information for VOD. This should be used to call // MpdNotifier::NotifyNewSegment() after NotifyNewSegment() is called diff --git a/packager/media/event/mpd_notify_muxer_listener_unittest.cc b/packager/media/event/mpd_notify_muxer_listener_unittest.cc index db5caef88b..f3a46c8e60 100644 --- a/packager/media/event/mpd_notify_muxer_listener_unittest.cc +++ b/packager/media/event/mpd_notify_muxer_listener_unittest.cc @@ -29,10 +29,7 @@ namespace { // Can be any string, we just want to check that it is preserved in the // protobuf. -const char kTestUUID[] = "somebogusuuid"; -const char kDrmName[] = "drmname"; const char kDefaultKeyId[] = "defaultkeyid"; -const char kPssh[] = "pssh"; const bool kInitialEncryptionInfo = true; const bool kNonInitialEncryptionInfo = false; @@ -152,22 +149,20 @@ TEST_F(MpdNotifyMuxerListenerTest, VodEncryptedContent) { const std::vector default_key_id( kDefaultKeyId, kDefaultKeyId + arraysize(kDefaultKeyId) - 1); - const std::vector pssh(kPssh, kPssh + arraysize(kPssh) - 1); const std::string kExpectedMediaInfo = std::string(kExpectedDefaultMediaInfo) + "protected_content {\n" " content_protection_entry {\n" - " uuid: 'somebogusuuid'\n" - " name_version: 'drmname'\n" - " pssh: 'pssh'\n" + " uuid: 'edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'\n" + " pssh: '" + std::string(kExpectedDefaultPsshBox) + "'\n" " }\n" " default_key_id: 'defaultkeyid'\n" "}\n"; EXPECT_CALL(*notifier_, NotifyNewContainer(_, _)).Times(0); - listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, kTestUUID, kDrmName, - default_key_id, pssh); + listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, + default_key_id, GetDefaultKeySystemInfo()); listener_->OnMediaStart(muxer_options, *video_stream_info, kDefaultReferenceTimeScale, @@ -275,7 +270,7 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) { scoped_refptr video_stream_info = CreateVideoStreamInfo(video_params); - const char kExpectedMediaInfo[] = + const std::string kExpectedMediaInfo = "video_info {\n" " codec: \"avc1.010101\"\n" " width: 720\n" @@ -291,9 +286,8 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) { "protected_content {\n" " default_key_id: \"defaultkeyid\"\n" " content_protection_entry {\n" - " uuid: \"somebogusuuid\"\n" - " name_version: \"drmname\"\n" - " pssh: \"pssh\"\n" + " uuid: 'edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'\n" + " pssh: \"" + std::string(kExpectedDefaultPsshBox) + "\"\n" " }\n" "}\n"; @@ -305,7 +299,6 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) { const uint64_t kSegmentFileSize2 = 83743u; const std::vector default_key_id( kDefaultKeyId, kDefaultKeyId + arraysize(kDefaultKeyId) - 1); - const std::vector pssh(kPssh, kPssh + arraysize(kPssh) - 1); InSequence s; EXPECT_CALL(*notifier_, NotifyEncryptionUpdate(_, _, _, _)).Times(0); @@ -319,8 +312,8 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) { NotifyNewSegment(_, kStartTime2, kDuration2, kSegmentFileSize2)); EXPECT_CALL(*notifier_, Flush()); - listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, kTestUUID, kDrmName, - default_key_id, pssh); + listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, + default_key_id, GetDefaultKeySystemInfo()); listener_->OnMediaStart(muxer_options, *video_stream_info, kDefaultReferenceTimeScale, MuxerListener::kContainerMp4); @@ -368,7 +361,6 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) { const uint64_t kSegmentFileSize2 = 83743u; const std::vector default_key_id( kDefaultKeyId, kDefaultKeyId + arraysize(kDefaultKeyId) - 1); - const std::vector pssh(kPssh, kPssh + arraysize(kPssh) - 1); InSequence s; EXPECT_CALL(*notifier_, @@ -382,13 +374,14 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) { NotifyNewSegment(_, kStartTime2, kDuration2, kSegmentFileSize2)); EXPECT_CALL(*notifier_, Flush()); - listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, "", "", - default_key_id, std::vector()); + listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, default_key_id, + std::vector()); listener_->OnMediaStart(muxer_options, *video_stream_info, kDefaultReferenceTimeScale, MuxerListener::kContainerMp4); - listener_->OnEncryptionInfoReady(kNonInitialEncryptionInfo, kTestUUID, - kDrmName, std::vector(), pssh); + listener_->OnEncryptionInfoReady(kNonInitialEncryptionInfo, + std::vector(), + GetDefaultKeySystemInfo()); listener_->OnNewSegment(kStartTime1, kDuration1, kSegmentFileSize1); listener_->OnNewSegment(kStartTime2, kDuration2, kSegmentFileSize2); ::testing::Mock::VerifyAndClearExpectations(notifier_.get()); diff --git a/packager/media/event/muxer_listener.h b/packager/media/event/muxer_listener.h index 2003a106eb..abbae36004 100644 --- a/packager/media/event/muxer_listener.h +++ b/packager/media/event/muxer_listener.h @@ -19,8 +19,9 @@ namespace edash_packager { namespace media { -class StreamInfo; struct MuxerOptions; +class ProtectionSystemSpecificInfo; +class StreamInfo; /// MuxerListener is an event handler that can be registered to a muxer. /// A MuxerListener cannot be shared amongst muxer instances, in other words, @@ -40,14 +41,10 @@ class MuxerListener { // Called when the media's encryption information is ready. This should be // called before OnMediaStart(), if the media is encrypted. // All the parameters may be empty just to notify that the media is encrypted. - // |content_protection_uuid| is one of the UUIDs listed here - // http://dashif.org/identifiers/protection/. This should be in human - // readable form. // |is_initial_encryption_info| is true if this is the first encryption info // for the media. // In general, this flag should always be true for non-key-rotated media and // should be called only once. - // |content_protection_name_version| is the DRM system and version name. // |key_id| is the key ID for the media. // The format should be a vector of uint8_t, i.e. not (necessarily) human // readable hex string. @@ -56,13 +53,10 @@ class MuxerListener { // 'tenc' box. // If |is_initial_encryption_info| is false then |key_id| is the new key ID // for the for the next crypto period. - // |pssh| is the whole 'pssh' box. virtual void OnEncryptionInfoReady( bool is_initial_encryption_info, - const std::string& content_protection_uuid, - const std::string& content_protection_name_version, const std::vector& key_id, - const std::vector& pssh) = 0; + const std::vector& key_system_info) = 0; // Called when muxing starts. // For MPEG DASH Live profile, the initialization segment information is diff --git a/packager/media/event/muxer_listener_internal.cc b/packager/media/event/muxer_listener_internal.cc index 01f5e4cd1f..fd3f531e16 100644 --- a/packager/media/event/muxer_listener_internal.cc +++ b/packager/media/event/muxer_listener_internal.cc @@ -9,8 +9,11 @@ #include #include "packager/base/logging.h" +#include "packager/base/strings/string_number_conversions.h" +#include "packager/base/strings/string_util.h" #include "packager/media/base/audio_stream_info.h" #include "packager/media/base/muxer_options.h" +#include "packager/media/base/protection_system_specific_info.h" #include "packager/media/base/video_stream_info.h" #include "packager/media/filters/ec3_audio_util.h" #include "packager/mpd/base/media_info.pb.h" @@ -213,10 +216,8 @@ bool SetVodInformation(bool has_init_range, } void SetContentProtectionFields( - const std::string& content_protection_uuid, - const std::string& content_protection_name_version, const std::string& default_key_id, - const std::string& pssh, + const std::vector& key_system_info, MediaInfo* media_info) { DCHECK(media_info); MediaInfo::ProtectedContent* protected_content = @@ -225,21 +226,26 @@ void SetContentProtectionFields( if (!default_key_id.empty()) protected_content->set_default_key_id(default_key_id); - if (content_protection_uuid.empty() && - content_protection_name_version.empty() && pssh.empty()) { - return; + for (const ProtectionSystemSpecificInfo& info : key_system_info) { + MediaInfo::ProtectedContent::ContentProtectionEntry* entry = + protected_content->add_content_protection_entry(); + if (!info.system_id().empty()) + entry->set_uuid(CreateUUIDString(info.system_id())); + + const std::vector pssh = info.CreateBox(); + entry->set_pssh(pssh.data(), pssh.size()); } +} - MediaInfo::ProtectedContent::ContentProtectionEntry* entry = - protected_content->add_content_protection_entry(); - if (!content_protection_uuid.empty()) - entry->set_uuid(content_protection_uuid); - - if (!content_protection_name_version.empty()) - entry->set_name_version(content_protection_name_version); - - if (!pssh.empty()) - entry->set_pssh(pssh); +std::string CreateUUIDString(const std::vector& data) { + DCHECK_EQ(16u, data.size()); + std::string uuid = base::HexEncode(data.data(), data.size()); + base::StringToLowerASCII(&uuid); + uuid.insert(20, "-"); + uuid.insert(16, "-"); + uuid.insert(12, "-"); + uuid.insert(8, "-"); + return uuid; } } // namespace internal diff --git a/packager/media/event/muxer_listener_internal.h b/packager/media/event/muxer_listener_internal.h index ba4a57b94c..5e16c688a7 100644 --- a/packager/media/event/muxer_listener_internal.h +++ b/packager/media/event/muxer_listener_internal.h @@ -45,22 +45,20 @@ bool SetVodInformation(bool has_init_range, uint64_t file_size, MediaInfo* media_info); -/// @param content_protection_uuid is the UUID of the content protection -/// in human readable form. -/// @param content_protection_name_version is the DRM name and verion. /// @param default_key_id is the key ID for this media in hex (i.e. non-human /// readable, typically 16 bytes.) -/// @param pssh is the pssh for the media in hex (i.e. non-human readable, raw -/// 'pssh' box.) +/// @param key_system_info the key-system specific info for the media. /// @param media_info is where the content protection information is stored and /// cannot be null. void SetContentProtectionFields( - const std::string& content_protection_uuid, - const std::string& content_protection_name_version, const std::string& default_key_id, - const std::string& pssh, + const std::vector& key_system_info, MediaInfo* media_info); +/// Creates a UUID string from the given binary data. The data must be 16 bytes +/// long. Outputs: "00000000-0000-0000-0000-000000000000" +std::string CreateUUIDString(const std::vector& data); + } // namespace internal } // namespace media } // namespace edash_packager diff --git a/packager/media/event/muxer_listener_test_helper.cc b/packager/media/event/muxer_listener_test_helper.cc index 8a7feaf122..c03075cdf4 100644 --- a/packager/media/event/muxer_listener_test_helper.cc +++ b/packager/media/event/muxer_listener_test_helper.cc @@ -94,6 +94,20 @@ void SetDefaultMuxerOptionsValues(MuxerOptions* muxer_options) { muxer_options->temp_dir.clear(); } +std::vector GetDefaultKeySystemInfo() { + const uint8_t kPsshData[] = {'p', 's', 's', 'h'}; + + ProtectionSystemSpecificInfo info; + info.set_system_id(kWidevineSystemId, arraysize(kWidevineSystemId)); + info.set_pssh_data( + std::vector(kPsshData, kPsshData + arraysize(kPsshData))); + info.set_pssh_box_version(0); + + std::vector key_system_info; + key_system_info.push_back(info); + return key_system_info; +} + void ExpectMediaInfoEqual(const MediaInfo& expect, const MediaInfo& actual) { ASSERT_TRUE(MediaInfoEqual(expect, actual)); } diff --git a/packager/media/event/muxer_listener_test_helper.h b/packager/media/event/muxer_listener_test_helper.h index 1ebc53529a..c2b4cbbf41 100644 --- a/packager/media/event/muxer_listener_test_helper.h +++ b/packager/media/event/muxer_listener_test_helper.h @@ -11,6 +11,7 @@ #include #include "packager/base/memory/ref_counted.h" +#include "packager/media/base/key_source.h" #include "packager/media/base/muxer_options.h" #include "packager/media/base/stream_info.h" #include "packager/media/base/video_stream_info.h" @@ -20,6 +21,12 @@ namespace edash_packager { namespace media { +// A string containing the escaped PSSH box (for use with a MediaInfo proto). +// This is a full v0 PSSH box with the Widevine system ID and the PSSH data +// 'pssh' +const char kExpectedDefaultPsshBox[] = + "\\000\\000\\000$pssh\\000\\000\\000\\000\\355\\357\\213\\251y\\326J\\316" + "\\243\\310\\'\\334\\325\\035!\\355\\000\\000\\000\\4pssh"; const char kExpectedDefaultMediaInfo[] = "bandwidth: 7620\n" "video_info {\n" @@ -87,6 +94,9 @@ VideoStreamInfoParameters GetDefaultVideoStreamInfoParams(); // Returns the "default" values for OnMediaEnd(). OnMediaEndParameters GetDefaultOnMediaEndParams(); +// Returns the "default" ProtectionSystemSpecificInfo for testing. +std::vector GetDefaultKeySystemInfo(); + // Sets "default" values for muxer_options for testing. void SetDefaultMuxerOptionsValues(MuxerOptions* muxer_options); diff --git a/packager/media/event/vod_media_info_dump_muxer_listener.cc b/packager/media/event/vod_media_info_dump_muxer_listener.cc index f16f829fd6..286f26f537 100644 --- a/packager/media/event/vod_media_info_dump_muxer_listener.cc +++ b/packager/media/event/vod_media_info_dump_muxer_listener.cc @@ -11,6 +11,7 @@ #include "packager/base/logging.h" #include "packager/media/base/muxer_options.h" #include "packager/media/base/stream_info.h" +#include "packager/media/base/protection_system_specific_info.h" #include "packager/media/event/muxer_listener_internal.h" #include "packager/media/file/file.h" #include "packager/mpd/base/media_info.pb.h" @@ -24,24 +25,15 @@ VodMediaInfoDumpMuxerListener::VodMediaInfoDumpMuxerListener( VodMediaInfoDumpMuxerListener::~VodMediaInfoDumpMuxerListener() {} -void VodMediaInfoDumpMuxerListener::SetContentProtectionSchemeIdUri( - const std::string& scheme_id_uri) { - scheme_id_uri_ = scheme_id_uri; -} - void VodMediaInfoDumpMuxerListener::OnEncryptionInfoReady( bool is_initial_encryption_info, - const std::string& content_protection_uuid, - const std::string& content_protection_name_version, const std::vector& default_key_id, - const std::vector& pssh) { + const std::vector& key_system_info) { LOG_IF(WARNING, !is_initial_encryption_info) << "Updating (non initial) encryption info is not supported by " "this module."; - content_protection_uuid_ = content_protection_uuid; - content_protection_name_version_ = content_protection_name_version; default_key_id_.assign(default_key_id.begin(), default_key_id.end()); - pssh_.assign(pssh.begin(), pssh.end()); + key_system_info_ = key_system_info; is_encrypted_ = true; } @@ -63,8 +55,7 @@ void VodMediaInfoDumpMuxerListener::OnMediaStart( if (is_encrypted_) { internal::SetContentProtectionFields( - content_protection_uuid_, content_protection_name_version_, - default_key_id_, pssh_, media_info_.get()); + default_key_id_, key_system_info_, media_info_.get()); } } diff --git a/packager/media/event/vod_media_info_dump_muxer_listener.h b/packager/media/event/vod_media_info_dump_muxer_listener.h index 79a272b37c..8c1c7b043f 100644 --- a/packager/media/event/vod_media_info_dump_muxer_listener.h +++ b/packager/media/event/vod_media_info_dump_muxer_listener.h @@ -30,17 +30,12 @@ class VodMediaInfoDumpMuxerListener : public MuxerListener { VodMediaInfoDumpMuxerListener(const std::string& output_file_name); ~VodMediaInfoDumpMuxerListener() override; - /// If the stream is encrypted use this as 'schemeIdUri' attribute for - /// ContentProtection element. - void SetContentProtectionSchemeIdUri(const std::string& scheme_id_uri); - /// @name MuxerListener implementation overrides. /// @{ void OnEncryptionInfoReady(bool is_initial_encryption_info, - const std::string& content_protection_uuid, - const std::string& content_protection_name_version, const std::vector& default_key_id, - const std::vector& pssh) override; + const std::vector& + key_system_info) override; void OnMediaStart(const MuxerOptions& muxer_options, const StreamInfo& stream_info, uint32_t time_scale, @@ -71,15 +66,12 @@ class VodMediaInfoDumpMuxerListener : public MuxerListener { private: std::string output_file_name_; - std::string scheme_id_uri_; scoped_ptr media_info_; bool is_encrypted_; // Storage for values passed to OnEncryptionInfoReady(). - std::string content_protection_uuid_; - std::string content_protection_name_version_; std::string default_key_id_; - std::string pssh_; + std::vector key_system_info_; DISALLOW_COPY_AND_ASSIGN(VodMediaInfoDumpMuxerListener); }; diff --git a/packager/media/event/vod_media_info_dump_muxer_listener_unittest.cc b/packager/media/event/vod_media_info_dump_muxer_listener_unittest.cc index 0a2e8b2311..950fec1f6b 100644 --- a/packager/media/event/vod_media_info_dump_muxer_listener_unittest.cc +++ b/packager/media/event/vod_media_info_dump_muxer_listener_unittest.cc @@ -24,15 +24,7 @@ const bool kEnableEncryption = true; const uint8_t kBogusDefaultKeyId[] = {0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x5f}; -// 'pssh'. Not a valid pssh box. -const uint8_t kInvalidPssh[] = { - 0x70, 0x73, 0x73, 0x68 -}; -// This should be in the uuid field of the protobuf. This is not a valid UUID -// format but the protobof generation shouldn't care. -const char kTestUUID[] = "myuuid"; -const char kTestContentProtectionName[] = "MyContentProtection version 1"; const bool kInitialEncryptionInfo = true; } // namespace @@ -85,14 +77,9 @@ class VodMediaInfoDumpMuxerListenerTest : public ::testing::Test { kBogusDefaultKeyId, kBogusDefaultKeyId + arraysize(kBogusDefaultKeyId)); - // This isn't a valid pssh box but the MediaInfo protobuf creator - // shouldn't worry about it. - std::vector invalid_pssh(kInvalidPssh, - kInvalidPssh + arraysize(kInvalidPssh)); - - listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, kTestUUID, - kTestContentProtectionName, - bogus_default_key_id, invalid_pssh); + listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, + bogus_default_key_id, + GetDefaultKeySystemInfo()); } listener_->OnMediaStart(muxer_options, stream_info, kReferenceTimeScale, MuxerListener::kContainerMp4); @@ -162,15 +149,13 @@ TEST_F(VodMediaInfoDumpMuxerListenerTest, UnencryptedStream_Normal) { } TEST_F(VodMediaInfoDumpMuxerListenerTest, EncryptedStream_Normal) { - listener_->SetContentProtectionSchemeIdUri("http://foo.com/bar"); - scoped_refptr stream_info = CreateVideoStreamInfo(GetDefaultVideoStreamInfoParams()); FireOnMediaStartWithDefaultMuxerOptions(*stream_info, kEnableEncryption); OnMediaEndParameters media_end_param = GetDefaultOnMediaEndParams(); FireOnMediaEndWithParams(media_end_param); - const char kExpectedProtobufOutput[] = + const std::string kExpectedProtobufOutput = "bandwidth: 7620\n" "video_info {\n" " codec: 'avc1.010101'\n" @@ -194,9 +179,8 @@ TEST_F(VodMediaInfoDumpMuxerListenerTest, EncryptedStream_Normal) { "media_duration_seconds: 10.5\n" "protected_content {\n" " content_protection_entry {\n" - " uuid: 'myuuid'\n" - " name_version: 'MyContentProtection version 1'\n" - " pssh: 'pssh'\n" + " uuid: 'edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'\n" + " pssh: '" + std::string(kExpectedDefaultPsshBox) + "'\n" " }\n" " default_key_id: '_default_key_id_'\n" "}\n"; diff --git a/packager/media/formats/mp4/key_rotation_fragmenter.cc b/packager/media/formats/mp4/key_rotation_fragmenter.cc index 9922b97f60..0d25b38226 100644 --- a/packager/media/formats/mp4/key_rotation_fragmenter.cc +++ b/packager/media/formats/mp4/key_rotation_fragmenter.cc @@ -14,7 +14,7 @@ namespace media { namespace mp4 { namespace { -const bool kInitialEncryptionInfo = false; +const bool kInitialEncryptionInfo = true; } // namespace KeyRotationFragmenter::KeyRotationFragmenter(MovieFragment* moof, @@ -58,17 +58,18 @@ Status KeyRotationFragmenter::PrepareFragmentForEncryption( need_to_refresh_encryptor = true; } - // One and only one 'pssh' box is needed. - if (moof_->pssh.empty()) - moof_->pssh.resize(1); DCHECK(encryption_key()); - moof_->pssh[0].raw_box = encryption_key()->pssh; + const std::vector& system_info = + encryption_key()->key_system_info; + moof_->pssh.resize(system_info.size()); + for (size_t i = 0; i < system_info.size(); i++) { + moof_->pssh[i].raw_box = system_info[i].CreateBox(); + } if (muxer_listener_) { - muxer_listener_->OnEncryptionInfoReady( - !kInitialEncryptionInfo, - encryption_key_source_->UUID(), encryption_key_source_->SystemName(), - encryption_key()->key_id, encryption_key()->pssh); + muxer_listener_->OnEncryptionInfoReady(!kInitialEncryptionInfo, + encryption_key()->key_id, + encryption_key()->key_system_info); } // Skip the following steps if the current fragment is not going to be diff --git a/packager/media/formats/mp4/segmenter.cc b/packager/media/formats/mp4/segmenter.cc index 6d23e48172..ef6a320001 100644 --- a/packager/media/formats/mp4/segmenter.cc +++ b/packager/media/formats/mp4/segmenter.cc @@ -165,11 +165,11 @@ Status Segmenter::Initialize(const std::vector& streams, kKeyRotationDefaultKeyId + arraysize(kKeyRotationDefaultKeyId)); GenerateEncryptedSampleEntry(encryption_key, clear_lead_in_seconds, &description); + if (muxer_listener_) { muxer_listener_->OnEncryptionInfoReady( - kInitialEncryptionInfo, encryption_key_source->UUID(), - encryption_key_source->SystemName(), encryption_key.key_id, - std::vector()); + kInitialEncryptionInfo, encryption_key.key_id, + encryption_key.key_system_info); } fragmenters_[i] = new KeyRotationFragmenter( @@ -190,17 +190,16 @@ Status Segmenter::Initialize(const std::vector& streams, GenerateEncryptedSampleEntry(*encryption_key, clear_lead_in_seconds, &description); - // One and only one pssh box is needed. if (moov_->pssh.empty()) { - moov_->pssh.resize(1); - moov_->pssh[0].raw_box = encryption_key->pssh; + moov_->pssh.resize(encryption_key->key_system_info.size()); + for (size_t i = 0; i < encryption_key->key_system_info.size(); i++) { + moov_->pssh[i].raw_box = encryption_key->key_system_info[i].CreateBox(); + } - // Also only one default key id. if (muxer_listener_) { - muxer_listener_->OnEncryptionInfoReady( - kInitialEncryptionInfo, - encryption_key_source->UUID(), encryption_key_source->SystemName(), - encryption_key->key_id, encryption_key->pssh); + muxer_listener_->OnEncryptionInfoReady(kInitialEncryptionInfo, + encryption_key->key_id, + encryption_key->key_system_info); } } diff --git a/packager/media/formats/webm/encrypted_segmenter_unittest.cc b/packager/media/formats/webm/encrypted_segmenter_unittest.cc index 558cee07e3..df79d9719a 100644 --- a/packager/media/formats/webm/encrypted_segmenter_unittest.cc +++ b/packager/media/formats/webm/encrypted_segmenter_unittest.cc @@ -15,7 +15,7 @@ namespace media { namespace { const uint64_t kDuration = 1000; -const std::string kKeyId = "68656c6c6f20776f726c64"; +const std::string kKeyId = "4c6f72656d20697073756d20646f6c6f"; const std::string kIv = "0123456789012345"; const std::string kKey = "01234567890123456789012345678901"; const std::string kPsshData = ""; @@ -37,8 +37,8 @@ const uint8_t kBasicSupportData[] = { 0x42, 0x87, 0x81, 0x02, // DocTypeReadVersion: 2 0x42, 0x85, 0x81, 0x02, - // ID: Segment, Payload Size: 406 - 0x18, 0x53, 0x80, 0x67, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x96, + // ID: Segment, Payload Size: 411 + 0x18, 0x53, 0x80, 0x67, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9b, // ID: SeekHead, Payload Size: 30 0x11, 0x4d, 0x9b, 0x74, 0x9e, // ID: Seek, Payload Size: 12 @@ -46,13 +46,13 @@ const uint8_t kBasicSupportData[] = { // SeekID: binary(4) (Cluster) 0x53, 0xab, 0x84, 0x1f, 0x43, 0xb6, 0x75, // SeekPosition: 322 - 0x53, 0xac, 0x82, 0x01, 0x42, + 0x53, 0xac, 0x82, 0x01, 0x47, // ID: Seek, Payload Size: 12 0x4d, 0xbb, 0x8c, // SeekID: binary(4) (Cues) 0x53, 0xab, 0x84, 0x1c, 0x53, 0xbb, 0x6b, // SeekPosition: 429 - 0x53, 0xac, 0x82, 0x01, 0xb3, + 0x53, 0xac, 0x82, 0x01, 0xb8, // ID: Void, Payload Size: 52 0xec, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -75,10 +75,10 @@ const uint8_t kBasicSupportData[] = { 0x65, 0x2f, 0x65, 0x64, 0x61, 0x73, 0x68, 0x2d, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x72, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x65, 0x73, 0x74, - // ID: Tracks, Payload Size: 87 - 0x16, 0x54, 0xae, 0x6b, 0xd7, - // ID: Track, Payload Size: 85 - 0xae, 0xd5, + // ID: Tracks, Payload Size: 92 + 0x16, 0x54, 0xae, 0x6b, 0xdc, + // ID: Track, Payload Size: 90 + 0xae, 0xda, // TrackNumber: 1 0xd7, 0x81, 0x01, // TrackUID: 1 @@ -89,24 +89,24 @@ const uint8_t kBasicSupportData[] = { 0x86, 0x85, 0x56, 0x5f, 0x56, 0x50, 0x38, // Language: 'en' 0x22, 0xb5, 0x9c, 0x82, 0x65, 0x6e, - // ID: ContentEncodings, Payload Size: 43 - 0x6d, 0x80, 0xab, - // ID: ContentEncoding, Payload Size: 40 - 0x62, 0x40, 0xa8, + // ID: ContentEncodings, Payload Size: 48 + 0x6d, 0x80, 0xb0, + // ID: ContentEncoding, Payload Size: 45 + 0x62, 0x40, 0xad, // ContentEncodingOrder: 0 0x50, 0x31, 0x81, 0x00, // ContentEncodingScope: 1 0x50, 0x32, 0x81, 0x01, // ContentEncodingType: 1 0x50, 0x33, 0x81, 0x01, - // ID: ContentEncryption, Payload Size: 25 - 0x50, 0x35, 0x99, + // ID: ContentEncryption, Payload Size: 30 + 0x50, 0x35, 0x9e, // ContentEncAlgo: 5 0x47, 0xe1, 0x81, 0x05, - // ContentEncKeyID: binary(11) - 0x47, 0xe2, 0x8b, - 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, - 0x64, + // ContentEncKeyID: binary(16) + 0x47, 0xe2, 0x90, + 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, + 0x73, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, // ID: ContentEncAESSettings, Payload Size: 4 0x47, 0xe7, 0x84, // AESSettingsCipherMode: 1 @@ -177,8 +177,8 @@ const uint8_t kBasicSupportData[] = { 0xb7, 0x87, // CueTrack: 1 0xf7, 0x81, 0x01, - // CueClusterPosition: 274 - 0xf1, 0x82, 0x01, 0x12 + // CueClusterPosition: 279 + 0xf1, 0x82, 0x01, 0x17 }; } // namespace diff --git a/packager/media/formats/webm/encryptor.cc b/packager/media/formats/webm/encryptor.cc index 1f3cff6ec6..554c1f9ff0 100644 --- a/packager/media/formats/webm/encryptor.cc +++ b/packager/media/formats/webm/encryptor.cc @@ -119,9 +119,9 @@ Status Encryptor::CreateEncryptor(MuxerListener* muxer_listener, if (muxer_listener) { const bool kInitialEncryptionInfo = true; - muxer_listener->OnEncryptionInfoReady( - kInitialEncryptionInfo, key_source->UUID(), key_source->SystemName(), - encryption_key->key_id, encryption_key->pssh); + muxer_listener->OnEncryptionInfoReady(kInitialEncryptionInfo, + encryption_key->key_id, + encryption_key->key_system_info); } key_ = encryption_key.Pass(); diff --git a/packager/mpd/base/simple_mpd_notifier_unittest.cc b/packager/mpd/base/simple_mpd_notifier_unittest.cc index e34b04c219..4ceff9fea2 100644 --- a/packager/mpd/base/simple_mpd_notifier_unittest.cc +++ b/packager/mpd/base/simple_mpd_notifier_unittest.cc @@ -268,7 +268,7 @@ TEST_P(SimpleMpdNotifierTest, UpdateEncryption) { " content_protection_entry {\n" " uuid: 'myuuid'\n" " name_version: 'MyContentProtection version 1'\n" - " pssh: 'pssh1'\n" + " pssh: 'psshsomethingelse'\n" " }\n" " default_key_id: '_default_key_id_'\n" "}\n"