applied patches of issues #56 and #57

This commit is contained in:
rafael@riseup.net 2012-01-16 20:58:27 +00:00
parent 73ba0c72d2
commit 5fbdf2edf6
13 changed files with 143 additions and 135 deletions

View File

@ -45,3 +45,4 @@ with contributions by:
Adrian Knoth <adi@drcomp.erfurt.thur.de> Adrian Knoth <adi@drcomp.erfurt.thur.de>
Filipe Roque <flip.roque@gmail.com> Filipe Roque <flip.roque@gmail.com>
Johann Fot <johann.fot@dunkelfuerst.com> Johann Fot <johann.fot@dunkelfuerst.com>
Alban Peignier <alban.peignier@gmail.com>

View File

@ -1,3 +1,9 @@
next version
o Issue #56: Wrong icecast2 password isn't properly reported, fixed.
thanks to Filipe Roque <flip.roque@gmail.com>
o Issue #57: BufferedSink makes streams invalid, fixed.
thanks to Alban Peignier <alban.peignier@gmail.com>
27-10-2011 Darkice 1.1 released 27-10-2011 Darkice 1.1 released
o Updated aac+ encoding to use libaacplus-2.0.0 api. o Updated aac+ encoding to use libaacplus-2.0.0 api.
thanks to Sergiy <piratfm@gmail.com> thanks to Sergiy <piratfm@gmail.com>

View File

@ -61,8 +61,7 @@ CastSink :: init ( TcpSocket * socket,
const char * name, const char * name,
const char * url, const char * url,
const char * genre, const char * genre,
bool isPublic, bool isPublic )
unsigned int bufferDuration )
throw ( Exception ) throw ( Exception )
{ {
this->socket = socket; this->socket = socket;
@ -73,13 +72,6 @@ CastSink :: init ( TcpSocket * socket,
this->url = url ? Util::strDup( url) : 0; this->url = url ? Util::strDup( url) : 0;
this->genre = genre ? Util::strDup( genre) : 0; this->genre = genre ? Util::strDup( genre) : 0;
this->isPublic = isPublic; this->isPublic = isPublic;
this->bufferDuration = bufferDuration;
int bufferSize = bitRate ? (bitRate * 1024 / 8) * bufferDuration
: (128 * 1024 / 8) * bufferDuration;
bufferedSink = socket ? new BufferedSink( socket, bufferSize)
: 0;
} }
@ -118,7 +110,7 @@ CastSink :: open ( void ) throw ( Exception )
return false; return false;
} }
if ( !bufferedSink->open() ) { if ( !getSink()->open() ) {
return false; return false;
} }

View File

