diff --git a/webrtc/common_video/h264/pps_parser.cc b/webrtc/common_video/h264/pps_parser.cc index 01a6c76d91..a48d27bfc7 100644 --- a/webrtc/common_video/h264/pps_parser.cc +++ b/webrtc/common_video/h264/pps_parser.cc @@ -38,6 +38,20 @@ rtc::Optional PpsParser::ParsePps(const uint8_t* data, return ParseInternal(&bit_buffer); } +bool PpsParser::ParsePpsIds(const uint8_t* data, + size_t length, + uint32_t* pps_id, + uint32_t* sps_id) { + RTC_DCHECK(pps_id); + RTC_DCHECK(sps_id); + // First, parse out rbsp, which is basically the source buffer minus emulation + // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in + // section 7.3.1 of the H.264 standard. + std::unique_ptr unpacked_buffer = H264::ParseRbsp(data, length); + rtc::BitBuffer bit_buffer(unpacked_buffer->data(), unpacked_buffer->size()); + return ParsePpsIdsInternal(&bit_buffer, pps_id, sps_id); +} + rtc::Optional PpsParser::ParsePpsIdFromSlice(const uint8_t* data, size_t length) { std::unique_ptr slice_rbsp(H264::ParseRbsp(data, length)); @@ -61,12 +75,10 @@ rtc::Optional PpsParser::ParseInternal( rtc::BitBuffer* bit_buffer) { PpsState pps; + RETURN_EMPTY_ON_FAIL(ParsePpsIdsInternal(bit_buffer, &pps.id, &pps.sps_id)); + uint32_t bits_tmp; uint32_t golomb_ignored; - // pic_parameter_set_id: ue(v) - RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&pps.id)); - // seq_parameter_set_id: ue(v) - RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&pps.sps_id)); // entropy_coding_mode_flag: u(1) uint32_t entropy_coding_mode_flag; RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&entropy_coding_mode_flag, 1)); @@ -166,4 +178,16 @@ rtc::Optional PpsParser::ParseInternal( return rtc::Optional(pps); } +bool PpsParser::ParsePpsIdsInternal(rtc::BitBuffer* bit_buffer, + uint32_t* pps_id, + uint32_t* sps_id) { + // pic_parameter_set_id: ue(v) + if (!bit_buffer->ReadExponentialGolomb(pps_id)) + return false; + // seq_parameter_set_id: ue(v) + if (!bit_buffer->ReadExponentialGolomb(sps_id)) + return false; + return true; +} + } // namespace webrtc diff --git a/webrtc/common_video/h264/pps_parser.h b/webrtc/common_video/h264/pps_parser.h index c84f210278..6c896fe8ea 100644 --- a/webrtc/common_video/h264/pps_parser.h +++ b/webrtc/common_video/h264/pps_parser.h @@ -40,6 +40,11 @@ class PpsParser { // Unpack RBSP and parse PPS state from the supplied buffer. static rtc::Optional ParsePps(const uint8_t* data, size_t length); + static bool ParsePpsIds(const uint8_t* data, + size_t length, + uint32_t* pps_id, + uint32_t* sps_id); + static rtc::Optional ParsePpsIdFromSlice(const uint8_t* data, size_t length); @@ -47,6 +52,9 @@ class PpsParser { // Parse the PPS state, for a bit buffer where RBSP decoding has already been // performed. static rtc::Optional ParseInternal(rtc::BitBuffer* bit_buffer); + static bool ParsePpsIdsInternal(rtc::BitBuffer* bit_buffer, + uint32_t* pps_id, + uint32_t* sps_id); }; } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc index 1a3408e306..19467ca651 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_format_h264.cc @@ -489,11 +489,16 @@ bool RtpDepacketizerH264::ProcessStapAOrSingleNalu( break; } case H264::NaluType::kPps: { - rtc::Optional pps = PpsParser::ParsePps( - &payload_data[start_offset], end_offset - start_offset); - if (pps) { - nalu.sps_id = pps->sps_id; - nalu.pps_id = pps->id; + uint32_t pps_id; + uint32_t sps_id; + if (PpsParser::ParsePpsIds(&payload_data[start_offset], + end_offset - start_offset, &pps_id, + &sps_id)) { + nalu.pps_id = pps_id; + nalu.sps_id = sps_id; + } else { + LOG(LS_WARNING) + << "Failed to parse PPS id and SPS id from PPS slice."; } break; }