View | Details | Raw Unified | Return to bug 261302 | Differences between
and this patch

Collapse All | Expand All

(-)b/multimedia/ffmpeg/Makefile (-7 / +25 lines)
Lines 1-5 Link Here
1
PORTNAME=	ffmpeg
1
PORTNAME=	ffmpeg
2
PORTVERSION=	4.4.3
2
PORTVERSION=	5.1.2
3
PORTEPOCH=	1
3
PORTEPOCH=	1
4
CATEGORIES=	multimedia audio net
4
CATEGORIES=	multimedia audio net
5
MASTER_SITES=	https://ffmpeg.org/releases/
5
MASTER_SITES=	https://ffmpeg.org/releases/
Lines 33-42 PORTSCOUT= limit:^4\. Link Here
33
OPTIONS_DEFINE=	ALSA AMR_NB AMR_WB AOM ARIBB24 ASM ASS BS2B CACA CDIO \
33
OPTIONS_DEFINE=	ALSA AMR_NB AMR_WB AOM ARIBB24 ASM ASS BS2B CACA CDIO \
34
		CODEC2 DAV1D DAVS2 DC1394 DEBUG DOCS DRM FDK_AAC FLITE \
34
		CODEC2 DAV1D DAVS2 DC1394 DEBUG DOCS DRM FDK_AAC FLITE \
35
		FONTCONFIG FREETYPE FREI0R FRIBIDI GLSLANG GME GSM ICONV ILBC \
35
		FONTCONFIG FREETYPE FREI0R FRIBIDI GLSLANG GME GSM ICONV ILBC \
36
		JACK KLVANC KVAZAAR LADSPA LAME LENSFUN LIBBLURAY LIBRSVG2 \
36
		JACK JXL KLVANC KVAZAAR LADSPA LAME LCMS2 LENSFUN LIBBLURAY LIBPLACEBO LIBRSVG2 \
37
		LIBXML2 LTO LV2 MODPLUG MYSOFA OPENAL OPENCL OPENGL \
37
		LIBXML2 LTO LV2 MODPLUG MYSOFA OPENAL OPENCL OPENGL \
38
		OPENH264 OPENJPEG OPENMPT OPENVINO OPTIMIZED_CFLAGS OPUS POCKETSPHINX \
38
		OPENH264 OPENJPEG OPENMPT OPENVINO OPTIMIZED_CFLAGS OPUS POCKETSPHINX \
39
		PULSEAUDIO RAV1E RABBITMQ RIST RTCPU RUBBERBAND SDL SMB SNAPPY \
39
		PULSEAUDIO RAV1E RABBITMQ RIST RTCPU RUBBERBAND SDL SHADERC SMB SNAPPY \
40
		SNDIO SOXR SPEEX SRT SSH SVTAV1 SVTHEVC SVTVP9 TENSORFLOW \
40
		SNDIO SOXR SPEEX SRT SSH SVTAV1 SVTHEVC SVTVP9 TENSORFLOW \
41
		TESSERACT THEORA TWOLAME UAVS3D V4L VAAPI VAPOURSYNTH VDPAU VIDSTAB \
41
		TESSERACT THEORA TWOLAME UAVS3D V4L VAAPI VAPOURSYNTH VDPAU VIDSTAB \
42
		VMAF VO_AMRWBENC VORBIS VPX VULKAN WEBP X264 X265 \
42
		VMAF VO_AMRWBENC VORBIS VPX VULKAN WEBP X264 X265 \
Lines 46-53 OPTIONS_DEFINE_amd64= MFX Link Here
46
OPTIONS_DEFINE_i386=	MFX
46
OPTIONS_DEFINE_i386=	MFX
47
47
48
OPTIONS_DEFAULT=	AOM ASM ASS DAV1D DRM FONTCONFIG FREETYPE FREI0R GMP \
48
OPTIONS_DEFAULT=	AOM ASM ASS DAV1D DRM FONTCONFIG FREETYPE FREI0R GMP \
49
			GNUTLS ICONV LAME LIBXML2 OPTIMIZED_CFLAGS OPUS RTCPU \
49
			GNUTLS ICONV JXL LAME LCMS2 LIBPLACEBO LIBXML2 OPTIMIZED_CFLAGS OPUS RTCPU \
50
			V4L VAAPI VDPAU VMAF VORBIS VPX WEBP X264 X265 XCB
50
			V4L VAAPI VDPAU VMAF VORBIS VPX WEBP VULKAN X264 X265 XCB
51
OPTIONS_DEFAULT_amd64=	SVTAV1
51
OPTIONS_DEFAULT_amd64=	SVTAV1
52
52
53
# i386 is too register-starved for LTO (PR257124)
53
# i386 is too register-starved for LTO (PR257124)
Lines 122-131 RIST_DESC= Reliable Internet Stream Transport protocol via librist Link Here
122
RUBBERBAND_DESC=Time-stretching and pitch-shifting with librubberband
122
RUBBERBAND_DESC=Time-stretching and pitch-shifting with librubberband
123
RTCPU_DESC=	Detect CPU capabilities at runtime
123
RTCPU_DESC=	Detect CPU capabilities at runtime
124
RTMP_DESC=	RTMP(T)E protocol support
124
RTMP_DESC=	RTMP(T)E protocol support
125
SHADERC_DESC=	GLSL->SPIRV compilation via libshaderc
125
SRT_DESC=	Haivision SRT protocol via libsrt
126
SRT_DESC=	Haivision SRT protocol via libsrt
126
SVTAV1_DESC=	AV1 encoding via SVT-AV1
127
SVTAV1_DESC=	AV1 encoding via SVT-AV1
127
SVTHEVC_DESC=	HEVC encoding via SVT-HEVC
128
SVTHEVC_DESC=	HEVC encoding via SVT-HEVC
128
SVTVP9_DESC=	VP9 encoding via SVT-VP9
129
SVTVP9_DESC=	VP9 encoding via SVT-VP9
130
LIBPLACEBO_DESC=GPU filters from libplacebo
129
LIBRTMP_DESC=	${RTMP_DESC} via librtmp
131
LIBRTMP_DESC=	${RTMP_DESC} via librtmp
130
TENSORFLOW_DESC=TensorFlow as a DNN module backend for DNN based filters like sr
132
TENSORFLOW_DESC=TensorFlow as a DNN module backend for DNN based filters like sr
131
TESSERACT_DESC=	Optical Character Recognition via Tesseract
133
TESSERACT_DESC=	Optical Character Recognition via Tesseract
Lines 282-287 ILBC_CONFIGURE_ENABLE= libilbc Link Here
282
JACK_LIB_DEPENDS=	libjack.so:audio/jack
284
JACK_LIB_DEPENDS=	libjack.so:audio/jack
283
JACK_CONFIGURE_ENABLE=	libjack
285
JACK_CONFIGURE_ENABLE=	libjack
284
286
287
# jxl
288
JXL_LIB_DEPENDS=	libjxl.so:graphics/libjxl
289
JXL_CONFIGURE_ENABLE=	libjxl
290
285
# klvanc
291
# klvanc
286
KLVANC_LIB_DEPENDS=	libklvanc.so:multimedia/libklvanc
292
KLVANC_LIB_DEPENDS=	libklvanc.so:multimedia/libklvanc
287
KLVANC_CONFIGURE_ENABLE=	libklvanc
293
KLVANC_CONFIGURE_ENABLE=	libklvanc
Lines 299-304 LADSPA_CONFIGURE_ENABLE= ladspa Link Here
299
LAME_LIB_DEPENDS=	libmp3lame.so:audio/lame
305
LAME_LIB_DEPENDS=	libmp3lame.so:audio/lame
300
LAME_CONFIGURE_ENABLE=	libmp3lame
306
LAME_CONFIGURE_ENABLE=	libmp3lame
301
307
308
# lcms2
309
LCMS2_LIB_DEPENDS=	liblcms2.so:graphics/lcms2
310
LCMS2_CONFIGURE_ENABLE=	lcms2
311
302
# lensfun
312
# lensfun
303
LENSFUN_LIB_DEPENDS=	liblensfun.so:graphics/lensfun
313
LENSFUN_LIB_DEPENDS=	liblensfun.so:graphics/lensfun
304
LENSFUN_CONFIGURE_ENABLE=	liblensfun
314
LENSFUN_CONFIGURE_ENABLE=	liblensfun
Lines 307-312 LENSFUN_CONFIGURE_ENABLE= liblensfun Link Here
307
LIBBLURAY_LIB_DEPENDS=	libbluray.so:multimedia/libbluray
317
LIBBLURAY_LIB_DEPENDS=	libbluray.so:multimedia/libbluray
308
LIBBLURAY_CONFIGURE_ENABLE=	libbluray
318
LIBBLURAY_CONFIGURE_ENABLE=	libbluray
309
319
320
# libplacebo
321
LIBPLACEBO_LIB_DEPENDS=	libplacebo.so:graphics/libplacebo
322
LIBPLACEBO_CONFIGURE_ENABLE=	libplacebo
323
310
# librsvg
324
# librsvg
311
LIBRSVG2_USES=			gnome
325
LIBRSVG2_USES=			gnome
312
LIBRSVG2_USE=			GNOME=cairo,librsvg2
326
LIBRSVG2_USE=			GNOME=cairo,librsvg2
Lines 426-431 SDL_USES= sdl Link Here
426
SDL_USE=		SDL=sdl2
440
SDL_USE=		SDL=sdl2
427
SDL_CONFIGURE_ENABLE=	sdl2
441
SDL_CONFIGURE_ENABLE=	sdl2
428
442
443
# shaderc
444
SHADERC_LIB_DEPENDS=	libshaderc_shared.so:graphics/shaderc
445
SHADERC_CONFIGURE_ENABLE=	libshaderc
446
SHADERC_PREVENTS=	GLSLANG
447
429
# smbclient
448
# smbclient
430
SMB_USES=		samba:lib
449
SMB_USES=		samba:lib
431
SMB_CONFIGURE_ENABLE=	libsmbclient
450
SMB_CONFIGURE_ENABLE=	libsmbclient
Lines 537-543 VPX_CONFIGURE_ENABLE= libvpx Link Here
537
VULKAN_BUILD_DEPENDS=	vulkan-headers>0:graphics/vulkan-headers
556
VULKAN_BUILD_DEPENDS=	vulkan-headers>0:graphics/vulkan-headers
538
VULKAN_LIB_DEPENDS=	libvulkan.so:graphics/vulkan-loader
557
VULKAN_LIB_DEPENDS=	libvulkan.so:graphics/vulkan-loader
539
VULKAN_CONFIGURE_ENABLE=	vulkan
558
VULKAN_CONFIGURE_ENABLE=	vulkan
540
VULKAN_IMPLIES=		GLSLANG
559
VULKAN_IMPLIES=		${"${PORT_OPTIONS:MGLSLANG}":?GLSLANG:SHADERC}
541
560
542
# webp
561
# webp
543
WEBP_LIB_DEPENDS=	libwebp.so:graphics/webp
562
WEBP_LIB_DEPENDS=	libwebp.so:graphics/webp
Lines 610-616 CONFIGURE_ARGS+=--prefix="${PREFIX}" \ Link Here
610
		--enable-shared \
