Commit 43084cb6 authored by François Cartegnie's avatar François Cartegnie 🤞

Qt: profile_selector: rework profiles backup/restore

parent d7ad3f6f
......@@ -32,10 +32,17 @@
#include <QLabel>
#include <QMessageBox>
#include <QRadioButton>
#include <QRegExp>
#include <QButtonGroup>
#include <QSpinBox>
#include <assert.h>
#include <vlc_modules.h>
#define CATPROP2NAME( val ) QString("valueholder_%1").arg( val )
#define CATANDPROP( cat, prop ) QString("%1_%2").arg( cat ).arg( prop )
#define OLDFORMAT "^\\w+;\\d+;\\d+;\\d+;"
VLCProfileSelector::VLCProfileSelector( QWidget *_parent ): QWidget( _parent )
{
QHBoxLayout *layout = new QHBoxLayout( this );
......@@ -131,7 +138,7 @@ void VLCProfileSelector::editProfile( const QString& qs, const QString& value )
int i_profile = profileBox->findText( qs );
assert( i_profile != -1 );
profileBox->setItemText( i_profile, editor->name );
profileBox->setItemData( i_profile, QVariant( editor->transcodeValue() ) );
profileBox->setItemData( i_profile, editor->transcodeValue() );
/* Force mrl recreation */
updateOptions( i_profile );
}
......@@ -170,6 +177,141 @@ void VLCProfileSelector::saveProfiles()
}
void VLCProfileSelector::updateOptions( int i )
{
QString options = profileBox->itemData( i ).toString();
QRegExp rx(OLDFORMAT);
if ( !options.contains( ";" ) ) return;
if ( rx.indexIn( options ) != -1 )
return updateOptionsOldFormat( i );
transcode = "";
QStringList tuples = options.split( ";" );
typedef QHash<QString, QString> proptovalueHashType;
QHash<QString, proptovalueHashType *> categtopropHash;
proptovalueHashType *proptovalueHash;
QString value;
/* Build a double hash structure because we need to make ordered lookups */
foreach ( const QString &tuple, tuples )
{
QStringList keyvalue = tuple.split( "=" );
if ( keyvalue.count() != 2 ) continue;
QString key = keyvalue[0];
value = keyvalue[1];
keyvalue = key.split( "_" );
if ( keyvalue.count() != 2 ) continue;
QString categ = keyvalue[0];
QString prop = keyvalue[1];
if ( ! categtopropHash.contains( categ ) )
{
proptovalueHash = new proptovalueHashType();
categtopropHash.insert( categ, proptovalueHash );
} else {
proptovalueHash = categtopropHash.value( categ );
}
proptovalueHash->insert( prop, value );
}
/* Now we can build the/translate into MRL */
#define HASHPICK( categ, prop ) \
if ( categtopropHash.contains( categ ) ) \
{\
proptovalueHash = categtopropHash.value( categ );\
value = proptovalueHash->take( prop );\
}\
else value = QString()
SoutMrl smrl;
smrl.begin( "transcode" );
/* First muxer options */
HASHPICK( "muxer", "mux" );
if ( value.isEmpty() ) goto cleanup;
mux = value;
HASHPICK( "video", "enable" );
if ( !value.isEmpty() )
{
HASHPICK( "video", "codec" );
if ( !value.isEmpty() )
{
smrl.option( "vcodec", value );
HASHPICK( "vcodec", "bitrate" );
smrl.option( "vb", value.toInt() );
HASHPICK( "vcodec", "framerate" );
if ( !value.isEmpty() && value.toInt() > 0 )
smrl.option( "fps", value );
HASHPICK( "vcodec", "scale" );
if ( !value.isEmpty() )
smrl.option( "scale", value );
HASHPICK( "vcodec", "width" );
if ( !value.isEmpty() && value.toInt() > 0 )
smrl.option( "width", value );
HASHPICK( "vcodec", "height" );
if ( !value.isEmpty() && value.toInt() > 0 )
smrl.option( "height", value );
} else {
HASHPICK( "video", "copy" );
if ( ! value.isEmpty() )
smrl.option( "vcodec", "none" );
}
}
HASHPICK( "audio", "enable" );
if ( !value.isEmpty() )
{
HASHPICK( "audio", "codec" );
if ( !value.isEmpty() )
{
smrl.option( "acodec", value );
HASHPICK( "acodec", "bitrate" );
smrl.option( "ab", value.toInt() );
HASHPICK( "acodec", "channels" );
smrl.option( "channels", value.toInt() );
HASHPICK( "acodec", "samplerate" );
smrl.option( "samplerate", value.toInt() );
} else {
HASHPICK( "audio", "copy" );
if ( ! value.isEmpty() )
smrl.option( "acodec", "none" );
}
}
HASHPICK( "subtitles", "enable" );
if( !value.isEmpty() )
{
HASHPICK( "subtitles", "codec" );
smrl.option( "scodec", value );
HASHPICK( "subtitles", "overlay" );
if ( !value.isEmpty() )
smrl.option( "soverlay" );
}
smrl.end();
#undef HASHPICK
transcode = smrl.getMrl();
cleanup:
/* Temp hash tables cleanup */
foreach( proptovalueHashType *hash, categtopropHash )
delete hash;
emit optionsChanged();
}
void VLCProfileSelector::updateOptionsOldFormat( int i )
{
QStringList options = profileBox->itemData( i ).toString().split( ";" );
if( options.count() < 16 )
......@@ -235,6 +377,7 @@ VLCProfileEditor::VLCProfileEditor( const QString& qs_name, const QString& value
: QVLCDialog( _parent, NULL )
{
ui.setupUi( this );
ui.buttonGroup->setObjectName( CATPROP2NAME( CATANDPROP( "muxer", "mux" ) ) );
if( !qs_name.isEmpty() )
{
ui.profileLine->setText( qs_name );
......@@ -242,11 +385,11 @@ VLCProfileEditor::VLCProfileEditor( const QString& qs_name, const QString& value
}
loadCapabilities();
registerCodecs();
CONNECT( ui.transcodeVideo, toggled( bool ),
CONNECT( ui.valueholder_video_enable, toggled( bool ),
this, setVTranscodeOptions( bool ) );
CONNECT( ui.transcodeAudio, toggled( bool ),
CONNECT( ui.valueholder_audio_enable, toggled( bool ),
this, setATranscodeOptions( bool ) );
CONNECT( ui.transcodeSubs, toggled( bool ),
CONNECT( ui.valueholder_subtitles_enable, toggled( bool ),
this, setSTranscodeOptions( bool ) );
setVTranscodeOptions( false );
setATranscodeOptions( false );
......@@ -307,7 +450,8 @@ inline void VLCProfileEditor::registerCodecs()
SETMUX( MJPEGMux, "mpjpeg", true, false, false, false, false, false )
#undef SETMUX
#define ADD_VCODEC( name, fourcc ) ui.vCodecBox->addItem( name, QVariant( fourcc ) );
#define ADD_VCODEC( name, fourcc ) \
ui.valueholder_video_codec->addItem( name, QVariant( fourcc ) );
ADD_VCODEC( "MPEG-1", "mp1v" )
ADD_VCODEC( "MPEG-2", "mp2v" )
ADD_VCODEC( "MPEG-4", "mp4v" )
......@@ -324,7 +468,7 @@ inline void VLCProfileEditor::registerCodecs()
ADD_VCODEC( "Dirac", "drac" )
#undef ADD_VCODEC
#define ADD_ACODEC( name, fourcc ) ui.aCodecBox->addItem( name, QVariant( fourcc ) );
#define ADD_ACODEC( name, fourcc ) ui.valueholder_audio_codec->addItem( name, QVariant( fourcc ) );
ADD_ACODEC( "MPEG Audio", "mpga" )
ADD_ACODEC( "MP3", "mp3" )
ADD_ACODEC( "MPEG 4 Audio ( AAC )", "mp4a" )
......@@ -336,7 +480,7 @@ inline void VLCProfileEditor::registerCodecs()
ADD_ACODEC( "WMA2", "wma2" )
#undef ADD_ACODEC
#define ADD_SCALING( factor ) ui.vScaleBox->addItem( factor );
#define ADD_SCALING( factor ) ui.valueholder_vcodec_scale->addItem( factor );
ADD_SCALING( qtr("Auto") );
ADD_SCALING( "1" )
ADD_SCALING( "0.25" )
......@@ -348,7 +492,7 @@ inline void VLCProfileEditor::registerCodecs()
ADD_SCALING( "2" )
#undef ADD_SCALING
#define ADD_SAMPLERATE( sample, val ) ui.aSampleBox->addItem( sample, val );
#define ADD_SAMPLERATE( sample, val ) ui.valueholder_acodec_samplerate->addItem( sample, val );
ADD_SAMPLERATE( "8000 Hz", 8000 )
ADD_SAMPLERATE( "11025 Hz", 11025 )
ADD_SAMPLERATE( "22050 Hz", 22050 )
......@@ -356,7 +500,7 @@ inline void VLCProfileEditor::registerCodecs()
ADD_SAMPLERATE( "48000 Hz", 48000 )
#undef ADD_SAMPLERATE
#define ADD_SCODEC( name, fourcc ) ui.subsCodecBox->addItem( name, QVariant( fourcc ) );
#define ADD_SCODEC( name, fourcc ) ui.valueholder_subtitles_codec->addItem( name, QVariant( fourcc ) );
ADD_SCODEC( "DVB subtitle", "dvbs" )
ADD_SCODEC( "T.140", "t140" )
#undef ADD_SCODEC
......@@ -395,6 +539,57 @@ void VLCProfileEditor::muxSelected()
}
void VLCProfileEditor::fillProfile( const QString& qs )
{
QRegExp rx(OLDFORMAT);
if ( rx.indexIn( qs ) != -1 ) return fillProfileOldFormat( qs );
QStringList tuples = qs.split( ";" );
foreach ( const QString &tuple, tuples )
{
QStringList keyvalue = tuple.split( "=" );
if ( keyvalue.count() != 2 ) continue;
QString key = keyvalue[0];
QString value = keyvalue[1];
QObject *object = findChild<QObject *>( CATPROP2NAME( key ) );
if ( object )
{
if( object->inherits( "QButtonGroup" ) )
{ /* Buttongroup for Radios */
const QButtonGroup *group = qobject_cast<const QButtonGroup *>( object );
foreach( QAbstractButton *button, group->buttons() )
{
if ( button->property("sout").toString() == value )
{
button->setChecked( true );
break;/* radios are exclusive */
}
}
}
else if( object->inherits( "QCheckBox" ) )
{
QCheckBox *box = qobject_cast<QCheckBox *>( object );
box->setChecked( ! value.isEmpty() );
}
else if( object->inherits( "QSpinBox" ) )
{
QSpinBox *box = qobject_cast<QSpinBox *>( object );
box->setValue( value.toInt() );
}
else if( object->inherits( "QDoubleSpinBox" ) )
{
QDoubleSpinBox *box = qobject_cast<QDoubleSpinBox *>( object );
box->setValue( value.toDouble() );
}
else if( object->inherits( "QComboBox" ) )
{
QComboBox *box = qobject_cast<QComboBox *>( object );
box->setCurrentIndex( box->findData( value ) );
}
}
}
}
void VLCProfileEditor::fillProfileOldFormat( const QString& qs )
{
QStringList options = qs.split( ";" );
if( options.count() < 16 )
......@@ -413,68 +608,68 @@ void VLCProfileEditor::fillProfile( const QString& qs )
}
}
ui.keepVideo->setChecked( !options[1].toInt() );
ui.transcodeVideo->setChecked( ( options[4] != "none" ) );
ui.keepAudio->setChecked( !options[2].toInt() );
ui.transcodeAudio->setChecked( ( options[10] != "none" ) );
ui.transcodeSubs->setChecked( options[3].toInt() );
ui.valueholder_video_copy->setChecked( !options[1].toInt() );
ui.valueholder_video_enable->setChecked( ( options[4] != "none" ) );
ui.valueholder_audio_copy->setChecked( !options[2].toInt() );
ui.valueholder_audio_enable->setChecked( ( options[10] != "none" ) );
ui.valueholder_subtitles_enable->setChecked( options[3].toInt() );
ui.vCodecBox->setCurrentIndex( ui.vCodecBox->findData( options[4] ) );
ui.vBitrateSpin->setValue( options[5].toInt() );
ui.valueholder_video_codec->setCurrentIndex( ui.valueholder_video_codec->findData( options[4] ) );
ui.valueholder_vcodec_bitrate->setValue( options[5].toInt() );
if ( options[6].toInt() > 0 )
ui.vScaleBox->setEditText( options[6] );
ui.valueholder_vcodec_scale->setEditText( options[6] );
else
ui.vScaleBox->setCurrentIndex( 0 );
ui.vFrameBox->setValue( options[7].toDouble() );
ui.widthBox->setValue( options[8].toInt() );
ui.heightBox->setValue( options[9].toInt() );
ui.valueholder_vcodec_scale->setCurrentIndex( 0 );
ui.valueholder_vcodec_framerate->setValue( options[7].toDouble() );
ui.valueholder_vcodec_width->setValue( options[8].toInt() );
ui.valueholder_vcodec_height->setValue( options[9].toInt() );
ui.aCodecBox->setCurrentIndex( ui.aCodecBox->findData( options[10] ) );
ui.aBitrateSpin->setValue( options[11].toInt() );
ui.aChannelsSpin->setValue( options[12].toInt() );
ui.valueholder_audio_codec->setCurrentIndex( ui.valueholder_audio_codec->findData( options[10] ) );
ui.valueholder_acodec_bitrate->setValue( options[11].toInt() );
ui.valueholder_acodec_channels->setValue( options[12].toInt() );
int index = ui.aSampleBox->findData( options[13] );
if ( index == -1 ) index = ui.aSampleBox->findData( 44100 );
ui.aSampleBox->setCurrentIndex( index );
int index = ui.valueholder_acodec_samplerate->findData( options[13] );
if ( index == -1 ) index = ui.valueholder_acodec_samplerate->findData( 44100 );
ui.valueholder_acodec_samplerate->setCurrentIndex( index );
ui.subsCodecBox->setCurrentIndex( ui.subsCodecBox->findData( options[14] ) );
ui.subsOverlay->setChecked( options[15].toInt() );
ui.valueholder_subtitles_codec->setCurrentIndex( ui.valueholder_subtitles_codec->findData( options[14] ) );
ui.valueholder_subtitles_overlay->setChecked( options[15].toInt() );
}
void VLCProfileEditor::setVTranscodeOptions( bool b_trans )
{
ui.vCodecLabel->setEnabled( b_trans );
ui.vCodecBox->setEnabled( b_trans );
ui.valueholder_video_codec->setEnabled( b_trans );
ui.vBitrateLabel->setEnabled( b_trans );
ui.vBitrateSpin->setEnabled( b_trans );
ui.valueholder_vcodec_bitrate->setEnabled( b_trans );
ui.vScaleLabel->setEnabled( b_trans );
ui.vScaleBox->setEnabled( b_trans );
ui.heightBox->setEnabled( b_trans );
ui.valueholder_vcodec_scale->setEnabled( b_trans );
ui.valueholder_vcodec_height->setEnabled( b_trans );
ui.heightLabel->setEnabled( b_trans );
ui.widthBox->setEnabled( b_trans );
ui.valueholder_vcodec_width->setEnabled( b_trans );
ui.widthLabel->setEnabled( b_trans );
ui.vFrameBox->setEnabled( b_trans );
ui.valueholder_vcodec_framerate->setEnabled( b_trans );
ui.vFrameLabel->setEnabled( b_trans );
ui.keepVideo->setEnabled( b_trans );
ui.valueholder_video_copy->setEnabled( b_trans );
}
void VLCProfileEditor::setATranscodeOptions( bool b_trans )
{
ui.aCodecLabel->setEnabled( b_trans );
ui.aCodecBox->setEnabled( b_trans );
ui.valueholder_audio_codec->setEnabled( b_trans );
ui.aBitrateLabel->setEnabled( b_trans );
ui.aBitrateSpin->setEnabled( b_trans );
ui.valueholder_acodec_bitrate->setEnabled( b_trans );
ui.aChannelsLabel->setEnabled( b_trans );
ui.aChannelsSpin->setEnabled( b_trans );
ui.valueholder_acodec_channels->setEnabled( b_trans );
ui.aSampleLabel->setEnabled( b_trans );
ui.aSampleBox->setEnabled( b_trans );
ui.keepAudio->setEnabled( b_trans );
ui.valueholder_acodec_samplerate->setEnabled( b_trans );
ui.valueholder_audio_copy->setEnabled( b_trans );
}
void VLCProfileEditor::setSTranscodeOptions( bool b_trans )
{
ui.subsCodecBox->setEnabled( b_trans );
ui.subsOverlay->setEnabled( b_trans );
ui.valueholder_subtitles_codec->setEnabled( b_trans );
ui.valueholder_subtitles_overlay->setEnabled( b_trans );
}
void VLCProfileEditor::close()
......@@ -491,51 +686,61 @@ void VLCProfileEditor::close()
accept();
}
#define currentData( box ) box->itemData( box->currentIndex() )
QString VLCProfileEditor::transcodeValue()
{
for ( int i=0; i< ui.muxer->layout()->count(); i++ )
QList<QObject *> allwidgets = findChildren<QObject *>();
QStringList configuration;
foreach( const QObject *object, allwidgets )
{
QRadioButton *current =
qobject_cast<QRadioButton *>(ui.muxer->layout()->itemAt(i)->widget());
if ( unlikely( !current ) ) continue;/* someone is messing up with ui */
if ( current->isChecked() )
if ( ! object->objectName().startsWith( CATPROP2NAME( "" ) ) )
continue;
if ( object->inherits( "QWidget" ) &&
! qobject_cast<const QWidget *>(object)->isEnabled() ) continue;
QString name = object->objectName();
QStringList vals = object->objectName().split( "_" );
if ( vals.count() != 3 ) continue;
QString &categ = vals[1];
QString &prop = vals[2];
QString value;
if( object->inherits( "QButtonGroup" ) )
{
muxValue = current->property("sout").toString();
break;/* radios are exclusive */
const QButtonGroup *group = qobject_cast<const QButtonGroup *>( object );
value = group->checkedButton()->property( "sout" ).toString();
}
else if( object->inherits( "QCheckBox" ) )
{
const QCheckBox *box = qobject_cast<const QCheckBox *>( object );
value = box->isChecked() ? "yes" : "";
}
else if( object->inherits( "QSpinBox" ) )
{
const QSpinBox *box = qobject_cast<const QSpinBox *>( object );
value = QString::number( box->value() );
}
else if( object->inherits( "QDoubleSpinBox" ) )
{
const QDoubleSpinBox *box = qobject_cast<const QDoubleSpinBox *>( object );
value = QString::number( box->value() );
}
else if( object->inherits( "QComboBox" ) )
{
const QComboBox *box = qobject_cast<const QComboBox *>( object );
value = currentData( box ).toString();
}
if ( !value.isEmpty() )
configuration << QString( "%1_%2=%3" )
.arg( categ ).arg( prop ).arg( value );
}
#define currentData( box ) box->itemData( box->currentIndex() )
QString qs_acodec, qs_vcodec;
qs_vcodec = ( ui.transcodeVideo->isChecked() ) ? currentData( ui.vCodecBox ).toString()
: "none";
qs_acodec = ( ui.transcodeAudio->isChecked() ) ? currentData( ui.aCodecBox ).toString()
: "none";
QStringList transcodeMRL;
transcodeMRL
<< muxValue
<< QString::number( !ui.keepVideo->isChecked() )
<< QString::number( !ui.keepAudio->isChecked() )
<< QString::number( ui.transcodeSubs->isChecked() )
<< qs_vcodec
<< QString::number( ui.vBitrateSpin->value() )
<< ( ( ui.vScaleBox->currentIndex() != 0 ) ? ui.vScaleBox->currentText() : QString("0") )
<< QString::number( ui.vFrameBox->value() )
<< QString::number( ui.widthBox->value() )
<< QString::number( ui.heightBox->value() )
<< qs_acodec
<< QString::number( ui.aBitrateSpin->value() )
<< QString::number( ui.aChannelsSpin->value() )
<< currentData( ui.aSampleBox ).toString()
<< currentData( ui.subsCodecBox ).toString()
<< QString::number( ui.subsOverlay->isChecked() );
#undef currentData
return transcodeMRL.join( ";" );
return configuration.join( ";" );
}
#undef CATPROP2NAME
#undef CATANDPROP
#undef OLDFORMAT
......@@ -34,6 +34,7 @@
#include "ui/profiles.h"
class QComboBox;
class VLCProfileSelector : public QWidget
{
Q_OBJECT
......@@ -54,6 +55,7 @@ private slots:
void editProfile();
void deleteProfile();
void updateOptions( int i );
void updateOptionsOldFormat( int i );
signals:
void optionsChanged();
};
......@@ -72,6 +74,7 @@ public:
private:
void registerCodecs();
void fillProfile( const QString& qs );
void fillProfileOldFormat( const QString& qs );
typedef QSet<QString> resultset;
QHash<QString, resultset> caps;
void loadCapabilities();
......
......@@ -66,6 +66,9 @@
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="1" column="0">
......@@ -73,6 +76,9 @@
<property name="text">
<string>MPEG-PS</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="2" column="0">
......@@ -80,6 +86,9 @@
<property name="text">
<string>MPEG 1</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="3" column="0">
......@@ -87,6 +96,9 @@
<property name="text">
<string>ASF/WMV</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="0" column="1">
......@@ -94,6 +106,9 @@
<property name="text">
<string>Webm</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="1" column="1">
......@@ -101,6 +116,9 @@
<property name="text">
<string>MJPEG</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="2" column="1">
......@@ -108,6 +126,9 @@
<property name="text">
<string>MKV</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="0" column="2">
......@@ -115,6 +136,9 @@
<property name="text">
<string>Ogg/Ogm</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="1" column="2">
......@@ -122,6 +146,9 @@
<property name="text">
<string>WAV</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="2" column="2">
......@@ -129,6 +156,9 @@
<property name="text">
<string>RAW</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="0" column="3">
......@@ -136,6 +166,9 @@
<property name="text">
<string>MP4/MOV</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="1" column="3">
......@@ -143,6 +176,9 @@
<property name="text">
<string>FLV</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item row="2" column="3">
......@@ -150,6 +186,9 @@
<property name="text">
<string>AVI</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
</layout>
......@@ -260,7 +299,7 @@
<number>6</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="transcodeVideo">
<widget class="QCheckBox" name="valueholder_video_enable">
<property name="text">
<string>Video</string>
</property>
......@@ -275,12 +314,12 @@
<string>Codec</string>
</property>
<property name="buddy">
<cstring>vCodecBox</cstring>
<cstring>valueholder_video_codec</cstring>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QComboBox" name="vCodecBox">
<widget class="QComboBox" name="valueholder_video_codec">
<property name="editable">
<bool>false</bool>
</property>
......@@ -292,12 +331,12 @@
<string>Bitrate</string>
</property>
<property name="buddy">
<cstring>vBitrateSpin</cstring>
<cstring>valueholder_vcodec_bitrate</cstring>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="vBitrateSpin">
<widget class="QSpinBox" name="valueholder_vcodec_bitrate">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
......@@ -324,12 +363,12 @@
<string>Frame Rate</string>
</property>
<property name="buddy">
<cstring>vFrameBox</cstring>
<cstring>valueholder_vcodec_framerate</cstring>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QDoubleSpinBox" name="vFrameBox">
<widget class="QDoubleSpinBox" name="valueholder_vcodec_framerate">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>