Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
| 11 | #ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_PAYLOAD_REGISTRY_H_ |
| 12 | #define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_PAYLOAD_REGISTRY_H_ |
| 13 | |
danilchap | bafd7a0 | 2015-12-10 13:05:27 | [diff] [blame] | 14 | #include <map> |
kwiberg | 6e27acd | 2016-04-27 08:19:58 | [diff] [blame] | 15 | #include <memory> |
danilchap | bafd7a0 | 2015-12-10 13:05:27 | [diff] [blame] | 16 | |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 17 | #include "webrtc/base/criticalsection.h" |
terelius | 1da39d1 | 2016-04-26 16:31:59 | [diff] [blame] | 18 | #include "webrtc/base/scoped_ptr.h" |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 19 | #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" |
| 20 | #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
| 21 | |
| 22 | namespace webrtc { |
| 23 | |
| 24 | // This strategy deals with the audio/video-specific aspects |
| 25 | // of payload handling. |
| 26 | class RTPPayloadStrategy { |
| 27 | public: |
| 28 | virtual ~RTPPayloadStrategy() {} |
| 29 | |
| 30 | virtual bool CodecsMustBeUnique() const = 0; |
| 31 | |
| 32 | virtual bool PayloadIsCompatible(const RtpUtility::Payload& payload, |
| 33 | const uint32_t frequency, |
Peter Kasting | 80590d9 | 2016-01-13 00:26:35 | [diff] [blame] | 34 | const size_t channels, |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 35 | const uint32_t rate) const = 0; |
| 36 | |
| 37 | virtual void UpdatePayloadRate(RtpUtility::Payload* payload, |
| 38 | const uint32_t rate) const = 0; |
| 39 | |
| 40 | virtual RtpUtility::Payload* CreatePayloadType( |
| 41 | const char payloadName[RTP_PAYLOAD_NAME_SIZE], |
| 42 | const int8_t payloadType, |
| 43 | const uint32_t frequency, |
Peter Kasting | 80590d9 | 2016-01-13 00:26:35 | [diff] [blame] | 44 | const size_t channels, |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 45 | const uint32_t rate) const = 0; |
| 46 | |
| 47 | virtual int GetPayloadTypeFrequency( |
| 48 | const RtpUtility::Payload& payload) const = 0; |
| 49 | |
| 50 | static RTPPayloadStrategy* CreateStrategy(const bool handling_audio); |
| 51 | |
| 52 | protected: |
| 53 | RTPPayloadStrategy() {} |
| 54 | }; |
| 55 | |
| 56 | class RTPPayloadRegistry { |
| 57 | public: |
| 58 | // The registry takes ownership of the strategy. |
danilchap | 221f87d | 2015-12-10 17:51:54 | [diff] [blame] | 59 | explicit RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 60 | ~RTPPayloadRegistry(); |
| 61 | |
| 62 | int32_t RegisterReceivePayload( |
| 63 | const char payload_name[RTP_PAYLOAD_NAME_SIZE], |
| 64 | const int8_t payload_type, |
| 65 | const uint32_t frequency, |
Peter Kasting | 80590d9 | 2016-01-13 00:26:35 | [diff] [blame] | 66 | const size_t channels, |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 67 | const uint32_t rate, |
| 68 | bool* created_new_payload_type); |
| 69 | |
| 70 | int32_t DeRegisterReceivePayload( |
| 71 | const int8_t payload_type); |
| 72 | |
| 73 | int32_t ReceivePayloadType( |
| 74 | const char payload_name[RTP_PAYLOAD_NAME_SIZE], |
| 75 | const uint32_t frequency, |
Peter Kasting | 80590d9 | 2016-01-13 00:26:35 | [diff] [blame] | 76 | const size_t channels, |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 77 | const uint32_t rate, |
| 78 | int8_t* payload_type) const; |
| 79 | |
| 80 | bool RtxEnabled() const; |
| 81 | |
| 82 | void SetRtxSsrc(uint32_t ssrc); |
| 83 | |
| 84 | bool GetRtxSsrc(uint32_t* ssrc) const; |
| 85 | |
| 86 | void SetRtxPayloadType(int payload_type, int associated_payload_type); |
| 87 | |
| 88 | bool IsRtx(const RTPHeader& header) const; |
| 89 | |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 90 | bool RestoreOriginalPacket(uint8_t* restored_packet, |
| 91 | const uint8_t* packet, |
| 92 | size_t* packet_length, |
| 93 | uint32_t original_ssrc, |
| 94 | const RTPHeader& header) const; |
| 95 | |
| 96 | bool IsRed(const RTPHeader& header) const; |
| 97 | |
| 98 | // Returns true if the media of this RTP packet is encapsulated within an |
| 99 | // extra header, such as RTX or RED. |
| 100 | bool IsEncapsulated(const RTPHeader& header) const; |
| 101 | |
| 102 | bool GetPayloadSpecifics(uint8_t payload_type, PayloadUnion* payload) const; |
| 103 | |
| 104 | int GetPayloadTypeFrequency(uint8_t payload_type) const; |
| 105 | |
danilchap | 221f87d | 2015-12-10 17:51:54 | [diff] [blame] | 106 | const RtpUtility::Payload* PayloadTypeToPayload(uint8_t payload_type) const; |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 107 | |
| 108 | void ResetLastReceivedPayloadTypes() { |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 109 | rtc::CritScope cs(&crit_sect_); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 110 | last_received_payload_type_ = -1; |
| 111 | last_received_media_payload_type_ = -1; |
| 112 | } |
| 113 | |
| 114 | // This sets the payload type of the packets being received from the network |
| 115 | // on the media SSRC. For instance if packets are encapsulated with RED, this |
| 116 | // payload type will be the RED payload type. |
| 117 | void SetIncomingPayloadType(const RTPHeader& header); |
| 118 | |
| 119 | // Returns true if the new media payload type has not changed. |
| 120 | bool ReportMediaPayloadType(uint8_t media_payload_type); |
| 121 | |
| 122 | int8_t red_payload_type() const { |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 123 | rtc::CritScope cs(&crit_sect_); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 124 | return red_payload_type_; |
| 125 | } |
| 126 | int8_t ulpfec_payload_type() const { |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 127 | rtc::CritScope cs(&crit_sect_); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 128 | return ulpfec_payload_type_; |
| 129 | } |
| 130 | int8_t last_received_payload_type() const { |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 131 | rtc::CritScope cs(&crit_sect_); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 132 | return last_received_payload_type_; |
| 133 | } |
| 134 | void set_last_received_payload_type(int8_t last_received_payload_type) { |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 135 | rtc::CritScope cs(&crit_sect_); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 136 | last_received_payload_type_ = last_received_payload_type; |
| 137 | } |
| 138 | |
| 139 | int8_t last_received_media_payload_type() const { |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 140 | rtc::CritScope cs(&crit_sect_); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 141 | return last_received_media_payload_type_; |
danilchap | 221f87d | 2015-12-10 17:51:54 | [diff] [blame] | 142 | } |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 143 | |
| 144 | bool use_rtx_payload_mapping_on_restore() const { |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 145 | rtc::CritScope cs(&crit_sect_); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 146 | return use_rtx_payload_mapping_on_restore_; |
| 147 | } |
| 148 | |
| 149 | void set_use_rtx_payload_mapping_on_restore(bool val) { |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 150 | rtc::CritScope cs(&crit_sect_); |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 151 | use_rtx_payload_mapping_on_restore_ = val; |
| 152 | } |
| 153 | |
| 154 | private: |
| 155 | // Prunes the payload type map of the specific payload type, if it exists. |
| 156 | void DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType( |
| 157 | const char payload_name[RTP_PAYLOAD_NAME_SIZE], |
| 158 | const size_t payload_name_length, |
| 159 | const uint32_t frequency, |
Peter Kasting | 80590d9 | 2016-01-13 00:26:35 | [diff] [blame] | 160 | const size_t channels, |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 161 | const uint32_t rate); |
| 162 | |
| 163 | bool IsRtxInternal(const RTPHeader& header) const; |
| 164 | |
danilchap | 590e847 | 2016-04-14 10:05:31 | [diff] [blame] | 165 | rtc::CriticalSection crit_sect_; |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 166 | RtpUtility::PayloadTypeMap payload_type_map_; |
kwiberg | 6e27acd | 2016-04-27 08:19:58 | [diff] [blame] | 167 | std::unique_ptr<RTPPayloadStrategy> rtp_payload_strategy_; |
Henrik Kjellander | 36a14b5 | 2015-11-04 07:31:52 | [diff] [blame] | 168 | int8_t red_payload_type_; |
| 169 | int8_t ulpfec_payload_type_; |
| 170 | int8_t incoming_payload_type_; |
| 171 | int8_t last_received_payload_type_; |
| 172 | int8_t last_received_media_payload_type_; |
| 173 | bool rtx_; |
| 174 | // TODO(changbin): Remove rtx_payload_type_ once interop with old clients that |
| 175 | // only understand one RTX PT is no longer needed. |
| 176 | int rtx_payload_type_; |
| 177 | // Mapping rtx_payload_type_map_[rtx] = associated. |
| 178 | std::map<int, int> rtx_payload_type_map_; |
| 179 | // When true, use rtx_payload_type_map_ when restoring RTX packets to get the |
| 180 | // correct payload type. |
| 181 | bool use_rtx_payload_mapping_on_restore_; |
| 182 | uint32_t ssrc_rtx_; |
| 183 | }; |
| 184 | |
| 185 | } // namespace webrtc |
| 186 | |
| 187 | #endif // WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_PAYLOAD_REGISTRY_H_ |