ros_compressed_streamer.cpp
Go to the documentation of this file.
00001 #include "web_video_server/ros_compressed_streamer.h"
00002 
00003 namespace web_video_server
00004 {
00005 
00006 RosCompressedStreamer::RosCompressedStreamer(const async_web_server_cpp::HttpRequest &request,
00007                              async_web_server_cpp::HttpConnectionPtr connection, ros::NodeHandle& nh) :
00008   ImageStreamer(request, connection, nh), stream_(connection)
00009 {
00010   stream_.sendInitialHeader();
00011 }
00012 
00013 RosCompressedStreamer::~RosCompressedStreamer()
00014 {
00015   this->inactive_ = true;
00016   boost::mutex::scoped_lock lock(send_mutex_); // protects sendImage.
00017 }
00018 
00019 void RosCompressedStreamer::start() {
00020   std::string compressed_topic = topic_ + "/compressed";
00021   image_sub_ = nh_.subscribe(compressed_topic, 1, &RosCompressedStreamer::imageCallback, this);
00022 }
00023 
00024 void RosCompressedStreamer::restreamFrame(double max_age)
00025 {
00026   if (inactive_ || (last_msg == 0))
00027     return;
00028 
00029   if ( last_frame + ros::Duration(max_age) < ros::Time::now() ) {
00030     boost::mutex::scoped_lock lock(send_mutex_);
00031     sendImage(last_msg, ros::Time::now() ); // don't update last_frame, it may remain an old value.
00032   }
00033 }
00034 
00035 void RosCompressedStreamer::sendImage(const sensor_msgs::CompressedImageConstPtr &msg,
00036                                       const ros::Time &time) {
00037   try {
00038     std::string content_type;
00039     if(msg->format.find("jpeg") != std::string::npos) {
00040       content_type = "image/jpeg";
00041     }
00042     else if(msg->format.find("png") != std::string::npos) {
00043       content_type = "image/png";
00044     }
00045     else {
00046       ROS_WARN_STREAM("Unknown ROS compressed image format: " << msg->format);
00047       return;
00048     }
00049 
00050     stream_.sendPart(time, content_type, boost::asio::buffer(msg->data), msg);
00051   }
00052   catch (boost::system::system_error &e)
00053   {
00054     // happens when client disconnects
00055     ROS_DEBUG("system_error exception: %s", e.what());
00056     inactive_ = true;
00057     return;
00058   }
00059   catch (std::exception &e)
00060   {
00061     ROS_ERROR_THROTTLE(30, "exception: %s", e.what());
00062     inactive_ = true;
00063     return;
00064   }
00065   catch (...)
00066   {
00067     ROS_ERROR_THROTTLE(30, "exception");
00068     inactive_ = true;
00069     return;
00070   }
00071 }
00072 
00073 
00074 void RosCompressedStreamer::imageCallback(const sensor_msgs::CompressedImageConstPtr &msg) {
00075   boost::mutex::scoped_lock lock(send_mutex_); // protects last_msg and last_frame
00076   last_msg = msg;
00077   last_frame = ros::Time(msg->header.stamp.sec, msg->header.stamp.nsec);
00078   sendImage(last_msg, last_frame);
00079 }
00080 
00081 
00082 boost::shared_ptr<ImageStreamer> RosCompressedStreamerType::create_streamer(const async_web_server_cpp::HttpRequest &request,
00083                                                                                  async_web_server_cpp::HttpConnectionPtr connection,
00084                                                                                  ros::NodeHandle& nh)
00085 {
00086   return boost::shared_ptr<ImageStreamer>(new RosCompressedStreamer(request, connection, nh));
00087 }
00088 
00089 std::string RosCompressedStreamerType::create_viewer(const async_web_server_cpp::HttpRequest &request)
00090 {
00091   std::stringstream ss;
00092   ss << "<img src=\"/stream?";
00093   ss << request.query;
00094   ss << "\"></img>";
00095   return ss.str();
00096 }
00097 
00098 
00099 }


web_video_server
Author(s): Mitchell Wills
autogenerated on Thu Jun 6 2019 18:02:48