FFmpeg
Data Structures | Macros | Enumerations | Functions | Variables
whip.c File Reference
#include "libavcodec/avcodec.h"
#include "libavcodec/codec_desc.h"
#include "libavcodec/h264.h"
#include "libavcodec/startcode.h"
#include "libavutil/base64.h"
#include "libavutil/bprint.h"
#include "libavutil/crc.h"
#include "libavutil/hmac.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/lfg.h"
#include "libavutil/opt.h"
#include "libavutil/mem.h"
#include "libavutil/random_seed.h"
#include "libavutil/time.h"
#include "avc.h"
#include "nal.h"
#include "avio_internal.h"
#include "http.h"
#include "internal.h"
#include "mux.h"
#include "network.h"
#include "rtp.h"
#include "srtp.h"
#include "tls.h"

Go to the source code of this file.

Data Structures

struct  WHIPContext
 

Macros

#define MAX_SDP_SIZE   8192
 Maximum size limit of a Session Description Protocol (SDP), be it an offer or answer. More...
 
#define DTLS_SRTP_KEY_LEN   16
 The size of the Secure Real-time Transport Protocol (SRTP) master key material that is exported by Secure Sockets Layer (SSL) after a successful Datagram Transport Layer Security (DTLS) handshake. More...
 
#define DTLS_SRTP_SALT_LEN   14
 
#define DTLS_SRTP_CHECKSUM_LEN   16
 The maximum size of the Secure Real-time Transport Protocol (SRTP) HMAC checksum and padding that is appended to the end of the packet. More...
 
#define WHIP_US_PER_MS   1000
 
#define ICE_DTLS_READ_MAX_RETRY   10
 If we try to read from UDP and get EAGAIN, we sleep for 5ms and retry up to 10 times. More...
 
#define ICE_DTLS_READ_SLEEP_DURATION   5
 
#define STUN_MAGIC_COOKIE   0x2112A442
 
#define STUN_HOST_CANDIDATE_PRIORITY   126 << 24 | 65535 << 8 | 255
 Refer to RFC 8445 5.1.2 priority = (2^24)*(type preference) + (2^8)*(local preference) + (2^0)*(256 - component ID) host candidate priority is 126 << 24 | 65535 << 8 | 255. More...
 
#define DTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC   20
 The DTLS content type. More...
 
#define DTLS_RECORD_LAYER_HEADER_LEN   13
 The DTLS record layer header has a total size of 13 bytes, consisting of ContentType (1 byte), ProtocolVersion (2 bytes), Epoch (2 bytes), SequenceNumber (6 bytes), and Length (2 bytes). More...
 
#define DTLS_VERSION_10   0xfeff
 The DTLS version number, which is 0xfeff for DTLS 1.0, or 0xfefd for DTLS 1.2. More...
 
#define DTLS_VERSION_12   0xfefd
 
#define MAX_UDP_BUFFER_SIZE   4096
 Maximum size of the buffer for sending and receiving UDP packets. More...
 
#define WHIP_RTP_PAYLOAD_TYPE_H264   106
 
#define WHIP_RTP_PAYLOAD_TYPE_OPUS   111
 
#define WHIP_RTP_PAYLOAD_TYPE_VIDEO_RTX   105
 
#define ICE_STUN_HEADER_SIZE   20
 The STUN message header, which is 20 bytes long, comprises the STUNMessageType (1B), MessageLength (2B), MagicCookie (4B), and TransactionID (12B). More...
 
#define WHIP_RTP_HEADER_SIZE   12
 The RTP header is 12 bytes long, comprising the Version(1B), PT(1B), SequenceNumber(2B), Timestamp(4B), and SSRC(4B). More...
 
#define WHIP_RTCP_PT_START   192
 For RTCP, PT is [128, 223] (or without marker [0, 95]). More...
 
#define WHIP_RTCP_PT_END   223
 
#define WHIP_SDP_SESSION_ID   "4489045141692799359"
 In the case of ICE-LITE, these fields are not used; instead, they are defined as constant values. More...
 
#define WHIP_SDP_CREATOR_IP   "127.0.0.1"
 
#define WHIP_ICE_CONSENT_CHECK_INTERVAL   5000
 Refer to RFC 7675 5.1,. More...
 
