void ofGstVideoUtils::update(){ if (isLoaded()){ if(!isFrameByFrame()){ mutex.lock(); bHavePixelsChanged = bBackPixelsChanged; if (bHavePixelsChanged){ bBackPixelsChanged=false; pixels = backPixels; } mutex.unlock(); }else{ GstBuffer *buffer; //get the buffer from appsink if(isPaused()) buffer = gst_app_sink_pull_preroll (GST_APP_SINK (getSink())); else buffer = gst_app_sink_pull_buffer (GST_APP_SINK (getSink())); if(buffer){ guint size = GST_BUFFER_SIZE (buffer); if(pixels.isAllocated()){ memcpy (pixels.getPixels(), GST_BUFFER_DATA (buffer), size); bHavePixelsChanged=true; } /// we don't need the appsink buffer anymore gst_buffer_unref (buffer); } } }else{ ofLog(OF_LOG_WARNING,"not loaded"); } bIsFrameNew = bHavePixelsChanged; bHavePixelsChanged = false; }
void ofGstVideoUtils::update(){ if (isLoaded()){ if(!isFrameByFrame()){ ofScopedLock lock(mutex); bHavePixelsChanged = bBackPixelsChanged; if (bHavePixelsChanged){ bBackPixelsChanged=false; swap(pixels,backPixels); #ifdef OF_USE_GST_GL if(backTexture.isAllocated()){ frontTexture.getTextureData() = backTexture.getTextureData(); frontTexture.setTextureMinMagFilter(GL_LINEAR,GL_LINEAR); frontTexture.setTextureWrap(GL_CLAMP_TO_EDGE,GL_CLAMP_TO_EDGE); } #endif if(!copyPixels){ frontBuffer = backBuffer; } } }else{ #if GST_VERSION_MAJOR==0 GstBuffer *buffer; //get the buffer from appsink if(isPaused()) buffer = gst_app_sink_pull_preroll (GST_APP_SINK (getSink())); else buffer = gst_app_sink_pull_buffer (GST_APP_SINK (getSink())); if(buffer){ if(pixels.isAllocated()){ pixels.setFromExternalPixels(GST_BUFFER_DATA (buffer),pixels.getWidth(),pixels.getHeight(),pixels.getNumChannels()); prevBuffer = shared_ptr<GstBuffer>(buffer,gst_buffer_unref);; bHavePixelsChanged=true; } } } #else GstBuffer * buffer; GstSample * sample; //get the buffer from appsink if(isPaused()){ sample = gst_app_sink_pull_preroll (GST_APP_SINK (getSink())); }else{ sample = gst_app_sink_pull_sample (GST_APP_SINK (getSink())); } buffer = gst_sample_get_buffer(sample); if(buffer){ if(pixels.isAllocated()){ gst_buffer_map (buffer, &mapinfo, GST_MAP_READ); //TODO: stride = mapinfo.size / height; pixels.setFromExternalPixels(mapinfo.data,pixels.getWidth(),pixels.getHeight(),pixels.getNumChannels()); backBuffer = shared_ptr<GstSample>(sample,gst_sample_unref); bHavePixelsChanged=true; gst_buffer_unmap(buffer,&mapinfo); } } } #endif }else{
void ofGstVideoUtils::update(){ if (isLoaded()){ if(!isFrameByFrame()){ mutex.lock(); bHavePixelsChanged = bBackPixelsChanged; if (bHavePixelsChanged){ bBackPixelsChanged=false; pixels.swap(backPixels); #if GST_VERSION_MAJOR==0 if(prevBuffer) gst_buffer_unref (prevBuffer); #else if(prevBuffer) gst_sample_unref (prevBuffer); #endif prevBuffer = buffer; } mutex.unlock(); }else{ #if GST_VERSION_MAJOR==0 GstBuffer *buffer; //get the buffer from appsink if(isPaused()) buffer = gst_app_sink_pull_preroll (GST_APP_SINK (getSink())); else buffer = gst_app_sink_pull_buffer (GST_APP_SINK (getSink())); if(buffer){ if(pixels.isAllocated()){ if(prevBuffer) gst_buffer_unref (prevBuffer); pixels.setFromExternalPixels(GST_BUFFER_DATA (buffer),pixels.getWidth(),pixels.getHeight(),pixels.getNumChannels()); prevBuffer = buffer; bHavePixelsChanged=true; } } } #else GstBuffer *buffer; GstSample * sample; //get the buffer from appsink if(isPaused()){ sample = gst_app_sink_pull_preroll (GST_APP_SINK (getSink())); }else{ sample = gst_app_sink_pull_sample (GST_APP_SINK (getSink())); } buffer = gst_sample_get_buffer(sample); if(buffer){ if(pixels.isAllocated()){ if(prevBuffer) gst_sample_unref (prevBuffer); gst_buffer_map (buffer, &mapinfo, GST_MAP_READ); //TODO: stride = mapinfo.size / height; pixels.setFromExternalPixels(mapinfo.data,pixels.getWidth(),pixels.getHeight(),pixels.getNumChannels()); prevBuffer = sample; bHavePixelsChanged=true; gst_buffer_unmap(buffer,&mapinfo); } } } #endif }else{
void ofGstVideoUtils::update(){ if (isLoaded()){ if(!isFrameByFrame()){ std::unique_lock<std::mutex> lock(mutex); bHavePixelsChanged = bBackPixelsChanged; if (bHavePixelsChanged){ bBackPixelsChanged=false; swap(pixels,backPixels); #ifdef OF_USE_GST_GL if(backTexture.isAllocated()){ frontTexture.getTextureData() = backTexture.getTextureData(); frontTexture.setTextureMinMagFilter(GL_LINEAR,GL_LINEAR); frontTexture.setTextureWrap(GL_CLAMP_TO_EDGE,GL_CLAMP_TO_EDGE); } #endif if(!copyPixels){ frontBuffer = backBuffer; } } }else{ #if GST_VERSION_MAJOR==0 ofLogError() << "frame by frame doesn't work any more in 0.10"; #else GstBuffer * buffer; GstSample * sample; //get the buffer from appsink if(isPaused()){ sample = gst_app_sink_pull_preroll (GST_APP_SINK (getSink())); }else{ sample = gst_app_sink_pull_sample (GST_APP_SINK (getSink())); } buffer = gst_sample_get_buffer(sample); if(buffer){ if(pixels.isAllocated()){ gst_buffer_map (buffer, &mapinfo, GST_MAP_READ); //TODO: stride = mapinfo.size / height; pixels.setFromExternalPixels(mapinfo.data,pixels.getWidth(),pixels.getHeight(),pixels.getNumChannels()); backBuffer = shared_ptr<GstSample>(sample,gst_sample_unref); bHavePixelsChanged=true; gst_buffer_unmap(buffer,&mapinfo); } } #endif } }else{ ofLogWarning("ofGstVideoUtils") << "update(): ofGstVideoUtils not loaded"; } bIsFrameNew = bHavePixelsChanged; bHavePixelsChanged = false; }
/*------------------------------------------------------------------------------ * Open the connection *----------------------------------------------------------------------------*/ bool CastSink :: open ( void ) throw ( Exception ) { if ( isOpen() ) { return false; } if ( !getSink()->open() ) { return false; } if ( !sendLogin() ) { close(); return false; } if ( streamDump != 0 ) { if ( !streamDump->isOpen() ) { if ( !streamDump->open() ) { reportEvent( 2, "can't open stream dump"); } } } return true; }
/*------------------------------------------------------------------------------ * Flush the data from the encoder *----------------------------------------------------------------------------*/ void FaacEncoder :: flush ( void ) throw ( Exception ) { if ( !isOpen() ) { return; } getSink()->flush(); }
/*------------------------------------------------------------------------------ * Close the encoding session *----------------------------------------------------------------------------*/ void FaacEncoder :: close ( void ) throw ( Exception ) { if ( isOpen() ) { flush(); faacEncClose(encoderHandle); faacOpen = false; getSink()->close(); } }
int flowConservative1(GraphFlow *g) { int i = 0; for( i =0; i < getNumNodes(g); i++) { if( i != getSink(g) && i != getSource(g) && positiveFlowToNode(g,i) != positiveFlowFromNode(g,i) ) { return FALSE; } } return TRUE; }
void ofGstVideoUtils::update(){ if (isLoaded()){ if(!isFrameByFrame()){ mutex.lock(); bHavePixelsChanged = bBackPixelsChanged; if (bHavePixelsChanged){ bBackPixelsChanged=false; pixels.swap(backPixels); if(prevBuffer) gst_buffer_unref (prevBuffer); prevBuffer = buffer; } mutex.unlock(); }else{ GstBuffer *buffer; //get the buffer from appsink if(isPaused()) buffer = gst_app_sink_pull_preroll (GST_APP_SINK (getSink())); else buffer = gst_app_sink_pull_buffer (GST_APP_SINK (getSink())); if(buffer){ if(pixels.isAllocated()){ if(prevBuffer) gst_buffer_unref (prevBuffer); //memcpy (pixels.getPixels(), GST_BUFFER_DATA (buffer), size); pixels.setFromExternalPixels(GST_BUFFER_DATA (buffer),pixels.getWidth(),pixels.getHeight(),pixels.getNumChannels()); prevBuffer = buffer; bHavePixelsChanged=true; } } } }else{ ofLog(OF_LOG_WARNING,"ofGstVideoUtils not loaded"); } bIsFrameNew = bHavePixelsChanged; bHavePixelsChanged = false; }
bool analyse(pxl::Sink *sink) throw (std::runtime_error) { _Count++; // output basic statistics if ((_Count > 0) && (_Count % _Stats == 0)) { std::cout << "Example Module: " << _Count << " events analysed" << std::endl; } // simply pass the events from input to output getSource("output")->setTargets(getSink("input")->get()); return getSource("output")->processTargets(); }
GraphFlow *getResidualNetwork(GraphFlow *g) { GraphFlow *newGraph = newGraphFlow( getNumNodes(g), getSource(g), getSink(g) ); int i = 0, j = 0; int capacity = 0; for(i=0; i < getNumNodes(newGraph); i++) { for(j=0; i < getNumNodes(newGraph); i++) { capacity = getResidualCapacity(g,i,j); if(capacity > 0) { addEdge(newGraph,i,j); setCapacity(newGraph,i,j,capacity); } } } }
bool DinicFlow :: dfsDinicFlow(int v, int skip) { if (v == getSink()) { return true; } for (; neighbours[v] < getNumbersNeigbor(v); ++neighbours[v]) { NetworkEdge * edge = getNeigbor(v, neighbours[v]); if (distance[edge->getTo()] == distance[v] + 1 && edge->getCapacity() - edge->getFlow() >= skip) { bool checkDfs = dfsDinicFlow(edge->getTo(), skip); if (checkDfs) { edge->changeFlow(skip); return true; } } } return false; }
void DinicFlow :: solveDinicFlow() { int skipFlow; skipFlow = (1<<30); while (skipFlow != 0) { Bfs BfsDinicFlow; BfsDinicFlow.getDistances(*this, distance, skipFlow); if (distance[getSink()] == getVertices()) { skipFlow>>=1; continue; } for (int i = 0; i < getVertices(); ++i) { neighbours[i] = 0; } while (dfsDinicFlow(getSourse(), skipFlow)) { flow += skipFlow; } }
int flowConservative2(GraphFlow *g) { int i = 0; int j = 0; int balance = 0; for( i=0; i < getNumNodes(g); i++) { if( i != getSource(g) && i != getSink(g) ) { for(j=0, balance =0; j < getNumNodes(g); j++) { balance += getFlow(g,i,j); } if(balance != 0) return FALSE; } } return TRUE; }
/*------------------------------------------------------------------------------ * Write data to the encoder *----------------------------------------------------------------------------*/ unsigned int FaacEncoder :: write ( const void * buf, unsigned int len ) throw ( Exception ) { if ( !isOpen() || len == 0 ) { return 0; } unsigned int channels = getInChannel(); unsigned int bitsPerSample = getInBitsPerSample(); unsigned int sampleSize = (bitsPerSample / 8) * channels; unsigned char * b = (unsigned char*) buf; unsigned int processed = len - (len % sampleSize); unsigned int nSamples = processed / sampleSize; unsigned char * faacBuf = new unsigned char[maxOutputBytes]; int samples = (int) nSamples * channels; int processedSamples = 0; if ( converter ) { unsigned int converted; #ifdef HAVE_SRC_LIB src_short_to_float_array ((short *) b, (float *) converterData.data_in, samples); converterData.input_frames = nSamples; converterData.data_out = resampledOffset + (resampledOffsetSize * channels); int srcError = src_process (converter, &converterData); if (srcError) throw Exception (__FILE__, __LINE__, "libsamplerate error: ", src_strerror (srcError)); converted = converterData.output_frames_gen; #else int inCount = nSamples; short int * shortBuffer = new short int[samples]; int outCount = (int) (inCount * resampleRatio); Util::conv( bitsPerSample, b, processed, shortBuffer, isInBigEndian()); converted = converter->resample( inCount, outCount+1, shortBuffer, &resampledOffset[resampledOffsetSize*channels]); delete[] shortBuffer; #endif resampledOffsetSize += converted; // encode samples (if enough) while(resampledOffsetSize - processedSamples >= inputSamples/channels) { int outputBytes; #ifdef HAVE_SRC_LIB short *shortData = new short[inputSamples]; src_float_to_short_array(resampledOffset + (processedSamples * channels), shortData, inputSamples) ; outputBytes = faacEncEncode(encoderHandle, (int32_t*) shortData, inputSamples, faacBuf, maxOutputBytes); delete [] shortData; #else outputBytes = faacEncEncode(encoderHandle, (int32_t*) &resampledOffset[processedSamples*channels], inputSamples, faacBuf, maxOutputBytes); #endif getSink()->write(faacBuf, outputBytes); processedSamples+=inputSamples/channels; } if (processedSamples && (int) resampledOffsetSize >= processedSamples) { resampledOffsetSize -= processedSamples; //move least part of resampled data to beginning if(resampledOffsetSize) #ifdef HAVE_SRC_LIB resampledOffset = (float *) memmove(resampledOffset, &resampledOffset[processedSamples*channels], resampledOffsetSize*channels*sizeof(float)); #else resampledOffset = (short *) memmove(resampledOffset, &resampledOffset[processedSamples*channels], resampledOffsetSize*sampleSize); #endif } } else { while (processedSamples < samples) { int outputBytes; int inSamples = samples - processedSamples < (int) inputSamples ? samples - processedSamples : inputSamples; outputBytes = faacEncEncode(encoderHandle, (int32_t*) (b + processedSamples/sampleSize), inSamples, faacBuf, maxOutputBytes); getSink()->write(faacBuf, outputBytes); processedSamples += inSamples; } } delete[] faacBuf; return samples * sampleSize; }
/*------------------------------------------------------------------------------ * Log in to the IceCast server *----------------------------------------------------------------------------*/ bool IceCast :: sendLogin ( void ) throw ( Exception ) { Sink * sink = getSink(); Source * source = getSocket(); const char * str; char resp[STRBUF_SIZE]; unsigned int len; if ( !source->isOpen() ) { return false; } if ( !sink->isOpen() ) { return false; } /* send the request, a string like: * "SOURCE <password> /<mountpoint>\n" */ str = "SOURCE "; sink->write( str, strlen( str)); str = getPassword(); sink->write( str, strlen( str)); str = " /"; sink->write( str, strlen( str)); str = getMountPoint(); sink->write( str, strlen( str)); /* send the x-audiocast headers */ str = "\nx-audiocast-bitrate: "; sink->write( str, strlen( str)); if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) { throw Exception( __FILE__, __LINE__, "bitrate does not fit string buffer", getBitRate()); } sprintf( resp, "%d", getBitRate()); sink->write( resp, strlen( resp)); str = "\nx-audiocast-public: "; sink->write( str, strlen( str)); str = getIsPublic() ? "1" : "0"; sink->write( str, strlen( str)); if ( getName() ) { str = "\nx-audiocast-name: "; sink->write( str, strlen( str)); str = getName(); sink->write( str, strlen( str)); } if ( getDescription() ) { str = "\nx-audiocast-description: "; sink->write( str, strlen( str)); str = getDescription(); sink->write( str, strlen( str)); } if ( getUrl() ) { str = "\nx-audiocast-url: "; sink->write( str, strlen( str)); str = getUrl(); sink->write( str, strlen( str)); } if ( getGenre() ) { str = "\nx-audiocast-genre: "; sink->write( str, strlen( str)); str = getGenre(); sink->write( str, strlen( str)); } if ( getRemoteDumpFile() ) { str = "\nx-audiocast-dumpfile: "; sink->write( str, strlen( str)); str = getRemoteDumpFile(); sink->write( str, strlen( str)); } str = "\n\n"; sink->write( str, strlen( str)); sink->flush(); /* read the anticipated response: "OK" */ len = source->read( resp, STRBUF_SIZE); if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { return false; } /* suck anything that the other side has to say */ while ( source->canRead( 0, 0) && (len = source->read( resp, STRBUF_SIZE)) ) { ; } return true; }
/*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ bool FaacEncoder :: open ( void ) throw ( Exception ) { if ( isOpen() ) { close(); } // open the underlying sink if ( !getSink()->open() ) { throw Exception( __FILE__, __LINE__, "faac lib opening underlying sink error"); } char * faacVersion; char * faacCopyright; faacEncGetVersion(&faacVersion, &faacCopyright); reportEvent(1, "Using faac codec version", faacVersion); encoderHandle = faacEncOpen(getOutSampleRate(), getInChannel(), &inputSamples, &maxOutputBytes); faacEncConfiguration * faacConfig; faacConfig = faacEncGetCurrentConfiguration(encoderHandle); faacConfig->aacObjectType = MAIN; faacConfig->mpegVersion = MPEG2; faacConfig->useTns = 1; faacConfig->shortctl = SHORTCTL_NORMAL; faacConfig->useLfe = 0; faacConfig->allowMidside = 1; faacConfig->bitRate = getOutBitrate() * 1000 / getOutChannel(); faacConfig->bandWidth = lowpass; faacConfig->quantqual = (unsigned long) (getOutQuality() * 1000.0); faacConfig->outputFormat = 1; faacConfig->inputFormat = FAAC_INPUT_16BIT; if (!faacEncSetConfiguration(encoderHandle, faacConfig)) { throw Exception(__FILE__, __LINE__, "error configuring faac library"); } // initialize the resampling coverter if needed if ( converter ) { #ifdef HAVE_SRC_LIB converterData.input_frames = 4096/((getInBitsPerSample() / 8) * getInChannel()); converterData.data_in = new float[converterData.input_frames*getInChannel()]; converterData.output_frames = (int) (converterData.input_frames * resampleRatio + 1); if ((int) inputSamples > getInChannel() * converterData.output_frames) { resampledOffset = new float[2 * inputSamples]; } else { resampledOffset = new float[2 * getInChannel() * converterData.input_frames]; } converterData.src_ratio = resampleRatio; converterData.end_of_input = 0; #else converter->initialize( resampleRatio, getInChannel()); //needed 2x(converted input samples) to handle offsets int outCount = 2 * getInChannel() * (inputSamples + 1); if (resampleRatio > 1) outCount = (int) (outCount * resampleRatio); resampledOffset = new short int[outCount]; #endif resampledOffsetSize = 0; } faacOpen = true; return true; }
/*------------------------------------------------------------------------------ * Log in to the ShoutCast server using the icy login scheme *----------------------------------------------------------------------------*/ bool ShoutCast :: sendLogin ( void ) throw ( Exception ) { Sink * sink = getSink(); Source * source = getSocket(); const char * str; char resp[STRBUF_SIZE]; unsigned int len; if ( !source->isOpen() ) { return false; } if ( !sink->isOpen() ) { return false; } /* first line is the password in itself */ str = getPassword(); sink->write( str, strlen( str)); str = "\n"; sink->write( str, strlen( str)); sink->flush(); /* read the anticipated response: "OK" */ len = source->read( resp, STRBUF_SIZE); reportEvent(8, "server response length: ", len); reportEvent(8, "server response: ", resp); if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { return false; } /* suck anything that the other side has to say */ while ( source->canRead( 0, 0) && (len = source->read( resp, STRBUF_SIZE)) ) { ; } /* send the icy headers */ if ( getName() ) { str = "icy-name:"; sink->write( str, strlen( str)); str = getName(); sink->write( str, strlen( str)); } if ( getGenre() ) { str = "\nicy-genre:"; sink->write( str, strlen( str)); str = getGenre(); sink->write( str, strlen( str)); } str = "\nicy-pub:"; sink->write( str, strlen( str)); str = getIsPublic() ? "1" : "0"; sink->write( str, strlen( str)); str = "\nicy-br:"; sink->write( str, strlen( str)); if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) { throw Exception( __FILE__, __LINE__, "bitrate does not fit string buffer", getBitRate()); } sprintf( resp, "%d", getBitRate()); sink->write( resp, strlen( resp)); if ( getUrl() ) { str = "\nicy-url:"; sink->write( str, strlen( str)); str = getUrl(); sink->write( str, strlen( str)); } if ( getIrc() ) { str = "\nicy-irc:"; sink->write( str, strlen( str)); str = getIrc(); sink->write( str, strlen( str)); } if ( getIcq() ) { str = "\nicy-icq:"; sink->write( str, strlen( str)); str = getIcq(); sink->write( str, strlen( str)); } if ( getAim() ) { str = "\nicy-aim:"; sink->write( str, strlen( str)); str = getAim(); sink->write( str, strlen( str)); } str = "\n\n"; sink->write( str, strlen( str)); sink->flush(); /* suck anything that the other side has to say */ len = source->read( resp, STRBUF_SIZE); reportEvent(8, "server response length: ", len); reportEvent(8, "server response: ", resp); while ( source->canRead( 0, 0) && (len = source->read( resp, STRBUF_SIZE)) ) { ; } return true; }
/*------------------------------------------------------------------------------ * Log in to the IceCast2 server *----------------------------------------------------------------------------*/ bool IceCast2 :: sendLogin ( void ) throw ( Exception ) { Sink * sink = getSink(); Source * source = getSocket(); const char * str; char resp[STRBUF_SIZE]; unsigned int len; unsigned int lenExpected; if ( !source->isOpen() ) { return false; } if ( !sink->isOpen() ) { return false; } // send the request, a string like: // "SOURCE <mountpoint> ICE/1.0" str = "SOURCE /"; sink->write( str, strlen( str)); str = getMountPoint(); sink->write( str, strlen( str)); str = " HTTP/1.0"; sink->write( str, strlen( str)); // send the content type, Ogg Vorbis str = "\nContent-type: "; sink->write( str, strlen( str)); switch ( format ) { case mp3: str = "audio/mpeg"; break; case oggVorbis: str = "application/x-ogg"; break; default: throw Exception( __FILE__, __LINE__, "unsupported stream format", format); break; } sink->write( str, strlen( str)); // send the authentication info str = "\nAuthorization: Basic "; sink->write( str, strlen(str)); { // send source:<password> encoded as base64 char * source = "source:"; const char * pwd = getPassword(); char * tmp = new char[Util::strLen(source) + Util::strLen(pwd) + 1]; Util::strCpy( tmp, source); Util::strCat( tmp, pwd); char * base64 = Util::base64Encode( tmp); delete[] tmp; sink->write( base64, strlen(base64)); delete[] base64; } // send user agent info str = "\nUser-Agent: DarkIce/" VERSION " (http://darkice.sourceforge.net/)"; sink->write( str, strlen( str)); // send the ice- headers str = "\nice-bitrate: "; sink->write( str, strlen( str)); if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) { throw Exception( __FILE__, __LINE__, "bitrate does not fit string buffer", getBitRate()); } sprintf( resp, "%d", getBitRate()); sink->write( resp, strlen( resp)); str = "\nice-public: "; sink->write( str, strlen( str)); str = getIsPublic() ? "1" : "0"; sink->write( str, strlen( str)); if ( getName() ) { str = "\nice-name: "; sink->write( str, strlen( str)); str = getName(); sink->write( str, strlen( str)); } if ( getDescription() ) { str = "\nice-description: "; sink->write( str, strlen( str)); str = getDescription(); sink->write( str, strlen( str)); } if ( getUrl() ) { str = "\nice-url: "; sink->write( str, strlen( str)); str = getUrl(); sink->write( str, strlen( str)); } if ( getGenre() ) { str = "\nice-genre: "; sink->write( str, strlen( str)); str = getGenre(); sink->write( str, strlen( str)); } str = "\n\n"; sink->write( str, strlen( str)); sink->flush(); // read the response, expected response begins with responseOK lenExpected = Util::strLen( responseOK); if ( (len = source->read( resp, STRBUF_SIZE-1)) < lenExpected ) { return false; } resp[lenExpected] = 0; if ( !Util::strEq( resp, responseOK) ) { return false; } // suck anything that the other side has to say while ( source->canRead( 0, 0) && (len = source->read( resp, STRBUF_SIZE-1)) ); return true; }
/*------------------------------------------------------------------------------ * Log in to the ShoutCast server using the icy login scheme *----------------------------------------------------------------------------*/ bool ShoutCast :: sendLogin ( void ) throw ( Exception ) { Sink * sink = getSink(); Source * source = getSocket(); const char * str; char resp[STRBUF_SIZE]; unsigned int len; bool needsMountPoint = false; const char * mountPoint = getMountPoint(); if ( !source->isOpen() ) { return false; } if ( !sink->isOpen() ) { return false; } // We will add SOURCE only if really needed: if the mountPoint is not null // and is different of "/". This is to keep maximum compatibility with // NullSoft Shoutcast server. if (mountPoint != 0L && strlen(mountPoint) > 0 && 0 != strcmp("/", mountPoint)) { needsMountPoint = true; } std::ostringstream os; if (needsMountPoint) { os << "SOURCE "; } /* first line is the password in itself */ os << getPassword(); os << "\n"; // send the mount point if (needsMountPoint) { os << " "; if (strncmp("/", mountPoint, 1) != 0) { os << "/"; } os << mountPoint; os << "\n"; } str = os.str().c_str(); // Ok, now we send login which will be different of classical Shoutcast // if mountPoint is not null and is different from "/" ... sink->write( str, strlen( str)); sink->flush(); /* read the anticipated response: "OK" */ len = source->read( resp, STRBUF_SIZE); reportEvent(8, "server response length: ", len); reportEvent(8, "server response: ", resp); if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { return false; } /* suck anything that the other side has to say */ while ( source->canRead( 0, 0) && (len = source->read( resp, STRBUF_SIZE)) ) { ; } /* send the icy headers */ if ( getName() ) { str = "icy-name:"; sink->write( str, strlen( str)); str = getName(); sink->write( str, strlen( str)); } if ( getUrl() ) { str = "\nicy-url:"; sink->write( str, strlen( str)); str = getUrl(); sink->write( str, strlen( str)); } if ( getGenre() ) { str = "\nicy-genre:"; sink->write( str, strlen( str)); str = getGenre(); sink->write( str, strlen( str)); } if ( getIrc() ) { str = "\nicy-irc:"; sink->write( str, strlen( str)); str = getIrc(); sink->write( str, strlen( str)); } if ( getAim() ) { str = "\nicy-aim:"; sink->write( str, strlen( str)); str = getAim(); sink->write( str, strlen( str)); } if ( getIcq() ) { str = "\nicy-icq:"; sink->write( str, strlen( str)); str = getIcq(); sink->write( str, strlen( str)); } str = "\nicy-br:"; sink->write( str, strlen( str)); if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) { throw Exception( __FILE__, __LINE__, "bitrate does not fit string buffer", getBitRate()); } sprintf( resp, "%d", getBitRate()); sink->write( resp, strlen( resp)); str = "\nicy-pub:"; sink->write( str, strlen( str)); str = getIsPublic() ? "1" : "0"; sink->write( str, strlen( str)); str = "\n\n"; sink->write( str, strlen( str)); sink->flush(); return true; }