From 94a64bef039b22acdac4cb8e98c186f1bfe4de4b Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Fri, 6 Oct 2017 11:14:40 -0700 Subject: [PATCH] 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 --- .../media/formats/webm/webm_video_client.cc | 62 ++++++++++++------- .../media/formats/webm/webm_video_client.h | 36 ++++++----- packager/packager.h | 6 +- 3 files changed, 61 insertions(+), 43 deletions(-) diff --git a/packager/media/formats/webm/webm_video_client.cc b/packager/media/formats/webm/webm_video_client.cc index d9fda12e9a..da52a68ed7 100644 --- a/packager/media/formats/webm/webm_video_client.cc +++ b/packager/media/formats/webm/webm_video_client.cc @@ -27,12 +27,9 @@ int64_t GetGreatestCommonDivisor(int64_t a, int64_t b) { namespace shaka { namespace media { -WebMVideoClient::WebMVideoClient() { - Reset(); -} +WebMVideoClient::WebMVideoClient() {} -WebMVideoClient::~WebMVideoClient() { -} +WebMVideoClient::~WebMVideoClient() {} void WebMVideoClient::Reset() { pixel_width_ = -1; @@ -46,11 +43,15 @@ void WebMVideoClient::Reset() { display_unit_ = -1; alpha_mode_ = -1; - vp_config_ = VPCodecConfigurationRecord(); + matrix_coefficients_ = -1; + bits_per_channel_ = -1; chroma_subsampling_horz_ = -1; chroma_subsampling_vert_ = -1; chroma_siting_horz_ = -1; chroma_siting_vert_ = -1; + color_range_ = -1; + transfer_characteristics_ = -1; + color_primaries_ = -1; } std::shared_ptr WebMVideoClient::GetVideoStreamInfo( @@ -119,17 +120,37 @@ std::shared_ptr WebMVideoClient::GetVideoStreamInfo( sar_y, 0, 0, std::string(), is_encrypted); } -const VPCodecConfigurationRecord& WebMVideoClient::GetVpCodecConfig( +VPCodecConfigurationRecord WebMVideoClient::GetVpCodecConfig( const std::vector& 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) { - vp_config_.SetChromaSubsampling(chroma_subsampling_horz_, - chroma_subsampling_vert_); + vp_config.SetChromaSubsampling(chroma_subsampling_horz_, + chroma_subsampling_vert_); } 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) { @@ -141,8 +162,7 @@ bool WebMVideoClient::OnListEnd(int id) { } bool WebMVideoClient::OnUInt(int id, int64_t val) { - VPCodecConfigurationRecord vp_config; - int64_t* dst = NULL; + int64_t* dst = nullptr; switch (id) { case kWebMIdPixelWidth: @@ -176,10 +196,10 @@ bool WebMVideoClient::OnUInt(int id, int64_t val) { dst = &alpha_mode_; break; case kWebMIdColorMatrixCoefficients: - vp_config.set_matrix_coefficients(static_cast(val)); + dst = &matrix_coefficients_; break; case kWebMIdColorBitsPerChannel: - vp_config.set_bit_depth(static_cast(val)); + dst = &bits_per_channel_; break; case kWebMIdColorChromaSubsamplingHorz: dst = &chroma_subsampling_horz_; @@ -194,17 +214,13 @@ bool WebMVideoClient::OnUInt(int id, int64_t val) { dst = &chroma_siting_vert_; break; case kWebMIdColorRange: - if (val == 0) - 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. + dst = &color_range_; break; case kWebMIdColorTransferCharacteristics: - vp_config.set_transfer_characteristics(static_cast(val)); + dst = &transfer_characteristics_; break; case kWebMIdColorPrimaries: - vp_config.set_color_primaries(static_cast(val)); + dst = &color_primaries_; break; case kWebMIdColorMaxCLL: case kWebMIdColorMaxFALL: diff --git a/packager/media/formats/webm/webm_video_client.h b/packager/media/formats/webm/webm_video_client.h index 3a146d91a9..308855c45e 100644 --- a/packager/media/formats/webm/webm_video_client.h +++ b/packager/media/formats/webm/webm_video_client.h @@ -39,7 +39,7 @@ class WebMVideoClient : public WebMParserClient { /// Extracts VPCodecConfigurationRecord parsed from codec private data and /// Colour element. - const VPCodecConfigurationRecord& GetVpCodecConfig( + VPCodecConfigurationRecord GetVpCodecConfig( const std::vector& codec_private); private: @@ -50,22 +50,26 @@ class WebMVideoClient : public WebMParserClient { bool OnBinary(int id, const uint8_t* data, int size) override; bool OnFloat(int id, double val) override; - int64_t pixel_width_; - int64_t pixel_height_; - int64_t crop_bottom_; - int64_t crop_top_; - int64_t crop_left_; - int64_t crop_right_; - int64_t display_width_; - int64_t display_height_; - int64_t display_unit_; - int64_t alpha_mode_; + int64_t pixel_width_ = -1; + int64_t pixel_height_ = -1; + int64_t crop_bottom_ = -1; + int64_t crop_top_ = -1; + int64_t crop_left_ = -1; + int64_t crop_right_ = -1; + int64_t display_width_ = -1; + int64_t display_height_ = -1; + int64_t display_unit_ = -1; + int64_t alpha_mode_ = -1; - VPCodecConfigurationRecord vp_config_; - int64_t chroma_subsampling_horz_; - int64_t chroma_subsampling_vert_; - int64_t chroma_siting_horz_; - int64_t chroma_siting_vert_; + int64_t matrix_coefficients_ = -1; + int64_t bits_per_channel_ = -1; + int64_t chroma_subsampling_horz_ = -1; + int64_t chroma_subsampling_vert_ = -1; + 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); }; diff --git a/packager/packager.h b/packager/packager.h index 46ed24ffa0..c9df36b983 100644 --- a/packager/packager.h +++ b/packager/packager.h @@ -42,10 +42,8 @@ struct PackagingParams { /// Chunking (segmentation) related parameters. ChunkingParams chunking_params; - /// Manifest generation related parameters. Right now only one of - /// `output_media_info`, `mpd_params` and `hls_params` should be set. Create a - /// human readable format of MediaInfo. The output file name will be the name - /// specified by output flag, suffixed with `.media_info`. + /// Create a 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; /// DASH MPD related parameters. MpdParams mpd_params;