/*****************************************************************************
* sout.cpp : Stream output dialog ( old-style )
****************************************************************************
- * Copyright (C) 2007-2008 the VideoLAN team
- * Copyright (C) 2007 Société des arts technologiques
- * Copyright (C) 2007 Savoir-faire Linux
+ * Copyright (C) 2007-2009 the VideoLAN team
*
* $Id$
*
* Authors: Clément Stenac <zorglub@videolan.org>
* Jean-Baptiste Kempf <jb@videolan.org>
- * Jean-François Massol <jf.massol -at- gmail.com>
- * Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <QString>
#include <QFileDialog>
#include <QToolButton>
+#include <QSpinBox>
+#include <assert.h>
-SoutDialog* SoutDialog::instance = NULL;
-
-SoutDialog::SoutDialog( QWidget *parent, intf_thread_t *_p_intf, QString inputMRL )
+SoutDialog::SoutDialog( QWidget *parent, intf_thread_t *_p_intf, const QString& inputMRL )
: QVLCDialog( parent, _p_intf )
{
setWindowTitle( qtr( "Stream Output" ) );
+ setWindowRole( "vlc-stream-output" );
/* UI stuff */
ui.setupUi( this );
ui.inputBox->setMRL( inputMRL );
- ui.helpEdit->setPlainText( "This dialog will allow you to stream or convert "
- "your media, locally, on your private network or on the "
- "Internet.\n"
- "You should start by checking that your input matches what you "
- "want and go on with the \"Next\" button.\n" );
+ ui.helpEdit->setPlainText( qtr("This dialog will allow you to stream or "
+ "convert your media for use locally, on your private network, "
+ "or on the Internet.\n"
+ "You should start by checking that source matches what you want "
+ "your input to be and then press the \"Next\" "
+ "button to continue.\n") );
ui.mrlEdit->setToolTip ( qtr( "Stream output string.\n"
"This is automatically generated "
ui.destTab->setCornerWidget( closeTabButton );
closeTabButton->hide();
closeTabButton->setAutoRaise( true );
- closeTabButton->setIcon( QIcon( ":/clear" ) );
+ closeTabButton->setIcon( QIcon( ":/toolbar/clear" ) );
BUTTONACT( closeTabButton, closeTab() );
#endif
CONNECT( ui.destTab, currentChanged( int ), this, tabChanged( int ) );
- ui.destTab->setTabIcon( 0, QIcon( ":/playlist_add" ) );
+ ui.destTab->setTabIcon( 0, QIcon( ":/buttons/playlist/playlist_add" ) );
ui.destBox->addItem( qtr( "File" ) );
ui.destBox->addItem( "HTTP" );
- ui.destBox->addItem( "MMS" );
- ui.destBox->addItem( "UDP" );
- ui.destBox->addItem( "RTP" );
+ ui.destBox->addItem( "MS-WMSP (MMSH)" );
+ ui.destBox->addItem( "RTSP" );
+ ui.destBox->addItem( "RTP / MPEG Transport Stream" );
+ ui.destBox->addItem( "RTP Audio/Video Profile" );
+ ui.destBox->addItem( "UDP (legacy)" );
ui.destBox->addItem( "IceCast" );
BUTTONACT( ui.addButton, addDest() );
// /* Connect everything to the updateMRL function */
- #define CB( x ) CONNECT( ui.x, toggled( bool ), this, updateMRL() );
- #define CT( x ) CONNECT( ui.x, textChanged( const QString ), this, updateMRL() );
- #define CS( x ) CONNECT( ui.x, valueChanged( int ), this, updateMRL() );
- #define CC( x ) CONNECT( ui.x, currentIndexChanged( int ), this, updateMRL() );
+#define CB( x ) CONNECT( ui.x, toggled( bool ), this, updateMRL() );
+#define CT( x ) CONNECT( ui.x, textChanged( const QString& ), this, updateMRL() );
+#define CS( x ) CONNECT( ui.x, valueChanged( int ), this, updateMRL() );
+#define CC( x ) CONNECT( ui.x, currentIndexChanged( int ), this, updateMRL() );
/* Misc */
- CB( soutAll ); CB( soutKeep ); CS( ttl ); CT( sapName ); CT( sapGroup );
- CB( localOutput );
+ CB( soutAll ); CS( ttl ); CT( sapName ); CT( sapGroup );
+ CB( localOutput ); CB( transcodeBox );
CONNECT( ui.profileSelect, optionsChanged(), this, updateMRL() );
okButton = new QPushButton( qtr( "&Stream" ) );
BUTTONACT( ui.nextButton2, next() );
BUTTONACT( ui.prevButton, prev() );
BUTTONACT( ui.prevButton2, prev() );
+
+#undef CC
+#undef CS
+#undef CT
+#undef CB
}
void SoutDialog::next()
void SoutDialog::addDest( )
{
- int index;
+ VirtualDestBox *db;
+ QString caption;
+
switch( ui.destBox->currentIndex() )
{
case 0:
- {
- FileDestBox *fdb = new FileDestBox( this );
- index = ui.destTab->addTab( fdb, "File" );
- CONNECT( fdb, mrlUpdated(), this, updateMRL() );
- }
+ db = new FileDestBox( this );
+ caption = qtr( "File" );
break;
case 1:
- {
- HTTPDestBox *hdb = new HTTPDestBox( this );
- index = ui.destTab->addTab( hdb, "HTTP" );
- CONNECT( hdb, mrlUpdated(), this, updateMRL() );
- }
+ db = new HTTPDestBox( this );
+ caption = qfu( "HTTP" );
break;
case 2:
- {
- MMSHDestBox *mdb = new MMSHDestBox( this );
- index = ui.destTab->addTab( mdb, "MMSH" );
- CONNECT( mdb, mrlUpdated(), this, updateMRL() );
- }
+ db = new MMSHDestBox( this );
+ caption = qfu( "WMSP" );
break;
case 3:
- {
- UDPDestBox *udb = new UDPDestBox( this );
- index = ui.destTab->addTab( udb, "UDP" );
- CONNECT( udb, mrlUpdated(), this, updateMRL() );
- }
+ db = new RTSPDestBox( this );
+ caption = qfu( "RTSP" );
break;
case 4:
- {
- RTPDestBox *rdb = new RTPDestBox( this );
- index = ui.destTab->addTab( rdb, "RTP" );
- CONNECT( rdb, mrlUpdated(), this, updateMRL() );
- }
+ db = new RTPDestBox( this, "ts" );
+ caption = "RTP/TS";
break;
case 5:
- {
- ICEDestBox *idb = new ICEDestBox( this );
- index = ui.destTab->addTab( idb, "Icecast" );
- CONNECT( idb, mrlUpdated(), this, updateMRL() );
- }
+ db = new RTPDestBox( this );
+ caption = "RTP/AVP";
+ break;
+ case 6:
+ db = new UDPDestBox( this );
+ caption = "UDP";
+ break;
+ case 7:
+ db = new ICEDestBox( this );
+ caption = "Icecast";
+ break;
+ default:
+ assert(0);
}
+ int index = ui.destTab->addTab( db, caption );
+ CONNECT( db, mrlUpdated(), this, updateMRL() );
ui.destTab->setCurrentIndex( index );
updateMRL();
}
QString qs_mux = ui.profileSelect->getMux();
SoutMrl smrl( ":sout=#" );
- if( !ui.profileSelect->getTranscode().isEmpty() )
+ if( !ui.profileSelect->getTranscode().isEmpty() && ui.transcodeBox->isChecked() )
{
smrl.begin( ui.profileSelect->getTranscode() );
smrl.end();
for( int i = 1; i < ui.destTab->count(); i++ )
{
VirtualDestBox *vdb = qobject_cast<VirtualDestBox *>(ui.destTab->widget( i ));
- QString tempMRL = vdb->getMRL( qs_mux );
+ if( !vdb )
+ continue;
+ QString tempMRL = vdb->getMRL( qs_mux );
if( tempMRL.isEmpty() ) continue;
+
if( multi )
smrl.option( "dst", tempMRL );
else
mrl = smrl.getMrl();
- /* FIXME, deal with SAP
- sout.b_sap = ui.sap->isChecked();
- sout.psz_group = strdup( qtu( ui.sapGroup->text() ) );
- sout.psz_name = strdup( qtu( ui.sapName->text() ) ); */
+ if( ui.sap->isChecked() )
+ {
+ QString group = ui.sapGroup->text();
+ QString name = ui.sapName->text();
+
+ /* FIXME: This sucks. We should really return a QStringList instead of
+ * (mis)quoting, concatainating and split input item paramters. */
+ name = name.replace( " ", " " );
+ group = group.replace( " ", " " );
+
+ /* We need to add options for both standard and rtp targets */
+ /* This is inelegant but simple and functional */
+ mrl.append( qfu( " :sout-rtp-sap" ) );
+ mrl.append( qfu( " :sout-rtp-name=" ) + name );
+ mrl.append( qfu( " :sout-standard-sap" ) );
+ mrl.append( qfu( " :sout-standard-name=" ) + name );
+ mrl.append( qfu( " :sout-standard-group=" ) + group );
+ }
+ else
+ {
+ mrl.append( qfu( " :no-sout-rtp-sap" ) );
+ mrl.append( qfu( " :no-sout-standard-sap" ) );
+ }
+
+ if( ui.soutAll->isChecked() ) mrl.append( " :sout-all" );
- if( ui.soutAll->isChecked() ) mrl.append( " :sout-all" );
+ if( ui.ttl->value() != 1 ) mrl.append( " :ttl=" + ui.ttl->value() );
- if( ui.soutKeep->isChecked() ) mrl.append( " :sout-keep" );
+ mrl.append( " :sout-keep" );
ui.mrlEdit->setPlainText( mrl );
}