#include "writer.h" #include #include #include using namespace std::chrono; void Writer::setVideoSpecs(VideoSpecs specs) { videoSpecs = specs; specs_valid = true; } void Writer::setProjectMetadata(ProjectMetadata mdata) { qDebug() << "received metadata"; metadata = mdata; metadata_valid = true; } void Writer::writeMetadata(nix::Section &s){ s.createProperty("project", nix::Value(this->metadata.project().toStdString())); s.createProperty("experimenter", nix::Value(this->metadata.experimenter().toStdString())); s.createProperty("experiment", nix::Value(this->metadata.experiment().toStdString())); s.createProperty("condition", nix::Value(this->metadata.condition().toStdString())); s.createProperty("comment", nix::Value(this->metadata.comment().toStdString())); s.createProperty("subject", nix::Value(this->metadata.subject().toStdString())); s.createProperty("setup", nix::Value(this->metadata.setup().toStdString())); } void Writer::run() { size_t count = 0; size_t chunksize = 256; // size_t framecount = 0; std::ofstream myFile; if (videoSpecs.format == VideoFormat::mp4 && !Pylon::CVideoWriter::IsSupported()) { qWarning() << "VideoWriter is not supported at the moment. Please install the pylon Supplementary Package for MPEG-4 which is available on the Basler website."; // Releases all pylon resources. // PylonTerminate(); // Return with error code 1. emit writingDone(this->cam_number); return; } Pylon::CVideoWriter videoWriter; if (specs_valid) { stop_request = false; stopNow = false; if (videoSpecs.format == VideoFormat::raw) { myFile.open(videoSpecs.filename, std::ios::out | std::ios::binary); myFile.write((char*)&videoSpecs.width, 4); myFile.write((char*)&videoSpecs.height, 4); } else { videoWriter.SetParameter(videoSpecs.width, videoSpecs.height, videoSpecs.pixelType, videoSpecs.fps, videoSpecs.quality); videoWriter.Open(videoSpecs.filename.c_str()); } nix::File nix_file =nix::File::open(videoSpecs.filename + ".nix", nix::FileMode::Overwrite, "hdf5", nix::Compression::DeflateNormal); nix::Block b = nix_file.createBlock("Recording", "nix.recording"); nix::Section s = nix_file.createSection("Recording", "nix.recording"); b.metadata(s); nix::Value v(nix::util::timeToStr(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()))); s.createProperty("date", v); nix::Value fn(videoSpecs.filename); s.createProperty("moviefile", fn); nix::Section sw_sec = s.createSection("PylonRecorder", "nix.software"); sw_sec.createProperty("version", nix::Value(1)); nix::Section hw_sec = s.createSection("Basler ACA2040-120um", "nix.hardware.camera"); hw_sec.createProperty("type", nix::Value("monochrome")); hw_sec.createProperty("manufacturer", nix::Value("Basler AG")); nix::Property p = hw_sec.createProperty("framerate", nix::Value(static_cast(videoSpecs.fps))); p.unit("Hz"); nix::Property p1 = hw_sec.createProperty("exposure time", nix::Value(static_cast(videoSpecs.exposureTime))); p1.unit("us"); nix::Property p2 = hw_sec.createProperty("detector gain", nix::Value(static_cast(videoSpecs.detectorGain))); p2.unit("dB"); if (metadata_valid) { writeMetadata(s); } nix::NDSize initial_shape(1, chunksize); nix::DataArray frametimes = b.createDataArray("frametimes", "nix.imaging.frametimes", nix::DataType::String, initial_shape); frametimes.label("time"); frametimes.appendSetDimension(); nix::DataArray frameindices = b.createDataArray("frameindex", "nix.imaging.frameid", nix::DataType::Int64, initial_shape); frameindices.appendSetDimension(); std::vector stamps_buffer(chunksize); std::vector ids_buffer(chunksize); nix::NDSize offset(1, 0); nix::NDSize current_shape(initial_shape); nix::NDSize chunk_shape(1, chunksize); while ((!stop_request || buffer->bufferLoad() > 0) && !stopNow) { if (buffer->bufferLoad() > 0 ) { size_t framecount = 0; MyImage *img = buffer->read(framecount); if (img != nullptr) { if (videoSpecs.format == VideoFormat::raw) { myFile.write((char*)img->data(), img->size()); } else { Pylon::CPylonImage pyImage; try { pyImage.AttachUserBuffer(img->data(), videoSpecs.width * videoSpecs.height, videoSpecs.pixelType, videoSpecs.width, videoSpecs.height, 0, videoSpecs.orientation); videoWriter.Add(pyImage); } catch (const Pylon::GenericException &e) { std::cerr << "Writer::run: An exception occurred." << std::endl << e.GetDescription() << std::endl; } } if (count < chunksize) { stamps_buffer[count] = nix::util::timeToStr(img->timestamp()); ids_buffer[count] = img->index(); count ++; } else { frametimes.setData(nix::DataType::String, stamps_buffer.data(), chunk_shape, offset); frameindices.setData(nix::DataType::Int64, ids_buffer.data(), chunk_shape, offset); current_shape += initial_shape; frametimes.dataExtent(current_shape); frameindices.dataExtent(current_shape); offset[0] += chunksize; count = 0; } } } else { while (buffer->bufferLoad() < 1 && !stop_request) { msleep(5); } } } if (count > 0) { chunk_shape[0] = count; frametimes.setData(nix::DataType::String, stamps_buffer.data(), chunk_shape, offset); frameindices.setData(nix::DataType::Int64, ids_buffer.data(), chunk_shape, offset); } // videoWriter.Close(); myFile.close(); nix_file.close(); } else { std::cerr << "Got no video specifications, not writing!" << std::endl; } emit writingDone(cam_number); }