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

};
