FFMPEG 框架分析

1 概述

按照DirectShow 对播放器模块的划分,一个完整的播放器应该需要获得以下四个模块支持:
Source Filter : 数据源,可以是本地文件fopen, 也可以是网络文件,http,rtp,rtmp 等等
Demux Fliter: 解复用,下载的数据是带容器封装的,需要Demux Filter 解析头部信息,分离音频,视频流,然后送到对应的解码器。
Decoder Fliter :对音频,视频流进行解码输出。
Render Filter:显示模块,这个FFMPEG 并没有去集成,它也是采用SDL render.

敲黑板:FFMPEG是一个多媒体的框架!!! 对用户而言,它统一了不同IO 协议,不同封装格式,不同编解码格式的接口, 用户在使用时只用关注自己业务逻辑就行,下面我们将根据以上4个模块来拆解FFMPEG 架构。

2 Source Filter

在FFMPEG 中,Source Filter 可以分三层,最底层是local file , http,rtp 等具体的文件协议,第二层是URLContext ,它的成员URLProtocol 则指向具体协议的open/read. 第三层AVIOContext 在URLContext 基础上加了buff 管理。
在这里插入图片描述

对应到FFMPEG 具体的类,可表示为: AVIOContext < URLContext < URLProtocol ,分别对应的文件为:aviobuf.c, avio.c ,file.c 。 URLProtocol 指向的是具体的协议,比如本地文件,在File.c 里面有这样一个定义:

const URLProtocol ff_pipe_protocol = {
    .name                = "pipe",
    .url_open            = pipe_open,
    .url_read            = file_read,
    .url_write           = file_write,
    .url_get_file_handle = file_get_handle,
    .url_check           = file_check,
    .priv_data_size      = sizeof(FileContext),
    .priv_data_class     = &pipe_class,
    .default_whitelist   = "crypto"
};

这会在初始化的时候根据不同的URL去指定,当上层调用open /read 函数时候,对应本地文件来说对应file_open/file_write,其实就是C 库支持的fopen/fread.

URLProtocol,它根据URL 指向具体的文件协议,使用者无需区分具体的文件协议,因为这里统一了文件协议API. 如下图,展现加载过程,url_protocols[i]包含具体文件协议的函数,然后匹配对应为文件协议。
加载具体文件协议flow
AVIOContext 则是实现对读取的数据进行Buff 管理。

问AVIOContext, URLContext, URLProtocol, FileContext 之间的关系?
答:它们关系如下图所示,URLProtocol,FileContext 都是URLContext 的成员,分别对应*prot, *priv_data. URLProtocol 统一了各个IO 协议的接口,FILEContext是本地文件协议的上下文。URLContext 是AVIOContext 成员(URLContext = AVIOConetx->opaque->h), 而AVIOContext 相对于URLContext加了buff 管理,其他IO 协议也可以类比。

3 Demux Fliter

Demux Fliter 可分为两层,底层是FLVContext,AVIContext 等等这些具体的文件封装,善上层是AVFormatContext, 它的成员struct AVInputFormat *iformat; 则指向具体的封装文件,统一了API,使用者无需区分具体的格式的文件。层次关系如下图所示:
在这里插入图片描述

4 Decoder Fliter

Decoder Fliter 实现解码功能, 也是播放器的核心和难点。 它可以分为两层,最底层是具体的编码格式,如H264,VP8,VP9等等,上层是AVCodecContext,它的成员AVCodec *codec; 则指向了具体的编解码格式,统一了编解码的API 接口,使用者调用统一的API即可,无需区分具体的编解码格式。其层次关系如下图所示:
在这里插入图片描述

5 Render Filter

解码后的数据就可以送到喇叭或者屏幕上输出了,FFMPEG 并没有集成render 模块,采用的是SDL 去输出声音和图像。关于SDL 的介绍请参考雷神博客:https://blog.csdn.net/leixiaohua1020/category_2619497.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
FFmpeg 是一套功用十分强大的开源媒体框架,被广泛应用于媒体处理和转码等方面。该框架由 C 语言编写实现,其核心功能主要包括媒体解码、编码、过滤、封装等。下面我们主要从源码层面展开分析FFmpeg 作为开源软件,源码具有极高的可读性和可扩展性,但是难度也很大,不适合初学者。如果我们要逐层分析 FFmpeg 常用流程,我们可以先从 FFmpeg 的主要模块开始,例如 AVFormatContext、AVCodecContext、AVFrame 等数据结构。 在一个典型的流程中,FFmpeg 首先通过 AVFormatContext 处理输入文件,然后通过 AVCodecContext 解码处理后输出到 AVFrame,最后通过 AVFormatContext 实现封装输出成文件。 此外,FFmpeg 还可以通过多种输入视频流格式(例如 RTSP,HTTP,FLV 等)对视频进行采集和处理,并支持多种输出格式(例如 MP4,FLV,AVI 等)。同时,FFmpeg 还能够实现多幅图像的合并、重采样和音视频混合等功能。要实现这些功能,我们需要从源代码层面着手。 FFmpeg 的源代码分别包括 libavformat、libavcodec、libavutil 等库,实现不同的功能。其中,libavformat 库主要提供了媒体文件的输入输出、封装和解封装等功能,libavcodec 库主要提供了音视频编码解码的功能,libavutil 库则提供了一些公共的工具函数和数据类型定义。通过逐层深入分析,我们可以深入地了解 FFmpeg 的实现原理,以及如何使用 FFmpeg 库来完成多种媒体处理和转码任务。 总的来说,FFmpeg 是一款优秀的媒体处理和转码库,它的源码具有极高的可扩展性和自定义性,同时难度也较大。如果要深入了解和使用 FFmpeg,需要有扎实的编程背景和相关经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值