mirror of https://github.com/jetkvm/kvm.git
[WIP] Cleanup, Refactor: Reduce PR complexity, common IPC layer
This commit is contained in:
parent
f71d18039b
commit
2bc7e50391
|
@ -234,7 +234,7 @@ func (abm *AdaptiveBufferManager) adaptationLoop() {
|
||||||
// The algorithm runs periodically and only applies changes when the adaptation interval
|
// The algorithm runs periodically and only applies changes when the adaptation interval
|
||||||
// has elapsed, preventing excessive adjustments that could destabilize the audio pipeline.
|
// has elapsed, preventing excessive adjustments that could destabilize the audio pipeline.
|
||||||
func (abm *AdaptiveBufferManager) adaptBufferSizes() {
|
func (abm *AdaptiveBufferManager) adaptBufferSizes() {
|
||||||
// Use fixed system metrics since monitoring is simplified
|
// Use fixed system metrics for stability
|
||||||
systemCPU := 50.0 // Assume moderate CPU usage
|
systemCPU := 50.0 // Assume moderate CPU usage
|
||||||
systemMemory := 60.0 // Assume moderate memory usage
|
systemMemory := 60.0 // Assume moderate memory usage
|
||||||
|
|
||||||
|
|
|
@ -1046,7 +1046,7 @@ func updateOpusEncoderParams(bitrate, complexity, vbr, vbrConstraint, signalType
|
||||||
// Buffer pool for reusing buffers in CGO functions
|
// Buffer pool for reusing buffers in CGO functions
|
||||||
var (
|
var (
|
||||||
// Using SizedBufferPool for better memory management
|
// Using SizedBufferPool for better memory management
|
||||||
// Track buffer pool usage for monitoring
|
// Track buffer pool usage
|
||||||
cgoBufferPoolGets atomic.Int64
|
cgoBufferPoolGets atomic.Int64
|
||||||
cgoBufferPoolPuts atomic.Int64
|
cgoBufferPoolPuts atomic.Int64
|
||||||
// Batch processing statistics - only enabled in debug builds
|
// Batch processing statistics - only enabled in debug builds
|
||||||
|
|
|
@ -505,11 +505,9 @@ func DefaultAudioConfig() *AudioConfigConstants {
|
||||||
AdaptiveMaxBufferSize: 1024, // Much higher maximum for quality changes
|
AdaptiveMaxBufferSize: 1024, // Much higher maximum for quality changes
|
||||||
AdaptiveDefaultBufferSize: 512, // Higher default for stability during bursts
|
AdaptiveDefaultBufferSize: 512, // Higher default for stability during bursts
|
||||||
|
|
||||||
// Adaptive Optimizer Configuration - Faster response
|
|
||||||
CooldownPeriod: 15 * time.Second, // Reduced cooldown period
|
CooldownPeriod: 15 * time.Second, // Reduced cooldown period
|
||||||
RollbackThreshold: 200 * time.Millisecond, // Lower rollback threshold
|
RollbackThreshold: 200 * time.Millisecond, // Lower rollback threshold
|
||||||
|
|
||||||
// Latency Monitor Configuration - More aggressive monitoring
|
|
||||||
MaxLatencyThreshold: 150 * time.Millisecond, // Lower max latency threshold
|
MaxLatencyThreshold: 150 * time.Millisecond, // Lower max latency threshold
|
||||||
JitterThreshold: 15 * time.Millisecond, // Reduced jitter threshold
|
JitterThreshold: 15 * time.Millisecond, // Reduced jitter threshold
|
||||||
LatencyOptimizationInterval: 3 * time.Second, // More frequent optimization
|
LatencyOptimizationInterval: 3 * time.Second, // More frequent optimization
|
||||||
|
@ -638,8 +636,6 @@ func DefaultAudioConfig() *AudioConfigConstants {
|
||||||
MinFrameSize: 1, // 1 byte minimum frame size (allow small frames)
|
MinFrameSize: 1, // 1 byte minimum frame size (allow small frames)
|
||||||
FrameSizeTolerance: 512, // 512 bytes frame size tolerance
|
FrameSizeTolerance: 512, // 512 bytes frame size tolerance
|
||||||
|
|
||||||
// Removed device health monitoring configuration - functionality not used
|
|
||||||
|
|
||||||
// Latency Histogram Bucket Configuration
|
// Latency Histogram Bucket Configuration
|
||||||
LatencyBucket10ms: 10 * time.Millisecond, // 10ms latency bucket
|
LatencyBucket10ms: 10 * time.Millisecond, // 10ms latency bucket
|
||||||
LatencyBucket25ms: 25 * time.Millisecond, // 25ms latency bucket
|
LatencyBucket25ms: 25 * time.Millisecond, // 25ms latency bucket
|
||||||
|
|
|
@ -406,8 +406,7 @@ func UpdateSocketBufferMetrics(component, bufferType string, size, utilization f
|
||||||
atomic.StoreInt64(&lastMetricsUpdate, time.Now().Unix())
|
atomic.StoreInt64(&lastMetricsUpdate, time.Now().Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateDeviceHealthMetrics - Device health monitoring functionality has been removed
|
// UpdateDeviceHealthMetrics - Placeholder for future device health metrics
|
||||||
// This function is no longer used as device health monitoring is not implemented
|
|
||||||
|
|
||||||
// UpdateMemoryMetrics updates memory metrics
|
// UpdateMemoryMetrics updates memory metrics
|
||||||
func UpdateMemoryMetrics() {
|
func UpdateMemoryMetrics() {
|
||||||
|
|
|
@ -132,6 +132,42 @@ func (mp *GenericMessagePool) GetStats() (hitCount, missCount int64, hitRate flo
|
||||||
return hits, misses, hitRate
|
return hits, misses, hitRate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
|
||||||
|
// EncodeMessageHeader encodes a message header into a byte slice
|
||||||
|
func EncodeMessageHeader(magic uint32, msgType uint8, length uint32, timestamp int64) []byte {
|
||||||
|
header := make([]byte, 17)
|
||||||
|
binary.LittleEndian.PutUint32(header[0:4], magic)
|
||||||
|
header[4] = msgType
|
||||||
|
binary.LittleEndian.PutUint32(header[5:9], length)
|
||||||
|
binary.LittleEndian.PutUint64(header[9:17], uint64(timestamp))
|
||||||
|
return header
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeAudioConfig encodes basic audio configuration to binary format
|
||||||
|
func EncodeAudioConfig(sampleRate, channels, frameSize int) []byte {
|
||||||
|
data := make([]byte, 12) // 3 * int32
|
||||||
|
binary.LittleEndian.PutUint32(data[0:4], uint32(sampleRate))
|
||||||
|
binary.LittleEndian.PutUint32(data[4:8], uint32(channels))
|
||||||
|
binary.LittleEndian.PutUint32(data[8:12], uint32(frameSize))
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeOpusConfig encodes complete Opus configuration to binary format
|
||||||
|
func EncodeOpusConfig(sampleRate, channels, frameSize, bitrate, complexity, vbr, signalType, bandwidth, dtx int) []byte {
|
||||||
|
data := make([]byte, 36) // 9 * int32
|
||||||
|
binary.LittleEndian.PutUint32(data[0:4], uint32(sampleRate))
|
||||||
|
binary.LittleEndian.PutUint32(data[4:8], uint32(channels))
|
||||||
|
binary.LittleEndian.PutUint32(data[8:12], uint32(frameSize))
|
||||||
|
binary.LittleEndian.PutUint32(data[12:16], uint32(bitrate))
|
||||||
|
binary.LittleEndian.PutUint32(data[16:20], uint32(complexity))
|
||||||
|
binary.LittleEndian.PutUint32(data[20:24], uint32(vbr))
|
||||||
|
binary.LittleEndian.PutUint32(data[24:28], uint32(signalType))
|
||||||
|
binary.LittleEndian.PutUint32(data[28:32], uint32(bandwidth))
|
||||||
|
binary.LittleEndian.PutUint32(data[32:36], uint32(dtx))
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
// Common write message function
|
// Common write message function
|
||||||
func WriteIPCMessage(conn net.Conn, msg IPCMessage, pool *GenericMessagePool, droppedFramesCounter *int64) error {
|
func WriteIPCMessage(conn net.Conn, msg IPCMessage, pool *GenericMessagePool, droppedFramesCounter *int64) error {
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
|
@ -143,10 +179,8 @@ func WriteIPCMessage(conn net.Conn, msg IPCMessage, pool *GenericMessagePool, dr
|
||||||
defer pool.Put(optMsg)
|
defer pool.Put(optMsg)
|
||||||
|
|
||||||
// Prepare header in pre-allocated buffer
|
// Prepare header in pre-allocated buffer
|
||||||
binary.LittleEndian.PutUint32(optMsg.header[0:4], msg.GetMagic())
|
header := EncodeMessageHeader(msg.GetMagic(), msg.GetType(), msg.GetLength(), msg.GetTimestamp())
|
||||||
optMsg.header[4] = msg.GetType()
|
copy(optMsg.header[:], header)
|
||||||
binary.LittleEndian.PutUint32(optMsg.header[5:9], msg.GetLength())
|
|
||||||
binary.LittleEndian.PutUint64(optMsg.header[9:17], uint64(msg.GetTimestamp()))
|
|
||||||
|
|
||||||
// Set write deadline for timeout handling (more efficient than goroutines)
|
// Set write deadline for timeout handling (more efficient than goroutines)
|
||||||
if deadline := time.Now().Add(Config.WriteTimeout); deadline.After(time.Now()) {
|
if deadline := time.Now().Add(Config.WriteTimeout); deadline.After(time.Now()) {
|
||||||
|
|
|
@ -767,11 +767,8 @@ func (aic *AudioInputClient) SendConfig(config InputIPCConfig) error {
|
||||||
return fmt.Errorf("input configuration validation failed: %w", err)
|
return fmt.Errorf("input configuration validation failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize config (simple binary format)
|
// Serialize config using common function
|
||||||
data := make([]byte, 12) // 3 * int32
|
data := EncodeAudioConfig(config.SampleRate, config.Channels, config.FrameSize)
|
||||||
binary.LittleEndian.PutUint32(data[0:4], uint32(config.SampleRate))
|
|
||||||
binary.LittleEndian.PutUint32(data[4:8], uint32(config.Channels))
|
|
||||||
binary.LittleEndian.PutUint32(data[8:12], uint32(config.FrameSize))
|
|
||||||
|
|
||||||
msg := &InputIPCMessage{
|
msg := &InputIPCMessage{
|
||||||
Magic: inputMagicNumber,
|
Magic: inputMagicNumber,
|
||||||
|
@ -799,17 +796,8 @@ func (aic *AudioInputClient) SendOpusConfig(config InputIPCOpusConfig) error {
|
||||||
config.SampleRate, config.Channels, config.FrameSize, config.Bitrate)
|
config.SampleRate, config.Channels, config.FrameSize, config.Bitrate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize Opus configuration (9 * int32 = 36 bytes)
|
// Serialize Opus configuration using common function
|
||||||
data := make([]byte, 36)
|
data := EncodeOpusConfig(config.SampleRate, config.Channels, config.FrameSize, config.Bitrate, config.Complexity, config.VBR, config.SignalType, config.Bandwidth, config.DTX)
|
||||||
binary.LittleEndian.PutUint32(data[0:4], uint32(config.SampleRate))
|
|
||||||
binary.LittleEndian.PutUint32(data[4:8], uint32(config.Channels))
|
|
||||||
binary.LittleEndian.PutUint32(data[8:12], uint32(config.FrameSize))
|
|
||||||
binary.LittleEndian.PutUint32(data[12:16], uint32(config.Bitrate))
|
|
||||||
binary.LittleEndian.PutUint32(data[16:20], uint32(config.Complexity))
|
|
||||||
binary.LittleEndian.PutUint32(data[20:24], uint32(config.VBR))
|
|
||||||
binary.LittleEndian.PutUint32(data[24:28], uint32(config.SignalType))
|
|
||||||
binary.LittleEndian.PutUint32(data[28:32], uint32(config.Bandwidth))
|
|
||||||
binary.LittleEndian.PutUint32(data[32:36], uint32(config.DTX))
|
|
||||||
|
|
||||||
msg := &InputIPCMessage{
|
msg := &InputIPCMessage{
|
||||||
Magic: inputMagicNumber,
|
Magic: inputMagicNumber,
|
||||||
|
|
|
@ -173,11 +173,7 @@ func (s *AudioOutputServer) SendFrame(frame []byte) error {
|
||||||
|
|
||||||
// writeMessage writes a message to the connection
|
// writeMessage writes a message to the connection
|
||||||
func (s *AudioOutputServer) writeMessage(conn net.Conn, msg *OutputIPCMessage) error {
|
func (s *AudioOutputServer) writeMessage(conn net.Conn, msg *OutputIPCMessage) error {
|
||||||
header := make([]byte, 17)
|
header := EncodeMessageHeader(msg.Magic, uint8(msg.Type), msg.Length, msg.Timestamp)
|
||||||
binary.LittleEndian.PutUint32(header[0:4], msg.Magic)
|
|
||||||
header[4] = uint8(msg.Type)
|
|
||||||
binary.LittleEndian.PutUint32(header[5:9], msg.Length)
|
|
||||||
binary.LittleEndian.PutUint64(header[9:17], uint64(msg.Timestamp))
|
|
||||||
|
|
||||||
if _, err := conn.Write(header); err != nil {
|
if _, err := conn.Write(header); err != nil {
|
||||||
return fmt.Errorf("failed to write header: %w", err)
|
return fmt.Errorf("failed to write header: %w", err)
|
||||||
|
|
|
@ -365,15 +365,7 @@ func (s *UnifiedAudioServer) SendFrame(frame []byte) error {
|
||||||
|
|
||||||
// writeMessage writes a message to the connection
|
// writeMessage writes a message to the connection
|
||||||
func (s *UnifiedAudioServer) writeMessage(conn net.Conn, msg *UnifiedIPCMessage) error {
|
func (s *UnifiedAudioServer) writeMessage(conn net.Conn, msg *UnifiedIPCMessage) error {
|
||||||
// Get header buffer from pool
|
header := EncodeMessageHeader(msg.Magic, uint8(msg.Type), msg.Length, msg.Timestamp)
|
||||||
headerPtr := headerBufferPool.Get().(*[]byte)
|
|
||||||
header := *headerPtr
|
|
||||||
defer headerBufferPool.Put(headerPtr)
|
|
||||||
|
|
||||||
binary.LittleEndian.PutUint32(header[0:4], msg.Magic)
|
|
||||||
header[4] = uint8(msg.Type)
|
|
||||||
binary.LittleEndian.PutUint32(header[5:9], msg.Length)
|
|
||||||
binary.LittleEndian.PutUint64(header[9:17], uint64(msg.Timestamp))
|
|
||||||
|
|
||||||
if _, err := conn.Write(header); err != nil {
|
if _, err := conn.Write(header); err != nil {
|
||||||
return fmt.Errorf("failed to write header: %w", err)
|
return fmt.Errorf("failed to write header: %w", err)
|
||||||
|
|
|
@ -48,8 +48,6 @@ func getOutputStreamingLogger() *zerolog.Logger {
|
||||||
|
|
||||||
// StartAudioOutputStreaming starts audio output streaming (capturing system audio)
|
// StartAudioOutputStreaming starts audio output streaming (capturing system audio)
|
||||||
func StartAudioOutputStreaming(send func([]byte)) error {
|
func StartAudioOutputStreaming(send func([]byte)) error {
|
||||||
// Initialize audio monitoring (latency tracking and cache cleanup)
|
|
||||||
|
|
||||||
if !atomic.CompareAndSwapInt32(&outputStreamingRunning, 0, 1) {
|
if !atomic.CompareAndSwapInt32(&outputStreamingRunning, 0, 1) {
|
||||||
return ErrAudioAlreadyRunning
|
return ErrAudioAlreadyRunning
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue