Track qualities availability correctly.

This commit is contained in:
John Preston 2024-10-30 16:30:57 +04:00
parent bc8bf672b4
commit a386d70ae4
8 changed files with 51 additions and 13 deletions

View file

@ -551,6 +551,10 @@ DocumentData *Media::document() const {
return nullptr; return nullptr;
} }
bool Media::hasQualitiesList() const {
return false;
}
PhotoData *Media::photo() const { PhotoData *Media::photo() const {
return nullptr; return nullptr;
} }
@ -964,12 +968,14 @@ MediaFile::MediaFile(
not_null<HistoryItem*> parent, not_null<HistoryItem*> parent,
not_null<DocumentData*> document, not_null<DocumentData*> document,
bool skipPremiumEffect, bool skipPremiumEffect,
bool hasQualitiesList,
bool spoiler, bool spoiler,
crl::time ttlSeconds) crl::time ttlSeconds)
: Media(parent) : Media(parent)
, _document(document) , _document(document)
, _emoji(document->sticker() ? document->sticker()->alt : QString()) , _emoji(document->sticker() ? document->sticker()->alt : QString())
, _skipPremiumEffect(skipPremiumEffect) , _skipPremiumEffect(skipPremiumEffect)
, _hasQualitiesList(hasQualitiesList)
, _spoiler(spoiler) , _spoiler(spoiler)
, _ttlSeconds(ttlSeconds) { , _ttlSeconds(ttlSeconds) {
parent->history()->owner().registerDocumentItem(_document, parent); parent->history()->owner().registerDocumentItem(_document, parent);
@ -999,6 +1005,7 @@ std::unique_ptr<Media> MediaFile::clone(not_null<HistoryItem*> parent) {
parent, parent,
_document, _document,
!_document->session().premium(), !_document->session().premium(),
_hasQualitiesList,
_spoiler, _spoiler,
_ttlSeconds); _ttlSeconds);
} }
@ -1007,6 +1014,10 @@ DocumentData *MediaFile::document() const {
return _document; return _document;
} }
bool MediaFile::hasQualitiesList() const {
return _hasQualitiesList;
}
bool MediaFile::uploading() const { bool MediaFile::uploading() const {
return _document->uploading(); return _document->uploading();
} }

View file

@ -165,6 +165,7 @@ public:
virtual std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) = 0; virtual std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) = 0;
virtual DocumentData *document() const; virtual DocumentData *document() const;
virtual bool hasQualitiesList() const;
virtual PhotoData *photo() const; virtual PhotoData *photo() const;
virtual WebPageData *webpage() const; virtual WebPageData *webpage() const;
virtual MediaWebPageFlags webpageFlags() const; virtual MediaWebPageFlags webpageFlags() const;
@ -287,6 +288,7 @@ public:
not_null<HistoryItem*> parent, not_null<HistoryItem*> parent,
not_null<DocumentData*> document, not_null<DocumentData*> document,
bool skipPremiumEffect, bool skipPremiumEffect,
bool hasQualitiesList,
bool spoiler, bool spoiler,
crl::time ttlSeconds); crl::time ttlSeconds);
~MediaFile(); ~MediaFile();
@ -294,6 +296,7 @@ public:
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override; std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
DocumentData *document() const override; DocumentData *document() const override;
bool hasQualitiesList() const override;
bool uploading() const override; bool uploading() const override;
Storage::SharedMediaTypesMask sharedMediaTypes() const override; Storage::SharedMediaTypesMask sharedMediaTypes() const override;
@ -324,6 +327,7 @@ private:
not_null<DocumentData*> _document; not_null<DocumentData*> _document;
QString _emoji; QString _emoji;
bool _skipPremiumEffect = false; bool _skipPremiumEffect = false;
bool _hasQualitiesList = false;
bool _spoiler = false; bool _spoiler = false;
// Video (unsupported) / Voice / Round. // Video (unsupported) / Voice / Round.

View file

