audio 层次结构

1。audio源码目录的层次结构






2. 播放mp3过程

1 AudioTrack.java 构造函数 其实实现都在cpp中

    public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
            int bufferSizeInBytes, int mode, int sessionId)

---》int initResult = native_setup(new WeakReference<AudioTrack>(this),
                mStreamType, mSampleRate, mChannels, mAudioFormat,
                mNativeBufferSizeInBytes, mDataLoadMode, session);


---》frameworks/base/core/jni/android_media_AudioTrack.cpp

               android_media_AudioTrack_native_setup

                                

                                1。// create the native AudioTrack object
                                     sp<AudioTrack> lpTrack = new AudioTrack(); 创建frameworks/av/media/libmedia/AudioTrack.cpp 中的AudioTrack()。

                                2。AudioTrackJniStorage* lpJniStorage = new AudioTrackJniStorage();
                                3。lpTrack->set


2。主要分析native空间,

1。frameworks/av/media/libmedia/AudioTrack.cpp 

status_t AudioTrack::set(
        audio_stream_type_t streamType,
        uint32_t sampleRate,
        audio_format_t format,
        audio_channel_mask_t channelMask,
        int frameCount,
        audio_output_flags_t flags,
        callback_t cbf,
        void* user,
        int notificationFrames,
        const sp<IMemory>& sharedBuffer,
        bool threadCanCallJava,
        int sessionId)

         1 audio_io_handle_t output = AudioSystem::getOutput(
                                    streamType,
                                    sampleRate, format, channelMask,
                                    flags);

         2.      if (cbf != NULL) {
            mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
            mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/);
        }
        // create the IAudioTrack
        status_t status = createTrack_l(streamType,
                                      sampleRate,
                                      format,
                                      channelMask,
                                      frameCount,
                                      flags,
                                      sharedBuffer,
                                      output);

        if (status != NO_ERROR) {
            if (mAudioTrackThread != 0) {
                mAudioTrackThread->requestExit();
                mAudioTrackThread.clear();
            }
            return status;
        }


   status_t AudioTrack::createTrack_l(
        audio_stream_type_t streamType,
        uint32_t sampleRate,
        audio_format_t format,
        audio_channel_mask_t channelMask,
        int frameCount,
        audio_output_flags_t flags,
        const sp<IMemory>& sharedBuffer,
        audio_io_handle_t output)

     

                              sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
                                                      streamType,
                                                      sampleRate,
                                                      format,
                                                      channelMask,
                                                      frameCount,
                                                      trackFlags,
                                                      sharedBuffer,
                                                      output,
                                                      tid,
                                                      &mSessionId,
                                                      &status);



生产者

libstagefright mp3数据播放流程 ,会不停的调用processAudioBuffer。正常的返回情况下,不会pause(). 所以也不用resume唤醒。从log看,不会调用void AudioTrack::AudioTrackThread::resume()。

V/AudioTrack(  270): set() streamType 3 frameCount 3763 flags 0008 notificationFrames=0

frameCount:桢缓存个数。这个值是从java层传下来的,通过计算得来的。


1. AudioTrack::AudioTrackThread::threadLoop

2.bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)

每次申请的侦缓存个数是 mRemainingFrames =1881

大部分情况下:mRemainingFrames=frameCount/2


status_t err = obtainBuffer(&audioBuffer, waitCount);

mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);