#define WHIP_ICE_CONSENT_EXPIRED_TIMER   30000
 
#define ELAPSED(starttime, endtime)   ((float)(endtime - starttime) / 1000)
 
#define OFFSET(x)   offsetof(WHIPContext, x)
 
#define ENC   AV_OPT_FLAG_ENCODING_PARAM
 

Enumerations

enum  STUNAttr {
  STUN_ATTR_USERNAME = 0x0006, STUN_ATTR_PRIORITY = 0x0024, STUN_ATTR_USE_CANDIDATE = 0x0025, STUN_ATTR_MESSAGE_INTEGRITY = 0x0008,
  STUN_ATTR_FINGERPRINT = 0x8028, STUN_ATTR_ICE_CONTROLLING = 0x802A
}
 
enum  WHIPState {
  WHIP_STATE_NONE, WHIP_STATE_INIT, WHIP_STATE_OFFER, WHIP_STATE_ANSWER,
  WHIP_STATE_NEGOTIATED, WHIP_STATE_UDP_CONNECTED, WHIP_STATE_ICE_CONNECTING, WHIP_STATE_ICE_CONNECTED,
  WHIP_STATE_DTLS_FINISHED, WHIP_STATE_SRTP_FINISHED, WHIP_STATE_READY, WHIP_STATE_FAILED
}
 

Functions

static int is_dtls_packet (uint8_t *b, int size)
 Whether the packet is a DTLS packet. More...
 
static av_cold int certificate_key_init (AVFormatContext *s)
 Get or Generate a self-signed certificate and private key for DTLS, fingerprint for SDP. More...
 
static av_cold int dtls_initialize (AVFormatContext *s)
 
static av_cold int initialize (AVFormatContext *s)
 Initialize and check the options for the WebRTC muxer. More...
 
static int parse_profile_level (AVFormatContext *s, AVCodecParameters *par)
 When duplicating a stream, the demuxer has already set the extradata, profile, and level of the par. More...
 
static int parse_codec (AVFormatContext *s)
 Parses video SPS/PPS from the extradata of codecpar and checks the codec. More...
 
static int generate_sdp_offer (AVFormatContext *s)
 Generate SDP offer according to the codec parameters, DTLS and ICE information. More...
 
static int exchange_sdp (AVFormatContext *s)
 Exchange SDP offer with WebRTC peer to get the answer. More...
 
static int parse_answer (AVFormatContext *s)
 Parses the ICE ufrag, pwd, and candidates from the SDP answer. More...
 
static int ice_create_request (AVFormatContext *s, uint8_t *buf, int buf_size, int *request_size)
 Creates and marshals an ICE binding request packet. More...
 
static int ice_create_response (AVFormatContext *s, char *tid, int tid_size, uint8_t *buf, int buf_size, int *response_size)
 Create an ICE binding response. More...
 
static int ice_is_binding_request (uint8_t *b, int size)
 A Binding request has class=0b00 (request) and method=0b000000000001 (Binding) and is encoded into the first 16 bits as 0x0001. More...
 
static int ice_is_binding_response (uint8_t *b, int size)
 A Binding response has class=0b10 (success response) and method=0b000000000001, and is encoded into the first 16 bits as 0x0101. More...
 
static int media_is_rtp_rtcp (const uint8_t *b, int size)
 In RTP packets, the first byte is represented as 0b10xxxxxx, where the initial two bits (0b10) indicate the RTP version, see https://www.rfc-editor.org/rfc/rfc3550#section-5.1 The RTCP packet header is similar to RTP, see https://www.rfc-editor.org/rfc/rfc3550#section-6.4.1. More...
 
static int media_is_rtcp (const uint8_t *b, int size)
 
static int ice_handle_binding_request (AVFormatContext *s, char *buf, int buf_size)
 This function handles incoming binding request messages by responding to them. More...
 
static int udp_connect (AVFormatContext *s)
 To establish a connection with the UDP server, we utilize ICE-LITE in a Client-Server mode. More...
 
static int ice_dtls_handshake (AVFormatContext *s)
 
static int setup_srtp (AVFormatContext *s)
 Establish the SRTP context using the keying material exported from DTLS. More...
 
