我正在开发2个需要协同工作的VoIP应用程序; 一个是软电话应用程序(App A),它使用各种音频模式,如RINGTONE,IN_COMMUNICATION等.另一个应用程序(App B)需要音频模式NORMAL.我尝试确保彼此玩得很好,所以当软电话App A完成一个电话时,它会将音频模式恢复为NORMAL.同样,如果App B需要在App A正在做的事情中间运行,它会保存它找到的音频模式并在完成后恢复.
例如,对于入站呼叫,App A可能会更改音频模式,如下所示:
如果App B在连接呼叫时需要做某事(上面的步骤2),它会
两个应用程序都使用其应用程序上下文获取Android AudioManager.
我遇到的问题是,一旦App B完成上述步骤,App A就会在呼叫终止后尝试将音频模式恢复为NORMAL.
myAudioManagerReference.setMode(AudioManager.MODE_NORMAL);
if (myAudioManagerReference.getMode() != AudioManager.MODE_NORMAL)
Log.w(CLASSTAG, "failure to set audio mode to MODE_NORMAL);
Run Code Online (Sandbox Code Playgroud)
我的App B是否可以对AudioManager模式进行某种锁定?或者更改了App A的权限,使其无法将模式更改回NORMAL?我发现一旦我退出App B,App A就可以成功地将模式更改为NORMAL.
我关心的是自适应抖动缓冲器的设计,该缓冲器随着抖动计算的增加和减少而增加和减少容量。
我认为没有理由对延迟或容量进行任何调整,除非存在缓冲区不足,然后可能会出现超出容量的传入数据包突发(假设缓冲区容量首先等于缓冲区深度/延迟)。例如,如果我接收 20 毫秒的数据包,我可能会实现一个 100 毫秒深的缓冲区,因此具有容纳 5 个数据包的容量。如果数据包之间经过 160 毫秒,那么我可能会期望看到几乎同时有多达 8 个数据包进入。此时我有两个选择:
假设选择 2,并且网络状况改善并且数据包传送再次变得正常(抖动值下降)。怎么办?再说一遍,我想我有两个选择:
使用自适应缓冲区,我认为我应该做出选择 4,但这似乎并不正确,因为它要求我人为/任意地丢弃在遇到较大抖动时选择选择 2 时专门保存的音频数据包。第一名。
在我看来,正确的做法是首先采取选择#1来维持延迟,同时丢弃数据包(如有必要),这些数据包由于抖动增加而延迟交付。
类似的情况可能是,在 160 毫秒的间隙后,我没有收到突发的 8 个数据包,而是只收到 5 个数据包(可能刚刚丢失了 3 个数据包)。在这种情况下,增加缓冲区容量并没有多大好处,但确实有助于减少以后溢出的可能性。但是,如果溢出的想法是要避免的(从网络端),那么我首先会将缓冲区容量设置为大于配置的“深度/延迟”的固定量。换句话说,如果溢出不是由于本地应用程序未能及时将数据包从缓冲区中取出而引起的,那么溢出只会因两个原因而发生:要么发送方撒谎并以比约定的速率更快的速率发送数据包(或从未来发送数据包),或者,数据包突发之间存在超出我的缓冲区深度的间隙。
显然,“自适应”缓冲区的全部意义在于识别后一种情况,增加缓冲区容量,并避免丢失任何数据包。但这让我直接面对上述问题:当网络抖动消除时,我如何“适应”回到理想设置,同时仍然执行相同的“不丢包”理念?
想法?
我正在开发一个应用程序,它将通过UDP从另一个本地服务接收RTP数据包.在协议的早期,我收到一条带有IP地址的消息,我将从中接收这些RTP数据包,但端口号将被赋予为0(零)...我将使用短暂的打开我的UDP套接字港口.我对给定消息的响应将包含我打开的实际端口,以便发送方可以知道在哪里引导数据包.
我的网络库是套接字的实现boost::asio
.我在哪里可以找到关于如何在不指定非零端口的情况下打开这种套接字的明确信息,即使用临时端口?在boost文档中搜索"ephemeral"并没有给我提供网络结果.
当然,我很乐意看到一个实际的例子,但找到好的文档也可以.
谢谢.