1 #ifndef CODEC_IMAGE_TRANSPORT_DECODING_SUBSCRIBERS_HPP 2 #define CODEC_IMAGE_TRANSPORT_DECODING_SUBSCRIBERS_HPP 11 #include <sensor_msgs/CompressedImage.h> 12 #include <sensor_msgs/Image.h> 15 #include <boost/mpl/string.hpp> 16 #include <boost/shared_ptr.hpp> 19 #include <libavcodec/avcodec.h> 20 #include <libavutil/imgutils.h> 21 #include <libswscale/swscale.h> 26 template < AVCodecID CodecID,
typename TransportName >
34 virtual std::string
getTransportName()
const {
return boost::mpl::c_str< TransportName >::value; }
38 uint32_t queue_size,
const Callback &callback,
43 avcodec_register_all();
44 av_log_set_level(AV_LOG_FATAL);
47 AVCodec *
const decoder(avcodec_find_decoder(CodecID));
59 if (avcodec_open2(
decoder_ctx_.get(), decoder, NULL) < 0) {
71 av_init_packet(&packet);
72 packet.size = message->data.size();
73 packet.data =
const_cast< uint8_t *
>(&message->data[0]);
76 if (avcodec_send_packet(
decoder_ctx_.get(), &packet) < 0) {
77 ROS_ERROR(
"Cannot send a packet to decoder");
90 const int res(avcodec_receive_frame(
decoder_ctx_.get(), frame.get()));
91 if (res == AVERROR(EAGAIN) || res == AVERROR_EOF) {
100 const sensor_msgs::ImagePtr out(
new sensor_msgs::Image());
101 out->header = message->header;
102 out->height = frame->height;
103 out->width = frame->width;
105 out->step = 3 * frame->width;
106 out->data.resize(3 * frame->width * frame->height);
112 frame->width, frame->height,
115 frame->width, frame->height, AV_PIX_FMT_BGR24,
117 SWS_FAST_BILINEAR, NULL, NULL, NULL),
119 int stride(out->step);
120 uint8_t *dst(&out->data[0]);
121 sws_scale(convert_ctx.get(),
123 frame->data, frame->linesize, 0, frame->height,
135 av_frame_free(&frame);
141 avcodec_free_context(&ctx);
148 case AV_PIX_FMT_YUVJ420P:
149 return AV_PIX_FMT_YUV420P;
150 case AV_PIX_FMT_YUVJ411P:
151 return AV_PIX_FMT_YUV411P;
152 case AV_PIX_FMT_YUVJ422P:
153 return AV_PIX_FMT_YUV422P;
154 case AV_PIX_FMT_YUVJ440P:
155 return AV_PIX_FMT_YUV440P;
156 case AV_PIX_FMT_YUVJ444P:
157 return AV_PIX_FMT_YUV444P;
static void deleteAVCodecContext(AVCodecContext *ctx)
static void deleteAVFrame(AVFrame *frame)
DecodingSubscriber< AV_CODEC_ID_H264, boost::mpl::string< 'h', '2', '6', '4' > > H264Subscriber
boost::function< void(const sensor_msgs::ImageConstPtr &)> Callback
const ros::NodeHandle & nh() const
virtual std::string getTransportName() 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)
virtual ~DecodingSubscriber()
virtual void internalCallback(const sensor_msgs::CompressedImage::ConstPtr &message, const Callback &user_cb)
static AVPixelFormat toUndeprecated(const AVPixelFormat format)
image_transport::SimpleSubscriberPlugin< sensor_msgs::CompressedImage > Base
boost::shared_ptr< AVCodecContext > decoder_ctx_
virtual void subscribeImpl(ros::NodeHandle &nh, const std::string &base_topic, uint32_t queue_size, const Callback &callback, const ros::VoidPtr &tracked_object, const TransportHints &transport_hints)