static int on_rtp_write_packet (void *opaque, const uint8_t *buf, int buf_size)
 Callback triggered by the RTP muxer when it creates and sends out an RTP packet. More...
 
static int create_rtp_muxer (AVFormatContext *s)
 Creates dedicated RTP muxers for each stream in the AVFormatContext to build RTP packets from the encoded frames. More...
 
static int dispose_session (AVFormatContext *s)
 RTC is connectionless, for it's based on UDP, so it check whether sesison is timeout. More...
 
static int h264_annexb_insert_sps_pps (AVFormatContext *s, AVPacket *pkt)
 Since the h264_mp4toannexb filter only processes the MP4 ISOM format and bypasses the annexb format, it is necessary to manually insert encoder metadata before each IDR when dealing with annexb format packets. More...
 
static av_cold int whip_init (AVFormatContext *s)
 
static void handle_nack_rtx (AVFormatContext *s, int size)
 
static int whip_write_packet (AVFormatContext *s, AVPacket *pkt)
 
static av_cold void whip_deinit (AVFormatContext *s)
 
static int whip_check_bitstream (AVFormatContext *s, AVStream *st, const AVPacket *pkt)
 

Variables

static const AVOption options []
 
static const AVClass whip_muxer_class
 
const FFOutputFormat ff_whip_muxer
 

Macro Definition Documentation

◆ MAX_SDP_SIZE

#define MAX_SDP_SIZE   8192

Maximum size limit of a Session Description Protocol (SDP), be it an offer or answer.

Definition at line 51 of file whip.c.

◆ DTLS_SRTP_KEY_LEN

#define DTLS_SRTP_KEY_LEN   16

The size of the Secure Real-time Transport Protocol (SRTP) master key material that is exported by Secure Sockets Layer (SSL) after a successful Datagram Transport Layer Security (DTLS) handshake.

This material consists of a key of 16 bytes and a salt of 14 bytes.

Definition at line 59 of file whip.c.

◆ DTLS_SRTP_SALT_LEN

#define DTLS_SRTP_SALT_LEN   14

Definition at line 60 of file whip.c.

◆ DTLS_SRTP_CHECKSUM_LEN

#define DTLS_SRTP_CHECKSUM_LEN   16

The maximum size of the Secure Real-time Transport Protocol (SRTP) HMAC checksum and padding that is appended to the end of the packet.

To calculate the maximum size of the User Datagram Protocol (UDP) packet that can be sent out, subtract this size from the pkt_size.

Definition at line 68 of file whip.c.

◆ WHIP_US_PER_MS

#define WHIP_US_PER_MS   1000

Definition at line 70 of file whip.c.

◆ ICE_DTLS_READ_MAX_RETRY

#define ICE_DTLS_READ_MAX_RETRY   10

If we try to read from UDP and get EAGAIN, we sleep for 5ms and retry up to 10 times.

This will limit the total duration (in milliseconds, 50ms)

Definition at line 76 of file whip.c.

◆ ICE_DTLS_READ_SLEEP_DURATION

#define ICE_DTLS_READ_SLEEP_DURATION   5

Definition at line 77 of file whip.c.

◆ STUN_MAGIC_COOKIE

#define STUN_MAGIC_COOKIE   0x2112A442

Definition at line 80 of file whip.c.

◆ STUN_HOST_CANDIDATE_PRIORITY

#define STUN_HOST_CANDIDATE_PRIORITY   126 << 24 | 65535 << 8 | 255

Refer to RFC 8445 5.1.2 priority = (2^24)*(type preference) + (2^8)*(local preference) + (2^0)*(256 - component ID) host candidate priority is 126 << 24 | 65535 << 8 | 255.

Definition at line 87 of file whip.c.

◆ DTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC

#define DTLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC   20

The DTLS content type.

See https://tools.ietf.org/html/rfc2246#section-6.2.1 change_cipher_spec(20), alert(21), handshake(22), application_data(23)

Definition at line 94 of file whip.c.

◆ DTLS_RECORD_LAYER_HEADER_LEN

#define DTLS_RECORD_LAYER_HEADER_LEN   13

