]> git.sesse.net Git - vlc/blobdiff - modules/gui/wxwindows/streamout.cpp
* wizard.cpp : - TTL and SAP support
[vlc] / modules / gui / wxwindows / streamout.cpp
index b6166f006eae4328f5813d75023337113e47addd..f4075200465ee748612016d6b47711b41b99d26e 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * streamout.cpp : wxWindows plugin for vlc
  *****************************************************************************
- * Copyright (C) 2000-2001 VideoLAN
- * $Id: streamout.cpp,v 1.10 2003/05/15 01:33:53 gbazin Exp $
+ * Copyright (C) 2000-2004 VideoLAN
+ * $Id$
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
 #include <stdio.h>
 
 #include <vlc/vlc.h>
+#include <vlc/intf.h>
 
-#ifdef WIN32                                                 /* mingw32 hack */
-#undef Yield
-#undef CreateDialog
-#endif
-
-/* Let vlc take care of the i18n stuff */
-#define WXINTL_NO_GETTEXT_MACRO
-
-#include <wx/wxprec.h>
-#include <wx/wx.h>
-#include <wx/notebook.h>
-#include <wx/textctrl.h>
+#include "wxwindows.h"
 #include <wx/combobox.h>
-#include <wx/spinctrl.h>
 #include <wx/statline.h>
 
-#include <vlc/intf.h>
-
-#if defined MODULE_NAME_IS_skins
-#   include "../skins/src/skin_common.h"
-#endif
-
-#include "wxwindows.h"
+#include "streamdata.h"
 
 #ifndef wxRB_SINGLE
 #   define wxRB_SINGLE 0
 #endif
 
-enum
-{
-    PLAY_ACCESS_OUT = 0,
-    FILE_ACCESS_OUT,
-    HTTP_ACCESS_OUT,
-    UDP_ACCESS_OUT,
-    RTP_ACCESS_OUT,
-    ACCESS_OUT_NUM
-};
-
-enum
-{
-    TS_ENCAPSULATION = 0,
-    PS_ENCAPSULATION,
-    AVI_ENCAPSULATION,
-    MP4_ENCAPSULATION,
-    OGG_ENCAPSULATION,
-    ENCAPS_NUM
-};
-
 /*****************************************************************************
  * Event Table.
  *****************************************************************************/
@@ -91,18 +54,25 @@ enum
 
     FileBrowse_Event,
     FileName_Event,
+    FileDump_Event,
 
     AccessType1_Event, AccessType2_Event, AccessType3_Event,
-    AccessType4_Event, AccessType5_Event,
-    NetPort_Event,
-    NetAddr_Event,
+    AccessType4_Event, AccessType5_Event, AccessType6_Event,
+    NetPort1_Event, NetPort2_Event, NetPort3_Event, NetPort4_Event,
+    NetAddr1_Event, NetAddr2_Event, NetAddr3_Event, NetAddr4_Event,
 
     EncapsulationRadio1_Event, EncapsulationRadio2_Event,
     EncapsulationRadio3_Event, EncapsulationRadio4_Event,
-    EncapsulationRadio5_Event,
+    EncapsulationRadio5_Event, EncapsulationRadio6_Event,
+    EncapsulationRadio7_Event, EncapsulationRadio8_Event,
+    EncapsulationRadio9_Event,
 
     VideoTranscEnable_Event, VideoTranscCodec_Event, VideoTranscBitrate_Event,
+    VideoTranscScale_Event,
     AudioTranscEnable_Event, AudioTranscCodec_Event, AudioTranscBitrate_Event,
+    AudioTranscChans_Event,
+
+    SAPMisc_Event, SLPMisc_Event, AnnounceAddr_Event
 };
 
 BEGIN_EVENT_TABLE(SoutDialog, wxDialog)
@@ -116,12 +86,20 @@ BEGIN_EVENT_TABLE(SoutDialog, wxDialog)
     EVT_CHECKBOX(AccessType3_Event, SoutDialog::OnAccessTypeChange)
     EVT_CHECKBOX(AccessType4_Event, SoutDialog::OnAccessTypeChange)
     EVT_CHECKBOX(AccessType5_Event, SoutDialog::OnAccessTypeChange)
+    EVT_CHECKBOX(AccessType6_Event, SoutDialog::OnAccessTypeChange)
     EVT_TEXT(FileName_Event, SoutDialog::OnFileChange)
     EVT_BUTTON(FileBrowse_Event, SoutDialog::OnFileBrowse)
-    EVT_TEXT(NetPort_Event, SoutDialog::OnNetChange)
-    EVT_SPINCTRL(NetPort_Event, SoutDialog::OnNetChange)
-    EVT_TEXT(NetAddr_Event, SoutDialog::OnNetChange)
+    EVT_CHECKBOX(FileDump_Event, SoutDialog::OnFileDump)
+
+    EVT_TEXT(NetPort1_Event, SoutDialog::OnNetChange)
+    EVT_TEXT(NetAddr1_Event, SoutDialog::OnNetChange)
+    EVT_TEXT(NetPort2_Event, SoutDialog::OnNetChange)
+    EVT_TEXT(NetAddr2_Event, SoutDialog::OnNetChange)
+    EVT_TEXT(NetPort3_Event, SoutDialog::OnNetChange)
+    EVT_TEXT(NetAddr3_Event, SoutDialog::OnNetChange)
+    EVT_TEXT(NetPort4_Event, SoutDialog::OnNetChange)
+    EVT_TEXT(NetAddr4_Event, SoutDialog::OnNetChange)
+
     /* Events generated by the encapsulation panel */
     EVT_RADIOBUTTON(EncapsulationRadio1_Event,
                     SoutDialog::OnEncapsulationChange)
