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