RTP
RTP (Real-time Transport Protocol)
RTP는 Multimedia data의 전송을 위한 protocol이다. RTP의 제어는 RTCP (Real-time Transport Control Protocol)이라는 별도의 protocol을 둔다. WebRTC의 data 전송에 사용되며 (secure RTP), 일반적으로 UDP위에서 동작하나 TCP에서도 동작할 수 있다. RTP의 고정 Header는 다음과 같이 정의된다.
RTP Header
- V (2): version = 2
- P (1): padding, payload 뒤에 패딩
- X (1): extention, header의 확장 여부
- CC (4): csrc count, 헤더 뒤에 CSRC ID의 개수
- M (1): marker, 프레임의 끝과 같은 중요한 이벤를 전달
- Payload type (7): 코덱의 종류 명시 (96~127 dynamic)
- Sequence Number (16): 매 패킷마다 1씩 증가
- Timestamp (32): 샘플링 간격을 기준으로 지정한 timestamp
- SSRC (32): 스트림에 대한 ID. 같은 port를 이용하더라도 다른 SSRC를 이용하여 여러개의 동영상 재생 가능.
- CSRC list (32 for each): 하나의 RTP stream이 여러 종류의 media stream을 갖는경우 CC에 갯수를 표시하고 각각 ID를 부여. CC = 1이면 X
RTP payload
Fig. 1과 같이 RTP packet은 header와 payload로 구성되어있다. 그리고 payload는 payload header로 시작된다. payload는 전달하려는 데이터의 type (codec type)에 따라 payload type을 부여한다. 0부터 95까지는 고정되어있는 static payload type이며, 96부터 127까지는 자유롭게 할당해서 사용할 수 있는 dynamic payload type이다. RTP는 각 코덱에 대해 packetization하는 방법을 표준으로 정해놓았다.
H264 Payload [2]
H264로 압축한 packet을 살펴보면 NAL unit (NALU, Network Abstraction Layer Unit)이라는 단위로 압축된다. 하나의 NAL unit 하나의 slice가 압축된 결과물로, 하나의 H264 packet안의 NAL unit 들은 각각 독립적으로 decoding된다. NALU unit은 각각 독립적으로 처리되기 때문에, RTP에 H264 packet을 담을 때도 NAL unit 단위로 packetization을 수행한다. Fig. 2에서 보이는 NAL unit type은 0 부터 23번까지는 지정되어 있거나 reserved되어있다. RTP에서는 24 부터 29번까지를 packetization의 타입을 기록하기위해 사용한다. 본 문서에서는 SNU (Single NAL unit), STAP-A (Single-time aggregation packet-A), FU-A (Fragmentatin unit-A)에 대해서만 다룬다.
Fig. 2: NAL Unit Yype of H264-RTP Payload [2]
H264의 RTP payload의 가장 처음에는 Fig. 3과 같은 1 byte 크기의 NAL unit header가 위치한다.
Fig. 3: NAL Unit Header in H264-RTP Payload [2]
- F (1): Forbidden zero bit, 패킷의 오류 여부를 나타내며 오류가 있을 시 1
- NRI (2): NAL ref idc, 클수록 priority가 높은 packet임을 의미. 00으로 채워져 있는 packet은 다른 frame의 reference frame으로 쓰이지 않는다.
- Type (5): NAL unit type
SNU packet (Single NAL unit packet): 하나의 RTP packet에 하나의 NAL unit이 담긴 packet을 의미. Payload는 Fig. 4와 같이 구성된다.
Fig. 4: Diagram of SNU Packet [2]
STAP-A (Single-time aggregation packet-A): 같은 timestamp를 같은 NAL unit이 하나의 RTP payload에 담겨있는 상태이다. SNU와 같이 Payload의 시작에는 NAL header가 위치하고 16 bit크기의 사이즈와 NAL unit data가 번갈아가면서 담겨있다.
FU-A (Fragmentation unit-A): 하나의 NAL unit이 RTP payload가 담을 수 있는 최대 크기를 초과했을 때 (ex. MTU - RTP header - UDP header - IP header - Ethernet Header), NAL unit을 여러 RTP packet에 나누어 보내는데, 이를 FU라 한다. Fig. 6의 FU indicator는 NAL unit header를 의미하며 FU에는 추가적으로 header가 붙게되며 Fig.7에 보이는 내용을 담고있다.
- S (1): Start bit, 1로 표시되어 있으면 NAL unit의 시작을 의미
- E (1): End bit, 1로 표시되어 있으면 NAL unit의 끝을 의미
- R (1): Reserved
- Type (5): NAL unit payload type
VP8 Payload [3]
VP8의 payload는 메타정보를 나타내는 payload descriptor/payload header와 실제 데이터인 payload data로 구성되어 있다. payload descriptor의 구조는 Fig. 2와 같다.
Fig. 8: RTP Payload Descriptor of VP8 Codec [2]
- X (1): X octet의 여부
- R (1): bit reserve (사용 X)
- N (1): Non-reference frame (이 프레임을 참조하는 프레임 X)
- S (1): 1이면 partition의 시작
- PID (3): partition index (vp8의 최대 partition = 8)
- I (1): I octet의 여부
- L (1): L octet의 여부
- T (1): T/K octet의 여부 1이면
- RSV (4): bit reserve (사용 X)
- PictrueID: M = 확장 플래그 1 ? 15bit PictureID : 7 bit Picture ID
- TLOPICIDX (8): 현재 프레임이 의존하는 temporal base layer frames을 표시
- TID (3): temporal layer index. 최하위 = 0, 상위 계층일수록 TID가 증가
VP8의 frame은 partition이라는 하나 이상의 block으로 나뉘어서 압축된다. 각 partition은 VP8데이터를 전송하는 하나의 단위가 되며, VP8의 Payload header는 partition의 시작에만 붙는다. 즉 partition이 여러 개의 network packet으로 fragmentation된다면, 첫 번째 fragment에만 payload header가 포함되어있다. payload header의 구조는 Fig. 3와 같다.
Fig. 9: RTP Payload Header of VP8 Codec [2]
- P (1): 1이면 P프레임
- PartitionSize = Size0 + 8 * Size1 + 2048 * Size2
AAC Payload [4]
AAC는 AU (Access Unit)라는 단위로 RTP payload에 담긴다. AU는 하나의 프레임이 압축된 형태이다. AAC의 RTP payload는 Fig. 10과 같이 AU header section/Auxiliary Section/Access unit data section으로 나뉘어 있는데, 여러 AU가 담기면, 모든 AU header가 AU header section에 모여있다.
AU header section은 Fig.11과 같이 AU headers length와 연속된 AU header로 이루어져 있다. AU headers length는 16 bit로, 이후에 기록된 AU header들의 사이즈 (bit)를 표기한다. AU header의 구성은 Fig. 12와 같이 구성되어 있다. 연속된 AU header이후에는 octet-align을 만족하기 위한 padding bit가 위치한다.
Fig. 11: AU Header Section [4]
- AU-size: AU의 byte size, fragmented 되어 있어도 AU 전체의 크기 표시
- AU-Index: AU/Fragment 단위로 1씩 증가. 패킷의 첫번 째 AU에만 존재
- AU-Index-delta: AU-Index(n) = AU-Index(n-1) + AU-Index-delta(n) + 1, 0보다 큰 값은 interleaving 되어 있음을 나타냄
- CTS-flag: CTS-delta의 여부. 1이면 존재함
- CTS-delta: compositing time의 RTP header로부터의 offset
- DTS-flag: DTS-delta의 여부. 1이면 존재
- DTS-delta: decoding time의 CTS로부터의 offset
- RAP-flag: random access point를 제공하는지 여부
- Stream-state: MPEG4-system stream을 위한 state
Auxiliary section은 auxiliary data size와 auxiliary data로 이루어져 있다. auxiliary data size는 뒤에나오는 auxiliary data의 크기를 bit 단위로 표시한다. Auxiliary section의 끝에는 octet-align을 만족시키기 위한 padding bit가 존재한다.
Fig. 13: Auxiliary Section [4]
Opus Payload [5]
Opus packet은 network abstraction을 codec에서 수행하기 때문에, Opus payload에는 Opus packet이 그대로 담긴다. OPUS packet은 TOC (Table of content)라는 1 byte 크기의 header와 압축된 데이터로 구성되어 있다. TOC는 Fig. 15와 같다.
Fig. 15: TOC in Opus Packet [6]
- config (5): band와 frams size
- s (1): Mono/Strereo
- c (2): Code, # of frames in packet
- 0: 1 frame / 1 packet
- 1: 2 same compressed size frames / 1 packet
- 2: 2 diff compressed size frames / 1packet
- 3: arbitrary # of frames / 1 packet
TOC의 code가 1인 경우 Opus payload는 Fig. 16과 같이 TOC 이후 연속된 두개의 compressed frame이 등장한다.
Fig. 16: Opus Payload with Code=1 [6]
References
- [0] https://tools.ietf.org/html/rfc3550
- [1] http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml
- [2] https://tools.ietf.org/html/rfc6184
- [3] https://tools.ietf.org/html/rfc7741
- [4] https://tools.ietf.org/html/rfc3640
- [5] https://tools.ietf.org/html/rfc7587
- [6] https://tools.ietf.org/html/rfc6716