从AVFrame-ffmpeg复制矩形区域

从AVFrame-ffmpeg复制矩形区域,ffmpeg,rgb,libav,Ffmpeg,Rgb,Libav,我试图拉出一个AVFrame的矩形区域,并且已经开始使用一个函数来实现这个功能。我只对使用格式为PIX_FMT_RGB24的AVFrames感兴趣。我可能会在这里重新发明一点轮子,所以如果已经有一个功能来做这件事,请跳进来。到目前为止,我的函数如下所示: AVFrame * getRGBsection(AVFrame *pFrameRGB, const int start_x, const int start_y, const int w, const int h) { AVFrame *pF

我试图拉出一个AVFrame的矩形区域,并且已经开始使用一个函数来实现这个功能。我只对使用格式为PIX_FMT_RGB24的AVFrames感兴趣。我可能会在这里重新发明一点轮子,所以如果已经有一个功能来做这件事,请跳进来。到目前为止,我的函数如下所示:

AVFrame * getRGBsection(AVFrame *pFrameRGB, const int start_x, const int start_y, const int w, const int h) {

AVFrame *pFrameSect;
int numBytes;
uint8_t *mb_buffer;

pFrameSect = avcodec_alloc_frame();
numBytes = avpicture_get_size(PIX_FMT_RGB24, w, h);
mb_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture *) pFrameSect, mb_buffer, PIX_FMT_RGB24, w, h);

int curY, curX, i = 0;
for (curY = start_y ; curY < (start_y + h); curY++) {

    for (curX = start_x; curX < (start_x + w); curX++) {

        int curIndex = curX * 3 + curY * pFrameRGB->linesize[0];

        pFrameSect->data[0][i] = pFrameRGB->data[0][curIndex];
        pFrameSect->data[0][i + 1] = pFrameRGB->data[0][curIndex + 1];
        pFrameSect->data[0][i + 2] = pFrameRGB->data[0][curIndex + 2];

        i += 3;

    }

}

return pFrameSect;

}
AVFrame*getRGBsection(AVFrame*pFrameRGB,常量int start\u x,常量int start\u y,常量int w,常量int h){
AVFrame*pFrameSect;
整数单位;
uint8_t*mb_缓冲区;
pFrameSect=avcodec_alloc_frame();
numBytes=avpicture\u get\u size(PIX\u FMT\u RGB24,w,h);
mb_buffer=(uint8_t*)av_malloc(numBytes*sizeof(uint8_t));
avpicture_填充((avpicture*)pFrameSect,mb_缓冲区,PIX_FMT_RGB24,w,h);
int curY,curX,i=0;
对于(curY=start\u y;curY<(start\u y+h);curY++){
对于(curX=start\u x;curX<(start\u x+w);curX++){
int curIndex=curX*3+curY*pFrameRGB->linesize[0];
pframessect->data[0][i]=pFrameRGB->data[0][curIndex];
pFrameSect->数据[0][i+1]=pFrameRGB->数据[0][curIndex+1];
pFrameSect->data[0][i+2]=pFrameRGB->data[0][curIndex+2];
i+=3;
}
}
返回pFrameSect;
}
当我从(0,0)(我想)开始时,该函数似乎可以工作,但当我移动到图像中的其他位置时,它输出的颜色与应该存在的颜色相似,但不正确。我想我离这里很近,有人能提供指导吗?

  • 有两种选择

  • 用户视频过滤器(vf_裁剪)。(filtering_video.c提供了实用地使用crop的示例)
  • imgconvert.c中的函数av_picture_crop()。此功能不完整,但您可以修改它以供使用
此代码适用于我(仅适用于RGB24)

#包括
// .....
//左上角
常数int crop_左=500;
常数int crop_top=500;
//输出宽度、高度
const int crop_width=300;
作物高度常数=200;
AVFrame*RGB24图片;
AVFrame*输出;
/// .... 初始化。。。。
const int one_pixel=av_image_get_linesize(像素数FMT_RGB24,1,0);
const int src_line_size=av_image_get_line size(像素点、源点、宽度、0);
const int copy_line_size=av_image_get_line size(像素点、调频图、RGB24、裁剪宽度,0);
用于(int h=作物顶部;h<作物顶部+作物高度;++h)
{
无符号字符*src=rgb24picture->data[0]+src_line_size*h+1_像素*crop_left;
无符号字符*dst=输出->数据[0]+复制行大小*(h-裁剪顶部);
memcpy(dst、src、拷贝行大小);
}

ffmpeg中提供的vf\u裁剪过滤器是否正是用于此目的?你还想用你自己的方法吗?使用过滤器会很好,但从同一帧中获取多个区域似乎很复杂,还是我错了?看看docs/example/filtering\u video.c中的示例,我认为这并不难。
#include <libavutil/imgutils.h>

// .....
// left, top
const int crop_left = 500;
const int crop_top = 500;

// output width, height
const int crop_width = 300;
const int crop_height = 200;

AVFrame * rgb24picure;
AVFrame * output;
/// .... initialize ....

const int one_pixel = av_image_get_linesize(PIX_FMT_RGB24, 1, 0);
const int src_line_size = av_image_get_linesize(PIX_FMT_RGB24, source_width, 0);
const int copy_line_size = av_image_get_linesize(PIX_FMT_RGB24, crop_width, 0);

for (int h = crop_top; h < crop_top + crop_height; ++h)
{
    unsigned char * src = rgb24picure->data[0] + src_line_size * h + one_pixel * crop_left;
    unsigned char * dst = output->data[0] + copy_line_size * (h - crop_top);
    memcpy(dst, src, copy_line_size);
}