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 2f3feb34cd3851f53da1bbda45d5f90a9f575bd8..ac8b38541bc4cb37515b96a010ddf78b4f8855c4 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtp_header_extensions.cc |
@@ -313,4 +313,100 @@ 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(const uint8_t* data, |
+ uint8_t length, |
+ FrameMarks* frame_marks) { |
+ RTC_DCHECK(frame_marks); |
+ RTC_DCHECK(length); |
+ // Set frame marking data |
+ frame_marks->startOfFrame = (data[0] & 0x80) != 0; |
+ frame_marks->endOfFrame = (data[0] & 0x40) != 0; |
+ frame_marks->independent = (data[0] & 0x20) != 0; |
+ frame_marks->discardable = (data[0] & 0x10) != 0; |
+ |
+ // Check variable length |
+ if (length==1) { |
danilchap
2017/06/28 16:07:06
please use git cl format (to add spaces around '==
sergio.garcia.murillo
2017/06/29 12:58:58
Done.
|
+ // We are non-scalable |
+ frame_marks->baseLayerSync = 0; |
+ frame_marks->temporalLayerId = 0; |
+ frame_marks->spatialLayerId = 0; |
+ frame_marks->tl0PicIdx = 0; |
+ } else if (length==3) { |
+ // Set scalable parts |
+ frame_marks->baseLayerSync = (data[0] & 0x08) != 0; |
+ frame_marks->temporalLayerId = (data[0] & 0x07) != 0; |
danilchap
2017/06/28 16:07:06
remove "!= 0"
sergio.garcia.murillo
2017/06/29 12:58:57
msvc gives C4800 warning: forcing value to bool 't
danilchap
2017/06/29 13:47:26
is temporal_layer_id a boolean field?
sergio.garcia.murillo
2017/06/30 10:09:23
uuuupsss!
|
+ frame_marks->spatialLayerId = data[1]; |
+ frame_marks->tl0PicIdx = data[2]; |
+ } else { |
+ // Incorrect length |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+size_t FrameMarking::ValueSize(const FrameMarks& frame_marks) { |
+ // Check if it is scalable |
+ if (frame_marks.baseLayerSync |
+ || (frame_marks.temporalLayerId |
+ && frame_marks.temporalLayerId != kNoTemporalIdx) |
+ || (frame_marks.spatialLayerId |
+ && frame_marks.spatialLayerId != kNoSpatialIdx) |
+ || (frame_marks.tl0PicIdx |
+ && frame_marks.tl0PicIdx != (uint8_t)kNoTl0PicIdx) |
danilchap
2017/06/28 16:07:06
use static_cast instead of c-cast,
sergio.garcia.murillo
2017/06/29 12:58:58
Done.
danilchap
2017/06/29 13:47:26
still c-cast in this line
sergio.garcia.murillo
2017/06/30 10:09:23
Done. This time for sure.
|
+ ) |
+ return 3; |
+ else |
+ return 1; |
+} |
+ |
+bool FrameMarking::Write(uint8_t* data, const FrameMarks& frame_marks) { |
+ data[0] = frame_marks.startOfFrame ? 0x80 : 0x00; |
+ data[0] |= frame_marks.endOfFrame ? 0x40 : 0x00; |
+ data[0] |= frame_marks.independent ? 0x20 : 0x00; |
+ data[0] |= frame_marks.discardable ? 0x10 : 0x00; |
+ |
+ // Check if it is scalable |
+ if (frame_marks.baseLayerSync |
+ || (frame_marks.temporalLayerId |
danilchap
2017/06/28 16:07:06
is temporal_layer_id == 0 a value that shouldn't b
sergio.garcia.murillo
2017/06/29 12:58:57
No, but if temporal and spatial layer are 0 and tl
|
+ && frame_marks.temporalLayerId != kNoTemporalIdx) |
+ || (frame_marks.spatialLayerId |
+ && frame_marks.spatialLayerId != kNoSpatialIdx) |
+ || (frame_marks.tl0PicIdx |
+ && frame_marks.tl0PicIdx != (uint8_t)kNoTl0PicIdx) |
+ ) { |
+ data[0] |= frame_marks.baseLayerSync ? 0x08 : 0x00; |
+ data[0] |= (frame_marks.temporalLayerId & 0x07); |
+ data[1] = frame_marks.spatialLayerId; |
+ data[2] = frame_marks.tl0PicIdx; |
+ } |
+ return true; |
+} |
+ |
} // namespace webrtc |