@@ -133,14 +111,35 @@ BEGIN_EVENT_TABLE(SoutDialog, wxDialog)
                     SoutDialog::OnEncapsulationChange)
     EVT_RADIOBUTTON(EncapsulationRadio5_Event,
                     SoutDialog::OnEncapsulationChange)
+    EVT_RADIOBUTTON(EncapsulationRadio6_Event,
+                    SoutDialog::OnEncapsulationChange)
+    EVT_RADIOBUTTON(EncapsulationRadio7_Event,
+                    SoutDialog::OnEncapsulationChange)
+    EVT_RADIOBUTTON(EncapsulationRadio8_Event,
+                    SoutDialog::OnEncapsulationChange)
+    EVT_RADIOBUTTON(EncapsulationRadio9_Event,
+                    SoutDialog::OnEncapsulationChange)
 
     /* Events generated by the transcoding panel */
     EVT_CHECKBOX(VideoTranscEnable_Event, SoutDialog::OnTranscodingEnable)
     EVT_CHECKBOX(AudioTranscEnable_Event, SoutDialog::OnTranscodingEnable)
     EVT_COMBOBOX(VideoTranscCodec_Event, SoutDialog::OnTranscodingChange)
+    EVT_TEXT(VideoTranscCodec_Event, SoutDialog::OnTranscodingChange)
     EVT_COMBOBOX(AudioTranscCodec_Event, SoutDialog::OnTranscodingChange)
+    EVT_TEXT(AudioTranscCodec_Event, SoutDialog::OnTranscodingChange)
     EVT_COMBOBOX(VideoTranscBitrate_Event, SoutDialog::OnTranscodingChange)
+    EVT_TEXT(VideoTranscBitrate_Event, SoutDialog::OnTranscodingChange)
     EVT_COMBOBOX(AudioTranscBitrate_Event, SoutDialog::OnTranscodingChange)
+    EVT_TEXT(AudioTranscBitrate_Event, SoutDialog::OnTranscodingChange)
+    EVT_COMBOBOX(VideoTranscScale_Event, SoutDialog::OnTranscodingChange)
+    EVT_TEXT(VideoTranscScale_Event, SoutDialog::OnTranscodingChange)
+    EVT_COMBOBOX(AudioTranscChans_Event, SoutDialog::OnTranscodingChange)
+    EVT_TEXT(AudioTranscChans_Event, SoutDialog::OnTranscodingChange)
+
+    /* Events generated by the misc panel */
+    EVT_CHECKBOX(SAPMisc_Event, SoutDialog::OnSAPMiscChange)
+    EVT_CHECKBOX(SLPMisc_Event, SoutDialog::OnSLPMiscChange)
+    EVT_TEXT(AnnounceAddr_Event, SoutDialog::OnAnnounceAddrChange)
 
 END_EVENT_TABLE()
 
@@ -168,7 +167,7 @@ SoutDialog::SoutDialog( intf_thread_t *_p_intf, wxWindow* _p_parent ):
                                                         wxHORIZONTAL );
     wxStaticText *mrl_label = new wxStaticText( panel, -1,
                                                 wxU(_("Destination Target:")));
