1。audio源码目录的层次结构
2. 播放mp3过程
1 AudioTrack.java 构造函数 其实实现都在cpp中
public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes, int mode, int sessionId)
---》int initResult = native_setup(new WeakReference<AudioTrack>(this),
mStreamType, mSampleRate, mChannels, mAudioFormat,
mNativeBufferSizeInBytes, mDataLoadMode, session);
---》frameworks/base/core/jni/android_media_AudioTrack.cpp
android_media_AudioTrack_native_setup
1。// create the native AudioTrack object
sp<AudioTrack> lpTrack = new AudioTrack(); 创建frameworks/av/media/libmedia/AudioTrack.cpp 中的AudioTrack()。
2。AudioTrackJniStorage* lpJniStorage = new AudioTrackJniStorage();
3。lpTrack->set
2。主要分析native空间,
1。frameworks/av/media/libmedia/AudioTrack.cpp
status_t AudioTrack::set(
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
int frameCount,
audio_output_flags_t flags,
callback_t cbf,
void* user,
int notificationFrames,
const sp<IMemory>& sharedBuffer,
bool threadCanCallJava,
int sessionId)
1 audio_io_handle_t output = AudioSystem::getOutput(
streamType,
sampleRate, format, channelMask,
flags);
2. if (cbf != NULL) {
mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/);
}
// create the IAudioTrack
status_t status = createTrack_l(streamType,
sampleRate,
format,
channelMask,
frameCount,
flags,
sharedBuffer,
output);
if (status != NO_ERROR) {
if (mAudioTrackThread != 0) {
mAudioTrackThread->requestExit();
mAudioTrackThread.clear();
}
return status;
}
status_t AudioTrack::createTrack_l(
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
int frameCount,
audio_output_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output)
sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
streamType,
sampleRate,
format,
channelMask,
frameCount,
trackFlags,
sharedBuffer,
output,
tid,
&mSessionId,
&status);
生产者
libstagefright mp3数据播放流程 ,会不停的调用processAudioBuffer。正常的返回情况下,不会pause(). 所以也不用resume唤醒。从log看,不会调用void AudioTrack::AudioTrackThread::resume()。
V/AudioTrack( 270): set() streamType 3 frameCount 3763 flags 0008 notificationFrames=0
frameCount:桢缓存个数。这个值是从java层传下来的,通过计算得来的。
1. AudioTrack::AudioTrackThread::threadLoop
2.bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
每次申请的侦缓存个数是 mRemainingFrames =1881
大部分情况下:mRemainingFrames=frameCount/2
status_t err = obtainBuffer(&audioBuffer, waitCount);
mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
3void MediaPlayerService::AudioOutput::CallbackWrapper(
int event, void *cookie, void *info) {
size_t actualSize = (*me->mCallback)(
me, buffer->raw, buffer->size, me->mCallbackCookie);
4。 frameworks/av/media/libstagefright/AudioPlayer.cpp size_t AudioPlayer::AudioSinkCallback(
MediaPlayerBase::AudioSink *audioSink,
void *buffer, size_t size, void *cookie) {
5. size_t AudioPlayer::fillBuffer(void *data, size_t size) // 把mp3中的数据放到data
6 releaseBuffer(&audioBuffer);
void AudioTrack::releaseBuffer(Buffer* audioBuffer)
{
AutoMutex lock(mLock);
mCblk->stepUser(audioBuffer->frameCount);// 更新写位置
if (audioBuffer->frameCount > 0) { //如果有audioBuffer有数据
// restart track if it was disabled by audioflinger due to previous underrun
if (mActive && (mCblk->flags & CBLK_DISABLED_MSK)) {
android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
ALOGW("releaseBuffer() track %p name=%#x disabled, restarting", this, mCblk->mName);//不会打印。
mAudioTrack->start();
}
}
}
消费者
audioflinger是消费者,process__OneTrack16BitsStereoNoResampling,实施混音。
E/AudioMixer( 268): process__OneTrack16BitsStereoNoResampling START
D/CallStack( 268): #00 pc 0002e5b8 /system/lib/libaudioflinger.so (android::AudioMixer::process__OneTrack16BitsStereoNoResampling(android::AudioMixer::state_t*, long long)+64)
D/CallStack( 268): #01 pc 00030fc0 /system/lib/libaudioflinger.so (android::AudioMixer::process(long long)+16)
D/CallStack( 268): #02 pc 0004b45c /system/lib/libaudioflinger.so (android::FastMixer::threadLoop()+1743)
D/CallStack( 268): #03 pc 00011264 /system/lib/libutils.so (android::Thread::_threadLoop(void*)+111)
看:FastMixer::threadLoop()代码,是一个死循环,不会返回。
size_t framesReady = fastTrack->mBufferProvider->framesReady();//计算有多少祯数据已经准备好了,一般是一祯四个字节。
mixer->process(pts);混音
当pause键按下,
FastMixer::threadLoop()会落到
__futex_syscall4(coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, NULL);//睡眠过去。
int __futex_wake_ex(volatile void *ftx, int pshared, int val)
{
return __futex_syscall3(ftx, pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, val);
}
int __futex_wait_ex(volatile void *ftx, int pshared, int val, const struct timespec *timeout)
{
return __futex_syscall4(ftx, pshared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, val, timeout);
}
看看谁来唤醒他。
void AudioFlinger::MixerThread::threadLoop_write()
3180 ALOGE("__futex_syscall3 start");
3181 __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1); //唤醒
3182 }
V( 266: 877) thread 0x40ce2d18 type 0 TID 877 waking up
V( 266: 877) acquireWakeLock_l() AudioOut_2 status 0
V( 266: 877) anticipated start
D( 266: 877) #00 pc 00034df8 /system/lib/libaudioflinger.so (android::AudioFlinger::MixerThread::threadLoop_write()+63)
D( 266: 877) #01 pc 000416fe /system/lib/libaudioflinger.so (android::AudioFlinger::PlaybackThread::threadLoop()+557)
D( 266: 877) #02 pc 00011264 /system/lib/libutils.so (android::Thread::_threadLoop(void*)+111)
D( 266: 877) #03 pc 00010dca /system/lib/libutils.so
D( 266: 877) #04 pc 0000e4b8 /system/lib/libc.so (__thread_entry+72)
D( 266: 877) #05 pc 0000dba4 /system/lib/libc.so (pthread_create+160)
E( 266: 877) __futex_syscall3 start
混音好的数据放到设备
frameworks/av/services/audioflinger/FastMixer.cpp : bool FastMixer::threadLoop()
ssize_t framesWritten = outputSink->write(mixBuffer, frameCount); //frameCount=512
/alsa_sound/audio_hw_hal.cpp
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
size_t bytes)
{
struct qcom_stream_out *out =
reinterpret_cast<struct qcom_stream_out *>(stream);
return out->qcom_out->write(buffer, bytes);
}
write:: buffer 0x4210de50, bytes 2048
void AudioFlinger::PlaybackThread::threadLoop_write()
framesWritten = mNormalSink->write(mMixBuffer, count); //count=1024
mOutputSink = new AudioStreamOutSink(output->stream);
ssize_t AudioStreamOutSink::write(const void *buffer, size_t count)
{
if (!mNegotiated) {
return NEGOTIATE;
}
ALOG_ASSERT(mFormat != Format_Invalid);
ssize_t ret = mStream->write(mStream, buffer, count << mBitShift);
if (ret > 0) {
ret >>= mBitShift;
mFramesWritten += ret;
} else {
// FIXME verify HAL implementations are returning the correct error codes e.g. WOULD_BLOCK
}
return ret;
}