代码改变世界

Stagefright AudioPlayer 流程

2011-10-21 10:26  shaobin0604  阅读(869)  评论(0编辑  收藏  举报

 

Stagefright中关于audio的部分由AudioPlayer处理,输出使用AudioSink 或AudioTrack。

AwesomePlayer在initAudioDecoder方法中建立audio decoder

status_t AwesomePlayer::initAudioDecoder() {
    ...
    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
        mAudioSource = mAudioTrack;
    } else {
        mAudioSource = OMXCodec::Create(
                mClient.interface(), mAudioTrack->getFormat(),
                false, // createEncoder
                mAudioTrack);
    }    
    ...
}

当调用play_l方法的时候建立AudioPlayer,并把Audio Decoder[mAudioSource]传递给它

status_t AwesomePlayer::play_l() {
    ...
    if (mAudioSource != NULL) {
        if (mAudioPlayer == NULL) {
            if (mAudioSink != NULL) {
                mAudioPlayer = new AudioPlayer(mAudioSink, this);
                mAudioPlayer->setSource(mAudioSource);
        ...
    }
    ...
}

AudioPlayer在调用start方法的时候会开启audioSink,并传递回调函数AudioSinkCallback

status_t AudioPlayer::start(bool sourceAlreadyStarted) {
    ...
    if (mAudioSink.get() != NULL) {
        status_t err = mAudioSink->open(
            mSampleRate, numChannels, AudioSystem::PCM_16_BIT,
            DEFAULT_AUDIOSINK_BUFFERCOUNT,
            &AudioPlayer::AudioSinkCallback, this);
    ...
    mAudioSink->start();
    ...
}

之后AudioSink会在需要Sample数据的时候回调AudioSinkCallback,要求将size大小Sample数据填充到buffer。这里调用fillBuffer函数从audio decoder读取解码后的Sample数据。

size_t AudioPlayer::AudioSinkCallback(
        MediaPlayerBase::AudioSink *audioSink,
        void *buffer, size_t size, void *cookie) {
    AudioPlayer *me = (AudioPlayer *)cookie;
 
    LOGI("[%s:%d]_____ enter AudioPlayer::AudioSinkCallback size = %d", __FUNCTION__, __LINE__, size);
    
    return me->fillBuffer(buffer, size);
}
 
void AudioPlayer::AudioCallback(int event, void *info) {
    if (event != AudioTrack::EVENT_MORE_DATA) {
        return;
    }
 
    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
    size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size);
 
    buffer->size = numBytesWritten;
}
 
 
size_t AudioPlayer::fillBuffer(void *data, size_t size) {
    ...
    size_t size_done = 0;
    size_t size_remaining = size;
    while (size_remaining > 0) {
        ...
        err = mSource->read(&mInputBuffer, &options);
        ...
        memcpy((char *)data + size_done,
              (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
              copy);
 
        mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
                               mInputBuffer->range_length() - copy);
 
        size_done += copy;
        size_remaining -= copy;
        ...
    }
    ...
}

这里的mSource实际上是decoder,其read方法会调用mAudioTrack的read方法获取DataSource的未解码数据,然后解码,返回解码后的数据。

总流程如下

AudioSink
    |
    +- AudioPlayer#AudioSinkCallback
                        |
                        +- AudioDecoder#read
                                         |
                                         +- Extractor::MediaSource#read

参考