Bug 1411681 - Cherrypick 6728003bcf5657da8f9ed52ad84f46c1197ce54b from upstream webrtc.org; r=pehrsons
authorDan Minor <dminor@mozilla.com>
Tue, 20 Nov 2018 12:07:07 +0000
changeset 503634 de0a29776deed09faa072a9058b5415c1e0dad46
parent 503633 65510a1c9b0f76ffaf22db3255ffbd53681d4c24
child 503635 1d9d15e8e072fb3f54ad858a4b6eabae2e7d8479
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspehrsons
bugs1411681
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1411681 - Cherrypick 6728003bcf5657da8f9ed52ad84f46c1197ce54b from upstream webrtc.org; r=pehrsons Differential Revision: https://phabricator.services.mozilla.com/D12417
media/webrtc/trunk/webrtc/common_video/h264/sps_parser.cc
media/webrtc/trunk/webrtc/common_video/h264/sps_parser_unittest.cc
--- a/media/webrtc/trunk/webrtc/common_video/h264/sps_parser.cc
+++ b/media/webrtc/trunk/webrtc/common_video/h264/sps_parser.cc
@@ -89,33 +89,41 @@ rtc::Optional<SpsParser::SpsState> SpsPa
     // bit_depth_chroma_minus8: ue(v)
     RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
     // qpprime_y_zero_transform_bypass_flag: u(1)
     RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
     // seq_scaling_matrix_present_flag: u(1)
     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) {
-        RETURN_EMPTY_ON_FAIL(
-            buffer->ReadBits(&seq_scaling_list_present_flags, 8));
-      } else {
+      // 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, 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;
+          }
+        }
       }
     }
   }
   // log2_max_frame_num_minus4: ue(v)
   RETURN_EMPTY_ON_FAIL(
       buffer->ReadExponentialGolomb(&sps.log2_max_frame_num_minus4));
   // pic_order_cnt_type: ue(v)
   RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&sps.pic_order_cnt_type));
--- a/media/webrtc/trunk/webrtc/common_video/h264/sps_parser_unittest.cc
+++ b/media/webrtc/trunk/webrtc/common_video/h264/sps_parser_unittest.cc
@@ -166,9 +166,22 @@ TEST_F(H264SpsParserTest, TestSyntheticS
   GenerateFakeSps(156u, 122u, 2, &buffer);
   EXPECT_TRUE(static_cast<bool>(
       sps_ = SpsParser::ParseSps(buffer.data(), buffer.size())));
   EXPECT_EQ(156u, sps_->width);
   EXPECT_EQ(122u, sps_->height);
   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<bool>(sps_ = SpsParser::ParseSps(buffer, arraysize(buffer))));
+  EXPECT_EQ(1920u, sps_->width);
+  EXPECT_EQ(1080u, sps_->height);
+}
+
 }  // namespace webrtc