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