总结此次出现错误原因是:提供给avcodec_encode_video2函数的frame数据的yuv格式和编码器所能编码的yuv数据格式不符。
项目之前使用ffmpeg完成了将yuv数据保存成视频文件的功能,最近需要添加一项新功能:满足条件时裁剪视频画面大小(不同于压缩画面大小)。网上查找资料之后知道可以用filter的crop功能来实现。因此在源代码基础上添加filter相关代码。完成之后发现之前没有问题的avcodec_encode_video2函数报错。
avcodec_encode_video2函数如下:
avcodec_encode_video2(c, pkt, m_StrmVideo->frame, &got_packet);
源frame颜色空间格式为AV_PIX_FMT_YUYV422,需要转换成AV_PIX_FMT_YUV420P。filter可以替换原来代码中的sws_scale方法进行视频大小和颜色空间变换。
调试后发现frame的格式format是1,即AV_PIX_FMT_YUYV422,另外编码器c codec_id为AV_CODEC_ID_MPEG4,而AV_CODEC_ID_MPEG4只能编码AV_PIX_FMT_YUV420P格式数据,不能编码AV_PIX_FMT_YUYV422格式数据。所以函数崩溃。最后发现是buffersrc_ctx源中错误的指定了pix_fmt=AV_PIX_FMT_YUV420P,而应该指定成pix_fmt=AV_PIX_FMT_YUYV422。
以下是filter相关代码。参考http://www.zhimengzhe.com/linux/249541.html