FFmpeg中的 sws_scale() 函数主要是用来做视频像素格式和分辨率的转换,其优势在于:可以在同一个函数里实现:1.图像色彩空间转换, 2:分辨率缩放,3:前后图像滤波处理。不足之处在于:效率相对较低,不如libyuv或shader,其关联的函数主要有:

1.sws_getContext():

struct SwsContext *sws_getContext(int srcW, /* 输入图像的宽度 */int srcH, /* 输入图像的宽度 */enum AVPixelFormat srcFormat, /* 输入图像的像素格式 */int dstW, /* 输出图像的宽度 */int dstH, /* 输出图像的高度 */enum AVPixelFormat dstFormat, /* 输出图像的像素格式 */int flags,/* 选择缩放算法(只有当输入输出图像大小不同时有效),一般选择SWS_FAST_BILINEAR */SwsFilter *srcFilter, /* 输入图像的滤波器信息, 若不需要传NULL */SwsFilter *dstFilter, /* 输出图像的滤波器信息, 若不需要传NULL */const double *param /* 特定缩放算法需要的参数(?),默认为NULL */);

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

2.sws_freeContext

// 释放sws_scale
void sws_freeContext(struct SwsContext *swsContext);

真正用来做转换的函数则是: sws_scale() ,其函数定义如下:

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

下面对其函数参数进行详细说明:

1.参数 SwsContext *c, 转换格式的上下文。也就是 sws_getContext 函数返回的结果。
2.参数 const uint8_t *const srcSlice[], 输入图像的每个颜色通道的数据指针。其实就是解码后的AVFrame中的data[]数组。因为不同像素的存储格式不同,所以srcSlice[]维数
也有可能不同。
以YUV420P为例,它是planar格式,它的内存中的排布如下:
YYYYYYYY UUUU VVVV
使用FFmpeg解码后存储在AVFrame的data[]数组中时:
data[0]——-Y分量, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8……
data[1]——-U分量, U1, U2, U3, U4……
data[2]——-V分量, V1, V2, V3, V4……
linesize[]数组中保存的是对应通道的数据宽度 ,
linesize[0]——-Y分量的宽度
linesize[1]——-U分量的宽度
linesize[2]——-V分量的宽度

而RGB24,它是packed格式,它在data[]数组中则只有一维,它在存储方式如下:
data[0]: R1, G1, B1, R2, G2, B2, R3, G3, B3, R4, G4, B4……
这里要特别注意,linesize[0]的值并不一定等于图片的宽度,有时候为了对齐各解码器的CPU,实际尺寸会大于图片的宽度,这点在我们编程时(比如OpengGL硬件转换/渲染)要特别注意,否则解码出来的图像会异常。

3.参数const int srcStride[],输入图像的每个颜色通道的跨度。.也就是每个通道的行字节数,对应的是解码后的AVFrame中的linesize[]数组。根据它可以确立下一行的起始位置,不过stride和width不一定相同,这是因为:
a.由于数据帧存储的对齐,有可能会向每行后面增加一些填充字节这样 stride = width + N;
b.packet色彩空间下,每个像素几个通道数据混合在一起,例如RGB24,每个像素3字节连续存放,因此下一行的位置需要跳过3*width字节。

4.参数int srcSliceY, int srcSliceH,定义在输入图像上处理区域,srcSliceY是起始位置,srcSliceH是处理多少行。如果srcSliceY=0,srcSliceH=height,表示一次性处理完整个图像。这种设置是为了多线程并行,例如可以创建两个线程,第一个线程处理 [0, h/2-1]行,第二个线程处理 [h/2, h-1]行。并行处理加快速度。
5.参数uint8_t *const dst[], const int dstStride[]定义输出图像信息(输出的每个颜色通道数据指针,每个颜色通道行字节数)

代码示例:将解码后的数据转换成1280*720的RGBA8888 格式

1. 定义转换格式的上下文

