Skip to content

Commit d82a7f6

Browse files
author
Raphael Dumusc
committed
Multi-channel streaming
1 parent bbde77a commit d82a7f6

File tree

13 files changed

+88
-17
lines changed

13 files changed

+88
-17
lines changed

apps/SimpleStreamer/main.cpp

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*********************************************************************/
2-
/* Copyright (c) 2014-2017, EPFL/Blue Brain Project */
2+
/* Copyright (c) 2014-2018, EPFL/Blue Brain Project */
33
/* Raphael Dumusc <raphael.dumusc@epfl.ch> */
44
/* */
55
/* Copyright (c) 2011 - 2012, The University of Texas at Austin. */
@@ -60,11 +60,15 @@ bool deflectCompressImage = true;
6060
bool deflectStereoStreamLeft = false;
6161
bool deflectStereoStreamRight = false;
6262
bool deflectStereoSideBySide = false;
63+
bool deflectDualChannel = false;
6364
unsigned int deflectCompressionQuality = 75;
6465
std::string deflectHost;
6566
std::string deflectStreamId = "SimpleStreamer";
6667
std::unique_ptr<deflect::Stream> deflectStream;
6768

69+
bool deflectFirstEventReceived = false;
70+
bool waitToStart = false;
71+
6872
void syntax(int exitStatus);
6973
void readCommandLineArguments(int argc, char** argv);
7074
void initGLWindow(int argc, char** argv);
@@ -118,6 +122,8 @@ void syntax(const int exitStatus)
118122
<< std::endl;
119123
std::cout << " -2 enable side-by-side stereo (default: OFF)"
120124
<< std::endl;
125+
std::cout << " -c enable dual-channel mode (default: OFF)"
126+
<< std::endl;
121127
exit(exitStatus);
122128
}
123129

@@ -158,6 +164,9 @@ void readCommandLineArguments(int argc, char** argv)
158164
case '2':
159165
deflectStereoSideBySide = true;
160166
break;
167+
case 'c':
168+
deflectDualChannel = true;
169+
break;
161170
case 'h':
162171
syntax(EXIT_SUCCESS);
163172
default:
@@ -280,7 +289,7 @@ struct Image
280289
}
281290
};
282291

283-
bool send(const Image& image, const deflect::View view)
292+
bool send(const Image& image, const deflect::View view, const uint8_t channel)
284293
{
285294
deflect::ImageWrapper deflectImage(image.data.data(), image.width,
286295
image.height, deflect::RGBA);
@@ -290,6 +299,7 @@ bool send(const Image& image, const deflect::View view)
290299
deflectImage.compressionQuality = deflectCompressionQuality;
291300
deflectImage.view = view;
292301
deflectImage.rowOrder = deflect::RowOrder::bottom_up;
302+
deflectImage.channel = channel;
293303
return deflectStream->send(deflectImage).get();
294304
}
295305

@@ -321,22 +331,18 @@ void drawMono()
321331
glutSolidTeapot(1.f);
322332
}
323333

