Add new flag max_sd_pixels to determine SD or HD track
Change-Id: If841af98345177cf1832b9e5b91148168b000f44
This commit is contained in:
parent
53287e5fe7
commit
1773d08b8d
|
@ -211,15 +211,8 @@ bool RunPackager(const std::string& input) {
|
||||||
encryption_key_source = CreateEncryptionKeySource();
|
encryption_key_source = CreateEncryptionKeySource();
|
||||||
if (!encryption_key_source)
|
if (!encryption_key_source)
|
||||||
return false;
|
return false;
|
||||||
EncryptionKeySource::TrackType track_type =
|
|
||||||
EncryptionKeySource::GetTrackTypeFromString(FLAGS_track_type);
|
|
||||||
if (track_type != EncryptionKeySource::TRACK_TYPE_SD &&
|
|
||||||
track_type != EncryptionKeySource::TRACK_TYPE_HD) {
|
|
||||||
LOG(ERROR) << "FLAGS_track_type should be either 'SD' or 'HD'";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
muxer->SetEncryptionKeySource(encryption_key_source.get(),
|
muxer->SetEncryptionKeySource(encryption_key_source.get(),
|
||||||
track_type,
|
FLAGS_max_sd_pixels,
|
||||||
FLAGS_clear_lead,
|
FLAGS_clear_lead,
|
||||||
FLAGS_crypto_period_duration);
|
FLAGS_crypto_period_duration);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,10 @@ DEFINE_bool(enable_widevine_encryption,
|
||||||
"--aes_signing_iv) or RSA signing key (--rsa_signing_key_path).");
|
"--aes_signing_iv) or RSA signing key (--rsa_signing_key_path).");
|
||||||
DEFINE_string(server_url, "", "License server url.");
|
DEFINE_string(server_url, "", "License server url.");
|
||||||
DEFINE_string(content_id, "", "Content Id.");
|
DEFINE_string(content_id, "", "Content Id.");
|
||||||
DEFINE_string(track_type, "SD", "Track type: SD or HD.");
|
DEFINE_int32(max_sd_pixels,
|
||||||
|
768 * 576,
|
||||||
|
"If the video track has more pixels per frame than max_sd_pixels, "
|
||||||
|
"it is considered as HD, SD otherwise. Default: 768 * 576.");
|
||||||
DEFINE_string(signer, "", "The name of the signer.");
|
DEFINE_string(signer, "", "The name of the signer.");
|
||||||
DEFINE_string(aes_signing_key,
|
DEFINE_string(aes_signing_key,
|
||||||
"",
|
"",
|
||||||
|
@ -43,6 +46,10 @@ static bool IsNotEmptyWithWidevineEncryption(const char* flag_name,
|
||||||
return FLAGS_enable_widevine_encryption ? !flag_value.empty() : true;
|
return FLAGS_enable_widevine_encryption ? !flag_value.empty() : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool IsPositive(const char* flag_name, int flag_value) {
|
||||||
|
return flag_value > 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool VerifyAesRsaKey(const char* flag_name,
|
static bool VerifyAesRsaKey(const char* flag_name,
|
||||||
const std::string& flag_value) {
|
const std::string& flag_value) {
|
||||||
if (!FLAGS_enable_widevine_encryption)
|
if (!FLAGS_enable_widevine_encryption)
|
||||||
|
@ -78,8 +85,7 @@ static bool dummy_content_id_validator =
|
||||||
google::RegisterFlagValidator(&FLAGS_content_id,
|
google::RegisterFlagValidator(&FLAGS_content_id,
|
||||||
&IsNotEmptyWithWidevineEncryption);
|
&IsNotEmptyWithWidevineEncryption);
|
||||||
static bool dummy_track_type_validator =
|
static bool dummy_track_type_validator =
|
||||||
google::RegisterFlagValidator(&FLAGS_track_type,
|
google::RegisterFlagValidator(&FLAGS_max_sd_pixels, &IsPositive);
|
||||||
&IsNotEmptyWithWidevineEncryption);
|
|
||||||
static bool dummy_signer_validator =
|
static bool dummy_signer_validator =
|
||||||
google::RegisterFlagValidator(&FLAGS_signer,
|
google::RegisterFlagValidator(&FLAGS_signer,
|
||||||
&IsNotEmptyWithWidevineEncryption);
|
&IsNotEmptyWithWidevineEncryption);
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "media/base/muxer.h"
|
#include "media/base/muxer.h"
|
||||||
|
|
||||||
#include "media/base/encryption_key_source.h"
|
|
||||||
#include "media/base/media_sample.h"
|
#include "media/base/media_sample.h"
|
||||||
#include "media/base/media_stream.h"
|
#include "media/base/media_stream.h"
|
||||||
|
|
||||||
|
@ -16,7 +15,7 @@ Muxer::Muxer(const MuxerOptions& options)
|
||||||
: options_(options),
|
: options_(options),
|
||||||
initialized_(false),
|
initialized_(false),
|
||||||
encryption_key_source_(NULL),
|
encryption_key_source_(NULL),
|
||||||
track_type_(EncryptionKeySource::TRACK_TYPE_SD),
|
max_sd_pixels_(0),
|
||||||
clear_lead_in_seconds_(0),
|
clear_lead_in_seconds_(0),
|
||||||
crypto_period_duration_in_seconds_(0),
|
crypto_period_duration_in_seconds_(0),
|
||||||
muxer_listener_(NULL),
|
muxer_listener_(NULL),
|
||||||
|
@ -25,12 +24,12 @@ Muxer::Muxer(const MuxerOptions& options)
|
||||||
Muxer::~Muxer() {}
|
Muxer::~Muxer() {}
|
||||||
|
|
||||||
void Muxer::SetEncryptionKeySource(EncryptionKeySource* encryption_key_source,
|
void Muxer::SetEncryptionKeySource(EncryptionKeySource* encryption_key_source,
|
||||||
EncryptionKeySource::TrackType track_type,
|
uint32 max_sd_pixels,
|
||||||
double clear_lead_in_seconds,
|
double clear_lead_in_seconds,
|
||||||
double crypto_period_duration_in_seconds) {
|
double crypto_period_duration_in_seconds) {
|
||||||
DCHECK(encryption_key_source);
|
DCHECK(encryption_key_source);
|
||||||
encryption_key_source_ = encryption_key_source;
|
encryption_key_source_ = encryption_key_source;
|
||||||
track_type_ = track_type;
|
max_sd_pixels_ = max_sd_pixels;
|
||||||
clear_lead_in_seconds_ = clear_lead_in_seconds;
|
clear_lead_in_seconds_ = clear_lead_in_seconds;
|
||||||
crypto_period_duration_in_seconds_ = crypto_period_duration_in_seconds;
|
crypto_period_duration_in_seconds_ = crypto_period_duration_in_seconds;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "media/base/encryption_key_source.h"
|
|
||||||
#include "media/base/muxer_options.h"
|
#include "media/base/muxer_options.h"
|
||||||
#include "media/base/status.h"
|
#include "media/base/status.h"
|
||||||
|
|
||||||
|
@ -42,14 +41,15 @@ class Muxer {
|
||||||
/// Set encryption key source.
|
/// Set encryption key source.
|
||||||
/// @param encryption_key_source points to the encryption key source to be
|
/// @param encryption_key_source points to the encryption key source to be
|
||||||
/// injected. Should not be NULL.
|
/// injected. Should not be NULL.
|
||||||
/// @param track_type should be either SD or HD. It affects whether SD key or
|
/// @param max_sd_pixels specifies the threshold to determine whether a video
|
||||||
/// HD key is used to encrypt the video content.
|
/// track should be considered as SD or HD. If the track has more
|
||||||
|
/// pixels per frame than max_sd_pixels, it is HD, SD otherwise.
|
||||||
/// @param clear_lead_in_seconds specifies clear lead duration in seconds.
|
/// @param clear_lead_in_seconds specifies clear lead duration in seconds.
|
||||||
/// @param crypto_period_duration_in_seconds specifies crypto period duration
|
/// @param crypto_period_duration_in_seconds specifies crypto period duration
|
||||||
/// in seconds. A positive value means key rotation is enabled, the
|
/// in seconds. A positive value means key rotation is enabled, the
|
||||||
/// key source must support key rotation in this case.
|
/// key source must support key rotation in this case.
|
||||||
void SetEncryptionKeySource(EncryptionKeySource* encryption_key_source,
|
void SetEncryptionKeySource(EncryptionKeySource* encryption_key_source,
|
||||||
EncryptionKeySource::TrackType track_type,
|
uint32 max_sd_pixels,
|
||||||
double clear_lead_in_seconds,
|
double clear_lead_in_seconds,
|
||||||
double crypto_period_duration_in_seconds);
|
double crypto_period_duration_in_seconds);
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ class Muxer {
|
||||||
EncryptionKeySource* encryption_key_source() {
|
EncryptionKeySource* encryption_key_source() {
|
||||||
return encryption_key_source_;
|
return encryption_key_source_;
|
||||||
}
|
}
|
||||||
EncryptionKeySource::TrackType track_type() const { return track_type_; }
|
uint32 max_sd_pixels() const { return max_sd_pixels_; }
|
||||||
double clear_lead_in_seconds() const { return clear_lead_in_seconds_; }
|
double clear_lead_in_seconds() const { return clear_lead_in_seconds_; }
|
||||||
double crypto_period_duration_in_seconds() const {
|
double crypto_period_duration_in_seconds() const {
|
||||||
return crypto_period_duration_in_seconds_;
|
return crypto_period_duration_in_seconds_;
|
||||||
|
@ -109,7 +109,7 @@ class Muxer {
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
std::vector<MediaStream*> streams_;
|
std::vector<MediaStream*> streams_;
|
||||||
EncryptionKeySource* encryption_key_source_;
|
EncryptionKeySource* encryption_key_source_;
|
||||||
EncryptionKeySource::TrackType track_type_;
|
uint32 max_sd_pixels_;
|
||||||
double clear_lead_in_seconds_;
|
double clear_lead_in_seconds_;
|
||||||
double crypto_period_duration_in_seconds_;
|
double crypto_period_duration_in_seconds_;
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ Status MP4Muxer::Initialize() {
|
||||||
Status segmenter_initialized =
|
Status segmenter_initialized =
|
||||||
segmenter_->Initialize(streams(),
|
segmenter_->Initialize(streams(),
|
||||||
encryption_key_source(),
|
encryption_key_source(),
|
||||||
track_type(),
|
max_sd_pixels(),
|
||||||
clear_lead_in_seconds(),
|
clear_lead_in_seconds(),
|
||||||
crypto_period_duration_in_seconds());
|
crypto_period_duration_in_seconds());
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,27 @@ void GenerateEncryptedSampleEntryForKeyRotation(
|
||||||
encryption_key, clear_lead_in_seconds, description);
|
encryption_key, clear_lead_in_seconds, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 GetNaluLengthSize(const StreamInfo& stream_info) {
|
||||||
|
if (stream_info.stream_type() != kStreamVideo)
|
||||||
|
return 0;
|
||||||
|
const VideoStreamInfo& video_stream_info =
|
||||||
|
static_cast<const VideoStreamInfo&>(stream_info);
|
||||||
|
return video_stream_info.nalu_length_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
EncryptionKeySource::TrackType GetTrackTypeForEncryption(
|
||||||
|
const StreamInfo& stream_info, uint32 max_sd_pixels) {
|
||||||
|
if (stream_info.stream_type() == kStreamAudio)
|
||||||
|
return EncryptionKeySource::TRACK_TYPE_AUDIO;
|
||||||
|
|
||||||
|
DCHECK_EQ(kStreamVideo, stream_info.stream_type());
|
||||||
|
const VideoStreamInfo& video_stream_info =
|
||||||
|
static_cast<const VideoStreamInfo&>(stream_info);
|
||||||
|
uint32 pixels = video_stream_info.width() * video_stream_info.height();
|
||||||
|
return (pixels > max_sd_pixels) ? EncryptionKeySource::TRACK_TYPE_HD
|
||||||
|
: EncryptionKeySource::TRACK_TYPE_SD;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Segmenter::Segmenter(const MuxerOptions& options,
|
Segmenter::Segmenter(const MuxerOptions& options,
|
||||||
|
@ -104,7 +125,7 @@ Segmenter::~Segmenter() { STLDeleteElements(&fragmenters_); }
|
||||||
|
|
||||||
Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
||||||
EncryptionKeySource* encryption_key_source,
|
EncryptionKeySource* encryption_key_source,
|
||||||
EncryptionKeySource::TrackType track_type,
|
uint32 max_sd_pixels,
|
||||||
double clear_lead_in_seconds,
|
double clear_lead_in_seconds,
|
||||||
double crypto_period_duration_in_seconds) {
|
double crypto_period_duration_in_seconds) {
|
||||||
DCHECK_LT(0u, streams.size());
|
DCHECK_LT(0u, streams.size());
|
||||||
|
@ -116,29 +137,22 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
||||||
for (uint32 i = 0; i < streams.size(); ++i) {
|
for (uint32 i = 0; i < streams.size(); ++i) {
|
||||||
stream_map_[streams[i]] = i;
|
stream_map_[streams[i]] = i;
|
||||||
moof_->tracks[i].header.track_id = i + 1;
|
moof_->tracks[i].header.track_id = i + 1;
|
||||||
uint8 nalu_length_size = 0;
|
|
||||||
if (streams[i]->info()->stream_type() == kStreamVideo) {
|
if (streams[i]->info()->stream_type() == kStreamVideo) {
|
||||||
VideoStreamInfo* video =
|
// Use the first video stream as the reference stream (which is 1-based).
|
||||||
static_cast<VideoStreamInfo*>(streams[i]->info().get());
|
|
||||||
nalu_length_size = video->nalu_length_size();
|
|
||||||
// We use the first video stream as the reference stream.
|
|
||||||
if (sidx_->reference_id == 0)
|
if (sidx_->reference_id == 0)
|
||||||
sidx_->reference_id = i + 1;
|
sidx_->reference_id = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!encryption_key_source) {
|
if (!encryption_key_source) {
|
||||||
fragmenters_[i] = new Fragmenter(
|
fragmenters_[i] = new Fragmenter(
|
||||||
&moof_->tracks[i], options_.normalize_presentation_timestamp);
|
&moof_->tracks[i], options_.normalize_presentation_timestamp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DCHECK(track_type == EncryptionKeySource::TRACK_TYPE_SD ||
|
uint8 nalu_length_size = GetNaluLengthSize(*streams[i]->info());
|
||||||
track_type == EncryptionKeySource::TRACK_TYPE_HD);
|
EncryptionKeySource::TrackType track_type =
|
||||||
|
GetTrackTypeForEncryption(*streams[i]->info(), max_sd_pixels);
|
||||||
SampleDescription& description =
|
SampleDescription& description =
|
||||||
moov_->tracks[i].media.information.sample_table.description;
|
moov_->tracks[i].media.information.sample_table.description;
|
||||||
EncryptionKeySource::TrackType cur_track_type =
|
|
||||||
description.type == kAudio ? EncryptionKeySource::TRACK_TYPE_AUDIO
|
|
||||||
: track_type;
|
|
||||||
|
|
||||||
const bool key_rotation_enabled = crypto_period_duration_in_seconds != 0;
|
const bool key_rotation_enabled = crypto_period_duration_in_seconds != 0;
|
||||||
if (key_rotation_enabled) {
|
if (key_rotation_enabled) {
|
||||||
|
@ -150,7 +164,7 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
||||||
&moof_->tracks[i],
|
&moof_->tracks[i],
|
||||||
options_.normalize_presentation_timestamp,
|
options_.normalize_presentation_timestamp,
|
||||||
encryption_key_source,
|
encryption_key_source,
|
||||||
cur_track_type,
|
track_type,
|
||||||
crypto_period_duration_in_seconds * streams[i]->info()->time_scale(),
|
crypto_period_duration_in_seconds * streams[i]->info()->time_scale(),
|
||||||
clear_lead_in_seconds * streams[i]->info()->time_scale(),
|
clear_lead_in_seconds * streams[i]->info()->time_scale(),
|
||||||
nalu_length_size);
|
nalu_length_size);
|
||||||
|
@ -159,7 +173,7 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
||||||
|
|
||||||
scoped_ptr<EncryptionKey> encryption_key(new EncryptionKey());
|
scoped_ptr<EncryptionKey> encryption_key(new EncryptionKey());
|
||||||
Status status =
|
Status status =
|
||||||
encryption_key_source->GetKey(cur_track_type, encryption_key.get());
|
encryption_key_source->GetKey(track_type, encryption_key.get());
|
||||||
if (!status.ok())
|
if (!status.ok())
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "base/memory/scoped_ptr.h"
|
#include "base/memory/scoped_ptr.h"
|
||||||
#include "media/base/encryption_key_source.h"
|
|
||||||
#include "media/base/status.h"
|
#include "media/base/status.h"
|
||||||
|
|
||||||
namespace media {
|
namespace media {
|
||||||
|
@ -53,14 +52,15 @@ class Segmenter {
|
||||||
/// @param encryption_key_source points to the key source which contains
|
/// @param encryption_key_source points to the key source which contains
|
||||||
/// the encryption keys. It can be NULL to indicate that no encryption
|
/// the encryption keys. It can be NULL to indicate that no encryption
|
||||||
/// is required.
|
/// is required.
|
||||||
/// @param track_type indicates whether SD key or HD key should be used to
|
/// @param max_sd_pixels specifies the threshold to determine whether a video
|
||||||
/// encrypt the video content.
|
/// track should be considered as SD or HD. If the track has more
|
||||||
|
/// pixels per frame than max_sd_pixels, it is HD, SD otherwise.
|
||||||
/// @param clear_time specifies clear lead duration in seconds.
|
/// @param clear_time specifies clear lead duration in seconds.
|
||||||
/// @param crypto_period_duration specifies crypto period duration in seconds.
|
/// @param crypto_period_duration specifies crypto period duration in seconds.
|
||||||
/// @return OK on success, an error status otherwise.
|
/// @return OK on success, an error status otherwise.
|
||||||
Status Initialize(const std::vector<MediaStream*>& streams,
|
Status Initialize(const std::vector<MediaStream*>& streams,
|
||||||
EncryptionKeySource* encryption_key_source,
|
EncryptionKeySource* encryption_key_source,
|
||||||
EncryptionKeySource::TrackType track_type,
|
uint32 max_sd_pixels,
|
||||||
double clear_lead_in_seconds,
|
double clear_lead_in_seconds,
|
||||||
double crypto_period_duration_in_seconds);
|
double crypto_period_duration_in_seconds);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue