[FFmpeg-devel] [PATCH] examples/transcoding: Fix time_base handling

2025-02-04 Thread Jack Lau
The `dec_ctx->time_base` was incorrectly default set to 0/60, while 
`enc_ctx->time_base` was derived from `dec_ctx->framerate`. This 
mismatch could cause incorrect video duration in the output.


This patch aligns `enc_ctx->time_base` with `dec_ctx->time_base` to 
prevent rescaling issues and ensure correct video duration.


Signed-off-by: Jack Lau 
---
 doc/examples/transcoding.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
index 013f89fc7d..847bdb7e1a 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcoding.c
@@ -172,7 +172,7 @@ static int open_output_file(const char *filename)
 else
 enc_ctx->pix_fmt = dec_ctx->pix_fmt;
 /* video time_base can be set to whatever is handy and 
supported by encoder */

-enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
+enc_ctx->time_base = dec_ctx->time_base;
 } else {
 enc_ctx->sample_rate = dec_ctx->sample_rate;
 ret = av_channel_layout_copy(&enc_ctx->ch_layout, 
&dec_ctx->ch_layout);

@@ -180,7 +180,7 @@ static int open_output_file(const char *filename)
 return ret;
 /* take first format from list of supported formats */
 enc_ctx->sample_fmt = encoder->sample_fmts[0];
-enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
+enc_ctx->time_base = dec_ctx->time_base;
 }
  if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
--
2.48.1

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

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


[FFmpeg-devel] [PATCHv3] examples/transcoding: Fix time_base handling

2025-02-04 Thread Jack Lau
--- Begin Message ---
From bfd5500a5448ad468d32994816e8a55c0d4a2428 Mon Sep 17 00:00:00 2001
From: Jack Lau 
Date: Tue, 4 Feb 2025 21:39:20 +0800
Subject: [PATCH] examples/transcoding: Fix time_base handling
X-Unsent: 1
To: ffmpeg-devel@ffmpeg.org

The `dec_ctx->time_base` was incorrectly default set to 0/60, while 
`enc_ctx->time_base` was derived from `dec_ctx->framerate`. This mismatch could 
cause incorrect video duration in the output.

This patch aligns `enc_ctx->time_base` with `dec_ctx->time_base` to prevent 
rescaling issues and ensure correct video duration.

Signed-off-by: JackLau1222 <2366536...@qq.com>
---
 doc/examples/transcoding.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
index 013f89fc7d..847bdb7e1a 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcoding.c
@@ -172,7 +172,7 @@ static int open_output_file(const char *filename)
 else
 enc_ctx->pix_fmt = dec_ctx->pix_fmt;
 /* video time_base can be set to whatever is handy and 
supported by encoder */
-enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
+enc_ctx->time_base = dec_ctx->time_base;
 } else {
 enc_ctx->sample_rate = dec_ctx->sample_rate;
 ret = av_channel_layout_copy(&enc_ctx->ch_layout, 
&dec_ctx->ch_layout);
@@ -180,7 +180,7 @@ static int open_output_file(const char *filename)
 return ret;
 /* take first format from list of supported formats */
 enc_ctx->sample_fmt = encoder->sample_fmts[0];
-enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
+enc_ctx->time_base = dec_ctx->time_base;
 }
 
 if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
-- 
2.45.2

--- End Message ---
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


[FFmpeg-devel] [PATCH] examples/transcoding: Fix time_base handling

2025-02-04 Thread Jack Lau


fix-time-base-handling.patch
Description: Binary data
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] examples/transcoding: Fix time_base handling

2025-02-04 Thread Jack Lau
> 
> AVCodecContext.time_base is not used for decoding.


Thank you for your reply. I understand that time_base is not used during 
decoding, but the transcoding code calls av_packet_rescale_ts twice, once 
before decoding and once after encoding, as shown below:

540 if (filter_ctx[stream_index].filter_graph) {
541 StreamContext *stream = &stream_ctx[stream_index];
542 
543 av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the 
frame\n");
544 
545 av_packet_rescale_ts(packet,
   
546  ifmt_ctx->streams[stream_index]->time_base,
547  stream->dec_ctx->time_base);
548 ret = avcodec_send_packet(stream->dec_ctx, packet);

448 /* prepare packet for muxing */ 
   
449 enc_pkt->stream_index = stream_index;
450 av_packet_rescale_ts(enc_pkt,
451  stream->enc_ctx->time_base,
452  ofmt_ctx->streams[stream_index]->time_base);
453 
454 av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
455 /* mux encoded frame */
456 ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);

If dec_ctx->time_base and enc_ctx->time_base are not consistent, it can lead to 
incorrect packet duration, which in turn causes issues with the output file's 
duration.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] examples/transcoding: Fix time_base handling

2025-02-04 Thread Jack Lau
> 
> AVCodecContext.time_base is not used for decoding.


Thank you for your reply. I understand that time_base is not used during 
decoding, but the transcoding code calls av_packet_rescale_ts twice, once 
before decoding and once after encoding, as shown below:

540 if (filter_ctx[stream_index].filter_graph) {
541 StreamContext *stream = &stream_ctx[stream_index];
542 
543 av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the 
frame\n");
544 
545 av_packet_rescale_ts(packet,
   
546  ifmt_ctx->streams[stream_index]->time_base,
547  stream->dec_ctx->time_base);
548 ret = avcodec_send_packet(stream->dec_ctx, packet);

448 /* prepare packet for muxing */ 
   
449 enc_pkt->stream_index = stream_index;
450 av_packet_rescale_ts(enc_pkt,
451  stream->enc_ctx->time_base,
452  ofmt_ctx->streams[stream_index]->time_base);
453 
454 av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
455 /* mux encoded frame */
456 ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);

If dec_ctx->time_base and enc_ctx->time_base are not consistent, it can lead to 
incorrect packet duration, which in turn causes issues with the output file's 
duration.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


[FFmpeg-devel] [PATCH] examples/transcoding: Fix time_base handling

2025-02-04 Thread Jack Lau
The `dec_ctx->time_base` was incorrectly default set to 0/60, while
`enc_ctx->time_base` was derived from `dec_ctx->framerate`. This mismatch
could cause incorrect video duration in the output.

This patch aligns `enc_ctx->time_base` with `dec_ctx->time_base` to prevent
rescaling issues and ensure correct video duration.

Signed-off-by: Jack Lau 
---
doc/examples/transcoding.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
index 013f89fc7d..847bdb7e1a 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcoding.c
@@ -172,7 +172,7 @@ static int open_output_file(const char *filename)
else
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
/* video time_base can be set to whatever is handy and
supported by encoder */
-enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
+enc_ctx->time_base = dec_ctx->time_base;
} else {
enc_ctx->sample_rate = dec_ctx->sample_rate;
ret = av_channel_layout_copy(&enc_ctx->ch_layout,
&dec_ctx->ch_layout);
@@ -180,7 +180,7 @@ static int open_output_file(const char *filename)
return ret;
/* take first format from list of supported formats */
enc_ctx->sample_fmt = encoder->sample_fmts[0];
-enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
+enc_ctx->time_base = dec_ctx->time_base;
}

if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
-- 
2.45.2
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


[FFmpeg-devel] [PATCH] examples/transcoding: Fix time_base handling

2025-02-04 Thread Jack Lau
The `dec_ctx->time_base` was incorrectly default set to 0/60, while 
`enc_ctx->time_base` was derived from `dec_ctx->framerate`. This mismatch could 
cause incorrect video duration in the output.

This patch aligns `enc_ctx->time_base` with `dec_ctx->time_base` to prevent 
rescaling issues and ensure correct video duration.

Signed-off-by: JackLau1222 <2366536...@qq.com>
---
doc/examples/transcoding.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
index 013f89fc7d..847bdb7e1a 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcoding.c
@@ -172,7 +172,7 @@ static int open_output_file(const char *filename)
  else
  enc_ctx->pix_fmt = dec_ctx->pix_fmt;
  /* video time_base can be set to whatever is handy and supported 
by encoder */
-enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
+enc_ctx->time_base = dec_ctx->time_base;
  } else {
  enc_ctx->sample_rate = dec_ctx->sample_rate;
  ret = av_channel_layout_copy(&enc_ctx->ch_layout, 
&dec_ctx->ch_layout);
@@ -180,7 +180,7 @@ static int open_output_file(const char *filename)
  return ret;
  /* take first format from list of supported formats */
  enc_ctx->sample_fmt = encoder->sample_fmts[0];
-enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
+enc_ctx->time_base = dec_ctx->time_base;
  }

  if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
-- 
2.45.2

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

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


Re: [FFmpeg-devel] [PATCH] examples/transcoding: Fix time_base handling

2025-02-04 Thread Jack Lau
To be clear, i want to give an example, i use a 10s duration, 30fps video.
The ifmt_ctx->streams[stream_index]->time_base is same as
ofmt_ctx->streams[stream_index]->time_base after initializing.
The stream->dec_ctx->time_base is default 0,60 but
stream->enc_ctx->time_base is set to av_inv_q(dec_ctx->framerate) so it's
0,30

174 /* video time_base can be set to whatever is handy and
supported by encoder */
175 enc_ctx->time_base = av_inv_q(dec_ctx->framerate);

so the twice rescale is this:
input pkt in_tb: 15360   out_tb: 60
output pkt in_tb: 30 out_tb: 15360

so i get one 20s duration and 15fps video(audio duration is normal because
the input's audio sample ratio is 44100)

So i think the problem is that the enc_ctx->time_base shouldn't set to
av_inv_q(dec_ctx->framerate)

On Wed, Feb 5, 2025 at 10:29 AM Jack Lau  wrote:

>
> AVCodecContext.time_base is not used for decoding.
>
>
>
> Thank you for your reply. I understand that time_base is not used during
> decoding, but the transcoding code calls av_packet_rescale_ts twice, once
> before decoding and once after encoding, as shown below:
>
> 540 if (filter_ctx[stream_index].filter_graph) {
> 541 StreamContext *stream = &stream_ctx[stream_index];
> 542
> 543 av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the
> frame\n");
> 544
> 545 av_packet_rescale_ts(packet,
>
>
> 546
>  ifmt_ctx->streams[stream_index]->time_base,
> 547  stream->dec_ctx->time_base);
> 548 ret = avcodec_send_packet(stream->dec_ctx, packet);
>
> 448 /* prepare packet for muxing */
>
>
> 449 enc_pkt->stream_index = stream_index;
> 450 av_packet_rescale_ts(enc_pkt,
> 451  stream->enc_ctx->time_base,
> 452
>  ofmt_ctx->streams[stream_index]->time_base);
> 453
> 454 av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
> 455 /* mux encoded frame */
> 456 ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);
>
> If dec_ctx->time_base and enc_ctx->time_base are not consistent, it can
> lead to incorrect packet duration, which in turn causes issues with the
> output file's duration.
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] examples/transcoding: Fix time_base handling

2025-02-05 Thread Jack Lau
Hello.

I found one better method to fix this issue. Firstly, i think the problem
caused by incorrectly setting enc_ctx->time_base, so i refer to the
implementation in avcodec_open2()

361 #if FF_API_AVCTX_TIMEBASE
362if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
363 avctx->time_base = av_inv_q(av_mul_q(avctx->framerate,
(AVRational){avctx->ticks_per_frame, 1}));
364 #endif

this is new version code and i submit it in new mail, it can be reviewed in
https://patchwork.ffmpeg.org/project/ffmpeg/patch/tencent_7adfe69819d49d96fa8bc2c9e688ccec2...@qq.com/
-enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
+enc_ctx->time_base = av_inv_q(av_mul_q(dec_ctx->framerate,
(AVRational){dec_ctx->ticks_per_frame, 1}));

-enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
+enc_ctx->time_base = (AVRational){1, dec_ctx->sample_rate};

but there is new issue in andriy/configure_x86 check:

error: Failed to merge in the changes.

i think it's maybe the mistake of branch? this patch is for release/5.1
branch rather than master branch.

Could any one give me some advice please so that i can fix it?


On Wed, Feb 5, 2025 at 11:25 AM Jack Lau  wrote:

> To be clear, i want to give an example, i use a 10s duration, 30fps video.
> The ifmt_ctx->streams[stream_index]->time_base is same as
> ofmt_ctx->streams[stream_index]->time_base after initializing.
> The stream->dec_ctx->time_base is default 0,60 but
> stream->enc_ctx->time_base is set to av_inv_q(dec_ctx->framerate) so it's
> 0,30
>
> 174 /* video time_base can be set to whatever is handy and
> supported by encoder */
> 175 enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
>
> so the twice rescale is this:
> input pkt in_tb: 15360   out_tb: 60
> output pkt in_tb: 30 out_tb: 15360
>
> so i get one 20s duration and 15fps video(audio duration is normal because
> the input's audio sample ratio is 44100)
>
> So i think the problem is that the enc_ctx->time_base shouldn't set to
> av_inv_q(dec_ctx->framerate)
>
> On Wed, Feb 5, 2025 at 10:29 AM Jack Lau  wrote:
>
>>
>> AVCodecContext.time_base is not used for decoding.
>>
>>
>>
>> Thank you for your reply. I understand that time_base is not used during
>> decoding, but the transcoding code calls av_packet_rescale_ts twice,
>> once before decoding and once after encoding, as shown below:
>>
>> 540 if (filter_ctx[stream_index].filter_graph) {
>> 541 StreamContext *stream = &stream_ctx[stream_index];
>> 542
>> 543 av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the
>> frame\n");
>> 544
>> 545 av_packet_rescale_ts(packet,
>>
>>
>> 546
>>  ifmt_ctx->streams[stream_index]->time_base,
>> 547  stream->dec_ctx->time_base);
>> 548 ret = avcodec_send_packet(stream->dec_ctx, packet);
>>
>> 448 /* prepare packet for muxing */
>>
>>
>> 449 enc_pkt->stream_index = stream_index;
>> 450 av_packet_rescale_ts(enc_pkt,
>> 451  stream->enc_ctx->time_base,
>> 452
>>  ofmt_ctx->streams[stream_index]->time_base);
>> 453
>> 454 av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
>> 455 /* mux encoded frame */
>> 456 ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt);
>>
>> If dec_ctx->time_base and enc_ctx->time_base are not consistent, it can
>> lead to incorrect packet duration, which in turn causes issues with the
>> output file's duration.
>>
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] avformat/hls: fix typo There is an extra space in the original comment

2025-02-09 Thread Jack Lau
Hi,

Thanks for your reply.

I'm trying to fix some issues with hls. I happened to see this typo. Since I 
saw in the ffmpeg documentation that cosmetic changes should be kept in 
separate patches, so i submitted it first. 

Thank you for your advice, I will try my best to submit more important patches.

Best wishes
Jack


> On Feb 10, 2025, at 08:54, Soft Works  
> wrote:
> 
> 
> 
>> -Original Message-
>> From: ffmpeg-devel > <mailto:ffmpeg-devel-boun...@ffmpeg.org>> On Behalf Of
>> Jack Lau via ffmpeg-devel
>> Sent: Monday, February 10, 2025 1:34 AM
>> To: ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
>> Cc: Jack Lau mailto:jacklau1...@qq.com>>
>> Subject: [FFmpeg-devel] [PATCH] avformat/hls: fix typo There is an
>> extra space in the original comment
>> 
>> ---
>> libavformat/hls.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/libavformat/hls.c b/libavformat/hls.c
>> index 3bdc1bc848..c2130bb883 100644
>> --- a/libavformat/hls.c
>> +++ b/libavformat/hls.c
>> @@ -1993,7 +1993,7 @@ static int hls_read_header(AVFormatContext *s)
>> return ret;
>> 
>> /* XXX: Some HLS servers don't like being sent the range header,
>> -   in this case, need to  setting http_seekable = 0 to disable
>> +   in this case, need to setting http_seekable = 0 to disable
>>the range header */
>> av_dict_set_int(&c->avio_opts, "seekable", c->http_seekable, 0);
>> 
>> --
>> 2.48.1
> 
> Hi Jack,
> 
> you're not working on a proof of concept regarding the vulnerability of the 
> GA, right? 
> (just kidding)
> 
> As an idea, you might be able to give that patch a little bit more meaning by 
> also fixing the grammar.
> 
> Best wishes
> sw
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avformat/hls: fix typo There is an extra space in the original comment

2025-02-09 Thread Jack Lau


> On Feb 10, 2025, at 11:08, Marth64  wrote:
> 
> I don't think its fair to shoot this down, its a simple but valid tidy up 
> work.
> I find typos and such when browsing code distracting and readability
> important down the road.
> Not everyone's first language is English and grammar correction may
> not come instinctively.
> 
> Thank you for the contribution Jack. Unless there is any objection on
> grounds of maintaining commit history, I'll adjust the grammar of
> "need to setting" -> "we need to set" and push this soon.
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe”.

Hi Marth,

Thanks very much for your reply. I feel the warmth of the open-source 
community. I indeed did not notice this grammar issue, and I will be more 
careful next time.

It's hard to express my gratitude in words.🥹

Best regards,
Jack
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] avformat/hls: fix typo There is an extra space in the original comment

2025-02-09 Thread Jack Lau


> On Feb 10, 2025, at 09:36, Soft Works  
> wrote:
> 
> 
> 
>> -Original Message-
>> From: ffmpeg-devel > <mailto:ffmpeg-devel-boun...@ffmpeg.org>> On Behalf Of
>> Jack Lau
>> Sent: Monday, February 10, 2025 2:13 AM
>> To: FFmpeg development discussions and patches > de...@ffmpeg.org <mailto:de...@ffmpeg.org>>
>> Subject: Re: [FFmpeg-devel] [PATCH] avformat/hls: fix typo There is
>> an extra space in the original comment
>> 
>>> On Feb 10, 2025, at 08:54, Soft Works > hotmail@ffmpeg.org <mailto:hotmail@ffmpeg.org>> wrote:
>>> 
>>> 
>>> 
>>>> -Original Message-
>>>> From: ffmpeg-devel >>> <mailto:ffmpeg-devel-boun...@ffmpeg.org>
>> <mailto:ffmpeg-devel-boun...@ffmpeg.org>> On Behalf Of
>>>> Jack Lau via ffmpeg-devel
>>>> Sent: Monday, February 10, 2025 1:34 AM
>>>> To: ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org> 
>>>> <mailto:ffmpeg-devel@ffmpeg.org>
>>>> Cc: Jack Lau mailto:jacklau1...@qq.com> 
>>>> <mailto:jacklau1...@qq.com>>
>>>> Subject: [FFmpeg-devel] [PATCH] avformat/hls: fix typo There is an
>>>> extra space in the original comment
>>>> 
>>>> ---
>>>> libavformat/hls.c | 2 +-
>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>> 
>>>> diff --git a/libavformat/hls.c b/libavformat/hls.c
>>>> index 3bdc1bc848..c2130bb883 100644
>>>> --- a/libavformat/hls.c
>>>> +++ b/libavformat/hls.c
>>>> @@ -1993,7 +1993,7 @@ static int hls_read_header(AVFormatContext
>> *s)
>>>>return ret;
>>>> 
>>>>/* XXX: Some HLS servers don't like being sent the range
>> header,
>>>> -   in this case, need to  setting http_seekable = 0 to
>> disable
>>>> +   in this case, need to setting http_seekable = 0 to disable
>>>>   the range header */
>>>>av_dict_set_int(&c->avio_opts, "seekable", c->http_seekable,
>> 0);
>>>> 
>>>> --
>>>> 2.48.1
>>> 
>>> Hi Jack,
>>> 
>>> you're not working on a proof of concept regarding the
>> vulnerability of the GA, right?
>>> (just kidding)
>>> 
>>> As an idea, you might be able to give that patch a little bit more
>> meaning by also fixing the grammar.
>>> 
>>> Best wishes
>>> sw
>>> ___
> 
> 
>> 
>> Hi,
>> 
>> Thanks for your reply.
>> 
>> I'm trying to fix some issues with hls. I happened to see this typo.
>> Since I saw in the ffmpeg documentation that cosmetic changes should
>> be kept in separate patches, so i submitted it first.
>> 
>> Thank you for your advice, I will try my best to submit more
>> important patches.
>> 
>> Best wishes
>> Jack
> 
> Hi,
> 
> please do not top-post (ask AI if you don't know what it is). It's a rule 
> here, probably because in those plaintext messages without formatting it's 
> hard to follow when some are replying at the top and some at the bottom.
> 
> Cosmetic changes should be in a separate commit but they can be in the same 
> patchset.
> 
> Personally, I don't think it's unimportant to fix whitespace, spelling and 
> formatting issues. There's value in everything that improves the code, but 
> you also need to consider efficiency and think about the time that gets bound 
> for others dealing with a single-char non-functional change. 
> If I would make such commit(s), then I would go through a large number of 
> code files (like all from a lib) looking for similar issues and include all 
> of them in my patch, so that a reviewer/maintainer sees that I have really 
> spent effort on it, and they feel that the given value is worth their time.
> 
> Best
> sw
> 
> 
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@ffmpeg.org> with 
> subject "unsubscribe”.


Hi,

Thank you very much for taking the time to point out my mistakes and for 
sharing your perspective—I completely agree.

I will make sure not to encounter these issues again in the future.

Thanks again!

Jack


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

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


Re: [FFmpeg-devel] Captions SCC

2025-02-06 Thread Jack Lau


> I have been absent from the list for a few years, so I would appreciate it
> if someone could catch me up a bit.  I am needing to extract and embed scc
> files with 608 captions.  I am pleased to see that transcoding without
> frame rate changes now preserves 608 intact, and there appear to be
> extraction and embed functions but they do seem to have bugs for my files
> at 1080p2997.  Are there any developers willing to take on a paid project
> to fix whatever is the issue?  Here are the commands I am working with.
> 
> Embed:
> "C:\FFmpeg\ffmpeg7.1_2024-12-14\ffmpeg.exe" -i
> "C:\Users\Captions\AIM-2301_premiereDF.mp4" -i
> "C:\Captions\AIM-2301_premiereDF.mp4.scc" -map 0:v -map 0:a -map 1 -c:v
> copy -c:a copy -c:s mov_text -metadata:s:s:0 language=eng
> "C:\Captions\AIM-2301_premiereDFcopy.mp4"
> 
> Extract:
> "C:\FFmpeg\ffmpeg7.1_2024-12-14\ffmpeg.exe" -f lavfi -i
> "movie=\'C:\\Captions\\AIM-2301_premiereDF_ffmpegEmbedscc.mp4\'"[out+subcc]
> -map 0:1 -c:s copy "C:\Captions\AIM-2301_premiereDF_ffmpegEmbedscc.scc”
> 


Hi,

I’ve reviewed the issue with embedding and extracting 608 SCC captions at 
1080p2997 resolution and identified a few areas that might help resolve the 
character duplication and data spill. Here's a summary of my findings:

The current command uses -c:s mov_text, but SCC files may work better with -c:s 
scc to preserve the format correctly.
The current command uses a filtergraph that might not map correctly for SCC 
extraction. Instead, try simplifying the extraction command: -map 0:s:0 -c:s 
copy
Frame Rate Issues: Ensure the video frame rate and the SCC file frame rate 
match. You might want to force a specific frame rate (e.g., -r 29.97).

Let me know if you have further questions.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] Captions SCC

2025-02-07 Thread Jack Lau

> 
> Hi Jack,
> 
> "paying attention next time"?  That's not the right answer.
> 
> Please make sure that there won't be a next time.
> 
> The big evil with LLVMs is not the fact they are making mistakes but the 
> extreme level of confidence at which they are presenting these mistakes - 
> like no human would do.
> That's why we tend to fall so easily into taking their trash for granted.
> 
> sw
> 
> 

Hi softworkz,

Thanks for your reply and reminder, I’ll ensure there won't be a next time.

Jack

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

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


Re: [FFmpeg-devel] Captions SCC

2025-02-06 Thread Jack Lau
> 
> 
> Hi Zack,
> 
> that message from "Jack" had confused me for a moment, but on re-reading it 
> appears to be an AI response.
> The content is total nonsense. There is no "SCC" encoder in ffmpeg, and if 
> there was one, it wouldn't help much because the CC data needs to get into 
> the video frames - so that it exists as input to the video encoder.
> For the same reason, it is also not possible to add CCs at the muxer level. 
> It always requires video encoding because the data needs to get into the 
> video stream itself, so there's no way to get data from an SCC file into a 
> video stream currently.
> 
> The only way in the ffmpeg architecture to get CC data encoded would be at 
> the filtering level. The Subtitle Filtering patchset that I have submitted a 
> while ago has a "splitcc" filter which has video as input and a video plus a 
> subtitle pin/pad at the output side.
> What would be needed is a reverse pendant like a "mergecc" filter with video 
> and subtitles input - plus a CEA-608/708 encoder.
> 
> softworkz
> 


Hi softworkz,

Sorry about that, The response is indeed from AI. I thought this question was 
enough for AI to answer, I will pay attention to it next time.

Thank you for pointing it out.

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

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


Re: [FFmpeg-devel] Captions SCC

2025-02-07 Thread Jack Lau
Hi softworkz,

Thank you very much for your patient reply and kind suggestions. I am new to 
the FFmpeg devel mailing list, and English is not my native language, so there 
is still a lot for me to learn.

May I ask a question? How long does it usually take for a patch to be reviewed? 
A few days ago, I submitted a patch titled "[PATCH] examples/transcoding: Fix 
time_base handling," but it seems that no one has reviewed it yet. I understand 
everyone is busy, but I was wondering if there has been any feedback or if 
there are any concerns regarding the patch.

Jack

> 
> Hi Jack,
> 
> thanks for your reply and understanding. I wanted to note that it's not about 
> wrong answers in general. 
> An answer from yourself that starts with "I think" or similar is very 
> welcome, even when it might be wrong. :-)
> 
> sw
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


[FFmpeg-devel] avoption: make the avoption like seekable more general

2025-02-11 Thread Jack Lau
Hi everyone,

I’m trying to solve this issue https://trac.ffmpeg.org/ticket/11394.

This ticket shows that we need use `-seekable` and `-http_seekable` to control 
the range header if send.

Because these options belong to different file(hls.c and http.c)

So I try to modify the http_seekable to seekable in hls.c, but I realized the 
avoption parameter will be released after being used once. 

In that case, the init_input and read_header functions in avformat_open_input 
of demux.c used avoption successively, resulting in no seekable parameter in 
the second part of the http request (it has been used and released by 
init_input). So the second part of http request still not controled by the 
seekable option.

I think it’s necessary to make the avoption used be more general, it can be 
more friendly to users, there is no need for users to use two options for the 
same function. So I have two solutions here:

1. Do not release avoption immediately after use, to ensure that all avoptions 
have a complete life cycle in avformat_open_input, but this will cause a 
problem, that is, it is impossible to determine which options are used and 
which are not used.

2. Add new avoption type like general_avoption which has a longer life cycle 
than ordinary avoption, so that ordinary avoption can still retain the feature 
of being detected whether it is used.

Anyone feel free to give me some advice, I really want to make some 
contribution for this issue.

Thanks
Jack
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] avformat/hlsenc: fix CODECS Attribute hard code in hevc EXT-X-STREAM-INF

2025-03-02 Thread Jack Lau


