/* * 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 <feng.yuan@intel.com> */ #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); } };