diff --git a/include/libmueb/muebtransmitter.h b/include/libmueb/muebtransmitter.h
index f12ea3c61bc7a78a1272ccf86b914335bab474e8..48b27089cce9aa2ef305298b7fc5afb512c6689f 100644
--- a/include/libmueb/muebtransmitter.h
+++ b/include/libmueb/muebtransmitter.h
@@ -45,6 +45,8 @@ class LIBMUEB_EXPORT MuebTransmitter final : public QObject {
 
   explicit MuebTransmitter(QObject* parent = nullptr);
   ~MuebTransmitter();
+
+  void SendPacket(QByteArray reduced_compressed_frame);
 };
 
 }  // namespace libmueb
diff --git a/libmueb.ini b/libmueb.ini
index d7ab61197d9b415bff145a4a40c145a3e750828f..db6b6fd85095b9ca32812c51f882bab6af6075a6 100644
--- a/libmueb.ini
+++ b/libmueb.ini
@@ -15,10 +15,14 @@ color_depth=4
 ; Network protocol specific constants.
 [network]
 animation_port=50001
-; Could be any valid IP(v4/v6) address: broadcast, multicast, unicast, localhost etc.
+; Could be any valid IPv4 address: broadcast, multicast, unicast, localhost etc.
+; Multicast example
+;multicast_interface=ethernet_32776
+;target_address=239.6.0.1
+; Broadcast example
 target_address=10.6.255.255
 ; The number of windows divided by max_windows_per_datagram must be an integer.
-; max_windows_per_datagram must be less than the number of windows.
+; max_windows_per_datagram must be less than or equal to the number of windows.
 ; Packet size must be less than 1472 bytes to avoid IPv4 fragmentation.
 ; Assuming 1500 MTU, 1500-20(IPv4 header)-8(UDP header) = 1472 bytes.
 max_windows_per_datagram=208