> On Mar 2, 2025, at 15:47, Jack Lau via ffmpeg-devel  
> wrote:
> 
> fix ticket: 10786
> parse the SPS from extradata and get profile_compatibility, tier, constraints 
> which was been hard code before.
> 
> HEVC CODECS Attribute reference to: ISO/IEC14496-15
> Signed-off-by: Jack Lau 
> ---
> libavformat/hlsenc.c | 37 ++---
> 1 file changed, 34 insertions(+), 3 deletions(-)
> 
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index 6148685f40..be7a78021a 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -379,7 +379,10 @@ static void write_codec_attr(AVStream *st, VariantStream 
> *vs)
> } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
> uint8_t *data = st->codecpar->extradata;
> int profile = AV_PROFILE_UNKNOWN;
> +uint32_t profile_compatibility = AV_PROFILE_UNKNOWN; 
> +char tier = '0';
> int level = AV_LEVEL_UNKNOWN;
> +char constraints[5] = "0";
> 
> if (st->codecpar->profile != AV_PROFILE_UNKNOWN)
> profile = st->codecpar->profile;
> @@ -393,6 +396,8 @@ static void write_codec_attr(AVStream *st, VariantStream 
> *vs)
> uint8_t *rbsp_buf;
> int remain_size = 0;
> int rbsp_size = 0;
> +uint32_t profile_compatibility_flags = 0;
> +uint8_t high_nibble = 0;
> /* skip start code + nalu header */
> data += 6;
> /* process by reference General NAL unit syntax */
> @@ -406,8 +411,31 @@ static void write_codec_attr(AVStream *st, VariantStream 
> *vs)
> }
> /* skip sps_video_parameter_set_id   u(4),
>  *  sps_max_sub_layers_minus1u(3),
> - *  and sps_temporal_id_nesting_flag u(1) */
> + *  and sps_temporal_id_nesting_flag u(1) 
> + * 
> + * TIER represents the general_tier_flag, with 'L' 
> indicating the flag is 0,
> + * and 'H' indicating the flag is 1
> + */
> +tier = (int)(rbsp_buf[1] & 0x20) == 0 ? 'L' : 'H';
> profile = rbsp_buf[1] & 0x1f;
> +/* PROFILE_COMPATIBILITY is 
> general_profile_compatibility_flags, but in reverse bit order,
> + * in a hexadecimal representation (leading zeroes may be 
> omitted).
> + */
> +profile_compatibility_flags = (rbsp_buf[2] << 24) | 
> (rbsp_buf[3] << 16) | (rbsp_buf[4] << 8) | rbsp_buf[5];
> +/* revise these bits to get the profile compatibility value 
> */
> +for (int i = 0; i < 32; i++) {
> +profile_compatibility = (profile_compatibility << 1) | 
> (profile_compatibility_flags & 1);
> +profile_compatibility_flags >>= 1;
> +}
> +/* skip 8 + 8 + 32
> + * CONSTRAINTS is a hexadecimal representation of the 
> general_constraint_indicator_flags. 
> + * each byte is separated by a '.', and trailing zero bytes 
> may be omitted.
> + * drop the trailing zero bytes refer to ISO/IEC14496-15.
> + */
> +high_nibble = rbsp_buf[7] >> 4;
> +snprintf(constraints, sizeof(constraints),
> + high_nibble ? "%02x.%x" : "%02x",
> + rbsp_buf[6], high_nibble);
> /* skip 8 + 8 + 32 + 4 + 43 + 1 bit */
> level = rbsp_buf[12];
> av_freep(&rbsp_buf);
> @@ -417,8 +445,11 @@ static void write_codec_attr(AVStream *st, VariantStream 
> *vs)
> }
> if (st->codecpar->codec_tag == MKTAG('h','v','c','1') &&
> profile != AV_PROFILE_UNKNOWN &&
> -level != AV_LEVEL_UNKNOWN) {
> -snprintf(attr, sizeof(attr), "%s.%d.4.L%d.B01", 
> av_fourcc2str(st->codecpar->codec_tag), profile, level);
> +profile_compatibility != AV_PROFILE_UNKNOWN &&
> +tier != '0' &&
> +level != AV_LEVEL_UNKNOWN &&
> +strcmp(constraints, "0") != 0) {
> +snprintf(attr, sizeof(attr), "%s.%d.%x.%c%d.%s", 
> av_fourcc2str(st->codecpar->codec_tag), profile, profile_compatibility, tier, 
> level, constraints);
> } else
> 

Re: [FFmpeg-devel] [PATCH] avformat/hlsenc: fix CODECS Attribute hard code in hevc EXT-X-STREAM-INF

2025-03-02 Thread Jack Lau


> On Mar 3, 2025, at 09:08, Steven Liu  wrote:
> 
> Jack Lau via ffmpeg-devel  <mailto:ffmpeg-devel@ffmpeg.org>> 于2025年3月2日周日 21:31写道:
>> 
>> fix ticket: 10786
>> parse the SPS from extradata and get profile_compatibility, tier, 
>> constraints which was been hard code before.
>> 
>> HEVC CODECS Attribute reference to: ISO/IEC14496-15
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/hlsenc.c | 41 ++---
>> 1 file changed, 38 insertions(+), 3 deletions(-)
>> 
>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>> index 6148685f40..849130196f 100644
>> --- a/libavformat/hlsenc.c
>> +++ b/libavformat/hlsenc.c
>> @@ -379,7 +379,10 @@ static void write_codec_attr(AVStream *st, 
>> VariantStream *vs)
>> } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
>> uint8_t *data = st->codecpar->extradata;
>> int profile = AV_PROFILE_UNKNOWN;
>> +uint32_t profile_compatibility = AV_PROFILE_UNKNOWN;
>> +char tier = 0;
>> int level = AV_LEVEL_UNKNOWN;
>> +char constraints[8] = "";
>> 
>> if (st->codecpar->profile != AV_PROFILE_UNKNOWN)
>> profile = st->codecpar->profile;
>> @@ -393,6 +396,8 @@ static void write_codec_attr(AVStream *st, VariantStream 
>> *vs)
>> uint8_t *rbsp_buf;
>> int remain_size = 0;
>> int rbsp_size = 0;
>> +uint32_t profile_compatibility_flags = 0;
>> +uint8_t high_nibble = 0;
>> /* skip start code + nalu header */
>> data += 6;
>> /* process by reference General NAL unit syntax */
>> @@ -406,8 +411,35 @@ static void write_codec_attr(AVStream *st, 
>> VariantStream *vs)
>> }
>> /* skip sps_video_parameter_set_id   u(4),
>>  *  sps_max_sub_layers_minus1u(3),
>> - *  and sps_temporal_id_nesting_flag u(1) */
>> + *  and sps_temporal_id_nesting_flag u(1)
>> + *
>> + * TIER represents the general_tier_flag, with 'L' 
>> indicating the flag is 0,
>> + * and 'H' indicating the flag is 1
>> + */
>> +tier = (int)(rbsp_buf[1] & 0x20) == 0 ? 'L' : 'H';
> Since 'tier' is a char, the cast to (int) should be unnecessary.
Got it! remove (int) already in the latest patch.
>> profile = rbsp_buf[1] & 0x1f;
>> +/* PROFILE_COMPATIBILITY is 
>> general_profile_compatibility_flags, but in reverse bit order,
>> + * in a hexadecimal representation (leading zeroes may be 
>> omitted).
>> + */
>> +profile_compatibility_flags = AV_RB32(rbsp_buf + 2);
>> +/* revise these bits to get the profile compatibility value 
>> */
>> +{
> remove this braces
> 
>> +   uint32_t x = profile_compatibility_flags;
>> +x = ((x & 0xU) << 1) | ((x >> 1) & 0xU);
>> +x = ((x & 0xU) << 2) | ((x >> 2) & 0xU);
>> +x = ((x & 0x0F0F0F0FU) << 4) | ((x >> 4) & 0x0F0F0F0FU);
>> +x = ((x & 0x00FF00FFU) << 8) | ((x >> 8) & 0x00FF00FFU);
>> +profile_compatibility = (x << 16) | (x >> 16);
>> +}
> ditoo
Thank you for reminding me of this problem. In the latest patch, I not only 
removed braces, but also removed the temporary variable x. Direct bit 
operations on profile_compatibility_flags will save more resources.
>> +/* skip 8 + 8 + 32
>> + * CONSTRAINTS is a hexadecimal representation of the 
>> general_constraint_indicator_flags.
>> + * each byte is separated by a '.', and trailing zero bytes 
>> may be omitted.
>> + * drop the trailing zero bytes refer to ISO/IEC14496-15.
>> + */
>> +high_nibble = rbsp_buf[7] >> 4;
>> +snprintf(constraints, sizeof(constraints),
>> + high_nibble ? "%02x.%x" : "%02x",
>> + rbsp_buf[6], high_nibble);
>> /* skip 8 + 8 + 32 + 4 + 43 + 1 bit */
>>

Re: [FFmpeg-devel] [PATCH] avformat/hlsenc: calculate bitrate for segments with duration < 0.5

2025-03-23 Thread Jack Lau


