Add new flag max_sd_pixels to determine SD or HD track

Change-Id: If841af98345177cf1832b9e5b91148168b000f44
This commit is contained in:
Kongqun Yang 2014-04-24 14:32:18 -07:00 committed by KongQun Yang
parent 53287e5fe7
commit 1773d08b8d
7 changed files with 52 additions and 40 deletions

View File

@ -211,15 +211,8 @@ bool RunPackager(const std::string& input) {
encryption_key_source = CreateEncryptionKeySource();
if (!encryption_key_source)
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(),
track_type,
FLAGS_max_sd_pixels,
FLAGS_clear_lead,
FLAGS_crypto_period_duration);
}

View File

@ -20,7 +20,10 @@ DEFINE_bool(enable_widevine_encryption,
"--aes_signing_iv) or RSA signing key (--rsa_signing_key_path).");
DEFINE_string(server_url, "", "License server url.");
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(aes_signing_key,
"",
@ -43,6 +46,10 @@ static bool IsNotEmptyWithWidevineEncryption(const char* flag_name,
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,
const std::string& flag_value) {
if (!FLAGS_enable_widevine_encryption)
@ -78,8 +85,7 @@ static bool dummy_content_id_validator =
google::RegisterFlagValidator(&FLAGS_content_id,
&IsNotEmptyWithWidevineEncryption);
static bool dummy_track_type_validator =
google::RegisterFlagValidator(&FLAGS_track_type,
&IsNotEmptyWithWidevineEncryption);
google::RegisterFlagValidator(&FLAGS_max_sd_pixels, &IsPositive);
static bool dummy_signer_validator =
google::RegisterFlagValidator(&FLAGS_signer,
&IsNotEmptyWithWidevineEncryption);

View File

@ -6,7 +6,6 @@
#include "media/base/muxer.h"
#include "media/base/encryption_key_source.h"
#include "media/base/media_sample.h"
#include "media/base/media_stream.h"
@ -16,7 +15,7 @@ Muxer::Muxer(const MuxerOptions& options)
: options_(options),
initialized_(false),
encryption_key_source_(NULL),
track_type_(EncryptionKeySource::TRACK_TYPE_SD),
max_sd_pixels_(0),
clear_lead_in_seconds_(0),
crypto_period_duration_in_seconds_(0),
muxer_listener_(NULL),
@ -25,12 +24,12 @@ Muxer::Muxer(const MuxerOptions& options)
Muxer::~Muxer() {}
void Muxer::SetEncryptionKeySource(EncryptionKeySource* encryption_key_source,
EncryptionKeySource::TrackType track_type,
uint32 max_sd_pixels,
double clear_lead_in_seconds,
double crypto_period_duration_in_seconds) {
DCHECK(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;
crypto_period_duration_in_seconds_ = crypto_period_duration_in_seconds;
}

View File

@ -13,7 +13,6 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/encryption_key_source.h"
#include "media/base/muxer_options.h"
#include "media/base/status.h"
@ -42,14 +41,15 @@ class Muxer {
/// Set encryption key source.
/// @param encryption_key_source points to the encryption key source to be
/// injected. Should not be NULL.
/// @param track_type should be either SD or HD. It affects whether SD key or
/// HD key is used to encrypt the video content.
/// @param max_sd_pixels specifies the threshold to determine whether a video
/// 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 crypto_period_duration_in_seconds specifies crypto period duration
/// in seconds. A positive value means key rotation is enabled, the
/// key source must support key rotation in this case.
void SetEncryptionKeySource(EncryptionKeySource* encryption_key_source,
EncryptionKeySource::TrackType track_type,
uint32 max_sd_pixels,
double clear_lead_in_seconds,
double crypto_period_duration_in_seconds);
@ -80,7 +80,7 @@ class Muxer {
EncryptionKeySource* 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 crypto_period_duration_in_seconds() const {
return crypto_period_duration_in_seconds_;
@ -109,7 +109,7 @@ class Muxer {
bool initialized_;
std::vector<MediaStream*> streams_;
EncryptionKeySource* encryption_key_source_;
EncryptionKeySource::TrackType track_type_;
uint32 max_sd_pixels_;
double clear_lead_in_seconds_;
double crypto_period_duration_in_seconds_;

View File

@ -101,7 +101,7 @@ Status MP4Muxer::Initialize() {
Status segmenter_initialized =
segmenter_->Initialize(streams(),
encryption_key_source(),
track_type(),
max_sd_pixels(),
clear_lead_in_seconds(),
crypto_period_duration_in_seconds());

View File

@ -86,6 +86,27 @@ void GenerateEncryptedSampleEntryForKeyRotation(
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
Segmenter::Segmenter(const MuxerOptions& options,
@ -104,7 +125,7 @@ Segmenter::~Segmenter() { STLDeleteElements(&fragmenters_); }
Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
EncryptionKeySource* encryption_key_source,
EncryptionKeySource::TrackType track_type,
uint32 max_sd_pixels,
double clear_lead_in_seconds,
double crypto_period_duration_in_seconds) {
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) {
stream_map_[streams[i]] = i;
moof_->tracks[i].header.track_id = i + 1;
uint8 nalu_length_size = 0;
if (streams[i]->info()->stream_type() == kStreamVideo) {
VideoStreamInfo* video =
static_cast<VideoStreamInfo*>(streams[i]->info().get());
nalu_length_size = video->nalu_length_size();
// We use the first video stream as the reference stream.
// Use the first video stream as the reference stream (which is 1-based).
if (sidx_->reference_id == 0)
sidx_->reference_id = i + 1;
}
if (!encryption_key_source) {
fragmenters_[i] = new Fragmenter(
&moof_->tracks[i], options_.normalize_presentation_timestamp);
continue;
}
DCHECK(track_type == EncryptionKeySource::TRACK_TYPE_SD ||
track_type == EncryptionKeySource::TRACK_TYPE_HD);
uint8 nalu_length_size = GetNaluLengthSize(*streams[i]->info());
EncryptionKeySource::TrackType track_type =
GetTrackTypeForEncryption(*streams[i]->info(), max_sd_pixels);
SampleDescription& 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;
if (key_rotation_enabled) {
@ -150,7 +164,7 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
&moof_->tracks[i],
options_.normalize_presentation_timestamp,
encryption_key_source,
cur_track_type,
track_type,
crypto_period_duration_in_seconds * streams[i]->info()->time_scale(),
clear_lead_in_seconds * streams[i]->info()->time_scale(),
nalu_length_size);
@ -159,7 +173,7 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
scoped_ptr<EncryptionKey> encryption_key(new EncryptionKey());
Status status =
encryption_key_source->GetKey(cur_track_type, encryption_key.get());
encryption_key_source->GetKey(track_type, encryption_key.get());
if (!status.ok())
return status;

View File

@ -12,7 +12,6 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/encryption_key_source.h"
#include "media/base/status.h"
namespace media {
@ -53,14 +52,15 @@ class Segmenter {
/// @param encryption_key_source points to the key source which contains
/// the encryption keys. It can be NULL to indicate that no encryption
/// is required.
/// @param track_type indicates whether SD key or HD key should be used to
/// encrypt the video content.
/// @param max_sd_pixels specifies the threshold to determine whether a video
/// 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 crypto_period_duration specifies crypto period duration in seconds.
/// @return OK on success, an error status otherwise.
Status Initialize(const std::vector<MediaStream*>& streams,
EncryptionKeySource* encryption_key_source,
EncryptionKeySource::TrackType track_type,
uint32 max_sd_pixels,
double clear_lead_in_seconds,
double crypto_period_duration_in_seconds);