Share bounded thumbnail workers and keep PM downloads in DM transport

This commit is contained in:
evgeny committed 2026-10-01 19:12:25 +03:00
1 parent c863b80917
commit 203ae61eda
3 files changed
+29 -20

No files matched your search

+24 -18
View File
@@ -965,23 +965,27 @@ void MessageList::onAttachmentDownloaded(const QString& chId, int64_t msgId) {
}
}
if (m.contentType == "video/mp4") {
QString fp = item->data(MsgVoiceFileRole).toString();
QString thumbPath = fp + ".jpg";
if (!fp.isEmpty() && QFile::exists(fp) && !QFile::exists(thumbPath)) {
QPointer<MessageList> self(this);
std::thread([self, fp, thumbPath]() {
int rc = video_extract_thumbnail(fp.toUtf8().constData(),
thumbPath.toUtf8().constData(), 320);
DEBUG_DEBUG(DEBUG_CATEGORY_VIDEO, "MessageList: thumbnail %s rc=%d",
qPrintable(thumbPath), rc);
if (self) {
QMetaObject::invokeMethod(self, [self]() { self->m_view->viewport()->update(); },
Qt::QueuedConnection);
}
}).detach();
}
}
if (m.contentType == "video/mp4") prepareVideoThumbnail(item->data(MsgVoiceFileRole).toString());
}
/* Общие превью для каналов/PM; не более двух decoder workers, без запуска из paint. */
void MessageList::prepareVideoThumbnail(const QString& path) {
if (path.isEmpty() || m_thumbnailJobs.contains(path) || !QFile::exists(path) || QFile::exists(path + ".jpg")) return;
m_thumbnailPool.setMaxThreadCount(2);
m_thumbnailJobs.insert(path);
QPointer<MessageList> self(this);
QObject* dispatcher = QCoreApplication::instance();
m_thumbnailPool.start([self, dispatcher, path]() {
QString output = path + ".jpg";
int rc = video_extract_thumbnail(path.toUtf8().constData(), output.toUtf8().constData(), 320);
if (rc) DEBUG_WARN(DEBUG_CATEGORY_VIDEO, "thumbnail failed path=%s error=%d", qPrintable(path), rc);
else DEBUG_DEBUG(DEBUG_CATEGORY_VIDEO, "thumbnail ready path=%s", qPrintable(output));
QMetaObject::invokeMethod(dispatcher, [self, path]() {
if (!self) return;
self->m_thumbnailJobs.remove(path);
self->m_view->viewport()->update();
}, Qt::QueuedConnection);
});
}
void MessageList::onMessageContextMenu(const QPoint& pos) {
@@ -992,6 +996,7 @@ void MessageList::onMessageContextMenu(const QPoint& pos) {
bool isVideo = (ct == "video/mp4");
bool isImage = ct.startsWith("image/");
bool isDmFile = isDmChannel(idx.data(MsgChannelIdRole).toString()) && ct == "application/octet-stream";
bool isDm = isDmChannel(idx.data(MsgChannelIdRole).toString());
if (!isVideo && !isImage && !isDmFile) return;
QString filePath = idx.data(MsgVoiceFileRole).toString();
@@ -1002,7 +1007,7 @@ void MessageList::onMessageContextMenu(const QPoint& pos) {
QAction* saveAct = menu.addAction(QString::fromUtf8("Сохранить в файл"));
saveAct->setEnabled(downloaded);
QAction* dlAct = nullptr;
if (!downloaded && !isDmFile) dlAct = menu.addAction(QString::fromUtf8("Скачать"));
if (!downloaded && !isDm) dlAct = menu.addAction(QString::fromUtf8("Скачать"));
QAction* chosen = menu.exec(m_view->viewport()->mapToGlobal(pos));
@@ -1137,6 +1142,7 @@ void MessageList::onDmMessages(const uint8_t* data, int len) {
item->setData(duration, MsgVideoDurationMsRole);
item->setData(message.value("width").toInt(), MsgVideoWidthRole);
item->setData(message.value("height").toInt(), MsgVideoHeightRole);
prepareVideoThumbnail(path);
}
}
m_model->appendRow(item);