SDL显示bmp,SDL播放yuv420P

SDL窗口能拖动的代码取自:[这里]

其他的SDL代码取自官网的[Demo]。

// sdl_test_console.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#define YUV420P_320240	320*240*3/2		//115200

void PrintHex(uint8_t *src, uint32_t size);
void display_bmp(char* file_name, SDL_Surface *screen);

int _tmain(int argc, _TCHAR* argv[])
{
	if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) == -1)) {
		printf("Could not initialize SDL: %s.\n", SDL_GetError());
		exit(-1);
	}
	atexit(SDL_Quit);
	
	SDL_Surface *sdl_screen = NULL;
	sdl_screen = SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE|SDL_ANYFORMAT);
	if (sdl_screen == NULL) {
		exit(1);
	}
	display_bmp("./320_240.bmp", sdl_screen);

	// main loop 
	bool bRun = true ;
	while (bRun) {
		//Update Screen 
		SDL_Flip(sdl_screen); 

		// delay, 50 for simple 
		SDL_Delay(50); 

		//While there's an event to handle 
		SDL_Event event; 
		while (SDL_PollEvent(&event)) { 
			if  (event.type == SDL_QUIT) {
				bRun = false ;
			}
		}
	}

	return 0;
}

void display_bmp(char* file_name, SDL_Surface *screen)
{
    SDL_Surface* image = NULL;

    /* Load the BMP file into a surface */
    image = SDL_LoadBMP(file_name);
    if (image == NULL) {
        fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError());
        return;
    }

    /*
     * Palettized screen modes will have a default palette (a standard
     * 8*8*4 colour cube), but if the image is palettized as well we can
     * use that palette for a nicer colour matching
     */
    if (image->format->palette && screen->format->palette) {
        SDL_SetColors(screen, image->format->palette->colors, 0, image->format->palette->ncolors);
    }

    /* Blit onto the screen surface */
    if (SDL_BlitSurface(image, NULL, screen, NULL) < 0)
        fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());

    /* Update the modified region of the screen */
    SDL_UpdateRect(screen, 0, 0, image->w, image->h);

    /* Free the allocated BMP surface */
    SDL_FreeSurface(image);
}

void PrintHex(uint8_t *src, uint32_t size)
{
	for (uint32_t i = 0; i < size; ++i) {
		if (i > 0 && i % 16 == 0) {
			::OutputDebugStringA("\n");
		}
		AtlTrace("%02x ", src[i]);
	}
	::OutputDebugStringA("\n");
}

效果:

==========================================================

2012 09-13 17:10更新:

SDL真是太棒了!接口清晰,这才是人类进步的希望。

实现的是播放yuv420P裸数据的代码,至于怎么得到yuv420P数据,用大家都喜欢的ffmpeg:

ffmpeg -i miku39.flv -pix_fmt yuv420p -s 320*240 -ss 60 -t 30 miku.yuv

SDL播放相关代码:

// sdl_test_console.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#define YUV420P_320240	320*240*3/2		//115200

void DisplayYUV420P(uint8_t *buf, uint32_t w, uint32_t h, SDL_Overlay *overlay);

int _tmain(int argc, _TCHAR* argv[])
{
	uint8_t one_frame[YUV420P_320240] = {0};
	std::fstream in_yuv420p;
	in_yuv420p.open("yuv420p_320240.yuv", std::ios_base::in | std::ios_base::binary);
	//PrintHex(one_frame, YUV420P_320240);

	if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) == -1)) {
		printf("Could not initialize SDL: %s.\n", SDL_GetError());
		exit(-1);
	}
	atexit(SDL_Quit);
	
	SDL_Surface *sdl_screen = NULL;
	sdl_screen = SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE|SDL_ANYFORMAT);
	if (sdl_screen == NULL) {
		exit(1);
	}
	SDL_Overlay *sdl_overlay = SDL_CreateYUVOverlay(320, 240, SDL_IYUV_OVERLAY, sdl_screen);
	if (sdl_overlay == NULL) {
		exit(1);
	}

	SDL_Rect video_rect;
	video_rect.x = 0;
	video_rect.y = 0;
	video_rect.w = 320;
	video_rect.h = 240;

	bool sdl_running = true;
	while (sdl_running) {
		//read yuv from file
		if (!in_yuv420p.eof()) {
			in_yuv420p.read((char *)one_frame, YUV420P_320240);
			auto rel_size = in_yuv420p.gcount();
			if (rel_size < YUV420P_320240) continue ;
			DisplayYUV420P(one_frame, 320, 240, sdl_overlay);
			SDL_DisplayYUVOverlay(sdl_overlay, &video_rect);
		}

		//Update Screen 
		SDL_Flip(sdl_screen); 

		// delay, 40 for sample (25 fps)
		SDL_Delay(40); 

		//While there's an event to handle 
		SDL_Event sdl_event; 
		while (SDL_PollEvent(&sdl_event)) { 
			if  (sdl_event.type == SDL_QUIT) {
				sdl_running = false ;
			}
		}
	}

	SDL_FreeYUVOverlay(sdl_overlay);
	return 0;
}

void DisplayYUV420P(uint8_t *buf, uint32_t w, uint32_t h, SDL_Overlay *overlay)
{
	/* Fill in video data */
	uint32_t yuv_size = (w*h) * 3/2;
	auto y_video_data = buf;
	auto u_video_data = buf + w * h;
	auto v_video_data = u_video_data + (w * h / 4);

	/* Fill in pixel data - the pitches array contains the length of a line in each plane */
	SDL_LockYUVOverlay(overlay);
	memcpy(overlay->pixels[0], y_video_data, w * h);
	memcpy(overlay->pixels[1], u_video_data, w * h / 4);
	memcpy(overlay->pixels[2], v_video_data, w * h / 4);

	SDL_UnlockYUVOverlay(overlay);
}

转载于:https://my.oschina.net/gysutantoman/blog/78369

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值