Skip to content

Commit

Permalink
DDP handles the type 0 (format is undefined and bits per pixel elemen…
Browse files Browse the repository at this point in the history
…t is undefined) like RGB with 8-bit per pixel element. That means full RGB with 24 bit per pixel.
  • Loading branch information
BlueAndi committed Nov 9, 2023
1 parent 49e4f72 commit 67d80c6
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 96 deletions.
33 changes: 25 additions & 8 deletions lib/DDPPlugin/src/DDPPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,29 +131,42 @@ void DDPPlugin::update(YAGfx& gfx)
* Private Methods
*****************************************************************************/

void DDPPlugin::onData(DDPServer::Format format, uint32_t offset, uint8_t bitsPerPixel, uint8_t* payload, uint16_t payloadSize, bool isFinal)
void DDPPlugin::onData(DDPServer::Format format, uint32_t offset, uint8_t bitsPerPixelElement, uint8_t* payload, uint16_t payloadSize, bool isFinal)
{
MutexGuard<Mutex> guard(m_mutex);

/* xlights <= v202301 sends FORMAT_UNDEFINED with 1-bit per pixel which is
* necessary to be interpreted as FORMAT_RGB with 24-bit per pixel.
/* xlights <= v202301 sends FORMAT_UNDEFINED with 1-bit per pixel element which is
* necessary to be interpreted as FORMAT_RGB with 8-bit per pixel element.
*/
if ((DDPServer::FORMAT_UNDEFINED == format) &&
(1U == bitsPerPixel))
(1U == bitsPerPixelElement))
{
/* Workaround! */
format = DDPServer::FORMAT_RGB;
bitsPerPixel = 24U;
format = DDPServer::FORMAT_RGB;
bitsPerPixelElement = 8U;
}
/* If the format is FORMAT_UNDEFINED and the bit per pixel element is undefined,
* we assume its 8-bit per pixel element.
*/
else if ((DDPServer::FORMAT_UNDEFINED == format) &&
(0U == bitsPerPixelElement))
{
format = DDPServer::FORMAT_RGB;
bitsPerPixelElement = 8U;
}
else
{
;
}

if ((nullptr != payload) &&
(DDPServer::FORMAT_RGB == format) &&
(24U == bitsPerPixel))
(8U == bitsPerPixelElement))
{
uint16_t srcIdx = 0U;
int16_t x = (offset % m_framebuffer.getWidth());
int16_t y = (offset / m_framebuffer.getWidth());
uint8_t bytePerPixel = bitsPerPixel / 8U;
uint8_t bytePerPixel = (bitsPerPixelElement * 3U) / 8U; /* RGB = 3 base colors */

while((payloadSize > srcIdx) && (m_framebuffer.getHeight() > y))
{
Expand Down Expand Up @@ -185,6 +198,10 @@ void DDPPlugin::onData(DDPServer::Format format, uint32_t offset, uint8_t bitsPe

m_isUpdated = isFinal;
}
else
{
LOG_WARNING("Unsupported DDP frame with format %d and bits per pixel element %u.", format, bitsPerPixelElement);
}
}

/******************************************************************************
Expand Down
15 changes: 7 additions & 8 deletions lib/DDPPlugin/src/DDPPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,22 +149,21 @@ class DDPPlugin : public Plugin
private:

DDPServer m_server; /**< DDP server */

Mutex m_mutex; /**< Mutex to protect against concurrent access */
YAGfxDynamicBitmap m_framebuffer; /**< Framebuffer used for synchronization */
bool m_isUpdated; /**< Is framebuffer updated and ready to show? */

/**
* On data reception, this method will be called from a different context.
*
* @param[in] format Format of the payload data
* @param[in] offset Byte offset in display framebuffer where to continue
* @param[in] bitsPerPixel Bits per pixel in payload data
* @param[in] payload Payload data
* @param[in] payloadSize Payload data size in byte
* @param[in] isFinal If final, its the last data and display shall show it. Otherwise more data will come.
* @param[in] format Format of the payload data
* @param[in] offset Byte offset in display framebuffer where to continue
* @param[in] bitsPerPixelElement Bits per pixel in payload data
* @param[in] payload Payload data
* @param[in] payloadSize Payload data size in byte
* @param[in] isFinal If final, its the last data and display shall show it. Otherwise more data will come.
*/
void onData(DDPServer::Format format, uint32_t offset, uint8_t bitsPerPixel, uint8_t* payload, uint16_t payloadSize, bool isFinal);
void onData(DDPServer::Format format, uint32_t offset, uint8_t bitsPerPixelElement, uint8_t* payload, uint16_t payloadSize, bool isFinal);
};

