diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 4a9b09fa2..cdf9f42a2 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -4107,7 +4107,16 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { switch (update.type()) { case mtpc_updateNewMessage: { - const auto &d(update.c_updateNewMessage()); + auto &d = update.c_updateNewMessage(); + + DataIsLoadedResult isDataLoaded = allDataLoadedForMessage(d.vmessage); + if (!requestingDifference() && isDataLoaded != DataIsLoadedResult::Ok) { + MTP_LOG(0, ("getDifference { good - after not all data loaded in updateNewMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); + + // This can be if this update was created by grouping + // some short message update into an updates vector. + return getDifference(); + } if (!ptsUpdated(d.vpts.v, d.vpts_count.v, update)) { return; @@ -4462,7 +4471,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { } break; case mtpc_updateNewChannelMessage: { - const auto &d(update.c_updateNewChannelMessage()); + auto &d = update.c_updateNewChannelMessage(); ChannelData *channel = App::channelLoaded(peerToChannel(peerFromMessage(d.vmessage))); DataIsLoadedResult isDataLoaded = allDataLoadedForMessage(d.vmessage); if (!requestingDifference() && (!channel || isDataLoaded != DataIsLoadedResult::Ok)) { diff --git a/Telegram/SourceFiles/media/media_audio.cpp b/Telegram/SourceFiles/media/media_audio.cpp index 799c3511a..71558181c 100644 --- a/Telegram/SourceFiles/media/media_audio.cpp +++ b/Telegram/SourceFiles/media/media_audio.cpp @@ -1765,8 +1765,8 @@ public: FFMpegAttributesReader(const FileLocation &file, const QByteArray &data) : AbstractFFMpegLoader(file, data) { } - bool open(qint64 position = 0) override { - if (!AbstractFFMpegLoader::open()) { + bool open(qint64 &position) override { + if (!AbstractFFMpegLoader::open(position)) { return false; } @@ -1862,7 +1862,8 @@ private: MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat) { FFMpegAttributesReader reader(FileLocation(StorageFilePartial, fname), data); - if (reader.open()) { + qint64 position = 0; + if (reader.open(position)) { int32 duration = reader.duration() / reader.frequency(); if (reader.duration() > 0) { cover = reader.cover(); @@ -1880,7 +1881,7 @@ public: FFMpegWaveformCounter(const FileLocation &file, const QByteArray &data) : FFMpegLoader(file, data) { } - bool open(qint64 position = 0) override { + bool open(qint64 &position) override { if (!FFMpegLoader::open(position)) { return false; } @@ -1976,7 +1977,8 @@ private: VoiceWaveform audioCountWaveform(const FileLocation &file, const QByteArray &data) { FFMpegWaveformCounter counter(file, data); - if (counter.open()) { + qint64 position = 0; + if (counter.open(position)) { return counter.waveform(); } return VoiceWaveform(); diff --git a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp index 69bd99cd2..b9ef7e020 100644 --- a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp +++ b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.cpp @@ -25,7 +25,7 @@ constexpr AVSampleFormat AudioToFormat = AV_SAMPLE_FMT_S16; constexpr int64_t AudioToChannelLayout = AV_CH_LAYOUT_STEREO; constexpr int32 AudioToChannels = 2; -bool AbstractFFMpegLoader::open(qint64 position) { +bool AbstractFFMpegLoader::open(qint64 &position) { if (!AudioPlayerLoader::openFile()) { return false; } @@ -137,7 +137,7 @@ FFMpegLoader::FFMpegLoader(const FileLocation &file, const QByteArray &data) : A frame = av_frame_alloc(); } -bool FFMpegLoader::open(qint64 position) { +bool FFMpegLoader::open(qint64 &position) { if (!AbstractFFMpegLoader::open(position)) { return false; } @@ -210,6 +210,7 @@ bool FFMpegLoader::open(qint64 position) { sampleSize = AudioToChannels * sizeof(short); freq = dstRate; len = av_rescale_rnd(len, dstRate, srcRate, AV_ROUND_UP); + position = av_rescale_rnd(position, dstRate, srcRate, AV_ROUND_DOWN); fmt = AL_FORMAT_STEREO16; maxResampleSamples = av_rescale_rnd(AVBlockSize / sampleSize, dstRate, srcRate, AV_ROUND_UP); diff --git a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.h b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.h index 02ff3d3a3..c856be631 100644 --- a/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.h +++ b/Telegram/SourceFiles/media/media_audio_ffmpeg_loader.h @@ -36,7 +36,7 @@ public: AbstractFFMpegLoader(const FileLocation &file, const QByteArray &data) : AudioPlayerLoader(file, data) { } - bool open(qint64 position = 0) override; + bool open(qint64 &position) override; int64 duration() override { return len; @@ -72,7 +72,7 @@ class FFMpegLoader : public AbstractFFMpegLoader { public: FFMpegLoader(const FileLocation &file, const QByteArray &data); - bool open(qint64 position = 0) override; + bool open(qint64 &position) override; int32 format() override { return fmt; diff --git a/Telegram/SourceFiles/media/media_audio_loader.h b/Telegram/SourceFiles/media/media_audio_loader.h index 74a749043..5e8a55012 100644 --- a/Telegram/SourceFiles/media/media_audio_loader.h +++ b/Telegram/SourceFiles/media/media_audio_loader.h @@ -27,7 +27,7 @@ public: virtual bool check(const FileLocation &file, const QByteArray &data); - virtual bool open(qint64 position = 0) = 0; + virtual bool open(qint64 &position) = 0; virtual int64 duration() = 0; virtual int32 frequency() = 0; virtual int32 format() = 0; diff --git a/Telegram/SourceFiles/media/media_audio_loaders.cpp b/Telegram/SourceFiles/media/media_audio_loaders.cpp index 5b1805b93..491eb8cda 100644 --- a/Telegram/SourceFiles/media/media_audio_loaders.cpp +++ b/Telegram/SourceFiles/media/media_audio_loaders.cpp @@ -321,7 +321,7 @@ void AudioPlayerLoaders::loadData(AudioMsgId audio, qint64 position) { } } -AudioPlayerLoader *AudioPlayerLoaders::setupLoader(const AudioMsgId &audio, SetupError &err, qint64 position) { +AudioPlayerLoader *AudioPlayerLoaders::setupLoader(const AudioMsgId &audio, SetupError &err, qint64 &position) { err = SetupErrorAtStart; QMutexLocker lock(internal::audioPlayerMutex()); AudioPlayer *voice = audioPlayer(); diff --git a/Telegram/SourceFiles/media/media_audio_loaders.h b/Telegram/SourceFiles/media/media_audio_loaders.h index 50a282b59..6e190ae95 100644 --- a/Telegram/SourceFiles/media/media_audio_loaders.h +++ b/Telegram/SourceFiles/media/media_audio_loaders.h @@ -73,7 +73,7 @@ private: SetupNoErrorStarted = 3, }; void loadData(AudioMsgId audio, qint64 position); - AudioPlayerLoader *setupLoader(const AudioMsgId &audio, SetupError &err, qint64 position); + AudioPlayerLoader *setupLoader(const AudioMsgId &audio, SetupError &err, qint64 &position); AudioPlayer::AudioMsg *checkLoader(AudioMsgId::Type type); }; diff --git a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp index 5016b1b4f..143f9f1c6 100644 --- a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp +++ b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp @@ -39,7 +39,7 @@ ChildFFMpegLoader::ChildFFMpegLoader(uint64 videoPlayId, std_::unique_ptr<VideoS _frame = av_frame_alloc(); } -bool ChildFFMpegLoader::open(qint64 position) { +bool ChildFFMpegLoader::open(qint64 &position) { int res = 0; char err[AV_ERROR_MAX_STRING_SIZE] = { 0 }; @@ -100,6 +100,7 @@ bool ChildFFMpegLoader::open(qint64 position) { _sampleSize = AudioToChannels * sizeof(short); _parentData->frequency = _dstRate; _parentData->length = av_rescale_rnd(_parentData->length, _dstRate, _srcRate, AV_ROUND_UP); + position = av_rescale_rnd(position, _dstRate, _srcRate, AV_ROUND_DOWN); _format = AL_FORMAT_STEREO16; _maxResampleSamples = av_rescale_rnd(AVBlockSize / _sampleSize, _dstRate, _srcRate, AV_ROUND_UP); diff --git a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h index 69926bfb8..ad92459ab 100644 --- a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h +++ b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.h @@ -83,7 +83,7 @@ class ChildFFMpegLoader : public AudioPlayerLoader { public: ChildFFMpegLoader(uint64 videoPlayId, std_::unique_ptr<VideoSoundData> &&data); - bool open(qint64 position = 0) override; + bool open(qint64 &position) override; bool check(const FileLocation &file, const QByteArray &data) override { return true; diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp index 8e321eb16..3104c4d9f 100644 --- a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp +++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp @@ -96,7 +96,10 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readNextFrame() { _currentFrameDelay = _nextFrameDelay; if (_frameMs + _currentFrameDelay < frameMs) { _currentFrameDelay = int32(frameMs - _frameMs); + } else if (frameMs < _frameMs + _currentFrameDelay) { + frameMs = _frameMs + _currentFrameDelay; } + if (duration == AV_NOPTS_VALUE) { _nextFrameDelay = 0; } else { @@ -129,7 +132,7 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readNextFrame() { avcodec_flush_buffers(_codecContext); _hadFrame = false; _frameMs = 0; - _lastReadPacketMs = 0; + _lastReadVideoMs = _lastReadAudioMs = 0; } } @@ -154,7 +157,6 @@ ReaderImplementation::ReadResult FFMpegReaderImplementation::readFramesTill(int6 // sync by audio stream auto correctMs = (frameMs >= 0) ? audioPlayer()->getVideoCorrectedTime(_playId, frameMs, systemMs) : frameMs; - if (!_frameRead) { auto readResult = readNextFrame(); if (readResult != ReadResult::Success) { @@ -237,7 +239,8 @@ bool FFMpegReaderImplementation::renderFrame(QImage &to, bool &hasAlpha, const Q // Read some future packets for audio stream. if (_audioStreamId >= 0) { - while (_frameMs + 5000 > _lastReadPacketMs) { + while (_frameMs + 5000 > _lastReadAudioMs + && _frameMs + 15000 > _lastReadVideoMs) { auto packetResult = readAndProcessPacket(); if (packetResult != PacketResult::Ok) { break; @@ -327,16 +330,16 @@ bool FFMpegReaderImplementation::start(Mode mode, int64 &positionMs) { if ((res = avcodec_open2(audioContext, audioCodec, 0)) < 0) { avcodec_free_context(&audioContext); LOG(("Gif Error: Unable to avcodec_open2 %1, error %2, %3").arg(logData()).arg(res).arg(av_make_error_string(err, sizeof(err), res))); - return false; - } - - soundData = std_::make_unique<VideoSoundData>(); - soundData->context = audioContext; - soundData->frequency = audioContextOriginal->sample_rate; - if (_fmtContext->streams[_audioStreamId]->duration == AV_NOPTS_VALUE) { - soundData->length = (_fmtContext->duration * soundData->frequency) / AV_TIME_BASE; + _audioStreamId = -1; } else { - soundData->length = (_fmtContext->streams[_audioStreamId]->duration * soundData->frequency * _fmtContext->streams[_audioStreamId]->time_base.num) / _fmtContext->streams[_audioStreamId]->time_base.den; + soundData = std_::make_unique<VideoSoundData>(); + soundData->context = audioContext; + soundData->frequency = audioContextOriginal->sample_rate; + if (_fmtContext->streams[_audioStreamId]->duration == AV_NOPTS_VALUE) { + soundData->length = (_fmtContext->duration * soundData->frequency) / AV_TIME_BASE; + } else { + soundData->length = (_fmtContext->streams[_audioStreamId]->duration * soundData->frequency * _fmtContext->streams[_audioStreamId]->time_base.num) / _fmtContext->streams[_audioStreamId]->time_base.den; + } } } @@ -425,11 +428,13 @@ void FFMpegReaderImplementation::processPacket(AVPacket *packet) { bool videoPacket = (packet->stream_index == _streamId); bool audioPacket = (_audioStreamId >= 0 && packet->stream_index == _audioStreamId); if (audioPacket || videoPacket) { - _lastReadPacketMs = countPacketMs(packet); - if (videoPacket) { + _lastReadVideoMs = countPacketMs(packet); + _packetQueue.enqueue(FFMpeg::dataWrapFromPacket(*packet)); } else if (audioPacket) { + _lastReadAudioMs = countPacketMs(packet); + // queue packet to audio player VideoSoundPart part; part.packet = packet; diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.h b/Telegram/SourceFiles/media/media_clip_ffmpeg.h index c73fdc8ac..e9cf5074c 100644 --- a/Telegram/SourceFiles/media/media_clip_ffmpeg.h +++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.h @@ -92,7 +92,8 @@ private: int _audioStreamId = 0; uint64 _playId = 0; - int64 _lastReadPacketMs = 0; + int64 _lastReadVideoMs = 0; + int64 _lastReadAudioMs = 0; QQueue<FFMpeg::AVPacketDataWrap> _packetQueue; AVPacket _packetNull; // for final decoding diff --git a/Telegram/SourceFiles/media/media_clip_reader.cpp b/Telegram/SourceFiles/media/media_clip_reader.cpp index 0795ada90..ffb5cca8a 100644 --- a/Telegram/SourceFiles/media/media_clip_reader.cpp +++ b/Telegram/SourceFiles/media/media_clip_reader.cpp @@ -489,7 +489,6 @@ public: int64 delta = static_cast<int64>(ms) - static_cast<int64>(_videoPausedAtMs); _animationStarted += delta; _nextFrameWhen += delta; - LOG(("RESUME VIDEO: next when: %1, started: %2, delta: %3").arg(_nextFrameWhen).arg(_animationStarted).arg(delta)); _videoPausedAtMs = 0; _implementation->resumeAudio();