FFmpeg – 常用的视频像素格式以及使用SwsContext和sws_scale进行视频像素格式转换和视频缩放
1 视频像素格式
YUV420P
YUV420P三个Plane,按照YYYY.....UUUU.....VVVV.....分别存储于各个Plane通道
RGB24
RGB24一个Plane,按照RGBRGBRGB......的顺序存储在一个Plane中
BGR24
BGR24一个Plane,按照BGRBGRBGR......的顺序存储在一个Plane中
NV12
NV12两个Plane,一个Plane存储YYYYYY......,另一个Plane按照UV的顺序交叉存储UVUVUV......
NV21
NV21两个Plane,一个Plane存储YYYYYY......,另一个Plane按照VU的顺序交叉存储VUVUVU......
2 FFmpeg视频像素格式转换和视频缩放相关函数
2.1 sws_getContext
函数形式
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 
)
函数功能
分配并返回一个SwsContext结构体,用于在sws_scale函数中执行图像缩放和转换操作。
函数参数
- srcW - 源图像的宽度
- srcH - 源图像的高度
- srcFormat - 源图像格式
- dstW - 目标图像的宽度
- dstH - 目标图像的高度
- dstFormat - 目标图像格式
- flags - 指定用于重新算法的算法和选项
- param - 调整使用的缩放器的额外参数
关于flags参数,可以有以下选项
#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
此篇文章 比较了不同flag的性能以及效果,可以参考以下。
函数返回值
返回已经分配的SwsContext的指针,如果出现错误,则返回NULL
2.2 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 
)
函数功能
此函数与之前的sws_getContext的区别在于,此函数会先行检查SwsContext是否可以重用,如果不可以则重新分配一个新的。
如果SwsContext为NULL,则会调用sws_getContext函数获取新的上下文,如果SwsContext不为NULL,检查设置的新参数是否是已经保存在输入的sws_getContext中,如果参数完全一致则返回当前上下文,否则则释放当前上下文并根据新参数获取新的上下文。
函数参数
- srcW - 源图像的宽度
- srcH - 源图像的高度
- srcFormat - 源图像格式
- dstW - 目标图像的宽度
- dstH - 目标图像的高度
- dstFormat - 目标图像格式
- flags - 指定用于重新算法的算法和选项
- param - 调整使用的缩放器的额外参数
关于flags参数,可以有以下选项
#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
此篇文章 比较了不同flag的性能以及效果,可以参考以下。
函数返回值
返回已经分配的SwsContext的指针,如果出现错误,则返回NULL
2.3 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[] 
)
函数功能
将原图像切片进行缩放,并将缩放的图像切片放入目标图像中。
切片是图像中的一系列连续行,切片必须连续提供,可以是自上而下或者自下而上的顺序。
函数参数
- c - 使用sws_getContext()创建的上下文
- srcSlice - 指向源切片平面的指针的数组
- srcStride - 指向源图像每个平面步幅的数组
- srcSliceY - 要处理的切片在源图像中的位置,即切片第一行的图像的数字(从零开始计数)
- srcSliceH - 源切片的高度,即切片中的行数
- dst - 指向目标图像平面的指针的数组
- dstStride - 指向目标图像每个平面的步幅的数组
函数返回值
目标图像切片的高度
2.4 sws_freeContext
函数形式
void sws_freeContext(struct SwsContext * swsContext)
函数功能
释放swscaler上下文swsContext,如果swsContext为NULL,则不做任何事情。
3 使用示例
将OpenCV的BGR24视频像素格式的cv::Mat转换成YUV420P,并保持相同的宽高
void CvMatToAVFrame(const cv::Mat& input_mat, AVFrame* out_avframe)
{
    int image_width = input_mat.cols;
    int image_height = input_mat.rows;
    int cvLinesizes[1];
    cvLinesizes[0] = input_mat.step1();
    SwsContext* openCVBGRToAVFrameSwsContext = sws_getContext(
        image_width,
        image_height,
        AVPixelFormat::AV_PIX_FMT_BGR24,
        image_width,
        image_height,
        AVPixelFormat::AV_PIX_FMT_YUV420P,
        SWS_FAST_BILINEAR,
        nullptr, nullptr, nullptr
    );
    sws_scale(openCVBGRToAVFrameSwsContext,
        &input_mat.data,
        cvLinesizes,
        0,
        image_height,
        out_avframe->data,
        out_avframe->linesize);
    if (openCVBGRToAVFrameSwsContext != nullptr)
    {
        sws_freeContext(openCVBGRToAVFrameSwsContext);
        openCVBGRToAVFrameSwsContext = nullptr;
    }
}
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:FFmpeg – 常用的视频像素格式以及使用SwsContext和sws_scale进行视频像素格式转换和视频缩放
原文链接:https://www.stubbornhuang.com/2135/
发布于:2022年05月21日 9:20:08
修改于:2023年06月26日 20:09:44
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
 
				 
 
 
																					 
														
						 
														
						 
														
						 
														
						 
														
						
评论
70