void Server::incomingConnection(int socketDescriptor) { qDebug() << "Server: incoming connection"; QMutexLocker lock(&m_serverPropMutex); ServerConnection* connection = new ServerConnection(socketDescriptor, m_lossless, m_maxFramesInQueue, m_maxFramesInFlight); connection->setAcknowledgeNeeded(m_acknowledge); lock.unlock(); // let errors go through the error reporting signal of this class connect( this, SIGNAL( onError(PlvErrorType,QString)), connection, SIGNAL(onError(PlvErrorType,QString))); // move the connection to its own thread QThreadEx* connectionThread = new QThreadEx(); connection->moveToThread(connectionThread); // when the connection is done it is scheduled for deletion connect( connection, SIGNAL(finished()), connection, SLOT(deleteLater())); // when the connection is done, it stops its thread connect( connection, SIGNAL(finished()), connectionThread, SLOT(quit())); // start the connection when its thread is started connect( connectionThread, SIGNAL(started()), connection, SLOT(start())); // inform server when this serverthead is waiting on the client connect( connection, SIGNAL( waitingOnClient(ServerConnection*,bool)), this, SLOT( serverThreadStalled(ServerConnection*,bool)) ); connect( parent(), SIGNAL( maxFramesInQueueChanged(int) ), connection, SLOT( setMaxFramesInQueue(int) ) ); //setMaxFrameInQueue &&maxFrameInQueueChanged added in TODO check connect( parent(), SIGNAL( maxFramesInFlightChanged(int) ), connection, SLOT( setMaxFramesInFlight(int)) ); connect( parent(), SIGNAL( losslessChanged(bool) ), connection, SLOT( setLossless(bool)) ); // stop this connection when stopAllConnections is called connect( this, SIGNAL(stopAllConnections()), connection, SLOT(stop())); // start the connection thread and its event loop connectionThread->start(); // connection receives all broadcasts and sends it to its connection connect( this, SIGNAL( broadcastFrame(quint32,QByteArray)), connection, SLOT( queueFrame(quint32,QByteArray))); }
//-------------------------------------------------------------------- void ofxVideoGrabberPvAPI::grabFrame(){ int ret; if( bGrabberInited ){ if( !bWaitingForFrame ) { bIsFrameNew = false; queueFrame(); } else { // check if queued capture frame is ready ret = PvCaptureWaitForFrameDone(cameraHandle, &cameraFrame, 5); if( ret == ePvErrTimeout ) { bIsFrameNew = false; } else if( ret == ePvErrSuccess ){ bIsFrameNew = true; if (bUseTexture){ tex.loadData((unsigned char*)cameraFrame.ImageBuffer, width, height, GL_LUMINANCE ); //GL_LUMINANCE8 } memcpy(pixels, cameraFrame.ImageBuffer, width*height); queueFrame(); } } } }
void Server::incomingConnection(int socketDescriptor) { qDebug() << "Server: incoming connection"; ServerConnection* connection = new ServerConnection(socketDescriptor); // let errors go through the error reporting signal of this class this->connect( connection, SIGNAL(errorOccurred(PipelineErrorType,QString)), SIGNAL(error(PipelineErrorType,QString))); // move the connection to its own thread QThreadEx* connectionThread = new QThreadEx(); connection->moveToThread(connectionThread); // when the connection is done it is scheduled for deletion connect( connection, SIGNAL(finished()), connection, SLOT(deleteLater())); // when the connection is done, it stops its thread connect( connection, SIGNAL(finished()), connectionThread, SLOT(quit())); // start the connection when its thread is started connect( connectionThread, SIGNAL(started()), connection, SLOT(start())); // inform server when this serverthead is waiting on the client connect( connection, SIGNAL( waitingOnClient(ServerConnection*,bool)), this, SLOT( serverThreadStalled(ServerConnection*,bool)) ); // stop this connection when stopAllConnections is called connect( this, SIGNAL(stopAllConnections()), connection, SLOT(stop())); // start the connection thread and its event loop connectionThread->start(); // connection receives all broadcasts and sends it to its connection connect( this, SIGNAL( broadcastFrame(quint32,QByteArray)), connection, SLOT( queueFrame(quint32,QByteArray))); }
// Thread entry point int StreamWAVFormatDecoder::run(void* pArgs) { int iSamplesInOutBuffer = 0; Sample partialFrame[80] ; int nSamplesPartialFrame = 0; int numOutSamples = 0; ssize_t iDataLength ; int nQueuedFrames = 0; //used if the files are aLaw or uLaw encodec InitG711Tables(); StreamDataSource* pSrc = getDataSource() ; if (pSrc != NULL) { ssize_t iRead = 0; char buf[16]; // "pre-read" 4 bytes, to see if this is a 0 length file and should // be skipped. Alas, apparently one cannot just call getLength() // as an http fetch might not have returned any info yet. if (pSrc->peek(buf, 4, iRead) != OS_SUCCESS) // empty file { // If one doesn't queue at least one frame, then it seems things stall // Queue one frame of a "click" to give some audible indication // a file was played (even if it was empty) Sample Click[80] = {0} ; // one frame of "click" to give audible // indication of some problem. Click[39] = -200 ; Click[40] = 20000 ; // An impulse should do nicely Click[41] = -200 ; queueFrame((const uint16_t*)Click); mbEnd = TRUE ; } while (!mbEnd && nextDataChunk(iDataLength)) { //we really want 80 SAMPLES not 80 bytes unsigned char InBuffer[NUM_SAMPLES*2] ; Sample OutBuffer[4000] = {0} ; //make room for lots of decompression iSamplesInOutBuffer = 0; while ((iDataLength > 0) && !mbEnd) { ssize_t iRead = 0; UtlBoolean retval = OS_INVALID; if (mFormatChunk.formatTag == 1 && mFormatChunk.nBitsPerSample == 8) //8bit unsigned { //we need to read 80 samples iRead = __min(iDataLength, NUM_SAMPLES); retval = pSrc->read((char *)InBuffer, iRead, iRead); //now convert to 16bit unsigned, which is what we use internally ConvertUnsigned8ToSigned16(InBuffer,OutBuffer,iRead); numOutSamples = iRead; } else if (mFormatChunk.formatTag == 1 && mFormatChunk.nBitsPerSample == 16) //16 bit signed { iRead = __min(iDataLength, NUM_SAMPLES*2); //just read in the data, because it's the format we need retval = pSrc->read((char *)OutBuffer, iRead, iRead); numOutSamples = iRead/2; #ifdef __BIG_ENDIAN__ if (retval == OS_SUCCESS) { //We are running on a big endian processor - 16-bit samples are //in the little endian byte order - convert them to big endian. unsigned short *pData = (unsigned short *)OutBuffer; for ( int index = 0; index < numOutSamples; index++, pData++ ) *pData = letohs(*pData); } #endif } else if (mFormatChunk.formatTag == 6 || mFormatChunk.formatTag == 7) //16 bit signed { //we need to read 80 samples iRead = __min(iDataLength, NUM_SAMPLES); retval = pSrc->read((char *)OutBuffer, iRead, iRead); //no conversion to 16bit will take place because we need to decompress this } else { syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::run Unsupport bit per sample rate!"); } iDataLength -= iRead; if (retval == OS_SUCCESS) { ssize_t bytes; switch (mFormatChunk.formatTag) { case 1: // PCM //NO CONVERSION NEEDED break ; case 6: // G711 alaw bytes = DecompressG711ALaw(OutBuffer, iRead); numOutSamples = iRead; break ; case 7: // G711 ulaw bytes = DecompressG711MuLaw(OutBuffer,iRead); numOutSamples = iRead; break ; } //we now should have a buffer filled with Samples, not bytes int numBytes = numOutSamples * sizeof(Sample); //next we check if the sound file is stereo...at this point in our lives //we only want to support mono //takes bytes in and gets bytes out. NOT samples if (mFormatChunk.nChannels > 1) { numBytes = mergeChannels((char *)OutBuffer, numBytes, mFormatChunk.nChannels); //now calculate how many sample we have numOutSamples = numBytes/sizeof(Sample); } //in the next fucntion we must pass bytes, NOT samples as second param numBytes = reSample((char *)OutBuffer, numBytes, mFormatChunk.nSamplesPerSec, DESIRED_SAMPLE_RATE); //now calculate how many sample we have numOutSamples = numBytes/sizeof(Sample); //this next part will buffer the samples if under 80 samples if (numOutSamples > 0) { int iCount = 0 ; while ((iCount < numOutSamples) && !mbEnd) { int iToCopy = numOutSamples - iCount ; if (iToCopy > 80) iToCopy = 80 ; if (nSamplesPartialFrame == 0) { if (iToCopy >= 80) { queueFrame((const uint16_t*)OutBuffer+iCount); nQueuedFrames++ ; } else { nSamplesPartialFrame = iToCopy ; memcpy(partialFrame, (const unsigned short *)OutBuffer+iCount,iToCopy*sizeof(Sample)) ; } } else { if (iToCopy > (80-nSamplesPartialFrame)) iToCopy = 80-nSamplesPartialFrame ; memcpy(&partialFrame[nSamplesPartialFrame],(const unsigned short *)OutBuffer+iCount, iToCopy*sizeof(Sample)) ; nSamplesPartialFrame += iToCopy ; if (nSamplesPartialFrame == 80) { queueFrame((const uint16_t*) partialFrame); nSamplesPartialFrame = 0 ; nQueuedFrames++ ; } } iCount += iToCopy ; } } } else { // Truncated data source? syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::run (FireEvent DecodingErrorEvent)"); fireEvent(DecodingErrorEvent) ; break ; } } } pSrc->close() ; } queueEndOfFrames() ; syslog(FAC_STREAMING, PRI_DEBUG, "StreamWAVFormatDecoder::run queued %d frames", nQueuedFrames); fireEvent(DecodingCompletedEvent) ; mSemExited.release() ; return 0 ; }