added memory usage settings for frame queue
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
@@ -94,6 +95,10 @@ void PreferencesDialog::save() {
|
|||||||
config.img_seq_formats = imgSeqFormatEdit->text();
|
config.img_seq_formats = imgSeqFormatEdit->text();
|
||||||
config.fast_seeking = fastSeekButton->isChecked();
|
config.fast_seeking = fastSeekButton->isChecked();
|
||||||
config.disable_multithreading_for_images = disable_img_multithread->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
|
// save keyboard shortcuts
|
||||||
for (int i=0;i<key_shortcut_fields.size();i++) {
|
for (int i=0;i<key_shortcut_fields.size();i++) {
|
||||||
@@ -160,31 +165,36 @@ void PreferencesDialog::setup_ui() {
|
|||||||
QVBoxLayout* verticalLayout = new QVBoxLayout(this);
|
QVBoxLayout* verticalLayout = new QVBoxLayout(this);
|
||||||
QTabWidget* tabWidget = new QTabWidget(this);
|
QTabWidget* tabWidget = new QTabWidget(this);
|
||||||
|
|
||||||
QTabWidget* tab = new QTabWidget();
|
QTabWidget* general_tab = new QTabWidget();
|
||||||
QGridLayout* gridLayout_2 = new QGridLayout(tab);
|
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("Mono");
|
||||||
recordingComboBox->addItem("Stereo");
|
recordingComboBox->addItem("Stereo");
|
||||||
|
|
||||||
gridLayout_2->addWidget(recordingComboBox, 1, 1, 1, 1);
|
general_layout->addWidget(recordingComboBox, 1, 1, 1, 1);
|
||||||
|
|
||||||
tabWidget->addTab(tab, "General");
|
tabWidget->addTab(general_tab, "General");
|
||||||
QWidget* tab_2 = new QWidget();
|
QWidget* behavior_tab = new QWidget();
|
||||||
tabWidget->addTab(tab_2, "Behavior");
|
tabWidget->addTab(behavior_tab, "Behavior");
|
||||||
|
|
||||||
// Playback
|
// Playback
|
||||||
QWidget* playback_tab = new QWidget();
|
QWidget* playback_tab = new QWidget();
|
||||||
QVBoxLayout* playback_tab_layout = new QVBoxLayout(playback_tab);
|
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
|
// Playback -> Seeking
|
||||||
QGroupBox* seeking_group = new QGroupBox(playback_tab);
|
QGroupBox* seeking_group = new QGroupBox(playback_tab);
|
||||||
seeking_group->setTitle("Seeking");
|
seeking_group->setTitle("Seeking");
|
||||||
@@ -197,10 +207,29 @@ void PreferencesDialog::setup_ui() {
|
|||||||
seeking_group_layout->addWidget(fastSeekButton);
|
seeking_group_layout->addWidget(fastSeekButton);
|
||||||
playback_tab_layout->addWidget(seeking_group);
|
playback_tab_layout->addWidget(seeking_group);
|
||||||
|
|
||||||
// Playback -> Disable Multithreading on Images
|
// Playback -> Memory Usage
|
||||||
disable_img_multithread = new QCheckBox("Disable Multithreading on Images");
|
QGroupBox* memory_usage_group = new QGroupBox(playback_tab);
|
||||||
disable_img_multithread->setChecked(config.disable_multithreading_for_images);
|
memory_usage_group->setTitle("Memory Usage");
|
||||||
playback_tab_layout->addWidget(disable_img_multithread);
|
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");
|
tabWidget->addTab(playback_tab, "Playback");
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class QTreeWidget;
|
|||||||
class QTreeWidgetItem;
|
class QTreeWidgetItem;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
|
class QDoubleSpinBox;
|
||||||
|
|
||||||
class KeySequenceEditor : public QKeySequenceEdit {
|
class KeySequenceEditor : public QKeySequenceEdit {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -46,6 +47,10 @@ private:
|
|||||||
QRadioButton* fastSeekButton;
|
QRadioButton* fastSeekButton;
|
||||||
QTreeWidget* keyboard_tree;
|
QTreeWidget* keyboard_tree;
|
||||||
QCheckBox* disable_img_multithread;
|
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<QAction*> key_shortcut_actions;
|
||||||
QVector<QTreeWidgetItem*> key_shortcut_items;
|
QVector<QTreeWidgetItem*> key_shortcut_items;
|
||||||
|
|||||||
+21
-1
@@ -39,7 +39,11 @@ Config::Config()
|
|||||||
project_view_type(PROJECT_VIEW_TREE),
|
project_view_type(PROJECT_VIEW_TREE),
|
||||||
set_name_with_marker(true),
|
set_name_with_marker(true),
|
||||||
show_project_toolbar(false),
|
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) {
|
void Config::load(QString path) {
|
||||||
@@ -134,6 +138,18 @@ void Config::load(QString path) {
|
|||||||
} else if (stream.name() == "DisableMultithreadedImages") {
|
} else if (stream.name() == "DisableMultithreadedImages") {
|
||||||
stream.readNext();
|
stream.readNext();
|
||||||
disable_multithreading_for_images = (stream.text() == "1");
|
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("SetNameWithMarker", QString::number(set_name_with_marker));
|
||||||
stream.writeTextElement("ShowProjectToolbar", QString::number(panel_project->toolbar_widget->isVisible()));
|
stream.writeTextElement("ShowProjectToolbar", QString::number(panel_project->toolbar_widget->isVisible()));
|
||||||
stream.writeTextElement("DisableMultithreadedImages", QString::number(disable_multithreading_for_images));
|
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.writeEndElement(); // configuration
|
||||||
stream.writeEndDocument(); // doc
|
stream.writeEndDocument(); // doc
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
#define PROJECT_VIEW_TREE 0
|
#define PROJECT_VIEW_TREE 0
|
||||||
#define PROJECT_VIEW_ICON 1
|
#define PROJECT_VIEW_ICON 1
|
||||||
|
|
||||||
|
#define FRAME_QUEUE_TYPE_FRAMES 0
|
||||||
|
#define FRAME_QUEUE_TYPE_SECONDS 1
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
Config();
|
Config();
|
||||||
bool saved_layout;
|
bool saved_layout;
|
||||||
@@ -51,6 +54,10 @@ struct Config {
|
|||||||
bool set_name_with_marker;
|
bool set_name_with_marker;
|
||||||
bool show_project_toolbar;
|
bool show_project_toolbar;
|
||||||
bool disable_multithreading_for_images;
|
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 load(QString path);
|
||||||
void save(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);
|
clip->codecCtx = avcodec_alloc_context3(clip->codec);
|
||||||
avcodec_parameters_to_context(clip->codecCtx, clip->stream->codecpar);
|
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;
|
if (ms->video_interlacing != VIDEO_PROGRESSIVE) clip->max_queue_size *= 2;
|
||||||
|
|
||||||
clip->opts = NULL;
|
clip->opts = NULL;
|
||||||
|
|||||||
+30
-9
@@ -163,23 +163,44 @@ void get_clip_frame(Clip* c, long playhead) {
|
|||||||
target_frame = c->queue.at(closest_frame);
|
target_frame = c->queue.at(closest_frame);
|
||||||
int64_t next_pts = INT64_MAX;
|
int64_t next_pts = INT64_MAX;
|
||||||
int64_t minimum_ts = target_frame->pts;
|
int64_t minimum_ts = target_frame->pts;
|
||||||
/*if (c->reverse) {
|
|
||||||
minimum_ts += quarter_pts;
|
int previous_frame_count = 0;
|
||||||
} else {
|
if (config.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) {
|
||||||
minimum_ts -= quarter_pts;
|
minimum_ts -= (second_pts*config.previous_queue_size);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
//dout << "closest frame was" << closest_frame << "with" << target_frame->pts << "/" << target_pts;
|
//dout << "closest frame was" << closest_frame << "with" << target_frame->pts << "/" << target_pts;
|
||||||
for (int i=0;i<c->queue.size();i++) {
|
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) {
|
if (c->queue.at(i)->pts > target_frame->pts && c->queue.at(i)->pts < next_pts) {
|
||||||
next_pts = c->queue.at(i)->pts;
|
next_pts = c->queue.at(i)->pts;
|
||||||
}
|
}
|
||||||
if (c->queue.at(i) != target_frame && ((c->queue.at(i)->pts > minimum_ts) == c->reverse)) {
|
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;
|
if (config.previous_queue_type == FRAME_QUEUE_TYPE_SECONDS) {
|
||||||
av_frame_free(&c->queue[i]); // may be a little heavy for the main thread?
|
//dout << "removed frame at" << i << "because its pts was" << c->queue.at(i)->pts << "compared to" << target_frame->pts;
|
||||||
c->queue.removeAt(i);
|
av_frame_free(&c->queue[i]); // may be a little heavy for the main thread?
|
||||||
i--;
|
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;
|
if (next_pts == INT64_MAX) next_pts = target_frame->pts + target_frame->pkt_duration;
|
||||||
|
|
||||||
// we didn't get the exact timestamp
|
// we didn't get the exact timestamp
|
||||||
|
|||||||
Reference in New Issue
Block a user