Re: [FFmpeg-devel] [RFC] Release 6.1

2023-07-07 Thread Steven Liu
Lynne  于2023年7月7日周五 14:40写道:
>
> Jul 6, 2023, 18:19 by j...@videolan.org:
>
> > Heya,
> >
> > On Thu, 6 Jul 2023, at 18:04, Lynne wrote:
> >
> >> It's been a while since we've had a release, and we've had
> >> a lot of new features in.
> >> We did say we would make releases more often, and I think
> >> it's about time we have a new release.
> >>
> >
> > It's a good idea.
> >
> >> Anything anyone wants to have merged or should we branch
> >> off 6.1 in a few days?
> >>
> >
> > By experience, it requires a bit more than a few days... :D
> >
>
> May as well decide on a name in the meanwhile.
> Anyone got any suggestions?

Ting
https://en.wikipedia.org/wiki/Samuel_C._C._Ting

> ___
> 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/hlsenc: fall back to av_get_random_seed() when generating AES128 key

2023-07-07 Thread Anton Khirnov
Quoting Michael Niedermayer (2023-07-07 02:55:46)
> 
> The litteral wording was
> "that guarantees either cryptographically secure randomness or an error."
> 
> that was what i refered to.
> 
> the wording used now:
> "to the best of our ability, and that of the underlying libraries we rely on) 
> cryptographically secure."
> 
> is perfectly fine with me.
> I would have the same issue if someone said AES gurantees ...

IMO the two formulations are equivalent whenever it comes to practical
computing. An algorithm can be mathematically proven to be sound*, but
any practical computing scheme on actual hardware is always subject to
software bugs, system misconfiguration, hardware bugs, hardware failure,
etc.

We use similar wording in other documentation, where e.g. we might
guarantee that some function returns a NULL-terminated string or so.
That guarantee is always under the implicit condition that there are no
bugs and the code runs in the expected environment. The same
considerations apply here.

* assuming there are no bugs in your proof

-- 
Anton Khirnov
___
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 02/22] lavc/encode: shorten code by using a local variable

2023-07-07 Thread Anton Khirnov
---
 libavcodec/encode.c | 48 +++--
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 2da9f6ba23..0d44f70ee9 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -550,6 +550,7 @@ int attribute_align_arg 
avcodec_receive_packet(AVCodecContext *avctx, AVPacket *
 
 static int encode_preinit_video(AVCodecContext *avctx)
 {
+const AVCodec *c = avctx->codec;
 const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(avctx->pix_fmt);
 int i;
 
@@ -559,20 +560,20 @@ static int encode_preinit_video(AVCodecContext *avctx)
 return AVERROR(EINVAL);
 }
 
-if (avctx->codec->pix_fmts) {
-for (i = 0; avctx->codec->pix_fmts[i] != AV_PIX_FMT_NONE; i++)
-if (avctx->pix_fmt == avctx->codec->pix_fmts[i])
+if (c->pix_fmts) {
+for (i = 0; c->pix_fmts[i] != AV_PIX_FMT_NONE; i++)
+if (avctx->pix_fmt == c->pix_fmts[i])
 break;
-if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE) {
+if (c->pix_fmts[i] == AV_PIX_FMT_NONE) {
 av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is not 
supported\n",
av_get_pix_fmt_name(avctx->pix_fmt));
 return AVERROR(EINVAL);
 }
-if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
-avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
-avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
-avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
-avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
+if (c->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
+c->pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
+c->pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
+c->pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
+c->pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
 avctx->color_range = AVCOL_RANGE_JPEG;
 }
 
@@ -625,6 +626,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
 static int encode_preinit_audio(AVCodecContext *avctx)
 {
+const AVCodec *c = avctx->codec;
 int i;
 
 if (!av_get_sample_fmt_name(avctx->sample_fmt)) {
@@ -633,28 +635,28 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 return AVERROR(EINVAL);
 }
 
-if (avctx->codec->sample_fmts) {
-for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
-if (avctx->sample_fmt == avctx->codec->sample_fmts[i])
+if (c->sample_fmts) {
+for (i = 0; c->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
+if (avctx->sample_fmt == c->sample_fmts[i])
 break;
 if (avctx->ch_layout.nb_channels == 1 &&
 av_get_planar_sample_fmt(avctx->sample_fmt) ==
-av_get_planar_sample_fmt(avctx->codec->sample_fmts[i])) {
-avctx->sample_fmt = avctx->codec->sample_fmts[i];
+av_get_planar_sample_fmt(c->sample_fmts[i])) {
+avctx->sample_fmt = c->sample_fmts[i];
 break;
 }
 }
-if (avctx->codec->sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
+if (c->sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
 av_log(avctx, AV_LOG_ERROR, "Specified sample format %s is not 
supported\n",
av_get_sample_fmt_name(avctx->sample_fmt));
 return AVERROR(EINVAL);
 }
 }
-if (avctx->codec->supported_samplerates) {
-for (i = 0; avctx->codec->supported_samplerates[i] != 0; i++)
-if (avctx->sample_rate == avctx->codec->supported_samplerates[i])
+if (c->supported_samplerates) {
+for (i = 0; c->supported_samplerates[i] != 0; i++)
+if (avctx->sample_rate == c->supported_samplerates[i])
 break;
-if (avctx->codec->supported_samplerates[i] == 0) {
+if (c->supported_samplerates[i] == 0) {
 av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not 
supported\n",
avctx->sample_rate);
 return AVERROR(EINVAL);
@@ -665,12 +667,12 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 avctx->sample_rate);
 return AVERROR(EINVAL);
 }
-if (avctx->codec->ch_layouts) {
-for (i = 0; avctx->codec->ch_layouts[i].nb_channels; i++) {
-if (!av_channel_layout_compare(&avctx->ch_layout, 
&avctx->codec->ch_layouts[i]))
+if (c->ch_layouts) {
+for (i = 0; c->ch_layouts[i].nb_channels; i++) {
+if (!av_channel_layout_compare(&avctx->ch_layout, 
&c->ch_layouts[i]))
 break;
 }
-if (!avctx->codec->ch_layouts[i].nb_channels) {
+if (!c->ch_layouts[i].nb_channels) {
 char buf[512];
 int ret = av_channel_layout_describe(&avctx->ch_layout, buf, 
sizeof(buf));
 if (ret > 0)
-- 
2.40.1

___
ffmpeg-devel mailing list
ffmpeg-dev

[FFmpeg-devel] [PATCH 03/22] lavc/encoder: always print an error on an unsupported channel layout

2023-07-07 Thread Anton Khirnov
Even if the layout is indescribable.
---
 libavcodec/encode.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 0d44f70ee9..ba91dcc31e 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -675,8 +675,8 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 if (!c->ch_layouts[i].nb_channels) {
 char buf[512];
 int ret = av_channel_layout_describe(&avctx->ch_layout, buf, 
sizeof(buf));
-if (ret > 0)
-av_log(avctx, AV_LOG_ERROR, "Specified channel layout '%s' is 
not supported\n", buf);
+av_log(avctx, AV_LOG_ERROR, "Specified channel layout '%s' is not 
supported\n",
+   ret > 0 ? buf : "?");
 return AVERROR(EINVAL);
 }
 }
-- 
2.40.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] [PATCH 04/22] lavc/encode: improve input sample rate validation

2023-07-07 Thread Anton Khirnov
Reject zero sample rates in addition to negative ones and describe them
as 'invalid' rather than 'unsupported'.
---
 libavcodec/encode.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index ba91dcc31e..9a279d9842 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -634,6 +634,11 @@ static int encode_preinit_audio(AVCodecContext *avctx)
avctx->sample_fmt);
 return AVERROR(EINVAL);
 }
+if (avctx->sample_rate <= 0) {
+av_log(avctx, AV_LOG_ERROR, "Invalid audio sample rate: %d\n",
+   avctx->sample_rate);
+return AVERROR(EINVAL);
+}
 
 if (c->sample_fmts) {
 for (i = 0; c->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
@@ -662,11 +667,6 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 return AVERROR(EINVAL);
 }
 }
-if (avctx->sample_rate < 0) {
-av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not 
supported\n",
-avctx->sample_rate);
-return AVERROR(EINVAL);
-}
 if (c->ch_layouts) {
 for (i = 0; c->ch_layouts[i].nb_channels; i++) {
 if (!av_channel_layout_compare(&avctx->ch_layout, 
&c->ch_layouts[i]))
-- 
2.40.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] [PATCH 01/22] lavc/encode: print separate messages for unknown and unsupported formats

2023-07-07 Thread Anton Khirnov
The former is typically a bug in the calling program, while the latter
will more often be a user configuration issue.
---
 libavcodec/encode.c | 25 +
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index ab5f889615..2da9f6ba23 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -24,6 +24,7 @@
 #include "libavutil/frame.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
+#include "libavutil/pixdesc.h"
 #include "libavutil/samplefmt.h"
 
 #include "avcodec.h"
@@ -552,15 +553,19 @@ static int encode_preinit_video(AVCodecContext *avctx)
 const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(avctx->pix_fmt);
 int i;
 
+if (!av_get_pix_fmt_name(avctx->pix_fmt)) {
+av_log(avctx, AV_LOG_ERROR, "Invalid video pixel format: %d\n",
+   avctx->pix_fmt);
+return AVERROR(EINVAL);
+}
+
 if (avctx->codec->pix_fmts) {
 for (i = 0; avctx->codec->pix_fmts[i] != AV_PIX_FMT_NONE; i++)
 if (avctx->pix_fmt == avctx->codec->pix_fmts[i])
 break;
 if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE) {
-char buf[128];
-snprintf(buf, sizeof(buf), "%d", avctx->pix_fmt);
-av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is invalid 
or not supported\n",
-   (char *)av_x_if_null(av_get_pix_fmt_name(avctx->pix_fmt), 
buf));
+av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is not 
supported\n",
+   av_get_pix_fmt_name(avctx->pix_fmt));
 return AVERROR(EINVAL);
 }
 if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
@@ -622,6 +627,12 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 {
 int i;
 
+if (!av_get_sample_fmt_name(avctx->sample_fmt)) {
+av_log(avctx, AV_LOG_ERROR, "Invalid audio sample format: %d\n",
+   avctx->sample_fmt);
+return AVERROR(EINVAL);
+}
+
 if (avctx->codec->sample_fmts) {
 for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
 if (avctx->sample_fmt == avctx->codec->sample_fmts[i])
@@ -634,10 +645,8 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 }
 }
 if (avctx->codec->sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
-char buf[128];
-snprintf(buf, sizeof(buf), "%d", avctx->sample_fmt);
-av_log(avctx, AV_LOG_ERROR, "Specified sample format %s is invalid 
or not supported\n",
-   (char 
*)av_x_if_null(av_get_sample_fmt_name(avctx->sample_fmt), buf));
+av_log(avctx, AV_LOG_ERROR, "Specified sample format %s is not 
supported\n",
+   av_get_sample_fmt_name(avctx->sample_fmt));
 return AVERROR(EINVAL);
 }
 }
-- 
2.40.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] [PATCH 06/22] lavfi: make sure frame SAR matches the link value

2023-07-07 Thread Anton Khirnov
---
 libavfilter/avfilter.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 0141b64cbc..04887b6ee5 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -984,6 +984,8 @@ int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
 av_assert1(frame->width   == link->w);
 av_assert1(frame->height   == link->h);
 }
+
+frame->sample_aspect_ratio = link->sample_aspect_ratio;
 } else {
 if (frame->format != link->format) {
 av_log(link->dst, AV_LOG_ERROR, "Format change is not 
supported\n");
-- 
2.40.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] [PATCH 07/22] fftools/ffmpeg_filter: make sure no input or output is bound twice

2023-07-07 Thread Anton Khirnov
---
 fftools/ffmpeg_filter.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 60e09866af..432e2fced9 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -595,6 +595,8 @@ static int ifilter_bind_ist(InputFilter *ifilter, 
InputStream *ist)
 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
 int ret;
 
+av_assert0(!ifp->ist);
+
 ifp->ist = ist;
 ifp->type_src= ist->st->codecpar->codec_type;
 
@@ -654,6 +656,8 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost)
 FilterGraph  *fg = ofilter->graph;
 const AVCodec *c = ost->enc_ctx->codec;
 
+av_assert0(!ofilter->ost);
+
 ofilter->ost = ost;
 av_freep(&ofilter->linklabel);
 
-- 
2.40.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] [PATCH 22/22] doc/ffmpeg: fix -enc_time_base documentation

2023-07-07 Thread Anton Khirnov
Stop claiming the argument is always a floating point number, which
* confuses floating point and decimal numbers
* is not always true even accounting for the above point
---
 doc/ffmpeg.texi | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 59e9fbfcb2..2273c39214 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -1803,8 +1803,7 @@ Try to make the choice automatically, in order to 
generate a sane output.
 Default value is -1.
 
 @item -enc_time_base[:@var{stream_specifier}] @var{timebase} 
(@emph{output,per-stream})
-Set the encoder timebase. @var{timebase} is a floating point number,
-and can assume one of the following values:
+Set the encoder timebase. @var{timebase} can assume one of the following 
values:
 
 @table @option
 @item 0
@@ -1818,11 +1817,11 @@ Use the timebase from the demuxer.
 @item filter
 Use the timebase from the filtergraph.
 
-@item >0
+@item a positive number
 Use the provided number as the timebase.
 
 This field can be provided as a ratio of two integers (e.g. 1:24, 1:48000)
-or as a floating point number (e.g. 0.04166, 2.0833e-5)
+or as a decimal number (e.g. 0.04166, 2.0833e-5)
 @end table
 
 Default value is 0.
-- 
2.40.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] [PATCH 16/22] fftools/ffmpeg: rework initializing encoders with no frames

2023-07-07 Thread Anton Khirnov
When no frames were passed from a filtergraph to an encoder, but the
filtergraph is configured (i.e. has output parameters), encoder flush
code will use those parameters to initialize the encoder in a last-ditch
effort to produce some useful output.

Rework this process so that it is triggered by the filtergraph, which
now sends a dummy frame with parameters, but no data, to the encoder,
rather than the encoder reaching backwards into the filter.

This approach is more in line with the natural data flow from filters to
encoders and will allow to reduce encoder-filter interactions in
following commits.

This code is tested by fate-adpcm-ima-cunning-trunc-t2-track1, which (as
confirmed by Zane) is supposed to produce empty output.
---
 fftools/ffmpeg_enc.c| 22 ++---
 fftools/ffmpeg_filter.c | 54 ++---
 2 files changed, 52 insertions(+), 24 deletions(-)

diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 4029501313..dd056e42f5 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -1142,26 +1142,8 @@ void enc_flush(void)
 AVCodecContext *enc = ost->enc_ctx;
 OutputFile  *of = output_files[ost->file_index];
 
-if (!enc)
-continue;
-
-// Try to enable encoding with no input frames.
-// Maybe we should just let encoding fail instead.
-if (!e->opened) {
-FilterGraph *fg = ost->filter->graph;
-
-av_log(ost, AV_LOG_WARNING,
-   "Finishing stream without any data written to it.\n");
-
-if (!fg->graph)
-continue;
-
-ret = enc_open(ost, NULL);
-if (ret < 0)
-exit_program(1);
-}
-
-if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != 
AVMEDIA_TYPE_AUDIO)
+if (!enc || !e->opened ||
+(enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != 
AVMEDIA_TYPE_AUDIO))
 continue;
 
 ret = submit_encode_frame(of, ost, NULL);
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 67a5f48245..f8e64ce6cc 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -143,11 +143,17 @@ typedef struct OutputFilterPriv {
 int sample_rate;
 AVChannelLayout ch_layout;
 
+AVRational time_base;
+AVRational sample_aspect_ratio;
+
 // those are only set if no format is specified and the encoder gives us 
multiple options
 // They point directly to the relevant lists of the encoder.
 const int *formats;
 const AVChannelLayout *ch_layouts;
 const int *sample_rates;
+
+// set to 1 after at least one frame passed through this output
+int got_frame;
 } OutputFilterPriv;
 
 static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter)
@@ -1576,6 +1582,9 @@ static int configure_filtergraph(FilterGraph *fg)
 ofp->width  = av_buffersink_get_w(sink);
 ofp->height = av_buffersink_get_h(sink);
 
+ofp->time_base   = av_buffersink_get_time_base(sink);
+ofp->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink);
+
 ofp->sample_rate= av_buffersink_get_sample_rate(sink);
 av_channel_layout_uninit(&ofp->ch_layout);
 ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
@@ -1688,6 +1697,7 @@ int reap_filters(int flush)
 {
 /* Reap all buffers present in the buffer sinks */
 for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
+OutputFilterPriv *ofp;
 FilterGraphPriv *fgp;
 AVFrame *filtered_frame;
 AVFilterContext *filter;
@@ -1697,6 +1707,7 @@ int reap_filters(int flush)
 continue;
 filter = ost->filter->filter;
 fgp= fgp_from_fg(ost->filter->graph);
+ofp= ofp_from_ofilter(ost->filter);
 
 filtered_frame = fgp->frame;
 
@@ -1749,6 +1760,7 @@ int reap_filters(int flush)
 
 enc_frame(ost, filtered_frame);
 av_frame_unref(filtered_frame);
+ofp->got_frame = 1;
 }
 }
 
