1.AudioTrack::play()

Frameworks/base/media/java/android/media/AudioTrack.java

public void play()

throws IllegalStateException {

if (mState != STATE_INITIALIZED) {

throw new IllegalStateException("play() called on uninitializedAudioTrack.");

}

synchronized(mPlayStateLock) {

native_start();

mPlayState = PLAYSTATE_PLAYING;

}

}

2.android_media_AudioTrack_start()

frameworks/base/core/jni/android_media_AudioTrack.cpp

static void

android_media_AudioTrack_start(JNIEnv*env, jobject thiz)

{

sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);

//这儿lpTrack是保存在javaenv中本地AudioTrack对象

//这个对象的mAudioTrack成员变量指向一个BpAudioTrack(BpBinder)对象

if (lpTrack == NULL) {

jniThrowException(env,"java/lang/IllegalStateException",

"Unable to retrieve AudioTrackpointer for start()");

return;

}

lpTrack->start();

}

3.AudioTrack::start()

Frameworks/av/media/libmedia/AudioTrack.cpp

voidAudioTrack::start()

{

sp<AudioTrackThread> t =mAudioTrackThread;

ALOGV("start %p", this);

AutoMutex lock(mLock);

// acquire a strong reference on theIMemory and IAudioTrack so that they cannot be destroyed

// while we are accessing the cblk

sp<IAudioTrack> audioTrack = mAudioTrack;

// get BpAudioTrack(BpBinder)对象指针

sp<IMemory> iMem = mCblkMemory;

audio_track_cblk_t* cblk = mCblk;

if (!mActive) {

mFlushed = false;

mActive = true;

mNewPosition = cblk->server +mUpdatePeriod;

cblk->lock.lock();

cblk->bufferTimeoutMs =MAX_STARTUP_TIMEOUT_MS;

cblk->waitTimeMs = 0;

android_atomic_and(~CBLK_DISABLED,&cblk->flags);

if (t != 0) {

t->resume();

} else {

mPreviousPriority =getpriority(PRIO_PROCESS, 0);

get_sched_policy(0,&mPreviousSchedulingGroup);

androidSetThreadPriority(0,ANDROID_PRIORITY_AUDIO);

}

ALOGV("start %p before lock cblk%p", this, cblk);

status_t status = NO_ERROR;

if (!(cblk->flags &CBLK_INVALID)) {

cblk->lock.unlock();

ALOGV("mAudioTrack->start()");

status =mAudioTrack->start();

// mAudioTrack指向BpAudioTrack(BpBinder)对象

//因此这儿实际调用的是BpAudioTrack::start()

cblk->lock.lock();

if (status == DEAD_OBJECT) {

android_atomic_or(CBLK_INVALID,&cblk->flags);

}

}

if (cblk->flags & CBLK_INVALID){

audio_track_cblk_t* temp = cblk;

status = restoreTrack_l(temp, true/*fromStart*/);

cblk = temp;

}

cblk->lock.unlock();

if (status != NO_ERROR) {

ALOGV("start() failed");

mActive = false;

if (t != 0) {

t->pause();

} else {

setpriority(PRIO_PROCESS, 0,mPreviousPriority);

set_sched_policy(0,mPreviousSchedulingGroup);

}

}

}

}

4.BpAudioTrack::start()

Frameworks/av/media/libmedia/IAudioTrack.cpp

virtual status_t start()

{

Parcel data, reply;

data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());

status_t status= remote()->transact(START, data, &reply);

// remote返回 BpAudioTrack::mRemote成员变量

//这个变量指向一个BpBinder对象

//因此这儿实际调用的BpBinder::transact()

if (status == NO_ERROR) {

status = reply.readInt32();

} else {

ALOGW("start() error:%s", strerror(-status));

}

return status;

}

5.BpBinder::transact()

Frameworks/native/libs/binder/BpBinder.cpp

status_tBpBinder::transact(

uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)

{

// Once a binder has died, it will nevercome back to life.

if (mAlive) {

status_t status= IPCThreadState::self()->transact(

mHandle,code, data, reply, flags);

if (status == DEAD_OBJECT) mAlive = 0;

return status;

}

return DEAD_OBJECT;

}

6.IPCThreadState::transact()

……………………………………….

IPCThreadState::waitForResponse() -> executeCommand()

……………………………………….

7.BBinder::transact()

--status_t AudioFlinger::TrackHandle::onTransact(

uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)

{

return BnAudioTrack::onTransact(code, data, reply, flags);

}

8.BnAudioTrack::onTransact()

Frameworks/av/media/libmedia/IAudioTrack.cpp

status_tBnAudioTrack::onTransact(

uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)

