Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef ENCODING_MANAGER_H_
00038 #define ENCODING_MANAGER_H_
00039
00040 #include "ffmpeg_encoder.h"
00041
00042 #include "server_configuration.h"
00043
00044 #include <map>
00045 #include <string>
00046
00047
00048
00049 namespace ros_http_video_streamer
00050 {
00051
00052 class EncoderManager
00053 {
00054 public:
00055 EncoderManager() :
00056 mutex_(),
00057 image_encoder_map_(),
00058 request_counter_(0)
00059 {
00060 }
00061
00062 virtual ~EncoderManager()
00063 {
00064 }
00065
00066
00067 FFMPEGEncoder::ptr subscribe(const std::string& topic,
00068 const ServerConfiguration& config)
00069 {
00070 boost::mutex::scoped_lock lock(mutex_);
00071
00072 ++request_counter_;
00073
00074 std::string refID = topic + ":" +
00075 config.codec_ + ":" +
00076 "BR:"+boost::lexical_cast<std::string>(config.bitrate_) +
00077 "FR:"+boost::lexical_cast<std::string>(config.framerate_) +
00078 "FW:"+boost::lexical_cast<std::string>(config.frame_width_) +
00079 "FH:"+boost::lexical_cast<std::string>(config.frame_height_) +
00080 "Q:"+boost::lexical_cast<std::string>(config.quality_) +
00081 "GOP:"+boost::lexical_cast<std::string>(config.gop_);
00082
00083 FFMPEGEncoder::ptr image_encoder;
00084
00085 #ifdef SHARED_ENCODERS
00086
00087 std::map<std::string, EncoderInfo>::iterator it;
00088 it = image_encoder_map_.find(refID);
00089
00090 if (it!=image_encoder_map_.end())
00091 {
00092 image_encoder = (it->second).enc_;
00093 (it->second).listener_count_++;
00094 }
00095 else
00096 {
00097
00098 image_encoder = FFMPEGEncoder::ptr(new FFMPEGEncoder(refID, topic, config));
00099
00100 EncoderInfo encInfo;
00101 encInfo.enc_ = image_encoder;
00102 encInfo.listener_count_ = 1;
00103
00104
00105 image_encoder_map_[refID] = encInfo;
00106 }
00107 #else
00108
00109 refID += "ReqID:" + boost::lexical_cast<std::string>(request_counter_);
00110 image_encoder = FFMPEGEncoder::ptr(new FFMPEGEncoder(refID, topic, config));
00111
00112 EncoderInfo encInfo;
00113 encInfo.enc_ = image_encoder;
00114 encInfo.listener_count_ = 1;
00115
00116 image_encoder_map_[refID] = encInfo;
00117 #endif
00118
00119 return image_encoder;
00120 }
00121
00122 void unsubscribe(const std::string& refID)
00123 {
00124 boost::mutex::scoped_lock lock(mutex_);
00125
00126
00127 std::map<std::string, EncoderInfo>::iterator it;
00128 it = image_encoder_map_.find(refID);
00129
00130 if (it != image_encoder_map_.end())
00131 {
00132 EncoderInfo& encInfo = it->second;
00133 encInfo.listener_count_--;
00134
00135 if (!encInfo.listener_count_)
00136 image_encoder_map_.erase(refID);
00137
00138 ROS_INFO("Deleting encoder: %s", refID.c_str());
00139 }
00140 }
00141
00142 private:
00143
00144
00145
00146 struct EncoderInfo
00147 {
00148 EncoderInfo() :
00149 listener_count_(0)
00150 {
00151 }
00152
00153
00154 FFMPEGEncoder::ptr enc_;
00155
00156 std::size_t listener_count_;
00157 };
00158
00159
00160 boost::mutex mutex_;
00161
00162 std::map<std::string, EncoderInfo> image_encoder_map_;
00163
00164
00165 unsigned int request_counter_;
00166
00167 };
00168
00169 }
00170
00171
00172 #endif