init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
This commit is contained in:
172
Telegram/SourceFiles/ui/peer/video_userpic_player.cpp
Normal file
172
Telegram/SourceFiles/ui/peer/video_userpic_player.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/peer/video_userpic_player.h"
|
||||
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_streaming.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "media/streaming/media_streaming_instance.h"
|
||||
#include "media/streaming/media_streaming_player.h"
|
||||
#include "media/streaming/media_streaming_document.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/empty_userpic.h"
|
||||
#include "ui/painter.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
VideoUserpicPlayer::VideoUserpicPlayer() = default;
|
||||
|
||||
VideoUserpicPlayer::~VideoUserpicPlayer() = default;
|
||||
|
||||
void VideoUserpicPlayer::setup(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<PhotoData*> photo) {
|
||||
if (_streamedPhoto == photo && _streamed && _peer == peer) {
|
||||
return;
|
||||
}
|
||||
if (!createStreaming(peer, photo)) {
|
||||
photo->setVideoPlaybackFailed();
|
||||
return;
|
||||
}
|
||||
_streamedPhoto = photo;
|
||||
_peer = peer;
|
||||
checkStarted();
|
||||
}
|
||||
|
||||
void VideoUserpicPlayer::clear() {
|
||||
_streamed = nullptr;
|
||||
_streamedPhoto = nullptr;
|
||||
_peer = nullptr;
|
||||
}
|
||||
|
||||
QImage VideoUserpicPlayer::frame(QSize size, not_null<PeerData*> peer) {
|
||||
if (!_streamed
|
||||
|| !_streamed->player().ready()
|
||||
|| _streamed->player().videoSize().isEmpty()
|
||||
|| !_streamedPhoto) {
|
||||
return {};
|
||||
}
|
||||
auto request = ::Media::Streaming::FrameRequest();
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
request.outer = request.resize = size * ratio;
|
||||
|
||||
const auto broadcast = peer->monoforumBroadcast();
|
||||
|
||||
if (broadcast) {
|
||||
if (_monoforumMask.isNull()) {
|
||||
_monoforumMask = Ui::MonoforumShapeMask(request.resize);
|
||||
}
|
||||
} else if (peer->isForum()) {
|
||||
const auto radius = int(
|
||||
size.width() * Ui::ForumUserpicRadiusMultiplier());
|
||||
if (_roundingCorners[0].width() != radius * ratio) {
|
||||
_roundingCorners = Images::CornersMask(radius);
|
||||
}
|
||||
request.rounding = Images::CornersMaskRef(_roundingCorners);
|
||||
} else {
|
||||
if (_ellipseMask.size() != request.outer) {
|
||||
_ellipseMask = Images::EllipseMask(size);
|
||||
}
|
||||
request.mask = _ellipseMask;
|
||||
}
|
||||
|
||||
auto result = _streamed->frame(request);
|
||||
if (broadcast) {
|
||||
constexpr auto kFormat = QImage::Format_ARGB32_Premultiplied;
|
||||
if (result.format() != kFormat) {
|
||||
result = std::move(result).convertToFormat(kFormat);
|
||||
}
|
||||
auto q = QPainter(&result);
|
||||
q.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
q.drawImage(
|
||||
QRect(QPoint(), result.size() / result.devicePixelRatio()),
|
||||
_monoforumMask);
|
||||
q.end();
|
||||
}
|
||||
_streamed->markFrameShown();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool VideoUserpicPlayer::ready() const {
|
||||
return _streamed
|
||||
&& _streamed->player().ready()
|
||||
&& !_streamed->player().videoSize().isEmpty();
|
||||
}
|
||||
|
||||
bool VideoUserpicPlayer::createStreaming(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<PhotoData*> photo) {
|
||||
using namespace ::Media::Streaming;
|
||||
const auto origin = peer->isUser()
|
||||
? Data::FileOriginUserPhoto(peerToUser(peer->id), photo->id)
|
||||
: Data::FileOrigin(Data::FileOriginPeerPhoto(peer->id));
|
||||
_streamed = std::make_unique<Instance>(
|
||||
photo->owner().streaming().sharedDocument(photo, origin),
|
||||
nullptr);
|
||||
_streamed->lockPlayer();
|
||||
_streamed->player().updates(
|
||||
) | rpl::on_next_error([=](Update &&update) {
|
||||
handleUpdate(std::move(update));
|
||||
}, [=](Error &&error) {
|
||||
handleError(std::move(error));
|
||||
}, _streamed->lifetime());
|
||||
if (_streamed->ready()) {
|
||||
streamingReady(base::duplicate(_streamed->info()));
|
||||
}
|
||||
if (!_streamed->valid()) {
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void VideoUserpicPlayer::checkStarted() {
|
||||
if (!_streamed) {
|
||||
return;
|
||||
} else if (_streamed->paused()) {
|
||||
_streamed->resume();
|
||||
}
|
||||
if (_streamed && !_streamed->active() && !_streamed->failed()) {
|
||||
const auto position = _streamedPhoto->videoStartPosition();
|
||||
auto options = ::Media::Streaming::PlaybackOptions();
|
||||
options.position = position;
|
||||
options.mode = ::Media::Streaming::Mode::Video;
|
||||
options.loop = true;
|
||||
_streamed->play(options);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoUserpicPlayer::handleUpdate(
|
||||
::Media::Streaming::Update &&update) {
|
||||
using namespace ::Media::Streaming;
|
||||
v::match(update.data, [&](Information &update) {
|
||||
streamingReady(std::move(update));
|
||||
}, [](PreloadedVideo) {
|
||||
}, [](UpdateVideo) {
|
||||
}, [](PreloadedAudio) {
|
||||
}, [](UpdateAudio) {
|
||||
}, [](WaitingForData) {
|
||||
}, [](SpeedEstimate) {
|
||||
}, [](MutedByOther) {
|
||||
}, [](Finished) {
|
||||
});
|
||||
}
|
||||
|
||||
void VideoUserpicPlayer::handleError(::Media::Streaming::Error &&error) {
|
||||
_streamedPhoto->setVideoPlaybackFailed();
|
||||
clear();
|
||||
}
|
||||
|
||||
void VideoUserpicPlayer::streamingReady(
|
||||
::Media::Streaming::Information &&info) {
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
Reference in New Issue
Block a user