// // decode_audio.swift // SwiftFFmpegExamples // // Created by sunlubo on 2019/1/9. // import SwiftFFmpeg #if canImport(Darwin) import Darwin #else import Glibc #endif private func decode( codecCtx: AVCodecContext, frame: AVFrame, pkt: AVPacket?, file: UnsafeMutablePointer ) throws { try codecCtx.sendPacket(pkt) while true { do { try codecCtx.receiveFrame(frame) } catch let err as AVError where err == .tryAgain || err == .eof { break } let dataSize = codecCtx.sampleFormat.bytesPerSample for i in 0...allocate( capacity: inbufSize + AVConstant.inputBufferPaddingSize) inbuf.initialize(to: 0) defer { inbuf.deallocate() } // decode until eof var size = fread(inbuf, 1, inbufSize, inFile) var data = inbuf while size > 0 { // use the parser to split the data into frames let (buf, bufSize, used) = try parser.parse(data: data, size: size) pkt.data = buf pkt.size = bufSize data = data.advanced(by: used) size -= used if pkt.size > 0 { try decode(codecCtx: codecCtx, frame: frame, pkt: pkt, file: outFile) } if size < refillThresh { memmove(inbuf, data, size) data = inbuf let len = fread(data.advanced(by: size), 1, inbufSize - size, inFile) if len > 0 { size += len } } } // flush the decoder pkt.data = nil pkt.size = 0 try decode(codecCtx: codecCtx, frame: frame, pkt: pkt, file: outFile) }