您的位置:首页 > 其它

SDL显示bmp,SDL播放yuv420P

2013-11-06 10:51 417 查看
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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SDL yuv