如何使用ffmpeg的功能裁剪AvFrame [英] How to crop AvFrame using ffmpeg's functions
问题描述
我想使用ffmpeg的函数(如av_picture_crop或vf_crop)裁剪图片,而不是命令行实用程序。
I wanna crop a picture by using the ffmpeg's functions(like av_picture_crop or vf_crop), not command line utility.
有没有人知道如何做?
Is there any one knows how to do it?
你有这个函数的源代码?
Do you have the source code for this function?
推荐答案
av_picture_crop()
是已弃用。
要使用 vf_crop
,请使用缓冲区
和 buffersink
libavfilter中的过滤器:
To use vf_crop
, use the buffer
and buffersink
filters in libavfilter:
#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;
}
不要忘记使用<$ c取消返回(裁剪)的框架$ C> av_frame_free()。输入框架数据不变,因此如果您不需要超出此功能,则需要 av_frame_free()
输入框架。
Don't forget to unref the returned (croppped) frame using av_frame_free()
. The input frame data is untouched so if you don't need it beyond this function, you need to av_frame_free()
the input frame also.
如果您打算裁剪多个帧,请尝试在帧之间保留过滤器图形,并且只有在帧大小/格式更改时才重置(或重新创建)。我把它留给你来弄清楚如何做到这一点。
If you intend to crop many frames, try to retain the filter graph between frames and only reset it (or recreate it) when the frame size/format changes. I'm leaving it up to you to figure out how to do that.
这篇关于如何使用ffmpeg的功能裁剪AvFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!