Skip to content

Commit

Permalink
Merge pull request #10 from huiping192/feature/encoder-refactroing
Browse files Browse the repository at this point in the history
encoder refactroing
  • Loading branch information
huiping192 authored Sep 12, 2023
2 parents 0bb282d + 4939090 commit 8676b5d
Show file tree
Hide file tree
Showing 15 changed files with 359 additions and 329 deletions.
66 changes: 15 additions & 51 deletions Sources/HPLiveKit/Coder/AudioCoderHelper.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import Foundation
import AVFoundation
import AudioToolbox
import HPRTMP

extension CMAudioFormatDescription {

Expand All @@ -12,55 +10,21 @@ extension CMAudioFormatDescription {
}
}


/*
AudioSpecificConfig = 2 bytes,
number = bits
------------------------------
| audioObjectType (5) |
| sampleingFrequencyIndex (4)|
| channelConfigration (4) |
| frameLengthFlag (1) |
| dependsOnCoreCoder (1) |
| extensionFlag (1) |
------------------------------
*/
struct AudioSpecificConfig {
let objectType: MPEG4ObjectID
var channelConfig: ChannelConfigType = .unknown
var frequencyType: SampleFrequencyType = .unknown
let frameLengthFlag: Bool
let dependsOnCoreCoder: UInt8
let extensionFlag: UInt8
init (data: Data) {
self.objectType = MPEG4ObjectID(rawValue: Int((0b11111000 & data[0]) >> 3)) ?? .aac_Main
self.frequencyType = SampleFrequencyType(rawValue: (0b00000111 & data[0]) << 1 | (0b10000000 & data[1]) >> 7)
self.channelConfig = ChannelConfigType(rawValue: (0b01111000 & data[1]) >> 3)
let value = UInt8(data[1] & 0b00100000) == 1
self.frameLengthFlag = value
self.dependsOnCoreCoder = data[1] & 0b000000010
self.extensionFlag = data[1] & 0b000000001
}

init(objectType: MPEG4ObjectID, channelConfig: ChannelConfigType, frequencyType: SampleFrequencyType, frameLengthFlag: Bool = false, dependsOnCoreCoder: UInt8 = 0, extensionFlag: UInt8 = 0) {
self.objectType = objectType
self.channelConfig = channelConfig
self.frequencyType = frequencyType
self.frameLengthFlag = frameLengthFlag
self.dependsOnCoreCoder = dependsOnCoreCoder
self.extensionFlag = extensionFlag
}

var encodeData: Data {
get {
let flag = self.frameLengthFlag ? 1 : 0
let first = UInt8(self.objectType.rawValue) << 3 | UInt8(self.frequencyType.rawValue >> 1 & 0b00000111)
let second = (0b10000000 & self.frequencyType.rawValue << 7) |
(0b01111000 & self.channelConfig.rawValue << 3) |
(UInt8(flag) << 2) |
(self.dependsOnCoreCoder << 1) |
self.extensionFlag
return Data([first, second])
extension CMSampleBuffer {
var audioRawData: Data {
var audioBufferList = AudioBufferList()
var data = Data()
var blockBuffer: CMBlockBuffer?

CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(self, bufferListSizeNeededOut: nil, bufferListOut: &audioBufferList, bufferListSize: MemoryLayout<AudioBufferList>.size, blockBufferAllocator: nil, blockBufferMemoryAllocator: nil, flags: 0, blockBufferOut: &blockBuffer)

let buffers = UnsafeBufferPointer<AudioBuffer>(start: &audioBufferList.mBuffers, count: Int(audioBufferList.mNumberBuffers))

for audioBuffer in buffers {
let frame = audioBuffer.mData?.assumingMemoryBound(to: UInt8.self)
data.append(frame!, count: Int(audioBuffer.mDataByteSize))
}
return data
}
}

4 changes: 2 additions & 2 deletions Sources/HPLiveKit/Coder/AudioEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protocol AudioEncoder: AnyObject {
set
}

func encodeAudioData(sampleBuffer: CMSampleBuffer)
func encode(sampleBuffer: CMSampleBuffer)

func stopEncoder()
func stop()
}
62 changes: 62 additions & 0 deletions Sources/HPLiveKit/Coder/AudioSpecificConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// AudioSpecificConfig.swift
//
//
// Created by 郭 輝平 on 2023/09/12.
//

import Foundation
import HPRTMP
import AVFoundation

/*
AudioSpecificConfig = 2 bytes,
number = bits
------------------------------
| audioObjectType (5) |
| sampleingFrequencyIndex (4)|
| channelConfigration (4) |
| frameLengthFlag (1) |
| dependsOnCoreCoder (1) |
| extensionFlag (1) |
------------------------------
*/
struct AudioSpecificConfig {
let objectType: MPEG4ObjectID
var channelConfig: ChannelConfigType = .unknown
var frequencyType: SampleFrequencyType = .unknown
let frameLengthFlag: Bool
let dependsOnCoreCoder: UInt8
let extensionFlag: UInt8
init (data: Data) {
self.objectType = MPEG4ObjectID(rawValue: Int((0b11111000 & data[0]) >> 3)) ?? .aac_Main
self.frequencyType = SampleFrequencyType(rawValue: (0b00000111 & data[0]) << 1 | (0b10000000 & data[1]) >> 7)
self.channelConfig = ChannelConfigType(rawValue: (0b01111000 & data[1]) >> 3)
let value = UInt8(data[1] & 0b00100000) == 1
self.frameLengthFlag = value
self.dependsOnCoreCoder = data[1] & 0b000000010
self.extensionFlag = data[1] & 0b000000001
}

init(objectType: MPEG4ObjectID, channelConfig: ChannelConfigType, frequencyType: SampleFrequencyType, frameLengthFlag: Bool = false, dependsOnCoreCoder: UInt8 = 0, extensionFlag: UInt8 = 0) {
self.objectType = objectType
self.channelConfig = channelConfig
self.frequencyType = frequencyType
self.frameLengthFlag = frameLengthFlag
self.dependsOnCoreCoder = dependsOnCoreCoder
self.extensionFlag = extensionFlag
}

var encodeData: Data {
get {
let flag = self.frameLengthFlag ? 1 : 0
let first = UInt8(self.objectType.rawValue) << 3 | UInt8(self.frequencyType.rawValue >> 1 & 0b00000111)
let second = (0b10000000 & self.frequencyType.rawValue << 7) |
(0b01111000 & self.channelConfig.rawValue << 3) |
(UInt8(flag) << 2) |
(self.dependsOnCoreCoder << 1) |
self.extensionFlag
return Data([first, second])
}
}
}
80 changes: 40 additions & 40 deletions Sources/HPLiveKit/Coder/EncoderManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,53 +9,53 @@ import Foundation
import CoreVideo
import CoreMedia

public protocol EncoderManagerDelegate: class {
func encodeOutput(encoderManager: EncoderManager, audioFrame: AudioFrame)
func encodeOutput(encoderManager: EncoderManager, videoFrame: VideoFrame)
public protocol EncoderManagerDelegate: AnyObject {
func encodeOutput(encoderManager: EncoderManager, audioFrame: AudioFrame)
func encodeOutput(encoderManager: EncoderManager, videoFrame: VideoFrame)
}

public class EncoderManager: NSObject {

// video,audio encoder
private let videoEncoder: VideoEncoder
private let audioEncoder: AudioEncoder

public weak var delegate: EncoderManagerDelegate?

public var videoBitRate: UInt {
get {
videoEncoder.videoBitRate
}
set {
videoEncoder.videoBitRate = newValue
}

// video,audio encoder
private let videoEncoder: VideoEncoder
private let audioEncoder: AudioEncoder

public weak var delegate: EncoderManagerDelegate?

public var videoBitRate: UInt {
get {
videoEncoder.videoBitRate
}

public init(audioConfiguration: LiveAudioConfiguration, videoConfiguration: LiveVideoConfiguration) {
videoEncoder = LiveVideoH264Encoder(configuration: videoConfiguration)
audioEncoder = LiveAudioAACEncoder(configuration: audioConfiguration)

super.init()

videoEncoder.delegate = self
audioEncoder.delegate = self
set {
videoEncoder.videoBitRate = newValue
}

}

public init(audioConfiguration: LiveAudioConfiguration, videoConfiguration: LiveVideoConfiguration) {
videoEncoder = LiveVideoH264Encoder(configuration: videoConfiguration)
audioEncoder = LiveAudioAACEncoder(configuration: audioConfiguration)

super.init()

videoEncoder.delegate = self
audioEncoder.delegate = self
}

public func encodeAudio(sampleBuffer: CMSampleBuffer) {
audioEncoder.encodeAudioData(sampleBuffer: sampleBuffer)
}

public func encodeVideo(sampleBuffer: CMSampleBuffer) {
videoEncoder.encodeVideoData(sampleBuffer: sampleBuffer)
}
audioEncoder.encode(sampleBuffer: sampleBuffer)
}
public func encodeVideo(sampleBuffer: CMSampleBuffer) {
videoEncoder.encode(sampleBuffer: sampleBuffer)
}
}

extension EncoderManager: AudioEncoderDelegate, VideoEncoderDelegate {
func audioEncoder(encoder: AudioEncoder, audioFrame: AudioFrame) {
delegate?.encodeOutput(encoderManager: self, audioFrame: audioFrame)
}

func videoEncoder(encoder: VideoEncoder, frame: VideoFrame) {
delegate?.encodeOutput(encoderManager: self, videoFrame: frame)
}
func audioEncoder(encoder: AudioEncoder, audioFrame: AudioFrame) {
delegate?.encodeOutput(encoderManager: self, audioFrame: audioFrame)
}
func videoEncoder(encoder: VideoEncoder, frame: VideoFrame) {
delegate?.encodeOutput(encoderManager: self, videoFrame: frame)
}
}
Loading

0 comments on commit 8676b5d

Please sign in to comment.