Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Commit 8c4e0ef

Browse files
committed
Moved test/v4l2_to_png to src/hyperion-v4l2; Added json backend temporarily
1 parent 47ecb30 commit 8c4e0ef

File tree

12 files changed

+533
-148
lines changed

12 files changed

+533
-148
lines changed

dependencies/build/getoptPlusPlus/getoptpp.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void OptionsParser::usage() const {
120120
for(i = parameters.parameters.begin();
121121
i != parameters.parameters.end(); i++)
122122
{
123-
cerr.width(30);
123+
cerr.width(31);
124124
cerr << std::left << " " + (*i)->usageLine();
125125

126126
cerr.width(40);

libsrc/protoserver/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/protoserver)
44
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/protoserver)
55

6-
# add protocol buffers
7-
find_package(Protobuf REQUIRED)
8-
96
include_directories(
107
${CMAKE_CURRENT_BINARY_DIR}
118
${PROTOBUF_INCLUDE_DIRS})

src/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
add_subdirectory(hyperiond)
22
add_subdirectory(hyperion-remote)
3+
if (ENABLE_V4L2)
4+
add_subdirectory(hyperion-v4l2)
5+
endif (ENABLE_V4L2)

src/hyperion-v4l2/CMakeLists.txt

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
cmake_minimum_required(VERSION 2.8)
2+
3+
project(hyperion-v4l2)
4+
5+
# add protocol buffers
6+
find_package(Protobuf REQUIRED)
7+
8+
# find Qt4
9+
find_package(Qt4 REQUIRED QtCore QtGui QtNetwork)
10+
11+
include_directories(
12+
${CMAKE_CURRENT_BINARY_DIR}
13+
${PROTOBUF_INCLUDE_DIRS}
14+
${QT_INCLUDES}
15+
)
16+
17+
set(Hyperion_V4L2_HEADERS
18+
V4L2Grabber.h
19+
ProtoConnection.h
20+
)
21+
22+
set(Hyperion_V4L2_SOURCES
23+
hyperion-v4l2.cpp
24+
V4L2Grabber.cpp
25+
ProtoConnection.cpp
26+
)
27+
28+
set(Hyperion_V4L2_PROTOS
29+
${CMAKE_CURRENT_SOURCE_DIR}/../../libsrc/protoserver/message.proto
30+
)
31+
32+
protobuf_generate_cpp(Hyperion_V4L2_PROTO_SRCS Hyperion_V4L2_PROTO_HDRS
33+
${Hyperion_V4L2_PROTOS}
34+
)
35+
36+
add_executable(hyperion-v4l2
37+
${Hyperion_V4L2_HEADERS}
38+
${Hyperion_V4L2_SOURCES}
39+
${Hyperion_V4L2_PROTO_SRCS}
40+
${Hyperion_V4L2_PROTO_HDRS}
41+
)
42+
43+
target_link_libraries(hyperion-v4l2
44+
getoptPlusPlus
45+
jsoncpp
46+
hyperion-utils
47+
${PROTOBUF_LIBRARIES}
48+
pthread
49+
)
50+
51+
qt4_use_modules(hyperion-v4l2
52+
Core
53+
Gui
54+
Network)

