camera_buffer_pool.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * camera_aravis
4  *
5  * Copyright © 2022 Fraunhofer IOSB and contributors
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  ****************************************************************************/
23 
25 
26 namespace camera_aravis
27 {
28 
29 CameraBufferPool::CameraBufferPool(ArvStream *stream, size_t payload_size_bytes, size_t n_preallocated_buffers) :
30  stream_(stream), payload_size_bytes_(payload_size_bytes), n_buffers_(0),
31  self_(this, [](CameraBufferPool *p) {})
32 {
33  allocateBuffers(n_preallocated_buffers);
34 }
35 
37 {
38 }
39 
40 sensor_msgs::ImagePtr CameraBufferPool::getRecyclableImg()
41 {
42  std::lock_guard<std::mutex> lock(mutex_);
43  if (dangling_imgs_.empty()) {
44  return sensor_msgs::ImagePtr(new sensor_msgs::Image, boost::bind(&CameraBufferPool::reclaim, this->weak_from_this(), boost::placeholders::_1));
45  }
46  else {
47  sensor_msgs::ImagePtr img_ptr = dangling_imgs_.top();
48  dangling_imgs_.pop();
49  return img_ptr;
50  }
51 }
52 
53 sensor_msgs::ImagePtr CameraBufferPool::operator[](ArvBuffer *buffer)
54 {
55  std::lock_guard<std::mutex> lock(mutex_);
56  sensor_msgs::ImagePtr img_ptr;
57  if (buffer) {
58  // get address and size
59  size_t buffer_size;
60  const uint8_t *buffer_data = (const uint8_t*)arv_buffer_get_data(buffer, &buffer_size);
61 
62  // find corresponding ImagePtr wrapper
63  std::map<const uint8_t*, sensor_msgs::ImagePtr>::iterator iter = available_img_buffers_.find(buffer_data);
64  if (iter != available_img_buffers_.end())
65  {
66  img_ptr = iter->second;
67  used_buffers_.emplace(img_ptr.get(), buffer);
68  available_img_buffers_.erase(iter);
69  }
70  else
71  {
72  ROS_WARN("Could not find available image in pool corresponding to buffer.");
73  img_ptr.reset(new sensor_msgs::Image);
74  img_ptr->data.resize(buffer_size);
75  memcpy(img_ptr->data.data(), buffer_data, buffer_size);
76  }
77  }
78 
79  return img_ptr;
80 }
81 
83 {
84  std::lock_guard<std::mutex> lock(mutex_);
85 
86  if (ARV_IS_STREAM(stream_))
87  {
88  for (size_t i = 0; i < n; ++i)
89  {
90  sensor_msgs::Image *p_img = new sensor_msgs::Image;
91  p_img->data.resize(payload_size_bytes_);
92  ArvBuffer *buffer = arv_buffer_new(payload_size_bytes_, p_img->data.data());
93  sensor_msgs::ImagePtr img_ptr(
94  p_img, boost::bind(&CameraBufferPool::reclaim, this->weak_from_this(), boost::placeholders::_1));
95  available_img_buffers_.emplace(p_img->data.data(), img_ptr);
96  arv_stream_push_buffer(stream_, buffer);
97  ++n_buffers_;
98  }
99  ROS_INFO_STREAM("Allocated " << n << " image buffers of size " << payload_size_bytes_);
100  }
101  else
102  {
103  ROS_ERROR("Error: Stream not valid. Failed to allocate buffers.");
104  }
105 }
106 
107 void CameraBufferPool::reclaim(const WPtr &self, sensor_msgs::Image *p_img)
108 {
109  Ptr s = self.lock();
110  if (s)
111  {
112  s->push(p_img);
113  }
114  else
115  {
116  delete p_img;
117  }
118 }
119 
120 void CameraBufferPool::push(sensor_msgs::Image *p_img)
121 {
122  std::lock_guard<std::mutex> lock(mutex_);
123 
124  std::map<sensor_msgs::Image*, ArvBuffer*>::iterator iter = used_buffers_.find(p_img);
125 
126  if (iter != used_buffers_.end())
127  {
128  if (ARV_IS_STREAM(stream_))
129  {
130  sensor_msgs::ImagePtr img_ptr(
131  p_img, boost::bind(&CameraBufferPool::reclaim, this->weak_from_this(), boost::placeholders::_1));
132  available_img_buffers_.emplace(p_img->data.data(), img_ptr);
133  arv_stream_push_buffer(stream_, iter->second);
134  }
135  else
136  {
137  // the camera stream is gone, so should its buffers
138  delete p_img;
139  }
140  used_buffers_.erase(iter);
141  }
142  else
143  {
144  // this image was not an aravis registered buffer
145  dangling_imgs_.emplace(p_img, boost::bind(&CameraBufferPool::reclaim, this->weak_from_this(), boost::placeholders::_1));
146  }
147 }
148 
149 } /* namespace camera_aravis */
s
XmlRpcServer s
camera_buffer_pool.h
camera_aravis::CameraBufferPool::dangling_imgs_
std::stack< sensor_msgs::ImagePtr > dangling_imgs_
Definition: camera_buffer_pool.h:150
camera_aravis
Definition: camera_aravis_nodelet.h:82
camera_aravis::CameraBufferPool::~CameraBufferPool
virtual ~CameraBufferPool()
Definition: camera_buffer_pool.cpp:57
camera_aravis::CameraBufferPool::operator[]
sensor_msgs::ImagePtr operator[](ArvBuffer *buffer)
Definition: camera_buffer_pool.cpp:74
camera_aravis::CameraBufferPool::Ptr
boost::shared_ptr< CameraBufferPool > Ptr
Definition: camera_buffer_pool.h:91
camera_aravis::CameraBufferPool::stream_
ArvStream * stream_
Definition: camera_buffer_pool.h:144
camera_aravis::CameraBufferPool::reclaim
static void reclaim(const WPtr &self, sensor_msgs::Image *p_img)
Definition: camera_buffer_pool.cpp:128
camera_aravis::CameraBufferPool::n_buffers_
size_t n_buffers_
Definition: camera_buffer_pool.h:146
camera_aravis::CameraBufferPool::used_buffers_
std::map< sensor_msgs::Image *, ArvBuffer * > used_buffers_
Definition: camera_buffer_pool.h:149
camera_aravis::CameraBufferPool::getRecyclableImg
sensor_msgs::ImagePtr getRecyclableImg()
Definition: camera_buffer_pool.cpp:61
ROS_WARN
#define ROS_WARN(...)
ROS_INFO_STREAM
#define ROS_INFO_STREAM(args)
camera_aravis::CameraBufferPool::CameraBufferPool
CameraBufferPool(ArvStream *stream, size_t payload_size_bytes, size_t n_preallocated_buffers=2)
Definition: camera_buffer_pool.cpp:50
camera_aravis::CameraBufferPool::mutex_
std::mutex mutex_
Definition: camera_buffer_pool.h:151
camera_aravis::CameraBufferPool::payload_size_bytes_
size_t payload_size_bytes_
Definition: camera_buffer_pool.h:145
ROS_ERROR
#define ROS_ERROR(...)
camera_aravis::CameraBufferPool::available_img_buffers_
std::map< const uint8_t *, sensor_msgs::ImagePtr > available_img_buffers_
Definition: camera_buffer_pool.h:148
camera_aravis::CameraBufferPool::push
void push(sensor_msgs::Image *p_img)
Definition: camera_buffer_pool.cpp:141
camera_aravis::CameraBufferPool::allocateBuffers
void allocateBuffers(size_t n=1)
Definition: camera_buffer_pool.cpp:103


camera_aravis
Author(s): Boitumelo Ruf, Fraunhofer IOSB , Dominik Kleiser, Fraunhofer IOSB , Dominik A. Klein, Fraunhofer FKIE , Steve Safarik, Straw Lab , Andrew Straw, Straw Lab , Floris van Breugel, van Breugel Lab
autogenerated on Wed Sep 25 2024 02:23:21