设为首页 - 加入收藏 焦点技术网
热搜:java
当前位置:首页 >

调用ffmpeg的 libswscale.so实现图像格式转换及大小缩放

导读:libswscale里面实现了各种图像格式的转换,以及图像大小的缩放功能。又做了相应指令集的优化,因此速度比自己写的格式转化C代码效率高一些。因为像素格式转换 和 图像大小缩放都是逐点计算的,各像素点之间没有依赖性,因此这两个操作可以合并一起来做。1. 配置 ./configure --enable-shared2. 编译 make。等待一阵子,就会生成libswscale.so等3. 准备文件:...。。。

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

 

(编辑: huibailingyu)

网友评论
相关文章