Remove FairPlayPsshGenerator

This was introduced earlier to indicate FairPlay protection system. But
in fact, it is sufficient to just use the system id for the indication.

- Also updated various parts of the pipeline to support empty PSSH.
- Added an additional FairPlay end to end test using fMP4.

Change-Id: Ica48b7b5235e9a2b5a7f722bcd0fc1ef2073ac13
This commit is contained in:
KongQun Yang 2018-09-17 15:39:26 -07:00
parent f39f9de6d8
commit 08aa9b6b2b
15 changed files with 105 additions and 99 deletions

View File

@ -862,6 +862,13 @@ class PackagerFunctionalTest(PackagerAppTest):
self._GetFlags(encryption=True, output_dash=True))
self._CheckTestResults('encryption', verify_decryption=True)
def testEncryptionWithFairplay(self):
self.assertPackageSuccess(
self._GetStreams(['audio', 'video']),
self._GetFlags(
encryption=True, fairplay=True, output_dash=True, output_hls=True))
self._CheckTestResults('encryption-with-fairplay')
# Test deprecated flag --enable_fixed_key_encryption, which is still
# supported currently.
def testEncryptionUsingFixedKey(self):

View File

@ -0,0 +1,7 @@
#EXTM3U
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
#EXT-X-MEDIA:TYPE=AUDIO,URI="stream_0.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2"
#EXT-X-STREAM-INF:BANDWIDTH=1111406,AVERAGE-BANDWIDTH=1009412,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
stream_1.m3u8

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.7360665798187256S">
<Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
<ContentProtection schemeIdUri="urn:uuid:29701fe4-3cc7-4a34-8c5b-ae90c7439a47"/>
<Representation id="0" bandwidth="977743" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
<BaseURL>bear-640x360-video.mp4</BaseURL>
<SegmentBase indexRange="1075-1142" timescale="30000">
<Initialization range="0-1074"/>
</SegmentBase>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio" subsegmentAlignment="true">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
<ContentProtection schemeIdUri="urn:uuid:29701fe4-3cc7-4a34-8c5b-ae90c7439a47"/>
<Representation id="1" bandwidth="133663" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>bear-640x360-audio.mp4</BaseURL>
<SegmentBase indexRange="951-1018" timescale="44100">
<Initialization range="0-950"/>
</SegmentBase>
</Representation>
</AdaptationSet>
</Period>
</MPD>

View File

@ -0,0 +1,17 @@
#EXTM3U
#EXT-X-VERSION:6
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
#EXT-X-TARGETDURATION:2
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="bear-640x360-audio.mp4",BYTERANGE="951@0"
#EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="skd://www.license.com/getkey?KeyId=31323334-3536-3738-3930-313233343536",KEYFORMATVERSIONS="1",KEYFORMAT="com.apple.streamingkeydelivery"
#EXTINF:1.022,
#EXT-X-BYTERANGE:17028@1019
bear-640x360-audio.mp4
#EXTINF:0.998,
#EXT-X-BYTERANGE:16682
bear-640x360-audio.mp4
#EXTINF:0.720,
#EXT-X-BYTERANGE:9859
bear-640x360-audio.mp4
#EXT-X-ENDLIST

View File

@ -0,0 +1,17 @@
#EXTM3U
#EXT-X-VERSION:6
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
#EXT-X-TARGETDURATION:2
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="bear-640x360-video.mp4",BYTERANGE="1075@0"
#EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="skd://www.license.com/getkey?KeyId=31323334-3536-3738-3930-313233343536",KEYFORMATVERSIONS="1",KEYFORMAT="com.apple.streamingkeydelivery"
#EXTINF:1.001,
#EXT-X-BYTERANGE:99313@1143
bear-640x360-video.mp4
#EXTINF:1.001,
#EXT-X-BYTERANGE:122340
bear-640x360-video.mp4
#EXTINF:0.734,
#EXT-X-BYTERANGE:80067
bear-640x360-video.mp4
#EXT-X-ENDLIST

View File

@ -1,44 +0,0 @@
// Copyright 2018 Google LLC. 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 "packager/media/base/fairplay_pssh_generator.h"
#include "packager/media/base/protection_system_ids.h"
namespace shaka {
namespace media {
namespace {
const uint8_t kFairPlayPsshBoxVersion = 1;
} // namespace
FairPlayPsshGenerator::FairPlayPsshGenerator()
: PsshGenerator(std::vector<uint8_t>(std::begin(kFairPlaySystemId),
std::end(kFairPlaySystemId)),
kFairPlayPsshBoxVersion) {}
FairPlayPsshGenerator::~FairPlayPsshGenerator() = default;
bool FairPlayPsshGenerator::SupportMultipleKeys() {
return true;
}
base::Optional<std::vector<uint8_t>>
FairPlayPsshGenerator::GeneratePsshDataFromKeyIdAndKey(
const std::vector<uint8_t>& key_id,
const std::vector<uint8_t>& key) const {
NOTIMPLEMENTED();
return base::nullopt;
}
base::Optional<std::vector<uint8_t>>
FairPlayPsshGenerator::GeneratePsshDataFromKeyIds(
const std::vector<std::vector<uint8_t>>& key_ids) const {
// Intentionally empty PSSH data for FairPlay.
return std::vector<uint8_t>();
}
} // namespace media
} // namespace shaka