src/hyperion-v4l2/ProtoConnection.cpp

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// stl includes
2+
#include <stdexcept>
3+
4+
// Qt includes
5+
#include <QRgb>
6+
7+
// hyperion-v4l2 includes
8+
#include "ProtoConnection.h"
9+
10+
ProtoConnection::ProtoConnection(const std::string & a) :
11+
_socket()
12+
{
13+
QString address(a.c_str());
14+
QStringList parts = address.split(":");
15+
if (parts.size() != 2)
16+
{
17+
throw std::runtime_error(QString("Wrong address: unable to parse address (%1)").arg(address).toStdString());
18+
}
19+
20+
bool ok;
21+
uint16_t port = parts[1].toUShort(&ok);
22+
if (!ok)
23+
{
24+
throw std::runtime_error(QString("Wrong address: Unable to parse the port number (%1)").arg(parts[1]).toStdString());
25+
}
26+
27+
_socket.connectToHost(parts[0], port);
28+
if (!_socket.waitForConnected())
29+
{
30+
throw std::runtime_error("Unable to connect to host");
31+
}
32+
33+
std::cout << "Connected to " << a << std::endl;
34+
}
35+
36+
ProtoConnection::~ProtoConnection()
37+
{
38+
_socket.close();
39+
}
40+
41+
void ProtoConnection::setColor(std::vector<QColor> colors, int priority, int duration)
42+
{
43+
// create command
44+
Json::Value command;
45+
command["command"] = "color";
46+
command["priority"] = priority;
47+
Json::Value & rgbValue = command["color"];
48+
for (const QColor & color : colors)
49+
{
50+
rgbValue.append(color.red());
51+
rgbValue.append(color.green());
52+
rgbValue.append(color.blue());
53+
}
54+
if (duration > 0)
55+
{
56+
command["duration"] = duration;
57+
}
58+
59+
// send command message
60+
Json::Value reply = sendMessage(command);
61+
62+
// parse reply message
63+
parseReply(reply);
64+
}
65+
66+
void ProtoConnection::setImage(const Image<ColorRgb> &image, int priority, int duration)
67+
{
68+
// ensure the image has RGB888 format
69+
QByteArray binaryImage = QByteArray::fromRawData(reinterpret_cast<const char *>(image.memptr()), image.width() * image.height() * 3);
70+
const QByteArray base64Image = binaryImage.toBase64();
71+
72+
// create command
73+
Json::Value command;
74+
command["command"] = "image";
75+
command["priority"] = priority;
76+
command["imagewidth"] = image.width();
77+
command["imageheight"] = image.height();
78+
command["imagedata"] = std::string(base64Image.data(), base64Image.size());
79+
if (duration > 0)
80+
{
81+
command["duration"] = duration;
82+
}
83+
84+
// send command message
85+
Json::Value reply = sendMessage(command);
86+
87+
// parse reply message
88+
parseReply(reply);
89+
}
90+
91+
void ProtoConnection::clear(int priority)
92+
{
93+
std::cout << "Clear priority channel " << priority << std::endl;
94+
95+
// create command
96+
Json::Value command;
97+
command["command"] = "clear";
98+
command["priority"] = priority;
99+
100+
// send command message
101+
Json::Value reply = sendMessage(command);
102+
103+
// parse reply message
104+
parseReply(reply);
105+
}
106+
107+
void ProtoConnection::clearAll()
108+
{
109+
std::cout << "Clear all priority channels" << std::endl;
110+
111+
// create command
112+
Json::Value command;
113+
command["command"] = "clearall";
114+
115+
// send command message
116+
Json::Value reply = sendMessage(command);
117+
118+
// parse reply message
119+
parseReply(reply);
120+
}
121+
122+
Json::Value ProtoConnection::sendMessage(const Json::Value & message)
123+
{
124+
// serialize message (FastWriter already appends a newline)
125+
std::string serializedMessage = Json::FastWriter().write(message);
126+
127+
// write message
128+
_socket.write(serializedMessage.c_str());
129+
if (!_socket.waitForBytesWritten())
130+
{
131+
throw std::runtime_error("Error while writing data to host");
132+
}
133+
134+
// read reply data
135+
QByteArray serializedReply;
136+
while (!serializedReply.contains('\n'))
137+
{
138+
// receive reply
139+
if (!_socket.waitForReadyRead())
140+
{
141+
throw std::runtime_error("Error while reading data from host");
142+
}
143+
144+
serializedReply += _socket.readAll();
145+
}
146+
int bytes = serializedReply.indexOf('\n') + 1; // Find the end of message
147+
148+
// parse reply data
149+
Json::Reader jsonReader;
150+
Json::Value reply;
151+
if (!jsonReader.parse(serializedReply.constData(), serializedReply.constData() + bytes, reply))
152+
{
153+
throw std::runtime_error("Error while parsing reply: invalid json");
154+
}
155+
156+
return reply;
157+
}
158+
159+
bool ProtoConnection::parseReply(const Json::Value &reply)
160+
{
161+
bool success = false;
162+
std::string reason = "No error info";
163+
164+
try
165+
{
166+
success = reply.get("success", false).asBool();
167+
if (!success)
168+
reason = reply.get("error", reason).asString();
169+
}
170+
catch (const std::runtime_error &)
171+
{
172+
// Some json parsing error: ignore and set parsing error
173+
}
174+
175+
if (!success)
176+
{
177+
throw std::runtime_error("Error: " + reason);
178+
}
179+
180+
return success;
181+
}

src/hyperion-v4l2/ProtoConnection.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#pragma once
2+
3+
// stl includes
4+
#include <string>
5+
6+
// Qt includes
7+
#include <QColor>
8+
#include <QImage>
9+
#include <QTcpSocket>
10+
#include <QMap>
11+
12+
// hyperion util
13+
#include <utils/Image.h>
14+
#include <utils/ColorRgb.h>
15+
16+
// jsoncpp includes
17+
#include <json/json.h>
18+
19+
///
20+
/// Connection class to setup an connection to the hyperion server and execute commands
21+
///
22+
class ProtoConnection
23+
{
24+
public:
25+
///
26+
/// Constructor
27+
///
28+
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
29+
///
30+
ProtoConnection(const std::string & address);
31+
32+
///
33+
/// Destructor
34+
///
35+
~ProtoConnection();
36+
37+
///
38+
/// Set all leds to the specified color
39+
///
40+
/// @param color The color
41+
/// @param priority The priority
42+
/// @param duration The duration in milliseconds
43+
///
44+
void setColor(std::vector<QColor> color, int priority, int duration);
45+
46+
///
47+
/// Set the leds according to the given image (assume the image is stretched to the display size)
48+
///
49+
/// @param image The image
50+
/// @param priority The priority
51+
/// @param duration The duration in milliseconds
52+
///
53+
void setImage(const Image<ColorRgb> & image, int priority, int duration);
54+
55+
///
56+
/// Clear the given priority channel
57+
///
58+
/// @param priority The priority
59+
///
60+
void clear(int priority);
61+
62+
///
63+
/// Clear all priority channels
64+
///
65+
void clearAll();
66+
67+
private:
68+
///
69+
/// Send a json command message and receive its reply
70+
///
71+
/// @param message The message to send
72+
///
73+
/// @return The returned reply
74+
///
75+
Json::Value sendMessage(const Json::Value & message);
76+
77+
///
78+
/// Parse a reply message
79+
///
80+
/// @param reply The received reply
81+
///
82+
/// @return true if the reply indicates success
83+
///
84+
bool parseReply(const Json::Value & reply);
85+
86+
private:
87+
/// The TCP-Socket with the connection to the server
88+
QTcpSocket _socket;
89+
};

0 commit comments

Comments
 (0)