http://blog.csdn.net/ameyume/article/details/7320470
首先需要注意的是,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();
- }
- }
- status_t err = startAudioPlayer_l(
- false /* sendErrorNotification */);
调用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
(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函数
在有数据到来时,循环调用此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);
- }
- CHECK(mInputBuffer->meta_data()->findInt64(
- kKeyTime, &mPositionTimeMediaUs));
- 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;
- }
- 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;