h264_bitstream_parser_unittest.cc (8364B)
1 /* 2 * Copyright (c) 2015 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/h264/h264_bitstream_parser.h" 12 13 #include <cstdint> 14 #include <optional> 15 16 #include "test/gtest.h" 17 18 namespace webrtc { 19 20 // SPS/PPS part of below chunk. 21 uint8_t kH264SpsPps[] = {0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x80, 0x20, 0xda, 22 0x01, 0x40, 0x16, 0xe8, 0x06, 0xd0, 0xa1, 0x35, 0x00, 23 0x00, 0x00, 0x01, 0x68, 0xce, 0x06, 0xe2}; 24 25 // Contains enough of the image slice to contain slice QP. 26 uint8_t kH264BitstreamChunk[] = { 27 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x80, 0x20, 0xda, 0x01, 0x40, 0x16, 28 0xe8, 0x06, 0xd0, 0xa1, 0x35, 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x06, 29 0xe2, 0x00, 0x00, 0x00, 0x01, 0x65, 0xb8, 0x40, 0xf0, 0x8c, 0x03, 0xf2, 30 0x75, 0x67, 0xad, 0x41, 0x64, 0x24, 0x0e, 0xa0, 0xb2, 0x12, 0x1e, 0xf8, 31 }; 32 33 uint8_t kH264BitstreamChunkCabac[] = { 34 0x00, 0x00, 0x00, 0x01, 0x27, 0x64, 0x00, 0x0d, 0xac, 0x52, 0x30, 35 0x50, 0x7e, 0xc0, 0x5a, 0x81, 0x01, 0x01, 0x18, 0x56, 0xbd, 0xef, 36 0x80, 0x80, 0x00, 0x00, 0x00, 0x01, 0x28, 0xfe, 0x09, 0x8b, 37 }; 38 39 // Contains enough of the image slice to contain slice QP. 40 uint8_t kH264BitstreamNextImageSliceChunk[] = { 41 0x00, 0x00, 0x00, 0x01, 0x41, 0xe2, 0x01, 0x16, 0x0e, 0x3e, 0x2b, 0x86, 42 }; 43 44 // Contains enough of the image slice to contain slice QP. 45 uint8_t kH264BitstreamNextImageSliceChunkCabac[] = { 46 0x00, 0x00, 0x00, 0x01, 0x21, 0xe1, 0x05, 0x11, 0x3f, 0x9a, 0xae, 0x46, 47 0x70, 0xbf, 0xc1, 0x4a, 0x16, 0x8f, 0x51, 0xf4, 0xca, 0xfb, 0xa3, 0x65, 48 }; 49 50 uint8_t kH264BitstreamWeightedPred[] = { 51 0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x28, 0xac, 0xb4, 0x03, 0xc0, 52 0x11, 0x3f, 0x2e, 0x02, 0xd4, 0x04, 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 53 0x01, 0x00, 0x00, 0x03, 0x00, 0x30, 0x8f, 0x18, 0x32, 0xa0, 0x00, 0x00, 54 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x68, 0xef, 0x3c, 0xb0, 0x00, 0x00, 55 0x00, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x26, 0x21, 0xf7, 0xff, 56 0xfe, 0x9e, 0x10, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x12}; 57 58 // First 4 P frames of CVWP1_TOSHIBA_E test file. 59 uint8_t H264BitstreamCVWP1SPS[] = {0x00, 0x00, 0x00, 0x01, 0x27, 0x4d, 0x40, 60 0x14, 0xd9, 0x81, 0x60, 0x94, 0x40}; 61 62 uint8_t H264BitstreamCVWP1PFrame1[] = { 63 0x00, 0x00, 0x00, 0x01, 0x28, 0xcf, 0x1b, 0x88, 0x00, 0x00, 0x00, 64 0x01, 0x21, 0x9a, 0x21, 0x8f, 0x02, 0xd8, 0x1b, 0xe0, 0x2c, 0xc3, 65 0x80, 0x20, 0x00, 0xe4, 0xcd, 0x72, 0xfe, 0x1c, 0xfc, 0x2a, 0x00, 66 0x02, 0x00, 0x26, 0x09, 0x04, 0xc1, 0x38, 0xe2, 0x9b, 0xcc, 0x60, 67 0x54, 0xee, 0x62, 0x6b, 0x00, 0x28, 0x86, 0xce, 0x81, 0x0f, 0xd2, 68 0x17, 0x26, 0x0d, 0x2f, 0x1c, 0x1d, 0xe3, 0x80, 0x01}; 69 70 uint8_t H264BitstreamCVWP1PFrame2[] = { 71 0x00, 0x00, 0x00, 0x01, 0x28, 0xca, 0xc6, 0xe2, 0x00, 0x00, 0x00, 72 0x01, 0x21, 0x9a, 0x41, 0xcb, 0x01, 0x8e, 0x02, 0x76, 0x28, 0x68, 73 0x20, 0x01, 0x9a, 0x33, 0x60, 0x58, 0xc3, 0x0d, 0x7c, 0x32, 0x00, 74 0x02, 0x00, 0x7c, 0x5d, 0xf7, 0x22, 0x6c, 0x3d, 0xa3, 0xcc, 0x60, 75 0x5a, 0x3d, 0x98, 0x3b, 0xf0, 0x14, 0x48, 0x1b, 0xa0, 0xdf, 0x69, 76 0xfc, 0xf2, 0x66, 0x21, 0x4d, 0x72, 0x99, 0xc2, 0x1c}; 77 78 uint8_t H264BitstreamCVWP1PFrame3[] = { 79 0x00, 0x00, 0x00, 0x01, 0x28, 0xcb, 0xc6, 0xe2, 0x00, 0x00, 0x00, 80 0x01, 0x21, 0x9a, 0x61, 0xcf, 0x04, 0xc0, 0x24, 0x20, 0x33, 0xc0, 81 0x5d, 0x80, 0x80, 0x05, 0x08, 0x0a, 0xb0, 0x30, 0x81, 0xf8, 0x0d, 82 0x70, 0x13, 0xa0, 0x31, 0x8e, 0x86, 0x94, 0x6c, 0x43, 0xbb, 0x58, 83 0x44, 0xc2, 0x41, 0x7c, 0x92, 0x04, 0x7e, 0x9f, 0xbf, 0x01, 0xe9, 84 0xab, 0x53, 0xfe, 0x8f, 0x1c, 0x00, 0x04, 0x1f, 0x23}; 85 86 uint8_t H264BitstreamCVWP1PFrame4[] = { 87 0x00, 0x00, 0x00, 0x01, 0x28, 0xc9, 0x31, 0xb8, 0x80, 0x00, 0x00, 88 0x00, 0x01, 0x21, 0x9a, 0x81, 0xe1, 0x04, 0xe0, 0x4f, 0x0f, 0x12, 89 0xc6, 0x58, 0x74, 0x34, 0x06, 0x73, 0x9f, 0x43, 0xa7, 0xd0, 0x3c, 90 0x9c, 0x9c, 0x92, 0x4f, 0x84, 0x4f, 0xd6, 0x36, 0x63, 0xff, 0xa0, 91 0x5b, 0x1c, 0x6f, 0x01, 0x0b, 0xc2, 0x5e, 0x7b, 0xb0, 0xd7, 0x8f, 92 0x19, 0x70, 0x81, 0xfa, 0x93, 0x4d, 0x48, 0x4f, 0xd2}; 93 94 // First 2 B frames of CVWP2_TOSHIBA_E test file. 95 uint8_t H264BitstreamCVWP2SPS[] = {0x00, 0x00, 0x00, 0x01, 0x27, 0x4d, 0x40, 96 0x14, 0xec, 0xc0, 0xb0, 0x4a, 0x20}; 97 98 uint8_t H264BitstreamCVWP2BFrame1[] = { 99 0x00, 0x00, 0x00, 0x01, 0x28, 0xce, 0x1b, 0x88, 0x00, 0x00, 0x00, 100 0x01, 0x01, 0x9a, 0x3e, 0x19, 0x69, 0xa1, 0xc4, 0x1e, 0x5d, 0xea, 101 0x84, 0x1c, 0x10, 0x65, 0x87, 0xc0, 0x25, 0x1b, 0x6d, 0x1e, 0xcf, 102 0xf9, 0x8d, 0xf1, 0x2f, 0xec, 0xf8, 0xc2, 0x07, 0xfe, 0x02, 0x27, 103 0xec, 0xcb, 0x74, 0x75, 0x59, 0xd5, 0x6e, 0xc0, 0x01, 0x4b, 0xb2, 104 0xe7, 0x68, 0xfe, 0xef, 0xaf, 0xb6, 0x76, 0xc6, 0xc5}; 105 106 uint8_t H264BitstreamCVWP2BFrame2[] = { 107 0x00, 0x00, 0x00, 0x01, 0x28, 0xce, 0x1b, 0x88, 0x00, 0x00, 0x00, 108 0x01, 0x01, 0x9a, 0x3e, 0x19, 0x69, 0xa1, 0xc4, 0x1e, 0x5d, 0xea, 109 0x84, 0x1c, 0x10, 0x65, 0x87, 0xc0, 0x25, 0x1b, 0x6d, 0x1e, 0xcf, 110 0xf9, 0x8d, 0xf1, 0x2f, 0xec, 0xf8, 0xc2, 0x07, 0xfe, 0x02, 0x27, 111 0xec, 0xcb, 0x74, 0x75, 0x59, 0xd5, 0x6e, 0xc0, 0x01, 0x4b, 0xb2, 112 0xe7, 0x68, 0xfe, 0xef, 0xaf, 0xb6, 0x76, 0xc6, 0xc5}; 113 114 TEST(H264BitstreamParserTest, ReportsNoQpWithoutParsedSlices) { 115 H264BitstreamParser h264_parser; 116 EXPECT_FALSE(h264_parser.GetLastSliceQp().has_value()); 117 } 118 119 TEST(H264BitstreamParserTest, ReportsNoQpWithOnlyParsedPpsAndSpsSlices) { 120 H264BitstreamParser h264_parser; 121 h264_parser.ParseBitstream(kH264SpsPps); 122 EXPECT_FALSE(h264_parser.GetLastSliceQp().has_value()); 123 } 124 125 TEST(H264BitstreamParserTest, ReportsLastSliceQpForImageSlices) { 126 H264BitstreamParser h264_parser; 127 h264_parser.ParseBitstream(kH264BitstreamChunk); 128 std::optional<int> qp = h264_parser.GetLastSliceQp(); 129 ASSERT_TRUE(qp.has_value()); 130 EXPECT_EQ(35, *qp); 131 132 // Parse an additional image slice. 133 h264_parser.ParseBitstream(kH264BitstreamNextImageSliceChunk); 134 qp = h264_parser.GetLastSliceQp(); 135 ASSERT_TRUE(qp.has_value()); 136 EXPECT_EQ(37, *qp); 137 } 138 139 TEST(H264BitstreamParserTest, ReportsLastSliceQpForCABACImageSlices) { 140 H264BitstreamParser h264_parser; 141 h264_parser.ParseBitstream(kH264BitstreamChunkCabac); 142 EXPECT_FALSE(h264_parser.GetLastSliceQp().has_value()); 143 144 // Parse an additional image slice. 145 h264_parser.ParseBitstream(kH264BitstreamNextImageSliceChunkCabac); 146 std::optional<int> qp = h264_parser.GetLastSliceQp(); 147 ASSERT_TRUE(qp.has_value()); 148 EXPECT_EQ(24, *qp); 149 } 150 151 TEST(H264BitstreamParserTest, ReportsLastSliceQpForWeightedPredSlices) { 152 H264BitstreamParser h264_parser; 153 h264_parser.ParseBitstream(kH264BitstreamWeightedPred); 154 155 std::optional<int> qp = h264_parser.GetLastSliceQp(); 156 ASSERT_TRUE(qp.has_value()); 157 EXPECT_EQ(11, *qp); 158 } 159 160 TEST(H264BitstreamParserTest, ReportsLastSliceQpForWeightedPredSlicesL0Active) { 161 H264BitstreamParser h264_parser; 162 std::optional<int> qp; 163 h264_parser.ParseBitstream(H264BitstreamCVWP1SPS); 164 165 h264_parser.ParseBitstream(H264BitstreamCVWP1PFrame1); 166 qp = h264_parser.GetLastSliceQp(); 167 ASSERT_TRUE(qp.has_value()); 168 EXPECT_EQ(25, *qp); 169 170 h264_parser.ParseBitstream(H264BitstreamCVWP1PFrame2); 171 qp = h264_parser.GetLastSliceQp(); 172 ASSERT_TRUE(qp.has_value()); 173 EXPECT_EQ(25, *qp); 174 175 h264_parser.ParseBitstream(H264BitstreamCVWP1PFrame3); 176 qp = h264_parser.GetLastSliceQp(); 177 ASSERT_TRUE(qp.has_value()); 178 EXPECT_EQ(25, *qp); 179 180 h264_parser.ParseBitstream(H264BitstreamCVWP1PFrame4); 181 qp = h264_parser.GetLastSliceQp(); 182 ASSERT_TRUE(qp.has_value()); 183 EXPECT_EQ(25, *qp); 184 } 185 186 TEST(H264BitstreamParserTest, ReportsLastSliceQpForWeightedPredSlicesL1Active) { 187 H264BitstreamParser h264_parser; 188 std::optional<int> qp; 189 h264_parser.ParseBitstream(H264BitstreamCVWP2SPS); 190 191 h264_parser.ParseBitstream(H264BitstreamCVWP2BFrame1); 192 qp = h264_parser.GetLastSliceQp(); 193 ASSERT_TRUE(qp.has_value()); 194 EXPECT_EQ(25, *qp); 195 196 h264_parser.ParseBitstream(H264BitstreamCVWP2BFrame1); 197 qp = h264_parser.GetLastSliceQp(); 198 ASSERT_TRUE(qp.has_value()); 199 EXPECT_EQ(25, *qp); 200 } 201 202 } // namespace webrtc