added memory usage settings for frame queue
This commit is contained in:
@@ -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");
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user