SDL2 播放视频数据(YUV420P)

news2024/11/18 9:32:48

1.简介

这里以常用的视频原始数据YUV420P为例,展示视频的播放。

SDL播放视频的流程如下:

  • 初始化SDL:SDL_Init();
  • 创建窗口:SDL_CreateWindow();
  • 创建渲染器:SDL_CreateRenderer();
  • 创建纹理:SDL_CreateTexture();
  • 设置纹理数据:SDL_UpdateTexture();
  • 纹理复制给渲染目标:使用SDL_RenderCopy()将纹理数据复制给渲染目标。在使用SDL_RenderCopy()之前,可以使用SDL_RenderClear()先使用清空渲染目标。
  • 显示界面:SDL_RenderPresent();

2.使用的数据结构以及方法介绍

SDL显示视频涉及到下列结构体:

  • SDL_Window:代表了窗口
  • SDL_Renderer:代表了渲染器
  • SDL_Texture:代表了纹理
  • SDL_Rect:一个矩形框,用于确定纹理显示的位置。

YUV/RGB像素数据首先加载至SDL_Texture,然后通过SDL_Render渲染至SDL_Window。其中SDL_Rect可以指定显示的位置。

SDL_CreateWindow:创建窗口

SDL_Window *SDL_CreateWindow(const char *title,int x, int y, int w,
                                                      int h, Uint32 flags);

flags有以下的类型:

typedef enum
{
    SDL_WINDOW_FULLSCREEN = 0x00000001,         /**< fullscreen window */
    SDL_WINDOW_OPENGL = 0x00000002,             /**< window usable with OpenGL context */
    SDL_WINDOW_SHOWN = 0x00000004,              /**< window is visible */
    SDL_WINDOW_HIDDEN = 0x00000008,             /**< window is not visible */
    SDL_WINDOW_BORDERLESS = 0x00000010,         /**< no window decoration */
    SDL_WINDOW_RESIZABLE = 0x00000020,          /**< window can be resized */
    SDL_WINDOW_MINIMIZED = 0x00000040,          /**< window is minimized */
    SDL_WINDOW_MAXIMIZED = 0x00000080,          /**< window is maximized */
    SDL_WINDOW_MOUSE_GRABBED = 0x00000100,      /**< window has grabbed mouse input */
    SDL_WINDOW_INPUT_FOCUS = 0x00000200,        /**< window has input focus */
    SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */
    SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
    SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */
    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported.
                                                     On macOS NSHighResolutionCapable must be set true in the
                                                     application's Info.plist for this to have any effect. */
    SDL_WINDOW_MOUSE_CAPTURE    = 0x00004000,   /**< window has mouse captured (unrelated to MOUSE_GRABBED) */
    SDL_WINDOW_ALWAYS_ON_TOP    = 0x00008000,   /**< window should always be above others */
    SDL_WINDOW_SKIP_TASKBAR     = 0x00010000,   /**< window should not be added to the taskbar */
    SDL_WINDOW_UTILITY          = 0x00020000,   /**< window should be treated as a utility window */
    SDL_WINDOW_TOOLTIP          = 0x00040000,   /**< window should be treated as a tooltip */
    SDL_WINDOW_POPUP_MENU       = 0x00080000,   /**< window should be treated as a popup menu */
    SDL_WINDOW_KEYBOARD_GRABBED = 0x00100000,   /**< window has grabbed keyboard input */
    SDL_WINDOW_VULKAN           = 0x10000000,   /**< window usable for Vulkan surface */
    SDL_WINDOW_METAL            = 0x20000000,   /**< window usable for Metal view */

    SDL_WINDOW_INPUT_GRABBED = SDL_WINDOW_MOUSE_GRABBED /**< equivalent to SDL_WINDOW_MOUSE_GRABBED for compatibility */
} SDL_WindowFlags;

SDL_CreateRenderer:创建渲染器

SDL_Renderer *SDL_CreateRenderer(SDL_Window * window,int index, Uint32 flags);

flags有以下的类型:

typedef enum
{
    SDL_RENDERER_SOFTWARE = 0x00000001,         /**< The renderer is a software fallback */
    SDL_RENDERER_ACCELERATED = 0x00000002,      /**< The renderer uses hardware
                                                     acceleration */
    SDL_RENDERER_PRESENTVSYNC = 0x00000004,     /**< Present is synchronized
                                                     with the refresh rate */
    SDL_RENDERER_TARGETTEXTURE = 0x00000008     /**< The renderer supports
                                                     rendering to texture */
} SDL_RendererFlags;

SDL_CreateTexture:创建纹理

SDL_Texture *SDL_CreateTexture(SDL_Renderer * renderer,Uint32 format
                                            ,int access, int w,int h);

 access有以下的类型:

typedef enum
{
    SDL_TEXTUREACCESS_STATIC,    /**< Changes rarely, not lockable */
    SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */
    SDL_TEXTUREACCESS_TARGET     /**< Texture can be used as a render target */
} SDL_TextureAccess;

