2019独角兽企业重金招聘Python工程师标准>>>

SDL和视频
为了在屏幕上显示,我们将使用SDL.SDL是Simple Direct Layer的缩写。它是一个出色的多媒体库,适用于多平台,并且被用在许多工程中。你可以从它的官方网站的网址 http://www.libsdl.org/上来得到这个库的源代码或者如果有可能的话你可以直接下载开发包到你的操作系统中。按照这个指导,你将需要 编译这个库。(剩下的几个指导中也是一样)
SDL库中有许多种方式来在屏幕上绘制图形,而且它有一个特殊的方式来在屏幕上显示图像――这种方式叫做YUV覆盖。YUV(从技术上来讲并不叫YUV而 是叫做YCbCr)是一种类似于RGB方式的存储原始图像的格式。粗略的讲,Y是亮度分量,U和V是色度分量。(这种格式比RGB复杂的多,因为很多的颜 色信息被丢弃了,而且你可以每2个Y有1个U和1个V)。SDL的YUV覆盖使用一组原始的YUV数据并且在屏幕上显示出他们。它可以允许4种不同的 YUV格式,但是其中的YV12是最快的一种。还有一个叫做YUV420P的YUV格式,它和YV12是一样的,除了U和V分量的位置被调换了以外。 420意味着它以4:2:0的比例进行了二次抽样,基本上就意味着1个颜色分量对应着4个亮度分量。所以它的色度信息只有原来的1/4。这是一种节省带宽 的好方式,因为人眼感觉不到这种变化。在名称中的P表示这种格式是平面的――简单的说就是Y,U和V分量分别在不同的数组中。FFMPEG可以把图像格式 转换为YUV420P,但是现在很多视频流的格式已经是YUV420P的了或者可以被很容易的转换成YUV420P格式。
于是,我们现在计划把指导1中的SaveFrame()函数替换掉,让它直接输出我们的帧到屏幕上去。但一开始我们必需要先看一下如何使用SDL库。首先我们必需先包含SDL库的头文件并且初始化它。
#include <SDL.h>
#include <SDL_thread.h>
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
fprintf(stderr, "Could not initialize SDL - %s/n", SDL_GetError());
exit(1);
}
SDL_Init()函数告诉了SDL库,哪些特性我们将要用到。当然SDL_GetError()是一个用来手工除错的函数。
创建一个显示
现在我们需要在屏幕上的一个地方放上一些东西。在SDL中显示图像的基本区域叫做面surface。
SDL_Surface *screen;
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
if(!screen) {
fprintf(stderr, "SDL: could not set video mode - exiting/n");
exit(1);
}
这就创建了一个给定高度和宽度的屏幕。下一个选项是屏幕的颜色深度――0表示使用和当前一样的深度。(这个在OS X系统上不能正常工作,原因请看源代码)
现在我们在屏幕上来创建一个YUV覆盖以便于我们输入视频上去:
SDL_Overlay *bmp;
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,
SDL_YV12_OVERLAY, screen);
正如前面我们所说的,我们使用YV12来显示图像。
显示图像
前面那些都是很简单的。现在我们需要来显示图像。让我们看一下是如何来处理完成后的帧的。我们将原来对RGB处理的方式,并且替换SaveFrame() 为显示到屏幕上的代码。为了显示到屏幕上,我们将先建立一个AVPicture结构体并且设置其数据指针和行尺寸来为我们的YUV覆盖服务:
if(frameFinished) {
SDL_LockYUVOverlay(bmp);
AVPicture pict;
pict.data[0] = bmp->pixels[0];
pict.data[1] = bmp->pixels[2];
pict.data[2] = bmp->pixels[1];
pict.linesize[0] = bmp->pitches[0];
pict.linesize[1] = bmp->pitches[2];
pict.linesize[2] = bmp->pitches[1];
// Convert the image into YUV format that SDL uses
img_convert(&pict, PIX_FMT_YUV420P,
(AVPicture *)pFrame, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height);
SDL_UnlockYUVOverlay(bmp);
}
首先,我们锁定这个覆盖,因为我们将要去改写它。这是一个避免以后发生问题的好习惯。正如前面所示的,这个AVPicture结构体有一个数据指针指向一 个有4个元素的指针数据。由于我们处理的是YUV420P,所以我们只需要3个通道即只要三组数据。其它的格式可能需要第四个指针来表示alpha通道或 者其它参数。行尺寸正如它的名字表示的意义一样。在YUV覆盖中相同功能的结构体是像素pixel和程度pitch。(程度pitch是在SDL里用来表 示指定行数据宽度的值)。所以我们现在做的是让我们的覆盖中的pict.data中的三个指针有一个指向必要的空间的地址。类似的,我们可以直接从覆盖中 得到行尺寸信息。像前面一样我们使用img_convert来把格式转换成PIX_FMT_YUV420P。
绘制图像
但我们仍然需要告诉SDL如何来实际显示我们给的数据。我们也会传递一个表明电影位置、宽度、高度和缩放大小的矩形参数给SDL的函数。这样,SDL为我们做缩放并且它可以通过显卡的帮忙来进行快速缩放。
SDL_Rect rect;
if(frameFinished) {
// Convert the image into YUV format that SDL uses
img_convert(&pict, PIX_FMT_YUV420P,
(AVPicture *)pFrame, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height);
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL_DisplayYUVOverlay(bmp, &rect);
}
现在我们的视频显示出来了!
让我们再花一点时间来看一下SDL的特性:它的事件驱动系统。SDL被设置成当你在SDL中点击或者移动鼠标或者向它发送一个信号它都将产生一个事件的驱 动方式。如果你的程序想要处理用户输入的话,它就会检测这些事件。你的程序也可以产生事件并且传递给SDL事件系统。当使用SDL进行多线程编程的时候, 这相当有用,这方面代码我们可以在指导4中看到。在这个程序中,我们将在处理完包以后就立即轮询事件。现在而言,我们将处理SDL_QUIT事件以便于我 们退出:
SDL_Event event;
av_free_packet(&packet);
SDL_PollEvent(&event);
switch(event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
default:
break;
}
让我们去掉旧的冗余代码,开始编译。如果你使用的是Linux或者其变体,使用SDL库进行编译的最好方式为:
gcc -o tutorial02 tutorial02.c -lavutil -lavformat -lavcodec -lz -lm /
`sdl-config --cflags --libs`
这里的sdl-config命令会打印出用于gcc编译的包含正确SDL库的适当参数。为了进行编译,在你自己的平台你可能需要做的有点不同:请查阅一下SDL文档中关于你的系统的那部分。一旦可以编译,就马上运行它。
当运行这个程序的时候会发生什么呢?电影简直跑疯了!实际上,我们只是以我们能从文件中解码帧的最快速度显示了所有的电影的帧。现在我们没有任何代码来计 算出我们什么时候需要显示电影的帧。最后(在教程5),我们将花足够的时间来探讨同步问题。但一开始我们会先忽略这个,因为我们有更加重要的事情要处理: 音频!