> On Mar 24, 2025, at 08:11, Steven Liu  wrote:
> 
> Jack Lau via ffmpeg-devel  <mailto:ffmpeg-devel@ffmpeg.org>> 于2025年3月24日周一 07:13写道:
>> 
>> The previous code sets the bitrate to be calculated only when duration>0.5, 
>> which is obviously not general enough.
>> 
>> In some scenarios, we may need to set hls_time<0.5, then the generated 
>> segments are all <0.5. At this time, because the bitrate is not calculated, 
>> max_bitrate is empty, and ff_hls_write_stream_info cannot write stream info 
>> normally, causing master_pl to be unavailable.
>> 
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/hlsenc.c | 4 +---
>> 1 file changed, 1 insertion(+), 3 deletions(-)
>> 
>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>> index c6ffdb99e5..223c516103 100644
>> --- a/libavformat/hlsenc.c
>> +++ b/libavformat/hlsenc.c
>> @@ -1150,9 +1150,7 @@ static int hls_append_segment(struct AVFormatContext 
>> *s, HLSContext *hls,
>> 
>> vs->total_size += size;
>> vs->total_duration += duration;
>> -if (duration > 0.5) {
>> -// Don't include the final, possibly very short segment in the
>> -// calculation of the max bitrate.
>> +if (duration > 0) {
> 
> I'm not sure if this will work well in llhls mode,
> but when the network conditions are even slightly poor,
> severe stuttering or even an inability to continue playback occurs.
> This is because the segments are so small that the network overhead
> exceeds the time it takes to play them.

Thanks for your reply, It seems that the actual situation requires more complex 
considerations. I will study it further.
> 
>> int cur_bitrate = (int)(8 * size / duration);
>> if (cur_bitrate > vs->max_bitrate)
>> vs->max_bitrate = cur_bitrate;
>> --
>> 2.47.1
>> 
>> ___
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> 
> Thanks
> Steven
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@ffmpeg.org> with 
> subject "unsubscribe”.

Regards
Jack



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

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


Re: [FFmpeg-devel] [PATCH] avformat/dashenc: add hevc codec attributes parse

2025-03-27 Thread Jack Lau


> On Mar 12, 2025, at 15:06, Jack Lau via ffmpeg-devel 
>  wrote:
> 
> fix ticket: 11316
> add set_hevc_codec_str function refer to hlsenc.c but do some necessary 
> changes
> Signed-off-by: Jack Lau 
> ---
> libavformat/dashenc.c | 81 +++
> 1 file changed, 81 insertions(+)
> 
> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
> index d4a6fe0304..04c5b562d5 100644
> --- a/libavformat/dashenc.c
> +++ b/libavformat/dashenc.c
> @@ -57,6 +57,7 @@
> #include "url.h"
> #include "vpcc.h"
> #include "dash.h"
> +#include "nal.h"
> 
> typedef enum {
>SEGMENT_TYPE_AUTO = 0,
> @@ -344,6 +345,84 @@ static void set_vp9_codec_str(AVFormatContext *s, 
> AVCodecParameters *par,
>return;
> }
> 
> +static void set_hevc_codec_str(AVCodecParameters *par, char *str, int size) {
> +uint8_t *data = par->extradata;
> +int profile = AV_PROFILE_UNKNOWN;
> +uint32_t profile_compatibility = AV_PROFILE_UNKNOWN; 
> +char tier = 0;
> +int level = AV_LEVEL_UNKNOWN;
> +char constraints[8] = "";
> +
> +if (par->profile != AV_PROFILE_UNKNOWN)
> +profile = par->profile;
> +if (par->level != AV_LEVEL_UNKNOWN)
> +level = par->level;
> +
> +/* check the boundary of data which from current position is small than 
> extradata_size */
> +while (data && (data - par->extradata + 19) < par->extradata_size) {
> +/* get HEVC SPS NAL and seek to profile_tier_level */
> +if (!(data[0] | data[1] | data[2]) && data[3] == 1 && ((data[4] & 
> 0x7E) == 0x42)) {
> +uint8_t *rbsp_buf;
> +int remain_size = 0;
> +int rbsp_size = 0;
> +uint32_t profile_compatibility_flags = 0;
> +uint8_t high_nibble = 0;
> +/* skip start code + nalu header */
> +data += 6;
> +/* process by reference General NAL unit syntax */
> +remain_size = par->extradata_size - (data - par->extradata);
> +rbsp_buf = ff_nal_unit_extract_rbsp(data, remain_size, 
> &rbsp_size, 0);
> +if (!rbsp_buf)
> +return;
> +if (rbsp_size < 13) {
> +av_freep(&rbsp_buf);
> +break;
> +}
> +/* skip sps_video_parameter_set_id   u(4),
> +*  sps_max_sub_layers_minus1u(3),
> +*  and sps_temporal_id_nesting_flag u(1) 
> +* 
> +* TIER represents the general_tier_flag, with 'L' indicating the 
> flag is 0,
> +* and 'H' indicating the flag is 1
> +*/
> +tier = (rbsp_buf[1] & 0x20) == 0 ? 'L' : 'H';
> +profile = rbsp_buf[1] & 0x1f;
> +/* PROFILE_COMPATIBILITY is general_profile_compatibility_flags, 
> but in reverse bit order,
> +* in a hexadecimal representation (leading zeroes may be 
> omitted).
> +*/
> +profile_compatibility_flags = AV_RB32(rbsp_buf + 2);
> +/* revise these bits to get the profile compatibility value */
> +profile_compatibility_flags = ((profile_compatibility_flags & 
> 0xU) << 1) | ((profile_compatibility_flags >> 1) & 0xU);
> +profile_compatibility_flags = ((profile_compatibility_flags & 
> 0xU) << 2) | ((profile_compatibility_flags >> 2) & 0xU);
> +profile_compatibility_flags = ((profile_compatibility_flags & 
> 0x0F0F0F0FU) << 4) | ((profile_compatibility_flags >> 4) & 0x0F0F0F0FU);
> +profile_compatibility_flags = ((profile_compatibility_flags & 
> 0x00FF00FFU) << 8) | ((profile_compatibility_flags >> 8) & 0x00FF00FFU);
> +profile_compatibility = (profile_compatibility_flags << 16) | 
> (profile_compatibility_flags >> 16);
> +/* skip 8 + 8 + 32
> +* CONSTRAINTS is a hexadecimal representation of the 
> general_constraint_indicator_flags. 
> +* each byte is separated by a '.', and trailing zero bytes may 
> be omitted.
> +* drop the trailing zero bytes refer to ISO/IEC14496-15.
> +*/
> +high_nibble = rbsp_buf[7] >> 4;
> +snprintf(constraints, sizeof(constraints),
> +high_nibble ? "%02x.%x" : "%02x",
> +rbsp_buf[6], high_nibble);
> +/* skip 8 + 8 + 32 + 4 + 43 + 

[FFmpeg-devel] WHIP Feature latest patch Preparation Notes

2025-05-16 Thread Jack Lau
Hi everyone,
I’m excited to be a GSoC student this year, working on supporting the WHIP 
feature in FFmpeg with my mentors Steven Liu and Zhao Jun.
Two years ago, my mentor Steven Liu sent a whip 
patch(https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230529115039.17409-1...@chinaffmpeg.org/)
 and got some reviews, most of these reviews were fixed except DTLS. So I 
refactored the DTLS implementation and merged it into tls_openssl.c. 
Before I send out the latest patch, I plan to respond to the previous reviews 
one by one. BTW, most of response from Winlin 
(https://github.com/ossrs/ffmpeg-webrtc/discussions)

 On Mon May 29 16:00:33 EEST 2023, Michael Niedermayer wrote:
> 
> On Mon, May 29, 2023 at 07:50:39PM +0800, Steven Liu wrote:
> > Co-authored-by: winlin 
> > Co-authored-by: yangrtc 
> > Co-authored-by: cloudwebrtc 
> > Co-authored-by: Haibo Chen <495810242 at qq.com>
> > Signed-off-by: Steven Liu 
> > ---
> > configure | 1 +
> > doc/muxers.texi | 50 +
> > libavformat/Makefile | 1 +
> > libavformat/allformats.c | 1 +
> > libavformat/http.c | 6 +
> > libavformat/http.h | 2 +
> > libavformat/rtcenc.c | 2208 ++
> > 7 files changed, 2269 insertions(+)
> > create mode 100644 libavformat/rtcenc.c
> 
> breaks build:
> 
> CC libavformat/rtcenc.o
> libavformat/rtcenc.c:30:2: error: #error "OpenSSL version 1.1.1b or newer is 
> required"
> #error "OpenSSL version 1.1.1b or newer is required"
> ^
> libavformat/rtcenc.c: In function ‘dtls_context_init’:
> libavformat/rtcenc.c:210:34: error: implicit declaration of function 
> ‘EVP_EC_gen’; did you mean ‘EVP_PBE_get’? 
> [-Werror=implicit-function-declaration]
> ctx->dtls_pkey = dtls_pkey = EVP_EC_gen(curve);
> ^~
> EVP_PBE_get
Winlin: This issue was caused by a combination of OpenSSL version check and API 
usage. I tested a set of OpenSSL versions, fixed the issue, and found that 
OpenSSL 1.0.1k and newer versions should work now.
OpenSSL 1.0.1k or newer versions are supported.
Fixed.
> libavformat/rtcenc.c:210:32: warning: assignment makes pointer from integer 
> without a cast [-Wint-conversion]
> ctx->dtls_pkey = dtls_pkey = EVP_EC_gen(curve);
> ^
> cc1: some warnings being treated as errors
> ffbuild/common.mak:81: recipe for target 'libavformat/rtcenc.o' failed
> make: *** [libavformat/rtcenc.o] Error 1
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB




On Tue May 30 11:44:06 EEST 2023, Kieran Kunhya wrote:


> On Mon, 29 May 2023 at 12:51, Steven Liu  wrote:
> 
> > Co-authored-by: winlin 
> > Co-authored-by: yangrtc 
> > Co-authored-by: cloudwebrtc 
> > Co-authored-by: Haibo Chen <495810242 at qq.com>
> > Signed-off-by: Steven Liu 
> > ---
> > configure | 1 +
> > doc/muxers.texi | 50 +
> > libavformat/Makefile | 1 +
> > libavformat/allformats.c | 1 +
> > libavformat/http.c | 6 +
> > libavformat/http.h | 2 +
> > libavformat/rtcenc.c | 2208 ++
> > 7 files changed, 2269 insertions(+)
> > create mode 100644 libavformat/rtcenc.c
> >
> > diff --git a/configure b/configure
> > index 495493aa0e..526ddc0bd6 100755
> > --- a/configure
> > +++ b/configure
> > @@ -3483,6 +3483,7 @@ ogg_demuxer_select="dirac_parse"
> > ogv_muxer_select="ogg_muxer"
> > opus_muxer_select="ogg_muxer"
> > psp_muxer_select="mov_muxer"
> > +rtc_muxer_deps_any="openssl"
> > rtp_demuxer_select="sdp_demuxer"
> > rtp_mpegts_muxer_select="mpegts_muxer rtp_muxer"
> > rtpdec_select="asf_demuxer mov_demuxer mpegts_demuxer rm_demuxer
> > rtp_protocol srtp"
> > diff --git a/doc/muxers.texi b/doc/muxers.texi
> > index 31fca17dd6..00052f51b4 100644
> > --- a/doc/muxers.texi
> > +++ b/doc/muxers.texi
> > @@ -1333,6 +1333,56 @@ Set custom HTTP headers, can override built in
> > default headers. Applicable only
> >
> > @end table
> >
> > + at anchor{rtc}
> > + at section rtc
> > +
> > +WebRTC (Real-Time Communication) muxer that supports sub-second latency
> > streaming according to
> > +the WHIP (WebRTC-HTTP ingestion protocol) specification.
> > +
> > +It uses HTTP as a signaling protocol to exchange SDP capabilities and ICE
> > lite candidates. Then,
> > +it uses STUN binding requests and responses to establish a session over
> > UDP. Subsequently, it
> > +initiates a DTLS handshake to exchange the SRTP encryption keys. Lastly,
> > it splits video and
> > +audio frames into RTP packets and encrypts them using SRTP.
> > +
> > +Ensure that you use H.264 without B frames and Opus for the audio codec.
> > For example, to convert
> > +an input file with @command{ffmpeg} to WebRTC:
> > + at example
> > +ffmpeg -re -i input.mp4 -acodec libopus -ar 48000 -ac 2 \
> > + -vcodec libx264 -profile:v baseline -tune zerolatency -threads 1 -bf 0 \
> > + -f rtc "http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream";
> > + at end example
> > +
> > +For this example, we have employed low latency options, resulting in an
> > end-to-end latency of
> > +approximately 150ms.
> > +
> > + at 

Re: [FFmpeg-devel] [PATCH] avformat/whip: mark as experimental

2025-06-20 Thread Jack Lau



> On Jun 10, 2025, at 17:26, Jack Lau via ffmpeg-devel 
>  wrote:
> 
> 
> From: Jack Lau 
> Subject: [PATCH] avformat/whip: mark as experimental
> Date: June 10, 2025 at 17:26:13 GMT+8
> To: ffmpeg-devel@ffmpeg.org
> Cc: Jack Lau 
> 
> 
> This muxer has been marked AVFMT_EXPERIMENTAL.
> 
> Add a note in muxers.texi that WHIP is an experimental feature
> 
> This patch doesn't effect WHIP usage command, as WHIP always
> needs to be explicitly specified
> 
> The details as follows:
> https://ffmpeg.org/pipermail/ffmpeg-devel/2025-June/344705.html
> 
> Signed-off-by: Jack Lau 
> ---
> doc/muxers.texi| 2 ++
> libavformat/whip.c | 2 +-
> 2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index 30c95c3d34..d2ee90bf33 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -3885,6 +3885,8 @@ ffmpeg -f webm_dash_manifest -i video1.webm \
> WebRTC (Real-Time Communication) muxer that supports sub-second latency 
> streaming according to
> the WHIP (WebRTC-HTTP ingestion protocol) specification.
> 
> +This is an experimental feature.
> +
> It uses HTTP as a signaling protocol to exchange SDP capabilities and ICE 
> lite candidates. Then,
> it uses STUN binding requests and responses to establish a session over UDP. 
> Subsequently, it
> initiates a DTLS handshake to exchange the SRTP encryption keys. Lastly, it 
> splits video and
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index 710f24fc5a..bb7b8657dc 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -1907,7 +1907,7 @@ const FFOutputFormat ff_whip_muxer = {
> .p.long_name= NULL_IF_CONFIG_SMALL("WHIP(WebRTC-HTTP ingestion 
> protocol) muxer"),
> .p.audio_codec  = AV_CODEC_ID_OPUS,
> .p.video_codec  = AV_CODEC_ID_H264,
> -.p.flags= AVFMT_GLOBALHEADER | AVFMT_NOFILE,
> +.p.flags= AVFMT_GLOBALHEADER | AVFMT_NOFILE | 
> AVFMT_EXPERIMENTAL,
> .p.priv_class   = &whip_muxer_class,
> .priv_data_size = sizeof(WHIPContext),
> .init   = whip_init,
> -- 
> 2.49.0
Forgot to tag v4
PING.
> 
> 
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 1/3] avformat/whip: replace AV_OPT_FLAG_DECODING_PARAM to ENCODING

2025-06-20 Thread Jack Lau


> On Jun 13, 2025, at 16:56, Jack Lau via ffmpeg-devel 
>  wrote:
> 
> 
> From: Jack Lau 
> Subject: [PATCH v3 1/3] avformat/whip: replace AV_OPT_FLAG_DECODING_PARAM to 
> ENCODING
> Date: June 13, 2025 at 16:56:03 GMT+8
> To: ffmpeg-devel@ffmpeg.org
> Cc: Jack Lau 
> 
> 
> Signed-off-by: Jack Lau 
> ---
> libavformat/whip.c | 12 ++--
> 1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index 710f24fc5a..a6827d3478 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -1885,13 +1885,13 @@ static int whip_check_bitstream(AVFormatContext *s, 
> AVStream *st, const AVPacket
> }
> 
> #define OFFSET(x) offsetof(WHIPContext, x)
> -#define DEC AV_OPT_FLAG_DECODING_PARAM
> +#define ENC AV_OPT_FLAG_ENCODING_PARAM
> static const AVOption options[] = {
> -{ "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
> handshake.",  OFFSET(handshake_timeout),  AV_OPT_TYPE_INT,{ .i64 = 
> 5000 },-1, INT_MAX, DEC },
> -{ "pkt_size",   "The maximum size, in bytes, of RTP packets that 
> send out", OFFSET(pkt_size),   AV_OPT_TYPE_INT,{ .i64 = 1200 },   
>  -1, INT_MAX, DEC },
> -{ "authorization",  "The optional Bearer token for WHIP 
> Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { 
> .str = NULL }, 0,   0, DEC },
> -{ "cert_file",  "The optional certificate file path for DTLS",   
>OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL },   
>   0,   0, DEC },
> -{ "key_file",   "The optional private key file path for DTLS",   
>OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0, 
>   0, DEC },
> +{ "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
> handshake.",  OFFSET(handshake_timeout),  AV_OPT_TYPE_INT,{ .i64 = 
> 5000 },-1, INT_MAX, ENC },
> +{ "pkt_size",   "The maximum size, in bytes, of RTP packets that 
> send out", OFFSET(pkt_size),   AV_OPT_TYPE_INT,{ .i64 = 1200 },   
>  -1, INT_MAX, ENC },
> +{ "authorization",  "The optional Bearer token for WHIP 
> Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { 
> .str = NULL }, 0,   0, ENC },
> +{ "cert_file",  "The optional certificate file path for DTLS",   
>OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL },   
>   0,   0, ENC },
> +{ "key_file",   "The optional private key file path for DTLS",   
>OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0, 
>   0, ENC },
> { NULL },
> };
> 
> -- 
> 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-requ...@ffmpeg.org with subject "unsubscribe”.
PING.



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

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


Re: [FFmpeg-devel] [PATCH v3] avformat/tls_openssl: fix warnings when openssl is lower version

2025-06-20 Thread Jack Lau


> On Jun 17, 2025, at 22:07, Jack Lau  wrote:
> 
> 
> 
>> On Jun 15, 2025, at 23:54, Andreas Rheinhardt 
>>  wrote:
>> 
>> Jack Lau via ffmpeg-devel:
>>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>>> index 86e8935fee..2a3905891d 100644
>>> --- a/libavformat/tls_openssl.c
>>> +++ b/libavformat/tls_openssl.c
>>> @@ -415,7 +415,11 @@ error:
>>> */
>>> static EVP_PKEY *pkey_from_pem_string(const char *pem_str, int is_priv)
>>> {
>>> +#if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
>>> +BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
>>> +#else
>>>BIO *mem = BIO_new_mem_buf(pem_str, -1);
>>> +#endif
>>>if (!mem) {
>>>av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
>>>return NULL;
>>> @@ -445,7 +449,11 @@ static EVP_PKEY *pkey_from_pem_string(const char 
>>> *pem_str, int is_priv)
>>> */
>>> static X509 *cert_from_pem_string(const char *pem_str)
>>> {
>>> +#if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
>>> +BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
>>> +#else
>>>BIO *mem = BIO_new_mem_buf(pem_str, -1);
>>> +#endif
>>>if (!mem) {
>>>av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
>>>return NULL;
>> 
>> That's what I had in mind.
> Thanks for your review!
> If everything looks good, could you help merge this please?
>> 
>> - Andreas
> Best regards
> Jack
>> 
>> ___
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@ffmpeg.org> 
>> with subject "unsubscribe”.
PING.

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

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


Re: [FFmpeg-devel] [PATCH v3 1/3] avformat/whip: replace AV_OPT_FLAG_DECODING_PARAM to ENCODING

2025-06-23 Thread Jack Lau


> On Jun 21, 2025, at 12:58, Zhao Zhili  
> wrote:
> 
> 
> 
>> On Jun 21, 2025, at 10:15, Jack Lau  
>> wrote:
>> 
>> 
>> 
>>> On Jun 13, 2025, at 16:56, Jack Lau via ffmpeg-devel 
>>>  wrote:
>>> 
>>> 
>>> From: Jack Lau 
>>> Subject: [PATCH v3 1/3] avformat/whip: replace AV_OPT_FLAG_DECODING_PARAM 
>>> to ENCODING
>>> Date: June 13, 2025 at 16:56:03 GMT+8
>>> To: ffmpeg-devel@ffmpeg.org
>>> Cc: Jack Lau 
>>> 
>>> 
>>> Signed-off-by: Jack Lau 
>>> ---
>>> libavformat/whip.c | 12 ++--
>>> 1 file changed, 6 insertions(+), 6 deletions(-)
>>> 
>>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>>> index 710f24fc5a..a6827d3478 100644
>>> --- a/libavformat/whip.c
>>> +++ b/libavformat/whip.c
>>> @@ -1885,13 +1885,13 @@ static int whip_check_bitstream(AVFormatContext *s, 
>>> AVStream *st, const AVPacket
>>> }
>>> 
>>> #define OFFSET(x) offsetof(WHIPContext, x)
>>> -#define DEC AV_OPT_FLAG_DECODING_PARAM
>>> +#define ENC AV_OPT_FLAG_ENCODING_PARAM
>>> static const AVOption options[] = {
>>> -{ "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
>>> handshake.",  OFFSET(handshake_timeout),  AV_OPT_TYPE_INT,{ .i64 = 
>>> 5000 },-1, INT_MAX, DEC },
>>> -{ "pkt_size",   "The maximum size, in bytes, of RTP packets 
>>> that send out", OFFSET(pkt_size),   AV_OPT_TYPE_INT,{ .i64 = 
>>> 1200 },-1, INT_MAX, DEC },
>>> -{ "authorization",  "The optional Bearer token for WHIP 
>>> Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { 
>>> .str = NULL }, 0,   0, DEC },
>>> -{ "cert_file",  "The optional certificate file path for DTLS", 
>>>  OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL 
>>> }, 0,   0, DEC },
>>> -{ "key_file",   "The optional private key file path for DTLS", 
>>>  OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL },
>>>  0,   0, DEC },
>>> +{ "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
>>> handshake.",  OFFSET(handshake_timeout),  AV_OPT_TYPE_INT,{ .i64 = 
>>> 5000 },-1, INT_MAX, ENC },
>>> +{ "pkt_size",   "The maximum size, in bytes, of RTP packets 
>>> that send out", OFFSET(pkt_size),   AV_OPT_TYPE_INT,{ .i64 = 
>>> 1200 },-1, INT_MAX, ENC },
>>> +{ "authorization",  "The optional Bearer token for WHIP 
>>> Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { 
>>> .str = NULL }, 0,   0, ENC },
>>> +{ "cert_file",  "The optional certificate file path for DTLS", 
>>>  OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL 
>>> }, 0,   0, ENC },
>>> +{ "key_file",   "The optional private key file path for DTLS", 
>>>  OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL },
>>>  0,   0, ENC },
>>>   { NULL },
>>> };
>>> 
>>> -- 
>>> 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-requ...@ffmpeg.org with subject "unsubscribe”.
>> PING.
> 
> Applied, 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-requ...@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-requ...@ffmpeg.org with subject "unsubscribe”.

There’re two other patches in this patchset 
https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=14768
, Could you help merge these please?

I want to submit WHIP NACK patch that depends on these patches.

Best regards
Jack



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

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


Re: [FFmpeg-devel] [PATCH v3] avformat/tls_openssl: fix warnings when openssl is lower version

2025-06-17 Thread Jack Lau



> On Jun 15, 2025, at 23:54, Andreas Rheinhardt 
>  wrote:
> 
> Jack Lau via ffmpeg-devel:
>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>> index 86e8935fee..2a3905891d 100644
>> --- a/libavformat/tls_openssl.c
>> +++ b/libavformat/tls_openssl.c
>> @@ -415,7 +415,11 @@ error:
>>  */
>> static EVP_PKEY *pkey_from_pem_string(const char *pem_str, int is_priv)
>> {
>> +#if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
>> +BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
>> +#else
>> BIO *mem = BIO_new_mem_buf(pem_str, -1);
>> +#endif
>> if (!mem) {
>> av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
>> return NULL;
>> @@ -445,7 +449,11 @@ static EVP_PKEY *pkey_from_pem_string(const char 
>> *pem_str, int is_priv)
>>  */
>> static X509 *cert_from_pem_string(const char *pem_str)
>> {
>> +#if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
>> +BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
>> +#else
>> BIO *mem = BIO_new_mem_buf(pem_str, -1);
>> +#endif
>> if (!mem) {
>> av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
>> return NULL;
> 
> That's what I had in mind.
Thanks for your review!
If everything looks good, could you help merge this please?
> 
> - Andreas
Best regards
Jack
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 2/2] avformat/whip: check the exchange sdp url is start with http

2025-06-08 Thread Jack Lau


> On Jun 6, 2025, at 11:02, Steven Liu  wrote:
> 
> Make sure the WHIP protocol performs the SDP offer/answer
> exchange with the WebRTC peer over HTTP.
> 
> Signed-off-by: Steven Liu 
> ---
> libavformat/whip.c | 8 
> 1 file changed, 8 insertions(+)
> 
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index ce06a66bc4..b78ad27858 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -732,10 +732,18 @@ static int exchange_sdp(AVFormatContext *s)
> URLContext *whip_uc = NULL;
> AVDictionary *opts = NULL;
> char *hex_data = NULL;
> +const char *proto_name = avio_find_protocol_name(s->url);
> 
> /* To prevent a crash during cleanup, always initialize it. */
> 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",
> +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");
> ret = AVERROR(EINVAL);
> -- 
> 2.39.3 (Apple Git-146)
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe”.

patchset LGTM

Thanks
Jack



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

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


Re: [FFmpeg-devel] [PATCH] avformat/whip: set this muxer as experimental

2025-06-05 Thread Jack Lau


> On Jun 5, 2025, at 22:56, James Almer  wrote:
> 
> On 6/5/2025 11:54 AM, Jack Lau via ffmpeg-devel wrote:
>> Signed-off-by: Jack Lau 
>> ---
>>  libavformat/whip.c | 6 ++
>>  1 file changed, 6 insertions(+)
>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>> index 0671e23635..e7cd57400d 100644
>> --- a/libavformat/whip.c
>> +++ b/libavformat/whip.c
>> @@ -1733,6 +1733,12 @@ static av_cold int whip_init(AVFormatContext *s)
>>  int ret;
>>  WHIPContext *whip = s->priv_data;
>>  +if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
>> +av_log(s, AV_LOG_ERROR,
>> +"WHIP: This muxer is experimental, please set -strict 
>> experimental in order to enable it\n");
>> +return AVERROR_EXPERIMENTAL;
>> +}
>> +
>>  if ((ret = initialize(s)) < 0)
>>  goto end;
> 
> I think the AVFMT_EXPERIMENTAL flag is used for this.
I’ve tried this, but the whip runs normally even I don’t set `-strict 
experimental`

@@ -1913,7 +1913,7 @@ const FFOutputFormat ff_whip_muxer = {
 .p.long_name= NULL_IF_CONFIG_SMALL("WHIP(WebRTC-HTTP ingestion 
protocol) muxer"),
 .p.audio_codec  = AV_CODEC_ID_OPUS,
 .p.video_codec  = AV_CODEC_ID_H264,
-.p.flags= AVFMT_GLOBALHEADER | AVFMT_NOFILE,
+.p.flags= AVFMT_GLOBALHEADER | AVFMT_NOFILE | 
AVFMT_EXPERIMENTAL,
 .p.priv_class   = &whip_muxer_class,
 .priv_data_size = sizeof(WHIPContext),
 .init   = whip_init,

> ffmpeg -re -i input.mp4 -c copy -f whip 
> "http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream";
ffmpeg version N-119824-gbdf45d079e Copyright (c) 2000-2025 the FFmpeg 
developers
  built with Apple clang version 17.0.0 (clang-1700.0.13.5)
  configuration: --enable-gpl --enable-shared --disable-static 
--disable-optimizations --enable-libx264 --enable-libx265 --enable-libopus 
--enable-sdl2 --enable-debug=3 --disable-stripping --enable-openssl 
--enable-version3
  libavutil  60.  3.100 / 60.  3.100
  libavcodec 62.  3.101 / 62.  3.101
  libavformat62.  0.102 / 62.  0.102
  libavdevice62.  0.100 / 62.  0.100
  libavfilter11.  0.100 / 11.  0.100
  libswscale  9.  0.100 /  9.  0.100
  libswresample   6.  0.100 /  6.  0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
major_brand : isom
minor_version   : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf60.9.100
comment : vid:v0300fg1cgho9hjc77u1ugkqvn10
  Duration: 00:01:47.40, start: 0.00, bitrate: 5716 kb/s
  Stream #0:0[0x1](und): Video: h264 (Constrained Baseline) (avc1 / 
0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 
5613 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
  handler_name: VideoHandler
  vendor_id   : [0][0][0][0]
  encoder : Lavc60.21.100 libx264
  Stream #0:1[0x2](und): Audio: opus (Opus / 0x7375704F), 48000 Hz, stereo, 
fltp, 95 kb/s (default)
Metadata:
  handler_name: SoundHandler
  vendor_id   : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
[WHIP muxer @ 0x119808200] WHIP: Muxer state=11, buffer_size=4096, 
max_packet_size=1184, 
elapsed=96ms(init:9,offer:0,answer:25,udp:0,ice:5,dtls:54,srtp:0)
Output #0, whip, to 
'http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream':
  Metadata:
major_brand : isom
minor_version   : 512
compatible_brands: isomiso2avc1mp41
comment : vid:v0300fg1cgho9hjc77u1ugkqvn10
encoder : Lavf62.0.102
  Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), 
yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 5613 
kb/s, 30 fps, 30 tbr, 90k tbn (default)
Metadata:
  handler_name: VideoHandler
  vendor_id   : [0][0][0][0]
  encoder : Lavc60.21.100 libx264
  Stream #0:1(und): Audio: opus (Opus / 0x7375704F), 48000 Hz, stereo, fltp, 95 
kb/s (default)
Metadata:
  handler_name: SoundHandler
  vendor_id   : [0][0][0][0]
Press [q] to stop, [?] for help
[WHIP muxer @ 0x119808200] WHIP: Dispose resource 
http://localhost:1985/rtc/v1/whip/?action=delete&token=i540z3223&app=live&stream=livestream&session=a2093739:93b7d050
 ok
[out#0/whip @ 0x14a905320] video:1738KiB audio:25KiB subtitle:0KiB other 
streams:0KiB global headers:0KiB muxing overhead: unknown
frame=   62 fps= 32 q=-1.0 Lsize=N/A time=00:00:02.03 bitrate=N/A speed=1.04x 
elapsed=0:00:01.94

I noticed the AVFMT_EXPERIMENTAL flag was used in this code:

format.c
186 while ((fmt1 = av_demuxer_iterate(&i))) {
187 if (fmt1->flags & AVFMT_EXPERIMENTAL)  

Re: [FFmpeg-devel] [PATCH v2] avformat/tls_openssl: fix warnings when openssl is lower version

2025-06-12 Thread Jack Lau


> On Jun 8, 2025, at 08:25, Jack Lau via ffmpeg-devel  
> wrote:
> 
> api doc: https://docs.openssl.org/1.0.2/man3/BIO_s_mem
> 
> In higher versions (openssl 1.0.2 and higher),
> the function signature is BIO *BIO_new_mem_buf(const void *buf, int len),
> so passing a const string doesn't cause an warnings.
> However, in lower versions of OpenSSL,
> the function signature becomes BIO *BIO_new_mem_buf(void *buf, int len),
> which leads to warnings.
> 
> OpenSSL guarantees that it will not modify the string,
> so it's safe to cast the pem_str to (void *) to avoid this warning.
> 
> Signed-off-by: Jack Lau 
> ---
> libavformat/tls_openssl.c | 14 --
> 1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
> index 86e8935fee..0a6e5680f4 100644
> --- a/libavformat/tls_openssl.c
> +++ b/libavformat/tls_openssl.c
> @@ -415,7 +415,12 @@ error:
>  */
> static EVP_PKEY *pkey_from_pem_string(const char *pem_str, int is_priv)
> {
> -BIO *mem = BIO_new_mem_buf(pem_str, -1);
> +BIO *mem = NULL;
> +#if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
> +mem = BIO_new_mem_buf((void *)pem_str, -1);
> +#else
> +mem = BIO_new_mem_buf(pem_str, -1);
> +#endif
> if (!mem) {
> av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
> return NULL;
> @@ -445,7 +450,12 @@ static EVP_PKEY *pkey_from_pem_string(const char 
> *pem_str, int is_priv)
>  */
> static X509 *cert_from_pem_string(const char *pem_str)
> {
> -BIO *mem = BIO_new_mem_buf(pem_str, -1);
> +BIO *mem = NULL;
> +#if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
> +mem = BIO_new_mem_buf((void *)pem_str, -1);
> +#else
> +mem = BIO_new_mem_buf(pem_str, -1);
> +#endif
> if (!mem) {
> av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
> return 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-requ...@ffmpeg.org with subject "unsubscribe”.
PING.



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

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


Re: [FFmpeg-devel] [PATCH v2] avformat/tls_openssl: fix warnings when openssl is lower version

2025-06-15 Thread Jack Lau


> On Jun 15, 2025, at 11:38, Andreas Rheinhardt 
>  wrote:
> 
> Jack Lau via ffmpeg-devel:
>> api doc: https://docs.openssl.org/1.0.2/man3/BIO_s_mem
>> 
>> In higher versions (openssl 1.0.2 and higher),
>> the function signature is BIO *BIO_new_mem_buf(const void *buf, int len),
>> so passing a const string doesn't cause an warnings.
>> However, in lower versions of OpenSSL,
>> the function signature becomes BIO *BIO_new_mem_buf(void *buf, int len),
>> which leads to warnings.
>> 
>> OpenSSL guarantees that it will not modify the string,
>> so it's safe to cast the pem_str to (void *) to avoid this warning.
>> 
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/tls_openssl.c | 14 --
>> 1 file changed, 12 insertions(+), 2 deletions(-)
>> 
>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>> index 86e8935fee..0a6e5680f4 100644
>> --- a/libavformat/tls_openssl.c
>> +++ b/libavformat/tls_openssl.c
>> @@ -415,7 +415,12 @@ error:
>>  */
>> static EVP_PKEY *pkey_from_pem_string(const char *pem_str, int is_priv)
>> {
>> -BIO *mem = BIO_new_mem_buf(pem_str, -1);
>> +BIO *mem = NULL;
>> +#if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
>> +mem = BIO_new_mem_buf((void *)pem_str, -1);
>> +#else
>> +mem = BIO_new_mem_buf(pem_str, -1);
>> +#endif
>> if (!mem) {
>> av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
>> return NULL;
>> @@ -445,7 +450,12 @@ static EVP_PKEY *pkey_from_pem_string(const char 
>> *pem_str, int is_priv)
>>  */
>> static X509 *cert_from_pem_string(const char *pem_str)
>> {
>> -BIO *mem = BIO_new_mem_buf(pem_str, -1);
>> +BIO *mem = NULL;
>> +#if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
>> +mem = BIO_new_mem_buf((void *)pem_str, -1);
>> +#else
>> +mem = BIO_new_mem_buf(pem_str, -1);
>> +#endif
> 
> #if OPENSSL_VERSION_NUMBER < 0x10002000L /* OpenSSL 1.0.2 */
>BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
> #else
>BIO *mem = BIO_new_mem_buf(pem_str, -1);
> #endif
> 
> would have the advantage that it avoids the useless initialization and
> that the old code can be cleanly removed when we drop support for old
> versions of openssl. Same for above.
Thanks for your reply, I’ve sent the latest v3 patch refer to your reviews.
> 
>> if (!mem) {
>> av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
>> return NULL;
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [FFmpeg-cvslog] avformat/whip: Add WHIP muxer support for subsecond latency streaming

2025-06-04 Thread Jack Lau


> On Jun 4, 2025, at 22:05, Martin Storsjö  wrote:
> 
> On Wed, 4 Jun 2025, Jack Lau wrote:
> 
>> ffmpeg | branch: master | Jack Lau  | Fri May 16 
>> 20:15:05 2025 +0800| [167e343bbe75515a80db8ee72ffa0c607c944a00] | committer: 
>> Steven Liu
>> 
>> avformat/whip: Add WHIP muxer support for subsecond latency streaming
> 
> This breaks compilation with OpenSSL 1.1.1t:
> 
> src/libavformat/tls_openssl.c:1019:22: error: no member named 'dtls_eckey' in 
> 'struct TLSContext'
> 1019 | EC_KEY_free(ctx->dtls_eckey);
>  | ~~~  ^
> 

> So this change does require some configure checks or source level version 
> checks to see if we have a new enough version of OpenSSL to do what this does.
Sry about that, I’ve fix this issue in latest patch.
We support openssl versions > 1.0.1k, you can find it in configure checks, I’ll 
check other openssl versions if works well.

Thanks for your reminder!
Jack
> 
> // Martin
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3] avformat/whip: Add WHIP muxer support for subsecond latency streaming

2025-06-04 Thread Jack Lau


> On Jun 5, 2025, at 06:20, Kieran Kunhya via ffmpeg-devel 
>  wrote:
> 
> On Wed, 4 Jun 2025, 12:46 Steven Liu,  wrote:
> 
>> Kieran Kunhya via ffmpeg-devel  于2025年6月4日周三
>> 19:35写道:
>> Hi Kieran,
>> 
>>> 
>>> @Andreas Rheinhardt
>>> Should we revert this?
>> 
>> I believe it would be better to leave comments if there are any
>> concerns about the patch. Several weeks have passed without
>> objections, and I’ve been actively maintaining it for over half a
>> month.
>> 
>> As stated in the rules: "We will review all submitted patches, but
>> sometimes we are quite busy, so especially for large patches, this can
>> take several weeks." I reviewed this patch years ago and addressed the
>> questions that were raised at the time.
>> 
>> If anyone wants to contribute to this work, patches are welcome.
>> However, I don’t think reverting it is the right approach.
>> 
> 
> How do you handle RTCP retransmission requests in this patch?
> 
> Unless I am mistaken this isn't implemented so how can this patch work
> outside of a LAN?
Hi Kieran,

You're right — I'm currently working on NACK. 
I plan to finish some essential work before the end of this year's GSoC, 
including (but not limited to) NACK and support for multiple SSL libraries.

> 
> Kieran
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe”.

Thanks
Jack


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

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


Re: [FFmpeg-devel] [PATCH] avformat/tls_openssl: fix build error when openssl version < 3

2025-06-06 Thread Jack Lau


> On Jun 5, 2025, at 19:20, Martin Storsjö  wrote:
> 
> On Thu, 5 Jun 2025, Jack Lau wrote:
> 
>>> On Jun 5, 2025, at 15:02, Martin Storsjö  wrote:
>>> On Thu, 5 Jun 2025, Jack Lau via ffmpeg-devel wrote:
>>>> fix the missing data structure pkey in the tls_context
>>>> Signed-off-by: Jack Lau 
>>>> ---
>>>> libavformat/tls_openssl.c | 30 +-
>>>> 1 file changed, 17 insertions(+), 13 deletions(-)
>>> Thanks, this does fix the build break. However, I don't quite understand 
>>> the fix...
>>>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>>>> index b589d5d90a..bddeee9af8 100644
>>>> --- a/libavformat/tls_openssl.c
>>>> +++ b/libavformat/tls_openssl.c
>>>> @@ -467,6 +467,7 @@ typedef struct TLSContext {
>>>>   TLSShared tls_shared;
>>>>   SSL_CTX *ctx;
>>>>   SSL *ssl;
>>>> +EVP_PKEY *pkey;
>>>> #if OPENSSL_VERSION_NUMBER >= 0x101fL
>>>>   BIO_METHOD* url_bio_method;
>>>> #endif
>>> As far as I can see, nothing ever sets this new field, it is only used in a 
>>> couple of places?
>> Thanks for the review.
>> 
>> The previous build error occurred because I forgot to properly set the 
>> EC_KEY when using OpenSSL versions earlier than 3.0.
>> 
>> In the current WHIP implementation, I initialize the key and certificate 
>> (either by reading from file or generating them) before the DTLS handshake, 
>> since the SDP requires fingerprints. The WHIP layer then passes the key and 
>> certificate content as strings into the DTLS context.
>> 
>> This fix ensures that the EVP_PKEY is loaded into the tls_context when DTLS 
>> starts. For OpenSSL versions below 1.0.2, we need to call 
>> SSL_CTX_set_tmp_ecdh, which requires an EC_KEY. So, i extract the EC_KEY 
>> from the EVP_PKEY.
>> 
>> I hope that explanation was clear—please feel free to reach out if you have 
>> any further questions.
> 
> No that didn't answer my question.
> 
> As far as I can see, nothing sets the context variable p->pkey. It is used in 
> openssl_init_ca_key_cert and later in dtls_start. But nothing ever sets 
> p->key, so it will be NULL everywhere.
> 
> Did you test this code with openssl 1.0.2 (which those codepaths are for)?
> 
> It looks to me like this maybe should have an assignment in 
> openssl_init_ca_key_cert, setting "p->key = pkey;" maybe?
Thanks for your reminder! 
I’ve sent the patch v2 that fix this issue.

And I tested the major openssl versions (1.0.1, 1.0.2, 1.1.0, 3.0, latest) and 
it works well.

> 
> // Martin
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@ffmpeg.org> with 
> subject "unsubscribe”.
Thanks
Jack



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

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


Re: [FFmpeg-devel] [PATCH v2] avformat/format: make experimental flag works for muxer

2025-06-07 Thread Jack Lau


> On Jun 6, 2025, at 12:44, Zhao Zhili  
> wrote:
> 
> From: Zhao Zhili 
> 
> ---
> libavformat/avformat.h | 3 +--
> libavformat/format.c   | 2 ++
> 2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 2034d2aecc..441e31bc2f 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -470,8 +470,7 @@ typedef struct AVProbeData {
> /**
>  * The muxer/demuxer is experimental and should be used with caution.
>  *
> - * - demuxers: will not be selected automatically by probing, must be 
> specified
> - * explicitly.
> + * It will not be selected automatically, and must be specified explicitly.
>  */
> #define AVFMT_EXPERIMENTAL  0x0004
> #define AVFMT_SHOW_IDS  0x0008 /**< Show format stream IDs numbers. */
> diff --git a/libavformat/format.c b/libavformat/format.c
> index 71018ea6ab..516925e7e4 100644
> --- a/libavformat/format.c
> +++ b/libavformat/format.c
> @@ -95,6 +95,8 @@ const AVOutputFormat *av_guess_format(const char 
> *short_name, const char *filena
> /* Find the proper file type. */
> score_max = 0;
> while ((fmt = av_muxer_iterate(&i))) {
> +if (fmt->flags & AVFMT_EXPERIMENTAL && !short_name)

If `&& !short_name` means this if check is always false as long as this muxer 
has a name?
Shouldn’t drop this `!` ?

> +continue;
> score = 0;
> if (fmt->name && short_name && av_match_name(short_name, fmt->name))
> score += 100;
> -- 
> 2.46.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-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avformat/tls_openssl: fix build error when openssl version < 3

2025-06-05 Thread Jack Lau


> On Jun 5, 2025, at 15:02, Martin Storsjö  wrote:
> 
> On Thu, 5 Jun 2025, Jack Lau via ffmpeg-devel wrote:
> 
>> fix the missing data structure pkey in the tls_context
>> 
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/tls_openssl.c | 30 +-
>> 1 file changed, 17 insertions(+), 13 deletions(-)
> 
> Thanks, this does fix the build break. However, I don't quite understand the 
> fix...
> 
>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>> index b589d5d90a..bddeee9af8 100644
>> --- a/libavformat/tls_openssl.c
>> +++ b/libavformat/tls_openssl.c
>> @@ -467,6 +467,7 @@ typedef struct TLSContext {
>>TLSShared tls_shared;
>>SSL_CTX *ctx;
>>SSL *ssl;
>> +EVP_PKEY *pkey;
>> #if OPENSSL_VERSION_NUMBER >= 0x101fL
>>BIO_METHOD* url_bio_method;
>> #endif
> 
> As far as I can see, nothing ever sets this new field, it is only used in a 
> couple of places?
Thanks for the review.

The previous build error occurred because I forgot to properly set the EC_KEY 
when using OpenSSL versions earlier than 3.0.

In the current WHIP implementation, I initialize the key and certificate 
(either by reading from file or generating them) before the DTLS handshake, 
since the SDP requires fingerprints. The WHIP layer then passes the key and 
certificate content as strings into the DTLS context.

This fix ensures that the EVP_PKEY is loaded into the tls_context when DTLS 
starts. For OpenSSL versions below 1.0.2, we need to call SSL_CTX_set_tmp_ecdh, 
which requires an EC_KEY. So, i extract the EC_KEY from the EVP_PKEY.

I hope that explanation was clear—please feel free to reach out if you have any 
further questions.

> @@ -876,6 +877,9 @@ static int dtls_start(URLContext *h, const char *url, int 
> flags, AVDictionary **
> int ret = 0;
> c->is_dtls = 1;
> const char* ciphers = "ALL";
> +#if OPENSSL_VERSION_NUMBER < 0x10002000L // v1.0.2
> +EC_KEY *ec_key;
> +#endif
> /**
>  * The profile for OpenSSL's SRTP is SRTP_AES128_CM_SHA1_80, see 
> ssl/d1_srtp.c.
>  * The profile for FFmpeg's SRTP is SRTP_AES128_CM_HMAC_SHA1_80, see 
> libavformat/srtp.c.
> @@ -908,15 +912,6 @@ static int dtls_start(URLContext *h, const char *url, 
> int flags, AVDictionary **
> }
> #endif
> 
> -#if OPENSSL_VERSION_NUMBER < 0x1010L // v1.1.x
> -#if OPENSSL_VERSION_NUMBER < 0x10002000L // v1.0.2
> -if (ctx->dtls_eckey)
> -SSL_CTX_set_tmp_ecdh(p->ctx, p->dtls_eckey);
> -#else
> -SSL_CTX_set_ecdh_auto(p->ctx, 1);
> -#endif
> -#endif
> -
> /**
>  * We activate "ALL" cipher suites to align with the peer's capabilities,
>  * ensuring maximum compatibility.
> @@ -930,6 +925,17 @@ static int dtls_start(URLContext *h, const char *url, 
> int flags, AVDictionary **
> ret = openssl_init_ca_key_cert(h);
> if (ret < 0) goto fail;
> 
> +#if OPENSSL_VERSION_NUMBER < 0x1010L // v1.1.x
> +#if OPENSSL_VERSION_NUMBER < 0x10002000L // v1.0.2
> +if (p->pkey)
> +ec_key = EVP_PKEY_get1_EC_KEY(p->pkey);
> +if (ec_key)
> +SSL_CTX_set_tmp_ecdh(p->ctx, ec_key);
> +#else
> +SSL_CTX_set_ecdh_auto(p->ctx, 1);
> +#endif
> +#endif
> +
> /* Server will send Certificate Request. */
> SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, 
> openssl_dtls_verify_callback);
> /* The depth count is "level 0:peer certificate", "level 1: CA 
> certificate",
> @@ -1015,9 +1021,7 @@ static av_cold int dtls_close(URLContext *h)
> av_freep(&ctx->tls_shared.fingerprint);
> av_freep(&ctx->tls_shared.cert_buf);
> av_freep(&ctx->tls_shared.key_buf);
> -#if OPENSSL_VERSION_NUMBER < 0x3000L /* OpenSSL 3.0 */
> -EC_KEY_free(ctx->dtls_eckey);
> -#endif
> +EVP_PKEY_free(ctx->pkey);
> return 0;
> }
> 
> -- 
> 2.49.0

> 
> // Martin
Thanks
Jack
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 2/2] avformat/whip: Constify arguments in is_rtp_rtcp/is_rtcp

2025-06-05 Thread Jack Lau



> On Jun 5, 2025, at 17:41, Zhao Zhili  
> wrote:
> 
> From: Zhao Zhili 
> 
> Fix warning of -Wincompatible-pointer-types-discards-qualifiers.
> ---
> libavformat/whip.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index 0671e23635..710f24fc5a 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -1115,13 +1115,13 @@ static int ice_is_binding_response(uint8_t *b, int 
> size)
>  * The RTCP packet header is similar to RTP,
>  * see https://www.rfc-editor.org/rfc/rfc3550#section-6.4.1
>  */
> -static int media_is_rtp_rtcp(uint8_t *b, int size)
> +static int media_is_rtp_rtcp(const uint8_t *b, int size)
> {
> return size >= WHIP_RTP_HEADER_SIZE && (b[0] & 0xC0) == 0x80;
> }
> 
> /* Whether the packet is RTCP. */
> -static int media_is_rtcp(uint8_t *b, int size)
> +static int media_is_rtcp(const uint8_t *b, int size)
> {
> return size >= WHIP_RTP_HEADER_SIZE && b[1] >= WHIP_RTCP_PT_START && b[1] 
> <= WHIP_RTCP_PT_END;
> }
> -- 
> 2.25.1
LGTM

Thanks
Jack
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 1/2] avformat/tls: Fix integer overflow with option mtu

2025-06-05 Thread Jack Lau



> On Jun 5, 2025, at 17:41, Zhao Zhili  
> wrote:
> 
> From: Zhao Zhili 
> 
> ---
> libavformat/tls.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/libavformat/tls.h b/libavformat/tls.h
> index cb626f1977..2f381acc04 100644
> --- a/libavformat/tls.h
> +++ b/libavformat/tls.h
> @@ -90,7 +90,7 @@ typedef struct TLSShared {
> {"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}, INT64_MIN, INT64_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}, \
> {"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}
> -- 
> 2.25.1
LGTM

Thanks
Jack
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avformat/tls_openssl: fix warnings when openssl is lower version

2025-06-08 Thread Jack Lau



> On Jun 8, 2025, at 04:04, Andreas Rheinhardt  
> wrote:
> 
> Jack Lau via ffmpeg-devel:
>> In higher versions (like openssl 1.1.1 and higher),
>> the function signature is BIO *BIO_new_mem_buf(const void *buf, int len),
>> so passing a const string doesn't cause an warnings.
>> However, in lower versions of OpenSSL,
>> the function signature becomes BIO *BIO_new_mem_buf(void *buf, int len),
>> which leads to warnings.
>> 
>> OpenSSL guarantees that it will not modify the string,
>> so it's safe to cast the pem_str to (void *) to avoid this warning.
>> 
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/tls_openssl.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>> 
>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>> index 86e8935fee..5387e21df1 100644
>> --- a/libavformat/tls_openssl.c
>> +++ b/libavformat/tls_openssl.c
>> @@ -415,7 +415,7 @@ error:
>>  */
>> static EVP_PKEY *pkey_from_pem_string(const char *pem_str, int is_priv)
>> {
>> -BIO *mem = BIO_new_mem_buf(pem_str, -1);
>> +BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
>> if (!mem) {
>> av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
>> return NULL;
>> @@ -445,7 +445,7 @@ static EVP_PKEY *pkey_from_pem_string(const char 
>> *pem_str, int is_priv)
>>  */
>> static X509 *cert_from_pem_string(const char *pem_str)
>> {
>> -BIO *mem = BIO_new_mem_buf(pem_str, -1);
>> +BIO *mem = BIO_new_mem_buf((void *)pem_str, -1);
>> if (!mem) {
>> av_log(NULL, AV_LOG_ERROR, "BIO_new_mem_buf failed\n");
>> return NULL;
> 
> Shouldn't this use #if checks to only cast const away when building for
> old versions so that we do not forget to remove these casts when we drop
> support for these old versions (and to avoid warnings when using
> -Wcast-qual)?
Thanks for the review! The Patch v2 already is here 
https://ffmpeg.org/pipermail/ffmpeg-devel/2025-June/344816.html

Thanks
Jack
> 
> - Andreas
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3] avformat/whip: mark as experimental

2025-06-09 Thread Jack Lau


> On Jun 9, 2025, at 21:19, Tristan Matthews  wrote:
> 
> Hi,
> 
> 
> On Mon, Jun 9, 2025 at 6:25 AM Jack Lau via ffmpeg-devel
>  wrote:
>> 
>> 
>> 
>> 
>> ------ Forwarded message --
>> From: Jack Lau 
>> To: ffmpeg-devel@ffmpeg.org
>> Cc: Jack Lau 
>> Bcc:
>> Date: Mon,  9 Jun 2025 18:24:46 +0800
>> Subject: [PATCH v3] avformat/whip: mark as experimental
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/whip.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>> index 710f24fc5a..bb7b8657dc 100644
>> --- a/libavformat/whip.c
>> +++ b/libavformat/whip.c
>> @@ -1907,7 +1907,7 @@ const FFOutputFormat ff_whip_muxer = {
>> .p.long_name= NULL_IF_CONFIG_SMALL("WHIP(WebRTC-HTTP ingestion 
>> protocol) muxer"),
>> .p.audio_codec  = AV_CODEC_ID_OPUS,
>> .p.video_codec  = AV_CODEC_ID_H264,
>> -.p.flags= AVFMT_GLOBALHEADER | AVFMT_NOFILE,
>> +.p.flags= AVFMT_GLOBALHEADER | AVFMT_NOFILE | 
>> AVFMT_EXPERIMENTAL,
>> .p.priv_class   = &whip_muxer_class,
>> .priv_data_size = sizeof(WHIPContext),
>> .init   = whip_init,
>> --
>> 2.49.0
>> 
> 
> You may want to update the intended usage example in doc/muxers.texi
> to include the `experimental` flag (probably in a separate patch).
Thanks for the reminder!
I’ve sent the separate patch in 
https://patchwork.ffmpeg.org/project/ffmpeg/patch/mailman.2674.1749476775.1384.ffmpeg-de...@ffmpeg.org/
> 
> Best,
> Tristan

Thanks 
Jack
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 02/14] avformat/tls_openssl: force dtls handshake to be blocking

2025-07-15 Thread Jack Lau


> On Jul 14, 2025, at 03:24, Timo Rothenpieler  wrote:
> 
> There is no sensible way to handle this otherwise anyway, one just has
> to loop over this function until it succeeds.
> ---
> libavformat/tls_openssl.c | 18 --
> 1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
> index f6826222f9..54213c4090 100644
> --- a/libavformat/tls_openssl.c
> +++ b/libavformat/tls_openssl.c
> @@ -685,27 +685,33 @@ static int openssl_dtls_verify_callback(int 
> preverify_ok, X509_STORE_CTX *ctx)
> 
> static int dtls_handshake(URLContext *h)
> {
> -int ret = 0, r0, r1;
> +int ret = 1, r0, r1;
> TLSContext *p = h->priv_data;
> 
> +int was_nonblock = h->flags & AVIO_FLAG_NONBLOCK;
> +h->flags &= ~AVIO_FLAG_NONBLOCK;
> +
> r0 = SSL_do_handshake(p->ssl);
> -r1 = SSL_get_error(p->ssl, r0);
> if (r0 <= 0) {
> +r1 = SSL_get_error(p->ssl, r0);
> +
> if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != 
> SSL_ERROR_ZERO_RETURN) {
> -av_log(p, AV_LOG_ERROR, "TLS: Read failed, r0=%d, r1=%d %s\n", 
> r0, r1, openssl_get_error(p));
> -ret = AVERROR(EIO);
> +av_log(p, AV_LOG_ERROR, "Handshake failed, r0=%d, r1=%d\n", r0, 
> r1);
> +ret = print_ssl_error(h, r0);
> goto end;
> }
> } else {
> -av_log(p, AV_LOG_TRACE, "TLS: Read %d bytes, r0=%d, r1=%d\n", r0, 
> r0, r1);
> +av_log(p, AV_LOG_TRACE, "Handshake success, r0=%d\n", r0);
> }
> 
> -/* Check whether the DTLS is completed. */
> if (SSL_is_init_finished(p->ssl) != 1)
> goto end;
> 
> +ret = 0;
> p->tls_shared.state = DTLS_STATE_FINISHED;
> end:
> +if (was_nonblock)
> +h->flags |= AVIO_FLAG_NONBLOCK;
> 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-requ...@ffmpeg.org with subject "unsubscribe”.

The flag of DTLS didn’t pass into udp, so maybe you should add this diff:

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 07d1af40d8..62f0df2202 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -701,9 +701,10 @@ static int dtls_handshake(URLContext *h)
 {
 int ret = 1, r0, r1;
 TLSContext *p = h->priv_data;
-
+TLSShared *c = &p->tls_shared;
+URLContext *uc = c->is_dtls ? c->udp : c->tcp;
 int was_nonblock = h->flags & AVIO_FLAG_NONBLOCK;
-h->flags &= ~AVIO_FLAG_NONBLOCK;
+uc->flags &= ~AVIO_FLAG_NONBLOCK;
 
 r0 = SSL_do_handshake(p->ssl);
 if (r0 <= 0) {
@@ -725,7 +726,7 @@ static int dtls_handshake(URLContext *h)
 p->tls_shared.state = DTLS_STATE_FINISHED;
 end:
 if (was_nonblock)
-h->flags |= AVIO_FLAG_NONBLOCK;
+uc->flags |= AVIO_FLAG_NONBLOCK;
 return ret;
 }

Thanks
Jack



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

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


Re: [FFmpeg-devel] [PATCH v5 3/3] avformat/whip: fix typos

2025-06-28 Thread Jack Lau
Hi Timo,
> On Jun 29, 2025, at 06:49, Timo Rothenpieler  wrote:
> 
> I've actually cleaned this up a bit while trying to implement DTLS via 
> schannel, and effectively removed the whole section:
> 
>> https://github.com/BtbN/FFmpeg/commit/b6794f1373fb07b791cfacd2189c7efc4d6bdbcc
> 
> There's also a bunch of other necessary UDP related fixes in tls.c.
> 
> Don't try to use an http proxy for UDP. It doesn't work:
>> https://github.com/BtbN/FFmpeg/commit/709ce9e5c48e3a27a400cf5af35038d3f0602c8a
I totally agree with the above two patches, it’s very reasonable
> 
> Properly forward the various hosts and ports to udp.c so it actually works 
> when using a non-external UDP connection:
>> https://github.com/BtbN/FFmpeg/commit/46375adf7d9cc61f709ab14dd2ea017995f735db
But I think this patch need a bit modify, I think the c->listen stands for 
FFmpeg if is server. When it is true, FFmpeg as server. 
So maybe:
if (c->listen) {
av_dict_set_int(options, "localport", port, 0);
av_dict_set(options, "localaddr", c->underlying_host, 0);Add 
commentMore actions
} else {
av_dict_set_int(options, "connect", 1, 0);
}
What do you think?
If you don’t mind, I’m glad to fix this and submit it to mail list.

BTW, do you have other comments for this patchset 
https://ffmpeg.org/pipermail/ffmpeg-devel/2025-June/345948.html  
 ?
I think we can merge that firstly because this patchset is simple and I want to 
submit WHIP NACK patch that depends these patch.

Best regards
Jack
> 
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v5 3/3] avformat/whip: fix typos

2025-06-28 Thread Jack Lau


> On Jun 29, 2025, at 11:11, Jack Lau  wrote:
> 
> Hi Timo,
>> On Jun 29, 2025, at 06:49, Timo Rothenpieler  wrote:
>> 
>> I've actually cleaned this up a bit while trying to implement DTLS via 
>> schannel, and effectively removed the whole section:
>> 
>>> https://github.com/BtbN/FFmpeg/commit/b6794f1373fb07b791cfacd2189c7efc4d6bdbcc
>> 
>> There's also a bunch of other necessary UDP related fixes in tls.c.
>> 
>> Don't try to use an http proxy for UDP. It doesn't work:
>>> https://github.com/BtbN/FFmpeg/commit/709ce9e5c48e3a27a400cf5af35038d3f0602c8a
> I totally agree with the above two patches, it’s very reasonable
>> 
>> Properly forward the various hosts and ports to udp.c so it actually works 
>> when using a non-external UDP connection:
>>> https://github.com/BtbN/FFmpeg/commit/46375adf7d9cc61f709ab14dd2ea017995f735db
> But I think this patch need a bit modify, I think the c->listen stands for 
> FFmpeg if is server. When it is true, FFmpeg as server. 
> So maybe:
> if (c->listen) {
> av_dict_set_int(options, "localport", port, 0);
> av_dict_set(options, "localaddr", c->underlying_host, 0);Add 
> commentMore actions
> } else {
> av_dict_set_int(options, "connect", 1, 0);
> }
Sry for forgetting modify this code, the right code I want to express is that:
if (c->listen) {
av_dict_set_int(options, "connect", 1, 0);
} else {
av_dict_set_int(options, "localport", port, 0);
av_dict_set(options, "localaddr", c->underlying_host, 0);
}

c->listen is true, ffmpeg as server
> What do you think?
> If you don’t mind, I’m glad to fix this and submit it to mail list.
> 
> BTW, do you have other comments for this patchset 
> https://ffmpeg.org/pipermail/ffmpeg-devel/2025-June/345948.html  
> <https://ffmpeg.org/pipermail/ffmpeg-devel/2025-June/345948.html?> ?
> I think we can merge that firstly because this patchset is simple and I want 
> to submit WHIP NACK patch that depends these patch.
> 
> Best regards
> Jack
>> 
>> 
>> ___
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 2/3] avformat/whip: add whip_flags ignore_ipv6 to skip IPv6 candidates

2025-06-27 Thread Jack Lau


> On Jun 27, 2025, at 22:03, Marvin Scholz  
> wrote:
> 
> On 13 Jun 2025, at 10:56, Jack Lau via ffmpeg-devel wrote:
> 
>> mark this ignore_ipv6 flag could ignore any ipv6 ICE candidate,
>> preventing “No route to host” errors on devices without IPv6 connectivity.
>> 
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/whip.c | 13 +
>> 1 file changed, 13 insertions(+)
>> 
>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>> index a6827d3478..84c2092e5e 100644
>> --- a/libavformat/whip.c
>> +++ b/libavformat/whip.c
>> @@ -193,9 +193,14 @@ enum WHIPState {
>> WHIP_STATE_FAILED,
>> };
>> 
>> +typedef enum WHIPFlags {
>> +WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
>> +} WHIPFlags;
>> +
>> typedef struct WHIPContext {
>> AVClass *av_class;
>> 
>> +uint32_t flags;// enum WHIPFlags
>> /* The state of the RTC connection. */
>> enum WHIPState state;
>> /* The callback return value for DTLS. */
>> @@ -871,6 +876,7 @@ static int parse_answer(AVFormatContext *s)
>> if (ptr && av_stristr(ptr, "host")) {
>> char protocol[17], host[129];
>> int priority, port;
>> +struct in6_addr addr6;
>> 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",
>> @@ -879,6 +885,11 @@ static int parse_answer(AVFormatContext *s)
>> goto end;
>> }
>> 
>> +if (whip->flags & WHIP_FLAG_IGNORE_IPV6 && 
>> inet_pton(AF_INET6, host, &addr6) == 1) {
>> +av_log(whip, AV_LOG_DEBUG, "WHIP: Ignore ipv6 %s, line 
>> %d %s \n", host, i, line);
> 
> Nit: "Ignoring IPv6"
> Also why the WHIP prefix? Your log context would already add the whip demux 
> name to the message, no?
> 
>> +continue;
>> +}
>> +
>> 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",
>> protocol, i, line, whip->sdp_answer);
>> @@ -1892,6 +1903,8 @@ static const AVOption options[] = {
>> { "authorization",  "The optional Bearer token for WHIP 
>> Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { 
>> .str = NULL }, 0,   0, ENC },
>> { "cert_file",  "The optional certificate file path for DTLS",   
>>OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL },  
>>0,   0, ENC },
>> { "key_file",   "The optional private key file path for DTLS",   
>>OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 
>> 0,   0, ENC },
>> +{ "whip_flags", "Set flags affecting WHIP connection behavior", 
>> OFFSET(flags),  AV_OPT_TYPE_FLAGS,  { .i64 = 0 },
>> 0, UINT_MAX, ENC, .unit = "flags" },
>> +{ "ignore_ipv6","The optional ignore any IPv6 ICE candidate", 
>> 0, AV_OPT_TYPE_CONST,  { .i64 = WHIP_FLAG_IGNORE_IPV6 }, 0, UINT_MAX, ENC, 
>> .unit = "flags" },
> 
> Nit: The description grammar is a bit confusing, maybe just: "Ignore any IPv6 
> ICE candidates".
I totally agree with your ideas, I’ve already send the v4 patchset 
https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=14867

Thanks for your reviews!
Jack
> 
>> { NULL },
>> };
> 
>> ___
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-requ...@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-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v5 3/3] avformat/whip: fix typos

2025-06-29 Thread Jack Lau


> On Jun 29, 2025, at 19:47, Timo Rothenpieler  wrote:
> 
> On 29.06.2025 05:14, Jack Lau wrote:
>>> On Jun 29, 2025, at 11:11, Jack Lau  wrote:
>>> 
>>> Hi Timo,
>>>> On Jun 29, 2025, at 06:49, Timo Rothenpieler  wrote:
>>>> 
>>>> I've actually cleaned this up a bit while trying to implement DTLS via 
>>>> schannel, and effectively removed the whole section:
>>>> 
>>>>> https://github.com/BtbN/FFmpeg/commit/b6794f1373fb07b791cfacd2189c7efc4d6bdbcc
>>>> 
>>>> There's also a bunch of other necessary UDP related fixes in tls.c.
>>>> 
>>>> Don't try to use an http proxy for UDP. It doesn't work:
>>>>> https://github.com/BtbN/FFmpeg/commit/709ce9e5c48e3a27a400cf5af35038d3f0602c8a
>>> I totally agree with the above two patches, it’s very reasonable
>>>> 
>>>> Properly forward the various hosts and ports to udp.c so it actually works 
>>>> when using a non-external UDP connection:
>>>>> https://github.com/BtbN/FFmpeg/commit/46375adf7d9cc61f709ab14dd2ea017995f735db
>>> But I think this patch need a bit modify, I think the c->listen stands for 
>>> FFmpeg if is server. When it is true, FFmpeg as server.
>>> So maybe:
>>> if (c->listen) {
>>> av_dict_set_int(options, "localport", port, 0);
>>> av_dict_set(options, "localaddr", c->underlying_host, 0);Add 
>>> commentMore actions
>>> } else {
>>> av_dict_set_int(options, "connect", 1, 0);
>>> }
>> Sry for forgetting modify this code, the right code I want to express is 
>> that:
>> if (c->listen) {
>> av_dict_set_int(options, "connect", 1, 0);
>> } else {
>> av_dict_set_int(options, "localport", port, 0);
>> av_dict_set(options, "localaddr", c->underlying_host, 0);
>> }
> 
> It goes together with
>> https://github.com/BtbN/FFmpeg/commit/6fc902eb75554e6ad91a2ddf4ce1d131feee6f55
> 
> Without setting the localport to 0 in client-mode in combination with above 
> patch, it'll try to bind to the port passed in the URL, which when tryong to 
> connect to a server on localhost will result in a bind failure, cause it 
> tried to bind to the same port.
I also found this issue, I’m not sure modify the udp code if is suitable, but I 
can provide a workaround:

@@ -127,23 +127,22 @@ 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,
+ret = ffurl_open_whitelist(c->is_dtls ? &c->udp : &c->tcp, buf,
+   c->is_dtls ? (c->listen ? AVIO_FLAG_READ : 
AVIO_FLAG_WRITE) : AVIO_FLAG_READ_WRITE,
&parent->interrupt_callback, options,
parent->protocol_whitelist, 
parent->protocol_blacklist, parent);
diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2a3905891d..9cc5acd3e1 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_WRITE | 
AVIO_FLAG_NONBLOCK;
 }
 
> 
> And "connect" in listen mode makes no sense to me?
> There is no remote address, where would it "connect" the socket to?
Oops! I got it mixed up.
You’re right.
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 2/8] avformat/udp: make recv addr of each packet available

2025-07-07 Thread Jack Lau


> On Jul 7, 2025, at 19:28, Timo Rothenpieler  wrote:
> 
> On 07/07/2025 10:03, Jack Lau wrote:
>>> On Jul 7, 2025, at 02:36, Timo Rothenpieler  wrote:
>>> 
>>> ---
>>> 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;
>&g

Re: [FFmpeg-devel] [PATCH v2 1/8] avformat/tls: move whip specific init out of generic tls code

2025-07-07 Thread Jack Lau


> On Jul 7, 2025, at 19:26, Timo Rothenpieler  wrote:
> 
> On 07/07/2025 08:30, Jack Lau wrote:
>>> On Jul 7, 2025, at 02:36, Timo Rothenpieler  wrote:
>>> 
>>> ---
>>> libavformat/tls.c |  9 -
>>> libavformat/tls_openssl.c | 12 
>>> libavformat/whip.c|  5 +
>>> 3 files changed, 13 insertions(+), 13 deletions(-)
>>> 
>>> diff --git a/libavformat/tls.c b/libavformat/tls.c
>>> index c0adaf61ce..bd9c05e6dc 100644
>>> --- a/libavformat/tls.c
>>> +++ b/libavformat/tls.c
>>> @@ -141,15 +141,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 08527418b0..0c76f110e3 100644
>>> --- a/libavformat/tls_openssl.c
>>> +++ b/libavformat/tls_openssl.c
>>> @@ -1128,14 +1128,16 @@ static int tls_write(URLContext *h, const uint8_t 
>>> *buf, int size)
>>> 
>>> static int tls_get_file_handle(URLContext *h)
>>> {
>>> -TLSContext *c = h->priv_data;
>>> -return ffurl_get_file_handle(c->tls_shared.tcp);
>>> +TLSContext *p = h->priv_data;
>>> +TLSShared *c = &p->tls_shared;
>>> +return ffurl_get_file_handle(c->is_dtls ? c->udp : c->tcp);
>>> }
>>> 
>>> static int tls_get_short_seek(URLContext *h)
>>> {
>>> -TLSContext *s = h->priv_data;
>>> -return ffurl_get_short_seek(s->tls_shared.tcp);
>>> +TLSContext *p = h->priv_data;
>>> +TLSShared *c = &p->tls_shared;
>>> +return ffurl_get_short_seek(c->is_dtls ? c->udp : c->tcp);
>>> }
>>> 
>>> static const AVOption options[] = {
>>> @@ -1177,6 +1179,8 @@ const URLProtocol ff_dtls_protocol = {
>>> .url_close  = dtls_close,
>>> .url_read   = tls_read,
>>> .url_write  = tls_write,
>>> +.url_get_file_handle = tls_get_file_handle,
>>> +.url_get_short_seek  = tls_get_short_seek,
>>> .priv_data_size = sizeof(TLSContext),
>>> .flags  = URL_PROTOCOL_FLAG_NETWORK,
>>> .priv_data_class = &dtls_class,
>>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>>> index 84d4c5a1f3..4ac76e79f2 100644
>>> --- a/libavformat/whip.c
>>> +++ b/libavformat/whip.c
>>> @@ -388,6 +388,11 @@ 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);
>>> +
>>> +/* Make the socket non-blocking */
>>> +ff_socket_nonblock(ffurl_get_file_handle(whip->dtls_uc), 1);
>>> +whip->dtls_uc->flags |= AVIO_FLAG_NONBLOCK;
>>> +
>> I think it’s redundant since udp_connect function has set these already.
> 
> No, it needs to be set on the tls URLContext, since all implementations 
> forward their nonblocking flag (or lack thereof) to the underlying context 
> each read/write.
Thanks for the explanation.
This patch Looks good to me.
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 2/8] avformat/udp: make recv addr of each packet available

2025-07-07 Thread Jack Lau


> On Jul 7, 2025, at 02:36, Timo Rothenpieler  wrote:
> 
> ---
> 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@ffm

Re: [FFmpeg-devel] [PATCH v2 1/8] avformat/tls: move whip specific init out of generic tls code

2025-07-06 Thread Jack Lau


> On Jul 7, 2025, at 02:36, Timo Rothenpieler  wrote:
> 
> ---
> libavformat/tls.c |  9 -
> libavformat/tls_openssl.c | 12 
> libavformat/whip.c|  5 +
> 3 files changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/libavformat/tls.c b/libavformat/tls.c
> index c0adaf61ce..bd9c05e6dc 100644
> --- a/libavformat/tls.c
> +++ b/libavformat/tls.c
> @@ -141,15 +141,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 08527418b0..0c76f110e3 100644
> --- a/libavformat/tls_openssl.c
> +++ b/libavformat/tls_openssl.c
> @@ -1128,14 +1128,16 @@ static int tls_write(URLContext *h, const uint8_t 
> *buf, int size)
> 
> static int tls_get_file_handle(URLContext *h)
> {
> -TLSContext *c = h->priv_data;
> -return ffurl_get_file_handle(c->tls_shared.tcp);
> +TLSContext *p = h->priv_data;
> +TLSShared *c = &p->tls_shared;
> +return ffurl_get_file_handle(c->is_dtls ? c->udp : c->tcp);
> }
> 
> static int tls_get_short_seek(URLContext *h)
> {
> -TLSContext *s = h->priv_data;
> -return ffurl_get_short_seek(s->tls_shared.tcp);
> +TLSContext *p = h->priv_data;
> +TLSShared *c = &p->tls_shared;
> +return ffurl_get_short_seek(c->is_dtls ? c->udp : c->tcp);
> }
> 
> static const AVOption options[] = {
> @@ -1177,6 +1179,8 @@ const URLProtocol ff_dtls_protocol = {
> .url_close  = dtls_close,
> .url_read   = tls_read,
> .url_write  = tls_write,
> +.url_get_file_handle = tls_get_file_handle,
> +.url_get_short_seek  = tls_get_short_seek,
> .priv_data_size = sizeof(TLSContext),
> .flags  = URL_PROTOCOL_FLAG_NETWORK,
> .priv_data_class = &dtls_class,
> diff --git a/libavformat/whip.c b/libavformat/whip.c
> index 84d4c5a1f3..4ac76e79f2 100644
> --- a/libavformat/whip.c
> +++ b/libavformat/whip.c
> @@ -388,6 +388,11 @@ 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);
> +
> +/* Make the socket non-blocking */
> +ff_socket_nonblock(ffurl_get_file_handle(whip->dtls_uc), 1);
> +whip->dtls_uc->flags |= AVIO_FLAG_NONBLOCK;
> +
I think it’s redundant since udp_connect function has set these already.
> 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-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 0/4] Fix some issues in tls_openssl and udp

2025-07-09 Thread Jack Lau
This patchset aims to fix some issues when i try to utilize DTLS using avio.
I create a simple DTLS client and server case here
https://github.com/JackLau1222/openssl-dtls-bio-example/tree/master/ffmpeg_case

This patchset fix:
1. dtls_handshake can't return positive code when it still in progressing
2. udp server mode haven't dest_addr so we need set it through last_recv_addr
3. some code cleanup

This patchset depends Timo's latest schannel patchset
More details: https://github.com/BtbN/FFmpeg/pull/3

Jack Lau (4):
  avformat/tls_openssl: add record trace function
  avformat/tls_openssl: fix dtls_handshake return code
  avformat/tls_openssl: remove all redundant "TLS: " in log with AVClass
  avformat/udp: fix udp server mode haven't dest_addr

 libavformat/tls_openssl.c | 78 +++
 libavformat/udp.c |  2 +
 2 files changed, 64 insertions(+), 16 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/4] avformat/tls_openssl: fix dtls_handshake return code

2025-07-09 Thread Jack Lau
If the handshake is still in progress, dtls_handshake should
return a positive status code.

Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 8639ac9758..ffd9cd51d2 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -716,15 +716,14 @@ static int openssl_dtls_verify_callback(int preverify_ok, 
X509_STORE_CTX *ctx)
 
 static int dtls_handshake(URLContext *h)
 {
-int ret = 0, r0, r1;
+int ret = EINPROGRESS, r0, r1;
 TLSContext *p = h->priv_data;
 
 r0 = SSL_do_handshake(p->ssl);
 r1 = SSL_get_error(p->ssl, r0);
 if (r0 <= 0) {
 if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != 
SSL_ERROR_ZERO_RETURN) {
-av_log(p, AV_LOG_ERROR, "TLS: Read failed, r0=%d, r1=%d %s\n", r0, 
r1, openssl_get_error(p));
-ret = AVERROR(EIO);
+ret = print_ssl_error(h, r1);
 goto end;
 }
 } else {
@@ -734,7 +733,7 @@ static int dtls_handshake(URLContext *h)
 /* Check whether the DTLS is completed. */
 if (SSL_is_init_finished(p->ssl) != 1)
 goto end;
-
+ret = 0;
 p->tls_shared.state = DTLS_STATE_FINISHED;
 end:
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/4] avformat/tls_openssl: remove all redundant "TLS: " in log with AVClass

2025-07-09 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index ffd9cd51d2..a519c8c880 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -509,7 +509,7 @@ int ff_dtls_export_materials(URLContext *h, char 
*dtls_srtp_materials, size_t ma
 ret = SSL_export_keying_material(c->ssl, dtls_srtp_materials, materials_sz,
 dst, strlen(dst), NULL, 0, 0);
 if (!ret) {
-av_log(c, AV_LOG_ERROR, "TLS: Failed to export SRTP material, %s\n", 
openssl_get_error(c));
+av_log(c, AV_LOG_ERROR, "Failed to export SRTP material, %s\n", 
openssl_get_error(c));
 return -1;
 }
 return 0;
@@ -727,7 +727,7 @@ static int dtls_handshake(URLContext *h)
 goto end;
 }
 } else {
-av_log(p, AV_LOG_TRACE, "TLS: Read %d bytes, r0=%d, r1=%d\n", r0, r0, 
r1);
+av_log(p, AV_LOG_TRACE, "Read %d bytes, r0=%d, r1=%d\n", r0, r0, r1);
 }
 
 /* Check whether the DTLS is completed. */
@@ -768,7 +768,7 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
 return ret;
 }
 } else if (c->is_dtls){
-av_log(p, AV_LOG_ERROR, "TLS: Init cert failed, %s\n", 
openssl_get_error(p));
+av_log(p, AV_LOG_ERROR, "Init cert failed, %s\n", 
openssl_get_error(p));
 ret = AVERROR(EINVAL);
 goto fail;
 }
@@ -784,12 +784,12 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
 } 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));
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_use_PrivateKey failed, 
%s\n", openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
 }
 } else if (c->is_dtls) {
-av_log(p, AV_LOG_ERROR, "TLS: Init pkey failed, %s\n", 
openssl_get_error(p));
+av_log(p, AV_LOG_ERROR, "Init pkey failed, %s\n", 
openssl_get_error(p));
 ret = AVERROR(EINVAL);
 goto fail;
 }
@@ -826,7 +826,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 
 /* For ECDSA, we could set the curves list. */
 if (SSL_CTX_set1_curves_list(p->ctx, curves) != 1) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set1_curves_list failed, 
curves=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set1_curves_list failed, 
curves=%s, %s\n",
 curves, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -837,7 +837,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
  * ensuring maximum compatibility.
  */
 if (SSL_CTX_set_cipher_list(p->ctx, ciphers) != 1) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_cipher_list failed, 
ciphers=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set_cipher_list failed, 
ciphers=%s, %s\n",
 ciphers, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -854,7 +854,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 SSL_CTX_set_read_ahead(p->ctx, 1);
 /* Setup the SRTP context */
 if (SSL_CTX_set_tlsext_use_srtp(p->ctx, profiles)) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_tlsext_use_srtp failed, 
profiles=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set_tlsext_use_srtp failed, 
profiles=%s, %s\n",
 profiles, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -906,12 +906,12 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 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) {
-av_log(p, AV_LOG_ERROR, "TLS: Failed to drive SSL context, 
ret=%d\n", ret);
+av_log(p, AV_LOG_ERROR, "Failed to drive SSL context, ret=%d\n", 
ret);
 return AVERROR(EIO);
 }
 }
 
-av_log(p, AV_LOG_VERBOSE, "TLS: Setup ok, MTU=%d\n", p->tls_shared.mtu);
+av_log(p, AV_LOG_VERBOSE, "Setup ok, MTU=%d\n", p->tls_shared.mtu);
 
 ret = 0;
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/4] avformat/udp: fix udp server mode haven't dest_addr

2025-07-09 Thread Jack Lau
If udp is in server mode(init local addr and port through url),
then it maybe haven't dest_addr, so we should set it after udp_read
get the client addr and port

Signed-off-by: Jack Lau 
---
 libavformat/udp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavformat/udp.c b/libavformat/udp.c
index 0fde3548e7..6a2ed2cdcd 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -1144,6 +1144,8 @@ static int udp_write(URLContext *h, const uint8_t *buf, 
int size)
 }
 
 if (!s->is_connected) {
+if (!s->dest_addr_len && !s->dest_addr.ss_family)
+ff_udp_get_last_recv_addr(h, &s->dest_addr, &s->dest_addr_len);
 ret = sendto (s->udp_fd, buf, size, 0,
   (struct sockaddr *) &s->dest_addr,
   s->dest_addr_len);
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/4] avformat/tls_openssl: add record trace function

2025-07-09 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 51 +--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2a01fb387d..8639ac9758 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
 #include "network.h"
 #include "os_support.h"
@@ -559,6 +560,48 @@ static int tls_close(URLContext *h)
 return 0;
 }
 
+/*
+ * Trace a single TLS/DTLS record.
+ * 
+ * See RFC 5246 Section 6.2.1, RFC???6347 Section 4.1
+ * 
+ * @param data Raw record (network byte???order).
+ * @param length   Size of @data in bytes.
+ * @param incoming Non???zero when the packet was received, zero when sent.
+ */
+static void openssl_state_trace(uint8_t *data, int length, int incoming)
+{
+uint8_t  content_type   = 0;  /* TLS/DTLS ContentType   */
+uint16_t record_length  = 0;  /* Length field from header   */
+uint8_t  handshake_type = 0;  /* First byte of Handshake msg */
+int is_dtls = 0;
+
+/* ContentType is always the very first byte */
+if (length >= 1)
+content_type = AV_RB8(&data[0]);
+if (length >= 3 && data[1] == DTLS1_VERSION_MAJOR)
+is_dtls = 1;
+/* TLS header is 5??bytes, DTLS header is 13??bytes */
+if (length >= 13 && is_dtls)
+record_length = AV_RB16(&data[11]);
+else if (length >= 5 && !is_dtls)
+record_length = AV_RB16(&data[3]);
+/*
+ * HandshakeType values (TLS 1.0???1.2, DTLS 1.0/1.2)
+ * See RFC 5246 Section 7.4, RFC 6347 Section 4.2
+ *
+ * Only present when ContentType == handshake(22)
+ */
+if (content_type == 22) {
+int hs_off = is_dtls ? 13 : 5;
+if (length > hs_off)
+handshake_type = AV_RB8(&data[hs_off]);
+}
+
+av_log(NULL, AV_LOG_TRACE ,"TLS: Trace %s, len=%u, cnt=%u, size=%u, 
hs=%u\n",
+(incoming? "RECV":"SEND"), length, content_type, record_length, 
handshake_type);
+}
+
 static int url_bio_create(BIO *b)
 {
 BIO_set_init(b, 1);
@@ -576,8 +619,10 @@ static int url_bio_bread(BIO *b, char *buf, int len)
 {
 TLSContext *c = BIO_get_data(b);
 int ret = ffurl_read(c->tls_shared.is_dtls ? c->tls_shared.udp : 
c->tls_shared.tcp, buf, len);
-if (ret >= 0)
+if (ret >= 0) {
+openssl_state_trace((uint8_t*)buf, ret, 1);
 return ret;
+}
 BIO_clear_retry_flags(b);
 if (ret == AVERROR_EXIT)
 return 0;
@@ -592,8 +637,10 @@ static int url_bio_bwrite(BIO *b, const char *buf, int len)
 {
 TLSContext *c = BIO_get_data(b);
 int ret = ffurl_write(c->tls_shared.is_dtls ? c->tls_shared.udp : 
c->tls_shared.tcp, buf, len);
-if (ret >= 0)
+if (ret >= 0) {
+openssl_state_trace((uint8_t*)buf, ret, 0);
 return ret;
+}
 BIO_clear_retry_flags(b);
 if (ret == AVERROR_EXIT)
 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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 2/4] avformat/tls_openssl: fix dtls_handshake return code

2025-07-09 Thread Jack Lau


> On Jul 9, 2025, at 22:14, Timo Rothenpieler  wrote:
> 
> On 09/07/2025 15:36, Jack Lau wrote:
>> If the handshake is still in progress, dtls_handshake should
>> return a positive status code.
> 
> Shouldn't dtls_open/start also be calling it in a loop then?

> I don't think it's expected that you might be needed to call the handshake 
> function in a loop after a urlcontext was successfully opened.
It’s a special situation in WHIP.  The ICE, DTLS, SRTP reuse the same udp.
But the udp socket can’t be passed by FFmpeg option to DTLS, 
so I create a function(named ff_tls_set_external_socket now) and call it after 
dtls_open in WHIP implementation, 
dtls can’t handshake because the udp haven’t set
> 
> What I've done for the schannel implementation is force nonblocking off for 
> the handshake, since there is just no good way to perform it in a nonblocking 
> way, and you just always end up looping until it's done anyway.
But the handshake might work well using BLOCK mode then the dtls handshake will 
be finished in once function called(openssl will loop internal in BLOCK mode).

I’ll try it later.
> 
>> Signed-off-by: Jack Lau 
>> ---
>>  libavformat/tls_openssl.c | 7 +++
>>  1 file changed, 3 insertions(+), 4 deletions(-)
>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>> index 8639ac9758..ffd9cd51d2 100644
>> --- a/libavformat/tls_openssl.c
>> +++ b/libavformat/tls_openssl.c
>> @@ -716,15 +716,14 @@ static int openssl_dtls_verify_callback(int 
>> preverify_ok, X509_STORE_CTX *ctx)
>>static int dtls_handshake(URLContext *h)
>>  {
>> -int ret = 0, r0, r1;
>> +int ret = EINPROGRESS, r0, r1;
>>  TLSContext *p = h->priv_data;
>>r0 = SSL_do_handshake(p->ssl);
>>  r1 = SSL_get_error(p->ssl, r0);
>>  if (r0 <= 0) {
>>  if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 
>> != SSL_ERROR_ZERO_RETURN) {
>> -av_log(p, AV_LOG_ERROR, "TLS: Read failed, r0=%d, r1=%d %s\n", 
>> r0, r1, openssl_get_error(p));
>> -ret = AVERROR(EIO);
>> +ret = print_ssl_error(h, r1);
>>  goto end;
>>  }
>>  } else {
>> @@ -734,7 +733,7 @@ static int dtls_handshake(URLContext *h)
>>  /* Check whether the DTLS is completed. */
>>  if (SSL_is_init_finished(p->ssl) != 1)
>>  goto end;
>> -
>> +ret = 0;
>>  p->tls_shared.state = DTLS_STATE_FINISHED;
>>  end:
>>  return ret;
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 4/4] avformat/udp: fix udp server mode haven't dest_addr

2025-07-09 Thread Jack Lau



> On Jul 9, 2025, at 22:16, Timo Rothenpieler  wrote:
> 
> On 09/07/2025 15:36, Jack Lau wrote:
>> If udp is in server mode(init local addr and port through url),
>> then it maybe haven't dest_addr, so we should set it after udp_read
>> get the client addr and port
> 
> I'm also really not sure if this is correct, or what scenario it even fixes.
> The vast majority of uses of UDP are strictly unidirectional, making this a 
> non-issue.
> 
> DTLS is one of the few exceptions there, and as the user of udp.c should be 
> the one responsible for setting the appropriate destination address when in 
> "server" mode.
Maybe we could add a udp option that enable this feature? And only enable it 
when user explicitly 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-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 1/4] avformat/tls_openssl: add record trace function

2025-07-09 Thread Jack Lau



> On Jul 10, 2025, at 06:16, Michael Niedermayer  wrote:
> 
> On Wed, Jul 09, 2025 at 09:36:26PM +0800, Jack Lau wrote:
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/tls_openssl.c | 51 +--
>> 1 file changed, 49 insertions(+), 2 deletions(-)
> 
> my git here dislikes the encoding of this mail:
> 
> error: cannot convert from y to UTF-8
Sry about that, will submit new version later
> 
> thx
> 
> [...]
> 
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> The educated differ from the uneducated as much as the living from the
> dead. -- Aristotle 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 5/6] avformat/whip: implement NACK and RTX suppport

2025-07-12 Thread Jack Lau
RTP retransmission described in RFC4588 (RTX) is an effective packet
loss recovery technique for real-time applications with relaxed delay bounds.

This patch provides a minimal implementation for RTX and RTCP NACK (RFC3940)
and its associated SDP signaling and negotiation.

Co-authored-by: Sergio Garcia Murillo 
Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 206 -
 1 file changed, 202 insertions(+), 4 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index f1f8d1b4ad..d954e80830 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -114,6 +114,7 @@
 /* Referring to Chrome's definition of RTP payload types. */
 #define WHIP_RTP_PAYLOAD_TYPE_H264 106
 #define WHIP_RTP_PAYLOAD_TYPE_OPUS 111
+#define WHIP_RTP_PAYLOAD_TYPE_RTX  105
 
 /**
  * The STUN message header, which is 20 bytes long, comprises the
@@ -150,6 +151,11 @@
 #define WHIP_SDP_SESSION_ID "4489045141692799359"
 #define WHIP_SDP_CREATOR_IP "127.0.0.1"
 
+/**
+ * Retransmission / NACK support
+*/
+#define HISTORY_SIZE_DEFAULT 512
+
 /* Calculate the elapsed time from starttime to endtime in milliseconds. */
 #define ELAPSED(starttime, endtime) ((int)(endtime - starttime) / 1000)
 
@@ -194,9 +200,16 @@ enum WHIPState {
 };
 
 typedef enum WHIPFlags {
-WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
+WHIP_FLAG_IGNORE_IPV6  = (1 << 0), // Ignore ipv6 candidate
+WHIP_FLAG_DISABLE_RTX = (1 << 1)  // Enable NACK and RTX
 } WHIPFlags;
 
+typedef struct RtpHistoryItem {
+uint16_t seq; // original RTP seq
+int size; // length in bytes
+uint8_t* buf; // malloc-ed copy
+} RtpHistoryItem;
+
 typedef struct WHIPContext {
 AVClass *av_class;
 
@@ -285,6 +298,7 @@ typedef struct WHIPContext {
 /* The SRTP send context, to encrypt outgoing packets. */
 SRTPContext srtp_audio_send;
 SRTPContext srtp_video_send;
+SRTPContext srtp_video_rtx_send;
 SRTPContext srtp_rtcp_send;
 /* The SRTP receive context, to decrypt incoming packets. */
 SRTPContext srtp_recv;
@@ -309,6 +323,14 @@ typedef struct WHIPContext {
 /* The certificate and private key used for DTLS handshake. */
 char* cert_file;
 char* key_file;
+
+/* RTX and NACK */
+uint8_t rtx_payload_type;
+uint32_t video_rtx_ssrc;
+uint16_t rtx_seq;
+int  history_size;
+RtpHistoryItem *history;  /* ring buffer  */
+int hist_head;
 } WHIPContext;
 
 /**
@@ -611,6 +633,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 whip->audio_payload_type = WHIP_RTP_PAYLOAD_TYPE_OPUS;
 whip->video_payload_type = WHIP_RTP_PAYLOAD_TYPE_H264;
 
+/* RTX and NACK init */
+whip->rtx_payload_type = WHIP_RTP_PAYLOAD_TYPE_RTX;
+whip->video_rtx_ssrc = av_lfg_get(&whip->rnd);
+whip->rtx_seq = 0;
+whip->hist_head = 0;
+whip->history_size = FFMAX(64, whip->history_size);
+whip->history = av_calloc(whip->history_size, sizeof(*whip->history));
+if (!whip->history)
+return AVERROR(ENOMEM);
+
 av_bprintf(&bp, ""
 "v=0\r\n"
 "o=FFmpeg %s 2 IN IP4 %s\r\n"
@@ -661,7 +693,7 @@ static int generate_sdp_offer(AVFormatContext *s)
 }
 
 av_bprintf(&bp, ""
-"m=video 9 UDP/TLS/RTP/SAVPF %u\r\n"
+"m=video 9 UDP/TLS/RTP/SAVPF %u %u\r\n"
 "c=IN IP4 0.0.0.0\r\n"
 "a=ice-ufrag:%s\r\n"
 "a=ice-pwd:%s\r\n"
@@ -674,9 +706,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 "a=rtcp-rsize\r\n"
 "a=rtpmap:%u %s/9\r\n"
 "a=fmtp:%u 
level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=%02x%02x%02x\r\n"
+"a=rtcp-fb:%u nack\r\n"
+"a=rtpmap:%u rtx/9\r\n"
+"a=fmtp:%u apt=%u\r\n"
+"a=ssrc-group:FID %u %u\r\n"
+"a=ssrc:%u cname:FFmpeg\r\n"
+"a=ssrc:%u msid:FFmpeg video\r\n"
 "a=ssrc:%u cname:FFmpeg\r\n"
 "a=ssrc:%u msid:FFmpeg video\r\n",
 whip->video_payload_type,
+whip->rtx_payload_type,
 whip->ice_ufrag_local,
 whip->ice_pwd_local,
 whip->dtls_fingerprint,
@@ -686,8 +725,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 profile,
 whip->constraint_set_flags,
 level,
+whip->video_payload_type,
+whip->rtx_payload_type,
+whip->rtx_payload_type,
+whip->video_payload_type,
+whip->video_ssrc,
+whip->video_rtx_ssrc,
 whip->video_ssrc,
-whip->video_ss

[FFmpeg-devel] [PATCH v3 6/6] avformat/whip: reindent whip options

2025-07-12 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index d954e80830..f7eb6e1323 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -2089,13 +2089,13 @@ static int whip_check_bitstream(AVFormatContext *s, 
AVStream *st, const AVPacket
 #define OFFSET(x) offsetof(WHIPContext, x)
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-{ "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
handshake.",  OFFSET(handshake_timeout),  AV_OPT_TYPE_INT,{ .i64 = 5000 
},-1, INT_MAX, ENC },
-{ "pkt_size",   "The maximum size, in bytes, of RTP packets that 
send out", OFFSET(pkt_size),   AV_OPT_TYPE_INT,{ .i64 = 1200 },
-1, INT_MAX, ENC },
-{ "authorization",  "Optional Bearer token for WHIP Authorization",
 OFFSET(authorization),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,
   0, ENC },
-{ "cert_file",  "Optional certificate file path for DTLS", 
 OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,
   0, ENC },
-{ "key_file",   "Optional private key file path for DTLS", 
 OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,   
0, ENC },
-{ "whip_flags", "Set flags affecting WHIP connection behavior",
 OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 },   
0, UINT_MAX, ENC, .unit = "flags" },
-{ "ignore_ipv6","Ignore any IPv6 ICE candidate", 
0, AV_OPT_TYPE_CONST,  { .i64 = WHIP_FLAG_IGNORE_IPV6 },
   0, UINT_MAX, ENC, .unit = "flags" },
+{ "handshake_timeout", "Timeout in milliseconds for ICE and DTLS 
handshake.", OFFSET(handshake_timeout), AV_OPT_TYPE_INT,  { .i64 = 5000 }, -1, 
INT_MAX, ENC },
+{ "pkt_size", "The maximum size, in bytes, of RTP packets that send out", 
OFFSET(pkt_size), AV_OPT_TYPE_INT,  { .i64 = 1200 }, -1, INT_MAX, ENC },
+{ "authorization", "Optional Bearer token for WHIP Authorization", 
OFFSET(authorization), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
+{ "cert_file", "Optional certificate file path for DTLS", 
OFFSET(cert_file), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
+{ "key_file", "Optional private key file path for DTLS", OFFSET(key_file), 
AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
+{ "whip_flags", "Set flags affecting WHIP connection behavior", 
OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 }, 0, 0, ENC, .unit = "flags" },
+{ "ignore_ipv6", "Ignore any IPv6 ICE candidate", 0, AV_OPT_TYPE_CONST,  { 
.i64 = WHIP_FLAG_IGNORE_IPV6 }, 0, UINT_MAX, ENC, .unit = "flags" },
 { "disable_rtx", "Disable RFC 4588 RTX", 0, AV_OPT_TYPE_CONST,  { .i64 = 
WHIP_FLAG_DISABLE_RTX }, 0, UINT_MAX, ENC, .unit = "flags" },
 { "rtx_history_size", "Packet history size", OFFSET(history_size), 
AV_OPT_TYPE_INT, { .i64 = HISTORY_SIZE_DEFAULT }, 64, 2048, ENC },
 { 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 1/6] avformat/whip: add whip_flags ignore_ipv6 to skip IPv6 ICE candidates

2025-07-12 Thread Jack Lau
mark this ignore_ipv6 flag could ignore any IPv6 ICE candidate,
preventing “No route to host” errors on devices without IPv6 connectivity.

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index e272254a6f..e27a948b76 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -193,9 +193,14 @@ enum WHIPState {
 WHIP_STATE_FAILED,
 };
 
+typedef enum WHIPFlags {
+WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
+} WHIPFlags;
+
 typedef struct WHIPContext {
 AVClass *av_class;
 
+uint32_t flags;// enum WHIPFlags
 /* The state of the RTC connection. */
 enum WHIPState state;
 /* The callback return value for DTLS. */
@@ -884,6 +889,9 @@ static int parse_answer(AVFormatContext *s)
 if (ptr && av_stristr(ptr, "host")) {
 char protocol[17], host[129];
 int priority, port;
+#if HAVE_STRUCT_SOCKADDR_IN6
+struct in6_addr addr6;
+#endif
 ret = sscanf(ptr, "%16s %d %128s %d typ host", protocol, 
&priority, host, &port);
 if (ret != 4) {
 av_log(whip, AV_LOG_ERROR, "Failed %d to parse line %d %s 
from %s\n",
@@ -891,7 +899,12 @@ static int parse_answer(AVFormatContext *s)
 ret = AVERROR(EIO);
 goto end;
 }
-
+#if HAVE_STRUCT_SOCKADDR_IN6
+if (whip->flags & WHIP_FLAG_IGNORE_IPV6 && inet_pton(AF_INET6, 
host, &addr6) == 1) {
+av_log(whip, AV_LOG_DEBUG, "Ignoring IPv6 ICE candidates 
%s, line %d %s \n", host, i, line);
+continue;
+}
+#endif
 if (av_strcasecmp(protocol, "udp")) {
 av_log(whip, AV_LOG_ERROR, "Protocol %s is not supported 
by RTC, choose udp, line %d %s of %s\n",
 protocol, i, line, whip->sdp_answer);
@@ -1900,6 +1913,8 @@ static const AVOption options[] = {
 { "authorization",  "The optional Bearer token for WHIP 
Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { .str 
= NULL }, 0,   0, ENC },
 { "cert_file",  "The optional certificate file path for DTLS", 
 OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 
0,   0, ENC },
 { "key_file",   "The optional private key file path for DTLS", 
 OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0, 
  0, ENC },
+{ "whip_flags", "Set flags affecting WHIP connection behavior",
 OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 },   
0, UINT_MAX, ENC, .unit = "flags" },
+{ "ignore_ipv6","(Optional) Ignore any IPv6 ICE candidate",
 0, AV_OPT_TYPE_CONST,  { .i64 = 
WHIP_FLAG_IGNORE_IPV6 },   0, UINT_MAX, ENC, .unit = "flags" },
 { 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 0/6] avformat/whip: Add NACK and RTX support

2025-07-12 Thread Jack Lau
Version 3 of https://ffmpeg.org/pipermail/ffmpeg-devel/2025-July/346052.html

This patchset rebase latest commit

Jack Lau (5):
  avformat/whip: add whip_flags ignore_ipv6 to skip IPv6 ICE candidates
  avformat/whip: fix typos
  avformat/whip: fix H264 profile_iop bit map for SDP
  avformat/whip: implement NACK and RTX suppport
  avformat/whip: reindent whip options

winlin (1):
  WHIP: X509 cert serial number should be positive.

 libavformat/tls_openssl.c |   3 +-
 libavformat/whip.c| 278 --
 2 files changed, 240 insertions(+), 41 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 3/6] avformat/whip: fix H264 profile_iop bit map for SDP

2025-07-12 Thread Jack Lau
AVCodecParameters::profile only contains constraint_set1_flag
(AV_PROFILE_H264_CONSTRAINED 1<<9).
So add H264 constraints flag fully parse refer to hlsenc
write_codec_attr

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 47 --
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 0be976edc6..f1f8d1b4ad 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -210,6 +210,7 @@ typedef struct WHIPContext {
 /* Parameters for the input audio and video codecs. */
 AVCodecParameters *audio_par;
 AVCodecParameters *video_par;
+uint8_t constraint_set_flags;
 
 /**
  * The h264_mp4toannexb Bitstream Filter (BSF) bypasses the AnnexB packet;
@@ -450,45 +451,30 @@ static av_cold int initialize(AVFormatContext *s)
 static int parse_profile_level(AVFormatContext *s, AVCodecParameters *par)
 {
 int ret = 0;
-const uint8_t *r = par->extradata, *r1, *end = par->extradata + 
par->extradata_size;
-H264SPS seq, *const sps = &seq;
-uint32_t state;
+const uint8_t *r = par->extradata;
 WHIPContext *whip = s->priv_data;
 
 if (par->codec_id != AV_CODEC_ID_H264)
 return ret;
 
-if (par->profile != AV_PROFILE_UNKNOWN && par->level != AV_LEVEL_UNKNOWN)
-return ret;
-
 if (!par->extradata || par->extradata_size <= 0) {
 av_log(whip, AV_LOG_ERROR, "Unable to parse profile from empty 
extradata=%p, size=%d\n",
 par->extradata, par->extradata_size);
 return AVERROR(EINVAL);
 }
 
-while (1) {
-r = avpriv_find_start_code(r, end, &state);
-if (r >= end)
-break;
-
-r1 = ff_nal_find_startcode(r, end);
-if ((state & 0x1f) == H264_NAL_SPS) {
-ret = ff_avc_decode_sps(sps, r, r1 - r);
-if (ret < 0) {
-av_log(whip, AV_LOG_ERROR, "Failed to decode SPS, state=%x, 
size=%d\n",
-state, (int)(r1 - r));
-return ret;
-}
-
-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;
-}
+if (AV_RB32(r) == 0x0001 && (r[4] & 0x1F) == 7)
+r = &r[5];
+else if (AV_RB24(r) == 0x01 && (r[3] & 0x1F) == 7)
+r = &r[4];
+else if (r[0] == 0x01)  // avcC
+r = &r[1];
+else
+return AVERROR(EINVAL);
 
-r = r1;
-}
+if (par->profile == AV_PROFILE_UNKNOWN) par->profile = r[0];
+whip->constraint_set_flags = r[1];
+if (par->level == AV_LEVEL_UNKNOWN) par->level = r[2];
 
 return ret;
 }
@@ -599,7 +585,7 @@ static int parse_codec(AVFormatContext *s)
  */
 static int generate_sdp_offer(AVFormatContext *s)
 {
-int ret = 0, profile, level, profile_iop;
+int ret = 0, profile, level;
 const char *acodec_name = NULL, *vcodec_name = NULL;
 AVBPrint bp;
 WHIPContext *whip = s->priv_data;
@@ -667,11 +653,10 @@ static int generate_sdp_offer(AVFormatContext *s)
 }
 
 if (whip->video_par) {
-profile_iop = profile = whip->video_par->profile;
+profile = whip->video_par->profile;
 level = whip->video_par->level;
 if (whip->video_par->codec_id == AV_CODEC_ID_H264) {
 vcodec_name = "H264";
-profile_iop &= AV_PROFILE_H264_CONSTRAINED;
 profile &= (~AV_PROFILE_H264_CONSTRAINED);
 }
 
@@ -699,7 +684,7 @@ static int generate_sdp_offer(AVFormatContext *s)
 vcodec_name,
 whip->video_payload_type,
 profile,
-profile_iop,
+whip->constraint_set_flags,
 level,
 whip->video_ssrc,
 whip->video_ssrc);
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 2/6] avformat/whip: fix typos

2025-07-12 Thread Jack Lau
Remove redundant "WHIP: " prefix in log context
since it already add whip context.

Fix grammers in whip options descriptions

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index e27a948b76..0be976edc6 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -1910,11 +1910,11 @@ static int whip_check_bitstream(AVFormatContext *s, 
AVStream *st, const AVPacket
 static const AVOption options[] = {
 { "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
handshake.",  OFFSET(handshake_timeout),  AV_OPT_TYPE_INT,{ .i64 = 5000 
},-1, INT_MAX, ENC },
 { "pkt_size",   "The maximum size, in bytes, of RTP packets that 
send out", OFFSET(pkt_size),   AV_OPT_TYPE_INT,{ .i64 = 1200 },
-1, INT_MAX, ENC },
-{ "authorization",  "The optional Bearer token for WHIP 
Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { .str 
= NULL }, 0,   0, ENC },
-{ "cert_file",  "The optional certificate file path for DTLS", 
 OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 
0,   0, ENC },
-{ "key_file",   "The optional private key file path for DTLS", 
 OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0, 
  0, ENC },
+{ "authorization",  "Optional Bearer token for WHIP Authorization",
 OFFSET(authorization),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,
   0, ENC },
+{ "cert_file",  "Optional certificate file path for DTLS", 
 OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,
   0, ENC },
+{ "key_file",   "Optional private key file path for DTLS", 
 OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,   
0, ENC },
 { "whip_flags", "Set flags affecting WHIP connection behavior",
 OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 },   
0, UINT_MAX, ENC, .unit = "flags" },
-{ "ignore_ipv6","(Optional) Ignore any IPv6 ICE candidate",
 0, AV_OPT_TYPE_CONST,  { .i64 = 
WHIP_FLAG_IGNORE_IPV6 },   0, UINT_MAX, ENC, .unit = "flags" },
+{ "ignore_ipv6","Ignore any IPv6 ICE candidate", 
0, AV_OPT_TYPE_CONST,  { .i64 = WHIP_FLAG_IGNORE_IPV6 },
   0, UINT_MAX, ENC, .unit = "flags" },
 { 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 4/6] WHIP: X509 cert serial number should be positive.

2025-07-12 Thread Jack Lau
From: winlin 

See RFC5280 4.1.2.2

Co-authored-by: Jack Lau 
Signed-off-by: winlin 
---
 libavformat/tls_openssl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2a01fb387d..285ea166ac 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -311,7 +311,8 @@ static int openssl_gen_certificate(EVP_PKEY *pkey, X509 
**cert, char **fingerpri
 goto enomem_end;
 }
 
-serial = (int)av_get_random_seed();
+// According to RFC5280 4.1.2.2, The serial number MUST be a positive 
integer
+serial = (int)(av_get_random_seed() & 0x7FFF);
 if (ASN1_INTEGER_set(X509_get_serialNumber(*cert), serial) != 1) {
 av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set serial, %s\n", 
ERR_error_string(ERR_get_error(), NULL));
 goto einval_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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 2/4] avformat/tls_openssl: fix dtls_handshake return code

2025-07-11 Thread Jack Lau
If the handshake is still in progress, dtls_handshake should
return a positive status code.

Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 8639ac9758..ffd9cd51d2 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -716,15 +716,14 @@ static int openssl_dtls_verify_callback(int preverify_ok, 
X509_STORE_CTX *ctx)
 
 static int dtls_handshake(URLContext *h)
 {
-int ret = 0, r0, r1;
+int ret = EINPROGRESS, r0, r1;
 TLSContext *p = h->priv_data;
 
 r0 = SSL_do_handshake(p->ssl);
 r1 = SSL_get_error(p->ssl, r0);
 if (r0 <= 0) {
 if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != 
SSL_ERROR_ZERO_RETURN) {
-av_log(p, AV_LOG_ERROR, "TLS: Read failed, r0=%d, r1=%d %s\n", r0, 
r1, openssl_get_error(p));
-ret = AVERROR(EIO);
+ret = print_ssl_error(h, r1);
 goto end;
 }
 } else {
@@ -734,7 +733,7 @@ static int dtls_handshake(URLContext *h)
 /* Check whether the DTLS is completed. */
 if (SSL_is_init_finished(p->ssl) != 1)
 goto end;
-
+ret = 0;
 p->tls_shared.state = DTLS_STATE_FINISHED;
 end:
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 1/4] avformat/tls_openssl: add record trace function

2025-07-11 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 51 +--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2a01fb387d..8639ac9758 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
 #include "network.h"
 #include "os_support.h"
@@ -559,6 +560,48 @@ static int tls_close(URLContext *h)
 return 0;
 }
 
+/*
+ * Trace a single TLS/DTLS record.
+ * 
+ * See RFC 5246 Section 6.2.1, RFC 6347 Section 4.1
+ * 
+ * @param data Raw record (network byte‑order).
+ * @param length   Size of @data in bytes.
+ * @param incoming Non‑zero when the packet was received, zero when sent.
+ */
+static void openssl_state_trace(uint8_t *data, int length, int incoming)
+{
+uint8_t  content_type   = 0;  /* TLS/DTLS ContentType   */
+uint16_t record_length  = 0;  /* Length field from header   */
+uint8_t  handshake_type = 0;  /* First byte of Handshake msg */
+int is_dtls = 0;
+
+/* ContentType is always the very first byte */
+if (length >= 1)
+content_type = AV_RB8(&data[0]);
+if (length >= 3 && data[1] == DTLS1_VERSION_MAJOR)
+is_dtls = 1;
+/* TLS header is 5 bytes, DTLS header is 13 bytes */
+if (length >= 13 && is_dtls)
+record_length = AV_RB16(&data[11]);
+else if (length >= 5 && !is_dtls)
+record_length = AV_RB16(&data[3]);
+/*
+ * HandshakeType values (TLS 1.0–1.2, DTLS 1.0/1.2)
+ * See RFC 5246 Section 7.4, RFC 6347 Section 4.2
+ *
+ * Only present when ContentType == handshake(22)
+ */
+if (content_type == 22) {
+int hs_off = is_dtls ? 13 : 5;
+if (length > hs_off)
+handshake_type = AV_RB8(&data[hs_off]);
+}
+
+av_log(NULL, AV_LOG_TRACE ,"TLS: Trace %s, len=%u, cnt=%u, size=%u, 
hs=%u\n",
+(incoming? "RECV":"SEND"), length, content_type, record_length, 
handshake_type);
+}
+
 static int url_bio_create(BIO *b)
 {
 BIO_set_init(b, 1);
@@ -576,8 +619,10 @@ static int url_bio_bread(BIO *b, char *buf, int len)
 {
 TLSContext *c = BIO_get_data(b);
 int ret = ffurl_read(c->tls_shared.is_dtls ? c->tls_shared.udp : 
c->tls_shared.tcp, buf, len);
-if (ret >= 0)
+if (ret >= 0) {
+openssl_state_trace((uint8_t*)buf, ret, 1);
 return ret;
+}
 BIO_clear_retry_flags(b);
 if (ret == AVERROR_EXIT)
 return 0;
@@ -592,8 +637,10 @@ static int url_bio_bwrite(BIO *b, const char *buf, int len)
 {
 TLSContext *c = BIO_get_data(b);
 int ret = ffurl_write(c->tls_shared.is_dtls ? c->tls_shared.udp : 
c->tls_shared.tcp, buf, len);
-if (ret >= 0)
+if (ret >= 0) {
+openssl_state_trace((uint8_t*)buf, ret, 0);
 return ret;
+}
 BIO_clear_retry_flags(b);
 if (ret == AVERROR_EXIT)
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 0/4] Fix some issues in tls_openssl and udp

2025-07-11 Thread Jack Lau
v2 patchset add new udp option autodetect_dest.

Original description:
This patchset aims to fix some issues when i try to utilize DTLS using avio.
I create a simple DTLS client and server case here
https://github.com/JackLau1222/openssl-dtls-bio-example/tree/master/ffmpeg_case

This patchset fix:
1. dtls_handshake can't return positive code when it still in progressing
2. udp server mode haven't dest_addr so we need set it through last_recv_addr
3. some code cleanup

This patchset depends on Timo's latest schannel patchset
More details: https://github.com/BtbN/FFmpeg/pull/3

Jack Lau (4):
  avformat/tls_openssl: add record trace function
  avformat/tls_openssl: fix dtls_handshake return code
  avformat/tls_openssl: remove all redundant "TLS: " in log with AVClass
  avformat/udp: fix udp server mode haven't dest_addr

 libavformat/tls_openssl.c | 78 +++
 libavformat/udp.c |  4 ++
 2 files changed, 66 insertions(+), 16 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 4/4] avformat/udp: fix udp server mode haven't dest_addr

2025-07-11 Thread Jack Lau
If udp is in server mode(init local addr and port through url),
then it maybe haven't dest_addr, so we should set it after udp_read
get the client addr and port

This feature only enable when the new udp option autodetect_dest is specified

Signed-off-by: Jack Lau 
---
 libavformat/udp.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavformat/udp.c b/libavformat/udp.c
index 0fde3548e7..7d05e18dcd 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -99,6 +99,7 @@ typedef struct UDPContext {
 struct sockaddr_storage dest_addr;
 int dest_addr_len;
 int is_connected;
+int autodetect_dest;
 
 /* Circular Buffer variables for use in UDP receive code */
 int circular_buffer_size;
@@ -143,6 +144,7 @@ static const AVOption options[] = {
 { "broadcast", "explicitly allow or disallow broadcast destination",   
OFFSET(is_broadcast),   AV_OPT_TYPE_BOOL,   { .i64 = 0  }, 0, 1,   E },
 { "ttl","Time to live (multicast only)",   
OFFSET(ttl),AV_OPT_TYPE_INT,{ .i64 = 16 }, 0, 255, E },
 { "connect","set if connect() should be called on socket", 
OFFSET(is_connected),   AV_OPT_TYPE_BOOL,   { .i64 =  0 }, 0, 1,   
.flags = D|E },
+{ "autodetect_dest", "Auto detect destination from last received addr", 
OFFSET(autodetect_dest), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,D|E },
 { "fifo_size",  "set the UDP receiving circular buffer size, expressed 
as a number of packets with size of 188 bytes", OFFSET(circular_buffer_size), 
AV_OPT_TYPE_INT, {.i64 = 7*4096}, 0, INT_MAX, D },
 { "overrun_nonfatal", "survive in case of UDP receiving circular buffer 
overrun", OFFSET(overrun_nonfatal), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,D },
 { "timeout","set raise error timeout, in microseconds (only in 
read mode)",OFFSET(timeout), AV_OPT_TYPE_INT,  {.i64 = 0}, 0, INT_MAX, 
D },
@@ -1144,6 +1146,8 @@ static int udp_write(URLContext *h, const uint8_t *buf, 
int size)
 }
 
 if (!s->is_connected) {
+if (s->autodetect_dest && !s->dest_addr_len && !s->dest_addr.ss_family)
+ff_udp_get_last_recv_addr(h, &s->dest_addr, &s->dest_addr_len);
 ret = sendto (s->udp_fd, buf, size, 0,
   (struct sockaddr *) &s->dest_addr,
   s->dest_addr_len);
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 3/4] avformat/tls_openssl: remove all redundant "TLS: " in log with AVClass

2025-07-11 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index ffd9cd51d2..a519c8c880 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -509,7 +509,7 @@ int ff_dtls_export_materials(URLContext *h, char 
*dtls_srtp_materials, size_t ma
 ret = SSL_export_keying_material(c->ssl, dtls_srtp_materials, materials_sz,
 dst, strlen(dst), NULL, 0, 0);
 if (!ret) {
-av_log(c, AV_LOG_ERROR, "TLS: Failed to export SRTP material, %s\n", 
openssl_get_error(c));
+av_log(c, AV_LOG_ERROR, "Failed to export SRTP material, %s\n", 
openssl_get_error(c));
 return -1;
 }
 return 0;
@@ -727,7 +727,7 @@ static int dtls_handshake(URLContext *h)
 goto end;
 }
 } else {
-av_log(p, AV_LOG_TRACE, "TLS: Read %d bytes, r0=%d, r1=%d\n", r0, r0, 
r1);
+av_log(p, AV_LOG_TRACE, "Read %d bytes, r0=%d, r1=%d\n", r0, r0, r1);
 }
 
 /* Check whether the DTLS is completed. */
@@ -768,7 +768,7 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
 return ret;
 }
 } else if (c->is_dtls){
-av_log(p, AV_LOG_ERROR, "TLS: Init cert failed, %s\n", 
openssl_get_error(p));
+av_log(p, AV_LOG_ERROR, "Init cert failed, %s\n", 
openssl_get_error(p));
 ret = AVERROR(EINVAL);
 goto fail;
 }
@@ -784,12 +784,12 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
 } 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));
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_use_PrivateKey failed, 
%s\n", openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
 }
 } else if (c->is_dtls) {
-av_log(p, AV_LOG_ERROR, "TLS: Init pkey failed, %s\n", 
openssl_get_error(p));
+av_log(p, AV_LOG_ERROR, "Init pkey failed, %s\n", 
openssl_get_error(p));
 ret = AVERROR(EINVAL);
 goto fail;
 }
@@ -826,7 +826,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 
 /* For ECDSA, we could set the curves list. */
 if (SSL_CTX_set1_curves_list(p->ctx, curves) != 1) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set1_curves_list failed, 
curves=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set1_curves_list failed, 
curves=%s, %s\n",
 curves, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -837,7 +837,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
  * ensuring maximum compatibility.
  */
 if (SSL_CTX_set_cipher_list(p->ctx, ciphers) != 1) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_cipher_list failed, 
ciphers=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set_cipher_list failed, 
ciphers=%s, %s\n",
 ciphers, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -854,7 +854,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 SSL_CTX_set_read_ahead(p->ctx, 1);
 /* Setup the SRTP context */
 if (SSL_CTX_set_tlsext_use_srtp(p->ctx, profiles)) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_tlsext_use_srtp failed, 
profiles=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set_tlsext_use_srtp failed, 
profiles=%s, %s\n",
 profiles, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -906,12 +906,12 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 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) {
-av_log(p, AV_LOG_ERROR, "TLS: Failed to drive SSL context, 
ret=%d\n", ret);
+av_log(p, AV_LOG_ERROR, "Failed to drive SSL context, ret=%d\n", 
ret);
 return AVERROR(EIO);
 }
 }
 
-av_log(p, AV_LOG_VERBOSE, "TLS: Setup ok, MTU=%d\n", p->tls_shared.mtu);
+av_log(p, AV_LOG_VERBOSE, "Setup ok, MTU=%d\n", p->tls_shared.mtu);
 
 ret = 0;
 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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 2/4] avformat/tls_openssl: fix dtls_handshake return code

2025-07-11 Thread Jack Lau


> On Jul 11, 2025, at 23:05, Steven Liu  
> wrote:
> 
> Jack Lau  <mailto:jacklau1222gm-at-gmail@ffmpeg.org>> 于2025年7月11日周五 21:22写道:
>> 
>> If the handshake is still in progress, dtls_handshake should
>> return a positive status code.
>> 
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/tls_openssl.c | 7 +++
>> 1 file changed, 3 insertions(+), 4 deletions(-)
>> 
>> diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
>> index 8639ac9758..ffd9cd51d2 100644
>> --- a/libavformat/tls_openssl.c
>> +++ b/libavformat/tls_openssl.c
>> @@ -716,15 +716,14 @@ static int openssl_dtls_verify_callback(int 
>> preverify_ok, X509_STORE_CTX *ctx)
>> 
>> static int dtls_handshake(URLContext *h)
>> {
>> -int ret = 0, r0, r1;
>> +int ret = EINPROGRESS, r0, r1;
> AVERROR(EINPROGRESS) ?
Why I use the positive return code because avio_handshake specify:
0 on a complete and successful handshake 
> 0 if the handshake progressed, but is not complete 
< 0 for an AVERROR code

So when the dtls_handshake is still in processing, I return a positive code 
EINPROGRESS to match this description

>> TLSContext *p = h->priv_data;
>> 
>> r0 = SSL_do_handshake(p->ssl);
>> r1 = SSL_get_error(p->ssl, r0);
>> if (r0 <= 0) {
>> if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != 
>> SSL_ERROR_ZERO_RETURN) {
>> -av_log(p, AV_LOG_ERROR, "TLS: Read failed, r0=%d, r1=%d %s\n", 
>> r0, r1, openssl_get_error(p));
>> -ret = AVERROR(EIO);
>> +ret = print_ssl_error(h, r1);
>> goto end;
>> }
>> } else {
>> @@ -734,7 +733,7 @@ static int dtls_handshake(URLContext *h)
>> /* Check whether the DTLS is completed. */
>> if (SSL_is_init_finished(p->ssl) != 1)
>> goto end;
>> -
>> +ret = 0;
>> p->tls_shared.state = DTLS_STATE_FINISHED;
>> end:
>> 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-requ...@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-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 8/9] avformat/tls_openssl: auto set the dest addr when dtls in listen mode

2025-07-13 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 1c4d114205..344b152902 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -465,6 +465,8 @@ typedef struct TLSContext {
 BIO_METHOD* url_bio_method;
 int io_err;
 char error_message[256];
+struct sockaddr_storage dest_addr;
+socklen_t dest_addr_len;
 } TLSContext;
 
 /**
@@ -582,8 +584,19 @@ static int url_bio_destroy(BIO *b)
 static int url_bio_bread(BIO *b, char *buf, int len)
 {
 TLSContext *c = BIO_get_data(b);
+TLSShared *s = &c->tls_shared;
 int ret = ffurl_read(c->tls_shared.is_dtls ? c->tls_shared.udp : 
c->tls_shared.tcp, buf, len);
 if (ret >= 0) {
+if (!s->external_sock && s->is_dtls && s->listen && !c->dest_addr_len 
&& !c->dest_addr.ss_family) {
+int r1;
+ff_udp_get_last_recv_addr(s->udp, &c->dest_addr, 
&c->dest_addr_len);
+r1 = ff_udp_set_remote_addr(s->udp, (struct 
sockaddr*)&c->dest_addr, c->dest_addr_len, 1);
+if (r1 < 0) {
+av_log(c, AV_LOG_ERROR, "Failed to set remote addr\n");
+return r1;
+}
+av_log(c, AV_LOG_DEBUG, "Set UDP remote addr successfully\n");
+}
 openssl_state_trace((uint8_t*)buf, ret, 1);
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 9/9] avformat/tls_openssl: init DTLS context with explicit method

2025-07-13 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 344b152902..4874260b6b 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -787,7 +787,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 /* Refer to the test cases regarding these curves in the WebRTC code. */
 const char* curves = "X25519:P-256:P-384:P-521";
 
-p->ctx = SSL_CTX_new(DTLS_method());
+p->ctx = SSL_CTX_new(c->listen ? DTLS_server_method() : 
DTLS_client_method());
 if (!p->ctx) {
 ret = AVERROR(ENOMEM);
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 5/9] avformat/whip: free udp socket after dtls free

2025-07-13 Thread Jack Lau
the SSL_shutdown in tls_close need call the url_bio_bwrite
so we should keep udp still alive

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index e272254a6f..17a3cd0ea8 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -1865,12 +1865,12 @@ static av_cold void whip_deinit(AVFormatContext *s)
 av_freep(&whip->authorization);
 av_freep(&whip->cert_file);
 av_freep(&whip->key_file);
-ffurl_closep(&whip->udp);
 ff_srtp_free(&whip->srtp_audio_send);
 ff_srtp_free(&whip->srtp_video_send);
 ff_srtp_free(&whip->srtp_rtcp_send);
 ff_srtp_free(&whip->srtp_recv);
 ffurl_close(whip->dtls_uc);
+ffurl_closep(&whip->udp);
 }
 
 static int whip_check_bitstream(AVFormatContext *s, AVStream *st, const 
AVPacket *pkt)
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 7/9] avformat/tls_openssl: remove requirement for dtls must init cert and key