629
		--enable-shared \
611
		--enable-pic \
630
		--enable-pic \
612
		--enable-gpl \
631
		--enable-gpl \
613
		--enable-avresample \
614
		--cc="${CC}" \
632
		--cc="${CC}" \
615
		--cxx="${CXX}"
633
		--cxx="${CXX}"
616
634
(-)b/multimedia/ffmpeg/distinfo (-3 / +3 lines)
Lines 1-6 Link Here
1
TIMESTAMP = 1665342284
1
TIMESTAMP = 1664099167
2
SHA256 (ffmpeg-4.4.3.tar.xz) = 6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
2
SHA256 (ffmpeg-5.1.2.tar.xz) = 619e706d662c8420859832ddc259cd4d4096a48a2ce1eefd052db9e440eef3dc
3
SIZE (ffmpeg-4.4.3.tar.xz) = 9566020
3
SIZE (ffmpeg-5.1.2.tar.xz) = 10004956
4
SHA256 (0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch) = 376ea23e9d876390fbca936c80cb437bb9daa6232ff65df0ea91673e18b739ff
4
SHA256 (0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch) = 376ea23e9d876390fbca936c80cb437bb9daa6232ff65df0ea91673e18b739ff
5
SIZE (0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch) = 24259
5
SIZE (0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch) = 24259
6
SHA256 (0002-doc-Add-libsvt_hevc-encoder-docs.patch) = d16589efc4be2602a9f436e9938cfee0cc7b5ccd7a4a6b41c0c9a59ae0859fda
6
SHA256 (0002-doc-Add-libsvt_hevc-encoder-docs.patch) = d16589efc4be2602a9f436e9938cfee0cc7b5ccd7a4a6b41c0c9a59ae0859fda
(-)a/multimedia/ffmpeg/files/patch-svtav1 (-437 lines)
Removed Link Here
1
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/04b89e8ae33b
2
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/64e2fb3f9d89
3
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/0463f5d6d56d
4
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/c5f314309067
5
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/c33b4048859a
6
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/a2b090da7932
7
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/1dddb930aaf0
8
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/4e47ebf38b97
9
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/50bc87263576
10
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/d794b36a7788
11
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/51c0b9e829be
12
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/e3c4442b249a
13
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/6fd1533057ff
14
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/ded0334d214f
15
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/70887d44ffa3
16
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/fe100bc556d7
17
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/fb70e0611bd7
18
19
--- configure.orig	2021-10-24 20:47:11 UTC
20
+++ configure
21
@@ -6430,7 +6430,7 @@ enabled libsrt            && require_pkg_config libsrt
22
 enabled libssh            && require_pkg_config libssh libssh libssh/sftp.h sftp_init
23
 enabled libspeex          && require_pkg_config libspeex speex speex/speex.h speex_decoder_init
24
 enabled libsrt            && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket
25
-enabled libsvtav1         && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.8.4" EbSvtAv1Enc.h svt_av1_enc_init_handle
26
+enabled libsvtav1         && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.9.0" EbSvtAv1Enc.h svt_av1_enc_init_handle
27
 enabled libtensorflow     && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow
28
 enabled libtesseract      && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate
29
 enabled libtheora         && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
30
--- doc/encoders.texi.orig	2021-10-24 20:47:07 UTC
31
+++ doc/encoders.texi
32
@@ -1754,28 +1754,15 @@ Set the operating point tier.
33
 @item tier
34
 Set the operating point tier.
35
 
36
-@item rc
37
-Set the rate control mode to use.
38
-
39
-Possible modes:
40
-@table @option
41
-@item cqp
42
-Constant quantizer: use fixed values of qindex (dependent on the frame type)
43
-throughout the stream.  This mode is the default.
44
-
45
-@item vbr
46
-Variable bitrate: use a target bitrate for the whole stream.
47
-
48
-@item cvbr
49
-Constrained variable bitrate: use a target bitrate for each GOP.
50
-@end table
51
-
52
 @item qmax
53
 Set the maximum quantizer to use when using a bitrate mode.
54
 
55
 @item qmin
56
 Set the minimum quantizer to use when using a bitrate mode.
57
 
58
+@item crf
59
+Constant rate factor value used in crf rate control mode (0-63).
60
+
61
 @item qp
62
 Set the quantizer used in cqp rate control mode (0-63).
63
 
64
@@ -1786,14 +1773,18 @@ Set number of frames to look ahead (0-120).
65
 Set number of frames to look ahead (0-120).
66
 
67
 @item preset
68
-Set the quality-speed tradeoff, in the range 0 to 8.  Higher values are
69
-faster but lower quality.  Defaults to 8 (highest speed).
70
+Set the quality-speed tradeoff, in the range 0 to 13.  Higher values are
71
+faster but lower quality.
72
 
73
 @item tile_rows
74
 Set log2 of the number of rows of tiles to use (0-6).
75
 
76
 @item tile_columns
77
 Set log2 of the number of columns of tiles to use (0-4).
78
+
79
+@item svtav1-params
80
+Set SVT-AV1 options using a list of @var{key}=@var{value} pairs separated
81
+by ":". See the SVT-AV1 encoder user guide for a list of accepted parameters.
82
 
83
 @end table
84
 
85
--- libavcodec/libsvtav1.c.orig	2021-10-24 20:47:07 UTC
86
+++ libavcodec/libsvtav1.c
87
@@ -60,17 +60,20 @@ typedef struct SvtContext {
88
     EOS_STATUS eos_flag;
89
 
90
     // User options.
91
+    AVDictionary *svtav1_opts;
92
+#if FF_API_SVTAV1_OPTS
93
     int hierarchical_level;
94
     int la_depth;
95
-    int enc_mode;
96
-    int rc_mode;
97
     int scd;
98
-    int qp;
99
 
100
     int tier;
101
 
102
     int tile_columns;
103
     int tile_rows;
104
+#endif
105
+    int enc_mode;
106
+    int crf;
107
+    int qp;
108
 } SvtContext;
109
 
