]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/sout/profile_selector.cpp
Qt: When changing a profile, use it right now.
[vlc] / modules / gui / qt4 / components / sout / profile_selector.cpp
1 /*****************************************************************************
2  * profile_selector.cpp : A small profile selector and editor
3  ****************************************************************************
4  * Copyright (C) 2009 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Jean-Baptiste Kempf <jb@videolan.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24
25 #include "components/sout/profile_selector.hpp"
26 #include "components/sout/profiles.hpp"
27 #include "dialogs/sout.hpp"
28
29 #include <QHBoxLayout>
30 #include <QToolButton>
31 #include <QComboBox>
32 #include <QLabel>
33 #include <QMessageBox>
34
35 VLCProfileSelector::VLCProfileSelector( QWidget *_parent ): QWidget( _parent )
36 {
37     QHBoxLayout *layout = new QHBoxLayout( this );
38
39     QLabel *prLabel = new QLabel( qtr( "Profile"), this );
40     layout->addWidget( prLabel );
41
42     profileBox = new QComboBox( this );
43     layout->addWidget( profileBox );
44
45     QToolButton *editButton = new QToolButton( this );
46     editButton->setIcon( QIcon( ":/preferences" ) );
47     editButton->setToolTip( qtr( "Edit selected profile" ) );
48     layout->addWidget( editButton );
49
50     QToolButton *deleteButton = new QToolButton( this );
51     deleteButton->setIcon( QIcon( ":/clear" ) );
52     deleteButton->setToolTip( qtr( "Delete selected profile" ) );
53     layout->addWidget( deleteButton );
54
55     QToolButton *newButton = new QToolButton( this );
56     newButton->setIcon( QIcon( ":/new" ) );
57     newButton->setToolTip( qtr( "Create a new profile" ) );
58     layout->addWidget(newButton);
59
60     BUTTONACT( newButton, newProfile() );
61     BUTTONACT( editButton, editProfile() );
62     BUTTONACT( deleteButton, deleteProfile() );
63     fillProfilesCombo();
64
65     CONNECT( profileBox, activated( int ),
66              this, updateOptions( int ) );
67
68     updateOptions( 0 );
69 }
70
71 inline void VLCProfileSelector::fillProfilesCombo()
72 {
73     QSettings settings(
74 #ifdef WIN32
75             QSettings::IniFormat,
76 #else
77             QSettings::NativeFormat,
78 #endif
79             QSettings::UserScope, "vlc", "vlc-qt-interface" );
80
81     int i_size = settings.beginReadArray( "codecs-profiles" );
82
83     for( int i = 0; i < i_size; i++ )
84     {
85         settings.setArrayIndex( i );
86         if( settings.value( "Profile-Name" ).toString().isEmpty() ) continue;
87         profileBox->addItem( settings.value( "Profile-Name" ).toString(),
88                 settings.value( "Profile-Value" ) );
89     }
90     if( i_size == 0 )
91     {
92         for( int i = 0; i < NB_PROFILE; i++ )
93         {
94             profileBox->addItem( video_profile_name_list[i],
95                                  video_profile_value_list[i] );
96         }
97     }
98     settings.endArray();
99 }
100
101 void VLCProfileSelector::newProfile()
102 {
103     editProfile( "", "" );
104 }
105
106 void VLCProfileSelector::editProfile()
107 {
108     editProfile( profileBox->currentText(),
109                  profileBox->itemData( profileBox->currentIndex() ).toString() );
110 }
111
112 void VLCProfileSelector::editProfile( const QString& qs, const QString& value )
113 {
114     VLCProfileEditor *editor = new VLCProfileEditor( qs, value, this );
115
116     if( QDialog::Accepted == editor->exec() )
117     {
118         if( qs.isEmpty() )
119             profileBox->addItem( editor->name, QVariant( editor->transcodeValue() ) );
120         else
121         {
122             int i_profile = profileBox->findText( qs );
123             profileBox->setItemText( i_profile, editor->name );
124             profileBox->setItemData( i_profile, QVariant( editor->transcodeValue() ) );
125             updateOptions( i_profile );
126         }
127     }
128     delete editor;
129
130     saveProfiles();
131     emit optionsChanged();
132 }
133
134 void VLCProfileSelector::deleteProfile()
135 {
136     profileBox->removeItem( profileBox->currentIndex() );
137 }
138
139 void VLCProfileSelector::saveProfiles()
140 {
141     QSettings settings(
142 #ifdef WIN32
143             QSettings::IniFormat,
144 #else
145             QSettings::NativeFormat,
146 #endif
147             QSettings::UserScope, "vlc", "vlc-qt-interface" );
148
149     settings.beginWriteArray( "codecs-profiles" );
150     for( int i = 0; i < profileBox->count(); i++ )
151     {
152         settings.setArrayIndex( i );
153         settings.setValue( "Profile-Name", profileBox->itemText( i ) );
154         settings.setValue( "Profile-Value", profileBox->itemData( i ).toString() );
155     }
156     settings.endArray();
157 }
158
159 void VLCProfileSelector::updateOptions( int i )
160 {
161     QStringList options = profileBox->itemData( i ).toString().split( ";" );
162     if( options.size() < 16 )
163         return;
164
165     mux = options[0];
166
167     SoutMrl smrl;
168     if( options[1].toInt() || options[2].toInt() || options[3].toInt() )
169     {
170         smrl.begin( "transcode" );
171
172         if( options[1].toInt() )
173         {
174             smrl.option( "vcodec", options[4] );
175             if( options[4] != "none" )
176             {
177                 smrl.option( "vb", options[5].toInt() );
178                 smrl.option( "scale", options[6] );
179                 smrl.option( "fps", options[7] );
180                 smrl.option( "width", options[8].toInt() );
181                 smrl.option( "height", options[9].toInt() );
182             }
183         }
184
185         if( options[2].toInt() )
186         {
187             smrl.option( "acodec", options[10] );
188             if( options[10] != "none" )
189             {
190                 smrl.option( "ab", options[11].toInt() );
191                 smrl.option( "channels", options[12].toInt() );
192                 smrl.option( "samplerate", options[13].toInt() );
193             }
194         }
195
196         if( options[3].toInt() )
197         {
198             smrl.option( "scodec", options[14] );
199             if( options[15].toInt() )
200                 smrl.option( "soverlay" );
201         }
202
203         smrl.end();
204
205         transcode = smrl.getMrl();
206     }
207     else
208         transcode = "";
209     emit optionsChanged();
210 }
211
212
213 /**
214  * VLCProfileEditor
215  **/
216 VLCProfileEditor::VLCProfileEditor( const QString& qs_name, const QString& value,
217         QWidget *_parent )
218                  : QVLCDialog( _parent, NULL )
219 {
220     ui.setupUi( this );
221     if( !qs_name.isEmpty() )
222     {
223         ui.profileLine->setText( qs_name );
224         ui.profileLine->setReadOnly( true );
225     }
226     registerCodecs();
227     CONNECT( ui.transcodeVideo, toggled( bool ),
228             this, setVTranscodeOptions( bool ) );
229     CONNECT( ui.transcodeAudio, toggled( bool ),
230             this, setATranscodeOptions( bool ) );
231     CONNECT( ui.transcodeSubs, toggled( bool ),
232             this, setSTranscodeOptions( bool ) );
233     setVTranscodeOptions( false );
234     setATranscodeOptions( false );
235     setSTranscodeOptions( false );
236
237     QPushButton *saveButton = new QPushButton( qtr( "Save" ) );
238     ui.buttonBox->addButton( saveButton, QDialogButtonBox::AcceptRole );
239     BUTTONACT( saveButton, close() );
240     QPushButton *cancelButton = new QPushButton( qtr( "Cancel" ) );
241     ui.buttonBox->addButton( cancelButton, QDialogButtonBox::RejectRole );
242     BUTTONACT( cancelButton, reject() );
243
244     fillProfile( value );
245 }
246
247 inline void VLCProfileEditor::registerCodecs()
248 {
249
250 #define ADD_VCODEC( name, fourcc ) ui.vCodecBox->addItem( name, QVariant( fourcc ) );
251     ADD_VCODEC( "MPEG-1", "mp1v" )
252     ADD_VCODEC( "MPEG-2", "mp2v" )
253     ADD_VCODEC( "MPEG-4", "mp4v" )
254     ADD_VCODEC( "DIVX 1" , "DIV1" )
255     ADD_VCODEC( "DIVX 2" , "DIV2" )
256     ADD_VCODEC( "DIVX 3" , "DIV3" )
257     ADD_VCODEC( "H-263", "H263" )
258     ADD_VCODEC( "H-264", "h264" )
259     ADD_VCODEC( "WMV1", "WMV1" )
260     ADD_VCODEC( "WMV2" , "WMV2" )
261     ADD_VCODEC( "M-JPEG", "MJPG" )
262     ADD_VCODEC( "Theora", "theo" )
263     ADD_VCODEC( "Dirac", "drac" )
264 #undef ADD_VCODEC
265
266 #define ADD_ACODEC( name, fourcc ) ui.aCodecBox->addItem( name, QVariant( fourcc ) );
267     ADD_ACODEC( "MPEG Audio", "mpga" )
268     ADD_ACODEC( "MP3", "mp3" )
269     ADD_ACODEC( "MPEG 4 Audio ( AAC )", "mp4a" )
270     ADD_ACODEC( "A52/AC-3", "a52" )
271     ADD_ACODEC( "Vorbis", "vorb" )
272     ADD_ACODEC( "Flac", "flac" )
273     ADD_ACODEC( "Speex", "spx" )
274     ADD_ACODEC( "WAV", "s16l" )
275     ADD_ACODEC( "WMA", "wma" )
276 #undef ADD_ACODEC
277
278 #define ADD_SCALING( factor ) ui.vScaleBox->addItem( factor );
279     ADD_SCALING( "1" )
280     ADD_SCALING( "0.25" )
281     ADD_SCALING( "0.5" )
282     ADD_SCALING( "0.75" )
283     ADD_SCALING( "1.25" )
284     ADD_SCALING( "1.5" )
285     ADD_SCALING( "1.75" )
286     ADD_SCALING( "2" )
287 #undef ADD_SCALING
288
289 #define ADD_SAMPLERATE( sample ) ui.aSampleBox->addItem( sample );
290     ADD_SAMPLERATE( "11250" )
291     ADD_SAMPLERATE( "22500" )
292     ADD_SAMPLERATE( "44100" )
293     ADD_SAMPLERATE( "48000" )
294 #undef ADD_SAMPLERATE
295
296 #define ADD_SCODEC( name, fourcc ) ui.subsCodecBox->addItem( name, QVariant( fourcc ) );
297     ADD_SCODEC( "DVB subtitle", "dvbs" )
298     ADD_SCODEC( "T.140", "t140" )
299 #undef ADD_SCODEC
300 }
301
302 void VLCProfileEditor::fillProfile( const QString& qs )
303 {
304     QStringList options = qs.split( ";" );
305     if( options.size() < 16 )
306         return;
307
308     ui.keepVideo->setChecked( !options[1].toInt() );
309     ui.transcodeVideo->setChecked( ( options[4] != "none" ) );
310     ui.keepAudio->setChecked( !options[2].toInt() );
311     ui.transcodeAudio->setChecked( ( options[10] != "none" ) );
312     ui.transcodeSubs->setChecked( options[3].toInt() );
313
314     ui.vCodecBox->setCurrentIndex( ui.vCodecBox->findData( options[4] ) );
315     ui.vBitrateSpin->setValue( options[5].toInt() );
316     ui.vScaleBox->setEditText( options[6] );
317     ui.vFrameBox->setValue( options[7].toDouble() );
318     ui.widthBox->setText( options[8] );
319     ui.heightBox->setText( options[9] );
320
321     ui.aCodecBox->setCurrentIndex( ui.aCodecBox->findData( options[10] ) );
322     ui.aBitrateSpin->setValue( options[11].toInt() );
323     ui.aChannelsSpin->setValue( options[12].toInt() );
324     ui.aSampleBox->setCurrentIndex( ui.aSampleBox->findText( options[13] ) );
325
326     ui.subsCodecBox->setCurrentIndex( ui.subsCodecBox->findData( options[14] ) );
327     ui.subsOverlay->setChecked( options[15].toInt() );
328 }
329
330 void VLCProfileEditor::setVTranscodeOptions( bool b_trans )
331 {
332     ui.vCodecLabel->setEnabled( b_trans );
333     ui.vCodecBox->setEnabled( b_trans );
334     ui.vBitrateLabel->setEnabled( b_trans );
335     ui.vBitrateSpin->setEnabled( b_trans );
336     ui.vScaleLabel->setEnabled( b_trans );
337     ui.vScaleBox->setEnabled( b_trans );
338     ui.heightBox->setEnabled( b_trans );
339     ui.heightLabel->setEnabled( b_trans );
340     ui.widthBox->setEnabled( b_trans );
341     ui.widthLabel->setEnabled( b_trans );
342     ui.vFrameBox->setEnabled( b_trans );
343     ui.vFrameLabel->setEnabled( b_trans );
344     ui.keepVideo->setEnabled( b_trans );
345 }
346
347 void VLCProfileEditor::setATranscodeOptions( bool b_trans )
348 {
349     ui.aCodecLabel->setEnabled( b_trans );
350     ui.aCodecBox->setEnabled( b_trans );
351     ui.aBitrateLabel->setEnabled( b_trans );
352     ui.aBitrateSpin->setEnabled( b_trans );
353     ui.aChannelsLabel->setEnabled( b_trans );
354     ui.aChannelsSpin->setEnabled( b_trans );
355     ui.aSampleLabel->setEnabled( b_trans );
356     ui.aSampleBox->setEnabled( b_trans );
357     ui.keepAudio->setEnabled( b_trans );
358 }
359
360 void VLCProfileEditor::setSTranscodeOptions( bool b_trans )
361 {
362     ui.subsCodecBox->setEnabled( b_trans );
363     ui.subsOverlay->setEnabled( b_trans );
364 }
365
366 void VLCProfileEditor::close()
367 {
368     if( ui.profileLine->text().isEmpty() )
369     {
370         QMessageBox::warning( this, qtr(" Profile Name Missing" ),
371                 qtr( "You must set a name for the profile." ) );
372         ui.profileLine->setFocus();
373         return;
374     }
375     name = ui.profileLine->text();
376
377     accept();
378 }
379
380 QString VLCProfileEditor::transcodeValue()
381 {
382 #define SMUX( x, txt ) if( ui.x->isChecked() ) muxValue =  txt; else
383     SMUX( PSMux, "ps" )
384     SMUX( TSMux, "ts" )
385     SMUX( MPEG1Mux, "mpeg1" )
386     SMUX( OggMux, "ogg" )
387     SMUX( ASFMux, "asf" )
388     SMUX( MOVMux, "mp4" )
389     SMUX( WAVMux, "wav" )
390     SMUX( RAWMux, "raw" )
391     SMUX( FLVMux, "flv" )
392     SMUX( MKVMux, "mkv" )
393     SMUX( AVIMux, "avi" )
394     SMUX( MJPEGMux, "mjpg" ){}
395 #undef SMUX
396
397 #define currentData( box ) box->itemData( box->currentIndex() )
398     QString qs_acodec, qs_vcodec;
399
400     qs_vcodec = ( ui.transcodeVideo->isChecked() ) ? currentData( ui.vCodecBox ).toString()
401                                                    : "none";
402     qs_acodec = ( ui.transcodeAudio->isChecked() ) ? currentData( ui.aCodecBox ).toString()
403                                                    : "none";
404     QStringList transcodeMRL;
405     transcodeMRL
406             << muxValue
407
408             << QString::number( !ui.keepVideo->isChecked() )
409             << QString::number( !ui.keepAudio->isChecked() )
410             << QString::number( ui.transcodeSubs->isChecked() )
411
412             << qs_vcodec
413             << QString::number( ui.vBitrateSpin->value() )
414             << ui.vScaleBox->currentText()
415             << QString::number( ui.vFrameBox->value() )
416             << ui.widthBox->text()
417             << ui.heightBox->text()
418
419             << qs_acodec
420             << QString::number( ui.aBitrateSpin->value() )
421             << QString::number( ui.aChannelsSpin->value() )
422             << ui.aSampleBox->currentText()
423
424             << currentData( ui.subsCodecBox ).toString()
425             << QString::number( ui.subsOverlay->isChecked() );
426 #undef currentData
427
428     return transcodeMRL.join( ";" );
429 }
430