• C++-ffmpeg-2-1-RGB-YUV内存中的存储+SDL2对其渲染


    1.RGB和YUV在内存中如何存储
    2.SDL2渲染RGB
    3.SDL2渲染YUV


    1.RGB和YUV在内存中如何存储
       RGB存储的方式:
       

     读取RGB的代码

    1. void TestRGB::paintEvent(QPaintEvent* ev)
    2. {
    3. //1.QImage 存放RGB矩阵 后面专业术语叫材质
    4. QImage img(w,h,QImage::Format_RGB888);
    5. auto d = img.bits();
    6. unsigned char r = 255;
    7. for (int j = 0; j < h; j++)
    8. {
    9. r--;
    10. int b = j * w * 3;
    11. for (int i = 0; i < w * 3; i+=3)
    12. {
    13. d[b+i] = r; //R
    14. d[b + i + 1] = 0; //G
    15. d[b + i + 2] = 0; //B
    16. }
    17. }
    18. //2.QPainter 显示RGB矩阵 后面专业术语叫渲染器
    19. QPainter p;
    20. p.begin(this);
    21. p.drawImage(0, 0, img);
    22. p.end();
    23. }

      YUV格式是不被显卡显示的,要转换成RGB.是用软件把YUV文件转换成RGB软件的。
    2.SDL2渲染RGB
       2.1,安装和配置SDL2的环境。简单的下载包,配置dll,lib,include三个路径入工程。
       2.2, 2个词 :渲染器(一个窗口),材质(用于承载图像) 。还有一个内存数组用于存放RGBA的数据,可把这个内存数据写入材质中。
    基本的使用流程如下:


     代码如下:

     

    1. #include
    2. #include
    3. using namespace std;
    4. #pragma comment(lib,"SDL2.lib")
    5. #undef main
    6. int main(int argc, char* argv[])
    7. {
    8. int w = 800;
    9. int h = 600;
    10. //1 初始化SDL video库
    11. if (SDL_Init(SDL_INIT_VIDEO))
    12. {
    13. cout << SDL_GetError() << endl;
    14. return -1;
    15. }
    16. //2 生成SDL 窗口
    17. auto screen = SDL_CreateWindow("test sdl ffmpeg",
    18. SDL_WINDOWPOS_CENTERED,//窗口位置
    19. SDL_WINDOWPOS_CENTERED,
    20. w,h,
    21. SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE
    22. );
    23. if (!screen)
    24. {
    25. cout << SDL_GetError() << endl;
    26. return -2;
    27. }
    28. //3 生成渲染器
    29. auto render = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
    30. if (!render)
    31. {
    32. cout << SDL_GetError() << endl;
    33. return -3;
    34. }
    35. //4 生成材质
    36. auto texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_ARGB8888,
    37. SDL_TEXTUREACCESS_STREAMING,// 可加锁
    38. w, h
    39. );
    40. if (!texture)
    41. {
    42. cout << SDL_GetError() << endl;
    43. return -4;
    44. }
    45. // 存放图像的数据
    46. shared_ptr<unsigned char> rgb(new unsigned char[w * h * 4]);
    47. auto r = rgb.get();
    48. unsigned char tmp = 255;
    49. for (;;)
    50. {
    51. //判断退出
    52. SDL_Event ev;
    53. SDL_WaitEventTimeout(&ev, 10);
    54. if (ev.type == SDL_QUIT)
    55. {
    56. SDL_DestroyWindow(screen);
    57. break;
    58. }
    59. tmp--;
    60. for (int j = 0; j < h; j++)
    61. {
    62. int b = j * w * 4;
    63. for (int i = 0; i < w*4; i += 4)
    64. {
    65. r[b + i] = 0; //B
    66. r[b + i + 1] = 0; //G
    67. r[b + i + 2] = tmp; //R
    68. r[b + i + 3] = 0; //A
    69. }
    70. }
    71. //5 内存数据写入材质
    72. SDL_UpdateTexture(texture, NULL, r, w * 4);
    73. //6 清理屏幕
    74. SDL_RenderClear(render);
    75. SDL_Rect sdl_rect;
    76. sdl_rect.x = 0;
    77. sdl_rect.y = 0;
    78. sdl_rect.w = w;
    79. sdl_rect.h = h;
    80. //7 复制材质到渲染器
    81. SDL_RenderCopy(render, texture,
    82. NULL,//原图位置和尺寸
    83. &sdl_rect//目标位置和尺寸
    84. );
    85. //8 渲染
    86. SDL_RenderPresent(render);
    87. }
    88. getchar();
    89. return 0;
    90. }

    以上就是基本函数。
    定时刷新的就是材质中的rgb值,具体就是

    SDL_UpdateTexture(sdl_texture, NULL, rgb, sdl_width * pix_size);
    3.SDL2渲染YUVYUV格式分析:

    4个像素点共享1个UV 实心代表亮度,空心的代表色度。

     代码如下:
    这个版本已经是定时刷新屏幕了。

    1. #include "sdlqtrgb.h"
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. #pragma comment(lib,"SDL2.lib")
    7. static SDL_Window* sdl_win = NULL;
    8. static SDL_Renderer* sdl_render = NULL;
    9. static SDL_Texture* sdl_texture = NULL;
    10. static int sdl_width = 0;
    11. static int sdl_height = 0;
    12. static unsigned char* yuv = NULL;
    13. static int pix_size = 2;
    14. static ifstream yuv_file;
    15. void SdlQtRGB::timerEvent(QTimerEvent* ev)
    16. {
    17. yuv_file.read((char*)yuv, sdl_width * sdl_height * 1.5);
    18. //yuv 平面存储存储
    19. // yyyyyyyy uu vv
    20. SDL_UpdateTexture(sdl_texture, NULL, yuv,
    21. sdl_width //一行 y的字节数
    22. );
    23. SDL_RenderClear(sdl_render);
    24. SDL_Rect rect;
    25. rect.x = 0;
    26. rect.y = 0;
    27. rect.w = sdl_width;
    28. rect.h = sdl_height;
    29. SDL_RenderCopy(sdl_render,sdl_texture,NULL,&rect);
    30. SDL_RenderPresent(sdl_render);
    31. }
    32. SdlQtRGB::SdlQtRGB(QWidget *parent)
    33. : QWidget(parent)
    34. {
    35. //打开yuv文件
    36. yuv_file.open("400_300_25.yuv", ios::binary);
    37. if (!yuv_file)
    38. {
    39. QMessageBox::information(this, "", "open yuv failed!");
    40. return;
    41. }
    42. ui.setupUi(this);
    43. sdl_width = 400;
    44. sdl_height = 300;
    45. ui.label->resize(sdl_width, sdl_height);
    46. //初始化SDL
    47. SDL_Init(SDL_INIT_VIDEO);
    48. //创建窗口
    49. sdl_win = SDL_CreateWindowFrom((void*)ui.label->winId());
    50. //创建渲染器
    51. sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
    52. //创建材质 支持YUV
    53. sdl_texture = SDL_CreateTexture(sdl_render,
    54. SDL_PIXELFORMAT_IYUV,
    55. SDL_TEXTUREACCESS_STREAMING,
    56. sdl_width,
    57. sdl_height
    58. );
    59. yuv = new unsigned char[sdl_width * sdl_height * pix_size];
    60. startTimer(10);
    61. }

  • 相关阅读:
    正点原子linux阿尔法开发板使用——SPI驱动
    前端vue实现双飞翼布局【flex布局和浮动布局】
    【图像去雾】Matlab实现9种去雾图像评价
    c++新标准有用的语法特性
    HPC 集群计算类型的注意事项
    C++使用PIMPL机制优化代码结构,降低耦合,提高编译速度
    使用日志上下文聚合插件使能上下文查询及 Livetail
    PHP指定时间戳/日期加一天,一年,一周,一月
    每天5分钟快速玩转机器学习算法:带有核函数的支持向量机模型
    CentOS7安装flink1.17完全分布式
  • 原文地址:https://blog.csdn.net/aggie4628/article/details/126478983