Re: [FFmpeg-devel] [PATCH] Add and use cli options for v4l2

2022-03-25 Thread hydra3333
Oops, accidentally submitted with the wrong title so not in the right thread.  
Is submitted with the right one now.

A re-submit of a re-base of a formerly proposed patch to align with ffmpeg 
github 
commit 8ae15b565533944d042d3caf25f7262e002e8953
as at 2022.03.26 ACST, after ffmpeg changes overlapped the formerly proposed 
patch.

Add commandline options to v4l2_m2m_enc (h264_v4l2m2m only)
and use those to configure options for the h264_v4l2m2m encoder.
Uses AVOption options to filter for valid options per v4l2 spec.
For h264 it adds spec-compliant:
-profile  (high is max accepted by Raspberry Pi)
-level(4.2 is max  accepted by Raspberry Pi)
-rc   (Bitrate mode, VBR or CBR or CQ)
-shm(Sequence Header Mode, separate_buffer or joined_1st_frame)
-rsh   (Repeat Sequence Header 0(false) 1(true))
-fsme   (Frame Skip Mode for encoder, rejected by Pi OS)
-b:v   (Bit per second)
-g (pseudo GOP size, not an actual one)
-iframe_period  (the period between two I-frames)
-qmin  (Minimum quantization parameter for h264)
-qmax  (Maximum quantization parameter for h264)

Patch does not address pre-existing quirks with h264_v4l2m2m,
eg on a Raspberry Pi,
- Bitrate mode VBR, file is reported by mediainfo as CBR
- Bitrate mode CBR, encoder hangs and appears to
  "lock" /dev/video11 until reboot
- CFR input yields a VFR file reported by mediainfo (and an
  odd framerate) whereas an equivalent libx264 commandline
  yields expected CFR; tested on a Raspberry Pi4
- Bitrate mode CBR, profile is limited to less than "high"
- Bitrate mode VBR, only target bitrate option exposed to set
- Bitrate mode CQ, is not exposed to set

Notes:
Patch arises from a desire to use ffmpeg on a Raspberry Pi (4 +).
Fixes "--profile high" not working (required an integer).
The Raspberry Pi OS does not expose a GOP size to set, so -g is
used for backward compatibility with its value overriding
the "close enough" effect of an "iframe_period" value.
Hardware like Raspberry Pi 4 rejects some spec-compliant options
beyond its capacity and/or not implemented by the Raspberry Pi OS.
The Raspberry Pi OS repository for ffmpeg appears to have Repeat
Sequence Header hard-coded as True, rather than a cli an option.
Added more return value checking, AV_LOG_WARNING and a lot
more AV_LOG_DEBUG code; one-time runtime cost of debug code
during init phase is negligible.
Intentionally left in //commented-out debug code.

A working commandline using an interlaced source:
/usr/local/bin/ffmpeg -hide_banner -nostats -v debug -i 
"~/Desktop/input_file_tiny.mp4" -vsync cfr -sws_flags
lanczos+accurate_rnd+full_chroma_int+full_chroma_inp -strict experimental 
-filter_complex "[0:v]yadif=0:0:0,format=pix_fmts=yuv420p"
-c:v h264_v4l2m2m -pix_fmt yuv420p -rc VBR -b:v 400 -qmin 10 -qmax 51 
-profile:v high -level 4.2 -shm separate_buffer -rsh 0
-g:v 25 -movflags +faststart+write_colr -an -y 
"./output_file_tiny_h264_VBR_g25.mp4"

Signed-off-by: hydra mailto:hydra3...@gmail.com> >
---
 libavcodec/v4l2_m2m.h |   12 +
 libavcodec/v4l2_m2m_enc.c | 1013 -
 2 files changed, 894 insertions(+), 131 deletions(-)

diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
index b67b216..c1ca837 100644
--- a/libavcodec/v4l2_m2m.h
+++ b/libavcodec/v4l2_m2m.h
@@ -76,6 +76,18 @@ typedef struct V4L2m2mPriv {
 
 int num_output_buffers;
 int num_capture_buffers;
+/// h264 (mpeg4 part 10: AVC) add these to enable extra privately defined 
options (per V4L_M2M_h264_options) for h264 encoding
+int h264_profile;
+int h264_level;
+int h264_video_bit_rate_mode;
+int64_t h264_video_bit_rate;
+int h264_qmin;
+int h264_qmax;
+int h264_sequence_header_mode;
+_Bool   h264_repeat_seq_header;
+int h264_iframe_period;   // overridden by h264_gop_size
+int h264_gop_size;// if specified, overrides h264_iframe_period
+int h264_frame_skip_mode_encoder;
 } V4L2m2mPriv;
 
 /**
diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c
index 1d90de2..997c0be 100644
--- a/libavcodec/v4l2_m2m_enc.c
+++ b/libavcodec/v4l2_m2m_enc.c
@@ -1,4 +1,4 @@
-/*
+/**
  * V4L2 mem2mem encoders
  *
  * Copyright (C) 2017 Alexis Ballier mailto:aball...@gentoo.org> >
@@ -38,37 +38,54 @@
 #define MPEG_CID(x) V4L2_CID_MPEG_VIDEO_##x
 #define MPEG_VIDEO(x) V4L2_MPEG_VIDEO_##x
 
-static inline void v4l2_set_timeperframe(V4L2m2mContext *s, unsigned int num, 
unsigned int den)
+static inline int v4l2_set_timeperframe(V4L2m2mContext *s, unsigned int num, 
unsigned int den)
 {
+/**
+   v4l2_streamparm, V4L2_TYPE_IS_MULTIPLANAR defined in linux/videodev2.h
+ */
 struct v4l2_streamparm parm = { 0 };
-
+int ret;
 parm.type = V4L2_TYPE_IS_MULTIPLANAR(s->output.type) ? 
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT;
 parm.parm.output.timeperframe.denominator = den;
 parm.parm.output.timeperframe.numerator = num;
-
-  

[FFmpeg-devel] [PATCH] Add and use cli options for v4l2 encoder=h264_v4l2m2m [PATCH] Add and use cli options for v4l2 encoder=h264_v4l2m2m

2022-03-25 Thread hydra3333
Hello.

A re-submit of a re-base of a formerly proposed patch to align with ffmpeg 
github 
commit 8ae15b565533944d042d3caf25f7262e002e8953
at 2022.03.26 ACST, after changes overlapped the formerly proposed patch.


Add commandline options to v4l2_m2m_enc (h264_v4l2m2m only)
and use those to configure options for the h264_v4l2m2m encoder.
Uses AVOption options to filter for valid options per v4l2 spec.
For h264 it adds spec-compliant:
-profile  (high is max accepted by Raspberry Pi)
-level(4.2 is max  accepted by Raspberry Pi)
-rc   (Bitrate mode, VBR or CBR or CQ)
-shm(Sequence Header Mode, separate_buffer or joined_1st_frame)
-rsh   (Repeat Sequence Header 0(false) 1(true))
-fsme   (Frame Skip Mode for encoder, rejected by Pi OS)
-b:v   (Bit per second)
-g (pseudo GOP size, not an actual one)
-iframe_period  (the period between two I-frames)
-qmin  (Minimum quantization parameter for h264)
-qmax  (Maximum quantization parameter for h264)

Patch does not address pre-existing quirks with h264_v4l2m2m,
eg on a Raspberry Pi,
- Bitrate mode VBR, file is reported by mediainfo as CBR
- Bitrate mode CBR, encoder hangs and appears to
  "lock" /dev/video11 until reboot
- CFR input yields a VFR file reported by mediainfo (and an
  odd framerate) whereas an equivalent libx264 commandline
  yields expected CFR; tested on a Raspberry Pi4
- Bitrate mode CBR, profile is limited to less than "high"
- Bitrate mode VBR, only target bitrate option exposed to set
- Bitrate mode CQ, is not exposed to set

Notes:
Patch arises from a desire to use ffmpeg on a Raspberry Pi (4 +).
Fixes "--profile high" not working (required an integer).
The Raspberry Pi OS does not expose a GOP size to set, so -g is
used for backward compatibility with its value overriding
the "close enough" effect of an "iframe_period" value.
Hardware like Raspberry Pi 4 rejects some spec-compliant options
beyond its capacity and/or not implemented by the Raspberry Pi OS.
The Raspberry Pi OS repository for ffmpeg appears to have Repeat
Sequence Header hard-coded as True, rather than a cli an option.
Added more return value checking, AV_LOG_WARNING and a lot
more AV_LOG_DEBUG code; one-time runtime cost of debug code
during init phase is negligible.
Intentionally left in //commented-out debug code.

A working commandline using an interlaced source:
/usr/local/bin/ffmpeg -hide_banner -nostats -v debug -i 
"~/Desktop/input_file_tiny.mp4" -vsync cfr -sws_flags
lanczos+accurate_rnd+full_chroma_int+full_chroma_inp -strict experimental 
-filter_complex "[0:v]yadif=0:0:0,format=pix_fmts=yuv420p"
-c:v h264_v4l2m2m -pix_fmt yuv420p -rc VBR -b:v 400 -qmin 10 -qmax 51 
-profile:v high -level 4.2 -shm separate_buffer -rsh 0
-g:v 25 -movflags +faststart+write_colr -an -y 
"./output_file_tiny_h264_VBR_g25.mp4"

Signed-off-by: hydra 
---
 libavcodec/v4l2_m2m.h |   12 +
 libavcodec/v4l2_m2m_enc.c | 1013 -
 2 files changed, 894 insertions(+), 131 deletions(-)

diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
index b67b216..c1ca837 100644
--- a/libavcodec/v4l2_m2m.h
+++ b/libavcodec/v4l2_m2m.h
@@ -76,6 +76,18 @@ typedef struct V4L2m2mPriv {
 
 int num_output_buffers;
 int num_capture_buffers;
+/// h264 (mpeg4 part 10: AVC) add these to enable extra privately defined 
options (per V4L_M2M_h264_options) for h264 encoding
+int h264_profile;
+int h264_level;
+int h264_video_bit_rate_mode;
+int64_t h264_video_bit_rate;
+int h264_qmin;
+int h264_qmax;
+int h264_sequence_header_mode;
+_Bool   h264_repeat_seq_header;
+int h264_iframe_period;   // overridden by h264_gop_size
+int h264_gop_size;// if specified, overrides h264_iframe_period
+int h264_frame_skip_mode_encoder;
 } V4L2m2mPriv;
 
 /**
diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c
index 1d90de2..997c0be 100644
--- a/libavcodec/v4l2_m2m_enc.c
+++ b/libavcodec/v4l2_m2m_enc.c
@@ -1,4 +1,4 @@
-/*
+/**
  * V4L2 mem2mem encoders
  *
  * Copyright (C) 2017 Alexis Ballier 
@@ -38,37 +38,54 @@
 #define MPEG_CID(x) V4L2_CID_MPEG_VIDEO_##x
 #define MPEG_VIDEO(x) V4L2_MPEG_VIDEO_##x
 
-static inline void v4l2_set_timeperframe(V4L2m2mContext *s, unsigned int num, 
unsigned int den)
+static inline int v4l2_set_timeperframe(V4L2m2mContext *s, unsigned int num, 
unsigned int den)
 {
+/**
+   v4l2_streamparm, V4L2_TYPE_IS_MULTIPLANAR defined in linux/videodev2.h
+ */
 struct v4l2_streamparm parm = { 0 };
-
+int ret;
 parm.type = V4L2_TYPE_IS_MULTIPLANAR(s->output.type) ? 
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT;
 parm.parm.output.timeperframe.denominator = den;
 parm.parm.output.timeperframe.numerator = num;
-
-if (ioctl(s->fd, VIDIOC_S_PARM, ) < 0)
-av_log(s->avctx, AV_LOG_WARNING, "Failed to set timeperframe");
+av_log(s->avctx, AV_LOG_DEBUG, "Encoder v4l2_m2m 

Re: [FFmpeg-devel] [GAS-PP PATCH] Handle the aarch64 tbnz intruction in the same way as tbz, for armasm64

2022-03-25 Thread Martin Storsjö

On Mon, 21 Mar 2022, Martin Storsjö wrote:


---
I'll apply in a couple days if there's no comments.
---
gas-preprocessor.pl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)


Pushed.

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

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


[FFmpeg-devel] [PATCH 1/2] avformat/mov: Non overflowing ambisonic order check

2022-03-25 Thread Michael Niedermayer
Fixes: signed integer overflow: 536870913 * 536870913 cannot be represented in 
type 'int'
Fixes: 
45862/clusterfuzz-testcase-minimized-ffmpeg_dem_MOV_fuzzer-4730373768085504

Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer 
---
 libavformat/mov.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 6c847de164..3619be68f4 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7382,7 +7382,7 @@ static int mov_read_SA3D(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 }
 
 channel_count = avio_rb32(pb);
-if (channel_count != (ambisonic_order + 1) * (ambisonic_order + 1)) {
+if (ambisonic_order < 0 || channel_count != (ambisonic_order + 1LL) * 
(ambisonic_order + 1LL)) {
 av_log(c->fc, AV_LOG_ERROR,
"Invalid number of channels (%d / %d)\n",
channel_count, ambisonic_order);
-- 
2.17.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 2/2] avformat: Do not search through the AVOption table for a option not in it repeatedly on each packet

2022-03-25 Thread Michael Niedermayer
This search takes alot of time especially when compared with small packets

Signed-off-by: Michael Niedermayer 
---
 libavformat/demux.c| 15 +--
 libavformat/internal.h |  5 +
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/libavformat/demux.c b/libavformat/demux.c
index ac1f16edcd..ef189d9d8e 100644
--- a/libavformat/demux.c
+++ b/libavformat/demux.c
@@ -1407,12 +1407,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
 }
 }
 
-av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, );
-if (metadata) {
-s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
-av_dict_copy(>metadata, metadata, 0);
-av_dict_free();
-av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
+if (!si->metafree) {
+int metaret = av_opt_get_dict_val(s, "metadata", 
AV_OPT_SEARCH_CHILDREN, );
+if (metadata) {
+s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
+av_dict_copy(>metadata, metadata, 0);
+av_dict_free();
+av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
+}
+si->metafree = metaret == AVERROR_OPTION_NOT_FOUND;
 }
 
 if (s->debug & FF_FDEBUG_TS)
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 342e6f7327..3ad76d992c 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -183,6 +183,11 @@ typedef struct FFFormatContext {
  * Set if chapter ids are strictly monotonic.
  */
 int chapter_ids_monotonic;
+
+/**
+ * Contexts and child contexts do not contain a metadata option
+ */
+int metafree;
 } FFFormatContext;
 
 static av_always_inline FFFormatContext *ffformatcontext(AVFormatContext *s)
-- 
2.17.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 v5 2/2] lavf/mpegenc: fix termination on error conditions

2022-03-25 Thread Nicolas Gaullier
Avoid an infinite 'retry' loop in output_packet when flushing.

Signed-off-by: Nicolas Gaullier 
---
 libavformat/mpegenc.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index e0955a7d33..e113a42867 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -1002,7 +1002,7 @@ static int output_packet(AVFormatContext *ctx, int flush)
 MpegMuxContext *s = ctx->priv_data;
 AVStream *st;
 StreamInfo *stream;
-int i, avail_space = 0, es_size, trailer_size;
+int i, has_avail_data = 0, avail_space = 0, es_size, trailer_size;
 int best_i = -1;
 int best_score = INT_MIN;
 int ignore_constraints = 0;
@@ -1028,6 +1028,7 @@ retry:
 if (avail_data == 0)
 continue;
 av_assert0(avail_data > 0);
+has_avail_data = 1;
 
 if (space < s->packet_size && !ignore_constraints)
 continue;
@@ -1048,6 +1049,8 @@ retry:
 int64_t best_dts = INT64_MAX;
 int has_premux = 0;
 
+if (!has_avail_data)
+return 0;
 for (i = 0; i < ctx->nb_streams; i++) {
 AVStream *st = ctx->streams[i];
 StreamInfo *stream = st->priv_data;
-- 
2.34.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".


[FFmpeg-devel] [PATCH v5 1/2] lavf/mpegenc: fix ever-growing fifo size since the new API

2022-03-25 Thread Nicolas Gaullier
The older av_fifo_realloc2 implemented an auto grow that
should be ported as such in the new API.

This patch introduces a limitation in the fifo buffer size.
The default is set to 128MB and may be overriden by a new user option.
The amount of memory allocated depends on multiple factors, including
the number of audio streams.
A worst case scenario is where an out-of-spec high video bitrate is
combined with numerous low bitrate audios.

A fatal error mentions the availability of fifo_size_limit option.

Fix regressing since ea511196a6c85eb433e10cdbecb0b2c722faf20d

Signed-off-by: Nicolas Gaullier 
---
 libavformat/mpegenc.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index cc47a43288..e0955a7d33 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -84,6 +84,7 @@ typedef struct MpegMuxContext {
 int64_t vcd_padding_bytes_written;
 
 int preload;
+int fifo_size_limit;
 } MpegMuxContext;
 
 extern const AVOutputFormat ff_mpeg1vcd_muxer;
@@ -461,9 +462,10 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
av_get_media_type_string(st->codecpar->codec_type), i);
 return AVERROR(EINVAL);
 }
-stream->fifo = av_fifo_alloc2(16, 1, 0);
+stream->fifo = av_fifo_alloc2(16, 1, AV_FIFO_FLAG_AUTO_GROW);
 if (!stream->fifo)
 return AVERROR(ENOMEM);
+av_fifo_auto_grow_limit(stream->fifo, s->fifo_size_limit);
 }
 bitrate   = 0;
 audio_bitrate = 0;
@@ -1207,10 +1209,6 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, 
AVPacket *pkt)
 pkt_desc->unwritten_size =
 pkt_desc->size   = size;
 
-ret = av_fifo_grow2(stream->fifo, size);
-if (ret < 0)
-return ret;
-
 if (s->is_dvd) {
 // min VOBU length 0.4 seconds (mpucoder)
 if (is_iframe &&
@@ -1222,10 +1220,15 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, 
AVPacket *pkt)
 }
 }
 
-av_fifo_write(stream->fifo, buf, size);
+ret = av_fifo_write(stream->fifo, buf, size);
+if (ret == AVERROR(ENOSPC))
+av_log(s, AV_LOG_FATAL, "Input stream buffer overrun. "
+"To avoid, increase fifo_size_limit option.\n");
+if (ret < 0)
+return ret;
 
 for (;;) {
-int ret = output_packet(ctx, 0);
+ret = output_packet(ctx, 0);
 if (ret <= 0)
 return ret;
 }
@@ -1277,6 +1280,7 @@ static void mpeg_mux_deinit(AVFormatContext *ctx)
 static const AVOption options[] = {
 { "muxrate", NULL,  
OFFSET(user_mux_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, ((1<<22) - 1) * (8 * 
50), E },
 { "preload", "Initial demux-decode delay in microseconds.", 
OFFSET(preload),  AV_OPT_TYPE_INT, { .i64 = 50 }, 0, INT_MAX, E },
+{ "fifo_size_limit", "Maximum allowed memory for buffering an input stream 
in bytes", OFFSET(fifo_size_limit), AV_OPT_TYPE_INT, {.i64 = 128 * 1024 * 1024 
}, 16, FFMIN(INT_MAX, SIZE_MAX), E},
 { NULL },
 };
 
-- 
2.34.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".


[FFmpeg-devel] [PATCH v5 0/2] lavf/mpegenc: fixes

2022-03-25 Thread Nicolas Gaullier
The first patch is left unchanged since v4.
The second has been totally reworked after some investigations advised by 
Andreas.

Nicolas Gaullier (2):
  lavf/mpegenc: fix ever-growing fifo size since the new API
  lavf/mpegenc: fix termination on error conditions

 libavformat/mpegenc.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

-- 
2.34.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] [PATCH 01/10] checkasm: Add vc1dsp in-loop deblocking filter tests

2022-03-25 Thread Martin Storsjö

On Fri, 25 Mar 2022, Ben Avison wrote:


Note that the benchmarking results for these functions are highly dependent
upon the input data. Therefore, each function is benchmarked twice,
corresponding to the best and worst case complexity of the reference C
implementation. The performance of a real stream decode will fall somewhere
between these two extremes.

Signed-off-by: Ben Avison 
---
tests/checkasm/Makefile   |  1 +
tests/checkasm/checkasm.c |  3 ++
tests/checkasm/checkasm.h |  1 +
tests/checkasm/vc1dsp.c   | 94 +++
tests/fate/checkasm.mak   |  1 +
5 files changed, 100 insertions(+)
create mode 100644 tests/checkasm/vc1dsp.c

+#define CHECK_LOOP_FILTER(func) \
+do {\
+if (check_func(h.func, "vc1dsp." #func)) {  \
+declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, int, int);  \
+for (int count = 1000; count > 0; --count) {\
+int pq = rnd() % 31 + 1;\
+RANDOMIZE_BUFFER8_MID_WEIGHTED(filter_buf, 24 * 24);\
+call_ref(filter_buf0 + 4 * 24 + 4, 24, pq); \
+call_new(filter_buf1 + 4 * 24 + 4, 24, pq); \
+if (memcmp(filter_buf0, filter_buf1, 24 * 24))  \
+fail(); \
+}   \
+}   \
+for (int j = 0; j < 24; ++j)\
+for (int i = 0; i < 24; ++i)\
+filter_buf1[24*j + i] = 0x60 + 0x40 * (i >= 4 && j >= 4);   \
+if (check_func(h.func, "vc1dsp." #func "_bestcase")) {  \
+declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, int, int);  \
+bench_new(filter_buf1 + 4 * 24 + 4, 24, 1); \
+(void) checked_call;\
+}   \
+if (check_func(h.func, "vc1dsp." #func "_worstcase")) { \
+declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, int, int);  \
+bench_new(filter_buf1 + 4 * 24 + 4, 24, 31);\
+(void) checked_call;\
+}   \


(not a full review, just something that cropped up in initial build 
testing)


Why do you have the "(void) checked_call;" here? The checked_call isn't 
something that is universally defined; its availability depends on the 
OS/arch combinations, on other combinations, call_new/call_ref just call 
the function straight away without a wrapper. In particular, on macOS on 
arm64, we don't use checked_call, due to differences in how parameters are 
packed on the stack in the darwin ABI compared to AAPCS.


// Martin

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

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


Re: [FFmpeg-devel] [PATCH] rtpenc_vp8: Use 15-bit PictureIDs

2022-03-25 Thread Martin Storsjö

On Tue, 22 Mar 2022, ke...@muxable.com wrote:


From: Kevin Wang 

7-bit PictureIDs are not supported by WebRTC:
https://groups.google.com/g/discuss-webrtc/c/333-L02vuWA

In practice, 15-bit PictureIDs offer better compatibility.

Signed-off-by: Kevin Wang 
---
libavformat/rtpenc_vp8.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/rtpenc_vp8.c b/libavformat/rtpenc_vp8.c
index 671d245758..655d44517e 100644
--- a/libavformat/rtpenc_vp8.c
+++ b/libavformat/rtpenc_vp8.c
@@ -35,7 +35,8 @@ void ff_rtp_send_vp8(AVFormatContext *s1, const uint8_t *buf, 
int size)
// partition id 0
*s->buf_ptr++ = 0x90;
*s->buf_ptr++ = 0x80; // Picture id present
-*s->buf_ptr++ = s->frame_count++ & 0x7f;
+*s->buf_ptr++ = ((s->frame_count & 0x7f00) >> 8) | 0x80;
+*s->buf_ptr++ = s->frame_count++ & 0xff;
// Calculate the number of remaining bytes
header_size = s->buf_ptr - s->buf;
max_packet_size = s->max_payload_size - header_size;
--
2.34.1


LGTM, thanks!

// Martin

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

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


Re: [FFmpeg-devel] [PATCH v4 20/22] doc/examples: adding device_get_capabilities example

2022-03-25 Thread Diederick C. Niehorster
On Fri, Mar 25, 2022 at 6:26 PM Michael Niedermayer
 wrote:
>
> On Fri, Mar 25, 2022 at 03:10:39PM +0100, Diederick Niehorster wrote:
> > This example also shows use of get_device_list API.
> >
> > Also improve capability API doc in avdevice.h: now point to this example
> > instead of rough example code given in the header.
> >
> > Signed-off-by: Diederick Niehorster 
> > ---
> >  configure  |   2 +
> >  doc/examples/.gitignore|   1 +
> >  doc/examples/Makefile  |   1 +
> >  doc/examples/Makefile.example  |   1 +
> >  doc/examples/device_get_capabilities.c | 243 +
> >  libavdevice/avdevice.h |  33 +---
> >  6 files changed, 249 insertions(+), 32 deletions(-)
> >  create mode 100644 doc/examples/device_get_capabilities.c
>
> maybe i forgot something but this seems not building

It builds for me on MSVC. But searching these warnings and errors,
i've learned some new things about C i didn't know because i mostly
work in C++. I have locally fixed the -Wstrict-prototypes warnings by
adding void as function parameter, and the Werror=missing-prototypes
(hopefully) by declaring these internal functions static.

Will include in next version, awaiting more comments first.

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

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


Re: [FFmpeg-devel] [PATCH v3 2/2] lavf/mpegenc: fix termination following a fifo overrun

2022-03-25 Thread Nicolas Gaullier
>>Could this infinite loop also happen before switching to the new API?
>>Does it happen because avail_data is zero for all streams?
>>
>>- Andreas
>
>I will take time to double-check this very carefully, but in my experience, if 
>I remember correctly, it is nothing easy and was already buggy before.
>(but with the older API, it was almost impossible to reach such conditions).

Well, I really don't know how I missed that but indeed, no avail_data...
So, I am doing some testing and post right afterwards an updated patch with an 
'has_avail_data' check.
The problem happen before the new API, for a long time ago (I checked about one 
year ago).
Thanks to you!

Nicolas
___
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 06/10] avcodec/vc1: Arm 32-bit NEON deblocking filter fast paths