View File

@ -1,42 +0,0 @@
// Copyright 2018 Google LLC. 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
#ifndef PACKAGER_MEDIA_BASE_FAIRPLAY_PSSH_GENERATOR_H_
#define PACKAGER_MEDIA_BASE_FAIRPLAY_PSSH_GENERATOR_H_
#include "packager/media/base/pssh_generator.h"
namespace shaka {
namespace media {
class FairPlayPsshGenerator : public PsshGenerator {
public:
FairPlayPsshGenerator();
~FairPlayPsshGenerator() override;
/// @name PsshGenerator implemetation overrides.
/// @{
bool SupportMultipleKeys() override;
/// @}
private:
FairPlayPsshGenerator& operator=(const FairPlayPsshGenerator&) = delete;
FairPlayPsshGenerator(const FairPlayPsshGenerator&) = delete;
// PsshGenerator implemetation overrides.
base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
const std::vector<std::vector<uint8_t>>& key_ids) const override;
base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
const std::vector<uint8_t>& key_id,
const std::vector<uint8_t>& key) const override;
};
} // namespace media
} // namespace shaka
#endif // PACKAGER_MEDIA_BASE_FAIRPLAY_PSSH_GENERATOR_H_

View File

@ -8,8 +8,8 @@
#include "packager/base/logging.h"
#include "packager/media/base/common_pssh_generator.h"
#include "packager/media/base/fairplay_pssh_generator.h"
#include "packager/media/base/playready_pssh_generator.h"
#include "packager/media/base/protection_system_ids.h"
#include "packager/media/base/widevine_pssh_generator.h"
#include "packager/status_macros.h"
@ -30,7 +30,8 @@ KeySource::KeySource(int protection_systems_flags, FourCC protection_scheme) {
}
if (protection_systems_flags & FAIRPLAY_PROTECTION_SYSTEM_FLAG) {
pssh_generators_.emplace_back(new FairPlayPsshGenerator());
no_pssh_systems_.emplace_back(std::begin(kFairPlaySystemId),
std::end(kFairPlaySystemId));
}
}
@ -60,6 +61,14 @@ Status KeySource::UpdateProtectionSystemInfo(
}
}
for (const auto& no_pssh_system : no_pssh_systems_) {
ProtectionSystemSpecificInfo info;
info.system_id = no_pssh_system;
for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
pair.second->key_system_info.push_back(info);
}
}
return Status::OK;
}

View File

@ -92,6 +92,7 @@ class KeySource {
private:
std::vector<std::unique_ptr<PsshGenerator>> pssh_generators_;
std::vector<std::vector<uint8_t>> no_pssh_systems_;
DISALLOW_COPY_AND_ASSIGN(KeySource);
};

View File

@ -46,8 +46,6 @@
'decryptor_source.cc',
'decryptor_source.h',
'encryption_config.h',
'fairplay_pssh_generator.cc',
'fairplay_pssh_generator.h',
'fourccs.h',
'http_key_fetcher.cc',
'http_key_fetcher.h',

View File

@ -268,10 +268,15 @@ Status MP4Muxer::DelayInitializeMuxer() {
}
if (stream->is_encrypted() && options().mp4_params.include_pssh_in_stream) {
moov->pssh.clear();
const auto& key_system_info = stream->encryption_config().key_system_info;
moov->pssh.resize(key_system_info.size());
for (size_t j = 0; j < key_system_info.size(); j++)
moov->pssh[j].raw_box = key_system_info[j].psshs;
for (const ProtectionSystemSpecificInfo& system : key_system_info) {
if (system.psshs.empty())
continue;
ProtectionSystemSpecificHeader pssh;
pssh.raw_box = system.psshs;
moov->pssh.push_back(pssh);
}
}
}

View File

@ -278,11 +278,15 @@ void Segmenter::FinalizeFragmentForKeyRotation(
bool fragment_encrypted,
const EncryptionConfig& encryption_config) {
if (options_.mp4_params.include_pssh_in_stream) {
const std::vector<ProtectionSystemSpecificInfo>& system_info =
encryption_config.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].psshs;
moof_->pssh.clear();
const auto& key_system_info = encryption_config.key_system_info;
for (const ProtectionSystemSpecificInfo& system : key_system_info) {
if (system.psshs.empty())
continue;
ProtectionSystemSpecificHeader pssh;
pssh.raw_box = system.psshs;
moof_->pssh.push_back(pssh);
}
} else {
LOG(WARNING)
<< "Key rotation and no pssh in stream may not work well together.";

View File

@ -352,7 +352,7 @@ void AddContentProtectionElementsHelperTemplated(
if (entry.has_name_version())
drm_content_protection.value = entry.name_version();
if (entry.has_pssh()) {
if (!entry.pssh().empty()) {
std::string base64_encoded_pssh;
base::Base64Encode(
base::StringPiece(entry.pssh().data(), entry.pssh().size()),