/** * Test routine for the */ void TestCameraStreaming(CMMCore& core) { const long numFrames = 20; const int memoryFootprintMB = 100; const double intervalMs = 300.0; // ms core.setCircularBufferMemoryFootprint(memoryFootprintMB); cout << "Buffer capacity: " << core.getBufferTotalCapacity() << endl; string camera = core.getCameraDevice(); core.setExposure(200.0); // test normal mode core.snapImage(); core.getImage(); core.startSequenceAcquisition(numFrames, intervalMs, true); CDeviceUtils::SleepMs(5000); core.stopSequenceAcquisition(); int count=0; while (core.deviceBusy(camera.c_str())) { Metadata md; core.getLastImageMD(0, 0, md); double interval = core.getBufferIntervalMs(); printf("Displaying current image, %ld in que, %.0f ms interval.\n", core.getRemainingImageCount(), interval); MetadataSingleTag mdst = md.GetSingleTag(MM::g_Keyword_Elapsed_Time_ms); printf("Elapsed time %s, device %s\n", mdst.GetValue().c_str(), mdst.GetDevice().c_str()); } printf("Camera finished with %.0f ms interval.\n", core.getBufferIntervalMs()); core.setProperty(camera.c_str(), "ShutterMode", "Auto"); cout << "Done! Free space =" << core.getBufferFreeCapacity() << endl; core.startSequenceAcquisition(numFrames, intervalMs, true); count=0; while (core.deviceBusy(camera.c_str())) { Metadata md; core.getLastImageMD(0, 0, md); double interval = core.getBufferIntervalMs(); printf("Displaying current image, %ld in que, %.0f ms interval.\n", core.getRemainingImageCount(), interval); MetadataSingleTag mdst = md.GetSingleTag(MM::g_Keyword_Elapsed_Time_ms); printf("Elapsed time %s, device %s\n", mdst.GetValue().c_str(), mdst.GetDevice().c_str()); } printf("Camera finished with %.0f ms interval.\n", core.getBufferIntervalMs()); core.setProperty(camera.c_str(), "ShutterMode", "Auto"); }
/** * Inserts a multi-channel frame in the buffer. */ bool CircularBuffer::InsertMultiChannel(const unsigned char* pixArray, unsigned numChannels, unsigned width, unsigned height, unsigned byteDepth, const Metadata* pMd) throw (CMMError) { MMThreadGuard guard(g_insertLock); static unsigned long previousTicks = 0; bool notOverflowed; ImgBuffer* pImg; unsigned long singleChannelSize = (unsigned long)width * height * byteDepth; { MMThreadGuard guard(g_bufferLock); if (previousTicks > 0) estimatedIntervalMs_ = GetClockTicksMs() - previousTicks; else estimatedIntervalMs_ = 0; // check image dimensions if (width != width_ || height != height_ || byteDepth != pixDepth_) throw CMMError("Incompatible image dimensions in the circular buffer", MMERR_CircularBufferIncompatibleImage); notOverflowed = (long)frameArray_.size() - (insertIndex_ - saveIndex_) > 0; if (!notOverflowed) { // buffer overflow overflow_ = true; return false; } } for (unsigned i=0; i<numChannels; i++) { Metadata md; { MMThreadGuard guard(g_bufferLock); // check if the requested (channel, slice) combination exists // we assume that all buffers are pre-allocated pImg = frameArray_[insertIndex_ % frameArray_.size()].FindImage(i, 0); if (!pImg) return false; if (pMd) { // TODO: the same metadata is inserted for each channel ??? // Perhaps we need to add specific tags to each channel md = *pMd; } std::string cameraName = md.GetSingleTag("Camera").GetValue(); if (imageNumbers_.end() == imageNumbers_.find(cameraName)) { imageNumbers_[cameraName] = 0; } // insert image number. md.put(MM::g_Keyword_Metadata_ImageNumber, CDeviceUtils::ConvertToString(imageNumbers_[cameraName])); ++imageNumbers_[cameraName]; } if (!md.HasTag(MM::g_Keyword_Elapsed_Time_ms)) { // if time tag was not supplied by the camera insert current timestamp MM::MMTime timestamp = GetMMTimeNow(); md.PutImageTag(MM::g_Keyword_Elapsed_Time_ms, CDeviceUtils::ConvertToString(timestamp.getMsec())); } md.PutImageTag("Width",width); md.PutImageTag("Height",height); if (byteDepth == 1) md.PutImageTag("PixelType","GRAY8"); else if (byteDepth == 2) md.PutImageTag("PixelType","GRAY16"); else if (byteDepth == 4) md.PutImageTag("PixelType","RGB32"); else if (byteDepth == 8) md.PutImageTag("PixelType","RGB64"); else md.PutImageTag("PixelType","Unknown"); pImg->SetMetadata(md); pImg->SetPixels(pixArray + i*singleChannelSize); } { MMThreadGuard guard(g_bufferLock); imageCounter_++; insertIndex_++; if ((insertIndex_ - (long)frameArray_.size()) > adjustThreshold && (saveIndex_- (long)frameArray_.size()) > adjustThreshold) { // adjust buffer indices to avoid overflowing integer size insertIndex_ -= adjustThreshold; saveIndex_ -= adjustThreshold; } } previousTicks = GetClockTicksMs(); return true; }