Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dea53040 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

Refactor PatchPanel

Major changes:

 * since PatchPanel is internal to AudioFlinger, and has the same
   lifetime period, there is no need to use reference counting;

 * setAudioPortConfig moved to AudioFlinger;

 * store Patches in std::map instead of SortedVector, and
   directly--not as pointers;

 * move {create|clear}PatchConnections into Patch class;

 * use __func__ in logging.

Test: test basic audio functionality on taimen
Change-Id: I813fd8430a0e97cd01cc74e6b3b828b10ff5acd4
parent 03625f6e
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ AudioFlinger::AudioFlinger()
      mTotalMemory(0),
      mClientSharedHeapSize(kMinimumClientSharedHeapSizeBytes),
      mGlobalEffectEnableTime(0),
      mPatchPanel(this),
      mSystemReady(false)
{
    // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
@@ -225,8 +226,6 @@ void AudioFlinger::onFirstRef()
        }
    }

    mPatchPanel = new PatchPanel(this);

    mMode = AUDIO_MODE_NORMAL;

    gAudioFlinger = this;
@@ -1928,6 +1927,28 @@ size_t AudioFlinger::getClientSharedHeapSize() const
    return mClientSharedHeapSize;
}

status_t AudioFlinger::setAudioPortConfig(const struct audio_port_config *config)
{
    ALOGV(__func__);

    audio_module_handle_t module;
    if (config->type == AUDIO_PORT_TYPE_DEVICE) {
        module = config->ext.device.hw_module;
    } else {
        module = config->ext.mix.hw_module;
    }

    Mutex::Autolock _l(mLock);
    ssize_t index = mAudioHwDevs.indexOfKey(module);
    if (index < 0) {
        ALOGW("%s() bad hw module %d", __func__, module);
        return BAD_VALUE;
    }

    AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(index);
    return audioHwDevice->hwDevice()->setAudioPortConfig(config);
}

audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId)
{
    Mutex::Autolock _l(mLock);
+2 −1
Original line number Diff line number Diff line
@@ -843,7 +843,8 @@ private:

    nsecs_t mGlobalEffectEnableTime;  // when a global effect was last enabled

    sp<PatchPanel> mPatchPanel;
    // protected by mLock
    PatchPanel mPatchPanel;
    sp<EffectsFactoryHalInterface> mEffectsFactoryHal;

    bool        mSystemReady;
+190 −287

File changed.

Preview size limit exceeded, changes collapsed.

+16 −32
Original line number Diff line number Diff line
@@ -19,13 +19,10 @@
    #error This header file should only be included from AudioFlinger.h
#endif

class PatchPanel : public RefBase {
// PatchPanel is concealed within AudioFlinger, their lifetimes are the same.
class PatchPanel {
public:

    class Patch;

    explicit PatchPanel(const sp<AudioFlinger>& audioFlinger);
    virtual ~PatchPanel();
    explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}

    /* List connected audio ports and their attributes */
    status_t listAudioPorts(unsigned int *num_ports,
@@ -45,46 +42,33 @@ public:
    status_t listAudioPatches(unsigned int *num_patches,
                                      struct audio_patch *patches);

    /* Set audio port configuration */
    status_t setAudioPortConfig(const struct audio_port_config *config);

    status_t createPatchConnections(Patch *patch,
                                    const struct audio_patch *audioPatch);
    void clearPatchConnections(Patch *patch);

private:
    class Patch {
    public:
        explicit Patch(const struct audio_patch *patch) :
            mAudioPatch(*patch), mHandle(AUDIO_PATCH_HANDLE_NONE),
            mHalHandle(AUDIO_PATCH_HANDLE_NONE), mRecordPatchHandle(AUDIO_PATCH_HANDLE_NONE),
            mPlaybackPatchHandle(AUDIO_PATCH_HANDLE_NONE) {}
        ~Patch() {}
        explicit Patch(const struct audio_patch &patch) : mAudioPatch(patch) {}

        status_t createConnections(PatchPanel *panel);
        void clearConnections(PatchPanel *panel);

        // Note that audio_patch::id is only unique within a HAL module
        struct audio_patch              mAudioPatch;
        audio_patch_handle_t            mHandle;
        // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
        audio_patch_handle_t            mHalHandle;
        audio_patch_handle_t            mHalHandle = AUDIO_PATCH_HANDLE_NONE;
        // below members are used by a software audio patch connecting a source device from a
        // given audio HW module to a sink device on an other audio HW module.
        // playback thread created by createAudioPatch() and released by clearPatchConnections() if
        // no existing playback thread can be used by the software patch
        // the objects are created by createConnections() and released by clearConnections()
        // playback thread is created if no existing playback thread can be used
        sp<PlaybackThread>              mPlaybackThread;
        // audio track created by createPatchConnections() and released by clearPatchConnections()
        sp<PlaybackThread::PatchTrack>  mPatchTrack;
        // record thread created by createAudioPatch() and released by clearPatchConnections()
        sp<RecordThread>                mRecordThread;
        // audio record created by createPatchConnections() and released by clearPatchConnections()
        sp<RecordThread::PatchRecord>   mPatchRecord;
        // handle for audio patch connecting source device to record thread input.
        // created by createPatchConnections() and released by clearPatchConnections()
        audio_patch_handle_t            mRecordPatchHandle;
        audio_patch_handle_t            mRecordPatchHandle = AUDIO_PATCH_HANDLE_NONE;
        // handle for audio patch connecting playback thread output to sink device
        // created by createPatchConnections() and released by clearPatchConnections()
        audio_patch_handle_t            mPlaybackPatchHandle;
        audio_patch_handle_t            mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;

    };

private:
    const wp<AudioFlinger>      mAudioFlinger;
    SortedVector <Patch *>      mPatches;
    AudioFlinger &mAudioFlinger;
    std::map<audio_patch_handle_t, Patch> mPatches;
};