最近发现公司自研的智能车载设备上存在一个问题:手机通过蓝牙连接车机,在手机上播放音乐车机上发声然后跟车机上的导航语音播报一起混音播出的时候会出现卡顿的现象;但是在车机上播放音乐和导航混音就正常。另外需要说明的是播放音乐使用的是Music流,导航使用的是Alarm流
通过 adb shell dumpsys media.audio_flinger 工具对比查看两种场景下实时的音频流信息(截取其中一个回放线程中的音频流信息如下):
Output thread 0xe6c833c0 type 0 (MIXER):
Thread name: AudioOut_1D
I/O handle: 29
TID: 935
Standby: yes
Sample rate: 48000 Hz
HAL frame count: 1920
HAL format: 0x1 (pcm16)
HAL buffer size: 7680 bytes
Channel count: 2
Channel mask: 0x00000003 (front-left, front-right)
Processing format: 0x1 (pcm16)
Processing frame size: 4 bytes
Pending config events: none
Output device: 0x20000 (LINE)
Input device: 0 (NONE)
Audio source: 0 (default)
Normal frame count: 1920
Last write occurred (msecs): 1087537
Total writes: 4905
Delayed writes: 0
Blocked in write: no
Suspend count: 0
Sink buffer : 0xe73da000
Mixer buffer: 0xe83d8000
Effect buffer: 0xe73dc000
Fast track availMask=0xfe
Standby delay ns=3000000000
AudioStreamOut: 0xe83c82a0 flags 0x8 (DEEP_BUFFER)
Frames written: 9417600
Suspended frames: 0
Hal stream dump:
Thread throttle time (msecs): 106
AudioMixer tracks: 0x00000003
Master mono: off
FastMixer not initialized
Stream volumes in dB: 0:-11, 1:-10, 2:-10, 3:0, 4:-10, 5:-10, 6:0, 7:-10, 8:-10, 9:-96, 10:0, 11:0, 12:0
Normal mixer raw underrun counters: partial=0 empty=0
2 Tracks of which 0 are active
Name Active Client Type Fmt Chn mask Session fCount S F SRate L dB R dB Server Main buf Aux Buf Flags UndFrmCnt
1 no 3190 3 00000001 00000003 97 7088 I 0 22050 0 0 00000000 0xe73da000 0x0 0x000 0
0 no 3190 3 00000001 00000003 89 7072 P 3 44100 0 0 004FF80C 0xe73da000 0x0 0x600 1768
0 Effect Chains
进一步的简化和比较如下所示:
[En]
Further simplification and comparison can be seen as follows:
车机上播音乐和导航 不卡顿
导航语音是 AudioStreamOut: 0xea0c8150 flags 0x6 (PRIMARY|FAST)
后台音乐是 AudioStreamOut: 0xea0c82a0 flags 0x8 (DEEP_BUFFER)
在手机上播放音乐,在汽车上导航卡顿
[En]
Play music on mobile phones and navigation stutters on cars
导航语音和后台音乐都是 AudioStreamOut: 0xea0c8150 flags 0x6 (PRIMARY|FAST)
蓝牙连接上手机后Music流走的输出流通道和导航的Alarm流走的输出流通道是同一个;车机上的Music流和导航的Alarm流走的是不同的输出流通道,也即是虽然两种场景下音乐的流都是Music流但是属性是不一样的,导致了最终系统选择的输出流通道不一致。
分析蓝牙底层的服务,看看蓝牙播放音乐时构建的AudioTrack对象跟平时播放音乐的有什么不同之处
void *BtifAvrcpAudioTrackCreate(int trackFreq, int channelType)
{
LOG_VERBOSE(LOG_TAG, "%s Track.cpp: btCreateTrack freq %d channel %d ",
__func__, trackFreq, channelType);
sp track =
new android::AudioTrack(AUDIO_STREAM_MUSIC, trackFreq, AUDIO_FORMAT_PCM_16_BIT,
channelType, (size_t) 0 /*frameCount*/,
(audio_output_flags_t)AUDIO_OUTPUT_FLAG_FAST,
NULL /*callback_t*/, NULL /*void* user*/, 0 /*notificationFrames*/,
AUDIO_SESSION_ALLOCATE, android::AudioTrack::TRANSFER_SYNC);//!!!注意AUDIO_OUTPUT_FLAG_FAST属性
assert(track != NULL);
BtifAvrcpAudioTrack *trackHolder = new BtifAvrcpAudioTrack;
assert(trackHolder != NULL);
trackHolder->track = track;
if (trackHolder->track->initCheck() != 0)
{
return nullptr;
}
#if (defined(DUMP_PCM_DATA) && (DUMP_PCM_DATA == TRUE))
outputPcmSampleFile = fopen(outputFilename, "ab");
#endif
trackHolder->track->setVolume(1, 1);
return (void *)trackHolder;
}
调试的经验表明车机端音乐类应用在底层给出的属性一般是 AUDIO_OUTPUT_FLAG_DEEP_BUFFER ,这里给定的是 AUDIO_OUTPUT_FLAG_FAST,所以导致了这里的Music流走了跟Alarm流同一个输出流通道,当导航的Alarm音频流过来以后,音频路由发生了改变,先关闭了当前的输出流通道然后再开启才导致的卡顿问题,最后解决方案也很简单,将蓝牙这里的AUDIO_OUTPUT_FLAG_FAST属性修改为AUDIO_OUTPUT_FLAG_DEEP_BUFFER 属性即可,卡顿现象也随即消失。
Original: https://blog.csdn.net/downloadname/article/details/113810047
Author: 睡着的海豚
Title: 蓝牙音乐和导航语音播放混音卡顿问题
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/524791/
转载文章受原作者版权保护。转载请注明原作者出处!