2022-03-25 Thread Lynne
25 Mar 2022, 20:49 by mar...@martin.st:

> On Fri, 25 Mar 2022, Lynne wrote:
>
>> 25 Mar 2022, 19:52 by bavi...@riscosopen.org:
>>
>>> +@ VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of 
>>> vertically-neighbouring blocks
>>> +@ On entry:
>>> +@   r0 -> top-left pel of lower block
>>> +@   r1 = row stride, bytes
>>> +@   r2 = PQUANT bitstream parameter
>>> +function ff_vc1_v_loop_filter4_neon, export=1
>>> +sub r3, r0, r1, lsl #2
>>> +vldrd0, .Lcoeffs
>>> +vld1.32 {d1[0]}, [r0], r1   @ P5
>>> +vld1.32 {d2[0]}, [r3], r1   @ P1
>>> +vld1.32 {d3[0]}, [r3], r1   @ P2
>>> +vld1.32 {d4[0]}, [r0], r1   @ P6
>>> +vld1.32 {d5[0]}, [r3], r1   @ P3
>>> +vld1.32 {d6[0]}, [r0], r1   @ P7
>>> +vld1.32 {d7[0]}, [r3]   @ P4
>>> +vld1.32 {d16[0]}, [r0]  @ P8
>>>
>>
>> Nice patches, but 2 notes so far:
>>
>
> Indeed, the first glance seems great so far, I haven't applied and poked them 
> closer yet.
>
>> What's with the weird comment syntax used only in this commit?
>>
>
> In 32 bit arm assembly, @ is a native assembler comment character, and lots 
> of our existing 32 bit assembly uses that so far.
>
>> Different indentation style used. We try to indent our Arm assembly to:
>> <8 spaces>.
>>
>
> Hmm, I haven't applied this patch locally and checked yet, but at least from 
> browsing just the patch, it seems to be quite correctly indented?
>
> We already discussed this in the previous iteration of his patchset, and the 
> cover letter mentioned that he had fixed it to match the convention now. (And 
> even in the previous iteration, the 32 bit assembly matched the existing 
> code.)
>

Oh, right, my email client mangled them.
All looks good to me then.
___
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 06/10] avcodec/vc1: Arm 32-bit NEON deblocking filter fast paths

2022-03-25 Thread Martin Storsjö

On Fri, 25 Mar 2022, Lynne wrote:


25 Mar 2022, 19:52 by bavi...@riscosopen.org:


+@ VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of 
vertically-neighbouring blocks
+@ On entry:
+@   r0 -> top-left pel of lower block
+@   r1 = row stride, bytes
+@   r2 = PQUANT bitstream parameter
+function ff_vc1_v_loop_filter4_neon, export=1
+sub r3, r0, r1, lsl #2
+vldrd0, .Lcoeffs
+vld1.32 {d1[0]}, [r0], r1   @ P5
+vld1.32 {d2[0]}, [r3], r1   @ P1
+vld1.32 {d3[0]}, [r3], r1   @ P2
+vld1.32 {d4[0]}, [r0], r1   @ P6
+vld1.32 {d5[0]}, [r3], r1   @ P3
+vld1.32 {d6[0]}, [r0], r1   @ P7
+vld1.32 {d7[0]}, [r3]   @ P4
+vld1.32 {d16[0]}, [r0]  @ P8



Nice patches, but 2 notes so far:


Indeed, the first glance seems great so far, I haven't applied and poked 
them closer yet.



What's with the weird comment syntax used only in this commit?


In 32 bit arm assembly, @ is a native assembler comment character, and 
lots of our existing 32 bit assembly uses that so far.



Different indentation style used. We try to indent our Arm assembly to:
<8 spaces>.


Hmm, I haven't applied this patch locally and checked yet, but at least 
from browsing just the patch, it seems to be quite correctly indented?


We already discussed this in the previous iteration of his patchset, and 
the cover letter mentioned that he had fixed it to match the convention 
now. (And even in the previous iteration, the 32 bit assembly matched the 
existing code.)


// Martin

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

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


Re: [FFmpeg-devel] [PATCH 06/10] avcodec/vc1: Arm 32-bit NEON deblocking filter fast paths

2022-03-25 Thread Lynne
25 Mar 2022, 19:52 by bavi...@riscosopen.org:

> checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. Note that the C
> version can still outperform the NEON version in specific cases. The balance
> between different code paths is stream-dependent, but in practice the best
> case happens about 5% of the time, the worst case happens about 40% of the
> time, and the complexity of the remaining cases fall somewhere in between.
> Therefore, taking the average of the best and worst case timings is
> probably a conservative estimate of the degree by which the NEON code
> improves performance.
>
> vc1dsp.vc1_h_loop_filter4_bestcase_c: 19.0
> vc1dsp.vc1_h_loop_filter4_bestcase_neon: 48.5
> vc1dsp.vc1_h_loop_filter4_worstcase_c: 144.7
> vc1dsp.vc1_h_loop_filter4_worstcase_neon: 76.2
> vc1dsp.vc1_h_loop_filter8_bestcase_c: 41.0
> vc1dsp.vc1_h_loop_filter8_bestcase_neon: 75.0
> vc1dsp.vc1_h_loop_filter8_worstcase_c: 294.0
> vc1dsp.vc1_h_loop_filter8_worstcase_neon: 102.7
> vc1dsp.vc1_h_loop_filter16_bestcase_c: 54.7
> vc1dsp.vc1_h_loop_filter16_bestcase_neon: 130.0
> vc1dsp.vc1_h_loop_filter16_worstcase_c: 569.7
> vc1dsp.vc1_h_loop_filter16_worstcase_neon: 186.7
> vc1dsp.vc1_v_loop_filter4_bestcase_c: 20.2
> vc1dsp.vc1_v_loop_filter4_bestcase_neon: 47.2
> vc1dsp.vc1_v_loop_filter4_worstcase_c: 164.2
> vc1dsp.vc1_v_loop_filter4_worstcase_neon: 68.5
> vc1dsp.vc1_v_loop_filter8_bestcase_c: 43.5
> vc1dsp.vc1_v_loop_filter8_bestcase_neon: 55.2
> vc1dsp.vc1_v_loop_filter8_worstcase_c: 316.2
> vc1dsp.vc1_v_loop_filter8_worstcase_neon: 72.7
> vc1dsp.vc1_v_loop_filter16_bestcase_c: 62.2
> vc1dsp.vc1_v_loop_filter16_bestcase_neon: 103.7
> vc1dsp.vc1_v_loop_filter16_worstcase_c: 646.5
> vc1dsp.vc1_v_loop_filter16_worstcase_neon: 110.7
>
> Signed-off-by: Ben Avison 
> ---
>  libavcodec/arm/vc1dsp_init_neon.c |  14 +
>  libavcodec/arm/vc1dsp_neon.S  | 643 ++
>  2 files changed, 657 insertions(+)
>
> diff --git a/libavcodec/arm/vc1dsp_init_neon.c 
> b/libavcodec/arm/vc1dsp_init_neon.c
> index 2cca784f5a..f5f5c702d7 100644
> --- a/libavcodec/arm/vc1dsp_init_neon.c
> +++ b/libavcodec/arm/vc1dsp_init_neon.c
> @@ -32,6 +32,13 @@ void ff_vc1_inv_trans_4x8_dc_neon(uint8_t *dest, ptrdiff_t 
> stride, int16_t *bloc
>  void ff_vc1_inv_trans_8x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
> *block);
>  void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
> *block);
>  
> +void ff_vc1_v_loop_filter4_neon(uint8_t *src, int stride, int pq);
> +void ff_vc1_h_loop_filter4_neon(uint8_t *src, int stride, int pq);
> +void ff_vc1_v_loop_filter8_neon(uint8_t *src, int stride, int pq);
> +void ff_vc1_h_loop_filter8_neon(uint8_t *src, int stride, int pq);
> +void ff_vc1_v_loop_filter16_neon(uint8_t *src, int stride, int pq);
> +void ff_vc1_h_loop_filter16_neon(uint8_t *src, int stride, int pq);
> +
>  void ff_put_pixels8x8_neon(uint8_t *block, const uint8_t *pixels,
>  ptrdiff_t line_size, int rnd);
>  
> @@ -92,6 +99,13 @@ av_cold void ff_vc1dsp_init_neon(VC1DSPContext *dsp)
>  dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_neon;
>  dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_neon;
>  
> +dsp->vc1_v_loop_filter4  = ff_vc1_v_loop_filter4_neon;
> +dsp->vc1_h_loop_filter4  = ff_vc1_h_loop_filter4_neon;
> +dsp->vc1_v_loop_filter8  = ff_vc1_v_loop_filter8_neon;
> +dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_neon;
> +dsp->vc1_v_loop_filter16 = ff_vc1_v_loop_filter16_neon;
> +dsp->vc1_h_loop_filter16 = ff_vc1_h_loop_filter16_neon;
> +
>  dsp->put_vc1_mspel_pixels_tab[1][ 0] = ff_put_pixels8x8_neon;
>  FN_ASSIGN(1, 0);
>  FN_ASSIGN(2, 0);
> diff --git a/libavcodec/arm/vc1dsp_neon.S b/libavcodec/arm/vc1dsp_neon.S
> index 93f043bf08..a639e81171 100644
> --- a/libavcodec/arm/vc1dsp_neon.S
> +++ b/libavcodec/arm/vc1dsp_neon.S
> @@ -1161,3 +1161,646 @@ function ff_vc1_inv_trans_4x4_dc_neon, export=1
>  vst1.32 {d1[1]},  [r0,:32]
>  bx  lr
>  endfunc
> +
> +@ VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of 
> vertically-neighbouring blocks
> +@ On entry:
> +@   r0 -> top-left pel of lower block
> +@   r1 = row stride, bytes
> +@   r2 = PQUANT bitstream parameter
> +function ff_vc1_v_loop_filter4_neon, export=1
> +sub r3, r0, r1, lsl #2
> +vldrd0, .Lcoeffs
> +vld1.32 {d1[0]}, [r0], r1   @ P5
> +vld1.32 {d2[0]}, [r3], r1   @ P1
> +vld1.32 {d3[0]}, [r3], r1   @ P2
> +vld1.32 {d4[0]}, [r0], r1   @ P6
> +vld1.32 {d5[0]}, [r3], r1   @ P3
> +vld1.32 {d6[0]}, [r0], r1   @ P7
> +vld1.32 {d7[0]}, [r3]   @ P4
> +vld1.32 {d16[0]}, [r0]  @ P8
>

Nice patches, but 2 notes so far:
What's with the weird comment syntax used only in this commit?
Different indentation style used. We try to indent our Arm assembly to:
<8 spaces>.
Take a 

[FFmpeg-devel] [PATCH 10/10] avcodec/vc1: Arm 32-bit NEON unescape fast path

2022-03-25 Thread Ben Avison
checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows.

vc1dsp.vc1_unescape_buffer_c: 918624.7
vc1dsp.vc1_unescape_buffer_neon: 142958.0

Signed-off-by: Ben Avison 
---
 libavcodec/arm/vc1dsp_init_neon.c |  61 +++
 libavcodec/arm/vc1dsp_neon.S  | 118 ++
 2 files changed, 179 insertions(+)

diff --git a/libavcodec/arm/vc1dsp_init_neon.c 
b/libavcodec/arm/vc1dsp_init_neon.c
index f5f5c702d7..48cb816b70 100644
--- a/libavcodec/arm/vc1dsp_init_neon.c
+++ b/libavcodec/arm/vc1dsp_init_neon.c
@@ -19,6 +19,7 @@
 #include 
 
 #include "libavutil/attributes.h"
+#include "libavutil/intreadwrite.h"
 #include "libavcodec/vc1dsp.h"
 #include "vc1dsp.h"
 
@@ -84,6 +85,64 @@ void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, 
ptrdiff_t stride,
 void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
 int h, int x, int y);
 
+int ff_vc1_unescape_buffer_helper_neon(const uint8_t *src, int size, uint8_t 
*dst);
+
+static int vc1_unescape_buffer_neon(const uint8_t *src, int size, uint8_t *dst)
+{
+/* Dealing with starting and stopping, and removing escape bytes, are
+ * comparatively less time-sensitive, so are more clearly expressed using
+ * a C wrapper around the assembly inner loop. Note that we assume a
+ * little-endian machine that supports unaligned loads. */
+int dsize = 0;
+while (size >= 4)
+{
+int found = 0;
+while (!found && (((uintptr_t) dst) & 7) && size >= 4)
+{
+found = (AV_RL32(src) &~ 0x0300) == 0x0003;
+if (!found)
+{
+*dst++ = *src++;
+--size;
+++dsize;
+}
+}
+if (!found)
+{
+int skip = size - ff_vc1_unescape_buffer_helper_neon(src, size, 
dst);
+dst += skip;
+src += skip;
+size -= skip;
+dsize += skip;
+while (!found && size >= 4)
+{
+found = (AV_RL32(src) &~ 0x0300) == 0x0003;
+if (!found)
+{
+*dst++ = *src++;
+--size;
+++dsize;
+}
+}
+}
+if (found)
+{
+*dst++ = *src++;
+*dst++ = *src++;
+++src;
+size -= 3;
+dsize += 2;
+}
+}
+while (size > 0)
+{
+*dst++ = *src++;
+--size;
+++dsize;
+}
+return dsize;
+}
+
 #define FN_ASSIGN(X, Y) \
 dsp->put_vc1_mspel_pixels_tab[0][X+4*Y] = 
ff_put_vc1_mspel_mc##X##Y##_16_neon; \
 dsp->put_vc1_mspel_pixels_tab[1][X+4*Y] = ff_put_vc1_mspel_mc##X##Y##_neon
@@ -130,4 +189,6 @@ av_cold void ff_vc1dsp_init_neon(VC1DSPContext *dsp)
 dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_neon;
 dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_vc1_chroma_mc4_neon;
 dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = ff_avg_vc1_chroma_mc4_neon;
+
+dsp->vc1_unescape_buffer = vc1_unescape_buffer_neon;
 }
diff --git a/libavcodec/arm/vc1dsp_neon.S b/libavcodec/arm/vc1dsp_neon.S
index a639e81171..8e97bc5e58 100644
--- a/libavcodec/arm/vc1dsp_neon.S
+++ b/libavcodec/arm/vc1dsp_neon.S
@@ -1804,3 +1804,121 @@ function ff_vc1_h_loop_filter16_neon, export=1
 4:  vpop{d8-d15}
 pop {r4-r6,pc}
 endfunc
+
+@ Copy at most the specified number of bytes from source to destination buffer,
+@ stopping at a multiple of 16 bytes, none of which are the start of an escape 
sequence
+@ On entry:
+@   r0 -> source buffer
+@   r1 = max number of bytes to copy
+@   r2 -> destination buffer, optimally 8-byte aligned
+@ On exit:
+@   r0 = number of bytes not copied
+function ff_vc1_unescape_buffer_helper_neon, export=1
+@ Offset by 48 to screen out cases that are too short for us to handle,
+@ and also make it easy to test for loop termination, or to determine
+@ whether we need an odd number of half-iterations of the loop.
+subsr1, r1, #48
+bmi 90f
+
+@ Set up useful constants
+vmov.i32q0, #0x300
+vmov.i32q1, #0x3
+
+tst r1, #16
+bne 1f
+
+  vld1.8  {q8, q9}, [r0]!
+  vbicq12, q8, q0
+  vext.8  q13, q8, q9, #1
+  vext.8  q14, q8, q9, #2
+  vext.8  q15, q8, q9, #3
+  veorq12, q12, q1
+  vbicq13, q13, q0
+  vbicq14, q14, q0
+  vbicq15, q15, q0
+  vceq.i32q12, q12, #0
+  veorq13, q13, q1
+  veorq14, q14, q1
+  veorq15, q15, q1
+  vceq.i32q13, q13, #0
+  vceq.i32q14, q14, #0
+  vceq.i32q15, 

[FFmpeg-devel] [PATCH 07/10] avcodec/vc1: Arm 64-bit NEON inverse transform fast paths

2022-03-25 Thread Ben Avison
checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows.

vc1dsp.vc1_inv_trans_4x4_c: 158.2
vc1dsp.vc1_inv_trans_4x4_neon: 65.7
vc1dsp.vc1_inv_trans_4x4_dc_c: 86.5
vc1dsp.vc1_inv_trans_4x4_dc_neon: 26.5
vc1dsp.vc1_inv_trans_4x8_c: 335.2
vc1dsp.vc1_inv_trans_4x8_neon: 106.2
vc1dsp.vc1_inv_trans_4x8_dc_c: 151.2
vc1dsp.vc1_inv_trans_4x8_dc_neon: 25.5
vc1dsp.vc1_inv_trans_8x4_c: 365.7
vc1dsp.vc1_inv_trans_8x4_neon: 97.2
vc1dsp.vc1_inv_trans_8x4_dc_c: 139.7
vc1dsp.vc1_inv_trans_8x4_dc_neon: 16.5
vc1dsp.vc1_inv_trans_8x8_c: 547.7
vc1dsp.vc1_inv_trans_8x8_neon: 137.0
vc1dsp.vc1_inv_trans_8x8_dc_c: 268.2
vc1dsp.vc1_inv_trans_8x8_dc_neon: 30.5

Signed-off-by: Ben Avison 
---
 libavcodec/aarch64/vc1dsp_init_aarch64.c |  19 +
 libavcodec/aarch64/vc1dsp_neon.S | 678 +++
 2 files changed, 697 insertions(+)

diff --git a/libavcodec/aarch64/vc1dsp_init_aarch64.c 
b/libavcodec/aarch64/vc1dsp_init_aarch64.c
index edfb296b75..b672b2aa99 100644
--- a/libavcodec/aarch64/vc1dsp_init_aarch64.c
+++ b/libavcodec/aarch64/vc1dsp_init_aarch64.c
@@ -25,6 +25,16 @@
 
 #include "config.h"
 
+void ff_vc1_inv_trans_8x8_neon(int16_t *block);
+void ff_vc1_inv_trans_8x4_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
+void ff_vc1_inv_trans_4x8_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
+void ff_vc1_inv_trans_4x4_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
+
+void ff_vc1_inv_trans_8x8_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
+void ff_vc1_inv_trans_8x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
+void ff_vc1_inv_trans_4x8_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
+void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
+
 void ff_vc1_v_loop_filter4_neon(uint8_t *src, int stride, int pq);
 void ff_vc1_h_loop_filter4_neon(uint8_t *src, int stride, int pq);
 void ff_vc1_v_loop_filter8_neon(uint8_t *src, int stride, int pq);
@@ -46,6 +56,15 @@ av_cold void ff_vc1dsp_init_aarch64(VC1DSPContext *dsp)
 int cpu_flags = av_get_cpu_flags();
 
 if (have_neon(cpu_flags)) {
+dsp->vc1_inv_trans_8x8 = ff_vc1_inv_trans_8x8_neon;
+dsp->vc1_inv_trans_8x4 = ff_vc1_inv_trans_8x4_neon;
+dsp->vc1_inv_trans_4x8 = ff_vc1_inv_trans_4x8_neon;
+dsp->vc1_inv_trans_4x4 = ff_vc1_inv_trans_4x4_neon;
+dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_neon;
+dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_neon;
+dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_neon;
+dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_neon;
+
 dsp->vc1_v_loop_filter4  = ff_vc1_v_loop_filter4_neon;
 dsp->vc1_h_loop_filter4  = ff_vc1_h_loop_filter4_neon;
 dsp->vc1_v_loop_filter8  = ff_vc1_v_loop_filter8_neon;
diff --git a/libavcodec/aarch64/vc1dsp_neon.S b/libavcodec/aarch64/vc1dsp_neon.S
index 70391b4179..e68e0fce53 100644
--- a/libavcodec/aarch64/vc1dsp_neon.S
+++ b/libavcodec/aarch64/vc1dsp_neon.S
@@ -22,7 +22,685 @@
 
 #include "libavutil/aarch64/asm.S"
 
+// VC-1 8x8 inverse transform
+// On entry:
+//   x0 -> array of 16-bit inverse transform coefficients, in column-major 
order
+// On exit:
+//   array at x0 updated to hold transformed block; also now held in row-major 
order
+function ff_vc1_inv_trans_8x8_neon, export=1
+ld1 {v1.16b, v2.16b}, [x0], #32
+ld1 {v3.16b, v4.16b}, [x0], #32
+ld1 {v5.16b, v6.16b}, [x0], #32
+shl v1.8h, v1.8h, #2// 8/2 * src[0]
+sub x1, x0, #3*32
+ld1 {v16.16b, v17.16b}, [x0]
+shl v7.8h, v2.8h, #4//  16 * src[8]
+shl v18.8h, v2.8h, #2   //   4 * src[8]
+shl v19.8h, v4.8h, #4   //16 * 
src[24]
+ldr d0, .Lcoeffs_it8
+shl v5.8h, v5.8h, #2// 
 8/2 * src[32]
+shl v20.8h, v6.8h, #4   // 
  16 * src[40]
+shl v21.8h, v6.8h, #2   // 
   4 * src[40]
+shl v22.8h, v17.8h, #4  // 
 16 * src[56]
+ssrav20.8h, v19.8h, #2  // 4 * 
src[24] + 16 * src[40]
+mul v23.8h, v3.8h, v0.h[0]  //   6/2 * 
src[16]
+sub v19.8h, v19.8h, v21.8h  //16 * 
src[24] -  4 * src[40]
+ssrav7.8h, v22.8h, #2   //  16 * src[8]
   +  4 * src[56]
+sub v18.8h, v22.8h, v18.8h  //-  4 * src[8]
   + 16 * src[56]
+shl v3.8h, v3.8h, #3//  16/2 * 
src[16]
+  

[FFmpeg-devel] [PATCH 09/10] avcodec/vc1: Arm 64-bit NEON unescape fast path

2022-03-25 Thread Ben Avison
checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows.

vc1dsp.vc1_unescape_buffer_c: 655617.7
vc1dsp.vc1_unescape_buffer_neon: 118237.0

Signed-off-by: Ben Avison 
---
 libavcodec/aarch64/vc1dsp_init_aarch64.c |  61 
 libavcodec/aarch64/vc1dsp_neon.S | 176 +++
 2 files changed, 237 insertions(+)

diff --git a/libavcodec/aarch64/vc1dsp_init_aarch64.c 
b/libavcodec/aarch64/vc1dsp_init_aarch64.c
index b672b2aa99..161d5a972b 100644
--- a/libavcodec/aarch64/vc1dsp_init_aarch64.c
+++ b/libavcodec/aarch64/vc1dsp_init_aarch64.c
@@ -21,6 +21,7 @@
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/aarch64/cpu.h"
+#include "libavutil/intreadwrite.h"
 #include "libavcodec/vc1dsp.h"
 
 #include "config.h"
@@ -51,6 +52,64 @@ void ff_put_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, 
ptrdiff_t stride,
 void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
 int h, int x, int y);
 
