FFmpeg+sdl代码注释学习---多线程

本代码取之雷博士小学期课设

主要介绍了如何在视频播放中添加多线程,使得程序更加健全鲁棒地应用其他操作~

关于其中的一些隐含问题,我已经做了注释,如果问题可留言联系~

#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 threadnum=0;
int mainnum=0;
int refresh_video(void *opaque){
	thread_exit=0;
	while (thread_exit==0) {
		SDL_Event event;
		event.type = REFRESH_EVENT;//正常的视频刷新事件
		SDL_PushEvent(&event);//把事件放入队列中,这样就触发了wait_event
		//为什么把延迟放在这里了?首先需要明白,这个pushevent不会等待主程序,他是自我独立的,
		//如果没有延迟,他会在程序开始后,在消息队列中放入很多REFRESH_EVENT事件。
		//这样程序就一直在忙碌刷新视频画面,而没有时间立马去做当前做的事情,
		//举个例子:当把延迟放到主程序中,当你缩放窗口大小,视频画面大小不会立马更改
		//因为在消息队列中还有很多需要完成REFRESH_EVENT的事件
		SDL_Delay(40);
		printf("threadnum=%d\n",threadnum++);
	}
	thread_exit=0;
	//Break
	SDL_Event event;
	event.type = BREAK_EVENT;
	SDL_PushEvent(&event);
	return 0;
}

int main(int argc, char* argv[])
{
	//注册SDL
	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)
	//视频画面帧格式YUV
	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线程,1:函数名称
	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 ); 
			printf("mainnum=%d\n",mainnum++);
			
			
		}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
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值