71 #define OFFSET(x) offsetof(LIBVMAFContext, x)
72 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
75 {
"model_path",
"Set the model to be used for computing vmaf.",
OFFSET(model_path),
AV_OPT_TYPE_STRING, {.str=
"/usr/share/model/vmaf_v0.6.1.json"}, 0, 1,
FLAGS},
79 {
"phone_model",
"Invokes the phone model that will generate higher VMAF scores.",
OFFSET(phone_model),
AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1,
FLAGS},
84 {
"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},
85 {
"n_subsample",
"Set interval for frame subsampling used when computing vmaf.",
OFFSET(n_subsample),
AV_OPT_TYPE_INT, {.i64=1}, 1, UINT_MAX,
FLAGS},
92 #define read_frame_fn(type, bits) \
93 static int read_frame_##bits##bit(float *ref_data, float *main_data, \
94 float *temp_data, int stride, void *ctx) \
96 LIBVMAFContext *s = (LIBVMAFContext *) ctx; \
99 pthread_mutex_lock(&s->lock); \
101 while (!s->frame_set && !s->eof) { \
102 pthread_cond_wait(&s->cond, &s->lock); \
105 if (s->frame_set) { \
106 int ref_stride = s->gref->linesize[0]; \
107 int main_stride = s->gmain->linesize[0]; \
109 const type *ref_ptr = (const type *) s->gref->data[0]; \
110 const type *main_ptr = (const type *) s->gmain->data[0]; \
112 float *ptr = ref_data; \
113 float factor = 1.f / (1 << (bits - 8)); \
120 for (i = 0; i < h; i++) { \
121 for ( j = 0; j < w; j++) { \
122 ptr[j] = ref_ptr[j] * factor; \
124 ref_ptr += ref_stride / sizeof(*ref_ptr); \
125 ptr += stride / sizeof(*ptr); \
130 for (i = 0; i < h; i++) { \
131 for (j = 0; j < w; j++) { \
132 ptr[j] = main_ptr[j] * factor; \
134 main_ptr += main_stride / sizeof(*main_ptr); \
135 ptr += stride / sizeof(*ptr); \
139 ret = !s->frame_set; \
141 av_frame_unref(s->gref); \
142 av_frame_unref(s->gmain); \
145 pthread_cond_signal(&s->cond); \
146 pthread_mutex_unlock(&s->lock); \
160 int (*
read_frame)(
float *ref_data,
float *main_data,
float *temp_data,
164 if (
s->desc->comp[0].depth <= 8) {
170 format = (
char *)
s->desc->name;
172 s->error = compute_vmaf(&
s->vmaf_score,
format,
s->width,
s->height,
174 s->log_fmt, 0, 0,
s->enable_transform,
175 s->phone_model,
s->psnr,
s->ssim,
177 s->n_threads,
s->n_subsample,
s->enable_conf_interval);
210 while (
s->frame_set && !
s->error) {
216 "libvmaf encountered an error, check log for details\n");
238 if (!
s->gref || !
s->gmain)
243 s->vmaf_thread_created = 0;
272 if (
ctx->inputs[0]->w !=
ctx->inputs[1]->w ||
273 ctx->inputs[0]->h !=
ctx->inputs[1]->h) {
277 if (
ctx->inputs[0]->format !=
ctx->inputs[1]->format) {
283 s->width =
ctx->inputs[0]->w;
284 s->height =
ctx->inputs[0]->h;
291 s->vmaf_thread_created = 1;
306 outlink->
w = mainlink->
w;
307 outlink->
h = mainlink->
h;
334 if (
s->vmaf_thread_created)
337 s->vmaf_thread_created = 0;
371 .preinit = libvmaf_framesync_preinit,
377 .priv_class = &libvmaf_class,
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
static const char *const format[]
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Main libavfilter public API header.
#define fs(width, name, subs,...)
static double psnr(double d)
#define pthread_mutex_lock(a)
#define pthread_mutex_unlock(a)
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_YUV420P10LE
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_YUV422P10LE
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
@ AV_PIX_FMT_YUV444P10LE
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Describe the class of an AVClass context structure.
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0,...
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
const char * name
Pad name.
const char * name
Filter name.
This structure describes decoded (raw) audio or video data.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
const AVPixFmtDescriptor * desc
static int ref[MAX_W *MAX_W]
static int read_frame(AVFilterContext *ctx, FPSContext *s, AVFilterLink *inlink, AVFilterLink *outlink)
FRAMESYNC_DEFINE_CLASS(libvmaf, LIBVMAFContext, fs)
static const AVFilterPad libvmaf_inputs[]
static int do_vmaf(FFFrameSync *fs)
static int query_formats(AVFilterContext *ctx)
#define read_frame_fn(type, bits)
static int config_input_ref(AVFilterLink *inlink)
static const AVOption libvmaf_options[]
static void compute_vmaf_score(LIBVMAFContext *s)
static int activate(AVFilterContext *ctx)
static av_cold int init(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
static int config_output(AVFilterLink *outlink)
static void * call_vmaf(void *ctx)
static const AVFilterPad libvmaf_outputs[]