@ -68,21 +68,11 @@ class CastSink : public Sink, public virtual Reporter
*/ */
Ref<TcpSocket> socket; Ref<TcpSocket> socket;
/**
* The BufferedSink encapsulating the socket connection to the server.
*/
Ref<BufferedSink> bufferedSink;
/** /**
* An optional Sink to enable stream dumps. * An optional Sink to enable stream dumps.
*/ */
Ref<Sink> streamDump; Ref<Sink> streamDump;
/**
* Duration of the BufferedSink buffer in seconds.
*/
unsigned int bufferDuration;
/** /**
* Password to the server. * Password to the server.
*/ */
@ -123,8 +113,6 @@ class CastSink : public Sink, public virtual Reporter
* @param genre genre of the stream. * @param genre genre of the stream.
* @param bitRate bitrate of the stream (e.g. mp3 bitrate). * @param bitRate bitrate of the stream (e.g. mp3 bitrate).
* @param isPublic is the stream public? * @param isPublic is the stream public?
* @param bufferDuration duration of the BufferedSink buffer
* in seconds.
* @exception Exception * @exception Exception
*/ */
void void
@ -135,8 +123,7 @@ class CastSink : public Sink, public virtual Reporter
const char * name, const char * name,
const char * url, const char * url,
const char * genre, const char * genre,
bool isPublic, bool isPublic)
unsigned int bufferDuration )
throw ( Exception ); throw ( Exception );
/** /**
@ -178,7 +165,7 @@ class CastSink : public Sink, public virtual Reporter
inline Sink * inline Sink *
getSink ( void ) const throw () getSink ( void ) const throw ()
{ {
return bufferedSink.get(); return getSocket();
} }
/** /**
@ -206,8 +193,7 @@ class CastSink : public Sink, public virtual Reporter
* @param bitRate bitrate of the stream (e.g. mp3 bitrate). * @param bitRate bitrate of the stream (e.g. mp3 bitrate).
* @param isPublic is the stream public? * @param isPublic is the stream public?
* @param streamDump a Sink to dump the streamed binary data to * @param streamDump a Sink to dump the streamed binary data to
* @param bufferDuration duration of the BufferedSink buffer *
* in seconds.
* @exception Exception * @exception Exception
*/ */
inline inline
@ -218,8 +204,7 @@ class CastSink : public Sink, public virtual Reporter
const char * url = 0, const char * url = 0,
const char * genre = 0, const char * genre = 0,
bool isPublic = false, bool isPublic = false,
Sink * streamDump = 0, Sink * streamDump = 0)
unsigned int bufferDuration = 10 )
throw ( Exception ) throw ( Exception )
{ {
init( socket, init( socket,
@ -229,8 +214,7 @@ class CastSink : public Sink, public virtual Reporter
name, name,
url, url,
genre, genre,
isPublic, isPublic );
bufferDuration );
} }
/** /**
@ -249,8 +233,7 @@ class CastSink : public Sink, public virtual Reporter
cs.name, cs.name,
cs.url, cs.url,
cs.genre, cs.genre,
cs.isPublic, cs.isPublic );
cs.bufferDuration );
} }
/** /**
@ -284,8 +267,7 @@ class CastSink : public Sink, public virtual Reporter
cs.name, cs.name,
cs.url, cs.url,
cs.genre, cs.genre,
cs.isPublic, cs.isPublic );
cs.bufferDuration );
} }
return *this; return *this;
} }
@ -308,7 +290,7 @@ class CastSink : public Sink, public virtual Reporter
inline virtual bool inline virtual bool
isOpen ( void ) const throw () isOpen ( void ) const throw ()
{ {
return bufferedSink != NULL ? bufferedSink->isOpen() : false; return getSink()->isOpen();
} }
/** /**
@ -455,17 +437,6 @@ class CastSink : public Sink, public virtual Reporter
{ {
return isPublic; return isPublic;
} }
/**
* Get the duration of the BufferedSink buffer in seconds.
*
* @return the the duration of the BufferedSink buffer in seconds.
*/
inline unsigned int
getBufferDuration ( void ) const throw ()
{
return bufferDuration;
}
}; };

View File

