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

- 顶
- 0
- 踩
sws_scale函数的用法-具体应用的更多相关文章
- ffmpeg的API函数用法 :sws_scale函数的用法-具体应用
移植ffmpeg过程中,遇到swscale的用法问题,所以查到这篇文章.文章虽然已经过去很长时间,但是还有颇多可以借鉴之处.谢谢“咕咕钟. 转自:http://guguclock.blogspot.c ...
- 有关日期的函数操作用法总结,to_date(),trunc(),add_months();
相关知识链接: Oracle trunc()函数的用法 oracle add_months函数 Oracle日期格式转换,tochar(),todate() №2:取得当前日期是一个星期中的第几天,注 ...
- Oracle to_date()函数的用法
Oracle to_date()函数的用法 to_date()是Oracle数据库函数的代表函数之一,下文对Oracle to_date()函数的几种用法作了详细的介绍说明,供您参考学习. 在Orac ...
- js中bind、call、apply函数的用法
最近一直在用 js 写游戏服务器,我也接触 js 时间不长,大学的时候用 js 做过一个 H3C 的 web的项目,然后在腾讯实习的时候用 js 写过一些奇怪的程序,自己也用 js 写过几个的网站.但 ...
- Oracle trunc()函数的用法
Oracle trunc()函数的用法 /**************日期********************/1.select trunc(sysdate) from dual --2013-0 ...
- freemarker内置函数和用法
原文链接:http://www.iteye.com/topic/908500 在我们应用Freemarker 过程中,经常会操作例如字符串,数字,集合等,却不清楚Freemrker 有没有类似于Jav ...
- matlab中patch函数的用法
http://blog.sina.com.cn/s/blog_707b64550100z1nz.html matlab中patch函数的用法——emily (2011-11-18 17:20:33) ...
- JavaScript中常见的数组操作函数及用法
JavaScript中常见的数组操作函数及用法 昨天写了个帖子,汇总了下常见的JavaScript中的字符串操作函数及用法.今天正好有时间,也去把JavaScript中常见的数组操作函数及用法总结一下 ...
- JavaScript中常见的字符串操作函数及用法
JavaScript中常见的字符串操作函数及用法 最近几次参加前端实习生招聘的笔试,发现很多笔试题都会考到字符串的处理,比方说去哪儿网笔试题.淘宝的笔试题等.如果你经常参加笔试或者也是一个过来人,相信 ...
随机推荐
- Mysql主从复制,实现数据同步
大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢 ...
- 算不算类似微信小程序
这几天微信发布的微信里生成小程序,刷爆了朋友圈. 微信生成的小程序不用下载安装就能在手机里出现,即用即删. 想到这里,我想到苹果手机本身再带类似于微信的小程序的呈现方式,也可以即用即删,那是我在去年久 ...
- C语言基础知识【指针】
2017年7月11日18:33:41C指针 该看地址:http://www.runoob.com/cprogramming/c-pointers.html1.学习 C 语言的指针既简单又有趣.通过指 ...
- iPhone缓存网络数据
本文转载至 http://blog.csdn.net/wwang196988/article/details/7542918 在iPhone应用程序中,我们经常要用去网络下载一些文件,比如xml, ...
- iOS表格制作
由于项目上的需求,需要做一个表格出来,来显示流程状态.刚开始脑子一头雾水,没有一点思路,但是靠着自己的座右铭--“世上无难事,只怕有心人”,克服了所有困难.好,不说了,讲正事. 制作表格,还是需要ta ...
- NSNotificationCenter详解
本文转载至 http://blog.csdn.net/chengyingzhilian/article/details/7874408 作用:NSNotificationCenter是专门供程序中不同 ...
- maven;spring;pom
[说明]因为对环境配置文件理解的不充分,遇到问题经常是无法独自解决,特别是maven和javaweb的转换,也是糊里糊涂的,今天就又出问题了. [说明] 一:今日完成 1)任务二的效果展示看的我一脸懵 ...
- 【BZOJ4894】天赋 有向图生成树计数
[BZOJ4894]天赋 Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的.也就是 ...
- [原创]实现多层DIV叠加的js事件穿透
Flash里面有个很好的特性是,一个容器里,不存在实际对象的部分,不会阻拦鼠标事件穿透到下一层. 前端就不一样了,两个div层叠以后,上层div会接收到所有事件(即使这个div里面内容是空的,没有任何 ...
- linux c编程:进程控制(四)进程调度
当系统中有多个进程到时候,哪个进程先执行,哪个进程后执行是由进程的优先级决定的.进程的优先级是由nice值决定的.nice值越小,优先级越高.可以看做越友好那么调度优先级越低.进程可以通过nice函数 ...