-    mrl_combo = new wxComboBox( panel, MRL_Event, mrl,
+    mrl_combo = new wxComboBox( panel, MRL_Event, wxT(""),
                                 wxPoint(20,25), wxSize(120, -1), 0, NULL );
     mrl_combo->SetToolTip( wxU(_("You can use this field directly by typing "
         "the full MRL you want to open.\n""Alternatively, the field will be "
@@ -179,13 +178,16 @@ SoutDialog::SoutDialog( intf_thread_t *_p_intf, wxWindow* _p_parent ):
     mrl_sizer_sizer->Add( mrl_sizer, 1, wxEXPAND | wxALL, 5 );
 
     /* Create the output encapsulation panel */
-    wxPanel *encapsulation_panel = EncapsulationPanel( panel );
+    encapsulation_panel = EncapsulationPanel( panel );
 
     /* Create the access output panel */
-    wxPanel *access_panel = AccessPanel( panel );
+    access_panel = AccessPanel( panel );
 
     /* Create the transcoding panel */
-    wxPanel *transcoding_panel = TranscodingPanel( panel );
+    transcoding_panel = TranscodingPanel( panel );
+
+    /* Create the Misc panel */
+    misc_panel = MiscPanel( panel );
 
     /* Separation */
     wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
@@ -207,6 +209,7 @@ SoutDialog::SoutDialog( intf_thread_t *_p_intf, wxWindow* _p_parent ):
     panel_sizer->Add( access_panel, 1, wxEXPAND | wxALL, 5 );
     panel_sizer->Add( encapsulation_panel, 0, wxEXPAND | wxALL, 5 );
     panel_sizer->Add( transcoding_panel, 0, wxEXPAND | wxALL, 5 );
+    panel_sizer->Add( misc_panel, 0, wxEXPAND | wxALL, 5 );
     panel_sizer->Add( static_line, 0, wxEXPAND | wxALL, 5 );
     panel_sizer->Add( button_sizer, 0, wxALIGN_LEFT | wxALIGN_BOTTOM |
                       wxALL, 5 );
@@ -215,20 +218,35 @@ SoutDialog::SoutDialog( intf_thread_t *_p_intf, wxWindow* _p_parent ):
     main_sizer->Add( panel, 1, wxGROW, 0 );
     main_sizer->Layout();
     SetSizerAndFit( main_sizer );
-
-    /* Update all the values */
-    ParseMRL();
 }
 
 SoutDialog::~SoutDialog()
 {
 }
 
+wxArrayString SoutDialog::GetOptions()
+{
+   return SeparateEntries( mrl_combo->GetValue() );
+}
+
 /*****************************************************************************
  * Private methods.
  *****************************************************************************/
 void SoutDialog::UpdateMRL()
 {
+    /* Check the demux dump option */
+    if( dump_checkbox->IsChecked() )
+    {
+        wxString dumpfile;
+
+        if( file_combo->GetValue().size() )
+            dumpfile = wxT(" :demuxdump-file=\"") +
+                       file_combo->GetValue() + wxT("\"");
+        mrl_combo->SetValue( wxT(":demux=demuxdump") + dumpfile );
+
+        return;
+    }
+
     /* Let's start with the transcode options */
     wxString transcode;
     if( video_transc_checkbox->IsChecked() ||
@@ -239,12 +257,14 @@ void SoutDialog::UpdateMRL()
         {
             transcode += wxT("vcodec=") + video_codec_combo->GetValue();
             transcode += wxT(",vb=") + video_bitrate_combo->GetValue();
+            transcode += wxT(",scale=") + video_scale_combo->GetValue();
             if( audio_transc_checkbox->IsChecked() ) transcode += wxT(",");
         }
         if( audio_transc_checkbox->IsChecked() )
         {
             transcode += wxT("acodec=") + audio_codec_combo->GetValue();
             transcode += wxT(",ab=") + audio_bitrate_combo->GetValue();
+            transcode += wxT(",channels=") + audio_channels_combo->GetValue();
         }
         transcode += wxT("}");
     }
@@ -256,15 +276,27 @@ void SoutDialog::UpdateMRL()
     case PS_ENCAPSULATION:
         encapsulation = wxT("ps");
         break;
+    case MPEG1_ENCAPSULATION:
+        encapsulation = wxT("mpeg1");
+        break;
     case AVI_ENCAPSULATION:
         encapsulation = wxT("avi");
         break;
     case OGG_ENCAPSULATION:
         encapsulation = wxT("ogg");
         break;
+    case RAW_ENCAPSULATION:
+        encapsulation = wxT("raw");
+        break;
     case MP4_ENCAPSULATION:
         encapsulation = wxT("mp4");
         break;
+    case MOV_ENCAPSULATION:
+        encapsulation = wxT("mov");
+        break;
+    case ASF_ENCAPSULATION:
+        encapsulation = wxT("asf");
+        break;
     case TS_ENCAPSULATION:
     default:
         encapsulation = wxT("ts");
@@ -281,16 +313,29 @@ void SoutDialog::UpdateMRL()
     {
         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
         dup_opts += wxT("dst=std{access=file,mux=");
-        dup_opts += encapsulation + wxT(",url=");
-        dup_opts += file_combo->GetValue() + wxT("}");
+        dup_opts += encapsulation + wxT(",url=\"");
+        dup_opts += file_combo->GetValue() + wxT("\"}");
     }
     if( access_checkboxes[HTTP_ACCESS_OUT]->IsChecked() )
     {
         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
         dup_opts += wxT("dst=std{access=http,mux=");
         dup_opts += encapsulation + wxT(",url=");
-        dup_opts += net_addr->GetLineText(0);
-        dup_opts += wxString::Format( wxT(":%d"), net_port->GetValue() );
+        dup_opts += net_addrs[HTTP_ACCESS_OUT]->GetLineText(0);
+        dup_opts += wxString::Format( wxT(":%d"),
+                                      net_ports[HTTP_ACCESS_OUT]->GetValue() );
+        dup_opts += wxT("}");
+    }
+    if( access_checkboxes[MMSH_ACCESS_OUT]->IsChecked() )
+    {
+        if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
+        dup_opts += wxT("dst=std{access=mmsh,mux=");
+        dup_opts += encapsulation;
+        if( i_encapsulation_type == ASF_ENCAPSULATION ) dup_opts += wxT("h");
+        dup_opts += wxT(",url=");
+        dup_opts += net_addrs[HTTP_ACCESS_OUT]->GetLineText(0);
+        dup_opts += wxString::Format( wxT(":%d"),
+                                      net_ports[MMSH_ACCESS_OUT]->GetValue() );
         dup_opts += wxT("}");
     }
     if( access_checkboxes[UDP_ACCESS_OUT]->IsChecked() )
@@ -298,17 +343,54 @@ void SoutDialog::UpdateMRL()
         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
         dup_opts += wxT("dst=std{access=udp,mux=");
         dup_opts += encapsulation + wxT(",url=");
-        dup_opts += net_addr->GetLineText(0);
-        dup_opts += wxString::Format( wxT(":%d"), net_port->GetValue() );
+
+        wxString udp_addr = net_addrs[UDP_ACCESS_OUT]->GetLineText(0);
+        if ((udp_addr[0u] != '[') && (udp_addr.Find(':') != -1))
+        {
+            dup_opts += wxT ("[") + udp_addr + wxT ("]");
+        }
+        else
+        {
+            dup_opts += udp_addr;
+        }
+        dup_opts += wxString::Format( wxT(":%d"),
+                                      net_ports[UDP_ACCESS_OUT]->GetValue() );
+
+        /* SAP only if UDP */
+        if( sap_checkbox->IsChecked() )
+        {
+            dup_opts += wxT(",sap");
+            if( ! announce_addr->GetLineText(0).IsEmpty() )
+            {
+                dup_opts += wxT(",name=\"");
+                dup_opts += announce_addr->GetLineText(0);
+                dup_opts += wxT("\"");
+            }
+        }
+
+        /* SLP only if UDP */
+        if( slp_checkbox->IsChecked() )
+        {
+            dup_opts += wxT(",slp");
+            if( ! sap_checkbox->IsChecked() &&
+                ! announce_addr->GetLineText(0).IsEmpty() )
+            {
+                dup_opts += wxT(",name=\"");
+                dup_opts += announce_addr->GetLineText(0);
+                dup_opts += wxT("\"");
+            }
+        }
+
         dup_opts += wxT("}");
     }
-    if( access_checkboxes[UDP_ACCESS_OUT]->IsChecked() )
+    if( access_checkboxes[RTP_ACCESS_OUT]->IsChecked() )
     {
         if( !dup_opts.IsEmpty() ) dup_opts += wxT(",");
         dup_opts += wxT("dst=std{access=rtp,mux=");
         dup_opts += encapsulation + wxT(",url=");
-        dup_opts += net_addr->GetLineText(0);
-        dup_opts += wxString::Format( wxT(":%d"), net_port->GetValue() );
+        dup_opts += net_addrs[RTP_ACCESS_OUT]->GetLineText(0);
+        dup_opts += wxString::Format( wxT(":%d"),
+                                      net_ports[RTP_ACCESS_OUT]->GetValue() );
         dup_opts += wxT("}");
     }
 
@@ -320,11 +402,9 @@ void SoutDialog::UpdateMRL()
     }
 
     if( !transcode.IsEmpty() || !duplicate.IsEmpty() )
-        mrl = wxT("#") + transcode + duplicate;
+        mrl_combo->SetValue( wxT(":sout=#") + transcode + duplicate );
     else
-        mrl = wxT("");
-
-    mrl_combo->SetValue( mrl );
+        mrl_combo->SetValue( wxT("") );
 }
 
 wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
@@ -333,17 +413,18 @@ wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
     wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
                                   wxSize(200, 200) );
 