2025-07-13 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 4f950a2fde..1c4d114205 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -731,10 +731,6 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
 ret = AVERROR(EINVAL);
 return ret;
 }
-} else if (c->is_dtls){
-av_log(p, AV_LOG_ERROR, "Init cert failed, %s\n", 
openssl_get_error(p));
-ret = AVERROR(EINVAL);
-goto fail;
 }
 
 if (c->key_file) {
@@ -752,10 +748,6 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
 ret = AVERROR(EINVAL);
 return ret;
 }
-} else if (c->is_dtls) {
-av_log(p, AV_LOG_ERROR, "Init pkey failed, %s\n", 
openssl_get_error(p));
-ret = AVERROR(EINVAL);
-goto fail;
 }
 ret = 0;
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 6/9] avformat/tls_openssl: replace 1 to TLS_ST_OK to be more clear

2025-07-13 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 3ed4585ecf..4f950a2fde 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -695,7 +695,7 @@ static int dtls_handshake(URLContext *h)
 }
 
 /* Check whether the DTLS is completed. */
-if (SSL_is_init_finished(p->ssl) != 1)
+if (SSL_is_init_finished(p->ssl) != TLS_ST_OK)
 goto end;
 ret = 0;
 p->tls_shared.state = DTLS_STATE_FINISHED;
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 1/9] avformat/tls: add trace function for log TLS/DTLS record

