Skip to content

GSoC 2024, Libvmaf V0.1#2

Open
yigithanyigit wants to merge 20 commits intomasterfrom
libvmaf-v0.1
Open

GSoC 2024, Libvmaf V0.1#2
yigithanyigit wants to merge 20 commits intomasterfrom
libvmaf-v0.1

Conversation

@yigithanyigit
Copy link
Owner

@yigithanyigit yigithanyigit commented Aug 21, 2024

This version directly propagates to AVFrame->metadata . However there are some offset in the frame indexes and doesn't finish at frame index supposed to finish.

For example, Lets say I have an input that 30 fps. If I just pass 2 seconds of that file with -t 2 command, filter should take 60 frames, but in current situation it takes 60 + first vmaf calculated index frames (in my case that was 13. In other words first vmaf calculated and triggered the callback function at 13th frame, 60 + 13 = 73). This problem looks like related to ff_filter_frame function.
I think it should only be called inside the do_vmaf function, but I couldn't find a way that works like that.

Update

I think that sync loss happens because of the framesync. My guess is framesync generating(requesting) frames again when it loss the sync. I am still investigating.

Update 2

Those extra frames actually looks like not re-requested frames. They are actual frames of the input. Program doesn't obeying the command that given (-t 2) and giving extra frames that shouldn't give.

Tested with:
./ffmpeg_g -loglevel info -i images/reference.mp4 -i images/distorted.mp4 -t 2 -lavfi psnr='stats_file=-:stats_version=2' -f null -"
And
./ffmpeg_g -loglevel info -i images/reference.mp4 -i images/distorted.mp4 -t 1 -lavfi libvmaf='n_threads=30:feature=name=psnr|name=ciede:metadata_handler=name=vmaf|name=psnr_y|name=ciede2000' -f null -

Update 3

It works perfectly fine If I don't give -t command. Instead of I trimmed the files and I gave like that. Right now it works like supposed to be.

It also works with complex filtergraphs
./ffmpeg_g -loglevel debug -i images/refer ence.mp4 -i images/distorted.mp4 -filter_complex "[0:v]trim=duration=1, setpts=PTS-STARTPTS[ref];[1:v]trim=duration=1, setpts=PTS-STARTPTS[dist];[ref][dist]libvmaf" -f null -

{"n_subsample", "Set interval for frame subsampling used when computing vmaf.", OFFSET(n_subsample), AV_OPT_TYPE_INT, {.i64=1}, 1, UINT_MAX, FLAGS},
{"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},
{"feature", "Set the feature to be used for computing vmaf.", OFFSET(feature_cfg), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
{"metadata_handler", "Set the feature to be propagated as metadata.", OFFSET(metadata_feature_cfg), AV_OPT_TYPE_STRING, {.str="name=vmaf"}, 0, 1, FLAGS},
Copy link

@kylophone kylophone Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to have a bool option to enable metadata writing for all features/models. If you do it in the way you've written, only one feature can be written as metadata. If you do it in the way I've suggested, when the option is set, you can register metadata callbacks for everything.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

individual feature names as well as model names should both be available during init.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually users can give metadata handlers like this libvmaf='n_threads=30:feature=name=psnr|name=ciede:metadata_handler=name=vmaf|name=psnr_y|name=ciede2000' But obviously this makes hard to count metadata handlers, if someone enters wrong handler it still register that metadata handler.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. I still think a bool is nicer, since you don't have to repeat yourself for each option.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

individual feature names as well as model names should both be available during init.

I couldn't find a list of available feature names/models. Can you provide a link for me please?
Thanks

metadata_cfg->data = s->cb;
metadata_cfg->callback = &set_meta;

err = vmaf_register_metadata_handler(s->vmaf, *metadata_cfg);
Copy link

@kylophone kylophone Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anywhere we're using these new libvmaf metadata apis, we'll want to detect if they are available and guard with macros. See CONFIG_LIBVMAF_CUDA_FILTER for an example. This macro is generated during the configure stage.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this is compatibility with older libvmaf versions. fyi, these new apis are not part of a libvmaf release yet.

Copy link
Owner Author

@yigithanyigit yigithanyigit Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anywhere we're using these new libvmaf metadata apis, we'll want to detect if they are available and guard with macros. See CONFIG_LIBVMAF_CUDA_FILTER for an example. This macro is generated during the configure stage.

Should those changes need to own functions like libvmaf_cuda or putting guard macros like I did is fine?

unsigned frame_number;
unsigned propagated_handlers_cnt;
struct FrameList *next;
} FrameList;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could use something like av_fifo here instead?

https://ffmpeg.org/doxygen/trunk/group__lavu__fifo.html

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes! Thats what I was looking for!

Copy link
Owner Author

@yigithanyigit yigithanyigit Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kylophone I make some experiments with av_fifo and that might be not a good idea. Vmaf can send frames any order, If we use FIFO then we should make some operations to send them in order to next filter.

{"n_subsample", "Set interval for frame subsampling used when computing vmaf.", OFFSET(n_subsample), AV_OPT_TYPE_INT, {.i64=1}, 1, UINT_MAX, FLAGS},
{"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},
{"feature", "Set the feature to be used for computing vmaf.", OFFSET(feature_cfg), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
{"metadata_handler", "Set the feature to be propagated as metadata.", OFFSET(metadata_feature_cfg), AV_OPT_TYPE_STRING, {.str="name=vmaf"}, 0, 1, FLAGS},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. I still think a bool is nicer, since you don't have to repeat yourself for each option.

int n_subsample;
char *model_cfg;
#if CONFIG_LIBVMAF_METADATA_FILTER
char *feature_cfg;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feature_cfg should not be inside here

{"n_subsample", "Set interval for frame subsampling used when computing vmaf.", OFFSET(n_subsample), AV_OPT_TYPE_INT, {.i64=1}, 1, UINT_MAX, FLAGS},
{"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},
{"feature", "Set the feature to be used for computing vmaf.", OFFSET(feature_cfg), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
{"metadata_handler", "Set the feature to be propagated as metadata.", OFFSET(metadata_feature_cfg), AV_OPT_TYPE_STRING, {.str="name=vmaf"}, 0, 1, FLAGS},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This option needs a guard too

};
#endif

#if CONFIG_LIBVMAF_METADATA_FILTER

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unneeded. Not sure if this was intentional, or just a copy/paste error.

Copy link
Owner Author

@yigithanyigit yigithanyigit Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is copy/paste error. Fixed.

#if CONFIG_LIBVMAF_METADATA_FILTER
const AVFilter ff_vf_libvmaf_metadata = {
.name = "libvmaf_cuda",
.name = "libvmaf_metadata",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this extra filter at all. The only thing we need is to guard the option in the normal "libvmaf" filter.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't understand, could you explain more? You want me do something like this; libvmaf_filter_deps="libvmaf libvmaf-metadata"
instead of making
libvmaf_filter_deps="libvmaf"
libvmaf_metadata_filter_deps="libvmaf libvmaf_metadata" in the configure ? If answer is yes, in this way libvmaf filter doesn't work if not it's latest commit.

I couldn't find another way to do this in configuration stage without defining a new filter. If I not define a filter that macro (CONFIG_LIBVMAF_METADATA_FILTER) doesn't generate. I also tried with VMAF_VERSION but since it's string I can't do in macro stage.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my mistake, somehow I missed VMAF_VERSION_MAJOR/MINOR/PATCH. Fixed in those commits.

3ad9e15
364b219

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants