一、命令裁切
ffmpeg -pixel_format nv12 -f rawvideo -video_size 240x320 -i nv12_240x320.yuv -vf crop=120:160 -pix_fmt nv12 nv12_120x160.yuv
二、代码裁切,将240x320大小的数据裁切为120x160大小的数据
#include <iostream>
#include <fstream>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
#include "libavutil/opt.h"
#include "libavfilter/avfilter.h"
#include "libavfilter/buffersrc.h"
#include "libavfilter/buffersink.h"
#include "libavutil/imgutils.h"
};
/*
srcBuffer:源yuv数据
srcWidth:宽
srcHeight:高
dstBuffer:目标buffer
dstWidth:目标宽
dstHeight:目标高
offestX:起始x坐标
offsetY:起始y坐标
format:YUV数据的格式,例如AV_PIX_FMT_NV12 AV_PIX_FMT_NV21 AV_PIX_FMT_YUV420P
*/
int32_t Crop(uint8_t* srcBuffer, uint32_t srcWidth, uint32_t srcHeight,
uint8_t* dstBuffer, uint32_t dstWidth, uint32_t dstWidth,
uint32_t offsetX, uint32_t offsetY, AVPixelFormat format) {
// 创建AVFrame
AVFrame* srcFrame = av_frame_alloc();
srcFrame->width = srcWidth;
srcFrame->height = srcHeight;
srcFrame->format = format;
// 填充AVFrame
av_image_fill_arrays(srcFrame->data, srcFrame->linesize, srcBuffer, format, srcWidth, srcHeight, 1);
AVFrame* dstFrame = av_frame_alloc();
// 进行crop
AVFilterGraph* filterGraph = avfilter_graph_alloc();
char args[512] = "";
snprintf(args, sizeof(args),
"buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=1/1[in];" // Parsed_buffer_0
"[in]crop=x=%d:y=%d:out_w=%d:out_h=%d[out];" // Parsed_crop_1
"[out]buffersink", // Parsed_buffersink_2
srcWidth, srcHeight, format,
offsetX, offsetY, dstWidth, dstHeight);
AVFilterInOut* inputs = NULL;
AVFilterInOut* outputs = NULL;
avfilter_graph_parse2(filterGraph, args, &inputs, &outputs);
avfilter_graph_config(filterGraph, NULL);
AVFilterContext* srcFilterCtx = avfilter_graph_get_filter(filterGraph, "Parsed_buffer_0");
AVFilterContext* sinkFilterCtx = avfilter_graph_get_filter(filterGraph, "Parsed_buffersink_2");
dstFrame = av_frame_clone(srcFrame);
av_buffersrc_add_frame(srcFilterCtx, dstFrame);
av_buffersink_get_frame(sinkFilterCtx, dstFrame);
avfilter_graph_free(&filterGraph);
// 获取crop完成后的数据
avpicture_layout((AVPicture*)dstFrame, format, dstWidth, dstHeight, dstBuffer,
avpicture_get_size(format, dstWidth, dstHeight));
av_frame_free(&srcFrame);
av_frame_free(&dstFrame);
return 0;
}
int main(void) {
std::ifstream fin("nv21_240x320.yuv", std::ios::binary | std::ios::in);
std::ofstream fout("nv21_120x160.yuv", std::ios::binary | std::ios::out);
uint32_t width = 240;
uint32_t height = 320;
uint32_t size = width * height * 3 / 2;
uint8_t* src_data = new uint8_t[size];
uint8_t* dest_data = new uint8_t[size / 4];
while (!fin.eof()) {
fin.read((char*)src_data, size);
Crop(src_data, width, height, dest_data, width / 2, height / 2, 0, 0, AV_PIX_FMT_NV21);
fout.write((char*)dest_data, size / 4);
}
delete[] src_data;
delete[] dest_data;
fout.close();
fin.close();
getchar();
return 0;
}