Browse Source

opus解码异常修复

newdev_shunjiawei
fdp 1 year ago
parent
commit
475534199b
  1. 59
      local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftOpusAudioProcessor.swift

59
local_plugins/ble_service/ios/ble_service/Sources/ble_service/SwiftOpusAudioProcessor.swift

@ -26,22 +26,32 @@ class SwiftOpusAudioProcessor: NSObject {
cleanup() cleanup()
} }
/// 线程安全的解码器初始化
private func initializeOpusDecoder() -> Bool { private func initializeOpusDecoder() -> Bool {
objc_sync_enter(self)
defer { objc_sync_exit(self) }
if decoder != nil { if decoder != nil {
return true return true
} }
var error: Int32 = 0 var error: Int32 = 0
decoder = opus_decoder_create(sampleRate, channels, &error) let newDecoder = opus_decoder_create(sampleRate, channels, &error)
guard error == OPUS_OK, decoder != nil else { guard error == OPUS_OK, newDecoder != nil else {
print("Opus解码器创建失败,错误代码: \(error)")
return false return false
} }
decoder = newDecoder
return true return true
} }
/// 线程安全的解码器销毁
private func destroyOpusDecoder() { private func destroyOpusDecoder() {
objc_sync_enter(self)
defer { objc_sync_exit(self) }
if let decoder = decoder { if let decoder = decoder {
opus_decoder_destroy(decoder) opus_decoder_destroy(decoder)
self.decoder = nil self.decoder = nil
@ -112,23 +122,44 @@ class SwiftOpusAudioProcessor: NSObject {
} }
} }
// 简化的 Opus 解码方法,重点是容错处理 /// 改进的 Opus 解码方法,增强容错和线程安全
private func decodeOpusPacket(_ packet: Data) { private func decodeOpusPacket(_ packet: Data) {
guard let decoder = decoder else { return } // 添加线程安全锁
objc_sync_enter(self)
defer { objc_sync_exit(self) }
// 验证解码器状态
guard let decoder = decoder, isDecodingActive else {
print("解码器未初始化或已停止")
return
}
let maxSamples = Int(maxFrameSize) let maxSamples = Int(maxFrameSize)
var pcmBuffer = [opus_int16](repeating: 0, count: maxSamples * Int(channels)) var pcmBuffer = [opus_int16](repeating: 0, count: maxSamples * Int(channels))
let decodedSamples = packet.withUnsafeBytes { packetPtr in let decodedSamples = packet.withUnsafeBytes { packetPtr in
let uint8Ptr = packetPtr.bindMemory(to: UInt8.self).baseAddress // 确保指针有效
return opus_decode( guard let uint8Ptr = packetPtr.bindMemory(to: UInt8.self).baseAddress else {
decoder, print("无法获取数据包指针")
uint8Ptr, return opus_int32(-1)
opus_int32(packet.count), }
&pcmBuffer,
Int32(maxSamples), // 添加异常捕获机制
0 var result: opus_int32 = -1
)
// 使用 autoreleasepool 确保内存管理
autoreleasepool {
result = opus_decode(
decoder,
uint8Ptr,
opus_int32(packet.count),
&pcmBuffer,
Int32(maxSamples),
0
)
}
return result
} }
// 增强的错误处理:检查各种错误情况 // 增强的错误处理:检查各种错误情况
@ -237,4 +268,4 @@ class SwiftOpusAudioProcessor: NSObject {
func getCurrentConfig() -> (sampleRate: Int32, channels: Int32) { func getCurrentConfig() -> (sampleRate: Int32, channels: Int32) {
return (sampleRate, channels) return (sampleRate, channels)
} }
} }

Loading…
Cancel
Save