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

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

时间: 2024-10-21 15:56:44

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

ASP.NET下调用ffmpeg与mencoder实现视频转换截屏

最近要做一个视频播放的系统,用到了ffmpeg和mencoder两个工具,查了一些资料,发现这方面的资料还挺多的,但是就是乱了一点,我自己从头整理了一下,和大家分享一下: 1.ffmpeg实现视频(avi,wmv等格式)转换为flv格式: /// <summary> /// 转换视频为flv /// </summary> /// <param name="fileName">上传视频文件的路径(原文件)</param> /// <p

最简单的基于FFmpeg的libswscale的示例

本文记录一个基于FFmpeg的libswscale的示例.Libswscale里面实现了各种图像像素格式的转换,以及图像大小缩放功能.而且libswscale还做了相应指令集的优化,因此它的转换效率比自己写的C语言的转换效率高很多. 流程 简单的初始化方法 Libswscale使用起来很方便,最主要的函数只有3个:(1)       sws_getContext():使用参数初始化SwsContext结构体.(2)       sws_scale():转换一帧图像.(3)       sws_f

最简单的基于FFmpeg的libswscale的示例附件:测试图片生成工具

本文记录一个自己写的简单的测试图片生成工具:simplest_pic_gen.该工具可以生成视频测试时候常用的RGB/YUV格式的测试图片.下面简单介绍一下这些测试图片的生成函数.这里有一点需要注意:查看生成的图片需要使用RGB/YUV播放器. 灰阶测试图 亮度取值为16-235的灰阶测试图下面这张图是一张灰阶测试图的示例.这张图的分辨率是1280x720,像素格式是YUV420P,亮度的取值范围是16-235,一共包含了10级的灰度.最左边的灰度竖条的YUV取值为(16,128,128),最右

在visual studio 2010中调用ffmpeg

本文来自:http://blog.sina.com.cn/s/blog_4178f4bf01018wqh.html 最近几天一直在折腾ffmpeg,在网上也查了许多资料,费了不少劲,现在在这里和大家分享一下. 一.准备工作 本来是想自己在windows下编译ffmpeg生成lib.dll等库文件的,但是折腾好久总是出错,于是果断放弃.幸好网上已经有了编译好的版本,可以拿过来直接用,网址为http://ffmpeg.zeranoe.com/builds/.我们需要的是32-bit Builds (

史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)

ffmpeg.exe是大名鼎鼎的视频处理软件,以命令行参数形式运行.网上也有很多关于ffmpeg的资料介绍.但是在用C#做实际开发时,却遇到了几个问题及注意事项,比如如何无损处理视频?如何在转换格式的同时添加水印,以提升处理效率?,ffmpeg的版本应该选择什么版本?.今天史林峰将用实战的方式来探索C#操作ffmpeg的奥秘. 关于ffmpeg的使用及其参数命令,这里就不做过多介绍了.主要以项目实战中为主. 因工作需要,笔者手头有近300部短视频需要处理,在网上找了不少工具,虽然能用,但是用起来

.NET 2.0 调用FFMPEG

.NET 2.0 调用FFMPEG,并异步读取输出信息的代码... 1 public void ConvertVideo() 2 { 3           Process p = new Process();//建立外部调用线程 4           p.StartInfo.FileName = @"c:"ffmpeg.exe";//要调用外部程序的绝对路径 5           p.StartInfo.Arguments = "-i XXXXXXXXXXXX

CentOS 下通过 JavaCPP 调用 FFMPEG

1. Java 与 FFMPEG FFMPEG 是一个广泛用于媒体处理的库,在Java的世界里,处理视频的能力相当弱,于是有很大需求需要Java 调用 FFMPEG. Java 调用C 的方式有很多,可以用最原始的JNI方式,也可以JNA方式,还可以是命令行. 采用命令行的方式比较简单,不过有很大局限性,尤其是涉及到 视频的处理和分析的时候,比如要取出某个packet,然后进行处理. 这里介绍的是用JavaCPP 调用 ffmpeg 库的方式,而不是命令行模式. JavaCPP的源码在这里:ht

bash shell,调用ffmpeg定期截图

#!/bin/bash #获取当前目录中所有m3u8文件,并 var=$(ls |grep '.m3u8'|cut -d '.' -f1) #死循环 while [ 1 = 1 ] do #循环每个文件 for stream in $var do #获取当前最新视频文件 ts=$(ls -t|grep "$stream") for file in $ts do #存储M3U8文件文件名作为图片文件名,截图为220*120,截取第一帧,存储在当前目录的screen文件夹 img=$(ls

Ubuntu系统中QtCreate调用ffmpeg

创建QtCreate项目 在项目的pro文件中,添加如下代码(假设需要调用ffmpeg的libavformat库文件) INCLUDEPATH += /usr/local/ffmpeg/include/ LIBS += -L/usr/local/ffmpeg/lib/ -lavformat 在项目的cpp文件中添加需要调用的ffmpeg头文件(假设需要引用avformat.h头文件) extern "C" { #include "libavformat/avformat.h&