mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Fix video frame duration handling
This commit is contained in:
parent
1b010bc17f
commit
25d8dfc800
@ -10,6 +10,9 @@ objc_library(
|
||||
hdrs = glob([
|
||||
"Public/**/*.h",
|
||||
]),
|
||||
copts = [
|
||||
"-Werror",
|
||||
],
|
||||
includes = [
|
||||
"Public",
|
||||
],
|
||||
|
@ -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
|
||||
|
@ -35,7 +35,7 @@
|
||||
}
|
||||
|
||||
- (int32_t)channels {
|
||||
return (int32_t)_impl->channels;
|
||||
return (int32_t)_impl->ch_layout.nb_channels;
|
||||
}
|
||||
|
||||
- (int32_t)sampleRate {
|
||||
|
@ -45,7 +45,7 @@
|
||||
}
|
||||
|
||||
- (int64_t)duration {
|
||||
return _impl->pkt_duration;
|
||||
return _impl->duration;
|
||||
}
|
||||
|
||||
- (FFMpegAVFrameColorRange)colorRange {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user