golang调用sdl2,播放yuv视频
golang调用sdl2,播放yuv视频
win10 x64下测试成功,其他操作系统下不保证成功。
采用的是syscall方式,不是cgo方式。
代码如下:
package main
import (
"fmt"
"github.com/moonfdd/sdl2-go/sdl"
"github.com/moonfdd/sdl2-go/sdlcommon"
"io/ioutil"
"time"
"unsafe"
)
const REFRESH_EVENT = sdl.SDL_USEREVENT + 1 // 请求画面刷新事件
const QUIT_EVENT = sdl.SDL_USEREVENT + 2 // 退出事件
//定义分辨率
// YUV像素分辨率
const YUV_WIDTH = 320
const YUV_HEIGHT = 240
//定义YUV格式
const YUV_FORMAT = sdl.SDL_PIXELFORMAT_IYUV
var s_thread_exit = 0 // 退出标志 = 1则退出
func main() {
sdlcommon.SetSDL2Path("SDL2.dll")
sdl.SDL_Init(sdl.SDL_INIT_VIDEO)
pixformat := YUV_FORMAT
// 分辨率
// 1. YUV的分辨率
video_width := int32(YUV_WIDTH)
video_height := int32(YUV_HEIGHT)
// 2.显示窗口的分辨率
win_width := int32(YUV_WIDTH)
win_height := int32(YUV_WIDTH)
y_frame_len := video_width * video_height
u_frame_len := video_width * video_height / 4
v_frame_len := video_width * video_height / 4
yuv_frame_len := y_frame_len + u_frame_len + v_frame_len
window := sdl.SDL_CreateWindow("微信公众号:福大大架构师每日一题", sdl.SDL_WINDOWPOS_UNDEFINED, sdl.SDL_WINDOWPOS_UNDEFINED, video_width, video_height, sdl.SDL_WINDOW_OPENGL|sdl.SDL_WINDOW_RESIZABLE)
if window == nil {
fmt.Printf("Can't create window, err:%s", sdl.SDL_GetError())
return
}
renderer := window.SDL_CreateRenderer(-1, 0)
texture := renderer.SDL_CreateTexture(uint32(pixformat), sdl.SDL_TEXTUREACCESS_STREAMING, video_width, video_height)
var event sdl.SDL_Event
var rect sdl.SDL_Rect
fileData, err := ioutil.ReadFile("yuv420p_320x240.yuv")
if err != nil {
fmt.Println("读取文件失败", err)
return
}
//创建请求刷新线程
go func() {
for s_thread_exit == 0 {
var event sdl.SDL_Event
event.Type = REFRESH_EVENT
event.SDL_PushEvent()
time.Sleep(40 * time.Millisecond)
}
s_thread_exit = 0
var event sdl.SDL_Event
event.Type = QUIT_EVENT
event.SDL_PushEvent()
}()
for {
// 收取SDL系统里面的事件
event.SDL_WaitEvent()
if event.Type == REFRESH_EVENT { // 画面刷新事件
if len(fileData) < int(yuv_frame_len) {
break
}
video_buf := fileData[0:yuv_frame_len]
fileData = fileData[yuv_frame_len:]
// 设置纹理的数据 video_width = 320, plane
texture.SDL_UpdateTexture(nil, uintptr(unsafe.Pointer(&video_buf[0])), video_width)
// 显示区域,可以通过修改w和h进行缩放
rect.X = 0
rect.Y = 0
//w_ratio := win_width * 1.0 / video_width
//h_ratio := win_height * 1.0 / video_height
320x240 怎么保持原视频的宽高比例
//rect.W = video_width * w_ratio
//rect.H = video_height * h_ratio
rect.W = win_width
rect.H = win_height
// 清除当前显示
renderer.SDL_RenderClear()
// 将纹理的数据拷贝给渲染器
renderer.SDL_RenderCopy(texture, nil, &rect)
// 显示
renderer.SDL_RenderPresent()
} else if event.Type == sdl.SDL_WINDOWEVENT {
window.SDL_GetWindowSize(&win_width, &win_height)
} else if event.Type == sdl.SDL_QUIT {
s_thread_exit = 1
} else if event.Type == QUIT_EVENT {
break
}
}
texture.SDL_DestroyTexture()
renderer.SDL_DestroyRenderer()
window.SDL_DestroyWindow()
sdl.SDL_Quit()
}
执行结果如下:

