diff --git a/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift b/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift index 725051e022..9b409f1926 100644 --- a/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift +++ b/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift @@ -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,16 +21,58 @@ 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? { - return nil + 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? { diff --git a/submodules/MediaPlayer/Sources/FFMpegMediaPassthroughVideoFrameDecoder.swift b/submodules/MediaPlayer/Sources/FFMpegMediaPassthroughVideoFrameDecoder.swift index f417d3d40a..ef05414b40 100644 --- a/submodules/MediaPlayer/Sources/FFMpegMediaPassthroughVideoFrameDecoder.swift +++ b/submodules/MediaPlayer/Sources/FFMpegMediaPassthroughVideoFrameDecoder.swift @@ -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 } diff --git a/submodules/MediaPlayer/Sources/FFMpegMediaVideoFrameDecoder.swift b/submodules/MediaPlayer/Sources/FFMpegMediaVideoFrameDecoder.swift index 0bfdb1731f..d77320d18a 100644 --- a/submodules/MediaPlayer/Sources/FFMpegMediaVideoFrameDecoder.swift +++ b/submodules/MediaPlayer/Sources/FFMpegMediaVideoFrameDecoder.swift @@ -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 diff --git a/submodules/MediaPlayer/Sources/MediaTrackFrameBuffer.swift b/submodules/MediaPlayer/Sources/MediaTrackFrameBuffer.swift index 08650acba8..210fc7ab2a 100644 --- a/submodules/MediaPlayer/Sources/MediaTrackFrameBuffer.swift +++ b/submodules/MediaPlayer/Sources/MediaTrackFrameBuffer.swift @@ -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) { diff --git a/submodules/MediaPlayer/Sources/MediaTrackFrameDecoder.swift b/submodules/MediaPlayer/Sources/MediaTrackFrameDecoder.swift index 9e4c8266ec..0f27a3f02a 100644 --- a/submodules/MediaPlayer/Sources/MediaTrackFrameDecoder.swift +++ b/submodules/MediaPlayer/Sources/MediaTrackFrameDecoder.swift @@ -1,6 +1,7 @@ protocol MediaTrackFrameDecoder { func decode(frame: MediaTrackDecodableFrame) -> MediaTrackFrame? + func takeQueuedFrame() -> MediaTrackFrame? func takeRemainingFrame() -> MediaTrackFrame? func reset() } diff --git a/submodules/ffmpeg/FFMpeg/FFMpegGlobals.m b/submodules/ffmpeg/FFMpeg/FFMpegGlobals.m index c507fff969..50dfa7e1eb 100644 --- a/submodules/ffmpeg/FFMpeg/FFMpegGlobals.m +++ b/submodules/ffmpeg/FFMpeg/FFMpegGlobals.m @@ -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 diff --git a/submodules/ffmpeg/FFMpeg/build-ffmpeg.sh b/submodules/ffmpeg/FFMpeg/build-ffmpeg.sh index 5086bbe443..cc7f8a753b 100755 --- a/submodules/ffmpeg/FFMpeg/build-ffmpeg.sh +++ b/submodules/ffmpeg/FFMpeg/build-ffmpeg.sh @@ -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 \