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. LeetCode DB: Duplicate Emails

    Write a SQL query to find all duplicate emails in a table named Person. +----+---------+ | Id | Emai ...

  2. python解释器介绍以及Pycharm的破解

    python语言是弱类型解释型语言,弱类型指的是没有强制规定它的类型. 由于是解释型语言,则必有解释器与其匹配,根据不同的工作环境以及需求,python的解释器有很多种, 官方推荐的是CPython, ...

  3. vue-scroller记录滚动位置

    问题描述: 列表页进入详情页,或者tab页切换,然后再返回列表页,希望能切换到之前滚动位置 解决问题思路: 切换到其他页面前记录位置,返回列表页的时候返回位置.这就需要借助vue-router的bef ...

  4. Hibernate 中配置属性详解(hibernate.properties)

    Hibernate能在各种不同环境下工作而设计的, 因此存在着大量的配置参数.多数配置参数都 有比较直观的默认值, 并有随 Hibernate一同分发的配置样例hibernate.properties ...

  5. 如何选型商业智能和分析平台,Gartner给了这些建议!

    文 | 水手 在2017年1月20日Gartner发布的<China Summary Translation: 'Survey Analysis: Customers Rate Their BI ...

  6. JavaScript实现时间查询

    首先要引入js文件和css文件 <script src="jquery-1.11.2.min.js"></script> <script src=&q ...

  7. react native中Unable to load script from assets 'index.android.bundle'解决方案

    刚刚朋友问我,说是创建好一个项目,运行后报错:Unable to load script from assets 'index.android.bundle',以前好好的没出现这种现象,于是我找到一个 ...

  8. NETBEAN 启动报错 CANNOT LOCATE JAVA INSTALLATION IN SPECIFIED JDKHOME的解决办法

    打开 NetBeans 安装目录下的\etc目录,查找报错信息中的jdk字符串,修改netbeans.conf文件即可

  9. windows 远程连接

    * 方法1:windows自带的远程工具 缺点:如果操作系统是家庭版,会一致连接不上:尽管想办法把这个功能打开: 步骤: * 打开允许远程连接: 点进去自己设置就行,没有什么好说的 设置完之后,需要允 ...

  10. 如何把高版本的sqlserver 还原到低版本的 sqlserver(转载)

    本例为sql2012 还原到sql2008. 要实现的功能是把sql2012的数据库备份到sql2008,数据库名字为Test,并且这两个数据库在不同的电脑中. 微软的软件设计方案基本上都是新版本兼容 ...