/******************************************************************************
Expand Down
138 changes: 69 additions & 69 deletions lib/DDPPlugin/src/DDPServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,127 +43,127 @@
*****************************************************************************/

/** Bit index for the version in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_VERSION_BIT (6U)
#define DDP_HEADER_FLAGS_VERSION_BIT (6U)

/** Bit mask for the version in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_VERSION_MASK (0x03U)
#define DDP_HEADER_FLAGS_VERSION_MASK (0x03U)

/** Bit index for the timecode flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_TIMECODE_BIT (4U)
#define DDP_HEADER_FLAGS_TIMECODE_BIT (4U)

/** Bit mask for the timecode flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_TIMECODE_MASK (0x01U)
#define DDP_HEADER_FLAGS_TIMECODE_MASK (0x01U)

/** Bit index for the storage flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_STORAGE_BIT (3U)
#define DDP_HEADER_FLAGS_STORAGE_BIT (3U)

/** Bit mask for the storage flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_STORAGE_MASK (0x01U)
#define DDP_HEADER_FLAGS_STORAGE_MASK (0x01U)

/** Bit index for the reply flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_REPLY_BIT (2U)
#define DDP_HEADER_FLAGS_REPLY_BIT (2U)

/** Bit mask for the reply flagn in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_REPLY_MASK (0x01U)
#define DDP_HEADER_FLAGS_REPLY_MASK (0x01U)

/** Bit index for the query flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_QUERY_BIT (1U)
#define DDP_HEADER_FLAGS_QUERY_BIT (1U)

/** Bit mask for the query flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_QUERY_MASK (0x01U)
#define DDP_HEADER_FLAGS_QUERY_MASK (0x01U)

/** Bit index for the push flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_PUSH_BIT (0U)
#define DDP_HEADER_FLAGS_PUSH_BIT (0U)

/** Bit mask for the push flag in the DDP header flags byte. */
#define DDP_HEADER_FLAGS_PUSH_MASK (0x01U)
#define DDP_HEADER_FLAGS_PUSH_MASK (0x01U)

/** Bit index for the sequence number in the DDP header control byte. */
#define DDP_HEADER_CONTROL_SEQ_NO_BIT (0U)
#define DDP_HEADER_CONTROL_SEQ_NO_BIT (0U)

/** Bit mask for the sequence number in the DDP header control byte. */
#define DDP_HEADER_CONTROL_SEQ_NO_MASK (0x0fU)
#define DDP_HEADER_CONTROL_SEQ_NO_MASK (0x0fU)

/** Bit index for the customer bit in the DDP header data type byte. */
#define DDP_HEADER_DT_CUSTOM_BIT (7U)
#define DDP_HEADER_DT_CUSTOM_BIT (7U)

/** Bit mask for the customer bit in the DDP header data type byte. */
#define DDP_HEADER_DT_CUSTOM_MASK (0x01U)
#define DDP_HEADER_DT_CUSTOM_MASK (0x01U)

/** Bit index for the data type in the DDP header data type byte. */
#define DDP_HEADER_DT_DATA_TYPE_BIT (3U)
#define DDP_HEADER_DT_DATA_TYPE_BIT (3U)

/** Bit mask for the data type in the DDP header data type byte. */
#define DDP_HEADER_DT_DATA_TYPE_MASK (0x07U)
#define DDP_HEADER_DT_DATA_TYPE_MASK (0x07U)

/** Bit index for the pixel size in the DDP header data type byte. */
#define DDP_HEADER_DT_PIXEL_SIZE_BIT (0U)
#define DDP_HEADER_DT_PIXEL_ELEMENT_SIZE_BIT (0U)

