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

举报
DS小龙哥 发表于 2021/12/10 01:17:23 2021/12/10
【摘要】 一、环境介绍 FFMPEG版本: 4.2.2  测试系统:ubuntu18.04 二、示例代码 /*YUYV转QImage格式*/QImage YUYV422_TO_QImage(uint8_t *yuyv422,int image_width,int image_height){ uint8_t *out_bu...

一、环境介绍

FFMPEG版本: 4.2.2 

测试系统:ubuntu18.04

二、示例代码


  
  1. /*
  2. YUYV转QImage格式
  3. */
  4. QImage YUYV422_TO_QImage(uint8_t *yuyv422,int image_width,int image_height)
  5. {
  6. uint8_t *out_buffer= nullptr;
  7. AVFrame *Input_pFrame= nullptr;
  8. AVFrame *Output_pFrame = nullptr;
  9. struct SwsContext *img_convert_ctx=nullptr; //用于解码后的视频格式转换
  10. /*1. 申请空间*/
  11. Output_pFrame = av_frame_alloc(); //存放RGB数据的缓冲区
  12. Input_pFrame = av_frame_alloc();//存放YUV数据的缓冲区
  13. /*2.设置转码参数*/
  14. img_convert_ctx=sws_getContext(image_width, image_height,AV_PIX_FMT_YUYV422,
  15. image_width, image_height,AV_PIX_FMT_RGB24,
  16. SWS_BICUBIC, nullptr, nullptr, nullptr);
  17. /*3. 申请转码需要空间*/
  18. //获取转码后数据需要的内存空间大小
  19. int numBytes = avpicture_get_size(AV_PIX_FMT_RGB24,image_width,image_height);
  20. //申请空间
  21. out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
  22. /*4. 设置转码的源数据地址*/
  23. avpicture_fill((AVPicture *) Output_pFrame, out_buffer, AV_PIX_FMT_RGB24,image_width, image_height);
  24. avpicture_fill((AVPicture *) Input_pFrame, yuyv422, AV_PIX_FMT_YUYV422,image_width, image_height);
  25. //转格式
  26. sws_scale(img_convert_ctx,
  27. (uint8_t const **) Input_pFrame->data,
  28. Input_pFrame->linesize, 0, image_height, Output_pFrame->data,
  29. Output_pFrame->linesize);
  30. //加载图片数据
  31. QImage image(out_buffer,image_width,image_height,QImage::Format_RGB888);
  32. //释放空间
  33. if(Input_pFrame)av_free(Input_pFrame);
  34. if(Output_pFrame)av_free(Output_pFrame);
  35. if(out_buffer) av_free(out_buffer);
  36. if(img_convert_ctx)sws_freeContext(img_convert_ctx);
  37. return image.copy();
  38. }
  39. /*
  40. YUYV转YUV420P格式
  41. */
  42. void YUYV422_TO_YUV420P(uint8_t *yuyv422,uint8_t *yuv420p,int video_width,int video_height)
  43. {
  44. AVFrame *Input_pFrame= nullptr;
  45. AVFrame *Output_pFrame = nullptr;
  46. struct SwsContext *img_convert_ctx=nullptr; //用于解码后的格式转换
  47. /*1. 申请空间*/
  48. Input_pFrame = av_frame_alloc();
  49. Output_pFrame = av_frame_alloc();
  50. /*2.设置转码参数*/
  51. img_convert_ctx=sws_getContext(video_width, video_height,AV_PIX_FMT_YUYV422, //输入
  52. video_width, video_height,AV_PIX_FMT_YUV420P, //输出
  53. SWS_BICUBIC, nullptr, nullptr, nullptr);
  54. /*3. 申请转码需要空间*/
  55. /*4. 设置转码的源数据地址*/
  56. avpicture_fill((AVPicture *) Input_pFrame, yuyv422, AV_PIX_FMT_YUYV422,video_width, video_height);
  57. avpicture_fill((AVPicture *) Output_pFrame, yuv420p, AV_PIX_FMT_YUV420P,video_width, video_height);
  58. //转格式
  59. sws_scale(img_convert_ctx,
  60. (uint8_t const **) Input_pFrame->data,Input_pFrame->linesize,
  61. 0, video_height, Output_pFrame->data,Output_pFrame->linesize);
  62. //释放空间
  63. if(Input_pFrame)av_free(Input_pFrame);
  64. if(Output_pFrame)av_free(Output_pFrame);
  65. if(img_convert_ctx)sws_freeContext(img_convert_ctx);
  66. }
  67. /*
  68. YUYV422转RGB888格式
  69. */
  70. void YUYV422_TO_RGB888(uint8_t *yuyv422,uint8_t *rgb888,int image_width,int image_height)
  71. {
  72. AVFrame *Input_pFrame= nullptr;
  73. AVFrame *Output_pFrame = nullptr;
  74. struct SwsContext *img_convert_ctx=nullptr; //用于解码后的视频格式转换
  75. /*1. 申请空间*/
  76. Output_pFrame = av_frame_alloc(); //存放RGB数据的缓冲区
  77. Input_pFrame = av_frame_alloc();//存放YUV数据的缓冲区
  78. /*2.设置转码参数*/
  79. img_convert_ctx=sws_getContext(image_width, image_height,AV_PIX_FMT_YUYV422,
  80. image_width, image_height,AV_PIX_FMT_RGB24,
  81. SWS_BICUBIC, nullptr, nullptr, nullptr);
  82. /*4. 设置转码的源数据地址*/
  83. avpicture_fill((AVPicture *) Output_pFrame, rgb888, AV_PIX_FMT_RGB24,image_width, image_height);
  84. avpicture_fill((AVPicture *) Input_pFrame, yuyv422, AV_PIX_FMT_YUYV422,image_width, image_height);
  85. //转格式
  86. sws_scale(img_convert_ctx,
  87. (uint8_t const **) Input_pFrame->data,
  88. Input_pFrame->linesize, 0, image_height, Output_pFrame->data,
  89. Output_pFrame->linesize);
  90. //释放空间
  91. if(Input_pFrame)av_free(Input_pFrame);
  92. if(Output_pFrame)av_free(Output_pFrame);
  93. if(img_convert_ctx)sws_freeContext(img_convert_ctx);
  94. }

 

文章来源: xiaolong.blog.csdn.net,作者:DS小龙哥,版权归原作者所有,如需转载,请联系作者。

原文链接:xiaolong.blog.csdn.net/article/details/105978677

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。