[SimplePlayer] 2. 在屏幕上显示视频图像
我们这里采用SDL(本文所用版本为SDL2.0.5)来进行图像输出,SDL在进行图像渲染时一般采用的会是direct3D或者opengl,SDL对它们进行了封装,不过我们这里只讨论SDL的使用,并不会去涉及这些底层实现。尽管如此,我们还是有必要了解其中一些基本概念,这些概念能帮助我们很好地理解所使用的SDL api的实际作用。
其中最重要的一个概念就是render,中文译为渲染,rendering在计算机图像领域指的就是图像合成(image synthesis)。通俗一点的解释就是:render指的是把2D图像(图形)或者3D模型变成所展示出来的图像的过程,实际进行这种转换操作的物件被称为renderer(渲染器)。在SDL中,renderer主要处理的是2D的数据,其中包括
不过本文只用到renderer最基本的功能,即把图像输出到窗口。在SDL中,为了方便renderer的实现,renderer所处理的对象被规定为texture(纹理),因此图像需要先被包装成texture,texture会被render成rendered image,然后就可以输出到window。

初始化
在使用SDL的函数之前,需要先调用SDL_Init来进行初始化,由于本文的目的是进行视频图像输出,因此需要指定flag为SDL_INIT_VIDEO来初始化视频子系统。
    if(SDL_Init(SDL_INIT_VIDEO)){
        fprintf(stderr, "SDL init video failed\n");
        return -1;
    }
接下来创建window、renderer、texture。在创建texture时需要指定输入的图像像素格式,通常视频的像素格式都是yuv420p,对应的flag为SDL_PIXELFORMAT_IYUV。对于会频繁更换的视频图像,还需要指定texture为SDL_TEXTUREACCESS_STREAMING。
    window = SDL_CreateWindow("Simple Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DEF_WIDTH, DEF_HEIGHT, 0);
    if(!window){
        fprintf(stderr, "SDL create window failed\n");
        return -1;
    }
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if(!renderer){
        fprintf(stderr, "SDL create renderer failed\n");
        return -1;
    }
    texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, DEF_WIDTH, DEF_HEIGHT);
    if(!renderer){
        fprintf(stderr, "SDL create renderer failed\n");
        return -1;
    }
    SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE);
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
创建用于存储图像像素数据的缓冲区,并打开yuv文件,以供后续读取图像
YPlane = (unsigned char *)malloc(DEF_WIDTH*DEF_HEIGHT);
UPlane = (unsigned char *)malloc(DEF_WIDTH*DEF_HEIGHT/4);
VPlane = (unsigned char *)malloc(DEF_WIDTH*DEF_HEIGHT/4); pFile = fopen(argv[1], "rb");
if(pFile==NULL)
return -1;
显示
循环读取图像进入缓冲区,然后把图像传入texture进行包装、渲染、最后输出,每帧间隔为1/24秒。对于视频子系统来说,还有一个必不可少的步骤,就是在循环中调用SDL_PumpEvents。SDL_PumpEvents如其名称,主要的功能是推动event队列以进行队列状态的更新,不过它还有一个作用是进行视频子系统的设备状态更新,如果不调用这个函数,所显示的视频会在大约10秒后丢失色彩。
    while(1){
        sizeY = fread(YPlane, 1, DEF_WIDTH*DEF_HEIGHT, pFile);
        sizeU = fread(UPlane, 1, DEF_WIDTH*DEF_HEIGHT/4, pFile);
        sizeV = fread(VPlane, 1, DEF_WIDTH*DEF_HEIGHT/4, pFile);
        if(!sizeY||!sizeU||!sizeV)
            break;
        if(0!=SDL_UpdateYUVTexture(texture, NULL, YPlane, DEF_WIDTH, UPlane, DEF_WIDTH/2, VPlane, DEF_WIDTH/2)){
            fprintf(stdout, "Render Update Texture failed, reason: %s\n", SDL_GetError());
        }
        SDL_RenderCopyEx(renderer, texture, NULL, NULL, 0, NULL, 0);
        SDL_RenderPresent(renderer);
        SDL_Delay(1000/FRAMERATE);
        SDL_PumpEvents();
    }
退出
退出前的收尾处理
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
free(YPlane);
free(UPlane);
free(VPlane);
fclose(pFile);
[SimplePlayer] 2. 在屏幕上显示视频图像的更多相关文章
- 在屏幕上显示C盘根目录下的所有文件和文件夹
		
1 import java.io.File; //在屏幕上显示C盘根目录下的所有文件和文件夹 public class ListDemo { public static void main(Strin ...
 - 怎样在屏幕上显示多个alv
		