{

switch (code) {

case GET_CBLK: {

CHECK_INTERFACE(IAudioTrack, data,reply);

reply->writeStrongBinder(getCblk()->asBinder());

return NO_ERROR;

} break;

case START: {

CHECK_INTERFACE(IAudioTrack, data, reply);

reply->writeInt32(start());

return NO_ERROR;

} break;

case STOP: {

CHECK_INTERFACE(IAudioTrack, data,reply);

stop();

return NO_ERROR;

} break;

case FLUSH: {

CHECK_INTERFACE(IAudioTrack, data,reply);

flush();

return NO_ERROR;

} break;

case PAUSE: {

CHECK_INTERFACE(IAudioTrack, data, reply);

pause();

return NO_ERROR;

}

case ATTACH_AUX_EFFECT: {

CHECK_INTERFACE(IAudioTrack, data,reply);

reply->writeInt32(attachAuxEffect(data.readInt32()));

return NO_ERROR;

} break;

case ALLOCATE_TIMED_BUFFER: {

CHECK_INTERFACE(IAudioTrack, data,reply);

sp<IMemory> buffer;

status_t status =allocateTimedBuffer(data.readInt32(), &buffer);

reply->writeInt32(status);

if (status == NO_ERROR) {

reply->writeStrongBinder(buffer->asBinder());

}

return NO_ERROR;

} break;

case QUEUE_TIMED_BUFFER: {

CHECK_INTERFACE(IAudioTrack, data,reply);

sp<IMemory> buffer =interface_cast<IMemory>(

data.readStrongBinder());

uint64_t pts = data.readInt64();

reply->writeInt32(queueTimedBuffer(buffer, pts));

return NO_ERROR;

} break;

case SET_MEDIA_TIME_TRANSFORM: {

CHECK_INTERFACE(IAudioTrack, data,reply);

LinearTransform xform;

xform.a_zero = data.readInt64();

xform.b_zero = data.readInt64();

xform.a_to_b_numer = data.readInt32();

xform.a_to_b_denom =data.readInt32();

int target = data.readInt32();

reply->writeInt32(setMediaTimeTransform(xform, target));

return NO_ERROR;

} break;

default:

return BBinder::onTransact(code,data, reply, flags);

}

}

9.AudioFlinger::TrackHandle::start()

Frameworks/av/services/audioflinger/AudioFlinger.cpp

status_t AudioFlinger::TrackHandle::start() {

return mTrack->start();

}

10.AudioFlinger::PlaybackThread::Track::start()

Frameworks/av/services/audioflinger/Tracks.cpp

status_tAudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event,

int triggerSession)

{

status_t status = NO_ERROR;

ALOGV("start(%d), calling pid %dsession %d",

mName,IPCThreadState::self()->getCallingPid(), mSessionId);

sp<ThreadBase> thread =mThread.promote();

if (thread != 0) {

Mutex::Autolock _l(thread->mLock);

track_state state = mState;

// here the track could be either new,or restarted

// in both cases "unstop" thetrack

if (state == PAUSED) {

mState = TrackBase::RESUMING;

ALOGV("PAUSED => RESUMING(%d) on thread %p", mName, this);

} else {

mState = TrackBase::ACTIVE;

ALOGV("? => ACTIVE (%d) onthread %p", mName, this);

}

if (!isOutputTrack() && state!= ACTIVE && state != RESUMING) {

thread->mLock.unlock();

status =AudioSystem::startOutput(thread->id(), mStreamType, mSessionId);

thread->mLock.lock();

#ifdefADD_BATTERY_DATA

// to track the speaker usage

if (status == NO_ERROR) {

addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStart);

}

#endif

}

if (status == NO_ERROR) {

PlaybackThread *playbackThread = (PlaybackThread *)thread.get();

playbackThread->addTrack_l(this);

} else {

mState = state;

triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);

}

} else {

status = BAD_VALUE;

}

return status;

}

11.AudioFlinger::PlaybackThread::addTrack_l()

Frameworks/av/services/audioflinger/Threads.cpp

status_tAudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)

{

status_t status = ALREADY_EXISTS;

// set retry count for buffer fill

track->mRetryCount =kMaxTrackStartupRetries;

if (mActiveTracks.indexOf(track) < 0) {

// the track is newly added, make sureit fills up all its

// buffers before playing. This is toensure the client will

// effectively get the latency itrequested.

track->mFillingUpStatus =Track::FS_FILLING;

track->mResetDone = false;

track->mPresentationCompleteFrames =0;

mActiveTracks.add(track);

sp<EffectChain> chain =getEffectChain_l(track->sessionId());

if (chain != 0) {

ALOGV("addTrack_l() startingtrack on chain %p for session %d", chain.get(),

track->sessionId());

chain->incActiveTrackCnt();

}

status = NO_ERROR;

}

ALOGV("mWaitWorkCV.broadcast");

mWaitWorkCV.broadcast();

return status;

}

更多相关文章

  1. adb环境变量配置
  2. android webview 添加内置对象
  3. Android全局变量
  4. 在android中创建包含对象数组对象List 的Parcelable
  5. android解析二维数组对象key:value
  6. Mac 下面,添加android adb命令(一般环境变量的添加方法)
  7. android中application 关于全局变量

随机推荐

  1. 修改Android中strings.xml文件, 动态改变
  2. 学习Android(安卓)SDK Samples之旅-conne
  3. 789高手出招,国产手机的崛起路
  4. Android内存管理哪些事
  5. Android(安卓)Studio官方文档之使用Lint
  6. Drawable的Tint变色(让Android也能有iOS那
  7. Android处理服务器Openssl生成的RSA加解
  8. android中媒体扫描服务mediaScannerServi
  9. Android各种屏幕适配原理
  10. 针对网上流传的"Android(安卓)再按一次后