110
 static const struct {
111
@@ -151,11 +154,126 @@ static int config_enc_params(EbSvtAv1EncConfiguration 
112
 {
113
     SvtContext *svt_enc = avctx->priv_data;
114
     const AVPixFmtDescriptor *desc;
115
+    AVDictionaryEntry *en = NULL;
116
 
117
+    // Update param from options
118
+#if FF_API_SVTAV1_OPTS
119
+    param->hierarchical_levels      = svt_enc->hierarchical_level;
120
+    param->tier                     = svt_enc->tier;
121
+    param->scene_change_detection   = svt_enc->scd;
122
+    param->tile_columns             = svt_enc->tile_columns;
123
+    param->tile_rows                = svt_enc->tile_rows;
124
+
125
+    if (svt_enc->la_depth >= 0)
126
+        param->look_ahead_distance  = svt_enc->la_depth;
127
+#endif
128
+
129
+    if (svt_enc->enc_mode >= 0)
130
+        param->enc_mode             = svt_enc->enc_mode;
131
+
132
+    if (avctx->bit_rate) {
133
+        param->target_bit_rate      = avctx->bit_rate;
134
+        if (avctx->rc_max_rate != avctx->bit_rate)
135
+            param->rate_control_mode = 1;
136
+        else
137
+            param->rate_control_mode = 2;
138
+
139
+        param->max_qp_allowed       = avctx->qmax;
140
+        param->min_qp_allowed       = avctx->qmin;
141
+    }
142
+    param->max_bit_rate             = avctx->rc_max_rate;
143
+    param->vbv_bufsize              = avctx->rc_buffer_size;
144
+
145
+    if (svt_enc->crf > 0) {
146
+        param->qp                   = svt_enc->crf;
147
+        param->rate_control_mode    = 0;
148
+    } else if (svt_enc->qp > 0) {
149
+        param->qp                   = svt_enc->qp;
150
+        param->rate_control_mode    = 0;
151
+        param->enable_adaptive_quantization = 0;
152
+    }
153
+
154
+    desc = av_pix_fmt_desc_get(avctx->pix_fmt);
155
+    param->color_primaries          = avctx->color_primaries;
156
+    param->matrix_coefficients      = (desc->flags & AV_PIX_FMT_FLAG_RGB) ?
157
+                                      AVCOL_SPC_RGB : avctx->colorspace;
158
+    param->transfer_characteristics = avctx->color_trc;
159
+
160
+    if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED)
161
+        param->color_range = avctx->color_range == AVCOL_RANGE_JPEG;
162
+    else
163
+        param->color_range = !!(desc->flags & AV_PIX_FMT_FLAG_RGB);
164
+
165
+#if SVT_AV1_CHECK_VERSION(1, 0, 0)
166
+    if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) {
167
+        const char *name =
168
+            av_chroma_location_name(avctx->chroma_sample_location);
169
+
170
+        switch (avctx->chroma_sample_location) {
171
+        case AVCHROMA_LOC_LEFT:
172
+            param->chroma_sample_position = EB_CSP_VERTICAL;
173
+            break;
174
+        case AVCHROMA_LOC_TOPLEFT:
175
+            param->chroma_sample_position = EB_CSP_COLOCATED;
176
+            break;
177
+        default:
178
+            if (!name)
179
+                break;
180
+
181
+            av_log(avctx, AV_LOG_WARNING,
182
+                   "Specified chroma sample location %s is unsupported "
183
+                   "on the AV1 bit stream level. Usage of a container that "
184
+                   "allows passing this information - such as Matroska - "
185
+                   "is recommended.\n",
186
+                   name);
187
+            break;
188
+        }
189
+    }
190
+#endif
191
+
192
+    if (avctx->profile != FF_PROFILE_UNKNOWN)
193
+        param->profile = avctx->profile;
194
+
195
+    if (avctx->level != FF_LEVEL_UNKNOWN)
196
+        param->level = avctx->level;
197
+
198
+    if (avctx->gop_size > 0)
199
+        param->intra_period_length  = avctx->gop_size - 1;
200
+
201
+    if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
202
+        param->frame_rate_numerator   = avctx->framerate.num;
203
+        param->frame_rate_denominator = avctx->framerate.den;
204
+    } else {
205
+        param->frame_rate_numerator   = avctx->time_base.den;
206
+        param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame;
207
+    }
208
+
209
+    /* 2 = IDR, closed GOP, 1 = CRA, open GOP */
210
+    param->intra_refresh_type = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? 2 : 1;
211
+
212
+#if SVT_AV1_CHECK_VERSION(0, 9, 1)
213
+    while ((en = av_dict_get(svt_enc->svtav1_opts, "", en, AV_DICT_IGNORE_SUFFIX))) {
214
+        EbErrorType ret = svt_av1_enc_parse_parameter(param, en->key, en->value);
215
+        if (ret != EB_ErrorNone) {
216
+            int level = (avctx->err_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
217
+            av_log(avctx, level, "Error parsing option %s: %s.\n", en->key, en->value);
218
+            if (avctx->err_recognition & AV_EF_EXPLODE)
219
+                return AVERROR(EINVAL);
220
+        }
221
+    }
222
+#else
223
+    if ((en = av_dict_get(svt_enc->svtav1_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
224
+        int level = (avctx->err_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
225
+        av_log(avctx, level, "svt-params needs libavcodec to be compiled with SVT-AV1 "
226
+                             "headers >= 0.9.1.\n");
227
+        if (avctx->err_recognition & AV_EF_EXPLODE)
228
+            return AVERROR(ENOSYS);
229
+    }
230
+#endif
231
+
232
     param->source_width     = avctx->width;
233
     param->source_height    = avctx->height;
234
 
235
-    desc = av_pix_fmt_desc_get(avctx->pix_fmt);
236
     param->encoder_bit_depth = desc->comp[0].depth;
237
 
238
     if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 1)
239
@@ -169,12 +287,6 @@ static int config_enc_params(EbSvtAv1EncConfiguration 
240
         return AVERROR(EINVAL);
241
     }
242
 
243
-    if (avctx->profile != FF_PROFILE_UNKNOWN)
244
-        param->profile = avctx->profile;
245
-
246
-    if (avctx->level != FF_LEVEL_UNKNOWN)
247
-        param->level = avctx->level;
248
-
249
     if ((param->encoder_color_format == EB_YUV422 || param->encoder_bit_depth > 10)
250
          && param->profile != FF_PROFILE_AV1_PROFESSIONAL ) {
251
         av_log(avctx, AV_LOG_WARNING, "Forcing Professional profile\n");
252
@@ -184,40 +296,21 @@ static int config_enc_params(EbSvtAv1EncConfiguration 
253
         param->profile = FF_PROFILE_AV1_HIGH;
254
     }
255
 
256
-    // Update param from options
257
-    param->hierarchical_levels      = svt_enc->hierarchical_level;
258
-    param->enc_mode                 = svt_enc->enc_mode;
259
-    param->tier                     = svt_enc->tier;
260
-    param->rate_control_mode        = svt_enc->rc_mode;
261
-    param->scene_change_detection   = svt_enc->scd;
262
-    param->qp                       = svt_enc->qp;
263
+    avctx->bit_rate       = param->rate_control_mode > 0 ?
264
+                            param->target_bit_rate : 0;
265
+    avctx->rc_max_rate    = param->max_bit_rate;
266
+    avctx->rc_buffer_size = param->vbv_bufsize;
267
 
268
-    param->target_bit_rate          = avctx->bit_rate;
269
+    if (avctx->bit_rate || avctx->rc_max_rate || avctx->rc_buffer_size) {
270
+        AVCPBProperties *cpb_props = ff_add_cpb_side_data(avctx);
271
+        if (!cpb_props)
272
+            return AVERROR(ENOMEM);
273
 
274
-    if (avctx->gop_size > 0)
275
-        param->intra_period_length  = avctx->gop_size - 1;
276
-
277
-    if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
278
-        param->frame_rate_numerator   = avctx->framerate.num;
279
-        param->frame_rate_denominator = avctx->framerate.den;
280
-    } else {
281
-        param->frame_rate_numerator   = avctx->time_base.den;
282
-        param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame;
283
+        cpb_props->buffer_size = avctx->rc_buffer_size;
284
+        cpb_props->max_bitrate = avctx->rc_max_rate;
285
+        cpb_props->avg_bitrate = avctx->bit_rate;
286
     }
287
 
288
-    if (param->rate_control_mode) {
289
-        param->max_qp_allowed       = avctx->qmax;
290
-        param->min_qp_allowed       = avctx->qmin;
291
-    }
292
-
293
-    param->intra_refresh_type       = 2; /* Real keyframes only */
294
-
295
-    if (svt_enc->la_depth >= 0)
296
-        param->look_ahead_distance  = svt_enc->la_depth;
297
-
298
-    param->tile_columns = svt_enc->tile_columns;
299
-    param->tile_rows    = svt_enc->tile_rows;
300
-
301
     return 0;
302
 }
303
 
304
@@ -330,11 +423,8 @@ static int eb_send_frame(AVCodecContext *avctx, const 
305
         if (svt_enc->eos_flag == EOS_SENT)
306
             return 0;
307
 
308
-        headerPtrLast.n_alloc_len   = 0;
309
-        headerPtrLast.n_filled_len  = 0;
310
-        headerPtrLast.n_tick_count  = 0;
311
-        headerPtrLast.p_app_private = NULL;
312
-        headerPtrLast.p_buffer      = NULL;
313
+        memset(&headerPtrLast, 0, sizeof(headerPtrLast));
314
+        headerPtrLast.pic_type      = EB_AV1_INVALID_PICTURE;
315
         headerPtrLast.flags         = EB_BUFFERFLAG_EOS;
316
 
317
         svt_av1_enc_send_picture(svt_enc->svt_handle, &headerPtrLast);
318
@@ -350,6 +440,16 @@ static int eb_send_frame(AVCodecContext *avctx, const 
319
     headerPtr->p_app_private = NULL;
320
     headerPtr->pts           = frame->pts;
321
 
322
+    switch (frame->pict_type) {
323
+    case AV_PICTURE_TYPE_I:
324
+        headerPtr->pic_type = EB_AV1_KEY_PICTURE;
325
+        break;
326
+    default:
327
+        // Actually means auto, or default.
328
+        headerPtr->pic_type = EB_AV1_INVALID_PICTURE;
329
+        break;
330
+    }
331
+
332
     svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr);
333
 
334
     return 0;
335
@@ -472,21 +572,22 @@ static const AVOption options[] = {
336
 #define OFFSET(x) offsetof(SvtContext, x)
337
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
338
 static const AVOption options[] = {
339
-    { "hielevel", "Hierarchical prediction levels setting", OFFSET(hierarchical_level),
340
-      AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE , "hielevel"},
341
+#if FF_API_SVTAV1_OPTS
342
+    { "hielevel", "Hierarchical prediction levels setting (Deprecated, use svtav1-params)", OFFSET(hierarchical_level),
343
+      AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE | AV_OPT_FLAG_DEPRECATED , "hielevel"},
344
         { "3level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 },  INT_MIN, INT_MAX, VE, "hielevel" },
345
         { "4level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4 },  INT_MIN, INT_MAX, VE, "hielevel" },
346
 
347
-    { "la_depth", "Look ahead distance [0, 120]", OFFSET(la_depth),
348
-      AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE },
349
+    { "la_depth", "Look ahead distance [0, 120] (Deprecated, use svtav1-params)", OFFSET(la_depth),
350
+      AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE | AV_OPT_FLAG_DEPRECATED },
351
 
352
-    { "preset", "Encoding preset [0, 8]",
353
-      OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = MAX_ENC_PRESET }, 0, MAX_ENC_PRESET, VE },
354
-
355
-    { "tier", "Set operating point tier", OFFSET(tier),
356
-      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "tier" },
357
+    { "tier", "Set operating point tier (Deprecated, use svtav1-params)", OFFSET(tier),
358
+      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED, "tier" },
359
         { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, "tier" },
360
         { "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "tier" },
361
+#endif
362
+    { "preset", "Encoding preset",
363
+      OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, MAX_ENC_PRESET, VE },
364
 
365
     FF_AV1_PROFILE_OPTS
366
 
367
@@ -518,21 +619,20 @@ static const AVOption options[] = {
368
         { LEVEL("7.3", 73) },
369
 #undef LEVEL
370
 
371
-    { "rc", "Bit rate control mode", OFFSET(rc_mode),
372
-      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, VE , "rc"},
373
-        { "cqp", "Constant quantizer", 0, AV_OPT_TYPE_CONST, { .i64 = 0 },  INT_MIN, INT_MAX, VE, "rc" },
374
-        { "vbr", "Variable Bit Rate, use a target bitrate for the entire stream", 0, AV_OPT_TYPE_CONST, { .i64 = 1 },  INT_MIN, INT_MAX, VE, "rc" },
375
-        { "cvbr", "Constrained Variable Bit Rate, use a target bitrate for each GOP", 0, AV_OPT_TYPE_CONST,{ .i64 = 2 },  INT_MIN, INT_MAX, VE, "rc" },
376
+    { "crf", "Constant Rate Factor value", OFFSET(crf),
377
+      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE },
378
+    { "qp", "Initial Quantizer level value", OFFSET(qp),
379
+      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE },
380
+#if FF_API_SVTAV1_OPTS
381
+    { "sc_detection", "Scene change detection (Deprecated, use svtav1-params)", OFFSET(scd),
382
+      AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED },
383
 
384
-    { "qp", "Quantizer to use with cqp rate control mode", OFFSET(qp),
385
-      AV_OPT_TYPE_INT, { .i64 = 50 }, 0, 63, VE },
386
+    { "tile_columns", "Log2 of number of tile columns to use (Deprecated, use svtav1-params)", OFFSET(tile_columns), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 4, VE | AV_OPT_FLAG_DEPRECATED },
387
+    { "tile_rows", "Log2 of number of tile rows to use (Deprecated, use svtav1-params)", OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 6, VE | AV_OPT_FLAG_DEPRECATED },
388
+#endif
389
 
390
-    { "sc_detection", "Scene change detection", OFFSET(scd),
391
-      AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
392
+    { "svtav1-params", "Set the SVT-AV1 configuration using a :-separated list of key=value parameters", OFFSET(svtav1_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
393
 
394
-    { "tile_columns", "Log2 of number of tile columns to use", OFFSET(tile_columns), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, VE},
395
-    { "tile_rows", "Log2 of number of tile rows to use", OFFSET(tile_rows), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 6, VE},
396
-
397
     {NULL},
398
 };
399
 
400
@@ -544,9 +644,10 @@ static const AVCodecDefault eb_enc_defaults[] = {
401
 };
402
 
403
 static const AVCodecDefault eb_enc_defaults[] = {
404
-    { "b",         "7M"    },
405
+    { "b",         "0"    },
406
+    { "flags",     "+cgop" },
407
     { "g",         "-1"    },
408
-    { "qmin",      "0"     },
409
+    { "qmin",      "1"     },
410
     { "qmax",      "63"    },
411
     { NULL },
412
 };
413
@@ -561,12 +662,11 @@ AVCodec ff_libsvtav1_encoder = {
414
     .receive_packet = eb_receive_packet,
415
     .close          = eb_enc_close,
416
     .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
417
-    .caps_internal  = FF_CODEC_CAP_AUTO_THREADS,
418
+    .caps_internal  = FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP,
419
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
420
                                                     AV_PIX_FMT_YUV420P10,
421
                                                     AV_PIX_FMT_NONE },
422
     .priv_class     = &class,
423
     .defaults       = eb_enc_defaults,
424
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
425
     .wrapper_name   = "libsvtav1",
426
 };
427
--- libavcodec/version.h.orig	2021-10-24 20:47:07 UTC
428
+++ libavcodec/version.h
429
@@ -168,5 +168,8 @@
430
 #ifndef FF_API_INIT_PACKET
431
 #define FF_API_INIT_PACKET         (LIBAVCODEC_VERSION_MAJOR < 60)
432
 #endif
433
+#ifndef FF_API_SVTAV1_OPTS
434
+#define FF_API_SVTAV1_OPTS         (LIBAVCODEC_VERSION_MAJOR < 60)
435
+#endif
436
 
437
 #endif /* AVCODEC_VERSION_H */
(-)a/multimedia/ffmpeg/files/patch-vmaf (-951 lines)
Removed Link Here
1
https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/3d29724c008d
2
3
--- configure.orig	2021-10-24 20:47:11 UTC
4
+++ configure
5
@@ -3663,7 +3663,7 @@ vidstabtransform_filter_deps="libvidstab"
6
 vaguedenoiser_filter_deps="gpl"
7
 vidstabdetect_filter_deps="libvidstab"
8
 vidstabtransform_filter_deps="libvidstab"
9
-libvmaf_filter_deps="libvmaf pthreads"
10
+libvmaf_filter_deps="libvmaf"
11
 zmq_filter_deps="libzmq"
12
 zoompan_filter_deps="swscale"
13
 zscale_filter_deps="libzimg const_nan"
14
@@ -6441,7 +6441,7 @@ enabled libvidstab        && require_pkg_config libvid
15
 enabled libuavs3d         && require_pkg_config libuavs3d "uavs3d >= 1.1.41" uavs3d.h uavs3d_decode
16
 enabled libv4l2           && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl
17
 enabled libvidstab        && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
18
-enabled libvmaf           && require_pkg_config libvmaf "libvmaf >= 1.5.2" libvmaf.h compute_vmaf
19
+enabled libvmaf           && require_pkg_config libvmaf "libvmaf >= 2.0.0" libvmaf.h vmaf_init
20
 enabled libvo_amrwbenc    && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
21
 enabled libvorbis         && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init &&
22
                              require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init
23
--- doc/filters.texi.orig	2021-10-24 20:47:07 UTC
24
+++ doc/filters.texi
25
@@ -13867,66 +13867,58 @@ ffmpeg -i input.mov -vf lensfun=make=Canon:model="Cano
26
 
27
 @section libvmaf
28
 
29
-Obtain the VMAF (Video Multi-Method Assessment Fusion)
30
-score between two input videos.
31
+Calulate the VMAF (Video Multi-Method Assessment Fusion) score for a
32
+reference/distorted pair of input videos.
33
 
34
 The obtained VMAF score is printed through the logging system.
35
 
36
 It requires Netflix's vmaf library (libvmaf) as a pre-requisite.
37
 After installing the library it can be enabled using:
38
 @code{./configure --enable-libvmaf}.
39
-If no model path is specified it uses the default model: @code{vmaf_v0.6.1.pkl}.
40
 
41
 The filter has following options:
42
 
43
 @table @option
44
+@item model
45
+A `|` delimited list of vmaf models. Each model can be configured with a number of parameters.
46
+Default value: @code{"version=vmaf_v0.6.1"}
47
+
48
 @item model_path
49
-Set the model path which is to be used for SVM.
50
-Default value: @code{"/usr/local/share/model/vmaf_v0.6.1.pkl"}
51
+Deprecated, use model='path=...'.
52
 
53
-@item log_path
54
-Set the file path to be used to store logs.
55
-
56
-@item log_fmt
57
-Set the format of the log file (csv, json or xml).
58
-
59
 @item enable_transform
60
-This option can enable/disable the @code{score_transform} applied to the final predicted VMAF score,
61
-if you have specified score_transform option in the input parameter file passed to @code{run_vmaf_training.py}
62
-Default value: @code{false}
63
+Deprecated, use model='enable_transform=true'.
64
 
65
 @item phone_model
66
-Invokes the phone model which will generate VMAF scores higher than in the
67
-regular model, which is more suitable for laptop, TV, etc. viewing conditions.
68
-Default value: @code{false}
69
+Deprecated, use model='enable_transform=true'.
70
 
71
+@item enable_conf_interval
72
+Deprecated, use model='enable_conf_interval=true'.
73
+
74
+@item feature
75
+A `|` delimited list of features. Each feature can be configured with a number of parameters.
76
+
77
 @item psnr
78
-Enables computing psnr along with vmaf.
79
-Default value: @code{false}
80
+Deprecated, use feature='name=psnr'.
81
 
82
 @item ssim
83
-Enables computing ssim along with vmaf.
84
-Default value: @code{false}
85
+Deprecated, use feature='name=ssim'.
86
 
87
 @item ms_ssim
88
-Enables computing ms_ssim along with vmaf.
89
-Default value: @code{false}
90
+Deprecated, use feature='name=ms_ssim'.
91
 
92
-@item pool
93
-Set the pool method to be used for computing vmaf.
94
-Options are @code{min}, @code{harmonic_mean} or @code{mean} (default).
95
+@item log_path
96
+Set the file path to be used to store log files.
97
 
98
+@item log_fmt
99
+Set the format of the log file (xml, json, csv, or sub).
100
+
101
 @item n_threads
102
-Set number of threads to be used when computing vmaf.
103
-Default value: @code{0}, which makes use of all available logical processors.
104
+Set number of threads to be used when initializing libvmaf.
105
+Default value: @code{0}, no threads.
106
 
107
 @item n_subsample
108
-Set interval for frame subsampling used when computing vmaf.
109
-Default value: @code{1}
110
-
111
-@item enable_conf_interval
112
-Enables confidence interval.
113
-Default value: @code{false}
114
+Set frame subsampling interval to be used.
115
 @end table
116
 
117
 This filter also supports the @ref{framesync} options.
118
@@ -13934,23 +13926,31 @@ This filter also supports the @ref{framesync} options.
119
 @subsection Examples
120
 @itemize
121
 @item
122
-On the below examples the input file @file{main.mpg} being processed is
123
-compared with the reference file @file{ref.mpg}.
124
+In the examples below, a distorted video @file{distorted.mpg} is
125
+compared with a reference file @file{reference.mpg}.
126
 
127
+@item
128
+Basic usage:
129
 @example
130
-ffmpeg -i main.mpg -i ref.mpg -lavfi libvmaf -f null -
131
+ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf=log_path=output.xml -f null -
132
 @end example
133
 
134
 @item
135
-Example with options:
136
+Example with multiple models:
137
 @example
138
-ffmpeg -i main.mpg -i ref.mpg -lavfi libvmaf="psnr=1:log_fmt=json" -f null -
139
+ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf='model=version=vmaf_v0.6.1\\:name=vmaf|version=vmaf_v0.6.1neg\\:name=vmaf_neg' -f null -
140
 @end example
141
 
142
 @item
143
+Example with multiple addtional features:
144
+@example
145
+ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf='feature=name=psnr|name=ciede' -f null -
146
+@end example
147
+
148
+@item
149
 Example with options and different containers:
150
 @example
151
-ffmpeg -i main.mpg -i ref.mkv -lavfi "[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=psnr=1:log_fmt=json" -f null -
152
+ffmpeg -i distorted.mpg -i reference.mkv -lavfi "[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=log_fmt=json:log_path=output.json" -f null -
153
 @end example
154
 @end itemize
155
 
156
--- libavfilter/vf_libvmaf.c.orig	2021-10-24 20:47:07 UTC
157
+++ libavfilter/vf_libvmaf.c
158
@@ -24,8 +24,8 @@
159
  * Calculate the VMAF between two input videos.
160
  */
161
 
162
-#include <pthread.h>
163
 #include <libvmaf.h>
164
+
165
 #include "libavutil/avstring.h"
166
 #include "libavutil/opt.h"
167
 #include "libavutil/pixdesc.h"
168
@@ -39,23 +39,9 @@ typedef struct LIBVMAFContext {
169
 typedef struct LIBVMAFContext {
170
     const AVClass *class;
171
     FFFrameSync fs;
172
-    const AVPixFmtDescriptor *desc;
173
-    int width;
174
-    int height;
175
-    double vmaf_score;
176
-    int vmaf_thread_created;
177
-    pthread_t vmaf_thread;
178
-    pthread_mutex_t lock;
179
-    pthread_cond_t cond;
180
-    int eof;
181
-    AVFrame *gmain;
182
-    AVFrame *gref;
183
-    int frame_set;
184
     char *model_path;
185
     char *log_path;
186
     char *log_fmt;
187
-    int disable_clip;
188
-    int disable_avx;
189
     int enable_transform;
190
     int phone_model;
191
     int psnr;
192
@@ -65,185 +51,488 @@ typedef struct LIBVMAFContext {
193
     int n_threads;
194
     int n_subsample;
195
     int enable_conf_interval;
196
-    int error;
197
+    char *model_cfg;
198
+    char *feature_cfg;
199
+    VmafContext *vmaf;
200
+    VmafModel **model;
201
+    unsigned model_cnt;
202
+    unsigned frame_cnt;
203
+    unsigned bpc;
204
 } LIBVMAFContext;
205
 
206
 #define OFFSET(x) offsetof(LIBVMAFContext, x)
207
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
208
 
209
 static const AVOption libvmaf_options[] = {
210
-    {"model_path",  "Set the model to be used for computing vmaf.",                     OFFSET(model_path), AV_OPT_TYPE_STRING, {.str="/usr/local/share/model/vmaf_v0.6.1.pkl"}, 0, 1, FLAGS},
211
-    {"log_path",  "Set the file path to be used to store logs.",                        OFFSET(log_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
212
-    {"log_fmt",  "Set the format of the log (csv, json or xml).",                       OFFSET(log_fmt), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
213
-    {"enable_transform",  "Enables transform for computing vmaf.",                      OFFSET(enable_transform), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
214
-    {"phone_model",  "Invokes the phone model that will generate higher VMAF scores.",  OFFSET(phone_model), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
215
-    {"psnr",  "Enables computing psnr along with vmaf.",                                OFFSET(psnr), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
216
-    {"ssim",  "Enables computing ssim along with vmaf.",                                OFFSET(ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
217
-    {"ms_ssim",  "Enables computing ms-ssim along with vmaf.",                          OFFSET(ms_ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
218
+    {"model_path",  "use model='path=...'.",                                            OFFSET(model_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
219
+    {"log_path",  "Set the file path to be used to write log.",                         OFFSET(log_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
220
+    {"log_fmt",  "Set the format of the log (csv, json, xml, or sub).",                 OFFSET(log_fmt), AV_OPT_TYPE_STRING, {.str="xml"}, 0, 1, FLAGS},
221
+    {"enable_transform",  "use model='enable_transform=true'.",                         OFFSET(enable_transform), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
222
+    {"phone_model",  "use model='enable_transform=true'.",                              OFFSET(phone_model), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
223
+    {"psnr",  "use feature='name=psnr'.",                                               OFFSET(psnr), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
224
+    {"ssim",  "use feature='name=ssim'.",                                               OFFSET(ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
225
+    {"ms_ssim",  "use feature='name=ms_ssim'.",                                         OFFSET(ms_ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
226
     {"pool",  "Set the pool method to be used for computing vmaf.",                     OFFSET(pool), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
227
     {"n_threads", "Set number of threads to be used when computing vmaf.",              OFFSET(n_threads), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT_MAX, FLAGS},
228
     {"n_subsample", "Set interval for frame subsampling used when computing vmaf.",     OFFSET(n_subsample), AV_OPT_TYPE_INT, {.i64=1}, 1, UINT_MAX, FLAGS},
229
-    {"enable_conf_interval",  "Enables confidence interval.",                           OFFSET(enable_conf_interval), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
230
+    {"enable_conf_interval",  "model='enable_conf_interval=true'.",                     OFFSET(enable_conf_interval), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
231
+    {"model",  "Set the model to be used for computing vmaf.",                          OFFSET(model_cfg), AV_OPT_TYPE_STRING, {.str="version=vmaf_v0.6.1"}, 0, 1, FLAGS},
232
+    {"feature",  "Set the feature to be used for computing vmaf.",                      OFFSET(feature_cfg), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
233
     { NULL }
234
 };
235
 
236
 FRAMESYNC_DEFINE_CLASS(libvmaf, LIBVMAFContext, fs);
237
 
238
-#define read_frame_fn(type, bits)                                               \
239
-    static int read_frame_##bits##bit(float *ref_data, float *main_data,        \
240
-                                      float *temp_data, int stride, void *ctx)  \
241
-{                                                                               \
242
-    LIBVMAFContext *s = (LIBVMAFContext *) ctx;                                 \
243
-    int ret;                                                                    \
244
-    \
245
-    pthread_mutex_lock(&s->lock);                                               \
246
-    \
247
-    while (!s->frame_set && !s->eof) {                                          \
248
-        pthread_cond_wait(&s->cond, &s->lock);                                  \
249
-    }                                                                           \
250
-    \
251
-    if (s->frame_set) {                                                         \
252
-        int ref_stride = s->gref->linesize[0];                                  \
253
-        int main_stride = s->gmain->linesize[0];                                \
254
-        \
255
-        const type *ref_ptr = (const type *) s->gref->data[0];                  \
256
-        const type *main_ptr = (const type *) s->gmain->data[0];                \
257
-        \
258
-        float *ptr = ref_data;                                                  \
259
-        float factor = 1.f / (1 << (bits - 8));                                 \
260
-        \
261
-        int h = s->height;                                                      \
262
-        int w = s->width;                                                       \
263
-        \
264
-        int i,j;                                                                \
265
-        \
266
-        for (i = 0; i < h; i++) {                                               \
267
-            for ( j = 0; j < w; j++) {                                          \
268
-                ptr[j] = ref_ptr[j] * factor;                                   \
269
-            }                                                                   \
270
-            ref_ptr += ref_stride / sizeof(*ref_ptr);                           \
271
-            ptr += stride / sizeof(*ptr);                                       \
272
-        }                                                                       \
273
-        \
274
-        ptr = main_data;                                                        \
275
-        \
276
-        for (i = 0; i < h; i++) {                                               \
277
-            for (j = 0; j < w; j++) {                                           \
278
-                ptr[j] = main_ptr[j] * factor;                                  \
279
-            }                                                                   \
280
-            main_ptr += main_stride / sizeof(*main_ptr);                        \
281
-            ptr += stride / sizeof(*ptr);                                       \
282
-        }                                                                       \
283
-    }                                                                           \
284
-    \
285
-    ret = !s->frame_set;                                                        \
286
-    \
287
-    av_frame_unref(s->gref);                                                    \
288
-    av_frame_unref(s->gmain);                                                   \
289
-    s->frame_set = 0;                                                           \
290
-    \
291
-    pthread_cond_signal(&s->cond);                                              \
292
-    pthread_mutex_unlock(&s->lock);                                             \
293
-    \
294
-    if (ret) {                                                                  \
295
-        return 2;                                                               \
296
-    }                                                                           \
297
-    \
298
-    return 0;                                                                   \
299
+static enum VmafPixelFormat pix_fmt_map(enum AVPixelFormat av_pix_fmt)
300
+{
301
+    switch (av_pix_fmt) {
302
+    case AV_PIX_FMT_YUV420P:
303
+    case AV_PIX_FMT_YUV420P10LE:
304
+    case AV_PIX_FMT_YUV420P12LE:
305
+    case AV_PIX_FMT_YUV420P16LE:
306
+        return VMAF_PIX_FMT_YUV420P;
307
+    case AV_PIX_FMT_YUV422P:
308
+    case AV_PIX_FMT_YUV422P10LE:
309
+    case AV_PIX_FMT_YUV422P12LE:
310
+    case AV_PIX_FMT_YUV422P16LE:
311
+        return VMAF_PIX_FMT_YUV422P;
312
+    case AV_PIX_FMT_YUV444P:
313
+    case AV_PIX_FMT_YUV444P10LE:
314
+    case AV_PIX_FMT_YUV444P12LE:
315
+    case AV_PIX_FMT_YUV444P16LE:
316
+        return VMAF_PIX_FMT_YUV444P;
317
+    default:
318
+        return VMAF_PIX_FMT_UNKNOWN;
319
+    }
320
 }
321
 
322
-read_frame_fn(uint8_t, 8);
323
-read_frame_fn(uint16_t, 10);
324
+static int copy_picture_data(AVFrame *src, VmafPicture *dst, unsigned bpc)
325
+{
326
+    int err = vmaf_picture_alloc(dst, pix_fmt_map(src->format), bpc,
327
+                                 src->width, src->height);
328
+    if (err)
329
+        return AVERROR(ENOMEM);
330
 
331
-static void compute_vmaf_score(LIBVMAFContext *s)
332
+    for (unsigned i = 0; i < 3; i++) {
333
+        uint8_t *src_data = src->data[i];
334
+        uint8_t *dst_data = dst->data[i];
335
+        for (unsigned j = 0; j < dst->h[i]; j++) {
336
+            memcpy(dst_data, src_data, sizeof(*dst_data) * dst->w[i]);
337
+            src_data += src->linesize[i];
338
+            dst_data += dst->stride[i];
339
+        }
340
+    }
341
+
342
+    return 0;
343
+}
344
+
345
+static int do_vmaf(FFFrameSync *fs)
346
 {
347
-    int (*read_frame)(float *ref_data, float *main_data, float *temp_data,
348
-                      int stride, void *ctx);
349
-    char *format;
350
+    AVFilterContext *ctx = fs->parent;
351
+    LIBVMAFContext *s = ctx->priv;
352
+    VmafPicture pic_ref, pic_dist;
353
+    AVFrame *ref, *dist;
354
+    int err = 0;
355
 
356
-    if (s->desc->comp[0].depth <= 8) {
357
-        read_frame = read_frame_8bit;
358
-    } else {
359
-        read_frame = read_frame_10bit;
360
+    int ret = ff_framesync_dualinput_get(fs, &dist, &ref);
361
+    if (ret < 0)
362
+        return ret;
363
+    if (ctx->is_disabled || !ref)
364
+        return ff_filter_frame(ctx->outputs[0], dist);
365
+
366
+    err = copy_picture_data(ref, &pic_ref, s->bpc);
367
+    if (err) {
368
+        av_log(s, AV_LOG_ERROR, "problem during vmaf_picture_alloc.\n");
369
+        return AVERROR(ENOMEM);
370
     }
371
 
372
-    format = (char *) s->desc->name;
373
+    err = copy_picture_data(dist, &pic_dist, s->bpc);
374
+    if (err) {
375
+        av_log(s, AV_LOG_ERROR, "problem during vmaf_picture_alloc.\n");
376
+        vmaf_picture_unref(&pic_ref);
377
+        return AVERROR(ENOMEM);
378
+    }
379
 
380
-    s->error = compute_vmaf(&s->vmaf_score, format, s->width, s->height,
381
-                            read_frame, s, s->model_path, s->log_path,
382
-                            s->log_fmt, 0, 0, s->enable_transform,
383
-                            s->phone_model, s->psnr, s->ssim,
384
-                            s->ms_ssim, s->pool,
385
-                            s->n_threads, s->n_subsample, s->enable_conf_interval);
386
+    err = vmaf_read_pictures(s->vmaf, &pic_ref, &pic_dist, s->frame_cnt++);
387
+    if (err) {
388
+        av_log(s, AV_LOG_ERROR, "problem during vmaf_read_pictures.\n");
389
+        return AVERROR(EINVAL);
390
+    }
391
+
392
+    return ff_filter_frame(ctx->outputs[0], dist);
393
 }
394
 
395
-static void *call_vmaf(void *ctx)
396
+
397
+static AVDictionary **delimited_dict_parse(char *str, unsigned *cnt)
398
 {
399
-    LIBVMAFContext *s = (LIBVMAFContext *) ctx;
400
-    compute_vmaf_score(s);
401
-    if (!s->error) {
402
-        av_log(ctx, AV_LOG_INFO, "VMAF score: %f\n",s->vmaf_score);
403
-    } else {
404
-        pthread_mutex_lock(&s->lock);
405
-        pthread_cond_signal(&s->cond);
406
-        pthread_mutex_unlock(&s->lock);
407
+    AVDictionary **dict = NULL;
408
+    char *str_copy = NULL;
409
+    char *saveptr = NULL;
410
+    unsigned cnt2;
411
+    int err = 0;
412
+
413
+    if (!str)
414
+        return NULL;
415
+
416
+    cnt2 = 1;
417
+    for (char *p = str; *p; p++) {
418
+        if (*p == '|')
419
+            cnt2++;
420
     }
421
-    pthread_exit(NULL);
422
+
423
+    dict = av_calloc(cnt2, sizeof(*dict));
424
+    if (!dict)
425
+        goto fail;
426
+
427
+    str_copy = av_strdup(str);
428
+    if (!str_copy)
429
+        goto fail;
430
+
431
+    *cnt = 0;
432
+    for (unsigned i = 0; i < cnt2; i++) {
433
+        char *s = av_strtok(i == 0 ? str_copy : NULL, "|", &saveptr);
434
+        if (!s)
435
+            continue;
436
+        err = av_dict_parse_string(&dict[(*cnt)++], s, "=", ":", 0);
437
+        if (err)
438
+            goto fail;
439
+    }
440
+
441
+    av_free(str_copy);
442
+    return dict;
443
+
444
+fail:
445
+    if (dict) {
446
+        for (unsigned i = 0; i < *cnt; i++) {
447
+            if (dict[i])
448
+                av_dict_free(&dict[i]);
449
+        }
450
+        av_free(dict);
451
+    }
452
+
453
+    av_free(str_copy);
454
+    *cnt = 0;
455
     return NULL;
456
 }
457
 
458
-static int do_vmaf(FFFrameSync *fs)
459
+static int parse_features(AVFilterContext *ctx)
460
 {
461
-    AVFilterContext *ctx = fs->parent;
462
     LIBVMAFContext *s = ctx->priv;
463
-    AVFrame *master, *ref;
464
-    int ret;
465
+    AVDictionary **dict = NULL;
466
+    unsigned dict_cnt;
467
+    int err = 0;
468
 
469
-    ret = ff_framesync_dualinput_get(fs, &master, &ref);
470
-    if (ret < 0)
471
-        return ret;
472
-    if (!ref)
473
-        return ff_filter_frame(ctx->outputs[0], master);
474
+    if (!s->feature_cfg)
475
+        return 0;
476
 
477
-    pthread_mutex_lock(&s->lock);
478
+    dict = delimited_dict_parse(s->feature_cfg, &dict_cnt);
479
+    if (!dict) {
480
+        av_log(ctx, AV_LOG_ERROR,
481
+               "could not parse feature config: %s\n", s->feature_cfg);
482
+        return AVERROR(EINVAL);
483
+    }
484
 
485
-    while (s->frame_set && !s->error) {
486
-        pthread_cond_wait(&s->cond, &s->lock);
487
+    for (unsigned i = 0; i < dict_cnt; i++) {
488
+        char *feature_name = NULL;
489
+        VmafFeatureDictionary *feature_opts_dict = NULL;
490
+        AVDictionaryEntry *e = NULL;
491
+
492
+        while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
493
+            if (av_stristr(e->key, "name")) {
494
+                feature_name = e->value;
495
+                continue;
496
+            }
497
+
498
+            err = vmaf_feature_dictionary_set(&feature_opts_dict, e->key,
499
+                                              e->value);
500
+            if (err) {
501
+                av_log(ctx, AV_LOG_ERROR,
502
+                       "could not set feature option: %s.%s=%s\n",
503
+                       feature_name, e->key, e->value);
504
+                goto exit;
505
+            }
506
+        }
507
+
508
+        err = vmaf_use_feature(s->vmaf, feature_name, feature_opts_dict);
509
+        if (err) {
510
+            av_log(ctx, AV_LOG_ERROR,
511
+                   "problem during vmaf_use_feature: %s\n", feature_name);
512
+            goto exit;
513
+        }
514
     }
515
 
516
-    if (s->error) {
517
+exit:
518
+    for (unsigned i = 0; i < dict_cnt; i++) {
519
+        if (dict[i])
520
+            av_dict_free(&dict[i]);
521
+    }
522
+    av_free(dict);
523
+    return err;
524
+}
525
+
526
+static int parse_models(AVFilterContext *ctx)
527
+{
528
+    LIBVMAFContext *s = ctx->priv;
529
+    AVDictionary **dict;
530
+    unsigned dict_cnt;
531
+    int err = 0;
532
+
533
+    if (!s->model_cfg) return 0;
534
+
535
+    dict_cnt = 0;
536
+    dict = delimited_dict_parse(s->model_cfg, &dict_cnt);
537
+    if (!dict) {
538
         av_log(ctx, AV_LOG_ERROR,
539
-               "libvmaf encountered an error, check log for details\n");
540
-        pthread_mutex_unlock(&s->lock);
541
+               "could not parse model config: %s\n", s->model_cfg);
542
         return AVERROR(EINVAL);
543
     }
544
 
545
-    av_frame_ref(s->gref, ref);
546
-    av_frame_ref(s->gmain, master);
547
+    s->model_cnt = dict_cnt;
548
+    s->model = av_calloc(s->model_cnt, sizeof(*s->model));
549
+    if (!s->model)
550
+        return AVERROR(ENOMEM);
551
 
552
-    s->frame_set = 1;
553
+    for (unsigned i = 0; i < dict_cnt; i++) {
554
+        VmafModelConfig model_cfg = { 0 };
555
+        AVDictionaryEntry *e = NULL;
556
+        char *version = NULL;
557
+        char  *path = NULL;
558
 
559
-    pthread_cond_signal(&s->cond);
560
-    pthread_mutex_unlock(&s->lock);
561
+        while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
562
+            if (av_stristr(e->key, "disable_clip")) {
563
+                model_cfg.flags |= av_stristr(e->value, "true") ?
564
+                    VMAF_MODEL_FLAG_DISABLE_CLIP : 0;
565
+                continue;
566
+            }
567
 
568
-    return ff_filter_frame(ctx->outputs[0], master);
569
+            if (av_stristr(e->key, "enable_transform")) {
570
+                model_cfg.flags |= av_stristr(e->value, "true") ?
571
+                    VMAF_MODEL_FLAG_ENABLE_TRANSFORM : 0;
572
+                continue;
573
+            }
574
+
575
+            if (av_stristr(e->key, "name")) {
576
+                model_cfg.name = e->value;
577
+                continue;
578
+            }
579
+
580
+            if (av_stristr(e->key, "version")) {
581
+                version = e->value;
582
+                continue;
583
+            }
584
+
585
+            if (av_stristr(e->key, "path")) {
586
+                path = e->value;
587
+                continue;
588
+            }
589
+        }
590
+
591
+        if (version) {
592
+            err = vmaf_model_load(&s->model[i], &model_cfg, version);
593
+            if (err) {
594
+                av_log(ctx, AV_LOG_ERROR,
595
+                       "could not load libvmaf model with version: %s\n",
596
+                       version);
597
+                goto exit;
598
+            }
599
+        }
600
+
601
+        if (path && !s->model[i]) {
602
+            err = vmaf_model_load_from_path(&s->model[i], &model_cfg, path);
603
+            if (err) {
604
+                av_log(ctx, AV_LOG_ERROR,
605
+                       "could not load libvmaf model with path: %s\n",
606
+                       path);
607
+                goto exit;
608
+            }
609
+        }
610
+
611
+        if (!s->model[i]) {
612
+            av_log(ctx, AV_LOG_ERROR,
613
+                   "could not load libvmaf model with config: %s\n",
614
+                   s->model_cfg);
615
+            goto exit;
616
+        }
617
+
618
+        while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
619
+            VmafFeatureDictionary *feature_opts_dict = NULL;
620
+            char *feature_opt = NULL;
621
+
622
+            char *feature_name = av_strtok(e->key, ".", &feature_opt);
623
+            if (!feature_opt)
624
+                continue;
625
+
626
+            err = vmaf_feature_dictionary_set(&feature_opts_dict,
627
+                                              feature_opt, e->value);
628
+            if (err) {
629
+                av_log(ctx, AV_LOG_ERROR,
630
+                       "could not set feature option: %s.%s=%s\n",
631
+                       feature_name, feature_opt, e->value);
632
+                err = AVERROR(EINVAL);
633
+                goto exit;
634
+            }
635
+
636
+            err = vmaf_model_feature_overload(s->model[i], feature_name,
637
+                                              feature_opts_dict);
638
+            if (err) {
639
+                av_log(ctx, AV_LOG_ERROR,
640
+                       "could not overload feature: %s\n", feature_name);
641
+                err = AVERROR(EINVAL);
642
+                goto exit;
643
+            }
644
+        }
645
+    }
646
+
647
+    for (unsigned i = 0; i < s->model_cnt; i++) {
648
+        err = vmaf_use_features_from_model(s->vmaf, s->model[i]);
649
+        if (err) {
650
+            av_log(ctx, AV_LOG_ERROR,
651
+                   "problem during vmaf_use_features_from_model\n");
652
+            err = AVERROR(EINVAL);
653
+            goto exit;
654
+        }
655
+    }
656
+
657
+exit:
658
+    for (unsigned i = 0; i < dict_cnt; i++) {
659
+        if (dict[i])
660
+            av_dict_free(&dict[i]);
661
+    }
662
+    av_free(dict);
663
+    return err;
664
 }
665
 
666
+static enum VmafLogLevel log_level_map(int log_level)
667
+{
668
+    switch (log_level) {
669
+    case AV_LOG_QUIET:
670
+        return VMAF_LOG_LEVEL_NONE;
671
+    case AV_LOG_ERROR:
672
+        return VMAF_LOG_LEVEL_ERROR;
673
+    case AV_LOG_WARNING:
674
+        return VMAF_LOG_LEVEL_WARNING;
675
+    case AV_LOG_INFO:
676
+        return VMAF_LOG_LEVEL_INFO;
677
+    case AV_LOG_DEBUG:
678
+        return VMAF_LOG_LEVEL_DEBUG;
679
+    default:
680
+        return VMAF_LOG_LEVEL_INFO;
681
+    }
682
+}
683
+
684
+static int parse_deprecated_options(AVFilterContext *ctx)
685
+{
686
+    LIBVMAFContext *s = ctx->priv;
687
+    VmafModel *model = NULL;
688
+    VmafModelCollection *model_collection = NULL;
689
+    enum VmafModelFlags flags = VMAF_MODEL_FLAGS_DEFAULT;
690
+    int err = 0;
691
+
692
+    VmafModelConfig model_cfg = {
693
+        .name = "vmaf",
694
+        .flags = flags,
695
+    };
696
+
697
+    if (s->enable_transform || s->phone_model)
698
+        flags |= VMAF_MODEL_FLAG_ENABLE_TRANSFORM;
699
+
700
+    if (!s->model_path)
701
+        goto extra_metrics_only;
702
+
703
+    if (s->enable_conf_interval) {
704
+        err = vmaf_model_collection_load_from_path(&model, &model_collection,
705
+                                                   &model_cfg, s->model_path);
706
+        if (err) {
707
+            av_log(ctx, AV_LOG_ERROR,
708
+                   "problem loading model file: %s\n", s->model_path);
709
+            goto exit;
710
+        }
711
+
712
+        err = vmaf_use_features_from_model_collection(s->vmaf, model_collection);
713
+        if (err) {
714
+            av_log(ctx, AV_LOG_ERROR,
715
+                   "problem loading feature extractors from model file: %s\n",
716
+                   s->model_path);
717
+            goto exit;
718
+        }
719
+    } else {
720
+        err = vmaf_model_load_from_path(&model, &model_cfg, s->model_path);
721
+        if (err) {
722
+                av_log(ctx, AV_LOG_ERROR,
723
+                      "problem loading model file: %s\n", s->model_path);
724
+            goto exit;
725
+        }
726
+        err = vmaf_use_features_from_model(s->vmaf, model);
727
+        if (err) {
728
+            av_log(ctx, AV_LOG_ERROR,
729
+                   "problem loading feature extractors from model file: %s\n",
730
+                   s->model_path);
731
+            goto exit;
732
+        }
733
+    }
734
+
735
+extra_metrics_only:
736
+    if (s->psnr) {
737
+        VmafFeatureDictionary *d = NULL;
738
+        vmaf_feature_dictionary_set(&d, "enable_chroma", "false");
739
+
740
+        err = vmaf_use_feature(s->vmaf, "psnr", d);
741
+        if (err) {
742
+            av_log(ctx, AV_LOG_ERROR,
743
+                   "problem loading feature extractor: psnr\n");
744
+            goto exit;
745
+        }
746
+    }
747
+
748
+    if (s->ssim) {
749
+        err = vmaf_use_feature(s->vmaf, "float_ssim", NULL);
750
+        if (err) {
751
+            av_log(ctx, AV_LOG_ERROR,
752
+                   "problem loading feature extractor: ssim\n");
753
+            goto exit;
754
+        }
755
+    }
756
+
757
+    if (s->ms_ssim) {
758
+        err = vmaf_use_feature(s->vmaf, "float_ms_ssim", NULL);
759
+        if (err) {
760
+            av_log(ctx, AV_LOG_ERROR,
761
+                   "problem loading feature extractor: ms_ssim\n");
762
+            goto exit;
763
+        }
764
+    }
765
+
766
+exit:
767
+    return err;
768
+}
769
+
770
 static av_cold int init(AVFilterContext *ctx)
771
 {
772
     LIBVMAFContext *s = ctx->priv;
773
+    int err = 0;
774
 
775
-    s->gref = av_frame_alloc();
776
-    s->gmain = av_frame_alloc();
777
-    if (!s->gref || !s->gmain)
778
-        return AVERROR(ENOMEM);
779
+    VmafConfiguration cfg = {
780
+        .log_level = log_level_map(av_log_get_level()),
781
+        .n_subsample = s->n_subsample,
782
+        .n_threads = s->n_threads,
783
+    };
784
 
785
-    s->error = 0;
786
+    err = vmaf_init(&s->vmaf, cfg);
787
+    if (err)
788
+        return AVERROR(EINVAL);
789
 
790
-    s->vmaf_thread_created = 0;
791
-    pthread_mutex_init(&s->lock, NULL);
792
-    pthread_cond_init (&s->cond, NULL);
793
+    err = parse_deprecated_options(ctx);
794
+    if (err)
795
+        return err;
796
 
797
+    err = parse_models(ctx);
798
+    if (err)
799
+        return err;
800
+
801
+    err = parse_features(ctx);
802
+    if (err)
803
+        return err;
804
+
805
     s->fs.on_event = do_vmaf;
806
     return 0;
807
 }
808
@@ -265,31 +554,36 @@ static int config_input_ref(AVFilterLink *inlink)
809
 
810
 static int config_input_ref(AVFilterLink *inlink)
811
 {
812
-    AVFilterContext *ctx  = inlink->dst;
813
+    AVFilterContext *ctx = inlink->dst;
814
     LIBVMAFContext *s = ctx->priv;
815
-    int th;
816
+    const AVPixFmtDescriptor *desc;
817
+    int err = 0;
818
 
819
-    if (ctx->inputs[0]->w != ctx->inputs[1]->w ||
820
-        ctx->inputs[0]->h != ctx->inputs[1]->h) {
821
-        av_log(ctx, AV_LOG_ERROR, "Width and height of input videos must be same.\n");
822
-        return AVERROR(EINVAL);
823
+    if (ctx->inputs[0]->w != ctx->inputs[1]->w) {
824
+        av_log(ctx, AV_LOG_ERROR, "input width must match.\n");
825
+        err |= AVERROR(EINVAL);
826
     }
827
     if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
828
         av_log(ctx, AV_LOG_ERROR, "Inputs must be of same pixel format.\n");
829
         return AVERROR(EINVAL);
830
     }
831
 
832
-    s->desc = av_pix_fmt_desc_get(inlink->format);
833
-    s->width = ctx->inputs[0]->w;
834
-    s->height = ctx->inputs[0]->h;
835
+    if (ctx->inputs[0]->h != ctx->inputs[1]->h) {
836
+        av_log(ctx, AV_LOG_ERROR, "input height must match.\n");
837
+        err |= AVERROR(EINVAL);
838
+    }
839
 
840
-    th = pthread_create(&s->vmaf_thread, NULL, call_vmaf, (void *) s);
841
-    if (th) {
842
-        av_log(ctx, AV_LOG_ERROR, "Thread creation failed.\n");
843
-        return AVERROR(EINVAL);
844
+    if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
845
+        av_log(ctx, AV_LOG_ERROR, "input pix_fmt must match.\n");
846
+        err |= AVERROR(EINVAL);
847
     }
848
-    s->vmaf_thread_created = 1;
849
 
850
+    if (err)
851
+        return err;
852
+
853
+    desc = av_pix_fmt_desc_get(inlink->format);
854
+    s->bpc = desc->comp[0].depth;
855
+
856
     return 0;
857
 }
858
 
859
@@ -320,28 +614,80 @@ static int activate(AVFilterContext *ctx)
860
     return ff_framesync_activate(&s->fs);
861
 }
862
 
863
+static enum VmafOutputFormat log_fmt_map(const char *log_fmt)
864
+{
865
+    if (log_fmt) {
866
+        if (av_stristr(log_fmt, "xml"))
867
+            return VMAF_OUTPUT_FORMAT_XML;
868
+        if (av_stristr(log_fmt, "json"))
869
+            return VMAF_OUTPUT_FORMAT_JSON;
870
+        if (av_stristr(log_fmt, "csv"))
871
+            return VMAF_OUTPUT_FORMAT_CSV;
872
+        if (av_stristr(log_fmt, "sub"))
873
+            return VMAF_OUTPUT_FORMAT_SUB;
874
+    }
875
+
876
+    return VMAF_OUTPUT_FORMAT_XML;
877
+}
878
+
879
+static enum VmafPoolingMethod pool_method_map(const char *pool_method)
880
+{
881
+    if (pool_method) {
882
+        if (av_stristr(pool_method, "min"))
883
+            return VMAF_POOL_METHOD_MIN;
884
+        if (av_stristr(pool_method, "mean"))
885
+            return VMAF_POOL_METHOD_MEAN;
886
+        if (av_stristr(pool_method, "harmonic_mean"))
887
+            return VMAF_POOL_METHOD_HARMONIC_MEAN;
888
+    }
889
+
890
+    return VMAF_POOL_METHOD_MEAN;
891
+}
892
+
893
 static av_cold void uninit(AVFilterContext *ctx)
894
 {
895
     LIBVMAFContext *s = ctx->priv;
896
+    int err = 0;
897
 
898
     ff_framesync_uninit(&s->fs);
899
 
900
-    pthread_mutex_lock(&s->lock);
901
-    s->eof = 1;
902
-    pthread_cond_signal(&s->cond);
903
-    pthread_mutex_unlock(&s->lock);
904
+    if (!s->frame_cnt)
905
+        goto clean_up;
906
 
907
-    if (s->vmaf_thread_created)
908
-    {
909
-        pthread_join(s->vmaf_thread, NULL);
910
-        s->vmaf_thread_created = 0;
911
+    err = vmaf_read_pictures(s->vmaf, NULL, NULL, 0);
912
+    if (err) {
913
+        av_log(ctx, AV_LOG_ERROR,
914
+               "problem flushing libvmaf context.\n");
915
     }
916
 
917
-    av_frame_free(&s->gref);
918
-    av_frame_free(&s->gmain);
919
+    for (unsigned i = 0; i < s->model_cnt; i++) {
920
+        double vmaf_score;
921
+        err = vmaf_score_pooled(s->vmaf, s->model[i], pool_method_map(s->pool),
922
+                                &vmaf_score, 0, s->frame_cnt - 1);
923
+        if (err) {
924
+            av_log(ctx, AV_LOG_ERROR,
925
+                   "problem getting pooled vmaf score.\n");
926
+        }
927
 
928
-    pthread_mutex_destroy(&s->lock);
929
-    pthread_cond_destroy(&s->cond);
930
+        av_log(ctx, AV_LOG_INFO, "VMAF score: %f\n", vmaf_score);
931
+    }
932
+
933
+    if (s->vmaf) {
934
+        if (s->log_path && !err)
935
+            vmaf_write_output(s->vmaf, s->log_path, log_fmt_map(s->log_fmt));
936
+    }
937
+
938
+clean_up:
939
+    if (s->model) {
940
+        for (unsigned i = 0; i < s->model_cnt; i++) {
941
+            if (s->model[i])
942
+                vmaf_model_destroy(s->model[i]);
943
+        }
944
+        av_free(s->model);
945
+    }
946
+
947
+    if (s->vmaf)
948
+        vmaf_close(s->vmaf);
949
 }
950
 
951
 static const AVFilterPad libvmaf_inputs[] = {
(-)b/multimedia/ffmpeg/pkg-plist (-23 / +28 lines)
Lines 12-17 include/libavcodec/codec_desc.h Link Here
12
include/libavcodec/codec_id.h
12
include/libavcodec/codec_id.h
13
include/libavcodec/codec_par.h
13
include/libavcodec/codec_par.h
14
include/libavcodec/d3d11va.h
14
include/libavcodec/d3d11va.h
15
include/libavcodec/defs.h
15
include/libavcodec/dirac.h
16
include/libavcodec/dirac.h
16
include/libavcodec/dv_profile.h
17
include/libavcodec/dv_profile.h
17
include/libavcodec/dxva2.h
18
include/libavcodec/dxva2.h
Lines 19-41 include/libavcodec/jni.h Link Here
19
include/libavcodec/mediacodec.h
20
include/libavcodec/mediacodec.h
20
include/libavcodec/packet.h
21
include/libavcodec/packet.h
21
include/libavcodec/qsv.h
22
include/libavcodec/qsv.h
22
include/libavcodec/vaapi.h
23
include/libavcodec/vdpau.h
23
include/libavcodec/vdpau.h
24
include/libavcodec/version.h
24
include/libavcodec/version.h
25
include/libavcodec/version_major.h
25
include/libavcodec/videotoolbox.h
26
include/libavcodec/videotoolbox.h
26
include/libavcodec/vorbis_parser.h
27
include/libavcodec/vorbis_parser.h
27
include/libavcodec/xvmc.h
28
include/libavcodec/xvmc.h
28
include/libavdevice/avdevice.h
29
include/libavdevice/avdevice.h
29
include/libavdevice/version.h
30
include/libavdevice/version.h
31
include/libavdevice/version_major.h
30
include/libavfilter/avfilter.h
32
include/libavfilter/avfilter.h
31
include/libavfilter/buffersink.h
33
include/libavfilter/buffersink.h
32
include/libavfilter/buffersrc.h
34
include/libavfilter/buffersrc.h
33
include/libavfilter/version.h
35
include/libavfilter/version.h
36
include/libavfilter/version_major.h
34
include/libavformat/avformat.h
37
include/libavformat/avformat.h
35
include/libavformat/avio.h
38
include/libavformat/avio.h
36
include/libavformat/version.h
39
include/libavformat/version.h
37
include/libavresample/avresample.h
40
include/libavformat/version_major.h
38
include/libavresample/version.h
39
include/libavutil/adler32.h
41
include/libavutil/adler32.h
40
include/libavutil/aes.h
42
include/libavutil/aes.h
41
include/libavutil/aes_ctr.h
43
include/libavutil/aes_ctr.h
Lines 56-62 include/libavutil/channel_layout.h Link Here
56
include/libavutil/common.h
58
include/libavutil/common.h
57
include/libavutil/cpu.h
59
include/libavutil/cpu.h
58
include/libavutil/crc.h
60
include/libavutil/crc.h
61
include/libavutil/csp.h
59
include/libavutil/des.h
62
include/libavutil/des.h
63
include/libavutil/detection_bbox.h
60
include/libavutil/dict.h
64
include/libavutil/dict.h
61
include/libavutil/display.h
65
include/libavutil/display.h
62
include/libavutil/dovi_meta.h
66
include/libavutil/dovi_meta.h
Lines 71-76 include/libavutil/film_grain_params.h Link Here
71
include/libavutil/frame.h
75
include/libavutil/frame.h
72
include/libavutil/hash.h
76
include/libavutil/hash.h
73
include/libavutil/hdr_dynamic_metadata.h
77
include/libavutil/hdr_dynamic_metadata.h
78
include/libavutil/hdr_dynamic_vivid_metadata.h
74
include/libavutil/hmac.h
79
include/libavutil/hmac.h
75
include/libavutil/hwcontext.h
80
include/libavutil/hwcontext.h
76
include/libavutil/hwcontext_cuda.h
81
include/libavutil/hwcontext_cuda.h
Lines 120-166 include/libavutil/timestamp.h Link Here
120
include/libavutil/tree.h
125
include/libavutil/tree.h
121
include/libavutil/twofish.h
126
include/libavutil/twofish.h
122
include/libavutil/tx.h
127
include/libavutil/tx.h
128
include/libavutil/uuid.h
123
include/libavutil/version.h
129
include/libavutil/version.h
124
include/libavutil/video_enc_params.h
130
include/libavutil/video_enc_params.h
125
include/libavutil/xtea.h
131
include/libavutil/xtea.h
126
include/libpostproc/postprocess.h
132
include/libpostproc/postprocess.h
127
include/libpostproc/version.h
133
include/libpostproc/version.h
134
include/libpostproc/version_major.h
128
include/libswresample/swresample.h
135
include/libswresample/swresample.h
129
include/libswresample/version.h
136
include/libswresample/version.h
137
include/libswresample/version_major.h
130
include/libswscale/swscale.h
138
include/libswscale/swscale.h
131
include/libswscale/version.h
139
include/libswscale/version.h
140
include/libswscale/version_major.h
132
lib/libavcodec.so
141
lib/libavcodec.so
133
lib/libavcodec.so.58
142
lib/libavcodec.so.59
134
lib/libavcodec.so.58.134.100
143
lib/libavcodec.so.59.37.100
135
lib/libavdevice.so
144
lib/libavdevice.so
136
lib/libavdevice.so.58
145
lib/libavdevice.so.59
137
lib/libavdevice.so.58.13.100
146
lib/libavdevice.so.59.7.100
138
lib/libavfilter.so
147
lib/libavfilter.so
139
lib/libavfilter.so.7
148
lib/libavfilter.so.8
140
lib/libavfilter.so.7.110.100
149
lib/libavfilter.so.8.44.100
141
lib/libavformat.so
150
lib/libavformat.so
142
lib/libavformat.so.58
151
lib/libavformat.so.59
143
lib/libavformat.so.58.76.100
152
lib/libavformat.so.59.27.100
144
lib/libavresample.so
145
lib/libavresample.so.4
146
lib/libavresample.so.4.0.0
147
lib/libavutil.so
153
lib/libavutil.so
148
lib/libavutil.so.56
154
lib/libavutil.so.57
149
lib/libavutil.so.56.70.100
155
lib/libavutil.so.57.28.100
150
lib/libpostproc.so
156
lib/libpostproc.so
151
lib/libpostproc.so.55
157
lib/libpostproc.so.56
152
lib/libpostproc.so.55.9.100
158
lib/libpostproc.so.56.6.100
153
lib/libswresample.so
159
lib/libswresample.so
154
lib/libswresample.so.3
160
lib/libswresample.so.4
155
lib/libswresample.so.3.9.100
161
lib/libswresample.so.4.7.100
156
lib/libswscale.so
162
lib/libswscale.so
157
lib/libswscale.so.5
163
lib/libswscale.so.6
158
lib/libswscale.so.5.9.100
164
lib/libswscale.so.6.7.100
159
libdata/pkgconfig/libavcodec.pc
165
libdata/pkgconfig/libavcodec.pc
160
libdata/pkgconfig/libavdevice.pc
166
libdata/pkgconfig/libavdevice.pc
161
libdata/pkgconfig/libavfilter.pc
167
libdata/pkgconfig/libavfilter.pc
162
libdata/pkgconfig/libavformat.pc
168
libdata/pkgconfig/libavformat.pc
163
libdata/pkgconfig/libavresample.pc
164
libdata/pkgconfig/libavutil.pc
169
libdata/pkgconfig/libavutil.pc
165
libdata/pkgconfig/libpostproc.pc
170
libdata/pkgconfig/libpostproc.pc
166
libdata/pkgconfig/libswresample.pc
171
libdata/pkgconfig/libswresample.pc

Return to bug 261302