2024年1月2日发(作者:)
sp
} ... cblk = recordTrack->getCblk(); buffers = recordTrack->getBuffers(); // return handle to client recordHandle = new RecordHandle(recordTrack);Exit: *status = lStatus; return recordHandle;}重点分析:
if (event == AudioSystem::SYNC_EVENT_NONE) { recordTrack->clearSyncStartEvent(); } else if (event != AudioSystem::SYNC_EVENT_SAME) { recordTrack->mSyncStartEvent = mAudioFlinger->createSyncEvent(event, triggerSession, recordTrack->sessionId(), syncStartEventCallback, recordTrack); // Sync event can be cancelled by the trigger session if the track is not in a // compatible state in which case we start record immediately if (recordTrack->mSyncStartEvent->isCancelled()) { recordTrack->clearSyncStartEvent(); } else { // do not wait for the event for more than AudioSystem::kSyncRecordStartTimeOutMs recordTrack->mFramesToDrop = - ((AudioSystem::kSyncRecordStartTimeOutMs * recordTrack->mSampleRate) / 1000); } } { // This section is a rendezvous between binder thread executing start() and RecordThread AutoMutex lock(mLock); if (f(recordTrack) >= 0) { if (recordTrack->mState == TrackBase::PAUSING) { ALOGV("active record track PAUSING -> ACTIVE"); recordTrack->mState = TrackBase::ACTIVE; } else { ALOGV("active record track state %d", recordTrack->mState); } return status; } // TODO consider other ways of handling this, such as changing the state to :STARTING and // adding the track to mActiveTracks after returning from AudioSystem::startInput(), // or using a separate command thread recordTrack->mState = TrackBase::STARTING_1; (recordTrack); mActiveTracksGen++; status_t status = NO_ERROR; if (recordTrack->isExternalTrack()) { (); status = AudioSystem::startInput(mId, (audio_session_t)recordTrack->sessionId()); (); // FIXME should verify that recordTrack is still in mActiveTracks if (status != NO_ERROR) { (recordTrack); mActiveTracksGen++; recordTrack->clearSyncStartEvent(); ALOGV("RecordThread::start error %d", status); return status; } } // Catch up with current buffer indices if thread is already running. // This is what makes a new client discard all buffered data. If the track's mRsmpInFront // was initialized to some value closer to the thread's mRsmpInFront, then the track could // see previously buffered data before it called start(), but with greater risk of overrun. recordTrack->mRsmpInFront = mRsmpInRear; recordTrack->mRsmpInUnrel = 0; // FIXME why reset? if (recordTrack->mResampler != NULL) { recordTrack->mResampler->reset(); } recordTrack->mState = TrackBase::STARTING_2; // signal thread to start
{ ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d", ioHandle, (), IPCThreadState::self()->getCallingPid()); // check calling permissions if (!settingsAllowed()) { return PERMISSION_DENIED; } // AUDIO_IO_HANDLE_NONE means the parameters are global to the audio hardware interface if (ioHandle == AUDIO_IO_HANDLE_NONE) { Mutex::Autolock _l(mLock); status_t final_result = NO_ERROR; { AutoMutex lock(mHardwareLock); mHardwareStatus = AUDIO_HW_SET_PARAMETER; for (size_t i = 0; i < (); i++) { audio_hw_device_t *dev = t(i)->hwDevice(); status_t result = dev->set_parameters(dev, ()); final_result = result ?: final_result; } mHardwareStatus = AUDIO_HW_IDLE; } // disable AEC and NS if the device is a BT SCO headset supporting those pre processings AudioParameter param = AudioParameter(keyValuePairs); String8 value; if ((String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) { bool btNrecIsOff = (value == AUDIO_PARAMETER_VALUE_OFF); if (mBtNrecIsOff != btNrecIsOff) { for (size_t i = 0; i < (); i++) { sp


发布评论