VLC-Android音画同步原理
目录
简介
延伸——buffering机制的影响
延伸——时间转换位置
延伸——pause操作的影响
延伸——delay设置
总结
简介
播放器的音视频同步无外乎三种方式:视频往音频同步、音频往视频同步及音视频同时往系统时钟同步。大部分播放器都是采取第一种方式,例如ffplay、EXOPlayer、Nuplayer、ijkplayer等。而VLC就比较不合群了,它采用音视频同时往系统时钟同步的方式,下面结合代码简单介绍下音画同步的原理。
VLC专门有一个clock.c文件,用来维护时钟信息,其核心结构体如下,阐述了VLC音画同步的核心思想:
|
VLC将连续的时间变为离散的clock_point_t,每一个clock_point_t都记录了当前时间点的i_system和i_stream。i_system比较好理解,就是系统时间;i_stream则是片源的时间,或者理解为dts,例如,你在上午10点整播放一个视频,那么第一个clock_point_t的i_system就是上午十点,i_stream则是视频第一帧的dts(大概率是0)。VLC维护这两套时间基准,就是因为视频文件的音视频流只包含stream时间,需要将它转换为系统时间才能够跟系统时钟进行同步。
input_clock_t结构体内部维护了两个clock_point_t,分别名为ref和last。ref用来记录起播或seek后的第一个时间点,last用来记录最近的时间点。这两个clock_point_t的更新策略在input_clock_Update()函数中:
|
demux在解到数据后,会通过数据的dts来更新pcr,然后通过es_out_SetPCR()通知es_out,es_out每次setPCR都会调用上面的input_clock_Update()函数来更新时间信息(这部分流程都可以在代码里直接找到,这里就不再展开赘述了)。至此我们可以知道,ref的stream就是demux解到第一帧数据的dts,ref的system就是demux解到第一帧数据的系统时间。last则是demux解到最近一帧的dts和系统时间。
stream时间转换成system时间的函数如下:
|
至此,我们已经可以将stream时间转换成系统时间了,假设当前系统时间是10s,此时我们从视频20s的位置起播(1倍速),时钟信息如下:
stream |
20 |
21 |
22 |
23 |
24 |
25 |
---|---|---|---|---|---|---|
stream_to_system | 10 | 11 | 12 | 13 | 14 | 15 |
system | 10 | 11 | 12 | 14 | 14 | 15 |
stream为23时的计算公式为:
(23 - 20)× 1 + 10 = 13;
即我们在系统时间是10s时从视频的20s开始以1倍速播放,视频21s的内容应该在系统时间11s时展示。。。以此类推。这样看来我们的视频确实能够同步到系统时钟进行播放了。
再举一个倍速播放的例子,假设当前系统时间是30s,此时我们从视频10s的位置起播(2倍速),时钟信息如下:
stream |
10 |
11 |
12 |
13 |
14 |
---|---|---|---|---|---|
stream_to_system | 30 | 30.5 | 31 | 31.5 | 32 |
system | 30 | 30.5 | 31 | 31.5 | 32 |
stream为13时的计算公式为:
(13 - 10) × 0.5 + 30 = 31.5;
可以看到,本来需要4s才能播放完的视频,实际只用了2s,达到了两倍速播放的效果。
延伸——buffering机制的影响
对播放器有一定了解的同学都知道,播放器都是有buffering机制的。上面讲的同步机制只适用于理想条件下,一旦播放器发生了rebuffering,这个过程中视频是不会播放的,但系统时间仍在稳定增长,那么就会导致buffering结束后,所有帧都晚了,导致丢帧,如下表所示:
stream |
20 |
buffering 1s |
21 |
22 |
23 |
24 |
---|---|---|---|---|---|---|
stream_to_system | 10 | - | 11 | 12 | 13 | 14 |
system | 10 | 11 | 12 | 13 | 14 | 15 |
可以看到,buffering之后的所有帧都晚了1s,会出现大量的丢帧,这种情况肯定是不能容忍的。因此VLC将buffering的这段时间也考虑在内了,参考es_out.c的EsOutDecodersStopBuffering()函数:
|
至于input_clock_ChangeSystemOrigin就很简单了,把传进来的参数i_system做了下微调就设置给clock了。
|
延伸——时间转换位置
VLC的时间戳转换是在decoder.c中进行的,decoder.c的DecoderFixTs()函数调用了clock.c的input_clock_ConvertTS(),获取转换后的时间戳、duration、rate等信息。DecoderFixTs()函数又被DecoderPlayVideo()函数和DecoderPlayAudio()函数调用,说明decoder是对解码后的数据进行的时间戳转换。这里明确时间戳转换的位置,主要是为了更好的理解下一部分内容。
延伸——pause操作的影响
pause和buffering的情况比较像,pause状态下系统时钟仍在不断增长,resume时需要把这部分系统时间加到ref.i_system上。我们看下VLC是怎么做的:
|
到这部分位置和buffering的逻辑都是一样的,为什么要分开讲呢?我们再回顾下时间戳转换的位置是在decoder取得加码完的数据后,VLC从demux到output的框架大概如下:
demux---->block_fifo---->decoder---->picture_fifo----> output
时间戳转换发生在上图的decoder和picture_fifo之间,即clock.c的修正只对picture_fifo之前的数据起作用,然而picture_fifo中也是有缓存一部分解码后的数据的,这部分数据如果在pause-resume后不加修正,也会因为too late丢帧。这么简单的情况VLC肯定也考虑在内了,解码后的时间戳修正在video_output.c中:
|
延伸——delay设置
在VLC var机制中提到了VLC可以通过var来设置一些属性或下发event,其中就有audio-delay和spu-delay,我们可以通过这两个属性对音频和字幕的同步进行微调。属性设置的流程这里也不展开了,delay值最终生效的位置也是在decoder.c的DecoderFixTs()函数中。
总结
至此,VLC的音画同步原理就大致介绍完了,可以看到VLC用clock.c来维护时钟系统,其中最重要的就是名为ref的clock_point_t,它内部保存了起播时的stream时间和system时间,解码后的帧都需要以此为基准做时间戳的转换。对比其他两种同步方式,系统时钟的增长不会因为pause或buffering而停止,因此这两种情况需要特殊处理保证音画同步播放。
VLC-Android音画同步原理相关推荐
- 深入理解Android音视频同步机制(二)ExoPlayer的avsync逻辑
深入理解Android音视频同步机制(一)概述 深入理解Android音视频同步机制(二)ExoPlayer的avsync逻辑 深入理解Android音视频同步机制(三)NuPlayer的avsync ...
- 音视频同步原理解析;音频编码和解码原理
视频流中的DTS/PTS到底是什么? DTS(解码时间戳)和PTS(显示时间戳)分别是解码器进行解码和显示帧时相对于SCR(系统参考)的时间戳.SCR可以理解为解码器应该开始从磁盘读取数据时的时间. ...
- 音视频同步原理[ffmpeg]
音视频同步原理[ffmpeg] output_example.c 中AV同步的代码如下(我的代码有些修改),这个实现相当简单,不过挺说明问题. 阅读前希望大家先了解一下时间戳的概念. /* compu ...
- 探店视频批量剪辑神器,批量生成音画同步探店视频,好物视频和团购达人视频
探店视频批量剪辑神器,批量生成音画同步探店视频,好物视频和团购达人视频 主要按场景分场景做剪辑.三级文件 夹方式.合成视频. 比如:做餐饮探店,首先是按门头,菜品,环境,活动.分为四大场景,每个场景会 ...
- Android 音视频变速原理
视频倍速播放 假设视频帧率是24fps, 则播放器必须在1000/24 = 41.66ms 内 解封装 + 解码 + 渲染完一帧,一般只计算出把YUV数据从渲染队列中取出到渲染结束的时间(Render ...
- ffmpeg源码中ffplay音视频同步原理及实现
音视频指南 文章目录 音视频指南 前言 一.音视频同步简单介绍? 二.基本概念解释 1.为什么需要视频压缩 2.什么是I帧.p帧.b帧 3.什么是DTS,PTS 4.其他概念解释 三.常用同步策略 四 ...
- 【gitHubDailyShare】通过真实录音,让动漫人物的嘴唇实现音画同步。开发者可将其应用于计算机游戏
推荐 GitHub 上一款比较有意思的开源工具:Rhubarb Lip Sync,可通过真实录音,让动漫人物的嘴唇实现音画同步. 开发者可将其应用于计算机游戏.动画卡通角色.视频 Vlog 等场景上. ...
- 音画同步的几套方案的对比
文章目录 一. 首先回顾业界的常用的三种方案的优缺点以及实现 二. 方案三的实现 基础补充 1. CADisplaylink取代视频线程回调,从视频队列中获取大于且最接近音频pts的一帧,小于这个pt ...
- 上计算机课用什么耳机,在电脑上录课程用什么软件好?实现音画同步,画板标注就选它...
原标题:在电脑上录课程用什么软件好?实现音画同步,画板标注就选它 怎么在电脑上录制课程?对于每个人来说,学习都是一个长期积累的过程,即使你是早已离开学校为生活奔波的上班族,只要你愿意学习,网上的各种教 ...
最新文章
- idea 2018.2.2安装
- Google 系两公司联手,要让无人车少“犯错”
- UVA - 11491 Erasing and Winning(奖品的价值)(贪心)
- python爬虫脚本ie=utf-8_python脚本-共享文件爬虫
- Python dataframe列拆分多行与统计
- easyui input输入框的限制和校验条件
- Update From 用法
- hdu1166------树状数组(板子)
- 【产品工具使用】黑群晖史上最强安装教程
- Linux系统密码忘记教程
- ffmpeg命令分析-ss
- 【推理加速】博客翻译:利用融合conv和bn的方法加速模型
- android ndk 怎样调用第三方的so库文件。
- matlab学霸表白公式,一个理科学霸的表白:数学公式的超酷表白
- 动态规划求解机器人有多少种可能的路径
- 五子棋AI算法第三篇-Alpha Beta剪枝
- Linux-日志管理篇
- 使用AssetFileDescriptor 来读取(android)app的raw文件夹下的数据
- 【Unity编辑器扩展】(二)PSD转UGUI Prefab, 图层解析和碎图导出
- 计算机蓝屏 无法启动怎么办,电脑无法开机一直蓝屏怎么办
热门文章
- C++ cin输入空格
- 五道口考研之谈,困惑的人好好看看
- [凯立德]2014秋季版3321J0L(SP2)Android版
- 基因共表达网络分析java,好用的基因共表达网络分析工具
- java正则匹配英文句号_java正则表达式最简单 学习教程
- 初中在线测试软件,2020初中生成绩查询网址-2020年初中生成绩查询网址官网最新预约 v1.0-优盘手机站...
- TX2学习笔记(1)——NVIDIA Jetson TX2 开箱上电
- 30分钟带你精通Git使用
- SI4459ADY-T1-GE3 MOS管资料
- 点击按钮背景变灰色,松开恢复原来色