From 25d8dfc800d441d6cd6557c8ee18a0c7844b0f0b Mon Sep 17 00:00:00 2001 From: Ali <> Date: Fri, 29 Sep 2023 20:54:24 +0400 Subject: [PATCH] Fix video frame duration handling --- submodules/FFMpegBinding/BUILD | 3 +++ .../FFMpegBinding/Sources/FFMpegAVCodec.m | 8 +++--- .../Sources/FFMpegAVCodecContext.m | 2 +- .../FFMpegBinding/Sources/FFMpegAVFrame.m | 2 +- .../FFMpegBinding/Sources/FFMpegPacket.m | 26 +++++++++---------- .../FFMpegBinding/Sources/FFMpegRemuxer.m | 8 +++--- .../FFMpegBinding/Sources/FFMpegSWResample.m | 7 +++-- .../Sources/FFMpegAudioFrameDecoder.swift | 10 ++----- .../FFMpegMediaFrameSourceContext.swift | 2 +- 9 files changed, 34 insertions(+), 34 deletions(-) diff --git a/submodules/FFMpegBinding/BUILD b/submodules/FFMpegBinding/BUILD index 094b363bd2..7edfc881d9 100644 --- a/submodules/FFMpegBinding/BUILD +++ b/submodules/FFMpegBinding/BUILD @@ -10,6 +10,9 @@ objc_library( hdrs = glob([ "Public/**/*.h", ]), + copts = [ + "-Werror", + ], includes = [ "Public", ], diff --git a/submodules/FFMpegBinding/Sources/FFMpegAVCodec.m b/submodules/FFMpegBinding/Sources/FFMpegAVCodec.m index 857462cfec..0ea2b101a6 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegAVCodec.m +++ b/submodules/FFMpegBinding/Sources/FFMpegAVCodec.m @@ -3,14 +3,14 @@ #import "libavcodec/avcodec.h" @interface FFMpegAVCodec () { - AVCodec *_impl; + AVCodec const *_impl; } @end @implementation FFMpegAVCodec -- (instancetype)initWithImpl:(AVCodec *)impl { +- (instancetype)initWithImpl:(AVCodec const *)impl { self = [super init]; if (self != nil) { _impl = impl; @@ -19,7 +19,7 @@ } + (FFMpegAVCodec * _Nullable)findForId:(int)codecId { - AVCodec *codec = avcodec_find_decoder(codecId); + AVCodec const *codec = avcodec_find_decoder(codecId); if (codec) { return [[FFMpegAVCodec alloc] initWithImpl:codec]; } else { @@ -28,7 +28,7 @@ } - (void *)impl { - return _impl; + return (void *)_impl; } @end diff --git a/submodules/FFMpegBinding/Sources/FFMpegAVCodecContext.m b/submodules/FFMpegBinding/Sources/FFMpegAVCodecContext.m index 52f9e6541e..c9ca7b68e7 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegAVCodecContext.m +++ b/submodules/FFMpegBinding/Sources/FFMpegAVCodecContext.m @@ -35,7 +35,7 @@ } - (int32_t)channels { - return (int32_t)_impl->channels; + return (int32_t)_impl->ch_layout.nb_channels; } - (int32_t)sampleRate { diff --git a/submodules/FFMpegBinding/Sources/FFMpegAVFrame.m b/submodules/FFMpegBinding/Sources/FFMpegAVFrame.m index 9c8218e0fe..205cbc42e2 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegAVFrame.m +++ b/submodules/FFMpegBinding/Sources/FFMpegAVFrame.m @@ -45,7 +45,7 @@ } - (int64_t)duration { - return _impl->pkt_duration; + return _impl->duration; } - (FFMpegAVFrameColorRange)colorRange { diff --git a/submodules/FFMpegBinding/Sources/FFMpegPacket.m b/submodules/FFMpegBinding/Sources/FFMpegPacket.m index 47dab958c7..30e4d8f92f 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegPacket.m +++ b/submodules/FFMpegBinding/Sources/FFMpegPacket.m @@ -6,7 +6,7 @@ #import "libavformat/avformat.h" @interface FFMpegPacket () { - AVPacket _impl; + AVPacket *_impl; } @end @@ -16,49 +16,49 @@ - (instancetype)init { self = [super init]; if (self != nil) { - av_init_packet(&_impl); + _impl = av_packet_alloc(); } return self; } - (void)dealloc { - av_packet_unref(&_impl); + av_packet_free(&_impl); } - (void *)impl { - return &_impl; + return _impl; } - (int64_t)pts { - if (_impl.pts == 0x8000000000000000) { - return _impl.dts; + if (_impl->pts == 0x8000000000000000) { + return _impl->dts; } else { - return _impl.pts; + return _impl->pts; } } - (int64_t)dts { - return _impl.dts; + return _impl->dts; } - (int64_t)duration { - return _impl.duration; + return _impl->duration; } - (int32_t)streamIndex { - return (int32_t)_impl.stream_index; + return (int32_t)_impl->stream_index; } - (int32_t)size { - return (int32_t)_impl.size; + return (int32_t)_impl->size; } - (uint8_t *)data { - return _impl.data; + return _impl->data; } - (int32_t)sendToDecoder:(FFMpegAVCodecContext *)codecContext { - return avcodec_send_packet((AVCodecContext *)[codecContext impl], &_impl); + return avcodec_send_packet((AVCodecContext *)[codecContext impl], _impl); } @end diff --git a/submodules/FFMpegBinding/Sources/FFMpegRemuxer.m b/submodules/FFMpegBinding/Sources/FFMpegRemuxer.m index a5bcefdc9c..df3c1adfb8 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegRemuxer.m +++ b/submodules/FFMpegBinding/Sources/FFMpegRemuxer.m @@ -34,18 +34,18 @@ @end -static int readPacketImpl(void * _Nullable opaque, uint8_t * _Nullable buffer, int length) { +/*static int readPacketImpl(void * _Nullable opaque, uint8_t * _Nullable buffer, int length) { FFMpegRemuxerContext *context = (__bridge FFMpegRemuxerContext *)opaque; context->_offset += length; printf("read %lld bytes (offset is now %lld)\n", (int64_t)length, context->_offset); - return read(context->_fd, buffer, length); + return (int)read(context->_fd, buffer, length); } static int writePacketImpl(void * _Nullable opaque, uint8_t * _Nullable buffer, int length) { FFMpegRemuxerContext *context = (__bridge FFMpegRemuxerContext *)opaque; context->_offset += length; printf("write %lld bytes (offset is now %lld)\n", (int64_t)length, context->_offset); - return write(context->_fd, buffer, length); + return (int)write(context->_fd, buffer, length); } static int64_t seekImpl(void * _Nullable opaque, int64_t offset, int whence) { @@ -57,7 +57,7 @@ static int64_t seekImpl(void * _Nullable opaque, int64_t offset, int whence) { context->_offset = offset; return lseek(context->_fd, offset, SEEK_SET); } -} +}*/ @implementation FFMpegRemuxer diff --git a/submodules/FFMpegBinding/Sources/FFMpegSWResample.m b/submodules/FFMpegBinding/Sources/FFMpegSWResample.m index f8e68d51b0..5556d71c99 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegSWResample.m +++ b/submodules/FFMpegBinding/Sources/FFMpegSWResample.m @@ -52,7 +52,9 @@ swr_free(&_context); _context = NULL; } - + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" _context = swr_alloc_set_opts(NULL, av_get_default_channel_layout((int)_destinationChannelCount), (enum AVSampleFormat)_destinationSampleFormat, @@ -62,6 +64,7 @@ (int)_sourceSampleRate, 0, NULL); +#pragma clang diagnostic pop _currentSourceChannelCount = channelCount; _ratio = MAX(1, _destinationSampleRate / MAX(_sourceSampleRate, 1)) * MAX(1, _destinationChannelCount / channelCount) * 2; if (_context) { @@ -72,7 +75,7 @@ - (NSData * _Nullable)resample:(FFMpegAVFrame *)frame { AVFrame *frameImpl = (AVFrame *)[frame impl]; - int numChannels = frameImpl->channels; + int numChannels = frameImpl->ch_layout.nb_channels; if (numChannels != _currentSourceChannelCount) { [self resetContextForChannelCount:numChannels]; } diff --git a/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift b/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift index 260e5e54f3..9dd0b0c121 100644 --- a/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift +++ b/submodules/MediaPlayer/Sources/FFMpegAudioFrameDecoder.swift @@ -65,7 +65,7 @@ final class FFMpegAudioFrameDecoder: MediaTrackFrameDecoder { while true { let result = self.codecContext.receive(into: self.audioFrame) if case .success = result { - if let convertedFrame = convertAudioFrame(self.audioFrame, pts: frame.pts, duration: frame.duration) { + if let convertedFrame = convertAudioFrame(self.audioFrame, pts: frame.pts) { self.delayedFrames.append(convertedFrame) } } else { @@ -121,7 +121,7 @@ final class FFMpegAudioFrameDecoder: MediaTrackFrameDecoder { } } - private func convertAudioFrame(_ frame: FFMpegAVFrame, pts: CMTime, duration: CMTime) -> MediaTrackFrame? { + private func convertAudioFrame(_ frame: FFMpegAVFrame, pts: CMTime) -> MediaTrackFrame? { guard let data = self.swrContext.resample(frame) else { return nil } @@ -135,18 +135,12 @@ final class FFMpegAudioFrameDecoder: MediaTrackFrameDecoder { return nil } - //var timingInfo = CMSampleTimingInfo(duration: duration, presentationTimeStamp: pts, decodeTimeStamp: pts) var sampleBuffer: CMSampleBuffer? - //var sampleSize = data.count guard CMAudioSampleBufferCreateReadyWithPacketDescriptions(allocator: nil, dataBuffer: blockBuffer!, formatDescription: self.formatDescription, sampleCount: Int(data.count / 2), presentationTimeStamp: pts, packetDescriptions: nil, sampleBufferOut: &sampleBuffer) == noErr else { return nil } - /*guard CMSampleBufferCreate(allocator: nil, dataBuffer: blockBuffer, dataReady: true, makeDataReadyCallback: nil, refcon: nil, formatDescription: self.formatDescription, sampleCount: Int(frame.duration), sampleTimingEntryCount: 1, sampleTimingArray: &timingInfo, sampleSizeEntryCount: 1, sampleSizeArray: &sampleSize, sampleBufferOut: &sampleBuffer) == noErr else { - return nil - }*/ - let resetDecoder = self.resetDecoderOnNextFrame self.resetDecoderOnNextFrame = false diff --git a/submodules/MediaPlayer/Sources/FFMpegMediaFrameSourceContext.swift b/submodules/MediaPlayer/Sources/FFMpegMediaFrameSourceContext.swift index db27df800e..2cbbed178a 100644 --- a/submodules/MediaPlayer/Sources/FFMpegMediaFrameSourceContext.swift +++ b/submodules/MediaPlayer/Sources/FFMpegMediaFrameSourceContext.swift @@ -725,7 +725,7 @@ private func videoFrameFromPacket(_ packet: FFMpegPacket, videoStream: StreamCon if frameDuration != 0 { duration = CMTimeMake(value: frameDuration * videoStream.timebase.value, timescale: videoStream.timebase.timescale) } else { - duration = videoStream.fps + duration = CMTimeMake(value: Int64(videoStream.fps.timescale), timescale: Int32(videoStream.fps.value)) } return MediaTrackDecodableFrame(type: .video, packet: packet, pts: pts, dts: dts, duration: duration)