SDL窗口能拖动的代码取自:[这里]
其他的SDL代码取自官网的[Demo]。
// sdl_test_console.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#define YUV420P_320240320*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_320240320*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);
}