2025-07-13 Thread Jack Lau
Refer to RFC 5246, RFC 6347

Signed-off-by: Jack Lau 
---
 libavformat/tls.c | 56 +++
 libavformat/tls.h |  2 ++
 libavformat/tls_openssl.c |  8 --
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/libavformat/tls.c b/libavformat/tls.c
index bd9c05e6dc..c549b014cf 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -27,10 +27,66 @@
 #include "url.h"
 #include "tls.h"
 #include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/getenv_utf8.h"
 #include "libavutil/mem.h"
 #include "libavutil/parseutils.h"
 
+enum {
+CONTENT_TYPE_CHANGE_CIPHER_SPEC = 20,
+CONTENT_TYPE_ALERT = 21,
+CONTENT_TYPE_HANDSHAKE = 22,
+CONTENT_TYPE_APPLICATION_DATA = 23,
+CONTENT_TYPE_OTHERS = 255
+} ContentType;
+
+enum {
+TLS1_MAJOR_VERSION = 0x03,
+DTLS1_MAJOR_VERSION = 0xFE,
+} TLSVersion;
+
+/*
+ * Trace a single TLS/DTLS record.
+ * 
+ * See RFC 5246 Section 6.2.1, RFC 6347 Section 4.1
+ * 
+ * @param data Raw record (network byte‑order).
+ * @param length   Size of @data in bytes.
+ * @param incoming Non‑zero when the packet was received, zero when sent.
+ */
+void openssl_state_trace(uint8_t *data, int length, int incoming)
+{
+uint8_t  content_type   = 0;  /* TLS/DTLS ContentType   */
+uint16_t record_length  = 0;  /* Length field from header   */
+uint8_t  handshake_type = 0;  /* First byte of Handshake msg */
+int is_dtls = 0;
+
+/* ContentType is always the very first byte */
+if (length >= 1)
+content_type = AV_RB8(&data[0]);
+if (length >= 3 && data[1] == DTLS1_MAJOR_VERSION)
+is_dtls = 1;
+/* TLS header is 5 bytes, DTLS header is 13 bytes */
+if (length >= 13 && is_dtls)
+record_length = AV_RB16(&data[11]);
+else if (length >= 5 && !is_dtls)
+record_length = AV_RB16(&data[3]);
+/*
+ * HandshakeType values (TLS 1.0–1.2, DTLS 1.0/1.2)
+ * See RFC 5246 Section 7.4, RFC 6347 Section 4.2
+ *
+ * Only present when ContentType == handshake(22)
+ */
+if (content_type == CONTENT_TYPE_HANDSHAKE) {
+int hs_off = is_dtls ? 13 : 5;
+if (length > hs_off)
+handshake_type = AV_RB8(&data[hs_off]);
+}
+
+av_log(NULL, AV_LOG_TRACE ,"TLS: Trace %s, len=%u, cnt=%u, size=%u, 
hs=%u\n",
+(incoming? "RECV":"SEND"), length, content_type, record_length, 
handshake_type);
+}
+
 static int set_options(TLSShared *c, const char *uri)
 {
 char buf[1024];
diff --git a/libavformat/tls.h b/libavformat/tls.h
index 0c02a4ab27..cc8823e008 100644
--- a/libavformat/tls.h
+++ b/libavformat/tls.h
@@ -95,6 +95,8 @@ typedef struct TLSShared {
 {"key_pem","Private key PEM string",  offsetof(pstruct, 
options_field . key_buf),   AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \
 FF_TLS_CLIENT_OPTIONS(pstruct, options_field)
 
+void openssl_state_trace(uint8_t *data, int length, int incoming);
+
 int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, 
AVDictionary **options);
 
 int ff_url_read_all(const char *url, AVBPrint *bp);
diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2a01fb387d..2777a4f657 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -576,8 +576,10 @@ static int url_bio_bread(BIO *b, char *buf, int len)
 {
 TLSContext *c = BIO_get_data(b);
 int ret = ffurl_read(c->tls_shared.is_dtls ? c->tls_shared.udp : 
c->tls_shared.tcp, buf, len);
-if (ret >= 0)
+if (ret >= 0) {
+openssl_state_trace((uint8_t*)buf, ret, 1);
 return ret;
+}
 BIO_clear_retry_flags(b);
 if (ret == AVERROR_EXIT)
 return 0;
@@ -592,8 +594,10 @@ static int url_bio_bwrite(BIO *b, const char *buf, int len)
 {
 TLSContext *c = BIO_get_data(b);
 int ret = ffurl_write(c->tls_shared.is_dtls ? c->tls_shared.udp : 
c->tls_shared.tcp, buf, len);
-if (ret >= 0)
+if (ret >= 0) {
+openssl_state_trace((uint8_t*)buf, ret, 0);
 return ret;
+}
 BIO_clear_retry_flags(b);
 if (ret == AVERROR_EXIT)
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 0/9] Fix some issues in tls_openssl

2025-07-13 Thread Jack Lau
This patchset aims to fix some issues so that DTLS can work properly (not just 
for WHIP)

Quick experience using such command:
ffmpeg -v debug -listen 1 -cert_file cert.pem -key_file key.pem -mtu 1500 -i 
dtls://127.0.0.1: -c copy -y out.mp4
ffmpeg -v trace -f lavfi -re -i testsrc2=duration=5:size=128x72:rate=30 -an -sn 
-c:v libx264 -mtu 1 -f mpegts "dtls://127.0.0.1:"

Or using avio public api:
https://github.com/JackLau1222/openssl-dtls-bio-example/tree/master/ffmpeg_case

I notice DTLS still have to do some cleanups, I plan to implement WHIP DTLS 
client role next step so i'll do it also in coming days

Original description:
This patchset aims to fix some issues when i try to utilize DTLS using avio.
I create a simple DTLS client and server case here
https://github.com/JackLau1222/openssl-dtls-bio-example/tree/master/ffmpeg_case

This patchset fix:
1. dtls_handshake can't return positive code when it still in progressing
2. udp server mode haven't dest_addr so we need set it through last_recv_addr
3. some code cleanup

This patchset depends on Timo's latest schannel patchset
More details: https://github.com/BtbN/FFmpeg/pull/3

Jack Lau (9):
  avformat/tls: add trace function for log TLS/DTLS record
  avformat/tls_openssl: fix dtls_handshake return code
  avformat/tls_openssl: remove all redundant "TLS: " in log with AVClass
  avformat/tls_openssl: make tls and dtls use one close function
  avformat/whip: free udp socket after dtls free
  avformat/tls_openssl: replace 1 to TLS_ST_OK to be more clear
  avformat/tls_openssl: remove requirement for dtls must init cert and
key
  avformat/tls_openssl: auto set the dest addr when dtls in listen mode
  avformat/tls_openssl: init DTLS context with explicit method

 libavformat/tls.c | 56 +++
 libavformat/tls.h |  2 +
 libavformat/tls_openssl.c | 81 ---
 libavformat/whip.c|  2 +-
 4 files changed, 100 insertions(+), 41 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 3/9] avformat/tls_openssl: remove all redundant "TLS: " in log with AVClass

2025-07-13 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 25318d5fca..c824c5452b 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -508,7 +508,7 @@ int ff_dtls_export_materials(URLContext *h, char 
*dtls_srtp_materials, size_t ma
 ret = SSL_export_keying_material(c->ssl, dtls_srtp_materials, materials_sz,
 dst, strlen(dst), NULL, 0, 0);
 if (!ret) {
-av_log(c, AV_LOG_ERROR, "TLS: Failed to export SRTP material, %s\n", 
openssl_get_error(c));
+av_log(c, AV_LOG_ERROR, "Failed to export SRTP material, %s\n", 
openssl_get_error(c));
 return -1;
 }
 return 0;
@@ -684,7 +684,7 @@ static int dtls_handshake(URLContext *h)
 goto end;
 }
 } else {
-av_log(p, AV_LOG_TRACE, "TLS: Read %d bytes, r0=%d, r1=%d\n", r0, r0, 
r1);
+av_log(p, AV_LOG_TRACE, "Read %d bytes, r0=%d, r1=%d\n", r0, r0, r1);
 }
 
 /* Check whether the DTLS is completed. */
@@ -725,7 +725,7 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
 return ret;
 }
 } else if (c->is_dtls){
-av_log(p, AV_LOG_ERROR, "TLS: Init cert failed, %s\n", 
openssl_get_error(p));
+av_log(p, AV_LOG_ERROR, "Init cert failed, %s\n", 
openssl_get_error(p));
 ret = AVERROR(EINVAL);
 goto fail;
 }
