libswscale里面实现了各种图像格式的转换,以及图像大小的缩放功能。又做了相应指令集的优化,因此速度比自己写的格式转化C代码效率高一些。因为像素格式转换 和 图像大小缩放都是逐点计算的,各像素点之间没有依赖性,因此这两个操作可以合并一起来做。
1. 配置 ./configure --enable-shared
2. 编译 make。等待一阵子,就会生成libswscale.so等
3. 准备文件:
在工程下建立ffmpeg/lib 和 ffmpeg/include目录。
把libswscale.so, libavutil.so, libavformat.so拷贝到ffmpeg/lib目录;
把ffmpeg libavformat目录下 avformat.h, avio.h, version.h
libavutil目录下 attributes.h, avutil.h, common.h, infolat.h, log.h, macros.h, mathematics.h, mem.h,
pixdesc.h, pixfmt.h, rational.h version.h
libswscale目录下 swscale.h version.h
分别拷贝到相对应的目录结构中。
4. 配置eclipse.
在Properties-> C/C++ Build -> GCC C++ Linker -> Libraries 里面添加swscale, avutil, avformat三个.so。注意顺序,顺序不对会有链接错误。
在Properties-> C/C++ Build -> GCC C++ Linker -> Libraries path里面添加步骤3中这三个.so存放的文件路径,否则linker找不到他们。
5. swscale有三个接口函数。
1. sws_getContext, 配置swscale的输入输出,缩放方法等参数;
2. sws_scale, 真正的做事函数,完成格式转换,大小缩放;
3. sws_freeContext,释放空间。
写成三个函数的好处在于多帧重复以上转换时,配置工作只用做一次,减少循环内真正做事函数的负载。
6. sws_getContext函数:
参数1-3设置输入帧格式,图像宽,高,像素格式,图像宽高是像素级别,640x480的图像不管像素格式是什么样。
参数4-6设置输出帧格式,和前三个参数意义一样。
参数flags设置用哪种缩放算法。
最后三个参数都设置为NULL。
返回值是成功申请的SwsContext结构指针,或者失败的NULL指针。
7. sws_scale函数:
SwsContext *c 是sws_getContext成功申请到的SwsContext结构指针;
const uint8_t *const srcSlice[]是输入图像各分量数据起始指针。
例如有3个分量的YUV420P格式,srcSlice[4] = {Y_data, U_data, V_data, NULL};
有1个分量的YUYV422格式 srcSlice[4] = {data, NULL, NULL, NULL};
因为有可能有ARGB四个通道,所以srcSlice, srcStride一般设为4维,用不到的就设为NULL/0;
const int srcStride[]是输入图像各分量一行数据量。stride = width*Bpp
例如有3个分量的YUV420P格式,srcStride[4] = {width, width/2, width/2, 0};
有1个分量的YUYV422格式 srcStride[4] = {2*width, 0, 0, 0};
对于RGB24 srcStride[4] = {3*width, 0, 0, 0};
int srcSliceY 当前处理区域在图像中的起始纵坐标,
int srcSliceH 当前处理区域的高度。
srcSliceY 和 srcSliceH定义出图像中的一个条带,
这样做的目的可能是为了并行化,可以将整帧图像划分成N个条带,送给N个线程并行处理,加快速度。
如果不考虑这种并行性,srcSliceY = 0, srcSliceH = srcHeight。
uint8_t *const dst[]是输出图像各分量数据起始指针。它的定义原则和srcSlice一样。
const int dstStride[]是输出图像各分量一行数据量。它的定义原则和srcStride一样。
输出:在输出图像中做了多少行,跟srcSliceH相对应。
这个函数用起来很简单,注意srcSlice,srcStride。
8. sws_freeContext函数。
不用说了。
9. ffmpeg里面 libswscale/swscale-test.c文件里有使用例程可以参考。
10. 执行效率:
博客 http://www.cnblogs.com/acloud/archive/2011/10/29/sws_scale.html 测试了图像缩放算法的性能。
(没有验证,只是把结论总结如下)
1. 追求性能,但不明确是放大还是缩小的情况下用 Fast_BiLinear算法;
2. 明确是缩小,用Point算法;
3. 明确是方法,用Area算法;
4. 不计速度,追求画质,用SINC算法。
5. FFmpeg代码里面缺省的缩放算法是BiCubic