-    wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
     wxStaticBox *panel_box = new wxStaticBox( panel, -1,
-                                              wxU(_("Output Methods")) );
+                                              wxU(_("Output methods")) );
     wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
-                                                          wxHORIZONTAL );
+                                                          wxVERTICAL );
 
+    wxFlexGridSizer *sizer = new wxFlexGridSizer( 2, 4, 20 );
     static const wxString access_output_array[] =
     {
         wxU(_("Play locally")),
         wxU(_("File")),
         wxU(_("HTTP")),
+        wxU(_("MMSH")),
         wxU(_("UDP")),
         wxU(_("RTP"))
     };
@@ -362,9 +443,10 @@ wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
     subpanel_sizer = new wxFlexGridSizer( 1, 1, 20 );
     subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
     access_subpanels[0]->SetSizerAndFit( subpanel_sizer );
+    access_subpanels[0]->Hide();
 
     /* File row */
-    subpanel_sizer = new wxFlexGridSizer( 3, 1, 20 );
+    subpanel_sizer = new wxFlexGridSizer( 3, 2, 20 );
     label = new wxStaticText( access_subpanels[1], -1, wxU(_("Filename")) );
     file_combo = new wxComboBox( access_subpanels[1], FileName_Event, wxT(""),
                                  wxPoint(20,25), wxSize(200, -1), 0, NULL );
