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( "VP8", "VP80" )
273 ADD_VCODEC( "WMV1", "WMV1" )
274 ADD_VCODEC( "WMV2" , "WMV2" )
275 ADD_VCODEC( "M-JPEG", "MJPG" )
276 ADD_VCODEC( "Theora", "theo" )
277 ADD_VCODEC( "Dirac", "drac" )
280 #define ADD_ACODEC( name, fourcc ) ui.aCodecBox->addItem( name, QVariant( fourcc ) );
281 ADD_ACODEC( "MPEG Audio", "mpga" )
282 ADD_ACODEC( "MP3", "mp3" )
283 ADD_ACODEC( "MPEG 4 Audio ( AAC )", "mp4a" )
284 ADD_ACODEC( "A52/AC-3", "a52" )
285 ADD_ACODEC( "Vorbis", "vorb" )
286 ADD_ACODEC( "Flac", "flac" )
287 ADD_ACODEC( "Speex", "spx" )
288 ADD_ACODEC( "WAV", "s16l" )
289 ADD_ACODEC( "WMA2", "wma2" )
292 #define ADD_SCALING( factor ) ui.vScaleBox->addItem( factor );
294 ADD_SCALING( "0.25" )
296 ADD_SCALING( "0.75" )
297 ADD_SCALING( "1.25" )
299 ADD_SCALING( "1.75" )
303 #define ADD_SAMPLERATE( sample ) ui.aSampleBox->addItem( sample );
304 ADD_SAMPLERATE( "8000" )
305 ADD_SAMPLERATE( "11025" )
306 ADD_SAMPLERATE( "22050" )
307 ADD_SAMPLERATE( "44100" )
308 ADD_SAMPLERATE( "48000" )
309 #undef ADD_SAMPLERATE
311 #define ADD_SCODEC( name, fourcc ) ui.subsCodecBox->addItem( name, QVariant( fourcc ) );
312 ADD_SCODEC( "DVB subtitle", "dvbs" )
313 ADD_SCODEC( "T.140", "t140" )
317 void VLCProfileEditor::fillProfile( const QString& qs )
319 QStringList options = qs.split( ";" );
320 if( options.size() < 16 )
323 const QString mux = options[0];
324 #define CHECKMUX( button, text) if( text == mux ) ui.button->setChecked( true ); else
325 CHECKMUX( PSMux, "ps" )
326 CHECKMUX( TSMux, "ts" )
327 CHECKMUX( WEBMux, "webm" )
328 CHECKMUX( MPEG1Mux, "mpeg1" )
329 CHECKMUX( OggMux, "ogg" )
330 CHECKMUX( ASFMux, "asf" )
331 CHECKMUX( MOVMux, "mp4" )
332 CHECKMUX( WAVMux, "wav" )
333 CHECKMUX( RAWMux, "raw" )
334 CHECKMUX( FLVMux, "flv" )
335 CHECKMUX( MKVMux, "mkv" )
336 CHECKMUX( AVIMux, "avi" )
337 CHECKMUX( MJPEGMux, "mpjpeg" ){}
340 ui.keepVideo->setChecked( !options[1].toInt() );
341 ui.transcodeVideo->setChecked( ( options[4] != "none" ) );
342 ui.keepAudio->setChecked( !options[2].toInt() );
343 ui.transcodeAudio->setChecked( ( options[10] != "none" ) );
344 ui.transcodeSubs->setChecked( options[3].toInt() );
346 ui.vCodecBox->setCurrentIndex( ui.vCodecBox->findData( options[4] ) );
347 ui.vBitrateSpin->setValue( options[5].toInt() );
348 ui.vScaleBox->setEditText( options[6] );
349 ui.vFrameBox->setValue( options[7].toDouble() );
350 ui.widthBox->setText( options[8] );
351 ui.heightBox->setText( options[9] );
353 ui.aCodecBox->setCurrentIndex( ui.aCodecBox->findData( options[10] ) );
354 ui.aBitrateSpin->setValue( options[11].toInt() );
355 ui.aChannelsSpin->setValue( options[12].toInt() );
356 ui.aSampleBox->setCurrentIndex( ui.aSampleBox->findText( options[13] ) );
358 ui.subsCodecBox->setCurrentIndex( ui.subsCodecBox->findData( options[14] ) );
359 ui.subsOverlay->setChecked( options[15].toInt() );
362 void VLCProfileEditor::setVTranscodeOptions( bool b_trans )
364 ui.vCodecLabel->setEnabled( b_trans );
365 ui.vCodecBox->setEnabled( b_trans );
366 ui.vBitrateLabel->setEnabled( b_trans );
367 ui.vBitrateSpin->setEnabled( b_trans );
368 ui.vScaleLabel->setEnabled( b_trans );
369 ui.vScaleBox->setEnabled( b_trans );
370 ui.heightBox->setEnabled( b_trans );
371 ui.heightLabel->setEnabled( b_trans );
372 ui.widthBox->setEnabled( b_trans );
373 ui.widthLabel->setEnabled( b_trans );
374 ui.vFrameBox->setEnabled( b_trans );
375 ui.vFrameLabel->setEnabled( b_trans );
376 ui.keepVideo->setEnabled( b_trans );
379 void VLCProfileEditor::setATranscodeOptions( bool b_trans )
381 ui.aCodecLabel->setEnabled( b_trans );
382 ui.aCodecBox->setEnabled( b_trans );
383 ui.aBitrateLabel->setEnabled( b_trans );
384 ui.aBitrateSpin->setEnabled( b_trans );
385 ui.aChannelsLabel->setEnabled( b_trans );
386 ui.aChannelsSpin->setEnabled( b_trans );
387 ui.aSampleLabel->setEnabled( b_trans );
388 ui.aSampleBox->setEnabled( b_trans );
389 ui.keepAudio->setEnabled( b_trans );
392 void VLCProfileEditor::setSTranscodeOptions( bool b_trans )
394 ui.subsCodecBox->setEnabled( b_trans );
395 ui.subsOverlay->setEnabled( b_trans );
398 void VLCProfileEditor::close()
400 if( ui.profileLine->text().isEmpty() )
402 QMessageBox::warning( this, qtr(" Profile Name Missing" ),
403 qtr( "You must set a name for the profile." ) );
404 ui.profileLine->setFocus();
407 name = ui.profileLine->text();
412 QString VLCProfileEditor::transcodeValue()
414 #define SMUX( x, txt ) if( ui.x->isChecked() ) muxValue = txt; else
417 SMUX( WEBMux, "webm" )
418 SMUX( MPEG1Mux, "mpeg1" )
419 SMUX( OggMux, "ogg" )
420 SMUX( ASFMux, "asf" )
421 SMUX( MOVMux, "mp4" )
422 SMUX( WAVMux, "wav" )
423 SMUX( RAWMux, "raw" )
424 SMUX( FLVMux, "flv" )
425 SMUX( MKVMux, "mkv" )
426 SMUX( AVIMux, "avi" )
427 SMUX( MJPEGMux, "mpjpeg" ){}
430 #define currentData( box ) box->itemData( box->currentIndex() )
431 QString qs_acodec, qs_vcodec;
433 qs_vcodec = ( ui.transcodeVideo->isChecked() ) ? currentData( ui.vCodecBox ).toString()
435 qs_acodec = ( ui.transcodeAudio->isChecked() ) ? currentData( ui.aCodecBox ).toString()
437 QStringList transcodeMRL;
441 << QString::number( !ui.keepVideo->isChecked() )
442 << QString::number( !ui.keepAudio->isChecked() )
443 << QString::number( ui.transcodeSubs->isChecked() )
446 << QString::number( ui.vBitrateSpin->value() )
447 << ui.vScaleBox->currentText()
448 << QString::number( ui.vFrameBox->value() )
449 << ui.widthBox->text()
450 << ui.heightBox->text()
453 << QString::number( ui.aBitrateSpin->value() )
454 << QString::number( ui.aChannelsSpin->value() )
455 << ui.aSampleBox->currentText()
457 << currentData( ui.subsCodecBox ).toString()
458 << QString::number( ui.subsOverlay->isChecked() );
461 return transcodeMRL.join( ";" );