golang调用sdl2,播放yuv视频的更多相关文章
- potplayer 网页调用potplayer播放本地视频
网页调用potplayer播放本地视频 CreateTime--2018年1月3日10:36:24 Author:Marydon 源码展示: <!DOCTYPE html> <h ...
- avi视频格式转yuv格式与播放yuv视频
因为要用到yuv格式视频.而眼下仅仅有avi格式的视频,所以须要转换,而且opencv不支持yuv编码的视频播放.所以须要转换为rgb编码.而后播放.写了两个程序.以供參考: 1,avi格式视频转yu ...
- 最简单的视音频播放示例7:SDL2播放RGB/YUV
本文记录SDL播放视频的技术.在这里使用的版本是SDL2.实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API.在Windows平台下,SDL封装了Direct3D这类的API ...
- 最简单的视音频播放演示样例7:SDL2播放RGB/YUV
===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...
- 最简单的视音频播放示例9:SDL2播放PCM
本文记录SDL播放音频的技术.在这里使用的版本是SDL2.实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API.在Windows平台下,SDL封装了Direct3D这类的API ...
- 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surface)
上一篇文章记录了GDI播放视频的技术.打算接下来写两篇文章记录Direct3D(简称D3D)播放视频的技术.Direct3D应该Windows下最常用的播放视频的技术.实际上视频播放只是Direct3 ...
- 最简单的视音频播放示例2:GDI播放YUV, RGB
前一篇文章对“Simplest Media Play”工程作了概括性介绍.后续几篇文章打算详细介绍每个子工程中的几种技术.在记录Direct3D,OpenGL这两种相对复杂的技术之前,打算先记录一种和 ...
- 最简单的视音频播放演示样例3:Direct3D播放YUV,RGB(通过Surface)
===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...
- phongap开发中安卓平台上如何调用第三方播放器来播放HLS视频
前文曾经讲了关于在安卓平台上利用phonegap开发播放HLS的解决方案,其实最好的方案就是自己针对HLS视频开发自己的播放器,但是开发播放器是一个浩大的工程,必须对原生安卓开发非常熟悉,并且对视频播 ...
- ubuntu14.04 yuv文件的播放及视频信息的查看
1.安装ffmpeg sudo add-apt-repository ppa:mc3man/trusty-media sudo apt-get update sudo apt-get install ...
随机推荐
- k8s namespace kubeDNS
图中kube-dns只是一个service,但是他对外提供k8s集群内部的dns服务,真正的dns server,是 coredns这几个pod k8s namespace 的作用只是提供逻辑上的组件 ...
- 关于 Android sdk manager 的安装问题
最近刚刚接触小程序测试,故此需要搭建环境 我用的是python3.6+appium1.8.2+Android sdk manager 关于应用程序,大家有需要的话,可以找我要. 1.关于安装Andro ...
- Hugging Face 每周速递: Chatbot Hackathon;FLAN-T5 XL 微调;构建更安全的 LLM
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- JAVA重试机制多种方式深入浅出
重试机制在分布式系统中,或者调用外部接口中,都是十分重要的. 重试机制可以保护系统减少因网络波动.依赖服务短暂性不可用带来的影响,让系统能更稳定的运行的一种保护机制. 为了方便说明,先假设我们想要进行 ...
- Python学习笔记--高阶技巧(二)
Socket服务端开发 基本步骤如下: socket客户端开发 基本步骤如下: 1.创建socket对象 2.连接到服务器 3.发送消息 4.接收返回消息 5.关闭连接 正则表达式 基础方法 matc ...
- 多路复用IO:select poll epoll
[电话面试]io多路复用专题面试 这个真猛 有人做了笔记:点这里 select Select(Max+1,&rset,null,null,null)是因为0~max是max+1. 过程: 将文 ...
- [C++/Java/Py/C#/Ruby/Swift/Go/Scala/Kotlin/Rust/PHP/TS/Elixir/Dart/Racket/Erlang] LeetCode2185. 统计包含给定前缀的字符串
目录 题解地址 代码 cpp java python3 C# ruby swift golang scala kotlin rust php typescript elixir dart racket ...
- Spring 依赖注入有哪几种方式
1. 构造器注入 /*带参数,方便利用构造器进行注入*/ public CatDaoImpl(String message){ this. message = mess ...
- Java/Kotlin 使用Redis模拟发送验证码
原文地址: Java/Kotlin 使用Redis模拟发送邮件验证码 - Stars-One的杂货小窝 Java中常用语连接Redis的库有lettuce和jredis,一般是推荐lettuce,其具 ...
- 万字血书React—走近React
配置开发环境 脚手架工具create-react-app 储备知识:终端或命令行.代码编辑器 React官方中文文档 create-react-app 其是基于Node的快速搭建React项目的脚手架 ...