3void MediaPlayerService::AudioOutput::CallbackWrapper(
        int event, void *cookie, void *info) {

       size_t actualSize = (*me->mCallback)(
                me, buffer->raw, buffer->size, me->mCallbackCookie);

4。 frameworks/av/media/libstagefright/AudioPlayer.cpp    size_t AudioPlayer::AudioSinkCallback( 
                                                                                                                MediaPlayerBase::AudioSink *audioSink,
                                                                                                               void *buffer, size_t size, void *cookie) {


5.     size_t AudioPlayer::fillBuffer(void *data, size_t size) // 把mp3中的数据放到data

6    releaseBuffer(&audioBuffer);

void AudioTrack::releaseBuffer(Buffer* audioBuffer)
{
    AutoMutex lock(mLock);
    mCblk->stepUser(audioBuffer->frameCount);// 更新写位置
    if (audioBuffer->frameCount > 0) { //如果有audioBuffer有数据
        // restart track if it was disabled by audioflinger due to previous underrun
        if (mActive && (mCblk->flags & CBLK_DISABLED_MSK)) {
            android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
            ALOGW("releaseBuffer() track %p name=%#x disabled, restarting", this, mCblk->mName);//不会打印。
            mAudioTrack->start();  
        }
    }  
}

消费者

audioflinger是消费者,process__OneTrack16BitsStereoNoResampling,实施混音。


E/AudioMixer(  268): process__OneTrack16BitsStereoNoResampling START
D/CallStack(  268): #00  pc 0002e5b8  /system/lib/libaudioflinger.so (android::AudioMixer::process__OneTrack16BitsStereoNoResampling(android::AudioMixer::state_t*, long long)+64)
D/CallStack(  268): #01  pc 00030fc0  /system/lib/libaudioflinger.so (android::AudioMixer::process(long long)+16)
D/CallStack(  268): #02  pc 0004b45c  /system/lib/libaudioflinger.so (android::FastMixer::threadLoop()+1743)
D/CallStack(  268): #03  pc 00011264  /system/lib/libutils.so (android::Thread::_threadLoop(void*)+111)


看:FastMixer::threadLoop()代码,是一个死循环,不会返回。

size_t framesReady = fastTrack->mBufferProvider->framesReady();//计算有多少祯数据已经准备好了,一般是一祯四个字节。

mixer->process(pts);混音


当pause键按下,

FastMixer::threadLoop()会落到

__futex_syscall4(coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, NULL);//睡眠过去。


int  __futex_wake_ex(volatile void *ftx, int pshared, int val)
{
    return __futex_syscall3(ftx, pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, val);
}

int  __futex_wait_ex(volatile void *ftx, int pshared, int val, const struct timespec *timeout)
{
    return __futex_syscall4(ftx, pshared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, val, timeout);
}

看看谁来唤醒他。

void AudioFlinger::MixerThread::threadLoop_write()

 3180                  ALOGE("__futex_syscall3 start");
 3181                     __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1); //唤醒
 3182                 }


V(  266:  877) thread 0x40ce2d18 type 0 TID 877 waking up
V(  266:  877) acquireWakeLock_l() AudioOut_2 status 0
V(  266:  877) anticipated start
D(  266:  877) #00  pc 00034df8  /system/lib/libaudioflinger.so (android::AudioFlinger::MixerThread::threadLoop_write()+63)
D(  266:  877) #01  pc 000416fe  /system/lib/libaudioflinger.so (android::AudioFlinger::PlaybackThread::threadLoop()+557)
D(  266:  877) #02  pc 00011264  /system/lib/libutils.so (android::Thread::_threadLoop(void*)+111)
D(  266:  877) #03  pc 00010dca  /system/lib/libutils.so
D(  266:  877) #04  pc 0000e4b8  /system/lib/libc.so (__thread_entry+72)
D(  266:  877) #05  pc 0000dba4  /system/lib/libc.so (pthread_create+160)
E(  266:  877) __futex_syscall3 start


混音好的数据放到设备

frameworks/av/services/audioflinger/FastMixer.cpp :  bool FastMixer::threadLoop()

ssize_t framesWritten = outputSink->write(mixBuffer, frameCount); //frameCount=512


/alsa_sound/audio_hw_hal.cpp

static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
                         size_t bytes)
{
    struct qcom_stream_out *out =
        reinterpret_cast<struct qcom_stream_out *>(stream);
    return out->qcom_out->write(buffer, bytes);
}


ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)

write:: buffer 0x4210de50, bytes 2048








void AudioFlinger::PlaybackThread::threadLoop_write()

        framesWritten = mNormalSink->write(mMixBuffer, count); //count=1024


mOutputSink = new AudioStreamOutSink(output->stream);



ssize_t AudioStreamOutSink::write(const void *buffer, size_t count)
{                             
    if (!mNegotiated) {
        return NEGOTIATE;
    }
    ALOG_ASSERT(mFormat != Format_Invalid);
    ssize_t ret = mStream->write(mStream, buffer, count << mBitShift);
    if (ret > 0) {
        ret >>= mBitShift;
        mFramesWritten += ret;
    } else {
        // FIXME verify HAL implementations are returning the correct error codes e.g. WOULD_BLOCK
    }
    return ret;
}   

























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值