@ -258,6 +258,8 @@ DarkIce :: configIceCast ( const Config & config,
FileSink * localDumpFile = 0; FileSink * localDumpFile = 0;
bool fileAddDate = false; bool fileAddDate = false;
const char * fileDateFormat = 0; const char * fileDateFormat = 0;
AudioEncoder * encoder = 0;
int bufferSize = 0;
str = cs->get( "sampleRate"); str = cs->get( "sampleRate");
sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); sampleRate = str ? Util::strToL( str) : dsp->getSampleRate();
@ -326,6 +328,9 @@ DarkIce :: configIceCast ( const Config & config,
fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false; fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false;
fileDateFormat = cs->get("fileDateFormat"); fileDateFormat = cs->get("fileDateFormat");
bufferSize = dsp->getBitsPerSample() / 8 * dsp->getSampleRate() * dsp->getChannel() * bufferSecs;
reportEvent( 3, "buffer size: ", bufferSize);
localDumpName = cs->get( "localDumpFile"); localDumpName = cs->get( "localDumpFile");
// go on and create the things // go on and create the things
@ -366,8 +371,7 @@ DarkIce :: configIceCast ( const Config & config,
genre, genre,
isPublic, isPublic,
remoteDumpFile, remoteDumpFile,
localDumpFile, localDumpFile);
bufferSecs );
str = cs->getForSure( "format", " missing in section ", stream); str = cs->getForSure( "format", " missing in section ", stream);
@ -379,29 +383,30 @@ DarkIce :: configIceCast ( const Config & config,
#ifdef HAVE_LAME_LIB #ifdef HAVE_LAME_LIB
if ( Util::strEq( str, "mp3") ) { if ( Util::strEq( str, "mp3") ) {
audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), encoder = new LameLibEncoder( audioOuts[u].server.get(),
dsp.get(), dsp.get(),
bitrateMode, bitrateMode,
bitrate, bitrate,
quality, quality,
sampleRate, sampleRate,
channel, channel,
lowpass, lowpass,
highpass ); highpass );
} }
#endif #endif
#ifdef HAVE_TWOLAME_LIB #ifdef HAVE_TWOLAME_LIB
if ( Util::strEq( str, "mp2") ) { if ( Util::strEq( str, "mp2") ) {
audioOuts[u].encoder = new TwoLameLibEncoder( encoder = new TwoLameLibEncoder(
audioOuts[u].server.get(), audioOuts[u].server.get(),
dsp.get(), dsp.get(),
bitrateMode, bitrateMode,
bitrate, bitrate,
sampleRate, sampleRate,
channel ); channel );
} }
#endif #endif
audioOuts[u].encoder = new BufferedSink(encoder, bufferSize, dsp->getBitsPerSample() / 8);
encConnector->attach( audioOuts[u].encoder.get()); encConnector->attach( audioOuts[u].encoder.get());
#endif // HAVE_LAME_LIB || HAVE_TWOLAME_LIB #endif // HAVE_LAME_LIB || HAVE_TWOLAME_LIB
} }
@ -458,6 +463,8 @@ DarkIce :: configIceCast2 ( const Config & config,
FileSink * localDumpFile = 0; FileSink * localDumpFile = 0;
bool fileAddDate = false; bool fileAddDate = false;
const char * fileDateFormat = 0; const char * fileDateFormat = 0;
AudioEncoder * encoder = 0;
int bufferSize = 0;
str = cs->getForSure( "format", " missing in section ", stream); str = cs->getForSure( "format", " missing in section ", stream);
if ( Util::strEq( str, "vorbis") ) { if ( Util::strEq( str, "vorbis") ) {
@ -537,6 +544,9 @@ DarkIce :: configIceCast2 ( const Config & config,
str = cs->get( "fileAddDate"); str = cs->get( "fileAddDate");
fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false; fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false;
fileDateFormat = cs->get( "fileDateFormat"); fileDateFormat = cs->get( "fileDateFormat");
bufferSize = dsp->getBitsPerSample() / 8 * dsp->getSampleRate() * dsp->getChannel() * bufferSecs;
reportEvent( 3, "buffer size: ", bufferSize);
localDumpName = cs->get( "localDumpFile"); localDumpName = cs->get( "localDumpFile");
@ -579,8 +589,7 @@ DarkIce :: configIceCast2 ( const Config & config,
url, url,
genre, genre,
isPublic, isPublic,
localDumpFile, localDumpFile);
bufferSecs );
switch ( format ) { switch ( format ) {
case IceCast2::mp3: case IceCast2::mp3:
@ -590,16 +599,19 @@ DarkIce :: configIceCast2 ( const Config & config,
"thus can't create mp3 stream: ", "thus can't create mp3 stream: ",
stream); stream);
#else #else
audioOuts[u].encoder = new LameLibEncoder( encoder = new LameLibEncoder(
audioOuts[u].server.get(), audioOuts[u].server.get(),
dsp.get(), dsp.get(),
bitrateMode, bitrateMode,
bitrate, bitrate,
quality, quality,
sampleRate, sampleRate,
channel, channel,
lowpass, lowpass,
highpass ); highpass );
audioOuts[u].encoder = new BufferedSink(encoder, bufferSize, dsp->getBitsPerSample() / 8);
#endif // HAVE_LAME_LIB #endif // HAVE_LAME_LIB
break; break;
@ -611,15 +623,18 @@ DarkIce :: configIceCast2 ( const Config & config,
"thus can't Ogg Vorbis stream: ", "thus can't Ogg Vorbis stream: ",
stream); stream);
#else #else
audioOuts[u].encoder = new VorbisLibEncoder(
audioOuts[u].server.get(), encoder = new VorbisLibEncoder(
dsp.get(), audioOuts[u].server.get(),
bitrateMode, dsp.get(),
bitrate, bitrateMode,
quality, bitrate,
sampleRate, quality,
dsp->getChannel(), sampleRate,
maxBitrate); dsp->getChannel(),
maxBitrate);
audioOuts[u].encoder = new BufferedSink(encoder, bufferSize, dsp->getBitsPerSample() / 8);
#endif // HAVE_VORBIS_LIB #endif // HAVE_VORBIS_LIB
break; break;
@ -630,13 +645,15 @@ DarkIce :: configIceCast2 ( const Config & config,
"thus can't create mp2 stream: ", "thus can't create mp2 stream: ",
stream); stream);
#else #else
audioOuts[u].encoder = new TwoLameLibEncoder( encoder = new TwoLameLibEncoder(
audioOuts[u].server.get(), audioOuts[u].server.get(),
dsp.get(), dsp.get(),
bitrateMode, bitrateMode,
bitrate, bitrate,
sampleRate, sampleRate,
channel ); channel );
audioOuts[u].encoder = new BufferedSink(encoder, bufferSize, dsp->getBitsPerSample() / 8);
#endif // HAVE_TWOLAME_LIB #endif // HAVE_TWOLAME_LIB
break; break;
@ -648,14 +665,16 @@ DarkIce :: configIceCast2 ( const Config & config,
"thus can't aac stream: ", "thus can't aac stream: ",
stream); stream);
#else #else
audioOuts[u].encoder = new FaacEncoder( encoder = new FaacEncoder(
audioOuts[u].server.get(), audioOuts[u].server.get(),
dsp.get(), dsp.get(),
bitrateMode, bitrateMode,
bitrate, bitrate,
quality, quality,
sampleRate, sampleRate,
dsp->getChannel()); dsp->getChannel());
audioOuts[u].encoder = new BufferedSink(encoder, bufferSize, dsp->getBitsPerSample() / 8);
#endif // HAVE_FAAC_LIB #endif // HAVE_FAAC_LIB
break; break;
@ -666,14 +685,16 @@ DarkIce :: configIceCast2 ( const Config & config,
"thus can't aacp stream: ", "thus can't aacp stream: ",
stream); stream);
#else #else
audioOuts[u].encoder = new aacPlusEncoder( encoder = new aacPlusEncoder(
audioOuts[u].server.get(), audioOuts[u].server.get(),
dsp.get(), dsp.get(),
bitrateMode, bitrateMode,
bitrate, bitrate,
quality, quality,
sampleRate, sampleRate,
channel ); channel );
audioOuts[u].encoder = new BufferedSink(encoder, bufferSize, dsp->getBitsPerSample() / 8);
#endif // HAVE_AACPLUS_LIB #endif // HAVE_AACPLUS_LIB
break; break;
@ -744,6 +765,8 @@ DarkIce :: configShoutCast ( const Config & config,
FileSink * localDumpFile = 0; FileSink * localDumpFile = 0;
bool fileAddDate = false; bool fileAddDate = false;
const char * fileDateFormat = 0; const char * fileDateFormat = 0;
AudioEncoder * encoder = 0;
int bufferSize = 0;
str = cs->get( "sampleRate"); str = cs->get( "sampleRate");
sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); sampleRate = str ? Util::strToL( str) : dsp->getSampleRate();
@ -809,6 +832,9 @@ DarkIce :: configShoutCast ( const Config & config,
fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false; fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false;
fileDateFormat = cs->get( "fileDateFormat"); fileDateFormat = cs->get( "fileDateFormat");
bufferSize = dsp->getBitsPerSample() / 8 * dsp->getSampleRate() * dsp->getChannel() * bufferSecs;
reportEvent( 3, "buffer size: ", bufferSize);
localDumpName = cs->get( "localDumpFile"); localDumpName = cs->get( "localDumpFile");
// go on and create the things // go on and create the things
@ -851,18 +877,19 @@ DarkIce :: configShoutCast ( const Config & config,
irc, irc,
aim, aim,
icq, icq,
localDumpFile, localDumpFile);
bufferSecs );
audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(),
dsp.get(), encoder = new LameLibEncoder( audioOuts[u].server.get(),
bitrateMode, dsp.get(),
bitrate, bitrateMode,
quality, bitrate,
sampleRate, quality,
channel, sampleRate,
lowpass, channel,
highpass ); lowpass,
highpass );
audioOuts[u].encoder = new BufferedSink(encoder, bufferSize, dsp->getBitsPerSample() / 8);
encConnector->attach( audioOuts[u].encoder.get()); encConnector->attach( audioOuts[u].encoder.get());
#endif // HAVE_LAME_LIB #endif // HAVE_LAME_LIB

