http://www.guguclock.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;
}

转载于:https://www.cnblogs.com/mmix2009/p/3585981.html

ffmpeg 中 swscale 的用法相关推荐

  1. FFmpeg中可执行文件ffplay用法汇总

    从https://ffbinaries.com/downloads 下载最新的4.1版本的windows 64位FFplay.目前linux下的只有3.2版本的.FFplay是一个由FFmpeg和SD ...

  2. FFmpeg中可执行文件ffprobe用法汇总

    从https://ffbinaries.com/downloads 下载最新的4.1版本的Windows 64位FFprobe,FFprobe用于从多媒体流中获取相关信息或查看文件格式信息,并以可读的 ...

  3. ffmpeg 同宽度 画中画_FFmpeg中overlay滤镜用法-水印及画中画

    1. overlay 技术简介 overlay 技术又称视频叠加技术.overlay 视频技术使用非常广泛,常见的例子有,电视屏幕右上角显示的电视台台标,以及画中画功能.画中画是指在一个大的视频播放窗 ...

  4. linux服务器中学习使用FFmpeg命令overlay滤镜用法

    linux服务器中学习使用FFmpeg命令overlay滤镜用法 1.overlay技术简介 2.命令行用法 2.1 视频中叠加图标 2.1.1 直接叠加图标 2.1.2 延时叠加图标 2.2 视频中 ...

  5. ffmpeg中av_image_alloc()函数的用法 以及 另一种同样功能的函数用法

    一.ffmpeg中av_image_alloc()是这样定义的.此函数的功能是按照指定的宽.高.像素格式来分析图像内存. 参数说明: pointers[4]:保存图像通道的地址.如果是RGB,则前三个 ...

  6. FFmpeg中AVDictionary介绍

    FFmpeg中的AVDictionary是一个结构体,简单的key/value存储,经常使用AVDictionary设置或读取内部参数,声明如下,具体实现在libavutil模块中的dict.c/h, ...

  7. ffmpeg中av_log的实现分析

    [时间:2017-10] [状态:Open] [关键词:ffmpeg,avutil,av_log, 日志输出] 0 引言 FFmpeg的libavutil中的日志输出的接口整体比较少,但是功能还是不错 ...

  8. mysql中change用法,mysql 中alter的用法以及一些步骤

    mysql 中alter的用法以及一些方法 在用到alter的时间,查到了这个文章,就copy下来了,详细进入下面链接: MySQL之alter语句用法总结 1:删除列 ALTER TABLE [表名 ...

  9. mysql中正则表达式的用法_Mysql中正则表达式Regexp常见用法

    Mysql中Regexp常见用法 模糊匹配,包含特定字符串 # 查找content字段中包含"车友俱乐部"的记录 select * from club_content where ...

  10. 【C++】C/C++ 中 static 的用法全局变量与局部变量

    C/C++ 中 static 的用法全局变量与局部变量 目录 1. 什么是static? 1.1 static 的引入 1.2 静态数据的存储 2. 在 C/C++ 中static的作用 2.1 总的 ...

最新文章

  1. java 数组的基本操作
  2. [分享]关于windows下的小技巧
  3. python3 多线程_python3多线程知识点总结
  4. SAPscripts 到导数程序中取数据的实例
  5. 各种主流数据库的比较
  6. kepserver 6.5_非凡说| 先定一个6.5分小目标,财大生如何突破瓶颈拿下雅思!
  7. 扎克伯格预言即将成真:计算机可解读图片内容
  8. VScode编辑器设置中文的教程,超详细的
  9. android 使用javascript,可以在Android中使用JavaScript吗?
  10. 系统在此应用程序堆栈溢出_从部署我的第一个完整堆栈Web应用程序中学到的经验教训...
  11. mysql时间相减得到天数保留两位_【敲黑板!】分布式事务数据库 —-MySQL 数据库开发规范(第四节)...
  12. 吴恩达|机器学习作业8.1.推荐系统(协同过滤算法)
  13. python中监控错误的语句_Python学习_07_错误、异常
  14. centos7的php5.4竟然不支持原生的mysql
  15. hbuildx微信开发者工具-微信小程序测试
  16. 有道翻译爬虫 js逆向
  17. 【MATLAB】rem和mod函数的区别
  18. mysql优化 个人笔记 (mysql 主从复制 ) 非礼勿扰 -m11
  19. stata画时间趋势图时横坐标标签太长重叠怎么办
  20. 苹果m1可以虚拟服务器,苹果M1芯片可以运行ARM版win10 但需要利用虚拟机

热门文章

  1. 【Django 2021年最新版教程32】Django 事务 悲观锁 乐观锁
  2. 并发(concurrent)、并行(parallel)、顺序(sequential)、串行(serial)是什么 区别
  3. kubernetes视频教程笔记 (1)-什么是kubernetes和kubernetes的知识结构思维导图
  4. 微信小程序云开发教程-后端接口分析和接口返回值的格式定义
  5. 安装nuxt_一天上手Nuxt基于vue服务端渲染
  6. 采样次数不同平均值不一样_认知的不同,才有不一样的人生
  7. 用友t3服务器更改是哪个文件夹里,用友t3服务器地址变更
  8. js常用处理请求到的数据的方法(即map,filter,find,findIndex,some,every一些常用方法的使用)
  9. JAVA 泛型 入门
  10. HTML DOM Image 对象