1 /*
2  * Copyright (c) 2012-2018 Meltytech, LLC
3  * Author: Dan Dennedy <dan@dennedy.org>
4  *
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 3 of the License, or
8  * (at your option) any later version.
9  *
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.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "x11grabwidget.h"
20 #include "ui_x11grabwidget.h"
21 #include "pulseaudiowidget.h"
22 #include "jackproducerwidget.h"
23 #include "alsawidget.h"
24 #include "mltcontroller.h"
25 #include "shotcut_mlt_properties.h"
26 #include "util.h"
27 #include <QtWidgets>
28 
X11grabWidget(QWidget * parent)29 X11grabWidget::X11grabWidget(QWidget *parent) :
30     QWidget(parent),
31     ui(new Ui::X11grabWidget),
32     m_audioWidget(0)
33 {
34     ui->setupUi(this);
35     ui->applyButton->hide();
36     Util::setColorsToHighlight(ui->label_9);
37     ui->preset->saveDefaultPreset(getPreset());
38     ui->preset->loadPresets();
39 }
40 
~X11grabWidget()41 X11grabWidget::~X11grabWidget()
42 {
43     delete ui;
44 }
45 
on_positionComboBox_activated(int index)46 void X11grabWidget::on_positionComboBox_activated(int index)
47 {
48     ui->xSpinBox->setEnabled(index == 1);
49     ui->ySpinBox->setEnabled(index == 1);
50 }
51 
on_audioComboBox_activated(int index)52 void X11grabWidget::on_audioComboBox_activated(int index)
53 {
54     if (m_audioWidget)
55         delete m_audioWidget;
56     m_audioWidget = 0;
57     if (index == 1)
58         m_audioWidget = new PulseAudioWidget(this);
59     else if (index == 2)
60         m_audioWidget = new JackProducerWidget(this);
61     else if (index == 3)
62         m_audioWidget = new AlsaWidget(this);
63     if (m_audioWidget)
64         ui->audioLayout->addWidget(m_audioWidget);
65 }
66 
URL(Mlt::Profile & profile) const67 QString X11grabWidget::URL(Mlt::Profile& profile) const
68 {
69     if (!profile.is_explicit()) {
70         profile.set_width(ui->widthSpinBox->value());
71         profile.set_height(ui->heightSpinBox->value());
72         profile.set_sample_aspect(1, 1);
73         profile.set_progressive(1);
74         profile.set_colorspace(709);
75         profile.set_frame_rate(25, 1);
76     }
77     QString s = QString("x11grab:%1+%2,%3?width=%4&height=%5&framerate=%6&show_region=%7&draw_mouse=%8&follow_mouse=%9")
78             .arg(ui->lineEdit->text())
79             .arg(ui->xSpinBox->value())
80             .arg(ui->ySpinBox->value())
81             .arg(ui->widthSpinBox->value())
82             .arg(ui->heightSpinBox->value())
83             .arg(profile.fps())
84             .arg(ui->showRegionCheckBox->isChecked()? 1: 0)
85             .arg(ui->drawMouseCheckBox->isChecked()? 1 : 0)
86             .arg(ui->positionComboBox->currentIndex() - 1);
87     return s;
88 }
89 
newProducer(Mlt::Profile & profile)90 Mlt::Producer* X11grabWidget::newProducer(Mlt::Profile& profile)
91 {
92     Mlt::Producer* p = new Mlt::Producer(profile, URL(profile).toLatin1().constData());
93     if (!p->is_valid()) {
94         delete p;
95         p = new Mlt::Producer(profile, "color:");
96         p->set("error", 1);
97     }
98     else if (m_audioWidget) {
99         Mlt::Producer* audio = dynamic_cast<AbstractProducerWidget*>(m_audioWidget)->newProducer(profile);
100         Mlt::Tractor* tractor = new Mlt::Tractor;
101         tractor->set("_profile", profile.get_profile(), 0);
102         tractor->set_track(*p, 0);
103         delete p;
104         tractor->set_track(*audio, 1);
105         delete audio;
106         p = new Mlt::Producer(tractor->get_producer());
107         delete tractor;
108     }
109     p->set("display", ui->lineEdit->text().toLatin1().constData());
110     p->set("xpos", ui->xSpinBox->value());
111     p->set("ypos", ui->ySpinBox->value());
112     p->set("width", ui->widthSpinBox->value());
113     p->set("height", ui->heightSpinBox->value());
114     p->set("show_region", ui->showRegionCheckBox->isChecked()? 1: 0);
115     p->set("draw_mouse", ui->drawMouseCheckBox->isChecked()? 1: 0);
116     p->set("follow_mouse", ui->positionComboBox->currentIndex() - 1);
117     p->set("audio_ix", ui->audioComboBox->currentIndex());
118     p->set(kBackgroundCaptureProperty, 1);
119     p->set("force_seekable", 0);
120     return p;
121 }
122 
getPreset() const123 Mlt::Properties X11grabWidget::getPreset() const
124 {
125     Mlt::Properties p;
126     p.set("display", ui->lineEdit->text().toLatin1().constData());
127     p.set("xpos", ui->xSpinBox->value());
128     p.set("ypos", ui->ySpinBox->value());
129     p.set("width", ui->widthSpinBox->value());
130     p.set("height", ui->heightSpinBox->value());
131     p.set("show_region", ui->showRegionCheckBox->isChecked()? 1: 0);
132     p.set("draw_mouse", ui->drawMouseCheckBox->isChecked()? 1: 0);
133     p.set("follow_mouse", ui->positionComboBox->currentIndex() - 1);
134     p.set("audio_ix", ui->audioComboBox->currentIndex());
135     p.set(kBackgroundCaptureProperty, 1);
136     return p;
137 }
138 
loadPreset(Mlt::Properties & p)139 void X11grabWidget::loadPreset(Mlt::Properties& p)
140 {
141     ui->lineEdit->setText(p.get("display"));
142     ui->xSpinBox->setValue(p.get_int("xpos"));
143     ui->ySpinBox->setValue(p.get_int("ypos"));
144     ui->widthSpinBox->setValue(p.get_int("width"));
145     ui->heightSpinBox->setValue(p.get_int("height"));
146     ui->showRegionCheckBox->setChecked(p.get_int("show_region"));
147     ui->drawMouseCheckBox->setChecked(p.get_int("draw_mouse"));
148     ui->positionComboBox->setCurrentIndex(p.get_int("follow_mouse") + 1);
149     ui->audioComboBox->setCurrentIndex(p.get_int("audio_ix"));
150     on_audioComboBox_activated(p.get_int("audio_ix"));
151 }
152 
on_preset_selected(void * p)153 void X11grabWidget::on_preset_selected(void* p)
154 {
155     Mlt::Properties* properties = (Mlt::Properties*) p;
156     loadPreset(*properties);
157     delete properties;
158 }
159 
on_preset_saveClicked()160 void X11grabWidget::on_preset_saveClicked()
161 {
162     ui->preset->savePreset(getPreset());
163 }
164 
setProducer(Mlt::Producer * producer)165 void X11grabWidget::setProducer(Mlt::Producer* producer)
166 {
167     ui->applyButton->show();
168     if (producer)
169         loadPreset(*producer);
170 }
171 
on_applyButton_clicked()172 void X11grabWidget::on_applyButton_clicked()
173 {
174     MLT.close();
175     AbstractProducerWidget::setProducer(0);
176     emit producerChanged(0);
177     QCoreApplication::processEvents();
178 
179     Mlt::Producer* p = newProducer(MLT.profile());
180     AbstractProducerWidget::setProducer(p);
181     MLT.setProducer(p);
182     MLT.play();
183     emit producerChanged(p);
184 }
185