Android 9 Audio系统笔记:AudioFlinger音频流处理流程

好久没写了,今天碰巧有个小伙伴问我关于音频流这一块的,久了还有点记不起来,我就顺便写一下,后面就不用又找一遍代码了,所谓好记性不如烂笔头。

所以,这里是关于如何从AudioTrack 写入数据到audioflinger,以及audioflinger如何写入到hal层的音频流处理流程,主要写一下audioflinger处理流程,和写一些细节。

获取音频流

1、client写入数据:

app client 通过创建AudioTrack后,在播放的时候会不断的调用audiotrack的write方法,不断的向audioflinger写数据。

//frameworks\av\media\libaudioclient\AudioTrack.cpp
ssize_t AudioTrack::write(const void* buffer, size_t userSize, bool blocking)
{
   
    if (mTransfer != TRANSFER_SYNC) {
   
        return INVALID_OPERATION;
    }

    if (isDirect()) {
   
        AutoMutex lock(mLock);
        int32_t flags = android_atomic_and(
                            ~(CBLK_UNDERRUN | CBLK_LOOP_CYCLE | CBLK_LOOP_FINAL | CBLK_BUFFER_END),
                            &mCblk->mFlags);
        if (flags & CBLK_INVALID) {
   
            return DEAD_OBJECT;
        }
    }
    if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
   
        // Sanity-check: user is most-likely passing an error code, and it would
        // make the return value ambiguous (actualSize vs error).
        ALOGE("AudioTrack::write(buffer=%p, size=%zu (%zd)", buffer, userSize, userSize);
        return BAD_VALUE;
    }
    size_t written = 0;
    Buffer audioBuffer;
    while (userSize >= mFrameSize) {
   
        audioBuffer.frameCount = userSize / mFrameSize;
        status_t err = obtainBuffer(&audioBuffer,
                blocking ? &ClientProxy::kForever : &ClientProxy::kNonBlocking);
        if (err < 0) {
   
            if (written > 0) {
   
                break;
            }
            if (err == TIMED_OUT || err == -EINTR) {
   
                err = WOULD_BLOCK;
            }
            return ssize_t(err);
        }
        size_t toWrite = audioBuffer.size;
        memcpy(audioBuffer.i8, buffer, toWrite);
        buffer = ((const char *) buffer) + toWrite;
        userSize -= toWrite;
        written += toWrite;
        releaseBuffer(&audioBuffer);
    }
    if (written > 0) {
   
        mFramesWritten += written / mFrameSize;
    }
    return written;
}

2、service端的写

作为service端,不断的接收并处理client写入的数据。

//frameworks/av/services/audioflinger/Tracks.cpp
bool AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frames)
{
   
    Buffer *pInBuffer;
    Buffer inBuffer;
    bool outputBufferFull = false;
    inBuffer.frameCount = frames;
    inBuffer.raw = data;
    //处理客户端write数据,这个就不在这里细说了,这里不打算细讲这个环形缓冲,有兴趣的可以自行阅读代码
}

AudioFlinger音频流处理

主要处理流程:
track预处理
混音处理
向HAL输出数据

bool AudioFlinger::PlaybackThread::threadLoop()
{
   
  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值