【问题标题】:How to crop AvFrame using ffmpeg's functions如何使用 ffmpeg 的函数裁剪 AvFrame
【发布时间】:2016-06-29 22:48:05
【问题描述】:

我想使用 ffmpeg 的功能(如 av_picture_crop 或 vf_crop)来裁剪图片,而不是命令行实用程序。

有人知道怎么做吗?

你有这个函数的源代码吗?

【问题讨论】:

    标签: ffmpeg


    【解决方案1】:

    av_picture_crop()deprecated

    要使用vf_crop,请使用libavfilter 中的bufferbuffersink 过滤器:

    #include "libavfilter/avfilter.h"
    
    static AVFrame *crop_frame(const AVFrame *in, int left, int top, int right, int bottom)
    {
        AVFilterContext *buffersink_ctx;
        AVFilterContext *buffersrc_ctx;
        AVFilterGraph *filter_graph = avfilter_graph_alloc();
        AVFrame *f = av_frame_alloc();
        AVFilterInOut *inputs = NULL, *outputs = NULL;
        char args[512];
        int ret;
        snprintf(args, sizeof(args),
                 "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];"
                 "[in]crop=x=%d:y=%d:out_w=in_w-x-%d:out_h=in_h-y-%d[out];"
                 "[out]buffersink",
                 frame->width, frame->height, frame->format,
                 left, top, right, bottom);
    
        ret = avfilter_graph_parse2(filter_graph, args, &inputs, &outputs);
        if (ret < 0) return NULL;
        assert(inputs == NULL && outputs == NULL);
        ret = avfilter_graph_config(filter_graph, NULL);
        if (ret < 0) return NULL;
    
        buffersrc_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffer_0");
        buffersink_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffersink_2");
        assert(buffersrc_ctx != NULL);
        assert(buffersink_ctx != NULL);
    
        av_frame_ref(f, in);
        ret = av_buffersrc_add_frame(buffersrc_ctx, f);
        if (ret < 0) return NULL;
        ret = av_buffersink_get_frame(buffersink_ctx, f);
        if (ret < 0) return NULL;
    
        avfilter_graph_free(&filter_graph);
    
        return f;
    }
    

    不要忘记使用 av_frame_free() 取消引用返回(裁剪)的帧。输入帧的数据是不变的,所以如果你在这个功能之外不需要它,你还需要av_frame_free()输入帧。

    如果您打算裁剪许多帧,请尝试在帧之间保留过滤器图,并仅在帧大小/格式发生变化时重置(或重新创建)它。我将由您来决定如何做到这一点。

    【讨论】:

    • 非常感谢 Ronald,我以某种方式使用 av_picture_crop() 处理了它,但正如您所说,这是一个已弃用的函数,我将使用 vf_crop 函数在您的源代码中尝试它
    猜你喜欢
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 2017-04-29
    • 2018-06-10
    • 2014-08-14
    相关资源
    最近更新 更多