blob: 2621db9bd7b6fee879798276b363b0b3b7e3f68a [file] [log] [blame]
/*
* Copyright (c) 2017 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 API_RTP_HEADERS_H_
#define API_RTP_HEADERS_H_
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/video/color_space.h"
#include "api/video/video_content_type.h"
#include "api/video/video_frame_marking.h"
#include "api/video/video_rotation.h"
#include "api/video/video_timing.h"
#include "common_types.h" // NOLINT(build/include)
namespace webrtc {
// Class to represent the value of RTP header extensions that are
// variable-length strings (e.g., RtpStreamId and RtpMid).
// Unlike std::string, it can be copied with memcpy and cleared with memset.
//
// Empty value represents unset header extension (use empty() to query).
class StringRtpHeaderExtension {
public:
// String RTP header extensions are limited to 16 bytes because it is the
// maximum length that can be encoded with one-byte header extensions.
static constexpr size_t kMaxSize = 16;
static bool IsLegalMidName(rtc::ArrayView<const char> name);
static bool IsLegalRsidName(rtc::ArrayView<const char> name);
// TODO(bugs.webrtc.org/9537): Deprecate and remove when third parties have
// migrated to "IsLegalRsidName".
static bool IsLegalName(rtc::ArrayView<const char> name) {
return IsLegalRsidName(name);
}
StringRtpHeaderExtension() { value_[0] = 0; }
explicit StringRtpHeaderExtension(rtc::ArrayView<const char> value) {
Set(value.data(), value.size());
}
StringRtpHeaderExtension(const StringRtpHeaderExtension&) = default;
StringRtpHeaderExtension& operator=(const StringRtpHeaderExtension&) =
default;
bool empty() const { return value_[0] == 0; }
const char* data() const { return value_; }
size_t size() const { return strnlen(value_, kMaxSize); }
void Set(rtc::ArrayView<const uint8_t> value) {
Set(reinterpret_cast<const char*>(value.data()), value.size());
}
void Set(const char* data, size_t size);
friend bool operator==(const StringRtpHeaderExtension& lhs,
const StringRtpHeaderExtension& rhs) {
return strncmp(lhs.value_, rhs.value_, kMaxSize) == 0;
}
friend bool operator!=(const StringRtpHeaderExtension& lhs,
const StringRtpHeaderExtension& rhs) {
return !(lhs == rhs);
}
private:
char value_[kMaxSize];
};
// StreamId represents RtpStreamId which is a string.
typedef StringRtpHeaderExtension StreamId;
// Mid represents RtpMid which is a string.
typedef StringRtpHeaderExtension Mid;
struct FeedbackRequest {
// Determines whether the recv delta as specified in
// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
// should be included.
bool include_timestamps;
// Include feedback of received packets in the range [sequence_number -
// sequence_count, sequence_number].
int sequence_count;
};
struct RTPHeaderExtension {
RTPHeaderExtension();
RTPHeaderExtension(const RTPHeaderExtension& other);
RTPHeaderExtension& operator=(const RTPHeaderExtension& other);
bool hasTransmissionTimeOffset;
int32_t transmissionTimeOffset;
bool hasAbsoluteSendTime;
uint32_t absoluteSendTime;
bool hasTransportSequenceNumber;
uint16_t transportSequenceNumber;
absl::optional<FeedbackRequest> feedback_request;
// Audio Level includes both level in dBov and voiced/unvoiced bit. See:
// https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/
bool hasAudioLevel;
bool voiceActivity;
uint8_t audioLevel;
// For Coordination of Video Orientation. See
// http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/
// ts_126114v120700p.pdf
bool hasVideoRotation;
VideoRotation videoRotation;
// TODO(ilnik): Refactor this and one above to be absl::optional() and remove
// a corresponding bool flag.
bool hasVideoContentType;
VideoContentType videoContentType;
bool has_video_timing;
VideoSendTiming video_timing;
bool has_frame_marking;
FrameMarking frame_marking;
PlayoutDelay playout_delay = {-1, -1};
// For identification of a stream when ssrc is not signaled. See
// https://tools.ietf.org/html/draft-ietf-avtext-rid-09
// TODO(danilchap): Update url from draft to release version.
StreamId stream_id;
StreamId repaired_stream_id;
// For identifying the media section used to interpret this RTP packet. See
// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-38
Mid mid;
absl::optional<ColorSpace> color_space;
};
struct RTPHeader {
RTPHeader();
RTPHeader(const RTPHeader& other);
RTPHeader& operator=(const RTPHeader& other);
bool markerBit;
uint8_t payloadType;
uint16_t sequenceNumber;
uint32_t timestamp;
uint32_t ssrc;
uint8_t numCSRCs;
uint32_t arrOfCSRCs[kRtpCsrcSize];
size_t paddingLength;
size_t headerLength;
int payload_type_frequency;
RTPHeaderExtension extension;
};
// RTCP mode to use. Compound mode is described by RFC 4585 and reduced-size
// RTCP mode is described by RFC 5506.
enum class RtcpMode { kOff, kCompound, kReducedSize };
enum NetworkState {
kNetworkUp,
kNetworkDown,
};
struct RtpKeepAliveConfig final {
// If no packet has been sent for |timeout_interval_ms|, send a keep-alive
// packet. The keep-alive packet is an empty (no payload) RTP packet with a
// payload type of 20 as long as the other end has not negotiated the use of
// this value. If this value has already been negotiated, then some other
// unused static payload type from table 5 of RFC 3551 shall be used and set
// in |payload_type|.
int64_t timeout_interval_ms = -1;
uint8_t payload_type = 20;
bool operator==(const RtpKeepAliveConfig& o) const {
return timeout_interval_ms == o.timeout_interval_ms &&
payload_type == o.payload_type;
}
bool operator!=(const RtpKeepAliveConfig& o) const { return !(*this == o); }
};
} // namespace webrtc
#endif // API_RTP_HEADERS_H_