]> git.sesse.net Git - vlc/blob - modules/gui/wxwidgets/streamout.cpp
wxWindows -> wxWidgets in configure.ac and renaming the dir.
[vlc] / modules / gui / wxwidgets / streamout.cpp
1 /*****************************************************************************
2  * streamout.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <errno.h>                                                 /* ENOMEM */
29 #include <string.h>                                            /* strerror() */
30 #include <stdio.h>
31
32 #include <vlc/vlc.h>
33 #include <vlc/intf.h>
34
35 #include "wxwindows.h"
36 #include <wx/combobox.h>
37 #include <wx/statline.h>
38
39 #include "streamdata.h"
40
41 #ifndef wxRB_SINGLE
42 #   define wxRB_SINGLE 0
43 #endif
44
45 /*****************************************************************************
46  * Event Table.
47  *****************************************************************************/
48
49 /* IDs for the controls and the menu commands */
50 enum
51 {
52     Notebook_Event = wxID_HIGHEST,
53     MRL_Event,
54
55     FileBrowse_Event,
56     FileName_Event,
57     FileDump_Event,
58
59     AccessType1_Event, AccessType2_Event, AccessType3_Event,
60     AccessType4_Event, AccessType5_Event, AccessType6_Event,
61     NetPort1_Event, NetPort2_Event, NetPort3_Event, NetPort4_Event,
62     NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
63
64     EncapsulationRadio1_Event, EncapsulationRadio2_Event,
65     EncapsulationRadio3_Event, EncapsulationRadio4_Event,
66     EncapsulationRadio5_Event, EncapsulationRadio6_Event,
67     EncapsulationRadio7_Event, EncapsulationRadio8_Event,
68     EncapsulationRadio9_Event, EncapsulationRadio10_Event,
69
70     VideoTranscEnable_Event, VideoTranscCodec_Event, VideoTranscBitrate_Event,
71     VideoTranscScale_Event,
72     AudioTranscEnable_Event, AudioTranscCodec_Event, AudioTranscBitrate_Event,
73     AudioTranscChans_Event,
74     SubtitlesTranscEnable_Event, SubtitlesTranscCodec_Event,
75     SubtitlesOverlayEnable_Event,
76
77     SAPMisc_Event, SLPMisc_Event, AnnounceGroup_Event, AnnounceAddr_Event,
78     SoutAll_Event
79 };
80
81 BEGIN_EVENT_TABLE(SoutDialog, wxDialog)
82     /* Button events */
83     EVT_BUTTON(wxID_OK, SoutDialog::OnOk)
84     EVT_BUTTON(wxID_CANCEL, SoutDialog::OnCancel)
85
86     /* Events generated by the access output panel */
87     EVT_CHECKBOX(AccessType1_Event, SoutDialog::OnAccessTypeChange)
88     EVT_CHECKBOX(AccessType2_Event, SoutDialog::OnAccessTypeChange)
89     EVT_CHECKBOX(AccessType3_Event, SoutDialog::OnAccessTypeChange)
90     EVT_CHECKBOX(AccessType4_Event, SoutDialog::OnAccessTypeChange)
91     EVT_CHECKBOX(AccessType5_Event, SoutDialog::OnAccessTypeChange)
92     EVT_CHECKBOX(AccessType6_Event, SoutDialog::OnAccessTypeChange)
93     EVT_TEXT(FileName_Event, SoutDialog::OnFileChange)
94     EVT_BUTTON(FileBrowse_Event, SoutDialog::OnFileBrowse)
95     EVT_CHECKBOX(FileDump_Event, SoutDialog::OnFileDump)
96
97     EVT_TEXT(NetPort1_Event, SoutDialog::OnNetChange)
98     EVT_TEXT(NetAddr1_Event, SoutDialog::OnNetChange)
99     EVT_TEXT(NetPort2_Event, SoutDialog::OnNetChange)
100     EVT_TEXT(NetAddr2_Event, SoutDialog::OnNetChange)
101     EVT_TEXT(NetPort3_Event, SoutDialog::OnNetChange)
102     EVT_TEXT(NetAddr3_Event, SoutDialog::OnNetChange)
103     EVT_TEXT(NetPort4_Event, SoutDialog::OnNetChange)
104     EVT_TEXT(NetAddr4_Event, SoutDialog::OnNetChange)
105
106     /* Events generated by the encapsulation panel */
107     EVT_RADIOBUTTON(EncapsulationRadio1_Event,
108                     SoutDialog::OnEncapsulationChange)
109     EVT_RADIOBUTTON(EncapsulationRadio2_Event,
110                     SoutDialog::OnEncapsulationChange)
111     EVT_RADIOBUTTON(EncapsulationRadio3_Event,
112                     SoutDialog::OnEncapsulationChange)
113     EVT_RADIOBUTTON(EncapsulationRadio4_Event,
114                     SoutDialog::OnEncapsulationChange)
115     EVT_RADIOBUTTON(EncapsulationRadio5_Event,
116                     SoutDialog::OnEncapsulationChange)
117     EVT_RADIOBUTTON(EncapsulationRadio6_Event,
118                     SoutDialog::OnEncapsulationChange)
119     EVT_RADIOBUTTON(EncapsulationRadio7_Event,
120                     SoutDialog::OnEncapsulationChange)
121     EVT_RADIOBUTTON(EncapsulationRadio8_Event,
122                     SoutDialog::OnEncapsulationChange)
123     EVT_RADIOBUTTON(EncapsulationRadio9_Event,
124                     SoutDialog::OnEncapsulationChange)
125
126     /* Events generated by the transcoding panel */
127     EVT_CHECKBOX(VideoTranscEnable_Event, SoutDialog::OnTranscodingEnable)
128     EVT_CHECKBOX(AudioTranscEnable_Event, SoutDialog::OnTranscodingEnable)
129     EVT_CHECKBOX(SubtitlesTranscEnable_Event, SoutDialog::OnTranscodingEnable)
130     EVT_CHECKBOX(SubtitlesOverlayEnable_Event, SoutDialog::OnTranscodingEnable)
131     EVT_COMBOBOX(VideoTranscCodec_Event, SoutDialog::OnTranscodingChange)
132     EVT_TEXT(VideoTranscCodec_Event, SoutDialog::OnTranscodingChange)
133     EVT_COMBOBOX(AudioTranscCodec_Event, SoutDialog::OnTranscodingChange)
134     EVT_TEXT(AudioTranscCodec_Event, SoutDialog::OnTranscodingChange)
135     EVT_COMBOBOX(VideoTranscBitrate_Event, SoutDialog::OnTranscodingChange)
136     EVT_TEXT(VideoTranscBitrate_Event, SoutDialog::OnTranscodingChange)
137     EVT_COMBOBOX(AudioTranscBitrate_Event, SoutDialog::OnTranscodingChange)
138     EVT_TEXT(AudioTranscBitrate_Event, SoutDialog::OnTranscodingChange)
139     EVT_COMBOBOX(VideoTranscScale_Event, SoutDialog::OnTranscodingChange)
140     EVT_TEXT(VideoTranscScale_Event, SoutDialog::OnTranscodingChange)
141     EVT_COMBOBOX(AudioTranscChans_Event, SoutDialog::OnTranscodingChange)
142     EVT_TEXT(AudioTranscChans_Event, SoutDialog::OnTranscodingChange)
143     EVT_COMBOBOX(SubtitlesTranscCodec_Event, SoutDialog::OnTranscodingChange)
144     EVT_TEXT(SubtitlesTranscCodec_Event, SoutDialog::OnTranscodingChange)
145
146     /* Events generated by the misc panel */
147     EVT_CHECKBOX(SAPMisc_Event, SoutDialog::OnSAPMiscChange)
148     EVT_CHECKBOX(SLPMisc_Event, SoutDialog::OnSLPMiscChange)
149     EVT_TEXT(AnnounceGroup_Event, SoutDialog::OnAnnounceGroupChange)
150     EVT_TEXT(AnnounceAddr_Event, SoutDialog::OnAnnounceAddrChange)
151     EVT_CHECKBOX(SoutAll_Event, SoutDialog::OnAnnounceGroupChange)
152
153 END_EVENT_TABLE()
154
155 /*****************************************************************************
156  * Constructor.
157  *****************************************************************************/
158 SoutDialog::SoutDialog( intf_thread_t *_p_intf, wxWindow* _p_parent ):
159     wxDialog( _p_parent, -1, wxU(_("Stream output")),
160              wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE )
161 {
162     /* Initializations */
163     p_intf = _p_intf;
164     p_parent = _p_parent;
165     SetIcon( *p_intf->p_sys->p_icon );
166
167     /* Create a panel to put everything in */
168     wxPanel *panel = new wxPanel( this, -1 );
169     panel->SetAutoLayout( TRUE );
170
171     /* Create MRL combobox */
172     wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
173     wxStaticBox *mrl_box = new wxStaticBox( panel, -1,
174                                wxU(_("Stream output MRL")) );
175     wxStaticBoxSizer *mrl_sizer = new wxStaticBoxSizer( mrl_box,
176                                                         wxHORIZONTAL );
177     wxStaticText *mrl_label = new wxStaticText( panel, -1,
178                                                 wxU(_("Destination Target:")));
179     mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
180                                 wxPoint(20,25), wxSize(120, -1) );
181     mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
182         "the full MRL you want to open.\n""Alternatively, the field will be "
183         "filled automatically when you use the controls below")) );
184
185     mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
186     mrl_sizer->Add( mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
187     mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
188
189     /* Create the output encapsulation panel */
190     encapsulation_panel = EncapsulationPanel( panel );
191
192     /* Create the access output panel */
193     access_panel = AccessPanel( panel );
194
195     /* Create the transcoding panel */
196     transcoding_panel = TranscodingPanel( panel );
197
198     /* Create the Misc panel */
199     misc_panel = MiscPanel( panel );
200
201     /* Separation */
202     wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
203
204     /* Create the buttons */
205     wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
206     ok_button->SetDefault();
207     wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
208                                             wxU(_("Cancel")) );
209
210     /* Place everything in sizers */
211     wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
212     button_sizer->Add( ok_button, 0, wxALL, 5 );
213     button_sizer->Add( cancel_button, 0, wxALL, 5 );
214     button_sizer->Layout();
215     wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
216     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
217     panel_sizer->Add( mrl_sizer_sizer, 0, wxEXPAND, 5 );
218     panel_sizer->Add( access_panel, 1, wxEXPAND | wxALL, 5 );
219     panel_sizer->Add( encapsulation_panel, 0, wxEXPAND | wxALL, 5 );
220     panel_sizer->Add( transcoding_panel, 0, wxEXPAND | wxALL, 5 );
221     panel_sizer->Add( misc_panel, 0, wxEXPAND | wxALL, 5 );
222     panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
223     panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALIGN_BOTTOM |
224                       wxALL, 5 );
225     panel_sizer->Layout();
226     panel->SetSizerAndFit( panel_sizer );
227     main_sizer->Add( panel, 1, wxGROW, 0 );
228     main_sizer->Layout();
229     SetSizerAndFit( main_sizer );
230 }
231
232 SoutDialog::~SoutDialog()
233 {
234 }
235
236 wxArrayString SoutDialog::GetOptions()
237 {
238    return SeparateEntries( mrl_combo->GetValue() );
239 }
240
241 /*****************************************************************************
242  * Private methods.
243  *****************************************************************************/
244 void SoutDialog::UpdateMRL()
245 {
246     /* Check the demux dump option */
247     if( dump_checkbox->IsChecked() )
248     {
249         wxString dumpfile;
250
251         if( file_combo->GetValue().size() )
252             dumpfile = wxT(" :demuxdump-file=\"") +
253                        file_combo->GetValue() + wxT("\"");
254         mrl_combo->SetValue( wxT(":demux=dump") + dumpfile );
255
256         return;
257     }
258
259     /* Let's start with the transcode options */
260     wxString transcode;
261     if( video_transc_checkbox->IsChecked() ||
262         audio_transc_checkbox->IsChecked() ||
263         subtitles_transc_checkbox->IsChecked() ||
264         subtitles_overlay_checkbox->IsChecked() )
265     {
266         transcode = wxT("transcode{");
267         if( video_transc_checkbox->IsChecked() )
268         {
269             transcode += wxT("vcodec=") + video_codec_combo->GetValue();
270             transcode += wxT(",vb=") + video_bitrate_combo->GetValue();
271             transcode += wxT(",scale=") + video_scale_combo->GetValue();
272             if( audio_transc_checkbox->IsChecked() ||
273                 subtitles_transc_checkbox->IsChecked() ||
274                 subtitles_overlay_checkbox->IsChecked() )
275                 transcode += wxT(",");
276         }
277         if( audio_transc_checkbox->IsChecked() )
278         {
279             transcode += wxT("acodec=") + audio_codec_combo->GetValue();
280             transcode += wxT(",ab=") + audio_bitrate_combo->GetValue();
281             transcode += wxT(",channels=") + audio_channels_combo->GetValue();
282             if( subtitles_transc_checkbox->IsChecked() ||
283                 subtitles_overlay_checkbox->IsChecked() )
284                 transcode += wxT(",");
285         }
286         if( subtitles_transc_checkbox->IsChecked() )
287         {
288             transcode += wxT("scodec=") + subtitles_codec_combo->GetValue();
289         }
290         if( subtitles_overlay_checkbox->IsChecked() )
291         {
292             transcode += wxT("soverlay");
293         }
294         transcode += wxT("}");
295     }
296
297     /* Encapsulation */
298     wxString encapsulation;
299     switch( i_encapsulation_type )
300     {
301     case PS_ENCAPSULATION:
302         encapsulation = wxT("ps");
303         break;
304     case MPEG1_ENCAPSULATION:
305         encapsulation = wxT("mpeg1");
306         break;
307     case AVI_ENCAPSULATION:
308         encapsulation = wxT("avi");
309         break;
310     case OGG_ENCAPSULATION:
311         encapsulation = wxT("ogg");
312         break;
313     case RAW_ENCAPSULATION:
314         encapsulation = wxT("raw");
315         break;
316     case MP4_ENCAPSULATION:
317         encapsulation = wxT("mp4");
318         break;
319     case MOV_ENCAPSULATION:
320         encapsulation = wxT("mov");
321         break;
322     case ASF_ENCAPSULATION:
323         encapsulation = wxT("asf");
324         break;
325     case WAV_ENCAPSULATION:
326         encapsulation = wxT("wav");
327         break;
328     case TS_ENCAPSULATION:
329     default:
330         encapsulation = wxT("ts");
331         break;
332     }
333
334     /* Now continue with the duplicate option */
335     wxString dup_opts;
336     if( access_checkboxes[PLAY_ACCESS_OUT]->IsChecked() )
337     {
338         dup_opts += wxT("dst=display");
339     }
340     if( access_checkboxes[FILE_ACCESS_OUT]->IsChecked() )
341     {
342         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
343         dup_opts += wxT("dst=std{access=file,mux=");
344         dup_opts += encapsulation + wxT(",url=\"");
345         dup_opts += file_combo->GetValue() + wxT("\"}");
346     }
347     if( access_checkboxes[HTTP_ACCESS_OUT]->IsChecked() )
348     {
349         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
350         dup_opts += wxT("dst=std{access=http,mux=");
351         dup_opts += encapsulation + wxT(",url=");
352         dup_opts += net_addrs[HTTP_ACCESS_OUT]->GetLineText(0);
353         dup_opts += wxString::Format( wxT(":%d"),
354                                       net_ports[HTTP_ACCESS_OUT]->GetValue() );
355         dup_opts += wxT("}");
356     }
357     if( access_checkboxes[MMSH_ACCESS_OUT]->IsChecked() )
358     {
359         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
360         dup_opts += wxT("dst=std{access=mmsh,mux=");
361         dup_opts += encapsulation;
362         if( i_encapsulation_type == ASF_ENCAPSULATION ) dup_opts += wxT("h");
363         dup_opts += wxT(",url=");
364         dup_opts += net_addrs[HTTP_ACCESS_OUT]->GetLineText(0);
365         dup_opts += wxString::Format( wxT(":%d"),
366                                       net_ports[MMSH_ACCESS_OUT]->GetValue() );
367         dup_opts += wxT("}");
368     }
369     if( access_checkboxes[UDP_ACCESS_OUT]->IsChecked() )
370     {
371         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
372         dup_opts += wxT("dst=std{access=udp,mux=");
373         dup_opts += encapsulation + wxT(",url=");
374
375         wxString udp_addr = net_addrs[UDP_ACCESS_OUT]->GetLineText(0);
376         if ((udp_addr[0u] != '[') && (udp_addr.Find(':') != -1))
377         {
378             dup_opts += wxT ("[") + udp_addr + wxT ("]");
379         }
380         else
381         {
382             dup_opts += udp_addr;
383         }
384         dup_opts += wxString::Format( wxT(":%d"),
385                                       net_ports[UDP_ACCESS_OUT]->GetValue() );
386
387         /* SAP only if UDP */
388         if( sap_checkbox->IsChecked() )
389         {
390             dup_opts += wxT(",sap");
391             if( ! announce_group->GetLineText(0).IsEmpty() )
392             {
393                 dup_opts += wxT(",group=\"");
394                 dup_opts += announce_group->GetLineText(0);
395                 dup_opts += wxT("\"");
396             }
397             if( ! announce_addr->GetLineText(0).IsEmpty() )
398             {
399                 dup_opts += wxT(",name=\"");
400                 dup_opts += announce_addr->GetLineText(0);
401                 dup_opts += wxT("\"");
402             }
403         }
404
405         /* SLP only if UDP */
406         if( slp_checkbox->IsChecked() )
407         {
408             dup_opts += wxT(",slp");
409             if( ! sap_checkbox->IsChecked() &&
410                 ! announce_addr->GetLineText(0).IsEmpty() )
411             {
412                 dup_opts += wxT(",name=\"");
413                 dup_opts += announce_addr->GetLineText(0);
414                 dup_opts += wxT("\"");
415             }
416         }
417
418         dup_opts += wxT("}");
419     }
420
421     wxString duplicate;
422     if( !dup_opts.IsEmpty() )
423     {
424         if( !transcode.IsEmpty() ) duplicate = wxT(":");
425         duplicate += wxT("duplicate{") + dup_opts + wxT("}");
426     }
427
428     wxString misc;
429     if( (!transcode.IsEmpty() || !duplicate.IsEmpty()) &&
430         sout_all_checkbox->IsChecked() )
431     {
432         misc = wxT(" :sout-all");
433     }
434
435     if( !transcode.IsEmpty() || !duplicate.IsEmpty() )
436         mrl_combo->SetValue( wxT(":sout=#") + transcode + duplicate + misc );
437     else
438         mrl_combo->SetValue( wxT("") );
439 }
440
441 wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
442 {
443     int i;
444     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
445                                   wxSize(200, 200) );
446
447     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
448                                               wxU(_("Output methods")) );
449     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
450                                                           wxVERTICAL );
451
452     wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
453     static const wxString access_output_array[] =
454     {
455         wxU(_("Play locally")),
456         wxU(_("File")),
457         wxU(_("HTTP")),
458         wxU(_("MMSH")),
459         wxU(_("UDP")),
460     };
461
462     for( i=0; i < ACCESS_OUT_NUM; i++ )
463     {
464         access_checkboxes[i] = new wxCheckBox( panel, AccessType1_Event + i,
465                                                access_output_array[i] );
466         access_subpanels[i] = new wxPanel( panel, -1 );
467     }
468
469     /* Play locally row */
470     wxFlexGridSizer *subpanel_sizer;
471     wxStaticText *label;
472     label = new wxStaticText( access_subpanels[0], -1, wxT("") );
473     subpanel_sizer = new wxFlexGridSizer( 1, 1, 20 );
474     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
475     access_subpanels[0]->SetSizerAndFit( subpanel_sizer );
476     access_subpanels[0]->Hide();
477
478     /* File row */
479     subpanel_sizer = new wxFlexGridSizer( 3, 2, 20 );
480     label = new wxStaticText( access_subpanels[1], -1, wxU(_("Filename")) );
481     file_combo = new wxComboBox( access_subpanels[1], FileName_Event, wxT(""),
482                                  wxPoint(20,25), wxSize(200, -1) );
483     wxButton *browse_button = new wxButton( access_subpanels[1],
484                                   FileBrowse_Event, wxU(_("Browse...")) );
485     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
486     subpanel_sizer->Add( file_combo, 1,
487                          wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
488     subpanel_sizer->Add( browse_button, 0,
489                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
490     subpanel_sizer->Add( new wxPanel(access_subpanels[1], -1), 0,
491                          wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
492     dump_checkbox = new wxCheckBox( access_subpanels[1], FileDump_Event,
493                                     wxU(_("Dump raw input")) );
494     subpanel_sizer->Add( dump_checkbox, 0,
495                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxTOP, 5 );
496
497     access_subpanels[1]->SetSizerAndFit( subpanel_sizer );
498
499     /* Net rows */
500     for( i = HTTP_ACCESS_OUT; i < ACCESS_OUT_NUM; i++ )
501     {
502         subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
503         label = new wxStaticText( access_subpanels[i], -1, wxU(_("Address")) );
504         net_addrs[i] = new wxTextCtrl( access_subpanels[i],
505                                    NetAddr1_Event + i - HTTP_ACCESS_OUT,
506                                    wxT(""), wxDefaultPosition,
507                                    wxSize( 200, -1 ), wxTE_PROCESS_ENTER);
508         subpanel_sizer->Add( label, 0,
509                              wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
510         subpanel_sizer->Add( net_addrs[i], 1, wxEXPAND |
511                              wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
512
513         int val = config_GetInt( p_intf, "server-port" );
514         label = new wxStaticText( access_subpanels[i], -1, wxU(_("Port")) );
515         net_ports[i] = new wxSpinCtrl( access_subpanels[i],
516                                    NetPort1_Event + i - HTTP_ACCESS_OUT,
517                                    wxString::Format(wxT("%d"), val),
518                                    wxDefaultPosition, wxDefaultSize,
519                                    wxSP_ARROW_KEYS,
520                                    0, 65535, val );
521
522         subpanel_sizer->Add( label, 0,
523                              wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
524         subpanel_sizer->Add( net_ports[i], 0,
525                              wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
526
527         access_subpanels[i]->SetSizerAndFit( subpanel_sizer );
528     }
529
530
531     /* Stuff everything into the main panel */
532     for( i=1; i < ACCESS_OUT_NUM; i++ )
533     {
534         sizer->Add( access_checkboxes[i], 0,
535                     wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL  | wxALL, 5 );
536         sizer->Add( access_subpanels[i], 1, wxEXPAND | wxALIGN_CENTER_VERTICAL
537                     | wxALIGN_LEFT  | wxALL, 5 );
538     }
539
540     panel_sizer->Add( access_checkboxes[0], 0,
541                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL  | wxALL, 5 );
542     panel_sizer->Add( sizer, 1, wxEXPAND | wxTOP, 3 );
543
544     panel->SetSizerAndFit( panel_sizer );
545
546     /* Update access type panel */
547     for( i=1; i < ACCESS_OUT_NUM; i++ )
548     {
549         access_subpanels[i]->Disable();
550     }
551
552     return panel;
553 }
554
555 wxPanel *SoutDialog::MiscPanel( wxWindow* parent )
556 {
557     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
558                                   wxSize(200, 200) );
559
560     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
561                                    wxU(_("Miscellaneous options")) );
562     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
563                                                           wxVERTICAL );
564
565     /* Announce Row */
566     misc_subpanels[ANN_MISC_SOUT] = new wxPanel( panel, -1 );
567     misc_subpanels[TTL_MISC_SOUT] = new wxPanel( panel, -1 );
568     wxFlexGridSizer *subpanel_sizer = new wxFlexGridSizer( 3, 4, 20 );
569     wxFlexGridSizer *subpanel_sub_sizer = new wxFlexGridSizer( 2, 4, 20 );
570     wxFlexGridSizer *subpanel2_sizer = new wxFlexGridSizer( 3, 4, 20 );
571
572     sap_checkbox = new wxCheckBox( misc_subpanels[ANN_MISC_SOUT],SAPMisc_Event,
573                                    wxU(_("SAP announce")) );
574     slp_checkbox = new wxCheckBox( misc_subpanels[ANN_MISC_SOUT],SLPMisc_Event,
575                                    wxU(_("SLP announce")) );
576
577     wxStaticText *label_g = new wxStaticText( misc_subpanels[ANN_MISC_SOUT], -1,
578                                             wxU(_("Group name")) );
579     announce_group = new wxTextCtrl( misc_subpanels[ANN_MISC_SOUT],
580                                     AnnounceGroup_Event,
581                                     wxT(""), wxDefaultPosition,
582                                     wxSize( 200, -1 ), wxTE_PROCESS_ENTER);
583
584     wxStaticText *label = new wxStaticText( misc_subpanels[ANN_MISC_SOUT], -1,
585                                             wxU(_("Channel name")) );
586     announce_addr = new wxTextCtrl( misc_subpanels[ANN_MISC_SOUT],
587                                     AnnounceAddr_Event,
588                                     wxT(""), wxDefaultPosition,
589                                     wxSize( 200, -1 ), wxTE_PROCESS_ENTER);
590
591     wxStaticText *ttl_label = new wxStaticText( misc_subpanels[TTL_MISC_SOUT], -1,
592                         wxU(_("Time-To-Live (TTL)")) );
593     ttl_spin = new wxSpinCtrl( misc_subpanels[TTL_MISC_SOUT], -1, wxEmptyString, wxDefaultPosition, wxDefaultSize,
594                    0, 1, 255, config_GetInt( p_intf, "ttl" ) );
595
596     subpanel_sizer->Add( sap_checkbox, 0,
597                          wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
598     subpanel_sizer->Add( slp_checkbox, 0,
599                          wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
600     subpanel_sub_sizer->Add( label_g, 0, wxALIGN_RIGHT |
601                              wxALIGN_CENTER_VERTICAL );
602     subpanel_sub_sizer->Add( announce_group, 1, wxEXPAND |
603                              wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
604     subpanel_sub_sizer->Add( label, 0, wxALIGN_RIGHT |
605                              wxALIGN_CENTER_VERTICAL );
606     subpanel_sub_sizer->Add( announce_addr, 1, wxEXPAND |
607                              wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
608     subpanel_sizer->Add( subpanel_sub_sizer, 1, wxEXPAND |
609                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
610
611     sout_all_checkbox = new wxCheckBox( misc_subpanels[TTL_MISC_SOUT],
612                     SoutAll_Event, wxU(_("Select all elementary streams")) );
613     subpanel2_sizer->Add( sout_all_checkbox, 1,
614                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT, 5 );
615     subpanel2_sizer->Add( ttl_label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
616     subpanel2_sizer->Add( ttl_spin, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
617
618     misc_subpanels[ANN_MISC_SOUT]->SetSizerAndFit( subpanel_sizer );
619     misc_subpanels[TTL_MISC_SOUT]->SetSizerAndFit( subpanel2_sizer );
620
621     /* Stuff everything into the main panel */
622     panel_sizer->Add( misc_subpanels[ANN_MISC_SOUT], 1,
623                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT, 5 );
624
625     panel_sizer->Add( misc_subpanels[TTL_MISC_SOUT], 1,
626                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
627
628
629     panel->SetSizerAndFit( panel_sizer );
630
631     /* Update misc panel */
632     misc_subpanels[ANN_MISC_SOUT]->Disable();
633     announce_group->Disable();
634     announce_addr->Disable();
635
636     return panel;
637 }
638
639 wxPanel *SoutDialog::EncapsulationPanel( wxWindow* parent )
640 {
641     unsigned int i;
642     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
643                                   wxSize(200, 200) );
644
645     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
646                                               wxU(_("Encapsulation Method")) );
647     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
648                                                           wxHORIZONTAL );
649
650     static const wxString encapsulation_array[] =
651     {
652         wxT("MPEG TS"),
653         wxT("MPEG PS"),
654         wxT("MPEG 1"),
655         wxT("Ogg"),
656         wxT("ASF"),
657         wxT("MP4"),
658         wxT("MOV"),
659         wxT("WAV"),
660         wxT("Raw")
661     };
662
663     /* Stuff everything into the main panel */
664     for( i = 0; i < WXSIZEOF(encapsulation_array); i++ )
665     {
666         encapsulation_radios[i] =
667             new wxRadioButton( panel, EncapsulationRadio1_Event + i,
668                                encapsulation_array[i] );
669         panel_sizer->Add( encapsulation_radios[i], 0,
670                           wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
671                           wxALL, 4 );
672     }
673     /* Hide avi one */
674     for( i = WXSIZEOF(encapsulation_array); i < ENCAPS_NUM; i++ )
675     {
676         encapsulation_radios[i] =
677             new wxRadioButton( panel, EncapsulationRadio1_Event + i, wxT("") );
678         encapsulation_radios[i]->Hide();
679     }
680
681     panel->SetSizerAndFit( panel_sizer );
682
683     /* Update encapsulation panel */
684     encapsulation_radios[TS_ENCAPSULATION]->SetValue(true);
685     i_encapsulation_type = TS_ENCAPSULATION;
686
687     return panel;
688 }
689
690 wxPanel *SoutDialog::TranscodingPanel( wxWindow* parent )
691 {
692     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
693                                   wxSize(200, 200) );
694
695     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
696                                               wxU(_("Transcoding options")) );
697     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
698                                                           wxVERTICAL );
699
700     /* Create video transcoding checkox */
701     static const wxString wxvcodecs_array[] =
702     {
703         wxT("mp1v"),
704         wxT("mp2v"),
705         wxT("mp4v"),
706         wxT("DIV1"),
707         wxT("DIV2"),
708         wxT("DIV3"),
709         wxT("H263"),
710         wxT("h264"),
711         wxT("WMV1"),
712         wxT("WMV2"),
713         wxT("MJPG"),
714         wxT("theo")
715     };
716     /*
717     static const wxString vbitrates_array[] =
718     {
719             wxT("3072"),
720             wxT("2048"),
721             wxT("1024"),
722             wxT("768"),
723             wxT("512"),
724             wxT("384"),
725             wxT("256"),
726             wxT("192"),
727             wxT("128"),
728             wxT("96"),
729             wxT("64"),
730             wxT("32"),
731             wxT("16")
732     };
733 */
734     static const wxString vscales_array[] =
735     {
736             wxT("0.25"),
737             wxT("0.5"),
738             wxT("0.75"),
739             wxT("1"),
740             wxT("1.25"),
741             wxT("1.5"),
742             wxT("1.75"),
743             wxT("2")
744     };
745
746     wxFlexGridSizer *video_sizer = new wxFlexGridSizer( 6, 1, 20 );
747 #if defined( __WXMSW__ )
748     wxFlexGridSizer *video_sub_sizer = new wxFlexGridSizer( 4, 5, 20 );
749 #else
750     wxFlexGridSizer *video_sub_sizer = new wxFlexGridSizer( 2, 5, 20 );
751 #endif
752     video_transc_checkbox =
753         new wxCheckBox( panel, VideoTranscEnable_Event, wxU(_("Video codec")));
754     video_codec_combo =
755         new wxComboBox( panel, VideoTranscCodec_Event, wxvcodecs_array[2],
756                         wxPoint(20,25), wxDefaultSize,
757                         WXSIZEOF(wxvcodecs_array),
758                         wxvcodecs_array, wxCB_READONLY );
759     video_codec_combo->SetSelection(2);
760     wxStaticText *bitrate_label =
761         new wxStaticText( panel, -1, wxU(_("Bitrate (kb/s)")));
762     video_bitrate_combo =
763         new wxComboBox( panel, VideoTranscBitrate_Event, wxT("1024"),
764                         wxPoint(20,25), wxDefaultSize,
765                         WXSIZEOF(vbitrates_array), vbitrates_array );
766     wxStaticText *scale_label =
767         new wxStaticText( panel, -1, wxU(_("Scale")));
768     video_scale_combo =
769         new wxComboBox( panel, VideoTranscScale_Event, wxT("1"),
770                         wxPoint(20,25), wxDefaultSize,
771                         WXSIZEOF(vscales_array), vscales_array );
772     video_sizer->Add( video_transc_checkbox, 0,
773                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
774     video_sizer->Add( video_codec_combo, 1,
775                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
776     video_sub_sizer->Add( bitrate_label, 0,
777                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
778     video_sub_sizer->Add( video_bitrate_combo, 1,
779                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
780     video_sub_sizer->Add( scale_label, 0,
781                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
782     video_sub_sizer->Add( video_scale_combo, 1,
783                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
784     video_sizer->Add( video_sub_sizer, 1, wxEXPAND |
785                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
786
787     /* Create audio transcoding checkox */
788     static const wxString wxacodecs_array[] =
789     {
790         wxT("mpga"),
791         wxT("mp2a"),
792         wxT("mp3"),
793         wxT("mp4a"),
794         wxT("a52"),
795         wxT("vorb"),
796         wxT("flac"),
797         wxT("spx"),
798         wxT("s16l"),
799         wxT("fl32")
800     };
801     static const wxString achannels_array[] =
802     {
803         wxT("1"),
804         wxT("2"),
805         wxT("4"),
806         wxT("6")
807     };
808 /*
809     static const wxString abitrates_array[] =
810     {
811             wxT("512"),
812             wxT("256"),
813             wxT("192"),
814             wxT("128"),
815             wxT("96"),
816             wxT("64"),
817             wxT("32"),
818             wxT("16")
819     };
820 */
821     wxFlexGridSizer *audio_sizer = new wxFlexGridSizer( 3, 1, 20 );
822     audio_transc_checkbox =
823         new wxCheckBox( panel, AudioTranscEnable_Event, wxU(_("Audio codec")));
824     audio_codec_combo =
825         new wxComboBox( panel, AudioTranscCodec_Event, wxacodecs_array[0],
826                         wxPoint(10,25), wxDefaultSize,
827                         WXSIZEOF(wxacodecs_array),
828                         wxacodecs_array, wxCB_READONLY );
829     audio_codec_combo->SetSelection(0);
830 #if defined( __WXMSW__ )
831     wxFlexGridSizer *audio_sub_sizer = new wxFlexGridSizer( 4, 5, 20 );
832 #else
833     wxFlexGridSizer *audio_sub_sizer = new wxFlexGridSizer( 2, 5, 20 );
834 #endif
835     bitrate_label =
836         new wxStaticText( panel, -1, wxU(_("Bitrate (kb/s)")));
837     audio_bitrate_combo =
838         new wxComboBox( panel, AudioTranscBitrate_Event, wxT("192"),
839                         wxPoint(10,25), wxDefaultSize,
840                         WXSIZEOF(abitrates_array), abitrates_array );
841     wxStaticText *channels_label =
842         new wxStaticText( panel, -1, wxU(_("Channels")));
843     audio_channels_combo =
844         new wxComboBox( panel, AudioTranscChans_Event, achannels_array[1],
845                         wxPoint(10,25), wxDefaultSize,
846                         WXSIZEOF(achannels_array), achannels_array );
847     audio_channels_combo->SetSelection(1);
848     audio_sub_sizer->Add( bitrate_label, 0,
849                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
850     audio_sub_sizer->Add( audio_bitrate_combo, 1,
851                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
852     audio_sub_sizer->Add( channels_label, 0,
853                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
854     audio_sub_sizer->Add( audio_channels_combo, 1,
855                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
856
857     audio_sizer->Add( audio_transc_checkbox, 0,
858                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
859     audio_sizer->Add( audio_codec_combo, 1,
860                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
861     audio_sizer->Add( audio_sub_sizer, 1,
862                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
863
864     /* Create subtitles transcoding checkox */
865     static const wxString wxscodecs_array[] =
866     {
867         wxT("dvbs")
868     };
869
870     wxFlexGridSizer *subtitles_sizer = new wxFlexGridSizer( 3, 1, 20 );
871     subtitles_transc_checkbox =
872         new wxCheckBox( panel, SubtitlesTranscEnable_Event,
873                         wxU(_("Subtitles codec")));
874     subtitles_codec_combo =
875         new wxComboBox( panel, SubtitlesTranscCodec_Event, wxscodecs_array[0],
876                         wxPoint(10,25), wxDefaultSize,
877                         WXSIZEOF(wxscodecs_array),
878                         wxscodecs_array, wxCB_READONLY );
879     subtitles_codec_combo->SetSelection(0);
880     subtitles_overlay_checkbox =
881         new wxCheckBox( panel, SubtitlesOverlayEnable_Event,
882                         wxU(_("Subtitles overlay")));
883
884     subtitles_sizer->Add( subtitles_transc_checkbox, 0,
885                           wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
886     subtitles_sizer->Add( subtitles_codec_combo, 1,
887                           wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
888     subtitles_sizer->Add( subtitles_overlay_checkbox, 0,
889                           wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
890
891     /* Stuff everything into the main panel */
892     panel_sizer->Add( video_sizer, 0,
893                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
894     panel_sizer->Add( audio_sizer, 0,
895                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
896     panel_sizer->Add( subtitles_sizer, 0,
897                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
898
899     panel->SetSizerAndFit( panel_sizer );
900
901     /* Update transcoding panel */
902     wxCommandEvent event( 0, VideoTranscEnable_Event );
903     event.SetInt( 0 );
904     OnTranscodingEnable( event );
905     event.SetId( AudioTranscEnable_Event );
906     OnTranscodingEnable( event );
907     event.SetId( SubtitlesTranscEnable_Event );
908     OnTranscodingEnable( event );
909
910     return panel;
911 }
912
913 /*****************************************************************************
914  * Events methods.
915  *****************************************************************************/
916 void SoutDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
917 {
918     mrl_combo->Append( mrl_combo->GetValue() );
919     config_PutInt( p_intf, "ttl", ttl_spin->GetValue());
920     EndModal( wxID_OK );
921 }
922
923 void SoutDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
924 {
925     EndModal( wxID_CANCEL );
926 }
927
928 void SoutDialog::OnMRLChange( wxCommandEvent& event )
929 {
930     //mrl = event.GetString();
931 }
932
933 /*****************************************************************************
934  * Access output panel event methods.
935  *****************************************************************************/
936 void SoutDialog::OnAccessTypeChange( wxCommandEvent& event )
937 {
938     int i;
939     i_access_type = event.GetId() - AccessType1_Event;
940
941     access_subpanels[i_access_type]->Enable( event.GetInt() );
942
943     switch( i_access_type )
944     {
945     case UDP_ACCESS_OUT:
946         misc_subpanels[ANN_MISC_SOUT]->Enable( event.GetInt() );
947
948         for( i = 1; i < ENCAPS_NUM; i++ )
949         {
950             encapsulation_radios[i]->Enable( !event.GetInt() );
951         }
952         if( event.GetInt() )
953         {
954             encapsulation_radios[TS_ENCAPSULATION]->SetValue(true);
955             i_encapsulation_type = TS_ENCAPSULATION;
956         }
957         break;
958     }
959     UpdateMRL();
960 }
961
962 /*****************************************************************************
963  * AnnounceMisc panel event methods.
964  *****************************************************************************/
965 void SoutDialog::OnSAPMiscChange( wxCommandEvent& event )
966 {
967     if( !slp_checkbox->IsChecked() )
968     {
969         announce_addr->Enable( event.GetInt() );
970     }
971     announce_group->Enable( event.GetInt() );
972     UpdateMRL();
973 }
974
975 void SoutDialog::OnSLPMiscChange( wxCommandEvent& event )
976 {
977     if( !sap_checkbox->IsChecked() )
978     {
979         announce_addr->Enable( event.GetInt() );
980     }
981     UpdateMRL();
982 }
983
984 /*****************************************************************************
985  * SAPAddr panel event methods.
986  *****************************************************************************/
987 void SoutDialog::OnAnnounceAddrChange( wxCommandEvent& WXUNUSED(event) )
988 {
989     UpdateMRL();
990 }
991
992 void SoutDialog::OnAnnounceGroupChange( wxCommandEvent& WXUNUSED(event) )
993 {
994     UpdateMRL();
995 }
996
997 /*****************************************************************************
998  * File access output event methods.
999  *****************************************************************************/
1000 void SoutDialog::OnFileChange( wxCommandEvent& WXUNUSED(event) )
1001 {
1002     UpdateMRL();
1003 }
1004
1005 void SoutDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
1006 {
1007     wxFileDialog dialog( this, wxU(_("Save file")), wxT(""), wxT(""), wxT("*"),
1008                          wxSAVE | wxOVERWRITE_PROMPT );
1009
1010     if( dialog.ShowModal() == wxID_OK )
1011     {
1012         file_combo->SetValue( dialog.GetPath() );
1013         UpdateMRL();
1014     }
1015 }
1016
1017 void SoutDialog::OnFileDump( wxCommandEvent& event )
1018 {
1019     misc_panel->Enable( !event.GetInt() );
1020     encapsulation_panel->Enable( !event.GetInt() );
1021     transcoding_panel->Enable( !event.GetInt() );
1022
1023     for( int i = 0; i < ACCESS_OUT_NUM; i++ )
1024     {
1025         if( i != FILE_ACCESS_OUT )
1026         {
1027             access_checkboxes[i]->Enable( !event.GetInt() );
1028             access_subpanels[i]->Enable( !event.GetInt() &&
1029                                          access_checkboxes[i]->IsChecked() );
1030         }
1031     }
1032
1033     UpdateMRL();
1034 }
1035
1036 /*****************************************************************************
1037  * Net access output event methods.
1038  *****************************************************************************/
1039 void SoutDialog::OnNetChange( wxCommandEvent& WXUNUSED(event) )
1040 {
1041     UpdateMRL();
1042 }
1043
1044 /*****************************************************************************
1045  * Encapsulation panel event methods.
1046  *****************************************************************************/
1047 void SoutDialog::OnEncapsulationChange( wxCommandEvent& event )
1048 {
1049     i_encapsulation_type = event.GetId() - EncapsulationRadio1_Event;
1050     UpdateMRL();
1051 }
1052
1053 /*****************************************************************************
1054  * Transcoding panel event methods.
1055  *****************************************************************************/
1056 void SoutDialog::OnTranscodingEnable( wxCommandEvent& event )
1057 {
1058     switch( event.GetId() )
1059     {
1060     case VideoTranscEnable_Event:
1061         video_codec_combo->Enable( event.GetInt() );
1062         video_bitrate_combo->Enable( event.GetInt() );
1063         video_scale_combo->Enable( event.GetInt() );
1064         break;
1065     case AudioTranscEnable_Event:
1066         audio_codec_combo->Enable( event.GetInt() );
1067         audio_bitrate_combo->Enable( event.GetInt() );
1068         audio_channels_combo->Enable( event.GetInt() );
1069         break;
1070     case SubtitlesTranscEnable_Event:
1071         subtitles_overlay_checkbox->Enable( !event.GetInt() );
1072         subtitles_codec_combo->Enable( event.GetInt() );
1073         break;
1074     case SubtitlesOverlayEnable_Event:
1075         subtitles_transc_checkbox->Enable( !event.GetInt() );
1076         break;
1077     }
1078
1079     UpdateMRL();
1080 }
1081
1082 void SoutDialog::OnTranscodingChange( wxCommandEvent& event )
1083 {
1084     UpdateMRL();
1085 }