转载:http://www.cnblogs.com/azraelly/

http://www.cnblogs.com/azraelly/archive/2013/01/18/2865858.html

内容摘自《ffmpeg/ffplay源码剖析》

1.播放器一般原理

可以直观的看到播放这个媒体文件的基本模块(filter),七个模块按广度顺序:读文件模块(source filter),解复用模块(Demux filter),视/音频解码模块(Decode filter),颜色空间转换模块(Color Space converter filter),视频/音频播放模块(Render filter)。

Source filter 源过滤器的作用是为下级demux filter 以包的形式源源不断的提供数据流,在下一级的demux filter 看来,本地文件和网络数据是一样的

Demux filter 解复用过滤器的作用是识别文件类型,媒体类型,分离出各媒体原始数据流,打上时钟信息后 送给下级decoder filter。

Decoder filter 解码过滤器的作用就是解码数据包,并且把同步时钟信息传递下去。

Color space converter filte r 颜色空间转换过滤器的作用是把视频解码器解码出来的数据转换成当前显示系统 支持的颜色格式

Render filter 渲染过滤器的作用就是在适当的时间渲染相应的媒体,对视频媒体就是直接显示图像,对音频 就是播放声音

GraphEdit 应用程序可以看成是一个支撑平台,支撑框架。它容纳各种filter,在filte r 间的传递一些通讯消息, 控制filter 的运行(启动暂停停止),维护filter 运行状态

2.ffplay播放器原理

1)source filter读文件模块,分3层。最底层的是file ,pipe ,tcp,udp,http 等这些具体的本地文件或网络协议(注意ffplay 把file 也当协议看待);中间抽象层用URLContext 结构来统一表示底层具体的本地文件或网络协议,相关操作也只是简单的中转一下调用底层具体文件或协议的支撑函数;最上层用ByteIOContext 结构来扩展URLProtocol 结构成内部有缓冲机制的广泛意义上的文件,并且仅仅由ByteIOContext  对模块外提供服务。此模块主要有libavformat 目录下的file.c,avio.h, avio.c, aviobuf.c 等文件,实现读媒体文件功能。

ByteIOContext  接口
URLContext  抽象
file ,pipe ,tcp,udp,http  文件                       

2)Demux filter 解复用模块,可以简单的分为两层,底层是AVIContext,TCPContext,UDPContext 等等这些具体媒体的解复用结构和相关的基础程序,上层是AVInputFormat 结构和相关的程序。上下层之间由AVInputFormat 相对应的AVFormatContext 结构的priv_data 字段关联AVIContext 或TCPContext 或UDPContext 等等具体的文件 格式。AVInputFormat 和具体的音视频编码算法格式由AVFormatContext 结构的streams 字段关联媒体格式,streams 相当于demux filter 的output pin,解复用模块分离音视频裸数据通过streams 传递给下级音视频解码器。此模块 主要有libavformat 目录下的avidec.c,utils_format.c 文件。

AVInputFormat   
AVIContext,TCPContext,UDPContext   

3)Decoder filter 解码模块, 也可以简单的分为两层, 由AVCodec 统一表述。上层是AVCodec 对应的 AVCodecContext 结构和相关的基础程序,底层是TSContext,MsrleContext 等等这些具体的编解码器内部使用的 结构和相关的基础程序。AVCodecContext 结构的priv_data 字段关联TSContext,MsrleContext 等等具体解码器上 下文。此模块主要有libavcodec 目录下的msrle.c,truespeech.c,truespeech_data.h,utils_codec.c 等文件。

主要数据结构关系图:

有一些是动态与静态的关系,比如, URLProtocol 和URLContext,AVInputFormat 和AVFormatContext, AVCodec 和AVCodecContext。ffplay 把其他的每个大功能抽象成一个相当于C++中COM 接口的数据结构,着重于功能函数,同时这些功能函数指针在编译的时候就能静态确定。每一个大功能都要支持多种类型的广义数据,ffplay 把这多种类型的广义数据的共同的部分抽象成对应的Context 结构,这些对应的context 结构着重于动态性,其核心成员只能在程序运行时动态确定其值。并且COM接口类的数据结构在程序运行时有很多很多实例,而相应的Context 类只有一个实例,这里同时体现了数据结构的划分原则,如果有一对多的关系就要分开定义。

有一些是指针表述的排他性包含关系(因为程序运行时同一类型的多种数据只支持一种,所以就有排他性)。 比如,AVCodecContext 用priv_data 包含MsrleContext 或TSContext,AVFormatContext 用priv_data 包含AVIContext 或其他类Context,AVStream 用priv_data 包含AVIStream 或其他类Stream。由前面数据结构的动态与静态关系 可知,ffplay 把多种类型的广义数据的共同部分抽象成context 结构,那么广义数据的各个特征不同部分就抽象成 各种具体类型的context,然后用priv_data 字段表述的指针排他性的关联起来。由于瘦身后的ffplay 只支持有限 类型,所以AVFormatContext 只能关联包含AVIContext,AVStream 只能关联包含AVIStream。

3.视音频处理的简单流程:

