当前位置: 首页 > news >正文

SDL打开YUV视频

文章目录

      • 问题1:如何控制帧率?
      • 问题2:如何触发退出事件?
      • 问题3:如何实时调整视频窗口的大小
      • 问题4:YUV如何一次读取一帧的数据?

问题1:如何控制帧率?

在这里插入图片描述
单独用一个子线程给主线程发送刷新画面的事件 主线程负责刷新画面 每次发送刷新画面的命令后就延迟一段事件 具体的帧率公式为1000 / 延迟事件 = 帧率

问题2:如何触发退出事件?

SDL_QUIT 事件通常由用户触发,当关闭窗口时,SDL 会生成此事件。这可以通过用户点击窗口的关闭按钮(如窗口右上角的 “X”)或通过其他机制关闭窗口(例如按 Alt+F4)来触发。在事件循环中检测到 SDL_QUIT 后,通常会执行相应的退出操作,如设置退出标志(s_thread_exit = 1),从而安全地终止程序或线程。
在这里插入图片描述

问题3:如何实时调整视频窗口的大小

在这里插入图片描述
接受窗口变化的消息 实时更新窗口的尺寸 根据窗口和视频部分的比例
让实时渲染的时候 视频部分乘上这部分比例 就能到达 视频和窗口同步大小

问题4:YUV如何一次读取一帧的数据?

在 YUV420 格式中,一帧的数据大小可以通过以下方式计算:

Y 分量占据整个画面的大小:video_width * video_height
U 和 V 分量各占 Y 分量的四分之一:(video_width * video_height) / 4
因此,一帧的总大小为:
y_frame_len + u_frame_len + v_frame_len = video_width * video_height + 2 * (video_width * video_height / 4)

简化为:
yuv_frame_len = video_width * video_height * 1.5

这样你就可以通过 yuv_frame_len 获取一帧的总大小。

