AudioPlayer的处理流程

来源:互联网 发布:证件照片排版软件 编辑:程序博客网 时间:2024/05/23 11:40
首先需要注意的是,AudioPlayer处理的是已经解码后的数据。
1.创建AudioPlayer对象
(1)在 AwesomePlayer::play_l()函数中创建了AudioPlayer对象,并且在AwesomePlayer.cpp文件中,只在此函数中创建过AudioPlayer对象
    if (mAudioSource != NULL) {        if (mAudioPlayer == NULL) {            if (mAudioSink != NULL) { // 只有mAudioSink参数不为空时,才会创建AudioPlayer对象,并作为第一个参数                mAudioPlayer = new AudioPlayer(mAudioSink, this);                mAudioPlayer->setSource(mAudioSource);                mTimeSource = mAudioPlayer;                // If there was a seek request before we ever started,                // honor the request now.                // Make sure to do this before starting the audio player                // to avoid a race condition.                seekAudioIfNecessary_l();            }        }
(2)在 AwesomePlayer::play_l()函数中创建了mAudioPlayer后,调用startAudioPlayer_l执行输出数据
    status_t err = startAudioPlayer_l(            false /* sendErrorNotification */);
2. AwesomePlayer::startAudioPlayer_l
调用mAudioPlayer的start函数,开始输出数据
    // We've already started the MediaSource in order to enable    // the prefetcher to read its data.    status_t err = mAudioPlayer->start(            true /* sourceAlreadyStarted */); // sourceAlreadyStarted参数为true
3.AudioPlayer::start
(1)由于sourceAlreadyStarted参数为true,所以不会再调用mSource->start()函数

(2)读取第一段解码后的数据
    mFirstBufferResult = mSource->read(&mFirstBuffer, &options);

(3)由于mAudioSink不为空,所以会执行下面的 mAudioSink->open函数,并注册了AudioSinkCallback函数,而不会执行新建AudioTrack,即不会注册AudioCallback函数
    if (mAudioSink.get() != NULL) {        status_t err = mAudioSink->open(                mSampleRate, numChannels, AUDIO_FORMAT_PCM_16_BIT,                DEFAULT_AUDIOSINK_BUFFERCOUNT,                &AudioPlayer::AudioSinkCallback, this); // 注册的是AudioSinkCallback函数        if (err != OK) {            if (mFirstBuffer != NULL) {                mFirstBuffer->release();                mFirstBuffer = NULL;            }            if (!sourceAlreadyStarted) {                mSource->stop();            }            return err;        }        mLatencyUs = (int64_t)mAudioSink->latency() * 1000;        mFrameSize = mAudioSink->frameSize();        mAudioSink->start(); // 实际调用AudioSink的实现类AudioOutput::start(), AudioOutput::start()又调用AudioTrack::start()开始输出数据    } else {        mAudioTrack = new AudioTrack(                AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT,                (numChannels == 2)                    ? AUDIO_CHANNEL_OUT_STEREO                    : AUDIO_CHANNEL_OUT_MONO,                0, 0, &AudioCallback, this, 0); // 没有执行到新建AudioTrack函数,不会注册AudioCallback函数
4.AudioPlayer::AudioSinkCallback
在有数据到来时,循环调用此callback函数
调用fillBuffer函数进行填充数据

5.AudioPlayer::fillBuffer
(1)此函数的返回值size_done,代表已经处理的数据总大小,与传递进来的数据size(第二个参数)不一定相同

(2)获取解码后的数据
    if (mInputBuffer == NULL) {        status_t err;        if (mIsFirstBuffer) { // 第一段数据,把mFirstBuffer赋给mInputBuffer            mInputBuffer = mFirstBuffer;            mFirstBuffer = NULL;            err = mFirstBufferResult;            mIsFirstBuffer = false;        } else { // 以后直接从MediaSource的实现类中读数据            err = mSource->read(&mInputBuffer, &options);        }
(3)取得一帧数据在媒体文件中存储的时间戳mPositionTimeMediaUs
    CHECK(mInputBuffer->meta_data()->findInt64(                kKeyTime, &mPositionTimeMediaUs));
(4)计算一帧数据实际播放位置的时间戳
    mPositionTimeRealUs =        ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)            / mSampleRate;    LOGV("buffer->size() = %d, "         "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",         mInputBuffer->range_length(),         mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);    // 这两个时间戳,在AwesomePlayer::onVideoEvent()中,用于计算音视频同步的依据        int64_t realTimeUs, mediaTimeUs;        if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL            && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {            mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;        }
(5)输出解码数据并释放已经使用的mInputBuffer
    if (mInputBuffer->range_length() == 0) {        mInputBuffer->release();        mInputBuffer = NULL; // 释放mInputBuffer        continue;    }    size_t copy = size_remaining;    if (copy > mInputBuffer->range_length()) {        copy = mInputBuffer->range_length();    }    /// 把解码后的数据copy给输出buffer    memcpy((char *)data + size_done,           (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),           copy);    /// 每copy完一块数据后,重新设置剩余未copy数据的范围    mInputBuffer->set_range(mInputBuffer->range_offset() + copy,                            mInputBuffer->range_length() - copy);    size_done += copy;    size_remaining -= copy;