@@ -375,25 +457,33 @@ wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
                          wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
     subpanel_sizer->Add( browse_button, 0,
                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
+    subpanel_sizer->Add( new wxPanel(access_subpanels[1], -1), 0,
+                         wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    dump_checkbox = new wxCheckBox( access_subpanels[1], FileDump_Event,
+                                    wxU(_("Dump raw input")) );
+    subpanel_sizer->Add( dump_checkbox, 0,
+                         wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxTOP, 5 );
 
     access_subpanels[1]->SetSizerAndFit( subpanel_sizer );
 
     /* Net rows */
-    for( i=2; i < ACCESS_OUT_NUM; i++ )
+    for( i = HTTP_ACCESS_OUT; i < ACCESS_OUT_NUM; i++ )
     {
         subpanel_sizer = new wxFlexGridSizer( 4, 1, 20 );
         label = new wxStaticText( access_subpanels[i], -1, wxU(_("Address")) );
-        net_addr = new wxTextCtrl( access_subpanels[i], NetAddr_Event, wxT(""),
-                                   wxDefaultPosition, wxSize( 200, -1 ),
-                                   wxTE_PROCESS_ENTER);
+        net_addrs[i] = new wxTextCtrl( access_subpanels[i],
+                                   NetAddr1_Event + i - HTTP_ACCESS_OUT,
+                                   wxT(""), wxDefaultPosition,
+                                   wxSize( 200, -1 ), wxTE_PROCESS_ENTER);
         subpanel_sizer->Add( label, 0,
                              wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
-        subpanel_sizer->Add( net_addr, 1, wxEXPAND |
+        subpanel_sizer->Add( net_addrs[i], 1, wxEXPAND |
                              wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
 
         int val = config_GetInt( p_intf, "server-port" );
         label = new wxStaticText( access_subpanels[i], -1, wxU(_("Port")) );
-        net_port = new wxSpinCtrl( access_subpanels[i], NetPort_Event,
+        net_ports[i] = new wxSpinCtrl( access_subpanels[i],
+                                   NetPort1_Event + i - HTTP_ACCESS_OUT,
                                    wxString::Format(wxT("%d"), val),
                                    wxDefaultPosition, wxDefaultSize,
                                    wxSP_ARROW_KEYS,
@@ -401,7 +491,7 @@ wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
 
         subpanel_sizer->Add( label, 0,
                              wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
-        subpanel_sizer->Add( net_port, 0,
+        subpanel_sizer->Add( net_ports[i], 0,
                              wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
 
         access_subpanels[i]->SetSizerAndFit( subpanel_sizer );
@@ -409,15 +499,17 @@ wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
 
 
     /* Stuff everything into the main panel */
-    for( i=0; i < ACCESS_OUT_NUM; i++ )
+    for( i=1; i < ACCESS_OUT_NUM; i++ )
     {
         sizer->Add( access_checkboxes[i], 0,
-                    wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
+                    wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL  | wxALL, 5 );
         sizer->Add( access_subpanels[i], 1, wxEXPAND | wxALIGN_CENTER_VERTICAL
-                    | wxALIGN_LEFT );
+                    | wxALIGN_LEFT  | wxALL, 5 );
     }
 
-    panel_sizer->Add( sizer, 1, wxEXPAND, 0 );
+    panel_sizer->Add( access_checkboxes[0], 0,
+                      wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL  | wxALL, 5 );
+    panel_sizer->Add( sizer, 1, wxEXPAND | wxTOP, 3 );
 
     panel->SetSizerAndFit( panel_sizer );
 
@@ -430,6 +522,55 @@ wxPanel *SoutDialog::AccessPanel( wxWindow* parent )
     return panel;
 }
 
+wxPanel *SoutDialog::MiscPanel( wxWindow* parent )
+{
+    wxPanel *panel = new wxPanel( parent, -1, wxDefaultPosition,
+                                  wxSize(200, 200) );
+
+    wxStaticBox *panel_box = new wxStaticBox( panel, -1,
+                                   wxU(_("Miscellaneous options")) );
+    wxStaticBoxSizer *panel_sizer = new wxStaticBoxSizer( panel_box,
+                                                          wxVERTICAL );
+
+    /* Announce Row */
+    misc_subpanels[ANN_MISC_SOUT] = new wxPanel( panel, -1 );
+    wxFlexGridSizer *subpanel_sizer = new wxFlexGridSizer( 4, 4, 20 );
+
+    sap_checkbox = new wxCheckBox( misc_subpanels[ANN_MISC_SOUT],SAPMisc_Event,
+                                   wxU(_("SAP announce")) );
+    slp_checkbox = new wxCheckBox( misc_subpanels[ANN_MISC_SOUT],SLPMisc_Event,
+                                   wxU(_("SLP announce")) );
+
+    wxStaticText *label = new wxStaticText( misc_subpanels[ANN_MISC_SOUT], -1,
+                                            wxU(_("Channel name")) );
+    announce_addr = new wxTextCtrl( misc_subpanels[ANN_MISC_SOUT],
+                                    AnnounceAddr_Event,
+                                    wxT(""), wxDefaultPosition,
+                                    wxSize( 200, -1 ), wxTE_PROCESS_ENTER);
+
+    subpanel_sizer->Add( sap_checkbox, 0,
+                         wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    subpanel_sizer->Add( slp_checkbox, 0,
+                         wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    subpanel_sizer->Add( label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    subpanel_sizer->Add( announce_addr, 1, wxEXPAND |
+                         wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
+
+    misc_subpanels[ANN_MISC_SOUT]->SetSizerAndFit( subpanel_sizer );
+
+    /* Stuff everything into the main panel */
+    panel_sizer->Add( misc_subpanels[ANN_MISC_SOUT], 1,
+                      wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+
+    panel->SetSizerAndFit( panel_sizer );
+
+    /* Update misc panel */
+    misc_subpanels[ANN_MISC_SOUT]->Disable();
+    announce_addr->Disable();
+
+    return panel;
+}
+
 wxPanel *SoutDialog::EncapsulationPanel( wxWindow* parent )
 {
     int i;
@@ -445,9 +586,13 @@ wxPanel *SoutDialog::EncapsulationPanel( wxWindow* parent )
     {
         wxT("MPEG TS"),
         wxT("MPEG PS"),
+        wxT("MPEG 1"),
+        wxT("Ogg"),
+        wxT("Raw"),
+        wxT("ASF"),
         wxT("AVI"),
-        wxT("MP4/MOV"),
-        wxT("Ogg")
+        wxT("MP4"),
+        wxT("MOV")
     };
 
     /* Stuff everything into the main panel */
@@ -457,13 +602,14 @@ wxPanel *SoutDialog::EncapsulationPanel( wxWindow* parent )
             new wxRadioButton( panel, EncapsulationRadio1_Event + i,
                                encapsulation_array[i] );
         panel_sizer->Add( encapsulation_radios[i], 0,
-                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+                          wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
+                          wxALL, 4 );
     }
 
     panel->SetSizerAndFit( panel_sizer );
 
     /* Update encapsulation panel */
-    encapsulation_radios[0]->Enable();
+    encapsulation_radios[TS_ENCAPSULATION]->SetValue(true);
     i_encapsulation_type = TS_ENCAPSULATION;
 
     return panel;
@@ -480,10 +626,10 @@ wxPanel *SoutDialog::TranscodingPanel( wxWindow* parent )
                                                           wxVERTICAL );
 
     /* Create video transcoding checkox */
-#   define VCODECS_NUM 8
-    static const wxString vcodecs_array[] =
+    static const wxString wxvcodecs_array[] =
     {
-        wxT("mpgv"),
+        wxT("mp1v"),
+        wxT("mp2v"),
         wxT("mp4v"),
         wxT("DIV1"),
         wxT("DIV2"),
@@ -491,34 +637,61 @@ wxPanel *SoutDialog::TranscodingPanel( wxWindow* parent )
         wxT("H263"),
         wxT("I263"),
         wxT("WMV1"),
+        wxT("WMV2"),
+        wxT("MJPG"),
+        wxT("theo")
     };
-#   define VBITRATES_NUM 9
+    /*
     static const wxString vbitrates_array[] =
     {
-        wxT("3000"),
-        wxT("2000"),
-        wxT("1000"),
-        wxT("750"),
-        wxT("500"),
-        wxT("400"),
-        wxT("200"),
-        wxT("150"),
-        wxT("100")
+            wxT("3072"),
+            wxT("2048"),
+            wxT("1024"),
+            wxT("768"),
+            wxT("512"),
+            wxT("384"),
+            wxT("256"),
+            wxT("192"),
+            wxT("128"),
+            wxT("96"),
+            wxT("64"),
+            wxT("32"),
+            wxT("16")
+    };
+*/
+    static const wxString vscales_array[] =
+    {
+            wxT("0.25"),
+            wxT("0.5"),
+            wxT("0.75"),
+            wxT("1"),
+            wxT("1.25"),
+            wxT("1.5"),
+            wxT("1.75"),
+            wxT("2")
     };
 
-    wxFlexGridSizer *video_sizer = new wxFlexGridSizer( 4, 1, 20 );
+    wxFlexGridSizer *video_sizer = new wxFlexGridSizer( 6, 1, 20 );
     video_transc_checkbox =
         new wxCheckBox( panel, VideoTranscEnable_Event, wxU(_("Video codec")));
     video_codec_combo =
-        new wxComboBox( panel, VideoTranscCodec_Event, wxT("mp4v"),
+        new wxComboBox( panel, VideoTranscCodec_Event, wxT(""),
                         wxPoint(20,25), wxDefaultSize,
-                        VCODECS_NUM, vcodecs_array, wxCB_READONLY );
+                        WXSIZEOF(wxvcodecs_array),
+                        wxvcodecs_array, wxCB_READONLY );
+    video_codec_combo->SetSelection(2);
     wxStaticText *bitrate_label =
         new wxStaticText( panel, -1, wxU(_("Bitrate (kb/s)")));
     video_bitrate_combo =
-        new wxComboBox( panel, VideoTranscBitrate_Event, wxT("1000"),
+        new wxComboBox( panel, VideoTranscBitrate_Event, wxT("1024"),
+                        wxPoint(20,25), wxDefaultSize,
+                        WXSIZEOF(vbitrates_array), vbitrates_array );
+    wxStaticText *scale_label =
+        new wxStaticText( panel, -1, wxU(_("Scale")));
+    video_scale_combo =
+        new wxComboBox( panel, VideoTranscScale_Event, wxT("1"),
                         wxPoint(20,25), wxDefaultSize,
-                        VBITRATES_NUM, vbitrates_array );
+                        WXSIZEOF(vscales_array), vscales_array );
     video_sizer->Add( video_transc_checkbox, 0,
                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
     video_sizer->Add( video_codec_combo, 1,
@@ -527,44 +700,83 @@ wxPanel *SoutDialog::TranscodingPanel( wxWindow* parent )
                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
     video_sizer->Add( video_bitrate_combo, 1,
                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    video_sizer->Add( scale_label, 0,
+                      wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    video_sizer->Add( video_scale_combo, 1,
+                      wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
 
     /* Create audio transcoding checkox */
-#   define ACODECS_NUM 2
-    static const wxString acodecs_array[] =
+    static const wxString wxacodecs_array[] =
     {
         wxT("mpga"),
-        wxT("a52")
+        wxT("mp3"),
+        wxT("mp4a"),
+        wxT("a52"),
+        wxT("vorb"),
+        wxT("flac"),
+        wxT("spx")
+    };
+    static const wxString achannels_array[] =
+    {
+        wxT("1"),
+        wxT("2"),
+        wxT("4"),
+        wxT("6")
     };
-#   define ABITRATES_NUM 5
+/*
     static const wxString abitrates_array[] =
     {
-        wxT("512"),
-        wxT("256"),
-        wxT("192"),
-        wxT("128"),
-        wxT("96")
+            wxT("512"),
+            wxT("256"),
+            wxT("192"),
+            wxT("128"),
+            wxT("96"),
+            wxT("64"),
+            wxT("32"),
+            wxT("16")
     };
-
-    wxFlexGridSizer *audio_sizer = new wxFlexGridSizer( 4, 1, 20 );
+*/
+    wxFlexGridSizer *audio_sizer = new wxFlexGridSizer( 3, 1, 20 );
     audio_transc_checkbox =
         new wxCheckBox( panel, AudioTranscEnable_Event, wxU(_("Audio codec")));
     audio_codec_combo =
-        new wxComboBox( panel, AudioTranscCodec_Event, wxT("mpga"),
-                        wxPoint(20,25), wxDefaultSize,
-                        ACODECS_NUM, acodecs_array, wxCB_READONLY );
+        new wxComboBox( panel, AudioTranscCodec_Event, wxT(""),
+                        wxPoint(10,25), wxDefaultSize,
+                        WXSIZEOF(wxacodecs_array),
+                        wxacodecs_array, wxCB_READONLY );
+    audio_codec_combo->SetSelection(0);
+#if defined( __WXMSW__ )
+    wxFlexGridSizer *audio_sub_sizer = new wxFlexGridSizer( 4, 5, 20 );
+#else
+    wxFlexGridSizer *audio_sub_sizer = new wxFlexGridSizer( 2, 5, 20 );
+#endif
     bitrate_label =
         new wxStaticText( panel, -1, wxU(_("Bitrate (kb/s)")));
     audio_bitrate_combo =
         new wxComboBox( panel, AudioTranscBitrate_Event, wxT("192"),
-                        wxPoint(20,25), wxDefaultSize,
-                        ABITRATES_NUM, abitrates_array );
+                        wxPoint(10,25), wxDefaultSize,
+                        WXSIZEOF(abitrates_array), abitrates_array );
+    wxStaticText *channels_label =
+        new wxStaticText( panel, -1, wxU(_("Channels")));
+    audio_channels_combo =
+        new wxComboBox( panel, AudioTranscChans_Event, wxT(""),
+                        wxPoint(10,25), wxDefaultSize,
+                        WXSIZEOF(achannels_array), achannels_array );
+    audio_channels_combo->SetSelection(1);
+    audio_sub_sizer->Add( bitrate_label, 0,
+                      wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    audio_sub_sizer->Add( audio_bitrate_combo, 1,
+                      wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    audio_sub_sizer->Add( channels_label, 0,
+                      wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+    audio_sub_sizer->Add( audio_channels_combo, 1,
+                      wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
+
     audio_sizer->Add( audio_transc_checkbox, 0,
                       wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
     audio_sizer->Add( audio_codec_combo, 1,
                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
-    audio_sizer->Add( bitrate_label, 0,
-                      wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
-    audio_sizer->Add( audio_bitrate_combo, 1,
+    audio_sizer->Add( audio_sub_sizer, 1,
                       wxEXPAND | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL );
 
     /* Stuff everything into the main panel */
@@ -585,94 +797,12 @@ wxPanel *SoutDialog::TranscodingPanel( wxWindow* parent )
     return panel;
 }
 
-void SoutDialog::ParseMRL()
-{
-    /* Initialise MRL value */
-    char *psz_sout = config_GetPsz( p_intf, "sout" );
-    if( psz_sout )
-    {
-        mrl = wxU(psz_sout);
-        free( psz_sout );
-    }
-
-    /* Parse the MRL */
-    wxString access = mrl.BeforeFirst( wxT('/') );
-    wxString encapsulation = mrl.BeforeFirst( wxT(':') ).AfterFirst(wxT('/'));
-
-    if( !access.Cmp( wxT("http") ) )
-    {
-        i_access_type = HTTP_ACCESS_OUT;
-    }
-    else if( !access.Cmp( wxT("udp") ) )
-    {
-        i_access_type = UDP_ACCESS_OUT;
-    }
-    else if( !access.Cmp( wxT("rtp") ) )
-    {
-        i_access_type = RTP_ACCESS_OUT;
-    }
-    else
-    {
-        i_access_type = FILE_ACCESS_OUT;
-    }
-
-    if( !encapsulation.Cmp( wxT("ps") ) )
-    {
-        i_encapsulation_type = PS_ENCAPSULATION;
-    }
-    else if( !encapsulation.Cmp( wxT("avi") ) )
-    {
-        i_encapsulation_type = AVI_ENCAPSULATION;
-    }
-    else if( !encapsulation.Cmp( wxT("ogg") ) )
-    {
-        i_encapsulation_type = OGG_ENCAPSULATION;
-    }
-    else
-    {
-        i_encapsulation_type = TS_ENCAPSULATION;
-    }
-
-    wxString second_part = mrl.AfterFirst( wxT(':') );
-
-    if( i_access_type == FILE_ACCESS_OUT )
-    {
-        /* The whole second part of the MRL is the filename */
-        file_combo->SetValue( second_part );
-    }
-    else
-    {
-        /* we've got address:port */
-        wxString address = second_part.BeforeLast( wxT(':') );
-        net_addr->SetValue( address );
-
-        long int i_port;
-        wxString port = second_part.AfterLast( wxT(':') );
-        if( port.ToLong( &i_port ) )
-        {
-            net_port->SetValue( i_port );
-        }
-        else
-        {
-            net_port->SetValue( config_GetInt( p_intf, "server-port" ) );
-        }
-    }
-
-    /* Update access output panel */
-    wxCommandEvent dummy_event;
-    dummy_event.SetId( AccessType1_Event + i_access_type );
-    OnAccessTypeChange( dummy_event );
-
-    /* Update encapsulation output panel */
-    dummy_event.SetId( EncapsulationRadio1_Event + i_encapsulation_type );
-    OnEncapsulationChange( dummy_event );
-}
-
 /*****************************************************************************
  * Events methods.
  *****************************************************************************/
 void SoutDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
 {
+    mrl_combo->Append( mrl_combo->GetValue() );
     EndModal( wxID_OK );
 }
 
@@ -683,7 +813,7 @@ void SoutDialog::OnCancel( wxCommandEvent& WXUNUSED(event) )
 
 void SoutDialog::OnMRLChange( wxCommandEvent& event )
 {
-    mrl = event.GetString();
+    //mrl = event.GetString();
 }
 
 /*****************************************************************************
@@ -699,6 +829,8 @@ void SoutDialog::OnAccessTypeChange( wxCommandEvent& event )
     switch( i_access_type )
     {
     case UDP_ACCESS_OUT:
+        misc_subpanels[ANN_MISC_SOUT]->Enable( event.GetInt() );
+
     case RTP_ACCESS_OUT:
         for( i = 1; i < ENCAPS_NUM; i++ )
         {
@@ -711,7 +843,35 @@ void SoutDialog::OnAccessTypeChange( wxCommandEvent& event )
         }
         break;
     }
+    UpdateMRL();
+}
 
+/*****************************************************************************
+ * AnnounceMisc panel event methods.
+ *****************************************************************************/
+void SoutDialog::OnSAPMiscChange( wxCommandEvent& event )
+{
+    if( !slp_checkbox->IsChecked() )
+    {
+        announce_addr->Enable( event.GetInt() );
+    }
+    UpdateMRL();
+}
+
+void SoutDialog::OnSLPMiscChange( wxCommandEvent& event )
+{
+    if( !sap_checkbox->IsChecked() )
+    {
+        announce_addr->Enable( event.GetInt() );
+    }
+    UpdateMRL();
+}
+
+/*****************************************************************************
+ * SAPAddr panel event methods.
+ *****************************************************************************/
+void SoutDialog::OnAnnounceAddrChange( wxCommandEvent& WXUNUSED(event) )
+{
     UpdateMRL();
 }
 
@@ -725,8 +885,8 @@ void SoutDialog::OnFileChange( wxCommandEvent& WXUNUSED(event) )
 
 void SoutDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
 {
-    wxFileDialog dialog( this, wxU(_("Save file")),
-                         wxT(""), wxT(""), wxT("*.*"), wxSAVE );
+    wxFileDialog dialog( this, wxU(_("Save file")), wxT(""), wxT(""), wxT("*"),
+                         wxSAVE | wxOVERWRITE_PROMPT );
 
     if( dialog.ShowModal() == wxID_OK )
     {
@@ -735,6 +895,25 @@ void SoutDialog::OnFileBrowse( wxCommandEvent& WXUNUSED(event) )
     }
 }
 
+void SoutDialog::OnFileDump( wxCommandEvent& event )
+{
+    misc_panel->Enable( !event.GetInt() );
+    encapsulation_panel->Enable( !event.GetInt() );
+    transcoding_panel->Enable( !event.GetInt() );
+
+    for( int i = 0; i < ACCESS_OUT_NUM; i++ )
+    {
+        if( i != FILE_ACCESS_OUT )
+        {
+            access_checkboxes[i]->Enable( !event.GetInt() );
+            access_subpanels[i]->Enable( !event.GetInt() &&
+                                         access_checkboxes[i]->IsChecked() );
+        }
+    }
+
+    UpdateMRL();
+}
+
 /*****************************************************************************
  * Net access output event methods.
  *****************************************************************************/
@@ -762,10 +941,12 @@ void SoutDialog::OnTranscodingEnable( wxCommandEvent& event )
     case VideoTranscEnable_Event:
         video_codec_combo->Enable( event.GetInt() );
         video_bitrate_combo->Enable( event.GetInt() );
+        video_scale_combo->Enable( event.GetInt() );
         break;
     case AudioTranscEnable_Event:
         audio_codec_combo->Enable( event.GetInt() );
         audio_bitrate_combo->Enable( event.GetInt() );
+        audio_channels_combo->Enable( event.GetInt() );
         break;
     }