Skip to content
This repository has been archived by the owner on Oct 25, 2024. It is now read-only.

Enable packetization support for multi-slice encoding #19

Merged
merged 1 commit into from
Aug 16, 2019
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
4 changes: 3 additions & 1 deletion call/rtp_video_sender.cc
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,9 @@ EncodedImageCallback::Result RtpVideoSender::OnEncodedImage(
RTC_DCHECK_LT(stream_index, rtp_modules_.size());
RTPVideoHeader rtp_video_header = params_[stream_index].GetRtpVideoHeader(
encoded_image, codec_specific_info, shared_frame_id_);

if (codec_specific_info->codecSpecific.H264.last_fragment_in_frame)
absl::get<RTPVideoHeaderH264>(rtp_video_header.video_type_header)
.has_last_fragement = true;
uint32_t frame_id;
if (!rtp_modules_[stream_index]->Sending()) {
// The payload router could be active but this module isn't sending.
Expand Down
2 changes: 1 addition & 1 deletion modules/rtp_rtcp/source/rtp_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class RtpPacketizer {
virtual size_t SetPayloadData(
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) = 0;
const RTPFragmentationHeader* fragmentation, bool end_of_frame) = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the style is to put the new var on its own line?


// Get the next payload with payload header.
// Write payload and set marker bit of the |packet|.
Expand Down
16 changes: 13 additions & 3 deletions modules/rtp_rtcp/source/rtp_format_h264.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ RtpPacketizerH264::RtpPacketizerH264(size_t max_payload_len,
: max_payload_len_(max_payload_len),
last_packet_reduction_len_(last_packet_reduction_len),
num_packets_left_(0),
packetization_mode_(packetization_mode) {
packetization_mode_(packetization_mode),
end_of_frame_(true) {
// Guard against uninitialized memory in packetization_mode.
RTC_CHECK(packetization_mode == H264PacketizationMode::NonInterleaved ||
packetization_mode == H264PacketizationMode::SingleNalUnit);
Expand All @@ -104,10 +105,16 @@ RtpPacketizerH264::Fragment::Fragment(const Fragment& fragment)
size_t RtpPacketizerH264::SetPayloadData(
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) {
const RTPFragmentationHeader* fragmentation,
bool end_of_frame) {
RTC_DCHECK(packets_.empty());
RTC_DCHECK(input_fragments_.empty());
RTC_DCHECK(fragmentation);
end_of_frame_ = end_of_frame;

// Different fragments allows to be packetized as FU or STAP-A or NAL,
// so there's no need to look back into history about how previous slice
// was packetized before.
for (int i = 0; i < fragmentation->fragmentationVectorSize; ++i) {
const uint8_t* buffer =
&payload_data[fragmentation->fragmentationOffset[i]];
Expand Down Expand Up @@ -348,7 +355,10 @@ bool RtpPacketizerH264::NextPacket(RtpPacketToSend* rtp_packet) {
RTC_DCHECK_LE(rtp_packet->payload_size(),
max_payload_len_ - last_packet_reduction_len_);
}
rtp_packet->SetMarker(packets_.empty());
// We will only set marker if this is really last slice
// of the AU.
rtp_packet->SetMarker(packets_.empty() && end_of_frame_);

--num_packets_left_;
return true;
}
Expand Down
4 changes: 3 additions & 1 deletion modules/rtp_rtcp/source/rtp_format_h264.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class RtpPacketizerH264 : public RtpPacketizer {

size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation,
bool end_of_frame) override;

// Get the next payload with H264 payload header.
// Write payload and set marker bit of the |packet|.
Expand Down Expand Up @@ -93,6 +94,7 @@ class RtpPacketizerH264 : public RtpPacketizer {
const H264PacketizationMode packetization_mode_;
std::deque<Fragment> input_fragments_;
std::queue<PacketUnit> packets_;
bool end_of_frame_;

RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerH264);
};
Expand Down
3 changes: 2 additions & 1 deletion modules/rtp_rtcp/source/rtp_format_h265.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ RtpPacketizerH265::Fragment::Fragment(const Fragment& fragment)
size_t RtpPacketizerH265::SetPayloadData(
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) {
const RTPFragmentationHeader* fragmentation,
bool /*end_of_frame*/) {
RTC_DCHECK(packets_.empty());
RTC_DCHECK(input_fragments_.empty());
RTC_DCHECK(fragmentation);
Expand Down
2 changes: 1 addition & 1 deletion modules/rtp_rtcp/source/rtp_format_h265.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class RtpPacketizerH265 : public RtpPacketizer {

size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation, bool end_of_frame) override;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.


// Get the next payload with H.265 payload header.
// buffer is a pointer to where the output will be written.
Expand Down
3 changes: 2 additions & 1 deletion modules/rtp_rtcp/source/rtp_format_video_generic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ RtpPacketizerGeneric::~RtpPacketizerGeneric() {}
size_t RtpPacketizerGeneric::SetPayloadData(
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) {
const RTPFragmentationHeader* fragmentation,
bool /*end_of_frame*/) {
payload_data_ = payload_data;
payload_size_ = payload_size;

Expand Down
3 changes: 2 additions & 1 deletion modules/rtp_rtcp/source/rtp_format_video_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class RtpPacketizerGeneric : public RtpPacketizer {
// Returns total number of packets to be generated.
size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation,
bool end_of_frame) override;

// Get the next payload with generic payload header.
// Write payload and set marker bit of the |packet|.
Expand Down
3 changes: 2 additions & 1 deletion modules/rtp_rtcp/source/rtp_format_vp8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ RtpPacketizerVp8::~RtpPacketizerVp8() {}
size_t RtpPacketizerVp8::SetPayloadData(
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* /* fragmentation */) {
const RTPFragmentationHeader* /* fragmentation */,
bool /*end_of_frame*/) {
payload_data_ = payload_data;
payload_size_ = payload_size;
if (GeneratePackets() < 0) {
Expand Down
3 changes: 2 additions & 1 deletion modules/rtp_rtcp/source/rtp_format_vp8.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class RtpPacketizerVp8 : public RtpPacketizer {

size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation,
bool end_of_frame) override;

// Get the next payload with VP8 payload header.
// Write payload and set marker bit of the |packet|.
Expand Down
3 changes: 2 additions & 1 deletion modules/rtp_rtcp/source/rtp_format_vp9.cc
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,8 @@ std::string RtpPacketizerVp9::ToString() {
size_t RtpPacketizerVp9::SetPayloadData(
const uint8_t* payload,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) {
const RTPFragmentationHeader* fragmentation,
bool /*end_of_frame*/) {
payload_ = payload;
payload_size_ = payload_size;
GeneratePackets();
Expand Down
3 changes: 2 additions & 1 deletion modules/rtp_rtcp/source/rtp_format_vp9.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class RtpPacketizerVp9 : public RtpPacketizer {
// The payload data must be one encoded VP9 layer frame.
size_t SetPayloadData(const uint8_t* payload,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) override;
const RTPFragmentationHeader* fragmentation,
bool end_of_frame) override;

// Gets the next payload with VP9 payload header.
// Write payload and set marker bit of the |packet|.
Expand Down
12 changes: 9 additions & 3 deletions modules/rtp_rtcp/source/rtp_sender_video.cc
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ bool RTPSenderVideo::SendVideo(enum VideoCodecType video_type,
size_t fec_packet_overhead;
bool red_enabled;
int32_t retransmission_settings;
bool frame_completed = true;
{
rtc::CritScope cs(&crit_);
// According to
Expand All @@ -307,7 +308,12 @@ bool RTPSenderVideo::SendVideo(enum VideoCodecType video_type,
// packet in each group of packets which make up another type of frame
// (e.g. a P-Frame) only if the current value is different from the previous
// value sent.
if (video_header) {
if (video_header && video_header->codec == kVideoCodecH264 &&
!absl::get<RTPVideoHeaderH264>(video_header->video_type_header)
.has_last_fragement) {
frame_completed = false;
}
if (video_header && frame_completed) {
// Set rotation when key frame or when changed (to follow standard).
// Or when different from 0 (to follow current receiver implementation).
VideoRotation current_rotation = video_header->rotation;
Expand Down Expand Up @@ -363,8 +369,8 @@ bool RTPSenderVideo::SendVideo(enum VideoCodecType video_type,
video_header ? GetTemporalId(*video_header) : kNoTemporalIdx;
StorageType storage = GetStorageType(temporal_id, retransmission_settings,
expected_retransmission_time_ms);
size_t num_packets =
packetizer->SetPayloadData(payload_data, payload_size, fragmentation);
size_t num_packets = packetizer->SetPayloadData(
payload_data, payload_size, fragmentation, frame_completed);

if (num_packets == 0)
return false;
Expand Down
7 changes: 7 additions & 0 deletions modules/video_coding/codecs/h264/include/h264_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ struct RTPVideoHeaderH264 {
// depending along with Temporal ID (obtained from RTP header extn).
// '0' if PictureID does not exist.
uint16_t picture_id;
// For support slice-based transmission, mark end of a frame so that
// the H.264 packetizer will not set marker bit for the last fragment of
// current outgoing data if it does not contain last fragment of the frame;
// and will treat the first fragment of the frame as continuous playload, so
// that it will not create FU header or STAP-A header on first fragment if contains
// last fragment of the frame.
bool has_last_fragement;
};

} // namespace webrtc
Expand Down
1 change: 1 addition & 0 deletions modules/video_coding/include/video_codec_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct CodecSpecificInfoH264 {
H264PacketizationMode packetization_mode;
uint8_t simulcast_idx;
int16_t picture_id; // Required by temporal scalability
bool last_fragment_in_frame;
};

union CodecSpecificInfoUnion {
Expand Down