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> |
14 | 15 |
15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
16 | 17 |
17 #include "webrtc/base/bitbuffer.h" | 18 #include "webrtc/base/bitbuffer.h" |
18 #include "webrtc/base/buffer.h" | 19 #include "webrtc/base/buffer.h" |
19 #include "webrtc/common_video/h264/h264_common.h" | 20 #include "webrtc/common_video/h264/h264_common.h" |
20 | 21 |
21 namespace webrtc { | 22 namespace webrtc { |
22 | 23 |
23 static const size_t kPpsBufferMaxSize = 256; | 24 namespace { |
24 static const uint32_t kIgnored = 0; | 25 // Contains enough of the image slice to contain slice QP. |
| 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 |
25 | 35 |
26 void WritePps(const PpsParser::PpsState& pps, | 36 void WritePps(const PpsParser::PpsState& pps, |
27 int slice_group_map_type, | 37 int slice_group_map_type, |
28 int num_slice_groups, | 38 int num_slice_groups, |
29 int pic_size_in_map_units, | 39 int pic_size_in_map_units, |
30 rtc::Buffer* out_buffer) { | 40 rtc::Buffer* out_buffer) { |
31 uint8_t data[kPpsBufferMaxSize] = {0}; | 41 uint8_t data[kPpsBufferMaxSize] = {0}; |
32 rtc::BitBufferWriter bit_buffer(data, kPpsBufferMaxSize); | 42 rtc::BitBufferWriter bit_buffer(data, kPpsBufferMaxSize); |
33 | 43 |
34 // pic_parameter_set_id: ue(v) | 44 // pic_parameter_set_id: ue(v) |
35 bit_buffer.WriteExponentialGolomb(kIgnored); | 45 bit_buffer.WriteExponentialGolomb(pps.id); |
36 // seq_parameter_set_id: ue(v) | 46 // seq_parameter_set_id: ue(v) |
37 bit_buffer.WriteExponentialGolomb(kIgnored); | 47 bit_buffer.WriteExponentialGolomb(pps.sps_id); |
38 // entropy_coding_mode_flag: u(1) | 48 // entropy_coding_mode_flag: u(1) |
39 bit_buffer.WriteBits(kIgnored, 1); | 49 bit_buffer.WriteBits(kIgnored, 1); |
40 // bottom_field_pic_order_in_frame_present_flag: u(1) | 50 // bottom_field_pic_order_in_frame_present_flag: u(1) |
41 bit_buffer.WriteBits(pps.bottom_field_pic_order_in_frame_present_flag ? 1 : 0, | 51 bit_buffer.WriteBits(pps.bottom_field_pic_order_in_frame_present_flag ? 1 : 0, |
42 1); | 52 1); |
43 // num_slice_groups_minus1: ue(v) | 53 // num_slice_groups_minus1: ue(v) |
44 RTC_CHECK_GT(num_slice_groups, 0); | 54 RTC_CHECK_GT(num_slice_groups, 0); |
45 bit_buffer.WriteExponentialGolomb(num_slice_groups - 1); | 55 bit_buffer.WriteExponentialGolomb(num_slice_groups - 1); |
46 | 56 |
47 if (num_slice_groups > 1) { | 57 if (num_slice_groups > 1) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 &buffer_); | 178 &buffer_); |
169 parsed_pps_ = PpsParser::ParsePps(buffer_.data(), buffer_.size()); | 179 parsed_pps_ = PpsParser::ParsePps(buffer_.data(), buffer_.size()); |
170 EXPECT_TRUE(static_cast<bool>(parsed_pps_)); | 180 EXPECT_TRUE(static_cast<bool>(parsed_pps_)); |
171 EXPECT_EQ(pps.bottom_field_pic_order_in_frame_present_flag, | 181 EXPECT_EQ(pps.bottom_field_pic_order_in_frame_present_flag, |
172 parsed_pps_->bottom_field_pic_order_in_frame_present_flag); | 182 parsed_pps_->bottom_field_pic_order_in_frame_present_flag); |
173 EXPECT_EQ(pps.weighted_pred_flag, parsed_pps_->weighted_pred_flag); | 183 EXPECT_EQ(pps.weighted_pred_flag, parsed_pps_->weighted_pred_flag); |
174 EXPECT_EQ(pps.weighted_bipred_idc, parsed_pps_->weighted_bipred_idc); | 184 EXPECT_EQ(pps.weighted_bipred_idc, parsed_pps_->weighted_bipred_idc); |
175 EXPECT_EQ(pps.redundant_pic_cnt_present_flag, | 185 EXPECT_EQ(pps.redundant_pic_cnt_present_flag, |
176 parsed_pps_->redundant_pic_cnt_present_flag); | 186 parsed_pps_->redundant_pic_cnt_present_flag); |
177 EXPECT_EQ(pps.pic_init_qp_minus26, parsed_pps_->pic_init_qp_minus26); | 187 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); |
178 } | 190 } |
179 | 191 |
180 PpsParser::PpsState generated_pps_; | 192 PpsParser::PpsState generated_pps_; |
181 rtc::Buffer buffer_; | 193 rtc::Buffer buffer_; |
182 rtc::Optional<PpsParser::PpsState> parsed_pps_; | 194 rtc::Optional<PpsParser::PpsState> parsed_pps_; |
183 }; | 195 }; |
184 | 196 |
185 TEST_F(PpsParserTest, ZeroPps) { | 197 TEST_F(PpsParserTest, ZeroPps) { |
186 RunTest(); | 198 RunTest(); |
187 } | 199 } |
188 | 200 |
189 TEST_F(PpsParserTest, MaxPps) { | 201 TEST_F(PpsParserTest, MaxPps) { |
190 generated_pps_.bottom_field_pic_order_in_frame_present_flag = true; | 202 generated_pps_.bottom_field_pic_order_in_frame_present_flag = true; |
191 generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::max(); | 203 generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::max(); |
192 generated_pps_.redundant_pic_cnt_present_flag = 1; // 1 bit value. | 204 generated_pps_.redundant_pic_cnt_present_flag = 1; // 1 bit value. |
193 generated_pps_.weighted_bipred_idc = (1 << 2) - 1; // 2 bit value. | 205 generated_pps_.weighted_bipred_idc = (1 << 2) - 1; // 2 bit value. |
194 generated_pps_.weighted_pred_flag = true; | 206 generated_pps_.weighted_pred_flag = true; |
| 207 generated_pps_.id = 2; |
| 208 generated_pps_.sps_id = 1; |
195 RunTest(); | 209 RunTest(); |
196 | 210 |
197 generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::min() + 1; | 211 generated_pps_.pic_init_qp_minus26 = std::numeric_limits<int32_t>::min() + 1; |
198 RunTest(); | 212 RunTest(); |
199 } | 213 } |
200 | 214 |
| 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 |
201 } // namespace webrtc | 222 } // namespace webrtc |
OLD | NEW |