HLS流在播放时是先解协议(hls.c)后解封装(mpegts.c),libavformat下的hls.c和mpegts.c实际上是同一个级别的,同属于demuxer。

一、解HLS协议

1. FFmpeg代码分析

首先看一下ff_hls_demuxer的定义:

AVInputFormat ff_hls_demuxer = {
.name = "hls,applehttp",
.long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
.priv_class = &hls_class,
.priv_data_size = sizeof(HLSContext),
.read_probe = hls_probe,
.read_header = hls_read_header,
.read_packet = hls_read_packet,
.read_close = hls_close,
.read_seek = hls_read_seek,
};

(1)FFmpeg在拿到hls流后,它一开始并不知道该用哪个demuxer,这个时候它会进行probe,即依次调用demuxer的read_probe函数,选择返回分数最高的一个demuxer,最后选定ff_hls_demuxer。AVFormatContext中的s->iformat->priv_data一般是指demuxer内部的结构体,在解HLS协议时,这个priv_data就是HLSContext;

(2)之后FFmpeg会调用read_header函数,即执行hls_read_header,获取hls的播放列表,并赋值到HLSContext结构体中;

(3)当准备工作妥当后,FFmpeg会调用hls_read_packet读取数据,传递给上层;

(4)如果有seek操作会执行hls_read_seek;

(5)视频关闭时,FFmpeg会调用hls_close;

2. discontinue字段

FFmpeg3.4没有支持HLS标准的discontinue字段。discontinue字段常用于ts播放列表里插入一段广告,这段广告的参数可以与正片的参数不一致。上层在识别到这个参数后,可以重置解码器。对于iOS,需要重新创建解码器,对于Android,解码器兼容了这种情况,无需重新创建解码器。

二、解ts封装

以mpegts.c为例,probe一般是将读取到的probe数据与ts格式对比,如果是ts格式则返回高分数,上层选择最高的分数的demuxer;

PES包:分割打包的ES流,加入了PES头。

struct MpegTSFilter {
int pid;
int es_id;
int last_cc; /* last cc code (-1 if first packet) */
int64_t last_pcr;
enum MpegTSFilterType type;
union {// 一个Filter是下边的一种类型
MpegTSPESFilter pes_filter;
MpegTSSectionFilter section_filter;
} u;
};

handle_packet函数处理一个ts包,在函数中switch case语句中处理ts包。一般是先处理ts header, 之后是pes header,代码中状态定义:

/* TS stream handling */
// 标识TS流状态
enum MpegTSState {
MPEGTS_HEADER = ,
MPEGTS_PESHEADER,
MPEGTS_PESHEADER_FILL,
MPEGTS_PAYLOAD,
MPEGTS_SKIP,
};

从av_read_frame读到的pkt,其音频和视频的pts是连续的,但是两者之间不是连续的,因为pts乘以时基才是真正的显示时间,比如如下打印日志,pkt时间进行换算后,可以看到其整体pts是连续的。

martinjia time_base:1 30000, pkt index:0, pkt pts:83083(pts换算后:2.76s)
martinjia martinjia time_base:1 48000, pkt index:1, pkt pts:118784(pts换算后:2.47s)

FFMpeg笔记(七) 代码结构分析,以HLS为例的更多相关文章

  1. 《MFC游戏开发》笔记七 游戏特效的实现(一):背景滚动

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9344721 作者:七十一雾央 新浪微博:http:// ...

  2. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  3. python3.4学习笔记(七) 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

  4. iOS 学习笔记七 【博爱手把手教你使用2016年gitHub Mac客户端】

    iOS 学习笔记七 [博爱手把手教你使用gitHub客户端] 第一步:首先下载git客户端 链接:https://desktop.github.com 第二步:fork 大神的代码[这里以我的代码为例 ...

  5. 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  6. jQuery整理笔记七----几个经典表单应用

    1.文本框获得(失去)焦点 当文本框获得输入焦点时,将该文本框高亮显示,算不得一个应用,仅仅是一个小技巧,能够提高用户体验. <!DOCTYPE html PUBLIC "-//W3C ...

  7. DirectX11笔记(七)--Direct3D渲染3--INDICES AND INDEX BUFFERS

    原文:DirectX11笔记(七)--Direct3D渲染3--INDICES AND INDEX BUFFERS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  8. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  9. Java IO学习笔记七:多路复用从单线程到多线程

    作者:Grey 原文地址:Java IO学习笔记七:多路复用从单线程到多线程 在前面提到的多路复用的服务端代码中, 我们在处理读数据的同时,也处理了写事件: public void readHandl ...

  10. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

随机推荐

  1. PHP实现大转盘抽奖算法

    流程: 1.拼装奖项数组,2.计算概率,3.返回中奖情况 代码如下:中奖概率 ' v ' 可以在后台设置,传到此方法中,注意传整数 function get_gift(){ //拼装奖项数组 // 奖 ...

  2. idea 提交 Push rejected: Push to origin/master was rejected

    idea中,发布项目到码云上,当时按照这样的流程添加Git,然后push,提示:push to origin/master war rejected". 解决方案如下: 1.切换到自己项目所 ...

  3. html5的web存储与cookie的区别

    以下从3个方面进行比较: 1,容量:cookie只有4KB,localStorage和sessionStorage最大容量5M 2,是否会携带到ajax中:cookie由每个对服务器的请求来传递,会影 ...

  4. RecyclerView打造通用的万能Adapter

    既然想做到通用那么现在摆在面前的就三个问题:数据怎么办?布局怎么办? 绑定怎么办?.数据决定采用泛型,布局打算直接构造传递,绑定显示效果肯定就只能回传. 1 基本改造 数据决定采用泛型,布局打算直接构 ...

  5. jquery 绑定事件 获取方式 --------------data event 获取

    //绑定事件 bind event $("body").on("click",function(){ console.log("in") } ...

  6. aix rootvg镜像

    就一般生产系统而已,操作系统层面都要进行备份,而最常见的操作系统备份方式之一就是做镜像(mirror),而实践过程中,往往是把rootvg这个卷组做镜像操作.查看rootvg是否已经进行镜像方法: 1 ...

  7. centos7 修改中文字符集

    CentOS 7字符集的问题与6有点区别,会出现下面问题,查看是中文,vi进入就变成乱码了 生产中修改配置文件   [root@ce1d2002a999 ~]# cat /etc/locale.con ...

  8. linux访问Windows共享文件命令

    mount -o username=username,password=password,ip=10.0.0.1 //10.0.0.1/backupscm /home/package/image_vm ...

  9. OpenResty 安装配置

    0. 说明 1. Windows 下安装 下载软件包 openresty-1.13.6.1-win32.zip ,解压即可食用. [开启] 直接运行 nginx.exe 在 Windows 的命令窗口 ...

  10. Hadoop 的序列化

    1. 序列化 1.1 序列化与反序列化的概念 序列化:是指将结构化对象转化成字节流在网上传输或写到磁盘进行永久存储的过程 反序列化:是指将字节流转回结构化对象的逆过程 1.2 序列化的应用 序列化用于 ...