转载: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. 关于sublime text 3 pylinter的错误提示

    刚开始用windows下sublime text 3写python,搭建完以后,按ctrl+b可以build,然后保存时候一直提示. Fatal pylint error: x:/python: ca ...

  2. myeclipse发布项目

    最好不要点击restart 虽然点击run,也会发布,但是最好先点击发布. 点击restart,可能会出现tomcat关不掉又启动不了.

  3. open inventor 学习笔记

    初次接触open inventor,跟以前学习一种新的东西,都想要先做出个小的helloworld程序,这个当然也不例外. 首先会创建一个窗口句柄,初始化一下场景数据库. HWND window = ...

  4. [Linq] ORM

      orm  对象关系映射框架,主要将关系数据库中的数据 ,映射成应用程序的对象.表为类名,列为类的字段. ADO.NET entity framework   在ADO.NET基础上发展出来的对象关 ...

  5. Page 生命周期阶段 以及 生命周期事件

    MSDN 关于 页面生命周期事件的详细介绍: http://msdn.microsoft.com/zh-cn/library/ms178472.aspx ASP.NET  页面生命周期,当IIS接收访 ...

  6. 【Prism】MEF版Commanding

    引言 接下来的是Commanding Demo的改造. DelegateCommand    WPF本身提供了一个RoutedCommand,然而没什么卵用.在Prism框架中提供了个更人性化的ICo ...

  7. 20165210 Java第五周学习总结

    20165210 Java第五周学习总结 教材学习内容 - 第七章学习总结 内部类: 内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法. 内部类的类体中不可以声明类变 ...

  8. LeetCode Reverse String II

    原题链接在这里:https://leetcode.com/problems/reverse-string-ii/#/description 题目: Given a string and an inte ...

  9. Oracle存储过程创建及调用

    在大型数据库系统中,有两个很重要作用的功能,那就是存储过程和触发器.在数据库系统中无论是存储过程还是触发器,都是通过SQL 语句和控制流程语句的集合来完成的.相对来说,数据库系统中的触发器也是一种存储 ...

  10. 拨打电话demo

    - (IBAction)btnClick:(id)sender { UIActionSheet *action = [[UIActionSheet alloc] initWithTitle:nil d ...