Update API scheme on layer 160: Duration.

This commit is contained in:
John Preston 2023-06-05 16:50:43 +04:00
parent b71d72ca7c
commit aba84a6010
23 changed files with 88 additions and 87 deletions

View File

@ -22,8 +22,7 @@ MTPVector<MTPDocumentAttribute> ComposeSendingDocumentAttributes(
const auto dimensions = document->dimensions;
auto attributes = QVector<MTPDocumentAttribute>(1, filenameAttribute);
if (dimensions.width() > 0 && dimensions.height() > 0) {
const auto duration = document->getDuration();
if (duration >= 0 && !document->hasMimeType(u"image/gif"_q)) {
if (document->hasDuration() && !document->hasMimeType(u"image/gif"_q)) {
auto flags = MTPDdocumentAttributeVideo::Flags(0);
using VideoFlag = MTPDdocumentAttributeVideo::Flag;
if (document->isVideoMessage()) {
@ -34,7 +33,7 @@ MTPVector<MTPDocumentAttribute> ComposeSendingDocumentAttributes(
}
attributes.push_back(MTP_documentAttributeVideo(
MTP_flags(flags),
MTP_int(duration),
MTP_double(document->duration() / 1000.),
MTP_int(dimensions.width()),
MTP_int(dimensions.height()),
MTPint())); // preload_prefix_size
@ -57,7 +56,7 @@ MTPVector<MTPDocumentAttribute> ComposeSendingDocumentAttributes(
| MTPDdocumentAttributeAudio::Flag::f_performer;
attributes.push_back(MTP_documentAttributeAudio(
MTP_flags(flags),
MTP_int(song->duration),
MTP_int(document->duration() / 1000),
MTP_string(song->title),
MTP_string(song->performer),
MTPstring()));
@ -66,7 +65,7 @@ MTPVector<MTPDocumentAttribute> ComposeSendingDocumentAttributes(
| MTPDdocumentAttributeAudio::Flag::f_waveform;
attributes.push_back(MTP_documentAttributeAudio(
MTP_flags(flags),
MTP_int(voice->duration),
MTP_int(document->duration() / 1000),
MTPstring(),
MTPstring(),
MTP_bytes(documentWaveformEncode5bit(voice->waveform))));

View File

@ -202,8 +202,8 @@ int Ringtones::maxSavedCount() const {
100);
}
int Ringtones::maxDuration() const {
return _session->account().appConfig().get<int>(
crl::time Ringtones::maxDuration() const {
return crl::time(1000) * _session->account().appConfig().get<int>(
"ringtone_duration_max",
5);
}

View File

@ -40,7 +40,7 @@ public:
[[nodiscard]] int64 maxSize() const;
[[nodiscard]] int maxSavedCount() const;
[[nodiscard]] int maxDuration() const;
[[nodiscard]] crl::time maxDuration() const;
private:
struct UploadedData {

View File

@ -27,7 +27,7 @@ AudioMsgId::AudioMsgId(
, _externalPlayId(externalPlayId)
, _changeablePlaybackSpeed(_audio->isVoiceMessage()
|| _audio->isVideoMessage()
|| (_audio->getDuration() >= kMinLengthForChangeablePlaybackSpeed)) {
|| (_audio->duration() >= kMinLengthForChangeablePlaybackSpeed)) {
setTypeFromAudio();
}

View File

@ -326,6 +326,7 @@ Main::Session &DocumentData::session() const {
void DocumentData::setattributes(
const QVector<MTPDocumentAttribute> &attributes) {
_duration = -1;
_flags &= ~(Flag::ImageType
| Flag::HasAttachedStickers
| Flag::UseTextColor
@ -389,12 +390,12 @@ void DocumentData::setattributes(
: VideoDocument;
if (data.is_round_message()) {
_additional = std::make_unique<RoundData>();
round()->duration = data.vduration().v;
}
} else if (const auto info = sticker()) {
info->type = StickerType::Webm;
}
_duration = data.vduration().v;
_duration = crl::time(
base::SafeRound(data.vduration().v * 1000));
setMaybeSupportsStreaming(data.is_supports_streaming());
dimensions = QSize(data.vw().v, data.vh().v);
}, [&](const MTPDdocumentAttributeAudio &data) {
@ -408,14 +409,14 @@ void DocumentData::setattributes(
}
}
if (const auto voiceData = voice() ? voice() : round()) {
voiceData->duration = data.vduration().v;
_duration = data.vduration().v * crl::time(1000);
voiceData->waveform = documentWaveformDecode(
data.vwaveform().value_or_empty());
voiceData->wavemax = voiceData->waveform.empty()
? uchar(0)
: *ranges::max_element(voiceData->waveform);
} else if (const auto songData = song()) {
songData->duration = data.vduration().v;
_duration = data.vduration().v * crl::time(1000);
songData->title = qs(data.vtitle().value_or_empty());
songData->performer = qs(data.vperformer().value_or_empty());
refreshPossibleCoverThumbnail();
@ -1516,19 +1517,12 @@ bool DocumentData::isVideoFile() const {
return (type == VideoDocument);
}
TimeId DocumentData::getDuration() const {
if (const auto song = this->song()) {
return std::max(song->duration, 0);
} else if (const auto voice = this->voice()) {
return std::max(voice->duration, 0);
} else if (isAnimation() || isVideoFile()) {
return std::max(_duration, 0);
} else if (const auto sticker = this->sticker()) {
if (sticker->isWebm()) {
return std::max(_duration, 0);
}
}
return -1;
crl::time DocumentData::duration() const {
return std::max(_duration, crl::time());
}
bool DocumentData::hasDuration() const {
return _duration >= 0;
}
bool DocumentData::isImage() const {

View File

@ -79,14 +79,12 @@ struct StickerData : public DocumentAdditionalData {
};
struct SongData : public DocumentAdditionalData {
int32 duration = 0;
QString title, performer;
};
struct VoiceData : public DocumentAdditionalData {
~VoiceData();
int duration = 0;
VoiceWaveform waveform;
char wavemax = 0;
};
@ -172,7 +170,8 @@ public:
[[nodiscard]] bool isGifv() const;
[[nodiscard]] bool isTheme() const;
[[nodiscard]] bool isSharedMediaMusic() const;
[[nodiscard]] TimeId getDuration() const;
[[nodiscard]] crl::time duration() const;
[[nodiscard]] bool hasDuration() const;
[[nodiscard]] bool isImage() const;
void recountIsImage();
[[nodiscard]] bool supportsStreaming() const;
@ -356,10 +355,10 @@ private:
std::unique_ptr<Data::ReplyPreview> _replyPreview;
std::weak_ptr<Data::DocumentMedia> _media;
PhotoData *_goodThumbnailPhoto = nullptr;
crl::time _duration = -1;
Core::FileLocation _location;
std::unique_ptr<DocumentAdditionalData> _additional;
int32 _duration = -1;
mutable Flags _flags = kStreamingSupportedUnknown;
GoodThumbnailState _goodThumbnailState = GoodThumbnailState();
std::unique_ptr<FileLoader> _loader;

View File

@ -295,7 +295,7 @@ void ParseAttributes(
}
result.width = data.vw().v;
result.height = data.vh().v;
result.duration = data.vduration().v;
result.duration = int(data.vduration().v);
}, [&](const MTPDdocumentAttributeAudio &data) {
if (data.is_voice()) {
result.isVoiceMessage = true;

View File

@ -90,7 +90,6 @@ enum class FilterType {
[[nodiscard]] std::unique_ptr<VoiceData> ProcessCaptureResult(
const ::Media::Capture::Result &data) {
auto voiceData = std::make_unique<VoiceData>();
voiceData->duration = Duration(data.samples);
voiceData->waveform = data.waveform;
voiceData->wavemax = voiceData->waveform.empty()
? uchar(0)

View File

@ -1199,11 +1199,11 @@ void AddSaveSoundForNotifications(
} else if (int(ringtones.list().size()) >= ringtones.maxSavedCount()) {
return;
} else if (const auto song = document->song()) {
if (song->duration > ringtones.maxDuration()) {
if (document->duration() > ringtones.maxDuration()) {
return;
}
} else if (const auto voice = document->voice()) {
if (voice->duration > ringtones.maxDuration()) {
if (document->duration() > ringtones.maxDuration()) {
return;
}
} else {

View File

@ -172,7 +172,7 @@ void PaintWaveform(
accumulate_max(result, st::normalFont->width(text));
};
add(FormatDownloadText(document->size, document->size));
const auto duration = document->getDuration();
const auto duration = document->duration() / 1000;
if (const auto song = document->song()) {
add(FormatPlayedText(duration, duration));
add(FormatDurationAndSizeText(duration, document->size));
@ -1212,14 +1212,16 @@ bool Document::uploading() const {
}
void Document::setStatusSize(int64 newSize, TimeId realDuration) const {
TimeId duration = _data->isSong()
? _data->song()->duration
: (_data->isVoiceMessage()
? _data->voice()->duration
: _transcribedRound
? _data->round()->duration
: -1);
File::setStatusSize(newSize, _data->size, duration, realDuration);
const auto duration = (_data->isSong()
|| _data->isVoiceMessage()
|| _transcribedRound)
? _data->duration()
: -1;
File::setStatusSize(
newSize,
_data->size,
(duration >= 0) ? duration / 1000 : -1,
realDuration);
if (auto thumbed = Get<HistoryDocumentThumbed>()) {
if (_statusSize == Ui::FileStatusSizeReady) {
thumbed->link = tr::lng_media_download(tr::now).toUpper();

View File

@ -1600,12 +1600,12 @@ void Gif::setStatusSize(int64 newSize) const {
_statusText = Ui::FormatDurationText(-newSize - 1);
} else if (_data->isVideoMessage()) {
_statusSize = newSize;
_statusText = Ui::FormatDurationText(_data->getDuration());
_statusText = Ui::FormatDurationText(_data->duration() / 1000);
} else {
File::setStatusSize(
newSize,
_data->size,
_data->isVideoFile() ? _data->getDuration() : -2,
_data->isVideoFile() ? (_data->duration() / 1000) : -2,
0);
}
}
@ -1638,7 +1638,7 @@ void Gif::updateStatusText() const {
}
statusSize = -1 - int((state.length - position) / state.frequency + 1);
} else {
statusSize = -1 - _data->getDuration();
statusSize = -1 - (_data->duration() / 1000);
}
}
if (statusSize != _statusSize) {

View File

@ -56,7 +56,7 @@ TimeId DurationForTimestampLinks(not_null<DocumentData*> document) {
&& !document->isVoiceMessage()) {
return TimeId(0);
}
return std::max(document->getDuration(), TimeId(0));
return std::max(document->duration(), crl::time(0)) / 1000;
}
QString TimestampLinkBase(

View File

@ -88,8 +88,8 @@ int FileBase::content_height() const {
int FileBase::content_duration() const {
if (const auto document = getShownDocument()) {
if (document->getDuration() > 0) {
return document->getDuration();
if (document->hasDuration()) {
return document->duration() / 1000;
}
}
return getResultDuration();
@ -1143,12 +1143,10 @@ bool File::updateStatusText() const {
}
if (statusSize != _statusSize) {
TimeId duration = _document->isSong()
? _document->song()->duration
: (_document->isVoiceMessage()
? _document->voice()->duration
: -1);
setStatusSize(statusSize, _document->size, duration, realDuration);
const auto duration = _document->isSong()
? _document->duration()
: (_document->isVoiceMessage() ? _document->duration() : -1);
setStatusSize(statusSize, _document->size, (duration >= 0) ? (duration / 1000) : -1, realDuration);
}
return showPause;
}

View File

@ -974,7 +974,7 @@ Ui::PreparedFileInformation PrepareForSending(
auto seekPositionMs = crl::time(0);
auto reader = std::make_unique<internal::FFMpegReaderImplementation>(&localLocation, &localData);
if (reader->start(internal::ReaderImplementation::Mode::Inspecting, seekPositionMs)) {
auto durationMs = reader->durationMs();
const auto durationMs = reader->durationMs();
if (durationMs > 0) {
result.isGifv = reader->isGifv();
result.isWebmSticker = reader->isWebmSticker();
@ -994,7 +994,7 @@ Ui::PreparedFileInformation PrepareForSending(
if (hasAlpha && !result.isWebmSticker) {
result.thumbnail = Images::Opaque(std::move(result.thumbnail));
}
result.duration = static_cast<int>(durationMs / 1000);
result.duration = durationMs;
}
result.supportsStreaming = CheckStreamingSupport(

View File

@ -632,7 +632,7 @@ void Widget::updateTimeText(const TrackState &state) {
} else if (state.length) {
display = state.length;
} else if (const auto song = document->song()) {
display = (song->duration * frequency);
display = (document->duration() * frequency) / 1000;
}
_lastDurationMs = (state.length * 1000LL) / frequency;

View File

@ -954,9 +954,9 @@ Media::Player::TrackState Player::prepareLegacyState() const {
if (result.length == kTimeUnknown) {
const auto document = _options.audioId.audio();
const auto duration = document ? document->getDuration() : 0;
const auto duration = document ? document->duration() : 0;
if (duration > 0) {
result.length = duration * crl::time(1000);
result.length = duration;
} else {
result.length = std::max(crl::time(result.position), crl::time(0));
}

View File

@ -3887,8 +3887,8 @@ void OverlayWidget::restartAtSeekPosition(crl::time position) {
.position = position,
.durationOverride = ((_stories
&& _document
&& _document->getDuration() > 0)
? (_document->getDuration() * crl::time(1000) + crl::time(999))
&& _document->hasDuration())
? _document->duration()
: crl::time(0)),
.hwAllowed = Core::App().settings().hardwareAcceleratedVideo(),
.seekable = !_stories,

View File

@ -527,7 +527,7 @@ accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
documentAttributeAnimated#11b58939 = DocumentAttribute;
documentAttributeSticker#6319d612 flags:# mask:flags.1?true alt:string stickerset:InputStickerSet mask_coords:flags.0?MaskCoords = DocumentAttribute;
documentAttributeVideo#e9407793 flags:# round_message:flags.0?true supports_streaming:flags.1?true duration:int w:int h:int preload_prefix_size:flags.2?int = DocumentAttribute;
documentAttributeVideo#d38ff1c2 flags:# round_message:flags.0?true supports_streaming:flags.1?true duration:double w:int h:int preload_prefix_size:flags.2?int = DocumentAttribute;
documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute;
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
documentAttributeHasStickers#9801d2f7 = DocumentAttribute;
@ -1526,8 +1526,8 @@ sponsoredWebPage#3db8ec63 flags:# url:string site_name:string photo:flags.0?Phot
storyViews#d36760cf flags:# views_count:int recent_viewers:flags.0?Vector<long> = StoryViews;
storyItemDeleted#51e6ee4f id:int = StoryItem;
storyItemSkipped#a1d8cf8f id:int date:int = StoryItem;
storyItem#8fcd96ac flags:# pinned:flags.5?true expired:flags.6?true id:int date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews = StoryItem;
storyItemSkipped#693206a2 id:int date:int expire_date:int = StoryItem;
storyItem#562aa637 flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true id:int date:int expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews = StoryItem;
userStories#8611a200 flags:# user_id:long max_read_id:flags.0?int stories:Vector<StoryItem> = UserStories;
@ -1547,6 +1547,8 @@ stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = storie
inputReplyToMessage#9c5386e4 flags:# reply_to_msg_id:int top_msg_id:flags.0?int = InputReplyTo;
inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo;
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -2082,7 +2084,7 @@ chatlists.hideChatlistUpdates#66e486fb chatlist:InputChatlist = Bool;
chatlists.getLeaveChatlistSuggestions#fdbcd714 chatlist:InputChatlist = Vector<Peer>;
chatlists.leaveChatlist#74fae13a chatlist:InputChatlist peers:Vector<InputPeer> = Updates;
stories.sendStory#8b5c6986 flags:# pinned:flags.2?true media:InputMedia caption:flags.0?string entities:flags.1?Vector<MessageEntity> privacy_rules:Vector<InputPrivacyRule> random_id:long = Updates;
stories.sendStory#424cd47a flags:# pinned:flags.2?true media:InputMedia caption:flags.0?string entities:flags.1?Vector<MessageEntity> privacy_rules:Vector<InputPrivacyRule> random_id:long period:flags.3?int = Updates;
stories.editStory#2aae7a41 flags:# id:int media:flags.0?InputMedia caption:flags.1?string entities:flags.1?Vector<MessageEntity> privacy_rules:flags.2?Vector<InputPrivacyRule> = Updates;
stories.deleteStories#b5d501d7 id:Vector<int> = Vector<int>;
stories.togglePinned#51602944 id:Vector<int> pinned:Bool = Vector<int>;
@ -2095,3 +2097,4 @@ stories.readStories#edc5105b user_id:InputUser max_id:int = Vector<int>;
stories.incrementStoryViews#22126127 user_id:InputUser id:Vector<int> = Bool;
stories.getStoryViewsList#4b3b5e97 id:int offset_date:int offset_id:long limit:int = stories.StoryViewsList;
stories.getStoriesViews#9a75d6a6 id:Vector<int> = stories.StoryViews;
stories.exportStoryLink#16e443ce user_id:InputUser id:int = ExportedStoryLink;

View File

@ -448,7 +448,7 @@ Video::Video(
bool spoiler)
: RadialProgressItem(delegate, parent)
, _data(video)
, _duration(Ui::FormatDurationText(_data->getDuration()))
, _duration(Ui::FormatDurationText(_data->duration() / 1000))
, _spoiler(spoiler ? std::make_unique<Ui::SpoilerAnimation>([=] {
delegate->repaintItem(this);
}) : nullptr) {
@ -693,7 +693,7 @@ Voice::Voice(
lt_date,
dateText,
lt_duration,
{ .text = Ui::FormatDurationText(duration()) },
{ .text = Ui::FormatDurationText(_data->duration() / 1000) },
Ui::Text::WithEntities));
_details.setLink(1, JumpToMessageClickHandler(parent));
}
@ -958,10 +958,6 @@ void Voice::updateName() {
_nameVersion = parent()->fromOriginal()->nameVersion();
}
int Voice::duration() const {
return std::max(_data->getDuration(), 0);
}
bool Voice::updateStatusText() {
auto showPause = false;
auto statusSize = int64();
@ -983,7 +979,7 @@ bool Voice::updateStatusText() {
}
if (statusSize != _status.size()) {
_status.update(statusSize, _data->size, duration(), realDuration);
_status.update(statusSize, _data->size, _data->duration() / 1000, realDuration);
}
return showPause;
}
@ -1026,7 +1022,7 @@ Document::Document(
_status.update(
Ui::FileStatusSizeReady,
_data->size,
songLayout() ? _data->song()->duration : -1,
songLayout() ? (_data->duration() / 1000) : -1,
0);
if (withThumb()) {
@ -1541,7 +1537,7 @@ bool Document::updateStatusText() {
_status.update(
statusSize,
_data->size,
isSong ? _data->song()->duration : -1,
isSong ? (_data->duration() / 1000) : -1,
realDuration);
}
return showPause;

View File

@ -339,9 +339,8 @@ protected:
private:
void ensureDataMediaCreated() const;
int duration() const;
not_null<DocumentData*> _data;
const not_null<DocumentData*> _data;
mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
StatusText _status;
ClickHandlerPtr _namel;

View File

@ -868,7 +868,7 @@ void FileLoadTask::process(Args &&args) {
}
attributes.push_back(MTP_documentAttributeVideo(
MTP_flags(flags),
MTP_int(video->duration),
MTP_double(video->duration / 1000.),
MTP_int(coverWidth),
MTP_int(coverHeight),
MTPint())); // preload_prefix_size

View File

@ -18,7 +18,7 @@ namespace Serialize {
namespace {
constexpr auto kVersionTag = int32(0x7FFFFFFF);
constexpr auto kVersion = 5;
constexpr auto kVersion = 6;
enum StickerSetType {
StickerSetTypeEmpty = 0,
@ -58,7 +58,7 @@ void Document::writeToStream(QDataStream &stream, DocumentData *document) {
stream << qint32(StickerSetTypeEmpty);
}
}
stream << qint32(document->getDuration());
stream << qint64(document->hasDuration() ? document->duration() : -1);
if (document->type == StickerDocument) {
const auto premium = document->isPremiumSticker()
|| document->isPremiumEmoji();
@ -110,15 +110,19 @@ DocumentData *Document::readFromStreamHelper(
attributes.push_back(MTP_documentAttributeFilename(MTP_string(name)));
}
qint32 duration = -1;
qint64 duration = -1;
qint32 isPremiumSticker = 0;
qint32 useTextColor = 0;
if (type == StickerDocument) {
QString alt;
qint32 typeOfSet;
stream >> alt >> typeOfSet;
if (version >= 3) {
stream >> duration;
if (version >= 6) {
stream >> duration >> isPremiumSticker >> useTextColor;
} else if (version >= 3) {
qint32 oldDuration = -1;
stream >> oldDuration;
duration = (oldDuration < 0) ? oldDuration : oldDuration * 1000;
if (version >= 4) {
stream >> isPremiumSticker;
if (version >= 5) {
@ -166,7 +170,13 @@ DocumentData *Document::readFromStreamHelper(
}
}
} else {
stream >> duration;
if (version >= 6) {
stream >> duration;
} else {
qint32 oldDuration = -1;
stream >> oldDuration;
duration = (oldDuration < 0) ? oldDuration : oldDuration * 1000;
}
if (type == AnimatedDocument) {
attributes.push_back(MTP_documentAttributeAnimated());
}
@ -194,12 +204,14 @@ DocumentData *Document::readFromStreamHelper(
}
attributes.push_back(MTP_documentAttributeVideo(
MTP_flags(flags),
MTP_int(duration),
MTP_double(duration / 1000.),
MTP_int(width),
MTP_int(height),
MTPint())); // preload_prefix_size
} else {
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
attributes.push_back(MTP_documentAttributeImageSize(
MTP_int(width),
MTP_int(height)));
}
}

View File

@ -36,7 +36,7 @@ struct PreparedFileInformation {
bool isGifv = false;
bool isWebmSticker = false;
bool supportsStreaming = false;
int duration = -1;
crl::time duration = -1;
QImage thumbnail;
};