/** Bit mask for the pixel size in the DDP header data type byte. */
#define DDP_HEADER_DT_PIXEL_SIZE_MASK (0x07U)
#define DDP_HEADER_DT_PIXEL_ELEMENT_SIZE_MASK (0x07U)

/** DDP data type - undefined */
#define DDP_DATA_TYPE_UNDEFINED (0U)
#define DDP_DATA_TYPE_UNDEFINED (0U)

/** DDP data type - RGB order */
#define DDP_DATA_TYPE_RGB (1U)
#define DDP_DATA_TYPE_RGB (1U)

/** DDP data type - HSL order */
#define DDP_DATA_TYPE_HSL (2U)
#define DDP_DATA_TYPE_HSL (2U)

/** DDP data type - RGBW order */
#define DDP_DATA_TYPE_RGBW (3U)
#define DDP_DATA_TYPE_RGBW (3U)

/** DDP data type - Grayscale (shades of gray) */
#define DDP_DATA_TYPE_GRAYSCALE (4U)
#define DDP_DATA_TYPE_GRAYSCALE (4U)

/** DDP pixel size - undefined */
#define DDP_PIXEL_SIZE_UNDEFINED (0U)
#define DDP_PIXEL_ELEMENT_SIZE_UNDEFINED (0U)

/** DDP pixel size - 1 bit per pixel */
#define DDP_PIXEL_SIZE_1 (1U)
/** DDP pixel size - 1 bit per pixel element */
#define DDP_PIXEL_ELEMENT_SIZE_1 (1U)

/** DDP pixel size - 4 bit per pixel */
#define DDP_PIXEL_SIZE_4 (2U)
/** DDP pixel size - 4 bit per pixel element */
#define DDP_PIXEL_ELEMENT_SIZE_4 (2U)

/** DDP pixel size - 8 bit per pixel */
#define DDP_PIXEL_SIZE_8 (3U)
/** DDP pixel size - 8 bit per pixel element */
#define DDP_PIXEL_ELEMENT_SIZE_8 (3U)

/** DDP pixel size - 16 bit per pixel */
#define DDP_PIXEL_SIZE_16 (4U)
/** DDP pixel size - 16 bit per pixel element */
#define DDP_PIXEL_ELEMENT_SIZE_16 (4U)

/** DDP pixel size - 24 bit per pixel */
#define DDP_PIXEL_SIZE_24 (5U)
/** DDP pixel size - 24 bit per pixel element */
#define DDP_PIXEL_ELEMENT_SIZE_24 (5U)

/** DDP pixel size - 32 bit per pixel */
#define DDP_PIXEL_SIZE_32 (6U)
/** DDP pixel size - 32 bit per pixel element */
#define DDP_PIXEL_ELEMENT_SIZE_32 (6U)

/** DDP id - reserved */
#define DDP_ID_RESERVED (0U)
#define DDP_ID_RESERVED (0U)

/** DDP id - default device */
#define DDP_ID_DEFAULT (1U)
#define DDP_ID_DEFAULT (1U)

/** DDP id - custom id defined via JSON config */
#define DDP_ID_CUSTOM (2U)
#define DDP_ID_CUSTOM (2U)

/** DDP id - JSON control */
#define DDP_ID_JSON_CONTROL (246U)
#define DDP_ID_JSON_CONTROL (246U)

/** DDP id - JSON config */
#define DDP_ID_JSON_CONFIG (250U)
#define DDP_ID_JSON_CONFIG (250U)

/** DDP id - JSON status */
#define DDP_ID_JSON_STATUS (251U)
#define DDP_ID_JSON_STATUS (251U)

/** DDP id - DMX legay mode */
#define DDP_ID_DMX_TRANSIT (254U)
#define DDP_ID_DMX_TRANSIT (254U)

/** DDP id - all devices */
#define DDP_ID_ALL_DEVICES (255U)
#define DDP_ID_ALL_DEVICES (255U)

/** DDP timecode field size in byte */
#define DDP_TIMECODE_SIZE (4U)
#define DDP_TIMECODE_SIZE (4U)

