• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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