Fix WebM parsing crash when the source content contains color elements

Also updates outdated comment in packager.h related to multi-manifests.

Fixes #275

Change-Id: Ia2eb235607860f92a3c19bd791d711209da85c08
This commit is contained in:
KongQun Yang 2017-10-06 11:14:40 -07:00
parent 65d5ecc3cf
commit 94a64bef03
3 changed files with 61 additions and 43 deletions

View File

@ -27,12 +27,9 @@ int64_t GetGreatestCommonDivisor(int64_t a, int64_t b) {
namespace shaka { namespace shaka {
namespace media { namespace media {
WebMVideoClient::WebMVideoClient() { WebMVideoClient::WebMVideoClient() {}
Reset();
}
WebMVideoClient::~WebMVideoClient() { WebMVideoClient::~WebMVideoClient() {}
}
void WebMVideoClient::Reset() { void WebMVideoClient::Reset() {
pixel_width_ = -1; pixel_width_ = -1;
@ -46,11 +43,15 @@ void WebMVideoClient::Reset() {
display_unit_ = -1; display_unit_ = -1;
alpha_mode_ = -1; alpha_mode_ = -1;
vp_config_ = VPCodecConfigurationRecord(); matrix_coefficients_ = -1;
bits_per_channel_ = -1;
chroma_subsampling_horz_ = -1; chroma_subsampling_horz_ = -1;
chroma_subsampling_vert_ = -1; chroma_subsampling_vert_ = -1;
chroma_siting_horz_ = -1; chroma_siting_horz_ = -1;
chroma_siting_vert_ = -1; chroma_siting_vert_ = -1;
color_range_ = -1;
transfer_characteristics_ = -1;
color_primaries_ = -1;
} }
std::shared_ptr<VideoStreamInfo> WebMVideoClient::GetVideoStreamInfo( std::shared_ptr<VideoStreamInfo> WebMVideoClient::GetVideoStreamInfo(
@ -119,17 +120,37 @@ std::shared_ptr<VideoStreamInfo> WebMVideoClient::GetVideoStreamInfo(
sar_y, 0, 0, std::string(), is_encrypted); sar_y, 0, 0, std::string(), is_encrypted);
} }
const VPCodecConfigurationRecord& WebMVideoClient::GetVpCodecConfig( VPCodecConfigurationRecord WebMVideoClient::GetVpCodecConfig(
const std::vector<uint8_t>& codec_private) { const std::vector<uint8_t>& codec_private) {
vp_config_.ParseWebM(codec_private); VPCodecConfigurationRecord vp_config;
vp_config.ParseWebM(codec_private);
if (matrix_coefficients_ != -1) {
vp_config.set_matrix_coefficients(matrix_coefficients_);
}
if (bits_per_channel_ != -1) {
vp_config.set_bit_depth(bits_per_channel_);
}
if (chroma_subsampling_horz_ != -1 && chroma_subsampling_vert_ != -1) { if (chroma_subsampling_horz_ != -1 && chroma_subsampling_vert_ != -1) {
vp_config_.SetChromaSubsampling(chroma_subsampling_horz_, vp_config.SetChromaSubsampling(chroma_subsampling_horz_,
chroma_subsampling_vert_); chroma_subsampling_vert_);
} }
if (chroma_siting_horz_ != -1 && chroma_siting_vert_ != -1) { if (chroma_siting_horz_ != -1 && chroma_siting_vert_ != -1) {
vp_config_.SetChromaLocation(chroma_siting_horz_, chroma_siting_vert_); vp_config.SetChromaLocation(chroma_siting_horz_, chroma_siting_vert_);
} }
return vp_config_; if (color_range_ != -1) {
if (color_range_ == 0)
vp_config.set_video_full_range_flag(false);
else if (color_range_ == 1)
vp_config.set_video_full_range_flag(true);
// Ignore for other values.
}
if (transfer_characteristics_ != -1) {
vp_config.set_transfer_characteristics(transfer_characteristics_);
}
if (color_primaries_ != -1) {
vp_config.set_color_primaries(color_primaries_);
}
return vp_config;
} }
WebMParserClient* WebMVideoClient::OnListStart(int id) { WebMParserClient* WebMVideoClient::OnListStart(int id) {
@ -141,8 +162,7 @@ bool WebMVideoClient::OnListEnd(int id) {
} }
bool WebMVideoClient::OnUInt(int id, int64_t val) { bool WebMVideoClient::OnUInt(int id, int64_t val) {
VPCodecConfigurationRecord vp_config; int64_t* dst = nullptr;
int64_t* dst = NULL;
switch (id) { switch (id) {
case kWebMIdPixelWidth: case kWebMIdPixelWidth:
@ -176,10 +196,10 @@ bool WebMVideoClient::OnUInt(int id, int64_t val) {
dst = &alpha_mode_; dst = &alpha_mode_;
break; break;
case kWebMIdColorMatrixCoefficients: case kWebMIdColorMatrixCoefficients:
vp_config.set_matrix_coefficients(static_cast<uint8_t>(val)); dst = &matrix_coefficients_;
break; break;
case kWebMIdColorBitsPerChannel: case kWebMIdColorBitsPerChannel:
vp_config.set_bit_depth(static_cast<uint8_t>(val)); dst = &bits_per_channel_;
break; break;
case kWebMIdColorChromaSubsamplingHorz: case kWebMIdColorChromaSubsamplingHorz:
dst = &chroma_subsampling_horz_; dst = &chroma_subsampling_horz_;
@ -194,17 +214,13 @@ bool WebMVideoClient::OnUInt(int id, int64_t val) {
dst = &chroma_siting_vert_; dst = &chroma_siting_vert_;
break; break;
case kWebMIdColorRange: case kWebMIdColorRange:
if (val == 0) dst = &color_range_;
vp_config.set_video_full_range_flag(false);
else if (val == 1)
vp_config.set_video_full_range_flag(true);
// Ignore for other values of val.
break; break;
case kWebMIdColorTransferCharacteristics: case kWebMIdColorTransferCharacteristics:
vp_config.set_transfer_characteristics(static_cast<uint8_t>(val)); dst = &transfer_characteristics_;
break; break;
case kWebMIdColorPrimaries: case kWebMIdColorPrimaries:
vp_config.set_color_primaries(static_cast<uint8_t>(val)); dst = &color_primaries_;
break; break;
case kWebMIdColorMaxCLL: case kWebMIdColorMaxCLL:
case kWebMIdColorMaxFALL: case kWebMIdColorMaxFALL:

View File

@ -39,7 +39,7 @@ class WebMVideoClient : public WebMParserClient {
/// Extracts VPCodecConfigurationRecord parsed from codec private data and /// Extracts VPCodecConfigurationRecord parsed from codec private data and
/// Colour element. /// Colour element.
const VPCodecConfigurationRecord& GetVpCodecConfig( VPCodecConfigurationRecord GetVpCodecConfig(
const std::vector<uint8_t>& codec_private); const std::vector<uint8_t>& codec_private);
private: private:
@ -50,22 +50,26 @@ class WebMVideoClient : public WebMParserClient {
bool OnBinary(int id, const uint8_t* data, int size) override; bool OnBinary(int id, const uint8_t* data, int size) override;
bool OnFloat(int id, double val) override; bool OnFloat(int id, double val) override;
int64_t pixel_width_; int64_t pixel_width_ = -1;
int64_t pixel_height_; int64_t pixel_height_ = -1;
int64_t crop_bottom_; int64_t crop_bottom_ = -1;
int64_t crop_top_; int64_t crop_top_ = -1;
int64_t crop_left_; int64_t crop_left_ = -1;
int64_t crop_right_; int64_t crop_right_ = -1;
int64_t display_width_; int64_t display_width_ = -1;
int64_t display_height_; int64_t display_height_ = -1;
int64_t display_unit_; int64_t display_unit_ = -1;
int64_t alpha_mode_; int64_t alpha_mode_ = -1;
VPCodecConfigurationRecord vp_config_; int64_t matrix_coefficients_ = -1;
int64_t chroma_subsampling_horz_; int64_t bits_per_channel_ = -1;
int64_t chroma_subsampling_vert_; int64_t chroma_subsampling_horz_ = -1;
int64_t chroma_siting_horz_; int64_t chroma_subsampling_vert_ = -1;
int64_t chroma_siting_vert_; int64_t chroma_siting_horz_ = -1;
int64_t chroma_siting_vert_ = -1;
int64_t color_range_ = -1;
int64_t transfer_characteristics_ = -1;
int64_t color_primaries_ = -1;
DISALLOW_COPY_AND_ASSIGN(WebMVideoClient); DISALLOW_COPY_AND_ASSIGN(WebMVideoClient);
}; };

View File

@ -42,10 +42,8 @@ struct PackagingParams {
/// Chunking (segmentation) related parameters. /// Chunking (segmentation) related parameters.
ChunkingParams chunking_params; ChunkingParams chunking_params;
/// Manifest generation related parameters. Right now only one of /// Create a human readable format of MediaInfo. The output file name will be
/// `output_media_info`, `mpd_params` and `hls_params` should be set. Create a /// the name specified by output flag, suffixed with `.media_info`.
/// human readable format of MediaInfo. The output file name will be the name
/// specified by output flag, suffixed with `.media_info`.
bool output_media_info = false; bool output_media_info = false;
/// DASH MPD related parameters. /// DASH MPD related parameters.
MpdParams mpd_params; MpdParams mpd_params;