File indexing completed on 2025-01-05 03:53:06
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2021-07-24 0007 * Description : a MJPEG Stream server to export items on the network. 0008 * 0009 * SPDX-FileCopyrightText: 2021-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #ifndef DIGIKAM_MJPEG_SERVER_P_H 0016 #define DIGIKAM_MJPEG_SERVER_P_H 0017 0018 // Qt includes 0019 0020 #include <QList> 0021 #include <QStringList> 0022 #include <QFuture> 0023 #include <QMutex> 0024 #include <QTcpSocket> 0025 #include <QTcpServer> 0026 #include <QByteArray> 0027 0028 // Local includes 0029 0030 #include "mjpegserver.h" 0031 #include "digikam_debug.h" 0032 0033 namespace DigikamGenericMjpegStreamPlugin 0034 { 0035 0036 /** 0037 * MJPEG Server private container. 0038 * Internal use only. 0039 */ 0040 class Q_DECL_HIDDEN MjpegServer::Private : public QObject 0041 { 0042 Q_OBJECT 0043 0044 public: 0045 0046 explicit Private(QObject* const parent); 0047 ~Private(); 0048 0049 /** 0050 * Handle maximum clients connected to the server. 0051 */ 0052 void setMaxClients(int); 0053 int maxClients() const; 0054 0055 /** 0056 * Write data in native socket file descriptor. 0057 * We need to use native low level socket to write data inside 0058 * from separated threads, as QTCPSocket only work with a single thread. 0059 */ 0060 int writeInSocket(int sock, const QByteArray& data) const; 0061 0062 /** 0063 * Return an human readable description of client connected through a socket. 0064 */ 0065 QString clientDescription(QTcpSocket* const client) const; 0066 0067 /** 0068 * Return true if the server is running. 0069 */ 0070 bool isOpened() const; 0071 0072 /** 0073 * Initialize the server. 0074 */ 0075 bool open(const QString& address, int port); 0076 0077 /** 0078 * Start the server (aka listening on network). 0079 */ 0080 void start(); 0081 0082 /** 0083 * Stop the server (aka not listening on network). 0084 */ 0085 void stop(); 0086 0087 /** 0088 * Shutdown the server. 0089 */ 0090 void close(); 0091 0092 public: 0093 0094 QTcpServer* server; ///< main tcp/ip server. 0095 int rate; ///< stream frames rate per secs [1...30]. 0096 int delay; ///< delay between frames in us (1E6/rate). 0097 QList<QTcpSocket*> clients; ///< list of client connected sockets. 0098 QByteArray lastFrame; ///< the current JPEG frame to dispatch to all connected clients. 0099 QFuture<void> srvTask; ///< server threaded task used to stream on clients. 0100 QMutex mutexClients; ///< to protect current clients list. 0101 QMutex mutexFrame; ///< to protect current frame data. 0102 QStringList blackList; ///< Clients Ip address list to ban. 0103 0104 private Q_SLOTS: 0105 0106 /** 0107 * Called by server when new clients arrive. 0108 */ 0109 void slotNewConnection(); 0110 0111 /** 0112 * Called by server when client left the server. 0113 */ 0114 void slotClientDisconnected(); 0115 0116 private: 0117 0118 /** 0119 * Single thread method called to write data to all clients. 0120 */ 0121 void writerThread(); 0122 0123 /** 0124 * This method dispatch to all clients connected to a 0125 * separated thread running on one available core automatically. 0126 * This method is called through writerThread(). 0127 */ 0128 void clientWriteMultithreaded(int client, const QByteArray& data); 0129 }; 0130 0131 } // namespace DigikamGenericMjpegStreamPlugin 0132 0133 #endif // DIGIKAM_MJPEG_SERVER_P_H