]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/streamout.cpp
* src/input/input_ext-plugins.c: fixed previous commit.
[vlc] / modules / gui / wxwindows / streamout.cpp
1 /*****************************************************************************
2  * streamout.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2001 VideoLAN
5  * $Id: streamout.cpp,v 1.25 2003/07/20 15:33:53 gbazin Exp $
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
34 #ifdef WIN32                                                 /* mingw32 hack */
35 #undef Yield
36 #undef CreateDialog
37 #endif
38
39 /* Let vlc take care of the i18n stuff */
40 #define WXINTL_NO_GETTEXT_MACRO
41
42 #include <wx/wxprec.h>
43 #include <wx/wx.h>
44 #include <wx/notebook.h>
45 #include <wx/textctrl.h>
46 #include <wx/combobox.h>
47 #include <wx/spinctrl.h>
48 #include <wx/statline.h>
49
50 #include <vlc/intf.h>
51
52 #if defined MODULE_NAME_IS_skins
53 #   include "../skins/src/skin_common.h"
54 #endif
55
56 #include "wxwindows.h"
57
58 #ifndef wxRB_SINGLE
59 #   define wxRB_SINGLE 0
60 #endif
61
62 enum
63 {
64     PLAY_ACCESS_OUT = 0,
65     FILE_ACCESS_OUT,
66     HTTP_ACCESS_OUT,
67     UDP_ACCESS_OUT,
68     RTP_ACCESS_OUT,
69     ACCESS_OUT_NUM
70 };
71
72 enum
73 {
74     TS_ENCAPSULATION = 0,
75     PS_ENCAPSULATION,
76     MPEG1_ENCAPSULATION,
77     AVI_ENCAPSULATION,
78     OGG_ENCAPSULATION,
79     ENCAPS_NUM,
80     MP4_ENCAPSULATION
81 };
82
83 enum
84 {
85     SAP_MISC = 0
86 };
87
88
89 /*****************************************************************************
90  * Event Table.
91  *****************************************************************************/
92
93 /* IDs for the controls and the menu commands */
94 enum
95 {
96     Notebook_Event = wxID_HIGHEST,
97     MRL_Event,
98
99     FileBrowse_Event,
100     FileName_Event,
101
102     AccessType1_Event, AccessType2_Event, AccessType3_Event,
103     AccessType4_Event, AccessType5_Event,
104     NetPort1_Event, NetPort2_Event, NetPort3_Event,
105     NetAddr1_Event, NetAddr2_Event, NetAddr3_Event,
106
107     EncapsulationRadio1_Event, EncapsulationRadio2_Event,
108     EncapsulationRadio3_Event, EncapsulationRadio4_Event,
109     EncapsulationRadio5_Event,
110
111     VideoTranscEnable_Event, VideoTranscCodec_Event, VideoTranscBitrate_Event,
112     AudioTranscEnable_Event, AudioTranscCodec_Event, AudioTranscBitrate_Event,
113     AudioTranscChans_Event,
114
115     SAPMisc_Event, SAPAddr_Event
116 };
117
118 BEGIN_EVENT_TABLE(SoutDialog, wxDialog)
119     /* Button events */
120     EVT_BUTTON(wxID_OK, SoutDialog::OnOk)
121     EVT_BUTTON(wxID_CANCEL, SoutDialog::OnCancel)
122
123     /* Events generated by the access output panel */
124     EVT_CHECKBOX(AccessType1_Event, SoutDialog::OnAccessTypeChange)
125     EVT_CHECKBOX(AccessType2_Event, SoutDialog::OnAccessTypeChange)
126     EVT_CHECKBOX(AccessType3_Event, SoutDialog::OnAccessTypeChange)
127     EVT_CHECKBOX(AccessType4_Event, SoutDialog::OnAccessTypeChange)
128     EVT_CHECKBOX(AccessType5_Event, SoutDialog::OnAccessTypeChange)
129     EVT_TEXT(FileName_Event, SoutDialog::OnFileChange)
130     EVT_BUTTON(FileBrowse_Event, SoutDialog::OnFileBrowse)
131
132     EVT_TEXT(NetPort1_Event, SoutDialog::OnNetChange)
133     EVT_TEXT(NetAddr1_Event, SoutDialog::OnNetChange)
134     EVT_TEXT(NetPort2_Event, SoutDialog::OnNetChange)
135     EVT_TEXT(NetAddr2_Event, SoutDialog::OnNetChange)
136     EVT_TEXT(NetPort3_Event, SoutDialog::OnNetChange)
137     EVT_TEXT(NetAddr3_Event, SoutDialog::OnNetChange)
138  
139     /* Events generated by the encapsulation panel */
140     EVT_RADIOBUTTON(EncapsulationRadio1_Event,
141                     SoutDialog::OnEncapsulationChange)
142     EVT_RADIOBUTTON(EncapsulationRadio2_Event,
143                     SoutDialog::OnEncapsulationChange)
144     EVT_RADIOBUTTON(EncapsulationRadio3_Event,
145                     SoutDialog::OnEncapsulationChange)
146     EVT_RADIOBUTTON(EncapsulationRadio4_Event,
147                     SoutDialog::OnEncapsulationChange)
148     EVT_RADIOBUTTON(EncapsulationRadio5_Event,
149                     SoutDialog::OnEncapsulationChange)
150
151     /* Events generated by the transcoding panel */
152     EVT_CHECKBOX(VideoTranscEnable_Event, SoutDialog::OnTranscodingEnable)
153     EVT_CHECKBOX(AudioTranscEnable_Event, SoutDialog::OnTranscodingEnable)
154     EVT_COMBOBOX(VideoTranscCodec_Event, SoutDialog::OnTranscodingChange)
155     EVT_TEXT(VideoTranscCodec_Event, SoutDialog::OnTranscodingChange)
156     EVT_COMBOBOX(AudioTranscCodec_Event, SoutDialog::OnTranscodingChange)
157     EVT_TEXT(AudioTranscCodec_Event, SoutDialog::OnTranscodingChange)
158     EVT_COMBOBOX(VideoTranscBitrate_Event, SoutDialog::OnTranscodingChange)
159     EVT_TEXT(VideoTranscBitrate_Event, SoutDialog::OnTranscodingChange)
160     EVT_COMBOBOX(AudioTranscBitrate_Event, SoutDialog::OnTranscodingChange)
161     EVT_TEXT(AudioTranscBitrate_Event, SoutDialog::OnTranscodingChange)
162     EVT_COMBOBOX(AudioTranscChans_Event, SoutDialog::OnTranscodingChange)
163     EVT_TEXT(AudioTranscChans_Event, SoutDialog::OnTranscodingChange)
164
165     /* Events generated by the misc panel */
166     EVT_CHECKBOX(SAPMisc_Event, SoutDialog::OnSAPMiscChange)
167     EVT_TEXT(SAPAddr_Event, SoutDialog::OnSAPAddrChange)
168
169 END_EVENT_TABLE()
170
171 /*****************************************************************************
172  * Constructor.
173  *****************************************************************************/
174 SoutDialog::SoutDialog( intf_thread_t *_p_intf, wxWindow* _p_parent ):
175     wxDialog( _p_parent, -1, wxU(_("Stream output")),
176              wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE )
177 {
178     /* Initializations */
179     p_intf = _p_intf;
180     p_parent = _p_parent;
181     SetIcon( *p_intf->p_sys->p_icon );
182
183     /* Create a panel to put everything in */
184     wxPanel *panel = new wxPanel( this, -1 );
185     panel->SetAutoLayout( TRUE );
186
187     /* Create MRL combobox */
188     wxBoxSizer *mrl_sizer_sizer = new wxBoxSizer( wxHORIZONTAL );
189     wxStaticBox *mrl_box = new wxStaticBox( panel, -1,
190                                wxU(_("Stream output MRL")) );
191     wxStaticBoxSizer *mrl_sizer = new wxStaticBoxSizer( mrl_box,
192                                                         wxHORIZONTAL );
193     wxStaticText *mrl_label = new wxStaticText( panel, -1,
194                                                 wxU(_("Destination Target:")));
195     mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
196                                 wxPoint(20,25), wxSize(120, -1), 0, NULL );
197     mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
198         "the full MRL you want to open.\n""Alternatively, the field will be "
199         "filled automatically when you use the controls below")) );
200
201     mrl_sizer->Add( mrl_label, 0, wxALL | wxALIGN_CENTER, 5 );
202     mrl_sizer->Add( mrl_combo, 1, wxALL | wxALIGN_CENTER, 5 );
203     mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
204
205     /* Create the output encapsulation panel */
206     wxPanel *encapsulation_panel = EncapsulationPanel( panel );
207
208     /* Create the access output panel */
209     wxPanel *access_panel = AccessPanel( panel );
210
211     /* Create the transcoding panel */
212     wxPanel *transcoding_panel = TranscodingPanel( panel );
213
214     /* Create the Misc panel */
215     wxPanel *misc_panel = MiscPanel( panel );
216     
217     /* Separation */
218     wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
219
220     /* Create the buttons */
221     wxButton *ok_button = new wxButton( panel, wxID_OK, wxU(_("OK")) );
222     ok_button->SetDefault();
223     wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
224                                             wxU(_("Cancel")) );
225
226     /* Place everything in sizers */
227     wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
228     button_sizer->Add( ok_button, 0, wxALL, 5 );
229     button_sizer->Add( cancel_button, 0, wxALL, 5 );
230     button_sizer->Layout();
231     wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
232     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
233     panel_sizer->Add( mrl_sizer_sizer, 0, wxEXPAND, 5 );
234     panel_sizer->Add( access_panel, 1, wxEXPAND | wxALL, 5 );
235     panel_sizer->Add( encapsulation_panel, 0, wxEXPAND | wxALL, 5 );
236     panel_sizer->Add( transcoding_panel, 0, wxEXPAND | wxALL, 5 );
237     panel_sizer->Add( misc_panel, 0, wxEXPAND | wxALL, 5 );
238     panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
239     panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALIGN_BOTTOM |
240                       wxALL, 5 );
241     panel_sizer->Layout();
242     panel->SetSizerAndFit( panel_sizer );
243     main_sizer->Add( panel, 1, wxGROW, 0 );
244     main_sizer->Layout();
245     SetSizerAndFit( main_sizer );
246 }
247
248 SoutDialog::~SoutDialog()
249 {
250 }
251
252 /*****************************************************************************
253  * Private methods.
254  *****************************************************************************/
255 void SoutDialog::UpdateMRL()
256 {
257     /* Let's start with the transcode options */
258     wxString transcode;
259     if( video_transc_checkbox->IsChecked() ||
260         audio_transc_checkbox->IsChecked() )
261     {
262         transcode = wxT("transcode{");
263         if( video_transc_checkbox->IsChecked() )
264         {
265             transcode += wxT("vcodec=") + video_codec_combo->GetValue();
266             transcode += wxT(",vb=") + video_bitrate_combo->GetValue();
267             if( audio_transc_checkbox->IsChecked() ) transcode += wxT(",");
268         }
269         if( audio_transc_checkbox->IsChecked() )
270         {
271             transcode += wxT("acodec=") + audio_codec_combo->GetValue();
272             transcode += wxT(",ab=") + audio_bitrate_combo->GetValue();
273             transcode += wxT(",channels=") + audio_channels_combo->GetValue();
274         }
275         transcode += wxT("}");
276     }
277
278     /* Encapsulation */
279     wxString encapsulation;
280     switch( i_encapsulation_type )
281     {
282     case PS_ENCAPSULATION:
283         encapsulation = wxT("ps");
284         break;
285     case MPEG1_ENCAPSULATION:
286         encapsulation = wxT("mpeg1");
287         break;
288     case AVI_ENCAPSULATION:
289         encapsulation = wxT("avi");
290         break;
291     case OGG_ENCAPSULATION:
292         encapsulation = wxT("ogg");
293         break;
294     case MP4_ENCAPSULATION:
295         encapsulation = wxT("mp4");
296         break;
297     case TS_ENCAPSULATION:
298     default:
299         encapsulation = wxT("ts");
300         break;
301     }
302
303     /* Now continue with the duplicate option */
304     wxString dup_opts;
305     if( access_checkboxes[PLAY_ACCESS_OUT]->IsChecked() )
306     {
307         dup_opts += wxT("dst=display");
308     }
309     if( access_checkboxes[FILE_ACCESS_OUT]->IsChecked() )
310     {
311         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
312         dup_opts += wxT("dst=std{access=file,mux=");
313         dup_opts += encapsulation + wxT(",url=\"");
314         dup_opts += file_combo->GetValue() + wxT("\"}");
315     }
316     if( access_checkboxes[HTTP_ACCESS_OUT]->IsChecked() )
317     {
318         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
319         dup_opts += wxT("dst=std{access=http,mux=");
320         dup_opts += encapsulation + wxT(",url=");
321         dup_opts += net_addrs[HTTP_ACCESS_OUT]->GetLineText(0);
322         dup_opts += wxString::Format( wxT(":%d"),
323                                       net_ports[HTTP_ACCESS_OUT]->GetValue() );
324         dup_opts += wxT("}");
325     }
326     if( access_checkboxes[UDP_ACCESS_OUT]->IsChecked() )
327     {
328         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
329         dup_opts += wxT("dst=std{access=udp,mux=");
330         dup_opts += encapsulation + wxT(",url=");
331         dup_opts += net_addrs[UDP_ACCESS_OUT]->GetLineText(0);
332         dup_opts += wxString::Format( wxT(":%d"),
333                                       net_ports[UDP_ACCESS_OUT]->GetValue() );
334
335         /* SAP only if UDP */
336         if( sap_checkbox->IsChecked() )
337         {
338             dup_opts += wxT(",sap=\"");
339             dup_opts += sap_addr->GetLineText(0);
340             dup_opts += wxT("\"");
341         }
342
343         dup_opts += wxT("}");
344     }
345     if( access_checkboxes[RTP_ACCESS_OUT]->IsChecked() )
346     {
347         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
348         dup_opts += wxT("dst=std{access=rtp,mux=");
349         dup_opts += encapsulation + wxT(",url=");
350         dup_opts += net_addrs[RTP_ACCESS_OUT]->GetLineText(0);
351         dup_opts += wxString::Format( wxT(":%d"),
352                                       net_ports[RTP_ACCESS_OUT]->GetValue() );
353         dup_opts += wxT("}");
354     }
355
356     wxString duplicate;
357     if( !dup_opts.IsEmpty() )
358     {
359         if( !transcode.IsEmpty() ) duplicate = wxT(":");
360         duplicate += wxT("duplicate{") + dup_opts + wxT("}");
361     }
362
363     if( !transcode.IsEmpty() || !duplicate.IsEmpty() )
364         mrl_combo->SetValue( wxT("#") + transcode + duplicate );
365     else
366         mrl_combo->SetValue( wxT("") );
367 }
368
369 wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
370 {
371     int i;
372     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
373                                   wxSize(200, 200) );
374
375     wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
376     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
377                                               wxU(_("Output Methods")) );
378     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
379                                                           wxVERTICAL );
380
381     static const wxString access_output_array[] =
382     {
383         wxU(_("Play locally")),
384         wxU(_("File")),
385         wxU(_("HTTP")),
386         wxU(_("UDP")),
387         wxU(_("RTP"))
388     };
389
390     for( i=0; i < ACCESS_OUT_NUM; i++ )
391     {
392         access_checkboxes[i] = new wxCheckBox( panel, AccessType1_Event + i,
393                                                access_output_array[i] );
394         access_subpanels[i] = new wxPanel( panel, -1 );
395     }
396
397     /* Play locally row */
398     wxFlexGridSizer *subpanel_sizer;
399     wxStaticText *label;
400     label = new wxStaticText( access_subpanels[0], -1, wxT("") );
401     subpanel_sizer = new wxFlexGridSizer( 1, 1, 20 );
402     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
403     access_subpanels[0]->SetSizerAndFit( subpanel_sizer );
404
405     /* File row */
406     subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
407     label = new wxStaticText( access_subpanels[1], -1, wxU(_("Filename")) );
408     file_combo = new wxComboBox( access_subpanels[1], FileName_Event, wxT(""),
409                                  wxPoint(20,25), wxSize(200, -1), 0, NULL );
410     wxButton *browse_button = new wxButton( access_subpanels[1],
411                                   FileBrowse_Event, wxU(_("Browse...")) );
412     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
413     subpanel_sizer->Add( file_combo, 1,
414                          wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
415     subpanel_sizer->Add( browse_button, 0,
416                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
417
418     access_subpanels[1]->SetSizerAndFit( subpanel_sizer );
419
420     /* Net rows */
421     for( i = HTTP_ACCESS_OUT; i < ACCESS_OUT_NUM; i++ )
422     {
423         subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
424         label = new wxStaticText( access_subpanels[i], -1, wxU(_("Address")) );
425         net_addrs[i] = new wxTextCtrl( access_subpanels[i],
426                                    NetAddr1_Event + i - HTTP_ACCESS_OUT,
427                                    wxT(""), wxDefaultPosition,
428                                    wxSize( 200, -1 ), wxTE_PROCESS_ENTER);
429         subpanel_sizer->Add( label, 0,
430                              wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
431         subpanel_sizer->Add( net_addrs[i], 1, wxEXPAND |
432                              wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
433
434         int val = config_GetInt( p_intf, "server-port" );
435         label = new wxStaticText( access_subpanels[i], -1, wxU(_("Port")) );
436         net_ports[i] = new wxSpinCtrl( access_subpanels[i],
437                                    NetPort1_Event + i - HTTP_ACCESS_OUT,
438                                    wxString::Format(wxT("%d"), val),
439                                    wxDefaultPosition, wxDefaultSize,
440                                    wxSP_ARROW_KEYS,
441                                    0, 16000, val );
442
443         subpanel_sizer->Add( label, 0,
444                              wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
445         subpanel_sizer->Add( net_ports[i], 0,
446                              wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
447
448         access_subpanels[i]->SetSizerAndFit( subpanel_sizer );
449     }
450
451
452     /* Stuff everything into the main panel */
453     for( i=1; i < ACCESS_OUT_NUM; i++ )
454     {
455         sizer->Add( access_checkboxes[i], 0,
456                     wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL  | wxALL, 5 );
457         sizer->Add( access_subpanels[i], 1, wxEXPAND | wxALIGN_CENTER_VERTICAL
458                     | wxALIGN_LEFT  | wxALL, 5 );
459     }
460
461     panel_sizer->Add( access_checkboxes[0], 0,
462                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL  | wxALL, 5 );
463     panel_sizer->Add( sizer, 1, wxEXPAND | wxTOP, 3 );
464
465     panel->SetSizerAndFit( panel_sizer );
466
467     /* Update access type panel */
468     for( i=1; i < ACCESS_OUT_NUM; i++ )
469     {
470         access_subpanels[i]->Disable();
471     }
472
473     return panel;
474 }
475
476 wxPanel *SoutDialog::MiscPanel( wxWindow* parent )
477 {
478     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
479                                   wxSize(200, 200) );
480
481     // wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
482     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
483                                    wxU(_("Miscellaneous Options")) );
484     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
485                                                           wxVERTICAL );
486
487     /* SAP Row */
488     wxStaticText *label;
489     wxFlexGridSizer *subpanel_sizer;
490
491     misc_subpanels[SAP_MISC] = new wxPanel( panel, -1 );
492     subpanel_sizer = new wxFlexGridSizer( 4, 2, 20 );
493
494     sap_checkbox = new wxCheckBox( misc_subpanels[SAP_MISC], SAPMisc_Event,
495                                    wxU(_("SAP Announce")) );
496     label = new wxStaticText( misc_subpanels[SAP_MISC], -1,
497                               wxU(_("Channel Name ")) );
498     sap_addr = new wxTextCtrl( misc_subpanels[SAP_MISC], SAPAddr_Event,
499                                wxT(""), wxDefaultPosition,
500                                wxSize( 200, -1 ), wxTE_PROCESS_ENTER);
501
502     subpanel_sizer->Add( sap_checkbox, 0,
503                          wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
504     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
505     subpanel_sizer->Add( sap_addr, 1, wxEXPAND |
506                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
507
508     misc_subpanels[SAP_MISC]->SetSizerAndFit( subpanel_sizer );
509
510     /* Stuff everything into the main panel */
511     panel_sizer->Add( misc_subpanels[SAP_MISC], 1,
512                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
513
514     panel->SetSizerAndFit( panel_sizer );
515
516     /* Update misc panel */
517     misc_subpanels[SAP_MISC]->Disable();
518     sap_addr->Disable();
519
520     return panel;
521
522
523 wxPanel *SoutDialog::EncapsulationPanel( wxWindow* parent )
524 {
525     int i;
526     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
527                                   wxSize(200, 200) );
528
529     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
530                                               wxU(_("Encapsulation Method")) );
531     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
532                                                           wxHORIZONTAL );
533
534     static const wxString encapsulation_array[] =
535     {
536         wxT("MPEG TS"),
537         wxT("MPEG PS"),
538         wxT("MPEG 1"),
539         wxT("AVI"),
540         wxT("Ogg"),
541         wxT("MP4/MOV")
542     };
543
544     /* Stuff everything into the main panel */
545     for( i=0; i < ENCAPS_NUM; i++ )
546     {
547         encapsulation_radios[i] =
548             new wxRadioButton( panel, EncapsulationRadio1_Event + i,
549                                encapsulation_array[i] );
550         panel_sizer->Add( encapsulation_radios[i], 0,
551                           wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 8 );
552     }
553
554     panel->SetSizerAndFit( panel_sizer );
555
556     /* Update encapsulation panel */
557     encapsulation_radios[TS_ENCAPSULATION]->SetValue(true);
558     i_encapsulation_type = TS_ENCAPSULATION;
559
560     return panel;
561 }
562
563 wxPanel *SoutDialog::TranscodingPanel( wxWindow* parent )
564 {
565     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
566                                   wxSize(200, 200) );
567
568     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
569                                               wxU(_("Transcoding options")) );
570     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
571                                                           wxVERTICAL );
572
573     /* Create video transcoding checkox */
574     static const wxString vcodecs_array[] =
575     {
576         wxT("mpgv"),
577         wxT("mp4v"),
578         wxT("DIV1"),
579         wxT("DIV2"),
580         wxT("DIV3"),
581         wxT("H263"),
582         wxT("I263"),
583         wxT("WMV1"),
584         wxT("WMV2"),
585         wxT("MJPG")
586     };
587     static const wxString vbitrates_array[] =
588     {
589         wxT("3000"),
590         wxT("2000"),
591         wxT("1000"),
592         wxT("750"),
593         wxT("500"),
594         wxT("400"),
595         wxT("200"),
596         wxT("150"),
597         wxT("100")
598     };
599
600     wxFlexGridSizer *video_sizer = new wxFlexGridSizer( 4, 1, 20 );
601     video_transc_checkbox =
602         new wxCheckBox( panel, VideoTranscEnable_Event, wxU(_("Video codec")));
603     video_codec_combo =
604         new wxComboBox( panel, VideoTranscCodec_Event, wxT(""),
605                         wxPoint(20,25), wxDefaultSize, WXSIZEOF(vcodecs_array),
606                         vcodecs_array, wxCB_READONLY );
607     video_codec_combo->SetSelection(1);
608     wxStaticText *bitrate_label =
609         new wxStaticText( panel, -1, wxU(_("Bitrate (kb/s)")));
610     video_bitrate_combo =
611         new wxComboBox( panel, VideoTranscBitrate_Event, wxT("1000"),
612                         wxPoint(20,25), wxDefaultSize,
613                         WXSIZEOF(vbitrates_array), vbitrates_array );
614     video_sizer->Add( video_transc_checkbox, 0,
615                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
616     video_sizer->Add( video_codec_combo, 1,
617                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
618     video_sizer->Add( bitrate_label, 0,
619                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
620     video_sizer->Add( video_bitrate_combo, 1,
621                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
622
623     /* Create audio transcoding checkox */
624     static const wxString acodecs_array[] =
625     {
626         wxT("mpga"),
627         wxT("mp3"),
628         wxT("a52"),
629         wxT("vorb")
630     };
631     static const wxString abitrates_array[] =
632     {
633         wxT("512"),
634         wxT("256"),
635         wxT("192"),
636         wxT("128"),
637         wxT("96")
638     };
639     static const wxString achannels_array[] =
640     {
641         wxT("1"),
642         wxT("2"),
643         wxT("4"),
644         wxT("6")
645     };
646
647     wxFlexGridSizer *audio_sizer = new wxFlexGridSizer( 3, 1, 20 );
648     audio_transc_checkbox =
649         new wxCheckBox( panel, AudioTranscEnable_Event, wxU(_("Audio codec")));
650     audio_codec_combo =
651         new wxComboBox( panel, AudioTranscCodec_Event, wxT(""),
652                         wxPoint(10,25), wxDefaultSize, WXSIZEOF(acodecs_array),
653                         acodecs_array, wxCB_READONLY );
654     audio_codec_combo->SetSelection(0);
655     wxFlexGridSizer *audio_sub_sizer = new wxFlexGridSizer( 2, 5, 20 );
656     bitrate_label =
657         new wxStaticText( panel, -1, wxU(_("Bitrate (kb/s)")));
658     audio_bitrate_combo =
659         new wxComboBox( panel, AudioTranscBitrate_Event, wxT("192"),
660                         wxPoint(10,25), wxDefaultSize,
661                         WXSIZEOF(abitrates_array), abitrates_array );
662     wxStaticText *channels_label =
663         new wxStaticText( panel, -1, wxU(_("Channels")));
664     audio_channels_combo =
665         new wxComboBox( panel, AudioTranscChans_Event, wxT(""),
666                         wxPoint(10,25), wxDefaultSize,
667                         WXSIZEOF(achannels_array), achannels_array );
668     audio_channels_combo->SetSelection(1);
669     audio_sub_sizer->Add( bitrate_label, 0,
670                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
671     audio_sub_sizer->Add( audio_bitrate_combo, 1,
672                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
673     audio_sub_sizer->Add( channels_label, 0,
674                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
675     audio_sub_sizer->Add( audio_channels_combo, 1,
676                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
677
678     audio_sizer->Add( audio_transc_checkbox, 0,
679                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
680     audio_sizer->Add( audio_codec_combo, 1,
681                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
682     audio_sizer->Add( audio_sub_sizer, 1,
683                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
684
685     /* Stuff everything into the main panel */
686     panel_sizer->Add( video_sizer, 0,
687                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
688     panel_sizer->Add( audio_sizer, 0,
689                       wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
690
691     panel->SetSizerAndFit( panel_sizer );
692
693     /* Update transcoding panel */
694     wxCommandEvent event( 0, VideoTranscEnable_Event );
695     event.SetInt( 0 );
696     OnTranscodingEnable( event );
697     event.SetId( AudioTranscEnable_Event );
698     OnTranscodingEnable( event );
699
700     return panel;
701 }
702
703 /*****************************************************************************
704  * Events methods.
705  *****************************************************************************/
706 void SoutDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
707 {
708     mrl_combo->Append( mrl_combo->GetValue() );
709     mrl = mrl_combo->GetValue();
710     EndModal( wxID_OK );
711     
712 }
713
714 void SoutDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
715 {
716     EndModal( wxID_CANCEL );
717 }
718
719 void SoutDialog::OnMRLChange( wxCommandEvent& event )
720 {
721     //mrl = event.GetString();
722 }
723
724 /*****************************************************************************
725  * Access output panel event methods.
726  *****************************************************************************/
727 void SoutDialog::OnAccessTypeChange( wxCommandEvent& event )
728 {
729     int i;
730     i_access_type = event.GetId() - AccessType1_Event;
731
732     access_subpanels[i_access_type]->Enable( event.GetInt() );
733
734     switch( i_access_type )
735     {
736     case UDP_ACCESS_OUT:
737         misc_subpanels[SAP_MISC]->Enable( event.GetInt() );
738
739     case RTP_ACCESS_OUT:
740         for( i = 1; i < ENCAPS_NUM; i++ )
741         {
742             encapsulation_radios[i]->Enable( !event.GetInt() );
743         }
744         if( event.GetInt() )
745         {
746             encapsulation_radios[TS_ENCAPSULATION]->SetValue(true);
747             i_encapsulation_type = TS_ENCAPSULATION;
748         }
749         break;
750     }
751     UpdateMRL();
752 }
753
754 /*****************************************************************************
755  * SAPMisc panel event methods.
756  *****************************************************************************/
757 void SoutDialog::OnSAPMiscChange( wxCommandEvent& event )
758 {
759     sap_addr->Enable( event.GetInt() );
760     UpdateMRL();
761 }
762
763 /*****************************************************************************
764  * SAPAddr panel event methods.
765  *****************************************************************************/
766 void SoutDialog::OnSAPAddrChange( wxCommandEvent& WXUNUSED(event) )
767 {
768     UpdateMRL();
769 }
770
771 /*****************************************************************************
772  * File access output event methods.
773  *****************************************************************************/
774 void SoutDialog::OnFileChange( wxCommandEvent& WXUNUSED(event) )
775 {
776     UpdateMRL();
777 }
778
779 void SoutDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
780 {
781     wxFileDialog dialog( this, wxU(_("Save file")), wxT(""), wxT(""), wxT("*"),
782                          wxSAVE | wxOVERWRITE_PROMPT );
783
784     if( dialog.ShowModal() == wxID_OK )
785     {
786         file_combo->SetValue( dialog.GetPath() );
787         UpdateMRL();
788     }
789 }
790
791 /*****************************************************************************
792  * Net access output event methods.
793  *****************************************************************************/
794 void SoutDialog::OnNetChange( wxCommandEvent& WXUNUSED(event) )
795 {
796     UpdateMRL();
797 }
798
799 /*****************************************************************************
800  * Encapsulation panel event methods.
801  *****************************************************************************/
802 void SoutDialog::OnEncapsulationChange( wxCommandEvent& event )
803 {
804     i_encapsulation_type = event.GetId() - EncapsulationRadio1_Event;
805     UpdateMRL();
806 }
807
808 /*****************************************************************************
809  * Transcoding panel event methods.
810  *****************************************************************************/
811 void SoutDialog::OnTranscodingEnable( wxCommandEvent& event )
812 {
813     switch( event.GetId() )
814     {
815     case VideoTranscEnable_Event:
816         video_codec_combo->Enable( event.GetInt() );
817         video_bitrate_combo->Enable( event.GetInt() );
818         break;
819     case AudioTranscEnable_Event:
820         audio_codec_combo->Enable( event.GetInt() );
821         audio_bitrate_combo->Enable( event.GetInt() );
822         audio_channels_combo->Enable( event.GetInt() );
823         break;
824     }
825
826     UpdateMRL();
827 }
828
829 void SoutDialog::OnTranscodingChange( wxCommandEvent& event )
830 {
831     UpdateMRL();
832 }