@@ -741,12 +741,12 @@ static av_cold int openssl_init_ca_key_cert(URLContext *h)
 } 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));
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_use_PrivateKey failed, 
%s\n", openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
 }
 } else if (c->is_dtls) {
-av_log(p, AV_LOG_ERROR, "TLS: Init pkey failed, %s\n", 
openssl_get_error(p));
+av_log(p, AV_LOG_ERROR, "Init pkey failed, %s\n", 
openssl_get_error(p));
 ret = AVERROR(EINVAL);
 goto fail;
 }
@@ -783,7 +783,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 
 /* For ECDSA, we could set the curves list. */
 if (SSL_CTX_set1_curves_list(p->ctx, curves) != 1) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set1_curves_list failed, 
curves=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set1_curves_list failed, 
curves=%s, %s\n",
 curves, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -794,7 +794,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
  * ensuring maximum compatibility.
  */
 if (SSL_CTX_set_cipher_list(p->ctx, ciphers) != 1) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_cipher_list failed, 
ciphers=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set_cipher_list failed, 
ciphers=%s, %s\n",
 ciphers, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -811,7 +811,7 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 SSL_CTX_set_read_ahead(p->ctx, 1);
 /* Setup the SRTP context */
 if (SSL_CTX_set_tlsext_use_srtp(p->ctx, profiles)) {
-av_log(p, AV_LOG_ERROR, "TLS: Init SSL_CTX_set_tlsext_use_srtp failed, 
profiles=%s, %s\n",
+av_log(p, AV_LOG_ERROR, "Init SSL_CTX_set_tlsext_use_srtp failed, 
profiles=%s, %s\n",
 profiles, openssl_get_error(p));
 ret = AVERROR(EINVAL);
 return ret;
@@ -863,12 +863,12 @@ static int dtls_start(URLContext *h, const char *url, int 
flags, AVDictionary **
 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) {
-av_log(p, AV_LOG_ERROR, "TLS: Failed to drive SSL context, 
ret=%d\n", ret);
+av_log(p, AV_LOG_ERROR, "Failed to drive SSL context, ret=%d\n", 
ret);
 return AVERROR(EIO);
 }
 }
 
-av_log(p, AV_LOG_VERBOSE, "TLS: Setup ok, MTU=%d\n", p->tls_shared.mtu);
+av_log(p, AV_LOG_VERBOSE, "Setup ok, MTU=%d\n", p->tls_shared.mtu);
 
 ret = 0;
 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 4/9] avformat/tls_openssl: make tls and dtls use one close function

2025-07-13 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index c824c5452b..3ed4585ecf 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -553,9 +553,16 @@ static int tls_close(URLContext *h)
 }
 if (c->ctx)
 SSL_CTX_free(c->ctx);