+int ff_vc1_unescape_buffer_helper_neon(const uint8_t *src, int size, uint8_t 
*dst);
+
+static int vc1_unescape_buffer_neon(const uint8_t *src, int size, uint8_t *dst)
+{
+/* Dealing with starting and stopping, and removing escape bytes, are
+ * comparatively less time-sensitive, so are more clearly expressed using
+ * a C wrapper around the assembly inner loop. Note that we assume a
+ * little-endian machine that supports unaligned loads. */
+int dsize = 0;
+while (size >= 4)
+{
+int found = 0;
+while (!found && (((uintptr_t) dst) & 7) && size >= 4)
+{
+found = (AV_RL32(src) &~ 0x0300) == 0x0003;
+if (!found)
+{
+*dst++ = *src++;
+--size;
+++dsize;
+}
+}
+if (!found)
+{
+int skip = size - ff_vc1_unescape_buffer_helper_neon(src, size, 
dst);
+dst += skip;
+src += skip;
+size -= skip;
+dsize += skip;
+while (!found && size >= 4)
+{
+found = (AV_RL32(src) &~ 0x0300) == 0x0003;
+if (!found)
+{
+*dst++ = *src++;
+--size;
+++dsize;
+}
+}
+}
+if (found)
+{
+*dst++ = *src++;
+*dst++ = *src++;
+++src;
+size -= 3;
+dsize += 2;
+}
+}
+while (size > 0)
+{
+*dst++ = *src++;
+--size;
+++dsize;
+}
+return dsize;
+}
+
 av_cold void ff_vc1dsp_init_aarch64(VC1DSPContext *dsp)
 {
 int cpu_flags = av_get_cpu_flags();
@@ -76,5 +135,7 @@ av_cold void ff_vc1dsp_init_aarch64(VC1DSPContext *dsp)
 dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_neon;
 dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_vc1_chroma_mc4_neon;
 dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = ff_avg_vc1_chroma_mc4_neon;
+
+dsp->vc1_unescape_buffer = vc1_unescape_buffer_neon;
 }
 }
diff --git a/libavcodec/aarch64/vc1dsp_neon.S b/libavcodec/aarch64/vc1dsp_neon.S
index e68e0fce53..529c21d285 100644
--- a/libavcodec/aarch64/vc1dsp_neon.S
+++ b/libavcodec/aarch64/vc1dsp_neon.S
@@ -1374,3 +1374,179 @@ function ff_vc1_h_loop_filter16_neon, export=1
 st2 {v2.b, v3.b}[7], [x6]
 4:  ret
 endfunc
+
+// Copy at most the specified number of bytes from source to destination 
buffer,
+// stopping at a multiple of 32 bytes, none of which are the start of an 
escape sequence
+// On entry:
+//   x0 -> source buffer
+//   w1 = max number of bytes to copy
+//   x2 -> destination buffer, optimally 8-byte aligned
+// On exit:
+//   w0 = number of bytes not copied
+function ff_vc1_unescape_buffer_helper_neon, export=1
+// Offset by 80 to screen out cases that are too short for us to 
handle,
+// and also make it easy to test for loop termination, or to determine
+// whether we need an odd number of half-iterations of the loop.
+subsw1, w1, #80
+b.mi90f
+
+// Set up useful constants
+moviv20.4s, #3, lsl #24
+moviv21.4s, #3, lsl #16
+
+tst w1, #32
+b.ne1f
+
+  ld1 {v0.16b, v1.16b, v2.16b}, [x0], #48
+  ext v25.16b, v0.16b, v1.16b, #1
+  ext v26.16b, v0.16b, v1.16b, #2
+  ext v27.16b, v0.16b, v1.16b, #3
+  ext v29.16b, v1.16b, v2.16b, #1
+  ext v30.16b, v1.16b, v2.16b, #2
+  ext v31.16b, v1.16b, v2.16b, #3
+  bic v24.16b, v0.16b, v20.16b
+  bic v25.16b, v25.16b, v20.16b
+  bic v26.16b, v26.16b, v20.16b
+  bic 

[FFmpeg-devel] [PATCH 06/10] avcodec/vc1: Arm 32-bit NEON deblocking filter fast paths

2022-03-25 Thread Ben Avison
checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. Note that the C
version can still outperform the NEON version in specific cases. The balance
between different code paths is stream-dependent, but in practice the best
case happens about 5% of the time, the worst case happens about 40% of the
time, and the complexity of the remaining cases fall somewhere in between.
Therefore, taking the average of the best and worst case timings is
probably a conservative estimate of the degree by which the NEON code
improves performance.

vc1dsp.vc1_h_loop_filter4_bestcase_c: 19.0
vc1dsp.vc1_h_loop_filter4_bestcase_neon: 48.5
vc1dsp.vc1_h_loop_filter4_worstcase_c: 144.7
vc1dsp.vc1_h_loop_filter4_worstcase_neon: 76.2
vc1dsp.vc1_h_loop_filter8_bestcase_c: 41.0
vc1dsp.vc1_h_loop_filter8_bestcase_neon: 75.0
vc1dsp.vc1_h_loop_filter8_worstcase_c: 294.0
vc1dsp.vc1_h_loop_filter8_worstcase_neon: 102.7
vc1dsp.vc1_h_loop_filter16_bestcase_c: 54.7
vc1dsp.vc1_h_loop_filter16_bestcase_neon: 130.0
vc1dsp.vc1_h_loop_filter16_worstcase_c: 569.7
vc1dsp.vc1_h_loop_filter16_worstcase_neon: 186.7
vc1dsp.vc1_v_loop_filter4_bestcase_c: 20.2
vc1dsp.vc1_v_loop_filter4_bestcase_neon: 47.2
vc1dsp.vc1_v_loop_filter4_worstcase_c: 164.2
vc1dsp.vc1_v_loop_filter4_worstcase_neon: 68.5
vc1dsp.vc1_v_loop_filter8_bestcase_c: 43.5
vc1dsp.vc1_v_loop_filter8_bestcase_neon: 55.2
vc1dsp.vc1_v_loop_filter8_worstcase_c: 316.2
vc1dsp.vc1_v_loop_filter8_worstcase_neon: 72.7
vc1dsp.vc1_v_loop_filter16_bestcase_c: 62.2
vc1dsp.vc1_v_loop_filter16_bestcase_neon: 103.7
vc1dsp.vc1_v_loop_filter16_worstcase_c: 646.5
vc1dsp.vc1_v_loop_filter16_worstcase_neon: 110.7

Signed-off-by: Ben Avison 
---
 libavcodec/arm/vc1dsp_init_neon.c |  14 +
 libavcodec/arm/vc1dsp_neon.S  | 643 ++
 2 files changed, 657 insertions(+)

diff --git a/libavcodec/arm/vc1dsp_init_neon.c 
b/libavcodec/arm/vc1dsp_init_neon.c
index 2cca784f5a..f5f5c702d7 100644
--- a/libavcodec/arm/vc1dsp_init_neon.c
+++ b/libavcodec/arm/vc1dsp_init_neon.c
@@ -32,6 +32,13 @@ void ff_vc1_inv_trans_4x8_dc_neon(uint8_t *dest, ptrdiff_t 
stride, int16_t *bloc
 void ff_vc1_inv_trans_8x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
 void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t 
*block);
 
+void ff_vc1_v_loop_filter4_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter4_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_v_loop_filter8_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter8_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_v_loop_filter16_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter16_neon(uint8_t *src, int stride, int pq);
+
 void ff_put_pixels8x8_neon(uint8_t *block, const uint8_t *pixels,
ptrdiff_t line_size, int rnd);
 
@@ -92,6 +99,13 @@ av_cold void ff_vc1dsp_init_neon(VC1DSPContext *dsp)
 dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_neon;
 dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_neon;
 
+dsp->vc1_v_loop_filter4  = ff_vc1_v_loop_filter4_neon;
+dsp->vc1_h_loop_filter4  = ff_vc1_h_loop_filter4_neon;
+dsp->vc1_v_loop_filter8  = ff_vc1_v_loop_filter8_neon;
+dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_neon;
+dsp->vc1_v_loop_filter16 = ff_vc1_v_loop_filter16_neon;
+dsp->vc1_h_loop_filter16 = ff_vc1_h_loop_filter16_neon;
+
 dsp->put_vc1_mspel_pixels_tab[1][ 0] = ff_put_pixels8x8_neon;
 FN_ASSIGN(1, 0);
 FN_ASSIGN(2, 0);
diff --git a/libavcodec/arm/vc1dsp_neon.S b/libavcodec/arm/vc1dsp_neon.S
index 93f043bf08..a639e81171 100644
--- a/libavcodec/arm/vc1dsp_neon.S
+++ b/libavcodec/arm/vc1dsp_neon.S
@@ -1161,3 +1161,646 @@ function ff_vc1_inv_trans_4x4_dc_neon, export=1
 vst1.32 {d1[1]},  [r0,:32]
 bx  lr
 endfunc
+
+@ VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of 
vertically-neighbouring blocks
+@ On entry:
+@   r0 -> top-left pel of lower block
+@   r1 = row stride, bytes
+@   r2 = PQUANT bitstream parameter
+function ff_vc1_v_loop_filter4_neon, export=1
+sub r3, r0, r1, lsl #2
+vldrd0, .Lcoeffs
+vld1.32 {d1[0]}, [r0], r1   @ P5
+vld1.32 {d2[0]}, [r3], r1   @ P1
+vld1.32 {d3[0]}, [r3], r1   @ P2
+vld1.32 {d4[0]}, [r0], r1   @ P6
+vld1.32 {d5[0]}, [r3], r1   @ P3
+vld1.32 {d6[0]}, [r0], r1   @ P7
+vld1.32 {d7[0]}, [r3]   @ P4
+vld1.32 {d16[0]}, [r0]  @ P8
+vshll.u8q9, d1, #1  @ 2*P5
+vdup.16 d17, r2 @ pq
+vshll.u8q10, d2, #1 @ 2*P1
+vmovl.u8q11, d3 @ P2
+vmovl.u8q1, d4  @ P6
+vmovl.u8q12, d5 @ P3
+vmls.i16d20, d22, d0[1] 

[FFmpeg-devel] [PATCH 08/10] avcodec/idctdsp: Arm 64-bit NEON block add and clamp fast paths

2022-03-25 Thread Ben Avison
checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows.

idctdsp.add_pixels_clamped_c: 323.0
idctdsp.add_pixels_clamped_neon: 41.5
idctdsp.put_pixels_clamped_c: 243.0
idctdsp.put_pixels_clamped_neon: 30.0
idctdsp.put_signed_pixels_clamped_c: 225.7
idctdsp.put_signed_pixels_clamped_neon: 37.7

Signed-off-by: Ben Avison 
---
 libavcodec/aarch64/Makefile   |   3 +-
 libavcodec/aarch64/idctdsp_init_aarch64.c |  26 +++--
 libavcodec/aarch64/idctdsp_neon.S | 130 ++
 3 files changed, 150 insertions(+), 9 deletions(-)
 create mode 100644 libavcodec/aarch64/idctdsp_neon.S

diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile
index 5b25e4dfb9..c8935f205e 100644
--- a/libavcodec/aarch64/Makefile
+++ b/libavcodec/aarch64/Makefile
@@ -44,7 +44,8 @@ NEON-OBJS-$(CONFIG_H264PRED)+= 
aarch64/h264pred_neon.o
 NEON-OBJS-$(CONFIG_H264QPEL)+= aarch64/h264qpel_neon.o 
\
aarch64/hpeldsp_neon.o
 NEON-OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_neon.o
-NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/simple_idct_neon.o
+NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_neon.o  
\
+   aarch64/simple_idct_neon.o
 NEON-OBJS-$(CONFIG_MDCT)+= aarch64/mdct_neon.o
 NEON-OBJS-$(CONFIG_MPEGAUDIODSP)+= aarch64/mpegaudiodsp_neon.o
 NEON-OBJS-$(CONFIG_PIXBLOCKDSP) += aarch64/pixblockdsp_neon.o
diff --git a/libavcodec/aarch64/idctdsp_init_aarch64.c 
b/libavcodec/aarch64/idctdsp_init_aarch64.c
index 742a3372e3..eec21aa5a2 100644
--- a/libavcodec/aarch64/idctdsp_init_aarch64.c
+++ b/libavcodec/aarch64/idctdsp_init_aarch64.c
@@ -27,19 +27,29 @@
 #include "libavcodec/idctdsp.h"
 #include "idct.h"
 
+void ff_put_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
+void ff_put_signed_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
+void ff_add_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
+
 av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx,
  unsigned high_bit_depth)
 {
 int cpu_flags = av_get_cpu_flags();
 
-if (have_neon(cpu_flags) && !avctx->lowres && !high_bit_depth) {
-if (avctx->idct_algo == FF_IDCT_AUTO ||
-avctx->idct_algo == FF_IDCT_SIMPLEAUTO ||
-avctx->idct_algo == FF_IDCT_SIMPLENEON) {
-c->idct_put  = ff_simple_idct_put_neon;
-c->idct_add  = ff_simple_idct_add_neon;
-c->idct  = ff_simple_idct_neon;
-c->perm_type = FF_IDCT_PERM_PARTTRANS;
+if (have_neon(cpu_flags)) {
+if (!avctx->lowres && !high_bit_depth) {
+if (avctx->idct_algo == FF_IDCT_AUTO ||
+avctx->idct_algo == FF_IDCT_SIMPLEAUTO ||
+avctx->idct_algo == FF_IDCT_SIMPLENEON) {
+c->idct_put  = ff_simple_idct_put_neon;
+c->idct_add  = ff_simple_idct_add_neon;
+c->idct  = ff_simple_idct_neon;
+c->perm_type = FF_IDCT_PERM_PARTTRANS;
+}
 }
+
+c->add_pixels_clamped= ff_add_pixels_clamped_neon;
+c->put_pixels_clamped= ff_put_pixels_clamped_neon;
+c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_neon;
 }
 }
diff --git a/libavcodec/aarch64/idctdsp_neon.S 
b/libavcodec/aarch64/idctdsp_neon.S
new file mode 100644
index 00..7f47611206
--- /dev/null
+++ b/libavcodec/aarch64/idctdsp_neon.S
@@ -0,0 +1,130 @@
+/*
+ * IDCT AArch64 NEON optimisations
+ *
+ * Copyright (c) 2022 Ben Avison 
+ *
+ * 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/aarch64/asm.S"
+
+// Clamp 16-bit signed block coefficients to unsigned 8-bit
+// On entry:
+//   x0 -> array of 64x 16-bit coefficients
+//   x1 -> 8-bit results
+//   x2 = row stride for results, bytes
+function ff_put_pixels_clamped_neon, export=1
+ld1 {v0.16b, v1.16b, v2.16b, v3.16b}, [x0], #64
+ld1 {v4.16b, v5.16b, v6.16b, v7.16b}, [x0]
+sqxtun  v0.8b, v0.8h
+sqxtun  v1.8b, v1.8h
+sqxtun  v2.8b, v2.8h
+

[FFmpeg-devel] [PATCH 05/10] avcodec/vc1: Arm 64-bit NEON deblocking filter fast paths

2022-03-25 Thread Ben Avison
checkasm benchmarks on 1.5 GHz Cortex-A72 are as follows. Note that the C
version can still outperform the NEON version in specific cases. The balance
between different code paths is stream-dependent, but in practice the best
case happens about 5% of the time, the worst case happens about 40% of the
time, and the complexity of the remaining cases fall somewhere in between.
Therefore, taking the average of the best and worst case timings is
probably a conservative estimate of the degree by which the NEON code
improves performance.

vc1dsp.vc1_h_loop_filter4_bestcase_c: 10.7
vc1dsp.vc1_h_loop_filter4_bestcase_neon: 43.5
vc1dsp.vc1_h_loop_filter4_worstcase_c: 184.5
vc1dsp.vc1_h_loop_filter4_worstcase_neon: 73.7
vc1dsp.vc1_h_loop_filter8_bestcase_c: 31.2
vc1dsp.vc1_h_loop_filter8_bestcase_neon: 62.2
vc1dsp.vc1_h_loop_filter8_worstcase_c: 358.2
vc1dsp.vc1_h_loop_filter8_worstcase_neon: 88.2
vc1dsp.vc1_h_loop_filter16_bestcase_c: 51.0
vc1dsp.vc1_h_loop_filter16_bestcase_neon: 107.7
vc1dsp.vc1_h_loop_filter16_worstcase_c: 722.7
vc1dsp.vc1_h_loop_filter16_worstcase_neon: 140.5
vc1dsp.vc1_v_loop_filter4_bestcase_c: 9.7
vc1dsp.vc1_v_loop_filter4_bestcase_neon: 43.0
vc1dsp.vc1_v_loop_filter4_worstcase_c: 178.7
vc1dsp.vc1_v_loop_filter4_worstcase_neon: 69.0
vc1dsp.vc1_v_loop_filter8_bestcase_c: 30.2
vc1dsp.vc1_v_loop_filter8_bestcase_neon: 50.7
vc1dsp.vc1_v_loop_filter8_worstcase_c: 353.0
vc1dsp.vc1_v_loop_filter8_worstcase_neon: 69.2
vc1dsp.vc1_v_loop_filter16_bestcase_c: 60.0
vc1dsp.vc1_v_loop_filter16_bestcase_neon: 90.0
vc1dsp.vc1_v_loop_filter16_worstcase_c: 714.2
vc1dsp.vc1_v_loop_filter16_worstcase_neon: 97.2

Signed-off-by: Ben Avison 
---
 libavcodec/aarch64/Makefile  |   1 +
 libavcodec/aarch64/vc1dsp_init_aarch64.c |  14 +
 libavcodec/aarch64/vc1dsp_neon.S | 698 +++
 3 files changed, 713 insertions(+)
 create mode 100644 libavcodec/aarch64/vc1dsp_neon.S

diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile
index 954461f81d..5b25e4dfb9 100644
--- a/libavcodec/aarch64/Makefile
+++ b/libavcodec/aarch64/Makefile
@@ -48,6 +48,7 @@ NEON-OBJS-$(CONFIG_IDCTDSP) += 
aarch64/simple_idct_neon.o
 NEON-OBJS-$(CONFIG_MDCT)+= aarch64/mdct_neon.o
 NEON-OBJS-$(CONFIG_MPEGAUDIODSP)+= aarch64/mpegaudiodsp_neon.o
 NEON-OBJS-$(CONFIG_PIXBLOCKDSP) += aarch64/pixblockdsp_neon.o
+NEON-OBJS-$(CONFIG_VC1DSP)  += aarch64/vc1dsp_neon.o
 NEON-OBJS-$(CONFIG_VP8DSP)  += aarch64/vp8dsp_neon.o
 
 # decoders/encoders
diff --git a/libavcodec/aarch64/vc1dsp_init_aarch64.c 
b/libavcodec/aarch64/vc1dsp_init_aarch64.c
index 13dfd74940..edfb296b75 100644
--- a/libavcodec/aarch64/vc1dsp_init_aarch64.c
+++ b/libavcodec/aarch64/vc1dsp_init_aarch64.c
@@ -25,6 +25,13 @@
 
 #include "config.h"
 
+void ff_vc1_v_loop_filter4_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter4_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_v_loop_filter8_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter8_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_v_loop_filter16_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter16_neon(uint8_t *src, int stride, int pq);
+
 void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
 int h, int x, int y);
 void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
@@ -39,6 +46,13 @@ av_cold void ff_vc1dsp_init_aarch64(VC1DSPContext *dsp)
 int cpu_flags = av_get_cpu_flags();
 
 if (have_neon(cpu_flags)) {
+dsp->vc1_v_loop_filter4  = ff_vc1_v_loop_filter4_neon;
+dsp->vc1_h_loop_filter4  = ff_vc1_h_loop_filter4_neon;
+dsp->vc1_v_loop_filter8  = ff_vc1_v_loop_filter8_neon;
+dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_neon;
+dsp->vc1_v_loop_filter16 = ff_vc1_v_loop_filter16_neon;
+dsp->vc1_h_loop_filter16 = ff_vc1_h_loop_filter16_neon;
+
 dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_neon;
 dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_neon;
 dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_vc1_chroma_mc4_neon;
diff --git a/libavcodec/aarch64/vc1dsp_neon.S b/libavcodec/aarch64/vc1dsp_neon.S
new file mode 100644
index 00..70391b4179
--- /dev/null
+++ b/libavcodec/aarch64/vc1dsp_neon.S
@@ -0,0 +1,698 @@
+/*
+ * VC1 AArch64 NEON optimisations
+ *
+ * Copyright (c) 2022 Ben Avison 
+ *
+ * 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.  

[FFmpeg-devel] [PATCH 04/10] avcodec/vc1: Introduce fast path for unescaping bitstream buffer

2022-03-25 Thread Ben Avison
Includes a checkasm test.

Signed-off-by: Ben Avison 
---
 libavcodec/vc1dec.c | 20 +++---
 libavcodec/vc1dsp.c |  2 ++
 libavcodec/vc1dsp.h |  3 +++
 tests/checkasm/vc1dsp.c | 59 +
 4 files changed, 74 insertions(+), 10 deletions(-)

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 1c92b9d401..6a30b5b664 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -490,7 +490,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
 size = next - start - 4;
 if (size <= 0)
 continue;
-buf2_size = vc1_unescape_buffer(start + 4, size, buf2);
+buf2_size = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2);
 init_get_bits(, buf2, buf2_size * 8);
 switch (AV_RB32(start)) {
 case VC1_CODE_SEQHDR:
@@ -680,7 +680,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 case VC1_CODE_FRAME:
 if (avctx->hwaccel)
 buf_start = start;
-buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
+buf_size2 = v->vc1dsp.vc1_unescape_buffer(start + 4, size, 
buf2);
 break;
 case VC1_CODE_FIELD: {
 int buf_size3;
@@ -697,8 +697,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 ret = AVERROR(ENOMEM);
 goto err;
 }
-buf_size3 = vc1_unescape_buffer(start + 4, size,
-slices[n_slices].buf);
+buf_size3 = v->vc1dsp.vc1_unescape_buffer(start + 4, size,
+  
slices[n_slices].buf);
 init_get_bits([n_slices].gb, slices[n_slices].buf,
   buf_size3 << 3);
 slices[n_slices].mby_start = avctx->coded_height + 31 >> 5;
@@ -709,7 +709,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 break;
 }
 case VC1_CODE_ENTRYPOINT: /* it should be before frame data */
-buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
+buf_size2 = v->vc1dsp.vc1_unescape_buffer(start + 4, size, 
buf2);
 init_get_bits(>gb, buf2, buf_size2 * 8);
 ff_vc1_decode_entry_point(avctx, v, >gb);
 break;
@@ -726,8 +726,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 ret = AVERROR(ENOMEM);
 goto err;
 }
-buf_size3 = vc1_unescape_buffer(start + 4, size,
-slices[n_slices].buf);
+buf_size3 = v->vc1dsp.vc1_unescape_buffer(start + 4, size,
+  
slices[n_slices].buf);
 init_get_bits([n_slices].gb, slices[n_slices].buf,
   buf_size3 << 3);
 slices[n_slices].mby_start = 
get_bits([n_slices].gb, 9);
@@ -761,7 +761,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 ret = AVERROR(ENOMEM);
 goto err;
 }
