struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
int dstW, int dstH, enum AVPixelFormat dstFormat,
int flags, SwsFilter *srcFilter,
SwsFilter *dstFilter, const double *param);

创建转换上下文,参数分析:

flags参数是指选择的转换算法,如果没有精准的要求,这些算法差别不大,一般用SWS_BILINEAR参数,可选类型定义在//libswscale/swscale.h内,如下:

#define SWS_FAST_BILINEAR 1
#define SWS_BILINEAR 2
#define SWS_BICUBIC 4
#define SWS_X 8
#define SWS_POINT 0x10
#define SWS_AREA 0x20
#define SWS_BICUBLIN 0x40
#define SWS_GAUSS 0x80
#define SWS_SINC 0x100
#define SWS_LANCZOS 0x200
#define SWS_SPLINE 0x400

i9-9900KF CPU @ 3.60GHz 8核16线程下 3840x2160时,yuv420p->uyvy422,用SWS_BILINEAR转化一帧视频消耗31ms,用SWS_POINT消耗3ms。以上各个参数分析
AV_PIX_FMT_UYVY422 1080p50转成AV_PIX_FMT_UYVY422 720p50时,SWS_FAST_BILINEAR和SWS_AREA消耗cpu最小,并且负载均衡,其内部应该开启多个线程一起转换了。其他几个参数负载极不均衡而且对cpu消耗很大。

srcFilter, 输入图像的滤波器信息, 如果不用赋值NULL
dstFilter, 输出图像的滤波器信息, 如果不用赋值NULL
param 特定缩放算法需要的参数,如果不用赋值NULL

int attribute_align_arg sws_scale(struct SwsContext *c,
const uint8_t * const srcSlice[],
const int srcStride[], int srcSliceY,
int srcSliceH, uint8_t *const dst[],
const int dstStride[])

真正做转换的函数,参数分析:
这个转换是深拷贝,需要给dst申请空间,实测yuv420->uyvy422每执行一次就输出一帧,开始不需要多帧输入填充缓存。
sws_scale转换包含像素格式转换和缩放拉伸转换,输入输出可以是rgb或yuv中的任意一种。

srcSlice对应frame->data
yuv各种格式在AVFrame::data[]中的存储方式,另一篇博客:YUV的plannar,packet及semi-planar格式

srcStride这个参数填入frame->linesize linesize[]
数组中保存的是对应通道的数据宽度
linesize[0]——-Y分量的宽度
linesize[1]——-U分量的宽度
linesize[2]——-V分量的宽度
linesize[0]的值并不一定等于图片的宽度,有时候为了对齐各解码器的CPU(32位/64位),实际尺寸会大于图片的宽度,这点在我们编程时(比如OpengGL硬件转换/渲染)要特别注意,否则解码出来的图像会异常,增加linesize[0]的值使得,linesize[0]/32或linesize[0]/64为整数,叫做对齐cpu字节。
以上是planner格式,如果是packet格式,如1920x1080 uyvy422,linesize[1],linesize[2]都为0,因为只有一个分量了,此时linesize[0]为1920*2 = 3840
实测yuv422格式,1080i50视频,在x86上没有格式对齐, frame->linesize[0]为1920x2。此时frame->linesize[0] x frame->width即为此帧frame数据大小。
如果是planner格式的像素,frame的大小应该是(frame->linesize[0]+frame->linesize[1]+frame->linesize[2]) x frame->width。如果用宽x高x像素格式字节数算的话,当像需要补齐字节时,得到的值会小于frame包含的真实值,进行memcpy赋值时会少复制内容。

参数int srcSliceY, int srcSliceH,定义在输入图像上处理区域
srcSliceY是起始位置,srcSliceH是处理多少行。如果srcSliceY=0,srcSliceH=height,表示一次性处理完整个图像。这种设置是为了多线程并行,例如可以创建两个线程,第一个线程处理 [0, h/2-1]行,第二个线程处理 [h/2, h-1]行。并行处理加快速度。

参数uint8_t *const dst[], const int dstStride[]定义输出图像信息(输出的每个颜色通道数据指针,每个颜色通道行字节数)

与其类似的函数还有: sws_getCachedContext ,区别在于: sws_getContext 可以用于多路码流转换,为每个不同的码流都指定一个不同的转换上下文,而 sws_getCachedContext 只能用于一路码流转换。

/*** Free the swscaler context swsContext.* If swsContext is NULL, then does nothing.*/
void sws_freeContext(struct SwsContext *swsContext);

释放sws_scale

字节对齐解释:比如704*576分辨率的视频,它的width=704,height=576,摄像机芯片一般会要求64或者128对齐,当128位对齐时,704不能被128整除,需要在每一行结尾补64字节0x00占位,它的linesize也就是每一行的长度768。