-ffurl_closep(&c->tls_shared.tcp);
+if (c->tls_shared.external_sock != 1)
+ffurl_closep(c->tls_shared.is_dtls ? &c->tls_shared.udp : 
&c->tls_shared.tcp);
+if (c->tls_shared.cert_buf)
+av_freep(&c->tls_shared.cert_buf);
+if (c->tls_shared.key_buf)
+av_freep(&c->tls_shared.key_buf);
 if (c->url_bio_method)
 BIO_meth_free(c->url_bio_method);
+if (c->pkey)
+EVP_PKEY_free(c->pkey);
 return 0;
 }
 
@@ -875,20 +882,6 @@ fail:
 return ret;
 }
 
-/**
- * Cleanup the DTLS context.
- */
-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.cert_buf);
-av_freep(&ctx->tls_shared.key_buf);
-EVP_PKEY_free(ctx->pkey);
-return 0;
-}
-
 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary 
**options)
 {
 TLSContext *p = h->priv_data;
@@ -1032,7 +1025,7 @@ const URLProtocol ff_dtls_protocol = {
 .name   = "dtls",
 .url_open2  = dtls_start,
 .url_handshake  = dtls_handshake,
-.url_close  = dtls_close,
+.url_close  = tls_close,
 .url_read   = tls_read,
 .url_write  = tls_write,
 .url_get_file_handle = tls_get_file_handle,
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 2/9] avformat/tls_openssl: fix dtls_handshake return code

2025-07-13 Thread Jack Lau
If the handshake is still in progress, dtls_handshake should
return a status code.

init ret=AVERROR(EAGAIN) to match most of FFmpeg code

Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2777a4f657..25318d5fca 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -673,15 +673,14 @@ static int openssl_dtls_verify_callback(int preverify_ok, 
X509_STORE_CTX *ctx)
 
 static int dtls_handshake(URLContext *h)
 {
-int ret = 0, r0, r1;
+int ret = AVERROR(EAGAIN), r0, r1;
 TLSContext *p = h->priv_data;
 
 r0 = SSL_do_handshake(p->ssl);
 r1 = SSL_get_error(p->ssl, r0);
 if (r0 <= 0) {
 if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != 
SSL_ERROR_ZERO_RETURN) {
-av_log(p, AV_LOG_ERROR, "TLS: Read failed, r0=%d, r1=%d %s\n", r0, 
r1, openssl_get_error(p));
-ret = AVERROR(EIO);
+ret = print_ssl_error(h, r1);
 goto end;
 }
 } else {
@@ -691,7 +690,7 @@ static int dtls_handshake(URLContext *h)
 /* Check whether the DTLS is completed. */
 if (SSL_is_init_finished(p->ssl) != 1)
 goto end;
-
+ret = 0;
 p->tls_shared.state = DTLS_STATE_FINISHED;
 end:
 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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code

2025-07-03 Thread Jack Lau


> On Jul 3, 2025, at 22:24, Timo Rothenpieler  wrote:
> 
> On 03.07.2025 03:07, Jack Lau wrote:
>>> On Jul 3, 2025, at 00:56, Timo Rothenpieler  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-requ...@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-requ...@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-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code

2025-07-02 Thread Jack Lau


> On Jul 3, 2025, at 00:56, Timo Rothenpieler  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-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 5/6] avformat/whip: implement NACK and RTX suppport

2025-07-02 Thread Jack Lau
RTP retransmission described in RFC4588 (RTX) is an effective packet
loss recovery technique for real-time applications with relaxed delay bounds.

This patch provides a minimal implementation for RTX and RTCP NACK (RFC3940)
and its associated SDP signaling and negotiation.

Co-authored-by: Sergio Garcia Murillo 
Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 206 -
 1 file changed, 202 insertions(+), 4 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index e287a3062f..b86e343419 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -114,6 +114,7 @@
 /* Referring to Chrome's definition of RTP payload types. */
 #define WHIP_RTP_PAYLOAD_TYPE_H264 106
 #define WHIP_RTP_PAYLOAD_TYPE_OPUS 111
+#define WHIP_RTP_PAYLOAD_TYPE_RTX  105
 
 /**
  * The STUN message header, which is 20 bytes long, comprises the
@@ -150,6 +151,11 @@
 #define WHIP_SDP_SESSION_ID "4489045141692799359"
 #define WHIP_SDP_CREATOR_IP "127.0.0.1"
 
+/**
+ * Retransmission / NACK support
+*/
+#define HISTORY_SIZE_DEFAULT 512
+
 /* Calculate the elapsed time from starttime to endtime in milliseconds. */
 #define ELAPSED(starttime, endtime) ((int)(endtime - starttime) / 1000)
 
@@ -194,9 +200,16 @@ enum WHIPState {
 };
 
 typedef enum WHIPFlags {
-WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
+WHIP_FLAG_IGNORE_IPV6  = (1 << 0), // Ignore ipv6 candidate
+WHIP_FLAG_DISABLE_RTX = (1 << 1)  // Enable NACK and RTX
 } WHIPFlags;
 
+typedef struct RtpHistoryItem {
+uint16_t seq; // original RTP seq
+int size; // length in bytes
+uint8_t* buf; // malloc-ed copy
+} RtpHistoryItem;
+
 typedef struct WHIPContext {
 AVClass *av_class;
 
@@ -285,6 +298,7 @@ typedef struct WHIPContext {
 /* The SRTP send context, to encrypt outgoing packets. */
 SRTPContext srtp_audio_send;
 SRTPContext srtp_video_send;
+SRTPContext srtp_video_rtx_send;
 SRTPContext srtp_rtcp_send;
 /* The SRTP receive context, to decrypt incoming packets. */
 SRTPContext srtp_recv;
@@ -309,6 +323,14 @@ typedef struct WHIPContext {
 /* The certificate and private key used for DTLS handshake. */
 char* cert_file;
 char* key_file;
+
+/* RTX and NACK */
+uint8_t rtx_payload_type;
+uint32_t video_rtx_ssrc;
+uint16_t rtx_seq;
+int  history_size;
+RtpHistoryItem *history;  /* ring buffer  */
+int hist_head;
 } WHIPContext;
 
 /**
@@ -606,6 +628,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 whip->audio_payload_type = WHIP_RTP_PAYLOAD_TYPE_OPUS;
 whip->video_payload_type = WHIP_RTP_PAYLOAD_TYPE_H264;
 
+/* RTX and NACK init */
+whip->rtx_payload_type = WHIP_RTP_PAYLOAD_TYPE_RTX;
+whip->video_rtx_ssrc = av_lfg_get(&whip->rnd);
+whip->rtx_seq = 0;
+whip->hist_head = 0;
+whip->history_size = FFMAX(64, whip->history_size);
+whip->history = av_calloc(whip->history_size, sizeof(*whip->history));
+if (!whip->history)
+return AVERROR(ENOMEM);
+
 av_bprintf(&bp, ""
 "v=0\r\n"
 "o=FFmpeg %s 2 IN IP4 %s\r\n"
@@ -656,7 +688,7 @@ static int generate_sdp_offer(AVFormatContext *s)
 }
 
 av_bprintf(&bp, ""
-"m=video 9 UDP/TLS/RTP/SAVPF %u\r\n"
+"m=video 9 UDP/TLS/RTP/SAVPF %u %u\r\n"
 "c=IN IP4 0.0.0.0\r\n"
 "a=ice-ufrag:%s\r\n"
 "a=ice-pwd:%s\r\n"
@@ -669,9 +701,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 "a=rtcp-rsize\r\n"
 "a=rtpmap:%u %s/9\r\n"
 "a=fmtp:%u 
level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=%02x%02x%02x\r\n"
+"a=rtcp-fb:%u nack\r\n"
+"a=rtpmap:%u rtx/9\r\n"
+"a=fmtp:%u apt=%u\r\n"
+"a=ssrc-group:FID %u %u\r\n"
+"a=ssrc:%u cname:FFmpeg\r\n"
+"a=ssrc:%u msid:FFmpeg video\r\n"
 "a=ssrc:%u cname:FFmpeg\r\n"
 "a=ssrc:%u msid:FFmpeg video\r\n",
 whip->video_payload_type,
+whip->rtx_payload_type,
 whip->ice_ufrag_local,
 whip->ice_pwd_local,
 whip->dtls_fingerprint,
@@ -681,8 +720,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 profile,
 whip->constraint_set_flags,
 level,
+whip->video_payload_type,
+whip->rtx_payload_type,
+whip->rtx_payload_type,
+whip->video_payload_type,
+whip->video_ssrc,
+whip->video_rtx_ssrc,
 whip->video_ssrc,
-whip->video_ss

Re: [FFmpeg-devel] [PATCH 08/18] avformat/tls: move openssl specific init out of generic code

2025-07-05 Thread Jack Lau


> On Jul 4, 2025, at 00:41, Timo Rothenpieler  wrote:
> 
> On 03.07.2025 17:22, Jack Lau wrote:
>>> On Jul 3, 2025, at 22:24, Timo Rothenpieler  wrote:
>>> 
>>> On 03.07.2025 03:07, Jack Lau wrote:
>>>>> On Jul 3, 2025, at 00:56, Timo Rothenpieler  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.
Agree, please remove all of them.
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org <mailto:ffmpeg-devel-requ...@ffmpeg.org> with 
> subject "unsubscribe".

Thanks
Jack

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

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


Re: [FFmpeg-devel] [PATCH 11/18] avformat/udp: make recv addr of each packet available

2025-07-05 Thread Jack Lau



> On Jul 3, 2025, at 00:56, Timo Rothenpieler  wrote:
> 
> ---
> 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;
Should we add socklen_t last_recv_len also?
> 
> } 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);
s->last_recv_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);
ret = recvfrom(s->udp_fd, buf, size, 0, (struct sockaddr *)&s->last_recv_addr, 
&s->last_recv_len);
> if (ret < 0)
> return ff_neterrno();
> -if (ff_ip_check_source_lists(&addr, &s->filters))
> +if (ff_ip_check_source_lists(&s->last_

Re: [FFmpeg-devel] [PATCH v2 5/6] avformat/whip: implement NACK and RTX suppport

2025-07-02 Thread Jack Lau
Hi

> On Jul 2, 2025, at 21:46, Steven Liu  
> wrote:
> 
> Jack Lau  <mailto:jacklau1222gm-at-gmail@ffmpeg.org>> 于2025年7月2日周三 20:09写道:
>> 
>> RTP retransmission described in RFC4588 (RTX) is an effective packet
>> loss recovery technique for real-time applications with relaxed delay bounds.
>> 
>> This patch provides a minimal implementation for RTX and RTCP NACK (RFC3940)
>> and its associated SDP signaling and negotiation.
>> 
>> Co-authored-by: Sergio Garcia Murillo 
>> Signed-off-by: Jack Lau 
>> ---
>> libavformat/whip.c | 198 -
>> 1 file changed, 195 insertions(+), 3 deletions(-)
>> 
>> diff --git a/libavformat/whip.c b/libavformat/whip.c
>> index e287a3062f..fa6e3855d3 100644
>> --- a/libavformat/whip.c
>> +++ b/libavformat/whip.c
>> @@ -114,6 +114,7 @@
>> /* Referring to Chrome's definition of RTP payload types. */
>> #define WHIP_RTP_PAYLOAD_TYPE_H264 106
>> #define WHIP_RTP_PAYLOAD_TYPE_OPUS 111
>> +#define WHIP_RTP_PAYLOAD_TYPE_RTX  105
>> 
>> /**
>>  * The STUN message header, which is 20 bytes long, comprises the
>> @@ -150,6 +151,11 @@
>> #define WHIP_SDP_SESSION_ID "4489045141692799359"
>> #define WHIP_SDP_CREATOR_IP "127.0.0.1"
>> 
>> +/**
>> + * Retransmission / NACK support
>> +*/
>> +#define HISTORY_SIZE_DEFAULT 512
>> +
>> /* Calculate the elapsed time from starttime to endtime in milliseconds. */
>> #define ELAPSED(starttime, endtime) ((int)(endtime - starttime) / 1000)
>> 
>> @@ -194,9 +200,19 @@ enum WHIPState {
>> };
>> 
>> typedef enum WHIPFlags {
>> -WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
>> +WHIP_FLAG_IGNORE_IPV6  = (1 << 0), // Ignore ipv6 candidate
>> +WHIP_FLAG_DISABLE_RTX = (1 << 1)  // Enable NACK and RTX
>> } WHIPFlags;
>> 
>> +typedef struct RtpHistoryItem {
>> +/* original RTP seq */
>> +uint16_t seq;  /* original RTP seq */
>> +/* length in bytes */
>> +int size;/* length in bytes */
>> +/* malloc-ed copy */
> move the comments.
>> +uint8_t* buf; /* malloc-ed copy */
>> +} RtpHistoryItem;
> 
> for example:
> 
> 
> 171 typedef struct mkv_cuepoint {
> 172 uint64_tpts;
> 173 int stream_idx;
> 174 int64_t cluster_pos;///< offset of the
> cluster containing the block relative to the segment
> 175 int64_t relative_pos;   ///< relative offset from
> the position of the cluster containing the block
> 176 int64_t duration;   ///< duration of the
> block according to time base
> 177 } mkv_cuepoint;
> 
> 
> 
>> +
>> typedef struct WHIPContext {
>> AVClass *av_class;
>> 
>> @@ -285,6 +301,7 @@ typedef struct WHIPContext {
>> /* The SRTP send context, to encrypt outgoing packets. */
>> SRTPContext srtp_audio_send;
>> SRTPContext srtp_video_send;
>> +SRTPContext srtp_video_rtx_send;
>> SRTPContext srtp_rtcp_send;
>> /* The SRTP receive context, to decrypt incoming packets. */
>> SRTPContext srtp_recv;
>> @@ -309,6 +326,14 @@ typedef struct WHIPContext {
>> /* The certificate and private key used for DTLS handshake. */
>> char* cert_file;
>> char* key_file;
>> +
>> +/* RTX and NACK */
>> +uint8_t rtx_payload_type;
>> +uint32_t video_rtx_ssrc;
>> +uint16_t rtx_seq;
>> +int  history_size;
>> +RtpHistoryItem *history;  /* ring buffer  */
>> +int hist_head;
>> } WHIPContext;
>> 
>> /**
>> @@ -606,6 +631,16 @@ static int generate_sdp_offer(AVFormatContext *s)
>> whip->audio_payload_type = WHIP_RTP_PAYLOAD_TYPE_OPUS;
>> whip->video_payload_type = WHIP_RTP_PAYLOAD_TYPE_H264;
>> 
>> +/* RTX and NACK init */
>> +whip->rtx_payload_type = WHIP_RTP_PAYLOAD_TYPE_RTX;
>> +whip->video_rtx_ssrc = av_lfg_get(&whip->rnd);
>> +whip->rtx_seq = 0;
>> +whip->hist_head = 0;
>> +whip->history_size = FFMAX(64, whip->history_size);
>> +whip->history = av_calloc(whip->history_size, sizeof(*whip->history));
>> +if (!whip->history)
>> +return AVERROR(ENOMEM);
>> +
>> av_bprintf(&bp, ""
>> "v=0\r\n"
>> "o=FFmpeg %s 2 IN IP4 %s\r\n"
>> @@ -656,7 +691,7 @@ static int genera

[FFmpeg-devel] [PATCH 6/6] avformat/whip: implement NACK and RTX suppport

2025-07-01 Thread Jack Lau
RTP retransmission described in RFC4588 (RTX) is an effective packet
loss recovery technique for real-time applications with relaxed delay bounds.

This patch provides a minimal implementation for RTX and RTCP NACK (RFC3940)
and its associated SDP signaling and negotiation.

Co-authored-by: Sergio Garcia Murillo 
Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 198 -
 1 file changed, 195 insertions(+), 3 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 15d1de691e..a32177e0b4 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -114,6 +114,7 @@
 /* Referring to Chrome's definition of RTP payload types. */
 #define WHIP_RTP_PAYLOAD_TYPE_H264 106
 #define WHIP_RTP_PAYLOAD_TYPE_OPUS 111
+#define WHIP_RTP_PAYLOAD_TYPE_RTX  105
 
 /**
  * The STUN message header, which is 20 bytes long, comprises the
@@ -150,6 +151,11 @@
 #define WHIP_SDP_SESSION_ID "4489045141692799359"
 #define WHIP_SDP_CREATOR_IP "127.0.0.1"
 
+/**
+ * Retransmission / NACK support
+*/
+#define HISTORY_SIZE_DEFAULT 512
+
 /* Calculate the elapsed time from starttime to endtime in milliseconds. */
 #define ELAPSED(starttime, endtime) ((int)(endtime - starttime) / 1000)
 
@@ -194,9 +200,19 @@ enum WHIPState {
 };
 
 typedef enum WHIPFlags {
-WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
+WHIP_FLAG_IGNORE_IPV6  = (1 << 0), // Ignore ipv6 candidate
+WHIP_FLAG_DISABLE_RTX = (1 << 1)  // Enable NACK and RTX
 } WHIPFlags;
 
+typedef struct RtpHistoryItem {
+/* original RTP seq */
+uint16_t seq;
+/* length in bytes */
+int size;
+/* malloc-ed copy */
+uint8_t* pkt;
+} RtpHistoryItem;
+
 typedef struct WHIPContext {
 AVClass *av_class;
 
@@ -285,6 +301,7 @@ typedef struct WHIPContext {
 /* The SRTP send context, to encrypt outgoing packets. */
 SRTPContext srtp_audio_send;
 SRTPContext srtp_video_send;
+SRTPContext srtp_video_rtx_send;
 SRTPContext srtp_rtcp_send;
 /* The SRTP receive context, to decrypt incoming packets. */
 SRTPContext srtp_recv;
@@ -309,6 +326,14 @@ typedef struct WHIPContext {
 /* The certificate and private key used for DTLS handshake. */
 char* cert_file;
 char* key_file;
+
+/* RTX / NACK */
+uint8_t rtx_payload_type;
+uint32_t video_rtx_ssrc;
+uint16_t rtx_seq;
+int  history_size;
+RtpHistoryItem *history;  /* ring buffer  */
+int hist_head;
 } WHIPContext;
 
 /**
@@ -606,6 +631,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 whip->audio_payload_type = WHIP_RTP_PAYLOAD_TYPE_OPUS;
 whip->video_payload_type = WHIP_RTP_PAYLOAD_TYPE_H264;
 
+/* RTX and NACK init */
+whip->rtx_payload_type = WHIP_RTP_PAYLOAD_TYPE_RTX;
+whip->video_rtx_ssrc = av_lfg_get(&whip->rnd);
+whip->rtx_seq = 0;
+whip->hist_head = 0;
+whip->history_size = FFMAX(64, whip->history_size);
+whip->history = av_calloc(whip->history_size, sizeof(*whip->history));
+if (!whip->history)
+return AVERROR(ENOMEM);
+
 av_bprintf(&bp, ""
 "v=0\r\n"
 "o=FFmpeg %s 2 IN IP4 %s\r\n"
@@ -656,7 +691,7 @@ static int generate_sdp_offer(AVFormatContext *s)
 }
 
 av_bprintf(&bp, ""
-"m=video 9 UDP/TLS/RTP/SAVPF %u\r\n"
+"m=video 9 UDP/TLS/RTP/SAVPF %u %u\r\n"
 "c=IN IP4 0.0.0.0\r\n"
 "a=ice-ufrag:%s\r\n"
 "a=ice-pwd:%s\r\n"
@@ -669,9 +704,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 "a=rtcp-rsize\r\n"
 "a=rtpmap:%u %s/9\r\n"
 "a=fmtp:%u 
level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=%02x%02x%02x\r\n"
+"a=rtcp-fb:%u nack\r\n"
+"a=rtpmap:%u rtx/9\r\n"
+"a=fmtp:%u apt=%u\r\n"
+"a=ssrc-group:FID %u %u\r\n"
+"a=ssrc:%u cname:FFmpeg\r\n"
+"a=ssrc:%u msid:FFmpeg video\r\n"
 "a=ssrc:%u cname:FFmpeg\r\n"
 "a=ssrc:%u msid:FFmpeg video\r\n",
 whip->video_payload_type,
+whip->rtx_payload_type,
 whip->ice_ufrag_local,
 whip->ice_pwd_local,
 whip->dtls_fingerprint,
@@ -681,8 +723,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 profile,
 whip->constraint_set_flags,
 level,
+whip->video_payload_type,
+whip->rtx_payload_type,
+whip->rtx_payload_type,
+whip->video_payload_type,
+whip->video_ssrc,
+whip->video_rtx_ssrc,
 whip->video_ssrc,
- 

[FFmpeg-devel] [PATCH 3/6] avformat/whip: fix typos

2025-07-01 Thread Jack Lau
Remove redundant "WHIP: " prefix in log context
since it already add whip context.

Fix grammers in whip options descriptions

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 152 ++---
 1 file changed, 76 insertions(+), 76 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 8d1be90f32..8b011b8b1c 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -364,14 +364,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;
@@ -380,7 +380,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;
 }
@@ -409,7 +409,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;
 }
 
@@ -418,13 +418,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;
@@ -457,7 +457,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);
 }
@@ -471,12 +471,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;
@@ -520,62 +520,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, &quo

[FFmpeg-devel] [PATCH 4/6] avformat/whip: fix H264 profile_iop bit map for SDP

2025-07-01 Thread Jack Lau
AVCodecParameters::profile only contains constraint_set1_flag
(AV_PROFILE_H264_CONSTRAINED 1<<9).
So add H264 constraints flag fully parse refer to hlsenc
write_codec_attr

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 47 --
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 8b011b8b1c..15d1de691e 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -210,6 +210,7 @@ typedef struct WHIPContext {
 /* Parameters for the input audio and video codecs. */
 AVCodecParameters *audio_par;
 AVCodecParameters *video_par;
+uint8_t constraint_set_flags;
 
 /**
  * The h264_mp4toannexb Bitstream Filter (BSF) bypasses the AnnexB packet;
@@ -445,45 +446,30 @@ static av_cold int initialize(AVFormatContext *s)
 static int parse_profile_level(AVFormatContext *s, AVCodecParameters *par)
 {
 int ret = 0;
-const uint8_t *r = par->extradata, *r1, *end = par->extradata + 
par->extradata_size;
-H264SPS seq, *const sps = &seq;
-uint32_t state;
+const uint8_t *r = par->extradata;
 WHIPContext *whip = s->priv_data;
 
 if (par->codec_id != AV_CODEC_ID_H264)
 return ret;
 
-if (par->profile != AV_PROFILE_UNKNOWN && par->level != AV_LEVEL_UNKNOWN)
-return ret;
-
 if (!par->extradata || par->extradata_size <= 0) {
 av_log(whip, AV_LOG_ERROR, "Unable to parse profile from empty 
extradata=%p, size=%d\n",
 par->extradata, par->extradata_size);
 return AVERROR(EINVAL);
 }
 
-while (1) {
-r = avpriv_find_start_code(r, end, &state);
-if (r >= end)
-break;
-
-r1 = ff_nal_find_startcode(r, end);
-if ((state & 0x1f) == H264_NAL_SPS) {
-ret = ff_avc_decode_sps(sps, r, r1 - r);
-if (ret < 0) {
-av_log(whip, AV_LOG_ERROR, "Failed to decode SPS, state=%x, 
size=%d\n",
-state, (int)(r1 - r));
-return ret;
-}
-
-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;
-}
+if (AV_RB32(r) == 0x0001 && (r[4] & 0x1F) == 7)
+r = &r[5];
+else if (AV_RB24(r) == 0x01 && (r[3] & 0x1F) == 7)
+r = &r[4];
+else if (r[0] == 0x01)  // avcC
+r = &r[1];
+else
+return AVERROR(EINVAL);
 
-r = r1;
-}
+if (par->profile == AV_PROFILE_UNKNOWN) par->profile = r[0];
+whip->constraint_set_flags = r[1];
+if (par->level == AV_LEVEL_UNKNOWN) par->level = r[2];
 
 return ret;
 }
@@ -594,7 +580,7 @@ static int parse_codec(AVFormatContext *s)
  */
 static int generate_sdp_offer(AVFormatContext *s)
 {
-int ret = 0, profile, level, profile_iop;
+int ret = 0, profile, level;
 const char *acodec_name = NULL, *vcodec_name = NULL;
 AVBPrint bp;
 WHIPContext *whip = s->priv_data;
@@ -662,11 +648,10 @@ static int generate_sdp_offer(AVFormatContext *s)
 }
 
 if (whip->video_par) {
-profile_iop = profile = whip->video_par->profile;
+profile = whip->video_par->profile;
 level = whip->video_par->level;
 if (whip->video_par->codec_id == AV_CODEC_ID_H264) {
 vcodec_name = "H264";
-profile_iop &= AV_PROFILE_H264_CONSTRAINED;
 profile &= (~AV_PROFILE_H264_CONSTRAINED);
 }
 
@@ -694,7 +679,7 @@ static int generate_sdp_offer(AVFormatContext *s)
 vcodec_name,
 whip->video_payload_type,
 profile,
-profile_iop,
+whip->constraint_set_flags,
 level,
 whip->video_ssrc,
 whip->video_ssrc);
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/6] avformat/whip: add whip_flags ignore_ipv6 to skip IPv6 ICE candidates

2025-07-01 Thread Jack Lau
mark this ignore_ipv6 flag could ignore any IPv6 ICE candidate,
preventing “No route to host” errors on devices without IPv6 connectivity.

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 5fdbd6949d..be6ee9c951 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -193,9 +193,14 @@ enum WHIPState {
 WHIP_STATE_FAILED,
 };
 
+typedef enum WHIPFlags {
+WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
+} WHIPFlags;
+
 typedef struct WHIPContext {
 AVClass *av_class;
 
+uint32_t flags;// enum WHIPFlags
 /* The state of the RTC connection. */
 enum WHIPState state;
 /* The callback return value for DTLS. */
@@ -879,6 +884,7 @@ static int parse_answer(AVFormatContext *s)
 if (ptr && av_stristr(ptr, "host")) {
 char protocol[17], host[129];
 int priority, port;
+struct in6_addr addr6;
 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",
@@ -887,6 +893,11 @@ static int parse_answer(AVFormatContext *s)
 goto end;
 }
 
+if (whip->flags & WHIP_FLAG_IGNORE_IPV6 && inet_pton(AF_INET6, 
host, &addr6) == 1) {
+av_log(whip, AV_LOG_DEBUG, "Ignoring IPv6 ICE candidates 
%s, line %d %s \n", host, i, line);
+continue;
+}
+
 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",
 protocol, i, line, whip->sdp_answer);
@@ -1898,6 +1909,8 @@ static const AVOption options[] = {
 { "authorization",  "The optional Bearer token for WHIP 
Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { .str 
= NULL }, 0,   0, ENC },
 { "cert_file",  "The optional certificate file path for DTLS", 
 OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 
0,   0, ENC },
 { "key_file",   "The optional private key file path for DTLS", 
 OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0, 
  0, ENC },
+{ "whip_flags", "Set flags affecting WHIP connection behavior",
 OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 },   
0, UINT_MAX, ENC, .unit = "flags" },
+{ "ignore_ipv6","(Optional) Ignore any IPv6 ICE candidate",
 0, AV_OPT_TYPE_CONST,  { .i64 = 
WHIP_FLAG_IGNORE_IPV6 },   0, UINT_MAX, ENC, .unit = "flags" },
 { 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/6] avformat/whip: reindent whip options

2025-07-01 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index be6ee9c951..8d1be90f32 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -1904,13 +1904,20 @@ static int whip_check_bitstream(AVFormatContext *s, 
AVStream *st, const AVPacket
 #define OFFSET(x) offsetof(WHIPContext, x)
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-{ "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
handshake.",  OFFSET(handshake_timeout),  AV_OPT_TYPE_INT,{ .i64 = 5000 
},-1, INT_MAX, ENC },
-{ "pkt_size",   "The maximum size, in bytes, of RTP packets that 
send out", OFFSET(pkt_size),   AV_OPT_TYPE_INT,{ .i64 = 1200 },
-1, INT_MAX, ENC },
-{ "authorization",  "The optional Bearer token for WHIP 
Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { .str 
= NULL }, 0,   0, ENC },
-{ "cert_file",  "The optional certificate file path for DTLS", 
 OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 
0,   0, ENC },
-{ "key_file",   "The optional private key file path for DTLS", 
 OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0, 
  0, ENC },
-{ "whip_flags", "Set flags affecting WHIP connection behavior",
 OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 },   
0, UINT_MAX, ENC, .unit = "flags" },
-{ "ignore_ipv6","(Optional) Ignore any IPv6 ICE candidate",
 0, AV_OPT_TYPE_CONST,  { .i64 = 
WHIP_FLAG_IGNORE_IPV6 },   0, UINT_MAX, ENC, .unit = "flags" },
+{ "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
handshake.",  OFFSET(handshake_timeout),
+AV_OPT_TYPE_INT,{ .i64 = 5000 },-1, 
INT_MAX, ENC },
+{ "pkt_size",   "The maximum size, in bytes, of RTP packets that 
send out", OFFSET(pkt_size),
+AV_OPT_TYPE_INT,{ .i64 = 1200 },-1, 
INT_MAX, ENC },
+{ "authorization",  "The optional Bearer token for WHIP 
Authorization", OFFSET(authorization),
+AV_OPT_TYPE_STRING, { .str = NULL },0,
0, ENC },
+{ "cert_file",  "The optional certificate file path for DTLS", 
 OFFSET(cert_file),
+AV_OPT_TYPE_STRING, { .str = NULL },0,
0, ENC },
+{ "key_file",   "The optional private key file path for DTLS", 
 OFFSET(key_file),
+AV_OPT_TYPE_STRING, { .str = NULL },0,
0, ENC },
+{ "whip_flags", "Set flags affecting WHIP connection behavior",
 OFFSET(flags),
+AV_OPT_TYPE_FLAGS,  { .i64 = 0 },   0, 
UINT_MAX, ENC, .unit = "flags" },
+{ "ignore_ipv6","(Optional) Ignore any IPv6 ICE candidate",
   0,
+AV_OPT_TYPE_CONST,  { .i64 = WHIP_FLAG_IGNORE_IPV6 },   0, 
UINT_MAX, ENC, .unit = "flags" },
 { 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 0/6] avformat/whip: avformat/whip: Add NACK and RTX support (depends on ignore_ipv6 patchset)

2025-07-01 Thread Jack Lau
The NACK and RTX implementation depends the ignore_ipv6 patchset 
https://ffmpeg.org/pipermail/ffmpeg-devel/2025-June/345948.html

So send them all in this new patchset.

I want to thank Sergio Garcia Murillo for his help in providing the initial 
simple NACK prototype.
I’ve been improving and testing that patchset until it can really work.
I've been test this patch with Pion, Janus and it works well.

Jack Lau (5):
  avformat/whip: add whip_flags ignore_ipv6 to skip IPv6 ICE candidates
  avformat/whip: reindent whip options
  avformat/whip: fix typos
  avformat/whip: fix H264 profile_iop bit map for SDP
  avformat/whip: implement NACK and RTX suppport

winlin (1):
  WHIP: X509 cert serial number should be positive.

 libavformat/tls_openssl.c |   3 +-
 libavformat/whip.c| 413 --
 2 files changed, 307 insertions(+), 109 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 5/6] WHIP: X509 cert serial number should be positive.

2025-07-01 Thread Jack Lau
From: winlin 

See RFC5280 4.1.2.2

Co-authored-by: winlin 
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2a3905891d..4733faec9c 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -316,7 +316,8 @@ static int openssl_gen_certificate(EVP_PKEY *pkey, X509 
**cert, char **fingerpri
 goto enomem_end;
 }
 
-serial = (int)av_get_random_seed();
+// According to RFC5280 4.1.2.2, The serial number MUST be a positive 
integer
+serial = (int)(av_get_random_seed() & 0x7FFF);
 if (ASN1_INTEGER_set(X509_get_serialNumber(*cert), serial) != 1) {
 av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set serial, %s\n", 
ERR_error_string(ERR_get_error(), NULL));
 goto einval_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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 1/6] avformat/whip: add whip_flags ignore_ipv6 to skip IPv6 ICE candidates

2025-07-02 Thread Jack Lau
mark this ignore_ipv6 flag could ignore any IPv6 ICE candidate,
preventing “No route to host” errors on devices without IPv6 connectivity.

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 5fdbd6949d..42a6b2ec70 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -193,9 +193,14 @@ enum WHIPState {
 WHIP_STATE_FAILED,
 };
 
+typedef enum WHIPFlags {
+WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
+} WHIPFlags;
+
 typedef struct WHIPContext {
 AVClass *av_class;
 
+uint32_t flags;// enum WHIPFlags
 /* The state of the RTC connection. */
 enum WHIPState state;
 /* The callback return value for DTLS. */
@@ -879,6 +884,9 @@ static int parse_answer(AVFormatContext *s)
 if (ptr && av_stristr(ptr, "host")) {
 char protocol[17], host[129];
 int priority, port;
+#if HAVE_STRUCT_SOCKADDR_IN6
+struct in6_addr addr6;
+#endif
 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",
@@ -886,7 +894,12 @@ static int parse_answer(AVFormatContext *s)
 ret = AVERROR(EIO);
 goto end;
 }
-
+#if HAVE_STRUCT_SOCKADDR_IN6
+if (whip->flags & WHIP_FLAG_IGNORE_IPV6 && inet_pton(AF_INET6, 
host, &addr6) == 1) {
+av_log(whip, AV_LOG_DEBUG, "Ignoring IPv6 ICE candidates 
%s, line %d %s \n", host, i, line);
+continue;
+}
+#endif
 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",
 protocol, i, line, whip->sdp_answer);
@@ -1898,6 +1911,8 @@ static const AVOption options[] = {
 { "authorization",  "The optional Bearer token for WHIP 
Authorization", OFFSET(authorization),  AV_OPT_TYPE_STRING, { .str 
= NULL }, 0,   0, ENC },
 { "cert_file",  "The optional certificate file path for DTLS", 
 OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 
0,   0, ENC },
 { "key_file",   "The optional private key file path for DTLS", 
 OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0, 
  0, ENC },
+{ "whip_flags", "Set flags affecting WHIP connection behavior",
 OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 },   
0, UINT_MAX, ENC, .unit = "flags" },
+{ "ignore_ipv6","(Optional) Ignore any IPv6 ICE candidate",
 0, AV_OPT_TYPE_CONST,  { .i64 = 
WHIP_FLAG_IGNORE_IPV6 },   0, UINT_MAX, ENC, .unit = "flags" },
 { 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 0/6] avformat/whip: Add NACK and RTX support (depends on ignore_ipv6 patchset)

2025-07-02 Thread Jack Lau
Version 2 of https://ffmpeg.org/pipermail/ffmpeg-devel/2025-July/346052.html

This patchset fix the following issues:

* every option break into two new lines (now every of them is only one line)
* lack check HAVE_STRUCT_SOCKADDR_IN6 (add this check)
* change the variable name (pkt -> buf) to avoid misunderstanding
* add rtx_history_size option which can set the size of rtp packet history 
buffer

Jack Lau (5):
  avformat/whip: add whip_flags ignore_ipv6 to skip IPv6 ICE candidates
  avformat/whip: fix typos
  avformat/whip: fix H264 profile_iop bit map for SDP
  avformat/whip: implement NACK and RTX suppport
  avformat/whip: reindent whip options

winlin (1):
  WHIP: X509 cert serial number should be positive.

 libavformat/tls_openssl.c |   3 +-
 libavformat/whip.c| 410 --
 2 files changed, 303 insertions(+), 110 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 2/6] avformat/whip: fix typos

2025-07-02 Thread Jack Lau
Remove redundant "WHIP: " prefix in log context
since it already add whip context.

Fix grammers in whip options descriptions

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 152 ++---
 1 file changed, 76 insertions(+), 76 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 42a6b2ec70..932119a1c7 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -364,14 +364,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;
@@ -380,7 +380,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;
 }
@@ -409,7 +409,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;
 }
 
