最简单的SDL2播放视频的例子(SDL2播放RGB/YUV)--进阶

SDL中事件和多线程


SDL事件

SDL_WaitEvent()等待一个事件

        SDL_PushEvent()发送一个事件

/**
 * 最简单的SDL2播放视频的例子(SDL2播放RGB/YUV)
 * Simplest Video Play SDL2 (SDL2 play RGB/YUV) 
 *
 * 雷霄骅 Lei Xiaohua
 * leixiaohua1020@126.com
 * 中国传媒大学/数字电视技术
 * Communication University of China / Digital TV Technology
 * http://blog.csdn.net/leixiaohua1020
 *
 * 本程序使用SDL2播放RGB/YUV视频像素数据。SDL实际上是对底层绘图
 * API(Direct3D,OpenGL)的封装,使用起来明显简单于直接调用底层
 * API。
 *
 * This software plays RGB/YUV raw video data using SDL2.
 * SDL is a wrapper of low-level API (Direct3D, OpenGL).
 * Use SDL is much easier than directly call these low-level API.  
 */


#include <stdio.h>


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


const int bpp=12;


int screen_w=500,screen_h=500;
const int pixel_w=320,pixel_h=180;


unsigned char buffer[pixel_w*pixel_h*bpp/8];


//Refresh Event
#define REFRESH_EVENT  (SDL_USEREVENT + 1)
//Break
#define BREAK_EVENT  (SDL_USEREVENT + 2)


int thread_exit=0;


int refresh_video(void *opaque){
thread_exit=0;
while (thread_exit==0) {
SDL_Event event;
event.type = REFRESH_EVENT;
SDL_PushEvent(&event);
SDL_Delay(40);
}
thread_exit=0;
//Break
SDL_Event event;
event.type = BREAK_EVENT;
SDL_PushEvent(&event);
return 0;
}


int main(int argc, char* argv[])
{
if(SDL_Init(SDL_INIT_VIDEO)) {  
printf( "Could not initialize SDL - %s\n", SDL_GetError()); 
return -1;



SDL_Window *screen; 
//SDL 2.0 Support for multiple windows
screen = SDL_CreateWindow("Simplest Video Play SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_w, screen_h,SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
if(!screen) {  
printf("SDL: could not create window - exiting:%s\n",SDL_GetError());  
return -1;
}
SDL_Renderer* sdlRenderer = SDL_CreateRenderer(screen, -1, 0);  


Uint32 pixformat=0;
//IYUV: Y + U + V  (3 planes)
//YV12: Y + V + U  (3 planes)
pixformat= SDL_PIXELFORMAT_IYUV;  


SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer,pixformat, SDL_TEXTUREACCESS_STREAMING,pixel_w,pixel_h);


FILE *fp=NULL;
fp=fopen("test_yuv420p_320x180.yuv","rb+");


if(fp==NULL){
printf("cannot open this file\n");
return -1;
}


SDL_Rect sdlRect;  


SDL_Thread *refresh_thread = SDL_CreateThread(refresh_video,NULL,NULL);
SDL_Event event;
while(1){
//Wait
SDL_WaitEvent(&event);
if(event.type==REFRESH_EVENT){
if (fread(buffer, 1, pixel_w*pixel_h*bpp/8, fp) != pixel_w*pixel_h*bpp/8){
// Loop
fseek(fp, 0, SEEK_SET);
fread(buffer, 1, pixel_w*pixel_h*bpp/8, fp);
}


SDL_UpdateTexture( sdlTexture, NULL, buffer, pixel_w);  


//FIX: If window is resize
sdlRect.x = 0;  
sdlRect.y = 0;  
sdlRect.w = screen_w;  
sdlRect.h = screen_h;  

SDL_RenderClear( sdlRenderer );   
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);  
SDL_RenderPresent( sdlRenderer );  

}else if(event.type==SDL_WINDOWEVENT){
//If Resize
SDL_GetWindowSize(screen,&screen_w,&screen_h);
}else if(event.type==SDL_QUIT){
thread_exit=1;
}else if(event.type==BREAK_EVENT){
break;
}
}
SDL_Quit();
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include #include //用键盘控制精灵移动 int main(int argc, char ** argv) { SDL_Surface * screen; //主表面 SDL_Surface * image; //用来放MM-----的图片信息(像素) SDL_Surface * PlayerImage; //用来测试的图片 SDL_Event event; Uint32 BeginTicks, EndTicks; SDL_Rect PRect, BRect; //PRect对应精灵的移动的小图位置(实现动画),BRect对应精灵在屏幕的位置。 unsigned char PlayerStarts = 0; unsigned char PlayerIndex = 0; bool bAppRun = true; //初始化SDL if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) { fprintf(stderr, "SDL_Init %s\n", SDL_GetError()); return -1; } //初始化成功设置退出要调用的函数SDL_Quit atexit(SDL_Quit); //创建一个640X480 16-bit 模式的主表面 16位可以让MM的效果好看一点 screen = SDL_SetVideoMode(230, 230, 16, SDL_SWSURFACE); if (screen == NULL) { fprintf(stderr, "Couldn't set 640x480x8 video mode %s\n", SDL_GetError()); return -1; } //读取MM图片信息,并创建一个表面,并把数据填入该表面中。 image = SDL_LoadBMP("./mm.bmp"); //请在终端里运行该程序 if (image == NULL) { fprintf(stderr, "Couldn't load MM, %s\n", SDL_GetError()); //遗憾你不能显示MM了,不过你可以用图片浏览程序看。 return -1; } //读取player.bmp PlayerImage = SDL_LoadBMP("./player.bmp"); //请在终端里运行该程序 if (image == NULL) { fprintf(stderr, "Couldn't load MM, %s\n", SDL_GetError()); //遗憾你不能显示MM了,不过你可以用图片浏览程序看。 return -1; } //读取第一个像素 Uint8 key = *((Uint8 *)PlayerImage->pixels); //设置色键 SDL_SetColorKey(PlayerImage, SDL_SRCCOLORKEY, key); //有了MM的表面了,就可以显示了。 //将MM的表面画在我们的主表面上,用MM来作为背景 if (SDL_BlitSurface(image, NULL, screen, NULL) < 0) { //解释一下NULL,第一个是按照image的尺寸显示,第二个是默认显示。你也可以指定大小,不过要用到SDL_Rect你可以看一看帮助。 fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); //看看提示吧 return -1; } PRect.x = 0; //初始化动画显示的图片。 PRect.y = 0; PRect.w = 32; PRect.h = 48; BRect.x = 0; //初始化精灵的位置。 BRect.y = 0; BRect.w = 32; BRect.h = 48; //贴上测试用的表面 if (SDL_BlitSurface(PlayerImage, &PRect, screen, &BRect) w, image->h); BeginT

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值