命令行下配置:

G:\Coding\Video\SDL\proj>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:\Coding\Video\SDL\proj>dir
驱动器 G 中的卷没有标签。
卷的序列号是 0FD5-0CC8 G:\Coding\Video\SDL\proj 的目录 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:\Coding\Video\SDL\proj>

源码:

#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\n");
return -1;
} //初始化SDL系统
if (SDL_Init(SDL_INIT_VIDEO))
{
printf("Could not initialize SDL - %s\n", 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);
* \brief 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.
*
* \return 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\n", SDL_GetError());
return -1;
}
//创建渲染器SDL_Renderer
/**
* 函数声明:extern DECLSPEC SDL_Renderer * SDLCALL
* SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags);
* \brief 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.
*
* \return 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\n", 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);
* \brief 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.
*
* \return 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\n", 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);
* \brief 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.
*
* \return 0 on success, or -1 if the texture is not valid.
*
* \note 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);
* \brief Clear the current rendering target with the drawing color
*
* This function clears the entire rendering target, ignoring the viewport.
*
* \return 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);
* \brief 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.
*
* \return 0 on success, or -1 on error
*/
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); //显示数据
/**
* 函数声明:extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer);
* \brief Update the screen with rendering performed.
*/
SDL_RenderPresent(sdlRenderer); //工具函数,用于延时,视频一般一秒播放25帧
/**
* 函数声明:extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms);
* \brief 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\n");
return -1;
} //初始化SDL系统
if (SDL_Init(SDL_INIT_VIDEO))
{
printf("Could not initialize SDL - %s\n", 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);
* \brief 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.
*
* \return 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\n", SDL_GetError());
return -1;
}
//创建渲染器SDL_Renderer
/**
* 函数声明:extern DECLSPEC SDL_Renderer * SDLCALL
* SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags);
* \brief 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.
*
* \return 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\n", SDL_GetError());
return -1;
} //创建纹理SDL_Texture
/**
* 函数声明:extern DECLSPEC SDL_Texture * SDLCALL
* SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h);
* \brief 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.
*
* \return 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\n", 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);
* \brief 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.
*
* \return 0 on success, or -1 if the texture is not valid.
*
* \note 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);
* \brief Clear the current rendering target with the drawing color
*
* This function clears the entire rendering target, ignoring the viewport.
*
* \return 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);
* \brief 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.
*
* \return 0 on success, or -1 on error
*/
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect); //显示数据
/**
* 函数声明:extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer);
* \brief Update the screen with rendering performed.
*/
SDL_RenderPresent(sdlRenderer);
printf("Play Frame %d\n", 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;
}

FFMPEG学习----使用SDL播放YUV数据的更多相关文章

  1. FFMPEG学习----使用SDL播放PCM数据

    参考雷神的代码: /** * 最简单的SDL2播放音频的例子(SDL2播放PCM) * Simplest Audio Play SDL2 (SDL2 play PCM) * * 本程序使用SDL2播放 ...

  2. FFmpeg学习3:播放音频

    参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...

  3. 【转载】使用SDL播放YUV图像数据(转)

    SDL提供了针对YUV格式数据的直接写屏操作.废话不多说,直接上代码吧/** * file showyuv.c * author: rare * date: 2009/12/06 * email: d ...

  4. FFMPEG学习----使用SDL构建音频播放器

    ffmpeg版本:ffmpeg-20160413-git-0efafc5 #include <stdio.h> #include <stdlib.h> #include < ...

  5. SDL播放YUV——循环

    #include "SDL.h" #include "as_lesson_log.h" #define PATH_YUV420 "/sdcard/ou ...

  6. ffmpeg学习笔记-音频播放

    前文讲到音频解码,将音频解码,并且输入到PCM文件,这里将音频通过AudioTrack直接输出 音频播放说明 在Android中自带的MediaPlayer也可以对音频播放,但其支持格式太少 使用ff ...

  7. FFMPEG学习----使用SDL构建视频播放器

    #include <stdio.h> #include <string.h> extern "C" { #include "libavcodec/ ...

  8. ffplay播放YUV数据

    播放器YUV系列的格式用ffplay很方便 免费的 播放NV21 ffplay -i d:/cap.yuv -pix_fmt nv21 -s 640x480 播放YUV420P ffplay -i d ...

  9. FFmpeg学习5:多线程播放视音频

    在前面的学习中,视频和音频的播放是分开进行的.这主要是为了学习的方便,经过一段时间的学习,对FFmpeg的也有了一定的了解,本文就介绍了 如何使用多线程同时播放音频和视频(未实现同步),并对前面的学习 ...

随机推荐

  1. k8s-整体概述和架构

    1.Kubernetes是什么 Kubernetes是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务.通过Kubernetes能够进行应用的自动化部署和扩缩容.在Kubernetes中,会将组 ...

  2. 测开大佬告诉你:如何5分钟快速创建restful风格的API接口-使用django restframework框架

    一.思考❓❔ 1.创建API接口难吗? 软件测试工程师: 只测过API接口, 从没创建过 应该需要掌握一门后端开发语言和后端开发框架吧!? 脑容量有限,想想就可怕 2.如何创建API接口呢? 使用Dj ...

  3. Qt5学习(1)

    1. In Qt, if you want to apply styles to the main window  itself, you must apply it to  its central ...

  4. SQL 配置管理器无法连接到WMI

    在解决之前,需要注意一般出现这个问题是你的SQL SERVER安装有误. 这个问题是SQL 安装路径下sqlmgmproviderxpsp2up.mof的问题. 一般在C盘Program files( ...

  5. 从源码角度了解SpringMVC的执行流程

    目录 从源码角度了解SpringMVC的执行流程 SpringMVC介绍 源码分析思路 源码解读 几个关键接口和类 前端控制器 DispatcherServlet 结语 从源码角度了解SpringMV ...

  6. IDEA不编译空文件夹

    今天做项目的时候发现idea编译工程不会编译空文件夹,在resources下新建了个存储文件的空文件夹,编译后target里竟然没有,一直报空指针. 随便丢一个文件进去就行了,放一个demo.txt的 ...

  7. Spring Cloud Eureka------详解

    一 Eureka服务治理体系 1.1 服务治理 服务治理是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现. Spring Cloud Eureka是Spring Cl ...

  8. 20190918Java课堂记录

    1. EnumTest.java public class EnumTest { public static void main(String[] args) { Size s=Size.SMALL; ...

  9. 使用Oracle Stream Analytics 21步搭建大数据实时流分析平台

    概要: Oracle Stream Analytics(OSA)是企业级大数据流实时分析计算平台.它可以通过使用复杂的关联模式,扩充和机器学习算法来自动处理和分析大规模实时信息.流式传输的大数据可以源 ...

  10. .net core webapi搭建(2)跨域

    Core WebAPI中的跨域处理 在使用WebAPI项目的时候基本上都会用到跨域处理 Core WebAPI的项目中自带了跨域Cors的处理,不需要单独添加程序包 如图所示 修改 Configure ...