| 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 |