cocos 2dx 在android 5.1.1 出现 detected illegal retrograde motion by the server

最近在使用cocos开发小游戏的时候,出现了一个BUG
现象:游戏过程中调用录音机以后,再次调用cc.SimpleAudioEngine:getInstance():playEffect 很大概率出现不能播放,android log日志如下

0-12 18:18:01.724 262-262/? I/SurfaceFlinger: FPS: 56
10-12 18:18:01.849 1138-1161/com.turing.turingwatchgame D/cocos2d-x debug info: [LUA-print] audio/enemy4.mp3
10-12 18:18:01.870 1138-1161/com.turing.turingwatchgame W/AudioTrack: dead IAudioTrack, PCM, creating a new one from start()
10-12 18:18:01.885 1138-1161/com.turing.turingwatchgame E/AudioTrack: detected illegal retrograde motion by the server: mServer advanced by -882
10-12 18:18:01.886 353-5271/? E/AudioPolicyManager: unknown stream type 13
    unknown stream type 13
    unknown stream type 13
    unknown stream type 13
    unknown stream type 13
    unknown stream type 13
    unknown stream type 13
10-12 18:18:01.887 353-5271/? E/AudioPolicyManager: unknown stream type 13
    unknown stream type 13
    unknown stream type 13
10-12 18:18:01.891 353-858/? D/audio_hw_primary: start_output_stream: enter: stream(0xb83f6cd0)usecase(0: deep-buffer-playback) devices(0x2)
10-12 18:18:01.891 1138-1161/com.turing.turingwatchgame D/cocos2d-x debug info: [LUA-print] ------lua log:ffffffffffffffffffffffffffffffffffffff 
10-12 18:18:01.891 353-858/? D/audio_hw_primary: select_devices: out_snd_device(2: speaker) in_snd_device(0: )
10-12 18:18:01.891 353-858/? D/hardware_info: hw_info_append_hw_type : device_name = speaker
10-12 18:18:01.897 353-858/? W/audio_hw_utils: audio_extn_utils_update_stream_app_type_cfg: App type could not be selected. Falling back to default
10-12 18:18:01.897 353-858/? I/audio_hw_primary: select_devices Selected apptype: 69936
10-12 18:18:01.897 353-858/? E/audio_hw_dolby: audio_extn_dolby_ds2_set_endpoint: Dolby set endpint :0x2
10-12 18:18:01.897 353-858/? D/ACDB-LOADER: ACDB -> send_audio_cal, acdb_id = 14, path =  0
    ACDB -> send_asm_topology
    ACDB -> ACDB_CMD_GET_AUDPROC_STREAM_TOPOLOGY_ID
10-12 18:18:01.898 353-858/? D/ACDB-LOADER: ACDB -> send_adm_topology
    ACDB -> ACDB_CMD_GET_AUDPROC_COMMON_TOPOLOGY_ID
    ACDB -> send_audtable
    ACDB -> ACDB_CMD_GET_AUDPROC_COMMON_TABLE
    ACDB -> AUDIO_SET_AUDPROC_CAL
    ACDB -> send_audvoltable
    ACDB -> ACDB_CMD_GET_AUDPROC_GAIN_DEP_STEP_TABLE
10-12 18:18:01.899 353-858/? D/ACDB-LOADER: ACDB -> AUDIO_SET_AUDPROC_VOL_CAL
    ACDB -> send_afe_cal
    ACDB -> ACDB_CMD_GET_AFE_COMMON_TABLE
10-12 18:18:01.899 353-858/? E/ACDB-LOADER: Error: ACDB AFE returned = -19
10-12 18:18:01.899 353-858/? D/ACDB-LOADER: ACDB -> AUDIO_SET_AFE_CAL
    ACDB -> send_hw_delay : acdb_id = 14 path = 0
10-12 18:18:01.900 353-858/? D/ACDB-LOADER: ACDB -> ACDB_AVSYNC_INFO: ACDB_CMD_GET_DEVICE_PROPERTY
10-12 18:18:01.900 353-858/? I/audio_hw_utils: audio_extn_utils_send_app_type_cfg app_type 69936, acdb_dev_id 14, sample_rate 48000
10-12 18:18:01.901 353-858/? D/audio_hw_primary: select_devices: done

分析过程:

  1. 查看报错日志出处,查询android 源码android源码搜索,最终看到代码出处:
Modulo<uint32_t> AudioTrack::updateAndGetPosition_l()
2232{
2233    // This is the sole place to read server consumed frames
2234    Modulo<uint32_t> newServer(mProxy->getPosition());
2235    const int32_t delta = (newServer - mServer).signedValue();
2236    // TODO There is controversy about whether there can be "negative jitter" in server position.
2237    //      This should be investigated further, and if possible, it should be addressed.
2238    //      A more definite failure mode is infrequent polling by client.
2239    //      One could call (void)getPosition_l() in releaseBuffer(),
2240    //      so mReleased and mPosition are always lock-step as best possible.
2241    //      That should ensure delta never goes negative for infrequent polling
2242    //      unless the server has more than 2^31 frames in its buffer,
2243    //      in which case the use of uint32_t for these counters has bigger issues.
2244    ALOGE_IF(delta < 0,
2245            "detected illegal retrograde motion by the server: mServer advanced by %d",
2246            delta);
2247    mServer = newServer;
2248    if (delta > 0) { // avoid retrograde
2249        mPosition += delta;
2250    }
2251    return mPosition;
2252}

但是为什么是负数,感觉很奇怪啊,很大一个原因就是之前的audio track对象没有释放导致的。
2. 接着就考虑在play之前调用cc.SimpleAudioEngine:getInstance():stopAllEffect()
3. 事实上调用了该方法以后,确实可用了。
后来同事说,如果出现音效需要叠加的需求,就会出问题。虽然可能性不大,但是为了更好的满足需求,还是想想其他的解决方案。最终发现cocos还有另外一个audio播放api,
ccexp.AudioEngine:play2d ,尝试了一下,也可以。( Ĭ ^ Ĭ )
这就是一个问题的完整解决过程,看似短暂,其实耗费了不少的时间,这里总结一下,防止后来人踩坑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值