3.示例

#include <stdio.h>
#include <SDL.h>

#define WINDOW_W 800
#define WINDOW_H 600

const int bpp = 12;
const int pixel_w = 1920, pixel_h = 1080;
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;
}

#undef main
int main(int argc,char* argv[])
{
	/*SDL初始化*/
	SDL_Init(SDL_INIT_VIDEO);
	/*创建窗口*/
	SDL_Window *window = SDL_CreateWindow("SDL SHOW VIDEO", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_W, WINDOW_H, SDL_WINDOW_SHOWN);
	/*创建渲染器*/
	SDL_Renderer *render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
	/*设置渲染器颜色*/
	SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
	/*清空渲染器*/
	SDL_RenderClear(render);
	//YUV420P
	Uint32 pixformat = SDL_PIXELFORMAT_IYUV;
	//创建纹理
	SDL_Texture* sdlTexture = SDL_CreateTexture(render, pixformat, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h);
	//添加边框
	int border = 0;
	SDL_Rect sdlRect;
	sdlRect.x = border;
	sdlRect.y = border;
	sdlRect.w = WINDOW_W - border * 2;
	sdlRect.h = WINDOW_H - border * 2;

	//加载文件
	FILE *fp = NULL;
	fp = fopen("./test_yuv420p_1920x1080.yuv", "rb+");
	if (fp == NULL) 
	{
		printf("cannot open this file\n");
		return -1;
	}
	//刷新线程
	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);
			SDL_RenderClear(render);
			SDL_RenderCopy(render, sdlTexture, NULL, &sdlRect);
			SDL_RenderPresent(render);
			//Delay 40ms
			SDL_Delay(40);
		}
		else if (event.type == SDL_QUIT)
		{
			break;
		}
	}

	SDL_DestroyTexture(sdlTexture);/*释放纹理*/
	SDL_DestroyWindow(window);
	SDL_DestroyRenderer(render);

	return 0;
}

4.更多参考

[总结]FFMPEG视音频编解码零基础学习方法_零基础ffmpeg 雷霄骅-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1204934.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vivado产生报告阅读分析-常规报告2

1、Report I/O “ I/O Report ” &#xff08; I/O 报告 &#xff09; 用于替代 AMD ISE Design Suite PAD 文件。“ I/O Report ”可列出 &#xff1a; • “ Pin Number ” &#xff08; 管脚编号 &#xff09;&#xff1a; 表示器件中的所有管脚 • “ Signal Name ” …

vue3配置@别名

在项目开发中&#xff0c;通常我们是不写相对路径的&#xff0c;因为有些文件需要在不同的文件中使用&#xff0c;如果使用相对路径&#xff0c;那么我们每次去CV路径的时候就要重新修改。因此通常我们是写跟路径的&#xff0c;但是从头开始又太过于麻烦&#xff0c;因此我们使…

ChatGLM3本地部署运行(入门体验级)

文章目录 前言零 硬件小白基知填坑eForce Game Ready驱动程序CUDA常用命令 环境准备NVIDIA驱动更新CUDA安装 部署补充内容体验 前言 学习自B站up主技术爬爬虾&#xff0c;感谢up主提供的整合包&#xff01; 零 硬件 6GB以上显存的NVIDIA显卡&#xff08;品质越高&#xff0c…

22.斐波那契数列数列前20项.

#include<stdio.h>int main(){int i,sum1; int a[100];a[0]0;a[1]1;for(i2;i<20;i){a[i]a[i-1]a[i-2]; sumsuma[i];}printf("斐波那契数列的前20项和为&#xff1a;%d",sum);return 0;}

沧州市壹家人社工小赵庄乡社工站常态化开展关爱一老一小活动

沧州市壹家人社会工作服务中心承接新华区小赵庄乡社工站以来以服务一老一小为工作重点&#xff0c;发挥五社联动的重要作用&#xff0c;开展“幸福院”和“护蕾驿站”两个微项目&#xff0c;聚焦需求&#xff0c;采取社工引领志愿服务的模式&#xff0c;常态化为老人和孩子开展…

Wpf 使用 Prism 实战开发Day05

首页设计 1.效果图 一.代码现实 根据页面布局&#xff0c;可以将页面设计成3行&#xff0c;每行中分多少列&#xff0c;看需求而定根据页面内容&#xff0c;设计Model 实体类&#xff0c;以及View Model 1.Index.xaml 页面布局设计 RowDefinition 分行&#xff08;Row&#xf…

【LeetCode】每日一题 2023_11_12 每日一题 Range 模块(线段树)

文章目录 刷题前唠嗑题目&#xff1a;Range 模块题目描述代码与解题思路 刷题前唠嗑 LeetCode? 启动&#xff01;&#xff01;&#xff01; 嗯&#xff1f;怎么是 hard&#xff0c;好长&#xff0c;可恶&#xff0c;看不懂&#xff0c;怎么办 题目&#xff1a;Range 模块 题…

mindspore mindyolo目标检测华为昇腾上推理使用

