5 #include <sensor_msgs/CompressedImage.h> 7 #include <boost/thread.hpp> 8 #include <boost/tuple/tuple.hpp> 9 #include <boost/lexical_cast.hpp> 25 list<boost::tuple<struct mg_connection*, boost::condition_variable*, boost::mutex*> >
connections;
27 void image_callback(
const sensor_msgs::CompressedImage::ConstPtr& msg);
36 boost::mutex single_mutex;
37 boost::unique_lock<boost::mutex> lock(single_mutex);
44 string topic = node.resolveName(
"image");
45 int port, start_threads, max_threads;
52 std::stringstream port_ss, num_threads_ss, max_threads_ss;
54 num_threads_ss << start_threads;
55 max_threads_ss << max_threads;
57 const char *mg_options[] = {
58 "listening_ports", strdup(port_ss.str().c_str()),
59 "num_threads", strdup(num_threads_ss.str().c_str()),
60 "max_threads", strdup(max_threads_ss.str().c_str()),
61 "authentication_domain",
".",
65 image_sub = node.subscribe<sensor_msgs::CompressedImage>(topic, 1,
69 g_status_video =
this;
74 static char header_text[] =
"HTTP/1.0 200 OK\r\nConnection: Close\r\n" 75 "Server: ros/jpeg_streamer\r\n" 76 "Content-Type: multipart/x-mixed-replace;boundary=--myboundary\r\n\r\n";
82 boost::mutex::scoped_lock lock(con_mutex);
84 connections.push_back(boost::tuple<struct mg_connection*, boost::condition_variable*, boost::mutex*>(con, cond, single_mutex));
89 if (skipped++ ==
skip)
94 string data =
"--myboundary\r\nContent-Type: image/jpeg\r\nContent-Length: " 95 + boost::lexical_cast<
string>(msg->data.size()) +
"\r\n\r\n";
97 data.append((
const char*) &(msg->data[0]), msg->data.size());
101 const char *buf = data.c_str();
102 int buf_len = data.length();
106 boost::mutex::scoped_lock con_lock(con_mutex);
108 for (list<boost::tuple<struct mg_connection*, boost::condition_variable*, boost::mutex*> >::iterator it = connections.begin();
109 it != connections.end(); it++) {
114 if (
mg_write(con, buf, buf_len) < buf_len) {
115 it = connections.erase(it);
122 int main (
int argc,
char **argv) {
static char header_text[]
void wait(unique_lock< mutex > &m)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
int mg_write(struct mg_connection *, const void *buf, size_t len)
void * new_req_callback(enum mg_event event, struct mg_connection *con, const struct mg_request_info *req)
int main(int argc, char **argv)
ROSCPP_DECL void spin(Spinner &spinner)
ros::Subscriber image_sub
struct mg_context * mg_start(mg_callback_t callback, void *user_data, const char **options)
list< boost::tuple< struct mg_connection *, boost::condition_variable *, boost::mutex * > > connections
static char * skip(char **buf, const char *delimiters)
static JPEGStreamer * g_status_video
void add_connection(struct mg_connection *con, boost::condition_variable *cond, boost::mutex *single_mutex)
void notify_one() BOOST_NOEXCEPT
void image_callback(const sensor_msgs::CompressedImage::ConstPtr &msg)