The DTLS record layer header has a total size of 13 bytes, consisting of ContentType (1 byte), ProtocolVersion (2 bytes), Epoch (2 bytes), SequenceNumber (6 bytes), and Length (2 bytes).

See https://datatracker.ietf.org/doc/html/rfc9147#section-4

Definition at line 102 of file whip.c.

◆ DTLS_VERSION_10

#define DTLS_VERSION_10   0xfeff

The DTLS version number, which is 0xfeff for DTLS 1.0, or 0xfefd for DTLS 1.2.

See https://datatracker.ietf.org/doc/html/rfc9147#name-the-dtls-record-layer

Definition at line 108 of file whip.c.

◆ DTLS_VERSION_12

#define DTLS_VERSION_12   0xfefd

Definition at line 109 of file whip.c.

◆ MAX_UDP_BUFFER_SIZE

#define MAX_UDP_BUFFER_SIZE   4096

Maximum size of the buffer for sending and receiving UDP packets.

Please note that this size does not limit the size of the UDP packet that can be sent. To set the limit for packet size, modify the pkt_size parameter. For instance, it is possible to set the UDP buffer to 4096 to send or receive packets, but please keep in mind that the pkt_size option limits the packet size to 1400.

Definition at line 118 of file whip.c.

◆ WHIP_RTP_PAYLOAD_TYPE_H264

#define WHIP_RTP_PAYLOAD_TYPE_H264   106

Definition at line 121 of file whip.c.

◆ WHIP_RTP_PAYLOAD_TYPE_OPUS

#define WHIP_RTP_PAYLOAD_TYPE_OPUS   111

Definition at line 122 of file whip.c.

◆ WHIP_RTP_PAYLOAD_TYPE_VIDEO_RTX

#define WHIP_RTP_PAYLOAD_TYPE_VIDEO_RTX   105

Definition at line 123 of file whip.c.

◆ ICE_STUN_HEADER_SIZE

#define ICE_STUN_HEADER_SIZE   20

The STUN message header, which is 20 bytes long, comprises the STUNMessageType (1B), MessageLength (2B), MagicCookie (4B), and TransactionID (12B).

See https://datatracker.ietf.org/doc/html/rfc5389#section-6

Definition at line 131 of file whip.c.

◆ WHIP_RTP_HEADER_SIZE

#define WHIP_RTP_HEADER_SIZE   12

The RTP header is 12 bytes long, comprising the Version(1B), PT(1B), SequenceNumber(2B), Timestamp(4B), and SSRC(4B).

See https://www.rfc-editor.org/rfc/rfc3550#section-5.1

Definition at line 138 of file whip.c.

◆ WHIP_RTCP_PT_START

#define WHIP_RTCP_PT_START   192

For RTCP, PT is [128, 223] (or without marker [0, 95]).

Literally, RTCP starts from 64 not 0, so PT is [192, 223] (or without marker [64, 95]), see "RTCP Control Packet Types (PT)" at https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-4

For RTP, the PT is [96, 127], or [224, 255] with marker. See "RTP Payload Types (PT) for standard audio and video encodings" at https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-1

Definition at line 150 of file whip.c.

◆ WHIP_RTCP_PT_END

#define WHIP_RTCP_PT_END   223

Definition at line 151 of file whip.c.

◆ WHIP_SDP_SESSION_ID

#define WHIP_SDP_SESSION_ID   "4489045141692799359"

In the case of ICE-LITE, these fields are not used; instead, they are defined as constant values.

Definition at line 157 of file whip.c.

◆ WHIP_SDP_CREATOR_IP

#define WHIP_SDP_CREATOR_IP   "127.0.0.1"

Definition at line 158 of file whip.c.

◆ WHIP_ICE_CONSENT_CHECK_INTERVAL

#define WHIP_ICE_CONSENT_CHECK_INTERVAL   5000

Refer to RFC 7675 5.1,.

To prevent expiry of consent, a STUN binding request can be sent periodically. Implementations SHOULD set a default interval of 5 seconds(5000ms).

Consent expires after 30 seconds(30000ms).

Definition at line 168 of file whip.c.

◆ WHIP_ICE_CONSENT_EXPIRED_TIMER

#define WHIP_ICE_CONSENT_EXPIRED_TIMER   30000

