命令行下配置:
G:CodingVideoSDLproj>tree /F 文件夹 PATH 列表 卷序列号为 0FD5-0CC8 G:. │ sdl.cpp │ SDL2.dll │ SDL2.lib │ SDL2main.lib │ sintel_640_360.yuv │ test_yuv420p_320x180.yuv │ └─sdl begin_code.h close_code.h SDL.h SDL_assert.h SDL_atomic.h SDL_audio.h SDL_bits.h SDL_blendmode.h SDL_clipboard.h SDL_config.h SDL_cpuinfo.h SDL_egl.h SDL_endian.h SDL_error.h SDL_events.h SDL_filesystem.h SDL_gamecontroller.h SDL_gesture.h SDL_haptic.h SDL_hints.h SDL_joystick.h SDL_keyboard.h SDL_keycode.h SDL_loadso.h SDL_log.h SDL_main.h SDL_messagebox.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_opengles2.h SDL_opengles2_gl2.h SDL_opengles2_gl2ext.h SDL_opengles2_gl2platform.h SDL_opengles2_khrplatform.h SDL_opengl_glext.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_render.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_shape.h SDL_stdinc.h SDL_surface.h SDL_system.h SDL_syswm.h SDL_test.h SDL_test_assert.h SDL_test_common.h SDL_test_compare.h SDL_test_crc32.h SDL_test_font.h SDL_test_fuzzer.h SDL_test_harness.h SDL_test_images.h SDL_test_log.h SDL_test_md5.h SDL_test_random.h SDL_thread.h SDL_timer.h SDL_touch.h SDL_types.h SDL_version.h SDL_video.h G:CodingVideoSDLproj>dir 驱动器 G 中的卷没有标签。 卷的序列号是 0FD5-0CC8 G:CodingVideoSDLproj 的目录 2016/08/20 09:19 <DIR> . 2016/08/20 09:19 <DIR> .. 2016/01/02 11:39 <DIR> sdl 2016/08/20 09:17 1,757 sdl.cpp 2016/01/02 11:58 1,047,552 SDL2.dll 2016/01/02 11:39 120,400 SDL2.lib 2016/01/02 11:39 37,594 SDL2main.lib 2015/07/03 01:39 34,560,000 sintel_640_360.yuv 2014/10/13 15:50 4,320,000 test_yuv420p_320x180.yuv 6 个文件 40,087,303 字节 3 个目录 10,272,571,392 可用字节 G:CodingVideoSDLproj>
源码:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> extern "C" { #include "SDL.h" }; int main(int argc, char* argv[]) { //窗口 SDL_Window *sdlScreen; //渲染器 SDL_Renderer* sdlRenderer; //纹理 SDL_Texture* sdlTexture; //矩形结构 SDL_Rect sdlRect; const int bpp = 12; //屏幕宽高 int screen_w = 640, screen_h = 360; const int pixel_w = 640, pixel_h = 360; unsigned char buffer[pixel_w * pixel_h * bpp / 8]; char filename[] = "sintel_640_360.yuv"; FILE *fp = NULL; fp = fopen(filename, "rb+"); if (fp == NULL) { printf("cannot open this file "); return -1; } //初始化SDL系统 if (SDL_Init(SDL_INIT_VIDEO)) { printf("Could not initialize SDL - %s ", SDL_GetError()); return -1; } //创建窗口SDL_Window /** * 函数声明:extern DECLSPEC SDL_Window * SDLCALL * SDL_CreateWindow(const char *title,int x, int y, int w, int h, Uint32 flags); * rief Create a window with the specified position, dimensions, and flags. * * param title The title of the window, in UTF-8 encoding. * param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or * ::SDL_WINDOWPOS_UNDEFINED. * param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or * ::SDL_WINDOWPOS_UNDEFINED. * param w The width of the window, in screen coordinates. * param h The height of the window, in screen coordinates. * param flags The flags for the window, a mask of any of the following: * ::SDL_WINDOW_FULLSCREEN, ::SDL_WINDOW_OPENGL, * ::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_BORDERLESS, * ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED, * ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_INPUT_GRABBED, * ::SDL_WINDOW_ALLOW_HIGHDPI. * * eturn The id of the window created, or zero if window creation failed. * * If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size * in pixels may differ from its size in screen coordinates on platforms with * high-DPI support (e.g. iOS and Mac OS X). Use SDL_GetWindowSize() to query * the client area's size in screen coordinates, and SDL_GL_GetDrawableSize() * or SDL_GetRendererOutputSize() to query the drawable size in pixels. * * sa SDL_DestroyWindow() */ sdlScreen = SDL_CreateWindow("Simplest Video Play SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); if (sdlScreen == 0) { printf("SDL: could not create SDL_Window - exiting:%s ", SDL_GetError()); return -1; } //创建渲染器SDL_Renderer /** * 函数声明:extern DECLSPEC SDL_Renderer * SDLCALL * SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags); * rief Create a 2D rendering context for a window. * * param window The window where rendering is displayed. * param index The index of the rendering driver to initialize, or -1 to * initialize the first one supporting the requested flags. * param flags ::SDL_RendererFlags. * * eturn A valid rendering context or NULL if there was an error. * * sa SDL_CreateSoftwareRenderer() * sa SDL_GetRendererInfo() * sa SDL_DestroyRenderer() */ sdlRenderer = SDL_CreateRenderer(sdlScreen, -1, SDL_RENDERER_ACCELERATED); if (sdlRenderer == NULL) { printf("SDL: could not create SDL_Renderer - exiting:%s ", SDL_GetError()); return -1; } //IYUV: Y + U + V (3 planes) //YV12: Y + V + U (3 planes) //创建纹理SDL_Texture /** * 函数声明:extern DECLSPEC SDL_Texture * SDLCALL * SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h); * rief Create a texture for a rendering context. * * param renderer The renderer. * param format The format of the texture. * param access One of the enumerated values in ::SDL_TextureAccess. * param w The width of the texture in pixels. * param h The height of the texture in pixels. * * eturn The created texture is returned, or NULL if no rendering context was * active, the format was unsupported, or the width or height were out * of range. * * sa SDL_QueryTexture() * sa SDL_UpdateTexture() * sa SDL_DestroyTexture() */ sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h); if (sdlTexture == NULL) { printf("SDL: could not create SDL_Texture - exiting:%s ", SDL_GetError()); return -1; } while (1) { //读取一帧数据 if (fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp) != pixel_w * pixel_h * bpp / 8) { //循环播放 fseek(fp, 0, SEEK_SET); fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp); } //设置纹理数据 /** * 函数声明:extern DECLSPEC int SDLCALL * SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch); * rief Update the given texture rectangle with new pixel data. * * param texture The texture to update * param rect A pointer to the rectangle of pixels to update, or NULL to * update the entire texture. * param pixels The raw pixel data. * param pitch The number of bytes in a row of pixel data, including padding between lines. * * eturn 0 on success, or -1 if the texture is not valid. * * ote This is a fairly slow function. */ SDL_UpdateTexture(sdlTexture, NULL, buffer, pixel_w); sdlRect.x = 0; sdlRect.y = 0; sdlRect.w = screen_w; sdlRect.h = screen_h; /** * 函数声明:extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer); * rief Clear the current rendering target with the drawing color * * This function clears the entire rendering target, ignoring the viewport. * * eturn 0 on success, or -1 on error */ SDL_RenderClear(sdlRenderer); //将纹理数据拷贝给渲染器 /** * 函数声明:extern DECLSPEC int SDLCALL * SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect); * rief Copy a portion of the texture to the current rendering target. * * param renderer The renderer which should copy parts of a texture. * param texture The source texture. * param srcrect A pointer to the source rectangle, or NULL for the entire * texture. * param dstrect A pointer to the destination rectangle, or NULL for the * entire rendering target. * * eturn 0 on success, or -1 on error */ SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); //显示数据 /** * 函数声明:extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer); * rief Update the screen with rendering performed. */ SDL_RenderPresent(sdlRenderer); //工具函数,用于延时,视频一般一秒播放25帧 /** * 函数声明:extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); * rief Wait a specified number of milliseconds before returning. */ SDL_Delay(40); } SDL_DestroyTexture(sdlTexture); SDL_DestroyRenderer(sdlRenderer); SDL_DestroyWindow(sdlScreen); SDL_Quit(); return 0; }
命令行下:
多线程版本:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> extern "C" { #include "SDL.h" }; //Refresh Event #define REFRESH_EVENT (SDL_USEREVENT + 1) //Break #define BREAK_EVENT (SDL_USEREVENT + 2) bool thread_exit = false; int RefreshVideo(void *opaque) { thread_exit = false; while (!thread_exit) { SDL_Event event; event.type = REFRESH_EVENT; SDL_PushEvent(&event); SDL_Delay(40); } thread_exit = false; //Break SDL_Event event; event.type = BREAK_EVENT; SDL_PushEvent(&event); return 0; } int main(int argc, char* argv[]) { //窗口 SDL_Window *sdlScreen = NULL; //渲染器 SDL_Renderer* sdlRenderer = NULL; //纹理 SDL_Texture* sdlTexture = NULL; //矩形结构 SDL_Rect sdlRect; SDL_Thread *sdlThread = NULL; SDL_Event event; //屏幕宽高 int screen_w = 640, screen_h = 360; const int pixel_w = 640, pixel_h = 272; unsigned char buffer[pixel_w * pixel_h * 3 / 2]; char filename[] = "film_640_272.yuv"; int i = 1; FILE *fp = NULL; fp = fopen(filename, "rb+"); if (fp == NULL) { printf("cannot open this file "); return -1; } //初始化SDL系统 if (SDL_Init(SDL_INIT_VIDEO)) { printf("Could not initialize SDL - %s ", SDL_GetError()); return -1; } //创建窗口SDL_Window /** * 函数声明:extern DECLSPEC SDL_Window * SDLCALL * SDL_CreateWindow(const char *title,int x, int y, int w, int h, Uint32 flags); * rief Create a window with the specified position, dimensions, and flags. * * param title The title of the window, in UTF-8 encoding. * param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or * ::SDL_WINDOWPOS_UNDEFINED. * param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or * ::SDL_WINDOWPOS_UNDEFINED. * param w The width of the window, in screen coordinates. * param h The height of the window, in screen coordinates. * param flags The flags for the window, a mask of any of the following: * ::SDL_WINDOW_FULLSCREEN, ::SDL_WINDOW_OPENGL, * ::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_BORDERLESS, * ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED, * ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_INPUT_GRABBED, * ::SDL_WINDOW_ALLOW_HIGHDPI. * * eturn The id of the window created, or zero if window creation failed. * * If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size * in pixels may differ from its size in screen coordinates on platforms with * high-DPI support (e.g. iOS and Mac OS X). Use SDL_GetWindowSize() to query * the client area's size in screen coordinates, and SDL_GL_GetDrawableSize() * or SDL_GetRendererOutputSize() to query the drawable size in pixels. * * sa SDL_DestroyWindow() */ sdlScreen = SDL_CreateWindow("Simplest Video Play SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); if (sdlScreen == 0) { printf("SDL: could not create SDL_Window - exiting:%s ", SDL_GetError()); return -1; } //创建渲染器SDL_Renderer /** * 函数声明:extern DECLSPEC SDL_Renderer * SDLCALL * SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags); * rief Create a 2D rendering context for a window. * * param window The window where rendering is displayed. * param index The index of the rendering driver to initialize, or -1 to * initialize the first one supporting the requested flags. * param flags ::SDL_RendererFlags. * * eturn A valid rendering context or NULL if there was an error. * * sa SDL_CreateSoftwareRenderer() * sa SDL_GetRendererInfo() * sa SDL_DestroyRenderer() */ sdlRenderer = SDL_CreateRenderer(sdlScreen, -1, SDL_RENDERER_ACCELERATED); if (sdlRenderer == NULL) { printf("SDL: could not create SDL_Renderer - exiting:%s ", SDL_GetError()); return -1; } //创建纹理SDL_Texture /** * 函数声明:extern DECLSPEC SDL_Texture * SDLCALL * SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h); * rief Create a texture for a rendering context. * * param renderer The renderer. * param format The format of the texture. * param access One of the enumerated values in ::SDL_TextureAccess. * param w The width of the texture in pixels. * param h The height of the texture in pixels. * * eturn The created texture is returned, or NULL if no rendering context was * active, the format was unsupported, or the width or height were out * of range. * * sa SDL_QueryTexture() * sa SDL_UpdateTexture() * sa SDL_DestroyTexture() */ sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h); if (sdlTexture == NULL) { printf("SDL: could not create SDL_Texture - exiting:%s ", SDL_GetError()); return -1; } sdlThread = SDL_CreateThread(RefreshVideo, NULL, NULL); while (1) { SDL_WaitEvent(&event); if (event.type == REFRESH_EVENT) { //读取一帧数据 int count = fread(buffer, 1, pixel_w * pixel_h * 3 / 2, fp); if (count != pixel_w * pixel_h * 3 / 2) { break; //循环播放 fseek(fp, 0, SEEK_SET); i = 1; fread(buffer, 1, pixel_w * pixel_h * 3 / 2, fp); } //设置纹理数据 /** * 函数声明:extern DECLSPEC int SDLCALL * SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch); * rief Update the given texture rectangle with new pixel data. * * param texture The texture to update * param rect A pointer to the rectangle of pixels to update, or NULL to * update the entire texture. * param pixels The raw pixel data. * param pitch The number of bytes in a row of pixel data, including padding between lines. * * eturn 0 on success, or -1 if the texture is not valid. * * ote This is a fairly slow function. */ SDL_UpdateTexture(sdlTexture, NULL, buffer, pixel_w); sdlRect.x = 0; sdlRect.y = 0; sdlRect.w = screen_w; sdlRect.h = screen_h; /** * 函数声明:extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer); * rief Clear the current rendering target with the drawing color * * This function clears the entire rendering target, ignoring the viewport. * * eturn 0 on success, or -1 on error */ SDL_RenderClear(sdlRenderer); //将纹理数据拷贝给渲染器 /** * 函数声明:extern DECLSPEC int SDLCALL * SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect); * rief Copy a portion of the texture to the current rendering target. * * param renderer The renderer which should copy parts of a texture. * param texture The source texture. * param srcrect A pointer to the source rectangle, or NULL for the entire * texture. * param dstrect A pointer to the destination rectangle, or NULL for the * entire rendering target. * * eturn 0 on success, or -1 on error */ SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); //显示数据 /** * 函数声明:extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer); * rief Update the screen with rendering performed. */ SDL_RenderPresent(sdlRenderer); printf("Play Frame %d ", i++); } else if (event.type == SDL_WINDOWEVENT) { SDL_GetWindowSize(sdlScreen, &screen_w, &screen_h); } else if (event.type == BREAK_EVENT) { break; } else if (event.type == SDL_QUIT) { thread_exit = true; } } SDL_DestroyTexture(sdlTexture); SDL_DestroyRenderer(sdlRenderer); SDL_DestroyWindow(sdlScreen); SDL_Quit(); return 0; }