本文将指导你如何使用SDL库在屏幕上显示视频并绘制图形,特别介绍YUV覆盖技术的应用。通过本文,你将学会初始化SDL库、创建显示表面、处理YUV视频数据,并实现视频的实时显示。同时,我们还将探讨临界区在多线程环境中的应用,确保程序稳定性。
—
# 指导2:利用SDL显示屏幕及绘制图形,含YUV覆盖介绍
## SDL与视频显示
为了在屏幕上展示内容,我们将借助SDL(Simple DirectMedia Layer)库。SDL是一个跨平台的多媒体库,广泛应用于各种工程项目中。你可以从其官方网站[http://www.libsdl.org/](http://www/libsdl.org/)获取源代码,或直接下载到你的操作系统。本指导需要你编译这个库,后续指导也同样如此。
### 初始化SDL库
使用SDL前,首先需要包含其头文件并初始化库:
“`c
#include
#include
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
fprintf(stderr, “Could not initialize SDL – %sn”, SDL_GetError());
exit(1);
}
“`
`SDL_Init()`函数用于初始化SDL库,参数指定了所需的特性。`SDL_GetError()`则用于调试错误。
## 创建显示表面
在SDL中,显示图像的基本区域称为“面(surface)”。我们需要创建一个屏幕表面:
“`c
SDL_Surface screen;
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
if (!screen) {
fprintf(stderr, “SDL: could not set video mode – exitingn”);
exit(1);
}
“`
这里创建了一个给定宽度和高度的屏幕表面。参数`0`表示使用系统默认的颜色深度。
## 使用YUV覆盖
为了在屏幕上显示视频,我们创建一个YUV覆盖:
“`c
SDL_Overlay bmp;
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen);
“`
YUV覆盖允许直接在屏幕上显示原始YUV数据。YV12是最快的格式,而YUV420P则更节省带宽,通过4:2:0二次抽样减少色度信息。
### 处理YUV数据
我们需要将视频帧转换为YUV格式并显示到覆盖上:
“`c
if (frameFinished) {
SDL_LockYUVOverlay(bmp);
AVPicture pict;
pict.data[0] = bmp->pixels[0];
pict.data[1] = bmp->pixels[2];
pict.data[2] = bmp->pixels[3];
pict.linesize[0] = bmp->pitches[0];
pict.linesize[1] = bmp->pitches[1];
pict.linesize[2] = bmp->pitches[2];
// 转换为YUV420P格式
img_convert(&pict, PIX_FMT_YUV420P, (AVPicture )pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
SDL_UnlockYUVOverlay(bmp);
}
“`
首先锁定覆盖,然后设置`AVPicture`结构体的数据指针和行尺寸。`img_convert`函数用于格式转换。
### 绘制图像
最后,我们调用`SDL_DisplayYUVOverlay`显示图像:
“`c
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL_DisplayYUVOverlay(bmp, &rect);
“`
这个函数会自动处理缩放,并利用显卡加速显示。
## 事件处理
SDL采用事件驱动模型,可以通过鼠标点击、移动或信号触发事件。本程序将处理`SDL_QUIT`事件以退出:
“`c
SDL_Event event;
av_free_packet(&packet);
SDL_PollEvent(&event);
switch (event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
default:
break;
}
“`
## 编译与运行
使用Linux系统编译示例代码:
“`bash
gcc -o tutorial02 tutorial02.c -lavutil -lavformat -lavcodec -lz -lm `sdl-config –cflags –libs`
“`
`sdl-config`命令会提供正确的编译参数。不同平台可能需要调整编译命令。
## 总结
运行程序后,视频将实时显示。目前我们尚未处理帧同步问题,将在后续指导中探讨。下一部分将聚焦音频处理。
—
{1、SDL, 2、YUV覆盖, 3、视频显示, 4、临界区, 5、多媒体库}
本文是基于《指导2:利用SDL在屏幕显示及绘制图形,含YUV覆盖介绍》的AI重写版本
评论(0)