Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common_video/h265/h265_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ enum NaluType : uint8_t {
kBlaWRadl = 17,
kBlaNLp = 18,
kIdrWRadl = 19,
kIdr = 20,
kIdrNLp = 20,
kCra = 21,
kRsvIrapVcl23 = 23,
kVps = 32,
Expand Down
10 changes: 6 additions & 4 deletions modules/rtp_rtcp/source/rtp_format_h265.cc
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,6 @@ bool RtpDepacketizerH265::ProcessApOrSingleNalu(
nalu.sps_id = -1;
nalu.pps_id = -1;
start_offset += kHevcNalHeaderSize;

switch (nalu.type) {
case H265::NaluType::kVps: {
absl::optional<H265VpsParser::VpsState> vps = H265VpsParser::ParseVps(
Expand Down Expand Up @@ -532,7 +531,9 @@ bool RtpDepacketizerH265::ProcessApOrSingleNalu(
}
break;
}
case H265::NaluType::kIdr:
case H265::NaluType::kIdrWRadl:
case H265::NaluType::kIdrNLp:
case H265::NaluType::kCra:
parsed_payload->video_header().frame_type = VideoFrameType::kVideoFrameKey;
RTC_FALLTHROUGH();
case H265::NaluType::kTrailN:
Expand All @@ -559,7 +560,6 @@ bool RtpDepacketizerH265::ProcessApOrSingleNalu(
case H265::NaluType::kRadlR:
case H265::NaluType::kBlaWLp:
case H265::NaluType::kBlaWRadl:
case H265::NaluType::kIdrWRadl:
case H265::NaluType::kPrefixSei:
case H265::NaluType::kSuffixSei:
break;
Expand Down Expand Up @@ -622,7 +622,9 @@ bool RtpDepacketizerH265::ParseFuNalu(
length_ -= (kHevcNalHeaderSize + kHevcFuHeaderSize);
}

if (original_nal_type == H265::NaluType::kIdr) {
if (original_nal_type == H265::NaluType::kIdrWRadl
|| original_nal_type == H265::NaluType::kIdrNLp
|| original_nal_type == H265::NaluType::kCra) {
parsed_payload->video_header().frame_type = VideoFrameType::kVideoFrameKey;
} else {
parsed_payload->video_header().frame_type = VideoFrameType::kVideoFrameDelta;
Expand Down
6 changes: 4 additions & 2 deletions modules/video_coding/h265_vps_sps_pps_tracker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ H265VpsSpsPpsTracker::PacketAction H265VpsSpsPpsTracker::CopyAndFixBitstream(
pps_data_[nalu.pps_id].sps_id = nalu.sps_id;
break;
}
case H265::NaluType::kIdr: {
case H265::NaluType::kIdrWRadl:
case H265::NaluType::kIdrNLp:
case H265::NaluType::kCra: {
// If this is the first packet of an IDR, make sure we have the required
// SPS/PPS and also calculate how much extra space we need in the buffer
// to prepend the SPS/PPS to the bitstream with start codes.
Expand Down Expand Up @@ -193,7 +195,7 @@ H265VpsSpsPpsTracker::PacketAction H265VpsSpsPpsTracker::CopyAndFixBitstream(
h265_header.nalus[h265_header.nalus_length++] = sps_info;
h265_header.nalus[h265_header.nalus_length++] = pps_info;
} else {
RTC_LOG(LS_WARNING) << "Not enough space in H.264 codec header to insert "
RTC_LOG(LS_WARNING) << "Not enough space in H.265 codec header to insert "
"SPS/PPS provided out-of-band.";
}
}
Expand Down
2 changes: 1 addition & 1 deletion modules/video_coding/packet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ VCMPacket::VCMPacket(const uint8_t* ptr,
markerBit(rtp_header.markerBit),
timesNacked(-1),
completeNALU(kNaluIncomplete),
insertStartCode(videoHeader.codec == kVideoCodecH264 &&
insertStartCode((videoHeader.codec == kVideoCodecH264 || videoHeader.codec == kVideoCodecH265) &&
videoHeader.is_first_packet_in_frame),
video_header(videoHeader) {
if (is_first_packet_in_frame() && markerBit) {
Expand Down
46 changes: 43 additions & 3 deletions modules/video_coding/packet_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ std::vector<std::unique_ptr<RtpFrameObject>> PacketBuffer::FindFrames(
max_recv_time =
std::max(max_recv_time, data_buffer_[start_index].receive_time_ms);

if (!is_h264 && sequence_buffer_[start_index].frame_begin)
if (!is_h264 && !is_h265 && sequence_buffer_[start_index].frame_begin)
break;

if (is_h264 && !is_h264_keyframe) {
Expand Down Expand Up @@ -361,7 +361,9 @@ std::vector<std::unique_ptr<RtpFrameObject>> PacketBuffer::FindFrames(
has_h265_sps = true;
} else if (h265_header->nalus[j].type == H265::NaluType::kPps) {
has_h265_pps = true;
} else if (h265_header->nalus[j].type == H265::NaluType::kIdr) {
} else if (h265_header->nalus[j].type == H265::NaluType::kIdrWRadl
|| h265_header->nalus[j].type == H265::NaluType::kIdrNLp
|| h265_header->nalus[j].type == H265::NaluType::kCra) {
has_h265_idr = true;
}
}
Expand All @@ -381,7 +383,7 @@ std::vector<std::unique_ptr<RtpFrameObject>> PacketBuffer::FindFrames(
// the timestamp of that packet is the same as this one. This may cause
// the PacketBuffer to hand out incomplete frames.
// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106
if (is_h264 &&
if ((is_h264 || is_h265) &&
(!sequence_buffer_[start_index].used ||
data_buffer_[start_index].timestamp != frame_timestamp)) {
break;
Expand Down Expand Up @@ -432,6 +434,44 @@ std::vector<std::unique_ptr<RtpFrameObject>> PacketBuffer::FindFrames(
}
}

#ifndef DISABLE_H265
if (is_h265) {
// Warn if this is an unsafe frame.
if (has_h265_idr && (!has_h265_sps || !has_h265_pps)) {
std::stringstream ss;
ss << "Received H.265-IDR frame "
<< "(SPS: " << has_h265_sps << ", PPS: " << has_h265_pps << "). ";
ss << "Treating as delta frame since "
"WebRTC-SpsPpsIdrIsH265Keyframe is always enabled.";
RTC_LOG(LS_WARNING) << ss.str();
}

// Now that we have decided whether to treat this frame as a key frame
// or delta frame in the frame buffer, we update the field that
// determines if the RtpFrameObject is a key frame or delta frame.
const size_t first_packet_index = start_seq_num % size_;
RTC_CHECK_LT(first_packet_index, size_);
if (is_h265_keyframe) {
data_buffer_[first_packet_index].video_header.frame_type = VideoFrameType::kVideoFrameKey;
} else {
data_buffer_[first_packet_index].video_header.frame_type = VideoFrameType::kVideoFrameDelta;
}

// If this is not a key frame, make sure there are no gaps in the
// packet sequence numbers up until this point.
if (!is_h265_keyframe && missing_packets_.upper_bound(start_seq_num) !=
missing_packets_.begin()) {
uint16_t stop_index = (index + 1) % size_;
while (start_index != stop_index) {
sequence_buffer_[start_index].frame_created = false;
start_index = (start_index + 1) % size_;
}

return found_frames;
}
}
#endif

missing_packets_.erase(missing_packets_.begin(),
missing_packets_.upper_bound(seq_num));

Expand Down
1 change: 1 addition & 0 deletions video/send_statistics_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ HistogramCodecType PayloadNameToHistogramCodecType(
case kVideoCodecH264:
return kVideoH264;
#ifndef DISABLE_H265
case kVideoCodecH265:
return kVideoH265;
#endif
default:
Expand Down