-buf_size3 = vc1_unescape_buffer(divider + 4, buf + buf_size - 
divider - 4, slices[n_slices].buf);
+buf_size3 = v->vc1dsp.vc1_unescape_buffer(divider + 4, buf + 
buf_size - divider - 4, slices[n_slices].buf);
 init_get_bits([n_slices].gb, slices[n_slices].buf,
   buf_size3 << 3);
 slices[n_slices].mby_start = s->mb_height + 1 >> 1;
@@ -770,9 +770,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
 n_slices1 = n_slices - 1;
 n_slices++;
 }
-buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2);
+buf_size2 = v->vc1dsp.vc1_unescape_buffer(buf, divider - buf, 
buf2);
 } else {
-buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2);
+buf_size2 = v->vc1dsp.vc1_unescape_buffer(buf, buf_size, buf2);
 }
 init_get_bits(>gb, buf2, buf_size2*8);
 } else{
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index a29b91bf3d..11d493f002 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -34,6 +34,7 @@
 #include "rnd_avg.h"
 #include "vc1dsp.h"
 #include "startcode.h"
+#include "vc1_common.h"
 
 /* Apply overlap transform to horizontal edge */
 static void vc1_v_overlap_c(uint8_t *src, int stride)
@@ -1030,6 +1031,7 @@ av_cold void ff_vc1dsp_init(VC1DSPContext *dsp)
 #endif /* CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER */
 
 dsp->startcode_find_candidate 

[FFmpeg-devel] [PATCH 03/10] checkasm: Add idctdsp add/put-pixels-clamped tests

2022-03-25 Thread Ben Avison
Disable ff_add_pixels_clamped_arm, which was found to fail the test. As this
is normally only used for Arms prior to Armv6 (ARM11) it seems quite unlikely
that anyone is still using this, so I haven't put in the effort to debug it.

Signed-off-by: Ben Avison 
---
 libavcodec/arm/idctdsp_init_arm.c |  2 +
 tests/checkasm/Makefile   |  1 +
 tests/checkasm/checkasm.c |  3 ++
 tests/checkasm/checkasm.h |  1 +
 tests/checkasm/idctdsp.c  | 85 +++
 tests/fate/checkasm.mak   |  1 +
 6 files changed, 93 insertions(+)
 create mode 100644 tests/checkasm/idctdsp.c

diff --git a/libavcodec/arm/idctdsp_init_arm.c 
b/libavcodec/arm/idctdsp_init_arm.c
index ebc90e4b49..8c8f7daf06 100644
--- a/libavcodec/arm/idctdsp_init_arm.c
+++ b/libavcodec/arm/idctdsp_init_arm.c
@@ -83,7 +83,9 @@ av_cold void ff_idctdsp_init_arm(IDCTDSPContext *c, 
AVCodecContext *avctx,
 }
 }
 
+#if 0 // FIXME: this implementation fails checkasm test
 c->add_pixels_clamped = ff_add_pixels_clamped_arm;
+#endif
 
 if (have_armv5te(cpu_flags))
 ff_idctdsp_init_armv5te(c, avctx, high_bit_depth);
diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile
index 7133a6ee66..f6b1008855 100644
--- a/tests/checkasm/Makefile
+++ b/tests/checkasm/Makefile
@@ -9,6 +9,7 @@ AVCODECOBJS-$(CONFIG_G722DSP)   += g722dsp.o
 AVCODECOBJS-$(CONFIG_H264DSP)   += h264dsp.o
 AVCODECOBJS-$(CONFIG_H264PRED)  += h264pred.o
 AVCODECOBJS-$(CONFIG_H264QPEL)  += h264qpel.o
