/*
* 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);
}
};