Definition at line 169 of file whip.c.

◆ ELAPSED

#define ELAPSED (   starttime,
  endtime 
)    ((float)(endtime - starttime) / 1000)

Definition at line 172 of file whip.c.

◆ OFFSET

#define OFFSET (   x)    offsetof(WHIPContext, x)

Definition at line 2021 of file whip.c.

◆ ENC

#define ENC   AV_OPT_FLAG_ENCODING_PARAM

Definition at line 2022 of file whip.c.

Enumeration Type Documentation

◆ STUNAttr

enum STUNAttr
Enumerator
STUN_ATTR_USERNAME 
STUN_ATTR_PRIORITY 

shared secret response/bind request

STUN_ATTR_USE_CANDIDATE 

must be included in a Binding request

STUN_ATTR_MESSAGE_INTEGRITY 

bind request

STUN_ATTR_FINGERPRINT 

bind request/response

STUN_ATTR_ICE_CONTROLLING 

rfc5389

Definition at line 175 of file whip.c.

◆ WHIPState

enum WHIPState
Enumerator
WHIP_STATE_NONE 
WHIP_STATE_INIT 
WHIP_STATE_OFFER 
WHIP_STATE_ANSWER 
WHIP_STATE_NEGOTIATED 

After parsing the answer received from the peer, the muxer negotiates the abilities in the offer that it generated.

WHIP_STATE_UDP_CONNECTED 
WHIP_STATE_ICE_CONNECTING 
WHIP_STATE_ICE_CONNECTED 
WHIP_STATE_DTLS_FINISHED 
WHIP_STATE_SRTP_FINISHED 
WHIP_STATE_READY 
WHIP_STATE_FAILED 

Definition at line 184 of file whip.c.

Function Documentation

◆ is_dtls_packet()

static int is_dtls_packet ( uint8_t *  b,
int  size 
)
static

Whether the packet is a DTLS packet.

Definition at line 337 of file whip.c.

Referenced by ice_dtls_handshake(), and whip_write_packet().

◆ certificate_key_init()

static av_cold int certificate_key_init ( AVFormatContext s)
static

Get or Generate a self-signed certificate and private key for DTLS, fingerprint for SDP.

Definition at line 349 of file whip.c.

Referenced by initialize().

◆ dtls_initialize()

static av_cold int dtls_initialize ( AVFormatContext s)
static

Definition at line 377 of file whip.c.

Referenced by ice_dtls_handshake().

◆ initialize()

static av_cold int initialize ( AVFormatContext s)
static

Initialize and check the options for the WebRTC muxer.

Definition at line 393 of file whip.c.

Referenced by whip_init().

◆ parse_profile_level()

static int parse_profile_level ( AVFormatContext s,
AVCodecParameters par 
)
static

When duplicating a stream, the demuxer has already set the extradata, profile, and level of the par.

Keep in mind that this function will not be invoked since the profile and level are set.

When utilizing an encoder, such as libx264, to encode a stream, the extradata in par->extradata contains the SPS, which includes profile and level information. However, the profile and level of par remain unspecified. Therefore, it is necessary to extract the profile and level data from the extradata and assign it to the par's profile and level. Keep in mind that AVFMT_GLOBALHEADER must be enabled; otherwise, the extradata will remain empty.

Definition at line 446 of file whip.c.

Referenced by parse_codec().

◆ parse_codec()

static int parse_codec ( AVFormatContext s)
static

Parses video SPS/PPS from the extradata of codecpar and checks the codec.

Currently only supports video(h264) and audio(opus). Note that only baseline and constrained baseline profiles of h264 are supported.

If the profile is less than 0, the function considers the profile as baseline. It may need to parse the profile from SPS/PPS. This situation occurs when ingesting desktop and transcoding.

Parameters
sPointer to the AVFormatContext
Returns
Returns 0 if successful or AVERROR_xxx in case of an error.

TODO: FIXME: There is an issue with the timestamp of OPUS audio, especially when the input is an MP4 file. The timestamp deviates from the expected value of 960, causing Chrome to play the audio stream with noise. This problem can be replicated by transcoding a specific file into MP4 format and publishing it using the WHIP muxer. However, when directly transcoding and publishing through the WHIP muxer, the issue is not present, and the audio timestamp remains consistent. The root cause is still unknown, and this comment has been added to address this issue in the future. Further research is needed to resolve the problem.

