ffmpeg, libav学习记录
转载自:http://hi.baidu.com/y11022053/item/81f12035182257332e0f8196
一个偶然遇到了ffmpeg,看起来不多,而且通用性很强,算是一个扎实的技术。
研究了两天了,万事开头难啊。
主要是新手学习一个东西的时候,没有宏观的概念,如果猛地往某个细节去钻,往往碰的焦头烂额,事倍功半。
如果由一个“师傅”,能先点拨一下,讲讲宏观的概念,再说说改如何去学,那将很提升效率,可惜这样的“师傅”很难找。
问别人问题,太叼的人不屑于鸟你,太弱的人,也答不上来。
还有一点,我由于不懂这玩意儿,掌握不了发问的技巧,往往就问ffmpeg是什么啊,能不能给我讲讲,但是一般人都会反问,你想知道点什么呢?这个问题真的很难,我不知道我需要知道什么,我不知道我想要知道什么,所以我也无从回答。
我今天能有机会作为一个完全的新手,只具备linux+c的基本技能,来学习播放器,ffmpeg,libav这些东西,我想要把我整个学习的过程记录下来,然后分享给任何一个后来的新手,让他们能快速上手,快速的知道这是什么,我们要学什么。
首先要有一点基础知识来支撑,下面开始对我自己扫盲,答案不一定对,以后可以改正。
1. 什么是编解码,什么是codec?为什么要这样做。
答:编解码,就是codec。CODEC =COde (编码) +DECode(解码)。
假设显示器的设置是:每秒刷新60次,也就是刷新率为60Hz,1024 * 768的分辨率,
那么此时显卡每秒要处理的数据量是 60 * 1024 * 768 个像素点,可想而知,视频文件的大小是很恐怖的。
如果不用任何方法压缩,就单纯的存储视频文件,那么1GB的文件,也只能存储37秒左右的视频内容。
所以,咱们需要一个方式来压缩(code,编码)它,再存储起来,要播放的时候,再解压缩(decode,解码)。
这样牺牲一些时间,来换取很大一部分空间,这是值得的,并且咱们的硬件设备也有这个能力做到。
2. 如何来编解码呢?根据什么前提来做呢?
答:假设一个纯粹的没压缩过的视频文件,假设很大很大,他在展示给我们观看的时候,有些内容,即使被删去,也不会影响我们的观看效果。举个例子,你喝白开水的时候,里面的矿物质元素含量多少,有或者没有,并不影响你的口感。
所以,有些内容是不影响我们观看感受的,所以可以删去,那就是
编解码的编码器
原视频文件(很大) -------------------> 编码后的视频文件(相对要小一些)
前后两者在空间大小上有区别,后者小一些,当然后者的质量也要差一些。
编解码的解码器
编码后的视频文件(相对要小一些)-------------------> 原视频文件(大) ------------->给显卡展示。
所以,那就应该要有某一套规范来制约,那也肯定有某个配套的算法来支持这种规范。
上面举得这个例子是不影响我们观看的前提下的压缩。再举一个例子。
平常电脑上的视频文件,动辄1G多一个。但是放在移动设备上去观看是不是有点浪费呢。
所以,也可以在影响我们观看的前提下进行压缩,结果就会是:你把移动设备上的视频文件放在22寸显示器上去播放,而且还全屏,你肯定看着不爽,觉得质量超差,但是这也是很有必要的。
把高清的1080P压缩成半高清或者标清的也是一种损失质量的编码方式。
3. 基础概念扫盲,Container(容器),Stream(流),Frame(帧),Codec(编解码器),mux/demux(复用/解复用)。
答:一个container就是一个文件,一种container就是一种文件格式,举例:xxx.flv 和 yyy.mkv是两个文件,我们可以说他们是两个容器,并且是两种不同的容器。
容器和流 以及 复用/解复用
先看xxx.flv文件,假设里面包含两种stream,一种是音频流(audio stream),另一种是视频流(video stream),并且以flv规定的格式把这两个流封装在.flv容器里面。
再看yyy.mkv文件,假设里面包含三种stream,一种是音频流(audio stream),另一种是视频流(video stream),还有一种流是字幕流(subtitle stream),并且以mkv规定的格式把这三种流封装在.mkv的容器里面。
上面讲了容器和流的关系,那把不同的流按照某种容器的规则从那种容器(文件)中解析(或者说抽出来)出来,这种行为叫做解复用(demux),使用解复用器(demuxer),那反过来,把不同的流按照某种容器的规则放入那种容器(最后肯定生成了某种格式的文件),这种行为叫做复用(mux),使用复用器(muxer)。
这四个概念是抽象出来的,会有不同的结构体在实现这些抽象概念的。每个不同的容器都有不同的规则来整合流,常见的容器有,.mkv .rm .flv .mp4等等一些,那么针对不同的容器,就应该有不同的解复用器来解复用了。其实我们也可以自己实现这些解复用器,前提是我们能够清楚的掌握某每种容器的内部格式。
流和帧 以及 编解码器
如果仔细读了上文的话,大概也能猜到,这一段叙述的方式和上一段也会是一样的。两种不同的东西之间要发生转换,肯定要有正反两种器具,使得转换正进行,或者反进行。
直接了当,帧就是包含在流里面的!
当从容器中得到一个流以后,或者说不管你怎么弄的,反正你得到了一个流,那这个流就认为是被某种编码器 编码过后生成的,你需要把这个流里面的帧去解码。其实这样讲是反的,我们换个角度来理解。
什么是影片?其实就是一组(很多张)图片,时间间隔很小的连续展示出来,人们就觉得画面中的人物在动,这就是影片。那电影的实质就是N多张图片的集合。那每张图片和帧又有什么关系呢?事实上,如果一部影片里面的图片,我们原封不动的全部存起来,空间会很大很大很大,但是如果通过一定的算法(这里不讲相关算法),把每一张图片压缩(编码_encode)一下,变成 帧。再把帧连起来变成流,再把不同的流放到某个容器里面,这就是我们平常看见的电影文件了,比如这个文件 碟中谍4.H264.ACC.mkv,他为什么要这样命名呢? mkv表达了它的容器是.mkv的,且包含至少两个流,h264的视频流,ACC的音频流。这是一种典型的 牺牲时间来换取空间的做法。
现在应该明白了吧,回到之前的话题,得到一个流之后,就得设法找出里面的帧,然后使用 解码器/decoder 把帧还原,然后再去播放,也可以再去使用另一个编码器/encoder编码压缩成另一种格式的帧(这就是所谓的转格式软件要完成的一个步骤)。
4. ffmpeg是什么?
下面摘抄一段ffmpeg官网的东西。
FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。
5. 我们学习ffmpeg,究竟是学什么呢?
ffmpeg是一个方案,里面解决了编解码,复用解复用,里面提供很多API给我们用,当然,还有一些工作我们必须自己完成,比如同步的问题。首先我们要了解从打卡一个视频文件到解复用到解码到播放这一套流程,然后学习他提供的API怎么用,使用顺序是怎么样的。然后再去了解API的实现细节,最后把实现细节也掌握好了,咱们就可以按照自己的需求,进行修改,然后做一个符合需求的定制版。
6. 我试图编译ffmpeg的源文件包,发现编译出来了ffplay、ffmpeg、ffserver等等一些二进制文件,这些是什么?干什么用的?
ffplay:他就是一个真正的播放器了,就像vlc、mplayer等播放器,有图形界面的。
ffmpeg:可以理解成一个工具,利用ffmpeg方案提供的一些API,再加上一些其他操作,可以实现转码等一些功能。
ffserver:顾名思义了,做服务器的。可以单播或多播一些流。
ffmpeg, libav学习记录的更多相关文章
- 【Android】学习记录<1> -- 初识ffmpeg
工作需要用到ffmpeg来进行Android的软编码,对这玩意儿一点都不了解,做个学习记录先. FFmpeg:http://www.ffmpeg.org Fmpeg is the leading mu ...
- FFmpeg再学习 -- 硬件加速编解码
为了搞硬件加速编解码,用了一周时间来看 CUDA,接下来开始加以总结. 一.什么是 CUDA (1)首先需要了解一下,什么是 CUDA. 参看:百度百科 -- CUDA 参看:CUDA基础介绍 参看: ...
- FFmpeg Basic学习笔记(3)
视频叠加--画中画效果 overlay video filter 视频叠加比较常见的应用场景是台标的叠加,在画面左上角.右上角.左下角或右下角叠加台标. ffmpeg提供的overlay filter ...
- Quartz 学习记录1
原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...
- Java 静态内部类与非静态内部类 学习记录.
目的 为什么会有这篇文章呢,是因为我在学习各种框架的时候发现很多框架都用到了这些内部类的小技巧,虽然我平时写代码的时候基本不用,但是看别人代码的话至少要了解基本知识吧,另外到底内部类应该应用在哪些场合 ...
- Apache Shiro 学习记录4
今天看了教程的第三章...是关于授权的......和以前一样.....自己也研究了下....我觉得看那篇教程怎么说呢.....总体上是为数不多的精品教程了吧....但是有些地方确实是讲的太少了.... ...
- UWP学习记录12-应用到应用的通信
UWP学习记录12-应用到应用的通信 1.应用间通信 “共享”合约是用户可以在应用之间快速交换数据的一种方式. 例如,用户可能希望使用社交网络应用与其好友共享网页,或者将链接保存在笔记应用中以供日后参 ...
- UWP学习记录11-设计和UI
UWP学习记录11-设计和UI 1.输入和设备 通用 Windows 平台 (UWP) 中的用户交互组合了输入和输出源(例如鼠标.键盘.笔.触摸.触摸板.语音.Cortana.控制器.手势.注视等)以 ...
- UWP学习记录10-设计和UI之控件和模式7
UWP学习记录10-设计和UI之控件和模式7 1.导航控件 Hub,中心控件,利用它你可以将应用内容整理到不同但又相关的区域或类别中. 中心的各个区域可按首选顺序遍历,并且可用作更具体体验的起始点. ...
随机推荐
- OpenJudge/Poj 1517 u Calculate e
1.链接地址: http://bailian.openjudge.cn/practice/1517 http://poj.org/problem?id=1517 2.题目: 总时间限制: 1000ms ...
- Java中printStackTrace()、toString()、getMessage()的区别
一.三者之间的关系图: 二.演示 1.printStackTrace()演示: public class Test { public int div(int a, int b) { ...
- python 自动化之路 day 08 面向对象进阶
面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 面向对象高级语法部分 经典类vs新式类 把下面代码用python2 和python3都执行一下 1 2 ...
- Linux下通过软链接转移mysql目录,解决分区空间不足(转)
http://darwinclub.info/wp/?p=454(转) 当存放数据库分区的空间不足时,可以采取对数据库目录进行迁移的方法,具体步骤如下:1.先关闭数据库mysqladmin -p sh ...
- Android学习6—单元测试的使用
在这里对单元测试的使用,主要介绍两种方法,1.手动添加配置信息,然后编写测试类.2.通过Eclipse创建测试项目 1.手动添加配置信息,然后编写测试类: 待测试的类:/src/com/example ...
- Android LayoutInflater.inflate使用上的问题解惑
最近在在使用LayoutInflater.inflate方法时遇到了一些问题,以前没有仔细看过此类的使用方法,故将其记录下来,方便日后查阅. 相信大家都知道LayoutInflater.inflate ...
- ECMAScript一元操作符
在ECMAScript中提供了一元操作符进行简单的运算,一元操作符是ECMAScript中最简单的操作符,它只能对一个值进行操作. 一元操作符有两种类型,一种是递增和递减操作符,一种是一元加和一元减操 ...
- DIV+CSS 网页布局之:三列布局
1.宽度自适应三列布局 三列布局的原理和两列布局的原理是一样的,只不过多了一列,只需给宽度自适应两列布局中间再加一列,然后重新计算三列的宽度,就实现了宽度自适应的三列布局. 同样的道理,更多列的布局, ...
- 结构型模式(Structural patterns)->外观模式(Facade Pattern)
动机(Motivate): 在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化.那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子 ...
- jquery插件----文件上传uploadfile
使用了一款jquery上传的插件,ajax上传,可以显示上传的进度,高可配性,简要记录. 插件地址http://hayageek.com/docs/jquery-upload-file.php git ...