【FFmpeg 系列】 SDL 音视频渲染(七)

1、SDL 介绍

  • SDL(Simple DirectMedia Layer):一个简单的多媒体层
  • 由 C 语言实现的跨平台的媒体开源库
  • 多用于开发游戏、模拟器、媒体播放器等多媒体应用领域
  • 版本:SDL1.2(老)、SDL2.0(新),以 SDL2.0 为基础
  • 官网:https://www.libsdl.org/index.php

2、SDL 编译与安装

// 第一步:下载 SDL 源码
https://www.libsdl.org/release/SDL2-2.0.20.tar.gz
// 第二步:解压缩
tar SDL2-2.0.20.tar.gz
// 第三步:生成 Makefile
cd SDL2-2.0.20 目录,并执行 ./configure --prefix=/usr/local
// 第四步:安装
sudo make -j 8 && make install

3、SDL 基本使用步骤

  • API:
<!-- 头文件 -->
// 添加头文件:
#include

// 初始化 SDL
SDL_Init()
// 退出 SDL
SDL_Quit()

<!-- SDL 渲染窗口 -->
// 创建渲染窗口
SDL_CreateWindow()
// 销毁渲染窗口
SDL_DestroyWindow()

<!-- SDL 渲染器 -->
// 创建渲染器,用作于将图形、视频帧给绘制到窗口
SDL_CreateRenderer()
// 销毁渲染器
SDL_DestroyRenderer()
// 设置渲染器颜色
SDL_SetRenderDrawColor()
// 清空渲染器,防止上次遗留的数据同时被渲染出去
SDL_RenderClear()
// 将渲染器数据推送到驱动去
SDL_RenderPresent()
  • 示例:
#include 

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

    SDL_Window *window = NULL;
    SDL_Renderer *render = NULL;
    // 初始化 SDL
    SDL_Init(SDL_INIT_VIDEO);
    // 创建渲染窗口(窗口名,x轴角标,y轴角标,宽度,高度,窗口属性)
    window = SDL_CreateWindow("SDL2 Window", 200, 200, 640, 480, SDL_WINDOW_SHOWN);
    if (!window) {
        SDL_Log("Failed to create window!");
        goto __EXIT;
    }
    // 创建渲染器
    render = SDL_CreateRenderer(window, -1, 0);
    if (!render) {
        SDL_Log("Failed to create render!");
        goto __DWINODW;
    }
    // 设置渲染器颜色色值
    SDL_SetRenderDrawColor(render, 255, 0, 0, 255);
    // 清空渲染器
    SDL_RenderClear(render);
    // 将渲染器数据推送到驱动去
    SDL_RenderPresent(render);
    // SDL 延迟10000毫秒
    SDL_Delay(10000);

    SDL_DestroyRenderer(render);// 销毁渲染器

    __DWINODW:
    SDL_DestroyWindow(window);// 销毁渲染窗口
    __EXIT:
    SDL_Quit();// 退出 SDL

    return 0;
}
  • 编译与运行:
clang -g -o 13_ff_hello_sdl 13_ff_hello_sdl.c `pkg-config --cflags --libs sdl2`

// 执行编译后的结果:
./13_ff_hello_sdl

4、SDL 事件基本原理

  • SDL 将所有事件都存放在一个队列中
  • SDL 所有对事件的操作,其实就是对队列的操作
  • SDL 事件种类 API:
// 窗口事件
SDL_WindowEvent
// 键盘事件
SDL_KeyboardEvent
// 鼠标事件
SDL_MouseMotionEvent
// 如果以上事件都不能满足需求,还可以自己进行事件定义和处理操作
  • SDL 事件处理 API:
// 轮训事件处理
SDL_PollEvent
// 等待事件处理
SDL_WaitEvent
  • 示例:
