Loading services/audioflinger/PatchPanel.cpp +38 −1 Original line number Diff line number Diff line Loading @@ -475,11 +475,48 @@ void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel) mPlayback.closeConnections(panel); } status_t AudioFlinger::PatchPanel::Patch::getLatencyMs(double *latencyMs) const { if (!isSoftware()) return INVALID_OPERATION; auto recordTrack = mRecord.const_track(); if (recordTrack.get() == nullptr) return INVALID_OPERATION; auto playbackTrack = mPlayback.const_track(); if (playbackTrack.get() == nullptr) return INVALID_OPERATION; // Latency information for tracks may be called without obtaining // the underlying thread lock. // // We use record server latency + playback track latency (generally smaller than the // reverse due to internal biases). // // TODO: is this stable enough? Consider a PatchTrack synchronized version of this. double recordServerLatencyMs; if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) != OK) return INVALID_OPERATION; double playbackTrackLatencyMs; if (playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) != OK) return INVALID_OPERATION; *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs; return OK; } String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle) { String8 result; result.appendFormat("Patch %d: thread %p => thread %p\n", // TODO: Consider table dump form for patches, just like tracks. result.appendFormat("Patch %d: thread %p => thread %p", myHandle, mRecord.thread().get(), mPlayback.thread().get()); // add latency if it exists double latencyMs; if (getLatencyMs(&latencyMs) == OK) { result.appendFormat(" latency: %.2lf", latencyMs); } result.append("\n"); return result; } Loading services/audioflinger/PatchPanel.h +4 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ private: audio_patch_handle_t handle() const { return mHandle; } sp<ThreadType> thread() { return mThread; } sp<TrackType> track() { return mTrack; } sp<const TrackType> const_track() const { return mTrack; } void closeConnections(PatchPanel *panel) { if (mHandle != AUDIO_PATCH_HANDLE_NONE) { Loading Loading @@ -118,6 +119,9 @@ private: return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE || mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; } // returns the latency of the patch (from record to playback). status_t getLatencyMs(double *latencyMs) const; String8 dump(audio_patch_handle_t myHandle); // Note that audio_patch::id is only unique within a HAL module Loading Loading
services/audioflinger/PatchPanel.cpp +38 −1 Original line number Diff line number Diff line Loading @@ -475,11 +475,48 @@ void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel) mPlayback.closeConnections(panel); } status_t AudioFlinger::PatchPanel::Patch::getLatencyMs(double *latencyMs) const { if (!isSoftware()) return INVALID_OPERATION; auto recordTrack = mRecord.const_track(); if (recordTrack.get() == nullptr) return INVALID_OPERATION; auto playbackTrack = mPlayback.const_track(); if (playbackTrack.get() == nullptr) return INVALID_OPERATION; // Latency information for tracks may be called without obtaining // the underlying thread lock. // // We use record server latency + playback track latency (generally smaller than the // reverse due to internal biases). // // TODO: is this stable enough? Consider a PatchTrack synchronized version of this. double recordServerLatencyMs; if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) != OK) return INVALID_OPERATION; double playbackTrackLatencyMs; if (playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) != OK) return INVALID_OPERATION; *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs; return OK; } String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle) { String8 result; result.appendFormat("Patch %d: thread %p => thread %p\n", // TODO: Consider table dump form for patches, just like tracks. result.appendFormat("Patch %d: thread %p => thread %p", myHandle, mRecord.thread().get(), mPlayback.thread().get()); // add latency if it exists double latencyMs; if (getLatencyMs(&latencyMs) == OK) { result.appendFormat(" latency: %.2lf", latencyMs); } result.append("\n"); return result; } Loading
services/audioflinger/PatchPanel.h +4 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ private: audio_patch_handle_t handle() const { return mHandle; } sp<ThreadType> thread() { return mThread; } sp<TrackType> track() { return mTrack; } sp<const TrackType> const_track() const { return mTrack; } void closeConnections(PatchPanel *panel) { if (mHandle != AUDIO_PATCH_HANDLE_NONE) { Loading Loading @@ -118,6 +119,9 @@ private: return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE || mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; } // returns the latency of the patch (from record to playback). status_t getLatencyMs(double *latencyMs) const; String8 dump(audio_patch_handle_t myHandle); // Note that audio_patch::id is only unique within a HAL module Loading