@@ -1961,6 +1973,7 @@ int ifilter_send_frame(InputFilter *ifilter, AVFrame 
*frame, int keep_reference)
 
 int fg_transcode_step(FilterGraph *graph, InputStream **best_ist)
 {
+FilterGraphPriv *fgp = fgp_from_fg(graph);
 int i, ret;
 int nb_requests, nb_requests_max = 0;
 InputStream *ist;
@@ -1988,10 +2001,43 @@ int fg_transcode_step(FilterGraph *graph, InputStream 
**best_ist)
 return reap_filters(0);
 
 if (ret == AVERROR_EOF) {
-ret = reap_filters(1);
-for (i = 0; i < graph->nb_outputs; i++)
-close_output_stream(graph->outputs[i]->ost);
-return ret;
+reap_filters(1);
+for (int i = 0; i < graph->nb_outputs; i++) {
+OutputFilter *ofilter = graph->outputs[i];
+OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
+
+// we are finished and no frames were ever seen at this outp

[FFmpeg-devel] [PATCH 19/22] fftools/ffmpeg_filter: make OutputFilter.filter private

2023-07-07 Thread Anton Khirnov
It should not be accessed from outside of filtering code.
---
 fftools/ffmpeg.h|  1 -
 fftools/ffmpeg_filter.c | 18 ++
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 3201163a4f..abea424486 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -283,7 +283,6 @@ typedef struct InputFilter {
 } InputFilter;
 
 typedef struct OutputFilter {
-AVFilterContext *filter;
 struct OutputStream *ost;
 struct FilterGraph  *graph;
 uint8_t *name;
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 4955fe38dd..e14b8f0f3c 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -137,6 +137,8 @@ static InputFilterPriv *ifp_from_ifilter(InputFilter 
*ifilter)
 typedef struct OutputFilterPriv {
 OutputFilterofilter;
 
+AVFilterContext*filter;
+
 /* desired output stream properties */
 int format;
 int width, height;
@@ -1060,7 +1062,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 char name[255];
 
 snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
-ret = avfilter_graph_create_filter(&ofilter->filter,
+ret = avfilter_graph_create_filter(&ofp->filter,
avfilter_get_by_name("buffersink"),
name, NULL, NULL, fg->graph);
 
@@ -1116,7 +1118,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 return ret;
 
 
-if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
+if ((ret = avfilter_link(last_filter, pad_idx, ofp->filter, 0)) < 0)
 return ret;
 
 return 0;
@@ -1134,12 +1136,12 @@ static int configure_output_audio_filter(FilterGraph 
*fg, OutputFilter *ofilter,
 int ret;
 
 snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
-ret = avfilter_graph_create_filter(&ofilter->filter,
+ret = avfilter_graph_create_filter(&ofp->filter,
avfilter_get_by_name("abuffersink"),
name, NULL, NULL, fg->graph);
 if (ret < 0)
 return ret;
-if ((ret = av_opt_set_int(ofilter->filter, "all_channel_counts", 1, 
AV_OPT_SEARCH_CHILDREN)) < 0)
+if ((ret = av_opt_set_int(ofp->filter, "all_channel_counts", 1, 
AV_OPT_SEARCH_CHILDREN)) < 0)
 return ret;
 
 #define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
@@ -1222,7 +1224,7 @@ static int configure_output_audio_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 if (ret < 0)
 goto fail;
 
-if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
+if ((ret = avfilter_link(last_filter, pad_idx, ofp->filter, 0)) < 0)
 goto fail;
 fail:
 av_bprint_finalize(&args, NULL);
@@ -1470,7 +1472,7 @@ static void cleanup_filtergraph(FilterGraph *fg)
 {
 int i;
 for (i = 0; i < fg->nb_outputs; i++)
-fg->outputs[i]->filter = (AVFilterContext *)NULL;
+ofp_from_ofilter(fg->outputs[i])->filter = NULL;
 for (i = 0; i < fg->nb_inputs; i++)
 ifp_from_ifilter(fg->inputs[i])->filter = NULL;
 avfilter_graph_free(&fg->graph);
@@ -1575,7 +1577,7 @@ static int configure_filtergraph(FilterGraph *fg)
 for (i = 0; i < fg->nb_outputs; i++) {
 OutputFilter *ofilter = fg->outputs[i];
 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
-AVFilterContext *sink = ofilter->filter;
+AVFilterContext *sink = ofp->filter;
 
 ofp->format = av_buffersink_get_format(sink);
 
@@ -1705,9 +1707,9 @@ int reap_filters(int flush)
 
 if (!ost->filter || !ost->filter->graph->graph)
 continue;
-filter = ost->filter->filter;
 fgp= fgp_from_fg(ost->filter->graph);
 ofp= ofp_from_ofilter(ost->filter);
+filter = ofp->filter;
 
 filtered_frame = fgp->frame;
 
-- 
2.40.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] [PATCH 10/22] fftools/ffmpeg_filter: make OutputFile.width, height private

2023-07-07 Thread Anton Khirnov
They are not used outside of the filtering code.
---
 fftools/ffmpeg.h|  3 ---
 fftools/ffmpeg_filter.c | 14 --
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index b789233a08..79f3f35b3a 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -294,9 +294,6 @@ typedef struct OutputFilter {
 
 enum AVMediaType type;
 
-/* desired output stream properties */
-int width, height;
-
 // those are only set if no format is specified and the encoder gives us 
multiple options
 // They point directly to the relevant lists of the encoder.
 const int *formats;
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 0272b0a96b..0874187f3e 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -138,6 +138,7 @@ typedef struct OutputFilterPriv {
 
 /* desired output stream properties */
 int format;
+int width, height;
 int sample_rate;
 AVChannelLayout ch_layout;
 } OutputFilterPriv;
@@ -683,8 +684,8 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost)
 
 switch (ost->enc_ctx->codec_type) {
 case AVMEDIA_TYPE_VIDEO:
-ofilter->width  = ost->enc_ctx->width;
-ofilter->height = ost->enc_ctx->height;
+ofp->width  = ost->enc_ctx->width;
+ofp->height = ost->enc_ctx->height;
 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
 ofp->format = ost->enc_ctx->pix_fmt;
 } else {
@@ -1068,6 +1069,7 @@ static int insert_filter(AVFilterContext **last_filter, 
int *pad_idx,
 
 static int configure_output_video_filter(FilterGraph *fg, OutputFilter 
*ofilter, AVFilterInOut *out)
 {
+OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 OutputStream *ost = ofilter->ost;
 OutputFile*of = output_files[ost->file_index];
 AVFilterContext *last_filter = out->filter_ctx;
@@ -1085,13 +1087,13 @@ static int configure_output_video_filter(FilterGraph 
*fg, OutputFilter *ofilter,
 if (ret < 0)
 return ret;
 
-if ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) {
+if ((ofp->width || ofp->height) && ofilter->ost->autoscale) {
 char args[255];
 AVFilterContext *filter;
 const AVDictionaryEntry *e = NULL;
 
 snprintf(args, sizeof(args), "%d:%d",
- ofilter->width, ofilter->height);
+ ofp->width, ofp->height);
 
 while ((e = av_dict_iterate(ost->sws_dict, e))) {
 av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
@@ -1596,8 +1598,8 @@ static int configure_filtergraph(FilterGraph *fg)
 
 ofp->format = av_buffersink_get_format(sink);
 
-ofilter->width  = av_buffersink_get_w(sink);
-ofilter->height = av_buffersink_get_h(sink);
+ofp->width  = av_buffersink_get_w(sink);
+ofp->height = av_buffersink_get_h(sink);
 
 ofp->sample_rate= av_buffersink_get_sample_rate(sink);
 av_channel_layout_uninit(&ofp->ch_layout);
-- 
2.40.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] [PATCH 12/22] fftools/ffmpeg_filter: consolidate calling avfilter_graph_set_auto_convert()

2023-07-07 Thread Anton Khirnov
Do not call it from choose_pix_fmts(), as that function is not supposed
to modify random filtergraph properties.
---
 fftools/ffmpeg_filter.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index f60d1cd23b..caf85194c5 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -48,6 +48,7 @@ typedef struct FilterGraphPriv {
 // true when the filtergraph contains only meta filters
 // that do not modify the frame data
 int is_meta;
+int disable_conversions;
 
 const char *graph_desc;
 
@@ -321,8 +322,6 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, 
AVBPrint *bprint)
 av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0);
 
  if (ost->keep_pix_fmt) {
-avfilter_graph_set_auto_convert(ofilter->graph->graph,
-AVFILTER_AUTO_CONVERT_NONE);
 if (ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE)
 return NULL;
 return av_get_pix_fmt_name(ost->enc_ctx->pix_fmt);
@@ -679,6 +678,7 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost)
 {
 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 FilterGraph  *fg = ofilter->graph;
+FilterGraphPriv *fgp = fgp_from_fg(fg);
 const AVCodec *c = ost->enc_ctx->codec;
 
 av_assert0(!ofilter->ost);
@@ -695,6 +695,9 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost)
 } else {
 ofp->formats = c->pix_fmts;
 }
+
+fgp->disable_conversions |= ost->keep_pix_fmt;
+
 break;
 case AVMEDIA_TYPE_AUDIO:
 if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
@@ -830,6 +833,7 @@ FilterGraph *fg_create(char *graph_desc)
 fg->class   = &fg_class;
 fg->index  = nb_filtergraphs - 1;
 fgp->graph_desc = graph_desc;
+fgp->disable_conversions = !auto_conversion_filters;
 
 snprintf(fgp->log_name, sizeof(fgp->log_name), "fc#%d", fg->index);
 
@@ -1587,7 +1591,7 @@ static int configure_filtergraph(FilterGraph *fg)
 configure_output_filter(fg, fg->outputs[i], cur);
 avfilter_inout_free(&outputs);
 
-if (!auto_conversion_filters)
+if (fgp->disable_conversions)
 avfilter_graph_set_auto_convert(fg->graph, AVFILTER_AUTO_CONVERT_NONE);
 if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
 goto fail;
-- 
2.40.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] [PATCH 15/22] fftools/ffmpeg: drop an obsolete debug log

2023-07-07 Thread Anton Khirnov
The value it prints has not been cur_dts from lavf for a very long time,
so it's misleading.
---
 fftools/ffmpeg.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 435e12a37b..013935d6ce 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -941,10 +941,6 @@ static int choose_output(OutputStream **post)
 } else {
 opts = ost->last_mux_dts == AV_NOPTS_VALUE ?
INT64_MIN : ost->last_mux_dts;
-if (ost->last_mux_dts == AV_NOPTS_VALUE)
-av_log(ost, AV_LOG_DEBUG,
-"cur_dts is invalid [init:%d i_done:%d finish:%d] (this is 
harmless if it occurs once at the start per stream)\n",
-ost->initialized, ost->inputs_done, ost->finished);
 }
 
 if (!ost->initialized && !ost->inputs_done && !ost->finished) {
-- 
2.40.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] [PATCH 13/22] fftools/ffmpeg_filter: stop disregarding user-specified pixel format

2023-07-07 Thread Anton Khirnov
When the user explicitly specifies a pixel format that is not supported
by the encoder, ffmpeg CLI will currently use some heuristics to pick
another supported format. This is wrong and the correct action here is
to fail.

Surprisingly, a number of FATE tests are affected by this and actually
use a different pixel format than is specified in the makefiles.
---
 fftools/ffmpeg_filter.c   | 36 ++-
 tests/fate/fits.mak   |  6 ++--
 tests/fate/lavf-video.mak |  2 +-
 tests/fate/vcodec.mak |  4 +--
 .../{fitsdec-gbrap16le => fitsdec-gbrap16be}  |  4 +--
 .../fate/{fitsdec-gbrp16 => fitsdec-gbrp16be} |  4 +--
 tests/ref/lavf/gif|  2 +-
 7 files changed, 13 insertions(+), 45 deletions(-)
 rename tests/ref/fate/{fitsdec-gbrap16le => fitsdec-gbrap16be} (79%)
 rename tests/ref/fate/{fitsdec-gbrp16 => fitsdec-gbrp16be} (79%)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index caf85194c5..c283ee2b7a 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -277,43 +277,12 @@ static const enum AVPixelFormat 
*get_compliance_normal_pix_fmts(const AVCodec *c
 }
 }
 
-static enum AVPixelFormat
-choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat target,
- int strict_std_compliance)
-{
-if (codec && codec->pix_fmts) {
-const enum AVPixelFormat *p = codec->pix_fmts;
-const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
-//FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel 
format without alpha is implemented
-int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
-enum AVPixelFormat best= AV_PIX_FMT_NONE;
-
-if (strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
-p = get_compliance_normal_pix_fmts(codec, p);
-}
-for (; *p != AV_PIX_FMT_NONE; p++) {
-best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, 
NULL);
-if (*p == target)
-break;
-}
-if (*p == AV_PIX_FMT_NONE) {
-if (target != AV_PIX_FMT_NONE)
-av_log(NULL, AV_LOG_WARNING,
-   "Incompatible pixel format '%s' for codec '%s', 
auto-selecting format '%s'\n",
-   av_get_pix_fmt_name(target),
-   codec->name,
-   av_get_pix_fmt_name(best));
-return best;
-}
-}
-return target;
-}
-
 /* May return NULL (no pixel format found), a static string or a string
  * backed by the bprint. Nothing has been written to the AVBPrint in case
  * NULL is returned. The AVBPrint provided should be clean. */
 static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
 {
+OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 OutputStream *ost = ofilter->ost;
 AVCodecContext *enc = ost->enc_ctx;
 const AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, 
"strict", NULL, 0);
@@ -327,8 +296,7 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, 
AVBPrint *bprint)
 return av_get_pix_fmt_name(ost->enc_ctx->pix_fmt);
 }
 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
-return av_get_pix_fmt_name(choose_pixel_fmt(enc->codec, enc->pix_fmt,
-
ost->enc_ctx->strict_std_compliance));
+return av_get_pix_fmt_name(enc->pix_fmt);
 } else if (enc->codec->pix_fmts) {
 const enum AVPixelFormat *p;
 
diff --git a/tests/fate/fits.mak b/tests/fate/fits.mak
index b9e99d97ee..d85946bc1a 100644
--- a/tests/fate/fits.mak
+++ b/tests/fate/fits.mak
@@ -8,8 +8,8 @@ tests/data/fits-multi.fits: ffmpeg$(PROGSSUF)$(EXESUF) | 
tests/data
 # TODO: Use an actual 64bit input file and fix the gbrp16 test on big-endian
 fits-png-map-gray  := gray8
 fits-png-map-gbrp  := rgb24
-fits-png-map-gbrp16:= rgb48
-fits-png-map-gbrap16le := rgba64
+fits-png-map-gbrp16be  := rgb48
+fits-png-map-gbrap16be := rgba64
 
 FATE_FITS_DEC-$(call FRAMECRC, FITS, FITS, SCALE_FILTER) += 
fate-fitsdec-ext_data_min_max
 fate-fitsdec-ext_data_min_max: CMD = framecrc -i 
$(TARGET_SAMPLES)/fits/x0cj010ct_d0h.fit -pix_fmt gray16le -vf scale
@@ -30,7 +30,7 @@ fate-fitsdec-multi: CMD = framecrc -i 
$(TARGET_PATH)/tests/data/fits-multi.fits
 fate-fitsdec%: PIXFMT = $(word 3, $(subst -, ,$(@)))
 fate-fitsdec%: CMD = transcode image2 
$(TARGET_SAMPLES)/png1/lena-$(fits-png-map-$(PIXFMT)).png fits "-vf scale 
-pix_fmt $(PIXFMT)"
 
-FATE_FITS_DEC_PIXFMT = gray gbrp gbrp16 gbrap16le
+FATE_FITS_DEC_PIXFMT = gray gbrp gbrp16be gbrap16be
 FATE_FITS_DEC-$(call TRANSCODE, FITS, FITS, IMAGE2_DEMUXER PNG_DECODER 
SCALE_FILTER) += $(FATE_FITS_DEC_PIXFMT:%=fate-fitsdec-%)
 
 FATE_FITS += $(FATE_FITS_DEC-yes)
diff --git a/tests/fate/lavf-video.mak b/tests/fate/lavf-video.mak
index e73f8f203b..da3b114bc8 100644
--- a/tests/fate/lavf-

[FFmpeg-devel] [PATCH 18/22] fftools/ffmpeg_enc: initialize audio/video encoders from frame parameters

2023-07-07 Thread Anton Khirnov
This is possible now that enc_open() is always called with a non-NULL
frame for audio/video.

Previously the code would directly reach into the buffersink, which is a
layering violation.
---
 fftools/ffmpeg_enc.c | 35 +--
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index dd056e42f5..1347493f9f 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -34,8 +34,6 @@
 #include "libavutil/rational.h"
 #include "libavutil/timestamp.h"
 
-#include "libavfilter/buffersink.h"
-
 #include "libavcodec/avcodec.h"
 
 // FIXME private header, used for mid_pred()
@@ -198,12 +196,21 @@ int enc_open(OutputStream *ost, AVFrame *frame)
 AVCodecContext *dec_ctx = NULL;
 const AVCodec  *enc = enc_ctx->codec;
 OutputFile  *of = output_files[ost->file_index];
-FrameData *fd = frame ? frame_data(frame) : NULL;
+FrameData *fd;
 int ret;
 
 if (e->opened)
 return 0;
 
+// frame is always non-NULL for audio and video
+av_assert0(frame || (enc->type != AVMEDIA_TYPE_VIDEO && enc->type != 
AVMEDIA_TYPE_AUDIO));
+
+if (frame) {
+fd = frame_data(frame);
+if (!fd)
+return AVERROR(ENOMEM);
+}
+
 set_encoder_id(output_files[ost->file_index], ost);
 
 if (ist) {
@@ -212,15 +219,15 @@ int enc_open(OutputStream *ost, AVFrame *frame)
 
 switch (enc_ctx->codec_type) {
 case AVMEDIA_TYPE_AUDIO:
-enc_ctx->sample_fmt = 
av_buffersink_get_format(ost->filter->filter);
-enc_ctx->sample_rate= 
av_buffersink_get_sample_rate(ost->filter->filter);
-ret = av_buffersink_get_ch_layout(ost->filter->filter, 
&enc_ctx->ch_layout);
+enc_ctx->sample_fmt = frame->format;
+enc_ctx->sample_rate= frame->sample_rate;
+ret = av_channel_layout_copy(&enc_ctx->ch_layout, &frame->ch_layout);
 if (ret < 0)
 return ret;
 
 if (ost->bits_per_raw_sample)
 enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample;
-else if (fd)
+else
 enc_ctx->bits_per_raw_sample = FFMIN(fd->bits_per_raw_sample,
  
av_get_bytes_per_sample(enc_ctx->sample_fmt) << 3);
 
@@ -231,7 +238,7 @@ int enc_open(OutputStream *ost, AVFrame *frame)
 case AVMEDIA_TYPE_VIDEO: {
 AVRational fr = ost->frame_rate;
 
-if (!fr.num && fd)
+if (!fr.num)
 fr = fd->frame_rate_filter;
 if (!fr.num && !ost->max_frame_rate.num) {
 fr = (AVRational){25, 1};
@@ -261,7 +268,7 @@ int enc_open(OutputStream *ost, AVFrame *frame)
  av_inv_q(fr);
 
 if (!(enc_ctx->time_base.num && enc_ctx->time_base.den))
-enc_ctx->time_base = 
av_buffersink_get_time_base(ost->filter->filter);
+enc_ctx->time_base = frame->time_base;
 if (   av_q2d(enc_ctx->time_base) < 0.001 && ost->vsync_method != 
VSYNC_PASSTHROUGH
&& (ost->vsync_method == VSYNC_CFR || ost->vsync_method == 
VSYNC_VSCFR ||
(ost->vsync_method == VSYNC_AUTO && !(of->format->flags & 
AVFMT_VARIABLE_FPS{
@@ -270,18 +277,18 @@ int enc_open(OutputStream *ost, AVFrame *frame)
 "setting vsync/fps_mode to vfr\n");
 }
 
-enc_ctx->width  = av_buffersink_get_w(ost->filter->filter);
-enc_ctx->height = av_buffersink_get_h(ost->filter->filter);
+enc_ctx->width  = frame->width;
+enc_ctx->height = frame->height;
 enc_ctx->sample_aspect_ratio = ost->st->sample_aspect_ratio =
 ost->frame_aspect_ratio.num ? // overridden by the -aspect cli 
option
 av_mul_q(ost->frame_aspect_ratio, (AVRational){ enc_ctx->height, 
enc_ctx->width }) :
-av_buffersink_get_sample_aspect_ratio(ost->filter->filter);
+frame->sample_aspect_ratio;
 
-enc_ctx->pix_fmt = av_buffersink_get_format(ost->filter->filter);
+enc_ctx->pix_fmt = frame->format;
 
 if (ost->bits_per_raw_sample)
 enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample;
-else if (fd)
+else
 enc_ctx->bits_per_raw_sample = FFMIN(fd->bits_per_raw_sample,
  
av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth);
 
-- 
2.40.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] [PATCH 20/22] fftools/ffmpeg: add more structure to FrameData

2023-07-07 Thread Anton Khirnov
It now contains data from multiple sources, so group those items that
always come from the decoder. Also, initialize them to invalid values,
so that frames that did not originate from a decoder can be
distinguished.
---
 fftools/ffmpeg.c |  8 +++-
 fftools/ffmpeg.h | 10 +++---
 fftools/ffmpeg_dec.c |  6 +++---
 fftools/ffmpeg_enc.c |  6 +++---
 4 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 013935d6ce..96fbcd626a 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -434,9 +434,15 @@ InputStream *ist_iter(InputStream *prev)
 FrameData *frame_data(AVFrame *frame)
 {
 if (!frame->opaque_ref) {
-frame->opaque_ref = av_buffer_allocz(sizeof(FrameData));
+FrameData *fd;
+
+frame->opaque_ref = av_buffer_allocz(sizeof(*fd));
 if (!frame->opaque_ref)
 return NULL;
+fd = (FrameData*)frame->opaque_ref->data;
+
+fd->dec.frame_num = UINT64_MAX;
+fd->dec.pts   = AV_NOPTS_VALUE;
 }
 
 return (FrameData*)frame->opaque_ref->data;
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index abea424486..28474c1162 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -626,9 +626,13 @@ typedef struct OutputFile {
 
 // optionally attached as opaque_ref to decoded AVFrames
 typedef struct FrameData {
-uint64_t   idx;
-int64_tpts;
-AVRational tb;
+// properties that come from the decoder
+struct {
+uint64_t   frame_num;
+
+int64_tpts;
+AVRational tb;
+} dec;
 
 AVRational frame_rate_filter;
 
diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c
index 85bf8dc536..1ae8544394 100644
--- a/fftools/ffmpeg_dec.c
+++ b/fftools/ffmpeg_dec.c
@@ -610,9 +610,9 @@ static int packet_decode(InputStream *ist, const AVPacket 
*pkt, AVFrame *frame)
 av_frame_unref(frame);
 return AVERROR(ENOMEM);
 }
-fd->pts = frame->pts;
-fd->tb  = dec->pkt_timebase;
-fd->idx = dec->frame_num - 1;
+fd->dec.pts = frame->pts;
+fd->dec.tb  = dec->pkt_timebase;
+fd->dec.frame_num   = dec->frame_num - 1;
 fd->bits_per_raw_sample = dec->bits_per_raw_sample;
 
 frame->time_base = dec->pkt_timebase;
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 1347493f9f..612bf23770 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -569,8 +569,8 @@ void enc_stats_write(OutputStream *ost, EncStats *es,
 
 if ((frame && frame->opaque_ref) || (pkt && pkt->opaque_ref)) {
 fd   = (const FrameData*)(frame ? frame->opaque_ref->data : 
pkt->opaque_ref->data);
-tbi  = fd->tb;
-ptsi = fd->pts;
+tbi  = fd->dec.tb;
+ptsi = fd->dec.pts;
 }
 
 for (size_t i = 0; i < es->nb_components; i++) {
@@ -588,7 +588,7 @@ void enc_stats_write(OutputStream *ost, EncStats *es,
 case ENC_STATS_PTS_TIME_IN: avio_printf(io, "%g",   ptsi == 
INT64_MAX ?
 INFINITY : 
ptsi * av_q2d(tbi)); continue;
 case ENC_STATS_FRAME_NUM:   avio_printf(io, "%"PRIu64,  
frame_num); continue;
-case ENC_STATS_FRAME_NUM_IN:avio_printf(io, "%"PRIu64,  fd ? 
fd->idx : -1); continue;
+case ENC_STATS_FRAME_NUM_IN:avio_printf(io, "%"PRIu64,  fd ? 
fd->dec.frame_num : -1);   continue;
 }
 
 if (frame) {
-- 
2.40.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] [PATCH 21/22] fftools/ffmpeg: rework -enc_time_base handling

2023-07-07 Thread Anton Khirnov
Read the timebase from FrameData rather than the input stream. This
should fix #10393 and generally be more reliable.

Replace the use of '-1' to indicate demuxing timebase with the string
'demux'. Also allow to request filter timebase with
'-enc_time_base filter'.
---
 doc/ffmpeg.texi   |  7 ---
 fftools/ffmpeg.h  |  6 ++
 fftools/ffmpeg_enc.c  | 16 ++--
 fftools/ffmpeg_mux_init.c | 29 ++---
 tests/fate/video.mak  |  2 +-
 5 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 6769f8d305..59e9fbfcb2 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -1812,10 +1812,11 @@ Assign a default value according to the media type.
 
 For video - use 1/framerate, for audio - use 1/samplerate.
 
-@item -1
-Use the input stream timebase when possible.
+@item demux
+Use the timebase from the demuxer.
 
-If an input stream is not available, the default timebase will be used.
+@item filter
+Use the timebase from the filtergraph.
 
 @item >0
 Use the provided number as the timebase.
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 28474c1162..59ce29d815 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -56,6 +56,7 @@
 #define FFMPEG_ROTATION_METADATA 1
 #define FFMPEG_OPT_QPHIST 1
 #define FFMPEG_OPT_ADRIFT_THRESHOLD 1
+#define FFMPEG_OPT_ENC_TIME_BASE_NUM 1
 
 enum VideoSyncMethod {
 VSYNC_AUTO = -1,
@@ -66,6 +67,11 @@ enum VideoSyncMethod {
 VSYNC_DROP,
 };
 
+enum EncTimeBase {
+ENC_TIME_BASE_DEMUX  = -1,
+ENC_TIME_BASE_FILTER = -2,
+};
+
 #define MAX_STREAMS 1024/* arbitrary sanity check value */
 
 enum HWAccelID {
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index 612bf23770..6fafd3ff60 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -264,8 +264,20 @@ int enc_open(OutputStream *ost, AVFrame *frame)
   fr.num, fr.den, 65535);
 }
 
-enc_ctx->time_base = ost->enc_timebase.num > 0 ? ost->enc_timebase :
- av_inv_q(fr);
+if (ost->enc_timebase.num == ENC_TIME_BASE_DEMUX) {
+if (fd->dec.tb.num <= 0 || fd->dec.tb.den <= 0) {
+av_log(ost, AV_LOG_ERROR,
+   "Demuxing timebase not available - cannot use it for 
encoding\n");
+return AVERROR(EINVAL);
+}
+
+enc_ctx->time_base = fd->dec.tb;
+} else if (ost->enc_timebase.num == ENC_TIME_BASE_FILTER) {
+enc_ctx->time_base = frame->time_base;
+} else {
+enc_ctx->time_base = ost->enc_timebase.num > 0 ? ost->enc_timebase 
:
+ av_inv_q(fr);
+}
 
 if (!(enc_ctx->time_base.num && enc_ctx->time_base.den))
 enc_ctx->time_base = frame->time_base;
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 6ab541d7c5..89da128881 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -1140,20 +1140,27 @@ static OutputStream *ost_add(Muxer *mux, const 
OptionsContext *o,
 MATCH_PER_STREAM_OPT(enc_time_bases, str, enc_time_base, oc, st);
 if (enc_time_base) {
 AVRational q;
-if (av_parse_ratio(&q, enc_time_base, INT_MAX, 0, NULL) < 0 ||
-q.den <= 0) {
-av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", 
enc_time_base);
-exit_program(1);
-}
-if (q.num < 0) {
-if (!ost->ist) {
-av_log(ost, AV_LOG_FATAL,
-   "Cannot use input stream timebase for encoding - "
-   "no input stream available\n");
+if (!strcmp(enc_time_base, "demux")) {
+q = (AVRational){ ENC_TIME_BASE_DEMUX, 0 };
+} else if (!strcmp(enc_time_base, "filter")) {
+q = (AVRational){ ENC_TIME_BASE_FILTER, 0 };
+} else {
+ret = av_parse_ratio(&q, enc_time_base, INT_MAX, 0, NULL);
+if (ret < 0 || q.den <= 0
+#if !FFMPEG_OPT_ENC_TIME_BASE_NUM
+|| q.num < 0
+#endif
+) {
+av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", 
enc_time_base);
 exit_program(1);
 }
-q = ost->ist->st->time_base;
+#if FFMPEG_OPT_ENC_TIME_BASE_NUM
+if (q.num < 0)
+av_log(ost, AV_LOG_WARNING, "-enc_time_base -1 is 
deprecated,"
+   " use -enc_timebase demux\n");
+#endif
 }
+
 ost->enc_timebase = q;
 }
 } else {
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index a2011d0dad..4e7a77537f 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -270,7 +270,7 @@ FATE_VIDEO-$(call FRAMECRC, MXG, MXPEG) += fate-mxpeg
 fate-mxpeg: CMD = framecrc -idct simple -flags +bitexact -i 
$(TARGET_SAMPLES)/mx

[FFmpeg-devel] [PATCH 08/22] fftools/ffmpeg_filter: make OutputFile.format/sample_rate private

2023-07-07 Thread Anton Khirnov
They are not used outside of the filtering code.
---
 fftools/ffmpeg.h|  2 --
 fftools/ffmpeg_filter.c | 39 +--
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 316cd2b7a6..5b4117eeea 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -296,8 +296,6 @@ typedef struct OutputFilter {
 
 /* desired output stream properties */
 int width, height;
-int format;
-int sample_rate;
 AVChannelLayout ch_layout;
 
 // those are only set if no format is specified and the encoder gives us 
multiple options
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 432e2fced9..b1fda7b9e8 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -133,6 +133,19 @@ static InputFilterPriv *ifp_from_ifilter(InputFilter 
*ifilter)
 return (InputFilterPriv*)ifilter;
 }
 
+typedef struct OutputFilterPriv {
+OutputFilterofilter;
+
+/* desired output stream properties */
+int format;
+int sample_rate;
+} OutputFilterPriv;
+
+static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter)
+{
+return (OutputFilterPriv*)ofilter;
+}
+
 static int configure_filtergraph(FilterGraph *fg);
 
 static int sub2video_get_blank_frame(InputFilterPriv *ifp)
@@ -333,11 +346,12 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, 
AVBPrint *bprint)
 #define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, 
printf_format, get_name) \
 static void choose_ ## name (OutputFilter *ofilter, AVBPrint *bprint)  
\
 {  
\
-if (ofilter->var == none && !ofilter->supported_list)  
\
+OutputFilterPriv *ofp = ofp_from_ofilter(ofilter); 
\
+if (ofp->var == none && !ofilter->supported_list)  
\
 return;
\
 av_bprintf(bprint, #name "="); 
\
-if (ofilter->var != none) {
\
-av_bprintf(bprint, printf_format, get_name(ofilter->var)); 
\
+if (ofp->var != none) {
\
+av_bprintf(bprint, printf_format, get_name(ofp->var)); 
\
 } else {   
\
 const type *p; 
\

\
@@ -580,11 +594,14 @@ static char *describe_filter_link(FilterGraph *fg, 
AVFilterInOut *inout, int in)
 
 static OutputFilter *ofilter_alloc(FilterGraph *fg)
 {
+OutputFilterPriv *ofp;
 OutputFilter *ofilter;
 
-ofilter   = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
+ofp   = allocate_array_elem(&fg->outputs, sizeof(*ofp),
+&fg->nb_outputs);
+ofilter   = &ofp->ofilter;
 ofilter->graph= fg;
-ofilter->format   = -1;
+ofp->format   = -1;
 ofilter->last_pts = AV_NOPTS_VALUE;
 
 return ofilter;
@@ -653,6 +670,7 @@ static void set_channel_layout(OutputFilter *f, 
OutputStream *ost)
 
 void ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost)
 {
+OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 FilterGraph  *fg = ofilter->graph;
 const AVCodec *c = ost->enc_ctx->codec;
 
@@ -666,19 +684,19 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost)
 ofilter->width  = ost->enc_ctx->width;
 ofilter->height = ost->enc_ctx->height;
 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
-ofilter->format = ost->enc_ctx->pix_fmt;
+ofp->format = ost->enc_ctx->pix_fmt;
 } else {
 ofilter->formats = c->pix_fmts;
 }
 break;
 case AVMEDIA_TYPE_AUDIO:
 if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
-ofilter->format = ost->enc_ctx->sample_fmt;
+ofp->format = ost->enc_ctx->sample_fmt;
 } else {
 ofilter->formats = c->sample_fmts;
 }
 if (ost->enc_ctx->sample_rate) {
-ofilter->sample_rate = ost->enc_ctx->sample_rate;
+ofp->sample_rate = ost->enc_ctx->sample_rate;
 } else {
 ofilter->sample_rates = c->supported_samplerates;
 }
@@ -1570,14 +1588,15 @@ static int configure_filtergraph(FilterGraph *fg)
  * make sure they stay the same if the filtergraph is reconfigured later */
 for (i = 0; i < fg->nb_outputs; i++) {
 OutputFilter *ofilter = fg->outputs[i];
+OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 AVFilterContext *sink = ofilter->filter;
 
-ofilter->format = av_buffersink_get_format(sink);
+   

[FFmpeg-devel] [PATCH 05/22] lavc/encode: improve unsupported-format error messages

2023-07-07 Thread Anton Khirnov
Mention encoder name in the message to emphasize that the value in
question is not supported by this specific encoder, not necessarily by
libavcodec in general.

Print a list of values supported by the encoder.
---
 libavcodec/encode.c | 45 +
 1 file changed, 37 insertions(+), 8 deletions(-)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 9a279d9842..ee501132da 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -565,8 +565,16 @@ static int encode_preinit_video(AVCodecContext *avctx)
 if (avctx->pix_fmt == c->pix_fmts[i])
 break;
 if (c->pix_fmts[i] == AV_PIX_FMT_NONE) {
-av_log(avctx, AV_LOG_ERROR, "Specified pixel format %s is not 
supported\n",
-   av_get_pix_fmt_name(avctx->pix_fmt));
+av_log(avctx, AV_LOG_ERROR,
+   "Specified pixel format %s is not supported by the %s 
encoder.\n",
+   av_get_pix_fmt_name(avctx->pix_fmt), c->name);
+
+av_log(avctx, AV_LOG_ERROR, "Supported pixel formats:\n");
+for (int p = 0; c->pix_fmts[p] != AV_PIX_FMT_NONE; p++) {
+av_log(avctx, AV_LOG_ERROR, "  %s\n",
+   av_get_pix_fmt_name(c->pix_fmts[p]));
+}
+
 return AVERROR(EINVAL);
 }
 if (c->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
@@ -652,8 +660,16 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 }
 }
 if (c->sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
-av_log(avctx, AV_LOG_ERROR, "Specified sample format %s is not 
supported\n",
-   av_get_sample_fmt_name(avctx->sample_fmt));
+av_log(avctx, AV_LOG_ERROR,
+   "Specified sample format %s is not supported by the %s 
encoder\n",
+   av_get_sample_fmt_name(avctx->sample_fmt), c->name);
+
+av_log(avctx, AV_LOG_ERROR, "Supported sample formats:\n");
+for (int p = 0; c->sample_fmts[p] != AV_SAMPLE_FMT_NONE; p++) {
+av_log(avctx, AV_LOG_ERROR, "  %s\n",
+   av_get_sample_fmt_name(c->sample_fmts[p]));
+}
+
 return AVERROR(EINVAL);
 }
 }
@@ -662,8 +678,14 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 if (avctx->sample_rate == c->supported_samplerates[i])
 break;
 if (c->supported_samplerates[i] == 0) {
-av_log(avctx, AV_LOG_ERROR, "Specified sample rate %d is not 
supported\n",
-   avctx->sample_rate);
+av_log(avctx, AV_LOG_ERROR,
+   "Specified sample rate %d is not supported by the %s 
encoder\n",
+   avctx->sample_rate, c->name);
+
+av_log(avctx, AV_LOG_ERROR, "Supported sample rates:\n");
+for (int p = 0; c->supported_samplerates[p]; p++)
+av_log(avctx, AV_LOG_ERROR, "  %d\n", 
c->supported_samplerates[p]);
+
 return AVERROR(EINVAL);
 }
 }
@@ -675,8 +697,15 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 if (!c->ch_layouts[i].nb_channels) {
 char buf[512];
 int ret = av_channel_layout_describe(&avctx->ch_layout, buf, 
sizeof(buf));
-av_log(avctx, AV_LOG_ERROR, "Specified channel layout '%s' is not 
supported\n",
-   ret > 0 ? buf : "?");
+av_log(avctx, AV_LOG_ERROR,
+   "Specified channel layout '%s' is not supported by the %s 
encoder\n",
+   ret > 0 ? buf : "?", c->name);
+
+av_log(avctx, AV_LOG_ERROR, "Supported channel layouts:\n");
+for (int p = 0; c->ch_layouts[p].nb_channels; p++) {
+ret = av_channel_layout_describe(&c->ch_layouts[p], buf, 
sizeof(buf));
+av_log(avctx, AV_LOG_ERROR, "  %s\n", ret > 0 ? buf : "?");
+}
 return AVERROR(EINVAL);
 }
 }
-- 
2.40.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] [PATCH 11/22] fftools/ffmpeg_filter: make OutputFile.{formats, ch_layouts, sample_rates} private

2023-07-07 Thread Anton Khirnov
They are not used outside of the filtering code.
---
 fftools/ffmpeg.h|  6 --
 fftools/ffmpeg_filter.c | 35 ---
 2 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 79f3f35b3a..3201163a4f 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -294,12 +294,6 @@ typedef struct OutputFilter {
 
 enum AVMediaType type;
 
-// those are only set if no format is specified and the encoder gives us 
multiple options
-// They point directly to the relevant lists of the encoder.
-const int *formats;
-const AVChannelLayout *ch_layouts;
-const int *sample_rates;
-
 /* pts of the last frame received from this filter, in AV_TIME_BASE_Q */
 int64_t last_pts;
 } OutputFilter;
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 0874187f3e..f60d1cd23b 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -141,6 +141,12 @@ typedef struct OutputFilterPriv {
 int width, height;
 int sample_rate;
 AVChannelLayout ch_layout;
+
+// those are only set if no format is specified and the encoder gives us 
multiple options
+// They point directly to the relevant lists of the encoder.
+const int *formats;
+const AVChannelLayout *ch_layouts;
+const int *sample_rates;
 } OutputFilterPriv;
 
 static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter)
@@ -346,10 +352,9 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, 
AVBPrint *bprint)
 /* Define a function for appending a list of allowed formats
  * to an AVBPrint. If nonempty, the list will have a header. */
 #define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, 
printf_format, get_name) \
-static void choose_ ## name (OutputFilter *ofilter, AVBPrint *bprint)  
\
+static void choose_ ## name (OutputFilterPriv *ofp, AVBPrint *bprint)  
\
 {  
\
-OutputFilterPriv *ofp = ofp_from_ofilter(ofilter); 
\
-if (ofp->var == none && !ofilter->supported_list)  
\
+if (ofp->var == none && !ofp->supported_list)  
\
 return;
\
 av_bprintf(bprint, #name "="); 
\
 if (ofp->var != none) {
\
@@ -357,7 +362,7 @@ static void choose_ ## name (OutputFilter *ofilter, 
AVBPrint *bprint)  \
 } else {   
\
 const type *p; 
\

\
-for (p = ofilter->supported_list; *p != none; p++) {   
\
+for (p = ofp->supported_list; *p != none; p++) {   
\
 av_bprintf(bprint, printf_format "|", get_name(*p));   
\
 }  
\
 if (bprint->len > 0)   
\
@@ -375,17 +380,16 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, 
format, formats,
 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
   "%d", )
 
-static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint)
+static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
 {
-OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 if (av_channel_layout_check(&ofp->ch_layout)) {
 av_bprintf(bprint, "channel_layouts=");
 av_channel_layout_describe_bprint(&ofp->ch_layout, bprint);
-} else if (ofilter->ch_layouts) {
+} else if (ofp->ch_layouts) {
 const AVChannelLayout *p;
 
 av_bprintf(bprint, "channel_layouts=");
-for (p = ofilter->ch_layouts; p->nb_channels; p++) {
+for (p = ofp->ch_layouts; p->nb_channels; p++) {
 av_channel_layout_describe_bprint(p, bprint);
 av_bprintf(bprint, "|");
 }
@@ -689,24 +693,24 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost)
 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
 ofp->format = ost->enc_ctx->pix_fmt;
 } else {
-ofilter->formats = c->pix_fmts;
+ofp->formats = c->pix_fmts;
 }
 break;
 case AVMEDIA_TYPE_AUDIO:
 if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
 ofp->format = ost->enc_ctx->sample_fmt;
 } else {
-ofilter->formats = c->sample_fmts;
+ofp->formats = c->sample_fmts;
 }
 if (ost->enc_ctx->sample_rate) {
 ofp->sample_rate = ost->enc_ctx->sample_rate;
 } else {
-ofilter->sample_rates = c->supported_s

[FFmpeg-devel] [PATCH 09/22] fftools/ffmpeg_filter: make OutputFile.ch_layout private

2023-07-07 Thread Anton Khirnov
It is not used outside of the filtering code.
---
 fftools/ffmpeg.h|  1 -
 fftools/ffmpeg_filter.c | 17 ++---
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 5b4117eeea..b789233a08 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -296,7 +296,6 @@ typedef struct OutputFilter {
 
 /* desired output stream properties */
 int width, height;
-AVChannelLayout ch_layout;
 
 // those are only set if no format is specified and the encoder gives us 
multiple options
 // They point directly to the relevant lists of the encoder.
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index b1fda7b9e8..0272b0a96b 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -139,6 +139,7 @@ typedef struct OutputFilterPriv {
 /* desired output stream properties */
 int format;
 int sample_rate;
+AVChannelLayout ch_layout;
 } OutputFilterPriv;
 
 static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter)
@@ -375,9 +376,10 @@ DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, 
sample_rates, 0,
 
 static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint)
 {
-if (av_channel_layout_check(&ofilter->ch_layout)) {
+OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
+if (av_channel_layout_check(&ofp->ch_layout)) {
 av_bprintf(bprint, "channel_layouts=");
-av_channel_layout_describe_bprint(&ofilter->ch_layout, bprint);
+av_channel_layout_describe_bprint(&ofp->ch_layout, bprint);
 } else if (ofilter->ch_layouts) {
 const AVChannelLayout *p;
 
@@ -630,7 +632,7 @@ static int ifilter_bind_ist(InputFilter *ifilter, 
InputStream *ist)
 return 0;
 }
 
-static void set_channel_layout(OutputFilter *f, OutputStream *ost)
+static void set_channel_layout(OutputFilterPriv *f, OutputStream *ost)
 {
 const AVCodec *c = ost->enc_ctx->codec;
 int i, err;
@@ -701,7 +703,7 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost)
 ofilter->sample_rates = c->supported_samplerates;
 }
 if (ost->enc_ctx->ch_layout.nb_channels) {
-set_channel_layout(ofilter, ost);
+set_channel_layout(ofp, ost);
 } else if (c->ch_layouts) {
 ofilter->ch_layouts = c->ch_layouts;
 }
@@ -782,10 +784,11 @@ void fg_free(FilterGraph **pfg)
 av_freep(&fg->inputs);
 for (int j = 0; j < fg->nb_outputs; j++) {
 OutputFilter *ofilter = fg->outputs[j];
+OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 
 av_freep(&ofilter->linklabel);
 av_freep(&ofilter->name);
-av_channel_layout_uninit(&ofilter->ch_layout);
+av_channel_layout_uninit(&ofp->ch_layout);
 av_freep(&fg->outputs[j]);
 }
 av_freep(&fg->outputs);
@@ -1597,8 +1600,8 @@ static int configure_filtergraph(FilterGraph *fg)
 ofilter->height = av_buffersink_get_h(sink);
 
 ofp->sample_rate= av_buffersink_get_sample_rate(sink);
-av_channel_layout_uninit(&ofilter->ch_layout);
-ret = av_buffersink_get_ch_layout(sink, &ofilter->ch_layout);
+av_channel_layout_uninit(&ofp->ch_layout);
+ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
 if (ret < 0)
 goto fail;
 }
-- 
2.40.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] [PATCH 14/22] fftools/ffmpeg_filter: stop accessing encoder from pixfmt selection

2023-07-07 Thread Anton Khirnov
ffmpeg CLI pixel format selection for filtering currently special-cases
MJPEG encoding, where it will restrict the supported list of pixel
formats depending on the value of the -strict option. In order to get
that value it will apply it from the options dict into the encoder
context, which is a highly invasive action even now, and would become a
race once encoding is moved to its own thread.

The ugliness of this code can be much reduced by moving the special
handling of MJPEG into ofilter_bind_ost(), which is called from encoder
init and is thus synchronized with it. There is also no need to write
anything to the encoder context, we can evaluate the option into our
stack variable.

There is also no need to access AVCodec at all during pixel format
selection, as the pixel formats array is already stored in
OutputFilterPriv.
---
 fftools/ffmpeg_filter.c | 64 -
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index c283ee2b7a..67a5f48245 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -262,21 +262,6 @@ static void sub2video_update(InputFilterPriv *ifp, int64_t 
heartbeat_pts,
 ifp->sub2video.initialize = 0;
 }
 
-// FIXME: YUV420P etc. are actually supported with full color range,
-// yet the latter information isn't available here.
-static const enum AVPixelFormat *get_compliance_normal_pix_fmts(const AVCodec 
*codec, const enum AVPixelFormat default_formats[])
-{
-static const enum AVPixelFormat mjpeg_formats[] =
-{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
-  AV_PIX_FMT_NONE };
-
-if (!strcmp(codec->name, "mjpeg")) {
-return mjpeg_formats;
-} else {
-return default_formats;
-}
-}
-
 /* May return NULL (no pixel format found), a static string or a string
  * backed by the bprint. Nothing has been written to the AVBPrint in case
  * NULL is returned. The AVBPrint provided should be clean. */
@@ -284,26 +269,15 @@ static const char *choose_pix_fmts(OutputFilter *ofilter, 
AVBPrint *bprint)
 {
 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 OutputStream *ost = ofilter->ost;
-AVCodecContext *enc = ost->enc_ctx;
-const AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, 
"strict", NULL, 0);
-if (strict_dict)
-// used by choose_pixel_fmt() and below
-av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0);
 
- if (ost->keep_pix_fmt) {
-if (ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE)
-return NULL;
-return av_get_pix_fmt_name(ost->enc_ctx->pix_fmt);
+if (ost->keep_pix_fmt) {
+return ofp->format == AV_PIX_FMT_NONE ? NULL :
+   av_get_pix_fmt_name(ofp->format);
 }
-if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
-return av_get_pix_fmt_name(enc->pix_fmt);
-} else if (enc->codec->pix_fmts) {
-const enum AVPixelFormat *p;
-
-p = enc->codec->pix_fmts;
-if (ost->enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
-p = get_compliance_normal_pix_fmts(enc->codec, p);
-}
+if (ofp->format != AV_PIX_FMT_NONE) {
+return av_get_pix_fmt_name(ofp->format);
+} else if (ofp->formats) {
+const enum AVPixelFormat *p = ofp->formats;
 
 for (; *p != AV_PIX_FMT_NONE; p++) {
 const char *name = av_get_pix_fmt_name(*p);
@@ -662,6 +636,30 @@ void ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost)
 ofp->format = ost->enc_ctx->pix_fmt;
 } else {
 ofp->formats = c->pix_fmts;
+
+// MJPEG encoder exports a full list of supported pixel formats,
+// but the full-range ones are experimental-only.
+// Restrict the auto-conversion list unless -strict experimental
+// has been specified.
+if (!strcmp(c->name, "mjpeg")) {
+// FIXME: YUV420P etc. are actually supported with full color 
range,
+// yet the latter information isn't available here.
+static const enum AVPixelFormat mjpeg_formats[] =
+{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, 
AV_PIX_FMT_YUVJ444P,
+  AV_PIX_FMT_NONE };
+
+const AVDictionaryEntry *strict = 
av_dict_get(ost->encoder_opts, "strict", NULL, 0);
+int strict_val = ost->enc_ctx->strict_std_compliance;
+
+if (strict) {
+const AVOption *o = av_opt_find(ost->enc_ctx, strict->key, 
NULL, 0, 0);
+av_assert0(o);
+av_opt_eval_int(ost->enc_ctx, o, strict->value, 
&strict_val);
+}
+
+if (strict_val > FF_COMPLIANCE_UNOFFICIAL)
+ofp->formats = mjpeg_formats;
+}
 }
 
 fgp->disable_conversions |= ost->keep_pix_fmt;
-- 
2.40.1

_

[FFmpeg-devel] [PATCH 17/22] fftools/ffmpeg_filter: only flush vsync code if encoding actually started

2023-07-07 Thread Anton Khirnov
Otherwise this has no effect.

Will be useful in following commits.
---
 fftools/ffmpeg_filter.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index f8e64ce6cc..4955fe38dd 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -1720,10 +1720,10 @@ int reap_filters(int flush)
 if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
 av_log(fgp, AV_LOG_WARNING,
"Error in av_buffersink_get_frame_flags(): %s\n", 
av_err2str(ret));
-} else if (flush && ret == AVERROR_EOF) {
-if (av_buffersink_get_type(filter) == AVMEDIA_TYPE_VIDEO)
-enc_frame(ost, NULL);
-}
+} else if (flush && ret == AVERROR_EOF && ofp->got_frame &&
+   av_buffersink_get_type(filter) == 
AVMEDIA_TYPE_VIDEO)
+enc_frame(ost, NULL);
+
 break;
 }
 if (ost->finished) {
-- 
2.40.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] [PATCH] lavu/random_seed: use getrandom() when available

2023-07-07 Thread Anton Khirnov
It is a better interface for /dev/u?random on Linux, which avoids the
issues associated with opening files.
---
 configure   |  2 ++
 libavutil/random_seed.c | 15 +++
 2 files changed, 17 insertions(+)

diff --git a/configure b/configure
index d6e78297fe..a4b09577cf 100755
--- a/configure
+++ b/configure
@@ -2310,6 +2310,7 @@ SYSTEM_FUNCS="
 getauxval
 getenv
 gethrtime
+getrandom
 getopt
 GetModuleHandle
 GetProcessAffinityMask
@@ -6387,6 +6388,7 @@ check_func  fcntl
 check_func  fork
 check_func  gethrtime
 check_func  getopt
+check_func_headers "sys/random.h" getrandom
 check_func  getrusage
 check_func  gettimeofday
 check_func  isatty
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index 2980e565e0..9a3a5aa133 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -35,6 +35,9 @@
 #elif CONFIG_OPENSSL
 #include 
 #endif
+#if HAVE_GETRANDOM
+#include 
+#endif
 #include 
 #include 
 #include 
@@ -51,6 +54,7 @@
 #define TEST 0
 #endif
 
+#if !HAVE_GETRANDOM
 static int read_random(uint8_t *dst, size_t len, const char *file)
 {
 #if HAVE_UNISTD_H
@@ -70,6 +74,7 @@ static int read_random(uint8_t *dst, size_t len, const char 
*file)
 return AVERROR(ENOSYS);
 #endif
 }
+#endif
 
 static uint32_t get_generic_seed(void)
 {
@@ -147,7 +152,17 @@ int av_random_bytes(uint8_t* buf, size_t len)
 return 0;
 #endif
 
+// getrandom() is a better interface for /dev/(u)random on Linux,
+// so it makes no sense to try both
+#if HAVE_GETRANDOM
+{
+ssize_t read = getrandom(buf, len, GRND_NONBLOCK);
+err = read < 0? AVERROR(errno)  :
+  read != len ? AVERROR_UNKNOWN : 0;
+}
+#else
 err = read_random(buf, len, "/dev/urandom");
+#endif
 if (!err)
 return err;
 
-- 
2.40.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] [PATCH] tests/fate-run: add testing with a random number of threads

2023-07-07 Thread Anton Khirnov
Useful for discovering bugs that depend on a specific thread count.

Use like THREADS=randomX for a random thread count from 1 to X, with
X=16 when not specified.
---
Now using the awk rand() function, also used in configure.
The thread count can now be written into the errfile on test failure.
---
 doc/fate.texi |  8 
 tests/fate-run.sh | 10 ++
 2 files changed, 18 insertions(+)

diff --git a/doc/fate.texi b/doc/fate.texi
index 8450856015..2fa8c34c2d 100644
--- a/doc/fate.texi
+++ b/doc/fate.texi
@@ -223,6 +223,14 @@ meaning only while running the regression tests.
 Specify how many threads to use while running regression tests, it is
 quite useful to detect thread-related regressions.
 
+This variable may be set to the string "random", optionally followed by a
+number, like "random99", This will cause each test to use a random number of
+threads. If a number is specified, it is used as a maximum number of threads,
+otherwise 16 is the maximum.
+
+In case a test fails, the thread count used for it will be written into the
+errfile.
+
 @item THREAD_TYPE
 Specify which threading strategy test, either @samp{slice} or @samp{frame},
 by default @samp{slice+frame}
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index e12279e4cf..5a71ac001e 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -33,6 +33,15 @@ errfile="${outdir}/${test}.err"
 cmpfile="${outdir}/${test}.diff"
 repfile="${outdir}/${test}.rep"
 
+case $threads in
+random*)
+threads_max=${threads#random}
+[ -z "$threads_max" ] && threads_max=16
+threads=$(awk "BEGIN { print 1+int(rand() * $threads_max) }" < 
/dev/null)
+;;
+esac
+
+
 target_path(){
 test ${1} = ${1#/} && p=${target_path}/
 echo ${p}${1}
@@ -630,6 +639,7 @@ fi
 if [ $err -eq 0 ] && test $report_type = "standard" ; then
 unset cmpo erro
 else
+echo "threads=$threads" >> "$errfile"
 cmpo="$($base64 <$cmpfile)"
 erro="$($base64 <$errfile)"
 fi
-- 
2.40.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".


Re: [FFmpeg-devel] [PATCH] lavu/random_seed: use getrandom() when available

2023-07-07 Thread James Almer

On 7/7/2023 7:21 AM, Anton Khirnov wrote:

It is a better interface for /dev/u?random on Linux, which avoids the
issues associated with opening files.
---
  configure   |  2 ++
  libavutil/random_seed.c | 15 +++
  2 files changed, 17 insertions(+)

diff --git a/configure b/configure
index d6e78297fe..a4b09577cf 100755
--- a/configure
+++ b/configure
@@ -2310,6 +2310,7 @@ SYSTEM_FUNCS="
  getauxval
  getenv
  gethrtime
+getrandom
  getopt
  GetModuleHandle
  GetProcessAffinityMask
@@ -6387,6 +6388,7 @@ check_func  fcntl
  check_func  fork
  check_func  gethrtime
  check_func  getopt
+check_func_headers "sys/random.h" getrandom
  check_func  getrusage
  check_func  gettimeofday
  check_func  isatty
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index 2980e565e0..9a3a5aa133 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -35,6 +35,9 @@
  #elif CONFIG_OPENSSL
  #include 
  #endif
+#if HAVE_GETRANDOM
+#include 
+#endif
  #include 
  #include 
  #include 
@@ -51,6 +54,7 @@
  #define TEST 0
  #endif
  
+#if !HAVE_GETRANDOM

  static int read_random(uint8_t *dst, size_t len, const char *file)
  {
  #if HAVE_UNISTD_H
@@ -70,6 +74,7 @@ static int read_random(uint8_t *dst, size_t len, const char 
*file)
  return AVERROR(ENOSYS);
  #endif
  }
+#endif
  
  static uint32_t get_generic_seed(void)

  {
@@ -147,7 +152,17 @@ int av_random_bytes(uint8_t* buf, size_t len)
  return 0;
  #endif
  
+// getrandom() is a better interface for /dev/(u)random on Linux,

+// so it makes no sense to try both
+#if HAVE_GETRANDOM
+{
+ssize_t read = getrandom(buf, len, GRND_NONBLOCK);
+err = read < 0? AVERROR(errno)  :
+  read != len ? AVERROR_UNKNOWN : 0;


The documentation states

"By default, when reading from the random source, getrandom() blocks if 
no random bytes are available, and when reading from the urandom source, 
it blocks if the entropy pool has not yet been initialized.If the 
GRND_NONBLOCK flag is set, then getrandom() does not block in these 
cases, but instead immediately returns -1 with errno set to EAGAIN."


Returning EAGAIN may end up clashing with our usage of said error value 
internally (Marton's patch will make use of this function in hls), so 
maybe prevent said value from propagating here.


LGTM otherwise.


+}
+#else
  err = read_random(buf, len, "/dev/urandom");
+#endif
  if (!err)
  return err;
  

___
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] avformat/mov: avss box should be AV_CODEC_ID_CAVS

2023-07-07 Thread Zhao Zhili
From: Zhao Zhili 

I cannot find the spec, but according to the original commit
d4fdba0df71, it's CAVS. e571305a714 changed it to AVS by
accident. Ten years on, nothing happened. We still have the
sample [1], however, since there is no cavs_mp4tofoobar bsf, the
cavs decoder doesn't work. I don't know if there is any use case.

[1] https://samples.ffmpeg.org/AVS/AVSFileFormat/AVSFileFormat.mp4
---
 libavformat/mov.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 444aca5235..ac19b3157a 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1911,7 +1911,7 @@ static int mov_read_alac(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 
 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
-return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
+return mov_read_extradata(c, pb, atom, AV_CODEC_ID_CAVS);
 }
 
 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
-- 
2.25.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] [PATCH 1/3] avfilter/vf_overlay: Add support for yuv444p10 pixel format

2023-07-07 Thread Tobias Rapp
---
 doc/filters.texi |  3 +++
 libavfilter/vf_overlay.c | 36 +++-
 libavfilter/vf_overlay.h |  1 +
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index f17488c..3b82edf 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -18605,6 +18605,9 @@ force YUV422p10 output
 @item yuv444
 force YUV444 output
 
+@item yuv444p10
+force YUV444p10 output
+
 @item rgb
 force packed RGB output
 
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 36c04ac..fa39abb 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -156,7 +156,7 @@ static int process_command(AVFilterContext *ctx, const char 
*cmd, const char *ar
 
 static const enum AVPixelFormat alpha_pix_fmts[] = {
 AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
-AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10,
+AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
 AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA,
 AV_PIX_FMT_BGRA, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
 };
@@ -204,6 +204,13 @@ static int query_formats(AVFilterContext *ctx)
 AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE
 };
 
+static const enum AVPixelFormat main_pix_fmts_yuv444p10[] = {
+AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
+};
+static const enum AVPixelFormat overlay_pix_fmts_yuv444p10[] = {
+AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
+};
+
 static const enum AVPixelFormat main_pix_fmts_gbrp[] = {
 AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE
 };
@@ -248,6 +255,10 @@ static int query_formats(AVFilterContext *ctx)
 main_formats= main_pix_fmts_yuv444;
 overlay_formats = overlay_pix_fmts_yuv444;
 break;
+case OVERLAY_FORMAT_YUV444P10:
+main_formats= main_pix_fmts_yuv444p10;
+overlay_formats = overlay_pix_fmts_yuv444p10;
+break;
 case OVERLAY_FORMAT_RGB:
 main_formats= main_pix_fmts_rgb;
 overlay_formats = overlay_pix_fmts_rgb;
@@ -759,6 +770,22 @@ static int blend_slice_yuva444(AVFilterContext *ctx, void 
*arg, int jobnr, int n
 return 0;
 }
 
+static int blend_slice_yuv444p10(AVFilterContext *ctx, void *arg, int jobnr, 
int nb_jobs)
+{
+OverlayContext *s = ctx->priv;
+ThreadData *td = arg;
+blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, 
jobnr, nb_jobs);
+return 0;
+}
+
+static int blend_slice_yuva444p10(AVFilterContext *ctx, void *arg, int jobnr, 
int nb_jobs)
+{
+OverlayContext *s = ctx->priv;
+ThreadData *td = arg;
+blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, 
jobnr, nb_jobs);
+return 0;
+}
+
 static int blend_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int 
nb_jobs)
 {
 OverlayContext *s = ctx->priv;
@@ -902,6 +929,9 @@ static int config_input_main(AVFilterLink *inlink)
 case OVERLAY_FORMAT_YUV444:
 s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : 
blend_slice_yuv444;
 break;
+case OVERLAY_FORMAT_YUV444P10:
+s->blend_slice = s->main_has_alpha ? blend_slice_yuva444p10 : 
blend_slice_yuv444p10;
+break;
 case OVERLAY_FORMAT_RGB:
 s->blend_slice = s->main_has_alpha ? blend_slice_rgba : 
blend_slice_rgb;
 break;
@@ -925,6 +955,9 @@ static int config_input_main(AVFilterLink *inlink)
 case AV_PIX_FMT_YUVA444P:
 s->blend_slice = blend_slice_yuva444;
 break;
+case AV_PIX_FMT_YUVA444P10:
+s->blend_slice = blend_slice_yuva444p10;
+break;
 case AV_PIX_FMT_ARGB:
 case AV_PIX_FMT_RGBA:
 case AV_PIX_FMT_BGRA:
@@ -1084,6 +1117,7 @@ static const AVOption overlay_options[] = {
 { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, 
.flags = FLAGS, .unit = "format" },
 { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, 
{.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" },
 { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, 
.flags = FLAGS, .unit = "format" },
+{ "yuv444p10", "", 0, AV_OPT_TYPE_CONST, 
{.i64=OVERLAY_FORMAT_YUV444P10}, .flags = FLAGS, .unit = "format" },
 { "rgb","", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB},
.flags = FLAGS, .unit = "format" },
 { "gbrp",   "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP},   
.flags = FLAGS, .unit = "format" },
 { "auto",   "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_AUTO},   
.flags = FLAGS, .unit = "format" },
diff --git a/libavfilter/vf_overlay.h b/libavfilter/vf_overlay.h
index 7e65095..5974964 100644
--- a/libavfilter/vf_overlay.h
+++ b/libavfilter/vf_overlay.h
@@ -47,6 +47,7 @@ enum OverlayFormat {
 OVERLAY_FORMAT_YUV422,
 OVERLAY_FORMAT_YUV422P10,
 OVERLAY_FORMAT_YUV444,
+OVERLAY_FORMAT_YUV444P10,
 OVERLAY_FORMAT_RGB,
 OVERLAY_FORMAT

[FFmpeg-devel] [PATCH 2/3] tests/fate: Add test for overlay filter using yuv444p10 output format

2023-07-07 Thread Tobias Rapp
---
 tests/fate/filter-video.mak | 2 +-
 tests/filtergraphs/overlay_yuv444p10| 5 +
 tests/ref/fate/filter-overlay_yuv444p10 | 8 
 3 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 tests/filtergraphs/overlay_yuv444p10
 create mode 100644 tests/ref/fate/filter-overlay_yuv444p10

diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index e6de7de..789ec64 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -213,7 +213,7 @@ fate-filter-vstack: CMD = framecrc -c:v pgmyuv -i $(SRC) 
-c:v pgmyuv -i $(SRC) -
 FATE_FILTER_OVERLAY-$(call FILTERDEMDEC, SCALE OVERLAY, IMAGE2, PGMYUV) += 
fate-filter-overlay
 fate-filter-overlay: CMD = framecrc -c:v pgmyuv -i $(SRC) -c:v pgmyuv -i 
$(SRC) -filter_complex_script $(FILTERGRAPH)
 
-FATE_FILTER_OVERLAY-$(call FILTERDEMDEC, SPLIT SCALE PAD OVERLAY, IMAGE2, 
PGMYUV) += $(addprefix fate-filter-overlay_, rgb yuv420 yuv420p10 nv12 nv21 
yuv422 yuv422p10 yuv444)
+FATE_FILTER_OVERLAY-$(call FILTERDEMDEC, SPLIT SCALE PAD OVERLAY, IMAGE2, 
PGMYUV) += $(addprefix fate-filter-overlay_, rgb yuv420 yuv420p10 nv12 nv21 
yuv422 yuv422p10 yuv444 yuv444p10)
 fate-filter-overlay_%: CMD = framecrc -auto_conversion_filters -c:v pgmyuv -i 
$(SRC) -filter_complex_script $(FILTERGRAPH)
 fate-filter-overlay_yuv420: CMD = framecrc -c:v pgmyuv -i $(SRC) 
-filter_complex_script $(FILTERGRAPH)
 fate-filter-overlay_%p10: CMD = framecrc -auto_conversion_filters -c:v pgmyuv 
-i $(SRC) -filter_complex_script $(FILTERGRAPH) -pix_fmt 
$(@:fate-filter-overlay_%=%)le -frames:v 3
diff --git a/tests/filtergraphs/overlay_yuv444p10 
b/tests/filtergraphs/overlay_yuv444p10
new file mode 100644
index 000..b184277
--- /dev/null
+++ b/tests/filtergraphs/overlay_yuv444p10
@@ -0,0 +1,5 @@
+sws_flags=+accurate_rnd+bitexact;
+split [main][over];
+[over] scale=88:72, format=yuv444p10, pad=96:80:4:4 [overf];
+[main] format=yuv444p10 [mainf];
+[mainf][overf] overlay=240:16:format=yuv444p10
diff --git a/tests/ref/fate/filter-overlay_yuv444p10 
b/tests/ref/fate/filter-overlay_yuv444p10
new file mode 100644
index 000..b74dbcc
--- /dev/null
+++ b/tests/ref/fate/filter-overlay_yuv444p10
@@ -0,0 +1,8 @@
+#tb 0: 1/25
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 352x288
+#sar 0: 0/1
+0,  0,  0,1,   608256, 0xc5ba4285
+0,  1,  1,1,   608256, 0x3066fd50
+0,  2,  2,1,   608256, 0xdb8e68a8
-- 
2.7.4

___
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/3] doc/filters: Extend description of overlay filter format option values

2023-07-07 Thread Tobias Rapp
---
 doc/filters.texi | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 3b82edf..b57bb5a 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -18591,28 +18591,28 @@ Set the format for the output video.
 It accepts the following values:
 @table @samp
 @item yuv420
-force YUV420 output
+force YUV 4:2:0 8-bit planar output
 
 @item yuv420p10
-force YUV420p10 output
+force YUV 4:2:0 10-bit planar output
 
 @item yuv422
-force YUV422 output
+force YUV 4:2:2 8-bit planar output
 
 @item yuv422p10
-force YUV422p10 output
+force YUV 4:2:2 10-bit planar output
 
 @item yuv444
-force YUV444 output
+force YUV 4:4:4 8-bit planar output
 
 @item yuv444p10
-force YUV444p10 output
+force YUV 4:4:4 10-bit planar output
 
 @item rgb
-force packed RGB output
+force RGB 8-bit packed output
 
 @item gbrp
-force planar RGB output
+force RGB 8-bit planar output
 
 @item auto
 automatically pick format
-- 
2.7.4

___
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] avfilter/vf_vidstabdetect: force ASCII mode if possible

2023-07-07 Thread Timo Rothenpieler
Newer versions of the library added a new binary output format, and prefer 
using it by default.
Those binary files seem to cause issues for a lot of users, where ffmpeg fails 
to (sometimes?) read
back the trf file it has just written itself.

My guess is that this might be because of the fopen-mode of "w" below, where 
"wb" would be needed.
But since we can't really know what format the library is about to write, it's 
better to force
it into ASCII mode when possible.
---
 libavfilter/vf_vidstabdetect.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavfilter/vf_vidstabdetect.c b/libavfilter/vf_vidstabdetect.c
index b27b1e40a6..7170f56f81 100644
--- a/libavfilter/vf_vidstabdetect.c
+++ b/libavfilter/vf_vidstabdetect.c
@@ -110,6 +110,10 @@ static int config_input(AVFilterLink *inlink)
 return AVERROR(EINVAL);
 }
 
+#ifdef ASCII_SERIALIZATION_MODE
+md->serializationMode = ASCII_SERIALIZATION_MODE;
+#endif
+
 // set values that are not initialized by the options
 s->conf.algo = 1;
 s->conf.modName  = "vidstabdetect";
-- 
2.34.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] [PATCH v2 00/14] add vvc decoder

2023-07-07 Thread Nuo Mi
Major changes since v1:
* 12 bits and range extension support added.  Thanks to GSOC contributor 
frankplow.
* Make parser and inter prediction blockless to improve performance on high 
core count CPU.

Fixed following review comment since v1:
* Rename vvc prefix for executor, thanks to Lynne and Rémi
* Remove ff_vvc_executor_wakeup and ThreadInfo.idx, thanks to Rémi

Nuo Mi (14):
  vvcdec: add thread executor
  vvcdec: add vvc decoder stub
  vvcdec: add sps, pps, sh parser
  vvcdec: add cabac decoder
  vvcdec: add reference management
  vvcdec: add motion vector decoder
  vvcdec: add inter prediction
  vvcdec: add inv transform 1d
  vvcdec: add intra prediction
  vvcdec: add LMCS, Deblocking, SAO, and ALF filters
  vvcdec: add dsp init and inv transform
  vvcdec: add CTU parser
  vvcdec: add CTU thread logical
  vvcdec: add full vvc decoder

 configure|1 +
 libavcodec/Makefile  |1 +
 libavcodec/allcodecs.c   |1 +
 libavcodec/executor.c|  182 ++
 libavcodec/executor.h|   67 +
 libavcodec/vvc/Makefile  |   17 +
 libavcodec/vvc/vvc_cabac.c   | 2483 +++
 libavcodec/vvc/vvc_cabac.h   |  126 +
 libavcodec/vvc/vvc_ctu.c | 2457 ++
 libavcodec/vvc/vvc_ctu.h |  421 
 libavcodec/vvc/vvc_data.c| 3295 
 libavcodec/vvc/vvc_data.h|   69 +
 libavcodec/vvc/vvc_filter.c  | 1330 ++
 libavcodec/vvc/vvc_filter.h  |   70 +
 libavcodec/vvc/vvc_filter_template.c | 1088 
 libavcodec/vvc/vvc_inter.c   |  992 
 libavcodec/vvc/vvc_inter.h   |   42 +
 libavcodec/vvc/vvc_inter_template.c  | 1473 +++
 libavcodec/vvc/vvc_intra.c   |  771 ++
 libavcodec/vvc/vvc_intra.h   |   49 +
 libavcodec/vvc/vvc_intra_template.c  | 1018 
 libavcodec/vvc/vvc_itx_1d.c  |  713 ++
 libavcodec/vvc/vvc_itx_1d.h  |   52 +
 libavcodec/vvc/vvc_mvs.c | 1803 ++
 libavcodec/vvc/vvc_mvs.h |   46 +
 libavcodec/vvc/vvc_ps.c  | 3436 ++
 libavcodec/vvc/vvc_ps.h  |  828 +++
 libavcodec/vvc/vvc_refs.c|  502 
 libavcodec/vvc/vvc_refs.h|   51 +
 libavcodec/vvc/vvc_thread.c  |  804 ++
 libavcodec/vvc/vvc_thread.h  |   73 +
 libavcodec/vvc/vvcdec.c  | 1204 +
 libavcodec/vvc/vvcdec.h  |  314 +++
 libavcodec/vvc/vvcdsp.c  |  323 +++
 libavcodec/vvc/vvcdsp.h  |  182 ++
 libavcodec/vvc/vvcdsp_template.c |  119 +
 36 files changed, 26403 insertions(+)
 create mode 100644 libavcodec/executor.c
 create mode 100644 libavcodec/executor.h
 create mode 100644 libavcodec/vvc/Makefile
 create mode 100644 libavcodec/vvc/vvc_cabac.c
 create mode 100644 libavcodec/vvc/vvc_cabac.h
 create mode 100644 libavcodec/vvc/vvc_ctu.c
 create mode 100644 libavcodec/vvc/vvc_ctu.h
 create mode 100644 libavcodec/vvc/vvc_data.c
 create mode 100644 libavcodec/vvc/vvc_data.h
 create mode 100644 libavcodec/vvc/vvc_filter.c
 create mode 100644 libavcodec/vvc/vvc_filter.h
 create mode 100644 libavcodec/vvc/vvc_filter_template.c
 create mode 100644 libavcodec/vvc/vvc_inter.c
 create mode 100644 libavcodec/vvc/vvc_inter.h
 create mode 100644 libavcodec/vvc/vvc_inter_template.c
 create mode 100644 libavcodec/vvc/vvc_intra.c
 create mode 100644 libavcodec/vvc/vvc_intra.h
 create mode 100644 libavcodec/vvc/vvc_intra_template.c
 create mode 100644 libavcodec/vvc/vvc_itx_1d.c
 create mode 100644 libavcodec/vvc/vvc_itx_1d.h
 create mode 100644 libavcodec/vvc/vvc_mvs.c
 create mode 100644 libavcodec/vvc/vvc_mvs.h
 create mode 100644 libavcodec/vvc/vvc_ps.c
 create mode 100644 libavcodec/vvc/vvc_ps.h
 create mode 100644 libavcodec/vvc/vvc_refs.c
 create mode 100644 libavcodec/vvc/vvc_refs.h
 create mode 100644 libavcodec/vvc/vvc_thread.c
 create mode 100644 libavcodec/vvc/vvc_thread.h
 create mode 100644 libavcodec/vvc/vvcdec.c
 create mode 100644 libavcodec/vvc/vvcdec.h
 create mode 100644 libavcodec/vvc/vvcdsp.c
 create mode 100644 libavcodec/vvc/vvcdsp.h
 create mode 100644 libavcodec/vvc/vvcdsp_template.c

--
2.25.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] [PATCH v2 01/14] vvcdec: add thread executor

2023-07-07 Thread Nuo Mi
The executor design pattern was inroduced by java

it also adapted by python

Compared to handcrafted thread pool management, it greatly simplifies the 
thread code.
---
 libavcodec/Makefile |   1 +
 libavcodec/executor.c   | 182 
 libavcodec/executor.h   |  67 +++
 libavcodec/vvc/Makefile |   4 +
 4 files changed, 254 insertions(+)
 create mode 100644 libavcodec/executor.c
 create mode 100644 libavcodec/executor.h
 create mode 100644 libavcodec/vvc/Makefile

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 1b0226c089..4a3c7a7a1f 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -62,6 +62,7 @@ OBJS = ac3_parser.o   
  \
xiph.o   \
 
 # subsystems
+include $(SRC_PATH)/libavcodec/vvc/Makefile
 OBJS-$(CONFIG_AANDCTTABLES)+= aandcttab.o
 OBJS-$(CONFIG_AC3DSP)  += ac3dsp.o ac3.o ac3tab.o
 OBJS-$(CONFIG_ADTS_HEADER) += adts_header.o 
mpeg4audio_sample_rates.o
diff --git a/libavcodec/executor.c b/libavcodec/executor.c
new file mode 100644
index 00..c5094f608a
--- /dev/null
+++ b/libavcodec/executor.c
@@ -0,0 +1,182 @@
+/*
+ * VVC video Decoder
+ *
+ * Copyright (C) 2022 Nuo Mi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "libavutil/avutil.h"
+#include "libavutil/thread.h"
+
+#include "executor.h"
+
+typedef struct ThreadInfo {
+Executor *e;
+pthread_t thread;
+} ThreadInfo;
+
+struct Executor {
+TaskletCallbacks cb;
+ThreadInfo *threads;
+uint8_t *local_contexts;
+int thread_count;
+
+pthread_mutex_t lock;
+pthread_cond_t cond;
+int die;
+Tasklet *tasks;
+};
+
+static void remove_task(Tasklet **prev, Tasklet *t)
+{
+*prev  = t->next;
+t->next = NULL;
+}
+
+static void add_task(Tasklet **prev, Tasklet *t)
+{
+t->next = *prev;
+*prev   = t;
+}
+
+static void *executor_worker_task(void *data)
+{
+ThreadInfo *ti = (ThreadInfo*)data;
+Executor *e = ti->e;
+void *lc   = e->local_contexts + (ti - e->threads) * 
e->cb.local_context_size;
+Tasklet **prev;
+TaskletCallbacks *cb = &e->cb;
+
+pthread_mutex_lock(&e->lock);
+while (1) {
+Tasklet* t = NULL;
+if (e->die) break;
+
+for (prev = &e->tasks; *prev; prev = &(*prev)->next) {
+if (cb->ready(*prev, cb->user_data)) {
+t = *prev;
+break;
+}
+}
+if (t) {
+//found one task
+remove_task(prev, t);
+pthread_mutex_unlock(&e->lock);
+cb->run(t, lc, cb->user_data);
+pthread_mutex_lock(&e->lock);
+} else {
+//no task in one loop
+pthread_cond_wait(&e->cond, &e->lock);
+}
+}
+pthread_mutex_unlock(&e->lock);
+return NULL;
+}
+
+Executor* ff_executor_alloc(const TaskletCallbacks *cb, int thread_count)
+{
+Executor *e;
+int i, j, ret;
+if (!cb || !cb->user_data || !cb->ready || !cb->run || 
!cb->priority_higher)
+return NULL;
+e = av_calloc(1, sizeof(*e));
+if (!e)
+return NULL;
+e->cb = *cb;
+
+e->local_contexts = av_calloc(thread_count, e->cb.local_context_size);
+if (!e->local_contexts)
+goto free_executor;
+
+e->threads = av_calloc(thread_count, sizeof(*e->threads));
+if (!e->threads)
+goto free_contexts;
+ret = pthread_mutex_init(&e->lock, NULL);
+if (ret)
+goto free_threads;
+
+ret = pthread_cond_init(&e->cond, NULL);
+if (ret)
+goto destroy_lock;
+
+for (i = 0; i < thread_count; i++) {
+ThreadInfo *ti = e->threads + i;
+ti->e = e;
+ret = pthread_create(&ti->thread, NULL, executor_worker_task, ti);
+if (ret)
+goto join_threads;
+}
+e->thread_count = thread_count;
+return e;
+
+join_threads:
+pthread_mutex_lock(&e->lock);
+e->die = 1;
+pthread_cond_broadcast(&e->cond);
+pthread_mutex_unlock(&e->

[FFmpeg-devel] [PATCH v2 13/14] vvcdec: add CTU thread logical

2023-07-07 Thread Nuo Mi
This is the main entry point for the CTU (Coding Tree Unit) decoder.
The code will divide the CTU decoder into several stages.
It will check the stage dependencies and run the stage decoder.
---
 libavcodec/vvc/Makefile |   3 +-
 libavcodec/vvc/vvc_thread.c | 804 
 libavcodec/vvc/vvc_thread.h |  73 
 3 files changed, 879 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/vvc/vvc_thread.c
 create mode 100644 libavcodec/vvc/vvc_thread.h

diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index e8076329f9..9d13ae5b48 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -13,4 +13,5 @@ OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o  
  \
 vvc/vvc_itx_1d.o\
 vvc/vvc_mvs.o   \
 vvc/vvc_ps.o\
-vvc/vvc_refs.o
\ No newline at end of file
+vvc/vvc_refs.o  \
+vvc/vvc_thread.o
\ No newline at end of file
diff --git a/libavcodec/vvc/vvc_thread.c b/libavcodec/vvc/vvc_thread.c
new file mode 100644
index 00..1a0d465e7d
--- /dev/null
+++ b/libavcodec/vvc/vvc_thread.c
@@ -0,0 +1,804 @@
+/*
+ * VVC thread logic
+ *
+ * Copyright (C) 2023 Nuo Mi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include 
+
+#include "libavutil/thread.h"
+
+#include "vvc_thread.h"
+#include "vvc_ctu.h"
+#include "vvc_filter.h"
+#include "vvc_inter.h"
+#include "vvc_intra.h"
+#include "vvc_refs.h"
+
+typedef struct VVCRowThread {
+VVCTask reconstruct_task;
+VVCTask deblock_v_task;
+VVCTask sao_task;
+atomic_int progress[VVC_PROGRESS_LAST];
+} VVCRowThread;
+
+typedef struct VVCColThread {
+VVCTask deblock_h_task;
+} VVCColThread;
+
+struct VVCFrameThread {
+// error return for tasks
+atomic_int ret;
+
+atomic_uchar *avails;
+
+VVCRowThread *rows;
+VVCColThread *cols;
+VVCTask *tasks;
+
+int ctu_size;
+int ctu_width;
+int ctu_height;
+int ctu_count;
+
+//protected by lock
+int nb_scheduled_tasks;
+int nb_parse_tasks;
+int row_progress[VVC_PROGRESS_LAST];
+
+pthread_mutex_t lock;
+pthread_cond_t  cond;
+};
+
+static int get_avail(const VVCFrameThread *ft, const int rx, const int ry, 
const VVCTaskType type)
+{
+atomic_uchar *avail;
+if (rx < 0 || ry < 0)
+return 1;
+avail = ft->avails + FFMIN(ry,  ft->ctu_height - 1)* ft->ctu_width + 
FFMIN(rx, ft->ctu_width - 1);
+return atomic_load(avail) & (1 << type);
+}
+
+static void set_avail(const VVCFrameThread *ft, const int rx, const int ry, 
const VVCTaskType type)
+{
+atomic_uchar *avail = ft->avails + ry * ft->ctu_width + rx;
+if (rx < 0 || rx >= ft->ctu_width || ry < 0 || ry >= ft->ctu_height)
+return;
+atomic_fetch_or(avail, 1 << type);
+}
+
+void ff_vvc_task_init(VVCTask *task, VVCTaskType type, VVCFrameContext *fc)
+{
+memset(task, 0, sizeof(*task));
+task->type   = type;
+task->fc = fc;
+task->decode_order   = fc->decode_order;
+}
+
+void ff_vvc_parse_task_init(VVCTask *t, VVCTaskType type, VVCFrameContext *fc,
+SliceContext *sc, EntryPoint *ep, const int ctu_idx)
+{
+const VVCFrameThread *ft = fc->frame_thread;
+const int rs = sc->sh.ctb_addr_in_curr_slice[ctu_idx];
+
+ff_vvc_task_init(t, type, fc);
+t->sc = sc;
+t->ep = ep;
+t->ctu_idx = ctu_idx;
+t->rx = rs % ft->ctu_width;
+t->ry = rs / ft->ctu_width;
+}
+
+VVCTask* ff_vvc_task_alloc(void)
+{
+return av_malloc(sizeof(VVCTask));
+}
+
+static int check_colocation_ctu(const VVCFrameContext *fc, const VVCTask *t)
+{
+if (fc->ps.ph->temporal_mvp_enabled_flag || 
fc->ps.sps->sbtmvp_enabled_flag) {
+//-1 to avoid we are waiting for next CTU line.
+const int y = (t->ry << fc->ps.sps->ctb_log2_size_y) - 1;
+VVCFrame *col = fc->ref->collocated_ref;
+if (col && !ff_vvc_check_progress(col, VVC_PROGRESS_MV, y))
+return 0;
+}
+return 1;
+}
+
+static int is_parse_ready(const VVCFrameContext *fc, const VVCTask 

[FFmpeg-devel] [PATCH v2 02/14] vvcdec: add vvc decoder stub

2023-07-07 Thread Nuo Mi
---
 configure   |   1 +
 libavcodec/allcodecs.c  |   1 +
 libavcodec/vvc/Makefile |   3 +-
 libavcodec/vvc/vvcdec.c |  84 +++
 libavcodec/vvc/vvcdec.h | 306 
 5 files changed, 394 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/vvc/vvcdec.c
 create mode 100644 libavcodec/vvc/vvcdec.h

diff --git a/configure b/configure
index d6e78297fe..3d65b4305a 100755
--- a/configure
+++ b/configure
@@ -3025,6 +3025,7 @@ vp6f_decoder_select="vp6_decoder"
 vp7_decoder_select="h264pred videodsp vp8dsp"
 vp8_decoder_select="h264pred videodsp vp8dsp"
 vp9_decoder_select="videodsp vp9_parser vp9_superframe_split_bsf"
+vvc_decoder_select="cabac golomb videodsp"
 wcmv_decoder_select="inflate_wrapper"
 webp_decoder_select="vp8_decoder exif"
 wmalossless_decoder_select="llauddsp"
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 8775d15a4f..f5ac324cd9 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -388,6 +388,7 @@ extern const FFCodec ff_vp9_rkmpp_decoder;
 extern const FFCodec ff_vp9_v4l2m2m_decoder;
 extern const FFCodec ff_vqa_decoder;
 extern const FFCodec ff_vqc_decoder;
+extern const FFCodec ff_vvc_decoder;
 extern const FFCodec ff_wbmp_decoder;
 extern const FFCodec ff_wbmp_encoder;
 extern const FFCodec ff_webp_decoder;
diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index 16cdd04307..0e110206fa 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -1,4 +1,5 @@
 clean::
$(RM) $(CLEANSUFFIXES:%=libavcodec/vvc/%)
 
-OBJS-$(CONFIG_VVC_DECODER)  +=  executor.o
+OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o\
+executor.o
diff --git a/libavcodec/vvc/vvcdec.c b/libavcodec/vvc/vvcdec.c
new file mode 100644
index 00..8d027af0b9
--- /dev/null
+++ b/libavcodec/vvc/vvcdec.c
@@ -0,0 +1,84 @@
+/*
+ * VVC video decoder
+ *
+ * Copyright (C) 2021 Nuo Mi
+ * Copyright (C) 2022 Xu Mu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "config_components.h"
+
+#include "libavcodec/codec_internal.h"
+#include "libavcodec/decode.h"
+#include "libavcodec/golomb.h"
+#include "libavcodec/profiles.h"
+#include "libavcodec/vvc.h"
+
+#include "libavutil/cpu.h"
+
+#include "vvcdec.h"
+
+static int vvc_decode_frame(AVCodecContext *avctx, AVFrame *output,
+int *got_output, AVPacket *avpkt)
+{
+return avpkt->size;
+}
+
+static void vvc_decode_flush(AVCodecContext *avctx)
+{
+}
+
+static av_cold int vvc_decode_free(AVCodecContext *avctx)
+{
+return 0;
+}
+
+static av_cold int vvc_decode_init(AVCodecContext *avctx)
+{
+return 0;
+}
+
+#define OFFSET(x) offsetof(VVCContext, x)
+#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
+
+static const AVOption options[] = {
+{ NULL },
+};
+
+static const AVClass vvc_decoder_class = {
+.class_name = "vvc decoder",
+.item_name  = av_default_item_name,
+.option = options,
+.version= LIBAVUTIL_VERSION_INT,
+};
+
+const FFCodec ff_vvc_decoder = {
+.p.name  = "vvc",
+.p.long_name = NULL_IF_CONFIG_SMALL("VVC (Versatile Video 
Coding)"),
+.p.type  = AVMEDIA_TYPE_VIDEO,
+.p.id= AV_CODEC_ID_VVC,
+.priv_data_size  = sizeof(VVCContext),
+.p.priv_class= &vvc_decoder_class,
+.init= vvc_decode_init,
+.close   = vvc_decode_free,
+FF_CODEC_DECODE_CB(vvc_decode_frame),
+.flush   = vvc_decode_flush,
+.p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | 
AV_CODEC_CAP_OTHER_THREADS,
+.caps_internal   = FF_CODEC_CAP_EXPORTS_CROPPING | 
FF_CODEC_CAP_INIT_CLEANUP |
+   FF_CODEC_CAP_AUTO_THREADS,
+.p.profiles  = NULL_IF_CONFIG_SMALL(ff_vvc_profiles),
+};
diff --git a/libavcodec/vvc/vvcdec.h b/libavcodec/vvc/vvcdec.h
new file mode 100644
index 00..babc908f02
--- /dev/null
+++ b/libavcodec/vvc/vvcdec.h
@@ -0,0 +1,306 @@
+/*
+ * VVC video decoder
+ *
+ * Copyright (C) 2021 Nuo Mi
+ * Copyright (C) 2022 Xu Mu
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can

[FFmpeg-devel] [PATCH v2 04/14] vvcdec: add cabac decoder

2023-07-07 Thread Nuo Mi
add Context-based Adaptive Binary Arithmetic Coding (CABAC) decoder
---
 libavcodec/vvc/Makefile|2 +
 libavcodec/vvc/vvc_cabac.c | 2483 
 libavcodec/vvc/vvc_cabac.h |  126 ++
 libavcodec/vvc/vvc_ctu.c   |   32 +
 libavcodec/vvc/vvc_ctu.h   |  404 ++
 libavcodec/vvc/vvcdec.h|7 +-
 6 files changed, 3052 insertions(+), 2 deletions(-)
 create mode 100644 libavcodec/vvc/vvc_cabac.c
 create mode 100644 libavcodec/vvc/vvc_cabac.h
 create mode 100644 libavcodec/vvc/vvc_ctu.c
 create mode 100644 libavcodec/vvc/vvc_ctu.h

diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index ac51fb8d1d..39f376fddc 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -3,5 +3,7 @@ clean::
 
 OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o\
 executor.o  \
+vvc/vvc_cabac.o \
+vvc/vvc_ctu.o   \
 vvc/vvc_data.o  \
 vvc/vvc_ps.o
diff --git a/libavcodec/vvc/vvc_cabac.c b/libavcodec/vvc/vvc_cabac.c
new file mode 100644
index 00..30d0f38fc3
--- /dev/null
+++ b/libavcodec/vvc/vvc_cabac.c
@@ -0,0 +1,2483 @@
+/*
+ * VVC CABAC decoder
+ *
+ * Copyright (C) 2021 Nuo Mi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "libavcodec/cabac_functions.h"
+
+#include "vvc_cabac.h"
+#include "vvc_ctu.h"
+#include "vvc_data.h"
+
+#define CABAC_MAX_BIN 31
+
+#define CNU 35
+
+enum SyntaxElement {
+ALF_CTB_FLAG= 0,
+ALF_USE_APS_FLAG= ALF_CTB_FLAG  + 9,
+ALF_CTB_CC_CB_IDC,
+ALF_CTB_CC_CR_IDC   = ALF_CTB_CC_CB_IDC + 3,
+ALF_CTB_FILTER_ALT_IDX  = ALF_CTB_CC_CR_IDC + 3,
+SAO_MERGE_FLAG  = ALF_CTB_FILTER_ALT_IDX+ 2,
+SAO_TYPE_IDX,
+SPLIT_CU_FLAG,
+SPLIT_QT_FLAG   = SPLIT_CU_FLAG + 9,
+MTT_SPLIT_CU_VERTICAL_FLAG  = SPLIT_QT_FLAG + 6,
+MTT_SPLIT_CU_BINARY_FLAG= MTT_SPLIT_CU_VERTICAL_FLAG+ 5,
+NON_INTER_FLAG  = MTT_SPLIT_CU_BINARY_FLAG  + 4,
+CU_SKIP_FLAG= NON_INTER_FLAG+ 2,
+PRED_MODE_IBC_FLAG  = CU_SKIP_FLAG  + 3,
+PRED_MODE_FLAG  = PRED_MODE_IBC_FLAG+ 3,
+PRED_MODE_PLT_FLAG  = PRED_MODE_FLAG+ 2,
+CU_ACT_ENABLED_FLAG,
+INTRA_BDPCM_LUMA_FLAG,
+INTRA_BDPCM_LUMA_DIR_FLAG,
+INTRA_MIP_FLAG,
+INTRA_LUMA_REF_IDX  = INTRA_MIP_FLAG+ 4,
+INTRA_SUBPARTITIONS_MODE_FLAG   = INTRA_LUMA_REF_IDX+ 2,
+INTRA_SUBPARTITIONS_SPLIT_FLAG,
+INTRA_LUMA_MPM_FLAG,
+INTRA_LUMA_NOT_PLANAR_FLAG,
+INTRA_BDPCM_CHROMA_FLAG = INTRA_LUMA_NOT_PLANAR_FLAG+ 2,
+INTRA_BDPCM_CHROMA_DIR_FLAG,
+CCLM_MODE_FLAG,
+CCLM_MODE_IDX,
+INTRA_CHROMA_PRED_MODE,
+GENERAL_MERGE_FLAG,
+INTER_PRED_IDC,
+INTER_AFFINE_FLAG   = INTER_PRED_IDC+ 6,
+CU_AFFINE_TYPE_FLAG = INTER_AFFINE_FLAG + 3,
+SYM_MVD_FLAG,
+REF_IDX_LX,
+MVP_LX_FLAG = REF_IDX_LX+ 2,
+AMVR_FLAG,
+AMVR_PRECISION_IDX  = AMVR_FLAG + 2,
+BCW_IDX = AMVR_PRECISION_IDX+ 3,
+CU_CODED_FLAG,
+CU_SBT_FLAG,
+CU_SBT_QUAD_FLAG= CU_SBT_FLAG   + 2,
+CU_SBT_HORIZONTAL_FLAG,
+CU_SBT_POS_FLAG = CU_SBT_HORIZONTAL_FLAG+ 3,
+LFNST_IDX,
+MTS_IDX = LFNST_IDX + 3,
+COPY_ABOVE_PALETTE_INDICES_FLAG = MTS_IDX   + 4,
+PALETTE_TRANSPOSE_FLAG,
+RUN_COPY_FLAG,
+REGULAR_MERGE_FLAG  = RUN_COPY_FLAG + 8,
+MMVD_MERGE_FLAG = REGULAR_MERGE_FLAG+ 2,
+MMVD_CAND_FLAG,
+MMVD_DISTANCE_IDX,
+

[FFmpeg-devel] [PATCH v2 14/14] vvcdec: add full vvc decoder

2023-07-07 Thread Nuo Mi
vvc decoder plug-in to avcodec.
split frames into slices/tiles and send them to vvc_thread for further decoding
reorder and wait for the frame decoding to be done and output the frame

Features:
+ Support I, P, B frames
+ Support 8/10/12 bits, chroma 400, 420, 422, and 444 and range extension
+ Support VVC new tools like MIP, CCLM, AFFINE, GPM, DMVR, PROF, BDOF, 
LMCS, ALF
+ 295 conformace clips passed
- Not support RPR, IBC, PALETTE, and other minor features yet

C code FPS on i7-12700:
RitualDance_1920x1080_60_10_420_32_LD.266   129.7
Tango2_3840x2160_60_10_420_27_RA.26626.7
RitualDance_1920x1080_60_10_420_37_RA.266   144.3
Tango2_3840x2160_60_10_420_27_LD.26629.0
BQTerrace_1920x1080_60_10_420_22_RA.vvc 75.0
NovosobornayaSquare_1920x1080.bin   167.7
Chimera_8bit_1080P_1000_frames.vvc  155.3

Asm optimizations still working in progress. please check
https://github.com/ffvvc/FFmpeg/wiki#performance-data for the latest

Contributors(based on code merge order):
Nuo Mi 
Xu Mu 
frankplow 
Shaun Loo 
---
 libavcodec/vvc/vvcdec.c | 1122 ++-
 1 file changed, 1121 insertions(+), 1 deletion(-)

diff --git a/libavcodec/vvc/vvcdec.c b/libavcodec/vvc/vvcdec.c
index 8d027af0b9..33519a9733 100644
--- a/libavcodec/vvc/vvcdec.c
+++ b/libavcodec/vvc/vvcdec.c
@@ -24,32 +24,1152 @@
 
 #include "libavcodec/codec_internal.h"
 #include "libavcodec/decode.h"
-#include "libavcodec/golomb.h"
 #include "libavcodec/profiles.h"
 #include "libavcodec/vvc.h"
 
 #include "libavutil/cpu.h"
+#include "libavutil/thread.h"
 
 #include "vvcdec.h"
+#include "vvc_ctu.h"
+#include "vvc_data.h"
+#include "vvc_refs.h"
+#include "vvc_thread.h"
+
+static int vvc_frame_start(VVCContext *s, VVCFrameContext *fc, SliceContext 
*sc)
+{
+VVCPH *ph = s->ps.ph;
+const VVCSH *sh = &sc->sh;
+int ret;
+if (s->no_output_before_recovery_flag) {
+if (IS_GDR(s))
+s->gdr_recovery_point_poc = ph->poc + ph->recovery_poc_cnt;
+if (!GDR_IS_RECOVERED(s) && s->gdr_recovery_point_poc <= ph->poc)
+GDR_SET_RECOVERED(s);
+}
+
+// 8.3.1 Decoding process for picture order count
+if (!s->temporal_id && !ph->non_ref_pic_flag && !(IS_RASL(s) || 
IS_RADL(s)))
+s->pocTid0 = ph->poc;
+
+if ((ret = ff_vvc_set_new_ref(s, fc, &fc->frame)) < 0)
+goto fail;
+
+if (!IS_IDR(s))
+ff_vvc_bump_frame(s, fc);
+
+av_frame_unref(fc->output_frame);
+
+if ((ret = ff_vvc_output_frame(s, fc, fc->output_frame, 
sh->no_output_of_prior_pics_flag, 0)) < 0)
+goto fail;
+
+if ((ret = ff_vvc_frame_rpl(s, fc, sc)) < 0)
+goto fail;
+
+if ((ret = ff_vvc_frame_thread_init(fc)) < 0)
+goto fail;
+return 0;
+fail:
+if (fc->ref)
+ff_vvc_unref_frame(fc, fc->ref, ~0);
+fc->ref = NULL;
+return ret;
+}
+
+static void ctb_arrays_free(VVCFrameContext *fc)
+{
+av_freep(&fc->tab.deblock);
+av_freep(&fc->tab.sao);
+av_freep(&fc->tab.alf);
+av_freep(&fc->tab.slice_idx);
+av_freep(&fc->tab.coeffs);
+if (fc->tab.ctus) {
+for (int i = 0; i < fc->tab.ctu_count; i++)
+ff_vvc_ctu_free_cus(fc->tab.ctus + i);
+av_freep(&fc->tab.ctus);
+}
+av_buffer_pool_uninit(&fc->rpl_tab_pool);
+}
+
+static int ctb_arrays_init(VVCFrameContext *fc, const int ctu_count, const int 
ctu_size)
+{
+if (fc->tab.ctu_count != ctu_count || fc->tab.ctu_size != ctu_size) {
+ctb_arrays_free(fc);
+fc->tab.deblock = av_calloc(ctu_count, 
sizeof(*fc->tab.deblock));
+fc->tab.sao = av_calloc(ctu_count, sizeof(*fc->tab.sao));
+fc->tab.alf = av_calloc(ctu_count, sizeof(*fc->tab.alf));
+fc->tab.ctus= av_calloc(ctu_count, sizeof(*fc->tab.ctus));
+fc->tab.slice_idx   = av_malloc(ctu_count * 
sizeof(*fc->tab.slice_idx));
+if (!fc->tab.deblock || !fc->tab.sao || !fc->tab.alf || !fc->tab.ctus 
|| !fc->tab.slice_idx )
+return AVERROR(ENOMEM);
+fc->tab.coeffs = av_malloc(ctu_count * sizeof(*fc->tab.coeffs) * 
ctu_size * VVC_MAX_SAMPLE_ARRAYS);
+if (!fc->tab.coeffs)
+return AVERROR(ENOMEM);
+fc->rpl_tab_pool = av_buffer_pool_init(ctu_count * 
sizeof(RefPicListTab), av_buffer_allocz);
+if (!fc->rpl_tab_pool)
+return AVERROR(ENOMEM);
+} else {
+memset(fc->tab.deblock, 0, ctu_count * sizeof(*fc->tab.deblock));
+memset(fc->tab.sao, 0, ctu_count * sizeof(*fc->tab.sao));
+memset(fc->tab.alf, 0, ctu_count * sizeof(*fc->tab.alf));
+for (int i = 0; i < fc->tab.ctu_count; i++)
+ff_vvc_ctu_free_cus(fc->tab.ctus + i);
+memset(fc->tab.ctus, 0, ctu_count * sizeof(*fc->tab.ctus));
+}
+memset(fc->tab.slice_idx, -1, ctu_count * sizeof(*fc->tab.slice_idx));
+
+retu

[FFmpeg-devel] [PATCH v2 06/14] vvcdec: add motion vector decoder

2023-07-07 Thread Nuo Mi
---
 libavcodec/vvc/Makefile  |1 +
 libavcodec/vvc/vvc_ctu.c |   20 +-
 libavcodec/vvc/vvc_ctu.h |2 +
 libavcodec/vvc/vvc_mvs.c | 1803 ++
 libavcodec/vvc/vvc_mvs.h |   46 +
 5 files changed, 1871 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/vvc/vvc_mvs.c
 create mode 100644 libavcodec/vvc/vvc_mvs.h

diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index 9d2e6f60c4..891279e358 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -6,5 +6,6 @@ OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o
\
 vvc/vvc_cabac.o \
 vvc/vvc_ctu.o   \
 vvc/vvc_data.o  \
+vvc/vvc_mvs.o   \
 vvc/vvc_ps.o\
 vvc/vvc_refs.o
diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index 78b13ffb00..cfe26756fe 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -20,7 +20,25 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "vvc_cabac.h"
 #include "vvc_ctu.h"
+#include "vvc_mvs.h"
+
+void ff_vvc_set_neighbour_available(VVCLocalContext *lc,
+const int x0, const int y0, const int w, const int h)
+{
+const int log2_ctb_size = lc->fc->ps.sps->ctb_log2_size_y;
+const int x0b = av_mod_uintp2(x0, log2_ctb_size);
+const int y0b = av_mod_uintp2(y0, log2_ctb_size);
+
+lc->na.cand_up   = (lc->ctb_up_flag   || y0b);
+lc->na.cand_left = (lc->ctb_left_flag || x0b);
+lc->na.cand_up_left  = (x0b || y0b) ? lc->na.cand_left && lc->na.cand_up : 
lc->ctb_up_left_flag;
+lc->na.cand_up_right_sap =
+(x0b + w == 1 << log2_ctb_size) ? lc->ctb_up_right_flag && !y0b : 
lc->na.cand_up;
+lc->na.cand_up_right = lc->na.cand_up_right_sap && (x0 + w) < 
lc->end_of_tiles_x;
+}
+
 
 void ff_vvc_ep_init_stat_coeff(EntryPoint *ep,
const int bit_depth, const int persistent_rice_adaptation_enabled_flag)
@@ -29,4 +47,4 @@ void ff_vvc_ep_init_stat_coeff(EntryPoint *ep,
 ep->stat_coeff[i] =
 persistent_rice_adaptation_enabled_flag ? 2 * (av_log2(bit_depth - 
10)) : 0;
 }
-}
+}
\ No newline at end of file
diff --git a/libavcodec/vvc/vvc_ctu.h b/libavcodec/vvc/vvc_ctu.h
index c3d78c54e7..ee22f667c7 100644
--- a/libavcodec/vvc/vvc_ctu.h
+++ b/libavcodec/vvc/vvc_ctu.h
@@ -400,5 +400,7 @@ struct ALFParams {
 uint8_t applied[3];
 };
 
+//utils
+void ff_vvc_set_neighbour_available(VVCLocalContext *lc, int x0, int y0, int 
w, int h);
 void ff_vvc_ep_init_stat_coeff(EntryPoint *ep, int bit_depth, int 
persistent_rice_adaptation_enabled_flag);
 #endif // AVCODEC_VVC_CTU_H
diff --git a/libavcodec/vvc/vvc_mvs.c b/libavcodec/vvc/vvc_mvs.c
new file mode 100644
index 00..2832e1cb12
--- /dev/null
+++ b/libavcodec/vvc/vvc_mvs.c
@@ -0,0 +1,1803 @@
+/*
+ * VVC motion vector decoder
+ *
+ * Copyright (C) 2023 Nuo Mi
+ * Copyright (C) 2022 Xu Mu
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "vvc_ctu.h"
+#include "vvc_data.h"
+#include "vvc_refs.h"
+#include "vvc_mvs.h"
+
+#define IS_SAME_MV(a, b) (AV_RN64A(a) == AV_RN64A(b))
+
+//check if the two luma locations belong to the same motion estimation region
+static av_always_inline int is_same_mer(const VVCFrameContext *fc, const int 
xN, const int yN, const int xP, const int yP)
+{
+const uint8_t plevel = fc->ps.sps->log2_parallel_merge_level;
+
+return xN >> plevel == xP >> plevel &&
+   yN >> plevel == yP >> plevel;
+}
+
+//return true if we have same mvs and ref_idxs
+static av_always_inline int compare_mv_ref_idx(const MvField *n, const MvField 
*o)
+{
+if (!o || n->pred_flag != o->pred_flag)
+return 0;
+for (int i = 0; i < 2; i++) {
+PredFlag mask = i + 1;
+if (n->pred_flag & mask) {
+const int same_ref_idx = n->ref_idx[i] == o->ref_idx[i];
+const int same_mv = IS_SAME_MV(n->mv + i, o->mv + i);
+if (!same_ref_idx || !same_mv)
+return 0;
+}
+}
+ret

[FFmpeg-devel] [PATCH v2 07/14] vvcdec: add inter prediction

2023-07-07 Thread Nuo Mi
---
 libavcodec/vvc/Makefile |1 +
 libavcodec/vvc/vvc_inter.c  |  992 ++
 libavcodec/vvc/vvc_inter.h  |   42 +
 libavcodec/vvc/vvc_inter_template.c | 1473 +++
 libavcodec/vvc/vvcdec.h |2 +
 libavcodec/vvc/vvcdsp.h |  182 
 6 files changed, 2692 insertions(+)
 create mode 100644 libavcodec/vvc/vvc_inter.c
 create mode 100644 libavcodec/vvc/vvc_inter.h
 create mode 100644 libavcodec/vvc/vvc_inter_template.c
 create mode 100644 libavcodec/vvc/vvcdsp.h

diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index 891279e358..d6870625f8 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -6,6 +6,7 @@ OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o
\
 vvc/vvc_cabac.o \
 vvc/vvc_ctu.o   \
 vvc/vvc_data.o  \
+vvc/vvc_inter.o \
 vvc/vvc_mvs.o   \
 vvc/vvc_ps.o\
 vvc/vvc_refs.o
diff --git a/libavcodec/vvc/vvc_inter.c b/libavcodec/vvc/vvc_inter.c
new file mode 100644
index 00..f4734337e5
--- /dev/null
+++ b/libavcodec/vvc/vvc_inter.c
@@ -0,0 +1,992 @@
+/*
+ * VVC inter prediction
+ *
+ * Copyright (C) 2022 Nuo Mi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "vvc_data.h"
+#include "vvc_inter.h"
+#include "vvc_mvs.h"
+#include "vvc_refs.h"
+
+static const int bcw_w_lut[] = {4, 5, 3, 10, -2};
+
+static int emulated_edge(const VVCFrameContext *fc, uint8_t *dst, const 
uint8_t **src, ptrdiff_t *src_stride,
+const int x_off, const int y_off, const int block_w, const int block_h, 
const int is_luma)
+{
+const int extra_before = is_luma ? LUMA_EXTRA_BEFORE : CHROMA_EXTRA_BEFORE;
+const int extra_after  = is_luma ? LUMA_EXTRA_AFTER : CHROMA_EXTRA_AFTER;
+const int extra= is_luma ? LUMA_EXTRA : CHROMA_EXTRA;
+const int pic_width= is_luma ? fc->ps.pps->width  : (fc->ps.pps->width 
>> fc->ps.sps->hshift[1]);
+const int pic_height   = is_luma ? fc->ps.pps->height : 
(fc->ps.pps->height >> fc->ps.sps->vshift[1]);
+
+if (x_off < extra_before || y_off < extra_before ||
+x_off >= pic_width - block_w - extra_after ||
+y_off >= pic_height - block_h - extra_after) {
+const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << 
fc->ps.sps->pixel_shift;
+int offset = extra_before * *src_stride  + (extra_before << 
fc->ps.sps->pixel_shift);
+int buf_offset = extra_before * edge_emu_stride + (extra_before << 
fc->ps.sps->pixel_shift);
+
+fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, 
*src_stride,
+block_w + extra, block_h + extra, x_off - extra_before, y_off - 
extra_before,
+pic_width, pic_height);
+
+*src = dst + buf_offset;
+*src_stride = edge_emu_stride;
+return 1;
+}
+return 0;
+}
+
+static void emulated_edge_dmvr(const VVCFrameContext *fc, uint8_t *dst, const 
uint8_t **src, ptrdiff_t *src_stride,
+const int x_sb, const int y_sb, const int x_off, const int y_off, const 
int block_w, const int block_h, const int is_luma)
+{
+const int extra_before = is_luma ? LUMA_EXTRA_BEFORE : CHROMA_EXTRA_BEFORE;
+const int extra_after  = is_luma ? LUMA_EXTRA_AFTER : CHROMA_EXTRA_AFTER;
+const int extra= is_luma ? LUMA_EXTRA : CHROMA_EXTRA;
+const int pic_width= is_luma ? fc->ps.pps->width  : (fc->ps.pps->width 
>> fc->ps.sps->hshift[1]);
+const int pic_height   = is_luma ? fc->ps.pps->height : 
(fc->ps.pps->height >> fc->ps.sps->vshift[1]);
+
+if (x_off < extra_before || y_off < extra_before ||
+x_off >= pic_width - block_w - extra_after ||
+y_off >= pic_height - block_h - extra_after||
+(x_off != x_sb || y_off !=  y_sb)) {
+const int ps= fc->ps.sps->pixel_shift;
+const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << ps;
+const int offset= extra

[FFmpeg-devel] [PATCH v2 11/14] vvcdec: add dsp init and inv transform

2023-07-07 Thread Nuo Mi
---
 libavcodec/vvc/Makefile  |   3 +-
 libavcodec/vvc/vvcdsp.c  | 323 +++
 libavcodec/vvc/vvcdsp_template.c | 119 
 3 files changed, 444 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/vvc/vvcdsp.c
 create mode 100644 libavcodec/vvc/vvcdsp_template.c

diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index 32d08ff60b..e8076329f9 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -3,6 +3,7 @@ clean::
 
 OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o\
 executor.o  \
+vvc/vvcdsp.o\
 vvc/vvc_cabac.o \
 vvc/vvc_ctu.o   \
 vvc/vvc_data.o  \
@@ -12,4 +13,4 @@ OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o  
  \
 vvc/vvc_itx_1d.o\
 vvc/vvc_mvs.o   \
 vvc/vvc_ps.o\
-vvc/vvc_refs.o
+vvc/vvc_refs.o
\ No newline at end of file
diff --git a/libavcodec/vvc/vvcdsp.c b/libavcodec/vvc/vvcdsp.c
new file mode 100644
index 00..bb1590838d
--- /dev/null
+++ b/libavcodec/vvc/vvcdsp.c
@@ -0,0 +1,323 @@
+/*
+ * VVC DSP
+ *
+ * Copyright (C) 2021 Nuo Mi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "vvcdsp.h"
+#include "vvc_ctu.h"
+#include "vvc_itx_1d.h"
+
+#define VVC_SIGN(v) (v < 0 ? -1 : !!v)
+
+DECLARE_ALIGNED(16, const int8_t, ff_vvc_chroma_filters)[3][32][4] = {
+{
+//1x, Table 33
+{  0, 64,  0,  0 },
+{ -1, 63,  2,  0 },
+{ -2, 62,  4,  0 },
+{ -2, 60,  7, -1 },
+{ -2, 58, 10, -2 },
+{ -3, 57, 12, -2 },
+{ -4, 56, 14, -2 },
+{ -4, 55, 15, -2 },
+{ -4, 54, 16, -2 },
+{ -5, 53, 18, -2 },
+{ -6, 52, 20, -2 },
+{ -6, 49, 24, -3 },
+{ -6, 46, 28, -4 },
+{ -5, 44, 29, -4 },
+{ -4, 42, 30, -4 },
+{ -4, 39, 33, -4 },
+{ -4, 36, 36, -4 },
+{ -4, 33, 39, -4 },
+{ -4, 30, 42, -4 },
+{ -4, 29, 44, -5 },
+{ -4, 28, 46, -6 },
+{ -3, 24, 49, -6 },
+{ -2, 20, 52, -6 },
+{ -2, 18, 53, -5 },
+{ -2, 16, 54, -4 },
+{ -2, 15, 55, -4 },
+{ -2, 14, 56, -4 },
+{ -2, 12, 57, -3 },
+{ -2, 10, 58, -2 },
+{ -1,  7, 60, -2 },
+{  0,  4, 62, -2 },
+{  0,  2, 63, -1 },
+},
+{
+//1.5x, Table 34
+{ 12, 40, 12,  0 },
+{ 11, 40, 13,  0 },
+{ 10, 40, 15, -1 },
+{  9, 40, 16, -1 },
+{  8, 40, 17, -1 },
+{  8, 39, 18, -1 },
+{  7, 39, 19, -1 },
+{  6, 38, 21, -1 },
+{  5, 38, 22, -1 },
+{  4, 38, 23, -1 },
+{  4, 37, 24, -1 },
+{  3, 36, 25,  0 },
+{  3, 35, 26,  0 },
+{  2, 34, 28,  0 },
+{  2, 33, 29,  0 },
+{  1, 33, 30,  0 },
+{  1, 31, 31,  1 },
+{  0, 30, 33,  1 },
+{  0, 29, 33,  2 },
+{  0, 28, 34,  2 },
+{  0, 26, 35,  3 },
+{  0, 25, 36,  3 },
+{ -1, 24, 37,  4 },
+{ -1, 23, 38,  4 },
+{ -1, 22, 38,  5 },
+{ -1, 21, 38,  6 },
+{ -1, 19, 39,  7 },
+{ -1, 18, 39,  8 },
+{ -1, 17, 40,  8 },
+{ -1, 16, 40,  9 },
+{ -1, 15, 40, 10 },
+{  0, 13, 40, 11 },
+},
+{
+//2x, Table 35
+{ 17, 30, 17,  0 },
+{ 17, 30, 18, -1 },
+{ 16, 30, 18,  0 },
+{ 16, 30, 18,  0 },
+{ 15, 30, 18,  1 },
+{ 14, 30, 18,  2 },
+{ 13, 29, 19,  3 },
+{ 13, 29, 19,  3 },
+{ 12, 29, 20,  3 },
+{ 11, 28, 21,  4 },
+{ 10, 28, 22,  4 },
+{ 10, 27, 22,  5 },
+{  9, 27, 23,  5 },
+{  9, 26, 24,  5 },
+{  8, 26, 24,  6 },
+{  7, 26, 25,  6 },
+{  7, 25, 25,  7 },
+{  6,

[FFmpeg-devel] [PATCH v2 05/14] vvcdec: add reference management

2023-07-07 Thread Nuo Mi
---
 libavcodec/vvc/Makefile   |   3 +-
 libavcodec/vvc/vvc_refs.c | 502 ++
 libavcodec/vvc/vvc_refs.h |  51 
 3 files changed, 555 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/vvc/vvc_refs.c
 create mode 100644 libavcodec/vvc/vvc_refs.h

diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index 39f376fddc..9d2e6f60c4 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -6,4 +6,5 @@ OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o
\
 vvc/vvc_cabac.o \
 vvc/vvc_ctu.o   \
 vvc/vvc_data.o  \
-vvc/vvc_ps.o
+vvc/vvc_ps.o\
+vvc/vvc_refs.o
diff --git a/libavcodec/vvc/vvc_refs.c b/libavcodec/vvc/vvc_refs.c
new file mode 100644
index 00..4edbf3514f
--- /dev/null
+++ b/libavcodec/vvc/vvc_refs.c
@@ -0,0 +1,502 @@
+/*
+ * VVC reference management
+ *
+ * Copyright (C) 2023 Nuo Mi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include 
+
+#include "libavutil/thread.h"
+
+#include "vvc_refs.h"
+
+#define VVC_FRAME_FLAG_OUTPUT(1 << 0)
+#define VVC_FRAME_FLAG_SHORT_REF (1 << 1)
+#define VVC_FRAME_FLAG_LONG_REF  (1 << 2)
+#define VVC_FRAME_FLAG_BUMPING   (1 << 3)
+
+typedef struct FrameProgress {
+atomic_int progress[VVC_PROGRESS_LAST];
+pthread_mutex_t lock;
+pthread_cond_t cond;
+} FrameProgress;
+
+void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags)
+{
+/* frame->frame can be NULL if context init failed */
+if (!frame->frame || !frame->frame->buf[0])
+return;
+
+frame->flags &= ~flags;
+if (!frame->flags) {
+ff_thread_release_ext_buffer(fc->avctx, &frame->tf);
+
+av_buffer_unref(&frame->progress_buf);
+
+av_buffer_unref(&frame->tab_dmvr_mvf_buf);
+frame->tab_dmvr_mvf = NULL;
+
+av_buffer_unref(&frame->rpl_buf);
+av_buffer_unref(&frame->rpl_tab_buf);
+frame->rpl_tab= NULL;
+
+frame->collocated_ref = NULL;
+}
+}
+
+const RefPicList *ff_vvc_get_ref_list(const VVCFrameContext *fc, const 
VVCFrame *ref, int x0, int y0)
+{
+int x_cb = x0 >> fc->ps.sps->ctb_log2_size_y;
+int y_cb = y0 >> fc->ps.sps->ctb_log2_size_y;
+int pic_width_cb = fc->ps.pps->ctb_width;
+int ctb_addr_rs  = y_cb * pic_width_cb + x_cb;
+
+return (const RefPicList *)ref->rpl_tab[ctb_addr_rs];
+}
+
+void ff_vvc_clear_refs(VVCFrameContext *fc)
+{
+int i;
+for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
+ff_vvc_unref_frame(fc, &fc->DPB[i],
+VVC_FRAME_FLAG_SHORT_REF | VVC_FRAME_FLAG_LONG_REF);
+}
+
+static void free_progress(void *opaque, uint8_t *data)
+{
+FrameProgress *p = (FrameProgress*)data;
+pthread_cond_destroy(&p->cond);
+pthread_mutex_destroy(&p->lock);
+av_free(data);
+}
+
+static AVBufferRef *alloc_progress(void)
+{
+int ret;
+AVBufferRef *buf;
+FrameProgress *p = av_mallocz(sizeof(FrameProgress));
+
+if (!p)
+return NULL;
+ret = pthread_cond_init(&p->cond, NULL);
+if (ret) {
+av_free(p);
+return NULL;
+}
+
+ret = pthread_mutex_init(&p->lock, NULL);
+if (ret) {
+pthread_cond_destroy(&p->cond);
+av_free(p);
+return NULL;
+}
+buf = av_buffer_create((void*)p, sizeof(*p), free_progress, NULL, 0);
+if (!buf)
+free_progress(NULL, (void*)p);
+return buf;
+}
+
+static VVCFrame *alloc_frame(VVCContext *s, VVCFrameContext *fc)
+{
+const VVCPPS *pps = s->ps.pps;
+int i, j, ret;
+for (i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
+VVCFrame *frame = &fc->DPB[i];
+if (frame->frame->buf[0])
+continue;
+
+ret = ff_thread_get_ext_buffer(fc->avctx, &frame->tf,
+   AV_GET_BUFFER_FLAG_REF);
+if (ret < 0)
+return NULL;
+
+frame->rpl_buf = av_buffer_allocz(fc->pkt.nb_nals * 
sizeof(RefPicListTab));
+if (!frame->rpl_buf)
+goto fail;
+
+   

[FFmpeg-devel] [PATCH v2 08/14] vvcdec: add inv transform 1d

2023-07-07 Thread Nuo Mi
---
 libavcodec/vvc/Makefile |   3 +-
 libavcodec/vvc/vvc_itx_1d.c | 713 
 libavcodec/vvc/vvc_itx_1d.h |  52 +++
 3 files changed, 767 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/vvc/vvc_itx_1d.c
 create mode 100644 libavcodec/vvc/vvc_itx_1d.h

diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index d6870625f8..6ffed91e78 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -7,6 +7,7 @@ OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o
\
 vvc/vvc_ctu.o   \
 vvc/vvc_data.o  \
 vvc/vvc_inter.o \
+vvc/vvc_itx_1d.o\
 vvc/vvc_mvs.o   \
 vvc/vvc_ps.o\
-vvc/vvc_refs.o
+vvc/vvc_refs.o
\ No newline at end of file
diff --git a/libavcodec/vvc/vvc_itx_1d.c b/libavcodec/vvc/vvc_itx_1d.c
new file mode 100644
index 00..e96919f41d
--- /dev/null
+++ b/libavcodec/vvc/vvc_itx_1d.c
@@ -0,0 +1,713 @@
+/*
+ * VVC 1D transform
+ *
+ * Copyright (C) 2023 Nuo Mi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* The copyright in this software is being made available under the BSD
+ * License, included below. This software may be subject to other third party
+ * and contributor rights, including patent rights, and no such rights are
+ * granted under this license.
+ *
+ * Copyright (c) 2010-2021, ITU/ISO/IEC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *this list of conditions and the following disclaimer in the documentation
+ *and/or other materials provided with the distribution.
+ *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+ *be used to endorse or promote products derived from this software without
+ *specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* optimizaed with partial butterfly, see Hung C-Y, Landman P (1997)
+   Compact inverse discrete cosine transform circuit for MPEG video decoding.
+ */
+
+#include "vvc_data.h"
+#include "vvc_itx_1d.h"
+#include "libavutil/avutil.h"
+
+/*
+transmatrix[2][2] = {
+{ a,  a },
+{ a, -a },
+}
+ */
+void ff_vvc_inv_dct2_2(int *out, const ptrdiff_t out_stride, const int *in, 
ptrdiff_t in_stride)
+{
+const int a = 64;
+const int x0 = in[0 * in_stride], x1 = in[1 * in_stride];
+
+out[0 * out_stride] = a * (x0 + x1);
+out[1 * out_stride] = a * (x0 - x1);
+}
+
+/*
+transmatrix[4][4] = {
+{ a,  a,  a,  a},
+{ b,  c, -c, -b},
+{ a, -a, -a,  a},
+{ c, -b,  b, -c},
+}
+ */
+void ff_vvc_inv_dct2_4(int *out, const ptrdiff_t out_stride, const int *in, 
ptrdiff_t in_stride)
+{
+const int a = 64, b = 83, c = 36;
+const int x0 = in[0 * in_stride], x1 = in[1 * in_stride];
+const int x2 = in[2 * in_stride], x3 = in[3 * in_stride];
+const int E[2] = {
+a * (x0 +

[FFmpeg-devel] [PATCH v2 12/14] vvcdec: add CTU parser

2023-07-07 Thread Nuo Mi
---
 libavcodec/vvc/vvc_ctu.c | 2378 +-
 libavcodec/vvc/vvc_ctu.h |   11 +
 2 files changed, 2384 insertions(+), 5 deletions(-)

diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index d46a522a0d..4b86925ff7 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -22,8 +22,2359 @@
 
 #include "vvc_cabac.h"
 #include "vvc_ctu.h"
+#include "vvc_inter.h"
 #include "vvc_mvs.h"
 
+#define PROF_TEMP_SIZE (PROF_BLOCK_SIZE) * sizeof(int16_t)
+
+#define TAB_MSM(fc, depth, x, y) fc->tab.msm[(depth)][((y) >> 5) * 
fc->ps.pps->width32 + ((x) >> 5)]
+#define TAB_ISPMF(fc, x, y) fc->tab.ispmf[((y) >> 6) * fc->ps.pps->width64 + 
((x) >> 6)]
+
+typedef enum VVCModeType {
+MODE_TYPE_ALL,
+MODE_TYPE_INTER,
+MODE_TYPE_INTRA,
+} VVCModeType;
+
+static void set_tb_pos(const VVCFrameContext *fc, const TransformBlock *tb)
+{
+const int x_tb  = tb->x0 >> MIN_TU_LOG2;
+const int y_tb  = tb->y0 >> MIN_TU_LOG2;
+const int hs= fc->ps.sps->hshift[tb->c_idx];
+const int vs= fc->ps.sps->vshift[tb->c_idx];
+const int is_chroma = tb->c_idx != 0;
+const int width = FFMAX(1, tb->tb_width >> (MIN_TU_LOG2 - hs));
+const int end   = y_tb + FFMAX(1, tb->tb_height >> (MIN_TU_LOG2 - vs));
+
+for (int y = y_tb; y < end; y++) {
+const int off = y * fc->ps.pps->min_tu_width + x_tb;
+for (int i = 0; i < width; i++) {
+fc->tab.tb_pos_x0[is_chroma][off + i] = tb->x0;
+fc->tab.tb_pos_y0[is_chroma][off + i] = tb->y0;
+}
+memset(fc->tab.tb_width [is_chroma] + off, tb->tb_width,  width);
+memset(fc->tab.tb_height[is_chroma] + off, tb->tb_height, width);
+}
+}
+
+static void set_tb_tab(uint8_t *tab, uint8_t v, const VVCFrameContext *fc,
+const TransformBlock *tb)
+{
+const int width  = tb->tb_width  << fc->ps.sps->hshift[tb->c_idx];
+const int height = tb->tb_height << fc->ps.sps->vshift[tb->c_idx];
+
+for (int h = 0; h < height; h += MIN_TU_SIZE) {
+const int y = (tb->y0 + h) >> MIN_TU_LOG2;
+const int off = y * fc->ps.pps->min_tu_width + (tb->x0 >> MIN_TU_LOG2);
+const int w = FFMAX(1, width >> MIN_TU_LOG2);
+memset(tab + off, v, w);
+}
+}
+
+// 8.7.1 Derivation process for quantization parameters
+static int get_qp_y_pred(const VVCLocalContext *lc)
+{
+const VVCFrameContext *fc = lc->fc;
+const VVCSPS *sps   = fc->ps.sps;
+const VVCPPS *pps   = fc->ps.pps;
+const CodingUnit *cu= lc->cu;
+const int ctb_log2_size = sps->ctb_log2_size_y;
+const int ctb_size_mask = (1 << ctb_log2_size) - 1;
+const int xQg   = lc->parse.cu_qg_top_left_x;
+const int yQg   = lc->parse.cu_qg_top_left_y;
+const int min_cb_width  = fc->ps.pps->min_cb_width;
+const int x_cb  = cu->x0 >> sps->min_cb_log2_size_y;
+const int y_cb  = cu->y0 >> sps->min_cb_log2_size_y;
+const int x_ctb = cu->x0 >> ctb_log2_size;
+const int y_ctb = cu->y0 >> ctb_log2_size;
+const int in_same_ctb_a = ((xQg - 1) >> ctb_log2_size) == x_ctb && (yQg >> 
ctb_log2_size) == y_ctb;
+const int in_same_ctb_b = (xQg >> ctb_log2_size) == x_ctb && ((yQg - 1) >> 
ctb_log2_size) == y_ctb;
+int qPy_pred, qPy_a, qPy_b;
+
+if (lc->na.cand_up) {
+const int first_qg_in_ctu = !(xQg & ctb_size_mask) &&  !(yQg & 
ctb_size_mask);
+const int qPy_up  = fc->tab.qp[LUMA][x_cb + (y_cb - 1) * 
min_cb_width];
+if (first_qg_in_ctu && pps->ctb_to_col_bd[xQg >> ctb_log2_size] == xQg)
+return qPy_up;
+}
+
+// qPy_pred
+qPy_pred = lc->ep->is_first_qg ? lc->sc->sh.slice_qp_y : lc->ep->qp_y;
+
+// qPy_b
+if (!lc->na.cand_up || !in_same_ctb_b)
+qPy_b = qPy_pred;
+else
+qPy_b = fc->tab.qp[LUMA][x_cb + (y_cb - 1) * min_cb_width];
+
+// qPy_a
+if (!lc->na.cand_left || !in_same_ctb_a)
+qPy_a = qPy_pred;
+else
+qPy_a = fc->tab.qp[LUMA][(x_cb - 1) + y_cb * min_cb_width];
+
+av_assert2(qPy_a >= -fc->ps.sps->qp_bd_offset && qPy_a < 63);
+av_assert2(qPy_b >= -fc->ps.sps->qp_bd_offset && qPy_b < 63);
+
+return (qPy_a + qPy_b + 1) >> 1;
+}
+
+static void set_cb_tab(const VVCLocalContext *lc, uint8_t *tab, const uint8_t 
v)
+{
+const VVCFrameContext *fc   = lc->fc;
+const VVCPPS *pps   = fc->ps.pps;
+const CodingUnit *cu= lc->cu;
+const int log2_min_cb_size  = fc->ps.sps->min_cb_log2_size_y;
+const int x_cb  = cu->x0 >> log2_min_cb_size;
+const int y_cb  = cu->y0 >> log2_min_cb_size;
+const int cb_width  = cu->cb_width;
+const int cb_height = cu->cb_height;
+int x   = y_cb * pps->min_cb_width + x_cb;
+
+for (int y = 0; y < (cb_height >> log2_min_cb_size); y++) {
+const int width = cb_width >> log2_min_cb_size;
+
+mem

[FFmpeg-devel] [PATCH v2 09/14] vvcdec: add intra prediction

2023-07-07 Thread Nuo Mi
---
 libavcodec/vvc/Makefile |3 +-
 libavcodec/vvc/vvc_ctu.c|   39 +
 libavcodec/vvc/vvc_ctu.h|2 +
 libavcodec/vvc/vvc_intra.c  |  771 
 libavcodec/vvc/vvc_intra.h  |   49 ++
 libavcodec/vvc/vvc_intra_template.c | 1018 +++
 6 files changed, 1881 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/vvc/vvc_intra.c
 create mode 100644 libavcodec/vvc/vvc_intra.h
 create mode 100644 libavcodec/vvc/vvc_intra_template.c

diff --git a/libavcodec/vvc/Makefile b/libavcodec/vvc/Makefile
index 6ffed91e78..83021e4953 100644
--- a/libavcodec/vvc/Makefile
+++ b/libavcodec/vvc/Makefile
@@ -7,7 +7,8 @@ OBJS-$(CONFIG_VVC_DECODER)  +=  vvc/vvcdec.o
\
 vvc/vvc_ctu.o   \
 vvc/vvc_data.o  \
 vvc/vvc_inter.o \
+vvc/vvc_intra.o \
 vvc/vvc_itx_1d.o\
 vvc/vvc_mvs.o   \
 vvc/vvc_ps.o\
-vvc/vvc_refs.o
\ No newline at end of file
+vvc/vvc_refs.o
diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index cfe26756fe..d46a522a0d 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -24,6 +24,35 @@
 #include "vvc_ctu.h"
 #include "vvc_mvs.h"
 
+void ff_vvc_decode_neighbour(VVCLocalContext *lc, const int x_ctb, const int 
y_ctb,
+const int rx, const int ry, const int rs)
+{
+VVCFrameContext *fc = lc->fc;
+const int ctb_size = fc->ps.sps->ctb_size_y;
+
+lc->end_of_tiles_x = fc->ps.sps->width;
+lc->end_of_tiles_y = fc->ps.sps->height;
+if (fc->ps.pps->ctb_to_col_bd[rx] != fc->ps.pps->ctb_to_col_bd[rx + 1])
+lc->end_of_tiles_x = FFMIN(x_ctb + ctb_size, lc->end_of_tiles_x);
+if (fc->ps.pps->ctb_to_row_bd[ry] != fc->ps.pps->ctb_to_row_bd[ry + 1])
+lc->end_of_tiles_y = FFMIN(y_ctb + ctb_size, lc->end_of_tiles_y);
+
+lc->boundary_flags = 0;
+if (rx > 0 && fc->ps.pps->ctb_to_col_bd[rx] != 
fc->ps.pps->ctb_to_col_bd[rx - 1])
+lc->boundary_flags |= BOUNDARY_LEFT_TILE;
+if (rx > 0 && fc->tab.slice_idx[rs] != fc->tab.slice_idx[rs - 1])
+lc->boundary_flags |= BOUNDARY_LEFT_SLICE;
+if (ry > 0 && fc->ps.pps->ctb_to_row_bd[ry] != 
fc->ps.pps->ctb_to_row_bd[ry - 1])
+lc->boundary_flags |= BOUNDARY_UPPER_TILE;
+if (ry > 0 && fc->tab.slice_idx[rs] != fc->tab.slice_idx[rs - 
fc->ps.pps->ctb_width])
+lc->boundary_flags |= BOUNDARY_UPPER_SLICE;
+lc->ctb_left_flag = rx > 0 && !(lc->boundary_flags & BOUNDARY_LEFT_TILE);
+lc->ctb_up_flag   = ry > 0 && !(lc->boundary_flags & BOUNDARY_UPPER_TILE) 
&& !(lc->boundary_flags & BOUNDARY_UPPER_SLICE);
+lc->ctb_up_right_flag = lc->ctb_up_flag && (fc->ps.pps->ctb_to_col_bd[rx] 
== fc->ps.pps->ctb_to_col_bd[rx + 1]) &&
+(fc->ps.pps->ctb_to_row_bd[ry] == fc->ps.pps->ctb_to_row_bd[ry - 1]);
+lc->ctb_up_left_flag = lc->ctb_left_flag && lc->ctb_up_flag;
+}
+
 void ff_vvc_set_neighbour_available(VVCLocalContext *lc,
 const int x0, const int y0, const int w, const int h)
 {
@@ -39,6 +68,16 @@ void ff_vvc_set_neighbour_available(VVCLocalContext *lc,
 lc->na.cand_up_right = lc->na.cand_up_right_sap && (x0 + w) < 
lc->end_of_tiles_x;
 }
 
+void ff_vvc_ctu_free_cus(CTU *ctu)
+{
+while (ctu->cus) {
+CodingUnit *cu  = ctu->cus;
+AVBufferRef *buf= cu->buf;
+
+ctu->cus = ctu->cus->next;
+av_buffer_unref(&buf);
+}
+}
 
 void ff_vvc_ep_init_stat_coeff(EntryPoint *ep,
const int bit_depth, const int persistent_rice_adaptation_enabled_flag)
diff --git a/libavcodec/vvc/vvc_ctu.h b/libavcodec/vvc/vvc_ctu.h
index ee22f667c7..762ac57f0a 100644
--- a/libavcodec/vvc/vvc_ctu.h
+++ b/libavcodec/vvc/vvc_ctu.h
@@ -402,5 +402,7 @@ struct ALFParams {
 
 //utils
 void ff_vvc_set_neighbour_available(VVCLocalContext *lc, int x0, int y0, int 
w, int h);
+void ff_vvc_decode_neighbour(VVCLocalContext *lc, int x_ctb, int y_ctb, int 
rx, int ry, int rs);
+void ff_vvc_ctu_free_cus(CTU *ctu);
 void ff_vvc_ep_init_stat_coeff(EntryPoint *ep, int bit_depth, int 
persistent_rice_adaptation_enabled_flag);
 #endif // AVCODEC_VVC_CTU_H
diff --git a/libavcodec/vvc/vvc_intra.c b/libavcodec/vvc/vvc_intra.c
new file mode 100644
index 00..4243d7886b
--- /dev/null
+++ b/libavcodec/vvc/vvc_intra.c
@@ -0,0 +1,771 @@
+/*
+ * VVC intra prediction
+ *
+ * Copyright (C) 2021 Nuo Mi
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * versio

Re: [FFmpeg-devel] [PATCH v2 03/14] vvcdec: add sps, pps, sh parser

2023-07-07 Thread James Almer

On 7/7/2023 11:05 AM, Nuo Mi wrote:

---
  libavcodec/vvc/Makefile   |4 +-
  libavcodec/vvc/vvc_data.c | 3295 +++
  libavcodec/vvc/vvc_data.h |   69 +
  libavcodec/vvc/vvc_ps.c   | 3436 +
  libavcodec/vvc/vvc_ps.h   |  828 +
  libavcodec/vvc/vvcdec.h   |3 +
  6 files changed, 7634 insertions(+), 1 deletion(-)
  create mode 100644 libavcodec/vvc/vvc_data.c
  create mode 100644 libavcodec/vvc/vvc_data.h
  create mode 100644 libavcodec/vvc/vvc_ps.c
  create mode 100644 libavcodec/vvc/vvc_ps.h


I thought the plan for v2 was to use CBS? Hence you waiting until it was 
pushed.
CBS can store derived values and state, and you can always pass it a 
split AU in a loop if needed.

___
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/hlsenc: fall back to av_get_random_seed() when generating AES128 key

2023-07-07 Thread Michael Niedermayer
On Fri, Jul 07, 2023 at 10:05:50AM +0200, Anton Khirnov wrote:
> Quoting Michael Niedermayer (2023-07-07 02:55:46)
> > 
> > The litteral wording was
> > "that guarantees either cryptographically secure randomness or an error."
> > 
> > that was what i refered to.
> > 
> > the wording used now:
> > "to the best of our ability, and that of the underlying libraries we rely 
> > on) cryptographically secure."
> > 
> > is perfectly fine with me.
> > I would have the same issue if someone said AES gurantees ...
> 
> IMO the two formulations are equivalent whenever it comes to practical
> computing. An algorithm can be mathematically proven to be sound*, but
> any practical computing scheme on actual hardware is always subject to
> software bugs, system misconfiguration, hardware bugs, hardware failure,
> etc.
>

> We use similar wording in other documentation, where e.g. we might
> guarantee that some function returns a NULL-terminated string or so.
> That guarantee is always under the implicit condition that there are no
> bugs and the code runs in the expected environment. The same
> considerations apply here.

Theres a big difference between a bug in our implementation
And us claiming some cryptographic primitive is secure.
It was said previously that we shouldnt do things we lack the experties
on and rather delegate to cryptographic libraries writen and audited by
experts. (where it matters for security not just for playback)
But claiming CSPRNG or AES or anything else is guranteed secure is
exactly such a claim that is not within our experties.

If you claim your code produces a null terminated string that i believe
you (within the bounds you mentioned) but if you tell me AES will always
be secure i wont believe you that unless you have the mathemtical proofs
to back that up (and i read and understood them).

Now all that flawlessness with security primitives from proper security libs and
stuff needs to be taken with a grain of salt too.
just 4 months ago i found 2 issues with teh random number generator in the 
hardware
password manager that i use.
So yeah maybe people feels iam too nitpicky here but honestly id rather be 
nitpicky
on security stuff

thx

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

If you fake or manipulate statistics in a paper in physics you will never
get a job again.
If you fake or manipulate statistics in a paper in medicin you will get
a job for life at the pharma industry.


signature.asc
Description: PGP signature
___
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] [RFC] Release 6.1

2023-07-07 Thread Michael Niedermayer
Hi

On Thu, Jul 06, 2023 at 06:04:41PM +0200, Lynne wrote:
> It's been a while since we've had a release, and we've had
> a lot of new features in.
> We did say we would make releases more often, and I think
> it's about time we have a new release.

yes


> 
> Anything anyone wants to have merged or should we branch
> off 6.1 in a few days?

libavradio needs testing, at least build testing.
all parts of git master are tested automatically by our user base
but anything in seperate repositories might receive less testing
so we should encourage people to test these seperate repositories
for the release

also note iam quite busy ATM, its not the best time for me to
do 6.1, so "in a few days" is a bit too optimistic i think

thx


[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

it is not once nor twice but times without number that the same ideas make
their appearance in the world. -- Aristotle


signature.asc
Description: PGP signature
___
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] [RFC] Release 6.1

2023-07-07 Thread Lynne
Jul 7, 2023, 17:07 by mich...@niedermayer.cc:

> Hi
>
> On Thu, Jul 06, 2023 at 06:04:41PM +0200, Lynne wrote:
>
>> It's been a while since we've had a release, and we've had
>> a lot of new features in.
>> We did say we would make releases more often, and I think
>> it's about time we have a new release.
>>
>
> yes
>
>
>>
>> Anything anyone wants to have merged or should we branch
>> off 6.1 in a few days?
>>
>
> libavradio needs testing, at least build testing.
> all parts of git master are tested automatically by our user base
> but anything in seperate repositories might receive less testing
> so we should encourage people to test these seperate repositories
> for the release
>

It's still quite a new library, its API might change, I think we
should release 6.1 first, then release libavradio, so the next
FFmpeg release has a stable target API-wise to use.

It's fine if you don't have time in the next few days, I have to remove
the old FFT code, which means finishing my DCT/DST lavu/tx patch.
___
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 03/14] vvcdec: add sps, pps, sh parser

2023-07-07 Thread Nuo Mi
Hi James,
thank you for the review.

On Fri, Jul 7, 2023 at 10:28 PM James Almer  wrote:

> On 7/7/2023 11:05 AM, Nuo Mi wrote:
> > ---
> >   libavcodec/vvc/Makefile   |4 +-
> >   libavcodec/vvc/vvc_data.c | 3295 +++
> >   libavcodec/vvc/vvc_data.h |   69 +
> >   libavcodec/vvc/vvc_ps.c   | 3436 +
> >   libavcodec/vvc/vvc_ps.h   |  828 +
> >   libavcodec/vvc/vvcdec.h   |3 +
> >   6 files changed, 7634 insertions(+), 1 deletion(-)
> >   create mode 100644 libavcodec/vvc/vvc_data.c
> >   create mode 100644 libavcodec/vvc/vvc_data.h
> >   create mode 100644 libavcodec/vvc/vvc_ps.c
> >   create mode 100644 libavcodec/vvc/vvc_ps.h
>
> I thought the plan for v2 was to use CBS? Hence you waiting until it was
> pushed.

No. The software decoder depends on frame split, I am waiting for it. :)

> CBS can store derived values and state, and you can always pass it a
> split AU in a loop if needed.
>
We have many problems when if we use CBS as a parameter parser
1. The derived value is only needed by the software decoder. like
VVCPH.lmcs_fwd_lut and VVCPPS.column_width. Storing it in the CBS structure
may have performance implications in on other user cases since they never
use it. for example, Metadata rewriter
2. CBS strictly follows the spec name, making it hard to write a loop like
this
https://github.com/ffvvc/FFmpeg/blob/ae76f43e2e47426544d4dedae1cdc3e16f546458/libavcodec/vvc/vvc_ctu.c#L2136.
We can use a derived variable, but this makes the variable duplicate the
original one.
3. There are so many intermediate names in cbs like abc_minus1. If we use
it directly, we may have need to calculate xxx_minus1 + 1 every time. If we
save abc as a derived value. It will be duplicated again.
4. Using CBS will not save too much code or logic in some cases. Take the
Scaling list as an example, you need a for loop in CBS to read the syntax.
Then you need a duplicated loop in the software decoder to reconstruct the
scaling list.

Again, if Mark agrees and nobody rejects it, I can send out v3 to use it.

___
> 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] Optimization: support for libx264's mb_info

2023-07-07 Thread Carotti, Elias
On Mon, 2023-07-03 at 15:51 +, Carotti, Elias wrote:
> On Sat, 2023-07-01 at 10:33 +0200, Anton Khirnov wrote:
> > CAUTION: This email originated from outside of the organization. Do
> > not click links or open attachments unless you can confirm the
> > sender
> > and know the content is safe.
> > 
> > 
> > 
> > Sorry to still nag you, but I just noticed that unlike
> > video_enc_params,
> > you do not store AVVideoRect size in AVVideoHint. This means that
> > no new fields can be added to AVVideoRect without an ABI break.
> > This
> > seems suboptimal, since I do see potential use for per-block
> > information.
> > 
> 
> Hi Anton,
> I do agree with you. 
> Please find the updated (and rebased) patch attached to this email.
> 
> Best,
> Elias
> 
> P.S. By the way, I would be tempted  (I didn't do that here) to
> declare
> the block_size field as 
> 
> const size_t block_size;
> 
> and then when setting it into av_video_hint_alloc(...) cast away the
> const (it has to be assigned only once, upon allocation of the
> struct),
> just to enforce compiler checking against accidental assignments and
> for better clarity that this is a read-only field, in the general
> case.
> 
> P.P.S.: I'm sending the second part of the patch for libavcodec  as a
> separate email. 


Hi Anton, Hi Stefano,
do you think this solves the issue?
Best
Elias





NICE SRL, viale Monte Grappa 3/5, 20124 Milano, Italia, Registro delle Imprese 
di Milano Monza Brianza Lodi REA n. 2096882, Capitale Sociale: 10.329,14 EUR 
i.v., Cod. Fisc. e P.IVA 01133050052, Societa con Socio Unico


___
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 03/14] vvcdec: add sps, pps, sh parser

2023-07-07 Thread James Almer

On 7/7/2023 12:48 PM, Nuo Mi wrote:

Hi James,
thank you for the review.

On Fri, Jul 7, 2023 at 10:28 PM James Almer  wrote:


On 7/7/2023 11:05 AM, Nuo Mi wrote:

---
   libavcodec/vvc/Makefile   |4 +-
   libavcodec/vvc/vvc_data.c | 3295 +++
   libavcodec/vvc/vvc_data.h |   69 +
   libavcodec/vvc/vvc_ps.c   | 3436 +
   libavcodec/vvc/vvc_ps.h   |  828 +
   libavcodec/vvc/vvcdec.h   |3 +
   6 files changed, 7634 insertions(+), 1 deletion(-)
   create mode 100644 libavcodec/vvc/vvc_data.c
   create mode 100644 libavcodec/vvc/vvc_data.h
   create mode 100644 libavcodec/vvc/vvc_ps.c
   create mode 100644 libavcodec/vvc/vvc_ps.h


I thought the plan for v2 was to use CBS? Hence you waiting until it was
pushed.


No. The software decoder depends on frame split, I am waiting for it. :)


Why do you need that? You can use the receive_frame() API instead of 
decode(), and only request new packets after you're done with the last 
one you got.





CBS can store derived values and state, and you can always pass it a
split AU in a loop if needed.


We have many problems when if we use CBS as a parameter parser
1. The derived value is only needed by the software decoder. like
VVCPH.lmcs_fwd_lut and VVCPPS.column_width. Storing it in the CBS structure
may have performance implications in on other user cases since they never
use it. for example, Metadata rewriter
2. CBS strictly follows the spec name, making it hard to write a loop like
this
https://github.com/ffvvc/FFmpeg/blob/ae76f43e2e47426544d4dedae1cdc3e16f546458/libavcodec/vvc/vvc_ctu.c#L2136.
We can use a derived variable, but this makes the variable duplicate the
original one.


You can store decoder only derived values in a decoder struct, and have 
CBS store derived values required for header parsing within itself (As 
is the case with all the relevant fields at the end of H266RawPPS), plus 
any other that calculated within CBS itself would simplify things for 
users like the decoder.



3. There are so many intermediate names in cbs like abc_minus1. If we use
it directly, we may have need to calculate xxx_minus1 + 1 every time. If we
save abc as a derived value. It will be duplicated again.


Same thing here. After getting a parsed fragment from CBS, you can 
derive all the minus/plus values once and store them in decoder only 
structs, to be used afterwards instead of those in the raw CBS structs.



4. Using CBS will not save too much code or logic in some cases. Take the
Scaling list as an example, you need a for loop in CBS to read the syntax.
Then you need a duplicated loop in the software decoder to reconstruct the
scaling list.


The core gain is to prevent the duplication of all the header parsing 
code, and have a single point of failure and source of bugs.


The h264 and hevc decoders predate CBS, so those were obviously written 
as standalone modules, but this one doesn't, so ideally we should 
prevent duplicating huge bitstream parsing functions a third time.
Look at AV1, which even if not complete (No software implementation yet) 
has plenty of logic to derive values and tables CBS doesn't need to care 
about, but the hwaccel backends (and the eventual software 
implementation once it's ported from libdav1d) obviously need.




Again, if Mark agrees and nobody rejects it, I can send out v3 to use it.

___

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] lavc/libvpxenc: prevent fifo from filling up

2023-07-07 Thread James Zern
On Thu, Jul 6, 2023 at 12:45 AM Anton Khirnov  wrote:
>
> Quoting James Zern (2023-07-05 21:16:37)
> > On Wed, Jul 5, 2023 at 12:15 PM James Zern  wrote:
> > >
> > > Hi,
> > >
> >
> > +ffmpeg-dev. I took the wrong email off the reply.
> >
> > > On Mon, Jul 3, 2023 at 10:08 PM David Lemler  wrote:
> > > >
> > > > Prevent the fifo used in encoding VPx videos from filling up and 
> > > > stopping
> > > > encode when it reaches 21845 items, which happens when the video has 
> > > > more
> > > > than
> > > > that number of frames.
> > > >
> > >
> > > What failure do you see, a memory allocation error? 21845 sounds
> > > somewhat arbitrary, maybe specific to your machine, so I'd leave it
> > > off the comment and commit message.
> > >
> > > > This problem occurs when performing the first pass of a 2-pass encode, 
> > > > as
> > > > otherwise, the fifo is properly drained, preventing it from overflowing.
> > > >
> > > > Problem is fixed by manually draining the fifo when performing the first
> > > > pass
> > > > of a 2-pass encode.
> > > >
> > > > Fixes the regression originally introduced in
> > > > 5bda4ec6c3cb6f286bb40dee4457c3c26e0f78cb
> > > >
> > >
> > > Anton, any comments here?
>
> Is it guaranteed by the libvpx API that no encoded packets are returned
> for the first pass of 2pass encoding? If so, then it probably makes most
> sense not to send anything to the fifo in the first place.
>

You'll only get stats packets in the first pass, no frames.
David, you can check `!(avctx->flags & AV_CODEC_FLAG_PASS1)` before
calling `frame_data_submit()`.
___
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] lavc/libvpxenc: prevent fifo from filling up

2023-07-07 Thread James Zern
On Wed, Jul 5, 2023 at 7:22 PM David Lemler  wrote:
>
> > On 07/05/2023 2:16 PM CDT James Zern  wrote:
> >
> >
> > On Wed, Jul 5, 2023 at 12:15 PM James Zern  wrote:
> > >
> > > Hi,
> > >
> >
> > +ffmpeg-dev. I took the wrong email off the reply.
> >
> > > On Mon, Jul 3, 2023 at 10:08 PM David Lemler  wrote:
> > > >
> > > > Prevent the fifo used in encoding VPx videos from filling up and 
> > > > stopping
> > > > encode when it reaches 21845 items, which happens when the video has 
> > > > more
> > > > than
> > > > that number of frames.
> > > >
> > >
> > > What failure do you see, a memory allocation error? 21845 sounds
> > > somewhat arbitrary, maybe specific to your machine, so I'd leave it
> > > off the comment and commit message.
> > >
>
> When running a command like the following to perform the first pass of a
> 2-pass VP9 encode:
>
> ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 31 -pass 1 -an \
> -deadline best -threads 8 -row-mt 1 -f null /dev/null
>
> ffmpeg exited with the error:
> Error submitting video frame to the encoder
> Conversion failed!
>
> and the ffmpeg2pass-0.log file existed but was empty.
>
> I've tested and reproduced the issue on Intel x86-64 on Windows
> (10 22H2, gyan.dev build) and Linux (Debian 12, own compiled build), and on
> AMD EPYC x86-64 on Linux (Debian 12, own compiled build).  I believe the
> number of frames is (1024 * 1024) / sizeof(FrameData); see lavc/libvpxenc.c
> the call to av_fifo_alloc2 around line 999 and lavutil/fifo.c the assignment
> of f->auto_grow_limit around line 72.  I'm not sure if that calculation
> would change on different systems/architectures.
>

Thanks for the explanation, I didn't look closely enough before making
my comment.
___
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/9] avradio/sdr: use AVTree for candidate stations

2023-07-07 Thread Michael Niedermayer
This is needed so we can keep more information about stations without
performance issues

Signed-off-by: Michael Niedermayer 
---
 libavradio/sdr.h  |   4 +-
 libavradio/sdrdemux.c | 126 --
 2 files changed, 110 insertions(+), 20 deletions(-)

diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 84abdbe1d9..4d6887a296 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -30,6 +30,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
 #include "libavutil/thread.h"
+#include "libavutil/tree.h"
 #include "libavutil/tx.h"
 #include "libavformat/avformat.h"
 
@@ -131,8 +132,7 @@ typedef struct SDRContext {
  * Current list of detected stations, these can be overlapping and low 
quality detections.
  * Used for probing. Stations are not removed from this when added to 
station.
  */
-Station **candidate_station;
-int nb_candidate_stations;
+struct AVTreeNode *station_root;
 int width, height;
 int single_ch_audio_st_index;
 int waterfall_st_index;
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index d3f0368d7d..4ac360f71b 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -46,6 +46,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
 #include "libavutil/thread.h"
+#include "libavutil/tree.h"
 #include "libavutil/tx.h"
 #include "libavutil/xga_font_data.h"
 #include "libavcodec/kbdwin.h"
@@ -118,6 +119,55 @@ static void free_station(Station *station)
 av_free(station);
 }
 
+typedef struct FindStationContext {
+double freq;
+double range;
+Station **station_list;
+int station_list_size;
+int nb_stations;
+} FindStationContext;
+
+static int find_station_cmp(void *opaque, void *elem)
+{
+FindStationContext *c = opaque;
+Station *station = elem;
+double distance = station->frequency - c->freq;
+if (distance < -c->range)
+return -1;
+if (distance >  c->range)
+return  1;
+return 0;
+}
+
+static int find_station_enu(void *opaque, void *elem)
+{
+FindStationContext *c = opaque;
+if (c->nb_stations < c->station_list_size) {
+c->station_list[c->nb_stations++] = elem;
+} else
+av_log(NULL, AV_LOG_WARNING, "find station reached list size of %d\n", 
c->station_list_size);
+
+return 0;
+}
+
+/**
+ * Find stations within the given parameters.
+ * @param[out] station_list array to return stations in
+ * @param nb_stations size of station array
+ * @returns number of stations found
+ */
+static int find_stations(SDRContext *sdr, double freq, double range, Station 
**station_list, int station_list_size)
+{
+FindStationContext find_station_context;
+find_station_context.freq = freq;
+find_station_context.range = range;
+find_station_context.station_list = station_list;
+find_station_context.station_list_size = station_list_size;
+find_station_context.nb_stations = 0;
+av_tree_enumerate(sdr->station_root, &find_station_context, 
find_station_cmp, find_station_enu);
+return find_station_context.nb_stations;
+}
+
 static int create_station(SDRContext *sdr, Station *candidate_station) {
 enum Modulation modulation  = candidate_station->modulation;
 double freq = candidate_station->frequency;
@@ -165,14 +215,17 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 best_station->timeout = 0;
 return best_station_index;
 }
-for (i=0; inb_candidate_stations; i++) {
+Station *station_list[1000];
+int nb_stations = find_stations(sdr, sdr->block_center_freq, 
sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
+
+for (i=0; icandidate_station[i]->frequency - freq);
+double delta = fabs(station_list[i]->frequency - freq);
 // Station already added, or we have 2 rather close stations
-if (modulation == sdr->candidate_station[i]->modulation && delta < 
freq_precission && sdr->candidate_station[i] != candidate_station) {
+if (modulation == station_list[i]->modulation && delta < 
freq_precission && station_list[i] != candidate_station) {
 nb_candidate_match++;
 }
-if (modulation != sdr->candidate_station[i]->modulation && delta < 
(bandwidth + sdr->candidate_station[i]->bandwidth)/2.1)
+if (modulation != station_list[i]->modulation && delta < (bandwidth + 
station_list[i]->bandwidth)/2.1)
 nb_candidate_conflict++;
 }
 //if we have a recent conflict with an established station, skip this one
@@ -225,18 +278,51 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 
 static void create_stations(SDRContext *sdr)
 {
-for(int i = 0; inb_candidate_stations; i++) {
-Station *candidate_station = sdr->candidate_station[i];
-create_station(sdr, candidate_station);
+Station *station_list[1000];
+
+if (!sdr->block_center_freq)
+return;
+
+int nb_stations 

[FFmpeg-devel] [PATCH 2/9] avradio/sdr: Consolidate candidate station entries

2023-07-07 Thread Michael Niedermayer
also average frequcnies in candiddate station detections

Signed-off-by: Michael Niedermayer 
---
 libavradio/sdr.h  |  1 +
 libavradio/sdrdemux.c | 45 ---
 2 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 4d6887a296..29465df0a1 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -70,6 +70,7 @@ typedef struct Station {
 char *name;
 enum Modulation modulation;
 double frequency;
+int nb_frequency;   ///< number of detections which are used to 
compute the frequency
 int64_t bandwidth;
 int64_t bandwidth_p2;
 float score;
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 4ac360f71b..41eda615ae 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -150,6 +150,12 @@ static int find_station_enu(void *opaque, void *elem)
 return 0;
 }
 
+static int free_station_enu(void *opaque, void *elem)
+{
+free_station(elem);
+return 0;
+}
+
 /**
  * Find stations within the given parameters.
  * @param[out] station_list array to return stations in
@@ -218,15 +224,16 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 Station *station_list[1000];
 int nb_stations = find_stations(sdr, sdr->block_center_freq, 
sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
 
+nb_candidate_match += candidate_station->nb_frequency - 1;
 for (i=0; ifrequency - freq);
 // Station already added, or we have 2 rather close stations
 if (modulation == station_list[i]->modulation && delta < 
freq_precission && station_list[i] != candidate_station) {
-nb_candidate_match++;
+nb_candidate_match += station_list[i]->nb_frequency;
 }
 if (modulation != station_list[i]->modulation && delta < (bandwidth + 
station_list[i]->bandwidth)/2.1)
-nb_candidate_conflict++;
+nb_candidate_conflict += station_list[i]->nb_frequency;
 }
 //if we have a recent conflict with an established station, skip this one
 if (conflict < CANDIDATE_STATION_TIMEOUT)
@@ -355,20 +362,41 @@ static int create_candidate_station(SDRContext *sdr, enum 
Modulation modulation,
 Station *station;
 void *tmp;
 struct AVTreeNode *next = NULL;
+Station *station_list[1000];
+double snapdistance = modulation == AM ? 5 : 50;
+int nb_stations = find_stations(sdr, freq, snapdistance, station_list, 
FF_ARRAY_ELEMS(station_list));
+
+if (nb_stations) {
+for(int i = 1; imodulation != modulation ||
+(station_list[i]->modulation == modulation &&
+ fabs(station_list[0]->frequency - freq) > 
fabs(station_list[i]->frequency - freq)))
+station_list[0] = station_list[i];
+nb_stations = station_list[0]->modulation == modulation;
+}
 
-station = av_mallocz(sizeof(*station));
-if (!station)
-return AVERROR(ENOMEM);
+if (!nb_stations) {
+station = av_mallocz(sizeof(*station));
+if (!station)
+return AVERROR(ENOMEM);
+station->frequency = freq;
+} else {
+station = station_list[0];
+// We will update the frequency so we need to reinsert
+tree_remove(&sdr->station_root, station, station_cmp, &next);
+station->frequency = station->nb_frequency * station->frequency + freq;
+station->timeout   = 0;
+}
+station->frequency /= ++station->nb_frequency;
 
 station->modulation   = modulation;
-station->frequency= freq;
 station->bandwidth= bandwidth;
 station->bandwidth_p2 = bandwidth_p2;
 station->score= score;
 
 tmp = tree_insert(&sdr->station_root, station, station_cmp, &next);
 if (tmp && tmp != station) {
-//unlikely
+//This will not happen in real C implementations but floats allow odd 
things in theory
 av_freep(&station);
 }
 av_freep(&next);
@@ -2025,6 +2053,9 @@ int avpriv_sdr_read_close(AVFormatContext *s)
 }
 sdr->nb_stations = 0;
 av_freep(&sdr->station);
+av_tree_enumerate(sdr->station_root, NULL, NULL, free_station_enu);
+av_tree_destroy(sdr->station_root);
+sdr->station_root = NULL;
 
 av_freep(&sdr->windowed_block);
 av_freep(&sdr->block);
-- 
2.31.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] [PATCH 3/9] avradio/sdr: consolidate the candidate station list with the main list

2023-07-07 Thread Michael Niedermayer
This way any updates to one is reflected in the other
---
 libavradio/sdr.h  |  1 +
 libavradio/sdrdemux.c | 53 ++-
 2 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 29465df0a1..4b1543efd3 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -74,6 +74,7 @@ typedef struct Station {
 int64_t bandwidth;
 int64_t bandwidth_p2;
 float score;
+int in_station_list;///< non zero if this station is in the station 
list
 int timeout;//since how many blocks was this detectable but 
not detected
 int multiplex_index;//DAB can have multiple stations on one frequency
 
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 41eda615ae..7744ecdac0 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -180,7 +180,6 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 int64_t bandwidth   = candidate_station->bandwidth;
 int64_t bandwidth_p2= candidate_station->bandwidth_p2;
 float score = candidate_station->score;
-Station *station;
 void *tmp;
 int i;
 Station *best_station = NULL;
@@ -191,6 +190,9 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 int nb_candidate_conflict = 0;
 int nb_candidate_match = 0;
 
+if (candidate_station->in_station_list)
+return 0;
+
 for (i=0; inb_stations; i++) {
 double delta = fabs(sdr->station[i]->frequency - freq);
 // Station already added, or we have 2 rather close stations
@@ -215,10 +217,16 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 best_station->score, score,
 best_station->frequency - freq, best_station->frequency, 
freq
 );
-best_station->frequency  = freq;
-best_station->score  = score;
+
+if (best_station->stream) {
+candidate_station->stream = best_station->stream;
+best_station->stream = NULL;
+candidate_station->stream->station = candidate_station;
+}
+candidate_station->in_station_list = 1;
+best_station->in_station_list = 0;
+sdr->station[best_station_index] = candidate_station;
 }
-best_station->timeout = 0;
 return best_station_index;
 }
 Station *station_list[1000];
@@ -227,17 +235,21 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 nb_candidate_match += candidate_station->nb_frequency - 1;
 for (i=0; ifrequency - freq);
+Station *s = station_list[i];
+double delta = fabs(s->frequency - freq);
+
 // Station already added, or we have 2 rather close stations
-if (modulation == station_list[i]->modulation && delta < 
freq_precission && station_list[i] != candidate_station) {
-nb_candidate_match += station_list[i]->nb_frequency;
+if (modulation == s->modulation && delta < freq_precission && s != 
candidate_station) {
+nb_candidate_match += s->nb_frequency;
 }
-if (modulation != station_list[i]->modulation && delta < (bandwidth + 
station_list[i]->bandwidth)/2.1)
-nb_candidate_conflict += station_list[i]->nb_frequency;
+if (modulation != s->modulation && delta < (bandwidth + 
s->bandwidth)/2.1)
+nb_candidate_conflict += s->nb_frequency;
 }
 //if we have a recent conflict with an established station, skip this one
 if (conflict < CANDIDATE_STATION_TIMEOUT)
 return -1;
+if (conflict < candidate_station->timeout)
+return -1;
 
 //AM detection is less reliable ATM so we dont want it to override FM 
stations
 if (modulation == AM && conflict < INT_MAX)
@@ -255,7 +267,8 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 // We recheck that the stations we remove are not active because 
floating point could round differently
 if (sdr->station[i]->stream == NULL &&
 modulation != sdr->station[i]->modulation && delta < 
(bandwidth + sdr->station[i]->bandwidth)/2.1) {
-free_station(sdr->station[i]);
+
+sdr->station[i]->in_station_list = 0;
 sdr->station[i--] = sdr->station[--sdr->nb_stations];
 }
 }
@@ -266,17 +279,8 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 return AVERROR(ENOMEM);
 sdr->station = tmp;
 
-station = av_mallocz(sizeof(*station));
-if (!station)
-return AVERROR(ENOMEM);
-
-sdr->station[sdr->nb_stations++] = station;
-
-station->modulation   = modulation;
-station->frequency= freq;
-station->bandwidth= bandwidth;
-station->bandwidth_p2 = bandwidth_p2;
-station->score= score;
+sdr->sta

[FFmpeg-devel] [PATCH 4/9] avradio/sdr: Eliminate station list

2023-07-07 Thread Michael Niedermayer
Its redudnant with the AVTree information
Makes the code simpler

Signed-off-by: Michael Niedermayer 
---
 libavradio/sdr.h  |   9 
 libavradio/sdrdemux.c | 107 ++
 2 files changed, 55 insertions(+), 61 deletions(-)

diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 4b1543efd3..00066850f9 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -125,15 +125,6 @@ typedef struct SDRContext {
 char *dump_url;
 int fileheader_size;
 AVIOContext *dump_avio;
-/**
- * Current list of unambigously detected stations
- */
-Station **station;
-int nb_stations;
-/**
- * Current list of detected stations, these can be overlapping and low 
quality detections.
- * Used for probing. Stations are not removed from this when added to 
station.
- */
 struct AVTreeNode *station_root;
 int width, height;
 int single_ch_audio_st_index;
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 7744ecdac0..769cf3ade6 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -183,7 +183,6 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 void *tmp;
 int i;
 Station *best_station = NULL;
-int best_station_index = -1;
 float drift = bandwidth/3.0;
 double best_distance = drift;
 int conflict = INT_MAX;
@@ -193,27 +192,32 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 if (candidate_station->in_station_list)
 return 0;
 
-for (i=0; inb_stations; i++) {
-double delta = fabs(sdr->station[i]->frequency - freq);
+Station *station_list[1000];
+int nb_stations = find_stations(sdr, sdr->block_center_freq, 
sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
+for (i=0; ifrequency - freq);
+
+if (!s->in_station_list)
+continue;
+
 // Station already added, or we have 2 rather close stations
 //FIXME we want to make sure that the stronger station is not skiped 
but we also dont want to add a station twice
-if (modulation == sdr->station[i]->modulation && delta < 
best_distance) {
+if (modulation == s->modulation && delta < best_distance) {
 best_distance = delta;
-best_station = sdr->station[i];
-best_station_index = i;
+best_station = s;
 }
-if (modulation != sdr->station[i]->modulation && delta < (bandwidth + 
sdr->station[i]->bandwidth)/2.1) {
-conflict = FFMIN(conflict, sdr->station[i]->timeout);
+if (modulation !=s->modulation && delta < (bandwidth + 
s->bandwidth)/2.1) {
+conflict = FFMIN(conflict, s->timeout);
 // special case, lets not remove an actively listen to station, 
this can be done too but that needs more thought
-if (sdr->station[i]->stream)
+if (s->stream)
 conflict = 0;
 }
 }
 if (best_station) {
 if (score > best_station->score && conflict == INT_MAX) {
 int log_level = fabs(best_station->frequency - freq) < 3.0 ? 
AV_LOG_DEBUG : AV_LOG_WARNING;
-av_log(sdr->avfmt, log_level, "Update station %d score:%f -> %f 
freq: %f %f -> %f\n",
-best_station_index,
+av_log(sdr->avfmt, log_level, "Update station score:%f -> %f freq: 
%f %f -> %f\n",
 best_station->score, score,
 best_station->frequency - freq, best_station->frequency, 
freq
 );
@@ -225,12 +229,9 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 }
 candidate_station->in_station_list = 1;
 best_station->in_station_list = 0;
-sdr->station[best_station_index] = candidate_station;
 }
-return best_station_index;
+return 2;
 }
-Station *station_list[1000];
-int nb_stations = find_stations(sdr, sdr->block_center_freq, 
sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
 
 nb_candidate_match += candidate_station->nb_frequency - 1;
 for (i=0; inb_stations; i++) {
-double delta = fabs(sdr->station[i]->frequency - freq);
+for (i=0; ifrequency - freq);
 // We recheck that the stations we remove are not active because 
floating point could round differently
-if (sdr->station[i]->stream == NULL &&
-modulation != sdr->station[i]->modulation && delta < 
(bandwidth + sdr->station[i]->bandwidth)/2.1) {
+if (s->stream == NULL &&
+modulation != s->modulation && delta < (bandwidth + 
s->bandwidth)/2.1) {
 
-sdr->station[i]->in_station_list = 0;
-sdr->station[i--] = sdr->station[--sdr->nb_stations];
+s->in_station_list = 0;
 }
 }
 }
 
-tmp = av_realloc_array(sdr->station, sdr->nb_stations+1, 
sizeof(*sdr->s

[FFmpeg-devel] [PATCH 5/9] avradio/sdr: Allow user to adjust FM/AM thresholds

2023-07-07 Thread Michael Niedermayer
Signed-off-by: Michael Niedermayer 
---
 doc/demuxers.texi |  9 +
 libavradio/sdr.h  |  3 +++
 libavradio/sdrdemux.c | 18 +++---
 3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index fc2ab9fc27..81c46ce08f 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -956,6 +956,15 @@ for debuging.
 @item kbd_alpha
 Kaiser Bessel derived window parameter
 
+@item am_threshold
+AM station detection threshold
+
+@item fm_threshold
+FM station detection threshold, a lower value allows detection of weaker 
stations but
+it can also result in the detection of SDR artifacts such as reflections of 
strong FM stations
+as weak stations. Future versions may be better able to separate weak stations 
from artifacts
+looking like weak stations.
+
 @item am_mode
 AM Demodulation method. Several different methods are supported.
 @table @samp
diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 00066850f9..838fb1cef7 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -152,6 +152,9 @@ typedef struct SDRContext {
 int emphasis_mode;
 int am_fft_ref;
 
+float am_threshold;
+float fm_threshold;
+
 pthread_t hw_thread;
 int thread_started;
 pthread_mutex_t mutex;  ///< Mutex to protect common 
variable between mainthread and hw_thread, and also to protect soapy from 
concurrent calls
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 769cf3ade6..ad3e253ced 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -64,17 +64,9 @@
 #define STATION_TIMEOUT 100 ///< The number of frames after which a station is 
removed if it was not detected
 #define CANDIDATE_STATION_TIMEOUT 4
 
-/*
- * 100 detects nothing
- * 50 detects a good bit but not all
- */
-#define AM_THRESHOLD 20
-
 #define AM_MAX23 0.06 //smaller causes failure on synthetic signals
 #define AM_MAX4  0.02
 
-#define FM_THRESHOLD  50 //TODO adjust
-
 //Least squares fit at 1khz points of frequency response shown by Frank 
McClatchie, FM SYSTEMS, INC. 800-235-6960
 static double emphasis75us(int f)
 {
@@ -529,7 +521,7 @@ static int probe_am(SDRContext *sdr)
 continue;
 
 //TODO also check for symmetry in the spectrum
-if (mid > 0 && score > AM_THRESHOLD &&
+if (mid > 0 && score > sdr->am_threshold &&
 sdr->len2block[i - 1] <  mid  && sdr->len2block[i + 1] <= 
mid &&
 sdr->len2block[i - 2] <  mid*AM_MAX23 && sdr->len2block[i + 2] <  
mid*AM_MAX23 &&
 sdr->len2block[i - 3] <  mid*AM_MAX23 && sdr->len2block[i + 3] <  
mid*AM_MAX23
@@ -583,7 +575,7 @@ static double find_am_carrier(SDRContext *sdr, const 
AVComplexFloat *data, int d
 avg += len2block[i + index];
 score = len * mid / (avg - mid);
 //find optimal frequency for this block if we have a carrier
-if (score > AM_THRESHOLD / 4) {
+if (score > sdr->am_threshold / 4) {
 double peak_i = find_peak_macleod(sdr, data, i_max, data_len, NULL);
 if (peak_i < 0)
 return peak_i;
@@ -858,7 +850,7 @@ static int probe_fm(SDRContext *sdr)
 
 if (last_score[1] >= last_score[0] &&
 last_score[1] > last_score[2] &&
-last_score[1] > FM_THRESHOLD) {
+last_score[1] > sdr->fm_threshold) {
 
 float rmax   = max_in_range(sdr, i-half_bw_i/4, 
i+half_bw_i/4);
 int lowcount = countbelow(sdr, i-half_bw_i/4, 
i+half_bw_i/4, rmax / 100);
@@ -2122,6 +2114,10 @@ const AVOption avpriv_sdr_options[] = {
 { "emphasis75us", "FM De-Emphasis 75us", 0, AV_OPT_TYPE_CONST, {.i64 = 
EMPHASIS_75us}, 0, 0, DEC, "fm_emphasis"},
 { "emphasis50us", "FM De-Emphasis 50us", 0, AV_OPT_TYPE_CONST, {.i64 = 
EMPHASIS_50us}, 0, 0, DEC, "fm_emphasis"},
 { "none", "No FM De-Emphasis"  , 0, AV_OPT_TYPE_CONST, {.i64 = 
EMPHASIS_NONE}, 0, 0, DEC, "fm_emphasis"},
+
+{ "am_threshold" , "AM detection threshold", OFFSET(am_threshold), 
AV_OPT_TYPE_FLOAT, {.dbl = 20}, 0, FLT_MAX, DEC},
+{ "fm_threshold" , "FM detection threshold", OFFSET(fm_threshold), 
AV_OPT_TYPE_FLOAT, {.dbl = 50}, 0, FLT_MAX, DEC},
+
 { NULL },
 };
 
-- 
2.31.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] [PATCH 6/9] avradio/sdrdemux: count timeout irrespective of a station being active

2023-07-07 Thread Michael Niedermayer
Signed-off-by: Michael Niedermayer 
---
 libavradio/sdrdemux.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index ad3e253ced..6cb9d3b70a 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -327,12 +327,11 @@ static void decay_stations(SDRContext *sdr)
 if (station->frequency - station->bandwidth/2 < sdr->block_center_freq 
- sdr->bandwidth/2 ||
 station->frequency + station->bandwidth/2 > sdr->block_center_freq 
+ sdr->bandwidth/2)
 continue;
-if (station->stream)
-continue;
 
 if (station->in_station_list) {
 if (station->timeout++ > STATION_TIMEOUT) {
-station->in_station_list = 0;
+if (!station->stream)
+station->in_station_list = 0;
 }
 } else {
 if (station->timeout++ > CANDIDATE_STATION_TIMEOUT) {
-- 
2.31.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] [PATCH 7/9] avradio/sdr: Compute and use detection histogram

2023-07-07 Thread Michael Niedermayer
By analyzing the behavior of the detectability of stations with
different SDR settings we can separate some SDR artifacts from
weak stations.

Signed-off-by: Michael Niedermayer 
---
 libavradio/sdr.h  |  5 +
 libavradio/sdrdemux.c | 36 +++-
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/libavradio/sdr.h b/libavradio/sdr.h
index 838fb1cef7..1053e45efe 100644
--- a/libavradio/sdr.h
+++ b/libavradio/sdr.h
@@ -66,6 +66,8 @@ typedef enum Modulation {
 //QAM, PSK, ...
 } Modulation;
 
+#define HISTOGRAMM_SIZE 9
+
 typedef struct Station {
 char *name;
 enum Modulation modulation;
@@ -78,6 +80,9 @@ typedef struct Station {
 int timeout;//since how many blocks was this detectable but 
not detected
 int multiplex_index;//DAB can have multiple stations on one frequency
 
+int detection_per_mix_frequency[HISTOGRAMM_SIZE];
+int non_detection_per_mix_frequency[HISTOGRAMM_SIZE];
+
 struct SDRStream *stream;
 } Station;
 
diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 6cb9d3b70a..1fc528317c 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -111,6 +111,23 @@ static void free_station(Station *station)
 av_free(station);
 }
 
+static inline int histogram_index(SDRContext *sdr, double f)
+{
+f = HISTOGRAMM_SIZE*((f - sdr->block_center_freq) / sdr->sdr_sample_rate + 
0.5);
+return av_clip((int)f, 0, HISTOGRAMM_SIZE-1);
+}
+
+static int histogram_score(Station *s)
+{
+int score = 0;
+for(int i = 0; idetection_per_mix_frequency[i] > 
s->non_detection_per_mix_frequency[i])
+-(5*s->detection_per_mix_frequency[i] < 
s->non_detection_per_mix_frequency[i]);
+}
+return score;
+}
+
 typedef struct FindStationContext {
 double freq;
 double range;
@@ -184,6 +201,10 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 if (candidate_station->in_station_list)
 return 0;
 
+// suspect looking histogram
+if (histogram_score(candidate_station) <= 0)
+return 0;
+
 Station *station_list[1000];
 int nb_stations = find_stations(sdr, sdr->block_center_freq, 
sdr->sdr_sample_rate*0.5, station_list, FF_ARRAY_ELEMS(station_list));
 for (i=0; ifrequency + station->bandwidth/2 > sdr->block_center_freq 
+ sdr->bandwidth/2)
 continue;
 
+if (station->timeout)
+station->non_detection_per_mix_frequency[histogram_index(sdr, 
station->frequency)] ++;
+
 if (station->in_station_list) {
-if (station->timeout++ > STATION_TIMEOUT) {
+int station_timeout = STATION_TIMEOUT;
+int hs = histogram_score(station);
+
+if (hs == 0) {
+station_timeout = 5; //give the station a moment to be 
properly detected and then discard it
+} else if(hs < 0) {
+station_timeout = 0; //probably not a station
+}
+
+if (station->timeout++ > station_timeout) {
 if (!station->stream)
 station->in_station_list = 0;
 }
@@ -376,6 +409,7 @@ static int create_candidate_station(SDRContext *sdr, enum 
Modulation modulation,
 }
 station->frequency /= ++station->nb_frequency;
 
+station->detection_per_mix_frequency[histogram_index(sdr, freq)] ++;
 station->modulation   = modulation;
 station->bandwidth= bandwidth;
 station->bandwidth_p2 = bandwidth_p2;
-- 
2.31.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] [PATCH 8/9] avradio/sdrdemux: increase the FM station frequency tolerance

2023-07-07 Thread Michael Niedermayer
The current FM station probing code is quite inaccurate with the
detected frequency.
Doing better requires some extra computations, maybe this is good
enough

Signed-off-by: Michael Niedermayer 
---
 libavradio/sdrdemux.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 1fc528317c..4c1ec7b51c 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -248,7 +248,7 @@ static int create_station(SDRContext *sdr, Station 
*candidate_station) {
 
 nb_candidate_match += candidate_station->nb_frequency - 1;
 for (i=0; ifrequency - freq);
 
@@ -383,7 +383,7 @@ static int create_candidate_station(SDRContext *sdr, enum 
Modulation modulation,
 void *tmp;
 struct AVTreeNode *next = NULL;
 Station *station_list[1000];
-double snapdistance = modulation == AM ? 5 : 50;
+double snapdistance = modulation == AM ? 5 : 500;
 int nb_stations = find_stations(sdr, freq, snapdistance, station_list, 
FF_ARRAY_ELEMS(station_list));
 
 if (nb_stations) {
-- 
2.31.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] [PATCH 9/9] avradio/sdrdemux: Use 2 differnt FM station detectors

2023-07-07 Thread Michael Niedermayer
Detect station if both lie within 1kHz of each other
This eliminates some artifacts being detected

Signed-off-by: Michael Niedermayer 
---
 libavradio/sdrdemux.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/libavradio/sdrdemux.c b/libavradio/sdrdemux.c
index 4c1ec7b51c..bed74ebd26 100644
--- a/libavradio/sdrdemux.c
+++ b/libavradio/sdrdemux.c
@@ -855,13 +855,17 @@ static int probe_fm(SDRContext *sdr)
 
 for (int pass = 0; pass < 2; pass ++) {
 double avg[2] = {0}, tri = 0;
+double mean = 0;
+double center = 0;
 for (i = 0; ilen2block[i];
 tri+= i*sdr->len2block[i];
 }
+mean = tri;
 for (; i<2*half_bw_i; i++) {
 avg[1] += sdr->len2block[i];
 tri+= (2*half_bw_i-i)*sdr->len2block[i];
+mean   += i*sdr->len2block[i];
 }
 
 for(i = half_bw_i; i<2*sdr->block_size - half_bw_i; i++) {
@@ -871,6 +875,10 @@ static int probe_fm(SDRContext *sdr)
 b += avg[1];
 tri += avg[1] - avg[0];
 
+mean += (i+half_bw_i)*sdr->len2block[i+half_bw_i];
+center = mean / b;
+mean -= (i-half_bw_i)*sdr->len2block[i-half_bw_i];
+
 if (i < border_i || i > 2*sdr->block_size - border_i)
 continue;
 
@@ -884,6 +892,7 @@ static int probe_fm(SDRContext *sdr)
 if (last_score[1] >= last_score[0] &&
 last_score[1] > last_score[2] &&
 last_score[1] > sdr->fm_threshold) {
+double score = last_score[1];
 
 float rmax   = max_in_range(sdr, i-half_bw_i/4, 
i+half_bw_i/4);
 int lowcount = countbelow(sdr, i-half_bw_i/4, 
i+half_bw_i/4, rmax / 100);
@@ -898,7 +907,12 @@ static int probe_fm(SDRContext *sdr)
 if (peak_i < 0)
 continue;
 av_assert0(fabs(peak_i-i) < 2);
-create_candidate_station(sdr, FM, peak_i * 0.5 * 
sdr->sdr_sample_rate / sdr->block_size + sdr->block_center_freq - 
sdr->sdr_sample_rate/2, bandwidth_f, bandwidth_p2, last_score[1]);
+double f = peak_i * 0.5 * sdr->sdr_sample_rate / 
sdr->block_size + sdr->block_center_freq - sdr->sdr_sample_rate/2;
+double f2 = center * 0.5 * sdr->sdr_sample_rate / 
sdr->block_size + sdr->block_center_freq - sdr->sdr_sample_rate/2;
+
+if (fabs(f2 - f) > 1000)
+continue;
+create_candidate_station(sdr, FM, f2, bandwidth_f, 
bandwidth_p2, score);
 }
 }
 }
-- 
2.31.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".


Re: [FFmpeg-devel] [PATCH] configure: use just the pkg-config for sndio

2023-07-07 Thread Brad Smith

On 2023-07-01 2:58 p.m., Brad Smith wrote:

On 2023-06-23 7:36 p.m., Brad Smith wrote:

On 2023-06-23 7:35 p.m., Michael Niedermayer wrote:

On Fri, Jun 23, 2023 at 06:56:30PM -0400, Brad Smith wrote:

On 2023-06-23 6:55 p.m., Michael Niedermayer wrote:

On Fri, Jun 23, 2023 at 06:41:08PM -0400, Brad Smith wrote:

ping.

On 2023-06-17 6:48 p.m., Brad Smith wrote:
On Sun, Jun 18, 2023 at 12:01:14AM +0200, Michael Niedermayer 
wrote:

this breaks a plain configure
here on ubuntu

./configure
ERROR: sndio not found using pkg-config

If you think configure made a mistake, make sure you are using 
the latest
version from Git.  If the latest version fails, report the 
problem to the
ffmpeg-u...@ffmpeg.org mailing list or IRC #ffmpeg on 
irc.libera.chat.
Include the log file "ffbuild/config.log" produced by configure 
as this will help

solve the problem.



[...]
--
Michael GnuPG fingerprint: 
9FF2128B147EF6730BADF133611EC787040B0FAB


The misfortune of the wise is better than the prosperity of the 
fool.

-- Epicurus

This is what I had intended.

You intended to break a plain ./configure on ubuntu ?
If so i think we better dont apply that patch :)

thx

No, there was a second patch there.

oops i missed that, the 2nd patch works fine on ubuntu
no objections from me

thx



ping.



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] lavu/random_seed: use getrandom() when available

2023-07-07 Thread Marton Balint




On Fri, 7 Jul 2023, Anton Khirnov wrote:


It is a better interface for /dev/u?random on Linux, which avoids the
issues associated with opening files.



getrandom() actually have the same problem as read(). It can read less 
than requested. So you should use it in a loop in that case or if it 
returns EINTR.


Regards,
Marton



---
configure   |  2 ++
libavutil/random_seed.c | 15 +++
2 files changed, 17 insertions(+)

diff --git a/configure b/configure
index d6e78297fe..a4b09577cf 100755
--- a/configure
+++ b/configure
@@ -2310,6 +2310,7 @@ SYSTEM_FUNCS="
getauxval
getenv
gethrtime
+getrandom
getopt
GetModuleHandle
GetProcessAffinityMask
@@ -6387,6 +6388,7 @@ check_func  fcntl
check_func  fork
check_func  gethrtime
check_func  getopt
+check_func_headers "sys/random.h" getrandom
check_func  getrusage
check_func  gettimeofday
check_func  isatty
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index 2980e565e0..9a3a5aa133 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -35,6 +35,9 @@
#elif CONFIG_OPENSSL
#include 
#endif
+#if HAVE_GETRANDOM
+#include 
+#endif
#include 
#include 
#include 
@@ -51,6 +54,7 @@
#define TEST 0
#endif

+#if !HAVE_GETRANDOM
static int read_random(uint8_t *dst, size_t len, const char *file)
{
#if HAVE_UNISTD_H
@@ -70,6 +74,7 @@ static int read_random(uint8_t *dst, size_t len, const char 
*file)
return AVERROR(ENOSYS);
#endif
}
+#endif

static uint32_t get_generic_seed(void)
{
@@ -147,7 +152,17 @@ int av_random_bytes(uint8_t* buf, size_t len)
return 0;
#endif

+// getrandom() is a better interface for /dev/(u)random on Linux,
+// so it makes no sense to try both
+#if HAVE_GETRANDOM
+{
+ssize_t read = getrandom(buf, len, GRND_NONBLOCK);
+err = read < 0? AVERROR(errno)  :
+  read != len ? AVERROR_UNKNOWN : 0;
+}
+#else
err = read_random(buf, len, "/dev/urandom");
+#endif
if (!err)
return err;

--
2.40.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 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] lavc/libvpxenc: prevent fifo from filling up

2023-07-07 Thread David Lemler
Prevent the fifo used in encoding VPx videos from filling up and
stopping encode when it reaches 21845 items, which happens when the
video has more than that number of frames.

Incorporated suggestion from James Zern to prevent calling
frame_data_submit() at all when performing the first pass of a 2-pass
encode so the fifo is not filled at all; replaces original patch which
drained the fifo after filling to prevent it from becoming full.

Fixes the regression originally introduced in
5bda4ec6c3cb6f286bb40dee4457c3c26e0f78cb

Co-authored-by: James Zern 
Signed-off-by: David Lemler 
---
 libavcodec/libvpxenc.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 8833df2d68..549ac55aaa 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1780,9 +1780,11 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket
*pkt,
 }
 }
 
-res = frame_data_submit(avctx, ctx->fifo, frame);
-if (res < 0)
-return res;
+if (!(avctx->flags & AV_CODEC_FLAG_PASS1)) {
+res = frame_data_submit(avctx, ctx->fifo, frame);
+if (res < 0)
+return res;
+}
 }
 
 // this is for encoding with preset temporal layering patterns defined
in
-- 
2.41.0.windows.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".


Re: [FFmpeg-devel] [RFC] Release 6.1

2023-07-07 Thread Michael Niedermayer
On Fri, Jul 07, 2023 at 05:33:32PM +0200, Lynne wrote:
> Jul 7, 2023, 17:07 by mich...@niedermayer.cc:
> 
> > Hi
> >
> > On Thu, Jul 06, 2023 at 06:04:41PM +0200, Lynne wrote:
> >
> >> It's been a while since we've had a release, and we've had
> >> a lot of new features in.
> >> We did say we would make releases more often, and I think
> >> it's about time we have a new release.
> >>
> >
> > yes
> >
> >
> >>
> >> Anything anyone wants to have merged or should we branch
> >> off 6.1 in a few days?
> >>
> >
> > libavradio needs testing, at least build testing.
> > all parts of git master are tested automatically by our user base
> > but anything in seperate repositories might receive less testing
> > so we should encourage people to test these seperate repositories
> > for the release
> >
> 
> It's still quite a new library, its API might change, I think we
> should release 6.1 first, then release libavradio, so the next
> FFmpeg release has a stable target API-wise to use.

I think we should release early and often. also 7.0 would be a
major version bump, so the 6.1 API/ABI doesnt matter.
And i have not seen anyone working on changing the API ...

thx

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

When you are offended at any man's fault, turn to yourself and study your
own failings. Then you will forget your anger. -- Epictetus


signature.asc
Description: PGP signature
___
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] [RFC] Release 6.1

2023-07-07 Thread Neal Gompa
On Thu, Jul 6, 2023 at 12:04 PM Lynne  wrote:
>
> It's been a while since we've had a release, and we've had
> a lot of new features in.
> We did say we would make releases more often, and I think
> it's about time we have a new release.
>
> Anything anyone wants to have merged or should we branch
> off 6.1 in a few days?

I was hoping to see the enhanced RTMP/FLV stuff merged by now... And
maybe the Intel person finally posting their AV1 VA-API patches...



-- 
真実はいつも一つ!/ Always, there's only one truth!
___
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".