324-
void display()
334+
bool drawAndSend(const uint8_t channel)
325335
{
326-
static Camera camera;
327-
camera.apply();
328-
329336
bool success = false;
330-
bool waitToStart = false;
331-
static bool deflectFirstEventReceived = false;
337+
332338
if (deflectStereoSideBySide)
333339
{
334340
drawLeft();
335341
const auto leftImage = Image::readGlBuffer();
336342
drawRight();
337343
const auto rightImage = Image::readGlBuffer();
338344
const auto sideBySideImage = Image::sideBySide(leftImage, rightImage);
339-
success = send(sideBySideImage, deflect::View::side_by_side);
345+
success = send(sideBySideImage, deflect::View::side_by_side, channel);
340346
}
341347
else if (deflectStereoStreamLeft || deflectStereoStreamRight)
342348
{
@@ -352,21 +358,41 @@ void display()
352358
{
353359
drawLeft();
354360
const auto leftImage = Image::readGlBuffer();
355-
success = send(leftImage, deflect::View::left_eye);
361+
success = send(leftImage, deflect::View::left_eye, channel);
356362
}
357363
if (deflectStereoStreamRight && !waitToStart)
358364
{
359365
drawRight();
360366
const auto rightImage = Image::readGlBuffer();
361367
success = (!deflectStereoStreamLeft || success) &&
362-
send(rightImage, deflect::View::right_eye);
368+
send(rightImage, deflect::View::right_eye, channel);
363369
}
364370
}
365371
else
366372
{
367373
drawMono();
368-
success = send(Image::readGlBuffer(), deflect::View::mono);
374+
success = send(Image::readGlBuffer(), deflect::View::mono, channel);
375+
}
376+
377+
return success;
378+
}
379+
380+
void display()
381+
{
382+
static Camera camera;
383+
camera.apply();
384+
385+
bool success = false;
386+
if (deflectDualChannel)
387+
{
388+
glPushMatrix();
389+
glRotatef(90, -1.f, 0.f, 0.f);
390+
success = drawAndSend(1);
391+
glPopMatrix();
392+
success = success && drawAndSend(0);
369393
}
394+
else
395+
success = drawAndSend(0);
370396

371397
if (!waitToStart)
372398
success = success && deflectStream->finishFrame().get();

deflect/ImageSegmenter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ ImageSegmenter::SegmentTasks ImageSegmenter::_generateSegmentTasks(
243243
segment.view =
244244
image.view == View::side_by_side ? View::left_eye : image.view;
245245
segment.rowOrder = image.rowOrder;
246+
segment.channel = image.channel;
246247
segment.sourceImage = &image;
247248
segments.push_back(segment);
248249
}

deflect/ImageWrapper.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ struct ImageWrapper
152152
*/
153153
RowOrder rowOrder = RowOrder::top_down;
154154

155+
/**
156+
* The index of the channel which the image is a part of.
157+
* @version 1.0
158+
*/
159+
uint8_t channel = 0;
160+
155161
/**
156162
* Get the number of bytes per pixel based on the pixelFormat.
157163
* @version 1.0

deflect/MessageHeader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ enum MessageType
6969
MESSAGE_TYPE_DATA = 14,
7070
MESSAGE_TYPE_IMAGE_VIEW = 15,
7171
MESSAGE_TYPE_OBSERVER_OPEN = 16,
72-
MESSAGE_TYPE_IMAGE_ROW_ORDER = 17
72+
MESSAGE_TYPE_IMAGE_ROW_ORDER = 17,
73+
MESSAGE_TYPE_IMAGE_CHANNEL = 18
7374
};
7475

7576
#define MESSAGE_HEADER_URI_LENGTH 64

deflect/Segment.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct Segment
5858

5959
View view = View::mono; //!< Eye pass for the segment
6060
RowOrder rowOrder = RowOrder::top_down; //!< Row order of imageData
61+
uint8_t channel = 0; //!< Channel index for the segment
6162
};
6263
}
6364

deflect/StreamSendWorker.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ bool StreamSendWorker::_sendSegment(const Segment& segment)
199199
_currentView = segment.view;
200200
}
201201
_sendRowOrderIfChanged(segment.rowOrder);
202+
_sendImageChannelIfChanged(segment.channel);
202203

203204
auto message = QByteArray{(const char*)(&segment.parameters),
204205
sizeof(SegmentParameters)};
@@ -229,6 +230,23 @@ bool StreamSendWorker::_sendImageRowOrder(const RowOrder rowOrder)
229230
QByteArray{(const char*)(&rowOrder), sizeof(RowOrder)});
230231
}
231232

233+
bool StreamSendWorker::_sendImageChannelIfChanged(const uint8_t channel)
234+
{
235+
if (channel != _currentChannel)
236+
{
237+
if (!_sendImageChannel(channel))
238+
return false;
239+
_currentChannel = channel;
240+
}
241+
return true;
242+
}
243+
244+
bool StreamSendWorker::_sendImageChannel(const uint8_t channel)
245+
{
246+
return _send(MESSAGE_TYPE_IMAGE_CHANNEL,
247+
QByteArray{(const char*)(&channel), sizeof(uint8_t)});
248+
}
249+
232250
bool StreamSendWorker::_sendFinish()
233251
{
234252
return _send(MESSAGE_TYPE_PIXELSTREAM_FINISH_FRAME, {});

deflect/StreamSendWorker.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class StreamSendWorker : public QThread
106106
bool _running = false;
107107
View _currentView = View::mono;
108108
RowOrder _currentRowOrder = RowOrder::top_down;
109+
uint8_t _currentChannel = 0;
109110

110111
std::vector<Request> _dequeuedRequests;
111112
bool _pendingFinish = false;
@@ -127,6 +128,8 @@ class StreamSendWorker : public QThread
127128
bool _sendImageView(View view);
128129
bool _sendRowOrderIfChanged(RowOrder rowOrder);
129130
bool _sendImageRowOrder(RowOrder rowOrder);
131+
bool _sendImageChannelIfChanged(uint8_t channel);
132+
bool _sendImageChannel(uint8_t channel);
130133
bool _sendFinish();
131134
bool _sendData(const QByteArray data);
132135
bool _sendSizeHints(const SizeHints& hints);

deflect/server/Frame.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,15 @@ namespace deflect
4343
{
4444
namespace server
4545
{
46-
QSize Frame::computeDimensions() const
46+
QSize Frame::computeDimensions(const uint8_t channel) const
4747
{
4848
QSize size(0, 0);
4949

5050
for (const auto& tile : tiles)
5151
{
52+
if (tile.channel != channel)
53+
continue;
54+
5255
size.setWidth(std::max(size.width(), (int)(tile.width + tile.x)));
5356
size.setHeight(std::max(size.height(), (int)(tile.height + tile.y)));
5457
}

deflect/server/Frame.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ struct Frame
6161
/** The PixelStream uri to which this frame is associated. */
6262
QString uri;
6363

64-
/** @return the total dimensions of this frame. */
65-
DEFLECT_API QSize computeDimensions() const;
64+
/** @return the total dimensions of the given channel of this frame. */
65+
DEFLECT_API QSize computeDimensions(const uint8_t channel = 0) const;
6666

6767
/**
6868
* @return the row order of all frame tiles.

deflect/server/ServerWorker.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,13 @@ void ServerWorker::_handleMessage(const MessageHeader& messageHeader,
274274
break;
275275
}
276276

277+
case MESSAGE_TYPE_IMAGE_CHANNEL:
278+
{
279+
const auto channel = reinterpret_cast<const uint8_t*>(byteArray.data());
280+
_activeChannel = *channel;
281+
break;
282+
}
283+
277284
case MESSAGE_TYPE_BIND_EVENTS:
278285
case MESSAGE_TYPE_BIND_EVENTS_EX:
279286
if (_registeredToEvents)
@@ -323,6 +330,7 @@ void ServerWorker::_handlePixelStreamMessage(const QByteArray& message)
323330
tile.imageData = message.right(message.size() - sizeof(SegmentParameters));
324331
tile.view = _activeView;
325332
tile.rowOrder = _activeRowOrder;
333+
tile.channel = _activeChannel;
326334

327335
emit(receivedTile(_streamId, _sourceId, tile));
328336
}

0 commit comments

Comments
 (0)