muebtransmitter_p.h 3.16 KiB
#ifndef LIBMUEB_MUEBTRANSMITTER_P_H_
#define LIBMUEB_MUEBTRANSMITTER_P_H_
#include <QByteArray>
#include <QDebug>
#include <QNetworkDatagram>
#include <QUdpSocket>
#include <QtConcurrent>
#include "configuration.h"
#include "muebtransmitter.h"
class MuebTransmitterPrivate {
Q_DECLARE_PUBLIC(MuebTransmitter)
Q_DISABLE_COPY(MuebTransmitterPrivate)
public:
explicit MuebTransmitterPrivate(MuebTransmitter* q)
: datagram_(QByteArray(), configuration_.target_address(),
configuration_.broadcast_animation_port()),
q_ptr(q) {
qInfo().noquote() << "[MuebTransmitter] UDP Socket will send frame to"
<< QString("%1:%2")
.arg(configuration_.target_address().toString())
.arg(configuration_.broadcast_animation_port());
}
void SendFrame(libmueb::Frame frame) {
std::uint8_t packet_number{0};
QByteArray reduced_compressed_frame;
// Frame color reduction and compression
if (configuration_.color_depth() < 5) {
reduced_compressed_frame =
QtConcurrent::blockingMappedReduced<QByteArray>(
frame.constBits(), frame.constBits() + frame.sizeInBytes(),
/* Reference:
* http://threadlocalmutex.com/?p=48
* http://threadlocalmutex.com/?page_id=60
*/
[this](const uchar& color) -> uchar {
if (configuration_.color_depth() == 3) {
return (color * 225 + 4096) >> 13;
} else if (configuration_.color_depth() == 4) {
return (color * 15 + 135) >> 8;
}
return color;
},
[this](QByteArray& compressed_colors, const uchar& color) {
static bool msb{true};
// Compress 2 color components into 1 byte
if (msb) {
compressed_colors.append(color << configuration_.factor());
} else {
compressed_colors.back() = compressed_colors.back() | color;
}
msb = !msb;
},
QtConcurrent::OrderedReduce | QtConcurrent::SequentialReduce);
}
// No compression
else {
reduced_compressed_frame.setRawData(
reinterpret_cast<const char*>(frame.bits()), frame.sizeInBytes());
}
if (configuration_.max_packet_number() == 1) {
reduced_compressed_frame.insert(0, configuration_.protocol_type())
.insert(1, packet_number);
datagram_.setData(reduced_compressed_frame);
} else {
for (std::uint8_t i = 0; i < configuration_.max_packet_number(); ++i) {
QByteArray data;
data.append(configuration_.protocol_type())
.append(packet_number++)
.append(reduced_compressed_frame.sliced(
i * configuration_.frame_fragment_size(),
configuration_.frame_fragment_size()));
datagram_.setData(data);
}
}
socket_.writeDatagram(datagram_);
}
Configuration configuration_;
QUdpSocket socket_;
QNetworkDatagram datagram_;
MuebTransmitter* q_ptr;
};
#endif // LIBMUEB_MUEBTRANSMITTER_P_H_