@@ -418,13 +418,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;
@@ -457,7 +457,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);
 }
@@ -471,12 +471,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;
@@ -520,62 +520,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, &quo

[FFmpeg-devel] [PATCH v2 5/6] avformat/whip: implement NACK and RTX suppport

2025-07-02 Thread Jack Lau
RTP retransmission described in RFC4588 (RTX) is an effective packet
loss recovery technique for real-time applications with relaxed delay bounds.

This patch provides a minimal implementation for RTX and RTCP NACK (RFC3940)
and its associated SDP signaling and negotiation.

Co-authored-by: Sergio Garcia Murillo 
Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 198 -
 1 file changed, 195 insertions(+), 3 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index e287a3062f..fa6e3855d3 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -114,6 +114,7 @@
 /* Referring to Chrome's definition of RTP payload types. */
 #define WHIP_RTP_PAYLOAD_TYPE_H264 106
 #define WHIP_RTP_PAYLOAD_TYPE_OPUS 111
+#define WHIP_RTP_PAYLOAD_TYPE_RTX  105
 
 /**
  * The STUN message header, which is 20 bytes long, comprises the
@@ -150,6 +151,11 @@
 #define WHIP_SDP_SESSION_ID "4489045141692799359"
 #define WHIP_SDP_CREATOR_IP "127.0.0.1"
 
+/**
+ * Retransmission / NACK support
+*/
+#define HISTORY_SIZE_DEFAULT 512
+
 /* Calculate the elapsed time from starttime to endtime in milliseconds. */
 #define ELAPSED(starttime, endtime) ((int)(endtime - starttime) / 1000)
 
@@ -194,9 +200,19 @@ enum WHIPState {
 };
 
 typedef enum WHIPFlags {
-WHIP_FLAG_IGNORE_IPV6  = (1 << 0) // Ignore ipv6 candidate
+WHIP_FLAG_IGNORE_IPV6  = (1 << 0), // Ignore ipv6 candidate
+WHIP_FLAG_DISABLE_RTX = (1 << 1)  // Enable NACK and RTX
 } WHIPFlags;
 
+typedef struct RtpHistoryItem {
+/* original RTP seq */
+uint16_t seq;
+/* length in bytes */
+int size;
+/* malloc-ed copy */
+uint8_t* buf;
+} RtpHistoryItem;
+
 typedef struct WHIPContext {
 AVClass *av_class;
 
@@ -285,6 +301,7 @@ typedef struct WHIPContext {
 /* The SRTP send context, to encrypt outgoing packets. */
 SRTPContext srtp_audio_send;
 SRTPContext srtp_video_send;
+SRTPContext srtp_video_rtx_send;
 SRTPContext srtp_rtcp_send;
 /* The SRTP receive context, to decrypt incoming packets. */
 SRTPContext srtp_recv;
@@ -309,6 +326,14 @@ typedef struct WHIPContext {
 /* The certificate and private key used for DTLS handshake. */
 char* cert_file;
 char* key_file;
+
+/* RTX and NACK */
+uint8_t rtx_payload_type;
+uint32_t video_rtx_ssrc;
+uint16_t rtx_seq;
+int  history_size;
+RtpHistoryItem *history;  /* ring buffer  */
+int hist_head;
 } WHIPContext;
 
 /**
@@ -606,6 +631,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 whip->audio_payload_type = WHIP_RTP_PAYLOAD_TYPE_OPUS;
 whip->video_payload_type = WHIP_RTP_PAYLOAD_TYPE_H264;
 
+/* RTX and NACK init */
+whip->rtx_payload_type = WHIP_RTP_PAYLOAD_TYPE_RTX;
+whip->video_rtx_ssrc = av_lfg_get(&whip->rnd);
+whip->rtx_seq = 0;
+whip->hist_head = 0;
+whip->history_size = FFMAX(64, whip->history_size);
+whip->history = av_calloc(whip->history_size, sizeof(*whip->history));
+if (!whip->history)
+return AVERROR(ENOMEM);
+
 av_bprintf(&bp, ""
 "v=0\r\n"
 "o=FFmpeg %s 2 IN IP4 %s\r\n"
@@ -656,7 +691,7 @@ static int generate_sdp_offer(AVFormatContext *s)
 }
 
 av_bprintf(&bp, ""
-"m=video 9 UDP/TLS/RTP/SAVPF %u\r\n"
+"m=video 9 UDP/TLS/RTP/SAVPF %u %u\r\n"
 "c=IN IP4 0.0.0.0\r\n"
 "a=ice-ufrag:%s\r\n"
 "a=ice-pwd:%s\r\n"
@@ -669,9 +704,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 "a=rtcp-rsize\r\n"
 "a=rtpmap:%u %s/9\r\n"
 "a=fmtp:%u 
level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=%02x%02x%02x\r\n"
+"a=rtcp-fb:%u nack\r\n"
+"a=rtpmap:%u rtx/9\r\n"
+"a=fmtp:%u apt=%u\r\n"
+"a=ssrc-group:FID %u %u\r\n"
+"a=ssrc:%u cname:FFmpeg\r\n"
+"a=ssrc:%u msid:FFmpeg video\r\n"
 "a=ssrc:%u cname:FFmpeg\r\n"
 "a=ssrc:%u msid:FFmpeg video\r\n",
 whip->video_payload_type,
+whip->rtx_payload_type,
 whip->ice_ufrag_local,
 whip->ice_pwd_local,
 whip->dtls_fingerprint,
@@ -681,8 +723,16 @@ static int generate_sdp_offer(AVFormatContext *s)
 profile,
 whip->constraint_set_flags,
 level,
+whip->video_payload_type,
+whip->rtx_payload_type,
+whip->rtx_payload_type,
+whip->video_payload_type,
+whip->video_ssrc,
+whip->video_rtx_ssrc,
 whip->video_ssrc,
- 

[FFmpeg-devel] [PATCH v2 6/6] avformat/whip: reindent whip options

2025-07-02 Thread Jack Lau
Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index fa6e3855d3..0c44ef6c73 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -2081,13 +2081,13 @@ static int whip_check_bitstream(AVFormatContext *s, 
AVStream *st, const AVPacket
 #define OFFSET(x) offsetof(WHIPContext, x)
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-{ "handshake_timeout",  "Timeout in milliseconds for ICE and DTLS 
handshake.",  OFFSET(handshake_timeout),  AV_OPT_TYPE_INT,{ .i64 = 5000 
},-1, INT_MAX, ENC },
-{ "pkt_size",   "The maximum size, in bytes, of RTP packets that 
send out", OFFSET(pkt_size),   AV_OPT_TYPE_INT,{ .i64 = 1200 },
-1, INT_MAX, ENC },
-{ "authorization",  "Optional Bearer token for WHIP Authorization",
 OFFSET(authorization),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,
   0, ENC },
-{ "cert_file",  "Optional certificate file path for DTLS", 
 OFFSET(cert_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,
   0, ENC },
-{ "key_file",   "Optional private key file path for DTLS", 
 OFFSET(key_file),  AV_OPT_TYPE_STRING, { .str = NULL }, 0,   
0, ENC },
-{ "whip_flags", "Set flags affecting WHIP connection behavior",
 OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 },   
0, UINT_MAX, ENC, .unit = "flags" },
-{ "ignore_ipv6","Ignore any IPv6 ICE candidate", 
0, AV_OPT_TYPE_CONST,  { .i64 = WHIP_FLAG_IGNORE_IPV6 },
   0, UINT_MAX, ENC, .unit = "flags" },
+{ "handshake_timeout", "Timeout in milliseconds for ICE and DTLS 
handshake.", OFFSET(handshake_timeout), AV_OPT_TYPE_INT,  { .i64 = 5000 }, -1, 
INT_MAX, ENC },
+{ "pkt_size", "The maximum size, in bytes, of RTP packets that send out", 
OFFSET(pkt_size), AV_OPT_TYPE_INT,  { .i64 = 1200 }, -1, INT_MAX, ENC },
+{ "authorization", "Optional Bearer token for WHIP Authorization", 
OFFSET(authorization), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
+{ "cert_file", "Optional certificate file path for DTLS", 
OFFSET(cert_file), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
+{ "key_file", "Optional private key file path for DTLS", OFFSET(key_file), 
AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC },
+{ "whip_flags", "Set flags affecting WHIP connection behavior", 
OFFSET(flags), AV_OPT_TYPE_FLAGS,  { .i64 = 0 }, 0, 0, ENC, .unit = "flags" },
+{ "ignore_ipv6", "Ignore any IPv6 ICE candidate", 0, AV_OPT_TYPE_CONST,  { 
.i64 = WHIP_FLAG_IGNORE_IPV6 }, 0, UINT_MAX, ENC, .unit = "flags" },
 { "disable_rtx", "Disable RFC 4588 RTX", 0, AV_OPT_TYPE_CONST,  { .i64 = 
WHIP_FLAG_DISABLE_RTX }, 0, UINT_MAX, ENC, .unit = "flags" },
 { "rtx_history_size", "Packet history size", OFFSET(history_size), 
AV_OPT_TYPE_INT, { .i64 = HISTORY_SIZE_DEFAULT }, 64, 2048, ENC },
 { 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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 3/6] avformat/whip: fix H264 profile_iop bit map for SDP

2025-07-02 Thread Jack Lau
AVCodecParameters::profile only contains constraint_set1_flag
(AV_PROFILE_H264_CONSTRAINED 1<<9).
So add H264 constraints flag fully parse refer to hlsenc
write_codec_attr

Signed-off-by: Jack Lau 
---
 libavformat/whip.c | 47 --
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/libavformat/whip.c b/libavformat/whip.c
index 932119a1c7..e287a3062f 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -210,6 +210,7 @@ typedef struct WHIPContext {
 /* Parameters for the input audio and video codecs. */
 AVCodecParameters *audio_par;
 AVCodecParameters *video_par;
+uint8_t constraint_set_flags;
 
 /**
  * The h264_mp4toannexb Bitstream Filter (BSF) bypasses the AnnexB packet;
@@ -445,45 +446,30 @@ static av_cold int initialize(AVFormatContext *s)
 static int parse_profile_level(AVFormatContext *s, AVCodecParameters *par)
 {
 int ret = 0;
-const uint8_t *r = par->extradata, *r1, *end = par->extradata + 
par->extradata_size;
-H264SPS seq, *const sps = &seq;
-uint32_t state;
+const uint8_t *r = par->extradata;
 WHIPContext *whip = s->priv_data;
 
 if (par->codec_id != AV_CODEC_ID_H264)
 return ret;
 
-if (par->profile != AV_PROFILE_UNKNOWN && par->level != AV_LEVEL_UNKNOWN)
-return ret;
-
 if (!par->extradata || par->extradata_size <= 0) {
 av_log(whip, AV_LOG_ERROR, "Unable to parse profile from empty 
extradata=%p, size=%d\n",
 par->extradata, par->extradata_size);
 return AVERROR(EINVAL);
 }
 
-while (1) {
-r = avpriv_find_start_code(r, end, &state);
-if (r >= end)
-break;
-
-r1 = ff_nal_find_startcode(r, end);
-if ((state & 0x1f) == H264_NAL_SPS) {
-ret = ff_avc_decode_sps(sps, r, r1 - r);
-if (ret < 0) {
-av_log(whip, AV_LOG_ERROR, "Failed to decode SPS, state=%x, 
size=%d\n",
-state, (int)(r1 - r));
-return ret;
-}
-
-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;
-}
+if (AV_RB32(r) == 0x0001 && (r[4] & 0x1F) == 7)
+r = &r[5];
+else if (AV_RB24(r) == 0x01 && (r[3] & 0x1F) == 7)
+r = &r[4];
+else if (r[0] == 0x01)  // avcC
+r = &r[1];
+else
+return AVERROR(EINVAL);
 
-r = r1;
-}
+if (par->profile == AV_PROFILE_UNKNOWN) par->profile = r[0];
+whip->constraint_set_flags = r[1];
+if (par->level == AV_LEVEL_UNKNOWN) par->level = r[2];
 
 return ret;
 }
@@ -594,7 +580,7 @@ static int parse_codec(AVFormatContext *s)
  */
 static int generate_sdp_offer(AVFormatContext *s)
 {
-int ret = 0, profile, level, profile_iop;
+int ret = 0, profile, level;
 const char *acodec_name = NULL, *vcodec_name = NULL;
 AVBPrint bp;
 WHIPContext *whip = s->priv_data;
@@ -662,11 +648,10 @@ static int generate_sdp_offer(AVFormatContext *s)
 }
 
 if (whip->video_par) {
-profile_iop = profile = whip->video_par->profile;
+profile = whip->video_par->profile;
 level = whip->video_par->level;
 if (whip->video_par->codec_id == AV_CODEC_ID_H264) {
 vcodec_name = "H264";
-profile_iop &= AV_PROFILE_H264_CONSTRAINED;
 profile &= (~AV_PROFILE_H264_CONSTRAINED);
 }
 
@@ -694,7 +679,7 @@ static int generate_sdp_offer(AVFormatContext *s)
 vcodec_name,
 whip->video_payload_type,
 profile,
-profile_iop,
+whip->constraint_set_flags,
 level,
 whip->video_ssrc,
 whip->video_ssrc);
-- 
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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 4/6] WHIP: X509 cert serial number should be positive.

2025-07-02 Thread Jack Lau
From: winlin 

See RFC5280 4.1.2.2

Co-authored-by: winlin 
Signed-off-by: Jack Lau 
---
 libavformat/tls_openssl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 2a3905891d..4733faec9c 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -316,7 +316,8 @@ static int openssl_gen_certificate(EVP_PKEY *pkey, X509 
**cert, char **fingerpri
 goto enomem_end;
 }
 
-serial = (int)av_get_random_seed();
+// According to RFC5280 4.1.2.2, The serial number MUST be a positive 
integer
+serial = (int)(av_get_random_seed() & 0x7FFF);
 if (ASN1_INTEGER_set(X509_get_serialNumber(*cert), serial) != 1) {
 av_log(NULL, AV_LOG_ERROR, "TLS: Failed to set serial, %s\n", 
ERR_error_string(ERR_get_error(), NULL));
 goto einval_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-requ...@ffmpeg.org with subject "unsubscribe".


  1   2   >