1 ///////////////////////////////////////////////////////////////////////////////
2 // Simple x264 Launcher
3 // Copyright (C) 2004-2023 LoRd_MuldeR <MuldeR2@GMX.de>
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
22 #include "model_options.h"
26 #include "model_sysinfo.h"
29 #include <MUtils/Global.h>
32 #include <QDesktopServices>
34 #include <QStringList>
35 #include <QApplication>
37 #define COMPARE_VAL(OTHER, NAME) ((this->NAME) == (OTHER->NAME))
38 #define COMPARE_STR(OTHER, NAME) ((this->NAME).compare((model->NAME), Qt::CaseInsensitive) == 0)
39 #define ASSIGN_FROM(OTHER, NAME) ((this->NAME) = (OTHER.NAME))
42 static const char *KEY_ENCODER_TYPE
= "encoder_type";
43 static const char *KEY_ENCODER_ARCH
= "encoder_arch";
44 static const char *KEY_ENCODER_VARIANT
= "encoder_variant";
45 static const char *KEY_RATECTRL_MODE
= "rate_control_mode";
46 static const char *KEY_TARGET_BITRATE
= "target_bitrate";
47 static const char *KEY_TARGET_QUANT
= "target_quantizer";
48 static const char *KEY_PRESET_NAME
= "preset_name";
49 static const char *KEY_TUNING_NAME
= "tuning_name";
50 static const char *KEY_PROFILE_NAME
= "profile_name";
51 static const char *KEY_CUSTOM_ENCODER
= "custom_params_encoder";
52 static const char *KEY_CUSTOM_AVS2YUV
= "custom_params_avs2yuv";
54 const char *const OptionsModel::SETTING_UNSPECIFIED
= "<None>";
55 const char *const OptionsModel::PROFILE_UNRESTRICTED
= "<Unrestricted>";
57 OptionsModel::OptionsModel(const SysinfoModel
*sysinfo
)
59 m_encoderType
= EncType_X264
;
60 m_encoderArch
= sysinfo
->getCPUFeatures(SysinfoModel::CPUFeatures_X64
) ? 0 : 1;
66 m_tune
= QString::fromLatin1(OptionsModel::SETTING_UNSPECIFIED
);
67 m_profile
= QString::fromLatin1(OptionsModel::PROFILE_UNRESTRICTED
);
68 m_custom_encoder
= QString();
69 m_custom_avs2yuv
= QString();
72 OptionsModel::OptionsModel(const OptionsModel
&rhs
)
74 ASSIGN_FROM(rhs
, m_encoderType
);
75 ASSIGN_FROM(rhs
, m_encoderArch
);
76 ASSIGN_FROM(rhs
, m_encoderVariant
);
77 ASSIGN_FROM(rhs
, m_rcMode
);
78 ASSIGN_FROM(rhs
, m_bitrate
);
79 ASSIGN_FROM(rhs
, m_quantizer
);
80 ASSIGN_FROM(rhs
, m_preset
);
81 ASSIGN_FROM(rhs
, m_tune
);
82 ASSIGN_FROM(rhs
, m_profile
);
83 ASSIGN_FROM(rhs
, m_custom_encoder
);
84 ASSIGN_FROM(rhs
, m_custom_avs2yuv
);
87 OptionsModel::~OptionsModel(void)
91 bool OptionsModel::equals(const OptionsModel
*model
)
95 equal
= equal
&& COMPARE_VAL(model
, m_encoderType
);
96 equal
= equal
&& COMPARE_VAL(model
, m_encoderArch
);
97 equal
= equal
&& COMPARE_VAL(model
, m_encoderVariant
);
98 equal
= equal
&& COMPARE_VAL(model
, m_rcMode
);
99 equal
= equal
&& COMPARE_VAL(model
, m_bitrate
);
100 equal
= equal
&& COMPARE_VAL(model
, m_quantizer
);
101 equal
= equal
&& COMPARE_STR(model
, m_preset
);
102 equal
= equal
&& COMPARE_STR(model
, m_tune
);
103 equal
= equal
&& COMPARE_STR(model
, m_profile
);
104 equal
= equal
&& COMPARE_STR(model
, m_custom_encoder
);
105 equal
= equal
&& COMPARE_STR(model
, m_custom_avs2yuv
);
110 bool OptionsModel::saveTemplate(const OptionsModel
*model
, const QString
&name
)
112 const QString templateName
= name
.simplified();
113 const QString appDir
= x264_data_path();
115 if(templateName
.contains('\\') || templateName
.contains('/'))
120 QSettings
settings(QString("%1/templates.ini").arg(appDir
), QSettings::IniFormat
);
121 settings
.beginGroup(templateName
);
123 const bool okay
= saveOptions(model
, settings
);
131 bool OptionsModel::loadTemplate(OptionsModel
*model
, const QString
&name
)
133 const QString appDir
= x264_data_path();
135 if(name
.contains('\\') || name
.contains('/'))
140 QSettings
settings(QString("%1/templates.ini").arg(appDir
), QSettings::IniFormat
);
142 settings
.beginGroup(name
);
143 const bool okay
= loadOptions(model
, settings
);
149 QMap
<QString
, OptionsModel
*> OptionsModel::loadAllTemplates(const SysinfoModel
*sysinfo
)
151 QMap
<QString
, OptionsModel
*> list
;
152 const QString appDir
= x264_data_path();
153 QSettings
settings(QString("%1/templates.ini").arg(appDir
), QSettings::IniFormat
);
154 QStringList allTemplates
= settings
.childGroups();
156 while(!allTemplates
.isEmpty())
158 QString name
= allTemplates
.takeFirst();
159 if(!(name
.contains('<') || name
.contains('>') || name
.contains('\\') || name
.contains('/')))
161 OptionsModel
*options
= new OptionsModel(sysinfo
);
162 if(loadTemplate(options
, name
))
164 list
.insert(name
, options
);
167 MUTILS_DELETE(options
);
174 bool OptionsModel::templateExists(const QString
&name
)
176 const QString appDir
= x264_data_path();
177 QSettings
settings(QString("%1/templates.ini").arg(appDir
), QSettings::IniFormat
);
178 QStringList allGroups
= settings
.childGroups();
179 return allGroups
.contains(name
, Qt::CaseInsensitive
);
182 bool OptionsModel::deleteTemplate(const QString
&name
)
184 const QString appDir
= x264_data_path();
185 QSettings
settings(QString("%1/templates.ini").arg(appDir
), QSettings::IniFormat
);
187 if(settings
.childGroups().contains(name
, Qt::CaseInsensitive
))
189 settings
.remove(name
);
196 bool OptionsModel::saveOptions(const OptionsModel
*model
, QSettings
&settingsFile
)
198 settingsFile
.setValue(KEY_ENCODER_TYPE
, model
->m_encoderType
);
199 settingsFile
.setValue(KEY_ENCODER_ARCH
, model
->m_encoderArch
);
200 settingsFile
.setValue(KEY_ENCODER_VARIANT
, model
->m_encoderVariant
);
201 settingsFile
.setValue(KEY_RATECTRL_MODE
, model
->m_rcMode
);
202 settingsFile
.setValue(KEY_TARGET_BITRATE
, model
->m_bitrate
);
203 settingsFile
.setValue(KEY_TARGET_QUANT
, model
->m_quantizer
);
204 settingsFile
.setValue(KEY_PRESET_NAME
, model
->m_preset
);
205 settingsFile
.setValue(KEY_TUNING_NAME
, model
->m_tune
);
206 settingsFile
.setValue(KEY_PROFILE_NAME
, model
->m_profile
);
207 settingsFile
.setValue(KEY_CUSTOM_ENCODER
, model
->m_custom_encoder
);
208 settingsFile
.setValue(KEY_CUSTOM_AVS2YUV
, model
->m_custom_avs2yuv
);
213 bool OptionsModel::loadOptions(OptionsModel
*model
, QSettings
&settingsFile
)
215 fixTemplate(settingsFile
); /*for backward compatibility*/
217 bool complete
= true;
218 if(!settingsFile
.contains(KEY_ENCODER_TYPE
)) complete
= false;
219 if(!settingsFile
.contains(KEY_ENCODER_ARCH
)) complete
= false;
220 if(!settingsFile
.contains(KEY_ENCODER_VARIANT
)) complete
= false;
221 if(!settingsFile
.contains(KEY_RATECTRL_MODE
)) complete
= false;
222 if(!settingsFile
.contains(KEY_TARGET_BITRATE
)) complete
= false;
223 if(!settingsFile
.contains(KEY_TARGET_QUANT
)) complete
= false;
224 if(!settingsFile
.contains(KEY_PRESET_NAME
)) complete
= false;
225 if(!settingsFile
.contains(KEY_TUNING_NAME
)) complete
= false;
226 if(!settingsFile
.contains(KEY_PROFILE_NAME
)) complete
= false;
227 if(!settingsFile
.contains(KEY_CUSTOM_ENCODER
)) complete
= false;
228 if(!settingsFile
.contains(KEY_CUSTOM_AVS2YUV
)) complete
= false;
232 model
->setEncType (settingsFile
.value(KEY_ENCODER_TYPE
, model
->m_encoderType
) .toInt());
233 model
->setEncArch (settingsFile
.value(KEY_ENCODER_ARCH
, model
->m_encoderArch
) .toInt());
234 model
->setEncVariant (settingsFile
.value(KEY_ENCODER_VARIANT
, model
->m_encoderVariant
).toInt());
235 model
->setRCMode (settingsFile
.value(KEY_RATECTRL_MODE
, model
->m_rcMode
) .toInt());
236 model
->setBitrate (settingsFile
.value(KEY_TARGET_BITRATE
, model
->m_bitrate
) .toUInt());
237 model
->setQuantizer (settingsFile
.value(KEY_TARGET_QUANT
, model
->m_quantizer
) .toDouble());
238 model
->setPreset (settingsFile
.value(KEY_PRESET_NAME
, model
->m_preset
) .toString());
239 model
->setTune (settingsFile
.value(KEY_TUNING_NAME
, model
->m_tune
) .toString());
240 model
->setProfile (settingsFile
.value(KEY_PROFILE_NAME
, model
->m_profile
) .toString());
241 model
->setCustomEncParams(settingsFile
.value(KEY_CUSTOM_ENCODER
, model
->m_custom_encoder
).toString());
242 model
->setCustomAvs2YUV (settingsFile
.value(KEY_CUSTOM_AVS2YUV
, model
->m_custom_avs2yuv
).toString());
248 void OptionsModel::fixTemplate(QSettings
&settingsFile
)
250 if(!(settingsFile
.contains(KEY_ENCODER_TYPE
) || settingsFile
.contains(KEY_ENCODER_ARCH
) || settingsFile
.contains(KEY_ENCODER_VARIANT
)))
252 settingsFile
.setValue(KEY_ENCODER_TYPE
, 0);
253 settingsFile
.setValue(KEY_ENCODER_ARCH
, 0);
254 settingsFile
.setValue(KEY_ENCODER_VARIANT
, 0);
257 static const char *legacyKey
[] = { "custom_params", "custom_params_x264", NULL
};
258 for(int i
= 0; legacyKey
[i
]; i
++)
260 if(settingsFile
.contains(legacyKey
[i
]))
262 settingsFile
.setValue(KEY_CUSTOM_ENCODER
, settingsFile
.value(legacyKey
[i
]));
263 settingsFile
.remove(legacyKey
[i
]);
267 if(settingsFile
.value(KEY_PROFILE_NAME
).toString().compare("auto", Qt::CaseInsensitive
) == 0)
269 settingsFile
.setValue(KEY_PROFILE_NAME
, QString::fromLatin1(OptionsModel::PROFILE_UNRESTRICTED
));
271 if(settingsFile
.value(KEY_TUNING_NAME
).toString().compare("none", Qt::CaseInsensitive
) == 0)
273 settingsFile
.setValue(KEY_TUNING_NAME
, QString::fromLatin1(OptionsModel::SETTING_UNSPECIFIED
));