| /* |
| * buffer_pool.cpp - buffer pool |
| * |
| * Copyright (c) 2014-2015 Intel Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * Author: Wind Yuan <[email protected]> |
| */ |
| |
| #include "buffer_pool.h" |
| |
| namespace XCam { |
| |
| BufferProxy::BufferProxy (const VideoBufferInfo &info, const SmartPtr<BufferData> &data) |
| : VideoBuffer (info) |
| , _data (data) |
| { |
| XCAM_ASSERT (data.ptr ()); |
| } |
| |
| BufferProxy::BufferProxy (const SmartPtr<BufferData> &data) |
| : _data (data) |
| { |
| XCAM_ASSERT (data.ptr ()); |
| } |
| |
| BufferProxy::~BufferProxy () |
| { |
| if (_pool.ptr ()) { |
| _pool->release (_data); |
| } |
| _data.release (); |
| } |
| |
| uint8_t * |
| BufferProxy::map () |
| { |
| XCAM_ASSERT (_data.ptr ()); |
| return _data->map (); |
| } |
| |
| bool |
| BufferProxy::unmap () |
| { |
| XCAM_ASSERT (_data.ptr ()); |
| return _data->unmap (); |
| } |
| |
| int |
| BufferProxy::get_fd () |
| { |
| XCAM_ASSERT (_data.ptr ()); |
| return _data->get_fd (); |
| } |
| |
| BufferPool::BufferPool () |
| : _allocated_num (0) |
| , _max_count (0) |
| , _started (false) |
| { |
| } |
| |
| BufferPool::~BufferPool () |
| { |
| } |
| |
| bool |
| BufferPool::set_video_info (const VideoBufferInfo &info) |
| { |
| VideoBufferInfo new_info = info; |
| SmartLock lock (_mutex); |
| |
| XCAM_FAIL_RETURN ( |
| ERROR, |
| fixate_video_info (new_info), |
| false, |
| "BufferPool fixate video info failed"); |
| update_video_info_unsafe (new_info); |
| return true; |
| } |
| |
| void |
| BufferPool::update_video_info_unsafe (const VideoBufferInfo &info) |
| { |
| _buffer_info = info; |
| } |
| |
| bool |
| BufferPool::reserve (uint32_t max_count) |
| { |
| uint32_t i = 0; |
| |
| XCAM_ASSERT (max_count); |
| |
| SmartLock lock (_mutex); |
| |
| for (i = _allocated_num; i < max_count; ++i) { |
| SmartPtr<BufferData> new_data = allocate_data (_buffer_info); |
| if (!new_data.ptr ()) |
| break; |
| _buf_list.push (new_data); |
| } |
| |
| XCAM_FAIL_RETURN ( |
| ERROR, |
| i > 0, |
| false, |
| "BufferPool reserve failed with none buffer data allocated"); |
| |
| if (i != max_count) { |
| XCAM_LOG_WARNING ("BufferPool expect to reserve %d data but only reserved %d", max_count, i); |
| } |
| _max_count = i; |
| _allocated_num = _max_count; |
| _started = true; |
| |
| return true; |
| } |
| |
| bool |
| BufferPool::add_data_unsafe (const SmartPtr<BufferData> &data) |
| { |
| if (!data.ptr ()) |
| return false; |
| |
| _buf_list.push (data); |
| ++_allocated_num; |
| |
| XCAM_ASSERT (_allocated_num <= _max_count || !_max_count); |
| return true; |
| } |
| |
| SmartPtr<VideoBuffer> |
| BufferPool::get_buffer (const SmartPtr<BufferPool> &self) |
| { |
| SmartPtr<BufferProxy> ret_buf; |
| SmartPtr<BufferData> data; |
| |
| { |
| SmartLock lock (_mutex); |
| if (!_started) |
| return NULL; |
| } |
| |
| XCAM_ASSERT (self.ptr () == this); |
| XCAM_FAIL_RETURN( |
| WARNING, |
| self.ptr () == this, |
| NULL, |
| "BufferPool get_buffer failed since parameter<self> not this"); |
| |
| data = _buf_list.pop (); |
| if (!data.ptr ()) { |
| XCAM_LOG_DEBUG ("BufferPool failed to get buffer"); |
| return NULL; |
| } |
| ret_buf = create_buffer_from_data (data); |
| ret_buf->set_buf_pool (self); |
| |
| return ret_buf; |
| } |
| |
| SmartPtr<VideoBuffer> |
| BufferPool::get_buffer () |
| { |
| return get_buffer (SmartPtr<BufferPool>(this)); |
| } |
| |
| void |
| BufferPool::stop () |
| { |
| { |
| SmartLock lock (_mutex); |
| _started = false; |
| } |
| _buf_list.pause_pop (); |
| } |
| |
| void |
| BufferPool::release (SmartPtr<BufferData> &data) |
| { |
| { |
| SmartLock lock (_mutex); |
| if (!_started) |
| return; |
| } |
| _buf_list.push (data); |
| } |
| |
| bool |
| BufferPool::fixate_video_info (VideoBufferInfo &info) |
| { |
| XCAM_UNUSED (info); |
| return true; |
| } |
| |
| SmartPtr<BufferProxy> |
| BufferPool::create_buffer_from_data (SmartPtr<BufferData> &data) |
| { |
| const VideoBufferInfo &info = get_video_info (); |
| |
| XCAM_ASSERT (data.ptr ()); |
| return new BufferProxy (info, data); |
| } |
| |
| }; |