added memory usage settings for frame queue

This commit is contained in:
itsmattkc
2019-01-08 10:54:39 +11:00
parent d51ce537ae
commit 5f8db6b3be
6 changed files with 123 additions and 26 deletions
+44 -15
View File
@@ -18,6 +18,7 @@
#include <QPushButton>
#include <QTreeWidgetItem>
#include <QList>
#include <QDoubleSpinBox>
#include "debug.h"
@@ -94,6 +95,10 @@ void PreferencesDialog::save() {
config.img_seq_formats = imgSeqFormatEdit->text();
config.fast_seeking = fastSeekButton->isChecked();
config.disable_multithreading_for_images = disable_img_multithread->isChecked();
config.upcoming_queue_size = upcoming_queue_spinbox->value();
config.upcoming_queue_type = upcoming_queue_type->currentIndex();
config.previous_queue_size = previous_queue_spinbox->value();
config.previous_queue_type = previous_queue_type->currentIndex();
// save keyboard shortcuts
for (int i=0;i<key_shortcut_fields.size();i++) {
@@ -160,31 +165,36 @@ void PreferencesDialog::setup_ui() {
QVBoxLayout* verticalLayout = new QVBoxLayout(this);
QTabWidget* tabWidget = new QTabWidget(this);
QTabWidget* tab = new QTabWidget();
QGridLayout* gridLayout_2 = new QGridLayout(tab);
QTabWidget* general_tab = new QTabWidget();
QGridLayout* general_layout = new QGridLayout(general_tab);
gridLayout_2->addWidget(new QLabel("Image sequence formats:"), 0, 0, 1, 1);
general_layout->addWidget(new QLabel("Image sequence formats:"), 0, 0, 1, 1);
imgSeqFormatEdit = new QLineEdit(tab);
imgSeqFormatEdit = new QLineEdit(general_tab);
gridLayout_2->addWidget(imgSeqFormatEdit, 0, 1, 1, 1);
general_layout->addWidget(imgSeqFormatEdit, 0, 1, 1, 1);
gridLayout_2->addWidget(new QLabel("Audio Recording:"), 1, 0, 1, 1);
general_layout->addWidget(new QLabel("Audio Recording:"), 1, 0, 1, 1);
recordingComboBox = new QComboBox(tab);
recordingComboBox = new QComboBox(general_tab);
recordingComboBox->addItem("Mono");
recordingComboBox->addItem("Stereo");
gridLayout_2->addWidget(recordingComboBox, 1, 1, 1, 1);
general_layout->addWidget(recordingComboBox, 1, 1, 1, 1);
tabWidget->addTab(tab, "General");
QWidget* tab_2 = new QWidget();
tabWidget->addTab(tab_2, "Behavior");
tabWidget->addTab(general_tab, "General");
QWidget* behavior_tab = new QWidget();
tabWidget->addTab(behavior_tab, "Behavior");
// Playback
QWidget* playback_tab = new QWidget();
QVBoxLayout* playback_tab_layout = new QVBoxLayout(playback_tab);
// Playback -> Disable Multithreading on Images
disable_img_multithread = new QCheckBox("Disable Multithreading on Images");
disable_img_multithread->setChecked(config.disable_multithreading_for_images);
playback_tab_layout->addWidget(disable_img_multithread);
// Playback -> Seeking
QGroupBox* seeking_group = new QGroupBox(playback_tab);
seeking_group->setTitle("Seeking");
@@ -197,10 +207,29 @@ void PreferencesDialog::setup_ui() {
seeking_group_layout->addWidget(fastSeekButton);
playback_tab_layout->addWidget(seeking_group);
// Playback -> Disable Multithreading on Images
disable_img_multithread = new QCheckBox("Disable Multithreading on Images");
disable_img_multithread->setChecked(config.disable_multithreading_for_images);
playback_tab_layout->addWidget(disable_img_multithread);
// Playback -> Memory Usage
QGroupBox* memory_usage_group = new QGroupBox(playback_tab);
memory_usage_group->setTitle("Memory Usage");
QGridLayout* memory_usage_layout = new QGridLayout(memory_usage_group);
memory_usage_layout->addWidget(new QLabel("Upcoming Frame Queue:"), 0, 0);
upcoming_queue_spinbox = new QDoubleSpinBox();
upcoming_queue_spinbox->setValue(config.upcoming_queue_size);
memory_usage_layout->addWidget(upcoming_queue_spinbox, 0, 1);
upcoming_queue_type = new QComboBox();
upcoming_queue_type->addItem("frames");
upcoming_queue_type->addItem("seconds");
upcoming_queue_type->setCurrentIndex(config.upcoming_queue_type);
memory_usage_layout->addWidget(upcoming_queue_type, 0, 2);
memory_usage_layout->addWidget(new QLabel("Previous Frame Queue:"), 1, 0);
previous_queue_spinbox = new QDoubleSpinBox();
previous_queue_spinbox->setValue(config.previous_queue_size);
memory_usage_layout->addWidget(previous_queue_spinbox, 1, 1);
previous_queue_type = new QComboBox();
previous_queue_type->addItem("frames");
previous_queue_type->addItem("seconds");
previous_queue_type->setCurrentIndex(config.previous_queue_type);
memory_usage_layout->addWidget(previous_queue_type, 1, 2);
playback_tab_layout->addWidget(memory_usage_group);
tabWidget->addTab(playback_tab, "Playback");
+5
View File
@@ -11,6 +11,7 @@ class QTreeWidget;
class QTreeWidgetItem;
class QMenu;
class QCheckBox;
class QDoubleSpinBox;
class KeySequenceEditor : public QKeySequenceEdit {
Q_OBJECT
@@ -46,6 +47,10 @@ private:
QRadioButton* fastSeekButton;
QTreeWidget* keyboard_tree;
QCheckBox* disable_img_multithread;
QDoubleSpinBox* upcoming_queue_spinbox;
QComboBox* upcoming_queue_type;
QDoubleSpinBox* previous_queue_spinbox;
QComboBox* previous_queue_type;
QVector<QAction*> key_shortcut_actions;
QVector<QTreeWidgetItem*> key_shortcut_items;
+21 -1
View File
@@ -39,7 +39,11 @@ Config::Config()
project_view_type(PROJECT_VIEW_TREE),
set_name_with_marker(true),
show_project_toolbar(false),
disable_multithreading_for_images(false)
disable_multithreading_for_images(false),
previous_queue_size(3),
previous_queue_type(FRAME_QUEUE_TYPE_FRAMES),
upcoming_queue_size(0.5),
upcoming_queue_type(FRAME_QUEUE_TYPE_SECONDS)
{}
void Config::load(QString path) {
@@ -134,6 +138,18 @@ void Config::load(QString path) {
} else if (stream.name() == "DisableMultithreadedImages") {
stream.readNext();
disable_multithreading_for_images = (stream.text() == "1");
} else if (stream.name() == "PreviousFrameQueueSize") {
stream.readNext();
previous_queue_size = stream.text().toDouble();
} else if (stream.name() == "PreviousFrameQueueType") {
stream.readNext();
previous_queue_type = stream.text().toInt();
} else if (stream.name() == "UpcomingFrameQueueSize") {
stream.readNext();
upcoming_queue_size = stream.text().toDouble();
} else if (stream.name() == "UpcomingFrameQueueType") {
stream.readNext();
upcoming_queue_type = stream.text().toInt();
}
}
}
@@ -186,6 +202,10 @@ void Config::save(QString path) {
stream.writeTextElement("SetNameWithMarker", QString::number(set_name_with_marker));
stream.writeTextElement("ShowProjectToolbar", QString::number(panel_project->toolbar_widget->isVisible()));
stream.writeTextElement("DisableMultithreadedImages", QString::number(disable_multithreading_for_images));
stream.writeTextElement("PreviousFrameQueueSize", QString::number(previous_queue_size));
stream.writeTextElement("PreviousFrameQueueType", QString::number(previous_queue_type));
stream.writeTextElement("UpcomingFrameQueueSize", QString::number(upcoming_queue_size));
stream.writeTextElement("UpcomingFrameQueueType", QString::number(upcoming_queue_type));
stream.writeEndElement(); // configuration
stream.writeEndDocument(); // doc
+7
View File
@@ -21,6 +21,9 @@
#define PROJECT_VIEW_TREE 0
#define PROJECT_VIEW_ICON 1
#define FRAME_QUEUE_TYPE_FRAMES 0
#define FRAME_QUEUE_TYPE_SECONDS 1
struct Config {
Config();
bool saved_layout;
@@ -51,6 +54,10 @@ struct Config {
bool set_name_with_marker;
bool show_project_toolbar;
bool disable_multithreading_for_images;
double previous_queue_size;
int previous_queue_type;
double upcoming_queue_size;
int upcoming_queue_type;
void load(QString path);
void save(QString path);
+16 -1
View File
@@ -674,7 +674,22 @@ void open_clip_worker(Clip* clip) {
clip->codecCtx = avcodec_alloc_context3(clip->codec);
avcodec_parameters_to_context(clip->codecCtx, clip->stream->codecpar);
clip->max_queue_size = (ms->infinite_length) ? 1 : qCeil(ms->video_frame_rate * m->speed * 0.5);
if (ms->infinite_length) {
clip->max_queue_size = 1;
} else {
clip->max_queue_size = 0;
if (config.upcoming_queue_type == FRAME_QUEUE_TYPE_FRAMES) {
clip->max_queue_size += qCeil(config.upcoming_queue_size);
} else {
clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * config.upcoming_queue_size);
}
if (config.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) {
clip->max_queue_size += qCeil(config.previous_queue_size);
} else {
clip->max_queue_size += qCeil(ms->video_frame_rate * m->speed * config.previous_queue_size);
}
}
if (ms->video_interlacing != VIDEO_PROGRESSIVE) clip->max_queue_size *= 2;
clip->opts = NULL;
+30 -9
View File
@@ -163,23 +163,44 @@ void get_clip_frame(Clip* c, long playhead) {
target_frame = c->queue.at(closest_frame);
int64_t next_pts = INT64_MAX;
int64_t minimum_ts = target_frame->pts;
/*if (c->reverse) {
minimum_ts += quarter_pts;
} else {
minimum_ts -= quarter_pts;
}*/
int previous_frame_count = 0;
if (config.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) {
minimum_ts -= (second_pts*config.previous_queue_size);
}
//dout << "closest frame was" << closest_frame << "with" << target_frame->pts << "/" << target_pts;
for (int i=0;i<c->queue.size();i++) {
if (c->queue.at(i)->pts > target_frame->pts && c->queue.at(i)->pts < next_pts) {
next_pts = c->queue.at(i)->pts;
}
if (c->queue.at(i) != target_frame && ((c->queue.at(i)->pts > minimum_ts) == c->reverse)) {
//dout << "removed frame at" << i << "because its pts was" << c->queue.at(i)->pts << "compared to" << target_frame->pts;
av_frame_free(&c->queue[i]); // may be a little heavy for the main thread?
c->queue.removeAt(i);
i--;
if (config.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) {
//dout << "removed frame at" << i << "because its pts was" << c->queue.at(i)->pts << "compared to" << target_frame->pts;
av_frame_free(&c->queue[i]); // may be a little heavy for the main thread?
c->queue.removeAt(i);
i--;
} else {
// TODO sort from largest to smallest
previous_frame_count++;
}
}
}
if (config.previous_queue_type == FRAME_QUEUE_TYPE_FRAMES) {
while (previous_frame_count > qCeil(config.previous_queue_size)) {
int smallest = 0;
for (int i=1;i<c->queue.size();i++) {
if (c->queue.at(i)->pts < c->queue.at(smallest)->pts) {
smallest = i;
}
}
av_frame_free(&c->queue[smallest]);
c->queue.removeAt(smallest);
previous_frame_count--;
}
}
if (next_pts == INT64_MAX) next_pts = target_frame->pts + target_frame->pkt_duration;
// we didn't get the exact timestamp