Fix possible incorrect resolutions with avc3

The resolution values are uninitialized when parsing AVC decoder
configuration record if it does not contain parameter sets (SPS/PPS),
thus they could contain undefined values.

Fixes #750.

Change-Id: I6d54ec9f8740acd45a67b4b7d69031e097fbacc1
This commit is contained in:
KongQun Yang 2020-06-02 13:11:29 -07:00
parent 94f85a45ba
commit 6f10badd5d
3 changed files with 41 additions and 14 deletions

View File

@ -15,13 +15,9 @@
namespace shaka { namespace shaka {
namespace media { namespace media {
AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() = default;
: version_(0),
profile_indication_(0),
profile_compatibility_(0),
avc_level_(0) {}
AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() {} AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() = default;
bool AVCDecoderConfigurationRecord::ParseInternal() { bool AVCDecoderConfigurationRecord::ParseInternal() {
// See ISO 14496-15 sec 5.3.3.1.2 // See ISO 14496-15 sec 5.3.3.1.2

View File

@ -46,16 +46,16 @@ class AVCDecoderConfigurationRecord : public DecoderConfigurationRecord {
private: private:
bool ParseInternal() override; bool ParseInternal() override;
uint8_t version_; uint8_t version_ = 0;
uint8_t profile_indication_; uint8_t profile_indication_ = 0;
uint8_t profile_compatibility_; uint8_t profile_compatibility_ = 0;
uint8_t avc_level_; uint8_t avc_level_ = 0;
// Extracted from SPS. // Extracted from SPS.
uint32_t coded_width_; uint32_t coded_width_ = 0;
uint32_t coded_height_; uint32_t coded_height_ = 0;
uint32_t pixel_width_; uint32_t pixel_width_ = 0;
uint32_t pixel_height_; uint32_t pixel_height_ = 0;
DISALLOW_COPY_AND_ASSIGN(AVCDecoderConfigurationRecord); DISALLOW_COPY_AND_ASSIGN(AVCDecoderConfigurationRecord);
}; };

View File

@ -90,6 +90,37 @@ TEST(AVCDecoderConfigurationRecordTest, SuccessWithTransferCharacteristics) {
EXPECT_EQ("avc3.64001e", avc_config.GetCodecString(FOURCC_avc3)); EXPECT_EQ("avc3.64001e", avc_config.GetCodecString(FOURCC_avc3));
} }
TEST(AVCDecoderConfigurationRecordTest, SuccessWithNoParameterSets) {
// clang-format off
const uint8_t kAvcDecoderConfigurationData[] = {
0x01, // version
0x64, // profile_indication
0x00, // profile_compatibility
0x1E, // avc_level
0xFF, // Least significant 3 bits is length_size_minus_one
0xE0, // Least significant 5 bits is num_sps
0x00, // num_pps
};
// clang-format on
AVCDecoderConfigurationRecord avc_config;
ASSERT_TRUE(avc_config.Parse(kAvcDecoderConfigurationData,
arraysize(kAvcDecoderConfigurationData)));
EXPECT_EQ(1u, avc_config.version());
EXPECT_EQ(0x64, avc_config.profile_indication());
EXPECT_EQ(0u, avc_config.profile_compatibility());
EXPECT_EQ(0x1E, avc_config.avc_level());
EXPECT_EQ(4u, avc_config.nalu_length_size());
EXPECT_EQ(0u, avc_config.coded_width());
EXPECT_EQ(0u, avc_config.coded_height());
EXPECT_EQ(0u, avc_config.pixel_width());
EXPECT_EQ(0u, avc_config.pixel_height());
EXPECT_EQ(0u, avc_config.transfer_characteristics());
EXPECT_EQ("avc3.64001e", avc_config.GetCodecString(FOURCC_avc3));
}
TEST(AVCDecoderConfigurationRecordTest, FailsOnInvalidNaluLengthSize) { TEST(AVCDecoderConfigurationRecordTest, FailsOnInvalidNaluLengthSize) {
// clang-format off // clang-format off
const uint8_t kAvcDecoderConfigurationData[] = { const uint8_t kAvcDecoderConfigurationData[] = {