Fixed various bugs:
- 17932674 Packager crashes when an incorrect key is provided to wvm. - 17932293 Packager crashes if no key source is provided for wvm input. - 17932868 StreamInfo is cast to AudioStreamInfo unconditionally and corrupts memory in wvm_media_parser - 17932033 input: wvm --enable_fixed_key_decryption Segmentation Fault. Change-Id: I7fc774c87a33314a4c92bc907f06c17f0c269a16
This commit is contained in:
parent
9158f4a543
commit
e7e86d684a
|
@ -26,12 +26,17 @@ KeySource::~KeySource() {}
|
||||||
|
|
||||||
Status KeySource::FetchKeys(const std::vector<uint8_t>& content_id,
|
Status KeySource::FetchKeys(const std::vector<uint8_t>& content_id,
|
||||||
const std::string& policy) {
|
const std::string& policy) {
|
||||||
// Do nothing for fixed key decryption.
|
// Do nothing for fixed key encryption/decryption.
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status KeySource::FetchKeys(const std::vector<uint8_t>& pssh_data) {
|
Status KeySource::FetchKeys(const std::vector<uint8_t>& pssh_data) {
|
||||||
// Do nothing for fixed key decryption.
|
// Do nothing for fixed key encryption/decryption.
|
||||||
|
return Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status KeySource::FetchKeys(uint32_t asset_id) {
|
||||||
|
// Do nothing for fixed key encryption/decryption.
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,12 @@ class KeySource {
|
||||||
/// @return OK on success, an error status otherwise.
|
/// @return OK on success, an error status otherwise.
|
||||||
virtual Status FetchKeys(const std::vector<uint8_t>& pssh_data);
|
virtual Status FetchKeys(const std::vector<uint8_t>& pssh_data);
|
||||||
|
|
||||||
|
/// Fetch keys for WVM decryption from the key server.
|
||||||
|
/// @param asset_id is the Widevine Classic asset ID for the content to be
|
||||||
|
/// decrypted.
|
||||||
|
/// @return OK on success, an error status otherwise.
|
||||||
|
virtual Status FetchKeys(uint32_t asset_id) OVERRIDE;
|
||||||
|
|
||||||
/// Get encryption key of the specified track type.
|
/// Get encryption key of the specified track type.
|
||||||
/// @param track_type is the type of track for which retrieving the key.
|
/// @param track_type is the type of track for which retrieving the key.
|
||||||
/// @param key is a pointer to the EncryptionKey which will hold the retrieved
|
/// @param key is a pointer to the EncryptionKey which will hold the retrieved
|
||||||
|
|
|
@ -37,7 +37,7 @@ class WidevineKeySource : public KeySource {
|
||||||
virtual Status FetchKeys(const std::vector<uint8_t>& content_id,
|
virtual Status FetchKeys(const std::vector<uint8_t>& content_id,
|
||||||
const std::string& policy) OVERRIDE;
|
const std::string& policy) OVERRIDE;
|
||||||
virtual Status FetchKeys(const std::vector<uint8_t>& pssh_data) OVERRIDE;
|
virtual Status FetchKeys(const std::vector<uint8_t>& pssh_data) OVERRIDE;
|
||||||
virtual Status FetchKeys(uint32_t asset_id);
|
virtual Status FetchKeys(uint32_t asset_id) OVERRIDE;
|
||||||
|
|
||||||
virtual Status GetKey(TrackType track_type, EncryptionKey* key) OVERRIDE;
|
virtual Status GetKey(TrackType track_type, EncryptionKey* key) OVERRIDE;
|
||||||
virtual Status GetKey(const std::vector<uint8_t>& key_id,
|
virtual Status GetKey(const std::vector<uint8_t>& key_id,
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
|
|
||||||
#include "packager/base/strings/string_number_conversions.h"
|
#include "packager/base/strings/string_number_conversions.h"
|
||||||
#include "packager/media/base/audio_stream_info.h"
|
#include "packager/media/base/audio_stream_info.h"
|
||||||
|
#include "packager/media/base/key_source.h"
|
||||||
#include "packager/media/base/media_sample.h"
|
#include "packager/media/base/media_sample.h"
|
||||||
#include "packager/media/base/status.h"
|
#include "packager/media/base/status.h"
|
||||||
#include "packager/media/base/video_stream_info.h"
|
#include "packager/media/base/video_stream_info.h"
|
||||||
#include "packager/media/base/widevine_key_source.h"
|
|
||||||
#include "packager/media/formats/mp2t/adts_header.h"
|
#include "packager/media/formats/mp2t/adts_header.h"
|
||||||
|
|
||||||
#define HAS_HEADER_EXTENSION(x) ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) \
|
#define HAS_HEADER_EXTENSION(x) ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) \
|
||||||
|
@ -110,9 +110,7 @@ void WvmMediaParser::Init(const InitCB& init_cb,
|
||||||
DCHECK(!is_initialized_);
|
DCHECK(!is_initialized_);
|
||||||
DCHECK(!init_cb.is_null());
|
DCHECK(!init_cb.is_null());
|
||||||
DCHECK(!new_sample_cb.is_null());
|
DCHECK(!new_sample_cb.is_null());
|
||||||
DCHECK(decryption_key_source);
|
decryption_key_source_ = decryption_key_source;
|
||||||
decryption_key_source_ =
|
|
||||||
reinterpret_cast<WidevineKeySource*>(decryption_key_source);
|
|
||||||
init_cb_ = init_cb;
|
init_cb_ = init_cb;
|
||||||
new_sample_cb_ = new_sample_cb;
|
new_sample_cb_ = new_sample_cb;
|
||||||
}
|
}
|
||||||
|
@ -756,8 +754,11 @@ bool WvmMediaParser::Output() {
|
||||||
if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
|
if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
|
||||||
// Set data on the video stream from the NalUnitStream.
|
// Set data on the video stream from the NalUnitStream.
|
||||||
std::vector<uint8_t> nal_unit_stream;
|
std::vector<uint8_t> nal_unit_stream;
|
||||||
byte_to_unit_stream_converter_.ConvertByteStreamToNalUnitStream(
|
if (!byte_to_unit_stream_converter_.ConvertByteStreamToNalUnitStream(
|
||||||
&sample_data_[0], sample_data_.size(), &nal_unit_stream);
|
&sample_data_[0], sample_data_.size(), &nal_unit_stream)) {
|
||||||
|
LOG(ERROR) << "Could not convert h.264 byte stream sample";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
media_sample_->set_data(nal_unit_stream.data(), nal_unit_stream.size());
|
media_sample_->set_data(nal_unit_stream.data(), nal_unit_stream.size());
|
||||||
if (!is_initialized_) {
|
if (!is_initialized_) {
|
||||||
// Set extra data for video stream from AVC Decoder Config Record.
|
// Set extra data for video stream from AVC Decoder Config Record.
|
||||||
|
@ -767,48 +768,50 @@ bool WvmMediaParser::Output() {
|
||||||
&decoder_config_record);
|
&decoder_config_record);
|
||||||
for (uint32_t i = 0; i < stream_infos_.size(); i++) {
|
for (uint32_t i = 0; i < stream_infos_.size(); i++) {
|
||||||
if (stream_infos_[i]->stream_type() == media::kStreamVideo &&
|
if (stream_infos_[i]->stream_type() == media::kStreamVideo &&
|
||||||
stream_infos_[i]->extra_data().empty()) {
|
stream_infos_[i]->extra_data().empty()) {
|
||||||
stream_infos_[i]->set_extra_data(decoder_config_record);
|
stream_infos_[i]->set_extra_data(decoder_config_record);
|
||||||
stream_infos_[i]->set_codec_string(VideoStreamInfo::GetCodecString(
|
stream_infos_[i]->set_codec_string(VideoStreamInfo::GetCodecString(
|
||||||
kCodecH264, decoder_config_record[1], decoder_config_record[2],
|
kCodecH264, decoder_config_record[1], decoder_config_record[2],
|
||||||
decoder_config_record[3]));
|
decoder_config_record[3]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((prev_pes_stream_id_ & kPesStreamIdAudioMask) ==
|
} else if ((prev_pes_stream_id_ & kPesStreamIdAudioMask) ==
|
||||||
kPesStreamIdAudio) {
|
kPesStreamIdAudio) {
|
||||||
// Set data on the audio stream from AdtsHeader.
|
// Set data on the audio stream from AdtsHeader.
|
||||||
int frame_size = media::mp2t::AdtsHeader::GetAdtsFrameSize(
|
int frame_size = media::mp2t::AdtsHeader::GetAdtsFrameSize(
|
||||||
&sample_data_[0], kAdtsHeaderMinSize);
|
&sample_data_[0], kAdtsHeaderMinSize);
|
||||||
media::mp2t::AdtsHeader adts_header;
|
media::mp2t::AdtsHeader adts_header;
|
||||||
const uint8_t* frame_ptr = &sample_data_[0];
|
const uint8_t* frame_ptr = &sample_data_[0];
|
||||||
std::vector<uint8_t> extra_data;
|
std::vector<uint8_t> extra_data;
|
||||||
if (adts_header.Parse(frame_ptr, frame_size) &&
|
if (!adts_header.Parse(frame_ptr, frame_size) ||
|
||||||
(adts_header.GetAudioSpecificConfig(&extra_data))) {
|
!adts_header.GetAudioSpecificConfig(&extra_data)) {
|
||||||
size_t header_size = adts_header.GetAdtsHeaderSize(frame_ptr,
|
LOG(ERROR) << "Could not parse ADTS header";
|
||||||
frame_size);
|
return false;
|
||||||
media_sample_->set_data(frame_ptr + header_size,
|
}
|
||||||
frame_size - header_size);
|
size_t header_size = adts_header.GetAdtsHeaderSize(frame_ptr,
|
||||||
if (!is_initialized_) {
|
frame_size);
|
||||||
uint32_t sampling_frequency = adts_header.GetSamplingFrequency();
|
media_sample_->set_data(frame_ptr + header_size,
|
||||||
for (uint32_t i = 0; i < stream_infos_.size(); i++) {
|
frame_size - header_size);
|
||||||
AudioStreamInfo* audio_stream_info =
|
if (!is_initialized_) {
|
||||||
reinterpret_cast<AudioStreamInfo*>(
|
for (uint32_t i = 0; i < stream_infos_.size(); i++) {
|
||||||
stream_infos_[i].get());
|
if (stream_infos_[i]->stream_type() == media::kStreamAudio &&
|
||||||
audio_stream_info->set_sampling_frequency(sampling_frequency);
|
stream_infos_[i]->extra_data().empty()) {
|
||||||
// Set extra data and codec string on the audio stream from the
|
// Set AudioStreamInfo fields using information from the ADTS
|
||||||
// AdtsHeader.
|
// header.
|
||||||
if (stream_infos_[i]->stream_type() == media::kStreamAudio &&
|
AudioStreamInfo* audio_stream_info =
|
||||||
stream_infos_[i]->extra_data().empty()) {
|
reinterpret_cast<AudioStreamInfo*>(
|
||||||
stream_infos_[i]->set_extra_data(extra_data);
|
stream_infos_[i].get());
|
||||||
stream_infos_[i]->set_codec_string(
|
audio_stream_info->set_sampling_frequency(
|
||||||
AudioStreamInfo::GetCodecString(
|
adts_header.GetSamplingFrequency());
|
||||||
kCodecAAC, adts_header.GetObjectType()));
|
audio_stream_info->set_extra_data(extra_data);
|
||||||
}
|
audio_stream_info->set_codec_string(
|
||||||
}
|
AudioStreamInfo::GetCodecString(
|
||||||
|
kCodecAAC, adts_header.GetObjectType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_initialized_) {
|
if (!is_initialized_) {
|
||||||
bool is_extra_data_in_stream_infos = true;
|
bool is_extra_data_in_stream_infos = true;
|
||||||
|
@ -908,6 +911,10 @@ void WvmMediaParser::EmitSample(uint32_t parsed_audio_or_video_stream_id,
|
||||||
|
|
||||||
bool WvmMediaParser::GetAssetKey(const uint32_t asset_id,
|
bool WvmMediaParser::GetAssetKey(const uint32_t asset_id,
|
||||||
EncryptionKey* encryption_key) {
|
EncryptionKey* encryption_key) {
|
||||||
|
if (decryption_key_source_ == NULL) {
|
||||||
|
LOG(ERROR) << "Source content is encrypted, but decryption not enabled";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Status status = decryption_key_source_->FetchKeys(asset_id);
|
Status status = decryption_key_source_->FetchKeys(asset_id);
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
LOG(ERROR) << "Fetch Key(s) failed for AssetID = " << asset_id
|
LOG(ERROR) << "Fetch Key(s) failed for AssetID = " << asset_id
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
|
class KeySource;
|
||||||
struct EncryptionKey;
|
struct EncryptionKey;
|
||||||
class WidevineKeySource;
|
|
||||||
|
|
||||||
namespace wvm {
|
namespace wvm {
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ class WvmMediaParser : public MediaParser {
|
||||||
std::vector<scoped_refptr<StreamInfo> > stream_infos_;
|
std::vector<scoped_refptr<StreamInfo> > stream_infos_;
|
||||||
std::deque<DemuxStreamIdMediaSample> media_sample_queue_;
|
std::deque<DemuxStreamIdMediaSample> media_sample_queue_;
|
||||||
std::vector<uint8_t> sample_data_;
|
std::vector<uint8_t> sample_data_;
|
||||||
WidevineKeySource* decryption_key_source_;
|
KeySource* decryption_key_source_;
|
||||||
AesCbcCtsDecryptor content_decryptor_;
|
AesCbcCtsDecryptor content_decryptor_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(WvmMediaParser);
|
DISALLOW_COPY_AND_ASSIGN(WvmMediaParser);
|
||||||
|
|
Loading…
Reference in New Issue