1 /*****************************************************************************
2 * wizard.cpp : wxWindows plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2004 VideoLAN
5 * $Id: streamwizard.cpp 6961 2004-03-05 17:34:23Z sam $
7 * Authors: Clément Stenac <zorglub@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
28 #include <errno.h> /* ENOMEM */
29 #include <string.h> /* strerror() */
35 #include "wxwindows.h"
37 #include <wx/statline.h>
42 /*****************************************************************************
44 *****************************************************************************/
47 ActionRadio0_Event, ActionRadio1_Event,
51 InputRadio0_Event, InputRadio1_Event,
53 MethodRadio0_Event, MethodRadio1_Event,
54 MethodRadio2_Event, MethodRadio3_Event,
56 EncapRadio0_Event, EncapRadio1_Event,
57 EncapRadio2_Event, EncapRadio3_Event,
58 EncapRadio4_Event, EncapRadio5_Event,
59 EncapRadio6_Event, EncapRadio7_Event,
60 EncapRadio8_Event, EncapRadio9_Event,
62 VideoEnable_Event, VideoCodec_Event,
63 AudioEnable_Event, AudioCodec_Event,
68 #define ACTION_STREAM 0
69 #define ACTION_TRANSCODE 1
81 BEGIN_EVENT_TABLE(WizardDialog, wxWizard)
84 /*****************************************************************************
86 *****************************************************************************/
88 #define ERROR _("Error")
89 #define ITEM_NAME _("Streaming/Transcoding Wizard")
92 #define HELLO_TITLE _("Streaming/Transcoding Wizard")
93 #define HELLO_TEXT _("Welcome, streaming wizard")
94 #define HELLO_STREAMING _("Stream")
95 #define HELLO_STREAMING_DESC _("Use this to stream on a network")
96 #define HELLO_TRANSCODE _("Transcode")
97 #define HELLO_TRANSCODE_DESC _("Use this to re-encode a stream and save it to a file")
98 #define HELLO_NOTICE _("This wizard only gives access to a small subset of VLC's streaming and transcoding capabilities. Use the Open and Stream Output dialogs to get all of them")
101 #define INPUT_TITLE _("Choose input")
102 #define INPUT_TEXT _("Choose here your input stream")
104 #define INPUT_OPEN _("Select a stream" )
105 #define INPUT_PL _( "Existing playlist item" )
107 #define CHOOSE_STREAM _("You must choose a stream")
108 #define NO_PLAYLIST _("Uh Oh! Unable to find playlist !")
110 #define INPUT_BUTTON _("Choose")
113 #define TRANSCODE1_TITLE _("Transcode")
114 #define TRANSCODE1_TEXT _("If you want to change the compression format of the audio or video tracks, fill in this page. (If you only want to change the container format, proceed to next page)")
116 #define TR_VIDEO_TEXT0 _("If your stream has video and you want to " \
117 "transcode it, enable this")
118 #define TR_VIDEO_TEXT _("Select your video codec. Click one to get more " \
121 #define TR_AUDIO_TEXT0 _("If your stream has audio and you want to "\
122 "transcode it, enable this")
123 #define TR_AUDIO_TEXT _("Select your audio codec. Click one to get more " \
127 #define STREAMING1_TITLE _("Streaming")
128 #define STREAMING1_TEXT _("In this page, you will select how your input stream will be sent.")
131 #define INVALID_MCAST_ADDRESS _("This does not appear to be a valid " \
132 "multicast address" )
135 #define ENCAP_TITLE _("Encapsulation format")
136 #define ENCAP_TEXT _("In this page, you will select how the stream will be "\
141 #define EXTRATRANSCODE_TITLE _("Additional transcode options")
142 #define EXTRATRANSCODE_TEXT _("In this page, you will define a few " \
143 "additionnal parameters for your transcoding" )
146 #define EXTRASTREAMING_TITLE _("Additional streaming options")
147 #define EXTRASTREAMING_TEXT _("In this page, you will define a few " \
148 "additionnal parameters for your stream" )
151 /*****************************************************************************
153 *****************************************************************************/
161 struct codec vcodecs_array[] =
163 { "MPEG-1 Video" , "mp1v" , "MPEG-1 Video codec",
164 {MUX_PS, MUX_TS, MUX_MPEG, MUX_OGG, MUX_AVI, MUX_RAW, -1,-1,-1 } },
165 { "MPEG-2 Video" , "mp2v" , "MPEG-2 Video codec",
166 {MUX_PS, MUX_TS, MUX_MPEG, MUX_OGG, MUX_AVI, MUX_RAW, -1,-1,-1 } },
167 { "MPEG-4 Video" , "mp4v" , "MPEG-4 Video codec",
168 {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_MP4,MUX_OGG,MUX_AVI,MUX_RAW, -1} },
169 { "DIVX 1" ,"DIV1","Divx first version" ,
170 {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
171 { "DIVX 2" ,"DIV2","Divx second version" ,
172 {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
173 { "DIVX 3" ,"DIV3","Divx third version" ,
174 {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
175 { "H 263" , "H263" , "H263 is ..." ,
176 { MUX_TS, MUX_AVI, -1,-1,-1,-1,-1,-1,-1 } },
177 { "I 263", "I263", "I263 is ..." ,
178 { MUX_TS, MUX_AVI, -1,-1,-1,-1,-1,-1,-1 } },
179 { "WMV 1" , "WMV1", "First version of WMV" ,
180 {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
181 { "WMV 2" , "WMV2", "2 version of WMV" ,
182 {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
183 { "MJPEG" , "MJPG", "MJPEG consists of a series of JPEG pictures" ,
184 {MUX_TS , MUX_MPEG , MUX_ASF , MUX_OGG , MUX_AVI , -1,-1,-1,-1 } },
185 { "Theora" , "theo", "Experimental free codec",
186 {MUX_TS, -1,-1,-1,-1,-1,-1,-1,-1} },
187 { "Dummy", "dummy", "Dummy codec (do not transcode)" ,
188 {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_MP4,MUX_OGG,MUX_AVI,MUX_RAW,MUX_MOV}},
189 { NULL,NULL,NULL , {-1,-1,-1,-1,-1,-1,-1,-1,-1}} /* Do not remove me */
192 struct codec acodecs_array[] =
194 { "MPEG Audio" , "mpga" , "The standard MPEG audio (1/2) format" ,
195 {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_OGG,MUX_AVI,MUX_RAW, -1,-1} },
196 { "MP3" , "mp3" , "MPEG Audio Layer 3" ,
197 {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_OGG,MUX_AVI,MUX_RAW, -1,-1} },
198 { "MPEG 4 Audio" , "mp4a" , "Audio format for MPEG4" ,
199 {MUX_TS, MUX_MP4, -1,-1,-1,-1,-1,-1,-1 } },
200 { "A/52" , "a52" , "DVD audio format" ,
201 {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_OGG,MUX_AVI,MUX_RAW, -1,-1} },
202 { "Vorbis" , "vorb" , "This is a free audio codec" ,
203 {MUX_OGG, -1,-1,-1,-1,-1,-1,-1,-1} },
204 { "FLAC" , "flac" , "This is an audio codec" ,
205 {MUX_OGG , MUX_RAW, -1,-1,-1,-1,-1,-1,-1} },
206 { "Speex" , "spx" , "An audio codec dedicated to compression of voice" ,
207 {MUX_OGG, -1,-1,-1,-1,-1,-1,-1,-1} },
208 { "Dummy", "dummy", "Dummy codec (do not transcode)" ,
209 {MUX_PS,MUX_TS,MUX_MPEG,MUX_ASF,MUX_MP4,MUX_OGG,MUX_AVI,MUX_RAW,MUX_MOV}},
210 { NULL,NULL,NULL , {-1,-1,-1,-1,-1,-1,-1,-1,-1}} /* Do not remove me */
221 struct method methods_array[] =
223 {"udp:","UDP Unicast", "Use this to stream to a single computer",
224 "Enter the address of the computer to stream to",
225 { MUX_TS, -1,-1,-1,-1,-1,-1,-1,-1 } },
226 {"udp:","UDP Multicast",
227 "Use this to stream to a dynamic group of computers on a "
228 "multicast-enabled network. This is the most efficient method "
229 "to stream to several computers, but it does not work over Internet.",
230 "Enter the multicast address to stream to in this field. "
231 "This must be an IP address between 224.0.0.0 an 239.255.255.255 "
232 "For a private use, enter an address beginning with 239.255.",
233 { MUX_TS, -1,-1,-1,-1,-1,-1,-1,-1 } },
235 "Use this to stream to several computers. This method is "
236 "less efficient, as the server needs to send several times the "
238 "Enter the local addresses you want to listen to. Do not enter "
239 "anything to listen to all adresses. This is generally the best "
241 { MUX_TS, MUX_PS, MUX_MPEG, MUX_OGG, MUX_RAW, MUX_ASF, -1,-1,-1} },
242 { NULL, NULL,NULL,NULL , {-1,-1,-1,-1,-1,-1,-1,-1,-1}} /* Do not remove me */
252 struct encap encaps_array[] =
254 { MUX_PS, "ps","MPEG PS", "MPEG Program Stream" },
255 { MUX_TS, "ts","MPEG TS", "MPEG Transport Stream" },
256 { MUX_MPEG, "ps", "MPEG 1", "MPEG 1 Format" },
257 { MUX_OGG, "ogg," "OGG", "OGG" },
258 { MUX_RAW, "raw", "RAW", "RAW" },
259 { MUX_ASF, "asf","ASF", "ASF" },
260 { MUX_AVI, "avi","AVI", "AVI" },
261 { MUX_MP4, "mp4","MP4", "MPEG4" },
262 { MUX_MOV, "mov","MOV", "MOV" },
263 { -1 , NULL,NULL , NULL } /* Do not remove me */
266 /*****************************************************************************
267 * All the pages of the wizard, declaration
268 *****************************************************************************/
271 /* The open dialog */
272 class WizardOpen : public wxNotebook
277 wxPanel *FilePanel();
278 wxPanel *DiscPanel();
281 ArrayOfAutoBuiltPanel input_tab_array;
283 /* Controls for the file panel */
284 wxComboBox *file_combo;
285 wxFileDialog *file_dialog;
287 /* Controls for the disc panel */
288 wxRadioBox *disc_type;
289 wxTextCtrl *disc_device;
290 wxSpinCtrl *disc_title;
291 wxSpinCtrl *disc_chapter;
294 /* The media equivalent name for a DVD names. For example,
295 * "Title", is "Track" for a CD-DA */
296 wxStaticText *disc_title_label;
297 wxStaticText *disc_chapter_label;
298 /* Indicates if the disc device control was modified */
299 bool b_disc_device_changed;
302 /* Controls for the net panel */
303 wxRadioBox *net_type;
305 wxPanel *net_subpanels[4];
306 wxRadioButton *net_radios[4];
307 wxSpinCtrl *net_ports[4];
309 wxTextCtrl *net_addrs[4];
310 wxCheckBox *net_ipv6;
312 /* Controls for the v4l panel */
313 wxRadioBox *video_type;
314 wxTextCtrl *video_device;
315 wxSpinCtrl *video_channel;
316 wxButton *v4l_button;
317 V4LDialog *v4l_dialog;
318 wxArrayString v4l_mrl;
322 /* Declare classes */
323 class wizHelloPage : public wxWizardPageSimple
326 wizHelloPage( wxWizard *parent);
327 void OnActionChange(wxEvent& event);
328 void OnWizardPageChanging(wxWizardEvent& event);
331 WizardDialog *p_parent;
332 wxRadioButton *action_radios[2];
333 DECLARE_EVENT_TABLE()
336 BEGIN_EVENT_TABLE(wizHelloPage, wxWizardPageSimple)
337 EVT_RADIOBUTTON( ActionRadio0_Event, wizHelloPage::OnActionChange)
338 EVT_RADIOBUTTON( ActionRadio1_Event, wizHelloPage::OnActionChange)
339 EVT_WIZARD_PAGE_CHANGING(-1, wizHelloPage::OnWizardPageChanging)
343 class wizInputPage : public wxWizardPage
346 wizInputPage( wxWizard *, wxWizardPage *, intf_thread_t *);
347 wizInputPage::~wizInputPage();
348 void OnWizardPageChanging(wxWizardEvent& event);
349 void OnInputChange(wxEvent& event);
350 virtual wxWizardPage *GetPrev() const;
351 virtual wxWizardPage *GetNext() const;
352 void SetStreamingPage( wxWizardPage *page);
353 void SetTranscodePage( wxWizardPage *page);
354 void SetAction( int i_action );
355 void SetPintf( intf_thread_t *p_intf );
358 intf_thread_t *p_intf;
362 WizardDialog *p_parent;
363 wxRadioButton *input_radios[2];
364 wxBoxSizer *mainSizer;
366 wxTextCtrl *mrl_text;
367 OpenDialog *p_open_dialog;
368 wxListView *listview;
371 wxWizardPage *p_prev;
372 wxWizardPage *p_streaming_page;
373 wxWizardPage *p_transcode_page;
374 DECLARE_EVENT_TABLE()
377 BEGIN_EVENT_TABLE(wizInputPage, wxWizardPageSimple)
378 EVT_RADIOBUTTON( InputRadio0_Event, wizInputPage::OnInputChange)
379 EVT_RADIOBUTTON( InputRadio1_Event, wizInputPage::OnInputChange)
380 EVT_WIZARD_PAGE_CHANGING(-1, wizInputPage::OnWizardPageChanging)
384 class wizTranscodeCodecPage : public wxWizardPage
387 wizTranscodeCodecPage( wxWizard *parent, wxWizardPage *next);
388 ~wizTranscodeCodecPage();
389 void wizTranscodeCodecPage::OnWizardPageChanging(wxWizardEvent& event);
390 virtual wxWizardPage *GetPrev() const;
391 virtual wxWizardPage *GetNext() const;
392 void SetPrev( wxWizardPage *page);
394 wxCheckBox *video_checkbox;
395 wxComboBox *video_combo;
396 wxStaticText * video_text;
397 wxCheckBox *audio_checkbox;
398 wxComboBox *audio_combo;
399 wxStaticText * audio_text;
401 WizardDialog *p_parent;
408 wxWizardPage *p_prev;
409 wxWizardPage *p_next;
411 void OnVideoCodecChange(wxCommandEvent& event);
412 void OnAudioCodecChange(wxCommandEvent& event);
413 void OnEnableVideo(wxCommandEvent& event);
414 void OnEnableAudio(wxCommandEvent& event);
416 DECLARE_EVENT_TABLE()
419 BEGIN_EVENT_TABLE(wizTranscodeCodecPage, wxWizardPageSimple)
420 EVT_CHECKBOX( VideoEnable_Event, wizTranscodeCodecPage::OnEnableVideo)
421 EVT_CHECKBOX( AudioEnable_Event, wizTranscodeCodecPage::OnEnableAudio)
422 EVT_COMBOBOX( VideoCodec_Event, wizTranscodeCodecPage::OnVideoCodecChange)
423 EVT_COMBOBOX( AudioCodec_Event, wizTranscodeCodecPage::OnAudioCodecChange)
424 EVT_WIZARD_PAGE_CHANGING(-1, wizTranscodeCodecPage::OnWizardPageChanging)
427 class wizStreamingMethodPage : public wxWizardPage
430 wizStreamingMethodPage( wxWizard *parent, wxWizardPage *next);
431 void OnWizardPageChanging(wxWizardEvent& event);
432 virtual wxWizardPage *GetPrev() const;
433 virtual wxWizardPage *GetNext() const;
434 void SetPrev( wxWizardPage *page);
436 DECLARE_EVENT_TABLE()
438 wxStaticText *address_text;
439 wxTextCtrl *address_txtctrl;
440 WizardDialog * p_parent;
441 void OnMethodChange(wxEvent& event);
442 wxRadioButton *method_radios[4];
443 wxWizardPage *p_prev;
444 wxWizardPage *p_next;
447 BEGIN_EVENT_TABLE(wizStreamingMethodPage, wxWizardPageSimple)
448 EVT_RADIOBUTTON( MethodRadio0_Event, wizStreamingMethodPage::OnMethodChange)
449 EVT_RADIOBUTTON( MethodRadio1_Event, wizStreamingMethodPage::OnMethodChange)
450 EVT_RADIOBUTTON( MethodRadio2_Event, wizStreamingMethodPage::OnMethodChange)
451 EVT_RADIOBUTTON( MethodRadio3_Event, wizStreamingMethodPage::OnMethodChange)
452 EVT_WIZARD_PAGE_CHANGING(-1, wizStreamingMethodPage::OnWizardPageChanging)
456 class wizEncapPage : public wxWizardPage
459 wizEncapPage( wxWizard *parent);
460 wizEncapPage::~wizEncapPage();
461 void OnWizardPageChanging(wxWizardEvent& event);
462 virtual wxWizardPage *GetPrev() const;
463 virtual wxWizardPage *GetNext() const;
464 void SetStreamingPage( wxWizardPage *page);
465 void SetTranscodePage( wxWizardPage *page);
466 void SetPrev( wxWizardPage *page);
467 void SetAction( int );
468 void EnableEncap( int encap );
470 DECLARE_EVENT_TABLE()
474 void OnEncapChange(wxEvent& event);
475 wxRadioButton *encap_radios[9];
476 WizardDialog *p_parent;
477 wxWizardPage *p_prev;
478 wxWizardPage *p_streaming_page;
479 wxWizardPage *p_transcode_page;
482 BEGIN_EVENT_TABLE(wizEncapPage, wxWizardPageSimple)
483 EVT_WIZARD_PAGE_CHANGING(-1, wizEncapPage::OnWizardPageChanging)
484 EVT_RADIOBUTTON( EncapRadio0_Event, wizEncapPage::OnEncapChange)
485 EVT_RADIOBUTTON( EncapRadio1_Event, wizEncapPage::OnEncapChange)
486 EVT_RADIOBUTTON( EncapRadio2_Event, wizEncapPage::OnEncapChange)
487 EVT_RADIOBUTTON( EncapRadio3_Event, wizEncapPage::OnEncapChange)
488 EVT_RADIOBUTTON( EncapRadio4_Event, wizEncapPage::OnEncapChange)
489 EVT_RADIOBUTTON( EncapRadio5_Event, wizEncapPage::OnEncapChange)
490 EVT_RADIOBUTTON( EncapRadio6_Event, wizEncapPage::OnEncapChange)
491 EVT_RADIOBUTTON( EncapRadio7_Event, wizEncapPage::OnEncapChange)
492 EVT_RADIOBUTTON( EncapRadio8_Event, wizEncapPage::OnEncapChange)
493 EVT_RADIOBUTTON( EncapRadio9_Event, wizEncapPage::OnEncapChange)
496 /* Additional settings for transcode */
497 class wizTranscodeExtraPage : public wxWizardPage
500 wizTranscodeExtraPage( wxWizard *parent, wxWizardPage *prev,
502 virtual wxWizardPage *GetPrev() const;
503 virtual wxWizardPage *GetNext() const;
505 DECLARE_EVENT_TABLE()
506 void wizTranscodeExtraPage::OnSelectFile(wxCommandEvent&);
507 WizardDialog *p_parent;
508 wxWizardPage *p_prev;
509 wxWizardPage *p_next;
512 BEGIN_EVENT_TABLE(wizTranscodeExtraPage, wxWizardPage)
513 EVT_BUTTON( Open_Event, wizTranscodeExtraPage::OnSelectFile)
516 /* Additional settings for streaming */
517 class wizStreamingExtraPage : public wxWizardPage
520 wizStreamingExtraPage( wxWizard *parent, wxWizardPage *prev,
522 virtual wxWizardPage *GetPrev() const;
523 virtual wxWizardPage *GetNext() const;
525 DECLARE_EVENT_TABLE()
526 WizardDialog *p_parent;
527 wxWizardPage *p_prev;
528 wxWizardPage *p_next;
531 BEGIN_EVENT_TABLE(wizStreamingExtraPage, wxWizardPage)
535 /* Local functions */
536 static int ismult( char *psz_uri );
538 /***************************************************************************
539 * Implementation of the pages
540 ***************************************************************************/
543 /***************************************************
544 * First page: choose between stream and transcode *
545 ***************************************************/
546 wizHelloPage::wizHelloPage( wxWizard *parent) : wxWizardPageSimple(parent)
549 p_parent = (WizardDialog *)parent;
550 wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
552 /* Create the texts */
553 mainSizer->Add( new wxStaticText(this, -1, wxU( HELLO_TITLE ) ),
555 mainSizer->Add( new wxStaticText(this, -1,
556 wxU( vlc_wraptext(HELLO_TEXT , TEXTWIDTH, false ) ) ),
559 /* Create the radio buttons with their helps */
560 action_radios[0] = new wxRadioButton( this, ActionRadio0_Event,
561 wxU( HELLO_STREAMING ) );
562 action_radios[1] = new wxRadioButton( this, ActionRadio1_Event,
563 wxU( HELLO_TRANSCODE ) );
566 mainSizer->Add( action_radios[0], 0, wxALL, 5 );
567 mainSizer->Add( new wxStaticText(this, -1,
568 wxU( vlc_wraptext( HELLO_STREAMING_DESC ,TEXTWIDTH, false))),
571 mainSizer->Add( action_radios[1], 0, wxALL, 5 );
572 mainSizer->Add( new wxStaticText(this, -1,
573 wxU( vlc_wraptext( HELLO_TRANSCODE_DESC ,TEXTWIDTH, false)))
576 mainSizer->Add( new wxStaticLine(this, -1 ), 1, wxTOP|wxBOTTOM, 5 );
578 mainSizer->Add( new wxStaticText(this, -1,
579 wxU( vlc_wraptext(HELLO_NOTICE , TEXTWIDTH , false ))),
583 mainSizer->Fit(this);
586 void wizHelloPage::OnActionChange(wxEvent& event)
588 i_action = event.GetId() - ActionRadio0_Event;
589 ((wizInputPage *)GetNext())->SetAction( i_action );
590 p_parent->SetAction( i_action );
593 void wizHelloPage::OnWizardPageChanging(wxWizardEvent& event)
595 ((wizInputPage *)GetNext())->SetAction( i_action );
596 p_parent->SetAction( i_action );
599 /************************************
600 * Second page: choose input stream *
601 ************************************/
602 wizInputPage::wizInputPage( wxWizard *parent, wxWizardPage *prev, intf_thread_t *_p_intf) :
607 p_parent = (WizardDialog *)parent;
608 parent->SetModal(false);
610 mainSizer = new wxBoxSizer(wxVERTICAL);
612 /* Create the texts */
613 mainSizer->Add( new wxStaticText(this, -1, wxU( INPUT_TITLE ) ),
615 mainSizer->Add( new wxStaticText(this, -1,
616 wxU( vlc_wraptext(INPUT_TEXT , TEXTWIDTH, false ) ) ),
619 /* Create the radio buttons */
620 input_radios[0] = new wxRadioButton( this, InputRadio0_Event ,
622 mainSizer->Add( input_radios[0], 0, wxALL, 5 );
623 input_radios[1] = new wxRadioButton( this, InputRadio1_Event ,
626 mainSizer->Add( input_radios[1], 0, wxALL, 5 );
629 open_panel = new wxPanel(this, -1);
630 open_panel->SetAutoLayout( TRUE );
631 wxBoxSizer *openSizer = new wxBoxSizer(wxVERTICAL);
633 mrl_text = new wxTextCtrl( open_panel, -1, wxU( "" ) );
634 openSizer->Add( mrl_text, 0 , wxALL, 5 );
635 open_panel->SetSizer( openSizer );
637 openSizer->Fit(open_panel);
639 mainSizer->Add( open_panel );
641 playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
642 VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
646 if( p_playlist->i_size > 0)
648 pl_panel = new wxPanel(this, -1);
649 wxBoxSizer *plSizer = new wxBoxSizer( wxVERTICAL );
650 listview = new wxListView( pl_panel, ListView_Event,
651 wxDefaultPosition, wxDefaultSize,
652 wxLC_REPORT | wxSUNKEN_BORDER );
653 listview->InsertColumn( 0, wxU(_("Name")) );
654 listview->InsertColumn( 1, wxU(_("URI")) );
655 listview->SetColumnWidth( 0, 300 );
656 for( int i=0 ; i < p_playlist->i_size ; i++ )
658 wxString filename = wxL2U( p_playlist->pp_items[i]->input.
660 listview->InsertItem( i, filename );
661 listview->SetItem( i, 1, wxL2U( p_playlist->pp_items[i]->
664 listview->Select( p_playlist->i_index , TRUE);
665 plSizer->Add( listview, 0, wxALL, 5 );
666 pl_panel->SetSizer( plSizer );
668 mainSizer->Add( pl_panel );
673 input_radios[1]->Disable();
675 vlc_object_release( p_playlist );
679 input_radios[1]->Disable();
683 mainSizer->Fit(this);
686 wizInputPage::~wizInputPage()
688 if( p_open_dialog ) delete p_open_dialog;
691 void wizInputPage::OnInputChange(wxEvent& event)
693 i_input = event.GetId() - InputRadio0_Event;
699 mainSizer->Hide( pl_panel );
701 mainSizer->Show( open_panel );
707 mainSizer->Hide( open_panel );
709 mainSizer->Show( pl_panel );
713 void wizInputPage::OnWizardPageChanging(wxWizardEvent& event)
717 if( mrl_text->GetValue().IsSameAs( wxT(""), TRUE ) && event.GetDirection() )
719 wxMessageBox( wxU( CHOOSE_STREAM ), wxU( ERROR ),
720 wxICON_WARNING | wxOK, this );
725 p_parent->SetMrl( (const char *)mrl_text->GetValue().c_str() );
732 i = listview->GetNextItem( i , wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
736 listitem.SetColumn( 1 );
737 listview->GetItem( listitem );
738 p_parent->SetMrl( (const char*) listitem.GetText().c_str() );
744 wxWizardPage *wizInputPage::GetPrev() const { return p_prev; }
745 wxWizardPage *wizInputPage::GetNext() const
747 if( i_action == ACTION_STREAM )
748 return p_streaming_page;
750 return p_transcode_page;
753 void wizInputPage::SetStreamingPage( wxWizardPage *page)
755 p_streaming_page = page;
758 void wizInputPage::SetTranscodePage( wxWizardPage *page)
760 p_transcode_page = page;
763 void wizInputPage::SetAction( int i_action )
765 this->i_action = i_action;
768 void wizInputPage::SetPintf( intf_thread_t *p_intf )
770 this->p_intf = p_intf;
773 /***************************************************
774 * First transcode page: choose codecs *
775 ***************************************************/
776 wizTranscodeCodecPage::wizTranscodeCodecPage( wxWizard *parent,
777 wxWizardPage *next) : wxWizardPage(parent)
783 p_parent = (WizardDialog *) parent;
785 wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
787 /* Add the main texts */
788 main_sizer->Add( new wxStaticText(this, -1,
789 wxU( vlc_wraptext( TRANSCODE1_TITLE ,TEXTWIDTH, false ) ) ),
791 main_sizer->Add( new wxStaticText(this, -1,
792 wxU( vlc_wraptext(TRANSCODE1_TEXT , TEXTWIDTH, false ) ) ),
796 wxStaticBox *video_box = new wxStaticBox( this, -1, wxU(_("Video")) );
797 wxStaticBoxSizer *video_sizer = new wxStaticBoxSizer( video_box,
799 /* Line 1 : only the checkbox */
800 wxFlexGridSizer *video_sizer1 = new wxFlexGridSizer( 1,1,20 );
801 video_sizer1->Add( new wxCheckBox( this, VideoEnable_Event,
802 wxU(_("Transcode video") ) ), 0 , wxLEFT , 5 );
804 wxFlexGridSizer *video_sizer2 = new wxFlexGridSizer( 2,1,20 );
805 video_sizer2->Add( new wxStaticText(this, -1, wxU(_("Codec"))),0,wxLEFT ,5);
806 video_combo = new wxComboBox( this, VideoCodec_Event, wxT(""),
807 wxDefaultPosition, wxSize(200,25) );
808 for( int i= 0; vcodecs_array[i].psz_display != NULL; i++ )
810 video_combo->Append( wxU( vcodecs_array[i].psz_display ) ,
811 (void *)&vcodecs_array[i] );
813 video_sizer2->Add( video_combo, 0 , wxALIGN_RIGHT);
815 video_text = new wxStaticText( this, -1,
816 wxU( vlc_wraptext( TR_AUDIO_TEXT, TEXTWIDTH, false) ) );
817 wxFlexGridSizer *video_sizer3 = new wxFlexGridSizer( 2,1,20 );
818 video_sizer3->Add( video_text, 0, wxLEFT, 5 );
819 /* Fill the main video sizer */
820 video_sizer->Add( video_sizer1 , 0, wxEXPAND, 5 );
821 video_sizer->Add( video_sizer2, 0, wxALL, 5 );
822 video_sizer->Add( video_sizer3, 0, wxEXPAND );
825 wxStaticBox *audio_box = new wxStaticBox( this, -1, wxU(_("Audio")) );
826 wxStaticBoxSizer *audio_sizer = new wxStaticBoxSizer( audio_box,
829 wxFlexGridSizer *audio_sizer1 = new wxFlexGridSizer( 1,1,20);
830 audio_sizer1->Add( new wxCheckBox( this, AudioEnable_Event,
831 wxU(_("Transcode audio") ) ), 0 , wxLEFT, 5 );
833 wxFlexGridSizer *audio_sizer2 = new wxFlexGridSizer( 2,1,20 );
834 audio_sizer2->Add( new wxStaticText(this, -1, wxU(_("Codec"))),0,wxLEFT,5);
835 audio_combo = new wxComboBox( this, AudioCodec_Event, wxT(""),
836 wxDefaultPosition, wxSize(200,25) );
837 for( int i= 0; acodecs_array[i].psz_display != NULL; i++ )
839 audio_combo->Append( wxU( acodecs_array[i].psz_display ) ,
840 (void *)&acodecs_array[i] );
842 audio_sizer2->Add( audio_combo, 0 , wxALIGN_RIGHT );
844 audio_text = new wxStaticText( this, -1,
845 wxU( vlc_wraptext( TR_VIDEO_TEXT, TEXTWIDTH, false) ) );
846 wxFlexGridSizer *audio_sizer3 = new wxFlexGridSizer( 2,1,20 );
847 audio_sizer3->Add( audio_text, 0, wxLEFT,5 );
849 audio_sizer->Add(audio_sizer1, 0, wxEXPAND, 5);
850 audio_sizer->Add(audio_sizer2, 0, wxALL, 5 );
851 audio_sizer->Add(audio_sizer3, 0, wxEXPAND );
853 main_sizer->Add( video_sizer, 1, wxGROW, 0 );
854 main_sizer->Add( audio_sizer, 1, wxGROW, 0 );
855 main_sizer->Layout();
856 SetSizerAndFit( main_sizer );
858 /* Default disabled */
859 video_combo->Disable(); video_text->Disable();
860 audio_combo->Disable(); audio_text->Disable();
864 wizTranscodeCodecPage::~wizTranscodeCodecPage()
866 if( acodec ) free( acodec );
867 if( vcodec ) free( vcodec );
870 void wizTranscodeCodecPage::OnEnableVideo(wxCommandEvent& event)
872 video_combo->Enable( event.IsChecked() );
873 video_text->Enable( event.IsChecked() );
876 void wizTranscodeCodecPage::OnEnableAudio(wxCommandEvent& event)
878 audio_combo->Enable( event.IsChecked() );
879 audio_text->Enable( event.IsChecked() );
882 void wizTranscodeCodecPage::OnVideoCodecChange(wxCommandEvent& event)
884 struct codec *c = (struct codec*)
885 (video_combo->GetClientData(video_combo->GetSelection()));
886 video_text->SetLabel( wxU( vlc_wraptext(c->psz_descr, TEXTWIDTH, false) ) );
887 i_video_codec = video_combo->GetSelection();
888 vcodec = strdup(c->psz_codec);
891 void wizTranscodeCodecPage::OnAudioCodecChange(wxCommandEvent& event)
893 struct codec *c = (struct codec*)
894 (audio_combo->GetClientData(audio_combo->GetSelection()));
895 audio_text->SetLabel( wxU( vlc_wraptext(c->psz_descr, TEXTWIDTH, false) ) );
896 i_audio_codec = audio_combo->GetSelection();
897 acodec = strdup(c->psz_codec);
901 void wizTranscodeCodecPage::OnWizardPageChanging(wxWizardEvent& event)
905 if( !event.GetDirection() )
911 /* Set the dummy codec ( accept all muxers ) if needed */
912 if( !video_combo->IsEnabled() )
916 if( !audio_combo->IsEnabled() )
921 ((wizEncapPage *)GetNext())->SetPrev(this);
923 for( i = 0 ; i< 9 ; i++ )
925 //fprintf(stderr,"vcodecs[%i].muxers[%i] = %i\n",i_video_codec,i,vcodecs_array[i_video_codec].muxers[i]);
926 if( vcodecs_array[i_video_codec].muxers[i] != -1 )
928 for( j = 0 ; j< 9 ; j++ )
930 // fprintf(stderr," acodecs[%i].muxers[%i] = %i\n",i_audio_codec,j,acodecs_array[i_audio_codec].muxers[j]);
931 if( acodecs_array[i_audio_codec].muxers[j] ==
932 vcodecs_array[i_video_codec].muxers[i] )
934 ((wizEncapPage*)GetNext())->EnableEncap(
935 vcodecs_array[i_video_codec].muxers[i] );
940 struct codec *c = (struct codec*)
941 (video_combo->GetClientData(video_combo->GetSelection()));
942 vcodec = strdup(c->psz_codec);
944 (audio_combo->GetClientData(audio_combo->GetSelection()));
945 acodec = strdup(c->psz_codec);
948 /* FIXME: Support bitrate */
949 p_parent->SetTranscode( vcodec, 1000, acodec, 200 );
950 ((wizEncapPage*)GetNext())->SetAction( p_parent->GetAction() );
951 p_parent->SetAction( p_parent->GetAction() );
956 wxWizardPage *wizTranscodeCodecPage::GetPrev() const { return p_prev; }
957 wxWizardPage *wizTranscodeCodecPage::GetNext() const { return p_next; }
958 void wizTranscodeCodecPage::SetPrev( wxWizardPage *page) {p_prev = page; }
961 /***************************************************
962 * First streaming page: choose method *
963 ***************************************************/
964 wizStreamingMethodPage::wizStreamingMethodPage( wxWizard *parent,
965 wxWizardPage *next) : wxWizardPage(parent)
969 p_parent = (WizardDialog *)parent;
971 wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
973 /* Create the texts */
974 mainSizer->Add( new wxStaticText(this, -1, wxU(
975 vlc_wraptext( STREAMING1_TITLE, TEXTWIDTH, false) ) ),
977 mainSizer->Add( new wxStaticText(this, -1,
978 wxU( vlc_wraptext(STREAMING1_TEXT , TEXTWIDTH, false ) ) ),
983 for( i = 0 ; i< 3 ; i++ )
985 method_radios[i] = new wxRadioButton( this, MethodRadio0_Event + i,
986 wxU( methods_array[i].psz_method ) );
987 method_radios[i]->SetToolTip( wxU(_( methods_array[i].psz_descr ) ) );
988 mainSizer->Add( method_radios[i], 0, wxALL, 5 );
990 address_text = new wxStaticText(this, -1,
991 wxU( vlc_wraptext( methods_array[0].psz_address,
992 TEXTWIDTH, false ) ) );
993 address_txtctrl = new wxTextCtrl( this, -1, wxU("") );
994 mainSizer->Add( address_text, 0, wxALL, 5 );
995 mainSizer->Add( address_txtctrl, 0, wxALL, 5 );
998 mainSizer->Fit(this);
1003 void wizStreamingMethodPage::OnWizardPageChanging(wxWizardEvent& event)
1006 if( !event.GetDirection() ) return;
1008 /* Check valid multicast address */
1009 if( i_method == 1 && !ismult((char *) address_txtctrl->GetValue().c_str()) )
1011 wxMessageBox( wxU( INVALID_MCAST_ADDRESS ) , wxU( ERROR ),
1012 wxICON_WARNING | wxOK, this );
1016 ((wizEncapPage *)GetNext())->SetPrev(this);
1017 for( i = 0 ; i< 9 ; i++ )
1019 if( methods_array[i_method].muxers[i] != -1 )
1021 ((wizEncapPage*)GetNext())->EnableEncap(
1022 methods_array[i_method].muxers[i] );
1025 p_parent->SetStream( methods_array[i_method].psz_access ,
1026 (char *)address_txtctrl->GetValue().c_str() );
1030 wxWizardPage *wizStreamingMethodPage::GetPrev() const { return p_prev; }
1031 wxWizardPage *wizStreamingMethodPage::GetNext() const { return p_next; }
1033 void wizStreamingMethodPage::SetPrev( wxWizardPage *page) {p_prev = page; }
1036 void wizStreamingMethodPage::OnMethodChange(wxEvent& event)
1038 i_method = event.GetId() - MethodRadio0_Event;
1039 address_text->SetLabel( wxU(
1040 vlc_wraptext( _(methods_array[i_method].psz_address), TEXTWIDTH, false)));
1043 /***************************************************
1044 * Choose encapsulation format *
1045 ***************************************************/
1046 wizEncapPage::wizEncapPage( wxWizard *parent ) : wxWizardPage(parent)
1050 p_parent = (WizardDialog *)parent;
1051 p_streaming_page = NULL;
1052 p_transcode_page = NULL;
1054 wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1056 /* Create the texts */
1057 mainSizer->Add( new wxStaticText(this, -1, wxU(ENCAP_TITLE) ),
1059 mainSizer->Add( new wxStaticText(this, -1,
1060 wxU( vlc_wraptext(ENCAP_TEXT , TEXTWIDTH, false ) ) ),
1063 for( i = 0 ; i< 9 ; i++ )
1065 encap_radios[i] = new wxRadioButton( this, EncapRadio0_Event + i,
1066 wxU( encaps_array[i].psz_encap ) );
1067 encap_radios[i]->SetToolTip( wxU(_( encaps_array[i].psz_descr ) ) );
1068 mainSizer->Add( encap_radios[i], 0, wxALL, 5 );
1069 encap_radios[i]->Disable();
1072 SetSizer(mainSizer);
1073 mainSizer->Fit(this);
1076 wizEncapPage::~wizEncapPage()
1080 void wizEncapPage::OnWizardPageChanging(wxWizardEvent& event)
1083 if( !event.GetDirection() )
1085 for( i = 0 ; i< 9 ; i++ )
1087 encap_radios[i]->Disable();
1090 p_parent->SetMux( encaps_array[i_mux].psz_mux );
1094 void wizEncapPage::OnEncapChange(wxEvent& event)
1096 i_mux = event.GetId() - EncapRadio0_Event;
1099 void wizEncapPage::EnableEncap( int encap )
1102 for( i = 0 ; i< 9 ; i++)
1104 if( encaps_array[i].id == encap )
1106 encap_radios[i]->Enable();
1107 encap_radios[i]->SetValue(true);
1113 void wizEncapPage::SetStreamingPage( wxWizardPage *page)
1115 p_streaming_page = page;
1118 void wizEncapPage::SetTranscodePage( wxWizardPage *page)
1120 p_transcode_page = page;
1123 wxWizardPage *wizEncapPage::GetPrev() const { return p_prev; }
1125 wxWizardPage *wizEncapPage::GetNext() const
1127 if( i_action== ACTION_STREAM )
1128 return p_streaming_page;
1130 return p_transcode_page;
1134 void wizEncapPage::SetAction( int i_act ) { i_action = i_act; }
1136 void wizEncapPage::SetPrev( wxWizardPage *page) { p_prev = page; }
1138 /***************************************************
1139 * Extra transcoding page : Select file *
1140 ***************************************************/
1141 wizTranscodeExtraPage::wizTranscodeExtraPage( wxWizard *parent,
1143 wxWizardPage *next) : wxWizardPage(parent)
1147 p_parent = (WizardDialog *) parent;
1148 wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1150 /* Create the texts */
1151 mainSizer->Add( new wxStaticText(this, -1, wxU( EXTRATRANSCODE_TITLE )),
1153 mainSizer->Add( new wxStaticText(this, -1,
1154 wxU( vlc_wraptext( EXTRATRANSCODE_TEXT , TEXTWIDTH,
1155 false ) ) ), 0, wxALL, 5 );
1156 mainSizer->Add( new wxButton( this, Open_Event, wxU("Open") ) );
1157 SetSizer(mainSizer);
1158 mainSizer->Fit(this);
1161 void wizTranscodeExtraPage::OnSelectFile( wxCommandEvent &event)
1163 wxFileDialog *file_dialog = new wxFileDialog( this, wxU(_("Open File")),
1164 wxT(""), wxT(""), wxT("*"), wxSAVE );
1166 if( file_dialog && file_dialog->ShowModal() == wxID_OK )
1168 if( file_dialog->GetFilename().mb_str() )
1170 p_parent->SetTranscodeOut( (char*)file_dialog->GetFilename().
1177 wxWizardPage *wizTranscodeExtraPage::GetPrev() const { return p_prev; }
1178 wxWizardPage *wizTranscodeExtraPage::GetNext() const {return p_next; }
1180 /* Extra streaming page : Local display ? */
1181 wizStreamingExtraPage::wizStreamingExtraPage( wxWizard *parent,
1183 wxWizardPage *next) : wxWizardPage(parent)
1187 p_parent = (WizardDialog *) parent;
1188 wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
1190 /* Create the texts */
1191 mainSizer->Add( new wxStaticText(this, -1, wxU( EXTRASTREAMING_TITLE )),
1193 mainSizer->Add( new wxStaticText(this, -1,
1194 wxU( vlc_wraptext(EXTRASTREAMING_TEXT , TEXTWIDTH,
1195 false ) ) ), 0, wxALL, 5 );
1196 SetSizer(mainSizer);
1197 mainSizer->Fit(this);
1200 wxWizardPage *wizStreamingExtraPage::GetPrev() const { return p_prev; }
1201 wxWizardPage *wizStreamingExtraPage::GetNext() const {return p_next; }
1204 /***************************************************************************
1205 * Implementation of the wizard itself
1206 ***************************************************************************/
1207 wizHelloPage *page1;
1208 wizInputPage *page2 ;
1209 wizTranscodeCodecPage *tr_page1 ;
1210 wizStreamingMethodPage *st_page1;
1211 wizTranscodeExtraPage *tr_page2 ;
1212 wizStreamingExtraPage *st_page2;
1213 wizEncapPage *encap_page;
1215 WizardDialog::WizardDialog(intf_thread_t *_p_intf, wxWindow *_p_parent ) :
1216 wxWizard( _p_parent, -1, wxU(_("Streaming/Transcoding Wizard")), wxNullBitmap, wxDefaultPosition)
1218 /* Initializations */
1220 SetPageSize(wxSize(400,350));
1223 page1 = new wizHelloPage(this);
1224 page2 = new wizInputPage(this, page1, p_intf);
1225 encap_page = new wizEncapPage(this );
1226 tr_page1 = new wizTranscodeCodecPage(this, encap_page );
1227 st_page1 = new wizStreamingMethodPage(this, encap_page);
1229 tr_page2 = new wizTranscodeExtraPage(this, encap_page, NULL );
1230 st_page2 = new wizStreamingExtraPage(this, encap_page, NULL );
1233 page1->SetNext( page2 );
1234 /* 2->1 in constructor of 2 */
1237 page2->SetTranscodePage(tr_page1);
1238 page2->SetStreamingPage(st_page1);
1239 page2->SetPintf( p_intf );
1240 tr_page1->SetPrev(page2);
1241 st_page1->SetPrev(page2);
1244 encap_page->SetTranscodePage( tr_page2 );
1245 encap_page->SetStreamingPage( st_page2 );
1246 /* 3->4 in constructor of 3 */
1247 // encap_page->SetPrev(tr_page1);
1250 WizardDialog::~WizardDialog()
1253 msg_Dbg(p_intf,"Killing wizard");
1255 msg_Dbg(p_intf,"Killing wizard2");
1257 msg_Dbg(p_intf,"Killing wizard3");
1259 msg_Dbg(p_intf,"Killing wizard4");
1261 msg_Dbg(p_intf,"Killing wizard5");
1263 msg_Dbg(p_intf,"Killing wizard6");
1265 msg_Dbg(p_intf,"Killing wizard7");
1266 encap_page->SetPrev(NULL);
1268 msg_Dbg(p_intf,"Killing wizard done");
1271 void WizardDialog::SetMrl( const char *mrl )
1273 msg_Dbg(p_intf, "Set MRL to : %s", mrl );
1274 this->mrl = strdup( mrl );
1277 void WizardDialog::SetTranscode( char *vcodec, int vb, char *acodec,int ab)
1281 this->vcodec = strdup(vcodec);
1285 this->acodec = strdup(acodec);
1291 void WizardDialog::SetStream( char *method, char *address )
1293 this->method = strdup( method );
1294 this->address = strdup( address );
1297 void WizardDialog::SetTranscodeOut( char *address )
1299 this->address = strdup( address );
1302 void WizardDialog::SetMux( char *mux )
1304 this->mux = strdup( mux );
1307 void WizardDialog::SetAction( int i_action )
1309 this->i_action = i_action;
1312 int WizardDialog::GetAction()
1317 void WizardDialog::Run()
1319 msg_Dbg( p_intf,"Launching wizard");
1320 if( RunWizard(page1) )
1324 msg_Dbg( p_intf,"End wizard");
1326 msg_Dbg( p_intf,"Action: %i", i_action);
1327 if( i_action == ACTION_TRANSCODE)
1329 msg_Dbg( p_intf,"Starting transcode of %s to file %s", mrl, "caca");
1330 msg_Dbg( p_intf,"Using %s (%i kbps) / %s (%i kbps)",vcodec,vb,acodec,ab);
1331 msg_Dbg( p_intf,"Encap %s",mux);
1332 int i_tr_size = 10; /* 10 = ab + vb */
1333 i_tr_size += vcodec ? strlen(vcodec) : 0;
1334 i_tr_size += acodec ? strlen(acodec) : 0;
1336 char *psz_transcode = (char *)malloc( i_tr_size * sizeof(char));
1339 sprintf( psz_transcode, "vcodec=%s,vb=%i",
1344 sprintf( psz_transcode, "%s%cacodec=%s,ab=%i",
1345 psz_transcode, vcodec ? ',' : ' ',
1348 i_size = 73 + strlen(mux) + strlen(address) + strlen(psz_transcode);
1349 psz_opt = (char *)malloc( i_size * sizeof(char) );
1350 sprintf( psz_opt, ":sout=#transcode{%s}:standard{mux=%s,url=%s,"
1352 psz_transcode, mux, address );
1353 msg_Dbg( p_intf,"");
1357 msg_Dbg( p_intf, "Starting stream of %s to %s using %s", mrl,
1359 msg_Dbg( p_intf, "Encap %s", mux);
1361 i_size = 40 + strlen(mux) + strlen(address);
1362 psz_opt = (char *)malloc( i_size * sizeof(char) );
1363 sprintf( psz_opt, ":sout=#standard{mux=%s,url=%s,access=%s}",
1364 mux, address,method);
1367 playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
1368 VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
1371 playlist_AddExt( p_playlist, mrl, ITEM_NAME,PLAYLIST_APPEND |
1372 PLAYLIST_GO, PLAYLIST_END , -1 ,
1373 (const char **)&psz_opt , 1 );
1374 vlc_object_release(p_playlist);
1378 wxMessageBox( wxU( NO_PLAYLIST ), wxU( ERROR ),
1379 wxICON_WARNING | wxOK, this );
1384 msg_Dbg( p_intf, "Wizard cancelled");
1387 /****************************************************************
1388 * Local helper functions
1389 ****************************************************************/
1390 static int ismult( char *psz_uri )
1395 i_value = strtol( psz_uri, &psz_end, 0 );
1397 if( psz_uri[0] == '[')
1399 if( strncasecmp( &psz_uri[1], "FF0" , 3) ||
1400 strncasecmp( &psz_uri[2], "FF0" , 3))
1403 return( VLC_FALSE );
1405 if( *psz_end != '.' ) { return( VLC_FALSE ); }
1407 return( i_value < 224 ? VLC_FALSE : VLC_TRUE );