Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support
@ 2025-07-02 16:56 Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 01/18] avformat/Makefile: don't hardcode openssl for whip muxer Timo Rothenpieler
                   ` (17 more replies)
  0 siblings, 18 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

This was originally just me attempting to add DTLS support to SChannel,
so it can be used with the WHIP protocol. But on the way there, a lot of
random fixes and enhancements accumulated, resulting in this series.

The main new features are DTLS support for SChannel, which also happens
to enable support for listen-mode, which was previous unsupported for
normal TLS as well.

To enable that, udp.c had to be enhanced to allow reporting the address
a packet was received from.
In the process of that I realized that udp.c was clearly not made with
bidirectional communication in mind, so that had to be fixed as well (
The fifo buffer was used by both read and write without any checks,
meaning the two would interfere with each other).

The rest are misc fixes for issues in WHIP and the associated new tls
code I found.

Timo Rothenpieler (18):
  avformat/Makefile: don't hardcode openssl for whip muxer
  avformat/whip: use av_dict_set_int for int
  avformat/whip: don't leak options dict
  avformat/whip: remove redundant WHIP: prefix from all logging
  avformat/whip: fix format string for printing size_t
  avformat/tls: use non protocol specific error message
  avformat/tls: don't use http_proxy for udp sockets
  avformat/tls: move openssl specific init out of generic code
  avformat/udp: don't override 0 localport
  avformat/tls: fix udp init
  avformat/udp: make recv addr of each packet available
  avformat/udp: separate rx and tx fifo
  avformat/udp: add function to set remote address directly
  avformat/tls: remove unused fingerprint option
  avformat/tls: clean up new whip options
  avformat/tls: make passing an external socket universal
  avformat/tls_openssl: use existing context handle
  avformat/tls_schannel: add DTLS support

 configure                  |   6 +-
 libavformat/Makefile       |   2 +-
 libavformat/network.h      |   3 +
 libavformat/tls.c          |  23 +-
 libavformat/tls.h          |  20 +-
 libavformat/tls_openssl.c  |  33 +-
 libavformat/tls_schannel.c | 853 ++++++++++++++++++++++++++++++++++---
 libavformat/udp.c          | 100 +++--
 libavformat/whip.c         | 167 ++++----
 9 files changed, 998 insertions(+), 209 deletions(-)

-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 01/18] avformat/Makefile: don't hardcode openssl for whip muxer
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:00   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 02/18] avformat/whip: use av_dict_set_int for int Timo Rothenpieler
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 2e73f1325e..816eb9be4a 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -639,7 +639,7 @@ OBJS-$(CONFIG_WEBM_CHUNK_MUXER)          += webm_chunk.o
 OBJS-$(CONFIG_WEBP_MUXER)                += webpenc.o
 OBJS-$(CONFIG_WEBVTT_DEMUXER)            += webvttdec.o subtitles.o
 OBJS-$(CONFIG_WEBVTT_MUXER)              += webvttenc.o
-OBJS-$(CONFIG_WHIP_MUXER)                += whip.o avc.o http.o srtp.o tls_openssl.o
+OBJS-$(CONFIG_WHIP_MUXER)                += whip.o avc.o http.o srtp.o
 OBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood_aud.o
 OBJS-$(CONFIG_WSAUD_MUXER)               += westwood_audenc.o
 OBJS-$(CONFIG_WSD_DEMUXER)               += wsddec.o rawdec.o
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 02/18] avformat/whip: use av_dict_set_int for int
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 01/18] avformat/Makefile: don't hardcode openssl for whip muxer Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:01   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 03/18] avformat/whip: don't leak options dict Timo Rothenpieler
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/whip.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 5fdbd6949d..a6cdccc21c 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -1221,7 +1221,6 @@ static int ice_dtls_handshake(AVFormatContext *s)
     int64_t starttime = av_gettime(), now;
     WHIPContext *whip = s->priv_data;
     AVDictionary *opts = NULL;
-    char str[8];
     char buf[256], *cert_buf = NULL, *key_buf = NULL;
 
     if (whip->state < WHIP_STATE_UDP_CONNECTED || !whip->udp) {
@@ -1288,8 +1287,7 @@ next_packet:
                     whip->ice_ufrag_remote, whip->ice_ufrag_local, ret, ELAPSED(whip->whip_starttime, av_gettime()));
 
                 ff_url_join(buf, sizeof(buf), "dtls", NULL, whip->ice_host, whip->ice_port, NULL);
-                snprintf(str, sizeof(str), "%d", whip->pkt_size);
-                av_dict_set(&opts, "mtu", str, 0);
+                av_dict_set_int(&opts, "mtu", whip->pkt_size, 0);
                 if (whip->cert_file) {
                     av_dict_set(&opts, "cert_file", whip->cert_file, 0);
                 } else
@@ -1299,10 +1297,9 @@ next_packet:
                     av_dict_set(&opts, "key_file", whip->key_file, 0);
                 } else
                     av_dict_set(&opts, "key_buf", whip->key_buf, 0);
-
                 av_dict_set(&opts, "fingerprint", whip->dtls_fingerprint, 0);
-                av_dict_set(&opts, "use_external_udp", "1", 0);
-                av_dict_set(&opts, "listen", "1", 0);
+                av_dict_set_int(&opts, "use_external_udp", 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,
                     &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 03/18] avformat/whip: don't leak options dict
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 01/18] avformat/Makefile: don't hardcode openssl for whip muxer Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 02/18] avformat/whip: use av_dict_set_int for int Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:02   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 04/18] avformat/whip: remove redundant WHIP: prefix from all logging Timo Rothenpieler
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/whip.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index a6cdccc21c..a1cf8aff1b 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -1303,6 +1303,7 @@ next_packet:
                 /* If got the first binding response, start DTLS handshake. */
                 ret = ffurl_open_whitelist(&whip->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)
                     goto end;
                 dtls_initialize(s);
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 04/18] avformat/whip: remove redundant WHIP: prefix from all logging
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (2 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 03/18] avformat/whip: don't leak options dict Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:02   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t Timo Rothenpieler
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/whip.c | 150 ++++++++++++++++++++++-----------------------
 1 file changed, 75 insertions(+), 75 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index a1cf8aff1b..7cd3f48ba9 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -331,7 +331,7 @@ static av_cold int certificate_key_init(AVFormatContext *s)
                                         whip->key_buf, sizeof(whip->key_buf),
                                         whip->cert_buf, sizeof(whip->cert_buf),
                                         &whip->dtls_fingerprint)) < 0) {
-            av_log(s, AV_LOG_ERROR, "DTLS: Failed to read DTLS certificate from cert=%s, key=%s\n",
+            av_log(s, AV_LOG_ERROR, "Failed to read DTLS certificate from cert=%s, key=%s\n",
                 whip->cert_file, whip->key_file);
             return ret;
         }
@@ -340,7 +340,7 @@ static av_cold int certificate_key_init(AVFormatContext *s)
         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) {
-            av_log(s, AV_LOG_ERROR, "DTLS: Failed to generate DTLS private key and certificate\n");
+            av_log(s, AV_LOG_ERROR, "Failed to generate DTLS private key and certificate\n");
             return ret;
         }
     }
@@ -359,14 +359,14 @@ static int dtls_context_on_state(AVFormatContext *s, const char* type, const cha
 
     if (state == DTLS_STATE_CLOSED) {
         whip->dtls_closed = 1;
-        av_log(whip, AV_LOG_VERBOSE, "WHIP: DTLS session closed, type=%s, desc=%s, elapsed=%dms\n",
+        av_log(whip, AV_LOG_VERBOSE, "DTLS session closed, type=%s, desc=%s, elapsed=%dms\n",
             type ? type : "", desc ? desc : "", ELAPSED(whip->whip_starttime, av_gettime()));
         goto error;
     }
 
     if (state == DTLS_STATE_FAILED) {
         whip->state = WHIP_STATE_FAILED;
-        av_log(whip, AV_LOG_ERROR, "WHIP: DTLS session failed, type=%s, desc=%s\n",
+        av_log(whip, AV_LOG_ERROR, "DTLS session failed, type=%s, desc=%s\n",
             type ? type : "", desc ? desc : "");
         whip->dtls_ret = AVERROR(EIO);
         goto error;
@@ -375,7 +375,7 @@ static int dtls_context_on_state(AVFormatContext *s, const char* type, const cha
     if (state == DTLS_STATE_FINISHED && whip->state < WHIP_STATE_DTLS_FINISHED) {
         whip->state = WHIP_STATE_DTLS_FINISHED;
         whip->whip_dtls_time = av_gettime();
-        av_log(whip, AV_LOG_VERBOSE, "WHIP: DTLS handshake is done, elapsed=%dms\n",
+        av_log(whip, AV_LOG_VERBOSE, "DTLS handshake is done, elapsed=%dms\n",
             ELAPSED(whip->whip_starttime, av_gettime()));
         return ret;
     }
@@ -404,7 +404,7 @@ static av_cold int initialize(AVFormatContext *s)
 
     ret = certificate_key_init(s);
     if (ret < 0) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to init certificate and key\n");
+        av_log(whip, AV_LOG_ERROR, "Failed to init certificate and key\n");
         return ret;
     }
 
@@ -413,13 +413,13 @@ static av_cold int initialize(AVFormatContext *s)
     av_lfg_init(&whip->rnd, seed);
 
     if (whip->pkt_size < ideal_pkt_size)
-        av_log(whip, AV_LOG_WARNING, "WHIP: pkt_size=%d(<%d) is too small, may cause packet loss\n",
+        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 (whip->state < WHIP_STATE_INIT)
         whip->state = WHIP_STATE_INIT;
     whip->whip_init_time = av_gettime();
-    av_log(whip, AV_LOG_VERBOSE, "WHIP: Init state=%d, handshake_timeout=%dms, pkt_size=%d, seed=%d, elapsed=%dms\n",
+    av_log(whip, AV_LOG_VERBOSE, "Init state=%d, handshake_timeout=%dms, pkt_size=%d, seed=%d, elapsed=%dms\n",
         whip->state, whip->handshake_timeout, whip->pkt_size, seed, ELAPSED(whip->whip_starttime, av_gettime()));
 
     return 0;
@@ -452,7 +452,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, "WHIP: Unable to parse profile from empty extradata=%p, size=%d\n",
+        av_log(whip, AV_LOG_ERROR, "Unable to parse profile from empty extradata=%p, size=%d\n",
             par->extradata, par->extradata_size);
         return AVERROR(EINVAL);
     }
@@ -466,12 +466,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, "WHIP: Failed to decode SPS, state=%x, size=%d\n",
+                av_log(whip, AV_LOG_ERROR, "Failed to decode SPS, state=%x, size=%d\n",
                     state, (int)(r1 - r));
                 return ret;
             }
 
-            av_log(whip, AV_LOG_VERBOSE, "WHIP: Parse profile=%d, level=%d from SPS\n",
+            av_log(whip, 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;
@@ -515,62 +515,62 @@ static int parse_codec(AVFormatContext *s)
         switch (par->codec_type) {
         case AVMEDIA_TYPE_VIDEO:
             if (whip->video_par) {
-                av_log(whip, AV_LOG_ERROR, "WHIP: Only one video stream is supported by RTC\n");
+                av_log(whip, AV_LOG_ERROR, "Only one video stream is supported by RTC\n");
                 return AVERROR(EINVAL);
             }
             whip->video_par = par;
 
             if (par->codec_id != AV_CODEC_ID_H264) {
-                av_log(whip, AV_LOG_ERROR, "WHIP: Unsupported video codec %s by RTC, choose h264\n",
+                av_log(whip, 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, "WHIP: Unsupported B frames by RTC\n");
+                av_log(whip, 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, "WHIP: Failed to parse SPS/PPS from extradata\n");
+                av_log(whip, 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, "WHIP: No profile found in extradata, consider baseline\n");
+                av_log(whip, 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, "WHIP: No level found in extradata, consider 3.1\n");
+                av_log(whip, 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, "WHIP: Only one audio stream is supported by RTC\n");
+                av_log(whip, AV_LOG_ERROR, "Only one audio stream is supported by RTC\n");
                 return AVERROR(EINVAL);
             }
             whip->audio_par = par;
 
             if (par->codec_id != AV_CODEC_ID_OPUS) {
-                av_log(whip, AV_LOG_ERROR, "WHIP: Unsupported audio codec %s by RTC, choose opus\n",
+                av_log(whip, 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, "WHIP: Unsupported audio channels %d by RTC, choose stereo\n",
+                av_log(whip, 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, "WHIP: Unsupported audio sample rate %d by RTC, choose 48000\n", par->sample_rate);
+                av_log(whip, 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, "WHIP: Codec type '%s' for stream %d is not supported by RTC\n",
+            av_log(whip, 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;
         }
@@ -598,7 +598,7 @@ static int generate_sdp_offer(AVFormatContext *s)
     av_bprint_init(&bp, 1, MAX_SDP_SIZE);
 
     if (whip->sdp_offer) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: SDP offer is already set\n");
+        av_log(whip, AV_LOG_ERROR, "SDP offer is already set\n");
         ret = AVERROR(EINVAL);
         goto end;
     }
@@ -696,7 +696,7 @@ static int generate_sdp_offer(AVFormatContext *s)
     }
 
     if (!av_bprint_is_complete(&bp)) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Offer exceed max %d, %s\n", MAX_SDP_SIZE, bp.str);
+        av_log(whip, AV_LOG_ERROR, "Offer exceed max %d, %s\n", MAX_SDP_SIZE, bp.str);
         ret = AVERROR(EIO);
         goto end;
     }
@@ -710,7 +710,7 @@ static int generate_sdp_offer(AVFormatContext *s)
     if (whip->state < WHIP_STATE_OFFER)
         whip->state = WHIP_STATE_OFFER;
     whip->whip_offer_time = av_gettime();
-    av_log(whip, AV_LOG_VERBOSE, "WHIP: Generated state=%d, offer: %s\n", whip->state, whip->sdp_offer);
+    av_log(whip, AV_LOG_VERBOSE, "Generated state=%d, offer: %s\n", whip->state, whip->sdp_offer);
 
 end:
     av_bprint_finalize(&bp, NULL);
@@ -738,14 +738,14 @@ 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, "WHIP: Protocol %s is not supported by RTC, choose http, url is %s\n",
+        av_log(whip, 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, "WHIP: No offer to exchange\n");
+        av_log(whip, AV_LOG_ERROR, "No offer to exchange\n");
         ret = AVERROR(EINVAL);
         goto end;
     }
@@ -754,7 +754,7 @@ static int exchange_sdp(AVFormatContext *s)
     if (whip->authorization)
         ret += snprintf(buf + ret, sizeof(buf) - ret, "Authorization: Bearer %s\r\n", whip->authorization);
     if (ret <= 0 || ret >= sizeof(buf)) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to generate headers, size=%d, %s\n", ret, buf);
+        av_log(whip, AV_LOG_ERROR, "Failed to generate headers, size=%d, %s\n", ret, buf);
         ret = AVERROR(EINVAL);
         goto end;
     }
@@ -773,7 +773,7 @@ static int exchange_sdp(AVFormatContext *s)
     ret = ffurl_open_whitelist(&whip_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, "WHIP: Failed to request url=%s, offer: %s\n", s->url, whip->sdp_offer);
+        av_log(whip, AV_LOG_ERROR, "Failed to request url=%s, offer: %s\n", s->url, whip->sdp_offer);
         goto end;
     }
 
@@ -793,21 +793,21 @@ static int exchange_sdp(AVFormatContext *s)
             break;
         }
         if (ret <= 0) {
-            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to read response from url=%s, offer is %s, answer is %s\n",
+            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);
             goto end;
         }
 
         av_bprintf(&bp, "%.*s", ret, buf);
         if (!av_bprint_is_complete(&bp)) {
-            av_log(whip, AV_LOG_ERROR, "WHIP: Answer exceed max size %d, %.*s, %s\n", MAX_SDP_SIZE, ret, buf, bp.str);
+            av_log(whip, 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, "WHIP: Invalid answer: %s\n", bp.str);
+        av_log(whip, AV_LOG_ERROR, "Invalid answer: %s\n", bp.str);
         ret = AVERROR(EINVAL);
         goto end;
     }
@@ -820,7 +820,7 @@ static int exchange_sdp(AVFormatContext *s)
 
     if (whip->state < WHIP_STATE_ANSWER)
         whip->state = WHIP_STATE_ANSWER;
-    av_log(whip, AV_LOG_VERBOSE, "WHIP: Got state=%d, answer: %s\n", whip->state, whip->sdp_answer);
+    av_log(whip, AV_LOG_VERBOSE, "Got state=%d, answer: %s\n", whip->state, whip->sdp_answer);
 
 end:
     ffurl_closep(&whip_uc);
@@ -851,7 +851,7 @@ static int parse_answer(AVFormatContext *s)
     WHIPContext *whip = s->priv_data;
 
     if (!whip->sdp_answer || !strlen(whip->sdp_answer)) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: No answer to parse\n");
+        av_log(whip, AV_LOG_ERROR, "No answer to parse\n");
         ret = AVERROR(EINVAL);
         goto end;
     }
@@ -881,14 +881,14 @@ static int parse_answer(AVFormatContext *s)
                 int priority, port;
                 ret = sscanf(ptr, "%16s %d %128s %d typ host", protocol, &priority, host, &port);
                 if (ret != 4) {
-                    av_log(whip, AV_LOG_ERROR, "WHIP: Failed %d to parse line %d %s from %s\n",
+                    av_log(whip, AV_LOG_ERROR, "Failed %d to parse line %d %s from %s\n",
                         ret, i, line, whip->sdp_answer);
                     ret = AVERROR(EIO);
                     goto end;
                 }
 
                 if (av_strcasecmp(protocol, "udp")) {
-                    av_log(whip, AV_LOG_ERROR, "WHIP: Protocol %s is not supported by RTC, choose udp, line %d %s of %s\n",
+                    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);
                     ret = AVERROR(EIO);
                     goto end;
@@ -906,19 +906,19 @@ static int parse_answer(AVFormatContext *s)
     }
 
     if (!whip->ice_pwd_remote || !strlen(whip->ice_pwd_remote)) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: No remote ice pwd parsed from %s\n", whip->sdp_answer);
+        av_log(whip, AV_LOG_ERROR, "No remote ice pwd parsed from %s\n", whip->sdp_answer);
         ret = AVERROR(EINVAL);
         goto end;
     }
 
     if (!whip->ice_ufrag_remote || !strlen(whip->ice_ufrag_remote)) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: No remote ice ufrag parsed from %s\n", whip->sdp_answer);
+        av_log(whip, AV_LOG_ERROR, "No remote ice ufrag parsed from %s\n", whip->sdp_answer);
         ret = AVERROR(EINVAL);
         goto end;
     }
 
     if (!whip->ice_protocol || !whip->ice_host || !whip->ice_port) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: No ice candidate parsed from %s\n", whip->sdp_answer);
+        av_log(whip, AV_LOG_ERROR, "No ice candidate parsed from %s\n", whip->sdp_answer);
         ret = AVERROR(EINVAL);
         goto end;
     }
@@ -926,7 +926,7 @@ static int parse_answer(AVFormatContext *s)
     if (whip->state < WHIP_STATE_NEGOTIATED)
         whip->state = WHIP_STATE_NEGOTIATED;
     whip->whip_answer_time = av_gettime();
-    av_log(whip, AV_LOG_VERBOSE, "WHIP: SDP state=%d, offer=%luB, answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\n",
+    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%luB, answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\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()));
 
@@ -977,7 +977,7 @@ static int ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in
     /* 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);
     if (ret <= 0 || ret >= sizeof(username)) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to build username %s:%s, max=%lu, ret=%d\n",
+        av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s, max=%lu, ret=%d\n",
             whip->ice_ufrag_remote, whip->ice_ufrag_local, sizeof(username), ret);
         ret = AVERROR(EIO);
         goto end;
@@ -1046,7 +1046,7 @@ static int ice_create_response(AVFormatContext *s, char *tid, int tid_size, uint
     WHIPContext *whip = s->priv_data;
 
     if (tid_size != 12) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Invalid transaction ID size. Expected 12, got %d\n", tid_size);
+        av_log(whip, AV_LOG_ERROR, "Invalid transaction ID size. Expected 12, got %d\n", tid_size);
         return AVERROR(EINVAL);
     }
 
@@ -1149,7 +1149,7 @@ static int ice_handle_binding_request(AVFormatContext *s, char *buf, int buf_siz
         return ret;
 
     if (buf_size < ICE_STUN_HEADER_SIZE) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Invalid STUN message, expected at least %d, got %d\n",
+        av_log(whip, AV_LOG_ERROR, "Invalid STUN message, expected at least %d, got %d\n",
             ICE_STUN_HEADER_SIZE, buf_size);
         return AVERROR(EINVAL);
     }
@@ -1160,13 +1160,13 @@ static int ice_handle_binding_request(AVFormatContext *s, char *buf, int buf_siz
     /* Build the STUN binding response. */
     ret = ice_create_response(s, tid, sizeof(tid), whip->buf, sizeof(whip->buf), &size);
     if (ret < 0) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to create STUN binding response, size=%d\n", size);
+        av_log(whip, AV_LOG_ERROR, "Failed to create STUN binding response, size=%d\n", size);
         return ret;
     }
 
     ret = ffurl_write(whip->udp, whip->buf, size);
     if (ret < 0) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to send STUN binding response, size=%d\n", size);
+        av_log(whip, AV_LOG_ERROR, "Failed to send STUN binding response, size=%d\n", size);
         return ret;
     }
 
@@ -1196,7 +1196,7 @@ static int udp_connect(AVFormatContext *s)
     ret = ffurl_open_whitelist(&whip->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, "WHIP: Failed to connect udp://%s:%d\n", whip->ice_host, whip->ice_port);
+        av_log(whip, AV_LOG_ERROR, "Failed to connect udp://%s:%d\n", whip->ice_host, whip->ice_port);
         goto end;
     }
 
@@ -1207,7 +1207,7 @@ static int udp_connect(AVFormatContext *s)
     if (whip->state < WHIP_STATE_UDP_CONNECTED)
         whip->state = WHIP_STATE_UDP_CONNECTED;
     whip->whip_udp_time = av_gettime();
-    av_log(whip, AV_LOG_VERBOSE, "WHIP: UDP state=%d, elapsed=%dms, connected to udp://%s:%d\n",
+    av_log(whip, AV_LOG_VERBOSE, "UDP state=%d, elapsed=%dms, connected to udp://%s:%d\n",
         whip->state, ELAPSED(whip->whip_starttime, av_gettime()), whip->ice_host, whip->ice_port);
 
 end:
@@ -1224,7 +1224,7 @@ static int ice_dtls_handshake(AVFormatContext *s)
     char buf[256], *cert_buf = NULL, *key_buf = NULL;
 
     if (whip->state < WHIP_STATE_UDP_CONNECTED || !whip->udp) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: UDP not connected, state=%d, udp=%p\n", whip->state, whip->udp);
+        av_log(whip, AV_LOG_ERROR, "UDP not connected, state=%d, udp=%p\n", whip->state, whip->udp);
         return AVERROR(EINVAL);
     }
 
@@ -1233,13 +1233,13 @@ static int ice_dtls_handshake(AVFormatContext *s)
             /* Build the STUN binding request. */
             ret = ice_create_request(s, whip->buf, sizeof(whip->buf), &size);
             if (ret < 0) {
-                av_log(whip, AV_LOG_ERROR, "WHIP: Failed to create STUN binding request, size=%d\n", size);
+                av_log(whip, AV_LOG_ERROR, "Failed to create STUN binding request, size=%d\n", size);
                 goto end;
             }
 
             ret = ffurl_write(whip->udp, whip->buf, size);
             if (ret < 0) {
-                av_log(whip, AV_LOG_ERROR, "WHIP: Failed to send STUN binding request, size=%d\n", size);
+                av_log(whip, AV_LOG_ERROR, "Failed to send STUN binding request, size=%d\n", size);
                 goto end;
             }
 
@@ -1254,7 +1254,7 @@ next_packet:
 
         now = av_gettime();
         if (now - starttime >= whip->handshake_timeout * 1000) {
-            av_log(whip, AV_LOG_ERROR, "WHIP: DTLS handshake timeout=%dms, cost=%dms, elapsed=%dms, state=%d\n",
+            av_log(whip, AV_LOG_ERROR, "DTLS handshake timeout=%dms, cost=%dms, elapsed=%dms, state=%d\n",
                 whip->handshake_timeout, ELAPSED(starttime, now), ELAPSED(whip->whip_starttime, now), whip->state);
             ret = AVERROR(ETIMEDOUT);
             goto end;
@@ -1269,7 +1269,7 @@ next_packet:
                 av_usleep(5 * 1000);
                 continue;
             }
-            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to read message\n");
+            av_log(whip, AV_LOG_ERROR, "Failed to read message\n");
             goto end;
         }
 
@@ -1282,7 +1282,7 @@ next_packet:
             if (whip->state < WHIP_STATE_ICE_CONNECTED) {
                 whip->state = WHIP_STATE_ICE_CONNECTED;
                 whip->whip_ice_time = av_gettime();
-                av_log(whip, AV_LOG_VERBOSE, "WHIP: ICE STUN ok, state=%d, url=udp://%s:%d, location=%s, username=%s:%s, res=%dB, elapsed=%dms\n",
+                av_log(whip, AV_LOG_VERBOSE, "ICE STUN ok, state=%d, url=udp://%s:%d, location=%s, username=%s:%s, res=%dB, elapsed=%dms\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()));
 
@@ -1381,20 +1381,20 @@ 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, "WHIP: Failed to encode send key\n");
+        av_log(whip, 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);
     if (ret < 0) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to set crypto for audio send\n");
+        av_log(whip, AV_LOG_ERROR, "Failed to set crypto for audio send\n");
         goto end;
     }
 
     ret = ff_srtp_set_crypto(&whip->srtp_video_send, suite, buf);
     if (ret < 0) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to set crypto for video send\n");
+        av_log(whip, AV_LOG_ERROR, "Failed to set crypto for video send\n");
         goto end;
     }
 
@@ -1406,21 +1406,21 @@ static int setup_srtp(AVFormatContext *s)
 
     /* Setup SRTP context for incoming packets */
     if (!av_base64_encode(buf, sizeof(buf), recv_key, sizeof(recv_key))) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to encode recv key\n");
+        av_log(whip, AV_LOG_ERROR, "Failed to encode recv key\n");
         ret = AVERROR(EIO);
         goto end;
     }
 
     ret = ff_srtp_set_crypto(&whip->srtp_recv, suite, buf);
     if (ret < 0) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to set crypto for recv\n");
+        av_log(whip, 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();
-    av_log(whip, AV_LOG_VERBOSE, "WHIP: SRTP setup done, state=%d, suite=%s, key=%luB, elapsed=%dms\n",
+    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%luB, elapsed=%dms\n",
         whip->state, suite, sizeof(send_key), ELAPSED(whip->whip_starttime, av_gettime()));
 
 end:
@@ -1459,13 +1459,13 @@ static int on_rtp_write_packet(void *opaque, const uint8_t *buf, int buf_size)
     /* Encrypt by SRTP and send out. */
     cipher_size = ff_srtp_encrypt(srtp, buf, buf_size, whip->buf, sizeof(whip->buf));
     if (cipher_size <= 0 || cipher_size < buf_size) {
-        av_log(whip, AV_LOG_WARNING, "WHIP: Failed to encrypt packet=%dB, cipher=%dB\n", buf_size, cipher_size);
+        av_log(whip, 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);
     if (ret < 0) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to write packet=%dB, ret=%d\n", cipher_size, ret);
+        av_log(whip, AV_LOG_ERROR, "Failed to write packet=%dB, ret=%d\n", cipher_size, ret);
         return ret;
     }
 
@@ -1494,7 +1494,7 @@ static int create_rtp_muxer(AVFormatContext *s)
 
     const AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
     if (!rtp_format) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to guess rtp muxer\n");
+        av_log(whip, AV_LOG_ERROR, "Failed to guess rtp muxer\n");
         ret = AVERROR(ENOSYS);
         goto end;
     }
@@ -1562,7 +1562,7 @@ static int create_rtp_muxer(AVFormatContext *s)
 
         ret = avformat_write_header(rtp_ctx, &opts);
         if (ret < 0) {
-            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to write rtp header\n");
+            av_log(whip, AV_LOG_ERROR, "Failed to write rtp header\n");
             goto end;
         }
 
@@ -1574,7 +1574,7 @@ static int create_rtp_muxer(AVFormatContext *s)
 
     if (whip->state < WHIP_STATE_READY)
         whip->state = WHIP_STATE_READY;
-    av_log(whip, AV_LOG_INFO, "WHIP: Muxer state=%d, buffer_size=%d, max_packet_size=%d, "
+    av_log(whip, AV_LOG_INFO, "Muxer state=%d, buffer_size=%d, max_packet_size=%d, "
                            "elapsed=%dms(init:%d,offer:%d,answer:%d,udp:%d,ice:%d,dtls:%d,srtp:%d)\n",
         whip->state, buffer_size, max_packet_size, ELAPSED(whip->whip_starttime, av_gettime()),
         ELAPSED(whip->whip_starttime,   whip->whip_init_time),
@@ -1616,7 +1616,7 @@ static int dispose_session(AVFormatContext *s)
     if (whip->authorization)
         ret += snprintf(buf + ret, sizeof(buf) - ret, "Authorization: Bearer %s\r\n", whip->authorization);
     if (ret <= 0 || ret >= sizeof(buf)) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to generate headers, size=%d, %s\n", ret, buf);
+        av_log(whip, AV_LOG_ERROR, "Failed to generate headers, size=%d, %s\n", ret, buf);
         ret = AVERROR(EINVAL);
         goto end;
     }
@@ -1627,7 +1627,7 @@ static int dispose_session(AVFormatContext *s)
     ret = ffurl_open_whitelist(&whip_uc, whip->whip_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, "WHIP: Failed to DELETE url=%s\n", whip->whip_resource_url);
+        av_log(whip, AV_LOG_ERROR, "Failed to DELETE url=%s\n", whip->whip_resource_url);
         goto end;
     }
 
@@ -1638,12 +1638,12 @@ static int dispose_session(AVFormatContext *s)
             break;
         }
         if (ret < 0) {
-            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to read response from DELETE url=%s\n", whip->whip_resource_url);
+            av_log(whip, AV_LOG_ERROR, "Failed to read response from DELETE url=%s\n", whip->whip_resource_url);
             goto end;
         }
     }
 
-    av_log(whip, AV_LOG_INFO, "WHIP: Dispose resource %s ok\n", whip->whip_resource_url);
+    av_log(whip, AV_LOG_INFO, "Dispose resource %s ok\n", whip->whip_resource_url);
 
 end:
     ffurl_closep(&whip_uc);
@@ -1789,18 +1789,18 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt)
     if (ret > 0) {
         if (is_dtls_packet(whip->buf, ret)) {
             if ((ret = ffurl_write(whip->dtls_uc, whip->buf, ret)) < 0) {
-                av_log(whip, AV_LOG_ERROR, "WHIP: Failed to handle DTLS message\n");
+                av_log(whip, AV_LOG_ERROR, "Failed to handle DTLS message\n");
                 goto end;
             }
         }
     } else if (ret != AVERROR(EAGAIN)) {
-        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to read from UDP socket\n");
+        av_log(whip, AV_LOG_ERROR, "Failed to read from UDP socket\n");
         goto end;
     }
 
     if (whip->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, "WHIP: Failed to insert SPS/PPS before IDR\n");
+            av_log(whip, AV_LOG_ERROR, "Failed to insert SPS/PPS before IDR\n");
             goto end;
         }
     }
@@ -1808,10 +1808,10 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt)
     ret = ff_write_chained(rtp_ctx, 0, pkt, s, 0);
     if (ret < 0) {
         if (ret == AVERROR(EINVAL)) {
-            av_log(whip, AV_LOG_WARNING, "WHIP: Ignore failed to write packet=%dB, ret=%d\n", pkt->size, ret);
+            av_log(whip, AV_LOG_WARNING, "Ignore failed to write packet=%dB, ret=%d\n", pkt->size, ret);
             ret = 0;
         } else
-            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to write packet, size=%d\n", pkt->size);
+            av_log(whip, AV_LOG_ERROR, "Failed to write packet, size=%d\n", pkt->size);
         goto end;
     }
 
@@ -1832,7 +1832,7 @@ static av_cold void whip_deinit(AVFormatContext *s)
 
     ret = dispose_session(s);
     if (ret < 0)
-        av_log(whip, AV_LOG_WARNING, "WHIP: Failed to dispose resource, ret=%d\n", ret);
+        av_log(whip, 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;
@@ -1879,7 +1879,7 @@ static int whip_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket
         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, "WHIP: Enable BSF h264_mp4toannexb, packet=[%x %x %x %x %x ...], extradata_isom=%d\n",
+            av_log(whip, 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;
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (3 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 04/18] avformat/whip: remove redundant WHIP: prefix from all logging Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:03   ` Steven Liu
  2025-07-03 17:16   ` Andreas Rheinhardt
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 06/18] avformat/tls: use non protocol specific error message Timo Rothenpieler
                   ` (12 subsequent siblings)
  17 siblings, 2 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/whip.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 7cd3f48ba9..71c667cd31 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -926,7 +926,7 @@ static int parse_answer(AVFormatContext *s)
     if (whip->state < WHIP_STATE_NEGOTIATED)
         whip->state = WHIP_STATE_NEGOTIATED;
     whip->whip_answer_time = av_gettime();
