AudioPlayer的处理流程

首先需要注意的是,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参数为true3.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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值