/*
* fake_poll_thread.cpp - poll thread for raw image
*
* 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: Jia Meng <jia.meng@intel.com>
*/
#include "fake_poll_thread.h"
#if HAVE_LIBDRM
#include "drm_bo_buffer.h"
#endif
#define DEFAULT_FPT_BUF_COUNT 4
namespace XCam {
FakePollThread::FakePollThread (const char *raw_path)
: _raw_path (NULL)
, _raw (NULL)
{
XCAM_ASSERT (raw_path);
if (raw_path)
_raw_path = strndup (raw_path, XCAM_MAX_STR_SIZE);
}
FakePollThread::~FakePollThread ()
{
if (_raw_path)
xcam_free (_raw_path);
if (_raw)
fclose (_raw);
}
XCamReturn
FakePollThread::start()
{
XCAM_FAIL_RETURN(
ERROR,
_raw_path,
XCAM_RETURN_ERROR_FILE,
"FakePollThread failed due to raw path NULL");
_raw = fopen (_raw_path, "rb");
XCAM_FAIL_RETURN(
ERROR,
_raw,
XCAM_RETURN_ERROR_FILE,
"FakePollThread failed to open file:%s", XCAM_STR (_raw_path));
return PollThread::start ();
}
XCamReturn
FakePollThread::stop ()
{
if (_buf_pool.ptr ())
_buf_pool->stop ();
return PollThread::stop ();;
}
XCamReturn
FakePollThread::read_buf (SmartPtr<VideoBuffer> &buf)
{
uint8_t *dst = buf->map ();
const VideoBufferInfo info = buf->get_video_info ();
VideoBufferPlanarInfo planar;
XCamReturn ret = XCAM_RETURN_NO_ERROR;
for (uint32_t index = 0; index < info.components; index++) {
info.get_planar_info(planar, index);
uint32_t line_bytes = planar.width * planar.pixel_bytes;
for (uint32_t i = 0; i < planar.height; i++) {
if (fread (dst + info.offsets [index] + i * info.strides [index], 1, line_bytes, _raw) < line_bytes) {
if (feof (_raw)) {
fseek (_raw, 0, SEEK_SET);
ret = XCAM_RETURN_BYPASS;
} else {
XCAM_LOG_ERROR ("poll_buffer_loop failed to read file");
ret = XCAM_RETURN_ERROR_FILE;
}
goto done;
}
}
}
done:
buf->unmap ();
return ret;
}
XCamReturn
FakePollThread::poll_buffer_loop ()
{
XCamReturn ret = XCAM_RETURN_NO_ERROR;
if (!_buf_pool.ptr () && init_buffer_pool () != XCAM_RETURN_NO_ERROR)
return XCAM_RETURN_ERROR_MEM;
SmartPtr<VideoBuffer> buf = _buf_pool->get_buffer (_buf_pool);
if (!buf.ptr ()) {
XCAM_LOG_WARNING ("FakePollThread get buffer failed");
return XCAM_RETURN_ERROR_MEM;
}
ret = read_buf (buf);
if (ret == XCAM_RETURN_BYPASS) {
ret = read_buf (buf);
}
SmartPtr<VideoBuffer> video_buf = buf;
if (ret == XCAM_RETURN_NO_ERROR && _poll_callback)
return _poll_callback->poll_buffer_ready (video_buf);
return ret;
}
XCamReturn
FakePollThread::init_buffer_pool ()
{
struct v4l2_format format;
if (!_capture_dev.ptr () ||
_capture_dev->get_format (format) != XCAM_RETURN_NO_ERROR) {
XCAM_LOG_ERROR ("Can't init buffer pool without format");
return XCAM_RETURN_ERROR_PARAM;
}
VideoBufferInfo info;
info.init(format.fmt.pix.pixelformat,
format.fmt.pix.width,
format.fmt.pix.height, 0, 0, 0);
#if HAVE_LIBDRM
SmartPtr<DrmDisplay> drm_disp = DrmDisplay::instance ();
_buf_pool = new DrmBoBufferPool (drm_disp);
XCAM_ASSERT (_buf_pool.ptr ());
if (_buf_pool->set_video_info (info) && _buf_pool->reserve (DEFAULT_FPT_BUF_COUNT))
return XCAM_RETURN_NO_ERROR;
#endif
return XCAM_RETURN_ERROR_MEM;
}
};