\ No newline at end of file
diff --git a/src/configuration.cc b/src/configuration.cc
index aaf9958e6e0f9fc422d3d93a54e47a4323650f87..c17245bf42a0165f7b1e04309446fe76f63e0b2c 100644
--- a/src/configuration.cc
+++ b/src/configuration.cc
@@ -34,8 +34,8 @@ Configuration::Configuration() {
 
   quint32 pixels_per_window = vertical_pixel_unit_ * horizontal_pixel_unit_;
   window_per_floor_ = rooms_per_floor * windows_per_room;
-  quint32 windows = floors_ * window_per_floor_;
-  pixels_ = windows * pixels_per_window;
+  windows_ = floors_ * window_per_floor_;
+  pixels_ = windows_ * pixels_per_window;
   // Alpha channel is not supported by hardware
   // The image is stored using a 24-bit RGB format (8-8-8)
   frame_ = QImage(window_per_floor_ * horizontal_pixel_unit_,
@@ -56,7 +56,7 @@ Configuration::Configuration() {
   }
 
   quint32 max_windows_per_datagram =
-      settings.value("max_windows_per_datagram", windows).toUInt();
+      settings.value("max_windows_per_datagram", windows_).toUInt();
   packet_header_size_ = 2;
   packet_size_ =
       packet_header_size_ + max_windows_per_datagram * window_byte_size;
@@ -65,13 +65,13 @@ Configuration::Configuration() {
   frame_fragment_size_ =
       max_windows_per_datagram * pixels_per_window * kRgbByteSize;
   max_packet_number_ =
-      qCeil(static_cast<qreal>(windows) / max_windows_per_datagram);
+      qCeil(static_cast<qreal>(windows_) / max_windows_per_datagram);
   settings.endGroup();
 
   if (settings.status() != QSettings::NoError ||
       vertical_pixel_unit_ % 2 != 0 || horizontal_pixel_unit_ % 2 != 0 ||
       color_depth_ < 3 || color_depth_ > 8 || animation_port_ < 0 ||
-      windows % max_windows_per_datagram != 0 || packet_size_ > 1472 ||
+      windows_ % max_windows_per_datagram != 0 || packet_size_ > 1472 ||
       (target_address_.isMulticast() && !multicast_interface_.isValid())) {
     if (target_address_.isMulticast()) {
       qInfo() << "[Configuration] Possible multicast interfaces:"
diff --git a/src/muebtransmitter.cc b/src/muebtransmitter.cc
index e6b679c0f59e9055129a80f74363ef2f7d099772..77ad1c5415335980c1b9e656b10fb9f1063bb0e3 100644
--- a/src/muebtransmitter.cc
+++ b/src/muebtransmitter.cc
@@ -1,9 +1,16 @@
 #include "muebtransmitter.h"
 
+#include <QList>
+
 #include "muebtransmitter_p.h"
 
 namespace libmueb {
 
+struct CompressedColorsWrapper {
+  QByteArray compressed_colors;
+  bool msb{true};
+};
+
 MuebTransmitter::MuebTransmitter(QObject* parent)
     : QObject(parent), d_ptr_(new MuebTransmitterPrivate(this)) {}
 
@@ -26,62 +33,52 @@ void MuebTransmitter::SendFrame(libmueb::Frame frame) {
   }
 
   frame.convertTo(QImage::Format_RGB888);
+  QList<uchar> frame_bytes(frame.constBits(),
+                           frame.constBits() + frame.sizeInBytes());
 
   // Frame color reduction and compression
-  QByteArray reduced_compressed_frame;
   if (d->configuration_.color_depth() < 5) {
-    reduced_compressed_frame = QtConcurrent::blockingMappedReduced<QByteArray>(
-        frame.constBits(), frame.constBits() + frame.sizeInBytes(),
+    auto result = QtConcurrent::mappedReduced<CompressedColorsWrapper>(
+        frame_bytes,
         // Reference:
         // http://threadlocalmutex.com/?p=48
         // http://threadlocalmutex.com/?page_id=60
-        [d](const uchar& color) -> uchar {
+        [this](const uchar& color) -> uchar {
+          Q_D(MuebTransmitter);
+          uchar u_color = static_cast<uchar>(color);
+
           if (d->configuration_.color_depth() == 3) {
-            return (color * 225 + 4096) >> 13;
+            return (u_color * 225 + 4096) >> 13;
           } else if (d->configuration_.color_depth() == 4) {
-            return (color * 15 + 135) >> 8;
+            return (u_color * 15 + 135) >> 8;
           }
 
-          return color;
+          return u_color;
         },
-        [d](QByteArray& compressed_colors, const uchar& color) {
-          static bool msb{true};
-
+        [](CompressedColorsWrapper& compressed_colors_wrapper,
+           const uchar& color) {
           // Compress 2 color components into 1 byte
-          if (msb) {
-            compressed_colors.append(color << Configuration::kFactor);
+          if (compressed_colors_wrapper.msb) {
+            compressed_colors_wrapper.compressed_colors.append(
+                color << Configuration::kFactor);
           } else {
-            compressed_colors.back() = compressed_colors.back() | color;
+            compressed_colors_wrapper.compressed_colors.back() =
+                compressed_colors_wrapper.compressed_colors.back() | color;
           }
 
-          msb = !msb;
+          compressed_colors_wrapper.msb = !compressed_colors_wrapper.msb;
         },
         QtConcurrent::OrderedReduce | QtConcurrent::SequentialReduce);
+
+    result.then(this,
+                [this](CompressedColorsWrapper compressed_colors_wrapper) {
+                  SendPacket(compressed_colors_wrapper.compressed_colors);
+                });
   }
   // No compression
   else {
-    reduced_compressed_frame.setRawData(
-        reinterpret_cast<const char*>(frame.bits()), frame.sizeInBytes());
-  }
-
-  if (d->configuration_.max_packet_number() == 1) {
-    reduced_compressed_frame.insert(0, d->configuration_.protocol_type())
-        .insert(1, static_cast<char>(0) /*packet number*/);
-
-    d->datagram_.setData(reduced_compressed_frame);
-    d->socket_.writeDatagram(d->datagram_);
-  } else {
-    for (std::uint8_t i = 0; i < d->configuration_.max_packet_number(); ++i) {
-      QByteArray data;
-      data.append(d->configuration_.protocol_type())
-          .append(i /*packet number*/)
-          .append(reduced_compressed_frame.sliced(
-              i * d->configuration_.packet_payload_size(),
-              d->configuration_.packet_payload_size()));
-
-      d->datagram_.setData(data);
-      d->socket_.writeDatagram(d->datagram_);
-    }
+    SendPacket(QByteArray(reinterpret_cast<const char*>(frame.bits()),
+                          frame.sizeInBytes()));
   }
 }
 
@@ -144,4 +141,28 @@ libmueb::Frame MuebTransmitter::frame() const {
 
   return d->configuration_.frame();
 }
+
+void MuebTransmitter::SendPacket(QByteArray reduced_compressed_frame) {
+  Q_D(MuebTransmitter);
+
+  if (d->configuration_.max_packet_number() == 1) {
+    reduced_compressed_frame.insert(0, d->configuration_.protocol_type())
+        .insert(1, static_cast<char>(0) /*packet number*/);
+
+    d->datagram_.setData(reduced_compressed_frame);
+    d->socket_.writeDatagram(d->datagram_);
+  } else {
+    for (std::uint8_t i = 0; i < d->configuration_.max_packet_number(); ++i) {
+      QByteArray data;
+      data.append(d->configuration_.protocol_type())
+          .append(i /*packet number*/)
+          .append(reduced_compressed_frame.sliced(
+              i * d->configuration_.packet_payload_size(),
+              d->configuration_.packet_payload_size()));
+
+      d->datagram_.setData(data);
+      d->socket_.writeDatagram(d->datagram_);
+    }
+  }
+}
 }  // namespace libmueb