织梦CMS - 轻松建站从此开始!

罗索

当前位置: 主页>嵌入式开发>Android>

Stagefright AudioPlayer 流程

jackyhwei 发布于 2011-11-03 09:10 点击:次 
Stagefright中关于audio的部分由AudioPlayer处理,输出使用AudioSink 或AudioTrack。
TAG:

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

  1. status_t AwesomePlayer::play_l() { 
  2.     ... 
  3.     if (mAudioSource != NULL) { 
  4.         if (mAudioPlayer == NULL) { 
  5.             if (mAudioSink != NULL) { 
  6.                 mAudioPlayer = new AudioPlayer(mAudioSink, this); 
  7.                 mAudioPlayer->setSource(mAudioSource); 
  8.        ... 
  9.     } 
  10.     ... 

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]传递给它

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

  1. status_t AudioPlayer::start(bool sourceAlreadyStarted) { 
  2.     ... 
  3.     if (mAudioSink.get() != NULL) { 
  4.         status_t err = mAudioSink->open( 
  5.             mSampleRate, numChannels, AudioSystem::PCM_16_BIT, 
  6.             DEFAULT_AUDIOSINK_BUFFERCOUNT, 
  7.             &AudioPlayer::AudioSinkCallback, this); 
  8.     ... 
  9.     mAudioSink->start(); 
  10.     ... 

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

  1. size_t AudioPlayer::AudioSinkCallback( 
  2.         MediaPlayerBase::AudioSink *audioSink, 
  3.         void *buffer, size_t size, void *cookie) { 
  4.     AudioPlayer *me = (AudioPlayer *)cookie; 
  5.   
  6.     LOGI("[%s:%d]_____ enter AudioPlayer::AudioSinkCallback size = %d"
  7. , __FUNCTION__, __LINE__, size); 
  8.     
  9.     return me->fillBuffer(buffer, size); 
  10.  
  11. void AudioPlayer::AudioCallback(int event, void *info) { 
  12.     if (event != AudioTrack::EVENT_MORE_DATA) { 
  13.         return
  14.     } 
  15.     AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 
  16.     size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); 
  17.     buffer->size = numBytesWritten; 
  18.  
  19. size_t AudioPlayer::fillBuffer(void *data, size_t size) { 
  20.     ... 
  21.     size_t size_done = 0; 
  22.     size_t size_remaining = size; 
  23.     while (size_remaining > 0) { 
  24.         ... 
  25.         err = mSource->read(&mInputBuffer, &options); 
  26.         ... 
  27.         memcpy((char *)data + size_done, 
  28.               (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 
  29.               copy); 
  30.   mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 
  31.                           mInputBuffer->range_length() - copy); 
  32.         size_done += copy; 
  33.         size_remaining -= copy; 
  34.         ... 
  35.     } 
  36.     ... 

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

总流程如下

  1. AudioSink 
  2.     | 
  3.     +- AudioPlayer#AudioSinkCallback 
  4.                         | 
  5.                         +- AudioDecoder#read 
  6.                                          | 
  7.                                          +- Extractor::MediaSource#read 

参考

(shaobin0604)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201111/15264.html]
本文出处:cnblogs.com/shaobin0604 作者:shaobin0604
顶一下
(2)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容