-    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%luB, answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\n",
+    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%zuB, answer=%zuB, ufrag=%s, pwd=%zuB, transport=%s://%s:%d, elapsed=%dms\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()));
 
@@ -977,7 +977,7 @@ static int ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in
     /* 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);
     if (ret <= 0 || ret >= sizeof(username)) {
-        av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s, max=%lu, ret=%d\n",
+        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);
         ret = AVERROR(EIO);
         goto end;
@@ -1420,7 +1420,7 @@ static int setup_srtp(AVFormatContext *s)
     if (whip->state < WHIP_STATE_SRTP_FINISHED)
         whip->state = WHIP_STATE_SRTP_FINISHED;
     whip->whip_srtp_time = av_gettime();
-    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%luB, elapsed=%dms\n",
+    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%zuB, elapsed=%dms\n",
         whip->state, suite, sizeof(send_key), ELAPSED(whip->whip_starttime, av_gettime()));
 
 end:
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 06/18] avformat/tls: use non protocol specific error message
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (4 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:03   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 07/18] avformat/tls: don't use http_proxy for udp sockets Timo Rothenpieler
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/tls.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/tls.c b/libavformat/tls.c
index da53835200..018b24cd48 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -137,7 +137,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
                                parent->protocol_whitelist, parent->protocol_blacklist, parent);
     if (c->is_dtls) {
         if (ret < 0) {
-            av_log(c, AV_LOG_ERROR, "WHIP: Failed to connect udp://%s:%d\n", c->underlying_host, port);
+            av_log(c, AV_LOG_ERROR, "Failed to open udp://%s:%d\n", c->underlying_host, port);
             return ret;
         }
         /* Make the socket non-blocking, set to READ and WRITE mode after connected */
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 07/18] avformat/tls: don't use http_proxy for udp sockets
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (5 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 06/18] avformat/tls: use non protocol specific error message Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:04   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code Timo Rothenpieler
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/tls.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/tls.c b/libavformat/tls.c
index 018b24cd48..5ec4cca58a 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -114,7 +114,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
                 proxy_path && av_strstart(proxy_path, "http://", NULL);
     freeenv_utf8(env_no_proxy);
 
