实际开发中的问题:
在实际开发中,我们通过相机或者摄像头获得的数据可能是RGBA的,也可能是YUV的,获得这个原始的数据后,我们需要做一些事情,例如有可能将原始的数据转成mp4,将原始大小的分辨率变得小一点(例如摄像头得到的是4K的分辨率,现在要转成1080*720的)
这里就存在一个问题:有时候我们需要将原始的RGBA数据转成YUV的,有时候需要将YUV数据转成RGBA的,有时候将分辨率变小等。因此这一章我们学习一个方法能将 视频的大小转换。
目标:将YUV数据转成 RGBA, 将RGBA数据转成YUV
使用到的核心函数一 sws_getCachedContext
struct SwsContext *sws_getCachedContext(struct SwsContext *context,
int srcW, int srcH, enum AVPixelFormat srcFormat,
int dstW, int dstH, enum AVPixelFormat dstFormat,
int flags, SwsFilter *srcFilter,
SwsFilter *dstFilter, const double *param);
返回值:
参数说明:
struct SwsContext *context:如果传递nullptr,则会调用sws_getContext()重新生成一个,如果context是有值的,且这个值是符合下面参数的要求,也就是说,这个context本来就和下面的源图片的宽和高,源图片的格式,和要转换后的图片的宽和高,转换后的图片的格式相等,则返回值就是这个context,如果不符合,则会free 这个context 并调用sws_getContext()重新生成一个
int srcW, int srcH, 要转换的图片的宽和高。
enum AVPixelFormat srcFormat 要转换的图片的格式
int dstW, int dstH, 转换后的图片的宽和高
enum AVPixelFormat dstFormat 转换后的图片的格式
int flags, 在转换的时候使用那种算法 参考 ffmpeg中的sws_scale算法性能对比 - ahuo - 博客园
如果对图像的缩放,要追求高效,比如说是视频图像的处理,在不明确是放大还是缩小时,直接使用SWS_FAST_BILINEAR算法即可。如果明确是要缩小并显示,建议使用Point算法
#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
SwsFilter *srcFilter,SwsFilter *dstFilter, const double *param:过滤器相关的,在实际开发中,基本不会用ffmpeg 的过滤器,因此都填写nullptr就好
/**
* Check if context can be reused, otherwise reallocate a new one.
*
* If context is NULL, just calls sws_getContext() to get a new
* context. Otherwise, checks if the parameters are the ones already
* saved in context. If that is the case, returns the current
* context. Otherwise, frees context and gets a new context with
* the new parameters.
*
* Be warned that srcFilter and dstFilter are not checked, they
* are assumed to remain the same.
*/
struct SwsContext *sws_getCachedContext(struct SwsContext *context,
int srcW, int srcH, enum AVPixelFormat srcFormat,
int dstW, int dstH, enum AVPixelFormat dstFormat,
int flags, SwsFilter *srcFilter,
SwsFilter *dstFilter, const double *param);
我们看到还有一个 sws_getContext 函数,也可以返回一个 SwsContext *,那么这两个函数有啥区别呢?sws_getCachedContext 是可以反复调用的,因为如果传递的第一个参数context不符合要求,sws_getCachedContext函数会帮您自动的free,但是 sws_getContext函数不会,在多次调用的时候要user手动的free。
对比
struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
int dstW, int dstH, enum AVPixelFormat dstFormat,
int flags, SwsFilter *srcFilter,

最低0.47元/天 解锁文章
3466

被折叠的 条评论
为什么被折叠?



