diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp index 32ad6af85..1fb5ad077 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp @@ -268,7 +268,7 @@ bool Player::fileReady(Stream &&video, Stream &&audio) { error(_video)); } else if (video.index >= 0) { LOG(("Streaming Error: No codec for video stream %1, mode %2." - ).arg(audio.index + ).arg(video.index ).arg(int(mode))); return false; } diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_video_track.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_video_track.cpp index b91cb1d46..39fc2e1f5 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_video_track.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_video_track.cpp @@ -412,7 +412,6 @@ void VideoTrackObject::callReady() { Expects(_ready != nullptr); const auto frame = _shared->frameForPaint(); - Assert(frame != nullptr); auto data = VideoInformation(); data.size = CorrectByAspect(frame->original.size(), _stream.aspect); @@ -603,9 +602,13 @@ auto VideoTrack::Shared::presentFrame( } crl::time VideoTrack::Shared::nextFrameDisplayTime() const { - const auto frameDisplayTime = [&](int index) { + const auto frameDisplayTime = [&](int counter) { + const auto next = (counter + 1) % (2 * kFramesCount); + const auto index = next / 2; const auto frame = getFrame(index); - Assert(frame->displayed == kTimeUnknown); + Assert(IsRasterized(frame)); + Assert(frame->display != kTimeUnknown); + return frame->display; }; @@ -613,43 +616,50 @@ crl::time VideoTrack::Shared::nextFrameDisplayTime() const { case 0: return kTimeUnknown; case 1: return frameDisplayTime(1); case 2: return kTimeUnknown; - case 3: return frameDisplayTime(2); + case 3: return frameDisplayTime(3); case 4: return kTimeUnknown; - case 5: return frameDisplayTime(3); + case 5: return frameDisplayTime(5); case 6: return kTimeUnknown; - case 7: return frameDisplayTime(0); + case 7: return frameDisplayTime(7); } Unexpected("Counter value in VideoTrack::Shared::nextFrameDisplayTime."); } crl::time VideoTrack::Shared::markFrameDisplayed(crl::time now) { - const auto markAndJump = [&](int counter, int index) { + const auto markAndJump = [&](int counter) { + const auto next = (counter + 1) % (2 * kFramesCount); + const auto index = next / 2; const auto frame = getFrame(index); + Assert(frame->position != kTimeUnknown); Assert(frame->displayed == kTimeUnknown); frame->displayed = now; _counter.store( - (counter + 1) % (2 * kFramesCount), + next, std::memory_order_release); return frame->position; }; switch (counter()) { - case 0: return kTimeUnknown; - case 1: return markAndJump(1, 1); - case 2: return kTimeUnknown; - case 3: return markAndJump(3, 2); - case 4: return kTimeUnknown; - case 5: return markAndJump(5, 3); - case 6: return kTimeUnknown; - case 7: return markAndJump(7, 0); + case 0: Unexpected("Value 0 in VideoTrack::Shared::markFrameDisplayed."); + case 1: return markAndJump(1); + case 2: Unexpected("Value 2 in VideoTrack::Shared::markFrameDisplayed."); + case 3: return markAndJump(3); + case 4: Unexpected("Value 4 in VideoTrack::Shared::markFrameDisplayed."); + case 5: return markAndJump(5); + case 6: Unexpected("Value 6 in VideoTrack::Shared::markFrameDisplayed."); + case 7: return markAndJump(7); } Unexpected("Counter value in VideoTrack::Shared::markFrameDisplayed."); } not_null VideoTrack::Shared::frameForPaint() { - // #TODO streaming optimize mark as displayed if possible - return getFrame(counter() / 2); + const auto result = getFrame(counter() / 2); + Assert(!result->original.isNull()); + Assert(result->position != kTimeUnknown); + Assert(result->displayed != kTimeUnknown); + + return result; } VideoTrack::VideoTrack( @@ -719,13 +729,13 @@ crl::time VideoTrack::nextFrameDisplayTime() const { } crl::time VideoTrack::markFrameDisplayed(crl::time now) { - const auto position = _shared->markFrameDisplayed(now); - if (position != kTimeUnknown) { - _wrapped.with([](Implementation &unwrapped) { - unwrapped.frameDisplayed(); - }); - } - return position; + const auto result = _shared->markFrameDisplayed(now); + _wrapped.with([](Implementation &unwrapped) { + unwrapped.frameDisplayed(); + }); + + Ensures(result != kTimeUnknown); + return result; } QImage VideoTrack::frame(const FrameRequest &request) { @@ -756,17 +766,17 @@ QImage VideoTrack::PrepareFrameByRequest( return frame->prepared; } -bool VideoTrack::IsDecoded(not_null frame) { +bool VideoTrack::IsDecoded(not_null frame) { return (frame->position != kTimeUnknown) && (frame->displayed == kTimeUnknown); } -bool VideoTrack::IsRasterized(not_null frame) { +bool VideoTrack::IsRasterized(not_null frame) { return IsDecoded(frame) && !frame->original.isNull(); } -bool VideoTrack::IsStale(not_null frame, crl::time trackTime) { +bool VideoTrack::IsStale(not_null frame, crl::time trackTime) { Expects(IsDecoded(frame)); return (frame->position < trackTime); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_video_track.h b/Telegram/SourceFiles/media/streaming/media_streaming_video_track.h index ffff3d9bb..20c63cf9c 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_video_track.h +++ b/Telegram/SourceFiles/media/streaming/media_streaming_video_track.h @@ -120,10 +120,10 @@ private: static QImage PrepareFrameByRequest( not_null frame, bool useExistingPrepared = false); - [[nodiscard]] static bool IsDecoded(not_null frame); - [[nodiscard]] static bool IsRasterized(not_null frame); + [[nodiscard]] static bool IsDecoded(not_null frame); + [[nodiscard]] static bool IsRasterized(not_null frame); [[nodiscard]] static bool IsStale( - not_null frame, + not_null frame, crl::time trackTime); const int _streamIndex = 0;