tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

h265_bitstream_parser_unittest.cc (9262B)


      1 /*
      2 *  Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "common_video/h265/h265_bitstream_parser.h"
     12 
     13 #include <cstdint>
     14 #include <optional>
     15 
     16 #include "api/array_view.h"
     17 #include "common_video/h265/h265_common.h"
     18 #include "test/gmock.h"
     19 #include "test/gtest.h"
     20 
     21 using ::testing::Eq;
     22 using ::testing::Optional;
     23 
     24 namespace webrtc {
     25 
     26 // VPS/SPS/PPS part of below chunk.
     27 constexpr uint8_t kH265VpsSpsPps[] = {
     28    0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x04, 0x08,
     29    0x00, 0x00, 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78,
     30    0x95, 0x98, 0x09, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x04, 0x08,
     31    0x00, 0x00, 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78,
     32    0xb0, 0x03, 0xc0, 0x80, 0x10, 0xe5, 0x96, 0x56, 0x69, 0x24, 0xca, 0xe0,
     33    0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x01, 0xe0, 0x80,
     34    0x00, 0x00, 0x00, 0x01, 0x44, 0x01, 0xc1, 0x72, 0xb4, 0x62, 0x40};
     35 
     36 // Contains enough of the image slice to contain slice QP.
     37 constexpr uint8_t kH265BitstreamChunk[] = {
     38    0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x04, 0x08,
     39    0x00, 0x00, 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78,
     40    0x95, 0x98, 0x09, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x04, 0x08,
     41    0x00, 0x00, 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78,
     42    0xb0, 0x03, 0xc0, 0x80, 0x10, 0xe5, 0x96, 0x56, 0x69, 0x24, 0xca, 0xe0,
     43    0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x01, 0xe0, 0x80,
     44    0x00, 0x00, 0x00, 0x01, 0x44, 0x01, 0xc1, 0x72, 0xb4, 0x62, 0x40, 0x00,
     45    0x00, 0x01, 0x26, 0x01, 0xaf, 0x08, 0x42, 0x23, 0x10, 0x5d, 0x2b, 0x51,
     46    0xf9, 0x7a, 0x55, 0x15, 0x0d, 0x10, 0x40, 0xe8, 0x10, 0x05, 0x30, 0x95,
     47    0x09, 0x9a, 0xa5, 0xb6, 0x6a, 0x66, 0x6d, 0xde, 0xe0, 0xf9,
     48 };
     49 
     50 // Contains enough of the image slice to contain slice QP.
     51 constexpr uint8_t kH265BitstreamNextImageSliceChunk[] = {
     52    0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xe0, 0x24, 0xbf, 0x82, 0x05,
     53    0x21, 0x12, 0x22, 0xa3, 0x29, 0xb4, 0x21, 0x91, 0xa1, 0xaa, 0x40,
     54 };
     55 
     56 // Contains enough of the image slice to contain slice QP.
     57 constexpr uint8_t kH265SliceChunk[] = {
     58    0xa4, 0x04, 0x55, 0xa2, 0x6d, 0xce, 0xc0, 0xc3, 0xed, 0x0b, 0xac, 0xbc,
     59    0x00, 0xc4, 0x44, 0x2e, 0xf7, 0x55, 0xfd, 0x05, 0x86, 0x92, 0x19, 0xdf,
     60    0x58, 0xec, 0x38, 0x36, 0xb7, 0x7c, 0x00, 0x15, 0x33, 0x78, 0x03, 0x67,
     61    0x26, 0x0f, 0x7b, 0x30, 0x1c, 0xd7, 0xd4, 0x3a, 0xec, 0xad, 0xef, 0x73,
     62 };
     63 
     64 // Contains enough of data for the second slice of a frame.
     65 constexpr uint8_t kH265SecondSliceChunkInAFrame[] = {
     66    0x02, 0x01, 0x23, 0xfc, 0x20, 0x22, 0xad, 0x13, 0x68, 0xce, 0xc3, 0x5a,
     67    0x00, 0xdc, 0xeb, 0x86, 0x4b, 0x0b, 0xa7, 0x6a, 0xe1, 0x9c, 0x5c, 0xea,
     68 };
     69 
     70 // Contains short term ref pic set slice to verify Log2Ceiling path.
     71 constexpr uint8_t kH265SliceStrChunk[] = {
     72    0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x00,
     73    0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
     74    0x00, 0x99, 0x94, 0x90, 0x24, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01,
     75    0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
     76    0x03, 0x00, 0x00, 0x99, 0xa0, 0x01, 0x40, 0x20, 0x06, 0x41, 0xfe, 0x59,
     77    0x49, 0x26, 0x4d, 0x86, 0x16, 0x22, 0xaa, 0x4c, 0x4c, 0x32, 0xfb, 0x3e,
     78    0xbc, 0xdf, 0x96, 0x7d, 0x78, 0x51, 0x18, 0x9c, 0xbb, 0x20, 0x00, 0x00,
     79    0x00, 0x01, 0x44, 0x01, 0xc1, 0xa5, 0x58, 0x11, 0x20, 0x00, 0x00, 0x01,
     80    0x02, 0x01, 0xe1, 0x18, 0xfe, 0x47, 0x60, 0xd2, 0x74, 0xd6, 0x9f, 0xfc,
     81    0xbe, 0x6b, 0x15, 0x48, 0x59, 0x1f, 0xf7, 0xc1, 0x7c, 0xe2, 0xe8, 0x10,
     82 };
     83 
     84 // Contains enough of the image slice to contain invalid slice QP -52.
     85 constexpr uint8_t kH265BitstreamInvalidQPChunk[] = {
     86    0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x04, 0x08,
     87    0x00, 0x00, 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78,
     88    0x95, 0x98, 0x09, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x04, 0x08,
     89    0x00, 0x00, 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78,
     90    0xb0, 0x03, 0xc0, 0x80, 0x10, 0xe5, 0x96, 0x56, 0x69, 0x24, 0xca, 0xe0,
     91    0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x01, 0xe0, 0x80,
     92    0x00, 0x00, 0x00, 0x01, 0x44, 0x01, 0xc1, 0x72, 0xb4, 0x62, 0x40, 0x00,
     93    0x00, 0x01, 0x26, 0x01, 0xaf, 0x03, 0x4c,
     94 };
     95 
     96 // Contains enough of the image slice to contain invalid slice QP 52.
     97 constexpr uint8_t kH265BitstreamInvalidQPChunk52[] = {
     98    0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x04, 0x08,
     99    0x00, 0x00, 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78,
    100    0x95, 0x98, 0x09, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x04, 0x08,
    101    0x00, 0x00, 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78,
    102    0xb0, 0x03, 0xc0, 0x80, 0x10, 0xe5, 0x96, 0x56, 0x69, 0x24, 0xca, 0xe0,
    103    0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x01, 0xe0, 0x80,
    104    0x00, 0x00, 0x00, 0x01, 0x44, 0x01, 0xc1, 0x72, 0xb4, 0x62, 0x40, 0x00,
    105    0x00, 0x01, 0x26, 0x01, 0xaf, 0x03, 0x44,
    106 };
    107 
    108 // Bitstream that contains pred_weight_table. Contains enough data to parse
    109 // over pred_weight_table for slice QP. This is bear.hevc from Chromium source,
    110 // used for H265 hardware decoder's parser test, with some slices truncated.
    111 constexpr uint8_t kH265BitstreamWithPredWeightTable[] = {
    112    0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0c, 0x01, 0xff, 0xff, 0x01, 0x60,
    113    0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00,
    114    0x3c, 0x95, 0xc0, 0x90, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x01,
    115    0x60, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03,
    116    0x00, 0x3c, 0xa0, 0x0a, 0x08, 0x0b, 0x9f, 0x79, 0x65, 0x79, 0x24, 0xca,
    117    0xe0, 0x10, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0xbb, 0x50, 0x80, 0x00,
    118    0x00, 0x00, 0x01, 0x44, 0x01, 0xc1, 0x73, 0xd1, 0x89, 0x00, 0x00, 0x00,
    119    0x01, 0x02, 0x01, 0xd0, 0x21, 0x49, 0xe8, 0xee, 0x50, 0x9c, 0x27, 0x20,
    120    0x42, 0xc4, 0xcd, 0x33, 0xf0, 0xb1, 0x23, 0x7b, 0xfe, 0x4d, 0xcf, 0x40,
    121    0xeb, 0x17, 0x37, 0x91, 0x1c, 0xb6, 0xba, 0x21, 0x42, 0xf7, 0xef, 0x01,
    122    0x08, 0x90, 0x49, 0xdc, 0xfc, 0x10, 0x1f, 0x5e, 0x02, 0xd9, 0xaa, 0xe8,
    123    0x32, 0xeb, 0x74, 0xbc, 0xdb, 0x2c, 0xa3, 0xec,
    124 };
    125 
    126 TEST(H265BitstreamParserTest, ReportsNoQpWithoutParsedSlices) {
    127  H265BitstreamParser h265_parser;
    128  EXPECT_FALSE(h265_parser.GetLastSliceQp().has_value());
    129 }
    130 
    131 TEST(H265BitstreamParserTest, ReportsNoQpWithOnlyParsedPpsAndSpsSlices) {
    132  H265BitstreamParser h265_parser;
    133  h265_parser.ParseBitstream(kH265VpsSpsPps);
    134  EXPECT_FALSE(h265_parser.GetLastSliceQp().has_value());
    135 }
    136 
    137 TEST(H265BitstreamParserTest, ReportQpWithPredWeightTable) {
    138  H265BitstreamParser h265_parser;
    139  h265_parser.ParseBitstream(kH265BitstreamWithPredWeightTable);
    140  std::optional<int> qp = h265_parser.GetLastSliceQp();
    141  ASSERT_TRUE(qp.has_value());
    142  EXPECT_EQ(34, *qp);
    143 }
    144 
    145 TEST(H265BitstreamParserTest, ReportsLastSliceQpForImageSlices) {
    146  H265BitstreamParser h265_parser;
    147  h265_parser.ParseBitstream(kH265BitstreamChunk);
    148  std::optional<int> qp = h265_parser.GetLastSliceQp();
    149  ASSERT_TRUE(qp.has_value());
    150  EXPECT_EQ(34, *qp);
    151 
    152  // Parse an additional image slice.
    153  h265_parser.ParseBitstream(kH265BitstreamNextImageSliceChunk);
    154  qp = h265_parser.GetLastSliceQp();
    155  ASSERT_TRUE(qp.has_value());
    156  EXPECT_EQ(36, *qp);
    157 }
    158 
    159 TEST(H265BitstreamParserTest, ReportsLastSliceQpFromShortTermReferenceSlices) {
    160  H265BitstreamParser h265_parser;
    161  h265_parser.ParseBitstream(kH265SliceStrChunk);
    162  std::optional<int> qp = h265_parser.GetLastSliceQp();
    163  ASSERT_TRUE(qp.has_value());
    164  EXPECT_EQ(33, *qp);
    165 }
    166 
    167 TEST(H265BitstreamParserTest, PpsIdFromSlice) {
    168  std::optional<uint32_t> pps_id =
    169      H265BitstreamParser::ParsePpsIdFromSliceSegmentLayerRbsp(
    170          kH265SliceChunk, H265::NaluType::kTrailR);
    171  ASSERT_TRUE(pps_id);
    172  EXPECT_EQ(1u, *pps_id);
    173 }
    174 
    175 TEST(H265BitstreamParserTest, ReportsLastSliceQpInvalidQPSlices) {
    176  H265BitstreamParser h265_parser;
    177  h265_parser.ParseBitstream(kH265BitstreamInvalidQPChunk);
    178  std::optional<int> qp = h265_parser.GetLastSliceQp();
    179  ASSERT_FALSE(qp.has_value());
    180 
    181  h265_parser.ParseBitstream(kH265BitstreamInvalidQPChunk52);
    182  qp = h265_parser.GetLastSliceQp();
    183  ASSERT_FALSE(qp.has_value());
    184 }
    185 
    186 TEST(H265BitstreamParserTest, ReportsFirstSliceSegmentInPic) {
    187  EXPECT_THAT(H265BitstreamParser::IsFirstSliceSegmentInPic(kH265SliceChunk),
    188              Optional(Eq(true)));
    189 }
    190 
    191 TEST(H265BitstreamParserTest, ReportsFirstSliceSegmentInPicFalse) {
    192  EXPECT_THAT(H265BitstreamParser::IsFirstSliceSegmentInPic(
    193                  kH265SecondSliceChunkInAFrame),
    194              Optional(Eq(false)));
    195 }
    196 
    197 TEST(H265BitstreamParserTest, ReportsFirstSliceSegmentInPicParseInvalidSlice) {
    198  ArrayView<const uint8_t> slice_data(kH265SliceChunk);
    199  EXPECT_THAT(
    200      H265BitstreamParser::IsFirstSliceSegmentInPic(slice_data.subview(50)),
    201      Eq(std::nullopt));
    202 }
    203 
    204 }  // namespace webrtc