返回

音视频连载-005:基础学习篇——SDL 加载 YUV 文件并显示

Android

在音视频学习的道路上,我们已经掌握了图片的加载与显示,那么接下来,让我们挑战一个更高级的任务:加载 YUV 文件并显示。

引言:探索 YUV 文件的奥秘

YUV 是图像和视频领域中广泛使用的一种色彩空间模型。与 RGB 模型相比,YUV 模型更接近于人类对色彩的感知,因此常用于视频编码和传输。本次实践,我们将深入了解 YUV420P 文件格式,并学习如何使用 SDL 库加载和显示 YUV 文件。

准备工作:打造一个 YUV 文件

首先,我们需要一个 YUV 文件来进行操作。考虑到网上很难找到现成的 YUV 文件,我们巧妙地利用 FFmpeg 工具来自行生成。FFmpeg 是一个强大的多媒体框架,可用于处理各种音视频格式。

使用 FFmpeg 生成 YUV 文件

打开命令行终端,输入以下命令:

ffmpeg -f rawvideo -s 640x480 -pix_fmt yuv420p -i - -vcodec rawvideo -f yuv4mpegpipe -

该命令将生成一个 YUV420P 格式的原始视频流。接下来,我们将此流重定向到一个文件中:

ffmpeg -f rawvideo -s 640x480 -pix_fmt yuv420p -i - -vcodec rawvideo -f yuv4mpegpipe - | ffmpeg -i - -vcodec copy output.yuv

这样,名为 output.yuv 的 YUV 文件就生成了。

SDL 库:图像处理的得力助手

SDL(Simple DirectMedia Layer)是一个跨平台的多媒体库,可用于处理图像、声音和输入设备。它为我们提供了加载和显示图像的便捷功能。

加载 YUV 文件

使用 SDL 加载 YUV 文件的步骤如下:

  1. 初始化 SDL 库
  2. 创建一个 SDL 窗口和渲染器
  3. 打开 YUV 文件
  4. 创建 SDL 纹理
  5. 将 YUV 数据加载到纹理中

显示 YUV 文件

将 YUV 数据加载到纹理后,就可以将其绘制到 SDL 窗口中进行显示了。具体的步骤包括:

  1. 清除渲染器
  2. 渲染纹理
  3. 更新窗口

实践示例:一步步加载和显示 YUV 文件

现在,让我们将理论付诸实践。下面是一个加载和显示 YUV 文件的代码示例:

#include <SDL.h>

int main() {
    // 初始化 SDL
    SDL_Init(SDL_INIT_VIDEO);

    // 创建窗口和渲染器
    SDL_Window* window = SDL_CreateWindow("YUV Loader", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    // 打开 YUV 文件
    FILE* yuvFile = fopen("output.yuv", "rb");

    // 创建 SDL 纹理
    SDL_Texture* yuvTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, 640, 480);

    // 加载 YUV 数据到纹理
    SDL_UpdateYUVTexture(yuvTexture, nullptr, nullptr, yuvFile, 640, 480);

    // 主循环
    bool running = true;
    while (running) {
        // 事件处理
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                running = false;
            }
        }

        // 清除渲染器
        SDL_RenderClear(renderer);

        // 渲染纹理
        SDL_RenderCopy(renderer, yuvTexture, nullptr, nullptr);

        // 更新窗口
        SDL_RenderPresent(renderer);
    }

    // 清理资源
    SDL_DestroyTexture(yuvTexture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

结语:解锁 YUV 处理的新技能

通过本篇文章,我们深入了解了 YUV 文件格式,学会了使用 SDL 库加载和显示 YUV 文件。这为我们后续探索音视频编解码打下了坚实的基础。今后,我们将继续探索音视频领域的更多奥秘,敬请期待!