+AVCODECOBJS-$(CONFIG_IDCTDSP)   += idctdsp.o
 AVCODECOBJS-$(CONFIG_LLVIDDSP)  += llviddsp.o
 AVCODECOBJS-$(CONFIG_LLVIDENCDSP)   += llviddspenc.o
 AVCODECOBJS-$(CONFIG_VC1DSP)+= vc1dsp.o
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index c2efd81b6d..57134f96ea 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -123,6 +123,9 @@ static const struct {
 #if CONFIG_HUFFYUV_DECODER
 { "huffyuvdsp", checkasm_check_huffyuvdsp },
 #endif
+#if CONFIG_IDCTDSP
+{ "idctdsp", checkasm_check_idctdsp },
+#endif
 #if CONFIG_JPEG2000_DECODER
 { "jpeg2000dsp", checkasm_check_jpeg2000dsp },
 #endif
diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h
index 52ab18a5b1..a86db140e3 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -64,6 +64,7 @@ void checkasm_check_hevc_idct(void);
 void checkasm_check_hevc_pel(void);
 void checkasm_check_hevc_sao(void);
 void checkasm_check_huffyuvdsp(void);
+void checkasm_check_idctdsp(void);
 void checkasm_check_jpeg2000dsp(void);
 void checkasm_check_llviddsp(void);
 void checkasm_check_llviddspenc(void);
diff --git a/tests/checkasm/idctdsp.c b/tests/checkasm/idctdsp.c
new file mode 100644
index 00..d94728b672
--- /dev/null
+++ b/tests/checkasm/idctdsp.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2022 Ben Avison
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 "checkasm.h"
+
+#include "libavcodec/idctdsp.h"
+
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mem_internal.h"
+
+#define RANDOMIZE_BUFFER16(name, size)\
+do {  \
+int i;\
+for (i = 0; i < size; ++i) {  \
+uint16_t r = rnd();   \
+AV_WN16A(name##0 + i, r); \
+AV_WN16A(name##1 + i, r); \
+} \
+} while (0)
+
+#define RANDOMIZE_BUFFER8(name, size) \
+do {  \
+int i;\
+for (i = 0; i < size; ++i) {  \
+uint8_t r = rnd();\
+name##0[i] = r;   \
+name##1[i] = r;   \
+} \
+} while (0)
+
+#define CHECK_ADD_PUT_CLAMPED(func)
 \
+do {   
 \
+if (check_func(h.func, 

[FFmpeg-devel] [PATCH 02/10] checkasm: Add vc1dsp inverse transform tests

2022-03-25 Thread Ben Avison
This test deliberately doesn't exercise the full range of inputs described in
the committee draft VC-1 standard. It says:

input coefficients in frequency domain, D, satisfy   -2048 <= D < 2047
intermediate coefficients, E, satisfy-4096 <= E < 4095
fully inverse-transformed coefficients, R, satisfy-512 <= R <  511

For one thing, the inequalities look odd. Did they mean them to go the
other way round? That would make more sense because the equations generally
both add and subtract coefficients multiplied by constants, including powers
of 2. Requiring the most-negative values to be valid extends the number of
bits to represent the intermediate values just for the sake of that one case!

For another thing, the extreme values don't look to occur in real streams -
both in my experience and supported by the following comment in the AArch32
decoder:

tNhalf is half of the value of tN (as described in vc1_inv_trans_8x8_c).
This is done because sometimes files have input that causes tN + tM to
overflow. To avoid this overflow, we compute tNhalf, then compute
tNhalf + tM (which doesn't overflow), and then we use vhadd to compute
(tNhalf + (tNhalf + tM)) >> 1 which does not overflow because it is
one instruction.

My AArch64 decoder goes further than this. It calculates tNhalf and tM
then does an SRA (essentially a fused halve and add) to compute
(tN + tM) >> 1 without ever having to hold (tNhalf + tM) in a 16-bit element
without overflowing. It only encounters difficulties if either tNhalf or
tM overflow in isolation.

I haven't had sight of the final standard, so it's possible that these
issues were dealt with during finalisation, which could explain the lack
of usage of extreme inputs in real streams. Or a preponderance of decoders
that only support 16-bit intermediate values in their inverse transforms
might have caused encoders to steer clear of such cases.

I have effectively followed this approach in the test, and limited the
scale of the coefficients sufficient that both the existing AArch32 decoder
and my new AArch64 decoder both pass.

Signed-off-by: Ben Avison 
---
 tests/checkasm/vc1dsp.c | 258 
 1 file changed, 258 insertions(+)

diff --git a/tests/checkasm/vc1dsp.c b/tests/checkasm/vc1dsp.c
index db916d08f9..0823ccad31 100644
--- a/tests/checkasm/vc1dsp.c
+++ b/tests/checkasm/vc1dsp.c
@@ -29,6 +29,200 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mem_internal.h"
 
+typedef struct matrix {
+size_t width;
+size_t height;
+float d[];
+} matrix;
+
+static const matrix T8 = { 8, 8, {
+12,  12,  12,  12,  12,  12,  12,  12,
+16,  15,   9,   4,  -4,  -9, -15, -16,
+16,   6,  -6, -16, -16,  -6,   6,  16,
+15,  -4, -16,  -9,   9,  16,   4, -15,
+12, -12, -12,  12,  12, -12, -12,  12,
+ 9, -16,   4,  15, -15,  -4,  16,  -9,
+ 6, -16,  16,  -6,  -6,  16, -16,   6,
+ 4,  -9,  15, -16,  16, -15,   9,  -4
+} };
+
+static const matrix T4 = { 4, 4, {
+17,  17,  17,  17,
+22,  10, -10, -22,
+17, -17, -17,  17,
+10, -22,  22, -10
+} };
+
+static const matrix T8t = { 8, 8, {
+12,  16,  16,  15,  12,   9,   6,   4,
+12,  15,   6,  -4, -12, -16, -16,  -9,
+12,   9,  -6, -16, -12,   4,  16,  15,
+12,   4, -16,  -9,  12,  15,  -6, -16,
+12,  -4, -16,   9,  12, -15,  -6,  16,
+12,  -9,  -6,  16, -12,  -4,  16, -15,
+12, -15,   6,   4, -12,  16, -16,   9,
+12, -16,  16, -15,  12,  -9,   6,  -4
+} };
+
+static const matrix T4t = { 4, 4, {
+17,  22,  17,  10,
+17,  10, -17, -22,
+17, -10, -17,  22,
+17, -22,  17, -10
+} };
+
+static matrix *new_matrix(size_t width, size_t height)
+{
+matrix *out = av_mallocz(sizeof (matrix) + height * width * sizeof 
(float));
+if (out == NULL) {
+fprintf(stderr, "Memory allocation failure\n");
+exit(EXIT_FAILURE);
+}
+out->width = width;
+out->height = height;
+return out;
+}
+
+static matrix *multiply(const matrix *a, const matrix *b)
+{
+matrix *out;
+if (a->width != b->height) {
+fprintf(stderr, "Incompatible multiplication\n");
+exit(EXIT_FAILURE);
+}
+out = new_matrix(b->width, a->height);
+for (int j = 0; j < out->height; ++j)
+for (int i = 0; i < out->width; ++i) {
+float sum = 0;
+for (int k = 0; k < a->width; ++k)
+sum += a->d[j * a->width + k] * b->d[k * b->width + i];
+out->d[j * out->width + i] = sum;
+}
+return out;
+}
+
+static void normalise(matrix *a)
+{
+for (int j = 0; j < a->height; ++j)
+for (int i = 0; i < a->width; ++i) {
+float *p = a->d + j * a->width + i;
+*p *= 64;
+if (a->height == 4)
+*p /= (const unsigned[]) { 289, 292, 289, 292 } [j];
+else
+  

[FFmpeg-devel] [PATCH 01/10] checkasm: Add vc1dsp in-loop deblocking filter tests

2022-03-25 Thread Ben Avison
Note that the benchmarking results for these functions are highly dependent
upon the input data. Therefore, each function is benchmarked twice,
corresponding to the best and worst case complexity of the reference C
implementation. The performance of a real stream decode will fall somewhere
between these two extremes.

Signed-off-by: Ben Avison 
---
 tests/checkasm/Makefile   |  1 +
 tests/checkasm/checkasm.c |  3 ++
 tests/checkasm/checkasm.h |  1 +
 tests/checkasm/vc1dsp.c   | 94 +++
 tests/fate/checkasm.mak   |  1 +
 5 files changed, 100 insertions(+)
 create mode 100644 tests/checkasm/vc1dsp.c

diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile
index f768b1144e..7133a6ee66 100644
--- a/tests/checkasm/Makefile
+++ b/tests/checkasm/Makefile
@@ -11,6 +11,7 @@ AVCODECOBJS-$(CONFIG_H264PRED)  += h264pred.o
 AVCODECOBJS-$(CONFIG_H264QPEL)  += h264qpel.o
 AVCODECOBJS-$(CONFIG_LLVIDDSP)  += llviddsp.o
 AVCODECOBJS-$(CONFIG_LLVIDENCDSP)   += llviddspenc.o
+AVCODECOBJS-$(CONFIG_VC1DSP)+= vc1dsp.o
 AVCODECOBJS-$(CONFIG_VP8DSP)+= vp8dsp.o
 AVCODECOBJS-$(CONFIG_VIDEODSP)  += videodsp.o
 
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index 748d6a9f3a..c2efd81b6d 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -147,6 +147,9 @@ static const struct {
 #if CONFIG_V210_ENCODER
 { "v210enc", checkasm_check_v210enc },
 #endif
+#if CONFIG_VC1DSP
+{ "vc1dsp", checkasm_check_vc1dsp },
+#endif
 #if CONFIG_VP8DSP
 { "vp8dsp", checkasm_check_vp8dsp },
 #endif
diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h
index c3192d8c23..52ab18a5b1 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -78,6 +78,7 @@ void checkasm_check_sw_scale(void);
 void checkasm_check_utvideodsp(void);
 void checkasm_check_v210dec(void);
 void checkasm_check_v210enc(void);
+void checkasm_check_vc1dsp(void);
 void checkasm_check_vf_eq(void);
 void checkasm_check_vf_gblur(void);
 void checkasm_check_vf_hflip(void);
diff --git a/tests/checkasm/vc1dsp.c b/tests/checkasm/vc1dsp.c
new file mode 100644
index 00..db916d08f9
--- /dev/null
+++ b/tests/checkasm/vc1dsp.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2022 Ben Avison
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 "checkasm.h"
+
+#include "libavcodec/vc1dsp.h"
+
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mem_internal.h"
+
+#define RANDOMIZE_BUFFER8_MID_WEIGHTED(name, size)  \
+do {\
+uint8_t *p##0 = name##0, *p##1 = name##1;   \
+int i = (size); \
+while (i-- > 0) {   \
+int x = 0x80 | (rnd() & 0x7F);  \
+x >>= rnd() % 9;\
+if (rnd() & 1)  \
+x = -x; \
+*p##1++ = *p##0++ = 0x80 + x;   \
+}   \
+} while (0)
+
+#define CHECK_LOOP_FILTER(func) \
+do {\
+if (check_func(h.func, "vc1dsp." #func)) {  \
+declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, int, int);  \
+for (int count = 1000; count > 0; --count) {\
+int pq = rnd() % 31 + 1;\
+RANDOMIZE_BUFFER8_MID_WEIGHTED(filter_buf, 24 * 24);\
+call_ref(filter_buf0 + 4 * 24 + 4, 24, pq); \
+call_new(filter_buf1 + 4 * 24 + 4, 24, pq); \
+if (memcmp(filter_buf0, filter_buf1, 24 * 24))  \
+fail(); \
+}   \
+}   \
+for (int j = 0; 

[FFmpeg-devel] [PATCH v2 00/10] avcodec/vc1: Arm optimisations

2022-03-25 Thread Ben Avison
The VC1 decoder was missing lots of important fast paths for Arm, especially
for 64-bit Arm. This submission fills in implementations for all functions
where a fast path already existed and the fallback C implementation was
taking 1% or more of the runtime, and adds a new fast path to permit
vc1_unescape_buffer() to be overridden.

I've measured the playback speed on a 1.5 GHz Cortex-A72 (Raspberry Pi 4)
using `ffmpeg -i  -f null -` for a couple of example streams:

Architecture:  AArch32AArch32AArch64AArch64
Stream:1  2  1  2
Before speed:  1.22x  0.82x  1.00x  0.67x
After speed:   1.31x  0.98x  1.39x  1.06x
Improvement:   7.4%   20%39%58%

`make fate` passes on both AArch32 and AArch64.

Changes in v2:

* Use AV_RL32 when performing unaligned loads from C.
* Work around bug in some assemblers which require a size specifier on VMOV
  scalar-to-general-purpose-register for AArch32.
* Increase operand indentation in AArch64 assembly.
* Add checkasm tests for each fast path for which they did not yet exist.
* Add benchmarks (generated via checkasm) to individual commits.
* Remove AArch64 blockdsp fast paths since it was impossible to demonstrate
  that they had any appreciable effect on timings.

Ben Avison (10):
  checkasm: Add vc1dsp in-loop deblocking filter tests
  checkasm: Add vc1dsp inverse transform tests
  checkasm: Add idctdsp add/put-pixels-clamped tests
  avcodec/vc1: Introduce fast path for unescaping bitstream buffer
  avcodec/vc1: Arm 64-bit NEON deblocking filter fast paths
  avcodec/vc1: Arm 32-bit NEON deblocking filter fast paths
  avcodec/vc1: Arm 64-bit NEON inverse transform fast paths
  avcodec/idctdsp: Arm 64-bit NEON block add and clamp fast paths
  avcodec/vc1: Arm 64-bit NEON unescape fast path
  avcodec/vc1: Arm 32-bit NEON unescape fast path

 libavcodec/aarch64/Makefile   |4 +-
 libavcodec/aarch64/idctdsp_init_aarch64.c |   26 +-
 libavcodec/aarch64/idctdsp_neon.S |  130 ++
 libavcodec/aarch64/vc1dsp_init_aarch64.c  |   94 ++
 libavcodec/aarch64/vc1dsp_neon.S  | 1552 +
 libavcodec/arm/idctdsp_init_arm.c |2 +
 libavcodec/arm/vc1dsp_init_neon.c |   75 +
 libavcodec/arm/vc1dsp_neon.S  |  761 ++
 libavcodec/vc1dec.c   |   20 +-
 libavcodec/vc1dsp.c   |2 +
 libavcodec/vc1dsp.h   |3 +
 tests/checkasm/Makefile   |2 +
 tests/checkasm/checkasm.c |6 +
 tests/checkasm/checkasm.h |2 +
 tests/checkasm/idctdsp.c  |   85 ++
 tests/checkasm/vc1dsp.c   |  411 ++
 tests/fate/checkasm.mak   |2 +
 17 files changed, 3158 insertions(+), 19 deletions(-)
 create mode 100644 libavcodec/aarch64/idctdsp_neon.S
 create mode 100644 libavcodec/aarch64/vc1dsp_neon.S
 create mode 100644 tests/checkasm/idctdsp.c
 create mode 100644 tests/checkasm/vc1dsp.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".


Re: [FFmpeg-devel] [PATCH 1/3] avcodec/h264_slice: Fix decoding undamaged input with slices

2022-03-25 Thread Michael Niedermayer
On Thu, Mar 24, 2022 at 09:20:06PM +0100, Andreas Rheinhardt wrote:
> ff_er_frame_start() initializes ERContext.error_count
> to three times the number of macroblocks to decode.
> Later ff_er_add_slice() reduces this number by the amount
> of macroblocks whose AC resp. DC resp. MV have been finished
> (so every correctly decoded MB counts three times).
> So the frame has been decoded correctly if error_count is zero
> at the end.
> 
> The H.264 decoder uses multiple ERContexts when using
> slice threading and therefore combines these error counts:
> The first slice's ERContext is intended to be initialized
> by ff_er_frame_start(), error_count of all the other
> slice contexts is intended to be zeroed initially and
> all afterwards all the error_counts are summed.
> 
> Yet commit 43b434210e597d484aef57c4139c3126d22b7e2b
> (probably unintentionally) changed the code to set
> the first slice's error_count to zero as well.
> This leads to bogus error messages in case one decodes
> an input video using multiple slices with slice threading
> with error concealment enabled (which is not the default)
> ("concealing 0 DC, 0 AC, 0 MV errors in [IPB] frame");
> furthermore the returned frame is marked as corrupt as well
> (ffmpeg reports "corrupt decoded frame in stream %d" for this).
> 
> This can be fixed easily given that only the first ERContext
> is really used since 7be2d2a70cd20d88fd826a83f87037d14681a579:
> Don't reset the error_count; and don't sum the error counts as well.
> 
> Signed-off-by: Andreas Rheinhardt 
> ---
>  libavcodec/h264_slice.c | 7 ---
>  1 file changed, 7 deletions(-)

this patchset is a nice cleanup/fix to the error concealment code
in h264

thx

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

Frequently ignored answer#1 FFmpeg bugs should be sent to our bugtracker. User
questions about the command line tools should be sent to the ffmpeg-user ML.
And questions about how to use libav* should be sent to the libav-user ML.


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] [PATCH v4 20/22] doc/examples: adding device_get_capabilities example

2022-03-25 Thread Michael Niedermayer
On Fri, Mar 25, 2022 at 03:10:39PM +0100, Diederick Niehorster wrote:
> This example also shows use of get_device_list API.
> 
> Also improve capability API doc in avdevice.h: now point to this example
> instead of rough example code given in the header.
> 
> Signed-off-by: Diederick Niehorster 
> ---
>  configure  |   2 +
>  doc/examples/.gitignore|   1 +
>  doc/examples/Makefile  |   1 +
>  doc/examples/Makefile.example  |   1 +
>  doc/examples/device_get_capabilities.c | 243 +
>  libavdevice/avdevice.h |  33 +---
>  6 files changed, 249 insertions(+), 32 deletions(-)
>  create mode 100644 doc/examples/device_get_capabilities.c

maybe i forgot something but this seems not building

make examples -j32

CC  doc/examples/device_get_capabilities.o
In file included from ./libavformat/avformat.h:330:0,
 from doc/examples/device_get_capabilities.c:33:
./libavformat/version.h:55:1: warning: function declaration isn’t a prototype 
[-Wstrict-prototypes]
 unsigned avformat_version_same_minor();
 ^~~~
In file included from ./libavdevice/avdevice.h:27:0,
 from doc/examples/device_get_capabilities.c:34:
./libavdevice/version.h:54:1: warning: function declaration isn’t a prototype 
[-Wstrict-prototypes]
 unsigned avdevice_version_same_minor();
 ^~~~
doc/examples/device_get_capabilities.c:39:5: error: no previous prototype for 
‘print_option_ranges’ [-Werror=missing-prototypes]
 int print_option_ranges(enum AVOptionType type, AVOptionRanges *ranges)
 ^~~
doc/examples/device_get_capabilities.c:73:6: warning: function declaration 
isn’t a prototype [-Wstrict-prototypes]
 void list_queries()
  ^~~~
doc/examples/device_get_capabilities.c:81:6: error: no previous prototype for 
‘list_device_sources’ [-Werror=missing-prototypes]
 void list_device_sources(const AVInputFormat *fmt)
  ^~~
cc1: some warnings being treated as errors
ffbuild/common.mak:78: recipe for target 
'doc/examples/device_get_capabilities.o' failed
make: *** [doc/examples/device_get_capabilities.o] Error 1
make: *** Waiting for unfinished jobs


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

Its not that you shouldnt use gotos but rather that you should write
readable code and code with gotos often but not always is less readable


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".


[FFmpeg-devel] [PATCH v2] avfilter/vf_libplacebo: update for new tone mapping API

2022-03-25 Thread Niklas Haas
From: Niklas Haas 

Upstream gained a new tone-mapping API, which we never switched to. We
don't need a version bump for this because it was included as part of
the v4.192 release we currently already depend on.

Some of the old options can be moderately approximated with the new API,
but specifically "desaturation_base" and "max_boost" cannot. Remove
these entirely, rather than deprecating them. They have actually been
non-functional for a while as a result of the upstream deprecation.

Signed-off-by: Niklas Haas 
---
Changes in v2:
- Avoid use of strings in favor of replicating the enum values
- Fix two wrong enum option value ranges
- Simplify the option setting code again slightly
---
 libavfilter/vf_libplacebo.c | 112 
 1 file changed, 89 insertions(+), 23 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 31ae28ac38..8ce6462c66 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -26,6 +26,33 @@
 #include 
 #include 
 
+enum {
+TONE_MAP_AUTO,
+TONE_MAP_CLIP,
+TONE_MAP_BT2390,
+TONE_MAP_BT2446A,
+TONE_MAP_SPLINE,
+TONE_MAP_REINHARD,
+TONE_MAP_MOBIUS,
+TONE_MAP_HABLE,
+TONE_MAP_GAMMA,
+TONE_MAP_LINEAR,
+TONE_MAP_COUNT,
+};
+
+static const struct pl_tone_map_function * const 
tonemapping_funcs[TONE_MAP_COUNT] = {
+[TONE_MAP_AUTO] = _tone_map_auto,
+[TONE_MAP_CLIP] = _tone_map_clip,
+[TONE_MAP_BT2390]   = _tone_map_bt2390,
+[TONE_MAP_BT2446A]  = _tone_map_bt2446a,
+[TONE_MAP_SPLINE]   = _tone_map_spline,
+[TONE_MAP_REINHARD] = _tone_map_reinhard,
+[TONE_MAP_MOBIUS]   = _tone_map_mobius,
+[TONE_MAP_HABLE]= _tone_map_hable,
+[TONE_MAP_GAMMA]= _tone_map_gamma,
+[TONE_MAP_LINEAR]   = _tone_map_linear,
+};
+
 typedef struct LibplaceboContext {
 /* lavfi vulkan*/
 FFVulkanContext vkctx;
@@ -91,12 +118,16 @@ typedef struct LibplaceboContext {
 
 /* pl_color_map_params */
 int intent;
+int gamut_mode;
 int tonemapping;
 float tonemapping_param;
+int tonemapping_mode;
+int inverse_tonemapping;
+float crosstalk;
+int tonemapping_lut_size;
+/* for backwards compatibility */
 float desat_str;
 float desat_exp;
-float desat_base;
-float max_boost;
 int gamut_warning;
 int gamut_clipping;
 
@@ -281,6 +312,8 @@ static int process_frames(AVFilterContext *avctx, AVFrame 
*out, AVFrame *in)
 int err = 0, ok;
 LibplaceboContext *s = avctx->priv;
 struct pl_render_params params;
+enum pl_tone_map_mode tonemapping_mode = s->tonemapping_mode;
+enum pl_gamut_mode gamut_mode = s->gamut_mode;
 struct pl_frame image, target;
 ok = pl_map_avframe_ex(s->gpu, , pl_avframe_params(
 .frame= in,
@@ -305,6 +338,24 @@ static int process_frames(AVFilterContext *avctx, AVFrame 
*out, AVFrame *in)
 pl_rect2df_aspect_set(, aspect, s->pad_crop_ratio);
 }
 
+/* backwards compatibility with older API */
+if (!tonemapping_mode && (s->desat_str >= 0.0f || s->desat_exp >= 0.0f)) {
+float str = s->desat_str < 0.0f ? 0.9f : s->desat_str;
+float exp = s->desat_exp < 0.0f ? 0.2f : s->desat_exp;
+if (str >= 0.9f && exp <= 0.1f) {
+tonemapping_mode = PL_TONE_MAP_RGB;
+} else if (str > 0.1f) {
+tonemapping_mode = PL_TONE_MAP_HYBRID;
+} else {
+tonemapping_mode = PL_TONE_MAP_LUMA;
+}
+}
+
+if (s->gamut_warning)
+gamut_mode = PL_GAMUT_WARN;
+if (s->gamut_clipping)
+gamut_mode = PL_GAMUT_DESATURATE;
+
 /* Update render params */
 params = (struct pl_render_params) {
 PL_RENDER_DEFAULTS
@@ -338,14 +389,13 @@ static int process_frames(AVFilterContext *avctx, AVFrame 
*out, AVFrame *in)
 
 .color_map_params = pl_color_map_params(
 .intent = s->intent,
-.tone_mapping_algo = s->tonemapping,
+.gamut_mode = gamut_mode,
+.tone_mapping_function = tonemapping_funcs[s->tonemapping],
 .tone_mapping_param = s->tonemapping_param,
-.desaturation_strength = s->desat_str,
-.desaturation_exponent = s->desat_exp,
-.desaturation_base = s->desat_base,
-.max_boost = s->max_boost,
-.gamut_warning = s->gamut_warning,
-.gamut_clipping = s->gamut_clipping,
+.tone_mapping_mode = tonemapping_mode,
+.inverse_tone_mapping = s->inverse_tonemapping,
+.tone_mapping_crosstalk = s->crosstalk,
+.lut_size = s->tonemapping_lut_size,
 ),
 
 .dither_params = s->dithering < 0 ? NULL : pl_dither_params(
@@ -616,21 +666,37 @@ static const AVOption libplacebo_options[] = {
 { "relative", "Relative colorimetric", 0, AV_OPT_TYPE_CONST, {.i64 = 
PL_INTENT_RELATIVE_COLORIMETRIC}, 0, 0, STATIC, "intent" },
 { "absolute", "Absolute 

[FFmpeg-devel] [PATCH v4 22/22] avdevice/dshow: capabilities query also works on opened device

2022-03-25 Thread Diederick Niehorster
While the capabilities API is in principle meant to be used with an
allocated format context belonging to an unopened device, small changes
make it work for an opened dshow device as well. So hereby done.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 110 +---
 libavdevice/dshow_capture.h |   3 +
 2 files changed, 66 insertions(+), 47 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index c426cef905..216c888bed 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -849,7 +849,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 void *caps = NULL;
 int i, n, size, r;
 int wait_for_better = 0;
-int use_default;
+int use_default, already_opened;
 
 // format parameters requested by user
 // if none are requested by user, the values will below be set to
@@ -875,6 +875,9 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 if (!caps)
 goto end;
 
+// get if device is already opened
+already_opened = ctx->device_name[0] || ctx->device_name[1];
+
 /**
  * If we should open the device with the default format,
  * then:
@@ -1153,7 +1156,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 // in ranges, try to apply in all cases, and store
 // caps if successfully applied
 if (!wait_for_better || ranges) {
-if (IAMStreamConfig_SetFormat(config, type) != S_OK)
+if (!already_opened && IAMStreamConfig_SetFormat(config, type) != 
S_OK) // skip if device already opened
 goto next;
 else if (ranges) {
 // format matched and could be set successfully.
@@ -1494,12 +1497,19 @@ dshow_list_device_options(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 char *device_unique_name = NULL;
 int r;
 
-if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
_filter, _unique_name, NULL)) < 0)
-return r;
-ctx->device_filter[devtype] = device_filter;
-ctx->device_unique_name[devtype] = device_unique_name;
+if (!ctx->device_filter[devtype]) {
+if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
_filter, _unique_name, NULL)) < 0)
+return r;
+
+// put them in context so they'll be cleaned up again
+ctx->device_filter[devtype] = device_filter;
+ctx->device_unique_name[devtype] = device_unique_name;
+} else
+device_filter = ctx->device_filter[devtype];
+
 if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, 
ranges ? _pin : NULL, ranges, query_type)) < 0)
 return r;
+
 return 0;
 }
 
@@ -2319,7 +2329,8 @@ fail1:
 return ret;
 }
 
-// fake class to point av_opt_query_ranges to our query_ranges function
+// fake class to point av_opt functions to capabilities that can be queried,
+// and av_opt_query_ranges to our query_ranges function
 static const AVClass dshow_dev_caps_class = {
 .class_name   = "",
 .item_name= av_default_item_name,
@@ -2337,49 +2348,51 @@ static int dshow_create_device_capabilities(struct 
AVFormatContext *avctx, AVDev
 // set class so queries work
 caps->av_class = _dev_caps_class;
 
-if (ctx->device_name[0] || ctx->device_name[1]) {
-av_log(avctx, AV_LOG_ERROR, "You cannot query device capabilities on 
an opened device\n");
-ret = AVERROR(EIO);
-goto fail;
-}
+// check if device setup is needed or we will be querying capabilities of 
an already opened device
+ctx->cap_query_already_opened = ctx->device_name[0] || ctx->device_name[1];
+if (ctx->cap_query_already_opened)
+av_log(avctx, AV_LOG_WARNING, "Querying device capabilities on an 
opened device: may yield false positives\n");
 
-if (!parse_device_name(avctx)) {
-av_log(avctx, AV_LOG_ERROR, "You must set a device name 
(AVFormatContext url) to specify which device to query capabilities from\n");
-ret = AVERROR(EINVAL);
-goto fail;
-}
-
-CoInitialize(0);
-if (CoCreateInstance(_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
- _ICreateDevEnum, (void **) )) {
-av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
-ret = AVERROR(EIO);
-goto fail;
-}
+// if device not already opened, check that what user specified can be 
opened
+if (!ctx->cap_query_already_opened) {
+if (!parse_device_name(avctx)) {
+av_log(avctx, AV_LOG_ERROR, "You must set a device name 
(AVFormatContext url) to specify which device to query capabilities from\n");
+ret = AVERROR(EINVAL);
+goto fail;
+}
 
-// check devices can be found
-if (ctx->device_name[VideoDevice]) {
-IBaseFilter *device_filter = NULL;
-char *device_unique_name = NULL;
-if ((ret = 

[FFmpeg-devel] [PATCH v4 21/22] Makefile/examples: cosmetics

2022-03-25 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 doc/examples/Makefile | 48 +--
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index de707bb3ca..7988ed4226 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -1,27 +1,27 @@
-EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
-EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE)  += avio_reading
-EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE)  += decode_audio
-EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE)  += decode_video
-EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
-EXAMPLES-$(CONFIG_DEVICE_GET_CAPABILITIES_EXAMPLE) += device_get_capabilities
-EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE)  += encode_audio
-EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE)  += encode_video
-EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE)   += extract_mvs
-EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE)  += filter_audio
-EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE)   += filtering_audio
-EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE)   += filtering_video
-EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE)  += http_multiclient
-EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
-EXAMPLES-$(CONFIG_METADATA_EXAMPLE)  += metadata
-EXAMPLES-$(CONFIG_MUXING_EXAMPLE)+= muxing
-EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)+= qsvdec
-EXAMPLES-$(CONFIG_REMUXING_EXAMPLE)  += remuxing
-EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE)  += resampling_audio
-EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
-EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
-EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE)   += transcoding
-EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE)  += vaapi_encode
-EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE)   += vaapi_transcode
+EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
+EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE)  += avio_reading
+EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE)  += decode_audio
+EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE)  += decode_video
+EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
+EXAMPLES-$(CONFIG_DEVICE_GET_CAPABILITIES_EXAMPLE)   += device_get_capabilities
+EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE)  += encode_audio
+EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE)  += encode_video
+EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE)   += extract_mvs
+EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE)  += filter_audio
+EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE)   += filtering_audio
+EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE)   += filtering_video
+EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE)  += http_multiclient
+EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
+EXAMPLES-$(CONFIG_METADATA_EXAMPLE)  += metadata
+EXAMPLES-$(CONFIG_MUXING_EXAMPLE)+= muxing
+EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)+= qsvdec
+EXAMPLES-$(CONFIG_REMUXING_EXAMPLE)  += remuxing
+EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE)  += resampling_audio
+EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
+EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
+EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE)   += transcoding
+EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE)  += vaapi_encode
+EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE)   += vaapi_transcode
 
 EXAMPLES   := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
 EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 20/22] doc/examples: adding device_get_capabilities example

2022-03-25 Thread Diederick Niehorster
This example also shows use of get_device_list API.

Also improve capability API doc in avdevice.h: now point to this example
instead of rough example code given in the header.

Signed-off-by: Diederick Niehorster 
---
 configure  |   2 +
 doc/examples/.gitignore|   1 +
 doc/examples/Makefile  |   1 +
 doc/examples/Makefile.example  |   1 +
 doc/examples/device_get_capabilities.c | 243 +
 libavdevice/avdevice.h |  33 +---
 6 files changed, 249 insertions(+), 32 deletions(-)
 create mode 100644 doc/examples/device_get_capabilities.c

diff --git a/configure b/configure
index a7953ffc16..5c361f91a0 100755
--- a/configure
+++ b/configure
@@ -1726,6 +1726,7 @@ EXAMPLE_LIST="
 decode_audio_example
 decode_video_example
 demuxing_decoding_example
+device_get_capabilities_example
 encode_audio_example
 encode_video_example
 extract_mvs_example
@@ -3751,6 +3752,7 @@ avio_reading_deps="avformat avcodec avutil"
 decode_audio_example_deps="avcodec avutil"
 decode_video_example_deps="avcodec avutil"
 demuxing_decoding_example_deps="avcodec avformat avutil"
+device_get_capabilities_example_deps="avdevice avformat avutil"
 encode_audio_example_deps="avcodec avutil"
 encode_video_example_deps="avcodec avutil"
 extract_mvs_example_deps="avcodec avformat avutil"
diff --git a/doc/examples/.gitignore b/doc/examples/.gitignore
index 44960e1de7..256f33a600 100644
--- a/doc/examples/.gitignore
+++ b/doc/examples/.gitignore
@@ -3,6 +3,7 @@
 /decode_audio
 /decode_video
 /demuxing_decoding
+/device_get_capabilities
 /encode_audio
 /encode_video
 /extract_mvs
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 81bfd34d5d..de707bb3ca 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -3,6 +3,7 @@ EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE)  += avio_reading
 EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE)  += decode_audio
 EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE)  += decode_video
 EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
+EXAMPLES-$(CONFIG_DEVICE_GET_CAPABILITIES_EXAMPLE) += device_get_capabilities
 EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE)  += encode_audio
 EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE)  += encode_video
 EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE)   += extract_mvs
diff --git a/doc/examples/Makefile.example b/doc/examples/Makefile.example
index a232d97f98..b861b9cc74 100644
--- a/doc/examples/Makefile.example
+++ b/doc/examples/Makefile.example
@@ -16,6 +16,7 @@ EXAMPLES=   avio_list_dir  \
 decode_audio   \
 decode_video   \
 demuxing_decoding  \
+device_get_capabilities\
 encode_audio   \
 encode_video   \
 extract_mvs\
diff --git a/doc/examples/device_get_capabilities.c 
b/doc/examples/device_get_capabilities.c
new file mode 100644
index 00..45eb2eadf4
--- /dev/null
+++ b/doc/examples/device_get_capabilities.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2021 Diederick Niehorster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * avdevice getting capabilities example.
+ *
+ * Shows how to use the avdevice capabilities API to probe
+ * device capabilities (supported codecs, pixel formats, sample
+ * formats, resolutions, channel counts, etc)
+ * @example device_get_capabilities.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int print_option_ranges(enum AVOptionType type, AVOptionRanges *ranges)
+{
+for (int range_index = 0; range_index < ranges->nb_ranges; range_index++) {
+int ret;
+char *out_val = NULL;
+AVBPrint bp;
+av_bprint_init(, 0, 

[FFmpeg-devel] [PATCH v4 19/22] avformat: add avformat_alloc_input_context()

2022-03-25 Thread Diederick Niehorster
avformat_alloc_input_context function analogous to
avformat_alloc_output_context2, except that it does not take a filename
argument as guessing the format by just the filename does not make sense.
avformat_alloc_input_context can be used e.g. with the avdevice
capabilities API, which needs an allocated input format with priv_data
(and default options) set, but device should not be opened.

Added some checks to avformat_open_input, for the case that a
AVFormatContext* allocated by avformat_alloc_input_context is provided:
1.  if avformat_open_input's AVInputFormat *fmt argument is not NULL,
clean up any already set s->iformat
2.  if s->url is already set and avformat_open_input's filename argument
is not NULL, free current url and replace by provided filename
3.  if s->url is already set and avformat_open_input's filename argument
is NULL, do not set s->url to "", but keep current url
4.  if s->priv_data has already been allocated, do not do so again.
4b. do reset options to default and apply provided options (if any)
5.  add 4b to docs of avformat_open_input

Bump libavformat version.

Signed-off-by: Diederick Niehorster 
---
 libavformat/avformat.h | 29 +++--
 libavformat/demux.c| 74 ++
 libavformat/version.h  |  2 +-
 3 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 027a914e13..004d81640f 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2024,6 +2024,26 @@ AVProgram *av_new_program(AVFormatContext *s, int id);
  * @}
  */
 
+ /**
+  * Allocate an AVFormatContext for an input format.
+  * avformat_free_context() can be used to free the context and
+  * everything allocated by the framework within it. NB: in general
+  * the correct format cannot be known (unless the user has extra
+  * information) until the file is opened. If forcing a format by
+  * this method, but it turns out not to match the file's format
+  * upon avformat_open_input(), the latter will throw an error.
+  *
+  * @param *ctx is set to the created format context, or to NULL in
+  * case of failure
+  * @param iformat format to use for allocating the context, if NULL
+  * format_name is used instead
+  * @param format_name the name of input format to use for allocating the
+  * context
+  * @return >= 0 in case of success, a negative AVERROR code in case of
+  * failure
+  */
+int avformat_alloc_input_context(AVFormatContext **ctx, const AVInputFormat 
*iformat,
+ const char *format_name);
 
 /**
  * Allocate an AVFormatContext for an output format.
@@ -2119,9 +2139,9 @@ int av_probe_input_buffer(AVIOContext *pb, const 
AVInputFormat **fmt,
  * Open an input stream and read the header. The codecs are not opened.
  * The stream must be closed with avformat_close_input().
  *
- * @param ps Pointer to user-supplied AVFormatContext (allocated by 
avformat_alloc_context).
- *   May be a pointer to NULL, in which case an AVFormatContext is 
allocated by this
- *   function and written into ps.
+ * @param ps Pointer to user-supplied AVFormatContext (allocated by 
avformat_alloc_context, or
+ *   avformat_alloc_input_context). May be a pointer to NULL, in which 
case an
+ *   AVFormatContext is allocated by this function and written into ps.
  *   Note that a user-supplied AVFormatContext will be freed on 
failure.
  * @param url URL of the stream to open.
  * @param fmt If non-NULL, this parameter forces a specific input format.
@@ -2129,6 +2149,9 @@ int av_probe_input_buffer(AVIOContext *pb, const 
AVInputFormat **fmt,
  * @param options  A dictionary filled with AVFormatContext and 
demuxer-private options.
  * On return this parameter will be destroyed and replaced 
with a dict containing
  * options that were not found. May be NULL.
+ * Note that if a AVFormatContext allocated by 
avformat_alloc_input_context
+ * is provided, any demuxer-private options will be 
overwritten by their defaults
+ * before applying this new set of demuxer-private options, if 
any. 
  *
  * @return 0 on success, a negative AVERROR on failure.
  *
diff --git a/libavformat/demux.c b/libavformat/demux.c
index c1c9422ac0..b314477e47 100644
--- a/libavformat/demux.c
+++ b/libavformat/demux.c
@@ -217,6 +217,56 @@ FF_ENABLE_DEPRECATION_WARNINGS
 return 0;
 }
 
+
+int avformat_alloc_input_context(AVFormatContext** avctx, const AVInputFormat* 
iformat,
+const char* format)
+{
+AVFormatContext* s = avformat_alloc_context();
+int ret = 0;
+
+*avctx = NULL;
+if (!s)
+goto nomem;
+
+if (!iformat) {
+if (format) {
+iformat = av_find_input_format(format);
+if (!iformat) {
+av_log(s, AV_LOG_ERROR, "Requested input format '%s' not 
found\n", format);
+ret = AVERROR(EINVAL);

[FFmpeg-devel] [PATCH v4 18/22] avdevice/dshow: cosmetics

2022-03-25 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 25c7f5a0e8..c426cef905 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -933,6 +933,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 AVOptionRange *new_range[3] = { NULL };
 int nb_range = 0;
 struct dshow_format_info *fmt_info = NULL;
+
 r = IAMStreamConfig_GetStreamCaps(config, i, , (void *) caps);
 if (r != S_OK)
 goto next;
@@ -1558,7 +1559,8 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 goto error;
 }
 }
-if (ctx->device_filter[otherDevType]) {
+
+if (ctx->device_filter[otherDevType]) {
 // avoid adding add two instances of the same device to the graph, one 
for video, one for audio
 // a few devices don't support this (could also do this check earlier 
to avoid double crossbars, etc. but they seem OK)
 if (strcmp(device_filter_unique_name, 
ctx->device_unique_name[otherDevType]) == 0) {
@@ -2441,17 +2443,16 @@ static const AVClass dshow_class = {
 };
 
 const AVInputFormat ff_dshow_demuxer = {
-.name   = "dshow",
-.long_name  = NULL_IF_CONFIG_SMALL("DirectShow capture"),
-.priv_data_size = sizeof(struct dshow_ctx),
-.read_header= dshow_read_header,
-.read_packet= dshow_read_packet,
-.read_close = dshow_read_close,
-.get_device_list= dshow_get_device_list,
-.control_message= dshow_control_message,
-.get_device_list= dshow_get_device_list,
+.name   = "dshow",
+.long_name  = NULL_IF_CONFIG_SMALL("DirectShow capture"),
+.priv_data_size = sizeof(struct dshow_ctx),
+.read_header= dshow_read_header,
+.read_packet= dshow_read_packet,
+.read_close = dshow_read_close,
+.control_message= dshow_control_message,
+.get_device_list= dshow_get_device_list,
 .create_device_capabilities = dshow_create_device_capabilities,
-.free_device_capabilities = dshow_free_device_capabilities,
-.flags  = AVFMT_NOFILE | AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | 
AVFMT_NO_BYTE_SEEK,
-.priv_class = _class,
+.free_device_capabilities   = dshow_free_device_capabilities,
+.flags  = AVFMT_NOFILE | AVFMT_NOBINSEARCH | 
AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK,
+.priv_class = _class,
 };
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 17/22] avdevice/dshow: implement capabilities API

2022-03-25 Thread Diederick Niehorster
This implements avdevice_capabilities_create and
avdevice_capabilities_free for the dshow device.

This enables configuration discovery of DirectShow devices through the
API, which is important for my use case. It enables making proper GUIs
presenting users with options, instead of asking them to discover a
dshow device's capabilities through the list_options option with an
FFmpeg tool, and listing what they want to configure in dumb text boxes.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c   | 431 --
 libavdevice/version.h |   2 +-
 2 files changed, 413 insertions(+), 20 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 0d5f731030..25c7f5a0e8 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -27,6 +27,7 @@
 #include "libavformat/internal.h"
 #include "libavformat/riff.h"
 #include "avdevice.h"
+#include "internal.h"
 #include "libavcodec/raw.h"
 #include "objidl.h"
 #include "shlwapi.h"
@@ -830,11 +831,15 @@ static void dshow_get_default_format(IPin *pin, 
IAMStreamConfig *config, enum ds
  * try to set parameters specified through AVOptions, or the pin's
  * default format if no such parameters were set. If successful,
  * return 1 in *pformat_set.
- * If pformat_set is NULL, list all pin capabilities.
+ * If pformat_set is NULL or the ranges input is not NULL, list all
+ * pin capabilities.
+ * When listing pin capabilities, if ranges is NULL, output to log,
+ * else store capabilities in ranges.
  */
 static void
 dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
-IPin *pin, int *pformat_set)
+IPin *pin, int *pformat_set,
+AVOptionRanges *ranges, enum AVDeviceCapabilitiesQueryType 
query_type)
 {
 struct dshow_ctx *ctx = avctx->priv_data;
 IAMStreamConfig *config = NULL;
@@ -878,7 +883,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
  *one, with most info exposed (see comment below).
  */
 use_default = !dshow_should_set_format(avctx, devtype);
-if (use_default && pformat_set)
+if (use_default && pformat_set && !ranges)
 {
 // get default
 dshow_get_default_format(pin, config, devtype, );
@@ -924,7 +929,9 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 // exposes contains a VIDEOINFOHEADER2. Fall back to the VIDEOINFOHEADER
 // format if no corresponding VIDEOINFOHEADER2 is found when we finish
 // iterating.
-for (i = 0; i < n && !format_set; i++) {
+for (i = 0; i < n && (!format_set || ranges); i++) {
+AVOptionRange *new_range[3] = { NULL };
+int nb_range = 0;
 struct dshow_format_info *fmt_info = NULL;
 r = IAMStreamConfig_GetStreamCaps(config, i, , (void *) caps);
 if (r != S_OK)
@@ -960,7 +967,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 wait_for_better = 0;
 }
 
-if (!pformat_set) {
+if (!pformat_set && !ranges) {
 const char *chroma = 
av_chroma_location_name(fmt_info->chroma_loc);
 if (fmt_info->pix_fmt == AV_PIX_FMT_NONE) {
 const AVCodec *codec = 
avcodec_find_decoder(fmt_info->codec_id);
@@ -1024,6 +1031,60 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 bih->biWidth  = requested_width;
 bih->biHeight = requested_height;
 }
+
+if (ranges) {
+for (int j = 0; j < ranges->nb_components; j++) {
+new_range[j] = av_mallocz(sizeof(**new_range));
+if (!new_range[j])
+goto next;
+new_range[j]->value_max = -1.;  // init (min:0, max:-1 
means value not set)
+++nb_range;
+
+switch (query_type)
+{
+case AV_DEV_CAP_QUERY_CODEC:
+if (dshow_pixfmt(bih->biCompression, bih->biBitCount) 
== AV_PIX_FMT_NONE) {
+const AVCodecTag *const tags[] = { 
avformat_get_riff_video_tags(), NULL };
+new_range[j]->value_min = av_codec_get_id(tags, 
bih->biCompression);
+}
+else
+new_range[j]->value_min = AV_CODEC_ID_RAWVIDEO;
+new_range[j]->value_max = new_range[j]->value_min;
+break;
+case AV_DEV_CAP_QUERY_PIXEL_FORMAT:
+new_range[j]->value_min = new_range[j]->value_max = 
dshow_pixfmt(bih->biCompression, bih->biBitCount);
+new_range[j]->value_min;
+break;
+case AV_DEV_CAP_QUERY_FRAME_SIZE:
+{
+switch (j)
+   

[FFmpeg-devel] [PATCH v4 16/22] avdevice/dshow: when closing, set context fields back to zero

2022-03-25 Thread Diederick Niehorster
After the avdevice capabilities API is implemented, the format context
may be reused after querying device capabilities in a later
avformat_open_input call. To enable this reuse, after releasing
resources, make sure to also set the corresponding pointers back to
NULL. This correctly indicates their state after cleanup.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index d35224beb5..0d5f731030 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -264,14 +264,18 @@ dshow_read_close(AVFormatContext *s)
 ICaptureGraphBuilder2_Release(ctx->graph_builder2[VideoDevice]);
 if (ctx->graph_builder2[AudioDevice])
 ICaptureGraphBuilder2_Release(ctx->graph_builder2[AudioDevice]);
+ctx->graph_builder2[0] = NULL;
+ctx->graph_builder2[1] = NULL;
 
 if (ctx->control) {
 IMediaControl_Stop(ctx->control);
 IMediaControl_Release(ctx->control);
 }
+ctx->control = NULL;
 
 if (ctx->media_event)
 IMediaEvent_Release(ctx->media_event);
+ctx->media_event = NULL;
 
 if (ctx->graph) {
 IEnumFilters *fenum;
@@ -289,25 +293,34 @@ dshow_read_close(AVFormatContext *s)
 IEnumFilters_Release(fenum);
 }
 IGraphBuilder_Release(ctx->graph);
+ctx->graph = NULL;
 }
 
 if (ctx->capture_pin[VideoDevice])
 ff_dshow_pin_Release(ctx->capture_pin[VideoDevice]);
 if (ctx->capture_pin[AudioDevice])
 ff_dshow_pin_Release(ctx->capture_pin[AudioDevice]);
+ctx->capture_pin[0] = NULL;
+ctx->capture_pin[1] = NULL;
 if (ctx->capture_filter[VideoDevice])
 ff_dshow_filter_Release(ctx->capture_filter[VideoDevice]);
 if (ctx->capture_filter[AudioDevice])
 ff_dshow_filter_Release(ctx->capture_filter[AudioDevice]);
+ctx->capture_filter[0] = NULL;
+ctx->capture_filter[1] = NULL;
 
 if (ctx->device_pin[VideoDevice])
 IPin_Release(ctx->device_pin[VideoDevice]);
 if (ctx->device_pin[AudioDevice])
 IPin_Release(ctx->device_pin[AudioDevice]);
+ctx->device_pin[0] = NULL;
+ctx->device_pin[1] = NULL;
 if (ctx->device_filter[VideoDevice])
 IBaseFilter_Release(ctx->device_filter[VideoDevice]);
 if (ctx->device_filter[AudioDevice])
 IBaseFilter_Release(ctx->device_filter[AudioDevice]);
+ctx->device_filter[0] = NULL;
+ctx->device_filter[1] = NULL;
 
 av_freep(>device_name[0]);
 av_freep(>device_name[1]);
@@ -316,10 +329,13 @@ dshow_read_close(AVFormatContext *s)
 
 if(ctx->mutex)
 CloseHandle(ctx->mutex);
+ctx->mutex = NULL;
 if(ctx->event[0])
 CloseHandle(ctx->event[0]);
 if(ctx->event[1])
 CloseHandle(ctx->event[1]);
+ctx->event[0] = NULL;
+ctx->event[1] = NULL;
 
 pktl = ctx->pktl;
 while (pktl) {
@@ -328,6 +344,7 @@ dshow_read_close(AVFormatContext *s)
 av_free(pktl);
 pktl = next;
 }
+ctx->pktl = NULL;
 
 CoUninitialize();
 
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 15/22] avdevice/dshow: move audio format helpers

2022-03-25 Thread Diederick Niehorster
Needs to be moved up in file for upcoming implementation of
avdevice_capabilities_create.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 40 
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index a780351170..d35224beb5 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -79,6 +79,26 @@ static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, 
WORD biBitCount)
 return avpriv_pix_fmt_find(PIX_FMT_LIST_RAW, biCompression); // all others
 }
 
+static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
+{
+switch (sample_fmt) {
+case AV_SAMPLE_FMT_U8:  return AV_CODEC_ID_PCM_U8;
+case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE;
+case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE;
+default:return AV_CODEC_ID_NONE; /* Should never happen. */
+}
+}
+
+static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
+{
+switch (bits) {
+case 8:  return AV_SAMPLE_FMT_U8;
+case 16: return AV_SAMPLE_FMT_S16;
+case 32: return AV_SAMPLE_FMT_S32;
+default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
+}
+}
+
 static enum AVColorRange dshow_color_range(DXVA2_ExtendedFormat *fmt_info)
 {
 switch (fmt_info->NominalRange)
@@ -1610,26 +1630,6 @@ static int dshow_control_message(AVFormatContext *avctx, 
int type, void *data, s
 return ret;
 }
 
-static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
-{
-switch (sample_fmt) {
-case AV_SAMPLE_FMT_U8:  return AV_CODEC_ID_PCM_U8;
-case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE;
-case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE;
-default:return AV_CODEC_ID_NONE; /* Should never happen. */
-}
-}
-
-static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
-{
-switch (bits) {
-case 8:  return AV_SAMPLE_FMT_U8;
-case 16: return AV_SAMPLE_FMT_S16;
-case 32: return AV_SAMPLE_FMT_S32;
-default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
-}
-}
-
 static int
 dshow_add_device(AVFormatContext *avctx,
  enum dshowDeviceType devtype)
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 14/22] avdevice: improve capabilities' option API

2022-03-25 Thread Diederick Niehorster
This adds avdevice_capabilities_get_class() to allow examining the
capabilities that can be queried/set through the capabilities API, and
avdevice_capabilities_bprint_num() which allows printing the value
returned when querying a capability. These values (min_value and
max_value of an AVOptionRange) are doubles and this function formats
them properly, e.g. 1. for a AV_OPT_TYPE_PIXEL_FMT -> yuyv422.

bump minor version.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 80 ++
 libavdevice/avdevice.h | 27 ++
 libavdevice/version.h  |  4 +--
 3 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 33061b4408..0a75504d9c 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -19,6 +19,9 @@
 #include "libavutil/avassert.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/pixfmt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/avutil.h"
+#include "libavcodec/codec_id.h"
 #include "libavformat/version.h"
 #include "avdevice.h"
 #include "internal.h"
@@ -141,6 +144,83 @@ int avdevice_capabilities_create(AVDeviceCapabilitiesQuery 
**caps, AVFormatConte
 return ret;
 }
 
+static const AVClass avdevice_capabilities_context_class = {
+.class_name = "AVDeviceCapabilitiesQuery",
+.item_name = av_default_item_name,
+.option = ff_device_capabilities,
+.version = LIBAVUTIL_VERSION_INT
+};
+
+const AVClass *avdevice_capabilities_get_class(void)
+{
+return _capabilities_context_class;
+}
+
+int avdevice_capabilities_bprint_num(AVBPrint *bp, const char *name, double 
val)
+{
+int opt_type_set = 0, is_codec = 0;
+enum AVOptionType type;  // will be set below, opt_type_set tracks if has 
been set
+const AVClass *cap_class = avdevice_capabilities_get_class();
+
+// may fail, e.g. if name of a component of a multi-component option was 
provided as input
+const AVOption *field = av_opt_find(_class, name, NULL, 0, 
AV_OPT_SEARCH_FAKE_OBJ);
+if (field) {
+type = field->type;
+opt_type_set = 1;
+}
+
+// based on name, a type override or other extra info may be needed
+if (opt_type_set && type==AV_OPT_TYPE_INT && strcmp(name, "codec")==0)
+is_codec = 1;
+// next three are for the three components of a AV_OPT_TYPE_IMAGE_SIZE
+// NB: these wont be found by av_opt_find above
+else if (
+strcmp(name, 
ff_device_get_query_component_name(AV_DEV_CAP_QUERY_WINDOW_SIZE, 0))==0 ||
+strcmp(name, 
ff_device_get_query_component_name(AV_DEV_CAP_QUERY_WINDOW_SIZE, 1))==0 ||
+strcmp(name, 
ff_device_get_query_component_name(AV_DEV_CAP_QUERY_WINDOW_SIZE, 2))==0
+) {
+type = AV_OPT_TYPE_INT;
+opt_type_set = 1;
+}
+
+// now, format if type set, else error
+if (!opt_type_set) {
+av_log(NULL, AV_LOG_ERROR, "A device capability with the name '%s' is 
not known\n", name);
+return AVERROR_OPTION_NOT_FOUND;
+}
+
+switch (type)
+{
+case AV_OPT_TYPE_INT:
+{
+int temp = lrint(val);
+if (is_codec)
+av_bprintf(bp, "%s", (char *)avcodec_get_name((enum 
AVCodecID)lrint(val)));
+else
+av_bprintf(bp, "%d", temp);
+break;
+}
+case AV_OPT_TYPE_PIXEL_FMT:
+av_bprintf(bp, "%s", (char *)av_x_if_null(av_get_pix_fmt_name((enum 
AVPixelFormat)lrint(val)), "none"));
+break;
+case AV_OPT_TYPE_SAMPLE_FMT:
+av_bprintf(bp, "%s", (char *)av_x_if_null(av_get_sample_fmt_name((enum 
AVSampleFormat)lrint(val)), "none"));
+break;
+case AV_OPT_TYPE_DOUBLE:
+av_bprintf(bp, "%f", val);
+break;
+case AV_OPT_TYPE_CHANNEL_LAYOUT:
+av_bprintf(bp, "0x%"PRIx64, llrint(val));
+break;
+
+default:
+av_log(NULL, AV_LOG_ERROR, "avdevice_capabilities_bprint_num is not 
implemented for this option type\n", name);
+return AVERROR_PATCHWELCOME;
+}
+
+return 0;
+}
+
 void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, 
AVFormatContext *s)
 {
 if (!s || !caps || !(*caps))
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index a815d65f12..5f9dfccc34 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -64,6 +64,7 @@
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/dict.h"
+#include "libavutil/bprint.h"
 #include "libavformat/avformat.h"
 
 /**
@@ -418,6 +419,16 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
  */
 typedef struct AVDeviceCapabilitiesQuery AVDeviceCapabilitiesQuery;
 
+/**
+ * Get the AVClass for AVDeviceCapabilitiesQuery. It can be used
+ * in combination with AV_OPT_SEARCH_FAKE_OBJ for examining
+ * which capabilities can be queried through the
+ * AVDeviceCapabilitiesQuery API.
+ *
+ * @see av_opt_find(), av_opt_next().
+ */
+const AVClass *avdevice_capabilities_get_class(void);
+
 /**
 

[FFmpeg-devel] [PATCH v4 13/22] avdevice: change device capabilities option type

2022-03-25 Thread Diederick Niehorster
Changes fps option from AVRational to double. This since any device
capability query results are returned in AVOptionRanges, which hold the
value as doubles, which can't contain AVRationals.

Also updated documentation of other capabilities, some had the wrong
option type listed.

micro version bump as this capabilities API is unused for now.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 4 ++--
 libavdevice/avdevice.h | 6 +++---
 libavdevice/internal.h | 4 +++-
 libavdevice/version.h  | 2 +-
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index db412985b2..33061b4408 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -51,8 +51,8 @@ const AVOption ff_device_capabilities[] = {
 {.str = NULL}, -1, INT_MAX, E|D|V },
 { "frame_size", "frame size", OFFSET(frame_width), AV_OPT_TYPE_IMAGE_SIZE,
 {.str = NULL}, -1, INT_MAX, E|D|V },
-{ "fps", "fps", OFFSET(fps), AV_OPT_TYPE_RATIONAL,
-{.dbl = -1}, -1, INT_MAX, E|D|V },
+{ "fps", "fps", OFFSET(fps), AV_OPT_TYPE_DOUBLE,
+{.dbl = NAN}, 0, INT_MAX, E|D|V },
 { NULL }
 };
 
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 6d45c74616..a815d65f12 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -360,7 +360,7 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
  *  type: AV_OPT_TYPE_INT (AVCodecID value)
  *  - Capabilities valid for audio devices:
  *- sample_format:  supported sample formats.
- *  type: AV_OPT_TYPE_INT (AVSampleFormat value)
+ *  type: AV_OPT_TYPE_SAMPLE_FMT
  *- sample_rate:supported sample rates.
  *  type: AV_OPT_TYPE_INT
  *- channels:   supported number of channels.
@@ -369,13 +369,13 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
  *  type: AV_OPT_TYPE_INT64
  *  - Capabilities valid for video devices:
  *- pixel_format:   supported pixel formats.
- *  type: AV_OPT_TYPE_INT (AVPixelFormat value)
+ *  type: AV_OPT_TYPE_PIXEL_FMT
  *- window_size:supported window sizes (describes size of the window 
size presented to the user).
  *  type: AV_OPT_TYPE_IMAGE_SIZE
  *- frame_size: supported frame sizes (describes size of provided 
video frames).
  *  type: AV_OPT_TYPE_IMAGE_SIZE
  *- fps:supported fps values
- *  type: AV_OPT_TYPE_RATIONAL
+ *  type: AV_OPT_TYPE_DOUBLE
  *
  * Value of the capability may be set by user using av_opt_set() function
  * and AVDeviceCapabilitiesQuery object. Following queries will
diff --git a/libavdevice/internal.h b/libavdevice/internal.h
index eee493a4c7..5f0bd403dd 100644
--- a/libavdevice/internal.h
+++ b/libavdevice/internal.h
@@ -50,7 +50,9 @@ struct AVDeviceCapabilitiesQuery {
 int window_height;
 int frame_width;
 int frame_height;
-AVRational fps;
+// NB: an AVRational cannot be represented in the AVOptionRange
+// output of av_opt_query_ranges, so we store fps as double instead
+double fps;
 };
 
 /**
diff --git a/libavdevice/version.h b/libavdevice/version.h
index d789b3fd7b..9853069a2d 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -31,7 +31,7 @@
 #include "version_major.h"
 
 #define LIBAVDEVICE_VERSION_MINOR   1
-#define LIBAVDEVICE_VERSION_MICRO 100
+#define LIBAVDEVICE_VERSION_MICRO 101
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 12/22] avdevice: Add internal helpers for querying device capabilities

2022-03-25 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 libavdevice/internal.h | 31 +++
 libavdevice/utils.c| 48 ++
 2 files changed, 79 insertions(+)

diff --git a/libavdevice/internal.h b/libavdevice/internal.h
index bef3a4bd2d..eee493a4c7 100644
--- a/libavdevice/internal.h
+++ b/libavdevice/internal.h
@@ -58,4 +58,35 @@ struct AVDeviceCapabilitiesQuery {
  */
 extern const AVOption ff_device_capabilities[];
 
+/**
+ * Enumeration indicating which device capability is being queried.
+ */
+enum AVDeviceCapabilitiesQueryType {
+AV_DEV_CAP_QUERY_NONE = 0,
+// both audio and video
+AV_DEV_CAP_QUERY_CODEC,
+// audio
+AV_DEV_CAP_QUERY_SAMPLE_FORMAT,
+AV_DEV_CAP_QUERY_SAMPLE_RATE,
+AV_DEV_CAP_QUERY_CHANNELS,
+AV_DEV_CAP_QUERY_CHANNEL_LAYOUT,
+// video
+AV_DEV_CAP_QUERY_PIXEL_FORMAT,
+AV_DEV_CAP_QUERY_WINDOW_SIZE,
+AV_DEV_CAP_QUERY_FRAME_SIZE,
+AV_DEV_CAP_QUERY_FPS
+};
+
+/**
+ * Find AVDeviceCapabilitiesQueryType enumeration by means of options name.
+ * Returns AV_DEV_CAP_QUERY_NONE if not found.
+ */
+enum AVDeviceCapabilitiesQueryType ff_device_get_query_type(const char* 
option_name);
+
+/**
+ * Get component name from AVDeviceCapabilitiesQueryType enumeration and 
component index.
+ * (Some options have multiple components, e.g. AV_DEV_CAP_QUERY_FRAME_SIZE).
+ */
+const char* ff_device_get_query_component_name(enum 
AVDeviceCapabilitiesQueryType query_type, int component);
+
 #endif
diff --git a/libavdevice/utils.c b/libavdevice/utils.c
index d9a52c53ab..de9023f215 100644
--- a/libavdevice/utils.c
+++ b/libavdevice/utils.c
@@ -19,6 +19,7 @@
 #include "internal.h"
 #include "libavutil/opt.h"
 #include "libavformat/avformat.h"
+#include "libavutil/avassert.h"
 
 int ff_alloc_input_device_context(AVFormatContext **avctx, const AVInputFormat 
*iformat, const char *format)
 {
@@ -57,3 +58,50 @@ int ff_alloc_input_device_context(AVFormatContext **avctx, 
const AVInputFormat *
 avformat_free_context(s);
 return ret;
 }
+
+typedef struct AVDeviceCapabilitiesQueryTypeEntry {
+const char* name;
+enum AVDeviceCapabilitiesQueryType  query_type;
+} AVDeviceCapabilitiesQueryTypeEntry;
+
+static const AVDeviceCapabilitiesQueryTypeEntry query_table[] = {
+// both audio and video
+{ "codec",  AV_DEV_CAP_QUERY_CODEC },
+// audio
+{ "sample_format",  AV_DEV_CAP_QUERY_SAMPLE_FORMAT },
+{ "sample_rate",AV_DEV_CAP_QUERY_SAMPLE_RATE },
+{ "channels",   AV_DEV_CAP_QUERY_CHANNELS },
+{ "channel_layout", AV_DEV_CAP_QUERY_CHANNEL_LAYOUT },
+// video
+{ "pixel_format",   AV_DEV_CAP_QUERY_PIXEL_FORMAT },
+{ "frame_size", AV_DEV_CAP_QUERY_FRAME_SIZE },
+{ "window_size",AV_DEV_CAP_QUERY_WINDOW_SIZE },
+{ "fps",AV_DEV_CAP_QUERY_FPS },
+};
+
+enum AVDeviceCapabilitiesQueryType ff_device_get_query_type(const char* 
option_name)
+{
+for (int i = 0; i < FF_ARRAY_ELEMS(query_table); ++i) {
+if (!strcmp(query_table[i].name, option_name))
+return query_table[i].query_type;
+}
+// not found
+return AV_DEV_CAP_QUERY_NONE;
+}
+
+const char* ff_device_get_query_component_name(enum 
AVDeviceCapabilitiesQueryType query_type, int component)
+{
+if (query_type == AV_DEV_CAP_QUERY_WINDOW_SIZE || query_type == 
AV_DEV_CAP_QUERY_FRAME_SIZE) {
+// special case: different name for each component
+return component == 0 ? "pixel_count" : (component == 1 ? "width" : 
(component == 2 ? "height" : ""));
+}
+else {
+av_assert0(component == 0);
+for (int i = 0; i < FF_ARRAY_ELEMS(query_table); ++i) {
+if (query_table[i].query_type == query_type)
+return query_table[i].name;
+}
+}
+// not found
+return NULL;
+}
\ No newline at end of file
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 11/22] avutil/opt: document AVOptionRange min_value > max_value

2022-03-25 Thread Diederick Niehorster
AVOptionRange needs a way to encode that an option is not set. Here i
provide a documentation solution. When a range is invalid (value_min >
value_max), it should be considered unset/value not available.

When querying a range of formats of an avdevice, sometimes for a given
format the queried option is not available. This is not an error as the
user is asking for a valid capability, it just doesn't always apply to
all the matching formats of the device. This cannot be communicated
through a single special value (like 0 or -1) as that has the same
problem asany special value solution. Documenting that an invalid range
means value not available allows communicating this situation without
adding a field to the AVOptionRange struct.

This further documents that an AVOptionRange denotes a single value when
value_min == value_max, and a range only when value_max > value_min.
This makes the is_range field superfluous.

Signed-off-by: Diederick Niehorster 
---
 libavutil/opt.c | 2 +-
 libavutil/opt.h | 5 +
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libavutil/opt.c b/libavutil/opt.c
index 8ffb10449b..ebffbb2f36 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -1979,9 +1979,9 @@ int av_opt_query_ranges_default(AVOptionRanges 
**ranges_arg, void *obj, const ch
 ranges->range[0] = range;
 ranges->nb_ranges = 1;
 ranges->nb_components = 1;
-range->is_range = 1;
 range->value_min = field->min;
 range->value_max = field->max;
+range->is_range = field->max > field->min;
 
 switch (field->type) {
 case AV_OPT_TYPE_BOOL:
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 461b5d3b6b..4e7d7433e9 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -316,6 +316,11 @@ typedef struct AVOptionRange {
  * Value range.
  * For string ranges this represents the min/max length.
  * For dimensions this represents the min/max pixel count or width/height 
in multi-component case.
+ * If value_min  < value_max, the struct encodes a range.
+ * If value_min == value_max, the struct encodes a single value.
+ * If value_min  > value_max, the range is empty (a value is not 
available).
+ *Good sentinel values to use when a range is 
empty
+ *are value_min=0, value_max=-1, but this is 
not required.
  */
 double value_min, value_max;
 /**
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 10/22] avdevice: capabilities API details no longer public

2022-03-25 Thread Diederick Niehorster
Bumping avdevice major version (API removed, even if it cannot have been used 
by anyone)

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c  |  2 +-
 libavdevice/avdevice.h  | 28 +---
 libavdevice/internal.h  | 33 +
 libavdevice/version.h   |  2 +-
 libavdevice/version_major.h |  2 +-
 5 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 24e14b84c9..db412985b2 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -34,7 +34,7 @@ const char av_device_ffversion[] = "FFmpeg version " 
FFMPEG_VERSION;
 #define V AV_OPT_FLAG_VIDEO_PARAM
 #define OFFSET(x) offsetof(AVDeviceCapabilitiesQuery, x)
 
-const AVOption av_device_capabilities[] = {
+const AVOption ff_device_capabilities[] = {
 { "codec", "codec", OFFSET(codec), AV_OPT_TYPE_INT,
 {.i64 = AV_CODEC_ID_NONE}, AV_CODEC_ID_NONE, INT_MAX, E|D|A|V },
 { "sample_format", "sample format", OFFSET(sample_format), 
AV_OPT_TYPE_SAMPLE_FMT,
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 9724e7edf5..6d45c74616 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -416,33 +416,7 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
  *  avformat_free_context(oc);
  * @endcode
  */
-
-/**
- * Structure describes device capabilities.
- *
- * It is used by devices in conjunction with av_device_capabilities AVOption 
table
- * to implement capabilities probing API based on AVOption API. Should not be 
used directly.
- */
-typedef struct AVDeviceCapabilitiesQuery {
-const AVClass *av_class;
-AVFormatContext *device_context;
-enum AVCodecID codec;
-enum AVSampleFormat sample_format;
-enum AVPixelFormat pixel_format;
-int sample_rate;
-int channels;
-int64_t channel_layout;
-int window_width;
-int window_height;
-int frame_width;
-int frame_height;
-AVRational fps;
-} AVDeviceCapabilitiesQuery;
-
-/**
- * AVOption table used by devices to implement device capabilities API. Should 
not be used by a user.
- */
-extern const AVOption av_device_capabilities[];
+typedef struct AVDeviceCapabilitiesQuery AVDeviceCapabilitiesQuery;
 
 /**
  * Initialize capabilities probing API based on AVOption API.
diff --git a/libavdevice/internal.h b/libavdevice/internal.h
index 67c90e1f87..bef3a4bd2d 100644
--- a/libavdevice/internal.h
+++ b/libavdevice/internal.h
@@ -19,10 +19,43 @@
 #ifndef AVDEVICE_INTERNAL_H
 #define AVDEVICE_INTERNAL_H
 
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
+#include "libavutil/samplefmt.h"
+#include "libavcodec/codec_id.h"
 #include "libavformat/avformat.h"
 
 av_warn_unused_result
 int ff_alloc_input_device_context(struct AVFormatContext **avctx, const 
AVInputFormat *iformat,
   const char *format);
 
+/**
+ * Structure describes device capabilities.
+ *
+ * It is used by devices in conjunction with ff_device_capabilities AVOption 
table
+ * to implement capabilities probing API based on AVOption API.
+ */
+struct AVDeviceCapabilitiesQuery {
+const AVClass *av_class;
+AVFormatContext *device_context;
+enum AVCodecID codec;
+enum AVSampleFormat sample_format;
+enum AVPixelFormat pixel_format;
+int sample_rate;
+int channels;
+int64_t channel_layout;
+int window_width;
+int window_height;
+int frame_width;
+int frame_height;
+AVRational fps;
+};
+
+/**
+ * AVOption table used by devices to implement device capabilities API.
+ */
+extern const AVOption ff_device_capabilities[];
+
 #endif
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 2c25804784..d789b3fd7b 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -30,7 +30,7 @@
 
 #include "version_major.h"
 
-#define LIBAVDEVICE_VERSION_MINOR   9
+#define LIBAVDEVICE_VERSION_MINOR   1
 #define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
diff --git a/libavdevice/version_major.h b/libavdevice/version_major.h
index d255ff6992..b32de7325d 100644
--- a/libavdevice/version_major.h
+++ b/libavdevice/version_major.h
@@ -25,7 +25,7 @@
  * Libavdevice version macros
  */
 
-#define LIBAVDEVICE_VERSION_MAJOR  59
+#define LIBAVDEVICE_VERSION_MAJOR  60
 
 /**
  * FF_API_* defines may be placed below to indicate public API that will be
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 09/22] avdevice/avdevice: clean up avdevice_capabilities_create

2022-03-25 Thread Diederick Niehorster
Draw implementation in line with that of avdevice_list_devices

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 2000e63bb2..24e14b84c9 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -113,11 +113,14 @@ int 
avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatConte
  AVDictionary **device_options)
 {
 int ret;
-av_assert0(s && caps);
+av_assert0(s);
+av_assert0(caps);
 av_assert0(s->iformat || s->oformat);
 if ((s->oformat && !s->oformat->create_device_capabilities) ||
-(s->iformat && !s->iformat->create_device_capabilities))
+(s->iformat && !s->iformat->create_device_capabilities)) {
+*caps = NULL;
 return AVERROR(ENOSYS);
+}
 *caps = av_mallocz(sizeof(**caps));
 if (!(*caps))
 return AVERROR(ENOMEM);
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 08/22] avdevice/avdevice: Revert "Deprecate AVDevice Capabilities API"

2022-03-25 Thread Diederick Niehorster
This reverts commit 4f49ca7bbc75a9db4cdf93f27f95a668c751f160. The next
few patches clean up the API and implement this capability for
avdevice/dshow.

Bumping avformat and avdevice version.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 71 ++
 libavdevice/avdevice.h |  5 ---
 libavdevice/version.h  |  4 +--
 libavformat/avformat.h | 21 +
 libavformat/version.h  |  2 +-
 5 files changed, 89 insertions(+), 14 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 617c28d725..2000e63bb2 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -28,11 +28,39 @@
 #include "libavutil/ffversion.h"
 const char av_device_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
 
-#if FF_API_DEVICE_CAPABILITIES
+#define E AV_OPT_FLAG_ENCODING_PARAM
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define V AV_OPT_FLAG_VIDEO_PARAM
+#define OFFSET(x) offsetof(AVDeviceCapabilitiesQuery, x)
+
 const AVOption av_device_capabilities[] = {
+{ "codec", "codec", OFFSET(codec), AV_OPT_TYPE_INT,
+{.i64 = AV_CODEC_ID_NONE}, AV_CODEC_ID_NONE, INT_MAX, E|D|A|V },
+{ "sample_format", "sample format", OFFSET(sample_format), 
AV_OPT_TYPE_SAMPLE_FMT,
+{.i64 = AV_SAMPLE_FMT_NONE}, AV_SAMPLE_FMT_NONE, INT_MAX, E|D|A },
+{ "sample_rate", "sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT,
+{.i64 = -1}, -1, INT_MAX, E|D|A },
+{ "channels", "channels", OFFSET(channels), AV_OPT_TYPE_INT,
+{.i64 = -1}, -1, INT_MAX, E|D|A },
+{ "channel_layout", "channel layout", OFFSET(channel_layout), 
AV_OPT_TYPE_CHANNEL_LAYOUT,
+{.i64 = -1}, -1, INT_MAX, E|D|A },
+{ "pixel_format", "pixel format", OFFSET(pixel_format), 
AV_OPT_TYPE_PIXEL_FMT,
+{.i64 = AV_PIX_FMT_NONE}, AV_PIX_FMT_NONE, INT_MAX, E|D|V },
+{ "window_size", "window size", OFFSET(window_width), 
AV_OPT_TYPE_IMAGE_SIZE,
+{.str = NULL}, -1, INT_MAX, E|D|V },
+{ "frame_size", "frame size", OFFSET(frame_width), AV_OPT_TYPE_IMAGE_SIZE,
+{.str = NULL}, -1, INT_MAX, E|D|V },
+{ "fps", "fps", OFFSET(fps), AV_OPT_TYPE_RATIONAL,
+{.dbl = -1}, -1, INT_MAX, E|D|V },
 { NULL }
 };
-#endif
+
+#undef E
+#undef D
+#undef A
+#undef V
+#undef OFFSET
 
 unsigned avdevice_version(void)
 {
@@ -81,18 +109,49 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s, enum AVDevToA
 return s->control_message_cb(s, type, data, data_size);
 }
 
-#if FF_API_DEVICE_CAPABILITIES
 int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, 
AVFormatContext *s,
  AVDictionary **device_options)
 {
-return AVERROR(ENOSYS);
+int ret;
+av_assert0(s && caps);
+av_assert0(s->iformat || s->oformat);
+if ((s->oformat && !s->oformat->create_device_capabilities) ||
+(s->iformat && !s->iformat->create_device_capabilities))
+return AVERROR(ENOSYS);
+*caps = av_mallocz(sizeof(**caps));
+if (!(*caps))
+return AVERROR(ENOMEM);
+(*caps)->device_context = s;
+if (((ret = av_opt_set_dict(s->priv_data, device_options)) < 0))
+goto fail;
+if (s->iformat) {
+if ((ret = s->iformat->create_device_capabilities(s, *caps)) < 0)
+goto fail;
+} else {
+if ((ret = s->oformat->create_device_capabilities(s, *caps)) < 0)
+goto fail;
+}
+av_opt_set_defaults(*caps);
+return 0;
+  fail:
+av_freep(caps);
+return ret;
 }
 
 void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, 
AVFormatContext *s)
 {
-return;
+if (!s || !caps || !(*caps))
+return;
+av_assert0(s->iformat || s->oformat);
+if (s->iformat) {
+if (s->iformat->free_device_capabilities)
+s->iformat->free_device_capabilities(s, *caps);
+} else {
+if (s->oformat->free_device_capabilities)
+s->oformat->free_device_capabilities(s, *caps);
+}
+av_freep(caps);
 }
-#endif
 
 int avdevice_list_devices(AVFormatContext *s, AVDeviceInfoList **device_list)
 {
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 74e9518a8e..9724e7edf5 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -347,7 +347,6 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
 enum AVDevToAppMessageType type,
 void *data, size_t data_size);
 
-#if FF_API_DEVICE_CAPABILITIES
 /**
  * Following API allows user to probe device capabilities (supported codecs,
  * pixel formats, sample formats, resolutions, channel counts, etc).
@@ -443,7 +442,6 @@ typedef struct AVDeviceCapabilitiesQuery {
 /**
  * AVOption table used by devices to implement device capabilities API. Should 
not be used by a user.
  */
-attribute_deprecated
 extern const AVOption av_device_capabilities[];
 
 /**
@@ -463,7 +461,6 @@ extern 

[FFmpeg-devel] [PATCH v4 07/22] avdevice/dshow: add config dialog command for crossbar and tv tuner

2022-03-25 Thread Diederick Niehorster
The "show config dialog" command message can now also trigger dialog
boxes for the crossbar connecting pins filter the analog tuner
audio / analog tuner filters.

Bumping avdevice version.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c  | 51 ++--
 libavdevice/dshow_capture.h  | 10 
 libavdevice/dshow_crossbar.c | 91 +++-
 libavdevice/version.h|  2 +-
 4 files changed, 115 insertions(+), 39 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 78194406b5..a780351170 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -240,6 +240,11 @@ dshow_read_close(AVFormatContext *s)
 struct dshow_ctx *ctx = s->priv_data;
 PacketListEntry *pktl;
 
+if (ctx->graph_builder2[VideoDevice])
+ICaptureGraphBuilder2_Release(ctx->graph_builder2[VideoDevice]);
+if (ctx->graph_builder2[AudioDevice])
+ICaptureGraphBuilder2_Release(ctx->graph_builder2[AudioDevice]);
+
 if (ctx->control) {
 IMediaControl_Stop(ctx->control);
 IMediaControl_Release(ctx->control);
@@ -1464,6 +1469,7 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
 goto error;
 }
+ctx->graph_builder2[devtype] = graph_builder2;
 ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
 if (r != S_OK) {
 av_log(avctx, AV_LOG_ERROR, "Could not set graph for 
CaptureGraphBuilder2\n");
@@ -1488,9 +1494,6 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 ret = 0;
 
 error:
-if (graph_builder2 != NULL)
-ICaptureGraphBuilder2_Release(graph_builder2);
-
 if (pers_stream)
 IPersistStream_Release(pers_stream);
 
@@ -1536,10 +1539,48 @@ static int dshow_control_message(AVFormatContext 
*avctx, int type, void *data, s
 ff_dshow_show_filter_properties(ctx->device_filter[devtype], 
avctx);
 } else if (dialog & 1<<2) {
 // crossbar_connection_dialog
-// TODO
+if (ctx->device_filter[devtype] && ctx->graph_builder2[devtype]) {
+IAMCrossbar *cross_bar = NULL;
+IBaseFilter *cross_bar_base_filter = NULL;
+hr = 
ff_dshow_get_crossbar_and_filter(ctx->graph_builder2[devtype], 
ctx->device_filter[devtype], cross_bar, _bar_base_filter);
+
+if (hr == S_OK && cross_bar_base_filter)
+ff_dshow_show_filter_properties(cross_bar_base_filter, 
avctx);
+
+if (cross_bar)
+IAMCrossbar_Release(cross_bar);
+if (cross_bar_base_filter)
+IBaseFilter_Release(cross_bar_base_filter);
+}
 } else if (dialog & 1<<3) {
 // tv_tuner_dialog
-// TODO
+if (ctx->device_filter[devtype] && ctx->graph_builder2[devtype]) {
+if (devtype == VideoDevice) {
+IAMTVTuner *tv_tuner_filter = NULL;
+IBaseFilter *tv_tuner_base_filter = NULL;
+hr = 
ff_dshow_get_tvtuner_and_filter(ctx->graph_builder2[devtype], 
ctx->device_filter[devtype], tv_tuner_filter, tv_tuner_base_filter);
+
+if (hr == S_OK && tv_tuner_base_filter)
+ff_dshow_show_filter_properties(tv_tuner_base_filter, 
avctx);
+
+if (tv_tuner_filter)
+IAMTVTuner_Release(tv_tuner_filter);
+if (tv_tuner_base_filter)
+IBaseFilter_Release(tv_tuner_base_filter);
+} else {
+IAMAudioInputMixer *tv_audio_filter = NULL;
+IBaseFilter *tv_audio_base_filter = NULL;
+hr = 
ff_dshow_get_audiomixer_and_filter(ctx->graph_builder2[devtype], 
ctx->device_filter[devtype], tv_audio_filter, tv_audio_base_filter);
+
+if (hr == S_OK && tv_audio_base_filter)
+ff_dshow_show_filter_properties(tv_audio_base_filter, 
avctx);
+
+if (tv_audio_filter)
+IAMAudioInputMixer_Release(tv_audio_filter);
+if (tv_audio_base_filter)
+IBaseFilter_Release(tv_audio_base_filter);
+}
+}
 }
 break;
 }
diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h
index d0dd35a670..94ba9896b7 100644
--- a/libavdevice/dshow_capture.h
+++ b/libavdevice/dshow_capture.h
@@ -318,6 +318,7 @@ struct dshow_ctx {
 IPin*device_pin[2];
 DShowFilter *capture_filter[2];
 DShowPin*capture_pin[2];
+ICaptureGraphBuilder2 *graph_builder2[2];
 
 HANDLE mutex;
 HANDLE event[2]; /* event[0] is set by DirectShow
@@ -352,6 +353,15 @@ struct dshow_ctx {
 HRESULT ff_dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 

[FFmpeg-devel] [PATCH v4 06/22] avdevice/dshow: accept show config dialog control message

2022-03-25 Thread Diederick Niehorster
DirectShow source will pop up its configuration dialog when
AV_APP_TO_DEV_CONFIG is received. Implementation for several other
possible configuration dialogs is more involved and will be provided in
the next commit.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 29 -
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 652e093204..78194406b5 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1508,6 +1508,7 @@ static int dshow_control_message(AVFormatContext *avctx, 
int type, void *data, s
 struct dshow_ctx *ctx = avctx->priv_data;
 int run_state = ctx->is_running;
 HRESULT hr;
+int ret = 0;
 
 switch (type) {
 case AV_APP_TO_DEV_PAUSE:
@@ -1519,6 +1520,32 @@ static int dshow_control_message(AVFormatContext *avctx, 
int type, void *data, s
 case AV_APP_TO_DEV_TOGGLE_PAUSE:
 run_state = !run_state;
 break;
+case AV_APP_TO_DEV_CONFIG: {
+/* For documentation of dialog variable, see ffmpeg-devices.html in 
docs */
+int dialog;
+enum dshowDeviceType devtype;
+
+if (!data)
+av_log(avctx, AV_LOG_ERROR, "Use the data argument to indicate 
which dialog should be shown.");
+dialog = *(int *) data;
+devtype = (dialog & 1) ? AudioDevice : VideoDevice;
+
+if (dialog & 1<<1) {
+// device_dialog
+if (ctx->device_filter[devtype])
+ff_dshow_show_filter_properties(ctx->device_filter[devtype], 
avctx);
+} else if (dialog & 1<<2) {
+// crossbar_connection_dialog
+// TODO
+} else if (dialog & 1<<3) {
+// tv_tuner_dialog
+// TODO
+}
+break;
+}
+
+default:
+ret = AVERROR(ENOSYS);
 }
 
 // if play state change requested, apply
@@ -1539,7 +1566,7 @@ static int dshow_control_message(AVFormatContext *avctx, 
int type, void *data, s
 ctx->is_running = run_state;
 }
 
-return 0;
+return ret;
 }
 
 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 05/22] avdevice: add control message requesting to show config dialog

2022-03-25 Thread Diederick Niehorster
This control message can be used to programmatically ask a device to
show one of its configuration dialogs.

Adding documentation of this message's int argument.

Bumping avdevice version.

Signed-off-by: Diederick Niehorster 
---
 doc/indevs.texi| 34 ++
 libavdevice/avdevice.h | 10 ++
 libavdevice/version.h  |  4 ++--
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index 9d8020311a..0302859552 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -682,6 +682,40 @@ $ ffmpeg -f dshow -show_video_device_dialog true 
-crossbar_video_input_pin_numbe
 
 @end itemize
 
+@subsection Libavdevice user notes
+
+The dshow device supports the @code{avdevice_app_to_dev_control_message}
+interface.
+
+It understands the @code{AV_APP_TO_DEV_PAUSE}, @code{AV_APP_TO_DEV_PLAY}
+and @code{AV_APP_TO_DEV_TOGGLE_PAUSE} commands, which respective stop and
+start whether data is captured from the connected device, and toggle
+capture state.
+
+It furthermore understands the @code{AV_APP_TO_DEV_CONFIG} message, which
+requests the device to show a configuration dialog (if available). An
+@code{int} should be passed along with this command to indicate which
+configuration dialog should be shown. The bits in this @code{int} have
+the following meaning:
+
+@itemize @bullet
+@item
+1st bit: If set, the dialog for the audio device will be shown. If not set
+the dialog for the video device will be shown.
+
+@item
+2nd bit: If set, show property dialog for the audio or video capture device,
+allowing to change audio or video filter properties and configurations
+manually.
+
+@item
+3rd bit: If set, show property dialog where crossbar pin routings of the
+audio/video device can be manually modified.
+
+@item
+4th bit: If set, show property dialog where TV channels and frequencies can be 
manually modified (in case of video device), or TV audio (like mono vs. stereo, 
Language A, B or C) can be manually modified in case of audio device.
+@end itemize
+
 @section fbdev
 
 Linux framebuffer input device.
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index db16a2f27e..74e9518a8e 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -206,6 +206,16 @@ enum AVAppToDevMessageType {
  */
 AV_APP_TO_DEV_GET_VOLUME = MKBETAG('G', 'V', 'O', 'L'),
 AV_APP_TO_DEV_GET_MUTE   = MKBETAG('G', 'M', 'U', 'T'),
+
+/**
+ * Request to show configuration dialog.
+ * 
+ * If device has a configuration dialog of type indicated by
+ * data, show it.
+ * 
+ * data: int (device-specific).
+ */
+AV_APP_TO_DEV_CONFIG = MKBETAG('C', 'O', 'N', 'F'),
 };
 
 /**
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 69317c9280..96347a3893 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -30,8 +30,8 @@
 
 #include "version_major.h"
 
-#define LIBAVDEVICE_VERSION_MINOR   7
-#define LIBAVDEVICE_VERSION_MICRO 101
+#define LIBAVDEVICE_VERSION_MINOR   8
+#define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 04/22] avdevice/dshow: implement control_message interface

2022-03-25 Thread Diederick Niehorster
This allows programmatic users of avdevice to start and stop the
DirectShow Capture graph (i.e. receive frames or not). This is important
because now the buffer fills up and starts dropping samples when
enqueued packets are not read out immediately after the demuxer is
opened.

Bumping avdevice version.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 42 +
 libavdevice/dshow_capture.h |  1 +
 libavdevice/version.h   |  2 +-
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index abb8325bc3..652e093204 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1503,6 +1503,45 @@ error:
 return ret;
 }
 
+static int dshow_control_message(AVFormatContext *avctx, int type, void *data, 
size_t data_size)
+{
+struct dshow_ctx *ctx = avctx->priv_data;
+int run_state = ctx->is_running;
+HRESULT hr;
+
+switch (type) {
+case AV_APP_TO_DEV_PAUSE:
+run_state = 0;
+break;
+case AV_APP_TO_DEV_PLAY:
+run_state = 1;
+break;
+case AV_APP_TO_DEV_TOGGLE_PAUSE:
+run_state = !run_state;
+break;
+}
+
+// if play state change requested, apply
+if (run_state != ctx->is_running) {
+if (run_state)
+hr = IMediaControl_Run(ctx->control);
+else
+hr = IMediaControl_Pause(ctx->control);
+
+if (hr == S_FALSE) {
+OAFilterState pfs;
+hr = IMediaControl_GetState(ctx->control, 0, );
+}
+if (hr != S_OK) {
+av_log(avctx, AV_LOG_ERROR, "Could not run/pause graph\n");
+return AVERROR(EIO);
+}
+ctx->is_running = run_state;
+}
+
+return 0;
+}
+
 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
 {
 switch (sample_fmt) {
@@ -1747,6 +1786,7 @@ static int dshow_read_header(AVFormatContext *avctx)
 }
 // don't exit yet, allow it to list crossbar options in 
dshow_open_device
 }
+ctx->is_running = 0;
 if (ctx->device_name[VideoDevice]) {
 if ((r = dshow_open_device(avctx, devenum, VideoDevice, 
VideoSourceDevice)) < 0 ||
 (r = dshow_add_device(avctx, VideoDevice)) < 0) {
@@ -1820,6 +1860,7 @@ static int dshow_read_header(AVFormatContext *avctx)
 av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by 
a device already in use by other application)\n");
 goto error;
 }
+ctx->is_running = 1;
 
 ret = 0;
 
@@ -1932,6 +1973,7 @@ const AVInputFormat ff_dshow_demuxer = {
 .read_packet= dshow_read_packet,
 .read_close = dshow_read_close,
 .get_device_list= dshow_get_device_list,
+.control_message= dshow_control_message,
 .flags  = AVFMT_NOFILE | AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | 
AVFMT_NO_BYTE_SEEK,
 .priv_class = _class,
 };
diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h
index b548cd7afc..d0dd35a670 100644
--- a/libavdevice/dshow_capture.h
+++ b/libavdevice/dshow_capture.h
@@ -331,6 +331,7 @@ struct dshow_ctx {
 
 IMediaControl *control;
 IMediaEvent *media_event;
+int is_running;
 
 enum AVPixelFormat pixel_format;
 enum AVCodecID video_codec_id;
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 01e566a1be..69317c9280 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -31,7 +31,7 @@
 #include "version_major.h"
 
 #define LIBAVDEVICE_VERSION_MINOR   7
-#define LIBAVDEVICE_VERSION_MICRO 100
+#define LIBAVDEVICE_VERSION_MICRO 101
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 03/22] avformat: add control_message function to AVInputFormat

2022-03-25 Thread Diederick Niehorster
Control messages are useful for programmatic control of not only outdevs
but also indevs.

Bumping avformat version.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 8 +---
 libavformat/avformat.h | 6 ++
 libavformat/version.h  | 2 +-
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 9b684251aa..617c28d725 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -66,9 +66,11 @@ const char * avdevice_license(void)
 int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum 
AVAppToDevMessageType type,
 void *data, size_t data_size)
 {
-if (!s->oformat || !s->oformat->control_message)
-return AVERROR(ENOSYS);
-return s->oformat->control_message(s, type, data, data_size);
+if (s->oformat && s->oformat->control_message)
+return s->oformat->control_message(s, type, data, data_size);
+if (s->iformat && s->iformat->control_message)
+return s->iformat->control_message(s, type, data, data_size);
+return AVERROR(ENOSYS);
 }
 
 int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum 
AVDevToAppMessageType type,
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 350912e272..06db024559 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -785,6 +785,12 @@ typedef struct AVInputFormat {
  */
 int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t 
min_ts, int64_t ts, int64_t max_ts, int flags);
 
+/**
+ * Allows sending messages from application to device.
+ */
+int (*control_message)(struct AVFormatContext *s, int type,
+   void *data, size_t data_size);
+
 /**
  * Returns device list with it properties.
  * @see avdevice_list_devices() for more details.
diff --git a/libavformat/version.h b/libavformat/version.h
index ac14f8eb37..af5e2c496c 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,7 +32,7 @@
 
 #include "version_major.h"
 
-#define LIBAVFORMAT_VERSION_MINOR  21
+#define LIBAVFORMAT_VERSION_MINOR  22
 #define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 02/22] avdevice: lock to minor version of avformat

2022-03-25 Thread Diederick Niehorster
As per discussion on the list (
https://ffmpeg.org/pipermail/ffmpeg-devel/2021-June/281513.html, see
especially https://ffmpeg.org/pipermail/ffmpeg-devel/2021-June/281586.html),
to resolve the the unholy ABI-relationship between libavdevice and
libavformat and allow easier working on the part of the avdevice API
that lives in avformat, lock avdevice to a specific major and minor
version of avformat.

Documentation of this restriction added.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 13 +
 libavdevice/avdevice.h | 10 ++
 libavdevice/version.h  | 13 -
 libavformat/avformat.h |  3 +++
 libavformat/utils.c|  5 +
 libavformat/version.h  | 14 --
 libavutil/avutil.h |  3 +++
 libavutil/macros.h |  3 +++
 8 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 833d200054..9b684251aa 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -19,6 +19,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/pixfmt.h"
+#include "libavformat/version.h"
 #include "avdevice.h"
 #include "internal.h"
 #include "config.h"
@@ -39,6 +40,18 @@ unsigned avdevice_version(void)
 return LIBAVDEVICE_VERSION_INT;
 }
 
+unsigned avdevice_version_same_minor()
+{
+// check version of loaded lavf has same major and minor version as
+// this library was compiled against
+// NB: this function doesn't have to be called, dynamic linker will
+// signal error when avformat of wrong major or minor version is found.
+if ((avformat_version_same_minor()) & ~0xFF != (LIBAVFORMAT_VERSION_INT & 
~0xFF))
+abort();
+
+return avdevice_version();
+}
+
 const char * avdevice_configuration(void)
 {
 return FFMPEG_CONFIGURATION;
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 0b32e59fed..db16a2f27e 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -47,6 +47,16 @@
  *
  * To use libavdevice, simply call avdevice_register_all() to register all
  * compiled muxers and demuxers. They all use standard libavformat API.
+ * 
+ * Note that libavdevice is locked to be used with the same major and minor
+ * version of libavformat that it was built against. Attempting to use a 
+ * shared build of FFmpeg or its libavdevice library with a libavformat of
+ * a different major or minor version will generate a dynamic linker error.
+ * This is achieved by the internal function check_avformat_same_minor() in 
+ * avdevice.c. This function does not have to be called, its call to
+ * avformat_version_same_minor() (a macro which expands to a name with the
+ * specific major and minor version of avformat embedded in it) is sufficient
+ * to trigger link failure.
  *
  * @{
  */
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 09c1d778dc..01e566a1be 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -26,10 +26,11 @@
  */
 
 #include "libavutil/version.h"
+#include "libavutil/macros.h"
 
 #include "version_major.h"
 
-#define LIBAVDEVICE_VERSION_MINOR   6
+#define LIBAVDEVICE_VERSION_MINOR   7
 #define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
@@ -42,4 +43,14 @@
 
 #define LIBAVDEVICE_IDENT   "Lavd" AV_STRINGIFY(LIBAVDEVICE_VERSION)
 
+/**
+ * avdevice_version_same_minor() expands to a function with
+ * the same minor and major version it was compiled against
+ * encoded in it. Enables locking to the minor version of
+ * other libraries they were compiled against. Does not have
+ * to be called by user.
+ */
+#define avdevice_version_same_minor 
AV_MAKE_MAJOR_MINOR_FUNC_NAME(device,LIBAVFORMAT_VERSION_MAJOR,LIBAVFORMAT_VERSION_MINOR)
+unsigned avdevice_version_same_minor();
+
 #endif /* AVDEVICE_VERSION_H */
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index f12fa7d904..350912e272 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -64,6 +64,9 @@
  * set by user for input, always set by user for output (unless you are dealing
  * with an AVFMT_NOFILE format).
  *
+ * Note that libavdevice is locked to a specific major and minor version of
+ * libavformat, see @ref lavd "libavdevice" for more details.
+ *
  * @section lavf_options Passing options to (de)muxers
  * It is possible to configure lavf muxers and demuxers using the @ref 
avoptions
  * mechanism. Generic (format-independent) libavformat options are provided by
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 3f253c2045..5c4f14535e 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -64,6 +64,11 @@ unsigned avformat_version(void)
 return LIBAVFORMAT_VERSION_INT;
 }
 
+unsigned avformat_version_same_minor()
+{
+return avformat_version();
+}
+
 const char *avformat_configuration(void)
 {
 return FFMPEG_CONFIGURATION;
diff --git a/libavformat/version.h b/libavformat/version.h
index 

[FFmpeg-devel] [PATCH v4 01/22] avdevice/dshow: fix regression

2022-03-25 Thread Diederick Niehorster
a1c4929f accidentally undid part of d9a9b4c8, so the bug in ticket #9420
resurfaced. Fixing again.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 23 ++-
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 6039578ff9..abb8325bc3 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1002,23 +1002,12 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 );
 continue;
 }
-if (requested_sample_rate) {
-if (requested_sample_rate > acaps->MaximumSampleFrequency ||
-requested_sample_rate < acaps->MinimumSampleFrequency)
-goto next;
-fx->nSamplesPerSec = requested_sample_rate;
-}
-if (requested_sample_size) {
-if (requested_sample_size > acaps->MaximumBitsPerSample ||
-requested_sample_size < acaps->MinimumBitsPerSample)
-goto next;
-fx->wBitsPerSample = requested_sample_size;
-}
-if (requested_channels) {
-if (requested_channels > acaps->MaximumChannels ||
-requested_channels < acaps->MinimumChannels)
-goto next;
-fx->nChannels = requested_channels;
+if (
+(ctx->sample_rate && ctx->sample_rate != fx->nSamplesPerSec) ||
+(ctx->sample_size && ctx->sample_size != fx->wBitsPerSample) ||
+(ctx->channels&& ctx->channels!= fx->nChannels )
+) {
+goto next;
 }
 }
 
-- 
2.28.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".


[FFmpeg-devel] [PATCH v4 00/22] avdevice (mostly dshow) enhancements

2022-03-25 Thread Diederick Niehorster
This patch series implements a series of features, mostly enhancing the
dshow avdevice, but also adding new functionality to avformat.
This whole patchset enabled users of the FFmpeg API to fully
query and control a dshow device, making FFmpeg a nice backend for any
program that needs access to, e.g., a webcam.

Different from v3, part of the patches has now been accepted, so only
remaining features are in this set. Importantly, as per discussion on
the list (
https://ffmpeg.org/pipermail/ffmpeg-devel/2021-June/281513.html, see
especially https://ffmpeg.org/pipermail/ffmpeg-devel/2021-June/281586.html),
to resolve the the unholy ABI-relationship between libavdevice and
libavformat and allow easier working on the part of the avdevice API
that lives in avformat, avdevice is now locked to a specific major and minor
version of avformat. This is documented in libavdevice/avdevice.h.

Regarding new functionality added to avformat:
Querying the capabilities of a dshow device is also possible on a
device that is already opened. I expect/guess however that it may not be
possible to achieve that for all of the avdevices, so in principle it is
important that this patchset adds the ability to create an allocated but
unopened AVFormatContext+AVInputFormat with the new function
avformat_alloc_input_context(). This is tested in the new
device_get_capabilities example.


Diederick Niehorster (22):
  avdevice/dshow: fix regression
  avdevice: lock to minor version of avformat
  avformat: add control_message function to AVInputFormat
  avdevice/dshow: implement control_message interface
  avdevice: add control message requesting to show config dialog
  avdevice/dshow: accept show config dialog control message
  avdevice/dshow: add config dialog command for crossbar and tv tuner
  avdevice/avdevice: Revert "Deprecate AVDevice Capabilities API"
  avdevice/avdevice: clean up avdevice_capabilities_create
  avdevice: capabilities API details no longer public
  avutil/opt: document AVOptionRange min_value > max_value
  avdevice: Add internal helpers for querying device capabilities
  avdevice: change device capabilities option type
  avdevice: improve capabilities' option API
  avdevice/dshow: move audio format helpers
  avdevice/dshow: when closing, set context fields back to zero
  avdevice/dshow: implement capabilities API
  avdevice/dshow: cosmetics
  avformat: add avformat_alloc_input_context()
  doc/examples: adding device_get_capabilities example
  Makefile/examples: cosmetics
  avdevice/dshow: capabilities query also works on opened device

 configure  |   2 +
 doc/examples/.gitignore|   1 +
 doc/examples/Makefile  |  47 +-
 doc/examples/Makefile.example  |   1 +
 doc/examples/device_get_capabilities.c | 243 +
 doc/indevs.texi|  34 ++
 libavdevice/avdevice.c | 177 ++-
 libavdevice/avdevice.h | 111 ++---
 libavdevice/dshow.c| 662 ++---
 libavdevice/dshow_capture.h|  14 +
 libavdevice/dshow_crossbar.c   |  91 ++--
 libavdevice/internal.h |  66 +++
 libavdevice/utils.c|  48 ++
 libavdevice/version.h  |  15 +-
 libavdevice/version_major.h|   2 +-
 libavformat/avformat.h |  59 ++-
 libavformat/demux.c|  74 ++-
 libavformat/utils.c|   5 +
 libavformat/version.h  |  14 +-
 libavutil/avutil.h |   3 +
 libavutil/macros.h |   3 +
 libavutil/opt.c|   2 +-
 libavutil/opt.h|   5 +
 23 files changed, 1467 insertions(+), 212 deletions(-)
 create mode 100644 doc/examples/device_get_capabilities.c

-- 
2.28.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] [PATCH] avfilter/vf_libplacebo: update for new tone mapping API

2022-03-25 Thread Lynne
25 Mar 2022, 13:27 by ffm...@haasn.xyz:

> From: Niklas Haas 
>
> Upstream gained a new tone-mapping API, which we never switched to. We
> don't need a version bump for this because it was included as part of
> the v4.192 release we currently already depend on.
>
> The "tonemapping" was changed from an enum to a string, owing to the new
> (extensible) upstream tone mapping infrastructure. The old names still
> map cleanly to the new API, so this shouldn't break any typical users.
>
> Some of the remaining options can be moderately approximated with the
> new API, but specifically "desaturation_base" and "max_boost" cannot.
> Remove these entirely, rather than deprecating them. They have been
> non-functional for a while as a result of the upstream deprecation.
>
> Signed-off-by: Niklas Haas 
>

I'm sorry, but I can't accept that. The old API was well-exposed with all
its values available to the user via established methods.
Requiring a user to run once just to know all the available option is
reserved for the dumbest possible APIs like v4l2 and we shouldn't
be adding more of the same to encourage libraries to be lazy
with exposing options in the API.
___
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_libplacebo: update for new tone mapping API

2022-03-25 Thread Niklas Haas
From: Niklas Haas 

Upstream gained a new tone-mapping API, which we never switched to. We
don't need a version bump for this because it was included as part of
the v4.192 release we currently already depend on.

The "tonemapping" was changed from an enum to a string, owing to the new
(extensible) upstream tone mapping infrastructure. The old names still
map cleanly to the new API, so this shouldn't break any typical users.

Some of the remaining options can be moderately approximated with the
new API, but specifically "desaturation_base" and "max_boost" cannot.
Remove these entirely, rather than deprecating them. They have been
non-functional for a while as a result of the upstream deprecation.

Signed-off-by: Niklas Haas 
---
 libavfilter/vf_libplacebo.c | 114 +++-
 1 file changed, 85 insertions(+), 29 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 31ae28ac38..a2cb971e1f 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -91,12 +91,16 @@ typedef struct LibplaceboContext {
 
 /* pl_color_map_params */
 int intent;
-int tonemapping;
+int gamut_mode;
+char *tonemapping;
 float tonemapping_param;
+int tonemapping_mode;
+int inverse_tonemapping;
+float crosstalk;
+int tonemapping_lut_size;
+/* for backwards compatibility */
 float desat_str;
 float desat_exp;
-float desat_base;
-float max_boost;
 int gamut_warning;
 int gamut_clipping;
 
@@ -184,6 +188,30 @@ static int find_scaler(AVFilterContext *avctx,
 return AVERROR(EINVAL);
 }
 
+static int find_tone_mapper(AVFilterContext *avctx,
+const struct pl_tone_map_function **opt,
+const char *name)
+{
+const struct pl_tone_map_function * const *func;
+if (!strcmp(name, "help")) {
+av_log(avctx, AV_LOG_INFO, "Available tone mapping functions:\n");
+for (func = pl_tone_map_functions; *func; func++)
+av_log(avctx, AV_LOG_INFO, "%s (%s)\n",
+   (*func)->name, (*func)->description);
+return AVERROR_EXIT;
+}
+
+for (func = pl_tone_map_functions; *func; func++) {
+if (!strcmp(name, (*func)->name)) {
+*opt = *func;
+return 0;
+}
+}
+
+av_log(avctx, AV_LOG_ERROR, "No such tone mapping function '%s'.\n", name);
+return AVERROR(EINVAL);
+}
+
 static int libplacebo_init(AVFilterContext *avctx)
 {
 LibplaceboContext *s = avctx->priv;
@@ -281,6 +309,7 @@ static int process_frames(AVFilterContext *avctx, AVFrame 
*out, AVFrame *in)
 int err = 0, ok;
 LibplaceboContext *s = avctx->priv;
 struct pl_render_params params;
+struct pl_color_map_params color_params;
 struct pl_frame image, target;
 ok = pl_map_avframe_ex(s->gpu, , pl_avframe_params(
 .frame= in,
@@ -336,18 +365,6 @@ static int process_frames(AVFilterContext *avctx, AVFrame 
*out, AVFrame *in)
 .overshoot_margin = s->overshoot,
 ),
 
-.color_map_params = pl_color_map_params(
-.intent = s->intent,
-.tone_mapping_algo = s->tonemapping,
-.tone_mapping_param = s->tonemapping_param,
-.desaturation_strength = s->desat_str,
-.desaturation_exponent = s->desat_exp,
-.desaturation_base = s->desat_base,
-.max_boost = s->max_boost,
-.gamut_warning = s->gamut_warning,
-.gamut_clipping = s->gamut_clipping,
-),
-
 .dither_params = s->dithering < 0 ? NULL : pl_dither_params(
 .method = s->dithering,
 .lut_size = s->dither_lut_size,
@@ -374,6 +391,39 @@ static int process_frames(AVFilterContext *avctx, AVFrame 
*out, AVFrame *in)
 RET(find_scaler(avctx, , s->upscaler));
 RET(find_scaler(avctx, , s->downscaler));
 
+params.color_map_params = _params;
+color_params = (struct pl_color_map_params) {
+PL_COLOR_MAP_DEFAULTS
+.intent = s->intent,
+.gamut_mode = s->gamut_mode,
+.tone_mapping_param = s->tonemapping_param,
+.tone_mapping_mode = s->tonemapping_mode,
+.inverse_tone_mapping = s->inverse_tonemapping,
+.tone_mapping_crosstalk = s->crosstalk,
+.lut_size = s->tonemapping_lut_size,
+};
+
+/* backwards compatibility with older API */
+if (color_params.tone_mapping_mode == PL_TONE_MAP_AUTO &&
+(s->desat_str >= 0.0f || s->desat_exp >= 0.0f)) {
+float str = s->desat_str < 0.0f ? 0.9f : s->desat_str;
+float exp = s->desat_exp < 0.0f ? 0.2f : s->desat_exp;
+if (str >= 0.9f && exp <= 0.1f) {
+color_params.tone_mapping_mode = PL_TONE_MAP_RGB;
+} else if (str > 0.1f) {
+color_params.tone_mapping_mode = PL_TONE_MAP_HYBRID;
+} else {
+color_params.tone_mapping_mode = PL_TONE_MAP_LUMA;
+}
+}
+
+if 

[FFmpeg-devel] [PATCH] avfilter/f_realtime: add support for commands

2022-03-25 Thread Paul B Mahol
Signed-off-by: Paul B Mahol 
---
 doc/filters.texi | 4 
 libavfilter/f_realtime.c | 4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index d70ac3e237..1d56d24819 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26757,6 +26757,10 @@ A processing speed faster than what is possible 
without these filters cannot
 be achieved.
 @end table
 
+@subsection Commands
+
+Both filters supports the all above options as @ref{commands}.
+
 @section segment, asegment
 
 Split single input stream into multiple streams.
diff --git a/libavfilter/f_realtime.c b/libavfilter/f_realtime.c
index 78da5dc3a7..ef713474ea 100644
--- a/libavfilter/f_realtime.c
+++ b/libavfilter/f_realtime.c
@@ -66,7 +66,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 }
 
 #define OFFSET(x) offsetof(RealtimeContext, x)
-#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | 
AV_OPT_FLAG_FILTERING_PARAM
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | 
AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM
 static const AVOption options[] = {
 { "limit", "sleep time limit", OFFSET(limit), AV_OPT_TYPE_DURATION, { .i64 
= 200 }, 0, INT64_MAX, FLAGS },
 { "speed", "speed factor", OFFSET(speed), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 
}, DBL_MIN, DBL_MAX, FLAGS },
@@ -100,6 +100,7 @@ const AVFilter ff_vf_realtime = {
 .flags   = AVFILTER_FLAG_METADATA_ONLY,
 FILTER_INPUTS(avfilter_vf_realtime_inputs),
 FILTER_OUTPUTS(avfilter_vf_realtime_outputs),
+.process_command = ff_filter_process_command,
 };
 #endif /* CONFIG_REALTIME_FILTER */
 
@@ -128,5 +129,6 @@ const AVFilter ff_af_arealtime = {
 .flags   = AVFILTER_FLAG_METADATA_ONLY,
 FILTER_INPUTS(arealtime_inputs),
 FILTER_OUTPUTS(arealtime_outputs),
+.process_command = ff_filter_process_command,
 };
 #endif /* CONFIG_AREALTIME_FILTER */
-- 
2.35.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] rtpenc_vp8: Use 15-bit PictureIDs

2022-03-25 Thread zhilizhao(赵志立)



> On Mar 25, 2022, at 5:13 PM, Kevin Wang  wrote:
> 
> Hi, ping on this patch? It's quite simple, happy to answer any questions.
> 
> On Tue, Mar 22, 2022 at 2:25 PM  wrote:
> 
>> From: Kevin Wang 
>> 
>> 7-bit PictureIDs are not supported by WebRTC:
>> https://groups.google.com/g/discuss-webrtc/c/333-L02vuWA
>> 
>> In practice, 15-bit PictureIDs offer better compatibility.
>> 
>> Signed-off-by: Kevin Wang 
>> ---
>> libavformat/rtpenc_vp8.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>> 
>> diff --git a/libavformat/rtpenc_vp8.c b/libavformat/rtpenc_vp8.c
>> index 671d245758..655d44517e 100644
>> --- a/libavformat/rtpenc_vp8.c
>> +++ b/libavformat/rtpenc_vp8.c
>> @@ -35,7 +35,8 @@ void ff_rtp_send_vp8(AVFormatContext *s1, const uint8_t
>> *buf, int size)
>> // partition id 0
>> *s->buf_ptr++ = 0x90;
>> *s->buf_ptr++ = 0x80; // Picture id present
>> -*s->buf_ptr++ = s->frame_count++ & 0x7f;
>> +*s->buf_ptr++ = ((s->frame_count & 0x7f00) >> 8) | 0x80;
>> +*s->buf_ptr++ = s->frame_count++ & 0xff;
>> // Calculate the number of remaining bytes
>> header_size = s->buf_ptr - s->buf;
>> max_packet_size = s->max_payload_size - header_size;
>> --

LGTM.

___
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] rtpenc_vp8: Use 15-bit PictureIDs

2022-03-25 Thread Kevin Wang
Hi, ping on this patch? It's quite simple, happy to answer any questions.

On Tue, Mar 22, 2022 at 2:25 PM  wrote:

> From: Kevin Wang 
>
> 7-bit PictureIDs are not supported by WebRTC:
> https://groups.google.com/g/discuss-webrtc/c/333-L02vuWA
>
> In practice, 15-bit PictureIDs offer better compatibility.
>
> Signed-off-by: Kevin Wang 
> ---
>  libavformat/rtpenc_vp8.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/libavformat/rtpenc_vp8.c b/libavformat/rtpenc_vp8.c
> index 671d245758..655d44517e 100644
> --- a/libavformat/rtpenc_vp8.c
> +++ b/libavformat/rtpenc_vp8.c
> @@ -35,7 +35,8 @@ void ff_rtp_send_vp8(AVFormatContext *s1, const uint8_t
> *buf, int size)
>  // partition id 0
>  *s->buf_ptr++ = 0x90;
>  *s->buf_ptr++ = 0x80; // Picture id present
> -*s->buf_ptr++ = s->frame_count++ & 0x7f;
> +*s->buf_ptr++ = ((s->frame_count & 0x7f00) >> 8) | 0x80;
> +*s->buf_ptr++ = s->frame_count++ & 0xff;
>  // Calculate the number of remaining bytes
>  header_size = s->buf_ptr - s->buf;
>  max_packet_size = s->max_payload_size - header_size;
> --
> 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] MAINTAINERS: add myself as maintainer for libsrt protocol

2022-03-25 Thread Zhao Zhili
Signed-off-by: Zhao Zhili 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 931cf4bd2c..5daa6f8e03 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -516,6 +516,7 @@ Protocols:
   bluray.c  Petri Hintukainen
   ftp.c Lukasz Marek
   http.cRonald S. Bultje
+  libsrt.c  Zhao Zhili
   libssh.c  Lukasz Marek
   libzmq.c  Andriy Gelman
   mms*.cRonald S. Bultje
-- 
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] avformat/libsrt: fix deprecated warning

2022-03-25 Thread Zhao Zhili
srt_socket was deprecated after 1.4.1.
---
 libavformat/libsrt.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c
index 19b9cb9895..1610ce8318 100644
--- a/libavformat/libsrt.c
+++ b/libavformat/libsrt.c
@@ -429,7 +429,11 @@ static int libsrt_setup(URLContext *h, const char *uri, 
int flags)
 
  restart:
 
+#if SRT_VERSION_VALUE >= 0x010401
+fd = srt_create_socket();
+#else
 fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0);
+#endif
 if (fd < 0) {
 ret = libsrt_neterrno(h);
 goto fail;
-- 
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".