Definition at line 513 of file whip.c.

Referenced by whip_init().

◆ generate_sdp_offer()

static int generate_sdp_offer ( AVFormatContext s)
static

Generate SDP offer according to the codec parameters, DTLS and ICE information.

Note that we don't use av_sdp_create to generate SDP offer because it doesn't support DTLS and ICE information.

Returns
0 if OK, AVERROR_xxx on error

Definition at line 596 of file whip.c.

Referenced by whip_init().

◆ exchange_sdp()

static int exchange_sdp ( AVFormatContext s)
static

Exchange SDP offer with WebRTC peer to get the answer.

Returns
0 if OK, AVERROR_xxx on error

Definition at line 744 of file whip.c.

Referenced by whip_init().

◆ parse_answer()

static int parse_answer ( AVFormatContext s)
static

Parses the ICE ufrag, pwd, and candidates from the SDP answer.

This function is used to extract the ICE ufrag, pwd, and candidates from the SDP answer. It returns an error if any of these fields is NULL. The function only uses the first candidate if there are multiple candidates. However, support for multiple candidates will be added in the future.

Parameters
sPointer to the AVFormatContext
Returns
Returns 0 if successful or AVERROR_xxx if an error occurs.

Definition at line 863 of file whip.c.

Referenced by whip_init().

◆ ice_create_request()

static int ice_create_request ( AVFormatContext s,
uint8_t *  buf,
int  buf_size,
int *  request_size 
)
static

Creates and marshals an ICE binding request packet.

This function creates and marshals an ICE binding request packet. The function only generates the username attribute and does not include goog-network-info, use-candidate. However, some of these attributes may be added in the future.

Parameters
sPointer to the AVFormatContext
bufPointer to memory buffer to store the request packet
buf_sizeSize of the memory buffer
request_sizePointer to an integer that receives the size of the request packet
Returns
Returns 0 if successful or AVERROR_xxx if an error occurs.

Definition at line 972 of file whip.c.

Referenced by ice_dtls_handshake(), and whip_write_packet().

◆ ice_create_response()

static int ice_create_response ( AVFormatContext s,
char *  tid,
int  tid_size,
uint8_t *  buf,
int  buf_size,
int *  response_size 
)
static

Create an ICE binding response.

This function generates an ICE binding response and writes it to the provided buffer. The response is signed using the local password for message integrity.

Parameters
sPointer to the AVFormatContext structure.
tidPointer to the transaction ID of the binding request. The tid_size should be 12.
tid_sizeThe size of the transaction ID, should be 12.
bufPointer to the buffer where the response will be written.
buf_sizeThe size of the buffer provided for the response.
response_sizePointer to an integer that will store the size of the generated response.
Returns
Returns 0 if successful or AVERROR_xxx if an error occurs.

Definition at line 1070 of file whip.c.

Referenced by ice_handle_binding_request().

◆ ice_is_binding_request()

static int ice_is_binding_request ( uint8_t *  b,
int  size 
)
static

A Binding request has class=0b00 (request) and method=0b000000000001 (Binding) and is encoded into the first 16 bits as 0x0001.

See https://datatracker.ietf.org/doc/html/rfc5389#section-6

Definition at line 1134 of file whip.c.

Referenced by ice_dtls_handshake(), and ice_handle_binding_request().

◆ ice_is_binding_response()

static int ice_is_binding_response ( uint8_t *  b,
int  size 
)
static

A Binding response has class=0b10 (success response) and method=0b000000000001, and is encoded into the first 16 bits as 0x0101.

Definition at line 1143 of file whip.c.

Referenced by ice_dtls_handshake(), and whip_write_packet().

◆ media_is_rtp_rtcp()

static int media_is_rtp_rtcp ( const uint8_t *  b,
int  size 
)
static

In RTP packets, the first byte is represented as 0b10xxxxxx, where the initial two bits (0b10) indicate the RTP version, see https://www.rfc-editor.org/rfc/rfc3550#section-5.1 The RTCP packet header is similar to RTP, see https://www.rfc-editor.org/rfc/rfc3550#section-6.4.1.

