From 8d22d1855c068efed7de2eda72a48bb7fae5d339 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Fri, 26 Apr 2024 16:38:02 +0800 Subject: [PATCH] Implement single OBU packetizer --- src/rtp/rtp_codec.cpp | 139 ++++++++++++++++++++++++----------------- src/rtp/rtp_packet.cpp | 8 +-- src/rtp/rtp_packet.h | 26 ++------ 3 files changed, 89 insertions(+), 84 deletions(-) diff --git a/src/rtp/rtp_codec.cpp b/src/rtp/rtp_codec.cpp index e9e0ff8..7cc03c5 100644 --- a/src/rtp/rtp_codec.cpp +++ b/src/rtp/rtp_codec.cpp @@ -223,65 +223,18 @@ void RtpCodec::Encode(uint8_t* buffer, size_t size, for (int i = 0; i < obus.size(); i++) { LOG_ERROR("[{}] Obu size = [{}], Obu type [{}]", i, obus[i].size_, ObuTypeToString((OBU_TYPE)ObuType(obus[i].header_))); - } - - if (size <= MAX_NALU_LEN) { - RtpPacket rtp_packet; - rtp_packet.SetVerion(version_); - rtp_packet.SetHasPadding(has_padding_); - rtp_packet.SetHasExtension(has_extension_); - rtp_packet.SetMarker(1); - rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); - rtp_packet.SetSequenceNumber(sequence_number_++); - - timestamp_ = - std::chrono::high_resolution_clock::now().time_since_epoch().count(); - rtp_packet.SetTimestamp(timestamp_); - rtp_packet.SetSsrc(ssrc_); - - if (!csrcs_.empty()) { - rtp_packet.SetCsrcs(csrcs_); - } - - if (has_extension_) { - rtp_packet.SetExtensionProfile(extension_profile_); - rtp_packet.SetExtensionData(extension_data_, extension_len_); - } - - // int obu_header; - // memcpy(&obu_header, buffer, sizeof(char)); - // int obu_type = (obu_header & 0b0'1111'000) >> 3; - // LOG_ERROR("OBU type {}", obu_type); - // if (obu_type == kObuTypeTemporalDelimiter || - // obu_type == kObuTypeTileList || obu_type == kObuTypePadding) { - // LOG_ERROR("Unsupported OBU type", obu_type); - // } - - RtpPacket::AV1_AGGR_HEADER av1_aggr_header; - av1_aggr_header.z = av1_aggr_header.z; - av1_aggr_header.y = av1_aggr_header.y; - av1_aggr_header.w = av1_aggr_header.w; - av1_aggr_header.n = av1_aggr_header.n; - - rtp_packet.SetAv1AggrHeader(av1_aggr_header); - - rtp_packet.EncodeAv1(buffer, size); - packets.emplace_back(rtp_packet); - - } else { - size_t last_packet_size = size % MAX_NALU_LEN; - size_t packet_num = size / MAX_NALU_LEN + (last_packet_size ? 1 : 0); - timestamp_ = - std::chrono::high_resolution_clock::now().time_since_epoch().count(); - - for (size_t index = 0; index < packet_num; index++) { + if (obus[i].size_ <= MAX_NALU_LEN) { RtpPacket rtp_packet; rtp_packet.SetVerion(version_); rtp_packet.SetHasPadding(has_padding_); rtp_packet.SetHasExtension(has_extension_); - rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0); + rtp_packet.SetMarker(1); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); rtp_packet.SetSequenceNumber(sequence_number_++); + + timestamp_ = std::chrono::high_resolution_clock::now() + .time_since_epoch() + .count(); rtp_packet.SetTimestamp(timestamp_); rtp_packet.SetSsrc(ssrc_); @@ -294,14 +247,82 @@ void RtpCodec::Encode(uint8_t* buffer, size_t size, rtp_packet.SetExtensionData(extension_data_, extension_len_); } - if (index == packet_num - 1 && last_packet_size > 0) { - rtp_packet.EncodeAv1(buffer + index * MAX_NALU_LEN, last_packet_size); - } else { - rtp_packet.EncodeAv1(buffer + index * MAX_NALU_LEN, MAX_NALU_LEN); - } - packets.emplace_back(rtp_packet); + rtp_packet.SetAv1AggrHeader(0, 0, 1, 0); + + // rtp_packet.EncodeAv1(buffer, size); + // packets.emplace_back(rtp_packet); } } + + // if (size <= MAX_NALU_LEN) { + // RtpPacket rtp_packet; + // rtp_packet.SetVerion(version_); + // rtp_packet.SetHasPadding(has_padding_); + // rtp_packet.SetHasExtension(has_extension_); + // rtp_packet.SetMarker(1); + // rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); + // rtp_packet.SetSequenceNumber(sequence_number_++); + + // timestamp_ = + // std::chrono::high_resolution_clock::now().time_since_epoch().count(); + // rtp_packet.SetTimestamp(timestamp_); + // rtp_packet.SetSsrc(ssrc_); + + // if (!csrcs_.empty()) { + // rtp_packet.SetCsrcs(csrcs_); + // } + + // if (has_extension_) { + // rtp_packet.SetExtensionProfile(extension_profile_); + // rtp_packet.SetExtensionData(extension_data_, extension_len_); + // } + + // RtpPacket::AV1_AGGR_HEADER av1_aggr_header; + // av1_aggr_header.z = av1_aggr_header.z; + // av1_aggr_header.y = av1_aggr_header.y; + // av1_aggr_header.w = av1_aggr_header.w; + // av1_aggr_header.n = av1_aggr_header.n; + + // rtp_packet.SetAv1AggrHeader(av1_aggr_header); + + // rtp_packet.EncodeAv1(buffer, size); + // packets.emplace_back(rtp_packet); + + // } else { + // size_t last_packet_size = size % MAX_NALU_LEN; + // size_t packet_num = size / MAX_NALU_LEN + (last_packet_size ? 1 : 0); + // timestamp_ = + // std::chrono::high_resolution_clock::now().time_since_epoch().count(); + + // for (size_t index = 0; index < packet_num; index++) { + // RtpPacket rtp_packet; + // rtp_packet.SetVerion(version_); + // rtp_packet.SetHasPadding(has_padding_); + // rtp_packet.SetHasExtension(has_extension_); + // rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0); + // rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); + // rtp_packet.SetSequenceNumber(sequence_number_++); + // rtp_packet.SetTimestamp(timestamp_); + // rtp_packet.SetSsrc(ssrc_); + + // if (!csrcs_.empty()) { + // rtp_packet.SetCsrcs(csrcs_); + // } + + // if (has_extension_) { + // rtp_packet.SetExtensionProfile(extension_profile_); + // rtp_packet.SetExtensionData(extension_data_, extension_len_); + // } + + // if (index == packet_num - 1 && last_packet_size > 0) { + // rtp_packet.EncodeAv1(buffer + index * MAX_NALU_LEN, + // last_packet_size); + // } else { + // rtp_packet.EncodeAv1(buffer + index * MAX_NALU_LEN, MAX_NALU_LEN); + // } + // packets.emplace_back(rtp_packet); + // } + // } } else if (RtpPacket::PAYLOAD_TYPE::OPUS == payload_type_) { RtpPacket rtp_packet; rtp_packet.SetVerion(version_); diff --git a/src/rtp/rtp_packet.cpp b/src/rtp/rtp_packet.cpp index 10b8025..20a72aa 100644 --- a/src/rtp/rtp_packet.cpp +++ b/src/rtp/rtp_packet.cpp @@ -424,14 +424,12 @@ const uint8_t *RtpPacket::EncodeAv1(uint8_t *payload, size_t payload_size) { memcpy(buffer_ + 16 + extension_offset, extension_data_, extension_len_); } - uint32_t payload_offset = + uint32_t aggr_header_offset = (has_extension_ && extension_data_ ? extension_len_ : 0) + extension_offset; + memcpy(buffer_ + 12 + aggr_header_offset, &av1_aggr_header_, 1); - buffer_[12 + payload_offset] = fu_indicator_.forbidden_bit << 7 | - fu_indicator_.nal_reference_idc << 6 | - fu_indicator_.nal_unit_type; - + uint32_t payload_offset = aggr_header_offset + 1; memcpy(buffer_ + 13 + payload_offset, payload, payload_size); size_ = payload_size + (13 + payload_offset); diff --git a/src/rtp/rtp_packet.h b/src/rtp/rtp_packet.h index 9b3524e..ce472f6 100644 --- a/src/rtp/rtp_packet.h +++ b/src/rtp/rtp_packet.h @@ -218,20 +218,6 @@ class RtpPacket { uint8_t nal_unit_type : 5; } FU_HEADER; - typedef struct { - uint8_t z : 1; - uint8_t y : 1; - uint8_t w : 2; - uint8_t n : 1; - } AV1_AGGR_HEADER; - - // typedef struct Obu { - // uint8_t header; - // uint8_t extension_header; // undefined if (header & kXbit) == 0 - // rtc::ArrayView payload; - // int size; // size of the header and payload combined. - // } OBU; - void SetFuIndicator(FU_INDICATOR fu_indicator) { fu_indicator_.forbidden_bit = fu_indicator.forbidden_bit; fu_indicator_.nal_reference_idc = fu_indicator.nal_reference_idc; @@ -245,11 +231,11 @@ class RtpPacket { fu_header_.nal_unit_type = fu_header.nal_unit_type; } - void SetAv1AggrHeader(AV1_AGGR_HEADER av1_aggr_header) { - av1_aggr_header_.z = av1_aggr_header.z; - av1_aggr_header_.y = av1_aggr_header.y; - av1_aggr_header_.w = av1_aggr_header.w; - av1_aggr_header_.n = av1_aggr_header.n; + void SetAv1AggrHeader(int z, int y, int w, int n) { + if (z) av1_aggr_header_ |= (1 << 7); + if (y) av1_aggr_header_ |= (1 << 6); + if (w) av1_aggr_header_ |= w << 4; + if (n) av1_aggr_header_ |= (1 << 3); } void SetFecSymbolId(uint8_t fec_symbol_id) { fec_symbol_id_ = fec_symbol_id; } @@ -377,7 +363,7 @@ class RtpPacket { FU_HEADER fu_header_; uint8_t fec_symbol_id_ = 0; uint8_t fec_source_symbol_num_ = 0; - AV1_AGGR_HEADER av1_aggr_header_; + uint8_t av1_aggr_header_ = 0; // Payload uint8_t *payload_ = nullptr;