Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Unified Diff: webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc

Issue 2954503002: Implement FrameMarking header extension support
Patch Set: remove unneeded change in comment Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
index f630bafe280cd6b4cff76a6fe5404078932a89fe..a4f34f7c2b15a54bda50c7b2beed93ec7c6ac446 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc
@@ -379,4 +379,106 @@ bool RepairedRtpStreamId::Write(uint8_t* data, const std::string& rsid) {
return RtpStreamId::Write(data, rsid);
}
+// For Frame Marking RTP Header Extension:
+//
+// https://tools.ietf.org/html/draft-ietf-avtext-framemarking-04#page-4
+// This extensions provides meta-information about the RTP streams outside the
+// encrypted media payload, an RTP switch can do codec-agnostic
+// selective forwarding without decrypting the payload.
+//
+// for Non-Scalable Streams:
+//
+// 0 1
+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | ID=? | L=0 |S|E|I|D|0 0 0 0|
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// for Scalable Streams:
+//
+// 0 1 2 3
+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | ID=? | L=2 |S|E|I|D|B| TID | LID | TL0PICIDX |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+constexpr RTPExtensionType FrameMarking::kId;
+constexpr const char* FrameMarking::kUri;
+
+bool FrameMarking::Parse(rtc::ArrayView<const uint8_t> data,
+ FrameMarks* frame_marks) {
+ RTC_DCHECK(frame_marks);
+
+ if (data.empty())
+ return false;
+
+ // Set frame marking data
+ frame_marks->start_of_frame = (data[0] & 0x80) != 0;
+ frame_marks->end_of_frame = (data[0] & 0x40) != 0;
+ frame_marks->independent = (data[0] & 0x20) != 0;
+ frame_marks->discardable = (data[0] & 0x10) != 0;
+
+ // Check variable length.
+ if (data.size() == 1) {
+ // We are non-scalable.
+ frame_marks->base_layer_sync = false;
+ frame_marks->temporal_layer_id = 0;
+ frame_marks->layer_id = 0;
+ frame_marks->tl0_pic_idx = 0;
+ } else if (data.size() == 3) {
+ // Set scalable parts
+ frame_marks->base_layer_sync = (data[0] & 0x08) != 0;
+ frame_marks->temporal_layer_id = data[0] & 0x07;
+ frame_marks->layer_id = data[1];
+ frame_marks->tl0_pic_idx = data[2];
+ } else {
+ // Incorrect length.
+ return false;
+ }
+ return true;
+}
+
+bool FrameMarking::IsScalable(const FrameMarks& frame_marks) {
+ return (frame_marks.base_layer_sync ||
+ (frame_marks.temporal_layer_id &&
+ frame_marks.temporal_layer_id != kNoTemporalIdx) ||
+ (frame_marks.layer_id && frame_marks.layer_id != kNoSpatialIdx) ||
+ (frame_marks.tl0_pic_idx && frame_marks.tl0_pic_idx != kNoTl0PicIdx));
+}
+
+size_t FrameMarking::ValueSize(const FrameMarks& frame_marks) {
+ return IsScalable(frame_marks) ? 3 : 1;
+}
+
+bool FrameMarking::Write(uint8_t* data, const FrameMarks& frame_marks) {
+ data[0] = frame_marks.start_of_frame ? 0x80 : 0x00;
+ data[0] |= frame_marks.end_of_frame ? 0x40 : 0x00;
+ data[0] |= frame_marks.independent ? 0x20 : 0x00;
+ data[0] |= frame_marks.discardable ? 0x10 : 0x00;
+
+ // Check if it is scalable.
+ if (IsScalable(frame_marks)) {
+ data[0] |= frame_marks.base_layer_sync ? 0x08 : 0x00;
+ data[0] |= (frame_marks.temporal_layer_id & 0x07);
+ data[1] = frame_marks.layer_id;
+ data[2] = static_cast<uint8_t>(frame_marks.tl0_pic_idx);
+ }
+ return true;
+}
+
+uint8_t FrameMarking::CreateLayerId(const RTPVideoHeaderVP9& vp9) {
+ // The following shows VP9 Layer encoding information (3 bits for
+ // spatial and temporal layer) mapped to the generic LID and TID fields.
+ // The P and U bits MUST match the corresponding bits in the VP9 Payload
+ // Description.
+ // 0 1 2 3
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | ID=2 | L=2 |S|E|I|D|B| TID |0|0|0|P|U| SID | TL0PICIDX |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ return (vp9.spatial_idx != kNoSpatialIdx ? vp9.spatial_idx & 0x07 : 0x00) |
+ (vp9.temporal_up_switch ? 0x08 : 0x00) |
+ (vp9.inter_pic_predicted ? 0x10 : 0x00);
+}
+
} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698