View File

@ -89,7 +89,7 @@ class DarkIce : public virtual Referable, public virtual Reporter
* Type describing each lame library output. * Type describing each lame library output.
*/ */
typedef struct { typedef struct {
Ref<AudioEncoder> encoder; Ref<Sink> encoder;
Ref<TcpSocket> socket; Ref<TcpSocket> socket;
Ref<CastSink> server; Ref<CastSink> server;
} Output; } Output;

View File

@ -198,6 +198,11 @@ IceCast :: sendLogin ( void ) throw ( Exception )
/* read the anticipated response: "OK" */ /* read the anticipated response: "OK" */
len = source->read( resp, STRBUF_SIZE); len = source->read( resp, STRBUF_SIZE);
if ( Util::strEq( resp, "ERROR - Bad Password",20) ) {
throw Exception( __FILE__, __LINE__,
"Icecast - wrong password");
}
if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) {
return false; return false;
} }

View File

@ -153,8 +153,7 @@ class IceCast : public CastSink
const char * genre = 0, const char * genre = 0,
bool isPublic = false, bool isPublic = false,
const char * remoteDumpFile = 0, const char * remoteDumpFile = 0,
Sink * streamDump = 0, Sink * streamDump = 0 )
unsigned int bufferDuration = 10 )
throw ( Exception ) throw ( Exception )
: CastSink( socket, : CastSink( socket,
password, password,
@ -163,8 +162,7 @@ class IceCast : public CastSink
url, url,
genre, genre,
isPublic, isPublic,
streamDump, streamDump )
bufferDuration )
{ {
init( mountPoint, description, remoteDumpFile); init( mountPoint, description, remoteDumpFile);
} }

