音视频-SDL的简单使用

使用SDL进行音视频的播放

SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
SDL的下载地址: https://www.libsdl.org/
现在较为新的版本在main函数中需要添加#define SDL_MAIN_HANDLED定义, 初步代码如下:

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define SDL_MAIN_HANDLED
#include <SDL.h>

//自定义消息类型
#define REFRESH_EVENT   (SDL_USEREVENT + 1)     // 请求画面刷新事件
#define QUIT_EVENT      (SDL_USEREVENT + 2)     // 退出事件

//定义分辨率
// YUV像素分辨率
#define YUV_WIDTH   320
#define YUV_HEIGHT  240

//定义YUV格式
#define YUV_FORMAT  SDL_PIXELFORMAT_IYUV

int s_thread_exit = 0;  // 退出标志 = 1则退出

int refresh_video_timer(void *data)
{
   
    while (!s_thread_exit)
    {
   
        SDL_Event event;
        event.type = REFRESH_EVENT;
        SDL_PushEvent(&event);
        SDL_Delay(40);
    }

    s_thread_exit = 0;

    //push quit event
    SDL_Event event;
    event.type = QUIT_EVENT;
    SDL_PushEvent(&event);

    return 0;
}


int main()
{
   
    if (SDL_Init(SDL_INIT_VIDEO)) {
   
        fprintf(stderr, "Can't not initialize SDL, err: %s\n", SDL_GetError());
    }

    SDL_Event event;                    // 事件
    SDL_Rect rect;                      // 矩形
    SDL_Window *window = NULL;          // 窗口
    SDL_Renderer *renderer = NULL;      // 渲染
    SDL_Texture *texture = NULL;        // 纹理
    SDL_Thread *timer_thread = NULL;    // 请求刷新线程
    uint32_t pixformat = YUV_FORMAT;    // YUV420P,即是SDL_PIXELFORMAT_IYUV

    // 分辨率
    // 1. YUV的分辨率
    int video_width = YUV_WIDTH;
    int video_height = YUV_HEIGHT;
    // 2.显示窗口的分辨率
    int win_width = YUV_WIDTH;
    int win_height = YUV_WIDTH;

    // YUV文件句柄
    FILE *video_fd = NULL;
    const char *yuv_path = "yuv420p_320x240.yuv";

    size_t video_buff_len = 0;

    uint8_t *video_buf = NULL; //读取数据后先把放到buffer里面

    // 我们测试的文件是YUV420P格式
    uint32_t y_frame_len = video_width * video_height;
    uint32_t u_frame_len = video_width * video_height / 4; // 420p是4个y对应一个u
    uint32_t v_frame_len = video_width * video_height / 4; // 420p是4个y对应一个v
    uint32_t yuv_frame_len = y_frame_len + u_frame_len + v_frame_len;

    window = SDL_CreateWindow("Simplest YUV Player",
                              SDL_WINDOWPOS_UNDEFINED,
                              SDL_WINDOWPOS_UNDEFINED,
                              video_width, video_height,
                              SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    if (!window) {
   
        printf("Can't create window, err: %s\n", SDL_GetError());
        goto _FAIL;
    }

    // 基于窗口创建渲染器
    renderer = SDL_CreateRenderer(window, -1, 0);

    // 基于渲染器创建纹理
    texture = SDL_CreateTexture(renderer,
                                pixformat,
                                SDL_TEXTUREACCESS_STREAMING,
                                video_width,
                                video_height);

    // 分配空间
    video_buf = (uint8_t*)malloc(yuv_frame_len);
    if (!video_buf) {
   
        fprintf(stderr, "Failed to alloce yuv frame space!\n");
        goto _FAIL;
    }

    // 打开YUV文件
    video_fd = fopen(yuv_path, "rb");
    if (!video_fd) {
   
        fprintf(stderr, "Failed to open yuv file\n");
        goto _FAIL;
    }

    // 创建请求刷新线程
    timer_thread = SDL_CreateThread(refresh_video_timer, NULL, NULL);

    while (1) {
   
        SDL_WaitEvent(&event);

        if (event.type == REFRESH_EVENT) {
   
            video_buff_len = fread(video_buf, 1, yuv_frame_len, video_fd);
            if (video_buff_len <= 0) {
   
                fprintf(stderr, "Failed to read data from yuv file!\n");
                goto _FAIL;
            }

            // 设置纹理的数据
            SDL_UpdateTexture(texture, NULL, video_buf, video_width);

            // 显示区域, 可以通过修改w和h进行缩放
            rect.x = 0;
            rect.y = 0;
            float w_ratio = win_width * 1.0 / video_width;
            float h_ratio = win_height * 1.0 / video_height;
            rect.w = video_width * w_ratio;
            rect.h = video_height * h_ratio;

            // 清屏
            SDL_RenderClear(renderer);
            // 将纹理的数据拷贝给渲染器
            SDL_RenderCopy(renderer, texture, NULL, &rect);
            // 显示
            SDL_RenderPresent(renderer);
        } else if (event.type == SDL_WINDOWEVENT) {
   
            SDL_GetWindowSize(window, &win_width, &win_height);
            printf("SDL_WINDOWEVENT win_width:%d, win_height:%d\n", win_width, win_height);
        } else if (event.type == SDL_QUIT) {
   
            s_thread_exit = 1;
        } else if (event.type == QUIT_EVENT) {
   
            break;
        }
    }

_FAIL:
    s_thread_exit = 1;

    // 释放资源
    if(timer_thread)
        SDL_WaitThread(timer_thread, NULL); // 等待线程退出
    if(video_buf)
        free(video_buf);
    if(video_fd)
        fclose(video_fd);
    if(texture)
        SDL_DestroyTexture(texture);
    if(renderer)
        SDL_DestroyRenderer(renderer);
    if(window)
        SDL_DestroyWindow(window);

    SDL_Quit();

    return 0;
}

相关推荐

  1. 视频-SDL简单使用

    2024-01-17 11:24:01       31 阅读
  2. 视频开发_SDL彻底理解纹理

    2024-01-17 11:24:01       7 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-17 11:24:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-17 11:24:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-17 11:24:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-17 11:24:01       20 阅读

热门阅读

  1. php中项目目录下.htaccess文件讲解

    2024-01-17 11:24:01       29 阅读
  2. 开发人员应该了解哪些 SQL 知识?

    2024-01-17 11:24:01       37 阅读
  3. 加快网络安全事件响应速度的6个步骤

    2024-01-17 11:24:01       41 阅读
  4. GoLang刷题之leetcode

    2024-01-17 11:24:01       33 阅读
  5. 数据结构(五)数据结构与算法中的经典题

    2024-01-17 11:24:01       31 阅读
  6. C++中的算法与数据结构优化技巧

    2024-01-17 11:24:01       32 阅读
  7. 方案:如何列出 Jira 中授予用户的所有权限

    2024-01-17 11:24:01       40 阅读
  8. 数据结构-无向图(C++)

    2024-01-17 11:24:01       26 阅读
  9. 121_买卖股票的最佳时机

    2024-01-17 11:24:01       27 阅读
  10. 11.spring boot 启动源码(一)

    2024-01-17 11:24:01       34 阅读
  11. UDP和TCP

    2024-01-17 11:24:01       33 阅读
  12. 物流实时数仓DWD层——1.准备工作

    2024-01-17 11:24:01       26 阅读
  13. web练习题题解

    2024-01-17 11:24:01       24 阅读