前情简介
这个故事讲起来可能有点费事,前前后后涉及到的东西比较多,我希望尽量能把故事讲清楚,不足之处,还请各位看官包涵。
首先说一下令牌桶:
令牌桶是一种常用的流量控制技术。令牌桶本身没有丢弃和优先级策略。原理:
1.令牌以一定的速率放入桶中。
2.每个令牌允许源发送一定数量的比特。
3.发送一个包,流量调节器就要从桶中删除与包大小相等的令牌数。
4.如果没有足够的令牌发送包,这个包就会等待直到有足够的令牌(在整形器的情况下)或者包被丢弃,也有可能被标记更低的DSCP(在策略者的情况下)。
5.桶有特定的容量,如果桶已经满了,新加入的令牌就会被丢弃。因此,在任何时候,源发送到网络上的最大突发数据量与桶的大小成比例。令牌桶允许突发,但是不能超过限制。
画个图可能更直观:
啊,我好像不会画高大上的图啊,将就一下。。
说完令牌桶,再说一下我的应用场景,同样,画个图吧:
大致流程如上图所致,具体的过程更为复杂一些。
应用场景:
奇怪的现象是,当server-phone旋转后,偶现client端屏幕画面卡死现象。
案情侦破
猜测可能的原因:
- client 解码模块出现异常
- server 编码模块出现异常
- server 没有收到client的request
| 令牌数量 | VideoSource帧 | 用于编码的帧 | 发送出去帧 |
|---|---|---|---|
| request | input | drawing | output |
逻辑是这样的:
收到令牌: request++
|
|
收到Input(且 request大于0时):request--, drawing++
|
|
监听到encoder的output: drawing++
理论上
request = drawing = output
input 会由于没有request的情况被丢弃
从 VideoEncoder 收到图像帧到编码完成,输出适用于在网络上传输的 H.264 data 是一个耗时过程。
当屏幕旋转时,由于 ***VideoEncoder*** 会被销毁,然后再创建。
当旋转屏幕时
有drawing未被output --> 丢帧
丢帧 --> client收不到数据
client收不到数据 --> 不再产生令牌request
不再产生令牌request --> server收不到request
server收不到request --> 不再进行drawing
所以解决办法就是,重置Encoder时,要重新计算request:
reqeust = request + drawing;
drawing = 0;
案件总结
要谨慎小心对待每一个异步过程。