• 欢迎大家交换友链,可在https://www.stubbornhuang.com/申请友情链接进行友链交换申请!

  • 本站由于前段时间遭受到大量临时和国外邮箱注册,所以对可注册的邮箱类型进行了限制!

  • 问题反馈可发送邮件到stubbornhuang@qq.com

  • 感谢大家访问本站,希望本站的内容可以帮助到大家!

  • 本站会放置Google广告用于维持域名以及网站服务器费用。

  • 计算机图形学与计算几何经典必备书单整理,下载链接可参考:https://www.stubbornhuang.com/1256/

  • 如果觉得本站的内容有帮助,可以考虑打赏博主哦!

  • 工资「喂饱肚子」,副业「养活灵魂」!

  • 在本站开通年度VIP,无限制下载本站资源和阅读本站文章

FFmpeg – 常用的视频像素格式以及使用SwsContext和sws_scale进行视频像素格式转换和视频缩放

FFmpeg 发布于2022-05-21 阅读 5,579次 0次评论 0次点赞 本文共3154个字,阅读需要8分钟。

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

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

文章末尾
上一篇
OpenCV|FFmpeg - OpenCV cv::Mat与FFmpeg AVFrame的相互转换
FFmpeg
下一篇
C++ - 我的代码风格/代码规范备忘
C++
当前分类随机文章推荐

发表评论

您必须 [ 登录 ] 才能发表留言!

关注我们的公众号

微信公众号