@ -297,12 +297,12 @@ std::unique_ptr<Data::Media> HistoryItem::CreateMedia(
return nullptr; return nullptr;
} }
return document->match([&](const MTPDdocument &document) -> Result { return document->match([&](const MTPDdocument &document) -> Result {
const auto list = media.valt_documents();
return std::make_unique<Data::MediaFile>( return std::make_unique<Data::MediaFile>(
item, item,
item->history()->owner().processDocument( item->history()->owner().processDocument(document, list),
document,
media.valt_documents()),
media.is_nopremium(), media.is_nopremium(),
list && !list->v.isEmpty(),
media.is_spoiler(), media.is_spoiler(),
media.vttl_seconds().value_or_empty()); media.vttl_seconds().value_or_empty());
}, [](const MTPDdocumentEmpty &) -> Result { }, [](const MTPDdocumentEmpty &) -> Result {
@ -628,11 +628,13 @@ HistoryItem::HistoryItem(
createComponentsHelper(std::move(fields)); createComponentsHelper(std::move(fields));
const auto skipPremiumEffect = !history->session().premium(); const auto skipPremiumEffect = !history->session().premium();
const auto video = document->video();
const auto spoiler = false; const auto spoiler = false;
_media = std::make_unique<Data::MediaFile>( _media = std::make_unique<Data::MediaFile>(
this, this,
document, document,
skipPremiumEffect, skipPremiumEffect,
video && !video->qualities.empty(),
spoiler, spoiler,
/*ttlSeconds = */0); /*ttlSeconds = */0);
setText(caption); setText(caption);
@ -1789,6 +1791,7 @@ void HistoryItem::setStoryFields(not_null<Data::Story*> story) {
this, this,
document, document,
/*skipPremiumEffect=*/false, /*skipPremiumEffect=*/false,
/*hasQualitiesList=*/false,
spoiler, spoiler,
/*ttlSeconds = */0); /*ttlSeconds = */0);
} }

View file

@ -74,11 +74,13 @@ constexpr auto kFactcheckAboutDuration = 5 * crl::time(1000);
const auto spoiler = false; const auto spoiler = false;
for (const auto &item : data.items) { for (const auto &item : data.items) {
if (const auto document = std::get_if<DocumentData*>(&item)) { if (const auto document = std::get_if<DocumentData*>(&item)) {
const auto hasQualitiesList = false;
const auto skipPremiumEffect = false; const auto skipPremiumEffect = false;
result.push_back(std::make_unique<Data::MediaFile>( result.push_back(std::make_unique<Data::MediaFile>(
parent, parent,
*document, *document,
skipPremiumEffect, skipPremiumEffect,
hasQualitiesList,
spoiler, spoiler,
/*ttlSeconds = */0)); /*ttlSeconds = */0));
} else if (const auto photo = std::get_if<PhotoData*>(&item)) { } else if (const auto photo = std::get_if<PhotoData*>(&item)) {

View file

@ -2264,16 +2264,27 @@ OverlayWidget::~OverlayWidget() {
_dropdown.destroy(); _dropdown.destroy();
} }
auto OverlayWidget::resolveQualities() const
-> const std::vector<not_null<DocumentData*>> & {
static const auto empty = std::vector<not_null<DocumentData*>>();
const auto video = _document ? _document->video() : nullptr;
const auto media = _message ? _message->media() : nullptr;
if (!video || !media || media->document() != _document) {
return empty;
}
return media->hasQualitiesList() ? video->qualities : empty;
}
not_null<DocumentData*> OverlayWidget::chooseQuality() const { not_null<DocumentData*> OverlayWidget::chooseQuality() const {
Expects(_document != nullptr); Expects(_document != nullptr);
const auto video = _document->video(); const auto &list = resolveQualities();
if (!video || video->qualities.empty() || _quality == kOriginalQuality) { if (list.empty() || _quality == kOriginalQuality) {
return _document; return _document;
} }
auto closest = _document; auto closest = _document;
auto closestAbs = std::abs(_quality - _document->resolveVideoQuality()); auto closestAbs = std::abs(_quality - _document->resolveVideoQuality());
for (const auto &quality : video->qualities) { for (const auto &quality : list) {
const auto abs = std::abs(_quality - quality->resolveVideoQuality()); const auto abs = std::abs(_quality - quality->resolveVideoQuality());
if (abs < closestAbs) { if (abs < closestAbs) {
closestAbs = abs; closestAbs = abs;
@ -4428,20 +4439,20 @@ float64 OverlayWidget::playbackControlsCurrentSpeed(bool lastNonDefault) {
} }
std::vector<int> OverlayWidget::playbackControlsQualities() { std::vector<int> OverlayWidget::playbackControlsQualities() {
const auto video = _document ? _document->video() : nullptr; const auto &list = resolveQualities();
if (!video || video->qualities.empty()) { if (list.empty()) {
return {}; return {};
} }
auto result = std::vector<int>(); auto result = std::vector<int>();
result.reserve(video->qualities.size()); result.reserve(list.size());
for (const auto &quality : video->qualities) { for (const auto &quality : list) {
result.push_back(quality->resolveVideoQuality()); result.push_back(quality->resolveVideoQuality());
} }
return result; return result;
} }
int OverlayWidget::playbackControlsCurrentQuality() { int OverlayWidget::playbackControlsCurrentQuality() {
return _quality; return _chosenQuality ? _chosenQuality->resolveVideoQuality() : _quality;
} }
void OverlayWidget::playbackControlsQualityChanged(int quality) { void OverlayWidget::playbackControlsQualityChanged(int quality) {

View file

@ -528,6 +528,8 @@ private:
[[nodiscard]] bool canInitStreaming() const; [[nodiscard]] bool canInitStreaming() const;
[[nodiscard]] bool saveControlLocked() const; [[nodiscard]] bool saveControlLocked() const;
[[nodiscard]] not_null<DocumentData*> chooseQuality() const; [[nodiscard]] not_null<DocumentData*> chooseQuality() const;
[[nodiscard]] auto resolveQualities() const
-> const std::vector<not_null<DocumentData*>> &;
[[nodiscard]] bool topShadowOnTheRight() const; [[nodiscard]] bool topShadowOnTheRight() const;
void applyHideWindowWorkaround(); void applyHideWindowWorkaround();

View file

@ -70,8 +70,12 @@ PlaybackControls::PlaybackControls(
fadeUpdated(opacity); fadeUpdated(opacity);
}); });
_speedToggle->setSpeed(_delegate->playbackControlsCurrentSpeed(false)); _speedToggle->setSpeed(_speedControllable
_speedToggle->setQuality(_delegate->playbackControlsCurrentQuality()); ? _delegate->playbackControlsCurrentSpeed(false)
: 1.);
_speedToggle->setQuality(_qualitiesList.empty()
? 0
: _delegate->playbackControlsCurrentQuality());
if (const auto controller = _speedController.get()) { if (const auto controller = _speedController.get()) {
controller->menuToggledValue( controller->menuToggledValue(

View file

@ -295,6 +295,7 @@ void AddViewMediaHandler(
state->item, state->item,
owner->document(item.id), owner->document(item.id),
true, // skipPremiumEffect true, // skipPremiumEffect
false, // hasQualitiesList
false, // spoiler false, // spoiler
0)); // ttlSeconds 0)); // ttlSeconds
} }