#include <stdio.h>
#include <string.h>#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_IYUVint s_thread_exit = 0; // 退出标志 = 1则退出// 通过线程去控制1s刷多少帧
int refresh_video_timer(void *data) {while (!s_thread_exit) {SDL_Event event;// 事件类型为刷新事件event.type = REFRESH_EVENT;// 将事件推送到事件队列中SDL_PushEvent(&event);SDL_Delay(40); // 1000 / 40 = 25 帧}// 停止控制视频输出帧数的时候 将这里的状态重置s_thread_exit = 0;// push quit eventSDL_Event event;event.type = QUIT_EVENT;SDL_PushEvent(&event);return 0;
}
#undef main
int main(int argc, char *argv[]) {// 初始化 SDLif (SDL_Init(SDL_INIT_VIDEO)) {fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());return -1;}// SDLSDL_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;uint32_t v_frame_len = video_width * video_height / 4;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) {fprintf(stderr, "SDL: could not create window, err:%s\n", SDL_GetError());goto _FAIL;}// 基于窗口创建渲染器renderer = SDL_CreateRenderer(window, -1, 0);// 基于渲染器创建纹理texture = SDL_CreateTexture(renderer,pixformat, // 指定yuv格式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系统里面的事件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;}// 设置纹理的数据 video_width = 320, planeSDL_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;// 320x240 怎么保持原视频的宽高比例rect.w = video_width * w_ratio;rect.h = video_height * h_ratio;//            rect.w = video_width * 0.5;//            rect.h = video_height * 0.5;// 清除当前显示SDL_RenderClear(renderer);// 将纹理的数据拷贝给渲染器 会把比例还原回来设置一个视频SDL_RenderCopy(renderer, texture, NULL, &rect);// 显示SDL_RenderPresent(renderer);} else if (event.type == SDL_WINDOWEVENT) {// If Resize 更新窗口的尺寸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;
}

相关文章:

SDL打开YUV视频

文章目录 问题1&#xff1a;如何控制帧率&#xff1f;问题2&#xff1a;如何触发退出事件&#xff1f;问题3&#xff1a;如何实时调整视频窗口的大小问题4&#xff1a;YUV如何一次读取一帧的数据&#xff1f; 问题1&#xff1a;如何控制帧率&#xff1f; 单独用一个子线程给主线…...

微服务架构面试内容整理-Archaius

Archaius 是由 Netflix 开发的一个配置管理库,主要用于处理动态配置和环境配置。在微服务架构中,Archaius 允许开发者以灵活的方式管理配置,从而更好地应对变化的需求。以下是 Archaius 的主要特点、工作原理和使用场景: 主要特点 1. 动态配置: Archaius 支持动态更新配置…...

实现 Nuxt3 预览PDF文件

安装必要的库&#xff0c;这里使用PDF.js库 npm install pdfjs-dist --save 为了解决跨域问题&#xff0c;在server/api 下 创建一个请求api&#xff0c; downloadFileByProxy.ts import { defineEventHandler } from h3;export default defineEventHandler(async event >…...

udp为什么会比tcp 有更低的延迟

UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;相比TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;具有更低的延迟&#xff0c;这主要归因于UDP协议的设计特点和机制。以下是对UDP比TCP延迟低的原因的详细…...

基于java+SpringBoot+Vue的洗衣店订单管理系统设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven mysql5.7或8.0等等组成&#x…...

HarmonyOS-消息推送

一. 服务简述 Push Kit&#xff08;推送服务&#xff09;是华为提供的消息推送平台&#xff0c;建立了从云端到终端的消息推送通道。所有HarmonyOS 应用可通过集成 Push Kit&#xff0c;实现向应用实时推送消息&#xff0c;使消息易见&#xff0c;构筑良好的用户关系&#xff0…...

数据分析:宏基因组DESeq2差异分析筛选差异物种

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍原理:计算步骤:结果:加载R包准备画图主题数据链接导入数据Differential abundance (No BP vs 2BP TA)构建`countData`矩阵过滤低丰度物种构建DESeq数据对象DESeq2差异分析画图Di…...

出海企业如何借助云计算平台实现多区域部署?

云计算de小白 如需进一步了解&#xff0c;请单击链接了解有关 Akamai 云计算的更多信息 在本文中我们将告诉大家如何在Linode云计算平台上借助VLAN快速实现多地域部署。 首先我们需要明确一些基本概念和思想&#xff1a; 部署多区域 VLAN 为了在多区域部署中在不同的 VLAN …...

硬件---1电路设计安全要点以及欧姆定律

前言&#xff1a; 一直搞的东西都偏软件&#xff0c;硬件也一直在学&#xff0c;元器件、基础电路知识、PCB设计、模电运放都学的马马虎虎&#xff0c;因此决定进行系统性学习&#xff0c;内容基本来源于手里的视频和书本以及自己的感悟。 一电路安全 1电路安全 在初期基础…...

Linux如何更优质调节系统性能

一、硬件优化 增加物理内存&#xff1a;最直接的提升系统性能的方法。内存不足时&#xff0c;系统会频繁进行交换&#xff08;swapping&#xff09;活动&#xff0c;这会显著降低系统的响应速度&#xff0c;因为磁盘IO速度远低于内存访问速度。通过增加内存&#xff0c;可以减…...

第三十五章 Vue路由进阶之声明式导航(跳转传参)

目录 一、引言 二、查询参数传参 2.1. 使用方式 2.2. 完整代码 2.2.1. main.js 2.2.2. App.vue 2.2.3. Search.vue 2.2.4. Home.vue 2.2.5. index.js 三、动态路由传参 3.1. 使用方式 3.2. 完整代码 3.2.1. main.js 3.2.2. App.vue 3.2.3. Search.vue 3.2.4. Hom…...

python爬虫自动库DrissionPage保存网页快照mhtml/pdf/全局截图/打印机另存pdf

目录 零一、保存网页快照的三种方法二、利用打印机保存pdf的方法 零 最近星球有人问如何使用页面打印功能&#xff0c;另存为pdf 一、保存网页快照的三种方法 解决方案已经放在星球内&#xff1a;https://articles.zsxq.com/id_55mr53xahr9a.html当然也可以看如下代码&…...

基于毫米波雷达和TinyML的车内检测、定位与分类

英文标题&#xff1a;In-Cabin Detection, Localization and Classification based on mmWave Radar with TinyML 作者信息&#xff1a; 王志飞&#xff0c;程一格&#xff0c;彭辉&#xff0c;周会强&#xff0c;王铮&#xff0c;刘宏全所属机构&#xff1a;Calterah Semico…...

小E的射击训练

问题描述 小E正在训练场进行射击练习&#xff0c;靶有10个环&#xff0c;靶心位于坐标(0, 0)。每个环对应不同的得分&#xff0c;靶心内&#xff08;半径为1&#xff09;得10分&#xff0c;依次向外的每个环分数减少1分。若射击点在某个半径为i的圆内&#xff0c;则得11-i分。…...

React的概念以及发展前景如何?

React是一个由Facebook开发的用于构建用户界面的的开源JavaScript库&#xff0c;它主要用于构建大型、动态的Web应用程序。React的主要特点是使用VirtualDOM&#xff08;虚拟DOM&#xff09;来优化性能&#xff0c;并使用声明式的编程方式来编写UI。 React的主要概念包括&#…...

PDF生成:全面解析,C# 如何使用iTextSharp库(或其他类似库)生成PDF文档,包括如何将位图图像嵌入PDF中。

一、概述 PDF&#xff08;Portable Document Format&#xff09;是一种广泛使用的文档格式&#xff0c;由Adobe公司在1993年推出。PDF的目标是能够在任何设备上呈现固定格式的文档&#xff0c;无论是在不同的操作系统、硬件设备&#xff0c;还是在打印时&#xff0c;都能保证文…...

如何选择最适合的消息队列?详解 Kafka、RocketMQ、RabbitMQ 的使用场景

引言 在日常开发中&#xff0c;消息队列已经成为业务场景中几乎不可或缺的一部分。无论是订单系统、日志收集、分布式事务&#xff0c;还是大数据实时流处理&#xff0c;消息队列都在支撑着这些关键环节。目前市面上常用的消息队列有三种(ActiveMQ 虽然在企业集成中仍有应用&a…...

gitlab项目如何修改主分支main为master,以及可能遇到的问题

如果你希望将 Git 仓库的主分支名称从 main 修改为 master&#xff1a; 1. 本地修改分支名称 首先&#xff0c;切换到 main 分支&#xff1a; git checkout main将 main 分支重命名为 master&#xff1a; git branch -m main master2. 更新远程仓库 将本地更改推送到远程仓库…...

RRF(Reciprocal Rank Fusion,倒数排序融合)

RRF(Reciprocal Rank Fusion,倒数排序融合) 摘要 倒数排序融合 RRF 是一种简单的方法&#xff0c;用于结合多个 IR(Information Retrieval) 系统的文档排名&#xff0c;始终比任何单独的系统产生更好的结果。 通过使用 RRF 来结合几个TREC实验的结果&#xff0c;并建立一个 …...

移动开发(七):.NET MAUI使用RESTAPI实现查询天气笔记

目录 一、接口准备 二、实体部分 三、页面部分 四、后台代码逻辑 五、总结 在移动开发过程中,第三方对接是非常常见的。今天给大家分享.NET MAUI如何使用REST API实现输入城市名称查询天气的示例,希望对大家学习.NET MAUI可以提供一些帮助! 一、接口准备 首先我们需要…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...