OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 #include "webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h" | 10 #include "webrtc/modules/rtp_rtcp/source/h264_bitstream_parser.h" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 } | 83 } |
84 return rbsp_buffer; | 84 return rbsp_buffer; |
85 } | 85 } |
86 | 86 |
87 #define RETURN_FALSE_ON_FAIL(x) \ | 87 #define RETURN_FALSE_ON_FAIL(x) \ |
88 if (!(x)) { \ | 88 if (!(x)) { \ |
89 LOG_F(LS_ERROR) << "FAILED: " #x; \ | 89 LOG_F(LS_ERROR) << "FAILED: " #x; \ |
90 return false; \ | 90 return false; \ |
91 } | 91 } |
92 | 92 |
93 H264BitstreamParser::PpsState::PpsState() { | 93 H264BitstreamParser::PpsState::PpsState() {} |
94 } | |
95 | 94 |
96 H264BitstreamParser::SpsState::SpsState() { | 95 H264BitstreamParser::SpsState::SpsState() {} |
97 } | |
98 | 96 |
99 // These functions are similar to webrtc::H264SpsParser::Parse, and based on the | 97 // These functions are similar to webrtc::H264SpsParser::Parse, and based on the |
100 // same version of the H.264 standard. You can find it here: | 98 // same version of the H.264 standard. You can find it here: |
101 // http://www.itu.int/rec/T-REC-H.264 | 99 // http://www.itu.int/rec/T-REC-H.264 |
102 bool H264BitstreamParser::ParseSpsNalu(const uint8_t* sps, size_t length) { | 100 bool H264BitstreamParser::ParseSpsNalu(const uint8_t* sps, size_t length) { |
103 // Reset SPS state. | 101 // Reset SPS state. |
104 sps_ = SpsState(); | 102 sps_ = SpsState(); |
105 sps_parsed_ = false; | 103 sps_parsed_ = false; |
106 // Parse out the SPS RBSP. It should be small, so it's ok that we create a | 104 // Parse out the SPS RBSP. It should be small, so it's ok that we create a |
107 // copy. We'll eventually write this back. | 105 // copy. We'll eventually write this back. |
108 rtc::scoped_ptr<rtc::ByteBuffer> sps_rbsp( | 106 rtc::scoped_ptr<rtc::ByteBuffer> sps_rbsp( |
109 ParseRbsp(sps + kNaluHeaderAndTypeSize, length - kNaluHeaderAndTypeSize)); | 107 ParseRbsp(sps + kNaluHeaderAndTypeSize, length - kNaluHeaderAndTypeSize)); |
110 rtc::BitBuffer sps_parser(reinterpret_cast<const uint8*>(sps_rbsp->Data()), | 108 rtc::BitBuffer sps_parser(reinterpret_cast<const uint8_t*>(sps_rbsp->Data()), |
111 sps_rbsp->Length()); | 109 sps_rbsp->Length()); |
112 | 110 |
113 uint8_t byte_tmp; | 111 uint8_t byte_tmp; |
114 uint32_t golomb_tmp; | 112 uint32_t golomb_tmp; |
115 uint32_t bits_tmp; | 113 uint32_t bits_tmp; |
116 | 114 |
117 // profile_idc: u(8). | 115 // profile_idc: u(8). |
118 uint8 profile_idc; | 116 uint8_t profile_idc; |
119 RETURN_FALSE_ON_FAIL(sps_parser.ReadUInt8(&profile_idc)); | 117 RETURN_FALSE_ON_FAIL(sps_parser.ReadUInt8(&profile_idc)); |
120 // constraint_set0_flag through constraint_set5_flag + reserved_zero_2bits | 118 // constraint_set0_flag through constraint_set5_flag + reserved_zero_2bits |
121 // 1 bit each for the flags + 2 bits = 8 bits = 1 byte. | 119 // 1 bit each for the flags + 2 bits = 8 bits = 1 byte. |
122 RETURN_FALSE_ON_FAIL(sps_parser.ReadUInt8(&byte_tmp)); | 120 RETURN_FALSE_ON_FAIL(sps_parser.ReadUInt8(&byte_tmp)); |
123 // level_idc: u(8) | 121 // level_idc: u(8) |
124 RETURN_FALSE_ON_FAIL(sps_parser.ReadUInt8(&byte_tmp)); | 122 RETURN_FALSE_ON_FAIL(sps_parser.ReadUInt8(&byte_tmp)); |
125 // seq_parameter_set_id: ue(v) | 123 // seq_parameter_set_id: ue(v) |
126 RETURN_FALSE_ON_FAIL(sps_parser.ReadExponentialGolomb(&golomb_tmp)); | 124 RETURN_FALSE_ON_FAIL(sps_parser.ReadExponentialGolomb(&golomb_tmp)); |
127 sps_.separate_colour_plane_flag = 0; | 125 sps_.separate_colour_plane_flag = 0; |
128 // See if profile_idc has chroma format information. | 126 // See if profile_idc has chroma format information. |
129 if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || | 127 if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || |
130 profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || | 128 profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || |
131 profile_idc == 86 || profile_idc == 118 || profile_idc == 128 || | 129 profile_idc == 86 || profile_idc == 118 || profile_idc == 128 || |
132 profile_idc == 138 || profile_idc == 139 || profile_idc == 134) { | 130 profile_idc == 138 || profile_idc == 139 || profile_idc == 134) { |
133 // chroma_format_idc: ue(v) | 131 // chroma_format_idc: ue(v) |
134 uint32 chroma_format_idc; | 132 uint32_t chroma_format_idc; |
135 RETURN_FALSE_ON_FAIL(sps_parser.ReadExponentialGolomb(&chroma_format_idc)); | 133 RETURN_FALSE_ON_FAIL(sps_parser.ReadExponentialGolomb(&chroma_format_idc)); |
136 if (chroma_format_idc == 3) { | 134 if (chroma_format_idc == 3) { |
137 // separate_colour_plane_flag: u(1) | 135 // separate_colour_plane_flag: u(1) |
138 RETURN_FALSE_ON_FAIL( | 136 RETURN_FALSE_ON_FAIL( |
139 sps_parser.ReadBits(&sps_.separate_colour_plane_flag, 1)); | 137 sps_parser.ReadBits(&sps_.separate_colour_plane_flag, 1)); |
140 } | 138 } |
141 // bit_depth_luma_minus8: ue(v) | 139 // bit_depth_luma_minus8: ue(v) |
142 RETURN_FALSE_ON_FAIL(sps_parser.ReadExponentialGolomb(&golomb_tmp)); | 140 RETURN_FALSE_ON_FAIL(sps_parser.ReadExponentialGolomb(&golomb_tmp)); |
143 // bit_depth_chroma_minus8: ue(v) | 141 // bit_depth_chroma_minus8: ue(v) |
144 RETURN_FALSE_ON_FAIL(sps_parser.ReadExponentialGolomb(&golomb_tmp)); | 142 RETURN_FALSE_ON_FAIL(sps_parser.ReadExponentialGolomb(&golomb_tmp)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 return true; | 204 return true; |
207 } | 205 } |
208 | 206 |
209 bool H264BitstreamParser::ParsePpsNalu(const uint8_t* pps, size_t length) { | 207 bool H264BitstreamParser::ParsePpsNalu(const uint8_t* pps, size_t length) { |
210 RTC_CHECK(sps_parsed_); | 208 RTC_CHECK(sps_parsed_); |
211 // We're starting a new stream, so reset picture type rewriting values. | 209 // We're starting a new stream, so reset picture type rewriting values. |
212 pps_ = PpsState(); | 210 pps_ = PpsState(); |
213 pps_parsed_ = false; | 211 pps_parsed_ = false; |
214 rtc::scoped_ptr<rtc::ByteBuffer> buffer( | 212 rtc::scoped_ptr<rtc::ByteBuffer> buffer( |
215 ParseRbsp(pps + kNaluHeaderAndTypeSize, length - kNaluHeaderAndTypeSize)); | 213 ParseRbsp(pps + kNaluHeaderAndTypeSize, length - kNaluHeaderAndTypeSize)); |
216 rtc::BitBuffer parser(reinterpret_cast<const uint8*>(buffer->Data()), | 214 rtc::BitBuffer parser(reinterpret_cast<const uint8_t*>(buffer->Data()), |
217 buffer->Length()); | 215 buffer->Length()); |
218 | 216 |
219 uint32_t bits_tmp; | 217 uint32_t bits_tmp; |
220 uint32_t golomb_ignored; | 218 uint32_t golomb_ignored; |
221 // pic_parameter_set_id: ue(v) | 219 // pic_parameter_set_id: ue(v) |
222 RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored)); | 220 RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored)); |
223 // seq_parameter_set_id: ue(v) | 221 // seq_parameter_set_id: ue(v) |
224 RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored)); | 222 RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored)); |
225 // entropy_coding_mode_flag: u(1) | 223 // entropy_coding_mode_flag: u(1) |
226 uint32_t entropy_coding_mode_flag; | 224 uint32_t entropy_coding_mode_flag; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 | 313 |
316 bool H264BitstreamParser::ParseNonParameterSetNalu(const uint8_t* source, | 314 bool H264BitstreamParser::ParseNonParameterSetNalu(const uint8_t* source, |
317 size_t source_length, | 315 size_t source_length, |
318 uint8_t nalu_type) { | 316 uint8_t nalu_type) { |
319 RTC_CHECK(sps_parsed_); | 317 RTC_CHECK(sps_parsed_); |
320 RTC_CHECK(pps_parsed_); | 318 RTC_CHECK(pps_parsed_); |
321 last_slice_qp_delta_parsed_ = false; | 319 last_slice_qp_delta_parsed_ = false; |
322 rtc::scoped_ptr<rtc::ByteBuffer> slice_rbsp(ParseRbsp( | 320 rtc::scoped_ptr<rtc::ByteBuffer> slice_rbsp(ParseRbsp( |
323 source + kNaluHeaderAndTypeSize, source_length - kNaluHeaderAndTypeSize)); | 321 source + kNaluHeaderAndTypeSize, source_length - kNaluHeaderAndTypeSize)); |
324 rtc::BitBuffer slice_reader( | 322 rtc::BitBuffer slice_reader( |
325 reinterpret_cast<const uint8*>(slice_rbsp->Data()), slice_rbsp->Length()); | 323 reinterpret_cast<const uint8_t*>(slice_rbsp->Data()), |
| 324 slice_rbsp->Length()); |
326 // Check to see if this is an IDR slice, which has an extra field to parse | 325 // Check to see if this is an IDR slice, which has an extra field to parse |
327 // out. | 326 // out. |
328 bool is_idr = (source[kNaluHeaderSize] & 0x0F) == kNaluIdr; | 327 bool is_idr = (source[kNaluHeaderSize] & 0x0F) == kNaluIdr; |
329 uint8_t nal_ref_idc = (source[kNaluHeaderSize] & 0x60) >> 5; | 328 uint8_t nal_ref_idc = (source[kNaluHeaderSize] & 0x60) >> 5; |
330 uint32_t golomb_tmp; | 329 uint32_t golomb_tmp; |
331 uint32_t bits_tmp; | 330 uint32_t bits_tmp; |
332 | 331 |
333 // first_mb_in_slice: ue(v) | 332 // first_mb_in_slice: ue(v) |
334 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 333 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
335 // slice_type: ue(v) | 334 // slice_type: ue(v) |
336 uint32_t slice_type; | 335 uint32_t slice_type; |
337 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&slice_type)); | 336 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&slice_type)); |
338 // slice_type's 5..9 range is used to indicate that all slices of a picture | 337 // slice_type's 5..9 range is used to indicate that all slices of a picture |
339 // have the same value of slice_type % 5, we don't care about that, so we map | 338 // have the same value of slice_type % 5, we don't care about that, so we map |
340 // to the corresponding 0..4 range. | 339 // to the corresponding 0..4 range. |
341 slice_type %= 5; | 340 slice_type %= 5; |
342 // pic_parameter_set_id: ue(v) | 341 // pic_parameter_set_id: ue(v) |
343 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); | 342 RETURN_FALSE_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp)); |
344 if (sps_.separate_colour_plane_flag == 1) { | 343 if (sps_.separate_colour_plane_flag == 1) { |
345 // colour_plane_id | 344 // colour_plane_id |
346 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 2)); | 345 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 2)); |
347 } | 346 } |
348 // frame_num: u(v) | 347 // frame_num: u(v) |
349 // Represented by log2_max_frame_num_minus4 + 4 bits. | 348 // Represented by log2_max_frame_num_minus4 + 4 bits. |
350 RETURN_FALSE_ON_FAIL( | 349 RETURN_FALSE_ON_FAIL( |
351 slice_reader.ReadBits(&bits_tmp, sps_.log2_max_frame_num_minus4 + 4)); | 350 slice_reader.ReadBits(&bits_tmp, sps_.log2_max_frame_num_minus4 + 4)); |
352 uint32 field_pic_flag = 0; | 351 uint32_t field_pic_flag = 0; |
353 if (sps_.frame_mbs_only_flag == 0) { | 352 if (sps_.frame_mbs_only_flag == 0) { |
354 // field_pic_flag: u(1) | 353 // field_pic_flag: u(1) |
355 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&field_pic_flag, 1)); | 354 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&field_pic_flag, 1)); |
356 if (field_pic_flag != 0) { | 355 if (field_pic_flag != 0) { |
357 // bottom_field_flag: u(1) | 356 // bottom_field_flag: u(1) |
358 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 1)); | 357 RETURN_FALSE_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 1)); |
359 } | 358 } |
360 } | 359 } |
361 if (is_idr) { | 360 if (is_idr) { |
362 // idr_pic_id: ue(v) | 361 // idr_pic_id: ue(v) |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 } | 556 } |
558 | 557 |
559 bool H264BitstreamParser::GetLastSliceQp(int* qp) const { | 558 bool H264BitstreamParser::GetLastSliceQp(int* qp) const { |
560 if (!last_slice_qp_delta_parsed_) | 559 if (!last_slice_qp_delta_parsed_) |
561 return false; | 560 return false; |
562 *qp = 26 + pps_.pic_init_qp_minus26 + last_slice_qp_delta_; | 561 *qp = 26 + pps_.pic_init_qp_minus26 + last_slice_qp_delta_; |
563 return true; | 562 return true; |
564 } | 563 } |
565 | 564 |
566 } // namespace webrtc | 565 } // namespace webrtc |
OLD | NEW |