WebRTCソース分析のRTP/RTCP(二)
7729 ワード
WebRTCにおけるRTPとRTCPは1つのUDPポートを共有する
WebRTCのRTPとRTCPは共にudp伝送を用い,RTPとRTCPは同一のudpポートを混合して用いているが,NATをオンにすることは本来容易なことではないため,両ポートを分離すればプログラムの複雑さとNATホール成功の難しさを増す.
WebRTCはどのようにRTP/RTCPパッケージを区別します
RTPとRTCPが同じUDPポートを使用している以上、受信したUDPパケットがRTPであるかRTCPパケットであるかを区別し、上記のコードでは
RTP/RTCPの関連コードは
RTPの2バイト目は、タグビット(M):1ビットペイロードタイプ(PT):7ビット
RTCPの2バイト目はパケットタイプ(PT):8ビット
2バイト目の値が200の場合、バイナリに換算すると11001000になります.RTCPパケットであればPT=SR RTPパケットであればタグビット(M)=1、PT=72であるが72-76はRTCP保留使用と規定されているため、RTPパケットであることは不可能である.具体的なRTP Payload types参考:https://www.ietf.org/assignments/rtp-parameters/rtp-parameters.xml
したがって、PTが200−204に等しい値はいずれもRTCPパケットである.PTが205−207の場合、対応するRTPは77−79であり、RTCPに保留して使用するわけではないが、RTPにおいても定義されて使用されておらず、RTCPがこれらの値に用いられるため、WebRTCではRTCPとする.
PT=192、RTP換算64 PT=193、RTP換算65 PT=195、RTP換算66はRTPにおいてPT値が35-71と明示的に定義されていないが、193に等しい場合、WebRTCはRTCPパケットではないと判断し、RTPではこの値をさらに解析する.
一方、
この
WebRTCのRTPとRTCPは共にudp伝送を用い,RTPとRTCPは同一のudpポートを混合して用いているが,NATをオンにすることは本来容易なことではないため,両ポートを分離すればプログラムの複雑さとNATホール成功の難しさを増す.
WebRTCはどのようにRTP/RTCPパッケージを区別します
webrtc/call/call.cc:
PacketReceiver::DeliveryStatus Call::DeliverPacket(
MediaType media_type,
rtc::CopyOnWriteBuffer packet,
const PacketTime& packet_time) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&configuration_sequence_checker_);
if (RtpHeaderParser::IsRtcp(packet.cdata(), packet.size()))
return DeliverRtcp(media_type, packet.cdata(), packet.size());
return DeliverRtp(media_type, std::move(packet), packet_time);
}
RTPとRTCPが同じUDPポートを使用している以上、受信したUDPパケットがRTPであるかRTCPパケットであるかを区別し、上記のコードでは
IsRtcp
がRTCPパケットであるか否かを判断する.RTP/RTCPの関連コードは
modules/rtp_rtcp
ディレクトリの下にある.RtpHeaderParser::IsRtcp
は、RtpHeaderParser::RTCP()
を呼び出して、RTCPパケットの有無を判定する.webrtc/modules/rtp_rtcp/source/rtp_utility.cc:
bool RtpHeaderParser::RTCP() const {
// 72 to 76 is reserved for RTP
// 77 to 79 is not reserver but they are not assigned we will block them
// for RTCP 200 SR == marker bit + 72
// for RTCP 204 APP == marker bit + 76
/*
* RTCP
*
* FIR full INTRA-frame request 192 [RFC2032] supported
* NACK negative acknowledgement 193 [RFC2032]
* IJ Extended inter-arrival jitter report 195 [RFC-ietf-avt-rtp-toff
* set-07.txt] http://tools.ietf.org/html/draft-ietf-avt-rtp-toffset-07
* SR sender report 200 [RFC3551] supported
* RR receiver report 201 [RFC3551] supported
* SDES source description 202 [RFC3551] supported
* BYE goodbye 203 [RFC3551] supported
* APP application-defined 204 [RFC3551] ignored
* RTPFB Transport layer FB message 205 [RFC4585] supported
* PSFB Payload-specific FB message 206 [RFC4585] supported
* XR extended report 207 [RFC3611] supported
*/
/* 205 RFC 5104
* FMT 1 NACK supported
* FMT 2 reserved
* FMT 3 TMMBR supported
* FMT 4 TMMBN supported
*/
/* 206 RFC 5104
* FMT 1: Picture Loss Indication (PLI) supported
* FMT 2: Slice Lost Indication (SLI)
* FMT 3: Reference Picture Selection Indication (RPSI)
* FMT 4: Full Intra Request (FIR) Command supported
* FMT 5: Temporal-Spatial Trade-off Request (TSTR)
* FMT 6: Temporal-Spatial Trade-off Notification (TSTN)
* FMT 7: Video Back Channel Message (VBCM)
* FMT 15: Application layer FB message
*/
//RTCP 4 (kRtcpMinHeaderLength)
const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
if (length < kRtcpMinHeaderLength) {
return false;
}
//RTCP 2(kRtcpExpectedVersion)
const uint8_t V = _ptrRTPDataBegin[0] >> 6;
if (V != kRtcpExpectedVersion) {
return false;
}
const uint8_t payloadType = _ptrRTPDataBegin[1];
switch (payloadType) {
case 192:
return true;
case 193:
// not supported
// pass through and check for a potential RTP packet
return false;
case 195:
case 200:
case 201:
case 202:
case 203:
case 204:
case 205:
case 206:
case 207:
return true;
default:
return false;
}
}
RTPの2バイト目は、タグビット(M):1ビットペイロードタイプ(PT):7ビット
RTCPの2バイト目はパケットタイプ(PT):8ビット
2バイト目の値が200の場合、バイナリに換算すると11001000になります.RTCPパケットであればPT=SR RTPパケットであればタグビット(M)=1、PT=72であるが72-76はRTCP保留使用と規定されているため、RTPパケットであることは不可能である.具体的なRTP Payload types参考:https://www.ietf.org/assignments/rtp-parameters/rtp-parameters.xml
したがって、PTが200−204に等しい値はいずれもRTCPパケットである.PTが205−207の場合、対応するRTPは77−79であり、RTCPに保留して使用するわけではないが、RTPにおいても定義されて使用されておらず、RTCPがこれらの値に用いられるため、WebRTCではRTCPとする.
PT=192、RTP換算64 PT=193、RTP換算65 PT=195、RTP換算66はRTPにおいてPT値が35-71と明示的に定義されていないが、193に等しい場合、WebRTCはRTCPパケットではないと判断し、RTPではこの値をさらに解析する.
一方、
webrtc/pc/rtptransport.cc
においてPT値が63から96の間であると判定された場合は、RTCPとして直接使用される.webrtc/pc/rtptransport.cc:
// Check the RTP payload type. If 63 < payload type < 96, it's RTCP.
// For additional details, see http://tools.ietf.org/html/rfc5761.
bool IsRtcp(const char* data, int len) {
if (len < 2) {
return false;
}
char pt = data[1] & 0x7F;
return (63 < pt) && (pt < 96);
}
この
IsRtcp
メソッドは、同じファイルのvoid RtpTransport::OnReadPacket
でのみ呼び出されます.