1.RGB和YUV在内存中如何存储
2.SDL2渲染RGB
3.SDL2渲染YUV
1.RGB和YUV在内存中如何存储
RGB存储的方式:
读取RGB的代码:
- void TestRGB::paintEvent(QPaintEvent* ev)
- {
- //1.QImage 存放RGB矩阵 后面专业术语叫材质
- QImage img(w,h,QImage::Format_RGB888);
- auto d = img.bits();
- unsigned char r = 255;
- for (int j = 0; j < h; j++)
- {
- r--;
- int b = j * w * 3;
- for (int i = 0; i < w * 3; i+=3)
- {
- d[b+i] = r; //R
- d[b + i + 1] = 0; //G
- d[b + i + 2] = 0; //B
- }
- }
- //2.QPainter 显示RGB矩阵 后面专业术语叫渲染器
- QPainter p;
- p.begin(this);
- p.drawImage(0, 0, img);
- p.end();
- }
YUV格式是不被显卡显示的,要转换成RGB.是用软件把YUV文件转换成RGB软件的。
2.SDL2渲染RGB
2.1,安装和配置SDL2的环境。简单的下载包,配置dll,lib,include三个路径入工程。
2.2, 2个词 :渲染器(一个窗口),材质(用于承载图像) 。还有一个内存数组用于存放RGBA的数据,可把这个内存数据写入材质中。
基本的使用流程如下:
代码如下:
- #include
- #include
- using namespace std;
- #pragma comment(lib,"SDL2.lib")
- #undef main
- int main(int argc, char* argv[])
- {
- int w = 800;
- int h = 600;
- //1 初始化SDL video库
- if (SDL_Init(SDL_INIT_VIDEO))
- {
- cout << SDL_GetError() << endl;
- return -1;
- }
- //2 生成SDL 窗口
- auto screen = SDL_CreateWindow("test sdl ffmpeg",
- SDL_WINDOWPOS_CENTERED,//窗口位置
- SDL_WINDOWPOS_CENTERED,
- w,h,
- SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE
- );
- if (!screen)
- {
- cout << SDL_GetError() << endl;
- return -2;
- }
-
- //3 生成渲染器
- auto render = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
- if (!render)
- {
- cout << SDL_GetError() << endl;
- return -3;
- }
- //4 生成材质
- auto texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_ARGB8888,
- SDL_TEXTUREACCESS_STREAMING,// 可加锁
- w, h
- );
- if (!texture)
- {
- cout << SDL_GetError() << endl;
- return -4;
- }
-
- // 存放图像的数据
- shared_ptr<unsigned char> rgb(new unsigned char[w * h * 4]);
- auto r = rgb.get();
- unsigned char tmp = 255;
- for (;;)
- {
- //判断退出
- SDL_Event ev;
- SDL_WaitEventTimeout(&ev, 10);
- if (ev.type == SDL_QUIT)
- {
- SDL_DestroyWindow(screen);
- break;
- }
- tmp--;
-
- for (int j = 0; j < h; j++)
- {
- int b = j * w * 4;
- for (int i = 0; i < w*4; i += 4)
- {
- r[b + i] = 0; //B
- r[b + i + 1] = 0; //G
- r[b + i + 2] = tmp; //R
- r[b + i + 3] = 0; //A
- }
- }
- //5 内存数据写入材质
- SDL_UpdateTexture(texture, NULL, r, w * 4);
-
- //6 清理屏幕
- SDL_RenderClear(render);
- SDL_Rect sdl_rect;
- sdl_rect.x = 0;
- sdl_rect.y = 0;
- sdl_rect.w = w;
- sdl_rect.h = h;
-
- //7 复制材质到渲染器
- SDL_RenderCopy(render, texture,
- NULL,//原图位置和尺寸
- &sdl_rect//目标位置和尺寸
- );
- //8 渲染
- SDL_RenderPresent(render);
- }
- getchar();
- return 0;
- }
以上就是基本函数。
定时刷新的就是材质中的rgb值,具体就是
SDL_UpdateTexture(sdl_texture, NULL, rgb, sdl_width * pix_size);
3.SDL2渲染YUVYUV格式分析:
4个像素点共享1个UV 实心代表亮度,空心的代表色度。
代码如下:
这个版本已经是定时刷新屏幕了。
- #include "sdlqtrgb.h"
- #include
- #include
- #include
- using namespace std;
- #pragma comment(lib,"SDL2.lib")
- static SDL_Window* sdl_win = NULL;
- static SDL_Renderer* sdl_render = NULL;
- static SDL_Texture* sdl_texture = NULL;
- static int sdl_width = 0;
- static int sdl_height = 0;
- static unsigned char* yuv = NULL;
- static int pix_size = 2;
- static ifstream yuv_file;
- void SdlQtRGB::timerEvent(QTimerEvent* ev)
- {
- yuv_file.read((char*)yuv, sdl_width * sdl_height * 1.5);
- //yuv 平面存储存储
- // yyyyyyyy uu vv
- SDL_UpdateTexture(sdl_texture, NULL, yuv,
- sdl_width //一行 y的字节数
- );
- SDL_RenderClear(sdl_render);
- SDL_Rect rect;
- rect.x = 0;
- rect.y = 0;
- rect.w = sdl_width;
- rect.h = sdl_height;
- SDL_RenderCopy(sdl_render,sdl_texture,NULL,&rect);
- SDL_RenderPresent(sdl_render);
- }
-
- SdlQtRGB::SdlQtRGB(QWidget *parent)
- : QWidget(parent)
- {
- //打开yuv文件
- yuv_file.open("400_300_25.yuv", ios::binary);
- if (!yuv_file)
- {
- QMessageBox::information(this, "", "open yuv failed!");
- return;
- }
- ui.setupUi(this);
- sdl_width = 400;
- sdl_height = 300;
- ui.label->resize(sdl_width, sdl_height);
- //初始化SDL
- SDL_Init(SDL_INIT_VIDEO);
- //创建窗口
- sdl_win = SDL_CreateWindowFrom((void*)ui.label->winId());
- //创建渲染器
- sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
- //创建材质 支持YUV
- sdl_texture = SDL_CreateTexture(sdl_render,
- SDL_PIXELFORMAT_IYUV,
- SDL_TEXTUREACCESS_STREAMING,
- sdl_width,
- sdl_height
- );
- yuv = new unsigned char[sdl_width * sdl_height * pix_size];
- startTimer(10);
- }