OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MEDIA_CAST_NET_CAST_TRANSPORT_DEFINES_H_ | 5 #ifndef MEDIA_CAST_NET_CAST_TRANSPORT_DEFINES_H_ |
6 #define MEDIA_CAST_NET_CAST_TRANSPORT_DEFINES_H_ | 6 #define MEDIA_CAST_NET_CAST_TRANSPORT_DEFINES_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <map> | 10 #include <map> |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 kRtcpRrtr = 0x0800, | 54 kRtcpRrtr = 0x0800, |
55 kRtcpCast = 0x20000, | 55 kRtcpCast = 0x20000, |
56 kRtcpReceiverLog = 0x80000, | 56 kRtcpReceiverLog = 0x80000, |
57 }; | 57 }; |
58 | 58 |
59 // Each uint16 represents one packet id within a cast frame. | 59 // Each uint16 represents one packet id within a cast frame. |
60 typedef std::set<uint16> PacketIdSet; | 60 typedef std::set<uint16> PacketIdSet; |
61 // Each uint8 represents one cast frame. | 61 // Each uint8 represents one cast frame. |
62 typedef std::map<uint8, PacketIdSet> MissingFramesAndPacketsMap; | 62 typedef std::map<uint8, PacketIdSet> MissingFramesAndPacketsMap; |
63 | 63 |
| 64 class FrameIdWrapHelperTest; |
| 65 |
64 // TODO(miu): UGLY IN-LINE DEFINITION IN HEADER FILE! Move to appropriate | 66 // TODO(miu): UGLY IN-LINE DEFINITION IN HEADER FILE! Move to appropriate |
65 // location, separated into .h and .cc files. | 67 // location, separated into .h and .cc files. |
66 class FrameIdWrapHelper { | 68 class FrameIdWrapHelper { |
67 public: | 69 public: |
68 FrameIdWrapHelper() | 70 FrameIdWrapHelper() |
69 : first_(true), frame_id_wrap_count_(0), range_(kLowRange) {} | 71 : largest_frame_id_seen_(kStartFrameId) {} |
70 | 72 |
71 uint32 MapTo32bitsFrameId(const uint8 over_the_wire_frame_id) { | 73 uint32 MapTo32bitsFrameId(const uint8 over_the_wire_frame_id) { |
72 if (first_) { | 74 uint32 ret = (largest_frame_id_seen_ & ~0xff) | over_the_wire_frame_id; |
73 first_ = false; | 75 // Add 1000 to both sides to avoid underflows. |
74 if (over_the_wire_frame_id == 0xff) { | 76 if (1000 + ret - largest_frame_id_seen_ > 1000 + 127) { |
75 // Special case for startup. | 77 ret -= 0x100; |
76 return kStartFrameId; | 78 } else if (1000 + ret - largest_frame_id_seen_ < 1000 - 128) { |
77 } | 79 ret += 0x100; |
78 } | 80 } |
79 | 81 if (1000 + ret - largest_frame_id_seen_ > 1000) { |
80 uint32 wrap_count = frame_id_wrap_count_; | 82 largest_frame_id_seen_ = ret; |
81 switch (range_) { | |
82 case kLowRange: | |
83 if (over_the_wire_frame_id > kLowRangeThreshold && | |
84 over_the_wire_frame_id < kHighRangeThreshold) { | |
85 range_ = kMiddleRange; | |
86 } | |
87 if (over_the_wire_frame_id >= kHighRangeThreshold) { | |
88 // Wrap count was incremented in High->Low transition, but this frame | |
89 // is 'old', actually from before the wrap count got incremented. | |
90 --wrap_count; | |
91 } | |
92 break; | |
93 case kMiddleRange: | |
94 if (over_the_wire_frame_id >= kHighRangeThreshold) { | |
95 range_ = kHighRange; | |
96 } | |
97 break; | |
98 case kHighRange: | |
99 if (over_the_wire_frame_id <= kLowRangeThreshold) { | |
100 // Wrap-around detected. | |
101 range_ = kLowRange; | |
102 ++frame_id_wrap_count_; | |
103 // Frame triggering wrap-around so wrap count should be incremented as | |
104 // as well to match |frame_id_wrap_count_|. | |
105 ++wrap_count; | |
106 } | |
107 break; | |
108 } | 83 } |
109 return (wrap_count << 8) + over_the_wire_frame_id; | 84 return ret; |
110 } | 85 } |
111 | 86 |
112 private: | 87 private: |
113 enum Range { kLowRange, kMiddleRange, kHighRange, }; | 88 friend class FrameIdWrapHelperTest; |
114 | |
115 static const uint8 kLowRangeThreshold = 63; | |
116 static const uint8 kHighRangeThreshold = 192; | |
117 static const uint32 kStartFrameId = UINT32_C(0xffffffff); | 89 static const uint32 kStartFrameId = UINT32_C(0xffffffff); |
118 | 90 |
119 bool first_; | 91 uint32 largest_frame_id_seen_; |
120 uint32 frame_id_wrap_count_; | |
121 Range range_; | |
122 | 92 |
123 DISALLOW_COPY_AND_ASSIGN(FrameIdWrapHelper); | 93 DISALLOW_COPY_AND_ASSIGN(FrameIdWrapHelper); |
124 }; | 94 }; |
125 | 95 |
126 inline uint32 GetVideoRtpTimestamp(const base::TimeTicks& time_ticks) { | 96 inline uint32 GetVideoRtpTimestamp(const base::TimeTicks& time_ticks) { |
127 base::TimeTicks zero_time; | 97 base::TimeTicks zero_time; |
128 base::TimeDelta recorded_delta = time_ticks - zero_time; | 98 base::TimeDelta recorded_delta = time_ticks - zero_time; |
129 // Timestamp is in 90 KHz for video. | 99 // Timestamp is in 90 KHz for video. |
130 return static_cast<uint32>(recorded_delta.InMilliseconds() * 90); | 100 return static_cast<uint32>(recorded_delta.InMilliseconds() * 90); |
131 } | 101 } |
132 | 102 |
133 } // namespace cast | 103 } // namespace cast |
134 } // namespace media | 104 } // namespace media |
135 | 105 |
136 #endif // MEDIA_CAST_NET_CAST_TRANSPORT_DEFINES_H_ | 106 #endif // MEDIA_CAST_NET_CAST_TRANSPORT_DEFINES_H_ |
OLD | NEW |