参考:https://blog.csdn.net/weixin_30401605/article/details/94875795?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163635474716780357220302%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163635474716780357220302&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-13-94875795.pc_search_result_cache&utm_term=yuv420%E5%9C%A8AVFrame-%3Edata%E4%B8%AD%E6%80%8E%E4%B9%88%E5%AD%98%E5%82%A8%E7%9A%84&spm=1018.2226.3001.4187

参考:https://blog.csdn.net/m0_37346206/article/details/106634388

sws_getContext和sws_scale分析相关推荐

  1. FFmpeg之sws_scale库的应用(sws_getContext、sws_scale、sws_freeContext)

    FFmpeg里面的sws_scale库可以在一个函数里面同时实现:1.图像色彩空间转换:2.分辨率缩放:3.前后图像滤波处理. 其核心函数主要有三个: // 初始化sws_scale struct S ...

  2. 解码(五):sws_getContext和sws_scale像素格式和尺寸转换函数详解

    视频像素格式和尺寸转换 sws_getContext(像素格式转换上下文),提供了两个函数 sws_getContext像素格式上下文初始化代码演示 如下代码: //表示是视频if (cc == vc ...

  3. FFmpeg sws_scale库文件分析

    FFmpeg sws_scale分析1 FFmpeg里面的sws_scale库可以在一个函数里面同时实现:1.图像色彩空间转换:2.分辨率缩放:3.前后图像滤波处理. 其核心函数主要有三个: // 初 ...

  4. ffmpeg学习 函数分析sws_scale

    有关ffmpeg中主要的api函数源码解析参考雷神系列文章,整理如下ffmpeg学习(2)获取和使用,源码分析. 函数sws_scale位于libswscale库,该库是一个主要用于处理图片像素数据的 ...

  5. ffplay.c学习-5-视频输出和尺⼨变换

    ffplay.c学习-5-视频输出和尺⼨变换 目录 视频输出模块 视频输出初始化 视频输出初始化主要流程 初始化窗⼝显示⼤⼩ 视频输出逻辑 video_refresh 计算上⼀帧应显示的时⻓,判断是否 ...

  6. 轻松掌握FFmpeg编程:从架构到实践

    轻松掌握FFmpeg编程:从架构到实践 (Master FFmpeg Programming with Ease: From Architecture to Practice 引言 (Introduc ...

  7. 基于NDK、C++、FFmpeg的android视频播放器开发实战-夏曹俊-专题视频课程

    基于NDK.C++.FFmpeg的android视频播放器开发实战-1796人已学习 课程介绍         课程包含了对流媒体(拉流)的播放,演示了播放rtmp的香港卫视,支持rtsp摄像头和ht ...

  8. 视频教程-基于NDK、C++、FFmpeg的android视频播放器开发实战-Android

    基于NDK.C++.FFmpeg的android视频播放器开发实战 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟仿真,计算 ...

  9. FFmpeg编译出错_img_convert 找不到

    问题出现在下载的ffmpeg的版本不一样,在0.4.8以前的版本中还有img_convert这个函数,新版本中用sws_getContext和sws_scale代替了.简单说明如下: 新版本的ffmp ...

最新文章

  1. python3调用函数len结果不返回字符串长度_Python通过len函数返回对象长度
  2. 网站外部链接优化如何进一步提升?
  3. How to scroll the window using JQuery $.scrollTo() function
  4. 单脉冲雷达的相干干扰的研究文章_什么是量子纠缠和量子退相干?这个比喻太绝了!...
  5. 删除git仓库中的文件(从所有历史中清除,不留痕迹)【不可恢复】
  6. poj3311 经典tsp问题
  7. 英雄会在线编程题目(请大家不吝赐教)
  8. matlab 8.4,《DSP using MATLAB》Problem 8.42
  9. Mybatis在Maven项目中使用
  10. 海洋工作室——网站建设专家:全数据库比较工具
  11. 【2012百度之星/初赛上】小小度刷礼品
  12. 高德地图 web API 多点路线绘制
  13. 使用pdfobject.js实现在线浏览PDF--后台上传保存文件
  14. 开箱即用——用模板快速上线一个HR 服务中心
  15. 如何运用Origin进行曲线拟合
  16. abab的四字成语_带abab的四字成语大全
  17. 【程序员脑洞故事】宇宙尽头的描述符(下)
  18. python实现二维码识别_python实现二维码、条形码识别
  19. WMS智能仓储系统——保姆式服务系统
  20. ubuntu smba常用设置

热门文章

  1. c语言求纯粹合数,纯粹合数是哪些?
  2. mysql set password_MySQL修改用户的密码(SET PASSWORD)的例子
  3. 简介IntelliJ IDEAD
  4. [某人的题解]徒步旅行(travel)
  5. 【git】使用git链接远程gitee仓库并提交
  6. tensorflow进阶(更新中...)
  7. 软件工程-人事管理系统项目(一)
  8. 苹果笔记本python怎么换行_python怎么换行,我的换行就是执行啊
  9. php 屏蔽浸膏,【佳学基因】副甲状腺浸膏基因检测
  10. 本地图片转换成网络链接图片