Audiosink design
Audiosink的设计,需要满足下列一些需求:
良好的chain_based 支持。绝大多数简单playback pipelines都是将音频数据从decoder直接push给audiosink;
良好 getrange_based支持。大部分专业的应用都是audio sink从pipeline拉取数据。典型的作法是在一个回调函数中pull N Samples,回调函数一般在一个单独的线程或者是硬件设备来调度。
提供准确的时钟。必须能够提供即使samples被丢弃或在流中发现不连续时也能提供采样准确的时钟。
可能的话,提供DMA支持
Design
The design is based on a set of base classes and the concept of a ringbuffer of samples.
+-----------+ - provide preroll, rendering, timing
+ basesink + - caps nego
+-----+-----+
|
+-----V----------+ - manages ringbuffer
+ audiobasesink + - manages scheduling (push/pull)
+-----+----------+ - manages clock/query/seek
| - manages scheduling of samples in the ringbuffer
| - manages caps parsing
|
+-----V------+ - default ringbuffer implementation with a GThread
+ audiosink + - subclasses provide open/read/close methods
+------------+
The ringbuffer is a contiguous piece of memory divided into segtotal pieces of segments. Each segment has segsize bytes.
play position
v
+---+---+---+-------------------------------------+----------+
+ 0 | 1 | 2 | .... | segtotal |
+---+---+---+-------------------------------------+----------+
<--->
segsize bytes = N samples * bytes_per_sample.
如上,环形缓冲器有一个play position,以segment表示。play position是设备正在从ringbuffer读取samples的位置。
ringbuffer可以进入PLAYING或STOPPED状态:
在STOPPED状态下,没有samples被put到设备,play pointer不前进。
在PLAYING状态下,samples被写入设备,并且在每个seg被写入设备之后,ringbuffer应该调用可配置的回调,
play pointer在每个段被写入之后前进。
对ringbuffer的写入操作将会把新的samples放入ringbuffer中。如果ringbuffer中没有足够的空间,
写操作将被阻塞。即使buffer为空,ringbuffer的播放也不会停止。当buffer为空时,设备会播放静音。
ringbuffer通过无锁原子操作实现,特别是在读取端,以便尽可能地降低低延迟。
每当一个new samples要put进ringbuffer,先获取read pointer,请求的write position和actural position作差值,
/* get the currently processed segment */
segdone = g_atomic_int_get (&buf->segdone) - buf->segbase; /* see how far away it is from the write segment */
diff = writeseg - segdone;
..... /* segment too far ahead, writer too slow, we need to drop, hopefully UNLIKELY */
if (G_UNLIKELY (diff < 0)) {
/* we need to drop one segment at a time, pretend we wrote a segment. */
skip = TRUE;
break;
} /* write segment is within writable range, we can break the loop and
* start writing the data. */
if (diff <= segtotal) {
skip = FALSE;
break;
} /* else we need to wait for the segment to become writable. */
if (!wait_segment (buf))
goto not_started;
}
如果差值diff<0,则samples来太慢了,丢掉来太慢的数据。如果diff > segtotal,写入部分必须等待播放指针前进。
也就是需要设备先消耗掉ringbuffer中的数据,才能继续往ringbuffer中写入新的数据。
Audiosink design的更多相关文章
- 带你实现开发者头条APP(四)---首页优化(加入design包)
title: 带你实现开发者头条APP(四)---首页优化(加入design包) tags: design,Toolbar,TabLayout,RecyclerView grammar_cjkRuby ...
- 【知识必备】一文让你搞懂design设计的CoordinatorLayout和AppbarLayout联动,让Design设计更简单~
一.写在前面 其实博主在之前已经对design包的各个控件都做了博文说明,无奈个人觉得理解不够深入,所以有了这篇更加深入的介绍,希望各位看官拍砖~ 二.从是什么开始 1.首先我们得知道Coordina ...
- Android Material Design之 NavigationView侧滑界面自定义 随笔
一.侧滑界面Menu自定义: 在menu文件夹下新建activity_main_drawer.xml文件,自定义标题和icon: <?xml version="1.0" en ...
- Material Design Reveal effect(揭示效果) 你可能见过但是叫不出名字的小效果
Material Design Reveal effect(揭示效果) 你可能见过但是叫不出名字的小效果 前言: 每次写之前都会来一段(废)话.{心塞...} Google Play首页两个tab背景 ...
- 使用Design包实现QQ动画侧滑效果和滑动菜单导航
Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个supp ...
- 安卓Design包下的TextInputLayout和FloatingActionButton的简单使用
终于介绍到Design包的最后的东西了. 也很简单,一个是TextInputLayout. TextInputLayout作为一个父容器,包含一个新的EditText,可以给EditText添加意想不 ...
- 安卓Design包之AppBar和Toolbar的联用
前面讲了Design包的的CoordinatorLayout和SnackBar的混用,现在继续理解Design包的AppBar; AppBarLayout跟它的名字一样,把容器类的组件全部作为AppB ...
- 安卓Design包之超强控件CoordinatorLayout与SnackBar的简单使用
在前面的Design中,学习使用了TabLayout,NavigationView与DrawerLayout实现的神奇效果,今天就带来本次Design包中我认为最有意义的控件CoordinatorLa ...
- 安卓Design之NavigationView的使用
前面讲解了Design包下的TabLayout的使用,下面将带来NavagationView和DrawLayout以及toolbar的联动. 项目已经同步至:https://github.com/na ...
随机推荐
- [Javascript]js判断是否为undefined类型
概述 在项目获取某个元素的值会出现undefined,所以对这种情况要有特殊处理. 可通过下面的代码判断是否为undefined类型. if (typeof(reValue) == "und ...
- coco2dx-2.2.2 win32启动过程(opengl 和 窗口大小初始化部分) - 学习笔记 1
因为最近要做不同分辩率的适配,所于看了下引擎这方面的代码,记录一下当是学习笔记,cocos2d-x 版本 2.2.2 , 例子是samples\Cpp\TestCpp下的 TestCpp. 先看下ma ...
- inline-block空隙总结
如果inline-block,宽度都是50%会留有空隙,解决方法如下 1.标签之间不留空格 (1)直接不留空 <div></div><div></div> ...
- [Android Memory] Android性能测试小工具Emmagee
转载:http://blog.csdn.net/anlegor/article/details/22895993 Emmagee是网易杭州QA团队开发的用于测试指定android应用性能的小工具.该工 ...
- C语言中的联合体union所占内存方式
当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union).在C Programming Language 一书中对于联合体是这么描述的: 1)联合体是一个结构: ...
- php图片木马讲解
这是一个非常有趣的后门,它并没有依靠正常模式去隐藏起内容(比如 base64/gzip 编码),但是它却把自己的数据隐藏在JPEG图片的EXIF头部中了.它也使用exif_read_data和preg ...
- win7系统下ping不是内部或外部命令
win7下ping不是内部或外部命令,在使用java设置变量环境时,可能会遇到这样的问题,出现win7下ping不是内部或外部命令,是在设置变量环境是把一些设置删掉了的原因,请看在win7下怎么还原. ...
- XDebug 教程
安装说明: PHP调试时,不得不提XDEBUG这个调试利器.学习PHP以来,几乎所有的问题我都利用它来解决. 首先关于如何安装,不在赘述,请自行google之.(需要特别注意的是:PHP5.2 和5. ...
- LINUX 和WINDOWS下的自动登录小脚本
每天上班第一件事,就是连接公司LAB里面的机器,但首先要过一个防火墙,每次输用户名密码是很累人的事, 以下是两个脚本,可以放在启动项中,开机便自动登录 WINDOWS: @echo off ipcon ...
- Hello Ragel -- 生成状态机的神器
Ragel 是个很 NB 的能生成状态机的编译器,而且支持一堆语言:C.C++.Object-C.C#.D.Java.Go 以及 Ruby. 原来的文本解析器是用正则表达式实现的,随着状态(if-el ...