初识SDL

今天我们来学习一下怎么把YUV文件显示到屏幕上。

• 视频显示的流程
▫ 视频显示的流程,就是将像素数据“画”在屏幕上的过程。
▫ 例如显示YUV,就是将YUV“画”在系统的窗口中

下面是SDL的视频显示流程。

在这里插入图片描述
• SDL视频显示函数简介
▫ SDL_Init():初始化SDL系统
▫ SDL_CreateWindow():创建窗口SDL_Window
▫ SDL_CreateRenderer():创建渲染器SDL_Renderer
▫ SDL_CreateTexture():创建纹理SDL_Texture
▫ SDL_UpdateTexture():设置纹理的数据
▫ SDL_RenderCopy():将纹理的数据拷贝给渲染器
▫ SDL_RenderPresent():显示
▫ SDL_Delay():工具函数,用于延时。
▫ SDL_Quit():退出SDL系统

在这里插入图片描述

在这里插入图片描述

VC下SDL开发环境的搭建
• 新建控制台工程
▫ 打开VC++
▫ 文件->新建->项目->Win32控制台应用程序
• 拷贝SDL开发文件
▫ 头文件(.h)拷贝至项目文件夹的include子文件夹下
▫ 导入库文件(
.lib)拷贝至项目文件夹的lib子文件夹下
▫ 动态库文件(*.dll)拷贝至项目文件夹下
• 配置开发文件
▫ 打开属性面板
 解决方案资源管理器->右键单击项目->属性
▫ 头文件配置
 配置属性->C/C+±>常规->附加包含目录,输入“include”(刚才拷贝
文件的目录)
▫ 导入库配置
 配置属性->链接器->常规->附加库目录,输入“lib” (刚才拷贝文件
的目录)
 配置属性->链接器->输入->附加依赖项,输入“SDL2.lib;
SDL2main.lib”(导入库的文件名)
▫ 动态库不用配置

下面是详细代码。

#include <stdio.h>
#define SDL_MAIN_HANDLED	//这个宏很重要配置SDL不加上它会报错。产生这个问题的原因是SDL把main函数变成了自己的SDL_main,

extern "C"
{
#include "sdl/SDL.h"
}

//窗口宽高
int w_width = 640;
int w_height = 360;


//图像宽高
const int p_width = 640;
const int p_height = 360;

//读取文件到buff里面。buff大小:图片的宽x高*(Y + 1/4U + 1/4V)
unsigned char buf[p_width * p_height * 12 / 8];//申请buff空间

int main(int argc ,char *argv[])
{
	SDL_Window* window;		//窗口指针
	SDL_Renderer* renderer;	//渲染器指针
	SDL_Texture* texture;	//纹理指针

	//初始化SDL
	if (SDL_Init(SDL_INIT_VIDEO))
	{
		printf("SDL_INIT_VIDEO ERROR:%s\n", (char*)SDL_GetError);
		return - 1;
	}
	
	//创建窗口
	//SDL_WINDOWPOS_UNDEFINED默认位置,窗口中间
	window = SDL_CreateWindow("SDL_WINDOWS", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w_width, w_height, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
	
	if (!window)
	{
		printf("SDL_CreateWindow ERROR:%s\n", (char*)SDL_GetError);
		return -1;
	}

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

	if (!renderer)
	{
		printf("SDL_CreateRenderer ERROR:%s\n", (char*)SDL_GetError);
		return -1;
	}


	//创建纹理
	//纹理格式IYUV:SDL_PIXELFORMAT_IYUV
	texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, p_width, p_height);

	if (!texture)
	{
		printf("SDL_CreateTexture ERROR:%s\n", (char*)SDL_GetError);
		return -1;
	}

	//以只读方式打开文件
	FILE *yuvfile;
	yuvfile = fopen("sintel_640_360.yuv","rb+");
	//yuvfile = fopen("test_yuv420p_320x180.yuv", "rb+");
	
	if (!yuvfile)
	{
		printf("fopen file error\n");
		return -1;
	}

	int ret;//判断返回结果
	

	//定义矩形并初始化
	SDL_Rect sdlRect;
	sdlRect.x = 0;
	sdlRect.y = 0;
	sdlRect.w = w_width;
	sdlRect.h = w_height;

	while (1)
	{
		//读文件
		ret = fread(buf,1, p_width * p_height * 12 / 8, yuvfile);
		if (ret == 0)//循环播放
		{
			fseek(yuvfile, 0, SEEK_SET);
			continue;
		}

		//把数据更新到纹理
		ret = SDL_UpdateTexture(texture, NULL, buf, p_width);
		if (ret == -1)
		{
			printf("SDL_UpdateTexture ERROR:%s\n", (char*)SDL_GetError);
			return -1;
		}

		//清除整个渲染目标
		ret = SDL_RenderClear(renderer);
		if (ret == -1)
		{
			printf("SDL_RenderClear ERROR:%s\n", (char*)SDL_GetError);
			return -1;
		}

		//将纹理的一部分复制到当前渲染目标。
		ret = SDL_RenderCopy(renderer, texture,NULL, &sdlRect);
		if (ret == -1)
		{
			printf("SDL_RenderCopy ERROR:%s\n", (char*)SDL_GetError);
			return -1;
		}

		//执行渲染后更新屏幕。
		SDL_RenderPresent(renderer);

		SDL_Delay(40);//延时40ms
	}

	fclose(yuvfile);//关闭文件

	SDL_Quit();//退出SDL
	
	return 0;
}

下载链接:sdl视频显示源代码

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

捌玖ヾ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值