前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用FFMPEG的sws_scale函数实现各种原始颜色格式互转(YUV\RGB\)

使用FFMPEG的sws_scale函数实现各种原始颜色格式互转(YUV\RGB\)

作者头像
DS小龙哥
发布2022-01-17 15:15:20
1.6K0
发布2022-01-17 15:15:20
举报
文章被收录于专栏:嵌入式项目开发

一、环境介绍

FFMPEG版本: 4.2.2

测试系统:ubuntu18.04

二、示例代码

代码语言:javascript
复制
/*
YUYV转QImage格式
*/
QImage YUYV422_TO_QImage(uint8_t *yuyv422,int image_width,int image_height)
{
    uint8_t *out_buffer= nullptr;
    AVFrame *Input_pFrame= nullptr;
    AVFrame *Output_pFrame = nullptr;
    struct SwsContext *img_convert_ctx=nullptr;  //用于解码后的视频格式转换
    /*1. 申请空间*/
    Output_pFrame = av_frame_alloc();  //存放RGB数据的缓冲区
    Input_pFrame = av_frame_alloc();//存放YUV数据的缓冲区
    /*2.设置转码参数*/
    img_convert_ctx=sws_getContext(image_width, image_height,AV_PIX_FMT_YUYV422,
                                   image_width, image_height,AV_PIX_FMT_RGB24,
                                   SWS_BICUBIC, nullptr, nullptr, nullptr);
    /*3. 申请转码需要空间*/
    //获取转码后数据需要的内存空间大小
    int numBytes = avpicture_get_size(AV_PIX_FMT_RGB24,image_width,image_height);
    //申请空间
    out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
    /*4. 设置转码的源数据地址*/
    avpicture_fill((AVPicture *) Output_pFrame, out_buffer, AV_PIX_FMT_RGB24,image_width, image_height);
    avpicture_fill((AVPicture *) Input_pFrame, yuyv422, AV_PIX_FMT_YUYV422,image_width, image_height);

    //转格式
    sws_scale(img_convert_ctx,
     (uint8_t const **) Input_pFrame->data,
     Input_pFrame->linesize, 0, image_height, Output_pFrame->data,
     Output_pFrame->linesize);

    //加载图片数据
    QImage image(out_buffer,image_width,image_height,QImage::Format_RGB888);

    //释放空间
    if(Input_pFrame)av_free(Input_pFrame);
    if(Output_pFrame)av_free(Output_pFrame);
    if(out_buffer) av_free(out_buffer);
    if(img_convert_ctx)sws_freeContext(img_convert_ctx);
    return image.copy();
}

/*
YUYV转YUV420P格式
*/
void YUYV422_TO_YUV420P(uint8_t *yuyv422,uint8_t *yuv420p,int video_width,int video_height)
{
    AVFrame *Input_pFrame= nullptr;
    AVFrame *Output_pFrame = nullptr;
    struct SwsContext *img_convert_ctx=nullptr; //用于解码后的格式转换
    /*1. 申请空间*/
    Input_pFrame = av_frame_alloc();
    Output_pFrame = av_frame_alloc();
    /*2.设置转码参数*/
    img_convert_ctx=sws_getContext(video_width, video_height,AV_PIX_FMT_YUYV422, //输入
                                   video_width, video_height,AV_PIX_FMT_YUV420P,   //输出
                                   SWS_BICUBIC, nullptr, nullptr, nullptr);
    /*3. 申请转码需要空间*/
    /*4. 设置转码的源数据地址*/
    avpicture_fill((AVPicture *) Input_pFrame, yuyv422, AV_PIX_FMT_YUYV422,video_width, video_height);
    avpicture_fill((AVPicture *) Output_pFrame, yuv420p, AV_PIX_FMT_YUV420P,video_width, video_height);

    //转格式
    sws_scale(img_convert_ctx,
     (uint8_t const **) Input_pFrame->data,Input_pFrame->linesize,
      0, video_height, Output_pFrame->data,Output_pFrame->linesize);
    //释放空间
    if(Input_pFrame)av_free(Input_pFrame);
    if(Output_pFrame)av_free(Output_pFrame);
    if(img_convert_ctx)sws_freeContext(img_convert_ctx);
}

/*
YUYV422转RGB888格式
*/
void YUYV422_TO_RGB888(uint8_t *yuyv422,uint8_t *rgb888,int image_width,int image_height)
{
    AVFrame *Input_pFrame= nullptr;
    AVFrame *Output_pFrame = nullptr;
    struct SwsContext *img_convert_ctx=nullptr;  //用于解码后的视频格式转换
    /*1. 申请空间*/
    Output_pFrame = av_frame_alloc();  //存放RGB数据的缓冲区
    Input_pFrame = av_frame_alloc();//存放YUV数据的缓冲区
    /*2.设置转码参数*/
    img_convert_ctx=sws_getContext(image_width, image_height,AV_PIX_FMT_YUYV422,
                                   image_width, image_height,AV_PIX_FMT_RGB24,
                                   SWS_BICUBIC, nullptr, nullptr, nullptr);
    /*4. 设置转码的源数据地址*/
    avpicture_fill((AVPicture *) Output_pFrame, rgb888, AV_PIX_FMT_RGB24,image_width, image_height);
    avpicture_fill((AVPicture *) Input_pFrame, yuyv422, AV_PIX_FMT_YUYV422,image_width, image_height);

    //转格式
    sws_scale(img_convert_ctx,
     (uint8_t const **) Input_pFrame->data,
     Input_pFrame->linesize, 0, image_height, Output_pFrame->data,
     Output_pFrame->linesize);

    //释放空间
    if(Input_pFrame)av_free(Input_pFrame);
    if(Output_pFrame)av_free(Output_pFrame);
    if(img_convert_ctx)sws_freeContext(img_convert_ctx);
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/05/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、环境介绍
  • 二、示例代码
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档