1 #ifndef USB_CAM_CONTROLLERS_DECODING_CONTROLLERS 2 #define USB_CAM_CONTROLLERS_DECODING_CONTROLLERS 12 #include <sensor_msgs/Image.h> 18 #include <libavcodec/avcodec.h> 19 #include <libavutil/imgutils.h> 20 #include <libswscale/swscale.h> 25 template < AVCodecID CodecId, AVPixelFormat DstFormat, const std::
string *DstEncoding >
36 avcodec_register_all();
37 av_log_set_level(AV_LOG_FATAL);
40 AVCodec *
const decoder(avcodec_find_decoder(CodecId));
49 ROS_ERROR_STREAM(
"Cannot allocate a decoder context (codec id: " << CodecId <<
")");
54 if (avcodec_open2(
decoder_ctx_.get(), decoder, NULL) < 0) {
72 av_init_packet(&packet);
77 if (avcodec_send_packet(
decoder_ctx_.get(), &packet) < 0) {
78 ROS_ERROR_STREAM(
"Cannot send a packet to decoder (codec id: " << CodecId <<
")");
91 const int res(avcodec_receive_frame(
decoder_ctx_.get(), frame.get()));
92 if (res == AVERROR(EAGAIN) || res == AVERROR_EOF) {
101 const sensor_msgs::ImagePtr out(
new sensor_msgs::Image());
102 const int data_size(av_image_get_buffer_size(DstFormat, frame->width, frame->height, 1));
104 out->height = frame->height;
105 out->width = frame->width;
106 out->encoding = *DstEncoding;
107 out->step = data_size / frame->height;
108 out->data.resize(data_size);
114 frame->width, frame->height,
117 frame->width, frame->height, DstFormat,
119 SWS_FAST_BILINEAR, NULL, NULL, NULL),
121 int stride(out->step);
122 uint8_t *dst(&out->data[0]);
123 sws_scale(convert_ctx.get(),
125 frame->data, frame->linesize, 0, frame->height,
141 av_frame_free(&frame);
147 avcodec_free_context(&ctx);
154 case AV_PIX_FMT_YUVJ420P:
155 return AV_PIX_FMT_YUV420P;
156 case AV_PIX_FMT_YUVJ411P:
157 return AV_PIX_FMT_YUV411P;
158 case AV_PIX_FMT_YUVJ422P:
159 return AV_PIX_FMT_YUV422P;
160 case AV_PIX_FMT_YUVJ440P:
161 return AV_PIX_FMT_YUV440P;
162 case AV_PIX_FMT_YUVJ444P:
163 return AV_PIX_FMT_YUV444P;
const Byte * getStartAs() const
static AVPixelFormat toUndeprecated(const AVPixelFormat format)
boost::shared_ptr< AVCodecContext > decoder_ctx_
Publisher advertise(const std::string &base_topic, uint32_t queue_size, bool latch=false)
DecodingController< AV_CODEC_ID_MJPEG, AV_PIX_FMT_BGR24, &sensor_msgs::image_encodings::BGR8 > MjpegController
DecodingController< AV_CODEC_ID_H264, AV_PIX_FMT_BGR24, &sensor_msgs::image_encodings::BGR8 > H264Controller
static void deleteAVCodecContext(AVCodecContext *ctx)
virtual ~DecodingController()
virtual void startingImpl(const ros::Time &time)
void publish(const sensor_msgs::Image &message) const
ros::Time getStamp() const
virtual void stoppingImpl(const ros::Time &time)
virtual bool initImpl(usb_cam_hardware_interface::PacketInterface *hw, ros::NodeHandle &root_nh, ros::NodeHandle &controller_nh)
image_transport::Publisher publisher_
#define ROS_ERROR_STREAM(args)
static void deleteAVFrame(AVFrame *frame)
usb_cam_hardware_interface::PacketHandle packet_iface_
std::size_t getLength() const
virtual void updateImpl(const ros::Time &time, const ros::Duration &period)