SDL2的渲染

使用SDL2播放视频时需要通过渲染操作令视频的每一帧在窗口的显示。

SDL播放视频的流程如下图所示:

初始化组件:

SDL_Init();          //初始化SDL
SDL_CreateWindow();    //创建播放器的窗口
SDL_CreateRenderer();    //创建基于窗口的渲染器
SDL_CreateTexture();    //创建基于渲染器与视频格式的纹理

循环渲染:

SDL_UpdateTexture();  //设置纹理的数据
SDL_RenderCopy();    //将纹理复制给渲染器
SDL_RenderPresent();  //使用渲染器进行显示

初始化组件

SDL_Init(SDL_INIT_VIDEO);

由于我们想实现一个播放器,所以SDL的子系统设成视频。

        window = SDL_CreateWindow("Simplest YUV Player",
		SDL_WINDOWPOS_UNDEFINED,
		SDL_WINDOWPOS_UNDEFINED,
		video_width, video_height,
		SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

窗口主要仅和视频的长和宽有关。

renderer = SDL_CreateRenderer(window, -1, 0);

创建渲染器,渲染器可见也是基于窗口进行初始化的。

        texture = SDL_CreateTexture(renderer,
		pixformat,
		SDL_TEXTUREACCESS_STREAMING,
		video_width,
		video_height);

创建纹理,可以看到纹理的创建与渲染器renderer,视频的格式pixformat与视频的长宽video_width,video_height相关,实际上从源码中可以看出,纹理的创建使用了渲染器renderer的组件。

循环渲染

SDL_UpdateTexture(texture, NULL, video_buf, video_width);

以上代码实现了纹理的更新,设置纹理的像素数据,这里需要注意一个变量video_buf。

    // 分配空间
	video_buf = (uint8_t*)malloc(yuv_frame_len);
	if (!video_buf)
	{
		fprintf(stderr, "Failed to alloce yuv frame space!\n");
		goto _FAIL;
	}

video_buf是特别创建的一个缓冲区,视频会先放在缓冲区内,再交给纹理进行更新。

            // 清除当前显示
			SDL_RenderClear(renderer);
			// 将纹理的数据拷贝给渲染器
			SDL_RenderCopy(renderer, texture, NULL, &rect);
			// 显示
			SDL_RenderPresent(renderer);

纹理更新完毕后会将纹理的数据拷贝给渲染器,交由渲染器进行显示。

在SDL_RenderCopy()函数中,第三个第四个参数需要注意下。

第三个参数:选择输入纹理的一块矩形区域作为输入,设置为null时整个纹理输入。

第四个参数:选择渲染目标的一块矩形区域作为输出,设置为null时整个渲染目标输出。

我们可以理解为纹理就是原视频文件的图像,渲染目标是播放器中显示的输出图像。

因此,一般原视频文件的图像是要全部读取的,而输出的图像大小还需要取决于当前播放器窗口的大小,因此第四个参数通常是可调整的,而第三个参数一般是null。

    // 1. YUV的分辨率
	int video_width = YUV_WIDTH;
	int video_height = YUV_HEIGHT;
	// 2.显示窗口的分辨率
	int win_width = YUV_WIDTH;
	int win_height = YUV_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;

第四个参数使用SDL_Rect类型的rect变量进行表示。

当窗口大小相对视频的长宽大小出现变化时,需要根据变化比例,对渲染输出的目标,即显示的视频长宽也进行相应的调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值