一、概述
上一节使用SDL2在窗口上显示了一张图片,本节使用SDL2播放YUV420P数据。
YUV420P一帧数据的长度=width*height*3/2
二、代码示例
下面这段示例代码读取YUV数据和现实YUV数据都是在同一个线程中的。播放是能播放,但是会很卡,不一会儿就会出现无响应的情况。下一节使用多线程进行改造
#include "include/sdl_read_yuv.h" #include <iostream> using namespace std; SDLReadYuv::SDLReadYuv() { const int bpp = 12; int window_w = 640, window_h = 360; const int pixel_w = 640, pixel_h = 360; unsigned char buffer[pixel_w * pixel_h * bpp / 8]; if (SDL_Init(SDL_INIT_VIDEO)) { cout << "初始化SDL失败" << SDL_GetError() << endl; return; } SDL_Window* window; window = SDL_CreateWindow("Simplest Video Play SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_w, window_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); if (!window) { cout << "SDL: could not create window" << SDL_GetError() << endl; return; } SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0); Uint32 pixFormat = 0; pixFormat = SDL_PIXELFORMAT_IYUV; SDL_Texture* texture = SDL_CreateTexture(renderer, pixFormat, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h); FILE* fp = NULL; fp = fopen("E:/tony/demo/visualstudio_workspace/SDLDemo/out/build/x64-debug/SDLDemo/yuv/sintel_640_360.yuv", "rb+"); if (fp == NULL) { cout << "cannot open this file" << endl; return; } //这个区域会存放显示的视频 SDL_Rect sdlRect; while (true) { //这里是读取一帧视频真,数据格式是YUV420P,像素排列是4:2:0,一行像素=width*height+width*1/4+height*1/4 = width*height*3/2 //所以下面这句话刚好就是读取了一个视频帧YUV的数据长度 if (fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp) != pixel_w * pixel_h * bpp / 8) { // Loop fseek(fp, 0, SEEK_SET); fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp); } SDL_UpdateTexture(texture, NULL, buffer, pixel_w); sdlRect.x = 0; sdlRect.y = 0; sdlRect.w = window_w; sdlRect.h = window_h;//把视频就显示到这个区域 SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, &sdlRect); SDL_RenderPresent(renderer); SDL_Delay(40); } SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); }
标签:include,int,YUV,SDL,播放,pixel From: https://www.cnblogs.com/tony-yang-flutter/p/17831972.html