#include 

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

    SDL_Window *window = NULL;
    SDL_Renderer *render = NULL;
    int quit = 1;
    SDL_Event event;

    // 初始化 SDL
    SDL_Init(SDL_INIT_VIDEO);
    // 创建渲染窗口(窗口名,x轴角标,y轴角标,宽度,高度,窗口属性)
    window = SDL_CreateWindow("SDL2 Window", 200, 200, 640, 480, SDL_WINDOW_SHOWN);
    if (!window) {
        SDL_Log("Failed to create window!");
        goto __EXIT;
    }
    // 创建渲染器
    render = SDL_CreateRenderer(window, -1, 0);
    if (!render) {
        SDL_Log("Failed to create render!");
        goto __DWINODW;
    }
    // 设置渲染器颜色色值
    SDL_SetRenderDrawColor(render, 255, 0, 0, 255);
    // 清空渲染器
    SDL_RenderClear(render);
    // 将渲染器数据推送到驱动去
    SDL_RenderPresent(render);
    do {
        SDL_WaitEvent(&event);
        switch (event.type) {
            case SDL_QUIT:
                quit = 0;
                break;
            default:
                SDL_Log("event type is %d", event.type);
        }
    } while (quit);

    SDL_DestroyRenderer(render);// 销毁渲染器

    __DWINODW:
    SDL_DestroyWindow(window);// 销毁渲染窗口
    __EXIT:
    SDL_Quit();// 退出 SDL

    return 0;
}
  • 编译与运行:
clang -g -o 14_ff_event_sdl 14_ff_event_sdl.c `pkg-config --cflags --libs sdl2`

// 执行编译后的结果:
./14_ff_event_sdl

5、SDL 纹理渲染

  • 基本原理流程图:
    【FFmpeg 系列】 SDL 音视频渲染(七)_第1张图片
  • API:
#include 

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

    SDL_Window *window = NULL;
    SDL_Renderer *render = NULL;
    SDL_Texture *texture = NULL;
    int quit = 1;
    SDL_Event event;

    SDL_Rect rect;
    rect.w = 30;
    rect.y = 30;

    // 初始化 SDL
    SDL_Init(SDL_INIT_VIDEO);
    // 创建渲染窗口(窗口名,x轴角标,y轴角标,宽度,高度,窗口属性)
    window = SDL_CreateWindow("SDL2 Window", 200, 200, 640, 480, SDL_WINDOW_SHOWN);
    if (!window) {
        SDL_Log("Failed to create window!");
        goto __EXIT;
    }
    // 创建渲染器
    render = SDL_CreateRenderer(window, -1, 0);
    if (!render) {
        SDL_Log("Failed to create render!");
        goto __DWINODW;
    }
    // 设置渲染器颜色色值
    SDL_SetRenderDrawColor(render, 255, 0, 0, 255);
    // 清空渲染器
    SDL_RenderClear(render);
    // 将渲染器数据推送到驱动去
    SDL_RenderPresent(render);
    // 创建渲染器纹理
    texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 640, 480);
    if (!texture) {
        SDL_Log("Failed to create Texture!");
        goto __RENDER;
    }
    do {
        SDL_WaitEvent(&event);
        switch (event.type) {
            case SDL_QUIT:
                quit = 0;
                break;
            default:
                SDL_Log("event type is %d", event.type);
        }
        rect.x = rand() % 600;
        rect.y = rand() % 450;

        SDL_SetRenderTarget(render, texture);
        SDL_SetRenderDrawColor(render, 0, 0, 0, 0);
        SDL_RenderClear(render);

        SDL_RenderDrawRect(render, &rect);
        SDL_SetRenderDrawColor(render, 255, 0, 0, 0);
        SDL_RenderFillRect(render, &rect);

        SDL_SetRenderTarget(render, NULL);
        SDL_RenderCopy(render, texture, NULL, NULL);

        SDL_RenderPresent(render);

    } while (quit);
    SDL_DestroyTexture(texture);// 销毁渲染器纹理

    __RENDER:
    SDL_DestroyRenderer(render);// 销毁渲染器
    __DWINODW:
    SDL_DestroyWindow(window);// 销毁渲染窗口
    __EXIT:
    SDL_Quit();// 退出 SDL

    return 0;
}
  • 编译与运行:
clang -g -o 15_ff_texture_sdl 15_ff_texture_sdl.c `pkg-config --cflags --libs sdl2`

// 执行编译后的结果:
./15_ff_texture_sdl

5、实现 YUV 视频播放器

  • API:
<!-- SDL 创建线程 -->
// 创建 SDL 线程
SDL_CreateThread()
// 参数解析:
fn:线程执行函数
name:线程名
data:执行函数参数

<!-- 更新纹理 -->
// 更新 SDL 纹理
SDL_UpdateTexture()
// 更新 SDL 纹理,参数更多,但是效率更高
SDL_UpdateYUVTexture()

你可能感兴趣的:(FFmpeg,音视频)