diff --git a/src/rtp/obu_parser.cpp b/src/rtp/obu_parser.cpp index 8ce677c..b16c708 100644 --- a/src/rtp/obu_parser.cpp +++ b/src/rtp/obu_parser.cpp @@ -184,7 +184,7 @@ int AdditionalBytesForPreviousObuElement(const Packet& packet) { return Leb128Size(packet.last_obu_size); } -std::vector Packetize(std::vector obus, PayloadSizeLimits limits) { +std::vector Packetize(std::vector obus) { int max_payload_len = 1200; std::vector packets; if (obus.empty()) { diff --git a/src/rtp/obu_parser.h b/src/rtp/obu_parser.h index 7bddbe4..47281fb 100644 --- a/src/rtp/obu_parser.h +++ b/src/rtp/obu_parser.h @@ -12,10 +12,15 @@ #include #include "obu.h" +#include "rtp_packet.h" namespace obu { std::vector ParseObus(uint8_t* payload, int payload_size); +std::vector Packetize(std::vector obus); + +bool NextPacket(RtpPacket* packet); + const char* ObuTypeToString(OBU_TYPE type); bool ObuHasExtension(uint8_t obu_header); diff --git a/src/rtp/rtp_codec.cpp b/src/rtp/rtp_codec.cpp index b3b3de6..ccb87f2 100644 --- a/src/rtp/rtp_codec.cpp +++ b/src/rtp/rtp_codec.cpp @@ -517,7 +517,86 @@ void RtpCodec::Encode(VideoFrameType frame_type, uint8_t* buffer, size_t size, } } } else if (RtpPacket::PAYLOAD_TYPE::AV1 == payload_type_) { - EncodeAv1(buffer, size, packets); + std::vector obus = ParseObus(buffer, size); + // LOG_ERROR("Total size = [{}]", size); + + uint32_t timestamp = + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + + for (int i = 0; i < obus.size(); i++) { + // LOG_ERROR("1 [{}] Obu size = [{}], Obu type [{}]", i, obus[i].size_, + // ObuTypeToString((OBU_TYPE)ObuType(obus[i].header_))); + + 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(1); + 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_); + } + + rtp_packet.SetAv1AggrHeader(0, 0, 1, 0); + rtp_packet.EncodeAv1(obus[i].data_, obus[i].size_); + + packets.emplace_back(rtp_packet); + } else { + size_t last_packet_size = obus[i].size_ % MAX_NALU_LEN; + size_t packet_num = + obus[i].size_ / MAX_NALU_LEN + (last_packet_size ? 1 : 0); + + 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_); + } + + int z = index != 0 ? 1 : 0; + int y = index != packet_num - 1 ? 1 : 0; + int w = 1; + int n = (frame_type == VideoFrameType::kVideoFrameKey) && + (ObuType(obus[i].header_) == kObuTypeSequenceHeader) + ? 1 + : 0; + rtp_packet.SetAv1AggrHeader(z, y, w, n); + + if (index == packet_num - 1 && last_packet_size > 0) { + rtp_packet.EncodeAv1(obus[i].data_ + index * MAX_NALU_LEN, + last_packet_size); + } else { + rtp_packet.EncodeAv1(obus[i].data_ + index * MAX_NALU_LEN, + MAX_NALU_LEN); + } + + packets.emplace_back(rtp_packet); + } + } + } } } diff --git a/src/rtp/rtp_codec_av1.cpp b/src/rtp/rtp_codec_av1.cpp index f39be1c..78eb11c 100644 --- a/src/rtp/rtp_codec_av1.cpp +++ b/src/rtp/rtp_codec_av1.cpp @@ -1,9 +1,17 @@ #include "byte_buffer.h" #include "log.h" +#include "obu_parser.h" #include "rtp_codec.h" void EncodeAv1(uint8_t* buffer, size_t size, std::vector& packets) { - std::vector obus = ParseObus(buffer, size); + std::vector obus = obu::ParseObus(buffer, size); + std::vector packets = obu::Packetizer(obus); + + int num_packets = packets.size(); + + if (1 == num_packets) { + } + // LOG_ERROR("Total size = [{}]", size); uint32_t timestamp = std::chrono::duration_cast( diff --git a/src/rtp/rtp_packet.h b/src/rtp/rtp_packet.h index 6274f09..177f8a9 100644 --- a/src/rtp/rtp_packet.h +++ b/src/rtp/rtp_packet.h @@ -149,6 +149,17 @@ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | AV1 aggr hdr | +// +// Z=1: first obu element is an obu fragment that is a continuation of an OBU +// fragment from the previous packet. +// +// Y=1: the last OBU element is an OBU fragment that will continue in the next +// packet. +// +// W=1: two bit field that describes the number of OBU elements in the packet. +// +// N=1: the packet is the first packet of a coded video sequence. +// // 0 1 2 3 4 5 6 7 // +-+-+-+-+-+-+-+-+ // |Z|Y| W |N|-|-|-|