From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id AB68344AF7 for ; Sun, 12 Oct 2025 15:45:01 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'45DhgFxbB1EPll+e0qEmU3CHDpLDZbpj1KmSMG0gDo0=', expected b'u6UZX7zEioYaq77XhDJBNdBpd5zAcZEdamF8IbtQxd4=')) header.d=qq.com header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1760283780; h=message-id : to : date : in-reply-to : references : mime-version : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=75QWrB+8QjbPGEZ7CEwtwBXV2g/+weTEbqyyy5WXui0=; b=A3GPktdrkvkFqsrx/DstrhuaFU84f1JEfVsu/EIqBxkwADSUon3m+DXiXFd3QyYBTUm8I gr5BfjPmvQljE16d3LY+ueAJAiwCSV7/+ef3tFLJdpwd7Ggr0DtY4+wgNkXXugmfAz/pYcX aC7TW5z9q7z5+rWX9ZFa+G8YtoUB2n3V/AxRCnPDQKxm1M+G7srwQBw61IrC+LK26zt8bDP h792UZ2PL6FrRexmxHMvghD9i/57Osk6J0eIvrK/elrfG8Dw/Ffm2J7KCHzJlTUnFdwJWAL YbYUubrxuG+B349kZN57n2RSI2T2+ECKK1Me1cGQDrhSusrughenh/G8zhFA== Received: from [172.19.0.2] (unknown [172.19.0.2]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 8286568F2BE; Sun, 12 Oct 2025 18:43:00 +0300 (EEST) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1760283773; b=rg9q9e8jKhvQotIbql+P3qwigd9pnPFMO75Lyyh2Hgmhj7Jd4JrUM4iHoHXINvmm4Wu2s 3Z293+psxg9tCL3hTKc1a1jyEWdklc3Gcm9SKexROoaohNHylIGzeOvKC9duvlA/dud1j0x PBhdYC65zHzjhlouKrBy+uTq2hG7luawlkHjTfFvPLEmy2jc05h5oNs6kSa+jNY2HGmuKra xBx9TXFRMn2g1KEJ3UwVafwq4vIkPyKzTiiYNnxOcp5zXDfmlYuCgytjC2XxhosUyw+Ig2G k+SUM0iNh/22pB/Ldtwe00LRhr5qrfiCsMtS4g7n6vEoo9iKwTtSazNziZxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1760283773; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=45DhgFxbB1EPll+e0qEmU3CHDpLDZbpj1KmSMG0gDo0=; b=pNgCG05jx/7fEHpFpeu7hzK8eMRaLOOywjR2TjB2UIRTt0CcyyfIq1bsbdA3MtLlg0X/u 0cVr176ipgsQy8itBzo6M44LbI+zWkHhR4IBkbjyvvhWEfouuUN11yNINEqkR631i2qtiMA ZsYNALleYhrPjGRS2KSqmrBct3xgkjXggFw7yUIJXxX8VNKxoAFwice2nUUV0oLJmvAbUNB dMTC22baXlflCMD+l8aMPOY9lZSAwN5DhKjDegpTCiCN5BrjtPTmwNHY+M7T512AK3dhcvc 3twSVx2u0GufHpVLHx0npSWnwCq+XTR1b8NfF6IwyGjTdejRC5GWVV9MFf3Q== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=pass header.d=qq.com; arc=none; dmarc=pass header.from=qq.com policy.dmarc=quarantine Authentication-Results: ffmpeg.org; dkim=pass header.d=qq.com; arc=none (Message is not ARC signed); dmarc=pass (Used From Domain Record) header.from=qq.com policy.dmarc=quarantine Received: from out162-62-57-64.mail.qq.com (out162-62-57-64.mail.qq.com [162.62.57.64]) by ffbox0-bg.ffmpeg.org (Postfix) with UTF8SMTPS id 4135D68F1EF for ; Sun, 12 Oct 2025 18:42:31 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512; t=1760283745; bh=u6UZX7zEioYaq77XhDJBNdBpd5zAcZEdamF8IbtQxd4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=G+Ow7alXNKSstRq1WEM4i+a61bEl03690dXqFHwhRDUHYyBJ3wj1+kqLrPFk8HLAX /a5/MdCTQ2oldP2GP/c/hnikVh/nHd5I1QYHELdqcwhIsJLE8Jy+i8k7RzeiAhvlBL 7BKyZoW6F3D1+nomtNP7FRuJuhWUCupbcsnF1CdY= Received: from Cave.localdomain ([3.25.94.32]) by newxmesmtplogicsvrszb20-1.qq.com (NewEsmtp) with SMTP id A948E831; Sun, 12 Oct 2025 23:42:20 +0800 X-QQ-mid: xmsmtpt1760283740tjp4l9ae7 Message-ID: X-QQ-XMAILINFO: MapnONytPuziaSi9eDIu4KvzQ/20cjP89At/hQUx5TLsci25G3zd+z2QBf4Mco r+RRyKEY7JT/CJ5pG3lzKAiaIgN7yceM5mm00+KpYmr8htbRcQulCBfFj56ZEpUshusJB13aNDdY i0oZB49mlBpczbqwwDbrPRCSBAZAO41ZOvV6umtnhQkO33g20Xi5H7iFfelnTYie9OdMKbhKSYsb +221bdI4aTkzhE0iMHZ9wmYVzbulNujT1V5LXqi9t8G2EzTclAC4BrHtDJQCHhFOufkC4V5KGAim 9IKcFkUxb0CEJFPWuiYFE8CQHCW6AC00hMoJyn58SIE/J6F8ULPx4O0LxOP2HVmwzugCz7IwhgG3 TvXi8LT/F48UZ62Qt3Nr1g4E9I87GV3KiBKB8H0c5EGCcPxdQ1IX5NvzKcYxo8ebc+Mtcs9y0ohQ MeuWA3HJV0uU0FsPdNo8AoJg5+hrehIhGLzkq1GhwT6o2XRIsT/MvmVBHMYjUBSHjbCQiaPSWB19 J0vkvG+WUlDt0CpEsPTY75clXqh7dycjFY64Gns/OdAfK9UwSD4r7XjfUNEPvp/BeaVwJ7X+qMF3 HQYeDplpa7p7eyXQ/gPQAfU1BDz9qo92b9yzMcfFNeYYQva2BfFUqgpQeiCUmfayMfrHbpnv2p8D dhwd2uCUSQ6xsaWviW0DTV4/GzIl5oT0Da5YAvvR2H1wW+fKkrApRwm5jtYuhT9/RWfYt2Sa7JBI JC4zA+Fj3IyAG/bwWC17DreAxCNuVp/J2nnLscDu086ny5aiL2vcnM7pprZDwPtjm3sEaCIi+VQt H2KHRonVBK6DzzzQXoSbWbttllyVBOJE5mamwxGQ0oFjyZh0tker7ILRgBcDSMEydMGldUf9XjAV ObNJ/p+Oj+BLlEm3Uxq7BbQUsejmrsLdWflsprJ+PN+p7SkBic3YXE30xeg8srqWX4frfB3XKMee k3fUEdCdN5ux1PbuhWBOVk8wkYeH+qLZXY+aKlxKn56GGPauhYJQalX7Ace5lp75h805sSYoJFuH VKCol/RjBnCbCEGD6zkuc/N7XN34AHwDTqC5NIHzSquNyGFhZqji3kG2YDi+I= X-QQ-XMRINFO: Nq+8W0+stu50PRdwbJxPCL0= To: ffmpeg-devel@ffmpeg.org Date: Sun, 12 Oct 2025 23:42:15 +0800 X-OQ-MSGID: <20251012154215.1031885-1-1007668733@qq.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251012152347.1022477-1-1007668733@qq.com> References: <20251012152347.1022477-1-1007668733@qq.com> MIME-Version: 1.0 Message-ID-Hash: QE7DJZNS6AMGYTC3CKIQMPDVDXLARJW4 X-Message-ID-Hash: QE7DJZNS6AMGYTC3CKIQMPDVDXLARJW4 X-MailFrom: SRS0=CIIc=4V=qq.com=1007668733@ffmpeg.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH 2/3] avformat/whip whep: reanme whip prefix to rtc for common RTC structures List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: baigao via ffmpeg-devel Cc: baigao <1007668733@qq.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: --- libavformat/rtc.c | 564 ++++++++++++++++++++++----------------------- libavformat/rtc.h | 60 ++--- libavformat/whip.c | 180 +++++++-------- 3 files changed, 402 insertions(+), 402 deletions(-) diff --git a/libavformat/rtc.c b/libavformat/rtc.c index 2dc0383d3e..8c848b6026 100644 --- a/libavformat/rtc.c +++ b/libavformat/rtc.c @@ -97,9 +97,9 @@ #define MAX_UDP_BUFFER_SIZE 4096 /* Referring to Chrome's definition of RTP payload types. */ -#define WHIP_RTP_PAYLOAD_TYPE_H264 106 -#define WHIP_RTP_PAYLOAD_TYPE_OPUS 111 -#define WHIP_RTP_PAYLOAD_TYPE_VIDEO_RTX 105 +#define RTC_RTP_PAYLOAD_TYPE_H264 106 +#define RTC_RTP_PAYLOAD_TYPE_OPUS 111 +#define RTC_RTP_PAYLOAD_TYPE_VIDEO_RTX 105 /** * The STUN message header, which is 20 bytes long, comprises the @@ -113,8 +113,8 @@ * In the case of ICE-LITE, these fields are not used; instead, they are defined * as constant values. */ -#define WHIP_SDP_SESSION_ID "4489045141692799359" -#define WHIP_SDP_CREATOR_IP "127.0.0.1" +#define RTC_SDP_SESSION_ID "4489045141692799359" +#define RTC_SDP_CREATOR_IP "127.0.0.1" /* Calculate the elapsed time from starttime to endtime in milliseconds. */ #define ELAPSED(starttime, endtime) ((float)(endtime - starttime) / 1000) @@ -146,23 +146,23 @@ int ff_rtc_is_dtls_packet(uint8_t *b, int size) { static av_cold int certificate_key_init(AVFormatContext *s) { int ret = 0; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; - if (whip->cert_file && whip->key_file) { + if (rtc->cert_file && rtc->key_file) { /* Read the private key and certificate from the file. */ - if ((ret = ff_ssl_read_key_cert(whip->key_file, whip->cert_file, - whip->key_buf, sizeof(whip->key_buf), - whip->cert_buf, sizeof(whip->cert_buf), - &whip->dtls_fingerprint)) < 0) { + if ((ret = ff_ssl_read_key_cert(rtc->key_file, rtc->cert_file, + rtc->key_buf, sizeof(rtc->key_buf), + rtc->cert_buf, sizeof(rtc->cert_buf), + &rtc->dtls_fingerprint)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to read DTLS certificate from cert=%s, key=%s\n", - whip->cert_file, whip->key_file); + rtc->cert_file, rtc->key_file); return ret; } } else { /* Generate a private key to ctx->dtls_pkey and self-signed certificate. */ - if ((ret = ff_ssl_gen_key_cert(whip->key_buf, sizeof(whip->key_buf), - whip->cert_buf, sizeof(whip->cert_buf), - &whip->dtls_fingerprint)) < 0) { + if ((ret = ff_ssl_gen_key_cert(rtc->key_buf, sizeof(rtc->key_buf), + rtc->cert_buf, sizeof(rtc->cert_buf), + &rtc->dtls_fingerprint)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to generate DTLS private key and certificate\n"); return ret; } @@ -173,13 +173,13 @@ static av_cold int certificate_key_init(AVFormatContext *s) static av_cold int dtls_initialize(AVFormatContext *s) { - WHIPContext *whip = s->priv_data; - /* reuse the udp created by whip */ - ff_tls_set_external_socket(whip->dtls_uc, whip->udp); + RTCContext *rtc = s->priv_data; + /* reuse the udp created by rtc */ + ff_tls_set_external_socket(rtc->dtls_uc, rtc->udp); /* Make the socket non-blocking */ - ff_socket_nonblock(ffurl_get_file_handle(whip->dtls_uc), 1); - whip->dtls_uc->flags |= AVIO_FLAG_NONBLOCK; + ff_socket_nonblock(ffurl_get_file_handle(rtc->dtls_uc), 1); + rtc->dtls_uc->flags |= AVIO_FLAG_NONBLOCK; return 0; } @@ -190,40 +190,40 @@ static av_cold int dtls_initialize(AVFormatContext *s) av_cold int ff_rtc_initialize(AVFormatContext *s) { int ret, ideal_pkt_size = 532; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; uint32_t seed; - whip->whip_starttime = av_gettime_relative(); + rtc->rtc_starttime = av_gettime_relative(); ret = certificate_key_init(s); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to init certificate and key\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to init certificate and key\n"); return ret; } /* Initialize the random number generator. */ seed = av_get_random_seed(); - av_lfg_init(&whip->rnd, seed); + av_lfg_init(&rtc->rnd, seed); /* 64 bit tie breaker for ICE-CONTROLLING (RFC 8445 16.1) */ - ret = av_random_bytes((uint8_t *)&whip->ice_tie_breaker, sizeof(whip->ice_tie_breaker)); + ret = av_random_bytes((uint8_t *)&rtc->ice_tie_breaker, sizeof(rtc->ice_tie_breaker)); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Couldn't generate random bytes for ICE tie breaker\n"); + av_log(rtc, AV_LOG_ERROR, "Couldn't generate random bytes for ICE tie breaker\n"); return ret; } - whip->audio_first_seq = av_lfg_get(&whip->rnd) & 0x0fff; - whip->video_first_seq = whip->audio_first_seq + 1; + rtc->audio_first_seq = av_lfg_get(&rtc->rnd) & 0x0fff; + rtc->video_first_seq = rtc->audio_first_seq + 1; - if (whip->pkt_size < ideal_pkt_size) - av_log(whip, AV_LOG_WARNING, "pkt_size=%d(<%d) is too small, may cause packet loss\n", - whip->pkt_size, ideal_pkt_size); + if (rtc->pkt_size < ideal_pkt_size) + av_log(rtc, AV_LOG_WARNING, "pkt_size=%d(<%d) is too small, may cause packet loss\n", + rtc->pkt_size, ideal_pkt_size); - if (whip->state < WHIP_STATE_INIT) - whip->state = WHIP_STATE_INIT; - whip->whip_init_time = av_gettime_relative(); - av_log(whip, AV_LOG_VERBOSE, "Init state=%d, handshake_timeout=%dms, pkt_size=%d, seed=%d, elapsed=%.2fms\n", - whip->state, whip->handshake_timeout, whip->pkt_size, seed, ELAPSED(whip->whip_starttime, av_gettime_relative())); + if (rtc->state < RTC_STATE_INIT) + rtc->state = RTC_STATE_INIT; + rtc->rtc_init_time = av_gettime_relative(); + av_log(rtc, AV_LOG_VERBOSE, "Init state=%d, handshake_timeout=%dms, pkt_size=%d, seed=%d, elapsed=%.2fms\n", + rtc->state, rtc->handshake_timeout, rtc->pkt_size, seed, ELAPSED(rtc->rtc_starttime, av_gettime_relative())); return 0; } @@ -241,30 +241,30 @@ static int generate_sdp_offer(AVFormatContext *s) int ret = 0, profile_idc = 0, level, profile_iop = 0; const char *acodec_name = NULL, *vcodec_name = NULL; AVBPrint bp; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; /* To prevent a crash during cleanup, always initialize it. */ av_bprint_init(&bp, 1, MAX_SDP_SIZE); - if (whip->sdp_offer) { - av_log(whip, AV_LOG_ERROR, "SDP offer is already set\n"); + if (rtc->sdp_offer) { + av_log(rtc, AV_LOG_ERROR, "SDP offer is already set\n"); ret = AVERROR(EINVAL); goto end; } - snprintf(whip->ice_ufrag_local, sizeof(whip->ice_ufrag_local), "%08x", - av_lfg_get(&whip->rnd)); - snprintf(whip->ice_pwd_local, sizeof(whip->ice_pwd_local), "%08x%08x%08x%08x", - av_lfg_get(&whip->rnd), av_lfg_get(&whip->rnd), av_lfg_get(&whip->rnd), - av_lfg_get(&whip->rnd)); + snprintf(rtc->ice_ufrag_local, sizeof(rtc->ice_ufrag_local), "%08x", + av_lfg_get(&rtc->rnd)); + snprintf(rtc->ice_pwd_local, sizeof(rtc->ice_pwd_local), "%08x%08x%08x%08x", + av_lfg_get(&rtc->rnd), av_lfg_get(&rtc->rnd), av_lfg_get(&rtc->rnd), + av_lfg_get(&rtc->rnd)); - whip->audio_ssrc = av_lfg_get(&whip->rnd); - whip->video_ssrc = whip->audio_ssrc + 1; - whip->video_rtx_ssrc = whip->video_ssrc + 1; + rtc->audio_ssrc = av_lfg_get(&rtc->rnd); + rtc->video_ssrc = rtc->audio_ssrc + 1; + rtc->video_rtx_ssrc = rtc->video_ssrc + 1; - whip->audio_payload_type = WHIP_RTP_PAYLOAD_TYPE_OPUS; - whip->video_payload_type = WHIP_RTP_PAYLOAD_TYPE_H264; - whip->video_rtx_payload_type = WHIP_RTP_PAYLOAD_TYPE_VIDEO_RTX; + rtc->audio_payload_type = RTC_RTP_PAYLOAD_TYPE_OPUS; + rtc->video_payload_type = RTC_RTP_PAYLOAD_TYPE_H264; + rtc->video_rtx_payload_type = RTC_RTP_PAYLOAD_TYPE_VIDEO_RTX; av_bprintf(&bp, "" "v=0\r\n" @@ -274,11 +274,11 @@ static int generate_sdp_offer(AVFormatContext *s) "a=group:BUNDLE 0 1\r\n" "a=extmap-allow-mixed\r\n" "a=msid-semantic: WMS\r\n", - WHIP_SDP_SESSION_ID, - WHIP_SDP_CREATOR_IP); + RTC_SDP_SESSION_ID, + RTC_SDP_CREATOR_IP); - if (whip->audio_par) { - if (whip->audio_par->codec_id == AV_CODEC_ID_OPUS) + if (rtc->audio_par) { + if (rtc->audio_par->codec_id == AV_CODEC_ID_OPUS) acodec_name = "opus"; av_bprintf(&bp, "" @@ -295,25 +295,25 @@ static int generate_sdp_offer(AVFormatContext *s) "a=rtpmap:%u %s/%d/%d\r\n" "a=ssrc:%u cname:FFmpeg\r\n" "a=ssrc:%u msid:FFmpeg audio\r\n", - whip->audio_payload_type, - whip->ice_ufrag_local, - whip->ice_pwd_local, - whip->dtls_fingerprint, - whip->audio_payload_type, + rtc->audio_payload_type, + rtc->ice_ufrag_local, + rtc->ice_pwd_local, + rtc->dtls_fingerprint, + rtc->audio_payload_type, acodec_name, - whip->audio_par->sample_rate, - whip->audio_par->ch_layout.nb_channels, - whip->audio_ssrc, - whip->audio_ssrc); + rtc->audio_par->sample_rate, + rtc->audio_par->ch_layout.nb_channels, + rtc->audio_ssrc, + rtc->audio_ssrc); } - if (whip->video_par) { - level = whip->video_par->level; - if (whip->video_par->codec_id == AV_CODEC_ID_H264) { + if (rtc->video_par) { + level = rtc->video_par->level; + if (rtc->video_par->codec_id == AV_CODEC_ID_H264) { vcodec_name = "H264"; - profile_iop |= whip->video_par->profile & AV_PROFILE_H264_CONSTRAINED ? 1 << 6 : 0; - profile_iop |= whip->video_par->profile & AV_PROFILE_H264_INTRA ? 1 << 4 : 0; - profile_idc = whip->video_par->profile & 0x00ff; + profile_iop |= rtc->video_par->profile & AV_PROFILE_H264_CONSTRAINED ? 1 << 6 : 0; + profile_iop |= rtc->video_par->profile & AV_PROFILE_H264_INTRA ? 1 << 4 : 0; + profile_idc = rtc->video_par->profile & 0x00ff; } av_bprintf(&bp, "" @@ -336,43 +336,43 @@ static int generate_sdp_offer(AVFormatContext *s) "a=ssrc-group:FID %u %u\r\n" "a=ssrc:%u cname:FFmpeg\r\n" "a=ssrc:%u msid:FFmpeg video\r\n", - whip->video_payload_type, - whip->video_rtx_payload_type, - whip->ice_ufrag_local, - whip->ice_pwd_local, - whip->dtls_fingerprint, - whip->video_payload_type, + rtc->video_payload_type, + rtc->video_rtx_payload_type, + rtc->ice_ufrag_local, + rtc->ice_pwd_local, + rtc->dtls_fingerprint, + rtc->video_payload_type, vcodec_name, - whip->video_payload_type, + rtc->video_payload_type, profile_idc, profile_iop, level, - whip->video_payload_type, - whip->video_rtx_payload_type, - whip->video_rtx_payload_type, - whip->video_payload_type, - whip->video_ssrc, - whip->video_rtx_ssrc, - whip->video_ssrc, - whip->video_ssrc); + rtc->video_payload_type, + rtc->video_rtx_payload_type, + rtc->video_rtx_payload_type, + rtc->video_payload_type, + rtc->video_ssrc, + rtc->video_rtx_ssrc, + rtc->video_ssrc, + rtc->video_ssrc); } if (!av_bprint_is_complete(&bp)) { - av_log(whip, AV_LOG_ERROR, "Offer exceed max %d, %s\n", MAX_SDP_SIZE, bp.str); + av_log(rtc, AV_LOG_ERROR, "Offer exceed max %d, %s\n", MAX_SDP_SIZE, bp.str); ret = AVERROR(EIO); goto end; } - whip->sdp_offer = av_strdup(bp.str); - if (!whip->sdp_offer) { + rtc->sdp_offer = av_strdup(bp.str); + if (!rtc->sdp_offer) { ret = AVERROR(ENOMEM); goto end; } - if (whip->state < WHIP_STATE_OFFER) - whip->state = WHIP_STATE_OFFER; - whip->whip_offer_time = av_gettime_relative(); - av_log(whip, AV_LOG_VERBOSE, "Generated state=%d, offer: %s\n", whip->state, whip->sdp_offer); + if (rtc->state < RTC_STATE_OFFER) + rtc->state = RTC_STATE_OFFER; + rtc->rtc_offer_time = av_gettime_relative(); + av_log(rtc, AV_LOG_VERBOSE, "Generated state=%d, offer: %s\n", rtc->state, rtc->sdp_offer); end: av_bprint_finalize(&bp, NULL); @@ -389,9 +389,9 @@ static int exchange_sdp(AVFormatContext *s) int ret; char buf[MAX_URL_SIZE]; AVBPrint bp; - WHIPContext *whip = s->priv_data; - /* The URL context is an HTTP transport layer for the WHIP protocol. */ - URLContext *whip_uc = NULL; + RTCContext *rtc = s->priv_data; + /* The URL context is an HTTP transport layer for the WHIP/WHEP protocol. */ + URLContext *rtc_uc = NULL; AVDictionary *opts = NULL; char *hex_data = NULL; const char *proto_name = avio_find_protocol_name(s->url); @@ -400,23 +400,23 @@ static int exchange_sdp(AVFormatContext *s) av_bprint_init(&bp, 1, MAX_SDP_SIZE); if (!av_strstart(proto_name, "http", NULL)) { - av_log(whip, AV_LOG_ERROR, "Protocol %s is not supported by RTC, choose http, url is %s\n", + av_log(rtc, AV_LOG_ERROR, "Protocol %s is not supported by RTC, choose http, url is %s\n", proto_name, s->url); ret = AVERROR(EINVAL); goto end; } - if (!whip->sdp_offer || !strlen(whip->sdp_offer)) { - av_log(whip, AV_LOG_ERROR, "No offer to exchange\n"); + if (!rtc->sdp_offer || !strlen(rtc->sdp_offer)) { + av_log(rtc, AV_LOG_ERROR, "No offer to exchange\n"); ret = AVERROR(EINVAL); goto end; } ret = snprintf(buf, sizeof(buf), "Cache-Control: no-cache\r\nContent-Type: application/sdp\r\n"); - if (whip->authorization) - ret += snprintf(buf + ret, sizeof(buf) - ret, "Authorization: Bearer %s\r\n", whip->authorization); + if (rtc->authorization) + ret += snprintf(buf + ret, sizeof(buf) - ret, "Authorization: Bearer %s\r\n", rtc->authorization); if (ret <= 0 || ret >= sizeof(buf)) { - av_log(whip, AV_LOG_ERROR, "Failed to generate headers, size=%d, %s\n", ret, buf); + av_log(rtc, AV_LOG_ERROR, "Failed to generate headers, size=%d, %s\n", ret, buf); ret = AVERROR(EINVAL); goto end; } @@ -424,68 +424,68 @@ static int exchange_sdp(AVFormatContext *s) av_dict_set(&opts, "headers", buf, 0); av_dict_set_int(&opts, "chunked_post", 0, 0); - hex_data = av_mallocz(2 * strlen(whip->sdp_offer) + 1); + hex_data = av_mallocz(2 * strlen(rtc->sdp_offer) + 1); if (!hex_data) { ret = AVERROR(ENOMEM); goto end; } - ff_data_to_hex(hex_data, whip->sdp_offer, strlen(whip->sdp_offer), 0); + ff_data_to_hex(hex_data, rtc->sdp_offer, strlen(rtc->sdp_offer), 0); av_dict_set(&opts, "post_data", hex_data, 0); - ret = ffurl_open_whitelist(&whip_uc, s->url, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, + ret = ffurl_open_whitelist(&rtc_uc, s->url, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to request url=%s, offer: %s\n", s->url, whip->sdp_offer); + av_log(rtc, AV_LOG_ERROR, "Failed to request url=%s, offer: %s\n", s->url, rtc->sdp_offer); goto end; } - if (ff_http_get_new_location(whip_uc)) { - whip->whip_resource_url = av_strdup(ff_http_get_new_location(whip_uc)); - if (!whip->whip_resource_url) { + if (ff_http_get_new_location(rtc_uc)) { + rtc->rtc_resource_url = av_strdup(ff_http_get_new_location(rtc_uc)); + if (!rtc->rtc_resource_url) { ret = AVERROR(ENOMEM); goto end; } } while (1) { - ret = ffurl_read(whip_uc, buf, sizeof(buf)); + ret = ffurl_read(rtc_uc, buf, sizeof(buf)); if (ret == AVERROR_EOF) { /* Reset the error because we read all response as answer util EOF. */ ret = 0; break; } if (ret <= 0) { - av_log(whip, AV_LOG_ERROR, "Failed to read response from url=%s, offer is %s, answer is %s\n", - s->url, whip->sdp_offer, whip->sdp_answer); + av_log(rtc, AV_LOG_ERROR, "Failed to read response from url=%s, offer is %s, answer is %s\n", + s->url, rtc->sdp_offer, rtc->sdp_answer); goto end; } av_bprintf(&bp, "%.*s", ret, buf); if (!av_bprint_is_complete(&bp)) { - av_log(whip, AV_LOG_ERROR, "Answer exceed max size %d, %.*s, %s\n", MAX_SDP_SIZE, ret, buf, bp.str); + av_log(rtc, AV_LOG_ERROR, "Answer exceed max size %d, %.*s, %s\n", MAX_SDP_SIZE, ret, buf, bp.str); ret = AVERROR(EIO); goto end; } } if (!av_strstart(bp.str, "v=", NULL)) { - av_log(whip, AV_LOG_ERROR, "Invalid answer: %s\n", bp.str); + av_log(rtc, AV_LOG_ERROR, "Invalid answer: %s\n", bp.str); ret = AVERROR(EINVAL); goto end; } - whip->sdp_answer = av_strdup(bp.str); - if (!whip->sdp_answer) { + rtc->sdp_answer = av_strdup(bp.str); + if (!rtc->sdp_answer) { ret = AVERROR(ENOMEM); goto end; } - if (whip->state < WHIP_STATE_ANSWER) - whip->state = WHIP_STATE_ANSWER; - av_log(whip, AV_LOG_VERBOSE, "Got state=%d, answer: %s\n", whip->state, whip->sdp_answer); + if (rtc->state < RTC_STATE_ANSWER) + rtc->state = RTC_STATE_ANSWER; + av_log(rtc, AV_LOG_VERBOSE, "Got state=%d, answer: %s\n", rtc->state, rtc->sdp_answer); end: - ffurl_closep(&whip_uc); + ffurl_closep(&rtc_uc); av_bprint_finalize(&bp, NULL); av_dict_free(&opts); av_freep(&hex_data); @@ -510,58 +510,58 @@ static int parse_answer(AVFormatContext *s) char line[MAX_URL_SIZE]; const char *ptr; int i; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; - if (!whip->sdp_answer || !strlen(whip->sdp_answer)) { - av_log(whip, AV_LOG_ERROR, "No answer to parse\n"); + if (!rtc->sdp_answer || !strlen(rtc->sdp_answer)) { + av_log(rtc, AV_LOG_ERROR, "No answer to parse\n"); ret = AVERROR(EINVAL); goto end; } - pb = avio_alloc_context(whip->sdp_answer, strlen(whip->sdp_answer), 0, NULL, NULL, NULL, NULL); + pb = avio_alloc_context(rtc->sdp_answer, strlen(rtc->sdp_answer), 0, NULL, NULL, NULL, NULL); if (!pb) return AVERROR(ENOMEM); for (i = 0; !avio_feof(pb); i++) { ff_get_chomp_line(pb, line, sizeof(line)); if (av_strstart(line, "a=ice-lite", &ptr)) - whip->is_peer_ice_lite = 1; - if (av_strstart(line, "a=ice-ufrag:", &ptr) && !whip->ice_ufrag_remote) { - whip->ice_ufrag_remote = av_strdup(ptr); - if (!whip->ice_ufrag_remote) { + rtc->is_peer_ice_lite = 1; + if (av_strstart(line, "a=ice-ufrag:", &ptr) && !rtc->ice_ufrag_remote) { + rtc->ice_ufrag_remote = av_strdup(ptr); + if (!rtc->ice_ufrag_remote) { ret = AVERROR(ENOMEM); goto end; } - } else if (av_strstart(line, "a=ice-pwd:", &ptr) && !whip->ice_pwd_remote) { - whip->ice_pwd_remote = av_strdup(ptr); - if (!whip->ice_pwd_remote) { + } else if (av_strstart(line, "a=ice-pwd:", &ptr) && !rtc->ice_pwd_remote) { + rtc->ice_pwd_remote = av_strdup(ptr); + if (!rtc->ice_pwd_remote) { ret = AVERROR(ENOMEM); goto end; } - } else if (av_strstart(line, "a=candidate:", &ptr) && !whip->ice_protocol) { + } else if (av_strstart(line, "a=candidate:", &ptr) && !rtc->ice_protocol) { if (ptr && av_stristr(ptr, "host")) { /* Refer to RFC 5245 15.1 */ char foundation[33], protocol[17], host[129]; int component_id, priority, port; ret = sscanf(ptr, "%32s %d %16s %d %128s %d typ host", foundation, &component_id, protocol, &priority, host, &port); if (ret != 6) { - av_log(whip, AV_LOG_ERROR, "Failed %d to parse line %d %s from %s\n", - ret, i, line, whip->sdp_answer); + av_log(rtc, AV_LOG_ERROR, "Failed %d to parse line %d %s from %s\n", + ret, i, line, rtc->sdp_answer); ret = AVERROR(EIO); goto end; } if (av_strcasecmp(protocol, "udp")) { - av_log(whip, AV_LOG_ERROR, "Protocol %s is not supported by RTC, choose udp, line %d %s of %s\n", - protocol, i, line, whip->sdp_answer); + av_log(rtc, AV_LOG_ERROR, "Protocol %s is not supported by RTC, choose udp, line %d %s of %s\n", + protocol, i, line, rtc->sdp_answer); ret = AVERROR(EIO); goto end; } - whip->ice_protocol = av_strdup(protocol); - whip->ice_host = av_strdup(host); - whip->ice_port = port; - if (!whip->ice_protocol || !whip->ice_host) { + rtc->ice_protocol = av_strdup(protocol); + rtc->ice_host = av_strdup(host); + rtc->ice_port = port; + if (!rtc->ice_protocol || !rtc->ice_host) { ret = AVERROR(ENOMEM); goto end; } @@ -569,30 +569,30 @@ static int parse_answer(AVFormatContext *s) } } - if (!whip->ice_pwd_remote || !strlen(whip->ice_pwd_remote)) { - av_log(whip, AV_LOG_ERROR, "No remote ice pwd parsed from %s\n", whip->sdp_answer); + if (!rtc->ice_pwd_remote || !strlen(rtc->ice_pwd_remote)) { + av_log(rtc, AV_LOG_ERROR, "No remote ice pwd parsed from %s\n", rtc->sdp_answer); ret = AVERROR(EINVAL); goto end; } - if (!whip->ice_ufrag_remote || !strlen(whip->ice_ufrag_remote)) { - av_log(whip, AV_LOG_ERROR, "No remote ice ufrag parsed from %s\n", whip->sdp_answer); + if (!rtc->ice_ufrag_remote || !strlen(rtc->ice_ufrag_remote)) { + av_log(rtc, AV_LOG_ERROR, "No remote ice ufrag parsed from %s\n", rtc->sdp_answer); ret = AVERROR(EINVAL); goto end; } - if (!whip->ice_protocol || !whip->ice_host || !whip->ice_port) { - av_log(whip, AV_LOG_ERROR, "No ice candidate parsed from %s\n", whip->sdp_answer); + if (!rtc->ice_protocol || !rtc->ice_host || !rtc->ice_port) { + av_log(rtc, AV_LOG_ERROR, "No ice candidate parsed from %s\n", rtc->sdp_answer); ret = AVERROR(EINVAL); goto end; } - if (whip->state < WHIP_STATE_NEGOTIATED) - whip->state = WHIP_STATE_NEGOTIATED; - whip->whip_answer_time = av_gettime_relative(); - av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%zuB, answer=%zuB, ufrag=%s, pwd=%zuB, transport=%s://%s:%d, elapsed=%.2fms\n", - whip->state, strlen(whip->sdp_offer), strlen(whip->sdp_answer), whip->ice_ufrag_remote, strlen(whip->ice_pwd_remote), - whip->ice_protocol, whip->ice_host, whip->ice_port, ELAPSED(whip->whip_starttime, av_gettime_relative())); + if (rtc->state < RTC_STATE_NEGOTIATED) + rtc->state = RTC_STATE_NEGOTIATED; + rtc->rtc_answer_time = av_gettime_relative(); + av_log(rtc, AV_LOG_VERBOSE, "SDP state=%d, offer=%zuB, answer=%zuB, ufrag=%s, pwd=%zuB, transport=%s://%s:%d, elapsed=%.2fms\n", + rtc->state, strlen(rtc->sdp_offer), strlen(rtc->sdp_answer), rtc->ice_ufrag_remote, strlen(rtc->ice_pwd_remote), + rtc->ice_protocol, rtc->ice_host, rtc->ice_port, ELAPSED(rtc->rtc_starttime, av_gettime_relative())); end: avio_context_free(&pb); @@ -618,7 +618,7 @@ int ff_rtc_ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in char username[128]; AVIOContext *pb = NULL; AVHMAC *hmac = NULL; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; pb = avio_alloc_context(buf, buf_size, 1, NULL, NULL, NULL, NULL); if (!pb) @@ -634,15 +634,15 @@ int ff_rtc_ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in avio_wb16(pb, 0x0001); /* STUN binding request */ avio_wb16(pb, 0); /* length */ avio_wb32(pb, STUN_MAGIC_COOKIE); /* magic cookie */ - avio_wb32(pb, av_lfg_get(&whip->rnd)); /* transaction ID */ - avio_wb32(pb, av_lfg_get(&whip->rnd)); /* transaction ID */ - avio_wb32(pb, av_lfg_get(&whip->rnd)); /* transaction ID */ + avio_wb32(pb, av_lfg_get(&rtc->rnd)); /* transaction ID */ + avio_wb32(pb, av_lfg_get(&rtc->rnd)); /* transaction ID */ + avio_wb32(pb, av_lfg_get(&rtc->rnd)); /* transaction ID */ /* The username is the concatenation of the two ICE ufrag */ - ret = snprintf(username, sizeof(username), "%s:%s", whip->ice_ufrag_remote, whip->ice_ufrag_local); + ret = snprintf(username, sizeof(username), "%s:%s", rtc->ice_ufrag_remote, rtc->ice_ufrag_local); if (ret <= 0 || ret >= sizeof(username)) { - av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s, max=%zu, ret=%d\n", - whip->ice_ufrag_remote, whip->ice_ufrag_local, sizeof(username), ret); + av_log(rtc, AV_LOG_ERROR, "Failed to build username %s:%s, max=%zu, ret=%d\n", + rtc->ice_ufrag_remote, rtc->ice_ufrag_local, sizeof(username), ret); ret = AVERROR(EIO); goto end; } @@ -663,7 +663,7 @@ int ff_rtc_ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in avio_wb16(pb, STUN_ATTR_ICE_CONTROLLING); avio_wb16(pb, 8); - avio_wb64(pb, whip->ice_tie_breaker); + avio_wb64(pb, rtc->ice_tie_breaker); /* Build and update message integrity */ avio_wb16(pb, STUN_ATTR_MESSAGE_INTEGRITY); /* attribute type message integrity */ @@ -672,7 +672,7 @@ int ff_rtc_ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in size = avio_tell(pb); buf[2] = (size - 20) >> 8; buf[3] = (size - 20) & 0xFF; - av_hmac_init(hmac, whip->ice_pwd_remote, strlen(whip->ice_pwd_remote)); + av_hmac_init(hmac, rtc->ice_pwd_remote, strlen(rtc->ice_pwd_remote)); av_hmac_update(hmac, buf, size - 24); av_hmac_final(hmac, buf + size - 20, 20); @@ -715,10 +715,10 @@ static int ice_create_response(AVFormatContext *s, char *tid, int tid_size, uint int ret = 0, size, crc32; AVIOContext *pb = NULL; AVHMAC *hmac = NULL; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; if (tid_size != 12) { - av_log(whip, AV_LOG_ERROR, "Invalid transaction ID size. Expected 12, got %d\n", tid_size); + av_log(rtc, AV_LOG_ERROR, "Invalid transaction ID size. Expected 12, got %d\n", tid_size); return AVERROR(EINVAL); } @@ -745,7 +745,7 @@ static int ice_create_response(AVFormatContext *s, char *tid, int tid_size, uint size = avio_tell(pb); buf[2] = (size - 20) >> 8; buf[3] = (size - 20) & 0xFF; - av_hmac_init(hmac, whip->ice_pwd_local, strlen(whip->ice_pwd_local)); + av_hmac_init(hmac, rtc->ice_pwd_local, strlen(rtc->ice_pwd_local)); av_hmac_update(hmac, buf, size - 24); av_hmac_final(hmac, buf + size - 20, 20); @@ -796,14 +796,14 @@ static int ice_handle_binding_request(AVFormatContext *s, char *buf, int buf_siz { int ret = 0, size; char tid[12]; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; /* Ignore if not a binding request. */ if (!ff_rtc_ice_is_binding_request(buf, buf_size)) return ret; if (buf_size < ICE_STUN_HEADER_SIZE) { - av_log(whip, AV_LOG_ERROR, "Invalid STUN message, expected at least %d, got %d\n", + av_log(rtc, AV_LOG_ERROR, "Invalid STUN message, expected at least %d, got %d\n", ICE_STUN_HEADER_SIZE, buf_size); return AVERROR(EINVAL); } @@ -812,15 +812,15 @@ static int ice_handle_binding_request(AVFormatContext *s, char *buf, int buf_siz memcpy(tid, buf + 8, 12); /* Build the STUN binding response. */ - ret = ice_create_response(s, tid, sizeof(tid), whip->buf, sizeof(whip->buf), &size); + ret = ice_create_response(s, tid, sizeof(tid), rtc->buf, sizeof(rtc->buf), &size); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to create STUN binding response, size=%d\n", size); + av_log(rtc, AV_LOG_ERROR, "Failed to create STUN binding response, size=%d\n", size); return ret; } - ret = ffurl_write(whip->udp, whip->buf, size); + ret = ffurl_write(rtc->udp, rtc->buf, size); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to send STUN binding response, size=%d\n", size); + av_log(rtc, AV_LOG_ERROR, "Failed to send STUN binding response, size=%d\n", size); return ret; } @@ -837,33 +837,33 @@ static int udp_connect(AVFormatContext *s) int ret = 0; char url[256]; AVDictionary *opts = NULL; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; /* Build UDP URL and create the UDP context as transport. */ - ff_url_join(url, sizeof(url), "udp", NULL, whip->ice_host, whip->ice_port, NULL); + ff_url_join(url, sizeof(url), "udp", NULL, rtc->ice_host, rtc->ice_port, NULL); av_dict_set_int(&opts, "connect", 1, 0); av_dict_set_int(&opts, "fifo_size", 0, 0); /* Pass through the pkt_size and buffer_size to underling protocol */ - av_dict_set_int(&opts, "pkt_size", whip->pkt_size, 0); - av_dict_set_int(&opts, "buffer_size", whip->buffer_size, 0); + av_dict_set_int(&opts, "pkt_size", rtc->pkt_size, 0); + av_dict_set_int(&opts, "buffer_size", rtc->buffer_size, 0); - ret = ffurl_open_whitelist(&whip->udp, url, AVIO_FLAG_WRITE, &s->interrupt_callback, + ret = ffurl_open_whitelist(&rtc->udp, url, AVIO_FLAG_WRITE, &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to connect udp://%s:%d\n", whip->ice_host, whip->ice_port); + av_log(rtc, AV_LOG_ERROR, "Failed to connect udp://%s:%d\n", rtc->ice_host, rtc->ice_port); goto end; } /* Make the socket non-blocking, set to READ and WRITE mode after connected */ - ff_socket_nonblock(ffurl_get_file_handle(whip->udp), 1); - whip->udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK; + ff_socket_nonblock(ffurl_get_file_handle(rtc->udp), 1); + rtc->udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK; - if (whip->state < WHIP_STATE_UDP_CONNECTED) - whip->state = WHIP_STATE_UDP_CONNECTED; - whip->whip_udp_time = av_gettime_relative(); - av_log(whip, AV_LOG_VERBOSE, "UDP state=%d, elapsed=%.2fms, connected to udp://%s:%d\n", - whip->state, ELAPSED(whip->whip_starttime, av_gettime_relative()), whip->ice_host, whip->ice_port); + if (rtc->state < RTC_STATE_UDP_CONNECTED) + rtc->state = RTC_STATE_UDP_CONNECTED; + rtc->rtc_udp_time = av_gettime_relative(); + av_log(rtc, AV_LOG_VERBOSE, "UDP state=%d, elapsed=%.2fms, connected to udp://%s:%d\n", + rtc->state, ELAPSED(rtc->rtc_starttime, av_gettime_relative()), rtc->ice_host, rtc->ice_port); end: av_dict_free(&opts); @@ -874,88 +874,88 @@ static int ice_dtls_handshake(AVFormatContext *s) { int ret = 0, size, i; int64_t starttime = av_gettime_relative(), now; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; AVDictionary *opts = NULL; char buf[256], *cert_buf = NULL, *key_buf = NULL; - if (whip->state < WHIP_STATE_UDP_CONNECTED || !whip->udp) { - av_log(whip, AV_LOG_ERROR, "UDP not connected, state=%d, udp=%p\n", whip->state, whip->udp); + if (rtc->state < RTC_STATE_UDP_CONNECTED || !rtc->udp) { + av_log(rtc, AV_LOG_ERROR, "UDP not connected, state=%d, udp=%p\n", rtc->state, rtc->udp); return AVERROR(EINVAL); } while (1) { - if (whip->state <= WHIP_STATE_ICE_CONNECTING) { + if (rtc->state <= RTC_STATE_ICE_CONNECTING) { /* Build the STUN binding request. */ - ret = ff_rtc_ice_create_request(s, whip->buf, sizeof(whip->buf), &size); + ret = ff_rtc_ice_create_request(s, rtc->buf, sizeof(rtc->buf), &size); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to create STUN binding request, size=%d\n", size); + av_log(rtc, AV_LOG_ERROR, "Failed to create STUN binding request, size=%d\n", size); goto end; } - ret = ffurl_write(whip->udp, whip->buf, size); + ret = ffurl_write(rtc->udp, rtc->buf, size); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to send STUN binding request, size=%d\n", size); + av_log(rtc, AV_LOG_ERROR, "Failed to send STUN binding request, size=%d\n", size); goto end; } - if (whip->state < WHIP_STATE_ICE_CONNECTING) - whip->state = WHIP_STATE_ICE_CONNECTING; + if (rtc->state < RTC_STATE_ICE_CONNECTING) + rtc->state = RTC_STATE_ICE_CONNECTING; } next_packet: - if (whip->state >= WHIP_STATE_DTLS_FINISHED) + if (rtc->state >= RTC_STATE_DTLS_FINISHED) /* DTLS handshake is done, exit the loop. */ break; now = av_gettime_relative(); - if (now - starttime >= whip->handshake_timeout * WHIP_US_PER_MS) { - av_log(whip, AV_LOG_ERROR, "DTLS handshake timeout=%dms, cost=%.2fms, elapsed=%.2fms, state=%d\n", - whip->handshake_timeout, ELAPSED(starttime, now), ELAPSED(whip->whip_starttime, now), whip->state); + if (now - starttime >= rtc->handshake_timeout * RTC_US_PER_MS) { + av_log(rtc, AV_LOG_ERROR, "DTLS handshake timeout=%dms, cost=%.2fms, elapsed=%.2fms, state=%d\n", + rtc->handshake_timeout, ELAPSED(starttime, now), ELAPSED(rtc->rtc_starttime, now), rtc->state); ret = AVERROR(ETIMEDOUT); goto end; } /* Read the STUN or DTLS messages from peer. */ for (i = 0; i < ICE_DTLS_READ_MAX_RETRY; i++) { - if (whip->state > WHIP_STATE_ICE_CONNECTED) + if (rtc->state > RTC_STATE_ICE_CONNECTED) break; - ret = ffurl_read(whip->udp, whip->buf, sizeof(whip->buf)); + ret = ffurl_read(rtc->udp, rtc->buf, sizeof(rtc->buf)); if (ret > 0) break; if (ret == AVERROR(EAGAIN)) { - av_usleep(ICE_DTLS_READ_SLEEP_DURATION * WHIP_US_PER_MS); + av_usleep(ICE_DTLS_READ_SLEEP_DURATION * RTC_US_PER_MS); continue; } - av_log(whip, AV_LOG_ERROR, "Failed to read message\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to read message\n"); goto end; } /* Handle the ICE binding response. */ - if (ff_rtc_ice_is_binding_response(whip->buf, ret)) { - if (whip->state < WHIP_STATE_ICE_CONNECTED) { - if (whip->is_peer_ice_lite) - whip->state = WHIP_STATE_ICE_CONNECTED; - whip->whip_ice_time = av_gettime_relative(); - av_log(whip, AV_LOG_VERBOSE, "ICE STUN ok, state=%d, url=udp://%s:%d, location=%s, username=%s:%s, res=%dB, elapsed=%.2fms\n", - whip->state, whip->ice_host, whip->ice_port, whip->whip_resource_url ? whip->whip_resource_url : "", - whip->ice_ufrag_remote, whip->ice_ufrag_local, ret, ELAPSED(whip->whip_starttime, av_gettime_relative())); - - ff_url_join(buf, sizeof(buf), "dtls", NULL, whip->ice_host, whip->ice_port, NULL); - av_dict_set_int(&opts, "mtu", whip->pkt_size, 0); - if (whip->cert_file) { - av_dict_set(&opts, "cert_file", whip->cert_file, 0); + if (ff_rtc_ice_is_binding_response(rtc->buf, ret)) { + if (rtc->state < RTC_STATE_ICE_CONNECTED) { + if (rtc->is_peer_ice_lite) + rtc->state = RTC_STATE_ICE_CONNECTED; + rtc->rtc_ice_time = av_gettime_relative(); + av_log(rtc, AV_LOG_VERBOSE, "ICE STUN ok, state=%d, url=udp://%s:%d, location=%s, username=%s:%s, res=%dB, elapsed=%.2fms\n", + rtc->state, rtc->ice_host, rtc->ice_port, rtc->rtc_resource_url ? rtc->rtc_resource_url : "", + rtc->ice_ufrag_remote, rtc->ice_ufrag_local, ret, ELAPSED(rtc->rtc_starttime, av_gettime_relative())); + + ff_url_join(buf, sizeof(buf), "dtls", NULL, rtc->ice_host, rtc->ice_port, NULL); + av_dict_set_int(&opts, "mtu", rtc->pkt_size, 0); + if (rtc->cert_file) { + av_dict_set(&opts, "cert_file", rtc->cert_file, 0); } else - av_dict_set(&opts, "cert_pem", whip->cert_buf, 0); + av_dict_set(&opts, "cert_pem", rtc->cert_buf, 0); - if (whip->key_file) { - av_dict_set(&opts, "key_file", whip->key_file, 0); + if (rtc->key_file) { + av_dict_set(&opts, "key_file", rtc->key_file, 0); } else - av_dict_set(&opts, "key_pem", whip->key_buf, 0); + av_dict_set(&opts, "key_pem", rtc->key_buf, 0); av_dict_set_int(&opts, "external_sock", 1, 0); av_dict_set_int(&opts, "use_srtp", 1, 0); av_dict_set_int(&opts, "listen", 1, 0); /* If got the first binding response, start DTLS handshake. */ - ret = ffurl_open_whitelist(&whip->dtls_uc, buf, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, + ret = ffurl_open_whitelist(&rtc->dtls_uc, buf, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL); av_dict_free(&opts); if (ret < 0) @@ -966,28 +966,28 @@ next_packet: } /* When a binding request is received, it is necessary to respond immediately. */ - if (ff_rtc_ice_is_binding_request(whip->buf, ret)) { - if ((ret = ice_handle_binding_request(s, whip->buf, ret)) < 0) + if (ff_rtc_ice_is_binding_request(rtc->buf, ret)) { + if ((ret = ice_handle_binding_request(s, rtc->buf, ret)) < 0) goto end; goto next_packet; } /* If got any DTLS messages, handle it. */ - if (ff_rtc_is_dtls_packet(whip->buf, ret)) { + if (ff_rtc_is_dtls_packet(rtc->buf, ret)) { /* Start consent timer when ICE selected */ - whip->whip_last_consent_tx_time = whip->whip_last_consent_rx_time = av_gettime_relative(); - whip->state = WHIP_STATE_ICE_CONNECTED; - ret = ffurl_handshake(whip->dtls_uc); + rtc->rtc_last_consent_tx_time = rtc->rtc_last_consent_rx_time = av_gettime_relative(); + rtc->state = RTC_STATE_ICE_CONNECTED; + ret = ffurl_handshake(rtc->dtls_uc); if (ret < 0) { - whip->state = WHIP_STATE_FAILED; - av_log(whip, AV_LOG_VERBOSE, "DTLS session failed\n"); + rtc->state = RTC_STATE_FAILED; + av_log(rtc, AV_LOG_VERBOSE, "DTLS session failed\n"); goto end; } if (!ret) { - whip->state = WHIP_STATE_DTLS_FINISHED; - whip->whip_dtls_time = av_gettime_relative(); - av_log(whip, AV_LOG_VERBOSE, "DTLS handshake is done, elapsed=%.2fms\n", - ELAPSED(whip->whip_starttime, whip->whip_dtls_time)); + rtc->state = RTC_STATE_DTLS_FINISHED; + rtc->rtc_dtls_time = av_gettime_relative(); + av_log(rtc, AV_LOG_VERBOSE, "DTLS handshake is done, elapsed=%.2fms\n", + ELAPSED(rtc->rtc_starttime, rtc->rtc_dtls_time)); } goto next_packet; } @@ -1021,8 +1021,8 @@ static int setup_srtp(AVFormatContext *s) * The profile for FFmpeg's SRTP is SRTP_AES128_CM_HMAC_SHA1_80, see libavformat/srtp.c. */ const char* suite = "SRTP_AES128_CM_HMAC_SHA1_80"; - WHIPContext *whip = s->priv_data; - ret = ff_dtls_export_materials(whip->dtls_uc, whip->dtls_srtp_materials, sizeof(whip->dtls_srtp_materials)); + RTCContext *rtc = s->priv_data; + ret = ff_dtls_export_materials(rtc->dtls_uc, rtc->dtls_srtp_materials, sizeof(rtc->dtls_srtp_materials)); if (ret < 0) goto end; /** @@ -1031,8 +1031,8 @@ static int setup_srtp(AVFormatContext *s) * 16B 16B 14B 14B * client_key | server_key | client_salt | server_salt */ - char *client_key = whip->dtls_srtp_materials; - char *server_key = whip->dtls_srtp_materials + DTLS_SRTP_KEY_LEN; + char *client_key = rtc->dtls_srtp_materials; + char *server_key = rtc->dtls_srtp_materials + DTLS_SRTP_KEY_LEN; char *client_salt = server_key + DTLS_SRTP_KEY_LEN; char *server_salt = client_salt + DTLS_SRTP_SALT_LEN; @@ -1046,53 +1046,53 @@ static int setup_srtp(AVFormatContext *s) /* Setup SRTP context for outgoing packets */ if (!av_base64_encode(buf, sizeof(buf), send_key, sizeof(send_key))) { - av_log(whip, AV_LOG_ERROR, "Failed to encode send key\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to encode send key\n"); ret = AVERROR(EIO); goto end; } - ret = ff_srtp_set_crypto(&whip->srtp_audio_send, suite, buf); + ret = ff_srtp_set_crypto(&rtc->srtp_audio_send, suite, buf); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to set crypto for audio send\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to set crypto for audio send\n"); goto end; } - ret = ff_srtp_set_crypto(&whip->srtp_video_send, suite, buf); + ret = ff_srtp_set_crypto(&rtc->srtp_video_send, suite, buf); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to set crypto for video send\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to set crypto for video send\n"); goto end; } - ret = ff_srtp_set_crypto(&whip->srtp_video_rtx_send, suite, buf); + ret = ff_srtp_set_crypto(&rtc->srtp_video_rtx_send, suite, buf); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to set crypto for video rtx send\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to set crypto for video rtx send\n"); goto end; } - ret = ff_srtp_set_crypto(&whip->srtp_rtcp_send, suite, buf); + ret = ff_srtp_set_crypto(&rtc->srtp_rtcp_send, suite, buf); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to set crypto for rtcp send\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to set crypto for rtcp send\n"); goto end; } /* Setup SRTP context for incoming packets */ if (!av_base64_encode(buf, sizeof(buf), recv_key, sizeof(recv_key))) { - av_log(whip, AV_LOG_ERROR, "Failed to encode recv key\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to encode recv key\n"); ret = AVERROR(EIO); goto end; } - ret = ff_srtp_set_crypto(&whip->srtp_recv, suite, buf); + ret = ff_srtp_set_crypto(&rtc->srtp_recv, suite, buf); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to set crypto for recv\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to set crypto for recv\n"); goto end; } - if (whip->state < WHIP_STATE_SRTP_FINISHED) - whip->state = WHIP_STATE_SRTP_FINISHED; - whip->whip_srtp_time = av_gettime_relative(); - av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%zuB, elapsed=%.2fms\n", - whip->state, suite, sizeof(send_key), ELAPSED(whip->whip_starttime, av_gettime_relative())); + if (rtc->state < RTC_STATE_SRTP_FINISHED) + rtc->state = RTC_STATE_SRTP_FINISHED; + rtc->rtc_srtp_time = av_gettime_relative(); + av_log(rtc, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%zuB, elapsed=%.2fms\n", + rtc->state, suite, sizeof(send_key), ELAPSED(rtc->rtc_starttime, av_gettime_relative())); end: return ret; @@ -1110,18 +1110,18 @@ static int dispose_session(AVFormatContext *s) { int ret; char buf[MAX_URL_SIZE]; - URLContext *whip_uc = NULL; + URLContext *rtc_uc = NULL; AVDictionary *opts = NULL; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; - if (!whip->whip_resource_url) + if (!rtc->rtc_resource_url) return 0; ret = snprintf(buf, sizeof(buf), "Cache-Control: no-cache\r\n"); - if (whip->authorization) - ret += snprintf(buf + ret, sizeof(buf) - ret, "Authorization: Bearer %s\r\n", whip->authorization); + if (rtc->authorization) + ret += snprintf(buf + ret, sizeof(buf) - ret, "Authorization: Bearer %s\r\n", rtc->authorization); if (ret <= 0 || ret >= sizeof(buf)) { - av_log(whip, AV_LOG_ERROR, "Failed to generate headers, size=%d, %s\n", ret, buf); + av_log(rtc, AV_LOG_ERROR, "Failed to generate headers, size=%d, %s\n", ret, buf); ret = AVERROR(EINVAL); goto end; } @@ -1129,29 +1129,29 @@ static int dispose_session(AVFormatContext *s) av_dict_set(&opts, "headers", buf, 0); av_dict_set_int(&opts, "chunked_post", 0, 0); av_dict_set(&opts, "method", "DELETE", 0); - ret = ffurl_open_whitelist(&whip_uc, whip->whip_resource_url, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, + ret = ffurl_open_whitelist(&rtc_uc, rtc->rtc_resource_url, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to DELETE url=%s\n", whip->whip_resource_url); + av_log(rtc, AV_LOG_ERROR, "Failed to DELETE url=%s\n", rtc->rtc_resource_url); goto end; } while (1) { - ret = ffurl_read(whip_uc, buf, sizeof(buf)); + ret = ffurl_read(rtc_uc, buf, sizeof(buf)); if (ret == AVERROR_EOF) { ret = 0; break; } if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to read response from DELETE url=%s\n", whip->whip_resource_url); + av_log(rtc, AV_LOG_ERROR, "Failed to read response from DELETE url=%s\n", rtc->rtc_resource_url); goto end; } } - av_log(whip, AV_LOG_INFO, "Dispose resource %s ok\n", whip->whip_resource_url); + av_log(rtc, AV_LOG_INFO, "Dispose resource %s ok\n", rtc->rtc_resource_url); end: - ffurl_closep(&whip_uc); + ffurl_closep(&rtc_uc); av_dict_free(&opts); return ret; } @@ -1183,11 +1183,11 @@ end: void ff_rtc_close(AVFormatContext *s) { int i, ret; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; ret = dispose_session(s); if (ret < 0) - av_log(whip, AV_LOG_WARNING, "Failed to dispose resource, ret=%d\n", ret); + av_log(rtc, AV_LOG_WARNING, "Failed to dispose resource, ret=%d\n", ret); for (i = 0; i < s->nb_streams; i++) { AVFormatContext* rtp_ctx = s->streams[i]->priv_data; @@ -1206,26 +1206,26 @@ void ff_rtc_close(AVFormatContext *s) s->streams[i]->priv_data = NULL; } - av_freep(&whip->sdp_offer); - av_freep(&whip->sdp_answer); - av_freep(&whip->whip_resource_url); - av_freep(&whip->ice_ufrag_remote); - av_freep(&whip->ice_pwd_remote); - av_freep(&whip->ice_protocol); - av_freep(&whip->ice_host); - av_freep(&whip->authorization); - av_freep(&whip->cert_file); - av_freep(&whip->key_file); - ff_srtp_free(&whip->srtp_audio_send); - ff_srtp_free(&whip->srtp_video_send); - ff_srtp_free(&whip->srtp_video_rtx_send); - ff_srtp_free(&whip->srtp_rtcp_send); - ff_srtp_free(&whip->srtp_recv); - ffurl_close(whip->dtls_uc); - ffurl_closep(&whip->udp); + av_freep(&rtc->sdp_offer); + av_freep(&rtc->sdp_answer); + av_freep(&rtc->rtc_resource_url); + av_freep(&rtc->ice_ufrag_remote); + av_freep(&rtc->ice_pwd_remote); + av_freep(&rtc->ice_protocol); + av_freep(&rtc->ice_host); + av_freep(&rtc->authorization); + av_freep(&rtc->cert_file); + av_freep(&rtc->key_file); + ff_srtp_free(&rtc->srtp_audio_send); + ff_srtp_free(&rtc->srtp_video_send); + ff_srtp_free(&rtc->srtp_video_rtx_send); + ff_srtp_free(&rtc->srtp_rtcp_send); + ff_srtp_free(&rtc->srtp_recv); + ffurl_close(rtc->dtls_uc); + ffurl_closep(&rtc->udp); } -#define OFFSET(x) offsetof(WHIPContext, x) +#define OFFSET(x) offsetof(RTCContext, x) #define ENC AV_OPT_FLAG_ENCODING_PARAM const AVOption ff_rtc_options[] = { { "handshake_timeout", "Timeout in milliseconds for ICE and DTLS handshake.", OFFSET(handshake_timeout), AV_OPT_TYPE_INT, { .i64 = 5000 }, -1, INT_MAX, ENC }, diff --git a/libavformat/rtc.h b/libavformat/rtc.h index 146ad06f31..011e157b9f 100644 --- a/libavformat/rtc.h +++ b/libavformat/rtc.h @@ -32,34 +32,34 @@ #include "libavutil/log.h" #include "libavutil/opt.h" -enum WHIPState { - WHIP_STATE_NONE, +enum RTCState { + RTC_STATE_NONE, /* The initial state. */ - WHIP_STATE_INIT, + RTC_STATE_INIT, /* The muxer has sent the offer to the peer. */ - WHIP_STATE_OFFER, + RTC_STATE_OFFER, /* The muxer has received the answer from the peer. */ - WHIP_STATE_ANSWER, + RTC_STATE_ANSWER, /** * After parsing the answer received from the peer, the muxer negotiates the abilities * in the offer that it generated. */ - WHIP_STATE_NEGOTIATED, + RTC_STATE_NEGOTIATED, /* The muxer has connected to the peer via UDP. */ - WHIP_STATE_UDP_CONNECTED, + RTC_STATE_UDP_CONNECTED, /* The muxer has sent the ICE request to the peer. */ - WHIP_STATE_ICE_CONNECTING, + RTC_STATE_ICE_CONNECTING, /* The muxer has received the ICE response from the peer. */ - WHIP_STATE_ICE_CONNECTED, + RTC_STATE_ICE_CONNECTED, /* The muxer has finished the DTLS handshake with the peer. */ - WHIP_STATE_DTLS_FINISHED, + RTC_STATE_DTLS_FINISHED, /* The muxer has finished the SRTP setup. */ - WHIP_STATE_SRTP_FINISHED, + RTC_STATE_SRTP_FINISHED, /* The muxer is ready to send/receive media frames. */ - WHIP_STATE_READY, + RTC_STATE_READY, /* The muxer is failed. */ - WHIP_STATE_FAILED, + RTC_STATE_FAILED, }; /** @@ -70,7 +70,7 @@ enum WHIPState { */ #define DTLS_SRTP_KEY_LEN 16 #define DTLS_SRTP_SALT_LEN 14 -#define WHIP_US_PER_MS 1000 +#define RTC_US_PER_MS 1000 /** * Maximum size of the buffer for sending and receiving UDP packets. @@ -81,11 +81,11 @@ enum WHIPState { */ #define MAX_UDP_BUFFER_SIZE 4096 -typedef struct WHIPContext { +typedef struct RTCContext { AVClass *av_class; /* The state of the RTC connection. */ - enum WHIPState state; + enum RTCState state; /* Parameters for the input audio and video codecs. */ AVCodecParameters *audio_par; @@ -137,20 +137,20 @@ typedef struct WHIPContext { /* The SDP answer received from the WebRTC server. */ char *sdp_answer; - /* The resource URL returned in the Location header of WHIP HTTP response. */ - char *whip_resource_url; + /* The resource URL returned in the Location header of WHIP/WHEP HTTP response. */ + char *rtc_resource_url; /* These variables represent timestamps used for calculating and tracking the cost. */ - int64_t whip_starttime; - int64_t whip_init_time; - int64_t whip_offer_time; - int64_t whip_answer_time; - int64_t whip_udp_time; - int64_t whip_ice_time; - int64_t whip_dtls_time; - int64_t whip_srtp_time; - int64_t whip_last_consent_tx_time; - int64_t whip_last_consent_rx_time; + int64_t rtc_starttime; + int64_t rtc_init_time; + int64_t rtc_offer_time; + int64_t rtc_answer_time; + int64_t rtc_udp_time; + int64_t rtc_ice_time; + int64_t rtc_dtls_time; + int64_t rtc_srtp_time; + int64_t rtc_last_consent_tx_time; + int64_t rtc_last_consent_rx_time; /* The certificate and private key content used for DTLS handshake */ char cert_buf[MAX_CERTIFICATE_SIZE]; @@ -192,14 +192,14 @@ typedef struct WHIPContext { int pkt_size; int buffer_size;/* Underlying protocol send/receive buffer size */ /** - * The optional Bearer token for WHIP Authorization. + * The optional Bearer token for WHIP/WHEP Authorization. * See https://www.ietf.org/archive/id/draft-ietf-wish-whip-08.html#name-authentication-and-authoriz */ char* authorization; /* The certificate and private key used for DTLS handshake. */ char* cert_file; char* key_file; -} WHIPContext; +} RTCContext; int ff_rtc_initialize(AVFormatContext *s); diff --git a/libavformat/whip.c b/libavformat/whip.c index 8e517f62ee..c73c8d5c26 100644 --- a/libavformat/whip.c +++ b/libavformat/whip.c @@ -115,7 +115,7 @@ static int parse_profile_level(AVFormatContext *s, AVCodecParameters *par) const uint8_t *r = par->extradata, *r1, *end = par->extradata + par->extradata_size; H264SPS seq, *const sps = &seq; uint32_t state; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; if (par->codec_id != AV_CODEC_ID_H264) return ret; @@ -124,7 +124,7 @@ static int parse_profile_level(AVFormatContext *s, AVCodecParameters *par) return ret; if (!par->extradata || par->extradata_size <= 0) { - av_log(whip, AV_LOG_ERROR, "Unable to parse profile from empty extradata=%p, size=%d\n", + av_log(rtc, AV_LOG_ERROR, "Unable to parse profile from empty extradata=%p, size=%d\n", par->extradata, par->extradata_size); return AVERROR(EINVAL); } @@ -138,12 +138,12 @@ static int parse_profile_level(AVFormatContext *s, AVCodecParameters *par) if ((state & 0x1f) == H264_NAL_SPS) { ret = ff_avc_decode_sps(sps, r, r1 - r); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to decode SPS, state=%x, size=%d\n", + av_log(rtc, AV_LOG_ERROR, "Failed to decode SPS, state=%x, size=%d\n", state, (int)(r1 - r)); return ret; } - av_log(whip, AV_LOG_VERBOSE, "Parse profile=%d, level=%d from SPS\n", + av_log(rtc, AV_LOG_VERBOSE, "Parse profile=%d, level=%d from SPS\n", sps->profile_idc, sps->level_idc); par->profile = sps->profile_idc; par->level = sps->level_idc; @@ -179,70 +179,70 @@ static int parse_profile_level(AVFormatContext *s, AVCodecParameters *par) static int parse_codec(AVFormatContext *s) { int i, ret = 0; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; for (i = 0; i < s->nb_streams; i++) { AVCodecParameters *par = s->streams[i]->codecpar; const AVCodecDescriptor *desc = avcodec_descriptor_get(par->codec_id); switch (par->codec_type) { case AVMEDIA_TYPE_VIDEO: - if (whip->video_par) { - av_log(whip, AV_LOG_ERROR, "Only one video stream is supported by RTC\n"); + if (rtc->video_par) { + av_log(rtc, AV_LOG_ERROR, "Only one video stream is supported by RTC\n"); return AVERROR(EINVAL); } - whip->video_par = par; + rtc->video_par = par; if (par->codec_id != AV_CODEC_ID_H264) { - av_log(whip, AV_LOG_ERROR, "Unsupported video codec %s by RTC, choose h264\n", + av_log(rtc, AV_LOG_ERROR, "Unsupported video codec %s by RTC, choose h264\n", desc ? desc->name : "unknown"); return AVERROR_PATCHWELCOME; } if (par->video_delay > 0) { - av_log(whip, AV_LOG_ERROR, "Unsupported B frames by RTC\n"); + av_log(rtc, AV_LOG_ERROR, "Unsupported B frames by RTC\n"); return AVERROR_PATCHWELCOME; } if ((ret = parse_profile_level(s, par)) < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to parse SPS/PPS from extradata\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to parse SPS/PPS from extradata\n"); return AVERROR(EINVAL); } if (par->profile == AV_PROFILE_UNKNOWN) { - av_log(whip, AV_LOG_WARNING, "No profile found in extradata, consider baseline\n"); + av_log(rtc, AV_LOG_WARNING, "No profile found in extradata, consider baseline\n"); return AVERROR(EINVAL); } if (par->level == AV_LEVEL_UNKNOWN) { - av_log(whip, AV_LOG_WARNING, "No level found in extradata, consider 3.1\n"); + av_log(rtc, AV_LOG_WARNING, "No level found in extradata, consider 3.1\n"); return AVERROR(EINVAL); } break; case AVMEDIA_TYPE_AUDIO: - if (whip->audio_par) { - av_log(whip, AV_LOG_ERROR, "Only one audio stream is supported by RTC\n"); + if (rtc->audio_par) { + av_log(rtc, AV_LOG_ERROR, "Only one audio stream is supported by RTC\n"); return AVERROR(EINVAL); } - whip->audio_par = par; + rtc->audio_par = par; if (par->codec_id != AV_CODEC_ID_OPUS) { - av_log(whip, AV_LOG_ERROR, "Unsupported audio codec %s by RTC, choose opus\n", + av_log(rtc, AV_LOG_ERROR, "Unsupported audio codec %s by RTC, choose opus\n", desc ? desc->name : "unknown"); return AVERROR_PATCHWELCOME; } if (par->ch_layout.nb_channels != 2) { - av_log(whip, AV_LOG_ERROR, "Unsupported audio channels %d by RTC, choose stereo\n", + av_log(rtc, AV_LOG_ERROR, "Unsupported audio channels %d by RTC, choose stereo\n", par->ch_layout.nb_channels); return AVERROR_PATCHWELCOME; } if (par->sample_rate != 48000) { - av_log(whip, AV_LOG_ERROR, "Unsupported audio sample rate %d by RTC, choose 48000\n", par->sample_rate); + av_log(rtc, AV_LOG_ERROR, "Unsupported audio sample rate %d by RTC, choose 48000\n", par->sample_rate); return AVERROR_PATCHWELCOME; } break; default: - av_log(whip, AV_LOG_ERROR, "Codec type '%s' for stream %d is not supported by RTC\n", + av_log(rtc, AV_LOG_ERROR, "Codec type '%s' for stream %d is not supported by RTC\n", av_get_media_type_string(par->codec_type), i); return AVERROR_PATCHWELCOME; } @@ -264,7 +264,7 @@ static int on_rtp_write_packet(void *opaque, const uint8_t *buf, int buf_size) int ret, cipher_size, is_rtcp, is_video; uint8_t payload_type; AVFormatContext *s = opaque; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; SRTPContext *srtp; /* Ignore if not RTP or RTCP packet. */ @@ -274,23 +274,23 @@ static int on_rtp_write_packet(void *opaque, const uint8_t *buf, int buf_size) /* Only support audio, video and rtcp. */ is_rtcp = media_is_rtcp(buf, buf_size); payload_type = buf[1] & 0x7f; - is_video = payload_type == whip->video_payload_type; - if (!is_rtcp && payload_type != whip->video_payload_type && payload_type != whip->audio_payload_type) + is_video = payload_type == rtc->video_payload_type; + if (!is_rtcp && payload_type != rtc->video_payload_type && payload_type != rtc->audio_payload_type) return 0; /* Get the corresponding SRTP context. */ - srtp = is_rtcp ? &whip->srtp_rtcp_send : (is_video? &whip->srtp_video_send : &whip->srtp_audio_send); + srtp = is_rtcp ? &rtc->srtp_rtcp_send : (is_video? &rtc->srtp_video_send : &rtc->srtp_audio_send); /* Encrypt by SRTP and send out. */ - cipher_size = ff_srtp_encrypt(srtp, buf, buf_size, whip->buf, sizeof(whip->buf)); + cipher_size = ff_srtp_encrypt(srtp, buf, buf_size, rtc->buf, sizeof(rtc->buf)); if (cipher_size <= 0 || cipher_size < buf_size) { - av_log(whip, AV_LOG_WARNING, "Failed to encrypt packet=%dB, cipher=%dB\n", buf_size, cipher_size); + av_log(rtc, AV_LOG_WARNING, "Failed to encrypt packet=%dB, cipher=%dB\n", buf_size, cipher_size); return 0; } - ret = ffurl_write(whip->udp, whip->buf, cipher_size); + ret = ffurl_write(rtc->udp, rtc->buf, cipher_size); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to write packet=%dB, ret=%d\n", cipher_size, ret); + av_log(rtc, AV_LOG_ERROR, "Failed to write packet=%dB, ret=%d\n", cipher_size, ret); return ret; } @@ -315,12 +315,12 @@ static int create_rtp_muxer(AVFormatContext *s) AVDictionary *opts = NULL; uint8_t *buffer = NULL; char buf[64]; - WHIPContext *whip = s->priv_data; - whip->udp->flags |= AVIO_FLAG_NONBLOCK; + RTCContext *rtc = s->priv_data; + rtc->udp->flags |= AVIO_FLAG_NONBLOCK; const AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); if (!rtp_format) { - av_log(whip, AV_LOG_ERROR, "Failed to guess rtp muxer\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to guess rtp muxer\n"); ret = AVERROR(ENOSYS); goto end; } @@ -328,7 +328,7 @@ static int create_rtp_muxer(AVFormatContext *s) /* The UDP buffer size, may greater than MTU. */ buffer_size = MAX_UDP_BUFFER_SIZE; /* The RTP payload max size. Reserved some bytes for SRTP checksum and padding. */ - max_packet_size = whip->pkt_size - DTLS_SRTP_CHECKSUM_LEN; + max_packet_size = rtc->pkt_size - DTLS_SRTP_CHECKSUM_LEN; for (i = 0; i < s->nb_streams; i++) { rtp_ctx = avformat_alloc_context(); @@ -381,15 +381,15 @@ static int create_rtp_muxer(AVFormatContext *s) rtp_ctx->pb->av_class = &ff_avio_class; is_video = s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO; - snprintf(buf, sizeof(buf), "%d", is_video? whip->video_payload_type : whip->audio_payload_type); + snprintf(buf, sizeof(buf), "%d", is_video? rtc->video_payload_type : rtc->audio_payload_type); av_dict_set(&opts, "payload_type", buf, 0); - snprintf(buf, sizeof(buf), "%d", is_video? whip->video_ssrc : whip->audio_ssrc); + snprintf(buf, sizeof(buf), "%d", is_video? rtc->video_ssrc : rtc->audio_ssrc); av_dict_set(&opts, "ssrc", buf, 0); - av_dict_set_int(&opts, "seq", is_video ? whip->video_first_seq : whip->audio_first_seq, 0); + av_dict_set_int(&opts, "seq", is_video ? rtc->video_first_seq : rtc->audio_first_seq, 0); ret = avformat_write_header(rtp_ctx, &opts); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to write rtp header\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to write rtp header\n"); goto end; } @@ -399,18 +399,18 @@ static int create_rtp_muxer(AVFormatContext *s) rtp_ctx = NULL; } - if (whip->state < WHIP_STATE_READY) - whip->state = WHIP_STATE_READY; - av_log(whip, AV_LOG_INFO, "Muxer state=%d, buffer_size=%d, max_packet_size=%d, " + if (rtc->state < RTC_STATE_READY) + rtc->state = RTC_STATE_READY; + av_log(rtc, AV_LOG_INFO, "Muxer state=%d, buffer_size=%d, max_packet_size=%d, " "elapsed=%.2fms(init:%.2f,offer:%.2f,answer:%.2f,udp:%.2f,ice:%.2f,dtls:%.2f,srtp:%.2f)\n", - whip->state, buffer_size, max_packet_size, ELAPSED(whip->whip_starttime, av_gettime_relative()), - ELAPSED(whip->whip_starttime, whip->whip_init_time), - ELAPSED(whip->whip_init_time, whip->whip_offer_time), - ELAPSED(whip->whip_offer_time, whip->whip_answer_time), - ELAPSED(whip->whip_answer_time, whip->whip_udp_time), - ELAPSED(whip->whip_udp_time, whip->whip_ice_time), - ELAPSED(whip->whip_ice_time, whip->whip_dtls_time), - ELAPSED(whip->whip_dtls_time, whip->whip_srtp_time)); + rtc->state, buffer_size, max_packet_size, ELAPSED(rtc->rtc_starttime, av_gettime_relative()), + ELAPSED(rtc->rtc_starttime, rtc->rtc_init_time), + ELAPSED(rtc->rtc_init_time, rtc->rtc_offer_time), + ELAPSED(rtc->rtc_offer_time, rtc->rtc_answer_time), + ELAPSED(rtc->rtc_answer_time, rtc->rtc_udp_time), + ELAPSED(rtc->rtc_udp_time, rtc->rtc_ice_time), + ELAPSED(rtc->rtc_ice_time, rtc->rtc_dtls_time), + ELAPSED(rtc->rtc_dtls_time, rtc->rtc_srtp_time)); end: if (rtp_ctx) @@ -504,7 +504,7 @@ fail: static av_cold int whip_init(AVFormatContext *s) { int ret; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; if ((ret = ff_rtc_initialize(s)) < 0) goto end; @@ -520,14 +520,14 @@ static av_cold int whip_init(AVFormatContext *s) end: if (ret < 0) - whip->state = WHIP_STATE_FAILED; + rtc->state = RTC_STATE_FAILED; return ret; } static void handle_nack_rtx(AVFormatContext *s, int size) { int ret; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; uint8_t *buf = NULL; int rtcp_len, srtcp_len, header_len = 12/*RFC 4585 6.1*/; @@ -536,27 +536,27 @@ static void handle_nack_rtx(AVFormatContext *s, int size) * The length of this RTCP packet in 32 bit words minus one, * including the header and any padding. */ - rtcp_len = (AV_RB16(&whip->buf[2]) + 1) * 4; + rtcp_len = (AV_RB16(&rtc->buf[2]) + 1) * 4; if (rtcp_len <= header_len) { - av_log(whip, AV_LOG_WARNING, "NACK packet is broken, size: %d\n", rtcp_len); + av_log(rtc, AV_LOG_WARNING, "NACK packet is broken, size: %d\n", rtcp_len); goto error; } /* SRTCP index(4 bytes) + HMAC(SRTP_ARS128_CM_SHA1_80) 10bytes */ srtcp_len = rtcp_len + 4 + 10; if (srtcp_len != size) { - av_log(whip, AV_LOG_WARNING, "NACK packet size not match, srtcp_len:%d, size:%d\n", srtcp_len, size); + av_log(rtc, AV_LOG_WARNING, "NACK packet size not match, srtcp_len:%d, size:%d\n", srtcp_len, size); goto error; } - buf = av_memdup(whip->buf, srtcp_len); + buf = av_memdup(rtc->buf, srtcp_len); if (!buf) goto error; - if ((ret = ff_srtp_decrypt(&whip->srtp_recv, buf, &srtcp_len)) < 0) { - av_log(whip, AV_LOG_WARNING, "NACK packet decrypt failed: %d\n", ret); + if ((ret = ff_srtp_decrypt(&rtc->srtp_recv, buf, &srtcp_len)) < 0) { + av_log(rtc, AV_LOG_WARNING, "NACK packet decrypt failed: %d\n", ret); goto error; } goto end; error: - av_log(whip, AV_LOG_WARNING, "Failed to handle NACK and RTX, Skip...\n"); + av_log(rtc, AV_LOG_WARNING, "Failed to handle NACK and RTX, Skip...\n"); end: av_freep(&buf); } @@ -564,7 +564,7 @@ end: static int whip_write_packet(AVFormatContext *s, AVPacket *pkt) { int ret; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; AVStream *st = s->streams[pkt->stream_index]; AVFormatContext *rtp_ctx = st->priv_data; @@ -573,52 +573,52 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt) * Refer to RFC 7675 * Periodically send Consent Freshness STUN Binding Request */ - if (now - whip->whip_last_consent_tx_time > WHIP_ICE_CONSENT_CHECK_INTERVAL * WHIP_US_PER_MS) { + if (now - rtc->rtc_last_consent_tx_time > WHIP_ICE_CONSENT_CHECK_INTERVAL * RTC_US_PER_MS) { int size; - ret = ff_rtc_ice_create_request(s, whip->buf, sizeof(whip->buf), &size); + ret = ff_rtc_ice_create_request(s, rtc->buf, sizeof(rtc->buf), &size); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to create STUN binding request, size=%d\n", size); + av_log(rtc, AV_LOG_ERROR, "Failed to create STUN binding request, size=%d\n", size); goto end; } - ret = ffurl_write(whip->udp, whip->buf, size); + ret = ffurl_write(rtc->udp, rtc->buf, size); if (ret < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to send STUN binding request, size=%d\n", size); + av_log(rtc, AV_LOG_ERROR, "Failed to send STUN binding request, size=%d\n", size); goto end; } - whip->whip_last_consent_tx_time = now; - av_log(whip, AV_LOG_DEBUG, "Consent Freshness check sent\n"); + rtc->rtc_last_consent_tx_time = now; + av_log(rtc, AV_LOG_DEBUG, "Consent Freshness check sent\n"); } /** * Receive packets from the server such as ICE binding requests, DTLS messages, * and RTCP like PLI requests, then respond to them. */ - ret = ffurl_read(whip->udp, whip->buf, sizeof(whip->buf)); + ret = ffurl_read(rtc->udp, rtc->buf, sizeof(rtc->buf)); if (ret < 0) { if (ret == AVERROR(EAGAIN)) goto write_packet; - av_log(whip, AV_LOG_ERROR, "Failed to read from UDP socket\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to read from UDP socket\n"); goto end; } if (!ret) { - av_log(whip, AV_LOG_ERROR, "Receive EOF from UDP socket\n"); + av_log(rtc, AV_LOG_ERROR, "Receive EOF from UDP socket\n"); goto end; } - if (ff_rtc_ice_is_binding_response(whip->buf, ret)) { - whip->whip_last_consent_rx_time = av_gettime_relative(); - av_log(whip, AV_LOG_DEBUG, "Consent Freshness check received\n"); + if (ff_rtc_ice_is_binding_response(rtc->buf, ret)) { + rtc->rtc_last_consent_rx_time = av_gettime_relative(); + av_log(rtc, AV_LOG_DEBUG, "Consent Freshness check received\n"); } - if (ff_rtc_is_dtls_packet(whip->buf, ret)) { - if ((ret = ffurl_write(whip->dtls_uc, whip->buf, ret)) < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to handle DTLS message\n"); + if (ff_rtc_is_dtls_packet(rtc->buf, ret)) { + if ((ret = ffurl_write(rtc->dtls_uc, rtc->buf, ret)) < 0) { + av_log(rtc, AV_LOG_ERROR, "Failed to handle DTLS message\n"); goto end; } } - if (media_is_rtcp(whip->buf, ret)) { - uint8_t fmt = whip->buf[0] & 0x1f; - uint8_t pt = whip->buf[1]; + if (media_is_rtcp(rtc->buf, ret)) { + uint8_t fmt = rtc->buf[0] & 0x1f; + uint8_t pt = rtc->buf[1]; /** * Handle RTCP NACK packet * Refer to RFC 4585 6.2.1 @@ -631,17 +631,17 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt) } write_packet: now = av_gettime_relative(); - if (now - whip->whip_last_consent_rx_time > WHIP_ICE_CONSENT_EXPIRED_TIMER * WHIP_US_PER_MS) { - av_log(whip, AV_LOG_ERROR, + if (now - rtc->rtc_last_consent_rx_time > WHIP_ICE_CONSENT_EXPIRED_TIMER * RTC_US_PER_MS) { + av_log(rtc, AV_LOG_ERROR, "Consent Freshness expired after %.2fms (limited %dms), terminate session\n", - ELAPSED(now, whip->whip_last_consent_rx_time), WHIP_ICE_CONSENT_EXPIRED_TIMER); + ELAPSED(now, rtc->rtc_last_consent_rx_time), WHIP_ICE_CONSENT_EXPIRED_TIMER); ret = AVERROR(ETIMEDOUT); goto end; } - if (whip->h264_annexb_insert_sps_pps && st->codecpar->codec_id == AV_CODEC_ID_H264) { + if (rtc->h264_annexb_insert_sps_pps && st->codecpar->codec_id == AV_CODEC_ID_H264) { if ((ret = h264_annexb_insert_sps_pps(s, pkt)) < 0) { - av_log(whip, AV_LOG_ERROR, "Failed to insert SPS/PPS before IDR\n"); + av_log(rtc, AV_LOG_ERROR, "Failed to insert SPS/PPS before IDR\n"); goto end; } } @@ -649,18 +649,18 @@ write_packet: ret = ff_write_chained(rtp_ctx, 0, pkt, s, 0); if (ret < 0) { if (ret == AVERROR(EINVAL)) { - av_log(whip, AV_LOG_WARNING, "Ignore failed to write packet=%dB, ret=%d\n", pkt->size, ret); + av_log(rtc, AV_LOG_WARNING, "Ignore failed to write packet=%dB, ret=%d\n", pkt->size, ret); ret = 0; } else if (ret == AVERROR(EAGAIN)) { - av_log(whip, AV_LOG_ERROR, "UDP send blocked, please increase the buffer via -buffer_size\n"); + av_log(rtc, AV_LOG_ERROR, "UDP send blocked, please increase the buffer via -buffer_size\n"); } else - av_log(whip, AV_LOG_ERROR, "Failed to write packet, size=%d, ret=%d\n", pkt->size, ret); + av_log(rtc, AV_LOG_ERROR, "Failed to write packet, size=%d, ret=%d\n", pkt->size, ret); goto end; } end: if (ret < 0) - whip->state = WHIP_STATE_FAILED; + rtc->state = RTC_STATE_FAILED; return ret; } @@ -673,16 +673,16 @@ static int whip_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket { int ret = 1, extradata_isom = 0; uint8_t *b = pkt->data; - WHIPContext *whip = s->priv_data; + RTCContext *rtc = s->priv_data; if (st->codecpar->codec_id == AV_CODEC_ID_H264) { extradata_isom = st->codecpar->extradata_size > 0 && st->codecpar->extradata[0] == 1; if (pkt->size >= 5 && AV_RB32(b) != 0x0000001 && (AV_RB24(b) != 0x000001 || extradata_isom)) { ret = ff_stream_add_bitstream_filter(st, "h264_mp4toannexb", NULL); - av_log(whip, AV_LOG_VERBOSE, "Enable BSF h264_mp4toannexb, packet=[%x %x %x %x %x ...], extradata_isom=%d\n", + av_log(rtc, AV_LOG_VERBOSE, "Enable BSF h264_mp4toannexb, packet=[%x %x %x %x %x ...], extradata_isom=%d\n", b[0], b[1], b[2], b[3], b[4], extradata_isom); } else - whip->h264_annexb_insert_sps_pps = 1; + rtc->h264_annexb_insert_sps_pps = 1; } return ret; @@ -702,7 +702,7 @@ const FFOutputFormat ff_whip_muxer = { .p.video_codec = AV_CODEC_ID_H264, .p.flags = AVFMT_GLOBALHEADER | AVFMT_NOFILE | AVFMT_EXPERIMENTAL, .p.priv_class = &whip_muxer_class, - .priv_data_size = sizeof(WHIPContext), + .priv_data_size = sizeof(RTCContext), .init = whip_init, .write_packet = whip_write_packet, .deinit = whip_deinit, -- 2.51.0 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org