中华门窗网怎么做网站,做网站用html,网站服务公司特点,建站多少钱一个目录
编译和移植
视频子系统
视频子系统产生图像的步骤
api
初始化 SDL 的相关子系统
使用指定的宽、高和色深来创建一个视窗 surface
使用 fmt 指定的格式创建一个像素点编辑
将 dst 上的矩形 dstrect 填充为单色 color编辑
将 src 快速叠加到 dst 上编辑
更新…目录
编译和移植
视频子系统
视频子系统产生图像的步骤
api
初始化 SDL 的相关子系统
使用指定的宽、高和色深来创建一个视窗 surface
使用 fmt 指定的格式创建一个像素点编辑
将 dst 上的矩形 dstrect 填充为单色 color编辑
将 src 快速叠加到 dst 上编辑
更新 screen 上的图像元素编辑
api例子
音频子系统
SDL 中默认支持的对 wav 格式 的音频文件的 API
存放音频数据的具体信息
加载 wav 格式的音频文件编辑
启动音频设备编辑
暂停或者继续编辑
api例子
事件子系统
联合体
使用鼠标的实例
处理YUV视频源 sdl是一个跨平台的底层开发库提供操作诸如音频、 键盘、鼠标、游戏杆以及显卡等硬件的方法被很多多媒体播放器、模拟器和流行游戏所使 用SDL 支持 Windows、MacOS、Linux、iOS 以及 Android也就是说你目所能及的 几乎所有平台它都能运行并且 SDL 是开源的完全由 C 语言编写
编译和移植
下载http://www.libsdl.org/release/SDL-1.2.15.tar.gz解压进入根目录./configure --hostarm-none-Linux-gnueabi --prefix/usr/local/sdl 注意--host 是指定交叉编译器的前缀--prefix 是指定 SDL 的安装目录两者都要根 据你的具体情况来写不必照抄makemake install将编译后的目录/usr/local/sdl 全部拷贝到开发板中设置好库目录的环境变量 将此目录拷贝到开发板的/usr/local/sdl 中就设置export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/usr/local/sdl/lib
视频子系统
在屏幕的显示能力当我们需要显示图片、文字的时候那就必须使用视频子系统
支持设置视频模式即创建视频窗口也支持直接的图像帧缓冲、 支持 Alpha 像素混合、支持窗口管理和图形渲染等
视频子系统产生图像的步骤
初始化 SDL 视频子系统设置视频模式包括宽高、色深等并创建得到视窗 surface加载一张图像获得该图像的 surface将图像 surface“放到”视窗 surface 上同时可以设置你要放置的位置更新视窗 surface使得图像可 api
初始化 SDL 的相关子系统 使用指定的宽、高和色深来创建一个视窗 surface 使用 fmt 指定的格式创建一个像素点
将 dst 上的矩形 dstrect 填充为单色 color
将 src 快速叠加到 dst 上
更新 screen 上的图像元素
api例子
使用以上 API结合触摸屏运行库 tslib 来实现移动图片的效果
// 初始化 SDL 视频子系统并设置视窗 surface 的参数与 LCD 一致
SDL_Init(SDL_INIT_VIDEO);
screen SDL_SetVideoMode(LCD_WIDTH, LCD_HEIGHT, 0, SDL_ANYFORMAT | SDL_SWSURFACE);// 装载 BMP 图片文件 SDL 表示没压力
image SDL_LoadBMP(argv[1]);// 1, image_offset 规定了图片要显示的矩形部分
// 2, background_offset 规定了图像要显示在视窗的那个位置其中
SDL_Rect image_offset;
SDL_Rect backgroud_offset;
bzero(image_offset, sizeof(image_offset));
bzero(backgroud_offset, sizeof(backgroud_offset));
printf(press Ctrlc to quit.\n);
sem_init(s, 0, 0);pthread_t tid;
pthread_create(tid, NULL, read_moving, NULL);// 1, x 和 y 规定了图像要显示的矩形的左上角坐标
// 2, w 和 h 规定了以(x,y)为左上角的矩形的宽和高
image_offset.x 0;
image_offset.y 0;
image_offset.w 400;
image_offset.h 240;while (1) {// 产生一个 RGB 值为 000黑色的像素uint32_t black_pixel SDL_MapRGB(screen-format, 0, 0, 0);// 将屏幕刷成黑色SDL_FillRect(screen, screen-clip_rect, black_pixel);// 将图像imageblit 到屏幕上screenlong tmp1 backgroud_offset.x;long tmp2 backgroud_offset.y;SDL_BlitSurface(image, image_offset, screen, backgr_offset);// 显示 screen 上的元素SDL_Flip(screen);// 1x 和 y 规定了图像 surface 放在视窗的左上角坐标// 2w 和 h 都是作废的。backgroud_offset.x tmp1 xoffset;backgroud_offset.y tmp2 yoffset;printf(backgroud_offset.x: %d\n, backgroud_offset.x);printf(backgroud_offset.y: %d\n, backgroud_offset.y);sem_wait(s);
}要渲染视频流需要结合 FFmpeg 来做 图片不是 bmp 格式的比如 jpeg、png、tiff 等需要使用第三方扩展库 SDL_image
音频子系统
SDL 中默认支持的对 wav 格式 的音频文件的 API
存放音频数据的具体信息 加载 wav 格式的音频文件
启动音频设备
暂停或者继续
api例子
#include stdio.h
#include stdlib.h
#include SDL.h
#include SDL_audio.h
#include SDL_config.hstruct wave
{SDL_AudioSpec spec;Uint8 *sound; /* 音频数据缓冲区指针 */Uint32 soundlen; /* 音频数据尺寸 */int soundpos; /* 已处理数据大小 */
} wave;// 画进度条
void draw_progress_bar(int left, int len)
{int i;for (i 0; i 20; i)printf(\b);printf([);int n ((1 - (float)left / len) * 100) / 10;for (i 0; i n; i)printf(-);printf();for (i 0; i 9 - n; i)printf( );printf(] %.1f%%, (1 - (float)left / len) * 100);fflush(stdout);
}// 音频解码回调函数
void deal_audio(void *unused, Uint8 *stream, int len)
{Uint8 *waveptr;int waveleft;waveptr wave.sound wave.soundpos;waveleft wave.soundlen - wave.soundpos;while (waveleft len){memcpy(stream, waveptr, waveleft);stream waveleft;len - waveleft;waveptr wave.sound;waveleft wave.soundlen;wave.soundpos 0;printf(\n);SDL_CloseAudio();SDL_FreeWAV(wave.sound);SDL_Quit();exit(0);}memcpy(stream, waveptr, len);wave.soundpos len;draw_progress_bar(waveleft, wave.soundlen);
}int main(int argc, char *argv[])
{// 初始化音频子系统SDL_Init(SDL_INIT_AUDIO);// 加载 WAV 文件SDL_LoadWAV(argv[1], wave.spec, wave.sound, wave.soundlen);// 指定音频数据处理回调函数wave.spec.callback deal_audio;// 启动音频设备SDL_OpenAudio(wave.spec, NULL);SDL_PauseAudio(0);printf(\npress Enter to pause and unpause.\n);static int pause_on 1;while (1){// 按下回车键暂停或播放getchar();SDL_PauseAudio(pause_on);if (!(pause_on % 2))printf(stopped.\n);}return 0;
}SDL 利用函数 SDL_LoadWAV()将音频数据加载到一个缓冲区中然后 通过结构体 SDL_AudioSpec 中的 callback 指定回调函数 deal_audio()该函数会在音 频设备准备好要读取数据的时候被自动调用。 然后调用 SDL_OpenAudio()启动音频设备并且调用 SDL_PauseAudio(0)来使 得启动整个流程此时只要音频设备准备好了需要数据的时候就会自动调用 deal_audio 这个函数。回调函数 deal_audio()就像一个搬运工一旦音频设备准备好可以读取数据了 他就将音频数据源源不断地搬到音频设备上去播放 音频文件不是 wav 格式的比如 MP3,MIDI,OGG,MOD 这些就需要用到 SDL 的第三方扩展库 SDL_Mixer。
事件子系统
SDL的事件允许程序接收从用户输入的信息当调用SDL_Init(SDL_INIT_VIDEO)初始化视频子系统时事件子系统将被连带自动初始化。本质上所有的事件都将被SDL置入一个所谓的“等待队列”中我们可以使用诸如SDL_PollEvent()或者 SDL_WaitEvent()或者 SDL_PeepEvent()来处理或者检查当前正在等待的事件。SDL中处理事件的关键核心是一个叫SDL_Event的联合体事实上“等待队列”中储存的就是这些联合体SDL_PollEvent()或者SDL_WaitEvent()讲这些联合体从队列中读出然后根据其中的信息作出相应的处理
联合体 囊括了SDL-1.2版本所支持的所有事件
type事件的类型active事件触发key键盘motion鼠标移动button鼠标按键jaxis游戏杆摇杆jball游戏杆轨迹球jhatJoystick游戏杆帽jbutton游戏杆按键resize窗口大小变更expose窗口焦点变更quit退出user用户自定义事件syswm未定义窗口管理事件
使用鼠标的实例
功能
使用鼠标左键点击向左小箭头显示上一张图片使用鼠标左键点击向右小箭头显示下一张图片使用鼠标右键退出程序
代码
#include SDL.h
#include stdio.h
#include stdbool.h#define WIDTH 800
#define HEIGHT 480
#define BPP 32SDL_Surface* screen;
SDL_Surface* image;
SDL_Surface* left, *right;SDL_Surface* load_image(const char* filename) {return SDL_DisplayFormat(SDL_LoadBMP(filename));
}void show_bmp(const char* filename) {// Fill the screen with black coloruint32_t black_pixel SDL_MapRGB(screen-format, 0, 0, 0);SDL_FillRect(screen, screen-clip_rect, black_pixel);// Load the imageimage load_image(filename);// Set the position of the imagestatic SDL_Rect rect {0, 0};SDL_BlitSurface(image, NULL, screen, rect);// Set the positions of the left and right arrowsstatic SDL_Rect left_pos {100, 200};static SDL_Rect right_pos {700, 200};SDL_BlitSurface(left, NULL, screen, left_pos);SDL_BlitSurface(right, NULL, screen, right_pos);// Refresh the screen to display the imageSDL_Flip(screen);
}int main(int argc, char const* argv[]) {if (argc ! 2) {printf(Usage: %s bmp_directories\n, argv[0]);exit(0);}SDL_Init(SDL_INIT_EVERYTHING);screen SDL_SetVideoMode(WIDTH, HEIGHT, BPP, SDL_SWSURFACE);const char* bmp_files[] {1.bmp, 2.bmp, 3.bmp, 4.bmp};chdir(argv[1]);left load_image(left.bmp);right load_image(right.bmp);// Blit the image onto the screenSDL_Rect rect {0, 0};SDL_BlitSurface(image, NULL, screen, rect);SDL_Rect left_pos {100, 200};SDL_Rect right_pos {700, 200};// Set white color as transparentint32_t key SDL_MapRGB(screen-format, 0xff, 0xff, 0xff);SDL_SetColorKey(left, SDL_SRCCOLORKEY, key);SDL_SetColorKey(right, SDL_SRCCOLORKEY, key);// Display the first imageshow_bmp(bmp_files[0]);// Block and wait for mouse clickint i 0;SDL_Event event;while (1) {SDL_WaitEvent(event);// Switch to the previous image when the left arrow is clickedif (event.button.type SDL_MOUSEBUTTONUP event.button.button SDL_BUTTON_LEFT event.button.y 200 event.button.y 287) {if (event.button.x 100 event.button.x 160) {i (i 0) ? 3 : (i - 1);}if (event.button.x 700 event.button.x 760) {i (i 1) % 4;}// Release the current image resources before displaying another imageSDL_FreeSurface(image);show_bmp(bmp_files[i]);}// Quit the program when the right mouse button is clickedif (event.button.type SDL_MOUSEBUTTONUP event.button.button SDL_BUTTON_RIGHT) {break;}}return 0;
}处理YUV视频源
使用V4L2接口获取摄像头数据YUV格式然后使用SDL将视频数据显示到LCD显示器上
步骤
1.准备好LCD设置好相应的参数备用2.准备好摄像头设置好采集格式等参数备用3.初始化SDL并创建YUV层备用4.启动摄像头开始捕获YUV数据并将数据丢给SDL的YUV处理层显示
具体代码
1 打开LCD设备获取LCD显示器的设备参数申请一块适当跟LCD尺寸一样大小的显存2. 打开摄像头设备文件配置摄像头的采集格式设置即将要申请的摄像头缓存的参数使用该参数reqbuf来申请缓存根据刚刚设置的reqbuf.count的值来定义相应数量的struct v4l2_buffer3. 初始化带音视频和定时器子系统的SDL创建基本surface创建一个YUYV格式的surface4. 启动摄像头准备好应用层缓冲区参数开始捕获采集数据将数据丢给SDL处理
#include SDL.h
#include stdio.h
#include stdbool.h
#include fcntl.h
#include unistd.h
#include sys/ioctl.h
#include sys/mman.h
#include linux/fb.h
#include linux/videodev2.h#define LCD_WIDTH 800
#define LCD_HEIGHT 480void 打开LCD并分配显存(unsigned int **fb_mem, struct fb_var_screeninfo *lcdinfo) {int lcd open(/dev/fb0, O_RDWR);ioctl(lcd, FBIOGET_VSCREENINFO, lcdinfo);*fb_mem mmap(NULL, lcdinfo-xres * lcdinfo-yres * lcdinfo-bits_per_pixel / 8,PROT_READ | PROT_WRITE, MAP_SHARED, lcd, 0);
}void 打开摄像头并配置(int *cam_fd, struct v4l2_format *fmt, int *nbuf, struct v4l2_requestbuffers *reqbuf,struct v4l2_buffer *buffer, unsigned char **start) {*cam_fd open(/dev/video3, O_RDWR);bzero(fmt, sizeof(*fmt));fmt-type V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt-fmt.pix.width LCD_WIDTH;fmt-fmt.pix.height LCD_HEIGHT;fmt-fmt.pix.pixelformat V4L2_PIX_FMT_YUYV; // YUYV 格式fmt-fmt.pix.field V4L2_FIELD_INTERLACED;ioctl(*cam_fd, VIDIOC_S_FMT, fmt);*nbuf 3;bzero(reqbuf, sizeof(*reqbuf));reqbuf-type V4L2_BUF_TYPE_VIDEO_CAPTURE;reqbuf-memory V4L2_MEMORY_MMAP;reqbuf-count *nbuf;ioctl(*cam_fd, VIDIOC_REQBUFS, reqbuf);for (int i 0; i *nbuf; i) {bzero(buffer[i], sizeof(buffer[i]));buffer[i].type V4L2_BUF_TYPE_VIDEO_CAPTURE;buffer[i].memory V4L2_MEMORY_MMAP;buffer[i].index i;ioctl(*cam_fd, VIDIOC_QUERYBUF, buffer[i]);start[i] mmap(NULL, buffer[i].length, PROT_READ | PROT_WRITE,MAP_SHARED, *cam_fd, buffer[i].m.offset);ioctl(*cam_fd, VIDIOC_QBUF, buffer[i]);}
}int main() {int lcd, cam_fd, nbuf;unsigned int *fb_mem;struct fb_var_screeninfo lcdinfo;struct v4l2_format fmt;struct v4l2_requestbuffers reqbuf;struct v4l2_buffer buffer[3];unsigned char *start[3];// 打开 LCD 并分配帧缓冲区打开LCD并分配显存(fb_mem, lcdinfo);// 打开摄像头并配置打开摄像头并配置(cam_fd, fmt, nbuf, reqbuf, buffer, start);// 初始化 SDL 包括视频、音频和定时器子系统SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);// 创建基本表面SDL_Surface *screen NULL;screen SDL_SetVideoMode(LCD_WIDTH, LCD_HEIGHT, 0, 0);// 创建 YUYV 格式的表面SDL_Overlay *bmp SDL_CreateYUVOverlay(fmt.fmt.pix.width, fmt.fmt.pix.height,SDL_YUY2_OVERLAY, screen);// 启动摄像头enum v4l2_buf_type vtype V4L2_BUF_TYPE_VIDEO_CAPTURE;ioctl(cam_fd, VIDIOC_STREAMON, vtype);// 准备应用层缓冲区参数struct v4l2_buffer v4lbuf;bzero(v4lbuf, sizeof(v4lbuf));v4lbuf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;v4lbuf.memory V4L2_MEMORY_MMAP;while (1) {// 捕获数据for (int i 0; i nbuf; i) {v4lbuf.index i;ioctl(cam_fd, VIDIOC_DQBUF, v4lbuf);memcpy(bmp-pixels[0], start[i], buffer[i].length);bmp-pitches[0] fmt.fmt.pix.width;ioctl(cam_fd, VIDIOC_QBUF, v4lbuf);}// 锁定 YUV 重叠SDL_LockYUVOverlay(bmp);// 解锁 YUV 重叠SDL_UnlockYUVOverlay(bmp);// 显示 YUV 重叠SDL_DisplayYUVOverlay(bmp, NULL);}// 清理munmap(fb_mem, lcdinfo.xres * lcdinfo.yres * lcdinfo.bits_per_pixel / 8);close(lcd);close(cam_fd);return 0;
}