参考&#xff1a; https://github.com/mindspore-lab/mindyolo 使用案例&#xff1a; https://github.com/mindspore-lab/mindyolo/blob/master/GETTING_STARTED.md 安装&#xff1a; pip install mindyolo特别注意opencv-python、opencv-python-headless版本问题&#xff0…

深入理解C++关联式容器:set、multiset、map和multimap详解

序列式容器 与 关联式容器 我们知道&#xff1a; C 中&#xff0c;我们将 vector、list、queue 这种底层为线性序列的数据结构叫做 序列式容器&#xff0c;其存储的就是元素本身。而 关联式容器 以键-值对的形式存储数据。每个键在容器中必须是唯一的&#xff0c;而值则与相应…

基于连续Hopfield神经网络优化——旅行商问题优化计算

大家好&#xff0c;我是带我去滑雪&#xff01; 利用神经网络解决组合优化问题是神经网络应用的一个重要方面。所谓组合优化问题&#xff0c;就是在给定约束条件下&#xff0c;使目标函数极小&#xff08;或极大&#xff09;的变量组合问题。将Hopfield网络应用于求解组合优化问…

Centos7 升级到 Centos8 教程以及关于dnf包管理工具的若干问题解决方案

目录 为什么升级一、参考文档二、升级步骤三、安装git编码错误缓存问题安装git依赖冲突问题解决办法 为什么升级 jenkins 2.4版本需要CentOS8 一、参考文档 点我 二、升级步骤 1.安装epel源 yum -y install epel-release2.安装rpmconf和yum-utils yum -y install rpmco…

死锁(JAVA)

死锁在多线程代码中是非常严重的BUG&#xff0c;一旦代码中出现死锁就会导致线程卡死。 当单个线程连续两次对同一个对象进行加锁操作时&#xff0c;如果该锁是不可重入锁就会发生死锁&#xff08;线程卡死&#xff09; 两个线程两把锁&#xff0c;如果出现这种情况也是会发生…

瑞吉外卖Day02

小张推荐:瑞吉外卖Day01&#xff0c;瑞吉外卖Day03 1.登陆功能 1.1结果封装类 导入返回结果类R此类是一个通用结果类。服务端响应的所有结果最终都会包装成此种类型返回给前端页面 注意属性名&#xff0c;莫要写错&#xff0c;不然与前端很难对接&#xff01;&#xff01;&…

Docker 中的端口

Docker 中的端口 0.0.0.0:8080->80/tcp &#xff0c;主机&#xff08;即运行 Docker 的机器&#xff09;监听8080端口&#xff0c;如果有请求转发到容器的 80 端口上去。 详细解释一下&#xff1a; 0.0.0.0:8080->80/tcp &#xff1a;这是一个端口映射规则。 0.0.0.0:80…

Leetcode—202.快乐数【简单】

2023每日刷题&#xff08;二十八&#xff09; Leetcode—202.快乐数 快慢指针思想 通过手玩2&#xff0c;可以发现 会走入一个循环&#xff0c;并且fast和slow会在一个数字相遇&#xff0c;以下也大概花了一下推倒出来了。如果slow不是因为1和fast相等的&#xff0c;就说明它…

消息队列中的事务是什么呢?

消息队列中的事务是什么呢&#xff1f; 说到事务&#xff0c;肯定会优先想到数据库中的事务。在数据库中需要事务&#xff0c;是为了保证数据的一致性、完整性、持久性和隔离性。它可以将数据库中的一组操作合并为一个不可分割的工作单元&#xff0c;要么全部执行成功&#xf…

​软考-高级-系统架构设计师教程(清华第2版)【第4章 信息安全技术基础知识(P160~189)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第4章 信息安全技术基础知识&#xff08;P160~189&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

【沐风老师】3dMax使用克隆修改器插件创建旋转楼梯教程

3DMAX克隆修改器插件&#xff0c;它通过增量平移、旋转和缩放输入几何体来创建对象的副本。在某些方面&#xff0c;它类似于 3dMax 的内置“阵列”工具&#xff0c;但有一个主要优点 -克隆修改器是完全参数化的&#xff0c;因此您可以随时更改重复项的数量及其分布。其他功能包…

mapboxGL中的底图切换

概述 底图切换&#xff0c;这么简单的功能还要写一篇文章&#xff1f;值得的&#xff0c;为什么这么说呢&#xff1f;因为mapboxGL的矢量底图有上百个&#xff0c;不同的底图用的样式、图层的名称、图层的内容、字体库、图标库都不一样&#xff0c;尤其是当地图上已经叠加了很…

展会预告 | 图扑邀您相约高交会-全球清洁能源创新博览会

第二十五届中国国际高新技术成果交易会(简称“高交会”)将在深圳盛大开幕。高交会由商务部、科学技术部、工业和信息化部、国家发展改革委、农业农村部、国家知识产权局、中国科学院、中国工程院和深圳市人民政府共同举办。是目前中国规模最大、最具影响力的科技类展会。 图扑软…