-    if (use_proxy) {
+    if (!c->is_dtls && use_proxy) {
         char proxy_host[200], proxy_auth[200], dest[200];
         int proxy_port;
         av_url_split(NULL, 0, proxy_auth, sizeof(proxy_auth),
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (6 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 07/18] avformat/tls: don't use http_proxy for udp sockets Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03  1:07   ` Jack Lau
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 09/18] avformat/udp: don't override 0 localport Timo Rothenpieler
                   ` (9 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/tls.c         | 9 ---------
 libavformat/tls_openssl.c | 3 +++
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/libavformat/tls.c b/libavformat/tls.c
index 5ec4cca58a..f888970969 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -135,15 +135,6 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
     ret = ffurl_open_whitelist(c->is_dtls ? &c->udp : &c->tcp, buf, AVIO_FLAG_READ_WRITE,
                                &parent->interrupt_callback, options,
                                parent->protocol_whitelist, parent->protocol_blacklist, parent);
-    if (c->is_dtls) {
-        if (ret < 0) {
-            av_log(c, AV_LOG_ERROR, "Failed to open udp://%s:%d\n", c->underlying_host, port);
-            return ret;
-        }
-        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
-        ff_socket_nonblock(ffurl_get_file_handle(c->udp), 1);
-        c->udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
-    }
     return ret;
 }
 
diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2a3905891d..d83fe602d5 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -985,6 +985,9 @@ static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **
             av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
             return ret;
         }
+        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
+        ff_socket_nonblock(ffurl_get_file_handle(p->tls_shared.udp), 1);
+        p->tls_shared.udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
     }
 
     /* Setup DTLS as passive, which is server role. */
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 09/18] avformat/udp: don't override 0 localport
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (7 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:05   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 10/18] avformat/tls: fix udp init Timo Rothenpieler
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/udp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/udp.c b/libavformat/udp.c
index c1ebdd1222..30f075de8e 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -780,7 +780,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
             goto fail;
     }
 
-    if ((s->is_multicast || s->local_port <= 0) && (h->flags & AVIO_FLAG_READ))
+    if ((s->is_multicast || s->local_port < 0) && (h->flags & AVIO_FLAG_READ))
         s->local_port = port;
 
     udp_fd = udp_socket_create(h, &my_addr, &len, s->localaddr);
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 10/18] avformat/tls: fix udp init
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (8 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 09/18] avformat/udp: don't override 0 localport Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:06   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 11/18] avformat/udp: make recv addr of each packet available Timo Rothenpieler
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/tls.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/libavformat/tls.c b/libavformat/tls.c
index f888970969..bd9c05e6dc 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -81,7 +81,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
     if (ret < 0)
         return ret;
 
-    if (c->listen)
+    if (c->listen && !c->is_dtls)
         snprintf(opts, sizeof(opts), "?listen=1");
 
     av_url_split(NULL, 0, NULL, 0, c->underlying_host, sizeof(c->underlying_host), &port, NULL, 0, uri);
@@ -95,7 +95,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
             c->listen = 1;
     }
 
-    ff_url_join(buf, sizeof(buf), c->is_dtls ? "udp" : "tcp", NULL, c->underlying_host, port, "%s", p);
+    ff_url_join(buf, sizeof(buf), c->is_dtls ? "udp" : "tcp", NULL, (c->is_dtls && c->listen) ? "" : c->underlying_host, port, "%s", p);
 
     hints.ai_flags = AI_NUMERICHOST;
     if (!getaddrinfo(c->underlying_host, NULL, &hints, &ai)) {
@@ -127,7 +127,13 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
 
     freeenv_utf8(env_http_proxy);
     if (c->is_dtls) {
-        av_dict_set_int(options, "connect", 1, 0);
+        if (c->listen) {
+            av_dict_set_int(options, "localport", port, 0);
+            av_dict_set(options, "localaddr", c->underlying_host, 0);
+        } else {
+            av_dict_set_int(options, "localport", 0, 0);
+            av_dict_set_int(options, "connect", 1, 0);
+        }
         av_dict_set_int(options, "fifo_size", 0, 0);
         /* Set the max packet size to the buffer size. */
         av_dict_set_int(options, "pkt_size", c->mtu, 0);
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 11/18] avformat/udp: make recv addr of each packet available
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (9 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 10/18] avformat/tls: fix udp init Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 12/18] avformat/udp: separate rx and tx fifo Timo Rothenpieler
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/network.h |  2 ++
 libavformat/udp.c     | 25 +++++++++++++++++--------
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/libavformat/network.h b/libavformat/network.h
index ca214087fc..48bb75a758 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -338,4 +338,6 @@ int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
                         int parallel, URLContext *h, int *fd,
                         int (*customize_fd)(void *, int, int), void *customize_ctx);
 
+void ff_udp_get_last_recv_addr(URLContext *h, struct sockaddr_storage *addr);
+
 #endif /* AVFORMAT_NETWORK_H */
diff --git a/libavformat/udp.c b/libavformat/udp.c
index 30f075de8e..7d64ff07ed 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -107,7 +107,7 @@ typedef struct UDPContext {
     pthread_cond_t cond;
     int thread_started;
 #endif
-    uint8_t tmp[UDP_MAX_PKT_SIZE+4];
+    uint8_t tmp[UDP_MAX_PKT_SIZE + 4 + sizeof(struct sockaddr_storage)];
     int remaining_in_dg;
     char *localaddr;
     int timeout;
@@ -115,6 +115,7 @@ typedef struct UDPContext {
     char *sources;
     char *block;
     IPSourceFilters filters;
+    struct sockaddr_storage last_recv_addr;
 } UDPContext;
 
 #define OFFSET(x) offsetof(UDPContext, x)
@@ -467,6 +468,12 @@ int ff_udp_get_local_port(URLContext *h)
     return s->local_port;
 }
 
+void ff_udp_get_last_recv_addr(URLContext *h, struct sockaddr_storage *addr)
+{
+    UDPContext *s = h->priv_data;
+    *addr = s->last_recv_addr;
+}
+
 /**
  * Return the udp file handle for select() usage to wait for several RTP
  * streams at the same time.
@@ -498,13 +505,14 @@ static void *circular_buffer_task_rx( void *_URLContext)
         int len;
         struct sockaddr_storage addr;
         socklen_t addr_len = sizeof(addr);
+        const int header_sz = 4 + addr_len;
 
         pthread_mutex_unlock(&s->mutex);
         /* Blocking operations are always cancellation points;
            see "General Information" / "Thread Cancelation Overview"
            in Single Unix. */
         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate);
-        len = recvfrom(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0, (struct sockaddr *)&addr, &addr_len);
+        len = recvfrom(s->udp_fd, s->tmp + header_sz, sizeof(s->tmp) - header_sz, 0, (struct sockaddr *)&addr, &addr_len);
         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
         pthread_mutex_lock(&s->mutex);
         if (len < 0) {
@@ -517,8 +525,9 @@ static void *circular_buffer_task_rx( void *_URLContext)
         if (ff_ip_check_source_lists(&addr, &s->filters))
             continue;
         AV_WL32(s->tmp, len);
+        memcpy(s->tmp + 4, &addr, sizeof(addr));
 
-        if (av_fifo_can_write(s->fifo) < len + 4) {
+        if (av_fifo_can_write(s->fifo) < len + header_sz) {
             /* No Space left */
             if (s->overrun_nonfatal) {
                 av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
@@ -532,7 +541,7 @@ static void *circular_buffer_task_rx( void *_URLContext)
                 goto end;
             }
         }
-        av_fifo_write(s->fifo, s->tmp, len + 4);
+        av_fifo_write(s->fifo, s->tmp, len + header_sz);
         pthread_cond_signal(&s->cond);
     }
 
@@ -991,8 +1000,7 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
 {
     UDPContext *s = h->priv_data;
     int ret;
-    struct sockaddr_storage addr;
-    socklen_t addr_len = sizeof(addr);
+    socklen_t addr_len = sizeof(s->last_recv_addr);
 #if HAVE_PTHREAD_CANCEL
     int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
 
@@ -1004,6 +1012,7 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
                 uint8_t tmp[4];
 
                 av_fifo_read(s->fifo, tmp, 4);
+                av_fifo_read(s->fifo, &s->last_recv_addr, sizeof(s->last_recv_addr));
                 avail = AV_RL32(tmp);
                 if(avail > size){
                     av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
@@ -1043,10 +1052,10 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
         if (ret < 0)
             return ret;
     }
-    ret = recvfrom(s->udp_fd, buf, size, 0, (struct sockaddr *)&addr, &addr_len);
+    ret = recvfrom(s->udp_fd, buf, size, 0, (struct sockaddr *)&s->last_recv_addr, &addr_len);
     if (ret < 0)
         return ff_neterrno();
-    if (ff_ip_check_source_lists(&addr, &s->filters))
+    if (ff_ip_check_source_lists(&s->last_recv_addr, &s->filters))
         return AVERROR(EINTR);
     return ret;
 }
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 12/18] avformat/udp: separate rx and tx fifo
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (10 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 11/18] avformat/udp: make recv addr of each packet available Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-03 14:07   ` Steven Liu
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 13/18] avformat/udp: add function to set remote address directly Timo Rothenpieler
                   ` (5 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/udp.c | 49 +++++++++++++++++++++++++++--------------------
 1 file changed, 28 insertions(+), 21 deletions(-)

diff --git a/libavformat/udp.c b/libavformat/udp.c
index 7d64ff07ed..e02eff0f33 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -96,7 +96,8 @@ typedef struct UDPContext {
 
     /* Circular Buffer variables for use in UDP receive code */
     int circular_buffer_size;
-    AVFifo *fifo;
+    AVFifo *rx_fifo;
+    AVFifo *tx_fifo;
     int circular_buffer_error;
     int64_t bitrate; /* number of bits to send per second */
     int64_t burst_bits;
@@ -527,7 +528,7 @@ static void *circular_buffer_task_rx( void *_URLContext)
         AV_WL32(s->tmp, len);
         memcpy(s->tmp + 4, &addr, sizeof(addr));
 
-        if (av_fifo_can_write(s->fifo) < len + header_sz) {
+        if (av_fifo_can_write(s->rx_fifo) < len + header_sz) {
             /* No Space left */
             if (s->overrun_nonfatal) {
                 av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
@@ -541,7 +542,7 @@ static void *circular_buffer_task_rx( void *_URLContext)
                 goto end;
             }
         }
-        av_fifo_write(s->fifo, s->tmp, len + header_sz);
+        av_fifo_write(s->rx_fifo, s->tmp, len + header_sz);
         pthread_cond_signal(&s->cond);
     }
 
@@ -577,22 +578,22 @@ static void *circular_buffer_task_tx( void *_URLContext)
         uint8_t tmp[4];
         int64_t timestamp;
 
-        len = av_fifo_can_read(s->fifo);
+        len = av_fifo_can_read(s->tx_fifo);
 
         while (len<4) {
             if (s->close_req)
                 goto end;
             pthread_cond_wait(&s->cond, &s->mutex);
-            len = av_fifo_can_read(s->fifo);
+            len = av_fifo_can_read(s->tx_fifo);
         }
 
-        av_fifo_read(s->fifo, tmp, 4);
+        av_fifo_read(s->tx_fifo, tmp, 4);
         len = AV_RL32(tmp);
 
         av_assert0(len >= 0);
         av_assert0(len <= sizeof(s->tmp));
 
-        av_fifo_read(s->fifo, s->tmp, len);
+        av_fifo_read(s->tx_fifo, s->tmp, len);
 
         pthread_mutex_unlock(&s->mutex);
 
@@ -944,11 +945,15 @@ static int udp_open(URLContext *h, const char *uri, int flags)
 
     if ((!is_output && s->circular_buffer_size) || (is_output && s->bitrate && s->circular_buffer_size)) {
         /* start the task going */
-        s->fifo = av_fifo_alloc2(s->circular_buffer_size, 1, 0);
-        if (!s->fifo) {
+        AVFifo *fifo = av_fifo_alloc2(s->circular_buffer_size, 1, 0);
+        if (!fifo) {
             ret = AVERROR(ENOMEM);
             goto fail;
         }
+        if (is_output)
+            s->tx_fifo = fifo;
+        else
+            s->rx_fifo = fifo;
         ret = pthread_mutex_init(&s->mutex, NULL);
         if (ret != 0) {
             av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret));
@@ -981,7 +986,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
  fail:
     if (udp_fd >= 0)
         closesocket(udp_fd);
-    av_fifo_freep2(&s->fifo);
+    av_fifo_freep2(&s->rx_fifo);
+    av_fifo_freep2(&s->tx_fifo);
     ff_ip_reset_filters(&s->filters);
     return ret;
 }
@@ -1004,23 +1010,23 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
 #if HAVE_PTHREAD_CANCEL
     int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
 
-    if (s->fifo) {
+    if (s->rx_fifo) {
         pthread_mutex_lock(&s->mutex);
         do {
-            avail = av_fifo_can_read(s->fifo);
+            avail = av_fifo_can_read(s->rx_fifo);
             if (avail) { // >=size) {
                 uint8_t tmp[4];
 
-                av_fifo_read(s->fifo, tmp, 4);
-                av_fifo_read(s->fifo, &s->last_recv_addr, sizeof(s->last_recv_addr));
+                av_fifo_read(s->rx_fifo, tmp, 4);
+                av_fifo_read(s->rx_fifo, &s->last_recv_addr, sizeof(s->last_recv_addr));
                 avail = AV_RL32(tmp);
                 if(avail > size){
                     av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
                     avail = size;
                 }
 
-                av_fifo_read(s->fifo, buf, avail);
-                av_fifo_drain2(s->fifo, AV_RL32(tmp) - avail);
+                av_fifo_read(s->rx_fifo, buf, avail);
+                av_fifo_drain2(s->rx_fifo, AV_RL32(tmp) - avail);
                 pthread_mutex_unlock(&s->mutex);
                 return avail;
             } else if(s->circular_buffer_error){
@@ -1066,7 +1072,7 @@ static int udp_write(URLContext *h, const uint8_t *buf, int size)
     int ret;
 
 #if HAVE_PTHREAD_CANCEL
-    if (s->fifo) {
+    if (s->tx_fifo) {
         uint8_t tmp[4];
 
         pthread_mutex_lock(&s->mutex);
@@ -1081,14 +1087,14 @@ static int udp_write(URLContext *h, const uint8_t *buf, int size)
             return err;
         }
 
-        if (av_fifo_can_write(s->fifo) < size + 4) {
+        if (av_fifo_can_write(s->tx_fifo) < size + 4) {
             /* What about a partial packet tx ? */
             pthread_mutex_unlock(&s->mutex);
             return AVERROR(ENOMEM);
         }
         AV_WL32(tmp, size);
-        av_fifo_write(s->fifo, tmp, 4); /* size of packet */
-        av_fifo_write(s->fifo, buf, size); /* the data */
+        av_fifo_write(s->tx_fifo, tmp, 4); /* size of packet */
+        av_fifo_write(s->tx_fifo, buf, size); /* the data */
         pthread_cond_signal(&s->cond);
         pthread_mutex_unlock(&s->mutex);
         return size;
@@ -1150,7 +1156,8 @@ static int udp_close(URLContext *h)
     }
 #endif
     closesocket(s->udp_fd);
-    av_fifo_freep2(&s->fifo);
+    av_fifo_freep2(&s->rx_fifo);
+    av_fifo_freep2(&s->tx_fifo);
     ff_ip_reset_filters(&s->filters);
     return 0;
 }
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 13/18] avformat/udp: add function to set remote address directly
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (11 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 12/18] avformat/udp: separate rx and tx fifo Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 14/18] avformat/tls: remove unused fingerprint option Timo Rothenpieler
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/network.h |  1 +
 libavformat/udp.c     | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/libavformat/network.h b/libavformat/network.h
index 48bb75a758..5734b664cd 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -339,5 +339,6 @@ int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
                         int (*customize_fd)(void *, int, int), void *customize_ctx);
 
 void ff_udp_get_last_recv_addr(URLContext *h, struct sockaddr_storage *addr);
+int ff_udp_set_remote_addr(URLContext *h, const struct sockaddr *dest_addr, socklen_t dest_addr_len, int do_connect);
 
 #endif /* AVFORMAT_NETWORK_H */
diff --git a/libavformat/udp.c b/libavformat/udp.c
index e02eff0f33..3657acb985 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -458,6 +458,36 @@ int ff_udp_set_remote_url(URLContext *h, const char *uri)
     return 0;
 }
 
+/**
+ * This function is identical to ff_udp_set_remote_url, except that it takes a sockaddr directly.
+ */
+int ff_udp_set_remote_addr(URLContext *h, const struct sockaddr *dest_addr, socklen_t dest_addr_len, int do_connect)
+{
+    UDPContext *s = h->priv_data;
+
+    /* set the destination address */
+    if (dest_addr_len < 0 || dest_addr_len > sizeof(s->dest_addr))
+        return AVERROR(EIO);
+    s->dest_addr_len = dest_addr_len;
+    memcpy(&s->dest_addr, dest_addr, dest_addr_len);
+
+    s->is_multicast = ff_is_multicast_address((struct sockaddr*) &s->dest_addr);
+    if (do_connect >= 0) {
+        int was_connected = s->is_connected;
+        s->is_connected = do_connect;
+        if (s->is_connected && !was_connected) {
+            if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr,
+                        s->dest_addr_len)) {
+                s->is_connected = 0;
+                ff_log_net_error(h, AV_LOG_ERROR, "connect");
+                return AVERROR(EIO);
+            }
+        }
+    }
+
+    return 0;
+}
+
 /**
  * Return the local port used by the UDP connection
  * @param h media file context
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 14/18] avformat/tls: remove unused fingerprint option
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (12 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 13/18] avformat/udp: add function to set remote address directly Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 15/18] avformat/tls: clean up new whip options Timo Rothenpieler
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/tls.h         | 5 +----
 libavformat/tls_openssl.c | 4 +---
 libavformat/whip.c        | 1 -
 3 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/libavformat/tls.h b/libavformat/tls.h
index 2f381acc04..9285228657 100644
--- a/libavformat/tls.h
+++ b/libavformat/tls.h
@@ -66,12 +66,10 @@ typedef struct TLSShared {
     int use_external_udp;
     URLContext *udp;
 
-    /* The fingerprint of certificate, used in SDP offer. */
-    char *fingerprint;
-
     /* The certificate and private key content used for DTLS handshake */
     char* cert_buf;
     char* key_buf;
+
     /**
      * The size of RTP packet, should generally be set to MTU.
      * Note that pion requires a smaller value, for example, 1200.
@@ -91,7 +89,6 @@ typedef struct TLSShared {
     {"http_proxy", "Set proxy to tunnel through",         offsetof(pstruct, options_field . http_proxy), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
     {"use_external_udp", "Use external UDP from muxer or demuxer", offsetof(pstruct, options_field . use_external_udp), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 1, .flags = TLS_OPTFL }, \
     {"mtu", "Maximum Transmission Unit", offsetof(pstruct, options_field . mtu), AV_OPT_TYPE_INT,  { .i64 = 0 }, 0, INT_MAX, .flags = TLS_OPTFL}, \
-    {"fingerprint", "The optional fingerprint for DTLS", offsetof(pstruct, options_field . fingerprint), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL}, \
     {"cert_buf", "The optional certificate buffer for DTLS", offsetof(pstruct, options_field . cert_buf), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL}, \
     {"key_buf", "The optional private key buffer for DTLS", offsetof(pstruct, options_field . key_buf), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL}
 
diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index d83fe602d5..2049eb021b 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -1013,8 +1013,7 @@ static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **
         }
     }
 
-    av_log(p, AV_LOG_VERBOSE, "TLS: Setup ok, MTU=%d, fingerprint %s\n",
-        p->tls_shared.mtu, p->tls_shared.fingerprint);
+    av_log(p, AV_LOG_VERBOSE, "TLS: Setup ok, MTU=%d\n", p->tls_shared.mtu);
 
     ret = 0;
 fail:
@@ -1032,7 +1031,6 @@ static av_cold int dtls_close(URLContext *h)
     TLSContext *ctx = h->priv_data;
     SSL_free(ctx->ssl);
     SSL_CTX_free(ctx->ctx);
-    av_freep(&ctx->tls_shared.fingerprint);
     av_freep(&ctx->tls_shared.cert_buf);
     av_freep(&ctx->tls_shared.key_buf);
     EVP_PKEY_free(ctx->pkey);
diff --git a/libavformat/whip.c b/libavformat/whip.c
index 71c667cd31..602a4432bd 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -1297,7 +1297,6 @@ next_packet:
                     av_dict_set(&opts, "key_file", whip->key_file, 0);
                 } else
                     av_dict_set(&opts, "key_buf", whip->key_buf, 0);
-                av_dict_set(&opts, "fingerprint", whip->dtls_fingerprint, 0);
                 av_dict_set_int(&opts, "use_external_udp", 1, 0);
                 av_dict_set_int(&opts, "listen", 1, 0);
                 /* If got the first binding response, start DTLS handshake. */
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 15/18] avformat/tls: clean up new whip options
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (13 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 14/18] avformat/tls: remove unused fingerprint option Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 16/18] avformat/tls: make passing an external socket universal Timo Rothenpieler
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/tls.h  | 6 +++---
 libavformat/whip.c | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavformat/tls.h b/libavformat/tls.h
index 9285228657..83d6b1ab6e 100644
--- a/libavformat/tls.h
+++ b/libavformat/tls.h
@@ -84,13 +84,13 @@ typedef struct TLSShared {
     {"tls_verify", "Verify the peer certificate",         offsetof(pstruct, options_field . verify),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \
     {"cert_file",  "Certificate file",                    offsetof(pstruct, options_field . cert_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
     {"key_file",   "Private key file",                    offsetof(pstruct, options_field . key_file),  AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
+    {"cert_pem",   "Certificate PEM string",              offsetof(pstruct, options_field . cert_buf),  AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
+    {"key_pem",    "Private key PEM string",              offsetof(pstruct, options_field . key_buf),   AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
     {"listen",     "Listen for incoming connections",     offsetof(pstruct, options_field . listen),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \
     {"verifyhost", "Verify against a specific hostname",  offsetof(pstruct, options_field . host),      AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
     {"http_proxy", "Set proxy to tunnel through",         offsetof(pstruct, options_field . http_proxy), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
     {"use_external_udp", "Use external UDP from muxer or demuxer", offsetof(pstruct, options_field . use_external_udp), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 1, .flags = TLS_OPTFL }, \
-    {"mtu", "Maximum Transmission Unit", offsetof(pstruct, options_field . mtu), AV_OPT_TYPE_INT,  { .i64 = 0 }, 0, INT_MAX, .flags = TLS_OPTFL}, \
-    {"cert_buf", "The optional certificate buffer for DTLS", offsetof(pstruct, options_field . cert_buf), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL}, \
-    {"key_buf", "The optional private key buffer for DTLS", offsetof(pstruct, options_field . key_buf), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL}
+    {"mtu",        "Maximum Transmission Unit",           offsetof(pstruct, options_field . mtu),       AV_OPT_TYPE_INT,  { .i64 = 0 }, 0, INT_MAX, .flags = TLS_OPTFL }
 
 int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options);
 
diff --git a/libavformat/whip.c b/libavformat/whip.c
index 602a4432bd..84d4c5a1f3 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -1291,12 +1291,12 @@ next_packet:
                 if (whip->cert_file) {
                     av_dict_set(&opts, "cert_file", whip->cert_file, 0);
                 } else
-                    av_dict_set(&opts, "cert_buf", whip->cert_buf, 0);
+                    av_dict_set(&opts, "cert_pem", whip->cert_buf, 0);
 
                 if (whip->key_file) {
                     av_dict_set(&opts, "key_file", whip->key_file, 0);
                 } else
-                    av_dict_set(&opts, "key_buf", whip->key_buf, 0);
+                    av_dict_set(&opts, "key_pem", whip->key_buf, 0);
                 av_dict_set_int(&opts, "use_external_udp", 1, 0);
                 av_dict_set_int(&opts, "listen", 1, 0);
                 /* If got the first binding response, start DTLS handshake. */
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 16/18] avformat/tls: make passing an external socket universal
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (14 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 15/18] avformat/tls: clean up new whip options Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 17/18] avformat/tls_openssl: use existing context handle Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 18/18] avformat/tls_schannel: add DTLS support Timo Rothenpieler
  17 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/tls.h         | 11 +++++------
 libavformat/tls_openssl.c | 14 ++++++++++----
 libavformat/whip.c        |  4 ++--
 3 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/libavformat/tls.h b/libavformat/tls.h
index 83d6b1ab6e..1ab115aa81 100644
--- a/libavformat/tls.h
+++ b/libavformat/tls.h
@@ -57,15 +57,14 @@ typedef struct TLSShared {
     char underlying_host[200];
     int numerichost;
 
+    int external_sock;
+    URLContext *udp;
     URLContext *tcp;
 
     int is_dtls;
 
     enum DTLSState state;
 
-    int use_external_udp;
-    URLContext *udp;
-
     /* The certificate and private key content used for DTLS handshake */
     char* cert_buf;
     char* key_buf;
@@ -89,14 +88,14 @@ typedef struct TLSShared {
     {"listen",     "Listen for incoming connections",     offsetof(pstruct, options_field . listen),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \
     {"verifyhost", "Verify against a specific hostname",  offsetof(pstruct, options_field . host),      AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
     {"http_proxy", "Set proxy to tunnel through",         offsetof(pstruct, options_field . http_proxy), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
-    {"use_external_udp", "Use external UDP from muxer or demuxer", offsetof(pstruct, options_field . use_external_udp), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 1, .flags = TLS_OPTFL }, \
-    {"mtu",        "Maximum Transmission Unit",           offsetof(pstruct, options_field . mtu),       AV_OPT_TYPE_INT,  { .i64 = 0 }, 0, INT_MAX, .flags = TLS_OPTFL }
+    {"mtu",        "Maximum Transmission Unit",           offsetof(pstruct, options_field . mtu),       AV_OPT_TYPE_INT,  { .i64 = 0 }, 0, INT_MAX, .flags = TLS_OPTFL }, \
+    {"external_sock", "Use external socket",              offsetof(pstruct, options_field . external_sock), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 1, .flags = TLS_OPTFL }
 
 int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options);
 
 int ff_url_read_all(const char *url, AVBPrint *bp);
 
-int ff_dtls_set_udp(URLContext *h, URLContext *udp);
+int ff_tls_set_external_socket(URLContext *h, URLContext *sock);
 
 int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz);
 
diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2049eb021b..5805513065 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -502,10 +502,16 @@ static const char* openssl_get_error(TLSContext *ctx)
     return ctx->error_message;
 }
 
-int ff_dtls_set_udp(URLContext *h, URLContext *udp)
+int ff_tls_set_external_socket(URLContext *h, URLContext *sock)
 {
     TLSContext *c = h->priv_data;
-    c->tls_shared.udp = udp;
+    TLSShared *s = &c->tls_shared;
+
+    if (s->is_dtls)
+        c->tls_shared.udp = sock;
+    else
+        c->tls_shared.tcp = sock;
+
     return 0;
 }
 
@@ -980,7 +986,7 @@ static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **
 #endif
     init_bio_method(h);
 
-    if (p->tls_shared.use_external_udp != 1) {
+    if (p->tls_shared.external_sock != 1) {
         if ((ret = ff_tls_open_underlying(&p->tls_shared, h, url, options)) < 0) {
             av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
             return ret;
@@ -1004,7 +1010,7 @@ static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **
      *
      * The SSL_do_handshake can't be called if DTLS hasn't prepare for udp.
      */
-    if (p->tls_shared.use_external_udp != 1) {
+    if (p->tls_shared.external_sock != 1) {
         ret = dtls_handshake(h);
         // Fatal SSL error, for example, no available suite when peer is DTLS 1.0 while we are DTLS 1.2.
         if (ret < 0) {
diff --git a/libavformat/whip.c b/libavformat/whip.c
index 84d4c5a1f3..e109469a4f 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -387,7 +387,7 @@ static av_cold int dtls_initialize(AVFormatContext *s)
 {
     WHIPContext *whip = s->priv_data;
     /* reuse the udp created by whip */
-    ff_dtls_set_udp(whip->dtls_uc, whip->udp);
+    ff_tls_set_external_socket(whip->dtls_uc, whip->udp);
     return 0;
 }
 
@@ -1297,7 +1297,7 @@ next_packet:
                     av_dict_set(&opts, "key_file", whip->key_file, 0);
                 } else
                     av_dict_set(&opts, "key_pem", whip->key_buf, 0);
-                av_dict_set_int(&opts, "use_external_udp", 1, 0);
+                av_dict_set_int(&opts, "external_sock", 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,
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 17/18] avformat/tls_openssl: use existing context handle
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (15 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 16/18] avformat/tls: make passing an external socket universal Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 18/18] avformat/tls_schannel: add DTLS support Timo Rothenpieler
  17 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 libavformat/tls_openssl.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 5805513065..6c994b3b89 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -842,14 +842,14 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
             ret = AVERROR(EIO);
             goto fail;
         }
-    } else if (p->tls_shared.cert_buf) {
-        cert = cert_from_pem_string(p->tls_shared.cert_buf);
+    } else if (c->cert_buf) {
+        cert = cert_from_pem_string(c->cert_buf);
         if (SSL_CTX_use_certificate(p->ctx, cert) != 1) {
             av_log(p, AV_LOG_ERROR, "SSL: Init SSL_CTX_use_certificate failed, %s\n", openssl_get_error(p));
             ret = AVERROR(EINVAL);
             return ret;
         }
-    } else if (p->tls_shared.is_dtls){
+    } else if (c->is_dtls){
         av_log(p, AV_LOG_ERROR, "TLS: Init cert failed, %s\n", openssl_get_error(p));
         ret = AVERROR(EINVAL);
         goto fail;
@@ -863,14 +863,14 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
             ret = AVERROR(EIO);
             goto fail;
         }
-    } else if (p->tls_shared.key_buf) {
-        p->pkey = pkey = pkey_from_pem_string(p->tls_shared.key_buf, 1);
+    } else if (c->key_buf) {
+        p->pkey = pkey = pkey_from_pem_string(c->key_buf, 1);
         if (SSL_CTX_use_PrivateKey(p->ctx, pkey) != 1) {
             av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_use_PrivateKey failed, %s\n", openssl_get_error(p));
             ret = AVERROR(EINVAL);
             return ret;
         }
-    } else if (p->tls_shared.is_dtls){
+    } else if (c->is_dtls) {
         av_log(p, AV_LOG_ERROR, "TLS: Init pkey failed, %s\n", openssl_get_error(p));
         ret = AVERROR(EINVAL);
         goto fail;
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [FFmpeg-devel] [PATCH 18/18] avformat/tls_schannel: add DTLS support
  2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
                   ` (16 preceding siblings ...)
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 17/18] avformat/tls_openssl: use existing context handle Timo Rothenpieler
@ 2025-07-02 16:56 ` Timo Rothenpieler
  17 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-02 16:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Timo Rothenpieler

---
 configure                  |   6 +-
 libavformat/tls_schannel.c | 853 ++++++++++++++++++++++++++++++++++---
 2 files changed, 801 insertions(+), 58 deletions(-)

diff --git a/configure b/configure
index 976a21b931..d11e583e4f 100755
--- a/configure
+++ b/configure
@@ -3854,7 +3854,7 @@ tcp_protocol_select="network"
 tls_protocol_deps_any="gnutls openssl schannel securetransport libtls mbedtls"
 tls_protocol_select="tcp_protocol"
 # TODO: Support libtls, mbedtls, and gnutls.
-dtls_protocol_deps_any="openssl"
+dtls_protocol_deps_any="openssl schannel"
 dtls_protocol_select="udp_protocol"
 udp_protocol_select="network"
 udplite_protocol_select="network"
@@ -7266,8 +7266,10 @@ enabled securetransport &&
 
 enabled schannel &&
     check_func_headers "windows.h security.h" InitializeSecurityContext -DSECURITY_WIN32 -lsecur32 &&
+    check_func_headers "windows.h ncrypt.h" NCryptOpenStorageProvider -DSECURITY_WIN32 -lncrypt &&
+    check_func_headers "windows.h wincrypt.h" CertCreateSelfSignCertificate -DSECURITY_WIN32 -lcrypt32 &&
     test_cpp_condition winerror.h "defined(SEC_I_CONTEXT_EXPIRED)" &&
-    schannel_extralibs="-lsecur32" ||
+    schannel_extralibs="-lsecur32 -lncrypt -lcrypt32" ||
         disable schannel
 
 makeinfo --version > /dev/null 2>&1 && enable makeinfo  || disable makeinfo
diff --git a/libavformat/tls_schannel.c b/libavformat/tls_schannel.c
index ae9a311d2a..3e4df7a372 100644
--- a/libavformat/tls_schannel.c
+++ b/libavformat/tls_schannel.c
@@ -32,6 +32,7 @@
 #include <windows.h>
 #include <security.h>
 #include <schnlsp.h>
+#include <sddl.h>
 
 #define SCHANNEL_INITIAL_BUFFER_SIZE   4096
 #define SCHANNEL_FREE_BUFFER_SIZE      1024
@@ -41,6 +42,508 @@
 #define SECBUFFER_ALERT                17
 #endif
 
+#define FF_NCRYPT_TEMP_KEY_NAME L"FFMPEG_TEMP_TLS_KEY"
+
+static int der_to_pem(const char *data, size_t len, const char *header, char *buf, size_t bufsize)
+{
+    const int line_length = 64;
+    AVBPrint pem;
+    DWORD base64len = 0;
+    char *base64 = NULL;
+    int ret = 0;
+
+    if (!CryptBinaryToStringA(data, len, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &base64len)) {
+        av_log(NULL, AV_LOG_ERROR, "CryptBinaryToString failed\n");
+        ret = AVERROR_EXTERNAL;
+        goto end;
+    }
+
+    base64 = av_malloc(base64len);
+
+    if (!CryptBinaryToStringA(data, len, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, base64, &base64len)) {
+        av_log(NULL, AV_LOG_ERROR, "CryptBinaryToString failed\n");
+        ret = AVERROR_EXTERNAL;
+        goto end;
+    }
+
+    av_bprint_init_for_buffer(&pem, buf, bufsize);
+    av_bprintf(&pem, "-----BEGIN %s-----\n", header);
+
+    for (DWORD i = 0; i < base64len; i += line_length) {
+        av_bprintf(&pem, "%.*s\n", line_length, base64 + i);
+    }
+
+    av_bprintf(&pem, "-----END %s-----\n", header);
+
+    if (!av_bprint_is_complete(&pem)) {
+        ret = AVERROR(ENOSPC);
+        goto end;
+    }
+
+end:
+    av_free(base64);
+    return ret;
+}
+
+static int pem_to_der(const char *pem, char **buf, int *out_len)
+{
+    DWORD derlen = 0;
+
+    if (!CryptStringToBinaryA(pem, 0, CRYPT_STRING_BASE64HEADER, NULL, &derlen, NULL, NULL)) {
+        av_log(NULL, AV_LOG_ERROR, "CryptStringToBinaryA failed\n");
+        return AVERROR(EINVAL);
+    }
+
+    *buf = av_malloc(derlen);
+    if (!*buf)
+        return AVERROR(ENOMEM);
+
+    if (!CryptStringToBinaryA(pem, 0, CRYPT_STRING_BASE64HEADER, *buf, &derlen, NULL, NULL)) {
+        av_log(NULL, AV_LOG_ERROR, "CryptStringToBinaryA failed\n");
+        return AVERROR(EINVAL);
+    }
+
+    *out_len = derlen;
+
+    return 0;
+}
+
+static int der_to_fingerprint(const char *data, size_t len, char **fingerprint)
+{
+    AVBPrint buf;
+    unsigned char hash[32];
+    DWORD hashsize = sizeof(hash);
+
+    if (!CryptHashCertificate2(BCRYPT_SHA256_ALGORITHM, 0, NULL, data, len, hash, &hashsize))
+    {
+        av_log(NULL, AV_LOG_ERROR, "CryptHashCertificate2 failed\n");
+        return AVERROR_EXTERNAL;
+    }
+
+    av_bprint_init(&buf, hashsize*3, hashsize*3);
+
+    for (int i = 0; i < hashsize - 1; i++)
+        av_bprintf(&buf, "%02X:", hash[i]);
+    av_bprintf(&buf, "%02X", hash[hashsize - 1]);
+
+    return av_bprint_finalize(&buf, fingerprint);
+}
+
+static int tls_gen_self_signed(NCRYPT_KEY_HANDLE *key, PCCERT_CONTEXT *crtctx)
+{
+    NCRYPT_PROV_HANDLE provider = 0;
+    CERT_NAME_BLOB subject = { 0 };
+
+    DWORD export_props = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
+    DWORD usage_props = NCRYPT_ALLOW_ALL_USAGES;
+    LPCSTR ext_usages[] = { szOID_PKIX_KP_SERVER_AUTH };
+    BYTE key_usage = CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DIGITAL_SIGNATURE_KEY_USAGE;
+    CRYPT_BIT_BLOB key_usage_blob = { 0 };
+    CERT_ENHKEY_USAGE eku = { 0 };
+    CERT_BASIC_CONSTRAINTS2_INFO basic_constraints = { 0 };
+    CERT_ALT_NAME_ENTRY san_entry = { 0 };
+    CERT_ALT_NAME_INFO san_info = { 0 };
+    CERT_EXTENSION ext[4] = { 0 };
+    CERT_EXTENSIONS exts = { 0 };
+    CRYPT_ALGORITHM_IDENTIFIER sig_alg = { (LPSTR)szOID_ECDSA_SHA256 };
+    CRYPT_KEY_PROV_INFO prov_info = { 0 };
+    const char *subj_str = "CN=lavf";
+
+    SECURITY_STATUS sspi_ret;
+    int ret = 0;
+
+    *crtctx = NULL;
+
+    sspi_ret = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptOpenStorageProvider failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    sspi_ret = NCryptCreatePersistedKey(provider, key, BCRYPT_ECDSA_P256_ALGORITHM, FF_NCRYPT_TEMP_KEY_NAME, 0, NCRYPT_OVERWRITE_KEY_FLAG);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptCreatePersistedKey failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    sspi_ret = NCryptSetProperty(*key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)&export_props, sizeof(export_props), 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptSetProperty(NCRYPT_EXPORT_POLICY_PROPERTY) failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    sspi_ret = NCryptSetProperty(*key, NCRYPT_KEY_USAGE_PROPERTY, (PBYTE)&usage_props, sizeof(usage_props), 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptSetProperty(NCRYPT_KEY_USAGE_PROPERTY) failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    sspi_ret = NCryptFinalizeKey(*key, 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptFinalizeKey failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    if (!CertStrToNameA(X509_ASN_ENCODING, subj_str, 0, NULL, NULL, &subject.cbData, NULL))
+    {
+        av_log(NULL, AV_LOG_ERROR, "Initial subj init failed\n");
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    subject.pbData = av_malloc(subject.cbData);
+    if (!subject.pbData) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    if (!CertStrToNameA(X509_ASN_ENCODING, subj_str, 0, NULL, subject.pbData, &subject.cbData, NULL))
+    {
+        av_log(NULL, AV_LOG_ERROR, "Subj init failed\n");
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    // Extended Key Usage extension
+    eku.cUsageIdentifier = 1;
+    eku.rgpszUsageIdentifier = (LPSTR*)ext_usages;
+
+    if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_ENHANCED_KEY_USAGE, &eku,
+                             CRYPT_ENCODE_ALLOC_FLAG, NULL, &ext[0].Value.pbData, &ext[0].Value.cbData)) {
+        av_log(NULL, AV_LOG_ERROR, "CryptEncodeObjectEx for EKU failed\n");
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    ext[0].pszObjId = (LPSTR)szOID_ENHANCED_KEY_USAGE;
+    ext[0].fCritical = TRUE;
+
+    // Key usage extension
+    key_usage_blob.cbData = sizeof(key_usage);
+    key_usage_blob.pbData = &key_usage;
+
+    if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_BITS, &key_usage_blob,
+                             CRYPT_ENCODE_ALLOC_FLAG, NULL, &ext[1].Value.pbData, &ext[1].Value.cbData)) {
+        av_log(NULL, AV_LOG_ERROR, "CryptEncodeObjectEx for KU failed\n");
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    ext[1].pszObjId = (LPSTR)szOID_KEY_USAGE;
+    ext[1].fCritical = TRUE;
+
+    // Cert Basic Constraints
+    basic_constraints.fCA = FALSE;
+
+    if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_BASIC_CONSTRAINTS2, &basic_constraints,
+                             CRYPT_ENCODE_ALLOC_FLAG, NULL, &ext[2].Value.pbData, &ext[2].Value.cbData)) {
+        av_log(NULL, AV_LOG_ERROR, "CryptEncodeObjectEx for KU failed\n");
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    ext[2].pszObjId = (LPSTR)szOID_BASIC_CONSTRAINTS2;
+    ext[2].fCritical = TRUE;
+
+    // Subject Alt Names
+    san_entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
+    san_entry.pwszDNSName = (LPWSTR)L"localhost";
+
+    san_info.cAltEntry = 1;
+    san_info.rgAltEntry = &san_entry;
+
+    if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_ALTERNATE_NAME, &san_info,
+                             CRYPT_ENCODE_ALLOC_FLAG, NULL, &ext[3].Value.pbData, &ext[3].Value.cbData)) {
+        av_log(NULL, AV_LOG_ERROR, "CryptEncodeObjectEx for KU failed\n");
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    ext[3].pszObjId = (LPSTR)szOID_SUBJECT_ALT_NAME2;
+    ext[3].fCritical = TRUE;
+
+    exts.cExtension = 4;
+    exts.rgExtension = ext;
+
+    prov_info.pwszProvName = (LPWSTR)MS_KEY_STORAGE_PROVIDER;
+    prov_info.pwszContainerName = (LPWSTR)FF_NCRYPT_TEMP_KEY_NAME;
+    prov_info.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
+
+    *crtctx = CertCreateSelfSignCertificate(*key, &subject, 0, &prov_info, &sig_alg, NULL, NULL, &exts);
+    if (!*crtctx) {
+        av_log(NULL, AV_LOG_ERROR, "CertCreateSelfSignCertificate failed: %lu\n", GetLastError());
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    NCryptFreeObject(provider);
+    av_free(subject.pbData);
+    for (int i = 0; i < FF_ARRAY_ELEMS(ext); i++)
+        LocalFree(ext[i].Value.pbData);
+
+    return 0;
+
+fail:
+    if (*crtctx)
+        CertFreeCertificateContext(*crtctx);
+    if (*key)
+        if (NCryptDeleteKey(*key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
+            NCryptFreeObject(*key);
+    if (provider)
+        NCryptFreeObject(provider);
+    if (subject.pbData)
+        av_free(subject.pbData);
+    for (int i = 0; i < FF_ARRAY_ELEMS(ext); i++)
+        if (ext[i].Value.pbData)
+            LocalFree(ext[i].Value.pbData);
+
+    *key = 0;
+    *crtctx = NULL;
+
+    return ret;
+}
+
+static int tls_export_key_cert(NCRYPT_KEY_HANDLE key, PCCERT_CONTEXT crtctx,
+                               char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
+{
+    DWORD keysize = 0;
+    char *keybuf = NULL;
+
+    SECURITY_STATUS sspi_ret;
+    int ret = 0;
+
+    sspi_ret = NCryptExportKey(key, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL, NULL, 0, &keysize, 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "Initial NCryptExportKey failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto end;
+    }
+
+    keybuf = av_malloc(keysize);
+    if (!keybuf) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    sspi_ret = NCryptExportKey(key, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL, keybuf, keysize, &keysize, 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "Initial NCryptExportKey failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto end;
+    }
+
+    ret = der_to_pem(keybuf, keysize, "PRIVATE KEY", key_buf, key_sz);
+    if (ret < 0)
+        goto end;
+
+    ret = der_to_pem(crtctx->pbCertEncoded, crtctx->cbCertEncoded, "CERTIFICATE", cert_buf, cert_sz);
+    if (ret < 0)
+        goto end;
+
+    ret = der_to_fingerprint(crtctx->pbCertEncoded, crtctx->cbCertEncoded, fingerprint);
+    if (ret < 0)
+        goto end;
+
+end:
+    av_free(keybuf);
+    return ret;
+}
+
+int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
+{
+    NCRYPT_KEY_HANDLE key = 0;
+    PCCERT_CONTEXT crtctx = NULL;
+
+    int ret = tls_gen_self_signed(&key, &crtctx);
+    if (ret < 0)
+        goto end;
+
+    ret = tls_export_key_cert(key, crtctx, key_buf, key_sz, cert_buf, cert_sz, fingerprint);
+    if (ret < 0)
+        goto end;
+
+end:
+    if (key)
+        if (NCryptDeleteKey(key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
+            NCryptFreeObject(key);
+    if (crtctx)
+        CertFreeCertificateContext(crtctx);
+
+    return ret;
+}
+
+static int tls_import_key_cert(char *key_buf, char *cert_buf, NCRYPT_KEY_HANDLE *key, PCCERT_CONTEXT *crtctx)
+{
+    NCRYPT_PROV_HANDLE provider = 0;
+
+    DWORD export_props = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
+    DWORD usage_props = NCRYPT_ALLOW_ALL_USAGES;
+    NCryptBufferDesc buffer_desc = { 0 };
+    NCryptBuffer buffer = { 0 };
+    CRYPT_KEY_PROV_INFO prov_info = { 0 };
+
+    int key_der_len = 0, cert_der_len = 0;
+    char *key_der = NULL, *cert_der = NULL;
+
+    SECURITY_STATUS sspi_ret;
+    int ret = 0;
+
+    ret = pem_to_der(key_buf, &key_der, &key_der_len);
+    if (ret < 0)
+        goto fail;
+
+    ret = pem_to_der(cert_buf, &cert_der, &cert_der_len);
+    if (ret < 0)
+        goto fail;
+
+    sspi_ret = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptOpenStorageProvider failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    buffer_desc.ulVersion = NCRYPTBUFFER_VERSION;
+    buffer_desc.cBuffers = 1;
+    buffer_desc.pBuffers = &buffer;
+
+    buffer.BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;
+    buffer.pvBuffer = (LPWSTR)FF_NCRYPT_TEMP_KEY_NAME;
+    buffer.cbBuffer = sizeof(FF_NCRYPT_TEMP_KEY_NAME);
+
+    sspi_ret = NCryptImportKey(provider, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &buffer_desc, key, key_der, key_der_len, NCRYPT_DO_NOT_FINALIZE_FLAG | NCRYPT_OVERWRITE_KEY_FLAG);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptImportKey failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    sspi_ret = NCryptSetProperty(*key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)&export_props, sizeof(export_props), 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptSetProperty(NCRYPT_EXPORT_POLICY_PROPERTY) failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    sspi_ret = NCryptSetProperty(*key, NCRYPT_KEY_USAGE_PROPERTY, (PBYTE)&usage_props, sizeof(usage_props), 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptSetProperty(NCRYPT_KEY_USAGE_PROPERTY) failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    sspi_ret = NCryptFinalizeKey(*key, 0);
+    if (sspi_ret != ERROR_SUCCESS) {
+        av_log(NULL, AV_LOG_ERROR, "NCryptFinalizeKey failed(0x%lx)\n", sspi_ret);
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    *crtctx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert_der, cert_der_len);
+    if (!*crtctx) {
+        av_log(NULL, AV_LOG_ERROR, "CertCreateCertificateContext failed: %lu\n", GetLastError());
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    if (!CertSetCertificateContextProperty(*crtctx, CERT_NCRYPT_KEY_HANDLE_PROP_ID, 0, key)) {
+        av_log(NULL, AV_LOG_ERROR, "CertSetCertificateContextProperty(CERT_NCRYPT_KEY_HANDLE_PROP_ID) failed: %lu\n", GetLastError());
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    prov_info.pwszProvName = (LPWSTR)MS_KEY_STORAGE_PROVIDER;
+    prov_info.pwszContainerName = (LPWSTR)FF_NCRYPT_TEMP_KEY_NAME;
+    prov_info.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
+
+    if (!CertSetCertificateContextProperty(*crtctx, CERT_KEY_PROV_INFO_PROP_ID, 0, &prov_info)) {
+        av_log(NULL, AV_LOG_ERROR, "CertSetCertificateContextProperty(CERT_KEY_PROV_INFO_PROP_ID) failed: %lu\n", GetLastError());
+        ret = AVERROR_EXTERNAL;
+        goto fail;
+    }
+
+    goto end;
+
+fail:
+    if (*key)
+        if (NCryptDeleteKey(*key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
+            NCryptFreeObject(*key);
+    if (*crtctx)
+        CertFreeCertificateContext(*crtctx);
+
+    *key = 0;
+    *crtctx = NULL;
+
+end:
+    if (key_der)
+        av_free(key_der);
+    if (cert_der)
+        av_free(cert_der);
+    if (provider)
+        NCryptFreeObject(provider);
+    return ret;
+}
+
+static int tls_load_key_cert(char *key_url, char *cert_url, NCRYPT_KEY_HANDLE *key, PCCERT_CONTEXT *crtctx)
+{
+    AVBPrint key_bp, cert_bp;
+    int ret = 0;
+
+    av_bprint_init(&key_bp, 1, MAX_CERTIFICATE_SIZE);
+    av_bprint_init(&cert_bp, 1, MAX_CERTIFICATE_SIZE);
+
+    /* Read key file. */
+    ret = ff_url_read_all(key_url, &key_bp);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Failed to open key file %s\n", key_url);
+        goto end;
+    }
+
+    ret = ff_url_read_all(cert_url, &cert_bp);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Failed to open cert file %s\n", cert_url);
+        goto end;
+    }
+
+    ret = tls_import_key_cert(key_bp.str, cert_bp.str, key, crtctx);
+    if (ret < 0)
+        goto end;
+
+end:
+    av_bprint_finalize(&key_bp, NULL);
+    av_bprint_finalize(&cert_bp, NULL);
+
+    return ret;
+}
+
+int ff_ssl_read_key_cert(char *key_url, char *cert_url, char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
+{
+    NCRYPT_KEY_HANDLE key = 0;
+    PCCERT_CONTEXT crtctx = NULL;
+
+    int ret = tls_load_key_cert(key_url, cert_url, &key, &crtctx);
+    if (ret < 0)
+        goto end;
+
+    ret = tls_export_key_cert(key, crtctx, key_buf, key_sz, cert_buf, cert_sz, fingerprint);
+    if (ret < 0)
+        goto end;
+
+end:
+    if (key)
+        if (NCryptDeleteKey(key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
+            NCryptFreeObject(key);
+    if (crtctx)
+        CertFreeCertificateContext(crtctx);
+
+    return ret;
+}
+
 typedef struct TLSContext {
     const AVClass *class;
     TLSShared tls_shared;
@@ -49,6 +552,7 @@ typedef struct TLSContext {
     TimeStamp cred_timestamp;
 
     CtxtHandle ctxt_handle;
+    int have_context;
     TimeStamp ctxt_timestamp;
 
     ULONG request_flags;
@@ -69,6 +573,67 @@ typedef struct TLSContext {
     int sspi_close_notify;
 } TLSContext;
 
+int ff_tls_set_external_socket(URLContext *h, URLContext *sock)
+{
+    TLSContext *c = h->priv_data;
+    TLSShared *s = &c->tls_shared;
+
+    if (s->is_dtls)
+        c->tls_shared.udp = sock;
+    else
+        c->tls_shared.tcp = sock;
+
+    return 0;
+}
+
+int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
+{
+    TLSContext *c = h->priv_data;
+
+    SecPkgContext_KeyingMaterialInfo keying_info = { 0 };
+    SecPkgContext_KeyingMaterial keying_material = { 0 };
+
+    const char* dst = "EXTRACTOR-dtls_srtp";
+    SECURITY_STATUS sspi_ret;
+
+    if (!c->have_context)
+        return AVERROR(EINVAL);
+
+    keying_info.cbLabel = strlen(dst) + 1;
+    keying_info.pszLabel = (LPSTR)dst;
+    keying_info.cbContextValue = 0;
+    keying_info.pbContextValue = NULL;
+    keying_info.cbKeyingMaterial = materials_sz;
+
+    sspi_ret = SetContextAttributes(&c->ctxt_handle, SECPKG_ATTR_KEYING_MATERIAL_INFO, &keying_info, sizeof(keying_info));
+    if (sspi_ret != SEC_E_OK) {
+        av_log(h, AV_LOG_ERROR, "Setting keying material info failed: %lx\n", sspi_ret);
+        return AVERROR_EXTERNAL;
+    }
+
+    sspi_ret = QueryContextAttributes(&c->ctxt_handle, SECPKG_ATTR_KEYING_MATERIAL, &keying_material);
+    if (sspi_ret != SEC_E_OK) {
+        av_log(h, AV_LOG_ERROR, "Querying keying material failed: %lx\n", sspi_ret);
+        return AVERROR_EXTERNAL;
+    }
+
+    memcpy(dtls_srtp_materials, keying_material.pbKeyingMaterial, FFMIN(materials_sz, keying_material.cbKeyingMaterial));
+    FreeContextBuffer(keying_material.pbKeyingMaterial);
+
+    if (keying_material.cbKeyingMaterial > materials_sz) {
+        av_log(h, AV_LOG_WARNING, "Keying material size mismatch: %ld > %zu\n", keying_material.cbKeyingMaterial, materials_sz);
+        return AVERROR(ENOSPC);
+    }
+
+    return 0;
+}
+
+int ff_dtls_state(URLContext *h)
+{
+    TLSContext *c = h->priv_data;
+    return c->tls_shared.state;
+}
+
 static void init_sec_buffer(SecBuffer *buffer, unsigned long type,
                             void *data, unsigned long size)
 {
@@ -89,6 +654,7 @@ static int tls_shutdown_client(URLContext *h)
 {
     TLSContext *c = h->priv_data;
     TLSShared *s = &c->tls_shared;
+    URLContext *uc = s->is_dtls ? s->udp : s->tcp;
     int ret;
 
     if (c->connected) {
@@ -109,12 +675,17 @@ static int tls_shutdown_client(URLContext *h)
         init_sec_buffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
         init_sec_buffer_desc(&outbuf_desc, &outbuf, 1);
 
-        sspi_ret = InitializeSecurityContext(&c->cred_handle, &c->ctxt_handle, s->host,
-                                             c->request_flags, 0, 0, NULL, 0, &c->ctxt_handle,
-                                             &outbuf_desc, &c->context_flags, &c->ctxt_timestamp);
+        if (s->listen)
+            sspi_ret = AcceptSecurityContext(&c->cred_handle, &c->ctxt_handle, NULL, c->request_flags, 0,
+                                             &c->ctxt_handle, &outbuf_desc, &c->context_flags,
+                                             &c->ctxt_timestamp);
+        else
+            sspi_ret = InitializeSecurityContext(&c->cred_handle, &c->ctxt_handle, s->host,
+                                                 c->request_flags, 0, 0, NULL, 0, &c->ctxt_handle,
+                                                 &outbuf_desc, &c->context_flags, &c->ctxt_timestamp);
         if (sspi_ret == SEC_E_OK || sspi_ret == SEC_I_CONTEXT_EXPIRED) {
-            s->tcp->flags &= ~AVIO_FLAG_NONBLOCK;
-            ret = ffurl_write(s->tcp, outbuf.pvBuffer, outbuf.cbBuffer);
+            uc->flags &= ~AVIO_FLAG_NONBLOCK;
+            ret = ffurl_write(uc, outbuf.pvBuffer, outbuf.cbBuffer);
             FreeContextBuffer(outbuf.pvBuffer);
             if (ret < 0 || ret != outbuf.cbBuffer)
                 av_log(h, AV_LOG_ERROR, "Failed to send close message\n");
@@ -128,6 +699,7 @@ static int tls_shutdown_client(URLContext *h)
 static int tls_close(URLContext *h)
 {
     TLSContext *c = h->priv_data;
+    TLSShared *s = &c->tls_shared;
 
     tls_shutdown_client(h);
 
@@ -140,19 +712,27 @@ static int tls_close(URLContext *h)
     av_freep(&c->dec_buf);
     c->dec_buf_size = c->dec_buf_offset = 0;
 
-    ffurl_closep(&c->tls_shared.tcp);
+    if (s->is_dtls) {
+        if (!s->external_sock)
+            ffurl_closep(&c->tls_shared.udp);
+    } else {
+        ffurl_closep(&c->tls_shared.tcp);
+    }
+
     return 0;
 }
 
-static int tls_client_handshake_loop(URLContext *h, int initial)
+static int tls_handshake_loop(URLContext *h, int initial)
 {
     TLSContext *c = h->priv_data;
     TLSShared *s = &c->tls_shared;
+    URLContext *uc = s->is_dtls ? s->udp : s->tcp;
     SECURITY_STATUS sspi_ret;
     SecBuffer outbuf[3] = { 0 };
     SecBufferDesc outbuf_desc;
-    SecBuffer inbuf[2];
+    SecBuffer inbuf[3];
     SecBufferDesc inbuf_desc;
+    struct sockaddr_storage recv_addr = { 0 };
     int i, ret = 0, read_data = initial;
 
     if (c->enc_buf == NULL) {
@@ -182,19 +762,35 @@ static int tls_client_handshake_loop(URLContext *h, int initial)
         }
 
         if (read_data) {
-            ret = ffurl_read(c->tls_shared.tcp, c->enc_buf + c->enc_buf_offset,
-                             c->enc_buf_size - c->enc_buf_offset);
+            ret = ffurl_read(uc, c->enc_buf + c->enc_buf_offset, c->enc_buf_size - c->enc_buf_offset);
             if (ret < 0) {
                 av_log(h, AV_LOG_ERROR, "Failed to read handshake response\n");
                 goto fail;
             }
             c->enc_buf_offset += ret;
+            if (s->is_dtls && !recv_addr.ss_family) {
+                ff_udp_get_last_recv_addr(uc, &recv_addr);
+
+                if (s->listen) {
+                    ret = ff_udp_set_remote_addr(uc, (struct sockaddr *)&recv_addr, sizeof(recv_addr), 1);
+                    if (ret < 0) {
+                        av_log(h, AV_LOG_ERROR, "Failed connecting udp context\n");
+                        goto fail;
+                    }
+                    av_log(h, AV_LOG_TRACE, "Set UDP remote addr on UDP socket, now 'connected'\n");
+                }
+            }
         }
 
         /* input buffers */
         init_sec_buffer(&inbuf[0], SECBUFFER_TOKEN, av_malloc(c->enc_buf_offset), c->enc_buf_offset);
         init_sec_buffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
-        init_sec_buffer_desc(&inbuf_desc, inbuf, 2);
+        if (s->listen && s->is_dtls) {
+            init_sec_buffer(&inbuf[2], SECBUFFER_EXTRA, &recv_addr, sizeof(recv_addr));
+            init_sec_buffer_desc(&inbuf_desc, inbuf, 3);
+        } else {
+            init_sec_buffer_desc(&inbuf_desc, inbuf, 2);
+        }
 
         if (inbuf[0].pvBuffer == NULL) {
             av_log(h, AV_LOG_ERROR, "Failed to allocate input buffer\n");
@@ -210,17 +806,26 @@ static int tls_client_handshake_loop(URLContext *h, int initial)
         init_sec_buffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
         init_sec_buffer_desc(&outbuf_desc, outbuf, 3);
 
-        sspi_ret = InitializeSecurityContext(&c->cred_handle, &c->ctxt_handle, s->host, c->request_flags,
-                                             0, 0, &inbuf_desc, 0, NULL, &outbuf_desc, &c->context_flags,
-                                             &c->ctxt_timestamp);
+        if (s->listen)
+            sspi_ret = AcceptSecurityContext(&c->cred_handle, c->have_context ? &c->ctxt_handle : NULL, &inbuf_desc,
+                                             c->request_flags, 0, &c->ctxt_handle, &outbuf_desc,
+                                             &c->context_flags, &c->ctxt_timestamp);
+        else
+            sspi_ret = InitializeSecurityContext(&c->cred_handle, c->have_context ? &c->ctxt_handle : NULL,
+                                                 s->host, c->request_flags, 0, 0, &inbuf_desc, 0, &c->ctxt_handle,
+                                                 &outbuf_desc, &c->context_flags, &c->ctxt_timestamp);
         av_freep(&inbuf[0].pvBuffer);
 
+        av_log(h, AV_LOG_TRACE, "Handshake res with %d bytes of data: 0x%lx\n", c->enc_buf_offset, sspi_ret);
+
         if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
-            av_log(h, AV_LOG_DEBUG, "Received incomplete handshake, need more data\n");
+            av_log(h, AV_LOG_TRACE, "Received incomplete handshake, need more data\n");
             read_data = 1;
             continue;
         }
 
+        c->have_context = 1;
+
         /* remote requests a client certificate - attempt to continue without one anyway */
         if (sspi_ret == SEC_I_INCOMPLETE_CREDENTIALS &&
             !(c->request_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
@@ -231,10 +836,10 @@ static int tls_client_handshake_loop(URLContext *h, int initial)
         }
 
         /* continue handshake */
-        if (sspi_ret == SEC_I_CONTINUE_NEEDED || sspi_ret == SEC_E_OK) {
+        if (sspi_ret == SEC_I_CONTINUE_NEEDED || sspi_ret == SEC_I_MESSAGE_FRAGMENT || sspi_ret == SEC_E_OK) {
             for (i = 0; i < 3; i++) {
                 if (outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
-                    ret = ffurl_write(c->tls_shared.tcp, outbuf[i].pvBuffer, outbuf[i].cbBuffer);
+                    ret = ffurl_write(uc, outbuf[i].pvBuffer, outbuf[i].cbBuffer);
                     if (ret < 0 || ret != outbuf[i].cbBuffer) {
                         av_log(h, AV_LOG_VERBOSE, "Failed to send handshake data\n");
                         ret = AVERROR(EIO);
@@ -256,12 +861,19 @@ static int tls_client_handshake_loop(URLContext *h, int initial)
             goto fail;
         }
 
+        if (sspi_ret == SEC_I_MESSAGE_FRAGMENT) {
+            av_log(h, AV_LOG_TRACE, "Writing fragmented output message part\n");
+            read_data = 0;
+            continue;
+        }
+
         if (inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
             if (c->enc_buf_offset > inbuf[1].cbBuffer) {
                 memmove(c->enc_buf, (c->enc_buf + c->enc_buf_offset) - inbuf[1].cbBuffer,
                         inbuf[1].cbBuffer);
                 c->enc_buf_offset = inbuf[1].cbBuffer;
                 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
+                    av_log(h, AV_LOG_TRACE, "Sent reply, handshake continues. %d extra bytes\n", (int)inbuf[1].cbBuffer);
                     read_data = 0;
                     continue;
                 }
@@ -271,6 +883,7 @@ static int tls_client_handshake_loop(URLContext *h, int initial)
         }
 
         if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
+            av_log(h, AV_LOG_TRACE, "Handshake continues\n");
             read_data = 1;
             continue;
         }
@@ -278,6 +891,8 @@ static int tls_client_handshake_loop(URLContext *h, int initial)
         break;
     }
 
+    av_log(h, AV_LOG_TRACE, "Handshake completed\n");
+
     return 0;
 
 fail:
@@ -289,6 +904,8 @@ fail:
         }
     }
 
+    av_log(h, AV_LOG_TRACE, "Handshake failed\n");
+
     return ret;
 }
 
@@ -296,6 +913,7 @@ static int tls_client_handshake(URLContext *h)
 {
     TLSContext *c = h->priv_data;
     TLSShared *s = &c->tls_shared;
+    URLContext *uc = s->is_dtls ? s->udp : s->tcp;
     SecBuffer outbuf;
     SecBufferDesc outbuf_desc;
     SECURITY_STATUS sspi_ret;
@@ -305,8 +923,11 @@ static int tls_client_handshake(URLContext *h)
     init_sec_buffer_desc(&outbuf_desc, &outbuf, 1);
 
     c->request_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
-                       ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
-                       ISC_REQ_STREAM;
+                       ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY;
+    if (s->is_dtls)
+        c->request_flags |= ISC_REQ_DATAGRAM;
+    else
+        c->request_flags |= ISC_REQ_STREAM;
 
     sspi_ret = InitializeSecurityContext(&c->cred_handle, NULL, s->host, c->request_flags, 0, 0,
                                          NULL, 0, &c->ctxt_handle, &outbuf_desc, &c->context_flags,
@@ -317,8 +938,10 @@ static int tls_client_handshake(URLContext *h)
         goto fail;
     }
 
-    s->tcp->flags &= ~AVIO_FLAG_NONBLOCK;
-    ret = ffurl_write(s->tcp, outbuf.pvBuffer, outbuf.cbBuffer);
+    c->have_context = 1;
+
+    uc->flags &= ~AVIO_FLAG_NONBLOCK;
+    ret = ffurl_write(uc, outbuf.pvBuffer, outbuf.cbBuffer);
     FreeContextBuffer(outbuf.pvBuffer);
     if (ret < 0 || ret != outbuf.cbBuffer) {
         av_log(h, AV_LOG_ERROR, "Failed to send initial handshake data\n");
@@ -326,44 +949,121 @@ static int tls_client_handshake(URLContext *h)
         goto fail;
     }
 
-    return tls_client_handshake_loop(h, 1);
+    return tls_handshake_loop(h, 1);
 
 fail:
     DeleteSecurityContext(&c->ctxt_handle);
     return ret;
 }
 
-static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
+static int tls_server_handshake(URLContext *h)
+{
+    TLSContext *c = h->priv_data;
+    TLSShared *s = &c->tls_shared;
+
+    c->request_flags = ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
+                       ASC_REQ_CONFIDENTIALITY | ASC_REQ_ALLOCATE_MEMORY;
+    if (s->is_dtls)
+        c->request_flags |= ASC_REQ_DATAGRAM;
+    else
+        c->request_flags |= ASC_REQ_STREAM;
+
+    c->have_context = 0;
+
+    return tls_handshake_loop(h, 1);
+}
+
+static int tls_handshake(URLContext *h)
 {
     TLSContext *c = h->priv_data;
     TLSShared *s = &c->tls_shared;
     SECURITY_STATUS sspi_ret;
-    SCHANNEL_CRED schannel_cred = { 0 };
-    int ret;
+    int ret = 0;
 
-    if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
-        goto fail;
+    if (s->listen)
+        ret = tls_server_handshake(h);
+    else
+        ret = tls_client_handshake(h);
 
-    if (s->listen) {
-        av_log(h, AV_LOG_ERROR, "TLS Listen Sockets with SChannel is not implemented.\n");
-        ret = AVERROR(EINVAL);
+    if (ret < 0)
         goto fail;
+
+    if (s->is_dtls && s->mtu > 0) {
+        ULONG mtu = s->mtu;
+        sspi_ret = SetContextAttributes(&c->ctxt_handle, SECPKG_ATTR_DTLS_MTU, &mtu, sizeof(mtu));
+        if (sspi_ret != SEC_E_OK) {
+            av_log(h, AV_LOG_ERROR, "Failed setting DTLS MTU to %d.\n", s->mtu);
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+        av_log(h, AV_LOG_VERBOSE, "Set DTLS MTU to %d\n", s->mtu);
+    }
+
+    c->connected = 1;
+    s->state = DTLS_STATE_FINISHED;
+
+fail:
+    return ret;
+}
+
+static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
+{
+    TLSContext *c = h->priv_data;
+    TLSShared *s = &c->tls_shared;
+    SECURITY_STATUS sspi_ret;
+    SCHANNEL_CRED schannel_cred = { 0 };
+    PCCERT_CONTEXT crtctx = NULL;
+    NCRYPT_KEY_HANDLE key = 0;
+    int ret = 0;
+
+    if (!s->external_sock) {
+        if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
+            goto fail;
     }
 
     /* SChannel Options */
     schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
 
-    if (s->verify)
-        schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
-                                SCH_CRED_REVOCATION_CHECK_CHAIN;
-    else
-        schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
-                                SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
-                                SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+    if (s->listen) {
+        if (s->key_buf && s->cert_buf) {
+            ret = tls_import_key_cert(s->key_buf, s->cert_buf, &key, &crtctx);
+            if (ret < 0)
+                goto fail;
+        } else if (s->key_file && s->cert_file) {
+            ret = tls_load_key_cert(s->key_file, s->cert_file, &key, &crtctx);
+            if (ret < 0)
+                goto fail;
+        } else {
+            av_log(h, AV_LOG_VERBOSE, "No server certificate provided, using self-signed\n");
+            ret = tls_gen_self_signed(&key, &crtctx);
+            if (ret < 0)
+                goto fail;
+        }
+
+        schannel_cred.cCreds = 1;
+        schannel_cred.paCred = &crtctx;
+
+        schannel_cred.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER | SCH_CRED_MANUAL_CRED_VALIDATION;
+
+        if (s->is_dtls)
+            schannel_cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_SERVER;
+    } else {
+        if (s->verify)
+            schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
+                                    SCH_CRED_REVOCATION_CHECK_CHAIN;
+        else
+            schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+                                    SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+                                    SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+
+        if (s->is_dtls)
+            schannel_cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_CLIENT;
+    }
 
     /* Get credential handle */
-    sspi_ret = AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME, SECPKG_CRED_OUTBOUND,
-                                        NULL,  &schannel_cred, NULL, NULL, &c->cred_handle,
+    sspi_ret = AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
+                                        s->listen ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
+                                        NULL, &schannel_cred, NULL, NULL, &c->cred_handle,
                                         &c->cred_timestamp);
     if (sspi_ret != SEC_E_OK) {
         av_log(h, AV_LOG_ERROR, "Unable to acquire security credentials (0x%lx)\n", sspi_ret);
@@ -371,23 +1071,42 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op
         goto fail;
     }
 
-    ret = tls_client_handshake(h);
-    if (ret < 0)
-        goto fail;
-
-    c->connected = 1;
+    if (!s->external_sock) {
+        ret = tls_handshake(h);
+        if (ret < 0)
+            goto fail;
+    }
 
-    return 0;
+    goto end;
 
 fail:
     tls_close(h);
+
+end:
+    if (crtctx)
+        CertFreeCertificateContext(crtctx);
+    if (key)
+        if (NCryptDeleteKey(key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
+            NCryptFreeObject(key);
+
     return ret;
 }
 
+static int dtls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
+{
+    TLSContext *c = h->priv_data;
+    TLSShared *s = &c->tls_shared;
+
+    s->is_dtls = 1;
+
+    return tls_open(h, uri, flags, options);
+}
+
 static int tls_read(URLContext *h, uint8_t *buf, int len)
 {
     TLSContext *c = h->priv_data;
     TLSShared *s = &c->tls_shared;
+    URLContext *uc = s->is_dtls ? s->udp : s->tcp;
     SECURITY_STATUS sspi_ret = SEC_E_OK;
     SecBuffer inbuf[4];
     SecBufferDesc inbuf_desc;
@@ -418,10 +1137,10 @@ static int tls_read(URLContext *h, uint8_t *buf, int len)
             }
         }
 
-        s->tcp->flags &= ~AVIO_FLAG_NONBLOCK;
-        s->tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
+        uc->flags &= ~AVIO_FLAG_NONBLOCK;
+        uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
 
-        ret = ffurl_read(s->tcp, c->enc_buf + c->enc_buf_offset,
+        ret = ffurl_read(uc, c->enc_buf + c->enc_buf_offset,
                          c->enc_buf_size - c->enc_buf_offset);
         if (ret == AVERROR_EOF) {
             c->connection_closed = 1;
@@ -489,7 +1208,7 @@ static int tls_read(URLContext *h, uint8_t *buf, int len)
                 }
 
                 av_log(h, AV_LOG_VERBOSE, "Re-negotiating security context\n");
-                ret = tls_client_handshake_loop(h, 0);
+                ret = tls_handshake_loop(h, 0);
                 if (ret < 0) {
                     goto cleanup;
                 }
@@ -536,6 +1255,7 @@ static int tls_write(URLContext *h, const uint8_t *buf, int len)
 {
     TLSContext *c = h->priv_data;
     TLSShared *s = &c->tls_shared;
+    URLContext *uc = s->is_dtls ? s->udp : s->tcp;
     SECURITY_STATUS sspi_ret;
     int ret = 0, data_size;
     uint8_t *data = NULL;
@@ -549,7 +1269,7 @@ static int tls_write(URLContext *h, const uint8_t *buf, int len)
     }
 
     /* limit how much data we can consume */
-    len = FFMIN(len, c->sizes.cbMaximumMessage);
+    len = FFMIN(len, c->sizes.cbMaximumMessage - c->sizes.cbHeader - c->sizes.cbTrailer);
 
     data_size = c->sizes.cbHeader + len + c->sizes.cbTrailer;
     data = av_malloc(data_size);
@@ -572,10 +1292,10 @@ static int tls_write(URLContext *h, const uint8_t *buf, int len)
     if (sspi_ret == SEC_E_OK)  {
         len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
 
-        s->tcp->flags &= ~AVIO_FLAG_NONBLOCK;
-        s->tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
+        uc->flags &= ~AVIO_FLAG_NONBLOCK;
+        uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
 
-        ret = ffurl_write(s->tcp, data, len);
+        ret = ffurl_write(uc, data, len);
         if (ret == AVERROR(EAGAIN)) {
             goto done;
         } else if (ret < 0 || ret != len) {
@@ -600,13 +1320,15 @@ done:
 static int tls_get_file_handle(URLContext *h)
 {
     TLSContext *c = h->priv_data;
-    return ffurl_get_file_handle(c->tls_shared.tcp);
+    TLSShared *s = &c->tls_shared;
+    return ffurl_get_file_handle(s->is_dtls ? c->tls_shared.udp : c->tls_shared.tcp);
 }
 
 static int tls_get_short_seek(URLContext *h)
 {
-    TLSContext *s = h->priv_data;
-    return ffurl_get_short_seek(s->tls_shared.tcp);
+    TLSContext *c = h->priv_data;
+    TLSShared *s = &c->tls_shared;
+    return ffurl_get_short_seek(s->is_dtls ? c->tls_shared.udp : c->tls_shared.tcp);
 }
 
 static const AVOption options[] = {
@@ -633,3 +1355,22 @@ const URLProtocol ff_tls_protocol = {
     .flags          = URL_PROTOCOL_FLAG_NETWORK,
     .priv_data_class = &tls_class,
 };
+
+static const AVClass dtls_class = {
+    .class_name = "dtls",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+const URLProtocol ff_dtls_protocol = {
+    .name           = "dtls",
+    .url_open2      = dtls_open,
+    .url_handshake  = tls_handshake,
+    .url_close      = tls_close,
+    .url_read       = tls_read,
+    .url_write      = tls_write,
+    .priv_data_size = sizeof(TLSContext),
+    .flags          = URL_PROTOCOL_FLAG_NETWORK,
+    .priv_data_class = &dtls_class,
+};
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code Timo Rothenpieler
@ 2025-07-03  1:07   ` Jack Lau
  2025-07-03 14:24     ` Timo Rothenpieler
  0 siblings, 1 reply; 38+ messages in thread
From: Jack Lau @ 2025-07-03  1:07 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> On Jul 3, 2025, at 00:56, Timo Rothenpieler <timo@rothenpieler.org> wrote:
> 
> ---
> libavformat/tls.c         | 9 ---------
> libavformat/tls_openssl.c | 3 +++
> 2 files changed, 3 insertions(+), 9 deletions(-)
> 
> diff --git a/libavformat/tls.c b/libavformat/tls.c
> index 5ec4cca58a..f888970969 100644
> --- a/libavformat/tls.c
> +++ b/libavformat/tls.c
> @@ -135,15 +135,6 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>     ret = ffurl_open_whitelist(c->is_dtls ? &c->udp : &c->tcp, buf, AVIO_FLAG_READ_WRITE,
>                                &parent->interrupt_callback, options,
>                                parent->protocol_whitelist, parent->protocol_blacklist, parent);
> -    if (c->is_dtls) {
> -        if (ret < 0) {
> -            av_log(c, AV_LOG_ERROR, "Failed to open udp://%s:%d\n", c->underlying_host, port);
> -            return ret;
> -        }
> -        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
> -        ff_socket_nonblock(ffurl_get_file_handle(c->udp), 1);
> -        c->udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
> -    }
>     return ret;
> }
> 
> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
> index 2a3905891d..d83fe602d5 100644
> --- a/libavformat/tls_openssl.c
> +++ b/libavformat/tls_openssl.c
> @@ -985,6 +985,9 @@ static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **
>             av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
>             return ret;
>         }
> +        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
> +        ff_socket_nonblock(ffurl_get_file_handle(p->tls_shared.udp), 1);
> +        p->tls_shared.udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
Since AVIO_FLAG_READ_WRITE was flagged, it can be just "p->tls_shared.udp->flags |= AVIO_FLAG_NONBLOCK;”
>     }
> 
>     /* Setup DTLS as passive, which is server role. */
> -- 
> 2.49.0
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe”.
Thanks

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 01/18] avformat/Makefile: don't hardcode openssl for whip muxer
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 01/18] avformat/Makefile: don't hardcode openssl for whip muxer Timo Rothenpieler
@ 2025-07-03 14:00   ` Steven Liu
  2025-07-03 20:20     ` Timo Rothenpieler
  0 siblings, 1 reply; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:00 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 00:57写道:
>
> ---
>  libavformat/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index 2e73f1325e..816eb9be4a 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -639,7 +639,7 @@ OBJS-$(CONFIG_WEBM_CHUNK_MUXER)          += webm_chunk.o
>  OBJS-$(CONFIG_WEBP_MUXER)                += webpenc.o
>  OBJS-$(CONFIG_WEBVTT_DEMUXER)            += webvttdec.o subtitles.o
>  OBJS-$(CONFIG_WEBVTT_MUXER)              += webvttenc.o
> -OBJS-$(CONFIG_WHIP_MUXER)                += whip.o avc.o http.o srtp.o tls_openssl.o
> +OBJS-$(CONFIG_WHIP_MUXER)                += whip.o avc.o http.o srtp.o
>  OBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood_aud.o
>  OBJS-$(CONFIG_WSAUD_MUXER)               += westwood_audenc.o
>  OBJS-$(CONFIG_WSD_DEMUXER)               += wsddec.o rawdec.o
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 02/18] avformat/whip: use av_dict_set_int for int
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 02/18] avformat/whip: use av_dict_set_int for int Timo Rothenpieler
@ 2025-07-03 14:01   ` Steven Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:01 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 00:57写道:
>
> ---
>  libavformat/whip.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index 5fdbd6949d..a6cdccc21c 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -1221,7 +1221,6 @@ static int ice_dtls_handshake(AVFormatContext *s)
>      int64_t starttime = av_gettime(), now;
>      WHIPContext *whip = s->priv_data;
>      AVDictionary *opts = NULL;
> -    char str[8];
>      char buf[256], *cert_buf = NULL, *key_buf = NULL;
>
>      if (whip->state < WHIP_STATE_UDP_CONNECTED || !whip->udp) {
> @@ -1288,8 +1287,7 @@ next_packet:
>                      whip->ice_ufrag_remote, whip->ice_ufrag_local, ret, ELAPSED(whip->whip_starttime, av_gettime()));
>
>                  ff_url_join(buf, sizeof(buf), "dtls", NULL, whip->ice_host, whip->ice_port, NULL);
> -                snprintf(str, sizeof(str), "%d", whip->pkt_size);
> -                av_dict_set(&opts, "mtu", str, 0);
> +                av_dict_set_int(&opts, "mtu", whip->pkt_size, 0);
>                  if (whip->cert_file) {
>                      av_dict_set(&opts, "cert_file", whip->cert_file, 0);
>                  } else
> @@ -1299,10 +1297,9 @@ next_packet:
>                      av_dict_set(&opts, "key_file", whip->key_file, 0);
>                  } else
>                      av_dict_set(&opts, "key_buf", whip->key_buf, 0);
> -
>                  av_dict_set(&opts, "fingerprint", whip->dtls_fingerprint, 0);
> -                av_dict_set(&opts, "use_external_udp", "1", 0);
> -                av_dict_set(&opts, "listen", "1", 0);
> +                av_dict_set_int(&opts, "use_external_udp", 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,
>                      &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 03/18] avformat/whip: don't leak options dict
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 03/18] avformat/whip: don't leak options dict Timo Rothenpieler
@ 2025-07-03 14:02   ` Steven Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:02 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 00:57写道:
>
> ---
>  libavformat/whip.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index a6cdccc21c..a1cf8aff1b 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -1303,6 +1303,7 @@ next_packet:
>                  /* If got the first binding response, start DTLS handshake. */
>                  ret = ffurl_open_whitelist(&whip->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)
>                      goto end;
>                  dtls_initialize(s);
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 04/18] avformat/whip: remove redundant WHIP: prefix from all logging
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 04/18] avformat/whip: remove redundant WHIP: prefix from all logging Timo Rothenpieler
@ 2025-07-03 14:02   ` Steven Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:02 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 00:58写道:
>
> ---
>  libavformat/whip.c | 150 ++++++++++++++++++++++-----------------------
>  1 file changed, 75 insertions(+), 75 deletions(-)
>
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index a1cf8aff1b..7cd3f48ba9 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -331,7 +331,7 @@ static av_cold int certificate_key_init(AVFormatContext *s)
>                                          whip->key_buf, sizeof(whip->key_buf),
>                                          whip->cert_buf, sizeof(whip->cert_buf),
>                                          &whip->dtls_fingerprint)) < 0) {
> -            av_log(s, AV_LOG_ERROR, "DTLS: Failed to read DTLS certificate from cert=%s, key=%s\n",
> +            av_log(s, AV_LOG_ERROR, "Failed to read DTLS certificate from cert=%s, key=%s\n",
>                  whip->cert_file, whip->key_file);
>              return ret;
>          }
> @@ -340,7 +340,7 @@ static av_cold int certificate_key_init(AVFormatContext *s)
>          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) {
> -            av_log(s, AV_LOG_ERROR, "DTLS: Failed to generate DTLS private key and certificate\n");
> +            av_log(s, AV_LOG_ERROR, "Failed to generate DTLS private key and certificate\n");
>              return ret;
>          }
>      }
> @@ -359,14 +359,14 @@ static int dtls_context_on_state(AVFormatContext *s, const char* type, const cha
>
>      if (state == DTLS_STATE_CLOSED) {
>          whip->dtls_closed = 1;
> -        av_log(whip, AV_LOG_VERBOSE, "WHIP: DTLS session closed, type=%s, desc=%s, elapsed=%dms\n",
> +        av_log(whip, AV_LOG_VERBOSE, "DTLS session closed, type=%s, desc=%s, elapsed=%dms\n",
>              type ? type : "", desc ? desc : "", ELAPSED(whip->whip_starttime, av_gettime()));
>          goto error;
>      }
>
>      if (state == DTLS_STATE_FAILED) {
>          whip->state = WHIP_STATE_FAILED;
> -        av_log(whip, AV_LOG_ERROR, "WHIP: DTLS session failed, type=%s, desc=%s\n",
> +        av_log(whip, AV_LOG_ERROR, "DTLS session failed, type=%s, desc=%s\n",
>              type ? type : "", desc ? desc : "");
>          whip->dtls_ret = AVERROR(EIO);
>          goto error;
> @@ -375,7 +375,7 @@ static int dtls_context_on_state(AVFormatContext *s, const char* type, const cha
>      if (state == DTLS_STATE_FINISHED && whip->state < WHIP_STATE_DTLS_FINISHED) {
>          whip->state = WHIP_STATE_DTLS_FINISHED;
>          whip->whip_dtls_time = av_gettime();
> -        av_log(whip, AV_LOG_VERBOSE, "WHIP: DTLS handshake is done, elapsed=%dms\n",
> +        av_log(whip, AV_LOG_VERBOSE, "DTLS handshake is done, elapsed=%dms\n",
>              ELAPSED(whip->whip_starttime, av_gettime()));
>          return ret;
>      }
> @@ -404,7 +404,7 @@ static av_cold int initialize(AVFormatContext *s)
>
>      ret = certificate_key_init(s);
>      if (ret < 0) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to init certificate and key\n");
> +        av_log(whip, AV_LOG_ERROR, "Failed to init certificate and key\n");
>          return ret;
>      }
>
> @@ -413,13 +413,13 @@ static av_cold int initialize(AVFormatContext *s)
>      av_lfg_init(&whip->rnd, seed);
>
>      if (whip->pkt_size < ideal_pkt_size)
> -        av_log(whip, AV_LOG_WARNING, "WHIP: pkt_size=%d(<%d) is too small, may cause packet loss\n",
> +        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 (whip->state < WHIP_STATE_INIT)
>          whip->state = WHIP_STATE_INIT;
>      whip->whip_init_time = av_gettime();
> -    av_log(whip, AV_LOG_VERBOSE, "WHIP: Init state=%d, handshake_timeout=%dms, pkt_size=%d, seed=%d, elapsed=%dms\n",
> +    av_log(whip, AV_LOG_VERBOSE, "Init state=%d, handshake_timeout=%dms, pkt_size=%d, seed=%d, elapsed=%dms\n",
>          whip->state, whip->handshake_timeout, whip->pkt_size, seed, ELAPSED(whip->whip_starttime, av_gettime()));
>
>      return 0;
> @@ -452,7 +452,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, "WHIP: Unable to parse profile from empty extradata=%p, size=%d\n",
> +        av_log(whip, AV_LOG_ERROR, "Unable to parse profile from empty extradata=%p, size=%d\n",
>              par->extradata, par->extradata_size);
>          return AVERROR(EINVAL);
>      }
> @@ -466,12 +466,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, "WHIP: Failed to decode SPS, state=%x, size=%d\n",
> +                av_log(whip, AV_LOG_ERROR, "Failed to decode SPS, state=%x, size=%d\n",
>                      state, (int)(r1 - r));
>                  return ret;
>              }
>
> -            av_log(whip, AV_LOG_VERBOSE, "WHIP: Parse profile=%d, level=%d from SPS\n",
> +            av_log(whip, 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;
> @@ -515,62 +515,62 @@ static int parse_codec(AVFormatContext *s)
>          switch (par->codec_type) {
>          case AVMEDIA_TYPE_VIDEO:
>              if (whip->video_par) {
> -                av_log(whip, AV_LOG_ERROR, "WHIP: Only one video stream is supported by RTC\n");
> +                av_log(whip, AV_LOG_ERROR, "Only one video stream is supported by RTC\n");
>                  return AVERROR(EINVAL);
>              }
>              whip->video_par = par;
>
>              if (par->codec_id != AV_CODEC_ID_H264) {
> -                av_log(whip, AV_LOG_ERROR, "WHIP: Unsupported video codec %s by RTC, choose h264\n",
> +                av_log(whip, 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, "WHIP: Unsupported B frames by RTC\n");
> +                av_log(whip, 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, "WHIP: Failed to parse SPS/PPS from extradata\n");
> +                av_log(whip, 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, "WHIP: No profile found in extradata, consider baseline\n");
> +                av_log(whip, 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, "WHIP: No level found in extradata, consider 3.1\n");
> +                av_log(whip, 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, "WHIP: Only one audio stream is supported by RTC\n");
> +                av_log(whip, AV_LOG_ERROR, "Only one audio stream is supported by RTC\n");
>                  return AVERROR(EINVAL);
>              }
>              whip->audio_par = par;
>
>              if (par->codec_id != AV_CODEC_ID_OPUS) {
> -                av_log(whip, AV_LOG_ERROR, "WHIP: Unsupported audio codec %s by RTC, choose opus\n",
> +                av_log(whip, 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, "WHIP: Unsupported audio channels %d by RTC, choose stereo\n",
> +                av_log(whip, 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, "WHIP: Unsupported audio sample rate %d by RTC, choose 48000\n", par->sample_rate);
> +                av_log(whip, 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, "WHIP: Codec type '%s' for stream %d is not supported by RTC\n",
> +            av_log(whip, 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;
>          }
> @@ -598,7 +598,7 @@ static int generate_sdp_offer(AVFormatContext *s)
>      av_bprint_init(&bp, 1, MAX_SDP_SIZE);
>
>      if (whip->sdp_offer) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: SDP offer is already set\n");
> +        av_log(whip, AV_LOG_ERROR, "SDP offer is already set\n");
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
> @@ -696,7 +696,7 @@ static int generate_sdp_offer(AVFormatContext *s)
>      }
>
>      if (!av_bprint_is_complete(&bp)) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Offer exceed max %d, %s\n", MAX_SDP_SIZE, bp.str);
> +        av_log(whip, AV_LOG_ERROR, "Offer exceed max %d, %s\n", MAX_SDP_SIZE, bp.str);
>          ret = AVERROR(EIO);
>          goto end;
>      }
> @@ -710,7 +710,7 @@ static int generate_sdp_offer(AVFormatContext *s)
>      if (whip->state < WHIP_STATE_OFFER)
>          whip->state = WHIP_STATE_OFFER;
>      whip->whip_offer_time = av_gettime();
> -    av_log(whip, AV_LOG_VERBOSE, "WHIP: Generated state=%d, offer: %s\n", whip->state, whip->sdp_offer);
> +    av_log(whip, AV_LOG_VERBOSE, "Generated state=%d, offer: %s\n", whip->state, whip->sdp_offer);
>
>  end:
>      av_bprint_finalize(&bp, NULL);
> @@ -738,14 +738,14 @@ 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, "WHIP: Protocol %s is not supported by RTC, choose http, url is %s\n",
> +        av_log(whip, 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, "WHIP: No offer to exchange\n");
> +        av_log(whip, AV_LOG_ERROR, "No offer to exchange\n");
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
> @@ -754,7 +754,7 @@ static int exchange_sdp(AVFormatContext *s)
>      if (whip->authorization)
>          ret += snprintf(buf + ret, sizeof(buf) - ret, "Authorization: Bearer %s\r\n", whip->authorization);
>      if (ret <= 0 || ret >= sizeof(buf)) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to generate headers, size=%d, %s\n", ret, buf);
> +        av_log(whip, AV_LOG_ERROR, "Failed to generate headers, size=%d, %s\n", ret, buf);
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
> @@ -773,7 +773,7 @@ static int exchange_sdp(AVFormatContext *s)
>      ret = ffurl_open_whitelist(&whip_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, "WHIP: Failed to request url=%s, offer: %s\n", s->url, whip->sdp_offer);
> +        av_log(whip, AV_LOG_ERROR, "Failed to request url=%s, offer: %s\n", s->url, whip->sdp_offer);
>          goto end;
>      }
>
> @@ -793,21 +793,21 @@ static int exchange_sdp(AVFormatContext *s)
>              break;
>          }
>          if (ret <= 0) {
> -            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to read response from url=%s, offer is %s, answer is %s\n",
> +            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);
>              goto end;
>          }
>
>          av_bprintf(&bp, "%.*s", ret, buf);
>          if (!av_bprint_is_complete(&bp)) {
> -            av_log(whip, AV_LOG_ERROR, "WHIP: Answer exceed max size %d, %.*s, %s\n", MAX_SDP_SIZE, ret, buf, bp.str);
> +            av_log(whip, 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, "WHIP: Invalid answer: %s\n", bp.str);
> +        av_log(whip, AV_LOG_ERROR, "Invalid answer: %s\n", bp.str);
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
> @@ -820,7 +820,7 @@ static int exchange_sdp(AVFormatContext *s)
>
>      if (whip->state < WHIP_STATE_ANSWER)
>          whip->state = WHIP_STATE_ANSWER;
> -    av_log(whip, AV_LOG_VERBOSE, "WHIP: Got state=%d, answer: %s\n", whip->state, whip->sdp_answer);
> +    av_log(whip, AV_LOG_VERBOSE, "Got state=%d, answer: %s\n", whip->state, whip->sdp_answer);
>
>  end:
>      ffurl_closep(&whip_uc);
> @@ -851,7 +851,7 @@ static int parse_answer(AVFormatContext *s)
>      WHIPContext *whip = s->priv_data;
>
>      if (!whip->sdp_answer || !strlen(whip->sdp_answer)) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: No answer to parse\n");
> +        av_log(whip, AV_LOG_ERROR, "No answer to parse\n");
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
> @@ -881,14 +881,14 @@ static int parse_answer(AVFormatContext *s)
>                  int priority, port;
>                  ret = sscanf(ptr, "%16s %d %128s %d typ host", protocol, &priority, host, &port);
>                  if (ret != 4) {
> -                    av_log(whip, AV_LOG_ERROR, "WHIP: Failed %d to parse line %d %s from %s\n",
> +                    av_log(whip, AV_LOG_ERROR, "Failed %d to parse line %d %s from %s\n",
>                          ret, i, line, whip->sdp_answer);
>                      ret = AVERROR(EIO);
>                      goto end;
>                  }
>
>                  if (av_strcasecmp(protocol, "udp")) {
> -                    av_log(whip, AV_LOG_ERROR, "WHIP: Protocol %s is not supported by RTC, choose udp, line %d %s of %s\n",
> +                    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);
>                      ret = AVERROR(EIO);
>                      goto end;
> @@ -906,19 +906,19 @@ static int parse_answer(AVFormatContext *s)
>      }
>
>      if (!whip->ice_pwd_remote || !strlen(whip->ice_pwd_remote)) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: No remote ice pwd parsed from %s\n", whip->sdp_answer);
> +        av_log(whip, AV_LOG_ERROR, "No remote ice pwd parsed from %s\n", whip->sdp_answer);
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
>
>      if (!whip->ice_ufrag_remote || !strlen(whip->ice_ufrag_remote)) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: No remote ice ufrag parsed from %s\n", whip->sdp_answer);
> +        av_log(whip, AV_LOG_ERROR, "No remote ice ufrag parsed from %s\n", whip->sdp_answer);
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
>
>      if (!whip->ice_protocol || !whip->ice_host || !whip->ice_port) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: No ice candidate parsed from %s\n", whip->sdp_answer);
> +        av_log(whip, AV_LOG_ERROR, "No ice candidate parsed from %s\n", whip->sdp_answer);
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
> @@ -926,7 +926,7 @@ static int parse_answer(AVFormatContext *s)
>      if (whip->state < WHIP_STATE_NEGOTIATED)
>          whip->state = WHIP_STATE_NEGOTIATED;
>      whip->whip_answer_time = av_gettime();
> -    av_log(whip, AV_LOG_VERBOSE, "WHIP: SDP state=%d, offer=%luB, answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\n",
> +    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%luB, answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\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()));
>
> @@ -977,7 +977,7 @@ static int ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in
>      /* 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);
>      if (ret <= 0 || ret >= sizeof(username)) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to build username %s:%s, max=%lu, ret=%d\n",
> +        av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s, max=%lu, ret=%d\n",
>              whip->ice_ufrag_remote, whip->ice_ufrag_local, sizeof(username), ret);
>          ret = AVERROR(EIO);
>          goto end;
> @@ -1046,7 +1046,7 @@ static int ice_create_response(AVFormatContext *s, char *tid, int tid_size, uint
>      WHIPContext *whip = s->priv_data;
>
>      if (tid_size != 12) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Invalid transaction ID size. Expected 12, got %d\n", tid_size);
> +        av_log(whip, AV_LOG_ERROR, "Invalid transaction ID size. Expected 12, got %d\n", tid_size);
>          return AVERROR(EINVAL);
>      }
>
> @@ -1149,7 +1149,7 @@ static int ice_handle_binding_request(AVFormatContext *s, char *buf, int buf_siz
>          return ret;
>
>      if (buf_size < ICE_STUN_HEADER_SIZE) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Invalid STUN message, expected at least %d, got %d\n",
> +        av_log(whip, AV_LOG_ERROR, "Invalid STUN message, expected at least %d, got %d\n",
>              ICE_STUN_HEADER_SIZE, buf_size);
>          return AVERROR(EINVAL);
>      }
> @@ -1160,13 +1160,13 @@ static int ice_handle_binding_request(AVFormatContext *s, char *buf, int buf_siz
>      /* Build the STUN binding response. */
>      ret = ice_create_response(s, tid, sizeof(tid), whip->buf, sizeof(whip->buf), &size);
>      if (ret < 0) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to create STUN binding response, size=%d\n", size);
> +        av_log(whip, AV_LOG_ERROR, "Failed to create STUN binding response, size=%d\n", size);
>          return ret;
>      }
>
>      ret = ffurl_write(whip->udp, whip->buf, size);
>      if (ret < 0) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to send STUN binding response, size=%d\n", size);
> +        av_log(whip, AV_LOG_ERROR, "Failed to send STUN binding response, size=%d\n", size);
>          return ret;
>      }
>
> @@ -1196,7 +1196,7 @@ static int udp_connect(AVFormatContext *s)
>      ret = ffurl_open_whitelist(&whip->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, "WHIP: Failed to connect udp://%s:%d\n", whip->ice_host, whip->ice_port);
> +        av_log(whip, AV_LOG_ERROR, "Failed to connect udp://%s:%d\n", whip->ice_host, whip->ice_port);
>          goto end;
>      }
>
> @@ -1207,7 +1207,7 @@ static int udp_connect(AVFormatContext *s)
>      if (whip->state < WHIP_STATE_UDP_CONNECTED)
>          whip->state = WHIP_STATE_UDP_CONNECTED;
>      whip->whip_udp_time = av_gettime();
> -    av_log(whip, AV_LOG_VERBOSE, "WHIP: UDP state=%d, elapsed=%dms, connected to udp://%s:%d\n",
> +    av_log(whip, AV_LOG_VERBOSE, "UDP state=%d, elapsed=%dms, connected to udp://%s:%d\n",
>          whip->state, ELAPSED(whip->whip_starttime, av_gettime()), whip->ice_host, whip->ice_port);
>
>  end:
> @@ -1224,7 +1224,7 @@ static int ice_dtls_handshake(AVFormatContext *s)
>      char buf[256], *cert_buf = NULL, *key_buf = NULL;
>
>      if (whip->state < WHIP_STATE_UDP_CONNECTED || !whip->udp) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: UDP not connected, state=%d, udp=%p\n", whip->state, whip->udp);
> +        av_log(whip, AV_LOG_ERROR, "UDP not connected, state=%d, udp=%p\n", whip->state, whip->udp);
>          return AVERROR(EINVAL);
>      }
>
> @@ -1233,13 +1233,13 @@ static int ice_dtls_handshake(AVFormatContext *s)
>              /* Build the STUN binding request. */
>              ret = ice_create_request(s, whip->buf, sizeof(whip->buf), &size);
>              if (ret < 0) {
> -                av_log(whip, AV_LOG_ERROR, "WHIP: Failed to create STUN binding request, size=%d\n", size);
> +                av_log(whip, AV_LOG_ERROR, "Failed to create STUN binding request, size=%d\n", size);
>                  goto end;
>              }
>
>              ret = ffurl_write(whip->udp, whip->buf, size);
>              if (ret < 0) {
> -                av_log(whip, AV_LOG_ERROR, "WHIP: Failed to send STUN binding request, size=%d\n", size);
> +                av_log(whip, AV_LOG_ERROR, "Failed to send STUN binding request, size=%d\n", size);
>                  goto end;
>              }
>
> @@ -1254,7 +1254,7 @@ next_packet:
>
>          now = av_gettime();
>          if (now - starttime >= whip->handshake_timeout * 1000) {
> -            av_log(whip, AV_LOG_ERROR, "WHIP: DTLS handshake timeout=%dms, cost=%dms, elapsed=%dms, state=%d\n",
> +            av_log(whip, AV_LOG_ERROR, "DTLS handshake timeout=%dms, cost=%dms, elapsed=%dms, state=%d\n",
>                  whip->handshake_timeout, ELAPSED(starttime, now), ELAPSED(whip->whip_starttime, now), whip->state);
>              ret = AVERROR(ETIMEDOUT);
>              goto end;
> @@ -1269,7 +1269,7 @@ next_packet:
>                  av_usleep(5 * 1000);
>                  continue;
>              }
> -            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to read message\n");
> +            av_log(whip, AV_LOG_ERROR, "Failed to read message\n");
>              goto end;
>          }
>
> @@ -1282,7 +1282,7 @@ next_packet:
>              if (whip->state < WHIP_STATE_ICE_CONNECTED) {
>                  whip->state = WHIP_STATE_ICE_CONNECTED;
>                  whip->whip_ice_time = av_gettime();
> -                av_log(whip, AV_LOG_VERBOSE, "WHIP: ICE STUN ok, state=%d, url=udp://%s:%d, location=%s, username=%s:%s, res=%dB, elapsed=%dms\n",
> +                av_log(whip, AV_LOG_VERBOSE, "ICE STUN ok, state=%d, url=udp://%s:%d, location=%s, username=%s:%s, res=%dB, elapsed=%dms\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()));
>
> @@ -1381,20 +1381,20 @@ 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, "WHIP: Failed to encode send key\n");
> +        av_log(whip, 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);
>      if (ret < 0) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to set crypto for audio send\n");
> +        av_log(whip, AV_LOG_ERROR, "Failed to set crypto for audio send\n");
>          goto end;
>      }
>
>      ret = ff_srtp_set_crypto(&whip->srtp_video_send, suite, buf);
>      if (ret < 0) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to set crypto for video send\n");
> +        av_log(whip, AV_LOG_ERROR, "Failed to set crypto for video send\n");
>          goto end;
>      }
>
> @@ -1406,21 +1406,21 @@ static int setup_srtp(AVFormatContext *s)
>
>      /* Setup SRTP context for incoming packets */
>      if (!av_base64_encode(buf, sizeof(buf), recv_key, sizeof(recv_key))) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to encode recv key\n");
> +        av_log(whip, AV_LOG_ERROR, "Failed to encode recv key\n");
>          ret = AVERROR(EIO);
>          goto end;
>      }
>
>      ret = ff_srtp_set_crypto(&whip->srtp_recv, suite, buf);
>      if (ret < 0) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to set crypto for recv\n");
> +        av_log(whip, 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();
> -    av_log(whip, AV_LOG_VERBOSE, "WHIP: SRTP setup done, state=%d, suite=%s, key=%luB, elapsed=%dms\n",
> +    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%luB, elapsed=%dms\n",
>          whip->state, suite, sizeof(send_key), ELAPSED(whip->whip_starttime, av_gettime()));
>
>  end:
> @@ -1459,13 +1459,13 @@ static int on_rtp_write_packet(void *opaque, const uint8_t *buf, int buf_size)
>      /* Encrypt by SRTP and send out. */
>      cipher_size = ff_srtp_encrypt(srtp, buf, buf_size, whip->buf, sizeof(whip->buf));
>      if (cipher_size <= 0 || cipher_size < buf_size) {
> -        av_log(whip, AV_LOG_WARNING, "WHIP: Failed to encrypt packet=%dB, cipher=%dB\n", buf_size, cipher_size);
> +        av_log(whip, 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);
>      if (ret < 0) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to write packet=%dB, ret=%d\n", cipher_size, ret);
> +        av_log(whip, AV_LOG_ERROR, "Failed to write packet=%dB, ret=%d\n", cipher_size, ret);
>          return ret;
>      }
>
> @@ -1494,7 +1494,7 @@ static int create_rtp_muxer(AVFormatContext *s)
>
>      const AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
>      if (!rtp_format) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to guess rtp muxer\n");
> +        av_log(whip, AV_LOG_ERROR, "Failed to guess rtp muxer\n");
>          ret = AVERROR(ENOSYS);
>          goto end;
>      }
> @@ -1562,7 +1562,7 @@ static int create_rtp_muxer(AVFormatContext *s)
>
>          ret = avformat_write_header(rtp_ctx, &opts);
>          if (ret < 0) {
> -            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to write rtp header\n");
> +            av_log(whip, AV_LOG_ERROR, "Failed to write rtp header\n");
>              goto end;
>          }
>
> @@ -1574,7 +1574,7 @@ static int create_rtp_muxer(AVFormatContext *s)
>
>      if (whip->state < WHIP_STATE_READY)
>          whip->state = WHIP_STATE_READY;
> -    av_log(whip, AV_LOG_INFO, "WHIP: Muxer state=%d, buffer_size=%d, max_packet_size=%d, "
> +    av_log(whip, AV_LOG_INFO, "Muxer state=%d, buffer_size=%d, max_packet_size=%d, "
>                             "elapsed=%dms(init:%d,offer:%d,answer:%d,udp:%d,ice:%d,dtls:%d,srtp:%d)\n",
>          whip->state, buffer_size, max_packet_size, ELAPSED(whip->whip_starttime, av_gettime()),
>          ELAPSED(whip->whip_starttime,   whip->whip_init_time),
> @@ -1616,7 +1616,7 @@ static int dispose_session(AVFormatContext *s)
>      if (whip->authorization)
>          ret += snprintf(buf + ret, sizeof(buf) - ret, "Authorization: Bearer %s\r\n", whip->authorization);
>      if (ret <= 0 || ret >= sizeof(buf)) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to generate headers, size=%d, %s\n", ret, buf);
> +        av_log(whip, AV_LOG_ERROR, "Failed to generate headers, size=%d, %s\n", ret, buf);
>          ret = AVERROR(EINVAL);
>          goto end;
>      }
> @@ -1627,7 +1627,7 @@ static int dispose_session(AVFormatContext *s)
>      ret = ffurl_open_whitelist(&whip_uc, whip->whip_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, "WHIP: Failed to DELETE url=%s\n", whip->whip_resource_url);
> +        av_log(whip, AV_LOG_ERROR, "Failed to DELETE url=%s\n", whip->whip_resource_url);
>          goto end;
>      }
>
> @@ -1638,12 +1638,12 @@ static int dispose_session(AVFormatContext *s)
>              break;
>          }
>          if (ret < 0) {
> -            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to read response from DELETE url=%s\n", whip->whip_resource_url);
> +            av_log(whip, AV_LOG_ERROR, "Failed to read response from DELETE url=%s\n", whip->whip_resource_url);
>              goto end;
>          }
>      }
>
> -    av_log(whip, AV_LOG_INFO, "WHIP: Dispose resource %s ok\n", whip->whip_resource_url);
> +    av_log(whip, AV_LOG_INFO, "Dispose resource %s ok\n", whip->whip_resource_url);
>
>  end:
>      ffurl_closep(&whip_uc);
> @@ -1789,18 +1789,18 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt)
>      if (ret > 0) {
>          if (is_dtls_packet(whip->buf, ret)) {
>              if ((ret = ffurl_write(whip->dtls_uc, whip->buf, ret)) < 0) {
> -                av_log(whip, AV_LOG_ERROR, "WHIP: Failed to handle DTLS message\n");
> +                av_log(whip, AV_LOG_ERROR, "Failed to handle DTLS message\n");
>                  goto end;
>              }
>          }
>      } else if (ret != AVERROR(EAGAIN)) {
> -        av_log(whip, AV_LOG_ERROR, "WHIP: Failed to read from UDP socket\n");
> +        av_log(whip, AV_LOG_ERROR, "Failed to read from UDP socket\n");
>          goto end;
>      }
>
>      if (whip->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, "WHIP: Failed to insert SPS/PPS before IDR\n");
> +            av_log(whip, AV_LOG_ERROR, "Failed to insert SPS/PPS before IDR\n");
>              goto end;
>          }
>      }
> @@ -1808,10 +1808,10 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt)
>      ret = ff_write_chained(rtp_ctx, 0, pkt, s, 0);
>      if (ret < 0) {
>          if (ret == AVERROR(EINVAL)) {
> -            av_log(whip, AV_LOG_WARNING, "WHIP: Ignore failed to write packet=%dB, ret=%d\n", pkt->size, ret);
> +            av_log(whip, AV_LOG_WARNING, "Ignore failed to write packet=%dB, ret=%d\n", pkt->size, ret);
>              ret = 0;
>          } else
> -            av_log(whip, AV_LOG_ERROR, "WHIP: Failed to write packet, size=%d\n", pkt->size);
> +            av_log(whip, AV_LOG_ERROR, "Failed to write packet, size=%d\n", pkt->size);
>          goto end;
>      }
>
> @@ -1832,7 +1832,7 @@ static av_cold void whip_deinit(AVFormatContext *s)
>
>      ret = dispose_session(s);
>      if (ret < 0)
> -        av_log(whip, AV_LOG_WARNING, "WHIP: Failed to dispose resource, ret=%d\n", ret);
> +        av_log(whip, 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;
> @@ -1879,7 +1879,7 @@ static int whip_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket
>          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, "WHIP: Enable BSF h264_mp4toannexb, packet=[%x %x %x %x %x ...], extradata_isom=%d\n",
> +            av_log(whip, 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;
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".


LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t Timo Rothenpieler
@ 2025-07-03 14:03   ` Steven Liu
  2025-07-03 17:16   ` Andreas Rheinhardt
  1 sibling, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:03 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 00:59写道:
>
> ---
>  libavformat/whip.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index 7cd3f48ba9..71c667cd31 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -926,7 +926,7 @@ static int parse_answer(AVFormatContext *s)
>      if (whip->state < WHIP_STATE_NEGOTIATED)
>          whip->state = WHIP_STATE_NEGOTIATED;
>      whip->whip_answer_time = av_gettime();
> -    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%luB, answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\n",
> +    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%zuB, answer=%zuB, ufrag=%s, pwd=%zuB, transport=%s://%s:%d, elapsed=%dms\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()));
>
> @@ -977,7 +977,7 @@ static int ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in
>      /* 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);
>      if (ret <= 0 || ret >= sizeof(username)) {
> -        av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s, max=%lu, ret=%d\n",
> +        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);
>          ret = AVERROR(EIO);
>          goto end;
> @@ -1420,7 +1420,7 @@ static int setup_srtp(AVFormatContext *s)
>      if (whip->state < WHIP_STATE_SRTP_FINISHED)
>          whip->state = WHIP_STATE_SRTP_FINISHED;
>      whip->whip_srtp_time = av_gettime();
> -    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%luB, elapsed=%dms\n",
> +    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%zuB, elapsed=%dms\n",
>          whip->state, suite, sizeof(send_key), ELAPSED(whip->whip_starttime, av_gettime()));
>
>  end:
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 06/18] avformat/tls: use non protocol specific error message
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 06/18] avformat/tls: use non protocol specific error message Timo Rothenpieler
@ 2025-07-03 14:03   ` Steven Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:03 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 00:59写道:
>
> ---
>  libavformat/tls.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/libavformat/tls.c b/libavformat/tls.c
> index da53835200..018b24cd48 100644
> --- a/libavformat/tls.c
> +++ b/libavformat/tls.c
> @@ -137,7 +137,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>                                 parent->protocol_whitelist, parent->protocol_blacklist, parent);
>      if (c->is_dtls) {
>          if (ret < 0) {
> -            av_log(c, AV_LOG_ERROR, "WHIP: Failed to connect udp://%s:%d\n", c->underlying_host, port);
> +            av_log(c, AV_LOG_ERROR, "Failed to open udp://%s:%d\n", c->underlying_host, port);
>              return ret;
>          }
>          /* Make the socket non-blocking, set to READ and WRITE mode after connected */
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".


LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 07/18] avformat/tls: don't use http_proxy for udp sockets
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 07/18] avformat/tls: don't use http_proxy for udp sockets Timo Rothenpieler
@ 2025-07-03 14:04   ` Steven Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:04 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 01:09写道:
>
> ---
>  libavformat/tls.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/libavformat/tls.c b/libavformat/tls.c
> index 018b24cd48..5ec4cca58a 100644
> --- a/libavformat/tls.c
> +++ b/libavformat/tls.c
> @@ -114,7 +114,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>                  proxy_path && av_strstart(proxy_path, "http://", NULL);
>      freeenv_utf8(env_no_proxy);
>
> -    if (use_proxy) {
> +    if (!c->is_dtls && use_proxy) {
>          char proxy_host[200], proxy_auth[200], dest[200];
>          int proxy_port;
>          av_url_split(NULL, 0, proxy_auth, sizeof(proxy_auth),
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 09/18] avformat/udp: don't override 0 localport
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 09/18] avformat/udp: don't override 0 localport Timo Rothenpieler
@ 2025-07-03 14:05   ` Steven Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:05 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 01:09写道:
>
> ---
>  libavformat/udp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/libavformat/udp.c b/libavformat/udp.c
> index c1ebdd1222..30f075de8e 100644
> --- a/libavformat/udp.c
> +++ b/libavformat/udp.c
> @@ -780,7 +780,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
>              goto fail;
>      }
>
> -    if ((s->is_multicast || s->local_port <= 0) && (h->flags & AVIO_FLAG_READ))
> +    if ((s->is_multicast || s->local_port < 0) && (h->flags & AVIO_FLAG_READ))
>          s->local_port = port;
>
>      udp_fd = udp_socket_create(h, &my_addr, &len, s->localaddr);
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 10/18] avformat/tls: fix udp init
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 10/18] avformat/tls: fix udp init Timo Rothenpieler
@ 2025-07-03 14:06   ` Steven Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:06 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 01:09写道:
>
> ---
>  libavformat/tls.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/libavformat/tls.c b/libavformat/tls.c
> index f888970969..bd9c05e6dc 100644
> --- a/libavformat/tls.c
> +++ b/libavformat/tls.c
> @@ -81,7 +81,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>      if (ret < 0)
>          return ret;
>
> -    if (c->listen)
> +    if (c->listen && !c->is_dtls)
>          snprintf(opts, sizeof(opts), "?listen=1");
>
>      av_url_split(NULL, 0, NULL, 0, c->underlying_host, sizeof(c->underlying_host), &port, NULL, 0, uri);
> @@ -95,7 +95,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>              c->listen = 1;
>      }
>
> -    ff_url_join(buf, sizeof(buf), c->is_dtls ? "udp" : "tcp", NULL, c->underlying_host, port, "%s", p);
> +    ff_url_join(buf, sizeof(buf), c->is_dtls ? "udp" : "tcp", NULL, (c->is_dtls && c->listen) ? "" : c->underlying_host, port, "%s", p);
>
>      hints.ai_flags = AI_NUMERICHOST;
>      if (!getaddrinfo(c->underlying_host, NULL, &hints, &ai)) {
> @@ -127,7 +127,13 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>
>      freeenv_utf8(env_http_proxy);
>      if (c->is_dtls) {
> -        av_dict_set_int(options, "connect", 1, 0);
> +        if (c->listen) {
> +            av_dict_set_int(options, "localport", port, 0);
> +            av_dict_set(options, "localaddr", c->underlying_host, 0);
> +        } else {
> +            av_dict_set_int(options, "localport", 0, 0);
> +            av_dict_set_int(options, "connect", 1, 0);
> +        }
>          av_dict_set_int(options, "fifo_size", 0, 0);
>          /* Set the max packet size to the buffer size. */
>          av_dict_set_int(options, "pkt_size", c->mtu, 0);
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 12/18] avformat/udp: separate rx and tx fifo
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 12/18] avformat/udp: separate rx and tx fifo Timo Rothenpieler
@ 2025-07-03 14:07   ` Steven Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Steven Liu @ 2025-07-03 14:07 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler

Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 01:04写道:
>
> ---
>  libavformat/udp.c | 49 +++++++++++++++++++++++++++--------------------
>  1 file changed, 28 insertions(+), 21 deletions(-)
>
> diff --git a/libavformat/udp.c b/libavformat/udp.c
> index 7d64ff07ed..e02eff0f33 100644
> --- a/libavformat/udp.c
> +++ b/libavformat/udp.c
> @@ -96,7 +96,8 @@ typedef struct UDPContext {
>
>      /* Circular Buffer variables for use in UDP receive code */
>      int circular_buffer_size;
> -    AVFifo *fifo;
> +    AVFifo *rx_fifo;
> +    AVFifo *tx_fifo;
>      int circular_buffer_error;
>      int64_t bitrate; /* number of bits to send per second */
>      int64_t burst_bits;
> @@ -527,7 +528,7 @@ static void *circular_buffer_task_rx( void *_URLContext)
>          AV_WL32(s->tmp, len);
>          memcpy(s->tmp + 4, &addr, sizeof(addr));
>
> -        if (av_fifo_can_write(s->fifo) < len + header_sz) {
> +        if (av_fifo_can_write(s->rx_fifo) < len + header_sz) {
>              /* No Space left */
>              if (s->overrun_nonfatal) {
>                  av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
> @@ -541,7 +542,7 @@ static void *circular_buffer_task_rx( void *_URLContext)
>                  goto end;
>              }
>          }
> -        av_fifo_write(s->fifo, s->tmp, len + header_sz);
> +        av_fifo_write(s->rx_fifo, s->tmp, len + header_sz);
>          pthread_cond_signal(&s->cond);
>      }
>
> @@ -577,22 +578,22 @@ static void *circular_buffer_task_tx( void *_URLContext)
>          uint8_t tmp[4];
>          int64_t timestamp;
>
> -        len = av_fifo_can_read(s->fifo);
> +        len = av_fifo_can_read(s->tx_fifo);
>
>          while (len<4) {
>              if (s->close_req)
>                  goto end;
>              pthread_cond_wait(&s->cond, &s->mutex);
> -            len = av_fifo_can_read(s->fifo);
> +            len = av_fifo_can_read(s->tx_fifo);
>          }
>
> -        av_fifo_read(s->fifo, tmp, 4);
> +        av_fifo_read(s->tx_fifo, tmp, 4);
>          len = AV_RL32(tmp);
>
>          av_assert0(len >= 0);
>          av_assert0(len <= sizeof(s->tmp));
>
> -        av_fifo_read(s->fifo, s->tmp, len);
> +        av_fifo_read(s->tx_fifo, s->tmp, len);
>
>          pthread_mutex_unlock(&s->mutex);
>
> @@ -944,11 +945,15 @@ static int udp_open(URLContext *h, const char *uri, int flags)
>
>      if ((!is_output && s->circular_buffer_size) || (is_output && s->bitrate && s->circular_buffer_size)) {
>          /* start the task going */
> -        s->fifo = av_fifo_alloc2(s->circular_buffer_size, 1, 0);
> -        if (!s->fifo) {
> +        AVFifo *fifo = av_fifo_alloc2(s->circular_buffer_size, 1, 0);
> +        if (!fifo) {
>              ret = AVERROR(ENOMEM);
>              goto fail;
>          }
> +        if (is_output)
> +            s->tx_fifo = fifo;
> +        else
> +            s->rx_fifo = fifo;
>          ret = pthread_mutex_init(&s->mutex, NULL);
>          if (ret != 0) {
>              av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret));
> @@ -981,7 +986,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
>   fail:
>      if (udp_fd >= 0)
>          closesocket(udp_fd);
> -    av_fifo_freep2(&s->fifo);
> +    av_fifo_freep2(&s->rx_fifo);
> +    av_fifo_freep2(&s->tx_fifo);
>      ff_ip_reset_filters(&s->filters);
>      return ret;
>  }
> @@ -1004,23 +1010,23 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
>  #if HAVE_PTHREAD_CANCEL
>      int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
>
> -    if (s->fifo) {
> +    if (s->rx_fifo) {
>          pthread_mutex_lock(&s->mutex);
>          do {
> -            avail = av_fifo_can_read(s->fifo);
> +            avail = av_fifo_can_read(s->rx_fifo);
>              if (avail) { // >=size) {
>                  uint8_t tmp[4];
>
> -                av_fifo_read(s->fifo, tmp, 4);
> -                av_fifo_read(s->fifo, &s->last_recv_addr, sizeof(s->last_recv_addr));
> +                av_fifo_read(s->rx_fifo, tmp, 4);
> +                av_fifo_read(s->rx_fifo, &s->last_recv_addr, sizeof(s->last_recv_addr));
>                  avail = AV_RL32(tmp);
>                  if(avail > size){
>                      av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
>                      avail = size;
>                  }
>
> -                av_fifo_read(s->fifo, buf, avail);
> -                av_fifo_drain2(s->fifo, AV_RL32(tmp) - avail);
> +                av_fifo_read(s->rx_fifo, buf, avail);
> +                av_fifo_drain2(s->rx_fifo, AV_RL32(tmp) - avail);
>                  pthread_mutex_unlock(&s->mutex);
>                  return avail;
>              } else if(s->circular_buffer_error){
> @@ -1066,7 +1072,7 @@ static int udp_write(URLContext *h, const uint8_t *buf, int size)
>      int ret;
>
>  #if HAVE_PTHREAD_CANCEL
> -    if (s->fifo) {
> +    if (s->tx_fifo) {
>          uint8_t tmp[4];
>
>          pthread_mutex_lock(&s->mutex);
> @@ -1081,14 +1087,14 @@ static int udp_write(URLContext *h, const uint8_t *buf, int size)
>              return err;
>          }
>
> -        if (av_fifo_can_write(s->fifo) < size + 4) {
> +        if (av_fifo_can_write(s->tx_fifo) < size + 4) {
>              /* What about a partial packet tx ? */
>              pthread_mutex_unlock(&s->mutex);
>              return AVERROR(ENOMEM);
>          }
>          AV_WL32(tmp, size);
> -        av_fifo_write(s->fifo, tmp, 4); /* size of packet */
> -        av_fifo_write(s->fifo, buf, size); /* the data */
> +        av_fifo_write(s->tx_fifo, tmp, 4); /* size of packet */
> +        av_fifo_write(s->tx_fifo, buf, size); /* the data */
>          pthread_cond_signal(&s->cond);
>          pthread_mutex_unlock(&s->mutex);
>          return size;
> @@ -1150,7 +1156,8 @@ static int udp_close(URLContext *h)
>      }
>  #endif
>      closesocket(s->udp_fd);
> -    av_fifo_freep2(&s->fifo);
> +    av_fifo_freep2(&s->rx_fifo);
> +    av_fifo_freep2(&s->tx_fifo);
>      ff_ip_reset_filters(&s->filters);
>      return 0;
>  }
> --
> 2.49.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

LGTM

Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code
  2025-07-03  1:07   ` Jack Lau
@ 2025-07-03 14:24     ` Timo Rothenpieler
  2025-07-03 15:22       ` Jack Lau
  0 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-03 14:24 UTC (permalink / raw)
  To: ffmpeg-devel

On 03.07.2025 03:07, Jack Lau wrote:
> 
> 
>> On Jul 3, 2025, at 00:56, Timo Rothenpieler <timo@rothenpieler.org> wrote:
>>
>> ---
>> libavformat/tls.c         | 9 ---------
>> libavformat/tls_openssl.c | 3 +++
>> 2 files changed, 3 insertions(+), 9 deletions(-)
>>
>> diff --git a/libavformat/tls.c b/libavformat/tls.c
>> index 5ec4cca58a..f888970969 100644
>> --- a/libavformat/tls.c
>> +++ b/libavformat/tls.c
>> @@ -135,15 +135,6 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>>      ret = ffurl_open_whitelist(c->is_dtls ? &c->udp : &c->tcp, buf, AVIO_FLAG_READ_WRITE,
>>                                 &parent->interrupt_callback, options,
>>                                 parent->protocol_whitelist, parent->protocol_blacklist, parent);
>> -    if (c->is_dtls) {
>> -        if (ret < 0) {
>> -            av_log(c, AV_LOG_ERROR, "Failed to open udp://%s:%d\n", c->underlying_host, port);
>> -            return ret;
>> -        }
>> -        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
>> -        ff_socket_nonblock(ffurl_get_file_handle(c->udp), 1);
>> -        c->udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
>> -    }
>>      return ret;
>> }
>>
>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>> index 2a3905891d..d83fe602d5 100644
>> --- a/libavformat/tls_openssl.c
>> +++ b/libavformat/tls_openssl.c
>> @@ -985,6 +985,9 @@ static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **
>>              av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
>>              return ret;
>>          }
>> +        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
>> +        ff_socket_nonblock(ffurl_get_file_handle(p->tls_shared.udp), 1);
>> +        p->tls_shared.udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
> Since AVIO_FLAG_READ_WRITE was flagged, it can be just "p->tls_shared.udp->flags |= AVIO_FLAG_NONBLOCK;”

Isn't that redundant with ff_socket_nonblock right above it as well?

>>      }
>>
>>      /* Setup DTLS as passive, which is server role. */
>> -- 
>> 2.49.0
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe”.
> Thanks
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code
  2025-07-03 14:24     ` Timo Rothenpieler
@ 2025-07-03 15:22       ` Jack Lau
  2025-07-03 16:41         ` Timo Rothenpieler
  0 siblings, 1 reply; 38+ messages in thread
From: Jack Lau @ 2025-07-03 15:22 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> On Jul 3, 2025, at 22:24, Timo Rothenpieler <timo@rothenpieler.org> wrote:
> 
> On 03.07.2025 03:07, Jack Lau wrote:
>>> On Jul 3, 2025, at 00:56, Timo Rothenpieler <timo@rothenpieler.org> wrote:
>>> 
>>> ---
>>> libavformat/tls.c         | 9 ---------
>>> libavformat/tls_openssl.c | 3 +++
>>> 2 files changed, 3 insertions(+), 9 deletions(-)
>>> 
>>> diff --git a/libavformat/tls.c b/libavformat/tls.c
>>> index 5ec4cca58a..f888970969 100644
>>> --- a/libavformat/tls.c
>>> +++ b/libavformat/tls.c
>>> @@ -135,15 +135,6 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>>>     ret = ffurl_open_whitelist(c->is_dtls ? &c->udp : &c->tcp, buf, AVIO_FLAG_READ_WRITE,
>>>                                &parent->interrupt_callback, options,
>>>                                parent->protocol_whitelist, parent->protocol_blacklist, parent);
>>> -    if (c->is_dtls) {
>>> -        if (ret < 0) {
>>> -            av_log(c, AV_LOG_ERROR, "Failed to open udp://%s:%d\n", c->underlying_host, port);
>>> -            return ret;
>>> -        }
>>> -        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
>>> -        ff_socket_nonblock(ffurl_get_file_handle(c->udp), 1);
>>> -        c->udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
>>> -    }
>>>     return ret;
>>> }
>>> 
>>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>>> index 2a3905891d..d83fe602d5 100644
>>> --- a/libavformat/tls_openssl.c
>>> +++ b/libavformat/tls_openssl.c
>>> @@ -985,6 +985,9 @@ static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **
>>>             av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
>>>             return ret;
>>>         }
>>> +        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
>>> +        ff_socket_nonblock(ffurl_get_file_handle(p->tls_shared.udp), 1);
>>> +        p->tls_shared.udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
>> Since AVIO_FLAG_READ_WRITE was flagged, it can be just "p->tls_shared.udp->flags |= AVIO_FLAG_NONBLOCK;”
> 
> Isn't that redundant with ff_socket_nonblock right above it as well?
No, I think we need keep them all.

The first line ff_socket_nonblock tells the system nonblock
The second line NONBLOCK flag tells ffmpeg to skip ff_network_wait_fd (can see that in udp_read or udp_write)

I’m not very sure if I explained it right, but when I remove one line of them, the streaming is so choppy and it is almost unusable.
> 
>>>     }
>>> 
>>>     /* Setup DTLS as passive, which is server role. */
>>> -- 
>>> 2.49.0
>>> 
>>> _______________________________________________
>>> ffmpeg-devel mailing list
>>> ffmpeg-devel@ffmpeg.org
>>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>> 
>>> To unsubscribe, visit link above, or email
>>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe”.
>> Thanks
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code
  2025-07-03 15:22       ` Jack Lau
@ 2025-07-03 16:41         ` Timo Rothenpieler
  0 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-03 16:41 UTC (permalink / raw)
  To: ffmpeg-devel

On 03.07.2025 17:22, Jack Lau wrote:
> 
> 
>> On Jul 3, 2025, at 22:24, Timo Rothenpieler <timo@rothenpieler.org> wrote:
>>
>> On 03.07.2025 03:07, Jack Lau wrote:
>>>> On Jul 3, 2025, at 00:56, Timo Rothenpieler <timo@rothenpieler.org> wrote:
>>>>
>>>> ---
>>>> libavformat/tls.c         | 9 ---------
>>>> libavformat/tls_openssl.c | 3 +++
>>>> 2 files changed, 3 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/libavformat/tls.c b/libavformat/tls.c
>>>> index 5ec4cca58a..f888970969 100644
>>>> --- a/libavformat/tls.c
>>>> +++ b/libavformat/tls.c
>>>> @@ -135,15 +135,6 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
>>>>      ret = ffurl_open_whitelist(c->is_dtls ? &c->udp : &c->tcp, buf, AVIO_FLAG_READ_WRITE,
>>>>                                 &parent->interrupt_callback, options,
>>>>                                 parent->protocol_whitelist, parent->protocol_blacklist, parent);
>>>> -    if (c->is_dtls) {
>>>> -        if (ret < 0) {
>>>> -            av_log(c, AV_LOG_ERROR, "Failed to open udp://%s:%d\n", c->underlying_host, port);
>>>> -            return ret;
>>>> -        }
>>>> -        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
>>>> -        ff_socket_nonblock(ffurl_get_file_handle(c->udp), 1);
>>>> -        c->udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
>>>> -    }
>>>>      return ret;
>>>> }
>>>>
>>>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>>>> index 2a3905891d..d83fe602d5 100644
>>>> --- a/libavformat/tls_openssl.c
>>>> +++ b/libavformat/tls_openssl.c
>>>> @@ -985,6 +985,9 @@ static int dtls_start(URLContext *h, const char *url, int flags, AVDictionary **
>>>>              av_log(p, AV_LOG_ERROR, "Failed to connect %s\n", url);
>>>>              return ret;
>>>>          }
>>>> +        /* Make the socket non-blocking, set to READ and WRITE mode after connected */
>>>> +        ff_socket_nonblock(ffurl_get_file_handle(p->tls_shared.udp), 1);
>>>> +        p->tls_shared.udp->flags |= AVIO_FLAG_READ | AVIO_FLAG_NONBLOCK;
>>> Since AVIO_FLAG_READ_WRITE was flagged, it can be just "p->tls_shared.udp->flags |= AVIO_FLAG_NONBLOCK;”
>>
>> Isn't that redundant with ff_socket_nonblock right above it as well?
> No, I think we need keep them all.
> 
> The first line ff_socket_nonblock tells the system nonblock
> The second line NONBLOCK flag tells ffmpeg to skip ff_network_wait_fd (can see that in udp_read or udp_write)
> 
> I’m not very sure if I explained it right, but when I remove one line of them, the streaming is so choppy and it is almost unusable.

But shouldn't then instead _whip_ be setting the socket to nonblock, and 
not tls_openssl set it to nonblock for literally everyone?

tls_openssl, and all the other tls implementations, forward the 
nonblocking state.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t
  2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t Timo Rothenpieler
  2025-07-03 14:03   ` Steven Liu
@ 2025-07-03 17:16   ` Andreas Rheinhardt
  2025-07-03 17:54     ` Timo Rothenpieler
  1 sibling, 1 reply; 38+ messages in thread
From: Andreas Rheinhardt @ 2025-07-03 17:16 UTC (permalink / raw)
  To: ffmpeg-devel

Timo Rothenpieler:
> ---
>  libavformat/whip.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index 7cd3f48ba9..71c667cd31 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -926,7 +926,7 @@ static int parse_answer(AVFormatContext *s)
>      if (whip->state < WHIP_STATE_NEGOTIATED)
>          whip->state = WHIP_STATE_NEGOTIATED;
>      whip->whip_answer_time = av_gettime();
> -    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%luB, answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\n",
> +    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%zuB, answer=%zuB, ufrag=%s, pwd=%zuB, transport=%s://%s:%d, elapsed=%dms\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()));
>  
> @@ -977,7 +977,7 @@ static int ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in
>      /* 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);
>      if (ret <= 0 || ret >= sizeof(username)) {
> -        av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s, max=%lu, ret=%d\n",
> +        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);
>          ret = AVERROR(EIO);
>          goto end;
> @@ -1420,7 +1420,7 @@ static int setup_srtp(AVFormatContext *s)
>      if (whip->state < WHIP_STATE_SRTP_FINISHED)
>          whip->state = WHIP_STATE_SRTP_FINISHED;
>      whip->whip_srtp_time = av_gettime();
> -    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%luB, elapsed=%dms\n",
> +    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%zuB, elapsed=%dms\n",
>          whip->state, suite, sizeof(send_key), ELAPSED(whip->whip_starttime, av_gettime()));
>  
>  end:

Why not SIZE_SPECIFIER?

- Andreas

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t
  2025-07-03 17:16   ` Andreas Rheinhardt
@ 2025-07-03 17:54     ` Timo Rothenpieler
  2025-07-03 18:03       ` Andreas Rheinhardt
  0 siblings, 1 reply; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-03 17:54 UTC (permalink / raw)
  To: ffmpeg-devel

On 03.07.2025 19:16, Andreas Rheinhardt wrote:
> Timo Rothenpieler:
>> ---
>>   libavformat/whip.c | 6 +++---
>>   1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>> index 7cd3f48ba9..71c667cd31 100644
>> --- a/libavformat/whip.c
>> +++ b/libavformat/whip.c
>> @@ -926,7 +926,7 @@ static int parse_answer(AVFormatContext *s)
>>       if (whip->state < WHIP_STATE_NEGOTIATED)
>>           whip->state = WHIP_STATE_NEGOTIATED;
>>       whip->whip_answer_time = av_gettime();
>> -    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%luB, answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\n",
>> +    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%zuB, answer=%zuB, ufrag=%s, pwd=%zuB, transport=%s://%s:%d, elapsed=%dms\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()));
>>   
>> @@ -977,7 +977,7 @@ static int ice_create_request(AVFormatContext *s, uint8_t *buf, int buf_size, in
>>       /* 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);
>>       if (ret <= 0 || ret >= sizeof(username)) {
>> -        av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s, max=%lu, ret=%d\n",
>> +        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);
>>           ret = AVERROR(EIO);
>>           goto end;
>> @@ -1420,7 +1420,7 @@ static int setup_srtp(AVFormatContext *s)
>>       if (whip->state < WHIP_STATE_SRTP_FINISHED)
>>           whip->state = WHIP_STATE_SRTP_FINISHED;
>>       whip->whip_srtp_time = av_gettime();
>> -    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%luB, elapsed=%dms\n",
>> +    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d, suite=%s, key=%zuB, elapsed=%dms\n",
>>           whip->state, suite, sizeof(send_key), ELAPSED(whip->whip_starttime, av_gettime()));
>>   
>>   end:
> 
> Why not SIZE_SPECIFIER?

According to C99, %zu is the format specifier for size_t, so should work 
everywhere?
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t
  2025-07-03 17:54     ` Timo Rothenpieler
@ 2025-07-03 18:03       ` Andreas Rheinhardt
  2025-07-03 18:14         ` Timo Rothenpieler
  0 siblings, 1 reply; 38+ messages in thread
From: Andreas Rheinhardt @ 2025-07-03 18:03 UTC (permalink / raw)
  To: ffmpeg-devel

Timo Rothenpieler:
> On 03.07.2025 19:16, Andreas Rheinhardt wrote:
>> Timo Rothenpieler:
>>> ---
>>>   libavformat/whip.c | 6 +++---
>>>   1 file changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>>> index 7cd3f48ba9..71c667cd31 100644
>>> --- a/libavformat/whip.c
>>> +++ b/libavformat/whip.c
>>> @@ -926,7 +926,7 @@ static int parse_answer(AVFormatContext *s)
>>>       if (whip->state < WHIP_STATE_NEGOTIATED)
>>>           whip->state = WHIP_STATE_NEGOTIATED;
>>>       whip->whip_answer_time = av_gettime();
>>> -    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%luB,
>>> answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\n",
>>> +    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%zuB,
>>> answer=%zuB, ufrag=%s, pwd=%zuB, transport=%s://%s:%d, elapsed=%dms\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()));
>>>   @@ -977,7 +977,7 @@ static int ice_create_request(AVFormatContext
>>> *s, uint8_t *buf, int buf_size, in
>>>       /* 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);
>>>       if (ret <= 0 || ret >= sizeof(username)) {
>>> -        av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s,
>>> max=%lu, ret=%d\n",
>>> +        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);
>>>           ret = AVERROR(EIO);
>>>           goto end;
>>> @@ -1420,7 +1420,7 @@ static int setup_srtp(AVFormatContext *s)
>>>       if (whip->state < WHIP_STATE_SRTP_FINISHED)
>>>           whip->state = WHIP_STATE_SRTP_FINISHED;
>>>       whip->whip_srtp_time = av_gettime();
>>> -    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d,
>>> suite=%s, key=%luB, elapsed=%dms\n",
>>> +    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d,
>>> suite=%s, key=%zuB, elapsed=%dms\n",
>>>           whip->state, suite, sizeof(send_key), ELAPSED(whip-
>>> >whip_starttime, av_gettime()));
>>>     end:
>>
>> Why not SIZE_SPECIFIER?
> 
> According to C99, %zu is the format specifier for size_t, so should work
> everywhere?
IIRC some version of MSVCRT doesn't support it nevertheless. I don't
know whether we still support it, though.

- Andreas

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t
  2025-07-03 18:03       ` Andreas Rheinhardt
@ 2025-07-03 18:14         ` Timo Rothenpieler
  0 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-03 18:14 UTC (permalink / raw)
  To: ffmpeg-devel

On 03.07.2025 20:03, Andreas Rheinhardt wrote:
> Timo Rothenpieler:
>> On 03.07.2025 19:16, Andreas Rheinhardt wrote:
>>> Timo Rothenpieler:
>>>> ---
>>>>    libavformat/whip.c | 6 +++---
>>>>    1 file changed, 3 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>>>> index 7cd3f48ba9..71c667cd31 100644
>>>> --- a/libavformat/whip.c
>>>> +++ b/libavformat/whip.c
>>>> @@ -926,7 +926,7 @@ static int parse_answer(AVFormatContext *s)
>>>>        if (whip->state < WHIP_STATE_NEGOTIATED)
>>>>            whip->state = WHIP_STATE_NEGOTIATED;
>>>>        whip->whip_answer_time = av_gettime();
>>>> -    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%luB,
>>>> answer=%luB, ufrag=%s, pwd=%luB, transport=%s://%s:%d, elapsed=%dms\n",
>>>> +    av_log(whip, AV_LOG_VERBOSE, "SDP state=%d, offer=%zuB,
>>>> answer=%zuB, ufrag=%s, pwd=%zuB, transport=%s://%s:%d, elapsed=%dms\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()));
>>>>    @@ -977,7 +977,7 @@ static int ice_create_request(AVFormatContext
>>>> *s, uint8_t *buf, int buf_size, in
>>>>        /* 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);
>>>>        if (ret <= 0 || ret >= sizeof(username)) {
>>>> -        av_log(whip, AV_LOG_ERROR, "Failed to build username %s:%s,
>>>> max=%lu, ret=%d\n",
>>>> +        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);
>>>>            ret = AVERROR(EIO);
>>>>            goto end;
>>>> @@ -1420,7 +1420,7 @@ static int setup_srtp(AVFormatContext *s)
>>>>        if (whip->state < WHIP_STATE_SRTP_FINISHED)
>>>>            whip->state = WHIP_STATE_SRTP_FINISHED;
>>>>        whip->whip_srtp_time = av_gettime();
>>>> -    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d,
>>>> suite=%s, key=%luB, elapsed=%dms\n",
>>>> +    av_log(whip, AV_LOG_VERBOSE, "SRTP setup done, state=%d,
>>>> suite=%s, key=%zuB, elapsed=%dms\n",
>>>>            whip->state, suite, sizeof(send_key), ELAPSED(whip-
>>>>> whip_starttime, av_gettime()));
>>>>      end:
>>>
>>> Why not SIZE_SPECIFIER?
>>
>> According to C99, %zu is the format specifier for size_t, so should work
>> everywhere?
> IIRC some version of MSVCRT doesn't support it nevertheless. I don't
> know whether we still support it, though.

The docs suggest it's supported since at least MSVC 2015:
> https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-140#size-prefixes-for-printf-and-wprintf-format-type-specifiers

Can't select an older Version on MSDN, but 2015 should be sufficiently 
old to not care about anything even older.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [FFmpeg-devel] [PATCH 01/18] avformat/Makefile: don't hardcode openssl for whip muxer
  2025-07-03 14:00   ` Steven Liu
@ 2025-07-03 20:20     ` Timo Rothenpieler
  0 siblings, 0 replies; 38+ messages in thread
From: Timo Rothenpieler @ 2025-07-03 20:20 UTC (permalink / raw)
  To: ffmpeg-devel

On 03.07.2025 16:00, Steven Liu wrote:
> Timo Rothenpieler <timo@rothenpieler.org> 于2025年7月3日周四 00:57写道:
>>
>> ---
>>   libavformat/Makefile | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/libavformat/Makefile b/libavformat/Makefile
>> index 2e73f1325e..816eb9be4a 100644
>> --- a/libavformat/Makefile
>> +++ b/libavformat/Makefile
>> @@ -639,7 +639,7 @@ OBJS-$(CONFIG_WEBM_CHUNK_MUXER)          += webm_chunk.o
>>   OBJS-$(CONFIG_WEBP_MUXER)                += webpenc.o
>>   OBJS-$(CONFIG_WEBVTT_DEMUXER)            += webvttdec.o subtitles.o
>>   OBJS-$(CONFIG_WEBVTT_MUXER)              += webvttenc.o
>> -OBJS-$(CONFIG_WHIP_MUXER)                += whip.o avc.o http.o srtp.o tls_openssl.o
>> +OBJS-$(CONFIG_WHIP_MUXER)                += whip.o avc.o http.o srtp.o
>>   OBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood_aud.o
>>   OBJS-$(CONFIG_WSAUD_MUXER)               += westwood_audenc.o
>>   OBJS-$(CONFIG_WSD_DEMUXER)               += wsddec.o rawdec.o
>> --
>> 2.49.0
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> 
> LGTM

Applied this and all the other more or less obvious fixes to reduce the 
size of the set.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2025-07-03 20:20 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-02 16:56 [FFmpeg-devel] [PATCH 00/18] WHIP + TLS + UDP fixes and SChannel DTLS support Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 01/18] avformat/Makefile: don't hardcode openssl for whip muxer Timo Rothenpieler
2025-07-03 14:00   ` Steven Liu
2025-07-03 20:20     ` Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 02/18] avformat/whip: use av_dict_set_int for int Timo Rothenpieler
2025-07-03 14:01   ` Steven Liu
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 03/18] avformat/whip: don't leak options dict Timo Rothenpieler
2025-07-03 14:02   ` Steven Liu
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 04/18] avformat/whip: remove redundant WHIP: prefix from all logging Timo Rothenpieler
2025-07-03 14:02   ` Steven Liu
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 05/18] avformat/whip: fix format string for printing size_t Timo Rothenpieler
2025-07-03 14:03   ` Steven Liu
2025-07-03 17:16   ` Andreas Rheinhardt
2025-07-03 17:54     ` Timo Rothenpieler
2025-07-03 18:03       ` Andreas Rheinhardt
2025-07-03 18:14         ` Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 06/18] avformat/tls: use non protocol specific error message Timo Rothenpieler
2025-07-03 14:03   ` Steven Liu
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 07/18] avformat/tls: don't use http_proxy for udp sockets Timo Rothenpieler
2025-07-03 14:04   ` Steven Liu
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code Timo Rothenpieler
2025-07-03  1:07   ` Jack Lau
2025-07-03 14:24     ` Timo Rothenpieler
2025-07-03 15:22       ` Jack Lau
2025-07-03 16:41         ` Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 09/18] avformat/udp: don't override 0 localport Timo Rothenpieler
2025-07-03 14:05   ` Steven Liu
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 10/18] avformat/tls: fix udp init Timo Rothenpieler
2025-07-03 14:06   ` Steven Liu
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 11/18] avformat/udp: make recv addr of each packet available Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 12/18] avformat/udp: separate rx and tx fifo Timo Rothenpieler
2025-07-03 14:07   ` Steven Liu
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 13/18] avformat/udp: add function to set remote address directly Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 14/18] avformat/tls: remove unused fingerprint option Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 15/18] avformat/tls: clean up new whip options Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 16/18] avformat/tls: make passing an external socket universal Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 17/18] avformat/tls_openssl: use existing context handle Timo Rothenpieler
2025-07-02 16:56 ` [FFmpeg-devel] [PATCH 18/18] avformat/tls_schannel: add DTLS support Timo Rothenpieler

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git