OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/common_video/h264/pps_parser.h" | 11 #include "webrtc/common_video/h264/pps_parser.h" |
12 | 12 |
13 #include <limits> | 13 #include <limits> |
14 #include <memory> | |
15 | 14 |
16 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
17 | 16 |
18 #include "webrtc/base/bitbuffer.h" | 17 #include "webrtc/base/bitbuffer.h" |
19 #include "webrtc/base/buffer.h" | 18 #include "webrtc/base/buffer.h" |
20 #include "webrtc/common_video/h264/h264_common.h" | 19 #include "webrtc/common_video/h264/h264_common.h" |
21 | 20 |
22 namespace webrtc { | 21 namespace webrtc { |
23 | 22 |
24 namespace { | 23 static const size_t kPpsBufferMaxSize = 256; |
25 // Contains enough of the image slice to contain slice QP. | 24 static const uint32_t kIgnored = 0; |
26 const 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 const size_t kPpsBufferMaxSize = 256; | |
33 const uint32_t kIgnored = 0; | |
34 } // namespace | |
35 | 25 |
36 void WritePps(const PpsParser::PpsState& pps, | 26 void WritePps(const PpsParser::PpsState& pps, |
37 int slice_group_map_type, | 27 int slice_group_map_type, |
38 int num_slice_groups, | 28 int num_slice_groups, |
39 int pic_size_in_map_units, | 29 int pic_size_in_map_units, |
40 rtc::Buffer* out_buffer) { | 30 rtc::Buffer* out_buffer) { |
41 uint8_t data[kPpsBufferMaxSize] = {0}; | 31 uint8_t data[kPpsBufferMaxSize] = {0}; |
42 rtc::BitBufferWriter bit_buffer(data, kPpsBufferMaxSize); | 32 rtc::BitBufferWriter bit_buffer(data, kPpsBufferMaxSize); |
43 | 33 |
44 // pic_parameter_set_id: ue(v) | 34 // pic_parameter_set_id: ue(v) |
45 bit_buffer.WriteExponentialGolomb(pps.id); | 35 bit_buffer.WriteExponentialGolomb(kIgnored); |
46 // seq_parameter_set_id: ue(v) | 36 // seq_parameter_set_id: ue(v) |
47 bit_buffer.WriteExponentialGolomb(pps.sps_id); | 37 bit_buffer.WriteExponentialGolomb(kIgnored); |
48 // entropy_coding_mode_flag: u(1) | 38 // entropy_coding_mode_flag: u(1) |
49 bit_buffer.WriteBits(kIgnored, 1); | 39 bit_buffer.WriteBits(kIgnored, 1); |
50 // bottom_field_pic_order_in_frame_present_flag: u(1) | 40 // bottom_field_pic_order_in_frame_present_flag: u(1) |
51 bit_buffer.WriteBits(pps.bottom_field_pic_order_in_frame_present_flag ? 1 : 0, | 41 bit_buffer.WriteBits(pps.bottom_field_pic_order_in_frame_present_flag ? 1 : 0, |
52 1); | 42 1); |
53 // num_slice_groups_minus1: ue(v) | 43 // num_slice_groups_minus1: ue(v) |
54 RTC_CHECK_GT(num_slice_groups, 0); | 44 RTC_CHECK_GT(num_slice_groups, 0); |
55 bit_buffer.WriteExponentialGolomb(num_slice_groups - 1); | 45 bit_buffer.WriteExponentialGolomb(num_slice_groups - 1); |
56 | 46 |
57 if (num_slice_groups > 1) { | 47 if (num_slice_groups > 1) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 &buffer_); | 168 &buffer_); |
179 parsed_pps_ = PpsParser::ParsePps(buffer_.data(), buffer_.size()); | 169 parsed_pps_ = PpsParser::ParsePps(buffer_.data(), buffer_.size()); |
180 EXPECT_TRUE(static_cast<bool>(parsed_pps_)); | 170 EXPECT_TRUE(static_cast<bool>(parsed_pps_)); |
181 EXPECT_EQ(pps.bottom_field_pic_order_in_frame_present_flag, | 171 EXPECT_EQ(pps.bottom_field_pic_order_in_frame_present_flag, |
182 parsed_pps_->bottom_field_pic_order_in_frame_present_flag); | 172 parsed_pps_->bottom_field_pic_order_in_frame_present_flag); |
183 EXPECT_EQ(pps.weighted_pred_flag, parsed_pps_->weighted_pred_flag); | 173 EXPECT_EQ(pps.weighted_pred_flag, parsed_pps_->weighted_pred_flag); |
184 EXPECT_EQ(pps.weighted_bipred_idc, parsed_pps_->weighted_bipred_idc); | 174 EXPECT_EQ(pps.weighted_bipred_idc, parsed_pps_->weighted_bipred_idc); |
185 EXPECT_EQ(pps.redundant_pic_cnt_present_flag, | 175 EXPECT_EQ(pps.redundant_pic_cnt_present_flag, |
186 parsed_pps_->redundant_pic_cnt_present_flag); | 176 parsed_pps_->redundant_pic_cnt_present_flag); |
187 EXPECT_EQ(pps.pic_init_qp_minus26, parsed_pps_->pic_init_qp_minus26); | 177 EXPECT_EQ(pps.pic_init_qp_minus26, parsed_pps_->pic_init_qp_minus26); |
188 EXPECT_EQ(pps.id, parsed_pps_->id); | |
189 EXPECT_EQ(pps.sps_id, parsed_pps_->sps_id); | |
190 } | 178 } |
191 | 179 |
192 PpsParser::PpsState generated_pps_; | 180 PpsParser::PpsState generated_pps_; |
193 rtc::Buffer buffer_; | 181 rtc::Buffer buffer_; |
194 rtc::Optional<PpsParser::PpsState> parsed_pps_; | 182 rtc::Optional<PpsParser::PpsState> parsed_pps_; |
195 }; | 183 }; |
196 | 184 |
197 TEST_F(PpsParserTest, ZeroPps) { | 185 TEST_F(PpsParserTest, ZeroPps) { |
198 RunTest(); | 186 RunTest(); |
199 } | 187 } |
200 | 188 |
201 TEST_F(PpsParserTest, MaxPps) { | 189 TEST_F(PpsParserTest, MaxPps) { |
202 generated_pps_.bottom_field_pic_order_in_frame_present_flag = true; | 190 generated_pps_.bottom_field_pic_order_in_frame_present_flag = true; |
203 generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::max(); | 191 generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::max(); |
204 generated_pps_.redundant_pic_cnt_present_flag = 1; // 1 bit value. | 192 generated_pps_.redundant_pic_cnt_present_flag = 1; // 1 bit value. |
205 generated_pps_.weighted_bipred_idc = (1 << 2) - 1; // 2 bit value. | 193 generated_pps_.weighted_bipred_idc = (1 << 2) - 1; // 2 bit value. |
206 generated_pps_.weighted_pred_flag = true; | 194 generated_pps_.weighted_pred_flag = true; |
207 generated_pps_.id = 2; | |
208 generated_pps_.sps_id = 1; | |
209 RunTest(); | 195 RunTest(); |
210 | 196 |
211 generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::min() + 1; | 197 generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::min() + 1; |
212 RunTest(); | 198 RunTest(); |
213 } | 199 } |
214 | 200 |
215 TEST_F(PpsParserTest, PpsIdFromSlice) { | |
216 rtc::Optional<uint32_t> pps_id = PpsParser::ParsePpsIdFromSlice( | |
217 kH264BitstreamChunk, sizeof(kH264BitstreamChunk)); | |
218 ASSERT_TRUE(pps_id); | |
219 EXPECT_EQ(2u, *pps_id); | |
220 } | |
221 | |
222 } // namespace webrtc | 201 } // namespace webrtc |
OLD | NEW |