SDL2 基础(三)40行代码渲染一个YUV视频

1,342 阅读2分钟

40行代码渲染一个YUV视频

任何问题加 QQ群 981886174 联系

先直接上代码。

由于代码非常短直接上代码了,后面会简单解释

文件直接写死在代码里,简单测试使用,路径改成自己的就可以"G:/data/highway_cif.yuv" 数据 直接网上下载 ,我这里提供一份免积分下载 download.csdn.net/download/An… 文件 这里删除非常多的代码。只为了用最简洁的方式把YUV 视频内容显示出来。去掉冗余代码。能更简单的理解,如果需要项目里使用必须加入所有的销毁。

#include <iostream>
extern "C" {
#include "SDL.h"
}  

int main(int argc, char* argv[]) {

    int window_width = 352, window_height = 288; //窗口 大小/分辨率
    const int video_width = 352, video_height = 288;// 视频文件 分辨率   (352x288)  (176x144)

    const int fream_size = video_width * video_height * 3 / 2;
    unsigned char fream_buffer[fream_size]; // 定义一个数据帧

    SDL_Init(SDL_INIT_VIDEO); 
    SDL_Window* window = SDL_CreateWindow("YUV SDL2 Play", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height,  SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); 
    SDL_Renderer* sdlRenderer = SDL_CreateRenderer(window, -1, 0); 
    SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV , SDL_TEXTUREACCESS_STREAMING, video_width , video_height); 
    SDL_Rect sdlRect{ 0,0, window_width, window_height };
    
    // 读取 文件 
    FILE* fp = fopen("G:/data/highway_cif.yuv", "rb+");    if (fp == NULL) {  return -1;   } 

    while (1) {
        // 读取一帧数数据到缓冲区
        if (fread(fream_buffer, 1, fream_size, fp) != fream_size) {
            // Loop
            //fseek(fp, 0, SEEK_SET);
            fread(fream_buffer,1, fream_size, fp);
        }
        // 将数据更新到纹理
        SDL_UpdateTexture(sdlTexture, NULL, fream_buffer, video_width);//??? 
        SDL_RenderClear(sdlRenderer);
        // 将更新后的纹理拷贝到渲染器
        SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect);
        // 渲染器显示画面
        SDL_RenderPresent(sdlRenderer); 
        SDL_Delay(40);  
    } 
    return 0;  
}
重点代码

整个代码显示内容部分就是使用这个 刷新纹理,然后就显示到项目里了

更新纹理
SDL_UpdateTexture(sdlTexture, NULL, fream_buffer, video_width);
复制到渲染器
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect);

首先会创建一个帧缓冲器,这里使用一个byte数组。大小为一帧数据的大小 然后读取文件把文件数据读入到这个帧缓冲区的 数组里 读取一帧 马上渲染到屏幕 然后 休息40毫秒 继续刷新 这个40 毫秒需要根据 YUV 文件帧率计算 正常应该是 1000/22 这里22 表示帧率 根据视频具体帧率计算就可以。

内容非常少,比如读取文件,这些属于基础内容,这里不去扩展,只是简单介绍SDL最基础的使用。