1 /*****************************************************************************
2 * profile_selector.cpp : A small profile selector and editor
3 ****************************************************************************
4 * Copyright (C) 2009 the VideoLAN team
7 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
25 #include "components/sout/profile_selector.hpp"
26 #include "components/sout/profiles.hpp"
27 #include "dialogs/sout.hpp"
29 #include <QHBoxLayout>
30 #include <QToolButton>
33 #include <QMessageBox>
37 VLCProfileSelector::VLCProfileSelector( QWidget *_parent ): QWidget( _parent )
39 QHBoxLayout *layout = new QHBoxLayout( this );
41 QLabel *prLabel = new QLabel( qtr( "Profile"), this );
42 layout->addWidget( prLabel );
44 profileBox = new QComboBox( this );
45 layout->addWidget( profileBox );
47 QToolButton *editButton = new QToolButton( this );
48 editButton->setIcon( QIcon( ":/menu/preferences" ) );
49 editButton->setToolTip( qtr( "Edit selected profile" ) );
50 layout->addWidget( editButton );
52 QToolButton *deleteButton = new QToolButton( this );
53 deleteButton->setIcon( QIcon( ":/toolbar/clear" ) );
54 deleteButton->setToolTip( qtr( "Delete selected profile" ) );
55 layout->addWidget( deleteButton );
57 QToolButton *newButton = new QToolButton( this );
58 newButton->setIcon( QIcon( ":/new" ) );
59 newButton->setToolTip( qtr( "Create a new profile" ) );
60 layout->addWidget(newButton);
62 BUTTONACT( newButton, newProfile() );
63 BUTTONACT( editButton, editProfile() );
64 BUTTONACT( deleteButton, deleteProfile() );
67 CONNECT( profileBox, activated( int ),
68 this, updateOptions( int ) );
73 inline void VLCProfileSelector::fillProfilesCombo()
79 QSettings::NativeFormat,
81 QSettings::UserScope, "vlc", "vlc-qt-interface" );
83 int i_size = settings.beginReadArray( "codecs-profiles" );
85 for( int i = 0; i < i_size; i++ )
87 settings.setArrayIndex( i );
88 if( settings.value( "Profile-Name" ).toString().isEmpty() ) continue;
89 profileBox->addItem( settings.value( "Profile-Name" ).toString(),
90 settings.value( "Profile-Value" ) );
94 for( size_t i = 0; i < NB_PROFILE; i++ )
96 profileBox->addItem( video_profile_name_list[i],
97 video_profile_value_list[i] );
103 void VLCProfileSelector::newProfile()
105 editProfile( "", "" );
108 void VLCProfileSelector::editProfile()
110 editProfile( profileBox->currentText(),
111 profileBox->itemData( profileBox->currentIndex() ).toString() );
114 void VLCProfileSelector::editProfile( const QString& qs, const QString& value )
116 /* Create the Profile Editor */
117 VLCProfileEditor *editor = new VLCProfileEditor( qs, value, this );
120 if( QDialog::Accepted == editor->exec() )
124 profileBox->addItem( editor->name, QVariant( editor->transcodeValue() ) );
125 /* Update old profile */
128 /* Look for the profile */
129 int i_profile = profileBox->findText( qs );
130 assert( i_profile != -1 );
131 profileBox->setItemText( i_profile, editor->name );
132 profileBox->setItemData( i_profile, QVariant( editor->transcodeValue() ) );
133 /* Force mrl recreation */
134 updateOptions( i_profile );
140 emit optionsChanged();
143 void VLCProfileSelector::deleteProfile()
145 profileBox->removeItem( profileBox->currentIndex() );
148 void VLCProfileSelector::saveProfiles()
152 QSettings::IniFormat,
154 QSettings::NativeFormat,
156 QSettings::UserScope, "vlc", "vlc-qt-interface" );
158 settings.beginWriteArray( "codecs-profiles" );
159 for( int i = 0; i < profileBox->count(); i++ )
161 settings.setArrayIndex( i );
162 settings.setValue( "Profile-Name", profileBox->itemText( i ) );
163 settings.setValue( "Profile-Value", profileBox->itemData( i ).toString() );
168 void VLCProfileSelector::updateOptions( int i )
170 QStringList options = profileBox->itemData( i ).toString().split( ";" );
171 if( options.size() < 16 )
177 if( options[1].toInt() || options[2].toInt() || options[3].toInt() )
179 smrl.begin( "transcode" );
181 if( options[1].toInt() )
183 smrl.option( "vcodec", options[4] );
184 if( options[4] != "none" )
186 smrl.option( "vb", options[5].toInt() );
187 if( !options[7].isEmpty() && options[7].toInt() > 0 )
188 smrl.option( "fps", options[7] );
189 if( !options[6].isEmpty() )
190 smrl.option( "scale", options[6] );
191 if( !options[8].isEmpty() && options[8].toInt() > 0 )
192 smrl.option( "width", options[8].toInt() );
193 if( !options[9].isEmpty() && options[9].toInt() > 0 )
194 smrl.option( "height", options[9].toInt() );
198 if( options[2].toInt() )
200 smrl.option( "acodec", options[10] );
201 if( options[10] != "none" )
203 smrl.option( "ab", options[11].toInt() );
204 smrl.option( "channels", options[12].toInt() );
205 smrl.option( "samplerate", options[13].toInt() );
209 if( options[3].toInt() )
211 smrl.option( "scodec", options[14] );
212 if( options[15].toInt() )
213 smrl.option( "soverlay" );
218 transcode = smrl.getMrl();
222 emit optionsChanged();
229 VLCProfileEditor::VLCProfileEditor( const QString& qs_name, const QString& value,
231 : QVLCDialog( _parent, NULL )
234 if( !qs_name.isEmpty() )
236 ui.profileLine->setText( qs_name );
237 ui.profileLine->setReadOnly( true );
240 CONNECT( ui.transcodeVideo, toggled( bool ),
241 this, setVTranscodeOptions( bool ) );
242 CONNECT( ui.transcodeAudio, toggled( bool ),
243 this, setATranscodeOptions( bool ) );
244 CONNECT( ui.transcodeSubs, toggled( bool ),
245 this, setSTranscodeOptions( bool ) );
246 setVTranscodeOptions( false );
247 setATranscodeOptions( false );
248 setSTranscodeOptions( false );
250 QPushButton *saveButton = new QPushButton( qtr( "Save" ) );
251 ui.buttonBox->addButton( saveButton, QDialogButtonBox::AcceptRole );
252 BUTTONACT( saveButton, close() );
253 QPushButton *cancelButton = new QPushButton( qtr( "Cancel" ) );
254 ui.buttonBox->addButton( cancelButton, QDialogButtonBox::RejectRole );
255 BUTTONACT( cancelButton, reject() );
257 fillProfile( value );
260 inline void VLCProfileEditor::registerCodecs()
263 #define ADD_VCODEC( name, fourcc ) ui.vCodecBox->addItem( name, QVariant( fourcc ) );
264 ADD_VCODEC( "MPEG-1", "mp1v" )
265 ADD_VCODEC( "MPEG-2", "mp2v" )
266 ADD_VCODEC( "MPEG-4", "mp4v" )
267 ADD_VCODEC( "DIVX 1" , "DIV1" )
268 ADD_VCODEC( "DIVX 2" , "DIV2" )
269 ADD_VCODEC( "DIVX 3" , "DIV3" )
270 ADD_VCODEC( "H-263", "H263" )
271 ADD_VCODEC( "H-264", "h264" )
272 ADD_VCODEC( "WMV1", "WMV1" )
273 ADD_VCODEC( "WMV2" , "WMV2" )
274 ADD_VCODEC( "M-JPEG", "MJPG" )
275 ADD_VCODEC( "Theora", "theo" )
276 ADD_VCODEC( "Dirac", "drac" )
279 #define ADD_ACODEC( name, fourcc ) ui.aCodecBox->addItem( name, QVariant( fourcc ) );
280 ADD_ACODEC( "MPEG Audio", "mpga" )
281 ADD_ACODEC( "MP3", "mp3" )
282 ADD_ACODEC( "MPEG 4 Audio ( AAC )", "mp4a" )
283 ADD_ACODEC( "A52/AC-3", "a52" )
284 ADD_ACODEC( "Vorbis", "vorb" )
285 ADD_ACODEC( "Flac", "flac" )
286 ADD_ACODEC( "Speex", "spx" )
287 ADD_ACODEC( "WAV", "s16l" )
288 ADD_ACODEC( "WMA2", "wma2" )
291 #define ADD_SCALING( factor ) ui.vScaleBox->addItem( factor );
293 ADD_SCALING( "0.25" )
295 ADD_SCALING( "0.75" )
296 ADD_SCALING( "1.25" )
298 ADD_SCALING( "1.75" )
302 #define ADD_SAMPLERATE( sample ) ui.aSampleBox->addItem( sample );
303 ADD_SAMPLERATE( "8000" )
304 ADD_SAMPLERATE( "11025" )
305 ADD_SAMPLERATE( "22050" )
306 ADD_SAMPLERATE( "44100" )
307 ADD_SAMPLERATE( "48000" )
308 #undef ADD_SAMPLERATE
310 #define ADD_SCODEC( name, fourcc ) ui.subsCodecBox->addItem( name, QVariant( fourcc ) );
311 ADD_SCODEC( "DVB subtitle", "dvbs" )
312 ADD_SCODEC( "T.140", "t140" )
316 void VLCProfileEditor::fillProfile( const QString& qs )
318 QStringList options = qs.split( ";" );
319 if( options.size() < 16 )
322 const QString mux = options[0];
323 #define CHECKMUX( button, text) if( text == mux ) ui.button->setChecked( true ); else
324 CHECKMUX( PSMux, "ps" )
325 CHECKMUX( TSMux, "ts" )
326 CHECKMUX( MPEG1Mux, "mpeg1" )
327 CHECKMUX( OggMux, "ogg" )
328 CHECKMUX( ASFMux, "asf" )
329 CHECKMUX( MOVMux, "mp4" )
330 CHECKMUX( WAVMux, "wav" )
331 CHECKMUX( RAWMux, "raw" )
332 CHECKMUX( FLVMux, "flv" )
333 CHECKMUX( MKVMux, "mkv" )
334 CHECKMUX( AVIMux, "avi" )
335 CHECKMUX( MJPEGMux, "mpjpeg" ){}
338 ui.keepVideo->setChecked( !options[1].toInt() );
339 ui.transcodeVideo->setChecked( ( options[4] != "none" ) );
340 ui.keepAudio->setChecked( !options[2].toInt() );
341 ui.transcodeAudio->setChecked( ( options[10] != "none" ) );
342 ui.transcodeSubs->setChecked( options[3].toInt() );
344 ui.vCodecBox->setCurrentIndex( ui.vCodecBox->findData( options[4] ) );
345 ui.vBitrateSpin->setValue( options[5].toInt() );
346 ui.vScaleBox->setEditText( options[6] );
347 ui.vFrameBox->setValue( options[7].toDouble() );
348 ui.widthBox->setText( options[8] );
349 ui.heightBox->setText( options[9] );
351 ui.aCodecBox->setCurrentIndex( ui.aCodecBox->findData( options[10] ) );
352 ui.aBitrateSpin->setValue( options[11].toInt() );
353 ui.aChannelsSpin->setValue( options[12].toInt() );
354 ui.aSampleBox->setCurrentIndex( ui.aSampleBox->findText( options[13] ) );
356 ui.subsCodecBox->setCurrentIndex( ui.subsCodecBox->findData( options[14] ) );
357 ui.subsOverlay->setChecked( options[15].toInt() );
360 void VLCProfileEditor::setVTranscodeOptions( bool b_trans )
362 ui.vCodecLabel->setEnabled( b_trans );
363 ui.vCodecBox->setEnabled( b_trans );
364 ui.vBitrateLabel->setEnabled( b_trans );
365 ui.vBitrateSpin->setEnabled( b_trans );
366 ui.vScaleLabel->setEnabled( b_trans );
367 ui.vScaleBox->setEnabled( b_trans );
368 ui.heightBox->setEnabled( b_trans );
369 ui.heightLabel->setEnabled( b_trans );
370 ui.widthBox->setEnabled( b_trans );
371 ui.widthLabel->setEnabled( b_trans );
372 ui.vFrameBox->setEnabled( b_trans );
373 ui.vFrameLabel->setEnabled( b_trans );
374 ui.keepVideo->setEnabled( b_trans );
377 void VLCProfileEditor::setATranscodeOptions( bool b_trans )
379 ui.aCodecLabel->setEnabled( b_trans );
380 ui.aCodecBox->setEnabled( b_trans );
381 ui.aBitrateLabel->setEnabled( b_trans );
382 ui.aBitrateSpin->setEnabled( b_trans );
383 ui.aChannelsLabel->setEnabled( b_trans );
384 ui.aChannelsSpin->setEnabled( b_trans );
385 ui.aSampleLabel->setEnabled( b_trans );
386 ui.aSampleBox->setEnabled( b_trans );
387 ui.keepAudio->setEnabled( b_trans );
390 void VLCProfileEditor::setSTranscodeOptions( bool b_trans )
392 ui.subsCodecBox->setEnabled( b_trans );
393 ui.subsOverlay->setEnabled( b_trans );
396 void VLCProfileEditor::close()
398 if( ui.profileLine->text().isEmpty() )
400 QMessageBox::warning( this, qtr(" Profile Name Missing" ),
401 qtr( "You must set a name for the profile." ) );
402 ui.profileLine->setFocus();
405 name = ui.profileLine->text();
410 QString VLCProfileEditor::transcodeValue()
412 #define SMUX( x, txt ) if( ui.x->isChecked() ) muxValue = txt; else
415 SMUX( MPEG1Mux, "mpeg1" )
416 SMUX( OggMux, "ogg" )
417 SMUX( ASFMux, "asf" )
418 SMUX( MOVMux, "mp4" )
419 SMUX( WAVMux, "wav" )
420 SMUX( RAWMux, "raw" )
421 SMUX( FLVMux, "flv" )
422 SMUX( MKVMux, "mkv" )
423 SMUX( AVIMux, "avi" )
424 SMUX( MJPEGMux, "mpjpeg" ){}
427 #define currentData( box ) box->itemData( box->currentIndex() )
428 QString qs_acodec, qs_vcodec;
430 qs_vcodec = ( ui.transcodeVideo->isChecked() ) ? currentData( ui.vCodecBox ).toString()
432 qs_acodec = ( ui.transcodeAudio->isChecked() ) ? currentData( ui.aCodecBox ).toString()
434 QStringList transcodeMRL;
438 << QString::number( !ui.keepVideo->isChecked() )
439 << QString::number( !ui.keepAudio->isChecked() )
440 << QString::number( ui.transcodeSubs->isChecked() )
443 << QString::number( ui.vBitrateSpin->value() )
444 << ui.vScaleBox->currentText()
445 << QString::number( ui.vFrameBox->value() )
446 << ui.widthBox->text()
447 << ui.heightBox->text()
450 << QString::number( ui.aBitrateSpin->value() )
451 << QString::number( ui.aChannelsSpin->value() )
452 << ui.aSampleBox->currentText()
454 << currentData( ui.subsCodecBox ).toString()
455 << QString::number( ui.subsOverlay->isChecked() );
458 return transcodeMRL.join( ";" );