225 lines
6.6 KiB
C++
225 lines
6.6 KiB
C++
/*
|
|
* Copyright (C) 2016-2017 Intel Corporation.
|
|
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#define LOG_TAG "RKISP2FrameWorker"
|
|
|
|
#include "RKISP2FrameWorker.h"
|
|
#include "Camera3GFXFormat.h"
|
|
#include <sys/mman.h>
|
|
|
|
namespace android {
|
|
namespace camera2 {
|
|
namespace rkisp2 {
|
|
|
|
RKISP2FrameWorker::RKISP2FrameWorker(std::shared_ptr<V4L2VideoNode> node,
|
|
int cameraId, size_t pipelineDepth, std::string name) :
|
|
RKISP2IDeviceWorker(cameraId),
|
|
mIndex(0),
|
|
mName(name),
|
|
mNode(node),
|
|
mIsStarted(false),
|
|
mPollMe(false),
|
|
mPipelineDepth(pipelineDepth)
|
|
{
|
|
}
|
|
|
|
RKISP2FrameWorker::~RKISP2FrameWorker()
|
|
{
|
|
}
|
|
|
|
status_t RKISP2FrameWorker::attachNode(std::shared_ptr<V4L2VideoNode> node)
|
|
{
|
|
if(node.get() != NULL) {
|
|
LOGI("@%s :%s attach to node(%p) %s", __FUNCTION__, mName.c_str(), node.get(), node->name());
|
|
mNode = node;
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
status_t RKISP2FrameWorker::configure(bool configChanged)
|
|
{
|
|
return OK;
|
|
}
|
|
|
|
status_t RKISP2FrameWorker::startWorker(int initialSkips)
|
|
{
|
|
HAL_TRACE_CALL(CAM_GLBL_DBG_HIGH);
|
|
|
|
|
|
LOGI("@%s enter, %s, mIsStarted:%d", __FUNCTION__, mName.c_str(), mIsStarted);
|
|
if (mIsStarted == true)
|
|
return OK;
|
|
|
|
status_t ret = mNode->start(0);
|
|
if (ret != OK) {
|
|
LOGE("Unable to start device: %s ret: %d", mNode->name(), ret);
|
|
}
|
|
mIsStarted = true;
|
|
|
|
V4L2BufferInfo outBuf;
|
|
int index;
|
|
fd_set fds;
|
|
struct timeval tv;
|
|
int res;
|
|
|
|
ALOGI("@%s enter, %s, skipFrames: %d.", __FUNCTION__, mName.c_str(), initialSkips);
|
|
if (mNode->getBufsInDeviceCount() == 0) {
|
|
LOGE("@%s: devices: %s, mBuffersInDevice is 0, can't skip!", __FUNCTION__, mName.c_str());
|
|
return NO_ERROR;
|
|
}
|
|
|
|
FD_ZERO(&fds);
|
|
FD_SET(mNode->getFd(), &fds);
|
|
|
|
/* Timeout. */
|
|
tv.tv_sec = 3;
|
|
tv.tv_usec = 0;
|
|
|
|
for (int i = 0; i < initialSkips; i++) {
|
|
res = select(mNode->getFd() + 1, &fds, NULL, NULL, &tv);
|
|
if (res <= 0) {
|
|
LOGE("@%s(%d) error select or select time out!!",__FUNCTION__,__LINE__);
|
|
return 0;
|
|
}
|
|
index = mNode->grabFrame(&outBuf);
|
|
ALOGI("device: %s, grabFrame buf index(%d)!", mNode->name(), index);
|
|
ret = mNode->putFrame(outBuf.vbuffer);
|
|
if (ret != OK) {
|
|
LOGE("Unable to putFrame from device: %s ret: %d", mNode->name(), ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
status_t RKISP2FrameWorker::flushWorker()
|
|
{
|
|
LOGI("@%s enter, %s", __FUNCTION__, mName.c_str());
|
|
mMsg = nullptr;
|
|
return OK;
|
|
}
|
|
|
|
status_t RKISP2FrameWorker::stopWorker()
|
|
{
|
|
LOGI("@%s enter, %s, mIsStarted:%d", __FUNCTION__, mName.c_str(), mIsStarted);
|
|
if (mIsStarted == false)
|
|
return OK;
|
|
|
|
mMsg = nullptr;
|
|
mBuffers.clear();
|
|
mCameraBuffers.clear();
|
|
//stream_off and destory the buffer pool
|
|
status_t ret = mNode->stop();
|
|
if (ret != OK) {
|
|
LOGE("stop device failed: %s ret: %d", mNode->name(), ret);
|
|
}
|
|
mIsStarted = false;
|
|
return ret;
|
|
}
|
|
|
|
status_t RKISP2FrameWorker::setWorkerDeviceFormat(FrameInfo &frame)
|
|
{
|
|
HAL_TRACE_CALL(CAM_GLBL_DBG_HIGH);
|
|
LOGI("@%s enter, %s", __FUNCTION__, mName.c_str());
|
|
|
|
status_t ret = mNode->setFormat(frame);
|
|
CheckError(ret != NO_ERROR, ret, "@%s set worker format failed", __FUNCTION__);
|
|
ret = mNode->getFormat(mFormat);
|
|
CheckError(ret != NO_ERROR, ret, "@%s get worker format failed", __FUNCTION__);
|
|
|
|
return OK;
|
|
}
|
|
|
|
status_t RKISP2FrameWorker::setWorkerDeviceBuffers(int memType, bool cached)
|
|
{
|
|
LOGI("@%s enter, %s", __FUNCTION__, mName.c_str());
|
|
for (unsigned int i = 0; i < mPipelineDepth; i++) {
|
|
V4L2Buffer buffer;
|
|
mBuffers.push_back(buffer);
|
|
}
|
|
status_t ret = mNode->setBufferPool(mBuffers, cached, memType);
|
|
if (ret != OK) {
|
|
LOGE("Unable to set buffer pool, ret = %d", ret);
|
|
return ret;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
status_t RKISP2FrameWorker::allocateWorkerBuffers()
|
|
{
|
|
int memType = mNode->getMemoryType();
|
|
int dmaBufFd;
|
|
unsigned long userptr;
|
|
std::shared_ptr<CameraBuffer> buf = nullptr;
|
|
LOGD("@%s allocate format: %s size: %d %dx%d bytesperline: %d, memType(%d)", __func__, v4l2Fmt2Str(mFormat.pixelformat()),
|
|
mFormat.sizeimage(), mFormat.width(), mFormat.height(), mFormat.bytesperline(), memType);
|
|
for (unsigned int i = 0; i < mPipelineDepth; i++) {
|
|
switch (memType) {
|
|
case V4L2_MEMORY_USERPTR:
|
|
buf = MemoryUtils::allocateHeapBuffer(mFormat.width(),
|
|
mFormat.height(),
|
|
mFormat.bytesperline(),
|
|
mFormat.pixelformat(),
|
|
mCameraId,
|
|
PAGE_ALIGN(mFormat.sizeimage()));
|
|
if (buf.get() == nullptr)
|
|
return NO_MEMORY;
|
|
userptr = reinterpret_cast<unsigned long>(buf->data());
|
|
mBuffers[i].setUserptr(userptr);
|
|
memset(buf->data(), 0, buf->size());
|
|
LOGD("mBuffers[%d].userptr: 0x%lx", i , mBuffers[i].userptr());
|
|
break;
|
|
case V4L2_MEMORY_MMAP:
|
|
{
|
|
int prot = 0;
|
|
dmaBufFd = mNode->exportFrame(i);
|
|
if (mFormat.pixelformat() == V4L2_META_FMT_RK_ISP1_PARAMS)
|
|
prot = PROT_READ | PROT_WRITE;
|
|
else
|
|
prot = PROT_READ;
|
|
mNode->putFrame(i);
|
|
buf = std::make_shared<CameraBuffer>(mFormat.width(),
|
|
mFormat.height(),
|
|
mFormat.bytesperline(),
|
|
mNode->getFd(),
|
|
dmaBufFd,
|
|
mBuffers[i].length(),
|
|
mFormat.pixelformat(),
|
|
mBuffers[i].offset(), prot, MAP_SHARED);
|
|
if (buf.get() == nullptr)
|
|
return BAD_VALUE;
|
|
}
|
|
break;
|
|
default:
|
|
LOGE("@%s Unsupported memory type %d", __func__, memType);
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
mBuffers[i].setBytesused(mFormat.sizeimage());
|
|
mCameraBuffers.push_back(buf);
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
} /* namespace rkisp2 */
|
|
} /* namespace camera2 */
|
|
} /* namespace android */
|
|
|