/** * @brief * * @return */ int HttpStream::run() { Select select( 60 ); select.addWriter( mConnection->socket() ); if ( !waitForProviders() ) return( 1 ); while ( !mStop && select.wait() >= 0 ) { if ( mStop ) break; Select::CommsList writeable = select.getWriteable(); if ( writeable.size() <= 0 ) { Error( "Writer timed out" ); mStop = true; break; } mQueueMutex.lock(); if ( !mFrameQueue.empty() ) { for ( FrameQueue::iterator iter = mFrameQueue.begin(); iter != mFrameQueue.end(); iter++ ) { sendFrame( writeable, *iter ); //delete *iter; } mFrameQueue.clear(); } mQueueMutex.unlock(); usleep( INTERFRAME_TIMEOUT ); } return( 0 ); }
/** * @brief * * @return */ int QueuedVideoFilter::run() { if ( waitForProviders() ) { while ( !mStop ) { mQueueMutex.lock(); if ( !mFrameQueue.empty() ) { Debug( 3, "Got %zd frames on queue", mFrameQueue.size() ); for ( FrameQueue::iterator iter = mFrameQueue.begin(); iter != mFrameQueue.end(); iter++ ) { distributeFrame( *iter ); mFrameCount++; } mFrameQueue.clear(); } mQueueMutex.unlock(); checkProviders(); // Quite short so we can always keep up with the required packet rate for 25/30 fps usleep( INTERFRAME_TIMEOUT ); } } FeedProvider::cleanup(); FeedConsumer::cleanup(); return( !ended() ); }
/** * @brief * * @return */ int FilterSwapUV::run() { if ( waitForProviders() ) { uint16_t inputWidth = videoProvider()->width(); uint16_t inputHeight = videoProvider()->height(); PixelFormat inputPixelFormat = videoProvider()->pixelFormat(); ByteBuffer tempBuffer; int yChannelSize = inputWidth*inputHeight; int uvChannelSize = yChannelSize/4; if ( inputPixelFormat != PIX_FMT_YUV420P ) Fatal( "Can't swap UV for pixel format %d", inputPixelFormat ); while ( !mStop ) { mQueueMutex.lock(); if ( !mFrameQueue.empty() ) { Debug( 3, "Got %zd frames on queue", mFrameQueue.size() ); for ( FrameQueue::iterator iter = mFrameQueue.begin(); iter != mFrameQueue.end(); iter++ ) { //const VideoFrame *frame = dynamic_cast<const VideoFrame *>(iter->get()); //FramePtr framePtr( *iter ); const FeedFrame *frame = (*iter).get(); Debug(1, "%s / Provider: %s, Source: %s, Frame: %p (%ju / %.3f) - %lu", cname(), frame->provider()->cidentity(), frame->originator()->cidentity(), frame, frame->id(), frame->age(), frame->buffer().size() ); //Image image( inputPixelFormat, inputWidth, inputHeight, frame->buffer().data() ); tempBuffer.size( frame->buffer().size() ); memcpy( tempBuffer.data(), frame->buffer().data(), yChannelSize ); memcpy( tempBuffer.data()+yChannelSize, frame->buffer().data()+yChannelSize+uvChannelSize, uvChannelSize); memcpy( tempBuffer.data()+yChannelSize+uvChannelSize, frame->buffer().data()+yChannelSize, uvChannelSize); VideoFrame *videoFrame = new VideoFrame( this, *iter, mFrameCount, frame->timestamp(), tempBuffer ); distributeFrame( FramePtr( videoFrame ) ); //delete *iter; mFrameCount++; } mFrameQueue.clear(); } mQueueMutex.unlock(); checkProviders(); // Quite short so we can always keep up with the required packet rate for 25/30 fps usleep( INTERFRAME_TIMEOUT ); } } FeedProvider::cleanup(); FeedConsumer::cleanup(); return( !ended() ); }
/** * @brief * * @return */ int ImageTimestamper::run() { if ( waitForProviders() ) { uint16_t inputWidth = videoProvider()->width(); uint16_t inputHeight = videoProvider()->height(); PixelFormat inputPixelFormat = videoProvider()->pixelFormat(); while ( !mStop ) { mQueueMutex.lock(); if ( !mFrameQueue.empty() ) { Debug( 3, "Got %zd frames on queue", mFrameQueue.size() ); for ( FrameQueue::iterator iter = mFrameQueue.begin(); iter != mFrameQueue.end(); iter++ ) { //const VideoFrame *frame = dynamic_cast<const VideoFrame *>(iter->get()); //FramePtr framePtr( *iter ); const FeedFrame *frame = (*iter).get(); Debug(1, "%s / Provider: %s, Source: %s, Frame: %p (%ju / %.3f) - %lu", cname(), frame->provider()->cidentity(), frame->originator()->cidentity(), frame, frame->id(), frame->age(), frame->buffer().size() ); Image image( inputPixelFormat, inputWidth, inputHeight, frame->buffer().data() ); if ( timestampImage( &image, frame->timestamp() ) ) { VideoFrame *videoFrame = new VideoFrame( this, *iter, mFrameCount, frame->timestamp(), image.buffer() ); distributeFrame( FramePtr( videoFrame ) ); } else { distributeFrame( *iter ); } //delete *iter; mFrameCount++; } mFrameQueue.clear(); } mQueueMutex.unlock(); checkProviders(); // Quite short so we can always keep up with the required packet rate for 25/30 fps usleep( INTERFRAME_TIMEOUT ); } } FeedProvider::cleanup(); FeedConsumer::cleanup(); return( !ended() ); }
/** * @brief * * @return */ int LocalFileDump::run() { std::string filePath; FILE *fileDesc = NULL; if ( waitForProviders() ) { while( !mStop ) { mQueueMutex.lock(); if ( !mFrameQueue.empty() ) { for ( FrameQueue::iterator iter = mFrameQueue.begin(); iter != mFrameQueue.end(); iter++ ) { const FeedFrame *frame = iter->get(); Info( "F:%ld", frame->buffer().size() ); if ( filePath.empty() ) { filePath = stringtf( "%s/%s-%s", mLocation.c_str(), mName.c_str(), frame->provider()->cidentity() ); Info( "Path: %s", filePath.c_str() ); fileDesc = fopen( filePath.c_str(), "w" ); if ( !fileDesc ) Fatal( "Failed to open dump file '%s': %s", filePath.c_str(), strerror(errno) ); } if ( fwrite( frame->buffer().data(), frame->buffer().size(), 1, fileDesc ) <= 0 ) Fatal( "Failed to write to dump file '%s': %s", filePath.c_str(), strerror(errno) ); //delete *iter; } mFrameQueue.clear(); } mQueueMutex.unlock(); checkProviders(); usleep( INTERFRAME_TIMEOUT ); } fclose( fileDesc ); } cleanup(); return( 0 ); }
int NotifyOutput::run() { if ( waitForProviders() ) { while( !mStop ) { mQueueMutex.lock(); if ( !mFrameQueue.empty() ) { for ( FrameQueue::iterator iter = mFrameQueue.begin(); iter != mFrameQueue.end(); iter++ ) { processFrame( *iter ); } mFrameQueue.clear(); } mQueueMutex.unlock(); checkProviders(); usleep( INTERFRAME_TIMEOUT ); } } cleanup(); return( 0 ); }
/** * @brief * * @return */ int ImageScale::run() { AVFrame *inputFrame = av_frame_alloc(); AVFrame *outputFrame = av_frame_alloc(); if ( waitForProviders() ) { uint16_t inputWidth = videoProvider()->width(); uint16_t inputHeight = videoProvider()->height(); PixelFormat pixelFormat = videoProvider()->pixelFormat(); mWidth = inputWidth * mScale; mHeight = inputHeight * mScale; // Prepare for image format and size conversions mScaleContext = sws_getContext( inputWidth, inputHeight, pixelFormat, mWidth, mHeight, pixelFormat, SWS_BILINEAR, NULL, NULL, NULL ); if ( !mScaleContext ) Fatal( "Unable to create scale context" ); Debug( 1,"Scaling from %d x %d -> %d x %d", inputWidth, inputHeight, mWidth, mHeight ); Debug( 1,"%d bytes -> %d bytes", avpicture_get_size( pixelFormat, inputWidth, inputHeight ), avpicture_get_size( pixelFormat, mWidth, mHeight ) ); // Make space for anything that is going to be output ByteBuffer outputBuffer; outputBuffer.size( avpicture_get_size( pixelFormat, mWidth, mHeight ) ); // To get offsets only avpicture_fill( (AVPicture *)outputFrame, outputBuffer.data(), pixelFormat, mWidth, mHeight ); while ( !mStop ) { mQueueMutex.lock(); if ( !mFrameQueue.empty() ) { Debug( 3, "Got %zd frames on queue", mFrameQueue.size() ); for ( FrameQueue::iterator iter = mFrameQueue.begin(); iter != mFrameQueue.end(); iter++ ) { //const VideoFrame *frame = dynamic_cast<const VideoFrame *>(iter->get()); //FramePtr framePtr( *iter ); const FeedFrame *frame = (*iter).get(); if ( mWidth != inputWidth || mHeight != inputHeight ) { // Requires conversion Debug( 1,"%s / Provider: %s, Source: %s, Frame: %p (%ju / %.3f) - %lu", cname(), frame->provider()->cidentity(), frame->originator()->cidentity(), frame, frame->id(), frame->age(), frame->buffer().size() ); avpicture_fill( (AVPicture *)inputFrame, frame->buffer().data(), pixelFormat, inputWidth, inputHeight ); // Reformat the input frame to fit the desired output format if ( sws_scale( mScaleContext, inputFrame->data, inputFrame->linesize, 0, inputHeight, outputFrame->data, outputFrame->linesize ) < 0 ) Fatal( "Unable to convert input frame (%dx%d) to output frame (%dx%d) at frame %ju", inputWidth, inputHeight, mWidth, mHeight, mFrameCount ); VideoFrame *videoFrame = new VideoFrame( this, *iter, mFrameCount, frame->timestamp(), outputBuffer ); distributeFrame( FramePtr( videoFrame ) ); } else { // Send it out 'as is' distributeFrame( *iter ); } //delete *iter; mFrameCount++; } mFrameQueue.clear(); } mQueueMutex.unlock(); checkProviders(); // Quite short so we can always keep up with the required packet rate for 25/30 fps usleep( INTERFRAME_TIMEOUT ); } FeedProvider::cleanup(); FeedConsumer::cleanup(); sws_freeContext( mScaleContext ); mScaleContext = NULL; } av_free( outputFrame ); av_free( inputFrame ); return( !ended() ); }