摘要:
指导 8:软件缩放软件缩放库 libswscale 近来 ffmpeg 添加了新的接口:libswscale 来处理图像缩放。 但是在前面我们使用 img_convert 来把 RGB 转换成 YUV12,我们现在使用新的接口。新接口更加标准和快速,而且我相信里面有了 MMX 优化代码。换句话说,它是做更好的缩放方式。 我们将用来缩放的基本函数是 sws_scale。但一开始,我们必需建立一个 SwsContext 的概念。这将让我们进行想要的转换,然后把它传递给 sws_scale函数。类似于在 SQL 中的预备阶段或者是在 Python 中编译的规则表达式 regexp。 要准备这个上.. 阅读全文
摘要:
指导7:控制进度处理快进快退命令 现在我们来为我们的播放器加入一些快进和快退的功能,因为如果你不能全局搜索一部视频是很让人讨厌的。同时,这将告诉你 av_seek_frame 函数是多么容易使用。 我们将在视频播放中使用左方向键和右方向键来表示向后和向前一小段,使用向上和向下键来表示向前和向后一大段。这里一小段是 10 秒,一大段是 60 秒。所以我们需要设置我们的主循环来捕捉键盘事件。然而当我们捕捉到键盘事件后我们不能直接调用 av_seek_frame 函数。我们要主要的解码线程 decode_thread的循环中做这些。所以,我们要添加一些变量到大结构体中,用来包含新的跳转位置和一些.. 阅读全文
摘要:
指 导 6:同步音频同步音频 现在我们已经有了一个比较像样的播放器。所以让我们看一下还有哪些零碎的东西没处理。上次,我们掩饰了一点同步问题,也就是同步音频到视频而不是其它的同步方式。我们将采用和视频一样的方 式:做一个内部视频时钟来记录视频线程播放了多久,然后同步音频到上面去。后面我们也来看一下如何推而广之把音频和视频都同步到外部时钟。实现视频时钟 现在我们要生成一个类似于上次我们的声音时钟的视频时钟:一个给出当前视频播放时间的内部值。开始,你可能会想这和使用上一帧的时间戳来更新定时器一样简单。但是,不要忘了视频帧之间的时间间隔是很长的,如果以毫秒级别为计量单位。 解决办法是跟踪另外一个... 阅读全文
摘要:
例程4介绍了Tiled地图的使用,它还有一种45度角的地图,如下图(左边为新建地图时的设置,右边为我拼接的一副图)(上面说错了,感谢朱大仙的指正,其实还有一种45度交叉的图)一、45度地图解析下面来分析一下如何确定坐标,如下图,红色的菱形是组成地图的图块,黑色的矩形为一块菱形实际的形状,设A点的坐标为(xa,ya),矩形的宽、高位w和h,则B点的坐标为(xa+w/2,ya-h/2),C点的坐标为(xa+w/2,ya+h/2)。再看一下用Tiled导出的lua文件,与第一幅右边的图比较,我们发现数据是按列分布的,点从下到上与图的斜向右方向的图块对应。data = { 2, 2, 2, 2, 2, 阅读全文
摘要:
指导5:同步视频如何同步视频前面整个的一段时间,我们有了一个几乎无用的视频播放器。当然,它能播放视频,也能播放音频,但是它还不能被称为一部电影。那么我们还要做什么呢?PTS 和 DTS 幸运的是,音频和视频流都有一些关于以多快速度和什么时间来播放它们的信息。音频流有采样,视频流有每秒的帧率。然而,如果我们只是简单的通过计算帧和乘以帧率的方式来同步视频,那么就很有可能会失去同步。于是作为一种补充,在流中的包有种叫做 DTS(解码时间戳)和 PTS(显示时间戳)的机制。想理解这两个参数,你需要了解视频存放的方式。像 MPEG 等格式,使用叫做 B帧(B 表示双向 bidrectional)的方式. 阅读全文
摘要:
简述 上一章通过SDL的音频功能添加了音频支持,SDL启动一个线程监听音频回调函数,视频显示也将如此。这使得代码更加模块化,更容易协调,尤其是当我们想要添加同步时。现在从哪开始呢? 首先注意到我们的主函数处理很多:事件循环、读取数据包、解码视频。所以我们要做的是分开它们:一个负责解码数据包的线程;然后将数据包添加到队列中,并由相应的音频和视频的线程读取。我们已经这样设置了音频线程;视频线程将会复杂一点,因为我们要自己显示视频。我们将在主循环中添加显示代码。我们将把视频显示和事件循环放在一起,而不是每次循环显示视频。思路是这样的,解码视频,把产生的帧存到另一个队列里,然后创建一个自定义事件 .. 阅读全文
摘要:
可以使用srlua这个工具把lua脚本打包成exe,提供了lua 5.2、5.1、5.0的版本对应的源码。不过我懒得编译了,发现“白的菜”替懒人编译好了(感谢),点击下载。解压后出现“luapack\bin\debug"目录,如图然后打开cmd切换到当前目录,运行 glue srlua.exe test.lua test.exe其中test.lua 是你要打包的lua文件,test.exe是生成的exe文件名。 阅读全文
摘要:
眼看就快毕业了,写下一点东西以供自己回忆,另一方面以供读者参考。 大一是满怀着好奇进入学校(学校不好,在东北,本人湖北),结果发现我说话别人听不懂,其实我的普通话还可以,只是语速很快,在东北四年,仍是乡音不改。每个班由一个大三的学长带着上自习,名曰“带班”,还有一个名义上的班主任。开始要军训一个月,可惜后来学校出现了甲流,于是我们的军训被取消了,学校被封校,在寝室里呆了一个多星期,呜呼! 接着是学习《大学生管理规定》,去参加老乡会,结识了几个老乡,现在也一直联系着。 后来碰巧赶上学校校庆了,给我们没人发了10元还是20元的餐券记不清了,我还留了一张纪念。后来发现可以在学校周围的餐馆里用餐... 阅读全文
摘要:
指导3:播放声音音频 现在我们要来播放声音。SDL也为我们准备了输出声音的方法。函数SDL_OpenAudio()本身就是用来打开声音设备的。它使用一个叫做SDL_AudioSpec结构体作为参数,这个结构体中包含了我们将要输出的音频的所有信息。 在我们展示如何建立之前,让我们先解释一下电脑是如何处理音频的。数字音频是由一长串的样本流组成的。每个样本表示声音波形中的一个值。声音按照一个特定的采样率来进行录制,采样率表示以多快的速度来播放这段样本流,它的表示方式为每秒多少次采样。例如22050和44100的采样率就是电台和CD常用的采样率。此外,大多音频有不只一个通道来表示立体声或者... 阅读全文
摘要:
接上篇,这篇里我将介绍俄罗斯方块的运动和下一个方块的显示。这里我们主要使用随机数,由于lua采用的是C的随机数方法,所以生成的是一串伪随机数序列,可以这样理解这串随机数是用一个公式生成的,所以只要有足够的数,我们是可以推导出这个产生随机数的公式的。为了解决这个问题,C引入了随机数种子,即我们产生一个随机数种子,然后把这个种子带入公式,再产生随机数。只要种子每次都不同,那么就可以生成真正的随机数了。但是我们如何产生一个不同的种子呢,利用系统时间播种就可以了。代码如下:math.randomseed (os.time()) --利用时间产生一个种子n=math.random(start,end) 阅读全文