sws_getContext和sws_scale分析
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分析相关推荐
- FFmpeg之sws_scale库的应用(sws_getContext、sws_scale、sws_freeContext)
FFmpeg里面的sws_scale库可以在一个函数里面同时实现:1.图像色彩空间转换:2.分辨率缩放:3.前后图像滤波处理. 其核心函数主要有三个: // 初始化sws_scale struct S ...
- 解码(五):sws_getContext和sws_scale像素格式和尺寸转换函数详解
视频像素格式和尺寸转换 sws_getContext(像素格式转换上下文),提供了两个函数 sws_getContext像素格式上下文初始化代码演示 如下代码: //表示是视频if (cc == vc ...
- FFmpeg sws_scale库文件分析
FFmpeg sws_scale分析1 FFmpeg里面的sws_scale库可以在一个函数里面同时实现:1.图像色彩空间转换:2.分辨率缩放:3.前后图像滤波处理. 其核心函数主要有三个: // 初 ...
- ffmpeg学习 函数分析sws_scale
有关ffmpeg中主要的api函数源码解析参考雷神系列文章,整理如下ffmpeg学习(2)获取和使用,源码分析. 函数sws_scale位于libswscale库,该库是一个主要用于处理图片像素数据的 ...
- ffplay.c学习-5-视频输出和尺⼨变换
ffplay.c学习-5-视频输出和尺⼨变换 目录 视频输出模块 视频输出初始化 视频输出初始化主要流程 初始化窗⼝显示⼤⼩ 视频输出逻辑 video_refresh 计算上⼀帧应显示的时⻓,判断是否 ...
- 轻松掌握FFmpeg编程:从架构到实践
轻松掌握FFmpeg编程:从架构到实践 (Master FFmpeg Programming with Ease: From Architecture to Practice 引言 (Introduc ...
- 基于NDK、C++、FFmpeg的android视频播放器开发实战-夏曹俊-专题视频课程
基于NDK.C++.FFmpeg的android视频播放器开发实战-1796人已学习 课程介绍 课程包含了对流媒体(拉流)的播放,演示了播放rtmp的香港卫视,支持rtsp摄像头和ht ...
- 视频教程-基于NDK、C++、FFmpeg的android视频播放器开发实战-Android
基于NDK.C++.FFmpeg的android视频播放器开发实战 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟仿真,计算 ...
- FFmpeg编译出错_img_convert 找不到
问题出现在下载的ffmpeg的版本不一样,在0.4.8以前的版本中还有img_convert这个函数,新版本中用sws_getContext和sws_scale代替了.简单说明如下: 新版本的ffmp ...
最新文章
- python3调用函数len结果不返回字符串长度_Python通过len函数返回对象长度
- 网站外部链接优化如何进一步提升?
- How to scroll the window using JQuery $.scrollTo() function
- 单脉冲雷达的相干干扰的研究文章_什么是量子纠缠和量子退相干?这个比喻太绝了!...
- 删除git仓库中的文件(从所有历史中清除,不留痕迹)【不可恢复】
- poj3311 经典tsp问题
- 英雄会在线编程题目(请大家不吝赐教)
- matlab 8.4,《DSP using MATLAB》Problem 8.42
- Mybatis在Maven项目中使用
- 海洋工作室——网站建设专家:全数据库比较工具
- 【2012百度之星/初赛上】小小度刷礼品
- 高德地图 web API 多点路线绘制
- 使用pdfobject.js实现在线浏览PDF--后台上传保存文件
- 开箱即用——用模板快速上线一个HR 服务中心
- 如何运用Origin进行曲线拟合
- abab的四字成语_带abab的四字成语大全
- 【程序员脑洞故事】宇宙尽头的描述符(下)
- python实现二维码识别_python实现二维码、条形码识别
- WMS智能仓储系统——保姆式服务系统
- ubuntu smba常用设置
热门文章
- c语言求纯粹合数,纯粹合数是哪些?
- mysql set password_MySQL修改用户的密码(SET PASSWORD)的例子
- 简介IntelliJ IDEAD
- [某人的题解]徒步旅行(travel)
- 【git】使用git链接远程gitee仓库并提交
- tensorflow进阶(更新中...)
- 软件工程-人事管理系统项目(一)
- 苹果笔记本python怎么换行_python怎么换行,我的换行就是执行啊
- php 屏蔽浸膏,【佳学基因】副甲状腺浸膏基因检测
- 本地图片转换成网络链接图片