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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 61 |
62 // Parses RBSP from source bytes. Removes emulation bytes, but leaves the | 62 // Parses RBSP from source bytes. Removes emulation bytes, but leaves the |
63 // rbsp_trailing_bits() in the stream, since none of the parsing reads all the | 63 // rbsp_trailing_bits() in the stream, since none of the parsing reads all the |
64 // way to the end of a parsed RBSP sequence. When writing, that means the | 64 // way to the end of a parsed RBSP sequence. When writing, that means the |
65 // rbsp_trailing_bits() should be preserved and don't need to be restored (i.e. | 65 // rbsp_trailing_bits() should be preserved and don't need to be restored (i.e. |
66 // the rbsp_stop_one_bit, which is just a 1, then zero padded), and alignment | 66 // the rbsp_stop_one_bit, which is just a 1, then zero padded), and alignment |
67 // should "just work". | 67 // should "just work". |
68 // TODO(pbos): Make parsing RBSP something that can be integrated into BitBuffer | 68 // TODO(pbos): Make parsing RBSP something that can be integrated into BitBuffer |
69 // so we don't have to copy the entire frames when only interested in the | 69 // so we don't have to copy the entire frames when only interested in the |
70 // headers. | 70 // headers. |
71 rtc::ByteBuffer* ParseRbsp(const uint8_t* bytes, size_t length) { | 71 rtc::ByteBufferWriter* ParseRbsp(const uint8_t* bytes, size_t length) { |
72 // Copied from webrtc::H264SpsParser::Parse. | 72 // Copied from webrtc::H264SpsParser::Parse. |
73 rtc::ByteBuffer* rbsp_buffer = new rtc::ByteBuffer; | 73 rtc::ByteBufferWriter* rbsp_buffer = new rtc::ByteBufferWriter(); |
74 for (size_t i = 0; i < length;) { | 74 for (size_t i = 0; i < length;) { |
75 if (length - i >= 3 && bytes[i] == 0 && bytes[i + 1] == 0 && | 75 if (length - i >= 3 && bytes[i] == 0 && bytes[i + 1] == 0 && |
76 bytes[i + 2] == 3) { | 76 bytes[i + 2] == 3) { |
77 rbsp_buffer->WriteBytes(reinterpret_cast<const char*>(bytes) + i, 2); | 77 rbsp_buffer->WriteBytes(reinterpret_cast<const char*>(bytes) + i, 2); |
78 i += 3; | 78 i += 3; |
79 } else { | 79 } else { |
80 rbsp_buffer->WriteBytes(reinterpret_cast<const char*>(bytes) + i, 1); | 80 rbsp_buffer->WriteBytes(reinterpret_cast<const char*>(bytes) + i, 1); |
81 i++; | 81 i++; |
82 } | 82 } |
83 } | 83 } |
(...skipping 12 matching lines...) Expand all Loading... |
96 | 96 |
97 // 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 |
98 // 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: |
99 // http://www.itu.int/rec/T-REC-H.264 | 99 // http://www.itu.int/rec/T-REC-H.264 |
100 bool H264BitstreamParser::ParseSpsNalu(const uint8_t* sps, size_t length) { | 100 bool H264BitstreamParser::ParseSpsNalu(const uint8_t* sps, size_t length) { |
101 // Reset SPS state. | 101 // Reset SPS state. |
102 sps_ = SpsState(); | 102 sps_ = SpsState(); |
103 sps_parsed_ = false; | 103 sps_parsed_ = false; |
104 // 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 |
105 // copy. We'll eventually write this back. | 105 // copy. We'll eventually write this back. |
106 rtc::scoped_ptr<rtc::ByteBuffer> sps_rbsp( | 106 rtc::scoped_ptr<rtc::ByteBufferWriter> sps_rbsp( |
107 ParseRbsp(sps + kNaluHeaderAndTypeSize, length - kNaluHeaderAndTypeSize)); | 107 ParseRbsp(sps + kNaluHeaderAndTypeSize, length - kNaluHeaderAndTypeSize)); |
108 rtc::BitBuffer sps_parser(reinterpret_cast<const uint8_t*>(sps_rbsp->Data()), | 108 rtc::BitBuffer sps_parser(reinterpret_cast<const uint8_t*>(sps_rbsp->Data()), |
109 sps_rbsp->Length()); | 109 sps_rbsp->Length()); |
110 | 110 |
111 uint8_t byte_tmp; | 111 uint8_t byte_tmp; |
112 uint32_t golomb_tmp; | 112 uint32_t golomb_tmp; |
113 uint32_t bits_tmp; | 113 uint32_t bits_tmp; |
114 | 114 |
115 // profile_idc: u(8). | 115 // profile_idc: u(8). |
116 uint8_t profile_idc; | 116 uint8_t profile_idc; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 RETURN_FALSE_ON_FAIL(sps_parser.ReadBits(&sps_.frame_mbs_only_flag, 1)); | 202 RETURN_FALSE_ON_FAIL(sps_parser.ReadBits(&sps_.frame_mbs_only_flag, 1)); |
203 sps_parsed_ = true; | 203 sps_parsed_ = true; |
204 return true; | 204 return true; |
205 } | 205 } |
206 | 206 |
207 bool H264BitstreamParser::ParsePpsNalu(const uint8_t* pps, size_t length) { | 207 bool H264BitstreamParser::ParsePpsNalu(const uint8_t* pps, size_t length) { |
208 RTC_CHECK(sps_parsed_); | 208 RTC_CHECK(sps_parsed_); |
209 // 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. |
210 pps_ = PpsState(); | 210 pps_ = PpsState(); |
211 pps_parsed_ = false; | 211 pps_parsed_ = false; |
212 rtc::scoped_ptr<rtc::ByteBuffer> buffer( | 212 rtc::scoped_ptr<rtc::ByteBufferWriter> buffer( |
213 ParseRbsp(pps + kNaluHeaderAndTypeSize, length - kNaluHeaderAndTypeSize)); | 213 ParseRbsp(pps + kNaluHeaderAndTypeSize, length - kNaluHeaderAndTypeSize)); |
214 rtc::BitBuffer parser(reinterpret_cast<const uint8_t*>(buffer->Data()), | 214 rtc::BitBuffer parser(reinterpret_cast<const uint8_t*>(buffer->Data()), |
215 buffer->Length()); | 215 buffer->Length()); |
216 | 216 |
217 uint32_t bits_tmp; | 217 uint32_t bits_tmp; |
218 uint32_t golomb_ignored; | 218 uint32_t golomb_ignored; |
219 // pic_parameter_set_id: ue(v) | 219 // pic_parameter_set_id: ue(v) |
220 RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored)); | 220 RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored)); |
221 // seq_parameter_set_id: ue(v) | 221 // seq_parameter_set_id: ue(v) |
222 RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored)); | 222 RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored)); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 pps_parsed_ = true; | 310 pps_parsed_ = true; |
311 return true; | 311 return true; |
312 } | 312 } |
313 | 313 |
314 bool H264BitstreamParser::ParseNonParameterSetNalu(const uint8_t* source, | 314 bool H264BitstreamParser::ParseNonParameterSetNalu(const uint8_t* source, |
315 size_t source_length, | 315 size_t source_length, |
316 uint8_t nalu_type) { | 316 uint8_t nalu_type) { |
317 RTC_CHECK(sps_parsed_); | 317 RTC_CHECK(sps_parsed_); |
318 RTC_CHECK(pps_parsed_); | 318 RTC_CHECK(pps_parsed_); |
319 last_slice_qp_delta_parsed_ = false; | 319 last_slice_qp_delta_parsed_ = false; |
320 rtc::scoped_ptr<rtc::ByteBuffer> slice_rbsp(ParseRbsp( | 320 rtc::scoped_ptr<rtc::ByteBufferWriter> slice_rbsp(ParseRbsp( |
321 source + kNaluHeaderAndTypeSize, source_length - kNaluHeaderAndTypeSize)); | 321 source + kNaluHeaderAndTypeSize, source_length - kNaluHeaderAndTypeSize)); |
322 rtc::BitBuffer slice_reader( | 322 rtc::BitBuffer slice_reader( |
323 reinterpret_cast<const uint8_t*>(slice_rbsp->Data()), | 323 reinterpret_cast<const uint8_t*>(slice_rbsp->Data()), |
324 slice_rbsp->Length()); | 324 slice_rbsp->Length()); |
325 // 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 |
326 // out. | 326 // out. |
327 bool is_idr = (source[kNaluHeaderSize] & 0x0F) == kNaluIdr; | 327 bool is_idr = (source[kNaluHeaderSize] & 0x0F) == kNaluIdr; |
328 uint8_t nal_ref_idc = (source[kNaluHeaderSize] & 0x60) >> 5; | 328 uint8_t nal_ref_idc = (source[kNaluHeaderSize] & 0x60) >> 5; |
329 uint32_t golomb_tmp; | 329 uint32_t golomb_tmp; |
330 uint32_t bits_tmp; | 330 uint32_t bits_tmp; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 } | 556 } |
557 | 557 |
558 bool H264BitstreamParser::GetLastSliceQp(int* qp) const { | 558 bool H264BitstreamParser::GetLastSliceQp(int* qp) const { |
559 if (!last_slice_qp_delta_parsed_) | 559 if (!last_slice_qp_delta_parsed_) |
560 return false; | 560 return false; |
561 *qp = 26 + pps_.pic_init_qp_minus26 + last_slice_qp_delta_; | 561 *qp = 26 + pps_.pic_init_qp_minus26 + last_slice_qp_delta_; |
562 return true; | 562 return true; |
563 } | 563 } |
564 | 564 |
565 } // namespace webrtc | 565 } // namespace webrtc |
OLD | NEW |