Software aac decoding

This commit is contained in:
Peter 2019-10-19 17:52:07 +04:00
parent 5b889d6367
commit 595284dc9b
7 changed files with 62 additions and 5 deletions

View File

@ -9,6 +9,8 @@ final class FFMpegAudioFrameDecoder: MediaTrackFrameDecoder {
private let audioFrame: FFMpegAVFrame
private var resetDecoderOnNextFrame = true
private var delayedFrames: [MediaTrackFrame] = []
init(codecContext: FFMpegAVCodecContext) {
self.codecContext = codecContext
self.audioFrame = FFMpegAVFrame()
@ -19,17 +21,59 @@ final class FFMpegAudioFrameDecoder: MediaTrackFrameDecoder {
func decode(frame: MediaTrackDecodableFrame) -> MediaTrackFrame? {
let status = frame.packet.send(toDecoder: self.codecContext)
if status == 0 {
if self.codecContext.receive(into: self.audioFrame) {
return convertAudioFrame(self.audioFrame, pts: frame.pts, duration: frame.duration)
while self.codecContext.receive(into: self.audioFrame) {
if let convertedFrame = convertAudioFrame(self.audioFrame, pts: frame.pts, duration: frame.duration) {
self.delayedFrames.append(convertedFrame)
}
}
if self.delayedFrames.count >= 1 {
var minFrameIndex = 0
var minPosition = self.delayedFrames[0].position
for i in 1 ..< self.delayedFrames.count {
if CMTimeCompare(self.delayedFrames[i].position, minPosition) < 0 {
minFrameIndex = i
minPosition = self.delayedFrames[i].position
}
}
return self.delayedFrames.remove(at: minFrameIndex)
}
}
return nil
}
func takeQueuedFrame() -> MediaTrackFrame? {
if self.delayedFrames.count >= 1 {
var minFrameIndex = 0
var minPosition = self.delayedFrames[0].position
for i in 1 ..< self.delayedFrames.count {
if CMTimeCompare(self.delayedFrames[i].position, minPosition) < 0 {
minFrameIndex = i
minPosition = self.delayedFrames[i].position
}
}
return self.delayedFrames.remove(at: minFrameIndex)
} else {
return nil
}
}
func takeRemainingFrame() -> MediaTrackFrame? {
if !self.delayedFrames.isEmpty {
var minFrameIndex = 0
var minPosition = self.delayedFrames[0].position
for i in 1 ..< self.delayedFrames.count {
if CMTimeCompare(self.delayedFrames[i].position, minPosition) < 0 {
minFrameIndex = i
minPosition = self.delayedFrames[i].position
}
}
return self.delayedFrames.remove(at: minFrameIndex)
} else {
return nil
}
}
private func convertAudioFrame(_ frame: FFMpegAVFrame, pts: CMTime, duration: CMTime) -> MediaTrackFrame? {
guard let data = self.swrContext.resample(frame) else {

View File

@ -39,6 +39,10 @@ final class FFMpegMediaPassthroughVideoFrameDecoder: MediaTrackFrameDecoder {
return MediaTrackFrame(type: .video, sampleBuffer: sampleBuffer!, resetDecoder: resetDecoder, decoded: false, rotationAngle: self.rotationAngle)
}
func takeQueuedFrame() -> MediaTrackFrame? {
return nil
}
func takeRemainingFrame() -> MediaTrackFrame? {
return nil
}

View File

@ -87,6 +87,10 @@ public final class FFMpegMediaVideoFrameDecoder: MediaTrackFrameDecoder {
return nil
}
public func takeQueuedFrame() -> MediaTrackFrame? {
return nil
}
public func takeRemainingFrame() -> MediaTrackFrame? {
if !self.delayedFrames.isEmpty {
var minFrameIndex = 0

View File

@ -146,6 +146,10 @@ public final class MediaTrackFrameBuffer {
}
public func takeFrame() -> MediaTrackFrameResult {
if let decodedFrame = self.decoder.takeQueuedFrame() {
return .frame(decodedFrame)
}
if !self.frames.isEmpty {
let frame = self.frames.removeFirst()
if let decodedFrame = self.decoder.decode(frame: frame) {

View File

@ -1,6 +1,7 @@
protocol MediaTrackFrameDecoder {
func decode(frame: MediaTrackDecodableFrame) -> MediaTrackFrame?
func takeQueuedFrame() -> MediaTrackFrame?
func takeRemainingFrame() -> MediaTrackFrame?
func reset()
}

View File

@ -6,7 +6,7 @@
+ (void)initializeGlobals {
#if DEBUG
av_log_set_level(AV_LOG_ERROR);
av_log_set_level(AV_LOG_VERBOSE);
#else
av_log_set_level(AV_LOG_QUIET);
#endif

View File

@ -55,7 +55,7 @@ CONFIGURE_FLAGS="--enable-cross-compile --disable-programs \
--enable-libopus \
--enable-audiotoolbox \
--enable-bsf=aac_adtstoasc \
--enable-decoder=h264,hevc,libopus,mp3_at,aac_at,flac,alac_at,pcm_s16le,pcm_s24le,gsm_ms_at \
--enable-decoder=h264,hevc,libopus,mp3_at,aac,flac,alac_at,pcm_s16le,pcm_s24le,gsm_ms_at \
--enable-demuxer=aac,mov,m4v,mp3,ogg,libopus,flac,wav,aiff,matroska \
--enable-parser=aac,h264,mp3,libopus \
--enable-protocol=file \