Fix crash when toggling Use Proxy during playback and proxy generation output format

This commit is contained in:
2026-07-13 10:19:30 +08:00
parent 0969e2adc5
commit e8443f8f8f
3 changed files with 45 additions and 15 deletions
+3 -1
View File
@@ -66,7 +66,9 @@ QString ProxyManager::GetProxyFilename(const QString &cache_path,
QString ProxyManager::GetWorkingProxyFilename(const QString &proxy_filename)
{
return QStringLiteral("%1.working").arg(proxy_filename);
// Append a recognizable suffix while keeping a standard container extension
// so ffmpeg can infer the output format.
return QStringLiteral("%1.working.mp4").arg(proxy_filename);
}
ProxyManager::ProxyState
+6
View File
@@ -235,6 +235,9 @@ void Footage::set_proxy_enabled(bool enabled)
if (proxy_enabled_ != enabled) {
qDebug() << "Footage::set_proxy_enabled:" << filename() << enabled;
proxy_enabled_ = enabled;
if (Project *p = project()) {
p->set_modified(true);
}
emit ProxySettingsChanged();
}
}
@@ -253,6 +256,9 @@ void Footage::SetProxy(const QString &path,
proxy_video_stream_index_ = video_stream_index;
proxy_preset_version_ = preset_version;
proxy_enabled_ = enabled;
if (Project *p = project()) {
p->set_modified(true);
}
emit ProxySettingsChanged();
}
+36 -14
View File
@@ -22,6 +22,7 @@
#include "previewautocacher.h"
#include <QApplication>
#include <QPointer>
#include <QtConcurrent/QtConcurrent>
#include "codec/conformmanager.h"
@@ -107,31 +108,52 @@ RenderTicketPtr PreviewAutoCacher::GetRangeOfAudio(ViewerOutput *viewer,
void PreviewAutoCacher::ClearSingleFrameRenders()
{
QMap<RenderTicketWatcher *, QVector<RenderTicketPtr>> copy =
video_immediate_passthroughs_;
for (auto it = copy.cbegin(); it != copy.cend(); it++) {
// Snapshot the watchers as guarded pointers before doing anything that
// might synchronously delete them (emitting Finished runs VideoRendered,
// which deletes the watcher and removes it from the map). Iterating over a
// raw-pointer copy of the map would leave dangling pointers.
QList<QPointer<RenderTicketWatcher>> watchers;
for (auto it = video_immediate_passthroughs_.cbegin();
it != video_immediate_passthroughs_.cend(); it++) {
watchers.append(it.key());
}
foreach (const QPointer<RenderTicketWatcher> &w, watchers) {
if (!w) {
continue;
}
// Keep already-running workers alive: cancelling an in-flight render
// forces the worker process to be torn down, which defeats the process
// pool. Frames that finish late are simply ignored by the viewer.
if (it.key()->IsRunning()) {
if (w->IsRunning()) {
continue;
}
it.key()->Cancel();
RenderManager::instance()->RemoveTicket(it.key()->GetTicket());
emit it.key()->GetTicket()->Finished();
RenderTicketPtr ticket = w->GetTicket();
w->Cancel();
RenderManager::instance()->RemoveTicket(ticket);
emit ticket->Finished();
}
}
void PreviewAutoCacher::ClearSingleFrameRendersThatArentRunning()
{
QMap<RenderTicketWatcher *, QVector<RenderTicketPtr>> copy =
video_immediate_passthroughs_;
for (auto it = copy.cbegin(); it != copy.cend(); it++) {
if (!it.key()->IsRunning()) {
it.key()->Cancel();
RenderManager::instance()->RemoveTicket(it.key()->GetTicket());
emit it.key()->GetTicket()->Finished();
QList<QPointer<RenderTicketWatcher>> watchers;
for (auto it = video_immediate_passthroughs_.cbegin();
it != video_immediate_passthroughs_.cend(); it++) {
watchers.append(it.key());
}
foreach (const QPointer<RenderTicketWatcher> &w, watchers) {
if (!w || w->IsRunning()) {
continue;
}
RenderTicketPtr ticket = w->GetTicket();
w->Cancel();
RenderManager::instance()->RemoveTicket(ticket);
emit ticket->Finished();
}
}