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); }