本文解说怎样在屏幕上显示多个alv. 实现这种需求关键是下面几点(举例:在屏幕上显示4个alv): 1.须要定义4个alv control 2.由于有4个alv control,于是就须要定义4个容器 ...
 - Android视频录制从不入门到入门系列教程(二)————显示视频图像
		
1.创建一个空的工程,注意声明下列权限: <uses-permission android:name="android.permission.CAMERA"/> < ...
 - linux tail-在屏幕上显示指定文件的末尾若干行
		
博主推荐:获取更多 linux文件内容查看命令 收藏:linux命令大全 tail命令用于输入文件中的尾部内容.tail命令默认在屏幕上显示指定文件的末尾10行.如果给定的文件不止一个,则在显示的每个 ...
 - 【opengl】OpenGL中三维物体显示在二维屏幕上显示的变换过程
		
转自:http://blog.sina.com.cn/s/blog_957b9fdb0100zesv.html 为了说明在三维物体到二维图象之间,需要经过什么样的变换,我们引入了相机(Camera)模 ...
 - Droid@screen:在PC屏幕上显示Android手机屏幕
		
这里介绍一款工具——Droid@screen,用来获取手机屏幕,显示在PC屏幕上.它集截图.录像等多种功能于一体. 安装 1. 下载地址:http://droid-at-screen.org/d ...
 - iOS开发中获取视图在屏幕上显示的位置
		
在iOS开发中,我们会经常遇到一个问题,例如,点击一个按钮,弹出一个遮罩层,上面显示一个弹框,弹框显示的位置在按钮附近.如果这个按钮的位置相对于屏幕边缘的距离是固定的,那就容易了,可以直接写死位置.可 ...
 - 30、在LCD上显示摄像头图像
		
1. 准备虚拟机2.安装工具链sudo tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C /设置环境变量:sudo vi /etc/environment : PATH=& ...
 - ProgressDialog(三)——代号为中心的屏幕上显示ProgressDialog(ProgressBar)
		
MainActivity如下面: package cc.testprogressdialog; import android.os.Bundle; import android.view.Gravit ...
 
随机推荐
- cookie特殊字符在游览器被转义
			
环境:vue2.x axios 1.如果只是前端自己用,那么可以用 encodeURIComponent(string) 存 ,用decodeURIComponent(string)取. 2.遇到一种 ...
 - Dynamics 365新引入了多选选项集类型字段
			
本人微信和易信公众号:微软动态CRM专家罗勇 ,回复276或者20180630可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...
 - 从.Net到Java学习第九篇——SpringBoot下Thymeleaf
			
从.Net到Java学习系列目录 Thymeleaf概述 Thymeleaf 是一个流行的模板引擎,该模板引擎采用java语言开发.模板引擎是一个技术名称,是跨领域平台的概念,在java语言体系下有模 ...
 - 功能强大的PDF实用工具
			
PDF实用工具(PDFTool)是北京博信施科技有限有限公司研制开发的一款专门提供对PDF文件进行编辑.加工的处理软件.本软件具有对PDF文件进行分割.结合.加密.解密.添加水印.设定有效期限等多种功 ...
 - IPD体系向敏捷开发模式转型实施成功的四个关键因素
			
文/杨学明 集成产品开发(IPD).集成能力成熟度模型(CMMI).敏捷开发(Agile Development)是当前国内外企业产品研发管理的最常用的3种模式.随着创新环境的快速发展,许多企业都会 ...
 - 从0开始的Python学习004小的总结与补充
			
没有时间?快速阅读: Python确实是一种十分精彩又强大的语言. Python是程序.脚本或者软件 python helloworld.py运行你的Python help()帮助你的Python 命 ...
 - docker 基础
			
概述 起源 2013 年由 DotCloud 公司开源出来的容器管理工具 DotCloud 公司是一家 PAAS 服务提供商,从 docker 的出身也可以看出它的主要功能和方向 技术原理 开始时是基 ...
 - python基础篇实战
			
1. 判断下面的结果 # 1. 判断下面的结果 # 1 > 1 or 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 < 6 pri ...
 - python 文件名的操作
			
1.文件操作 open()文件句柄:获取文件的路径信息 open() 打开一个文件,获取文件句柄 read() 全部读出出文件中的内容 readline() 读取文件中逐一读取一行数据 readlin ...
 - 【Python使用】使用pip安装卸载Python包(含离线安装Python包)未完成???
			
pip 是 Python 包管理工具,该工具提供了对Python包的查找.下载.安装.卸载的功能.Python 2.7.9 + 或 Python 3.4+ 以上版本都自带 pip 工具. pip使用( ...