mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-24 23:19:29 -05:00
made camera/audio only active when config panel is shown
This commit is contained in:
parent
c4fbd3a4f5
commit
d7ecd775eb
@ -22,7 +22,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AudioStats.h"
|
#include "AudioStats.h"
|
||||||
#include "AudioInputConfig.h"
|
#include "VOIPConfigPanel.h"
|
||||||
#include "audiodevicehelper.h"
|
#include "audiodevicehelper.h"
|
||||||
#include "AudioWizard.h"
|
#include "AudioWizard.h"
|
||||||
#include "gui/VideoProcessor.h"
|
#include "gui/VideoProcessor.h"
|
||||||
@ -95,10 +95,41 @@ VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags)
|
|||||||
abSpeech = NULL;
|
abSpeech = NULL;
|
||||||
qtTick = NULL;
|
qtTick = NULL;
|
||||||
|
|
||||||
|
ui.qcbTransmit->addItem(tr("Continuous"), RsVOIP::AudioTransmitContinous);
|
||||||
|
ui.qcbTransmit->addItem(tr("Voice Activity"), RsVOIP::AudioTransmitVAD);
|
||||||
|
ui.qcbTransmit->addItem(tr("Push To Talk"), RsVOIP::AudioTransmitPushToTalk);
|
||||||
|
|
||||||
|
abSpeech = new AudioBar();
|
||||||
|
abSpeech->qcBelow = Qt::red;
|
||||||
|
abSpeech->qcInside = Qt::yellow;
|
||||||
|
abSpeech->qcAbove = Qt::green;
|
||||||
|
//abSpeech->setGeometry(9,20,50,10);
|
||||||
|
ui.qwVadLayout_2->addWidget(abSpeech,0,0,1,0);
|
||||||
|
|
||||||
|
connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) );
|
||||||
|
connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) );
|
||||||
|
connect( ui.qsAmp, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsAmp_valueChanged(int) ) );
|
||||||
|
connect( ui.qcbTransmit, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_qcbTransmit_currentIndexChanged(int) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void VOIPConfigPanel::showEvent(QShowEvent *)
|
||||||
|
{
|
||||||
|
std::cerr << "Creating the audio pipeline" << std::endl;
|
||||||
|
|
||||||
|
inputAudioProcessor = new QtSpeex::SpeexInputProcessor();
|
||||||
|
inputAudioProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
|
||||||
|
|
||||||
|
inputAudioDevice = AudioDeviceHelper::getPreferedInputDevice();
|
||||||
|
inputAudioDevice->start(inputAudioProcessor);
|
||||||
|
|
||||||
|
connect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(emptyBuffer()));
|
||||||
|
|
||||||
|
std::cerr << "Creating the video pipeline" << std::endl;
|
||||||
|
|
||||||
// Create the video pipeline.
|
// Create the video pipeline.
|
||||||
//
|
//
|
||||||
|
|
||||||
videoInput = new QVideoInputDevice(this) ;
|
videoInput = new QVideoInputDevice(this) ;
|
||||||
videoInput->setEchoVideoTarget(ui.videoDisplay) ;
|
|
||||||
|
|
||||||
videoProcessor = new VideoProcessor() ;
|
videoProcessor = new VideoProcessor() ;
|
||||||
videoProcessor->setDisplayTarget(NULL) ;
|
videoProcessor->setDisplayTarget(NULL) ;
|
||||||
@ -114,8 +145,34 @@ VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags)
|
|||||||
graph_source->setCollectionTimeLimit(1000*300) ;
|
graph_source->setCollectionTimeLimit(1000*300) ;
|
||||||
graph_source->start() ;
|
graph_source->start() ;
|
||||||
|
|
||||||
|
if(ui.showEncoded_CB->isChecked())
|
||||||
|
{
|
||||||
|
videoInput->setEchoVideoTarget(nullptr) ;
|
||||||
|
videoProcessor->setDisplayTarget(ui.videoDisplay) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
videoInput->setEchoVideoTarget(ui.videoDisplay) ;
|
||||||
|
videoProcessor->setDisplayTarget(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
QObject::connect(ui.showEncoded_CB,SIGNAL(toggled(bool)),this,SLOT(togglePreview(bool))) ;
|
QObject::connect(ui.showEncoded_CB,SIGNAL(toggled(bool)),this,SLOT(togglePreview(bool))) ;
|
||||||
QObject::connect(ui.availableBW_SB,SIGNAL(valueChanged(double)),this,SLOT(updateAvailableBW(double))) ;
|
QObject::connect(ui.availableBW_SB,SIGNAL(valueChanged(double)),this,SLOT(updateAvailableBW(double))) ;
|
||||||
|
|
||||||
|
loadSettings();
|
||||||
|
|
||||||
|
qtTick = new RsProtectedTimer(this);
|
||||||
|
connect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) );
|
||||||
|
qtTick->start(20);
|
||||||
|
|
||||||
|
videoInput->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VOIPConfigPanel::hideEvent(QHideEvent *)
|
||||||
|
{
|
||||||
|
std::cerr << "Deleting the video pipeline" << std::endl;
|
||||||
|
|
||||||
|
clearPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VOIPConfigPanel::updateAvailableBW(double r)
|
void VOIPConfigPanel::updateAvailableBW(double r)
|
||||||
@ -140,136 +197,86 @@ void VOIPConfigPanel::togglePreview(bool b)
|
|||||||
|
|
||||||
VOIPConfigPanel::~VOIPConfigPanel()
|
VOIPConfigPanel::~VOIPConfigPanel()
|
||||||
{
|
{
|
||||||
disconnect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) );
|
clearPipeline();
|
||||||
|
}
|
||||||
|
|
||||||
graph_source->stop() ;
|
void VOIPConfigPanel::clearPipeline()
|
||||||
graph_source->setVideoInput(NULL) ;
|
{
|
||||||
|
delete qtTick;
|
||||||
|
|
||||||
|
graph_source->stop() ;
|
||||||
|
graph_source->setVideoInput(NULL) ;
|
||||||
|
graph_source=nullptr; // is deleted by setSource below. This is a bad design.
|
||||||
|
|
||||||
|
ui.voipBwGraph->setSource(nullptr);
|
||||||
|
|
||||||
std::cerr << "Deleting audioInputConfig object" << std::endl;
|
std::cerr << "Deleting audioInputConfig object" << std::endl;
|
||||||
if(videoInput != NULL)
|
if(videoInput != NULL)
|
||||||
{
|
{
|
||||||
videoInput->stop() ;
|
videoInput->stop() ;
|
||||||
delete videoInput ;
|
delete videoInput ;
|
||||||
|
|
||||||
|
videoInput = nullptr;
|
||||||
}
|
}
|
||||||
|
delete videoProcessor;
|
||||||
|
videoProcessor = nullptr;
|
||||||
|
|
||||||
if (inputAudioDevice) {
|
if (inputAudioDevice) {
|
||||||
inputAudioDevice->stop();
|
inputAudioDevice->stop();
|
||||||
delete inputAudioDevice ;
|
delete inputAudioDevice ;
|
||||||
inputAudioDevice = NULL ;
|
inputAudioDevice = nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inputAudioProcessor)
|
if(inputAudioProcessor)
|
||||||
{
|
{
|
||||||
delete inputAudioProcessor ;
|
delete inputAudioProcessor ;
|
||||||
inputAudioProcessor = NULL ;
|
inputAudioProcessor = nullptr ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads the settings for this page */
|
|
||||||
void VOIPConfigPanel::load()
|
void VOIPConfigPanel::load()
|
||||||
{
|
{
|
||||||
//connect( ui.allowIpDeterminationCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleIpDetermination(bool) ) );
|
|
||||||
//connect( ui.allowTunnelConnectionCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleTunnelConnection(bool) ) );
|
|
||||||
|
|
||||||
qtTick = new RsProtectedTimer(this);
|
|
||||||
connect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) );
|
|
||||||
qtTick->start(20);
|
|
||||||
/*if (AudioInputRegistrar::qmNew) {
|
|
||||||
QList<QString> keys = AudioInputRegistrar::qmNew->keys();
|
|
||||||
foreach(QString key, keys) {
|
|
||||||
qcbSystem->addItem(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qcbSystem->setEnabled(qcbSystem->count() > 1);*/
|
|
||||||
|
|
||||||
ui.qcbTransmit->addItem(tr("Continuous"), RsVOIP::AudioTransmitContinous);
|
|
||||||
ui.qcbTransmit->addItem(tr("Voice Activity"), RsVOIP::AudioTransmitVAD);
|
|
||||||
ui.qcbTransmit->addItem(tr("Push To Talk"), RsVOIP::AudioTransmitPushToTalk);
|
|
||||||
|
|
||||||
abSpeech = new AudioBar();
|
|
||||||
abSpeech->qcBelow = Qt::red;
|
|
||||||
abSpeech->qcInside = Qt::yellow;
|
|
||||||
abSpeech->qcAbove = Qt::green;
|
|
||||||
//abSpeech->setGeometry(9,20,50,10);
|
|
||||||
ui.qwVadLayout_2->addWidget(abSpeech,0,0,1,0);
|
|
||||||
|
|
||||||
//on_qcbPushClick_clicked(g.s.bPushClick);
|
|
||||||
//ui.on_Tick_timeout();
|
|
||||||
loadSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Loads the settings for this page */
|
||||||
|
|
||||||
void VOIPConfigPanel::loadSettings() {
|
void VOIPConfigPanel::loadSettings()
|
||||||
/*QList<QString> keys;
|
{
|
||||||
|
ui.qcbTransmit->setCurrentIndex(rsVOIP->getVoipATransmit());
|
||||||
|
on_qcbTransmit_currentIndexChanged(rsVOIP->getVoipATransmit());
|
||||||
|
ui.qsTransmitHold->setValue(rsVOIP->getVoipVoiceHold());
|
||||||
|
on_qsTransmitHold_valueChanged(rsVOIP->getVoipVoiceHold());
|
||||||
|
ui.qsTransmitMin->setValue(rsVOIP->getVoipfVADmin());
|
||||||
|
ui.qsTransmitMax->setValue(rsVOIP->getVoipfVADmax());
|
||||||
|
ui.qcbEchoCancel->setChecked(rsVOIP->getVoipEchoCancel());
|
||||||
|
|
||||||
if (AudioInputRegistrar::qmNew)
|
if (rsVOIP->getVoipiNoiseSuppress() != 0)
|
||||||
keys=AudioInputRegistrar::qmNew->keys();
|
ui.qsNoise->setValue(-rsVOIP->getVoipiNoiseSuppress());
|
||||||
else
|
else
|
||||||
keys.clear();
|
ui.qsNoise->setValue(14);
|
||||||
i=keys.indexOf(AudioInputRegistrar::current);
|
|
||||||
if (i >= 0)
|
|
||||||
loadComboBox(qcbSystem, i);
|
|
||||||
|
|
||||||
loadCheckBox(qcbExclusive, r.bExclusiveInput);*/
|
on_qsNoise_valueChanged(-rsVOIP->getVoipiNoiseSuppress());
|
||||||
|
|
||||||
//qlePushClickPathOn->setText(r.qsPushClickOn);
|
ui.qsAmp->setValue(20000 - rsVOIP->getVoipiMinLoudness());
|
||||||
//qlePushClickPathOff->setText(r.qsPushClickOff);
|
on_qsAmp_valueChanged(20000 - rsVOIP->getVoipiMinLoudness());
|
||||||
|
|
||||||
/*loadComboBox(qcbTransmit, r.atTransmit);
|
loaded = true;
|
||||||
loadSlider(qsTransmitHold, r.iVoiceHold);
|
|
||||||
loadSlider(qsTransmitMin, iroundf(r.fVADmin * 32767.0f + 0.5f));
|
|
||||||
loadSlider(qsTransmitMax, iroundf(r.fVADmax * 32767.0f + 0.5f));
|
|
||||||
loadSlider(qsFrames, (r.iFramesPerPacket == 1) ? 1 : (r.iFramesPerPacket/2 + 1));
|
|
||||||
loadSlider(qsDoublePush, iroundf(static_cast<float>(r.uiDoublePush) / 1000.f + 0.5f));*/
|
|
||||||
ui.qcbTransmit->setCurrentIndex(rsVOIP->getVoipATransmit());
|
|
||||||
on_qcbTransmit_currentIndexChanged(rsVOIP->getVoipATransmit());
|
|
||||||
ui.qsTransmitHold->setValue(rsVOIP->getVoipVoiceHold());
|
|
||||||
on_qsTransmitHold_valueChanged(rsVOIP->getVoipVoiceHold());
|
|
||||||
ui.qsTransmitMin->setValue(rsVOIP->getVoipfVADmin());
|
|
||||||
ui.qsTransmitMax->setValue(rsVOIP->getVoipfVADmax());
|
|
||||||
ui.qcbEchoCancel->setChecked(rsVOIP->getVoipEchoCancel());
|
|
||||||
//ui.qsDoublePush->setValue(iroundf(static_cast<float>(r.uiDoublePush) / 1000.f + 0.5f));
|
|
||||||
|
|
||||||
//loadCheckBox(qcbPushClick, r.bPushClick);
|
|
||||||
//loadSlider(qsQuality, r.iQuality);
|
|
||||||
if (rsVOIP->getVoipiNoiseSuppress() != 0)
|
|
||||||
ui.qsNoise->setValue(-rsVOIP->getVoipiNoiseSuppress());
|
|
||||||
else
|
|
||||||
ui.qsNoise->setValue(14);
|
|
||||||
|
|
||||||
on_qsNoise_valueChanged(-rsVOIP->getVoipiNoiseSuppress());
|
|
||||||
|
|
||||||
ui.qsAmp->setValue(20000 - rsVOIP->getVoipiMinLoudness());
|
|
||||||
on_qsAmp_valueChanged(20000 - rsVOIP->getVoipiMinLoudness());
|
|
||||||
//loadSlider(qsIdle, r.iIdleTime);
|
|
||||||
|
|
||||||
/*int echo = 0;
|
|
||||||
if (r.bEcho)
|
|
||||||
echo = r.bEchoMulti ? 2 : 1;
|
|
||||||
|
|
||||||
loadComboBox(qcbEcho, echo);*/
|
|
||||||
connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) );
|
|
||||||
connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) );
|
|
||||||
connect( ui.qsAmp, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsAmp_valueChanged(int) ) );
|
|
||||||
connect( ui.qcbTransmit, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_qcbTransmit_currentIndexChanged(int) ) );
|
|
||||||
loaded = true;
|
|
||||||
|
|
||||||
std::cerr << "AudioInputConfig:: starting video." << std::endl;
|
|
||||||
videoInput->start() ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VOIPConfigPanel::save(QString &/*errmsg*/) {//mainly useless beacause saving occurs in realtime
|
bool VOIPConfigPanel::save(QString &/*errmsg*/)
|
||||||
//s.iQuality = qsQuality->value();
|
{
|
||||||
rsVOIP->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value());
|
//mainly useless beacause saving occurs in realtime
|
||||||
rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value());
|
//s.iQuality = qsQuality->value();
|
||||||
rsVOIP->setVoipVoiceHold(ui.qsTransmitHold->value());
|
rsVOIP->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value());
|
||||||
rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value());
|
rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value());
|
||||||
rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value());
|
rsVOIP->setVoipVoiceHold(ui.qsTransmitHold->value());
|
||||||
/*s.uiDoublePush = qsDoublePush->value() * 1000;*/
|
rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value());
|
||||||
rsVOIP->setVoipATransmit(static_cast<RsVOIP::enumAudioTransmit>(ui.qcbTransmit->currentIndex() ));
|
rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value());
|
||||||
rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked());
|
/*s.uiDoublePush = qsDoublePush->value() * 1000;*/
|
||||||
|
rsVOIP->setVoipATransmit(static_cast<RsVOIP::enumAudioTransmit>(ui.qcbTransmit->currentIndex() ));
|
||||||
|
rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VOIPConfigPanel::on_qsTransmitHold_valueChanged(int v) {
|
void VOIPConfigPanel::on_qsTransmitHold_valueChanged(int v) {
|
||||||
@ -323,30 +330,21 @@ void VOIPConfigPanel::on_qcbTransmit_currentIndexChanged(int v) {
|
|||||||
|
|
||||||
void VOIPConfigPanel::on_Tick_timeout()
|
void VOIPConfigPanel::on_Tick_timeout()
|
||||||
{
|
{
|
||||||
if (!inputAudioProcessor)
|
// update the sound capture bar
|
||||||
{
|
|
||||||
inputAudioProcessor = new QtSpeex::SpeexInputProcessor();
|
|
||||||
inputAudioProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
|
|
||||||
|
|
||||||
if (!inputAudioDevice) {
|
abSpeech->iBelow = ui.qsTransmitMin->value();
|
||||||
inputAudioDevice = AudioDeviceHelper::getPreferedInputDevice();
|
abSpeech->iAbove = ui.qsTransmitMax->value();
|
||||||
}
|
|
||||||
inputAudioDevice->start(inputAudioProcessor);
|
|
||||||
connect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(emptyBuffer()));
|
|
||||||
}
|
|
||||||
|
|
||||||
abSpeech->iBelow = ui.qsTransmitMin->value();
|
if (loaded) {
|
||||||
abSpeech->iAbove = ui.qsTransmitMax->value();
|
rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value());
|
||||||
if (loaded) {
|
rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value());
|
||||||
rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value());
|
}
|
||||||
rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value());
|
|
||||||
}
|
|
||||||
|
|
||||||
abSpeech->iValue = iroundf(inputAudioProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f);
|
abSpeech->iValue = iroundf(inputAudioProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f);
|
||||||
|
abSpeech->update();
|
||||||
|
|
||||||
abSpeech->update();
|
// also transmit encoded video
|
||||||
|
|
||||||
// also transmit encoded video
|
|
||||||
RsVOIPDataChunk chunk ;
|
RsVOIPDataChunk chunk ;
|
||||||
|
|
||||||
while((!videoInput->stopped()) && videoInput->getNextEncodedPacket(chunk))
|
while((!videoInput->stopped()) && videoInput->getNextEncodedPacket(chunk))
|
||||||
|
@ -67,9 +67,8 @@ class VOIPConfigPanel : public ConfigPage
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
QTimer *qtTick;
|
QTimer *qtTick;
|
||||||
/*void hideEvent(QHideEvent *event);
|
|
||||||
void showEvent(QShowEvent *event);*/
|
|
||||||
|
|
||||||
|
void clearPipeline();
|
||||||
public:
|
public:
|
||||||
/** Default Constructor */
|
/** Default Constructor */
|
||||||
VOIPConfigPanel(QWidget * parent = 0, Qt::WindowFlags flags = 0);
|
VOIPConfigPanel(QWidget * parent = 0, Qt::WindowFlags flags = 0);
|
||||||
@ -77,14 +76,16 @@ class VOIPConfigPanel : public ConfigPage
|
|||||||
~VOIPConfigPanel();
|
~VOIPConfigPanel();
|
||||||
|
|
||||||
/** Saves the changes on this page */
|
/** Saves the changes on this page */
|
||||||
virtual bool save(QString &errmsg);
|
virtual bool save(QString &errmsg)override ;
|
||||||
/** Loads the settings for this page */
|
/** Loads the settings for this page */
|
||||||
virtual void load();
|
virtual void load()override ;
|
||||||
|
|
||||||
virtual QPixmap iconPixmap() const { return QPixmap(":/images/talking_on.svg") ; }
|
virtual QPixmap iconPixmap() const override { return QPixmap(":/images/talking_on.svg") ; }
|
||||||
virtual QString pageName() const { return tr("VOIP") ; }
|
virtual QString pageName() const override { return tr("VOIP") ; }
|
||||||
virtual QString helpText() const { return ""; }
|
virtual QString helpText() const override { return ""; }
|
||||||
|
|
||||||
|
virtual void showEvent(QShowEvent *) override;
|
||||||
|
virtual void hideEvent(QHideEvent *event) override;
|
||||||
private slots:
|
private slots:
|
||||||
void updateAvailableBW(double r);
|
void updateAvailableBW(double r);
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
|
@ -239,7 +239,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="qgbAudio">
|
<widget class="QGroupBox" name="qgbAudio">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Audio Processing</string>
|
<string>Audio</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout">
|
<layout class="QGridLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
@ -353,7 +353,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Video Processing</string>
|
<string>Video</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
|
Loading…
Reference in New Issue
Block a user