Skip to content

Commit

Permalink
H264RtpDepacketizer: Make start sequence configurable
Browse files Browse the repository at this point in the history
Add a parameter to the constructor for configuring the start sequence to
use when writing NALUs.
  • Loading branch information
edmonds committed Apr 13, 2024
1 parent e9663d8 commit 27f238f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
7 changes: 6 additions & 1 deletion include/rtc/h264rtpdepacketizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "common.hpp"
#include "mediahandler.hpp"
#include "message.hpp"
#include "nalunit.hpp"
#include "rtp.hpp"

#include <iterator>
Expand All @@ -24,14 +25,18 @@ namespace rtc {
/// RTP depacketization for H264
class RTC_CPP_EXPORT H264RtpDepacketizer : public MediaHandler {
public:
H264RtpDepacketizer() = default;
using Separator = NalUnit::Separator;

H264RtpDepacketizer(Separator separator = Separator::LongStartSequence);
virtual ~H264RtpDepacketizer() = default;

void incoming(message_vector &messages, const message_callback &send) override;

private:
std::vector<message_ptr> mRtpBuffer;
const NalUnit::Separator separator;

void addSeparator(binary& accessUnit);
message_vector buildFrames(message_vector::iterator firstPkt, message_vector::iterator lastPkt,
uint32_t timestamp);
};
Expand Down
42 changes: 37 additions & 5 deletions src/h264rtpdepacketizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,44 @@

namespace rtc {

const binary naluStartCode = {byte{0}, byte{0}, byte{1}};
const binary naluLongStartCode = {byte{0}, byte{0}, byte{0}, byte{1}};
const binary naluShortStartCode = {byte{0}, byte{0}, byte{1}};

const uint8_t naluTypeSTAPA = 24;
const uint8_t naluTypeFUA = 28;

H264RtpDepacketizer::H264RtpDepacketizer(Separator separator) : separator(separator) {
switch (separator) {
case Separator::StartSequence: [[fallthrough]];
case Separator::LongStartSequence: [[fallthrough]];
case Separator::ShortStartSequence:
break;
case Separator::Length: [[fallthrough]];
default:
throw std::invalid_argument("Invalid separator");
}
}

void H264RtpDepacketizer::addSeparator(binary& accessUnit)
{
switch (separator) {
case Separator::StartSequence: [[fallthrough]];
case Separator::LongStartSequence:
accessUnit.insert(accessUnit.end(),
naluLongStartCode.begin(),
naluLongStartCode.end());
break;
case Separator::ShortStartSequence:
accessUnit.insert(accessUnit.end(),
naluShortStartCode.begin(),
naluShortStartCode.end());
break;
case Separator::Length: [[fallthrough]];
default:
throw std::invalid_argument("Invalid separator");
}
}

message_vector H264RtpDepacketizer::buildFrames(message_vector::iterator begin,
message_vector::iterator end, uint32_t timestamp) {
message_vector out = {};
Expand Down Expand Up @@ -49,8 +82,7 @@ message_vector H264RtpDepacketizer::buildFrames(message_vector::iterator begin,
std::to_integer<uint8_t>(pkt->at(rtpHeaderSize + sizeof(NalUnitHeader)))};

if (nFrags++ == 0) {
accessUnit.insert(accessUnit.end(), naluStartCode.begin(), naluStartCode.end());

addSeparator(accessUnit);
accessUnit.emplace_back(
byte(nalUnitHeader.idc() | nalUnitFragmentHeader.unitType()));
}
Expand All @@ -60,7 +92,7 @@ message_vector H264RtpDepacketizer::buildFrames(message_vector::iterator begin,
sizeof(NalUnitFragmentHeader),
pkt->end());
} else if (nalUnitHeader.unitType() > 0 && nalUnitHeader.unitType() < 24) {
accessUnit.insert(accessUnit.end(), naluStartCode.begin(), naluStartCode.end());
addSeparator(accessUnit);
accessUnit.insert(accessUnit.end(), pkt->begin() + rtpHeaderSize, pkt->end());
} else if (nalUnitHeader.unitType() == naluTypeSTAPA) {
auto currOffset = rtpHeaderSize + sizeof(NalUnitHeader);
Expand All @@ -75,7 +107,7 @@ message_vector H264RtpDepacketizer::buildFrames(message_vector::iterator begin,
throw std::runtime_error("H264 STAP-A declared size is larger than buffer");
}

accessUnit.insert(accessUnit.end(), naluStartCode.begin(), naluStartCode.end());
addSeparator(accessUnit);
accessUnit.insert(accessUnit.end(), pkt->begin() + currOffset,
pkt->begin() + currOffset + naluSize);

Expand Down

0 comments on commit 27f238f

Please sign in to comment.