From bfe302bd5c430bd9d51515427a3fd625c9fc21a4 Mon Sep 17 00:00:00 2001 From: sylt Date: Mon, 22 May 2017 19:17:58 +0200 Subject: [PATCH] Add support for skip_encryption stream descriptor (#219) This option makes it possible to control encryption for specific streams, e.g. for audio and video separately. --- packager/app/packager_main.cc | 6 +++-- packager/app/stream_descriptor.cc | 17 ++++++++++++ packager/app/stream_descriptor.h | 1 + packager/app/test/packager_test.py | 9 +++++++ .../bear-640x360-a-clear-v-cenc-golden.mpd | 27 +++++++++++++++++++ 5 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 packager/app/test/testdata/bear-640x360-a-clear-v-cenc-golden.mpd diff --git a/packager/app/packager_main.cc b/packager/app/packager_main.cc index 9d92983fd1..6508ec76de 100644 --- a/packager/app/packager_main.cc +++ b/packager/app/packager_main.cc @@ -107,7 +107,9 @@ const char kUsage[] = " The group ID for the output stream. For HLS this is used as the\n" " GROUP-ID attribute for EXT-X-MEDIA.\n" " - playlist_name: Required for HLS output.\n" - " Name of the playlist for the stream. Usually ends with '.m3u8'.\n"; + " Name of the playlist for the stream. Usually ends with '.m3u8'.\n" + " - skip_encryption=0|1: Optional. Defaults to 0 if not specified. If\n" + " it is set to 1, no encryption of the stream will be made.\n"; const char kMediaInfoSuffix[] = ".media_info"; @@ -378,7 +380,7 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors, handlers.push_back(chunking_handler); Status status; - if (encryption_key_source) { + if (encryption_key_source && !stream_iter->skip_encryption) { auto new_encryption_options = encryption_options; // Use Sample AES in MPEG2TS. // TODO(kqyang): Consider adding a new flag to enable Sample AES as we diff --git a/packager/app/stream_descriptor.cc b/packager/app/stream_descriptor.cc index af25a93eed..dd374c9ad3 100644 --- a/packager/app/stream_descriptor.cc +++ b/packager/app/stream_descriptor.cc @@ -31,6 +31,7 @@ enum FieldType { kHlsGroupIdField, kHlsPlaylistNameField, kTrickPlayFactorField, + kSkipEncryptionField, }; struct FieldNameToTypeMapping { @@ -60,6 +61,7 @@ const FieldNameToTypeMapping kFieldNameTypeMappings[] = { {"playlist_name", kHlsPlaylistNameField}, {"trick_play_factor", kTrickPlayFactorField}, {"tpf", kTrickPlayFactorField}, + {"skip_encryption", kSkipEncryptionField}, }; FieldType GetFieldType(const std::string& field_name) { @@ -158,6 +160,21 @@ bool InsertStreamDescriptor(const std::string& descriptor_string, descriptor.trick_play_factor = factor; break; } + case kSkipEncryptionField: { + unsigned skip_encryption_value; + if (!base::StringToUint(iter->second, &skip_encryption_value)) { + LOG(ERROR) << "Non-numeric option for skip encryption field " + "specified (" << iter->second << ")."; + return false; + } + if (skip_encryption_value > 1) { + LOG(ERROR) << "skip_encryption should be either 0 or 1."; + return false; + } + + descriptor.skip_encryption = skip_encryption_value > 0; + break; + } default: LOG(ERROR) << "Unknown field in stream descriptor (\"" << iter->first << "\")."; diff --git a/packager/app/stream_descriptor.h b/packager/app/stream_descriptor.h index 5389efbbe2..4ac538a612 100644 --- a/packager/app/stream_descriptor.h +++ b/packager/app/stream_descriptor.h @@ -34,6 +34,7 @@ struct StreamDescriptor { std::string hls_group_id; std::string hls_playlist_name; uint32_t trick_play_factor = 0; + bool skip_encryption = false; }; class StreamDescriptorCompareFn { diff --git a/packager/app/test/packager_test.py b/packager/app/test/packager_test.py index 7d12acf832..472ba9eb4a 100755 --- a/packager/app/test/packager_test.py +++ b/packager/app/test/packager_test.py @@ -240,6 +240,15 @@ class PackagerAppTest(unittest.TestCase): self._VerifyDecryption(self.output[0], 'bear-640x360-a-golden.mp4') self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4') + def testPackageWithEncryptionOfOnlyVideoStream(self): + self.packager.Package( + self._GetStreams(['audio,skip_encryption=1', 'video']), + self._GetFlags(encryption=True)) + self._DiffGold(self.output[0], 'bear-640x360-a-golden.mp4') + self._DiffGold(self.output[1], 'bear-640x360-v-cenc-golden.mp4') + self._DiffGold(self.mpd_output, 'bear-640x360-a-clear-v-cenc-golden.mpd') + self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4') + def testPackageWithEncryptionAndTrickPlay(self): self.packager.Package( self._GetStreams(['audio', 'video', 'video,trick_play_factor=1']), diff --git a/packager/app/test/testdata/bear-640x360-a-clear-v-cenc-golden.mpd b/packager/app/test/testdata/bear-640x360-a-clear-v-cenc-golden.mpd new file mode 100644 index 0000000000..3b00bcdb1f --- /dev/null +++ b/packager/app/test/testdata/bear-640x360-a-clear-v-cenc-golden.mpd @@ -0,0 +1,27 @@ + + + + + + + + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== + + + output_video.mp4 + + + + + + + + + output_audio_skip_encryption_1.mp4 + + + + + + +