38 #include <opencv2/imgproc/imgproc.hpp> 39 #include <boost/scoped_array.hpp> 46 TheoraSubscriber::TheoraSubscriber()
48 received_header_(false),
49 received_keyframe_(false),
50 decoding_context_(NULL),
72 Base::subscribeImpl(nh, base_topic, queue_size, callback, tracked_object, transport_hints);
84 config.post_processing_level =
pplevel_;
87 pplevel_ = config.post_processing_level;
93 int err = th_decode_ctl(
decoding_context_, TH_DECCTL_GET_PPLEVEL_MAX, &pplevel_max,
sizeof(
int));
95 ROS_WARN(
"Failed to get maximum post-processing level, error code %d", err);
96 else if (level > pplevel_max) {
97 ROS_WARN(
"Post-processing level %d is above the maximum, clamping to %d", level, pplevel_max);
101 err = th_decode_ctl(
decoding_context_, TH_DECCTL_SET_PPLEVEL, &level,
sizeof(
int));
103 ROS_ERROR(
"Failed to set post-processing level, error code %d", err);
112 ogg.bytes = msg.data.size();
113 ogg.b_o_s = msg.b_o_s;
114 ogg.e_o_s = msg.e_o_s;
115 ogg.granulepos = msg.granulepos;
116 ogg.packetno = msg.packetno;
117 ogg.packet =
new unsigned char[ogg.bytes];
118 memcpy(ogg.packet, &msg.data[0], ogg.bytes);
124 ogg_packet oggpacket;
126 boost::scoped_array<unsigned char> packet_guard(oggpacket.packet);
129 if (oggpacket.b_o_s == 1) {
154 ROS_ERROR(
"[theora] Decoding parameters were invalid");
161 ROS_WARN(
"[theora] EFAULT when processing header packet");
164 ROS_WARN(
"[theora] Bad header packet");
167 ROS_WARN(
"[theora] Header packet not decodable with this version of libtheora");
170 ROS_WARN(
"[theora] Packet was not a Theora header");
175 ROS_WARN(
"[theora] Error code %d when processing header packet", rval);
192 ROS_DEBUG(
"[theora] Got a duplicate frame");
199 ROS_WARN(
"[theora] EFAULT processing video packet");
202 ROS_WARN(
"[theora] Packet does not contain encoded video data");
205 ROS_WARN(
"[theora] The video data uses bitstream features not supported by this version of libtheora");
208 ROS_WARN(
"[theora] Error code %d when decoding video packet", rval);
213 th_ycbcr_buffer ycbcr_buffer;
217 th_img_plane &y_plane = ycbcr_buffer[0], &cb_plane = ycbcr_buffer[1], &cr_plane = ycbcr_buffer[2];
218 cv::Mat y(y_plane.height, y_plane.width, CV_8UC1, y_plane.data, y_plane.stride);
219 cv::Mat cb_sub(cb_plane.height, cb_plane.width, CV_8UC1, cb_plane.data, cb_plane.stride);
220 cv::Mat cr_sub(cr_plane.height, cr_plane.width, CV_8UC1, cr_plane.data, cr_plane.stride);
224 cv::pyrUp(cb_sub, cb);
225 cv::pyrUp(cr_sub, cr);
228 cv::Mat ycrcb, channels[] = {y, cr, cb};
229 cv::merge(channels, 3, ycrcb);
232 cv::Mat bgr, bgr_padded;
233 cv::cvtColor(ycrcb, bgr_padded, CV_YCrCb2BGR);
th_dec_ctx * decoding_context_
theora_image_transport::TheoraSubscriberConfig Config
virtual ~TheoraSubscriber()
boost::function< void(const sensor_msgs::ImageConstPtr &)> Callback
void msgToOggPacket(const theora_image_transport::Packet &msg, ogg_packet &ogg)
boost::shared_ptr< ReconfigureServer > reconfigure_server_
sensor_msgs::ImagePtr latest_image_
virtual void internalCallback(const theora_image_transport::PacketConstPtr &msg, const Callback &user_cb)
int updatePostProcessingLevel(int level)
th_setup_info * setup_info_
th_comment header_comment_
const ros::NodeHandle & nh() const
void configCb(Config &config, uint32_t level)
sensor_msgs::ImagePtr toImageMsg() const
virtual void subscribeImpl(ros::NodeHandle &nh, const std::string &base_topic, uint32_t queue_size, const Callback &callback, const ros::VoidPtr &tracked_object, const image_transport::TransportHints &transport_hints)