Definition at line 1155 of file whip.c.

Referenced by on_rtp_write_packet().

◆ media_is_rtcp()

static int media_is_rtcp ( const uint8_t *  b,
int  size 
)
static

Definition at line 1161 of file whip.c.

Referenced by on_rtp_write_packet(), and whip_write_packet().

◆ ice_handle_binding_request()

static int ice_handle_binding_request ( AVFormatContext s,
char *  buf,
int  buf_size 
)
static

This function handles incoming binding request messages by responding to them.

If the message is not a binding request, it will be ignored.

Definition at line 1170 of file whip.c.

Referenced by ice_dtls_handshake().

◆ udp_connect()

static int udp_connect ( AVFormatContext s)
static

To establish a connection with the UDP server, we utilize ICE-LITE in a Client-Server mode.

In this setup, FFmpeg acts as the UDP client, while the peer functions as the UDP server.

Definition at line 1210 of file whip.c.

Referenced by whip_init().

◆ ice_dtls_handshake()

static int ice_dtls_handshake ( AVFormatContext s)
static

Definition at line 1248 of file whip.c.

Referenced by whip_init().

◆ setup_srtp()

static int setup_srtp ( AVFormatContext s)
static

Establish the SRTP context using the keying material exported from DTLS.

Create separate SRTP contexts for sending video and audio, as their sequences differ and should not share a single context. Generate a single SRTP context for receiving RTCP only.

Returns
0 if OK, AVERROR_xxx on error

The profile for OpenSSL's SRTP is SRTP_AES128_CM_SHA1_80, see ssl/d1_srtp.c. The profile for FFmpeg's SRTP is SRTP_AES128_CM_HMAC_SHA1_80, see libavformat/srtp.c.

This represents the material used to build the SRTP master key. It is generated by DTLS and has the following layout: 16B 16B 14B 14B client_key | server_key | client_salt | server_salt

Definition at line 1388 of file whip.c.

Referenced by whip_init().

◆ on_rtp_write_packet()

static int on_rtp_write_packet ( void *  opaque,
const uint8_t *  buf,
int  buf_size 
)
static

Callback triggered by the RTP muxer when it creates and sends out an RTP packet.

This function modifies the video STAP packet, removing the markers, and updating the NRI of the first NALU. Additionally, it uses the corresponding SRTP context to encrypt the RTP packet, where the video packet is handled by the video SRTP context.

Definition at line 1483 of file whip.c.

Referenced by create_rtp_muxer().

◆ create_rtp_muxer()

static int create_rtp_muxer ( AVFormatContext s)
static

Creates dedicated RTP muxers for each stream in the AVFormatContext to build RTP packets from the encoded frames.

The corresponding SRTP context is utilized to encrypt each stream's RTP packets. For example, a video SRTP context is used for the video stream. Additionally, the "on_rtp_write_packet" callback function is set as the write function for each RTP muxer to send out encrypted RTP packets.

Returns
0 if OK, AVERROR_xxx on error

For H.264, consistently utilize the annexb format through the Bitstream Filter (BSF); therefore, we deactivate the extradata detection for the RTP muxer.

Definition at line 1532 of file whip.c.

Referenced by whip_init().

◆ dispose_session()

static int dispose_session ( AVFormatContext s)
static

RTC is connectionless, for it's based on UDP, so it check whether sesison is timeout.

In such case, publishers can't republish the stream util the session is timeout. This function is called to notify the server that the stream is ended, server should expire and close the session immediately, so that publishers can republish the stream quickly.

Definition at line 1652 of file whip.c.

Referenced by whip_deinit().

◆ h264_annexb_insert_sps_pps()

static int h264_annexb_insert_sps_pps ( AVFormatContext s,
AVPacket pkt 
)
static

Since the h264_mp4toannexb filter only processes the MP4 ISOM format and bypasses the annexb format, it is necessary to manually insert encoder metadata before each IDR when dealing with annexb format packets.

For instance, in the case of H.264, we must insert SPS and PPS before the IDR frame.

Definition at line 1708 of file whip.c.

Referenced by whip_write_packet().

◆ whip_init()

static av_cold int whip_init ( AVFormatContext s)
static

