ffmpeg的API函数用法 :sws_scale函数的用法-具体应用
移植ffmpeg过程中,遇到swscale的用法问题,所以查到这篇文章。文章虽然已经过去很长时间,但是还有颇多可以借鉴之处。谢谢“咕咕钟。
转自:http://guguclock.blogspot.com/2009/12/ffmpeg-swscale.html
如果想将某个PixelFormat转换至另一个PixelFormat,例如,将YUV420P转换成YUYV422,或是想变换图大小,都可以使用swscale达成。
其中,PixelFormat 的列表在 libavutil/pixfmt.h 內定义。
swscale的用法可以参考libswscale/swscale-example.c的sample code。主要function有三个
sws_getContext()
sws_scale()
sws_freeContext()
其中,我们可以把sws_getContext() 看成初始化函数,把sws_freeContext()看成结束函数。这两个函数分別在起始及结束各执行一次即可。
真正主要的函数,是sws_scale()。
sws_getContext() 的宣告如下
SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int dstW, int dstH, enum PixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
总共有十个参数,其中,较重要的是前七个;
前三个参数分別代表 source 的宽、高及PixelFormat;
四到六个参数分別代表 destination 的宽、高及PixelFormat;
第七个参数则代表要使用哪种scale的方法;此参数可用的方法可在 libswscale/swscale.h 内找到。
最后三个参数,如无使用,可以都填上NULL。
sws_getContext会回传一个SwsContext struct,我们可以把这个struct 看成是个 handler,之后的sws_scale和sws_freeContext皆会用到。
以下是一个sws_getContext的简单例子:
struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(in_width, in_height, PIX_FMT_YUV420P,
out_width, out_height, PIX_FMT_YUV420P, SWS_POINT,
NULL, NULL, NULL);
一开始,我们宣告img_convert_ctx 为指向 SwsContext 的一个 pointer;接着,我们将 sws_getContext 的回传值賦予给img_convert_ctx。
注意sws_getContext的参数;in_width及in_height分別代表 source 的宽及高,out_width及out_height分別代表转换后的宽与高;input 和 output 的 PixelFormat 皆为 YUV420P;使用SWS_POINT的scale方法。
初始化完成后,接着就要进行主要的 scale 动作;我们透过 sws_scale() 完成。sws_scale() 的宣告如下
int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[])
總共有七个参数;
第一个参数即是由 sws_getContext 所取得的参数。
第二个 src 及第六个 dst 分別指向input 和 output 的 buffer。
第三个 srcStride 及第七 个 dstStride 分別指向 input 及 output 的 stride;如果不知道什么是 stride,姑且可以先把它看成是每一列的 byte 数。
第四个srcSliceY,就注解的意思来看,是指第一列要处理的位置;这里我是从头处理,所以直接填0。想知道更详细说明的人,可以参考 swscale.h 的注解。
第五个srcSliceH指的是 source slice 的高度。
举一个例子如下
sws_scale(img_convert_ctx, inbuf, inlinesize, 0, in_height, outbuf, outlinesize);
这里应该比较好懂,可以参考上面的参数说明。
最后,全部处理完后,需呼叫sws_freeContext() 结束。用法很简单,把sws_getContext 取得的参数填入即可。如下
sws_freeContext(img_convert_ctx);
最后再整理一次,要使用swscale,只要使用 sws_getContext() 进行初始化、sws_scale() 进行主要转换、sws_freeContext() 结束,即可完成全部动作。
以下为一个简单的范例程式,可从foreman.yuv内取出第一张图,转换大小后存成另一张图。
=====================================================================================
/*
* 需设定 SRCFILE 及 DSTFILE, 长宽等咨询
* 需 link libswscale
* 主要有三个 function
* sws_getContext() 是 initial 用, sws_freeContext() 是结束用
* sws_scale() 是主要运作的 function
*预设只会转换第一张 YUV, 如果要转换整个文档, 可以把 Decoding loop 的注解拿掉
*/
#include "libswscale/swscale.h"
#define SRCFILE "foreman_cif.yuv"
#define DSTFILE "out.yuv"
int main()
{
// 设定原始 YUV 的长宽
const int in_width = 352;
const int in_height = 288;
// 设定目的 YUV 的长宽
const int out_width = 640;
const int out_height = 480;
const int read_size = in_width * in_height * 3 / 2;
const int write_size = out_width * out_height * 3 / 2;
struct SwsContext *img_convert_ctx;
uint8_t *inbuf[4];
uint8_t *outbuf[4];
int inlinesize[4] = {in_width, in_width/2, in_width/2, 0};
int outlinesize[4] = {out_width, out_width/2, out_width/2, 0};
uint8_t in[352*288*3>>1];
uint8_t out[640*480*3>>1];
FILE *fin = fopen(SRCFILE, "rb");
FILE *fout = fopen(DSTFILE, "wb");
if(fin == NULL) {
printf("open input file %s error.\n", SRCFILE);
return -1;
}
if(fout == NULL) {
printf("open output file %s error.\n", DSTFILE);
return -1;
}
inbuf[0] = malloc(in_width*in_height);
inbuf[1] = malloc(in_width*in_height>>2);
inbuf[2] = malloc(in_width*in_height>>2);
inbuf[3] = NULL;
outbuf[0] = malloc(out_width*out_height);
outbuf[1] = malloc(out_width*out_height>>2);
outbuf[2] = malloc(out_width*out_height>>2);
outbuf[3] = NULL;
// ********* Initialize software scaling *********
// ********* sws_getContext **********************
img_convert_ctx = sws_getContext(in_width, in_height, PIX_FMT_YUV420P,
out_width, out_height, PIX_FMT_YUV420P, SWS_POINT,
NULL, NULL, NULL);
if(img_convert_ctx == NULL) {
fprintf(stderr, "Cannot initialize the conversion context!\n");
return -1;
}
fread(in, 1, read_size, fin);
memcpy(inbuf[0], in, in_width*in_height);
memcpy(inbuf[1], in+in_width*in_height, in_width*in_height>>2);
memcpy(inbuf[2], in+(in_width*in_height*5>>2), in_width*in_height>>2);
// ********* 主要的 function ******
// ********* sws_scale ************
sws_scale(img_convert_ctx, inbuf, inlinesize,
0, in_height, outbuf, outlinesize);
memcpy(out, outbuf[0], out_width*out_height);
memcpy(out+out_width*out_height, outbuf[1], out_width*out_height>>2);
memcpy(out+(out_width*out_height*5>>2), outbuf[2], out_width*out_height>>2);
fwrite(out, 1, write_size, fout);
// ********* 结束的 function *******
// ********* sws_freeContext *******
sws_freeContext(img_convert_ctx);
fclose(fin);
fclose(fout);
return 0;
}
=====================================================================================
以下两张图为执行结果
Input Image
Output Image
ffmpeg的API函数用法 :sws_scale函数的用法-具体应用的更多相关文章
- FFmpeg 的sws_getContext函数 、sws_scale函数
FFmpeg里面的sws_scale库可以在一个函数里面同时实现:1.图像色彩空间转换:2.分辨率缩放:3.前后图像滤波处理. 其核心函数主要有三个: // 初始化sws_scalestruct Sw ...
- FFmpeg: FFmepg中的sws_scale() 函数分析
FFmpeg中的 sws_scale() 函数主要是用来做视频像素格式和分辨率的转换,其优势在于:可以在同一个函数里实现:1.图像色彩空间转换, 2:分辨率缩放,3:前后图像滤波处理.不足之处在于:效 ...
- Zookeeper C API 指南三(回调函数)(转)
2013-02-21 12:54 by Haippy, 9237 阅读, 0 评论, 收藏, 编辑 接上一篇<Zookeeper C API 指南二(监视(Wathes), 基本常量和结构体介绍 ...
- 【翻译】Flink Table Api & SQL — 内置函数
本文翻译自官网:Built-In Functions https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/fu ...
- SQL 语句日期用法及函数
SQL 语句日期用法及函数 --DAY().MONTH().YEAR()——返回指定日期的天数.月数.年数:select day(cl_s_time) as '日' from class --返回天 ...
- sql server ,OVER(PARTITION BY)函数用法,开窗函数,over子句,over开窗函数
https://technet.microsoft.com/zh-cn/library/ms189461(v=sql.105).aspx https://social.msdn.microsoft.c ...
- Python中的map()函数和reduce()函数的用法
Python中的map()函数和reduce()函数的用法 这篇文章主要介绍了Python中的map()函数和reduce()函数的用法,代码基于Python2.x版本,需要的朋友可以参考下 Py ...
- 如何通过HOOK改变windows的API函数(找到函数的相对偏移)
我们知道,系统函数都是以DLL封装起来的,应用程序应用到系统函数时,应首先把该DLL加载到当前的进程空间中,调用的系统函数的入口地址,可以通过GetProcAddress函数进行获取.当系统函数进行调 ...
- makefile高级用法--使用函数
makefile高级用法--使用函数 分类: C/C++ 使用函数 ———— 在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能.make所支持的函数也不算很多, ...
- 转: ES6异步编程: co函数库的含义与用法
转: ES6异步编程: co函数库的含义与用法 co 函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于 Generator 函数的自动执行. 比如,有一个 Ge ...
随机推荐
- eg_8
问题描述:比较两数组是否相等 Demo_1: import java.util.Arrays; public class TestArray { public static void main(Str ...
- 浏览器播放rtmp流
我是利用flash插件实现的,需要以下几个文件: flowplayer-3.2.8.min.js flowplayer-3.2.18.swf flowplayer.rtmp-3.2.8.swf flo ...
- iOS- CALayer绘图,如何绘制渐变效果图
1.渐变效果 —> 色彩空间 首先:自定义一个渐变视图,在自定义视图中重写drawRect #import "ViewController.h" #import " ...
- Spring 中使用Properties文件
Spring提供了加载Properties文件的工具类:org.springframework.beans.factory.config.PropertyPlaceholderConfigurer. ...
- Error: Unable to access jarfile D:\Apache\apache-jmeter-3.0\bin\ApacheJMete.jar
双击jmeter.bat后,在cmd窗口显示Error: Unable to access jarfile D:\Apache\apache-jmeter-3.0\bin\ApacheJMete.ja ...
- 微信公众平台实现获取用户OpenID的方法
这篇文章主要介绍了微信公众平台实现获取用户OpenID的方法,需要开发人员经过微信授权后获取高级接口才能使用此功能,用户OpenID对于微信公众平台建设有着非常广泛的用途,需要的朋友可以参考下 本文实 ...
- C语言版kafka消费者代码运行时异常kafka receive failed disconnected
https://github.com/edenhill/librdkafka/wiki/Broker-version-compatibility如果使用了broker版本是0.8的话, 在运行例程时需 ...
- Logrotate还有谁记得它??
我发现很多人的服务器上都运行着一些诸如每天切分Nginx日志之类的CRON脚本,大家似乎遗忘了Logrotate,争相发明自己的轮子,这真是让人沮丧啊!就好比明明身边躺着现成的性感美女,大家却忙着自娱 ...
- how to get iframe dom in js
how to get iframe dom in js https://stackoverflow.com/questions/3999101/get-iframes-document-from-ja ...
- 【转】Word 2010 取消拼写/语法检查,隐藏红线/绿线
转自:http://blog.chinaunix.net/uid-8203698-id-3040631.html 设置方法如下,在Word菜单栏-->文件-->选项-->校对,其中“ ...