BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
362c1f4
Branches
Tags
master
Blinker
src
common
EtherPix.cpp
update copyright header
Stefan Schuermans
commited
362c1f4
at 2019-05-04 17:17:10
EtherPix.cpp
Blame
History
Raw
/* Blinker Copyright 2011-2019 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <stdlib.h> #include <string> #include <string.h> #include <BlinkenLib/BlinkenFrame.h> #include <BlinkenLib/BlinkenProto.h> #ifdef BLINKER_CFG_ETHERPIX extern "C" { #include <etherpix/etherpix.h> } // extern "C" #endif // #ifdef BLINKER_CFG_ETHERPIX #include "Directory.h" #include "File.h" #include "EtherPix.h" #include "InStreamFile.h" #include "Mgrs.h" #include "Module.h" #include "Size.h" #include "StreamRecv.h" #include "Time.h" #include "TimeCallee.h" namespace Blinker { /** * @brief constructor * @param[in] name module name * @param[in] mgrs managers * @param[in] dirBase base directory */ EtherPix::EtherPix(const std::string &name, Mgrs &mgrs, const Directory &dirBase): Module(name, mgrs, dirBase), m_fileInStream(dirBase.getFile("instream"), mgrs.m_streamMgr), m_fileConfig(dirBase.getFile("etherpix.etp")), m_pDisplay(NULL) { // set up m_fileInStream.setStreamRecv(this); createDisplay(); } /// virtual destructor EtherPix::~EtherPix() { // clean up destroyDisplay(); m_fileInStream.setStreamRecv(NULL); m_mgrs.m_callMgr.cancelTimeCall(this); } /// check for update of configuration void EtherPix::updateConfig() { // input stream name file was modified -> re-get input stream if (m_fileInStream.checkModified()) m_fileInStream.update(); // EtherPix config file was modified -> re-create display if (m_fileConfig.checkModified()) createDisplay(); } /** * @brief set current frame * @param[in] stream stream name * @param[in] pFrame current frame (NULL for none) */ void EtherPix::setFrame(const std::string &stream, stBlinkenFrame *pFrame) { displayFrame(pFrame); (void)stream; // unused } /// callback when requested time reached void EtherPix::timeCall() { // refresh frame sendFrame(); } /// (re-)create EtherPix display void EtherPix::createDisplay() { #ifdef BLINKER_CFG_ETHERPIX destroyDisplay(); // create a display m_pDisplay = etp_display_create(m_fileConfig.getPath().c_str(), NULL, NULL); if (!m_pDisplay) return; // get size of display etp_display_get_size(m_pDisplay, &m_size.m_width, &m_size.m_height); // output current frame displayFrame(m_fileInStream.getCurFrame()); #endif // #ifdef BLINKER_CFG_ETHERPIX } /// destroy EtherPix display void EtherPix::destroyDisplay() { #ifdef BLINKER_CFG_ETHERPIX if (m_pDisplay) { etp_display_free(m_pDisplay); m_pDisplay = NULL; } #endif // #ifdef BLINKER_CFG_ETHERPIX } /** * @brief display frame on EtherPix * @param[in] pFrame frame to display (or NULL) */ void EtherPix::displayFrame(stBlinkenFrame *pFrame) { #ifdef BLINKER_CFG_ETHERPIX char data[65536]; bool haveData = false; etp_pixfmt_t pixfmt; stBlinkenFrame *pClonedFrame; int frameWidth, frameHeight, frameChannels, frameMaxval, channels; // leave if no display if (!m_pDisplay) return; // convert frame to needed size and then to MCUF data as EtherPix library // can read data section of MCUF packet // frame available if (pFrame) { frameWidth = BlinkenFrameGetWidth(pFrame); frameHeight = BlinkenFrameGetHeight(pFrame); frameChannels = BlinkenFrameGetChannels(pFrame); frameMaxval = BlinkenFrameGetMaxval(pFrame); // format matches // (size matches and 24bit RGB or monochrome as required by EtherPix) if (frameWidth == (int)m_size.m_width && frameHeight == (int)m_size.m_height && (frameChannels == 1 || frameChannels == 3) && frameMaxval == 255) { // convert to MCUF packet haveData = BlinkenFrameToNetwork(pFrame, BlinkenProtoMcuf, data, sizeof(data)) >= 0; channels = frameChannels; } // format does not match else { // convert format: clone and resize pClonedFrame = BlinkenFrameClone(pFrame); if (pClonedFrame) { channels = frameChannels == 1 ? 1 : 3; BlinkenFrameResize(pClonedFrame, m_size.m_height, m_size.m_width, channels, 255); // convert to MCUF packet haveData = BlinkenFrameToNetwork(pClonedFrame, BlinkenProtoMcuf, data, sizeof(data)) >= 0; // free cloned frame BlinkenFrameFree(pClonedFrame); } } } // data available -> to EtherPix display if (haveData) { pixfmt = channels == 1 ? etp_pixfmt_mono8 : etp_pixfmt_rgb24; etp_display_data_fmt(m_pDisplay, (etp_u8_t*)(data + 12), channels, m_size.m_width * channels, 0, 0, m_size.m_width, m_size.m_height, pixfmt); // no data available -> clear EtherPix display } else { etp_display_data_clear(m_pDisplay); } // send configured frame sendFrame(); #else // #ifdef BLINKER_CFG_ETHERPIX (void)pFrame; #endif // #ifdef BLINKER_CFG_ETHERPIX else } /// (re-)send frame to EtherPix void EtherPix::sendFrame() { #ifdef BLINKER_CFG_ETHERPIX if (m_pDisplay) { etp_display_send(m_pDisplay); m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + Time(1)); // refresh } #endif // #ifdef BLINKER_CFG_ETHERPIX } } // namespace Blinker