2016-06-29 4 views

ответ

2

av_picture_crop() является deprecated.

Для использования vf_crop используйте buffer и buffersink фильтры в 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; 
} 

Не забудьте UNREF возвращенного (croppped) кадр с помощью av_frame_free(). Данные входного кадра нетронуты, поэтому, если вы не нуждаетесь в нем помимо этой функции, вам необходимо также ввести av_frame_free() входной кадр.

Если вы намерены обрезать много кадров, попробуйте сохранить график фильтра между кадрами и только сбросить его (или воссоздать) при изменении размера и формата фрейма. Я оставляю это для вас, чтобы понять, как это сделать.

+0

Большое спасибо Рональду, я как-то обработал его с помощью av_picture_crop(), но, как вы сказали, это устаревшая функция, я попробую использовать ее с исходным кодом с помощью функции vf_crop – eruslu

Смежные вопросы