使用ffmpeg视频编码过程中踩的一个坑

时间:2022-09-27 22:23:45
       今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的。以下是不对的编码结果:
                                                    使用ffmpeg视频编码过程中踩的一个坑
       使用ffmpeg做视频编码过程中,首先要新建数据帧,并为数据帧分配对应内存,以便于保存图像数据,为数据帧分配内存须要用到av_image_alloc()这个函数,该函数将依据传入的图像宽、高、图像格式、数据对齐基数等參数进行内存分配。
                                    使用ffmpeg视频编码过程中踩的一个坑
       这当中有一个參数可能会让人迷惑,那就是数据对齐基数这个參数该设置多少?顺便说说为什么要数据对齐,之所以要对齐,主要是为了提高数据的读取效率。假设參考ffmpeg提供的相关demo,发现里面通常会将其设置为32,于是在我的项目里,我也想当然的将其设置为32,于是就有了上图所看到的效果,開始还以为是採集的原始数据有问题,以为自己没吃透yv12数据格式,想来想去,程序改动来改动去始终不对。 
     
       假设原始数据分辨率为480*480,那么y分量行宽为480,uv分量行宽均为240,假设数据对齐基数设置为32,那么ffmpeg分配的图像帧数据行宽将为32的倍数,对于宽度为480的数据,y分量的行宽为480,uv分量行宽为256,可是实际数据的uv分量行宽仅仅有240,这样一行就多出来16个字节,依次拷贝的时候数据就错位了,这样编码后得到的结果也就出错了。假设设置为16,那么y分量行宽为480,uv分量行宽为240,与採集的原始数据yuv各分量行宽吻合,拷贝时数据正确,视频编码后的文件也将是正确的。也就是说要依据自己实际数据的分辨率来反算数据对齐基数,不能想当然的设置,计算方法:首先数据行宽要能整除该基数,同一时候该对齐基数需是2的n次方,当然该值越小,比方设置为1,那肯定没问题了,可是数据读取效率要低些。下图为正确的视频编码结果。
                                                    使用ffmpeg视频编码过程中踩的一个坑