/******************************************************************************
* Types and classes
Expand Down Expand Up @@ -394,46 +394,46 @@ uint8_t DDPServer::getDataType(const DDPHeader& header)
return dataType;
}

uint8_t DDPServer::getBitsPerPixel(const DDPHeader& header)
uint8_t DDPServer::getBitsPerPixelElement(const DDPHeader& header)
{
uint8_t bitsPerPixel = (header.detail.dataType >> DDP_HEADER_DT_PIXEL_SIZE_BIT) & DDP_HEADER_DT_PIXEL_SIZE_MASK;
uint8_t bitsPerPixelElement = (header.detail.dataType >> DDP_HEADER_DT_PIXEL_ELEMENT_SIZE_BIT) & DDP_HEADER_DT_PIXEL_ELEMENT_SIZE_MASK;

switch(bitsPerPixel)
switch(bitsPerPixelElement)
{
case DDP_PIXEL_SIZE_UNDEFINED:
bitsPerPixel = 8U;
case DDP_PIXEL_ELEMENT_SIZE_UNDEFINED:
bitsPerPixelElement = 0U;
break;

case DDP_PIXEL_SIZE_1:
bitsPerPixel = 1U;
case DDP_PIXEL_ELEMENT_SIZE_1:
bitsPerPixelElement = 1U;
break;

case DDP_PIXEL_SIZE_4:
bitsPerPixel = 4U;
case DDP_PIXEL_ELEMENT_SIZE_4:
bitsPerPixelElement = 4U;
break;

case DDP_PIXEL_SIZE_8:
bitsPerPixel = 8U;
case DDP_PIXEL_ELEMENT_SIZE_8:
bitsPerPixelElement = 8U;
break;

case DDP_PIXEL_SIZE_16:
bitsPerPixel = 16U;
case DDP_PIXEL_ELEMENT_SIZE_16:
bitsPerPixelElement = 16U;
break;

case DDP_PIXEL_SIZE_24:
bitsPerPixel = 24U;
case DDP_PIXEL_ELEMENT_SIZE_24:
bitsPerPixelElement = 24U;
break;

case DDP_PIXEL_SIZE_32:
bitsPerPixel = 32U;
case DDP_PIXEL_ELEMENT_SIZE_32:
bitsPerPixelElement = 32U;
break;

default:
bitsPerPixel = 8U;
bitsPerPixelElement = 0U;
break;
}

return bitsPerPixel;
return bitsPerPixelElement;
}

uint16_t DDPServer::getOffset(const DDPHeader& header)
Expand Down Expand Up @@ -586,15 +586,15 @@ void DDPServer::handleData(const DDPHeader& header, uint8_t* payload, uint16_t p
else if ((DDP_ID_ALL_DEVICES == header.detail.id) ||
(DDP_ID_DEFAULT == header.detail.id))
{
ddpNotify(static_cast<DDPServer::Format>(getDataType(header)), getOffset(header), getBitsPerPixel(header), payload, payloadSize, isPushFlagSet(header));
ddpNotify(static_cast<DDPServer::Format>(getDataType(header)), getOffset(header), getBitsPerPixelElement(header), payload, payloadSize, isPushFlagSet(header));
}
else
{
/* Skip */
}
}

void DDPServer::ddpNotify(Format format, uint32_t offset, uint8_t bitsPerPixel, uint8_t* payload, uint16_t payloadSize, bool isFinal)
void DDPServer::ddpNotify(Format format, uint32_t offset, uint8_t bitsPerPixelElement, uint8_t* payload, uint16_t payloadSize, bool isFinal)
{
DDPCallback callback = nullptr;

Expand All @@ -606,7 +606,7 @@ void DDPServer::ddpNotify(Format format, uint32_t offset, uint8_t bitsPerPixel,

if (nullptr != callback)
{
callback(format, offset, bitsPerPixel, payload, payloadSize, isFinal);
callback(format, offset, bitsPerPixelElement, payload, payloadSize, isFinal);
}
}

Expand Down
Loading

0 comments on commit 67d80c6

Please sign in to comment.