• SDL 开发实战(六): 使用 SDL 实现 YUV 播放器


    前面铺垫了这么多,现在终于进入核心的主题了,那就是使用SDL播放视频,本节我们将使用SDL播放YUV视频,也就是做一个YUV播放器。

    下面说明一下使用SDL播放YUV视频的基本流程,主要分为两大部分:初始化SDL、循环显示画面。

    1. 初始化SDL

    1). 初始化SDL (SDL_Init)
    2). 创建窗口(SDL_CreateWindow)
    3). 基于窗口创建渲染器(SDL_CreateRenderer)
    4). 创建纹理(SDL_CreateTexture)

    2. 循环显示画面

    1). 设置纹理的数据(SDL_UpdateTexture)
    2). 纹理复制给渲染目标(SDL_RenderCopy)
    3). 显示(SDL_RenderPresent)

    具体涉及到每个API的含义,这里就不过多介绍了,在之前的内容中,我们已经都做了说明,下面我们直接开始实战。

    实战

    // SDL.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include "pch.h"
    #include <iostream>
    
    extern "C" {
    #include "SDL.h"
    }
    
    //Bit per Pixel
    const int bpp = 12;
    
    int screen_w = 500, screen_h = 500;
    
    // 根据不同的YUV视频,来设置不同的 宽 * 高 数据 
    const int pixel_w = 352, pixel_h = 288;
    
    unsigned char buffer[pixel_w*pixel_h*bpp / 8];
    
    //Refresh Event
    #define REFRESH_EVENT  (SDL_USEREVENT + 1)
    
    int thread_exit = 0;
    
    int refresh_video(void *opaque) {
        while (thread_exit == 0) {
            SDL_Event event;
            event.type = REFRESH_EVENT;
            SDL_PushEvent(&event);
            SDL_Delay(40);
        }
        return 0;
    }
    
    int main(int argc, char* argv[])
    {
        if (SDL_Init(SDL_INIT_VIDEO)) {
            printf("Could not initialize SDL - %s
    ", SDL_GetError());
            return -1;
        }
    
        SDL_Window *window;
    
        // 创建SDL窗口
        window = SDL_CreateWindow("Simplest Video Play SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 
          screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); // 判断是否创建窗口成功 if (!window) { printf("SDL: could not create window - exiting:%s ", SDL_GetError()); return -1; } // 创建SDL渲染器 SDL_Renderer* sdlRenderer = SDL_CreateRenderer(window, -1, 0); // 声明像素格式 Uint32 pixformat = 0; // IYUV: Y + U + V (3 planes) // YV12: Y + V + U (3 planes) // I420也叫IYUV, 也叫YUV420 pixformat = SDL_PIXELFORMAT_IYUV; // 按照YUV视频的宽高创建SDL纹理对象 SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer, pixformat, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h); FILE *fp = NULL; fp = fopen("222.yuv", "rb+"); if (fp == NULL) { printf("cannot open this file "); return -1; } SDL_Rect sdlRect; SDL_Thread *refresh_thread = SDL_CreateThread(refresh_video, NULL, NULL); SDL_Event event; while (1) { //Wait SDL_WaitEvent(&event); if (event.type == REFRESH_EVENT) { // 读取一帧数数据到缓冲区 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(sdlTexture, NULL, buffer, pixel_w); //FIX: If window is resize sdlRect.x = 0; sdlRect.y = 0; sdlRect.w = screen_w; sdlRect.h = screen_h; SDL_RenderClear(sdlRenderer); // 将更新后的纹理拷贝到渲染器 SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); // 渲染器显示画面 SDL_RenderPresent(sdlRenderer); //Delay 40ms -- Dealy时常根据帧率进行调整 SDL_Delay(40); } else if (event.type == SDL_WINDOWEVENT) { //If Resize SDL_GetWindowSize(window, &screen_w, &screen_h); } else if (event.type == SDL_QUIT) { break; } } return 0; }

    运行效果:

  • 相关阅读:
    wamp5配置及 phpmyadmin密码修改问题
    mysql存储过程详解
    office2013的破解方法
    java jdk配置环境变量
    打包Asp.Net 网站成为一个exe 方便快捷的进行客户演示
    CUDA的学习
    深度学习3线性回归,逻辑回归
    三维重建学习1特征提取
    深度学习2线性回归,逻辑回归
    特征学习2
  • 原文地址:https://www.cnblogs.com/renhui/p/10469980.html
Copyright © 2020-2023  润新知