bool BitmapData::initWithData(const unsigned char *data, ssize_t size) { Format imgType = checkImageFormat(data, size); bool result = false; switch (imgType) { case Format::PNG: result = initWithPNGData(data, size); break; case Format::JPG: result = initWithJPGData(data, size); break; default: result = false; break; } return result; }
void VideoWriter_ufmf::addFrame(StampedImage stampedImg) { bool skipFrame = false; bool haveNewMedianImage = false; currentImage_ = stampedImg; // On first call - setup output file, background modeling, start compressors, ... if (isFirst_) { checkImageFormat(stampedImg); // Set output file and write header setupOutputFile(stampedImg); writeHeader(); // Set initial bg median image - just use current image. bgMedianImage_ = stampedImg.image; bgMembershipImage_.create(stampedImg.image.rows, stampedImg.image.cols,CV_8UC1); cv::add(bgMedianImage_, backgroundThreshold_, bgUpperBoundImage_); cv::subtract(bgMedianImage_, backgroundThreshold_, bgLowerBoundImage_); // Start background model and frame compressors startBackgroundModeling(); startCompressors(); writeKeyFrame(); isFirst_ = false; } // Process frames or skip if (frameCount_%frameSkip_==0) { // Add frame to background image queue if it is empty bgImageQueuePtr_ -> acquireLock(); if (bgImageQueuePtr_ -> empty()) { bgImageQueuePtr_ -> push(stampedImg); bgImageQueuePtr_ -> signalNotEmpty(); } bgImageQueuePtr_ -> releaseLock(); // Get median image if available medianMatQueuePtr_ -> acquireLock(); if (!(medianMatQueuePtr_ -> empty())) { bgMedianImage_ = medianMatQueuePtr_ -> front(); medianMatQueuePtr_ -> pop(); haveNewMedianImage = true; } medianMatQueuePtr_ -> releaseLock(); // When new median image available re-calculate thresholds if (haveNewMedianImage) { cv::add(bgMedianImage_, backgroundThreshold_, bgUpperBoundImage_); cv::subtract(bgMedianImage_, backgroundThreshold_, bgLowerBoundImage_); bgUpdateCount_++; bgModelTimeStamp_ = currentImage_.timeStamp; bgModelFrameCount_ = currentImage_.frameCount; writeKeyFrame(); } // Create compressed frame and set its data using the current frame CompressedFrame_ufmf compressedFrame(boxLength_); compressedFrame.dilateEnabled(dilateState_); compressedFrame.setDilateWindowSize(dilateWindowSize_); if (!(framesWaitQueuePtr_ -> empty())) { // Take pre-allocated compressed frame if available compressedFrame = framesWaitQueuePtr_ -> front(); framesWaitQueuePtr_ -> pop(); } compressedFrame.setData( currentImage_, bgLowerBoundImage_, bgUpperBoundImage_, bgUpdateCount_ ); framesToDoQueuePtr_ -> acquireLock(); unsigned int framesToDoQueueSize = framesToDoQueuePtr_ -> size(); if (framesToDoQueueSize < FRAMES_TODO_MAX_QUEUE_SIZE) { // Insert new (uncalculated) compressed frame into "to do" queue. framesToDoQueuePtr_ -> push(compressedFrame); framesToDoQueuePtr_ -> wakeOne(); } else { skipFrame = true; } framesToDoQueuePtr_ -> releaseLock(); if (skipFrame) { // Queue is full - skip frame framesSkippedIndexListPtr_ -> acquireLock(); framesSkippedIndexListPtr_ -> push_back(stampedImg.frameCount); framesSkippedIndexListPtr_ -> releaseLock(); skipReported_ = true; } } // if (frameCount_%frameSkip_==0) // Remove frames from compressed frames "finished" set and write to disk //framesFinishedSetSize = clearFinishedFrames(); clearFinishedFrames(); frameCount_++; // Cull framesWaitQueue if it starts to grow too large unsigned int framesWaitQueueSize = framesWaitQueuePtr_ -> size(); if ( framesWaitQueueSize > FRAMES_WAIT_MAX_QUEUE_SIZE ) { unsigned int numToCull = framesWaitQueueSize - FRAMES_WAIT_MAX_QUEUE_SIZE/2; for (unsigned int i=0; i<numToCull; i++) { framesWaitQueuePtr_ -> pop(); } } // Report skipped frame if ((skipFrame) && (!skipReported_)) { std::cout << "warning: logging overflow - skipped frame -" << std::endl; unsigned int errorId = ERROR_FRAMES_TODO_MAX_QUEUE_SIZE; QString errorMsg("logger framesToDoQueue has exceeded the maximum allowed size"); emit imageLoggingError(errorId, errorMsg); skipReported_ = true; } }