diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index a29249edaf..6ade021c19 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -40,6 +40,7 @@ rtc_source_set("rtp_rtcp_format") { "source/rtcp_packet/tmmbr.h", "source/rtcp_packet/transport_feedback.h", "source/rtcp_packet/voip_metric.h", + "source/rtp_generic_frame_descriptor.h", "source/rtp_header_extensions.h", "source/rtp_packet.h", "source/rtp_packet_received.h", @@ -73,6 +74,7 @@ rtc_source_set("rtp_rtcp_format") { "source/rtcp_packet/tmmbr.cc", "source/rtcp_packet/transport_feedback.cc", "source/rtcp_packet/voip_metric.cc", + "source/rtp_generic_frame_descriptor.cc", "source/rtp_header_extension_map.cc", "source/rtp_header_extensions.cc", "source/rtp_packet.cc", diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc new file mode 100644 index 0000000000..caa81625c3 --- /dev/null +++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h" + +#include "rtc_base/checks.h" + +namespace webrtc { + +constexpr size_t RtpGenericFrameDescriptor::kMaxNumFrameDependencies; + +RtpGenericFrameDescriptor::RtpGenericFrameDescriptor() = default; + +int RtpGenericFrameDescriptor::TemporalLayer() const { + RTC_DCHECK(FirstPacketInSubFrame()); + return temporal_layer_; +} + +void RtpGenericFrameDescriptor::SetTemporalLayer(int temporal_layer) { + RTC_DCHECK_GE(temporal_layer, 0); + RTC_DCHECK_LE(temporal_layer, 7); + temporal_layer_ = temporal_layer; +} + +uint8_t RtpGenericFrameDescriptor::SpatialLayersBitmask() const { + RTC_DCHECK(FirstPacketInSubFrame()); + return spatial_layers_; +} + +void RtpGenericFrameDescriptor::SetSpatialLayersBitmask( + uint8_t spatial_layers) { + RTC_DCHECK(FirstPacketInSubFrame()); + spatial_layers_ = spatial_layers; +} + +uint16_t RtpGenericFrameDescriptor::FrameId() const { + RTC_DCHECK(FirstPacketInSubFrame()); + return frame_id_; +} + +void RtpGenericFrameDescriptor::SetFrameId(uint16_t frame_id) { + RTC_DCHECK(FirstPacketInSubFrame()); + frame_id_ = frame_id; +} + +rtc::ArrayView +RtpGenericFrameDescriptor::FrameDepedenciesDiffs() const { + RTC_DCHECK(FirstPacketInSubFrame()); + return rtc::MakeArrayView(frame_deps_id_diffs_, num_frame_deps_); +} + +bool RtpGenericFrameDescriptor::AddFrameDependencyDiff(uint16_t fdiff) { + RTC_DCHECK(FirstPacketInSubFrame()); + if (num_frame_deps_ == kMaxNumFrameDependencies) + return false; + RTC_DCHECK_LT(fdiff, 1 << 14); + RTC_DCHECK_GT(fdiff, 0); + frame_deps_id_diffs_[num_frame_deps_] = fdiff; + num_frame_deps_++; + return true; +} + +} // namespace webrtc diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h new file mode 100644 index 0000000000..07536e7af6 --- /dev/null +++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#ifndef MODULES_RTP_RTCP_SOURCE_RTP_GENERIC_FRAME_DESCRIPTOR_H_ +#define MODULES_RTP_RTCP_SOURCE_RTP_GENERIC_FRAME_DESCRIPTOR_H_ + +#include +#include + +#include "api/array_view.h" + +namespace webrtc { + +// Data to put on the wire for FrameDescriptor rtp header extension. +class RtpGenericFrameDescriptor { + public: + RtpGenericFrameDescriptor(); + + bool FirstPacketInSubFrame() const { return beginning_of_subframe_; } + void SetFirstPacketInSubFrame(bool first) { beginning_of_subframe_ = first; } + bool LastPacketInSubFrame() const { return end_of_subframe_; } + void SetLastPacketInSubFrame(bool last) { end_of_subframe_ = last; } + + bool FirstSubFrameInFrame() const { return beginning_of_frame_; } + void SetFirstSubFrameInFrame(bool first) { beginning_of_frame_ = first; } + bool LastSubFrameInFrame() const { return end_of_frame_; } + void SetLastSubFrameInFrame(bool last) { end_of_frame_ = last; } + + // Properties below undefined if !FirstPacketInSubFrame() + // Valid range for temporal layer: [0, 7] + int TemporalLayer() const; + void SetTemporalLayer(int temporal_layer); + + // Frame might by used, possible indrectly, for spatial layer sid iff + // (bitmask & (1 << sid)) != 0 + uint8_t SpatialLayersBitmask() const; + void SetSpatialLayersBitmask(uint8_t spatial_layers); + + uint16_t FrameId() const; + void SetFrameId(uint16_t frame_id); + + rtc::ArrayView FrameDepedenciesDiffs() const; + void ClearFrameDependencies() { num_frame_deps_ = 0; } + // Returns false on failure, i.e. number of dependencies is too large. + bool AddFrameDependencyDiff(uint16_t fdiff); + + private: + static constexpr size_t kMaxNumFrameDependencies = 8; + + bool beginning_of_subframe_ = false; + bool end_of_subframe_ = false; + bool beginning_of_frame_ = false; + bool end_of_frame_ = false; + + uint16_t frame_id_ = 0; + uint8_t spatial_layers_ = 1; + uint8_t temporal_layer_ = 0; + size_t num_frame_deps_ = 0; + uint16_t frame_deps_id_diffs_[kMaxNumFrameDependencies]; +}; + +} // namespace webrtc + +#endif // MODULES_RTP_RTCP_SOURCE_RTP_GENERIC_FRAME_DESCRIPTOR_H_