音视频数据流简单流程, 由ByteIOContext(URLContext/URLProtocol) 表示的广义输入文件, 在 AVStream(AVIStreamt)提供的特定文件容器流信息的指引下,用AVInputFormat(AVFormatContext /AVInputFormat )接口的read_packet()函数读取完整的一帧数据,分别放到音频或视频PacketQueue(AVPacketList/AVPacket)队列 中,这部分功能由decode_thread 线程完成。对于视频数据,video_thread 线程不停的从视频PacketQueue 队列中 取出视频帧,调用AVCodec(AVCodecContext/MsrleContext)接口的decode()函数解码视频帧,在适当延时后做颜 色空间转化并调用SDL 库显示出来。对于音频数据, SDL 播放库播放完缓冲区的PCM 数据后, 调用 sdl_audio_callback()函数解码音频数据,并把解码后的PCM 数据填充到SDL 音频缓存播放。当下次播放完后, 再调用sdl_audio_callback()函数解码填充,如此循环不已。

 
分类: ffmpeg

ffmpeg/ffplay源码剖析笔记<转>的更多相关文章

  1. STL源码剖析读书笔记之vector

    STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...

  2. [转]【安卓笔记】AsyncTask源码剖析

    [转][安卓笔记]AsyncTask源码剖析 http://blog.csdn.net/chdjj/article/details/39122547 前言: 初学AsyncTask时,就想研究下它的实 ...

  3. c++ stl源码剖析学习笔记(一)uninitialized_copy()函数

    template <class InputIterator, class ForwardIterator>inline ForwardIterator uninitialized_copy ...

  4. Hadoop源码学习笔记之NameNode启动场景流程二:http server启动源码剖析

    NameNodeHttpServer启动源码剖析,这一部分主要按以下步骤进行: 一.源码调用分析 二.伪代码调用流程梳理 三.http server服务流程图解 第一步,源码调用分析 前一篇文章已经锁 ...

  5. 《STL源码剖析》读书笔记

    转载:https://www.cnblogs.com/xiaoyi115/p/3721922.html 直接逼入正题. Standard Template Library简称STL.STL可分为容器( ...

  6. 通读《STL源码剖析》之后的一点读书笔记

    直接逼入正题. Standard Template Library简称STL.STL可分为容器(containers).迭代器(iterators).空间配置器(allocator).配接器(adap ...

  7. jquery源码学习笔记三:jQuery工厂剖析

    jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...

  8. Netty学习笔记(三)——netty源码剖析

    1.Netty启动源码剖析 启动类: public class NettyNioServer { public static void main(String[] args) throws Excep ...

  9. ffplay源码分析1-概述

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10301215.html ffplay是一个很简单的播放器,但是初次接触仍会感到概念和细节 ...

随机推荐

  1. numpy nonzero与isnan

    nonzero 直接看例子: In [83]: x = np.array([[1,0,0], [0,2,0], [1,1,0]]) In [84]: x.shape Out[84]: (3L, 3L) ...

  2. 查询优化 | MySQL慢查询优化

    ​Explain查询:rows,定位性能瓶颈. 只需要一行数据时,使用LIMIT1. 在搜索字段上建立索引. 使用ENUM而非VARCHAR. 选择区分度高的列作为索引. 采用扩展索引,而不是新建索引 ...

  3. display:none和visible:hidden两者的区别

    display:none和visible:hidden都能把网页上某个元素隐藏起来,但两者有区别:display:none ---不为被隐藏的对象保留其物理空间,即该对象在页面上彻底消失,通俗来说就是 ...

  4. 分享知识-快乐自己:Spring线程池配置

    Spring通过ThreadPoolTaskExecutor实现线程池技术,它是使用jdk中的Java.util.concurrent.ThreadPoolExecutor进行实现. Spring 配 ...

  5. Java中常见的比较器的实现方法

    在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题. 通常对象之间的比较可以从两个方面去看: 第一个方面:对象的地址是否一样,也就是是否引用自同一个对象.这种方式可以直接使用& ...

  6. poj 1300 欧拉图

    http://poj.org/problem?id=1300 要不是书上有翻译我估计要卡死,,,首先这是一个连通图,鬼知道是那句话表示出来的,终点必须是0,统计一下每个点的度数,如果是欧拉回路那么起点 ...

  7. 51nod 1428 贪心

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活动安排问题 基准时间限制:1 秒 空间限制:13107 ...

  8. orale存储技术

    一.存储的主要作用 1.海量存储 阵列存储   光盘存储   磁带存储   数据迁移   文件服务器,跨平台文件共享 2.容灾 数据备份及恢复:磁带.光盘.阵列  数据复制:本地镜像.远程镜像 3.高 ...

  9. run as android application过程

    1.打包 >> 把所有的class打包成为classes.dex >> AndroidManifest.xml 打包成二进制文件 >> res目录下面的文件打包到r ...

  10. BestCoder Round #18(hdu5105)Math Problem(高中数学)

    最大值无非就是在两个端点或极值点处取得. 我注意讨论了a=0和b=0,却忽略了极值点可能不在L到R的范围内这一问题.被Hack了. #include<iostream> #include& ...