前面铺垫了这么多,现在终于进入核心的主题了,那就是使用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 = ; int screen_w = , screen_h = ; // 根据不同的YUV视频,来设置不同的 宽 * 高 数据
const int pixel_w = , pixel_h = ; unsigned char buffer[pixel_w*pixel_h*bpp / ]; //Refresh Event
#define REFRESH_EVENT (SDL_USEREVENT + 1) int thread_exit = ; int refresh_video(void *opaque) {
while (thread_exit == ) {
SDL_Event event;
event.type = REFRESH_EVENT;
SDL_PushEvent(&event);
SDL_Delay();
}
return ;
} int main(int argc, char* argv[])
{
if (SDL_Init(SDL_INIT_VIDEO)) {
printf("Could not initialize SDL - %s\n", SDL_GetError());
return -;
} 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\n", SDL_GetError());
return -;
} // 创建SDL渲染器
SDL_Renderer* sdlRenderer = SDL_CreateRenderer(window, -, ); // 声明像素格式
Uint32 pixformat = ; // 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\n");
return -;
} SDL_Rect sdlRect; SDL_Thread *refresh_thread = SDL_CreateThread(refresh_video, NULL, NULL);
SDL_Event event;
while () {
//Wait
SDL_WaitEvent(&event);
if (event.type == REFRESH_EVENT) {
// 读取一帧数数据到缓冲区
if (fread(buffer, , pixel_w*pixel_h*bpp / , fp) != pixel_w * pixel_h*bpp / ) {
// Loop
fseek(fp, , SEEK_SET);
fread(buffer, , pixel_w*pixel_h*bpp / , fp);
}
// 将数据更新到纹理
SDL_UpdateTexture(sdlTexture, NULL, buffer, pixel_w);
//FIX: If window is resize
sdlRect.x = ;
sdlRect.y = ;
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();
}
else if (event.type == SDL_WINDOWEVENT) {
//If Resize
SDL_GetWindowSize(window, &screen_w, &screen_h);
}
else if (event.type == SDL_QUIT) {
break;
}
}
return ;
}

运行效果:

SDL 开发实战(六): 使用 SDL 实现 YUV 播放器的更多相关文章

  1. SDL 开发实战(二):SDL 2.0 核心 API 解析

    在上一篇文章 SDL 开发实战(一):SDL介绍及开发环境配置 中,我们配置好了SDL的开发环境,并成功运行了SDL的Hello World 代码.但是可能大部分人还是读不太明白具体Hello Wol ...

  2. SDL 开发实战(七): 使用 SDL 实现 PCM播放器

    在上文,我们做了YUV播放器,这样我们就入门了SDL播放视频.下面我们来做一个PCM播放,即使用SDL播放PCM数据. 下面说明一下使用SDL播放PCM音频的基本流程,主要分为两大部分:初始化SDL. ...

  3. SDL 开发实战(三):使用 SDL 绘制基本图形

    在上文 SDL 开发实战(二):SDL 2.0 核心 API 解析 我们讲解了SDL最核心的API,并结合Hello World代码了解了SDL渲染画面的基本原理. 本文我们来讲一下,如何使用SDL的 ...

  4. 【C语言探索之旅】 第三部分第一课:SDL开发游戏之安装SDL

    内容简介 1.课程大纲 2.第三部分第一课: SDL开发游戏之安装SDL 3.第三部分第二课预告: SDL开发游戏之创建窗口和画布 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会 ...

  5. iOS开发拓展篇—音频处理(音乐播放器1)

    iOS开发拓展篇—音频处理(音乐播放器1) 说明:该系列文章通过实现一个简单的音乐播放器来介绍音频处理的相关知识点,需要重点注意很多细节的处理. 一.调整项目的结构,导入必要的素材 调整后的项目结构如 ...

  6. iOS开发拓展篇—音频处理(音乐播放器2)

    iOS开发拓展篇—音频处理(音乐播放器2) 说明:该文主要介绍音乐播放界面的搭建. 一.跳转 1.跳转到音乐播放界面的方法选择 (1)使用模态跳转(又分为手动的和自动的) (2)使用xib并设置跳转 ...

  7. iOS开发拓展篇—音频处理(音乐播放器3)

    iOS开发拓展篇—音频处理(音乐播放器3) 说明:这篇文章主要介绍音频工具类和播放工具类的封装. 一.控制器间数据传递 1.两个控制器之间数据的传递 第一种方法:self.parentViewCont ...

  8. iOS开发拓展篇—音频处理(音乐播放器4)

    iOS开发拓展篇—音频处理(音乐播放器4) 说明:该文主要介绍音乐播放器实现过程中的一些细节控制. 实现的效果: 一.完整的代码 YYPlayingViewController.m文件 // // Y ...

  9. iOS开发拓展篇—音频处理(音乐播放器5)

    iOS开发拓展篇—音频处理(音乐播放器5) 实现效果: 一.半透明滑块的设置 /** *拖动滑块 */ - (IBAction)panSlider:(UIPanGestureRecognizer *) ...

随机推荐

  1. spring-cloud-zuul服务网关

    Zuul包含了对请求的路由和过滤两个最主要的功能: 其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础,类似于保安的职能,而过滤器功能则负责对请求的处理过程进行干预,是实 ...

  2. golang自动构建脚本

    #!/bin/sh #代码分支 branch_c=$ branch_p=$ #服务器 server=$ #构建版本 version=$ case $server in test1) echo &quo ...

  3. PHP获取服务器IP和客户端IP

    <?php echo '前端机IP:'.$_SERVER['REMOTE_ADDR']; echo '<br />'; echo '后端机IP:'.$_SERVER['SERVER_ ...

  4. Bootstrap模态框垂直高度居中问题

    Bootstrap对话框改变其默认宽高,高度不会自适应居中.为解决这个问题,最好的方式是能够通过css来解决,试了几种网上的方案发现都不行.然后想到可以通过js来修正,什么时候修正最好?于是想到可以注 ...

  5. resource links

    http://cenalulu.github.io/linux/all-about-cpu-cache/

  6. MongoDB的ORM框架——Morphia

    1.引入pom <dependency> <groupId>org.mongodb.morphia</groupId> <artifactId>morp ...

  7. 简单的dfs题 --- POJ1321 棋盘问题

    题目链接: http://poj.org/problem?id=1321 题目大意: 你有k个棋子,若干个可以填的位置,要求填下一个棋子后其行和列不能填棋子. 思路: dfs策略 画图理解更好些: 填 ...

  8. 一道令人抓狂的零一背包变式 -- UVA 12563 Jin Ge Jin Qu hao

    题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  9. LOJ.6435.[PKUSC2018]星际穿越(倍增)

    LOJ BZOJ 参考这儿qwq. 首先询问都是求,向左走的最短路. \(f[i][j]\)表示从\(i\)走到\(j\)最少需要多少步.表示这样只会\(O(n^2\log n)\)的= =但是感觉能 ...

  10. C\C++ 内存对齐现象

    前几天一个在自学C语言的小伙伴问了我个问题,C语言结构体储存所占空间为啥和自己预测的不一样.看一下下面这一段代码: struct node{ int num; char ch; }a; printf( ...