File indexing completed on 2024-04-21 04:51:53

0001 /*
0002    SPDX-FileCopyrightText: 2017 Nicolas Carion
0003    SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004    This file is part of Kdenlive. See www.kdenlive.org.
0005 */
0006 
0007 #include "profilemodel.hpp"
0008 #include "core.h"
0009 #include "kdenlive_debug.h"
0010 #include "kdenlivesettings.h"
0011 #include <KLocalizedString>
0012 
0013 #include <KMessageWidget>
0014 #include <QDir>
0015 #include <QFile>
0016 #include <memory>
0017 
0018 ProfileModel::ProfileModel(const QString &path)
0019     : m_path(path)
0020     , m_invalid(false)
0021     , m_bottom_field_first(false)
0022 {
0023     if (!QFile::exists(path) && path.contains(QLatin1Char('/'))) {
0024         qCWarning(KDENLIVE_LOG) << "WARNING, COULD NOT FIND PROFILE " << path << ". We will default to DV_PAL profile";
0025         m_invalid = true;
0026     }
0027     if (!path.contains(QLatin1Char('/'))) {
0028         QDir mltDir(KdenliveSettings::mltpath());
0029         if (!mltDir.exists(path)) {
0030             qCWarning(KDENLIVE_LOG) << "WARNING, COULD NOT FIND MLT PROFILE " << path << ". We will default to DV_PAL profile";
0031             m_invalid = true;
0032         }
0033     }
0034     QFile f(path);
0035     if (f.open(QFile::ReadOnly | QFile::Text)) {
0036         int lineCt = 0;
0037         QTextStream in(&f);
0038         while (!in.atEnd() && lineCt < 30) {
0039             QString line = in.readLine();
0040             if (line.contains(QStringLiteral("bottom_field_first"))) {
0041                 m_bottom_field_first = line.split(QStringLiteral("=")).at(1).toInt() == 1;
0042                 f.close();
0043             }
0044         }
0045         f.close();
0046     }
0047     m_profile = std::make_unique<Mlt::Profile>(path.toUtf8().constData());
0048     m_description = QString(qstrdup(m_profile->description()));
0049 }
0050 
0051 bool ProfileModel::is_valid() const
0052 {
0053     return (!m_invalid) && m_profile->is_valid();
0054 }
0055 
0056 QString ProfileModel::description() const
0057 {
0058     return QString(qstrdup(m_profile->description()));
0059 }
0060 
0061 int ProfileModel::frame_rate_num() const
0062 {
0063     return m_profile->frame_rate_num();
0064 }
0065 
0066 int ProfileModel::frame_rate_den() const
0067 {
0068     return m_profile->frame_rate_den();
0069 }
0070 
0071 double ProfileModel::fps() const
0072 {
0073     return m_profile->fps();
0074 }
0075 
0076 int ProfileModel::width() const
0077 {
0078     return m_profile->width();
0079 }
0080 
0081 int ProfileModel::height() const
0082 {
0083     return m_profile->height();
0084 }
0085 
0086 bool ProfileModel::progressive() const
0087 {
0088     return m_profile->progressive();
0089 }
0090 
0091 bool ProfileModel::bottom_field_first() const
0092 {
0093     return m_bottom_field_first;
0094 }
0095 
0096 int ProfileModel::sample_aspect_num() const
0097 {
0098     return m_profile->sample_aspect_num();
0099 }
0100 
0101 int ProfileModel::sample_aspect_den() const
0102 {
0103     return m_profile->sample_aspect_den();
0104 }
0105 
0106 double ProfileModel::sar() const
0107 {
0108     return m_profile->sar();
0109 }
0110 
0111 int ProfileModel::display_aspect_num() const
0112 {
0113     return m_profile->display_aspect_num();
0114 }
0115 
0116 int ProfileModel::display_aspect_den() const
0117 {
0118     return m_profile->display_aspect_den();
0119 }
0120 
0121 double ProfileModel::dar() const
0122 {
0123     return m_profile->dar();
0124 }
0125 
0126 int ProfileModel::is_explicit() const
0127 {
0128     return m_profile->is_explicit();
0129 }
0130 
0131 int ProfileModel::colorspace() const
0132 {
0133     return m_profile->colorspace();
0134 }
0135 
0136 QString ProfileModel::path() const
0137 {
0138     return m_path;
0139 }
0140 
0141 mlt_profile ProfileModel::get_profile() const
0142 {
0143     return m_profile->get_profile();
0144 }
0145 
0146 void ProfileModel::set_explicit(int b)
0147 {
0148     m_profile->set_explicit(b);
0149 }
0150 
0151 ProfileParam::ProfileParam(QDomElement element)
0152     : m_description(element.attribute(QStringLiteral("description")))
0153     , m_frame_rate_num(element.attribute(QStringLiteral("frame_rate_num")).toInt())
0154     , m_frame_rate_den(element.attribute(QStringLiteral("frame_rate_den")).toInt())
0155     , m_progressive(element.attribute(QStringLiteral("progressive")).toInt() != 0)
0156     , m_bottom_field_first(element.attribute(QStringLiteral("bottom_field_first")).toInt() != 0)
0157     , m_sample_aspect_num(element.attribute(QStringLiteral("sample_aspect_num")).toInt())
0158     , m_sample_aspect_den(element.attribute(QStringLiteral("sample_aspect_den")).toInt())
0159     , m_display_aspect_num(element.attribute(QStringLiteral("display_aspect_num")).toInt())
0160     , m_display_aspect_den(element.attribute(QStringLiteral("display_aspect_den")).toInt())
0161     , m_colorspace(element.attribute(QStringLiteral("colorspace")).toInt())
0162 {
0163     // Ensure profile has viable width / height
0164     int width = element.attribute(QStringLiteral("width")).toInt();
0165     int height = element.attribute(QStringLiteral("height")).toInt();
0166     if ((width % 2) + (height % 2) > 0) {
0167         pCore->displayBinMessage(
0168             i18n("The project profile is invalid (%1x%2), it was adjusted to %3x%4.", width, height, width + (width % 2), height + (height % 2)),
0169             KMessageWidget::Warning);
0170         width += width % 2;
0171         height += height % 2;
0172         element.setAttribute(QStringLiteral("width"), width);
0173         element.setAttribute(QStringLiteral("height"), height);
0174     }
0175     m_width = width;
0176     m_height = height;
0177     m_fps = m_frame_rate_num / m_frame_rate_den;
0178     m_sar = m_sample_aspect_num / m_sample_aspect_den;
0179     m_dar = m_display_aspect_num / m_display_aspect_den;
0180 }
0181 
0182 ProfileParam::ProfileParam(ProfileInfo *p)
0183     : m_frame_rate_num(p->frame_rate_num())
0184     , m_frame_rate_den(p->frame_rate_den())
0185     , m_width(p->width())
0186     , m_height(p->height())
0187     , m_progressive(p->progressive())
0188     , m_bottom_field_first(p->bottom_field_first())
0189     , m_sample_aspect_num(p->sample_aspect_num())
0190     , m_sample_aspect_den(p->sample_aspect_den())
0191     , m_display_aspect_num(p->display_aspect_num())
0192     , m_display_aspect_den(p->display_aspect_den())
0193     , m_colorspace(p->colorspace())
0194     , m_fps(p->fps())
0195     , m_sar(p->sar())
0196     , m_dar(p->dar())
0197 {
0198 }
0199 
0200 ProfileParam::ProfileParam(ProfileParam *p)
0201     : m_path(qstrdup(p->path().toUtf8().constData()))
0202     , m_description(qstrdup(p->description().toUtf8().constData()))
0203     , m_frame_rate_num(p->frame_rate_num())
0204     , m_frame_rate_den(p->frame_rate_den())
0205     , m_width(p->width())
0206     , m_height(p->height())
0207     , m_progressive(p->progressive())
0208     , m_bottom_field_first(p->bottom_field_first())
0209     , m_sample_aspect_num(p->sample_aspect_num())
0210     , m_sample_aspect_den(p->sample_aspect_den())
0211     , m_display_aspect_num(p->display_aspect_num())
0212     , m_display_aspect_den(p->display_aspect_den())
0213     , m_colorspace(p->colorspace())
0214     , m_fps(p->fps())
0215     , m_sar(p->sar())
0216     , m_dar(p->dar())
0217 {
0218 }
0219 
0220 ProfileParam::ProfileParam(Mlt::Profile *p)
0221     : m_frame_rate_num(p->frame_rate_num())
0222     , m_frame_rate_den(p->frame_rate_den())
0223     , m_width(p->width())
0224     , m_height(p->height())
0225     , m_progressive(p->progressive())
0226     , m_bottom_field_first(false)
0227     , m_sample_aspect_num(p->sample_aspect_num())
0228     , m_sample_aspect_den(p->sample_aspect_den())
0229     , m_display_aspect_num(p->display_aspect_num())
0230     , m_display_aspect_den(p->display_aspect_den())
0231     , m_colorspace(p->colorspace())
0232     , m_fps(p->fps())
0233     , m_sar(p->sar())
0234     , m_dar(p->dar())
0235 {
0236 }
0237 QString ProfileParam::path() const
0238 {
0239     return m_path;
0240 }
0241 QString ProfileParam::description() const
0242 {
0243     return m_description;
0244 }
0245 int ProfileParam::frame_rate_num() const
0246 {
0247     return m_frame_rate_num;
0248 }
0249 int ProfileParam::frame_rate_den() const
0250 {
0251     return m_frame_rate_den;
0252 }
0253 int ProfileParam::width() const
0254 {
0255     return m_width;
0256 }
0257 int ProfileParam::height() const
0258 {
0259     return m_height;
0260 }
0261 bool ProfileParam::progressive() const
0262 {
0263     return m_progressive;
0264 }
0265 bool ProfileParam::bottom_field_first() const
0266 {
0267     return m_bottom_field_first;
0268 }
0269 int ProfileParam::sample_aspect_num() const
0270 {
0271     return m_sample_aspect_num;
0272 }
0273 int ProfileParam::sample_aspect_den() const
0274 {
0275     return m_sample_aspect_den;
0276 }
0277 int ProfileParam::display_aspect_num() const
0278 {
0279     return m_display_aspect_num;
0280 }
0281 int ProfileParam::display_aspect_den() const
0282 {
0283     return m_display_aspect_den;
0284 }
0285 int ProfileParam::colorspace() const
0286 {
0287     return m_colorspace;
0288 }
0289 
0290 double ProfileParam::fps() const
0291 {
0292     return m_fps;
0293 }
0294 double ProfileParam::dar() const
0295 {
0296     return m_dar;
0297 }
0298 double ProfileParam::sar() const
0299 {
0300     return m_sar;
0301 }
0302 void ProfileParam::adjustDimensions()
0303 {
0304     if (m_width % 2 > 0) {
0305         m_width += m_width % 2;
0306     }
0307     m_height += m_height % 2;
0308 }
0309 
0310 bool ProfileParam::is_valid() const
0311 {
0312     return (m_frame_rate_den > 0 && m_sample_aspect_den > 0 && m_display_aspect_den > 0 && m_width > 0);
0313 }