View File

@ -80,7 +80,7 @@ static const char fileid[] = "$Id$";
* Expected positive response from server begins like this. * Expected positive response from server begins like this.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static const char responseOK[] = "HTTP/1.0 200"; static const char responseOK[] = "HTTP/1.0 200";
static const char responseWrongPasswd[] = "HTTP/1.0 401";
/* =============================================== local function prototypes */ /* =============================================== local function prototypes */
@ -246,6 +246,12 @@ IceCast2 :: sendLogin ( void ) throw ( Exception )
return false; return false;
} }
resp[lenExpected] = 0; resp[lenExpected] = 0;
if ( Util::strEq( resp, responseWrongPasswd) ) {
throw Exception( __FILE__, __LINE__,
"Icecast2 - wrong password");
}
if ( !Util::strEq( resp, responseOK) ) { if ( !Util::strEq( resp, responseOK) ) {
return false; return false;
} }

View File

@ -161,8 +161,7 @@ class IceCast2 : public CastSink
const char * url = 0, const char * url = 0,
const char * genre = 0, const char * genre = 0,
bool isPublic = false, bool isPublic = false,
Sink * streamDump = 0, Sink * streamDump = 0 )
unsigned int bufferDuration = 10 )
throw ( Exception ) throw ( Exception )
: CastSink( socket, : CastSink( socket,
password, password,
@ -171,8 +170,7 @@ class IceCast2 : public CastSink
url, url,
genre, genre,
isPublic, isPublic,
streamDump, streamDump )
bufferDuration )
{ {
init( format, mountPoint, description); init( format, mountPoint, description);
} }

View File

@ -182,6 +182,12 @@ ShoutCast :: sendLogin ( void ) throw ( Exception )
len = source->read( resp, STRBUF_SIZE); len = source->read( resp, STRBUF_SIZE);
reportEvent(8, "server response length: ", len); reportEvent(8, "server response length: ", len);
reportEvent(8, "server response: ", resp); reportEvent(8, "server response: ", resp);
if ( Util::strEq( resp, "invalid password",16) ) {
throw Exception( __FILE__, __LINE__,
"ShoutCast - wrong password");
}
if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) {
return false; return false;
} }

View File

@ -162,8 +162,7 @@ class ShoutCast : public CastSink
const char * irc = 0, const char * irc = 0,
const char * aim = 0, const char * aim = 0,
const char * icq = 0, const char * icq = 0,
Sink * streamDump = 0, Sink * streamDump = 0 )
unsigned int bufferDuration = 10 )
throw ( Exception ) throw ( Exception )
: CastSink( socket, : CastSink( socket,
password, password,
@ -172,8 +171,7 @@ class ShoutCast : public CastSink
url, url,
genre, genre,
isPublic, isPublic,
streamDump, streamDump )
bufferDuration )
{ {
init( irc, aim, icq, mountPoint ); init( irc, aim, icq, mountPoint );
} }

View File

@ -402,7 +402,7 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
return false; return false;
} }
return true; return getSink()->canWrite(sec, usec);
} }
/** /**