Files
utun2/tools/chatgui/src/call_camera_protocol.h
T

46 lines
1.8 KiB
C++

#pragma once
#include <QDataStream>
#include <QLocalSocket>
#include <QByteArray>
#include <functional>
namespace CallCameraProtocol {
enum Type : quint8 { Configure = 1, Quit, Ack, Devices, Frame, Stage, Error, Buffer };
constexpr quint32 FrameBytes = 1280 * 720 * 4;
constexpr quint32 MaxPacket = 65536;
// Только команды и метаданные. Пиксели — в mapping с владением Frame -> Ack, без shared mutex.
inline QByteArray packet(Type type, quint64 generation, const std::function<void(QDataStream&)>& write = {}) {
QByteArray result;
QDataStream out(&result, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_15);
out << quint32(0) << quint8(type) << generation;
if (write) write(out);
out.device()->seek(0); out << quint32(result.size() - 4);
return result;
}
class Reader {
QByteArray pending;
quint32 length = 0;
public:
bool read(QLocalSocket& socket, const std::function<bool(quint8, quint64, QDataStream&)>& consume) {
while (socket.bytesAvailable()) {
const qsizetype wanted = length ? length : 4;
pending += socket.read(wanted - pending.size());
if (pending.size() != wanted) return true;
QDataStream in(pending); in.setVersion(QDataStream::Qt_5_15);
if (!length) {
in >> length; pending.clear();
if (length < 9 || length > MaxPacket) return false;
} else {
quint8 type; quint64 generation; in >> type >> generation;
bool valid = consume(type, generation, in) && in.status() == QDataStream::Ok && in.atEnd();
pending.clear(); length = 0;
if (!valid) return false;
}
}
return true;
}
};
}