android audio buffer 分析

本文深入探讨了Android音频播放过程中AudioTrack和AudioFlinger之间如何通过audio buffer进行数据交换。分析了AudioFlinger创建Track时audio buffer的分配,以及AudioTrack的write过程。内存分配涉及AudioFlinger的Client、MemoryDealer和ashmem匿名共享内存机制。通过obtainBuffer和releaseBuffer实现读写同步,采用环形缓冲区设计确保高效的数据传输。
摘要由CSDN通过智能技术生成
我们知道,播放audio的时候,音频数据是从AT传送到AF的,然后AF中的audiomixer来读取PCM数据做mix
下面对这个流程做大体分析。
首先,分析一下AT和AF之间传递数据使用的内存是在哪里分配的。
AT章节里面,我们分析AudioTrack::createTrack_l函数时,有这么一段代码:
    sp<IAudioTrack> track = audioFlinger->createTrack(streamType,  //调用AF接口来在AF里面创建Track实例
                                                      sampleRate,
                                                      format == AUDIO_FORMAT_PCM_8_BIT ?
                                                              AUDIO_FORMAT_PCM_16_BIT : format,
                                                      mChannelMask,
                                                      frameCount,
                                                      &trackFlags,
                                                      sharedBuffer,
                                                      output,
                                                      tid,
                                                      &mSessionId,
                                                      mName,
                                                      mClientUid,
                                                      &status);
    sp<IMemory> iMem = track->getCblk();
    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
AT章节里,我们交代过,   cblk实际上就是指向了audio buffer.
我们是不是可以这么猜想:audioFlinger->createTrack中就完成了audio buffer的分配?
那我们看一下这个函数。
sp<IAudioTrack> AudioFlinger::createTrack(...)
{
        Mutex::Autolock _l(mLock);
        PlaybackThread *thread = checkPlaybackThread_l(output);//通过前面讲过的获得的output,来获得playbackThread
client = registerPid_l(pid);//根据AT所在的进程PID, 来为每个AT所在进程创建一个client
track = thread->createTrack_l(client, streamType, sampleRate, format,
                channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus); //在这个playbackThread里面创建Track
        trackHandle = new TrackHandle(track); //提供给AT的handle,是IAudioTrack形式的
}
这个函数里面最重要的一步就是track = thread->createTrack_l, 为每个AT在AF里面找到对应的PlaybackThread, 然后在playbackThread里面创建了Track.
继续往里跟踪。
AudioFlinger::PlaybackThread::createTrack_l
{
            track = new Track(this, client, streamType, sampleRate, format,
                    channelMask, frameCount, sharedBuffer, sessionId, uid, *flags);  //实例化一个Track
}
Track这个类,实际上继承了TrackBase这个类。
在TrackBase的构造函数AudioFlinger::ThreadBase::TrackBase::TrackBase里面,我们可以发现:
    size_t size = sizeof(audio_track_cblk_t);
    size_t bufferSize = (sharedBuffer == 0 ? roundup(frameCount) : frameCount) * mFrameSize;
    if (sharedBuffer == 0) {
        size += bufferSize;
    }
        mCblkMemory = client->heap()->allocate(size);
看到了吗?这里就是申请audio buffer的地方,并且申请的长度是 sizeof(audio_track_cblk_t)+bufferSize
这里实际上就是在需要的size基础上,多申请一块内存,用来存放 audio_track_cblk_t 这个头信息。
audio_track_cblk_t 是个啥呢?
audio_track_cblk_t的主要数据成员:
    use
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值