1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CAST_STREAMING_FRAME_ID_H_ 6 #define CAST_STREAMING_FRAME_ID_H_ 7 8 #include <stdint.h> 9 10 #include <sstream> 11 12 #include "cast/streaming/expanded_value_base.h" 13 14 namespace openscreen { 15 namespace cast { 16 17 // Forward declaration (see below). 18 class FrameId; 19 20 // Convenience operator overloads for logging. 21 std::ostream& operator<<(std::ostream& out, const FrameId rhs); 22 23 // Unique identifier for a frame in a RTP media stream. FrameIds are truncated 24 // to 8-bit values in RTP and RTCP headers, and then expanded back by the other 25 // endpoint when parsing the headers. 26 // 27 // Usage example: 28 // 29 // // Distance/offset math. 30 // FrameId first = FrameId::first(); 31 // FrameId second = first + 1; 32 // FrameId third = second + 1; 33 // int64_t offset = third - first; 34 // FrameId fourth = second + offset; 35 // 36 // // Logging convenience. 37 // OSP_DLOG_INFO << "The current frame is " << fourth; 38 class FrameId : public ExpandedValueBase<int64_t, FrameId> { 39 public: 40 // The "null" FrameId constructor. Represents a FrameId field that has not 41 // been set and/or a "not applicable" indicator. FrameId()42 constexpr FrameId() : FrameId(std::numeric_limits<int64_t>::min()) {} 43 44 // Allow copy construction and assignment. 45 constexpr FrameId(const FrameId&) = default; 46 constexpr FrameId& operator=(const FrameId&) = default; 47 48 // Returns true if this is the special value representing null. is_null()49 constexpr bool is_null() const { return *this == FrameId(); } 50 51 // Distance operator. 52 int64_t operator-(FrameId rhs) const { 53 OSP_DCHECK(!is_null()); 54 OSP_DCHECK(!rhs.is_null()); 55 return value_ - rhs.value_; 56 } 57 58 // Operators to compute advancement by incremental amounts. 59 FrameId operator+(int64_t rhs) const { 60 OSP_DCHECK(!is_null()); 61 return FrameId(value_ + rhs); 62 } 63 FrameId operator-(int64_t rhs) const { 64 OSP_DCHECK(!is_null()); 65 return FrameId(value_ - rhs); 66 } 67 FrameId& operator+=(int64_t rhs) { 68 OSP_DCHECK(!is_null()); 69 return (*this = (*this + rhs)); 70 } 71 FrameId& operator-=(int64_t rhs) { 72 OSP_DCHECK(!is_null()); 73 return (*this = (*this - rhs)); 74 } 75 FrameId& operator++() { 76 OSP_DCHECK(!is_null()); 77 ++value_; 78 return *this; 79 } 80 FrameId& operator--() { 81 OSP_DCHECK(!is_null()); 82 --value_; 83 return *this; 84 } 85 FrameId operator++(int) { 86 OSP_DCHECK(!is_null()); 87 return FrameId(value_++); 88 } 89 FrameId operator--(int) { 90 OSP_DCHECK(!is_null()); 91 return FrameId(value_--); 92 } 93 94 // The identifier for the first frame in a stream. first()95 static constexpr FrameId first() { return FrameId(0); } 96 97 // A virtual identifier, representing the frame before the first. There should 98 // never actually be a frame streamed with this identifier. Instead, this is 99 // used in various components to represent a "not yet seen/processed the first 100 // frame" state. 101 // 102 // The name "leader" comes from the terminology used in tape reels, which 103 // refers to the non-data-carrying segment of tape before the recording 104 // begins. leader()105 static constexpr FrameId leader() { return FrameId(-1); } 106 107 private: 108 friend class ExpandedValueBase<int64_t, FrameId>; 109 friend std::ostream& operator<<(std::ostream& out, const FrameId rhs); 110 FrameId(int64_t value)111 constexpr explicit FrameId(int64_t value) : ExpandedValueBase(value) {} 112 113 // Accessor used by ostream output function. value()114 constexpr int64_t value() const { return value_; } 115 }; 116 117 } // namespace cast 118 } // namespace openscreen 119 120 #endif // CAST_STREAMING_FRAME_ID_H_ 121