diff --git a/media/webrtc/trunk/webrtc/common_video/h264/sps_parser.cc b/media/webrtc/trunk/webrtc/common_video/h264/sps_parser.cc index 946c68574e45..1b9f0cd52131 100644 --- a/media/webrtc/trunk/webrtc/common_video/h264/sps_parser.cc +++ b/media/webrtc/trunk/webrtc/common_video/h264/sps_parser.cc @@ -94,23 +94,31 @@ rtc::Optional SpsParser::ParseSpsUpToVui( uint32_t seq_scaling_matrix_present_flag; RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&seq_scaling_matrix_present_flag, 1)); if (seq_scaling_matrix_present_flag) { - // seq_scaling_list_present_flags. Either 8 or 12, depending on - // chroma_format_idc. - uint32_t seq_scaling_list_present_flags; - if (chroma_format_idc != 3) { + // Process the scaling lists just enough to be able to properly + // skip over them, so we can still read the resolution on streams + // where this is included. + int scaling_list_count = (chroma_format_idc == 3 ? 12 : 8); + for (int i = 0; i < scaling_list_count; ++i) { + // seq_scaling_list_present_flag[i] : u(1) + uint32_t seq_scaling_list_present_flags; RETURN_EMPTY_ON_FAIL( - buffer->ReadBits(&seq_scaling_list_present_flags, 8)); - } else { - RETURN_EMPTY_ON_FAIL( - buffer->ReadBits(&seq_scaling_list_present_flags, 12)); - } - // We don't support reading the sequence scaling list, and we don't really - // see/use them in practice, so we'll just reject the full sps if we see - // any provided. - if (seq_scaling_list_present_flags > 0) { - RTC_LOG(LS_WARNING) - << "SPS contains scaling lists, which are unsupported."; - return OptionalSps(); + buffer->ReadBits(&seq_scaling_list_present_flags, 1)); + if (seq_scaling_list_present_flags != 0) { + int last_scale = 8; + int next_scale = 8; + int size_of_scaling_list = i < 6 ? 16 : 64; + for (int j = 0; j < size_of_scaling_list; j++) { + if (next_scale != 0) { + int32_t delta_scale; + // delta_scale: se(v) + RETURN_EMPTY_ON_FAIL( + buffer->ReadSignedExponentialGolomb(&delta_scale)); + next_scale = (last_scale + delta_scale + 256) % 256; + } + if (next_scale != 0) + last_scale = next_scale; + } + } } } } diff --git a/media/webrtc/trunk/webrtc/common_video/h264/sps_parser_unittest.cc b/media/webrtc/trunk/webrtc/common_video/h264/sps_parser_unittest.cc index e982449c88e7..39e6f2e36267 100644 --- a/media/webrtc/trunk/webrtc/common_video/h264/sps_parser_unittest.cc +++ b/media/webrtc/trunk/webrtc/common_video/h264/sps_parser_unittest.cc @@ -171,4 +171,17 @@ TEST_F(H264SpsParserTest, TestSyntheticSPSWeirdResolution) { EXPECT_EQ(2u, sps_->id); } +TEST_F(H264SpsParserTest, TestSampleSPSWithScalingLists) { + // SPS from a 1920x1080 video. Contains scaling lists (and veritcal cropping). + const uint8_t buffer[] = {0x64, 0x00, 0x2a, 0xad, 0x84, 0x01, 0x0c, 0x20, + 0x08, 0x61, 0x00, 0x43, 0x08, 0x02, 0x18, 0x40, + 0x10, 0xc2, 0x00, 0x84, 0x3b, 0x50, 0x3c, 0x01, + 0x13, 0xf2, 0xcd, 0xc0, 0x40, 0x40, 0x50, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xe8, 0x40}; + EXPECT_TRUE( + static_cast(sps_ = SpsParser::ParseSps(buffer, arraysize(buffer)))); + EXPECT_EQ(1920u, sps_->width); + EXPECT_EQ(1080u, sps_->height); +} + } // namespace webrtc