forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The actual encryption is assumed to have been carried out
according to the SAMPLE-AES encryption method cited by the HLS spec (informational RFC called draft-pantos-http-live- streaming). This encryption method is being incorporated in the Common Encryption specification ISO/IEC 23001-7 3rd Edition as the 'cbcs' scheme. Parsing of the stream requires it to be prefixed with extra TS packets that carry encryption metadata. These packets are formatted according to ISO/IEC 23001-9 "Common encryption of MPEG-2 transport streams". This CL is dependent on a prior CL (1490613005) that allows conveyance of the extended encryption metadata through the pipeline. BUG=568326 Review-Url: https://codereview.chromium.org/1517473002 Cr-Commit-Position: refs/heads/master@{#436058}
- Loading branch information
dougsteed
authored and
Commit bot
committed
Dec 2, 2016
1 parent
7dd3af9
commit a66a6e4
Showing
29 changed files
with
1,379 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
// Copyright 2015 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "media/formats/mp2t/descriptors.h" | ||
|
||
#include <vector> | ||
|
||
#include "base/logging.h" | ||
#include "media/base/bit_reader.h" | ||
#include "media/formats/mp2t/mp2t_common.h" | ||
|
||
namespace media { | ||
namespace mp2t { | ||
|
||
namespace { | ||
|
||
// Tag values for various kinds of descriptors for which there is specific | ||
// parsing support herein. | ||
enum DescriptorTag { | ||
DESCRIPTOR_TAG_REGISTRATION = 5, | ||
DESCRIPTOR_TAG_CA = 9, | ||
DESCRIPTOR_TAG_PRIVATE_DATA_INDICATOR = 15, | ||
}; | ||
|
||
const int kCASystemIdCenc = 0x6365; // 'ce' | ||
|
||
class StringBitReader : public BitReader { | ||
public: | ||
StringBitReader(const std::string& input); | ||
~StringBitReader() override; | ||
}; | ||
|
||
StringBitReader::StringBitReader(const std::string& input) | ||
: BitReader(reinterpret_cast<const uint8_t*>(input.data()), input.size()) {} | ||
|
||
StringBitReader::~StringBitReader() {} | ||
|
||
} // namespace | ||
|
||
Descriptors::Descriptors() {} | ||
|
||
Descriptors::Descriptors(const Descriptors& other) = default; | ||
|
||
Descriptors::~Descriptors() {} | ||
|
||
bool Descriptors::Read(BitReader* reader, int size) { | ||
DCHECK(reader); | ||
DCHECK(size >= 0); | ||
descriptors_.clear(); | ||
if (size == 0) | ||
return true; | ||
int initial_bits_read = reader->bits_read(); | ||
int bits_read = 0; | ||
int bits_available = reader->bits_available(); | ||
int size_in_bits = 8 * size; | ||
if (size_in_bits > bits_available) | ||
return false; | ||
bits_available = size_in_bits; | ||
do { | ||
int tag; | ||
size_t length; | ||
RCHECK(reader->ReadBits(8, &tag)); | ||
RCHECK(reader->ReadBits(8, &length)); | ||
char data[256]; | ||
for (size_t i = 0; i < length; i++) { | ||
RCHECK(reader->ReadBits(8, &data[i])); | ||
} | ||
descriptors_.insert(Descriptor(tag, std::string(data, length))); | ||
bits_read = reader->bits_read() - initial_bits_read; | ||
} while (bits_read < bits_available); | ||
return bits_read == bits_available; | ||
} | ||
|
||
bool Descriptors::HasRegistrationDescriptor( | ||
int64_t* format_identifier, | ||
std::string* additional_info) const { | ||
DCHECK(format_identifier); | ||
DCHECK(additional_info); | ||
auto search = descriptors_.find(DESCRIPTOR_TAG_REGISTRATION); | ||
if (search == descriptors_.end()) | ||
return false; | ||
const std::string& data = search->second; | ||
StringBitReader reader(data); | ||
RCHECK(reader.ReadBits(32, format_identifier)); | ||
size_t extra_bits = reader.bits_available(); | ||
RCHECK(extra_bits % 8 == 0); | ||
RCHECK(extra_bits > 0); | ||
RCHECK(reader.ReadString(extra_bits, additional_info)); | ||
return true; | ||
} | ||
|
||
bool Descriptors::HasCADescriptor(int* system_id, | ||
int* pid, | ||
std::string* private_data) const { | ||
DCHECK(system_id); | ||
DCHECK(pid); | ||
DCHECK(private_data); | ||
auto search = descriptors_.find(DESCRIPTOR_TAG_CA); | ||
if (search == descriptors_.end()) | ||
return false; | ||
const std::string& data = search->second; | ||
StringBitReader reader(data); | ||
RCHECK(reader.ReadBits(16, system_id)); | ||
RCHECK(reader.SkipBits(3)); | ||
RCHECK(reader.ReadBits(13, pid)); | ||
size_t extra_bits = reader.bits_available(); | ||
RCHECK(extra_bits % 8 == 0); | ||
RCHECK(reader.ReadString(extra_bits, private_data)); | ||
return true; | ||
} | ||
|
||
bool Descriptors::HasCADescriptorCenc(int* ca_pid, int* pssh_pid) const { | ||
DCHECK(ca_pid); | ||
DCHECK(pssh_pid); | ||
int system_id; | ||
std::string private_data; | ||
if (!HasCADescriptor(&system_id, ca_pid, &private_data)) | ||
return false; | ||
if (system_id != kCASystemIdCenc) | ||
return false; | ||
StringBitReader reader(private_data); | ||
uint32_t scheme_type; | ||
uint32_t scheme_version; | ||
int num_systems; | ||
int encryption_algorithm; | ||
char pssh_system_id[16]; | ||
// TODO(dougsteed). Currently we don't check many of the following values. | ||
// When we flesh out this implementation to cover all of ISO/IEC 23001-9 we | ||
// will need to use and check these values. | ||
RCHECK(reader.ReadBits(32, &scheme_type)); | ||
RCHECK(reader.ReadBits(32, &scheme_version)); | ||
RCHECK(reader.ReadBits(8, &num_systems)); | ||
RCHECK(num_systems == 1); | ||
RCHECK(reader.ReadBits(24, &encryption_algorithm)); | ||
for (size_t i = 0; i < 16; i++) { | ||
RCHECK(reader.ReadBits(8, &pssh_system_id[i])); | ||
} | ||
RCHECK(reader.ReadBits(13, pssh_pid)); | ||
return true; | ||
} | ||
|
||
bool Descriptors::HasPrivateDataIndicator(int64_t value) const { | ||
int64_t private_data_indicator; | ||
auto search = descriptors_.find(DESCRIPTOR_TAG_PRIVATE_DATA_INDICATOR); | ||
if (search == descriptors_.end()) | ||
return false; | ||
const std::string& data = search->second; | ||
StringBitReader reader(data); | ||
RCHECK(reader.ReadBits(32, &private_data_indicator)); | ||
RCHECK(reader.bits_available() == 0); | ||
return private_data_indicator == value; | ||
} | ||
|
||
} // namespace mp2t | ||
} // namespace media |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright 2015 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef MEDIA_FORMATS_MP2T_DESCRIPTORS_H_ | ||
#define MEDIA_FORMATS_MP2T_DESCRIPTORS_H_ | ||
|
||
#include <stdint.h> | ||
|
||
#include <map> | ||
#include <string> | ||
|
||
namespace media { | ||
|
||
class BitReader; | ||
|
||
namespace mp2t { | ||
|
||
// Representation of a list of descriptors, used in the MPEG-2 Systems standard | ||
// to extend the definitions of programs or program elements. While the standard | ||
// appears to permit multiple descriptors in such a list to have the same tag | ||
// value, the implementation herein will not support this. | ||
class Descriptors { | ||
public: | ||
Descriptors(); | ||
Descriptors(const Descriptors& other); | ||
~Descriptors(); | ||
|
||
// Attempts to read a (possibly empty) list of descriptors from the |reader|. | ||
// If |size| > 0, the descriptors must occupy exactly |size| bytes, Otherwise, | ||
// the descriptors should use all available bits from the reader. | ||
bool Read(BitReader* reader, int size); | ||
|
||
// Indicates whether a Registration descriptor is present. If so, the | ||
// |format_identifier| and |additional_info| values are populated with the | ||
// contents of the descriptor. | ||
bool HasRegistrationDescriptor(int64_t* format_identifier, | ||
std::string* additional_info) const; | ||
|
||
// Indicates whether a CA descriptor is present. If so, the |system_id|, | ||
// |pid|, and |private_data| values are populated with the contents of the | ||
// descriptor. | ||
bool HasCADescriptor(int* system_id, | ||
int* pid, | ||
std::string* private_data) const; | ||
|
||
// Indicates whether a CA descriptor is present, and if so, whether it is | ||
// of the type defined by ISO/IEC 23001-9:2014 (i.e. with a specific | ||
// system_id value and layout of the private_data). If so, the |ca_pid| and | ||
// |pssh_pid| are populated with the contents of the descriptor. | ||
bool HasCADescriptorCenc(int* ca_pid, int* pssh_pid) const; | ||
|
||
// Indicates whether a Private Data Indicator descriptor is present with a | ||
// particular |value|. | ||
bool HasPrivateDataIndicator(int64_t value) const; | ||
|
||
private: | ||
using Descriptor = std::pair<int, std::string>; | ||
std::map<int, std::string> descriptors_; | ||
|
||
// Allow copy and assign so that it can be used in a std C++ container. | ||
}; | ||
|
||
} // namespace mp2t | ||
} // namespace media | ||
|
||
#endif // MEDIA_FORMATS_MP2T_DESCRIPTOR_LIST_H_ |
Oops, something went wrong.