Filter 如何在ffmpeg psnr滤波器中添加参考电影(计算psnr)

Filter 如何在ffmpeg psnr滤波器中添加参考电影(计算psnr),filter,ffmpeg,Filter,Ffmpeg,我只是想了解如何在ffmpeg的编码中使用psnr滤波器 我已遵守以下文件中规定的代码: 但错误消息返回给我: Input pad "reference" with type video of the filter instance "psnr" of psnr not connected to any source 我在代码中搜索psnr过滤器,但没有太多关于它的信息。有人能帮上忙吗?您正在使用avfilter\u graph\u create\u filter()创建一个过滤器图而不是过滤

我只是想了解如何在ffmpeg的编码中使用psnr滤波器

我已遵守以下文件中规定的代码:

但错误消息返回给我:

Input pad "reference" with type video of the filter instance "psnr" of psnr not connected to any source

我在代码中搜索psnr过滤器,但没有太多关于它的信息。有人能帮上忙吗?

您正在使用
avfilter\u graph\u create\u filter()
创建一个过滤器图而不是过滤器。使用
avfilter\u graph\u parse2()
创建整个过滤器图

过滤图与您在ffmpeg命令行中输入的-Filter_复合体相同。例如,请参见以下示例,说明您将使用什么字符串作为输入来获取电影元素:

ffmpeg -filter_complex 'movie=file.mpg[in];movie=ref.mpg[ref];[in][ref]psnr[out]' -map '[out]' -f null -
在解析过滤图之前,不要忘记调用
avfilter\u register\u all()
av\u register\u all()
,否则电影元素还不会被注册

完整的示例代码:

#include <assert.h>

#include "libavcodec/avcodec.h"
#include "libavfilter/avfilter.h"
#include "libavfilter/buffersink.h"
#include "libavformat/avformat.h"

int main() {
    AVFilterGraph *filter_graph;
    AVFilterInOut *inputs = NULL, *outputs = NULL;
    AVFilterContext *buffersink_ctx;
    AVFrame *f;

    avfilter_register_all();
    av_register_all();

    filter_graph = avfilter_graph_alloc();
    int ret;

    ret = avfilter_graph_parse2(filter_graph,
                                "movie=file.mpg[in];"
                                "movie=ref.mpg[ref];"
                                "[in][ref]psnr[out];"
                                "[out]buffersink",
                                &inputs, &outputs);
    if (ret < 0) return ret;
    ret = avfilter_graph_config(filter_graph, NULL);
    if (ret < 0) return ret;
    buffersink_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffersink_3");
    assert(buffersink_ctx != NULL);
    f = av_frame_alloc();

    for (;;) {
        ret = av_buffersink_get_frame(buffersink_ctx, f);
        if (ret < 0) break;
        av_frame_unref(f);
    }

    av_frame_free(&f);
    avfilter_graph_free(&filter_graph);

    return 0;
}

要获得打印到stdout(序列范围的PSNR)的最终值,可以使用
av\u log\u set\u callback()
设置日志回调,并适当地解析字符串。

使用
avfilter\u graph\u create\u filter()
创建一个过滤图而不是过滤器。使用
avfilter\u graph\u parse2()
创建整个过滤器图

过滤图与您在ffmpeg命令行中输入的-Filter_复合体相同。例如,请参见以下示例,说明您将使用什么字符串作为输入来获取电影元素:

ffmpeg -filter_complex 'movie=file.mpg[in];movie=ref.mpg[ref];[in][ref]psnr[out]' -map '[out]' -f null -
在解析过滤图之前,不要忘记调用
avfilter\u register\u all()
av\u register\u all()
,否则电影元素还不会被注册

完整的示例代码:

#include <assert.h>

#include "libavcodec/avcodec.h"
#include "libavfilter/avfilter.h"
#include "libavfilter/buffersink.h"
#include "libavformat/avformat.h"

int main() {
    AVFilterGraph *filter_graph;
    AVFilterInOut *inputs = NULL, *outputs = NULL;
    AVFilterContext *buffersink_ctx;
    AVFrame *f;

    avfilter_register_all();
    av_register_all();

    filter_graph = avfilter_graph_alloc();
    int ret;

    ret = avfilter_graph_parse2(filter_graph,
                                "movie=file.mpg[in];"
                                "movie=ref.mpg[ref];"
                                "[in][ref]psnr[out];"
                                "[out]buffersink",
                                &inputs, &outputs);
    if (ret < 0) return ret;
    ret = avfilter_graph_config(filter_graph, NULL);
    if (ret < 0) return ret;
    buffersink_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffersink_3");
    assert(buffersink_ctx != NULL);
    f = av_frame_alloc();

    for (;;) {
        ret = av_buffersink_get_frame(buffersink_ctx, f);
        if (ret < 0) break;
        av_frame_unref(f);
    }

    av_frame_free(&f);
    avfilter_graph_free(&filter_graph);

    return 0;
}

要获得打印到stdout(序列范围的PSNR)的最终值,可以使用
av_log\u set_callback()
设置日志回调,并适当地解析字符串。

感谢您的回复,我想问的另一件事是关于SSIM,可以选择哪些参数,就像PSNRlavfi.SSIM.dB.y中的lavfi.PSNR.PSNR.y,谢谢你的回复,我想问的另一件事是关于ssim,可以选择哪些参数,就像PSNRlavfi.ssim.dB.y中的lavfi.psnr.psnr.y,lavfi.ssim.dB.U,lavfi.ssim.dB.V和lavfi.ssim.dB.dB中的lavfi.psnr.y一样
static void parse_psnr(AVFrame *f) {
    AVDictionary *metadata = av_frame_get_metadata(f);
    float psnr[4];

#define parse(a, b) \
    sscanf(av_dict_get(metadata, a, NULL, 0)->value, "%f", &b)

    parse("lavfi.psnr.psnr.y", psnr[0]);
    parse("lavfi.psnr.psnr.u", psnr[1]);
    parse("lavfi.psnr.psnr.v", psnr[2]);
    parse("lavfi.psnr.psnr_avg", psnr[3]);

}