vctx = sws_getCachedContext(vctx,frame->width, // 源图像的宽度frame->height, //  源图像的高度(AVPixelFormat)frame->format,outWidth,outHeight,AV_PIX_FMT_RGBA,SWS_FAST_BILINEAR,0, 0, 0);

2. 开始转换

int outWidth = 1280;
int outHeight = 720;
char *rgb = new char[1920*1080*4];
uint8_t *data[AV_NUM_DATA_POINTERS] = {0};data[0] = (uint8_t *)rgb;int lines[AV_NUM_DATA_POINTERS] = {0};lines[0] = outWidth * 4;int h = sws_scale(vctx,(const uint8_t **)frame->data,frame->linesize,0,frame->height,data,lines);

sws_scale函数相关推荐

  1. ffmpeg sws_scale函数详解

    1. 介绍 如果想在两个AVPixelFormat之间转换,例如将YUV420P 转换到YUV422,亦或者是要改变其大小,放大缩小什么的,就要用到ffmpeg中的swscale函数了,此版本基于ff ...

  2. FFmpeg 的sws_getContext函数 、sws_scale函数

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

  3. ffmpeg 视频像素尺寸转换SwsContext、sws_scale 函数解释

    函数介绍 SwsContext 格式转换的上下文,下面是 初始化函数 struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixe ...

  4. ffmpeg sws_scale函数的用法

    如果想將某個PixelFormat轉換至另一個PixelFormat,例如,將YUV420P轉換成YUYV422,或是想變換圖的大小,都可以使用swscale達成. 其中,PixelFormat 的列 ...

  5. sws_scale函数像素数据格式的转换yuv转rgba

    本文介绍如何使用ffmpeg中的接口转换像素数据格式. sws_scale()可以用于对视频原始数据的长宽进行转换, 或者转成别的格式 假定现有 yuv.yuv(YUV420P格式)文件需要转为RGB ...

  6. sws_scale函数的用法-具体应用

    移植ffmpeg过程中,遇到swscale的用法问题,所以查到这篇文章.文章虽然已经过去很长时间,但是还有颇多可以借鉴之处.谢谢"咕咕鐘". 转自:http://guguclock ...

  7. sws_scale图像缩放函数介绍

    sws_scale() 是 libswscale 库里面一个非常常用的函数,它的功能如下: 1,对图像的大小进行缩放. 2,转换图像格式跟颜色空间,例如把 YUYV422 转成 RGB24 . 3,转 ...

  8. 使用ffmpeg进行图像格式转换以及图像缩放/sws_scale/linux/c++/c/rgb-yuv420

    利用ffmpeg进行图像数据格式的转换以及图片的缩放应用中,主要用到了swscale.h文件中的三个函数,分别是: struct SwsContext *sws_getContext(int srcW ...

  9. FFmpeg源码分析:sws_scale图像缩放与图像转换

    FFmpeg在libswscale模块提供图像缩放与图像转换功能,比如1080P图像缩放为720P,或者YUV422P转换为YUV420P.图像缩放函数有个SwsContext结构体作为上下文,上一篇 ...

最新文章

  1. java垃圾回收机制_笔记 | Java垃圾回收机制
  2. Failed to load JavaHL Library(windows和mac)
  3. 第十一周项目实践2 用邻接表存储的图来实现基本应用
  4. 复习Javascript专题(一):基本概念部分
  5. 计算机组成原理第六章难,计算机组成原理第六章答案
  6. java中一个分而治之的框架ForkJoin
  7. 如何从Swift调用Objective-C代码?
  8. 网络上复制网页文字的方法
  9. c语言实验--九九乘法表,C语言实验报告(四)
  10. mac下安装破解版adobe photoshop cs6
  11. 企业信息化整体架构图
  12. 【某网页在手机上可以打开,但用电脑上所有浏览器都打不开】的解决办法
  13. 【mysql】【binlog】mysql配置binlog
  14. sparse_categorical_crossentropy的使用
  15. 三星4k3d电视测试软件,技术篇 | 央视4K超高清频道怎么看?三星电视让您大饱眼福!...
  16. C语言:输入三角形边长,求面积。
  17. Activiti进阶
  18. 四川计算机一级试题,四川省计算机一级考试的真题
  19. axios用catch的写法与不使用catch有什么区别?
  20. 一种节能环保(省钱)的家庭淋浴换热器

热门文章

  1. JS高级之静态成员和实例成员
  2. Revit二次开发之俯视图缩放匹配
  3. 医疗器械国内注册相关法规(一)
  4. Redis笔记-入门篇
  5. 基于ESP8266与Blinker(点灯科技平台)的智能遥控器设计(一)
  6. 春招求职篇(二)---面试篇之立讯精密
  7. 力扣题库设计循环队列
  8. python--海温、OLR数据分布做显著性检验,绘制空间分布并打点
  9. WPS表格如何根据数据的不同显示不同的背景色
  10. matlab上机操作心得,Matlab上机实习实习报告