Definition at line 1783 of file whip.c.

◆ handle_nack_rtx()

static void handle_nack_rtx ( AVFormatContext s,
int  size 
)
static

Refer to RFC 3550 6.4.1 The length of this RTCP packet in 32 bit words minus one, including the header and any padding.

Definition at line 1821 of file whip.c.

Referenced by whip_write_packet().

◆ whip_write_packet()

static int whip_write_packet ( AVFormatContext s,
AVPacket pkt 
)
static

Refer to RFC 7675 Periodically send Consent Freshness STUN Binding Request

Receive packets from the server such as ICE binding requests, DTLS messages, and RTCP like PLI requests, then respond to them.

Handle RTCP NACK packet Refer to RFC 4585 6.2.1 The Generic NACK message is identified by PT=RTPFB and FMT=1

Definition at line 1858 of file whip.c.

◆ whip_deinit()

static av_cold void whip_deinit ( AVFormatContext s)
static

Keep in mind that it is necessary to free the buffer of pb since we allocate it and pass it to pb using avio_alloc_context, while avio_context_free does not perform this action.

Definition at line 1957 of file whip.c.

◆ whip_check_bitstream()

static int whip_check_bitstream ( AVFormatContext s,
AVStream st,
const AVPacket pkt 
)
static

Definition at line 2002 of file whip.c.

Variable Documentation

◆ options

const AVOption options[]
static
Initial value:
= {
{ "handshake_timeout", "Timeout in milliseconds for ICE and DTLS handshake.", OFFSET(handshake_timeout), AV_OPT_TYPE_INT, { .i64 = 5000 }, -1, INT_MAX, ENC },
{ "pkt_size", "The maximum size, in bytes, of RTP packets that send out", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = 1200 }, -1, INT_MAX, ENC },
{ "buffer_size", "The buffer size, in bytes, of underlying protocol", OFFSET(buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ENC },
{ "authorization", "The optional Bearer token for WHIP Authorization", OFFSET(authorization), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
{ "cert_file", "The optional certificate file path for DTLS", OFFSET(cert_file), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
{ "key_file", "The optional private key file path for DTLS", OFFSET(key_file), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
{ NULL },
}

Definition at line 2023 of file whip.c.

◆ whip_muxer_class

const AVClass whip_muxer_class
static
Initial value:
= {
.class_name = "WHIP muxer",
.item_name = av_default_item_name,
.option = options,
}

Definition at line 2033 of file whip.c.

◆ ff_whip_muxer

const FFOutputFormat ff_whip_muxer
Initial value:
= {
.p.name = "whip",
.p.long_name = NULL_IF_CONFIG_SMALL("WHIP(WebRTC-HTTP ingestion protocol) muxer"),
.p.audio_codec = AV_CODEC_ID_OPUS,
.p.video_codec = AV_CODEC_ID_H264,
.p.priv_class = &whip_muxer_class,
.priv_data_size = sizeof(WHIPContext),
}

Definition at line 2040 of file whip.c.

whip_deinit
static av_cold void whip_deinit(AVFormatContext *s)
Definition: whip.c:1957
deinit
static void deinit(AVFormatContext *s)
Definition: chromaprint.c:52
WHIPContext
Definition: whip.c:214
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
NULL
#define NULL
Definition: coverity.c:32
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:241
whip_init
static av_cold int whip_init(AVFormatContext *s)
Definition: whip.c:1783
whip_muxer_class
static const AVClass whip_muxer_class
Definition: whip.c:2033
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:519
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
options
static const AVOption options[]
Definition: whip.c:2023
ENC
#define ENC
Definition: whip.c:2022
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:477
check_bitstream
static int check_bitstream(AVFormatContext *s, FFStream *sti, AVPacket *pkt)
Definition: mux.c:1056
whip_check_bitstream
static int whip_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Definition: whip.c:2002
AVFMT_EXPERIMENTAL
#define AVFMT_EXPERIMENTAL
The muxer/demuxer is experimental and should be used with caution.
Definition: avformat.h:475
OFFSET
#define OFFSET(x)
Definition: whip.c:2021
write_packet
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:209
whip_write_packet
static int whip_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: whip.c:1858
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276