mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Support quality change in PiP.
This commit is contained in:
parent
3cfa963f69
commit
0971485367
5 changed files with 182 additions and 42 deletions
|
@ -17,6 +17,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Media {
|
namespace Media {
|
||||||
namespace Streaming {
|
namespace Streaming {
|
||||||
|
|
||||||
|
Instance::Instance(const Instance &other)
|
||||||
|
: _shared(other._shared)
|
||||||
|
, _waitingCallback(other._waitingCallback)
|
||||||
|
, _priority(other._priority)
|
||||||
|
, _playerLocked(other._playerLocked) {
|
||||||
|
if (_shared) {
|
||||||
|
_shared->registerInstance(this);
|
||||||
|
if (_playerLocked) {
|
||||||
|
_shared->player().lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Instance::Instance(
|
Instance::Instance(
|
||||||
std::shared_ptr<Document> shared,
|
std::shared_ptr<Document> shared,
|
||||||
Fn<void()> waitingCallback)
|
Fn<void()> waitingCallback)
|
||||||
|
|
|
@ -27,6 +27,7 @@ class Player;
|
||||||
|
|
||||||
class Instance {
|
class Instance {
|
||||||
public:
|
public:
|
||||||
|
Instance(const Instance &other);
|
||||||
Instance(
|
Instance(
|
||||||
std::shared_ptr<Document> shared,
|
std::shared_ptr<Document> shared,
|
||||||
Fn<void()> waitingCallback);
|
Fn<void()> waitingCallback);
|
||||||
|
|
|
@ -345,6 +345,10 @@ struct OverlayWidget::PipWrap {
|
||||||
PipWrap(
|
PipWrap(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
|
Data::FileOrigin origin,
|
||||||
|
not_null<DocumentData*> chosenQuality,
|
||||||
|
HistoryItem *context,
|
||||||
|
VideoQuality quality,
|
||||||
std::shared_ptr<Streaming::Document> shared,
|
std::shared_ptr<Streaming::Document> shared,
|
||||||
FnMut<void()> closeAndContinue,
|
FnMut<void()> closeAndContinue,
|
||||||
FnMut<void()> destroy);
|
FnMut<void()> destroy);
|
||||||
|
@ -470,6 +474,10 @@ OverlayWidget::Streamed::Streamed(
|
||||||
OverlayWidget::PipWrap::PipWrap(
|
OverlayWidget::PipWrap::PipWrap(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
|
Data::FileOrigin origin,
|
||||||
|
not_null<DocumentData*> chosenQuality,
|
||||||
|
HistoryItem *context,
|
||||||
|
VideoQuality quality,
|
||||||
std::shared_ptr<Streaming::Document> shared,
|
std::shared_ptr<Streaming::Document> shared,
|
||||||
FnMut<void()> closeAndContinue,
|
FnMut<void()> closeAndContinue,
|
||||||
FnMut<void()> destroy)
|
FnMut<void()> destroy)
|
||||||
|
@ -477,6 +485,10 @@ OverlayWidget::PipWrap::PipWrap(
|
||||||
, wrapped(
|
, wrapped(
|
||||||
&delegate,
|
&delegate,
|
||||||
document,
|
document,
|
||||||
|
origin,
|
||||||
|
chosenQuality,
|
||||||
|
context,
|
||||||
|
quality,
|
||||||
std::move(shared),
|
std::move(shared),
|
||||||
std::move(closeAndContinue),
|
std::move(closeAndContinue),
|
||||||
std::move(destroy)) {
|
std::move(destroy)) {
|
||||||
|
@ -3849,10 +3861,14 @@ bool OverlayWidget::initStreaming(const StartStreaming &startStreaming) {
|
||||||
});
|
});
|
||||||
}, _streamed->instance.lifetime());
|
}, _streamed->instance.lifetime());
|
||||||
|
|
||||||
|
const auto continuing = startStreaming.continueStreaming
|
||||||
|
&& _pip
|
||||||
|
&& (_pip->wrapped.shared().get()
|
||||||
|
== _streamed->instance.shared().get());
|
||||||
if (startStreaming.continueStreaming) {
|
if (startStreaming.continueStreaming) {
|
||||||
_pip = nullptr;
|
_pip = nullptr;
|
||||||
}
|
}
|
||||||
if (!startStreaming.continueStreaming
|
if (!continuing
|
||||||
|| (!_streamed->instance.player().active()
|
|| (!_streamed->instance.player().active()
|
||||||
&& !_streamed->instance.player().finished())) {
|
&& !_streamed->instance.player().finished())) {
|
||||||
startStreamingPlayer(startStreaming);
|
startStreamingPlayer(startStreaming);
|
||||||
|
@ -4517,6 +4533,10 @@ void OverlayWidget::switchToPip() {
|
||||||
_pip = std::make_unique<PipWrap>(
|
_pip = std::make_unique<PipWrap>(
|
||||||
_window,
|
_window,
|
||||||
document,
|
document,
|
||||||
|
fileOrigin(),
|
||||||
|
_chosenQuality ? _chosenQuality : document,
|
||||||
|
_message,
|
||||||
|
_quality,
|
||||||
_streamed->instance.shared(),
|
_streamed->instance.shared(),
|
||||||
closeAndContinue,
|
closeAndContinue,
|
||||||
[=] { _pip = nullptr; });
|
[=] { _pip = nullptr; });
|
||||||
|
|
|
@ -885,18 +885,30 @@ void PipPanel::updateDecorations() {
|
||||||
Pip::Pip(
|
Pip::Pip(
|
||||||
not_null<Delegate*> delegate,
|
not_null<Delegate*> delegate,
|
||||||
not_null<DocumentData*> data,
|
not_null<DocumentData*> data,
|
||||||
|
Data::FileOrigin origin,
|
||||||
|
not_null<DocumentData*> chosenQuality,
|
||||||
|
HistoryItem *context,
|
||||||
|
VideoQuality quality,
|
||||||
std::shared_ptr<Streaming::Document> shared,
|
std::shared_ptr<Streaming::Document> shared,
|
||||||
FnMut<void()> closeAndContinue,
|
FnMut<void()> closeAndContinue,
|
||||||
FnMut<void()> destroy)
|
FnMut<void()> destroy)
|
||||||
: _delegate(delegate)
|
: _delegate(delegate)
|
||||||
, _data(data)
|
, _data(data)
|
||||||
, _instance(std::move(shared), [=] { waitingAnimationCallback(); })
|
, _origin(origin)
|
||||||
|
, _chosenQuality(chosenQuality)
|
||||||
|
, _context(context)
|
||||||
|
, _quality(quality)
|
||||||
|
, _instance(
|
||||||
|
std::in_place,
|
||||||
|
std::move(shared),
|
||||||
|
[=] { waitingAnimationCallback(); })
|
||||||
, _panel(
|
, _panel(
|
||||||
_delegate->pipParentWidget(),
|
_delegate->pipParentWidget(),
|
||||||
[=](Ui::GL::Capabilities capabilities) {
|
[=](Ui::GL::Capabilities capabilities) {
|
||||||
return chooseRenderer(capabilities);
|
return chooseRenderer(capabilities);
|
||||||
})
|
})
|
||||||
, _playbackProgress(std::make_unique<PlaybackProgress>())
|
, _playbackProgress(std::make_unique<PlaybackProgress>())
|
||||||
|
, _dataMedia(_data->createMediaView())
|
||||||
, _rotation(data->owner().mediaRotation().get(data))
|
, _rotation(data->owner().mediaRotation().get(data))
|
||||||
, _lastPositiveVolume((Core::App().settings().videoVolume() > 0.)
|
, _lastPositiveVolume((Core::App().settings().videoVolume() > 0.)
|
||||||
? Core::App().settings().videoVolume()
|
? Core::App().settings().videoVolume()
|
||||||
|
@ -911,15 +923,28 @@ Pip::Pip(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
_destroy();
|
_destroy();
|
||||||
}, _panel.rp()->lifetime());
|
}, _panel.rp()->lifetime());
|
||||||
|
|
||||||
|
if (_context) {
|
||||||
|
_data->owner().itemRemoved(
|
||||||
|
) | rpl::start_with_next([=](not_null<const HistoryItem*> data) {
|
||||||
|
if (_context != data) {
|
||||||
|
_context = nullptr;
|
||||||
|
}
|
||||||
|
}, _panel.rp()->lifetime());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pip::~Pip() = default;
|
Pip::~Pip() = default;
|
||||||
|
|
||||||
|
std::shared_ptr<Streaming::Document> Pip::shared() const {
|
||||||
|
return _instance->shared();
|
||||||
|
}
|
||||||
|
|
||||||
void Pip::setupPanel() {
|
void Pip::setupPanel() {
|
||||||
_panel.init();
|
_panel.init();
|
||||||
const auto size = [&] {
|
const auto size = [&] {
|
||||||
if (!_instance.info().video.size.isEmpty()) {
|
if (!_instance->info().video.size.isEmpty()) {
|
||||||
return _instance.info().video.size;
|
return _instance->info().video.size;
|
||||||
}
|
}
|
||||||
const auto media = _data->activeMediaView();
|
const auto media = _data->activeMediaView();
|
||||||
if (media) {
|
if (media) {
|
||||||
|
@ -1138,8 +1163,8 @@ void Pip::seekProgress(float64 value) {
|
||||||
_lastDurationMs);
|
_lastDurationMs);
|
||||||
if (_seekPositionMs != positionMs) {
|
if (_seekPositionMs != positionMs) {
|
||||||
_seekPositionMs = positionMs;
|
_seekPositionMs = positionMs;
|
||||||
if (!_instance.player().paused()
|
if (!_instance->player().paused()
|
||||||
&& !_instance.player().finished()) {
|
&& !_instance->player().finished()) {
|
||||||
_pausedBySeek = true;
|
_pausedBySeek = true;
|
||||||
playbackPauseResume();
|
playbackPauseResume();
|
||||||
}
|
}
|
||||||
|
@ -1157,7 +1182,7 @@ void Pip::seekFinish(float64 value) {
|
||||||
crl::time(0),
|
crl::time(0),
|
||||||
_lastDurationMs);
|
_lastDurationMs);
|
||||||
_seekPositionMs = -1;
|
_seekPositionMs = -1;
|
||||||
_startPaused = !_pausedBySeek && !_instance.player().finished();
|
_startPaused = !_pausedBySeek && !_instance->player().finished();
|
||||||
restartAtSeekPosition(positionMs);
|
restartAtSeekPosition(positionMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1294,18 +1319,71 @@ void Pip::updatePlayPauseResumeState(const Player::TrackState &state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pip::setupStreaming() {
|
void Pip::setupStreaming() {
|
||||||
_instance.setPriority(kPipLoaderPriority);
|
_instance->setPriority(kPipLoaderPriority);
|
||||||
_instance.lockPlayer();
|
_instance->lockPlayer();
|
||||||
|
|
||||||
_instance.player().updates(
|
_instance->switchQualityRequests(
|
||||||
|
) | rpl::filter([=](int quality) {
|
||||||
|
return !_quality.manual && _quality.height != quality;
|
||||||
|
}) | rpl::start_with_next([=](int quality) {
|
||||||
|
applyVideoQuality({
|
||||||
|
.manual = 0,
|
||||||
|
.height = uint32(quality),
|
||||||
|
});
|
||||||
|
}, _instance->lifetime());
|
||||||
|
|
||||||
|
_instance->player().updates(
|
||||||
) | rpl::start_with_next_error([=](Streaming::Update &&update) {
|
) | rpl::start_with_next_error([=](Streaming::Update &&update) {
|
||||||
handleStreamingUpdate(std::move(update));
|
handleStreamingUpdate(std::move(update));
|
||||||
}, [=](Streaming::Error &&error) {
|
}, [=](Streaming::Error &&error) {
|
||||||
handleStreamingError(std::move(error));
|
handleStreamingError(std::move(error));
|
||||||
}, _instance.lifetime());
|
}, _instance->lifetime());
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pip::applyVideoQuality(VideoQuality value) {
|
||||||
|
if (_quality == value
|
||||||
|
|| !_dataMedia->canBePlayed(_context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto resolved = _data->chooseQuality(_context, value);
|
||||||
|
if (_chosenQuality == resolved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto instance = Streaming::Instance(
|
||||||
|
resolved,
|
||||||
|
_data,
|
||||||
|
_context,
|
||||||
|
_origin,
|
||||||
|
[=] { waitingAnimationCallback(); });
|
||||||
|
if (!instance.valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_instance->ready()) {
|
||||||
|
_qualityChangeFrame = currentVideoFrameImage();
|
||||||
|
}
|
||||||
|
if (!_instance->player().active()
|
||||||
|
|| _instance->player().finished()) {
|
||||||
|
_qualityChangeFinished = true;
|
||||||
|
}
|
||||||
|
_startPaused = _qualityChangeFinished || _instance->player().paused();
|
||||||
|
|
||||||
|
_quality = value;
|
||||||
|
Core::App().settings().setVideoQuality(value);
|
||||||
|
Core::App().saveSettingsDelayed();
|
||||||
|
_chosenQuality = resolved;
|
||||||
|
_instance.emplace(std::move(instance));
|
||||||
|
setupStreaming();
|
||||||
|
restartAtSeekPosition(_lastUpdatePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage Pip::currentVideoFrameImage() const {
|
||||||
|
return _instance->player().ready()
|
||||||
|
? _instance->player().currentFrameImage()
|
||||||
|
: _instance->info().video.cover;
|
||||||
|
}
|
||||||
|
|
||||||
Ui::GL::ChosenRenderer Pip::chooseRenderer(
|
Ui::GL::ChosenRenderer Pip::chooseRenderer(
|
||||||
Ui::GL::Capabilities capabilities) {
|
Ui::GL::Capabilities capabilities) {
|
||||||
const auto use = Platform::IsMac()
|
const auto use = Platform::IsMac()
|
||||||
|
@ -1336,12 +1414,12 @@ void Pip::paint(not_null<Renderer*> renderer) const {
|
||||||
.fade = controlsShown,
|
.fade = controlsShown,
|
||||||
.outer = _panel.widget()->size(),
|
.outer = _panel.widget()->size(),
|
||||||
.rotation = _rotation,
|
.rotation = _rotation,
|
||||||
.videoRotation = _instance.info().video.rotation,
|
.videoRotation = _instance->info().video.rotation,
|
||||||
.useTransparency = _panel.useTransparency(),
|
.useTransparency = _panel.useTransparency(),
|
||||||
};
|
};
|
||||||
if (canUseVideoFrame()) {
|
if (canUseVideoFrame()) {
|
||||||
renderer->paintTransformedVideoFrame(geometry);
|
renderer->paintTransformedVideoFrame(geometry);
|
||||||
_instance.markFrameShown();
|
_instance->markFrameShown();
|
||||||
} else {
|
} else {
|
||||||
const auto content = staticContent();
|
const auto content = staticContent();
|
||||||
if (_preparedCoverState == ThumbState::Cover) {
|
if (_preparedCoverState == ThumbState::Cover) {
|
||||||
|
@ -1349,7 +1427,7 @@ void Pip::paint(not_null<Renderer*> renderer) const {
|
||||||
}
|
}
|
||||||
renderer->paintTransformedStaticContent(content, geometry);
|
renderer->paintTransformedStaticContent(content, geometry);
|
||||||
}
|
}
|
||||||
if (_instance.waitingShown()) {
|
if (_instance->waitingShown()) {
|
||||||
renderer->paintRadialLoading(countRadialRect(), controlsShown);
|
renderer->paintRadialLoading(countRadialRect(), controlsShown);
|
||||||
}
|
}
|
||||||
if (controlsShown > 0) {
|
if (controlsShown > 0) {
|
||||||
|
@ -1535,12 +1613,14 @@ void Pip::handleStreamingUpdate(Streaming::Update &&update) {
|
||||||
v::match(update.data, [&](const Information &update) {
|
v::match(update.data, [&](const Information &update) {
|
||||||
_panel.setAspectRatio(
|
_panel.setAspectRatio(
|
||||||
FlipSizeByRotation(update.video.size, _rotation));
|
FlipSizeByRotation(update.video.size, _rotation));
|
||||||
|
_qualityChangeFrame = QImage();
|
||||||
}, [&](PreloadedVideo) {
|
}, [&](PreloadedVideo) {
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
}, [&](UpdateVideo) {
|
}, [&](UpdateVideo update) {
|
||||||
_panel.update();
|
_panel.update();
|
||||||
Core::App().updateNonIdle();
|
Core::App().updateNonIdle();
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
|
_lastUpdatePosition = update.position;
|
||||||
}, [&](PreloadedAudio) {
|
}, [&](PreloadedAudio) {
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
}, [&](UpdateAudio) {
|
}, [&](UpdateAudio) {
|
||||||
|
@ -1554,7 +1634,7 @@ void Pip::handleStreamingUpdate(Streaming::Update &&update) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pip::updatePlaybackState() {
|
void Pip::updatePlaybackState() {
|
||||||
const auto state = _instance.player().prepareLegacyState();
|
const auto state = _instance->player().prepareLegacyState();
|
||||||
updatePlayPauseResumeState(state);
|
updatePlayPauseResumeState(state);
|
||||||
if (state.position == kTimeUnknown
|
if (state.position == kTimeUnknown
|
||||||
|| state.length == kTimeUnknown
|
|| state.length == kTimeUnknown
|
||||||
|
@ -1619,61 +1699,65 @@ void Pip::handleStreamingError(Streaming::Error &&error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pip::playbackPauseResume() {
|
void Pip::playbackPauseResume() {
|
||||||
if (_instance.player().failed()) {
|
if (_instance->player().failed()) {
|
||||||
_panel.widget()->close();
|
_panel.widget()->close();
|
||||||
} else if (_instance.player().finished()
|
} else if (_instance->player().finished()
|
||||||
|| !_instance.player().active()) {
|
|| !_instance->player().active()) {
|
||||||
_startPaused = false;
|
_startPaused = false;
|
||||||
restartAtSeekPosition(0);
|
restartAtSeekPosition(0);
|
||||||
} else if (_instance.player().paused()) {
|
} else if (_instance->player().paused()) {
|
||||||
_instance.resume();
|
_instance->resume();
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
} else {
|
} else {
|
||||||
_instance.pause();
|
_instance->pause();
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pip::restartAtSeekPosition(crl::time position) {
|
void Pip::restartAtSeekPosition(crl::time position) {
|
||||||
if (!_instance.info().video.cover.isNull()) {
|
_lastUpdatePosition = position;
|
||||||
|
|
||||||
|
if (!_instance->info().video.cover.isNull()) {
|
||||||
_preparedCoverStorage = QImage();
|
_preparedCoverStorage = QImage();
|
||||||
_preparedCoverState = ThumbState::Empty;
|
_preparedCoverState = ThumbState::Empty;
|
||||||
_instance.saveFrameToCover();
|
_instance->saveFrameToCover();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto options = Streaming::PlaybackOptions();
|
auto options = Streaming::PlaybackOptions();
|
||||||
options.position = position;
|
options.position = position;
|
||||||
options.hwAllowed = Core::App().settings().hardwareAcceleratedVideo();
|
options.hwAllowed = Core::App().settings().hardwareAcceleratedVideo();
|
||||||
options.audioId = _instance.player().prepareLegacyState().id;
|
options.audioId = _instance->player().prepareLegacyState().id;
|
||||||
options.speed = _delegate->pipPlaybackSpeed();
|
options.speed = _delegate->pipPlaybackSpeed();
|
||||||
|
|
||||||
_instance.play(options);
|
_instance->play(options);
|
||||||
if (_startPaused) {
|
if (_startPaused) {
|
||||||
_instance.pause();
|
_instance->pause();
|
||||||
}
|
}
|
||||||
_pausedBySeek = false;
|
_pausedBySeek = false;
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pip::canUseVideoFrame() const {
|
bool Pip::canUseVideoFrame() const {
|
||||||
return _instance.player().ready()
|
return _instance->player().ready()
|
||||||
&& !_instance.info().video.cover.isNull();
|
&& !_instance->info().video.cover.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage Pip::videoFrame(const FrameRequest &request) const {
|
QImage Pip::videoFrame(const FrameRequest &request) const {
|
||||||
Expects(canUseVideoFrame());
|
Expects(canUseVideoFrame());
|
||||||
|
|
||||||
return _instance.frame(request);
|
return _instance->frame(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
Streaming::FrameWithInfo Pip::videoFrameWithInfo() const {
|
Streaming::FrameWithInfo Pip::videoFrameWithInfo() const {
|
||||||
Expects(canUseVideoFrame());
|
Expects(canUseVideoFrame());
|
||||||
|
|
||||||
return _instance.frameWithInfo();
|
return _instance->frameWithInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage Pip::staticContent() const {
|
QImage Pip::staticContent() const {
|
||||||
const auto &cover = _instance.info().video.cover;
|
const auto &cover = !_qualityChangeFrame.isNull()
|
||||||
|
? _qualityChangeFrame
|
||||||
|
: _instance->info().video.cover;
|
||||||
const auto media = _data->activeMediaView();
|
const auto media = _data->activeMediaView();
|
||||||
const auto use = media
|
const auto use = media
|
||||||
? media
|
? media
|
||||||
|
@ -1701,7 +1785,7 @@ QImage Pip::staticContent() const {
|
||||||
}
|
}
|
||||||
_preparedCoverState = state;
|
_preparedCoverState = state;
|
||||||
if (state == ThumbState::Cover) {
|
if (state == ThumbState::Cover) {
|
||||||
_preparedCoverStorage = _instance.info().video.cover;
|
_preparedCoverStorage = cover;
|
||||||
} else {
|
} else {
|
||||||
_preparedCoverStorage = (good
|
_preparedCoverStorage = (good
|
||||||
? good
|
? good
|
||||||
|
@ -1727,7 +1811,7 @@ void Pip::paintRadialLoadingContent(
|
||||||
st::radialLine,
|
st::radialLine,
|
||||||
st::radialLine,
|
st::radialLine,
|
||||||
st::radialLine));
|
st::radialLine));
|
||||||
p.setOpacity(_instance.waitingOpacity());
|
p.setOpacity(_instance->waitingOpacity());
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::radialBg);
|
p.setBrush(st::radialBg);
|
||||||
{
|
{
|
||||||
|
@ -1737,7 +1821,7 @@ void Pip::paintRadialLoadingContent(
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
Ui::InfiniteRadialAnimation::Draw(
|
Ui::InfiniteRadialAnimation::Draw(
|
||||||
p,
|
p,
|
||||||
_instance.waitingState(),
|
_instance->waitingState(),
|
||||||
arc.topLeft(),
|
arc.topLeft(),
|
||||||
arc.size(),
|
arc.size(),
|
||||||
_panel.widget()->width(),
|
_panel.widget()->width(),
|
||||||
|
|
|
@ -7,13 +7,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "media/streaming/media_streaming_instance.h"
|
#include "media/streaming/media_streaming_instance.h"
|
||||||
|
#include "media/media_common.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/round_rect.h"
|
#include "ui/round_rect.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
|
||||||
#include <QtCore/QPointer>
|
#include <QtCore/QPointer>
|
||||||
|
|
||||||
|
class HistoryItem;
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class PowerSaveBlocker;
|
class PowerSaveBlocker;
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
@ -32,12 +36,15 @@ struct Capabilities;
|
||||||
} // namespace GL
|
} // namespace GL
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Media {
|
namespace Media::Player {
|
||||||
namespace Player {
|
|
||||||
struct TrackState;
|
struct TrackState;
|
||||||
} // namespace Player
|
} // namespace Media::Player
|
||||||
|
|
||||||
namespace View {
|
namespace Media::Streaming {
|
||||||
|
class Document;
|
||||||
|
} // namespace Media::Streaming
|
||||||
|
|
||||||
|
namespace Media::View {
|
||||||
|
|
||||||
class PlaybackProgress;
|
class PlaybackProgress;
|
||||||
|
|
||||||
|
@ -134,11 +141,17 @@ public:
|
||||||
Pip(
|
Pip(
|
||||||
not_null<Delegate*> delegate,
|
not_null<Delegate*> delegate,
|
||||||
not_null<DocumentData*> data,
|
not_null<DocumentData*> data,
|
||||||
|
Data::FileOrigin origin,
|
||||||
|
not_null<DocumentData*> chosenQuality,
|
||||||
|
HistoryItem *context,
|
||||||
|
VideoQuality quality,
|
||||||
std::shared_ptr<Streaming::Document> shared,
|
std::shared_ptr<Streaming::Document> shared,
|
||||||
FnMut<void()> closeAndContinue,
|
FnMut<void()> closeAndContinue,
|
||||||
FnMut<void()> destroy);
|
FnMut<void()> destroy);
|
||||||
~Pip();
|
~Pip();
|
||||||
|
|
||||||
|
[[nodiscard]] std::shared_ptr<Streaming::Document> shared() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class OverState {
|
enum class OverState {
|
||||||
None,
|
None,
|
||||||
|
@ -245,6 +258,8 @@ private:
|
||||||
QRect outer,
|
QRect outer,
|
||||||
float64 shown) const;
|
float64 shown) const;
|
||||||
[[nodiscard]] QRect countRadialRect() const;
|
[[nodiscard]] QRect countRadialRect() const;
|
||||||
|
void applyVideoQuality(VideoQuality value);
|
||||||
|
[[nodiscard]] QImage currentVideoFrameImage() const;
|
||||||
|
|
||||||
void seekUpdate(QPoint position);
|
void seekUpdate(QPoint position);
|
||||||
void seekProgress(float64 value);
|
void seekProgress(float64 value);
|
||||||
|
@ -252,7 +267,11 @@ private:
|
||||||
|
|
||||||
const not_null<Delegate*> _delegate;
|
const not_null<Delegate*> _delegate;
|
||||||
const not_null<DocumentData*> _data;
|
const not_null<DocumentData*> _data;
|
||||||
Streaming::Instance _instance;
|
const Data::FileOrigin _origin;
|
||||||
|
DocumentData *_chosenQuality = nullptr;
|
||||||
|
HistoryItem *_context = nullptr;
|
||||||
|
Media::VideoQuality _quality;
|
||||||
|
std::optional<Streaming::Instance> _instance;
|
||||||
bool _opengl = false;
|
bool _opengl = false;
|
||||||
PipPanel _panel;
|
PipPanel _panel;
|
||||||
QSize _size;
|
QSize _size;
|
||||||
|
@ -260,6 +279,10 @@ private:
|
||||||
std::unique_ptr<PlaybackProgress> _playbackProgress;
|
std::unique_ptr<PlaybackProgress> _playbackProgress;
|
||||||
std::shared_ptr<Data::DocumentMedia> _dataMedia;
|
std::shared_ptr<Data::DocumentMedia> _dataMedia;
|
||||||
|
|
||||||
|
QImage _qualityChangeFrame;
|
||||||
|
bool _qualityChangeFinished = false;
|
||||||
|
crl::time _lastUpdatePosition = 0;
|
||||||
|
|
||||||
bool _showPause = false;
|
bool _showPause = false;
|
||||||
bool _startPaused = false;
|
bool _startPaused = false;
|
||||||
bool _pausedBySeek = false;
|
bool _pausedBySeek = false;
|
||||||
|
@ -288,5 +311,4 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace View
|
} // namespace Media::View
|
||||||
} // namespace Media
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue