1 /*
2 * buffer_pool.cpp - buffer pool
3 *
4 * Copyright (c) 2014-2015 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 */
20
21 #include "buffer_pool.h"
22
23 namespace XCam {
24
BufferProxy(const VideoBufferInfo & info,const SmartPtr<BufferData> & data)25 BufferProxy::BufferProxy (const VideoBufferInfo &info, const SmartPtr<BufferData> &data)
26 : VideoBuffer (info)
27 , _data (data)
28 {
29 XCAM_ASSERT (data.ptr ());
30 }
31
BufferProxy(const SmartPtr<BufferData> & data)32 BufferProxy::BufferProxy (const SmartPtr<BufferData> &data)
33 : _data (data)
34 {
35 XCAM_ASSERT (data.ptr ());
36 }
37
~BufferProxy()38 BufferProxy::~BufferProxy ()
39 {
40 if (_pool.ptr ()) {
41 _pool->release (_data);
42 }
43 _data.release ();
44 }
45
46 uint8_t *
map()47 BufferProxy::map ()
48 {
49 XCAM_ASSERT (_data.ptr ());
50 return _data->map ();
51 }
52
53 bool
unmap()54 BufferProxy::unmap ()
55 {
56 XCAM_ASSERT (_data.ptr ());
57 return _data->unmap ();
58 }
59
60 int
get_fd()61 BufferProxy::get_fd ()
62 {
63 XCAM_ASSERT (_data.ptr ());
64 return _data->get_fd ();
65 }
66
BufferPool()67 BufferPool::BufferPool ()
68 : _allocated_num (0)
69 , _max_count (0)
70 , _started (false)
71 {
72 }
73
~BufferPool()74 BufferPool::~BufferPool ()
75 {
76 }
77
78 bool
set_video_info(const VideoBufferInfo & info)79 BufferPool::set_video_info (const VideoBufferInfo &info)
80 {
81 VideoBufferInfo new_info = info;
82 SmartLock lock (_mutex);
83
84 XCAM_FAIL_RETURN (
85 ERROR,
86 fixate_video_info (new_info),
87 false,
88 "BufferPool fixate video info failed");
89 update_video_info_unsafe (new_info);
90 return true;
91 }
92
93 void
update_video_info_unsafe(const VideoBufferInfo & info)94 BufferPool::update_video_info_unsafe (const VideoBufferInfo &info)
95 {
96 _buffer_info = info;
97 }
98
99 bool
reserve(uint32_t max_count)100 BufferPool::reserve (uint32_t max_count)
101 {
102 uint32_t i = 0;
103
104 XCAM_ASSERT (max_count);
105
106 SmartLock lock (_mutex);
107
108 for (i = _allocated_num; i < max_count; ++i) {
109 SmartPtr<BufferData> new_data = allocate_data (_buffer_info);
110 if (!new_data.ptr ())
111 break;
112 _buf_list.push (new_data);
113 }
114
115 XCAM_FAIL_RETURN (
116 ERROR,
117 i > 0,
118 false,
119 "BufferPool reserve failed with none buffer data allocated");
120
121 if (i != max_count) {
122 XCAM_LOG_WARNING ("BufferPool expect to reserve %d data but only reserved %d", max_count, i);
123 }
124 _max_count = i;
125 _allocated_num = _max_count;
126 _started = true;
127
128 return true;
129 }
130
131 bool
add_data_unsafe(const SmartPtr<BufferData> & data)132 BufferPool::add_data_unsafe (const SmartPtr<BufferData> &data)
133 {
134 if (!data.ptr ())
135 return false;
136
137 _buf_list.push (data);
138 ++_allocated_num;
139
140 XCAM_ASSERT (_allocated_num <= _max_count || !_max_count);
141 return true;
142 }
143
144 SmartPtr<VideoBuffer>
get_buffer(const SmartPtr<BufferPool> & self)145 BufferPool::get_buffer (const SmartPtr<BufferPool> &self)
146 {
147 SmartPtr<BufferProxy> ret_buf;
148 SmartPtr<BufferData> data;
149
150 {
151 SmartLock lock (_mutex);
152 if (!_started)
153 return NULL;
154 }
155
156 XCAM_ASSERT (self.ptr () == this);
157 XCAM_FAIL_RETURN(
158 WARNING,
159 self.ptr () == this,
160 NULL,
161 "BufferPool get_buffer failed since parameter<self> not this");
162
163 data = _buf_list.pop ();
164 if (!data.ptr ()) {
165 XCAM_LOG_DEBUG ("BufferPool failed to get buffer");
166 return NULL;
167 }
168 ret_buf = create_buffer_from_data (data);
169 ret_buf->set_buf_pool (self);
170
171 return ret_buf;
172 }
173
174 SmartPtr<VideoBuffer>
get_buffer()175 BufferPool::get_buffer ()
176 {
177 return get_buffer (SmartPtr<BufferPool>(this));
178 }
179
180 void
stop()181 BufferPool::stop ()
182 {
183 {
184 SmartLock lock (_mutex);
185 _started = false;
186 }
187 _buf_list.pause_pop ();
188 }
189
190 void
release(SmartPtr<BufferData> & data)191 BufferPool::release (SmartPtr<BufferData> &data)
192 {
193 {
194 SmartLock lock (_mutex);
195 if (!_started)
196 return;
197 }
198 _buf_list.push (data);
199 }
200
201 bool
fixate_video_info(VideoBufferInfo & info)202 BufferPool::fixate_video_info (VideoBufferInfo &info)
203 {
204 XCAM_UNUSED (info);
205 return true;
206 }
207
208 SmartPtr<BufferProxy>
create_buffer_from_data(SmartPtr<BufferData> & data)209 BufferPool::create_buffer_from_data (SmartPtr<BufferData> &data)
210 {
211 const VideoBufferInfo &info = get_video_info ();
212
213 XCAM_ASSERT (data.ptr ());
214 return new BufferProxy (info, data);
215 }
216
217 };
218