转载于:https://my.oschina.net/mexiaobai1315/blog/805932

ffmpeg 和 SDL 教程2:输出到屏幕相关推荐

  1. 详细介绍Qt,ffmpeg 和SDl 教程之间的联系

    Qt与 ffmpeg 与 SDl 教程是本文要介绍的内容,从多个角度介绍本文,运用了qmake,先来看内容. 1.  注释 从" #" 开始,到这一行结束. 2.  指定源文件 1 ...

  2. ffmpeg 和 SDL 教程

    教程1:制作屏幕录像 代码:tutorial01.c 概要 电影文件有很多基本的组成部分.首先,文件本身被称为容器Container,容器的类型决定了信息被存放在文件中的位置.AVI和Quicktim ...

  3. ffmpeg和SDL教程 04:创建线程

    2019独角兽企业重金招聘Python工程师标准>>> 概述 前面,我们利用 SDL 的音频处理功能优势增加声音支持.每次我们提供音频支持,需要创建一个函数,供SDL启动线程来回调. ...

  4. FFmpeg和SDL教程(五):同步视频

    英文原文地址:http://dranger.com/ffmpeg/tutorial05.html 警告 当我第一次做这个教程时,我的所有同步代码都是从ffplay.c中提取的.今天,这是一个完全不同的 ...

  5. ffmpeg文档2:输出到屏幕

    SDL和视频 为了在屏幕上显示,我们将使用SDL.SDL是Simple Direct Layer的缩写.它是一个出色的多媒体库,适用于多平台,并且被用在许多工程中.你可以从它的官方网站的网址 http ...

  6. FFmpeg源代码简单分析 日志输出系统(av log 等)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! ==== ...

  7. python 美化输出 错误 警告等信息_OpenCV抑制、隐藏或禁用输出到屏幕的错误或警告消息...

    我想知道是否有一种方法可以抑制.隐藏或禁用OpenCV输出到屏幕上的错误或警告消息,我认为这些消息源于上限读数()? 在 我认为它们来自使用FFMpeg的OpenCV,它们要么显示如下: 案例1:[m ...

  8. ffmpeg和SDL学习笔记

    根据ffmpeg官方网站上的例子程序开始学习ffmpeg和SDL编程. SDL是一个跨平台的多媒体开发包.适用于游戏,模拟器,播放器等应用软件开发.支持linux .win32 等操作系统. 主要应用 ...

  9. 物联网国赛LORA模块开发基础教程(通用库)—OLED屏幕

    LORA模块开发基础教程目录 物联网国赛LORA模块开发基础教程-开发环境配置 物联网国赛LORA模块开发基础教程-输出(LED) 物联网国赛LORA模块开发基础教程-输入(按键) 物联网国赛LORA ...

最新文章

  1. 题解 P4692 【[Ynoi2016]谁的梦】
  2. 使用 jQuery 简化 Ajax 开发.
  3. python 神经网络原理_神经网络理论基础及Python实现
  4. JS——基础知识--变量类型和变量计算
  5. css 中多种边框的实现小窍门
  6. 2021级C语言大作业 - 霓虹深渊
  7. Android Studio1.4.x JNI开发基础-基本环境配置
  8. v8引擎编译全记录2020-10-17(保姆级教程)
  9. c语言知道坐标求圆面积,用C语言编程推算圆的面积公式
  10. NVIDIA GeForce 800系列详细配置参数
  11. html link canonical
  12. 安卓虚拟摄像头_iPhone 的第四颗摄像头位置,为什么给了激光雷达?
  13. QQ Tim另存为文件时闪退,错误模块ntdll.dll
  14. apriori算法 python实现
  15. 爬虫实战_爬取静态单张图片
  16. 19 个接私活平台,有技术就有钱
  17. HTML+CSS大作业 电影网站设计——电影介绍(11页) 大学生电影网页作品 电影网页设计作业模板 学生网页制作源代码下载
  18. IntelliJ IDEA for Mac 2018.1.2 智能Java IDE开发工具 破解版下载
  19. java存储图片到数据库
  20. stata软件不出图_Stata软件的图形绘制—2

热门文章

  1. 安阳工学院计算机二级成绩查询,2008年下半年计算机等级考试成绩可以查询了?...
  2. c++:opencv的安装和配置
  3. 【AutoML】进化算法如何用于自动模型搜索(NAS)
  4. 【模型解读】从2D卷积到3D卷积,都有什么不一样
  5. 全球及中国盘式削片机行业运营模式与“十四五”投资规划建议报告2022-2027年版
  6. 中科微研课题上犹授牌-农业大健康·李喜贵:谋定功能性农业
  7. 谋定数字农业生态系统 万亿市场对话中国农民丰收节交易会
  8. beautifulsoup4
  9. 单片机入门学习笔记7:人机交互界面
  10. python升级或者其他原因把yum搞坏了