251 lines
8.7 KiB
C++
251 lines
8.7 KiB
C++
/*
|
|
* Copyright (C) 2013-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 "Stream"
|
|
#include <stddef.h>
|
|
|
|
#include "LogHelper.h"
|
|
#include "CameraStream.h"
|
|
#include "PlatformData.h"
|
|
#include "PerformanceTraces.h"
|
|
|
|
NAMESPACE_DECLARATION {
|
|
CameraStream::CameraStream(int seqNo, camera3_stream_t * stream,
|
|
IRequestCallback * callback) : mActive(false),
|
|
mSeqNo(seqNo),
|
|
mCallback(callback),
|
|
mOutputBuffersInHal(0),
|
|
mStream3(stream),
|
|
mFrameCount(0),
|
|
mLastFrameCount(0)
|
|
{
|
|
}
|
|
|
|
CameraStream::~CameraStream()
|
|
{
|
|
LOGI("%s, pending request size=%zu", __FUNCTION__, mPendingRequests.size());
|
|
|
|
std::unique_lock<std::mutex> l(mPendingLock);
|
|
mPendingRequests.clear();
|
|
l.unlock();
|
|
|
|
mCamera3Buffers.clear();
|
|
}
|
|
|
|
void CameraStream::setActive(bool active)
|
|
{
|
|
LOGI("CameraStream [%d] set %s", mSeqNo, active? " Active":" Inactive");
|
|
mActive = active;
|
|
}
|
|
|
|
void CameraStream::dump(bool dumpBuffers) const
|
|
{
|
|
LOGI("Stream %d (IO type %d) dump: -----", mSeqNo, mStream3->stream_type);
|
|
LOGI(" %dx%d, fmt%d usage %x, buffers num %d (available %zu)",
|
|
mStream3->width, mStream3->height,
|
|
mStream3->format,
|
|
mStream3->usage,
|
|
mStream3->max_buffers, mCamera3Buffers.size());
|
|
if (dumpBuffers) {
|
|
for (unsigned int i = 0; i < mCamera3Buffers.size(); i++) {
|
|
LOGI(" %d: handle %p, dataPtr %p", i,
|
|
mCamera3Buffers[i]->getBufferHandle(), mCamera3Buffers[i]->data());
|
|
}
|
|
}
|
|
}
|
|
|
|
status_t CameraStream::query(FrameInfo * info)
|
|
{
|
|
LOGI("%s", __FUNCTION__);
|
|
info->width= mStream3->width;
|
|
info->height= mStream3->height;
|
|
info->format = mStream3->format;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
status_t CameraStream::capture(std::shared_ptr<CameraBuffer> aBuffer,
|
|
Camera3Request* request)
|
|
{
|
|
LOGE("ERROR @%s: this is consumer node is nullptr", __FUNCTION__);
|
|
UNUSED(aBuffer);
|
|
UNUSED(request);
|
|
return NO_ERROR;
|
|
}
|
|
|
|
void CameraStream::showDebugFPS(int streamType)
|
|
{
|
|
double fps = 0;
|
|
mFrameCount++;
|
|
nsecs_t now = systemTime();
|
|
nsecs_t diff = now - mLastFpsTime;
|
|
if ((unsigned long)diff > 1000000000) {
|
|
fps = (((double)(mFrameCount - mLastFrameCount)) *
|
|
(double)(1000000000)) / (double)diff;
|
|
switch(streamType) {
|
|
case STREAM_PREVIEW:
|
|
LOGI("%s: Preview FPS : %.4f: mFrameCount=%d", __func__, fps, mFrameCount);
|
|
LOGI("%s, mPendingRequests size=%zu", __func__, mPendingRequests.size());
|
|
break;
|
|
case STREAM_VIDEO:
|
|
LOGI("%s: Video FPS : %.4f", __func__, fps);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
mLastFpsTime = now;
|
|
mLastFrameCount = mFrameCount;
|
|
}
|
|
}
|
|
|
|
status_t CameraStream::captureDone(std::shared_ptr<CameraBuffer> aBuffer,
|
|
Camera3Request* request)
|
|
{
|
|
std::lock_guard<std::mutex> l(mPendingLock);
|
|
showDebugFPS(mStreamType);
|
|
/* Usually the correct request is found at index 0 in the mPendingRequests
|
|
* Vector, but reprocessing requests are allowed to deviate from the FIFO
|
|
* rule. See camera3.h section "S10.3 Reprocessing pipeline characteristics"
|
|
*
|
|
* The PSL shall be responsible for maintaining per-stream FIFO processing
|
|
* order among all the normal output requests and among the reprocessing
|
|
* requests, but reprocessing requests may be completed before normal output
|
|
* requests.
|
|
*/
|
|
for (uint32_t i = 0; i < mPendingRequests.size(); i++) {
|
|
Camera3Request *pendingRequest;
|
|
pendingRequest = mPendingRequests.at(i);
|
|
if (aBuffer.get() != nullptr && aBuffer->requestId() == pendingRequest->getId()) {
|
|
switch (mStreamType) {
|
|
case STREAM_PREVIEW:
|
|
LOGI("%s:%d: Preview buffer done, instance(%p), requestId(%d), stream:%p", __FUNCTION__, __LINE__, this, pendingRequest->getId(), mStream3);
|
|
break;
|
|
case STREAM_CAPTURE:
|
|
LOGI("%s:%d: Capture buffer done, instance(%p), requestId(%d), stream:%p", __FUNCTION__, __LINE__, this, pendingRequest->getId(), mStream3);
|
|
break;
|
|
case STREAM_VIDEO:
|
|
LOGI("%s:%d: Video buffer done, instance(%p), requestId(%d), stream:%p", __FUNCTION__, __LINE__, this, pendingRequest->getId(), mStream3);
|
|
break;
|
|
case STREAM_ZSL:
|
|
LOGI("%s:%d: zsl buffer done, instance(%p), requestId(%d), stream:%p", __FUNCTION__, __LINE__, this, pendingRequest->getId(), mStream3);
|
|
break;
|
|
default :
|
|
LOGW("%s:%d: Not support the stream type, is a bug, fix me", __FUNCTION__, __LINE__);
|
|
break;
|
|
}
|
|
mPendingRequests.erase(mPendingRequests.begin() + i);
|
|
mCallback->bufferDone(pendingRequest, aBuffer);
|
|
if (pendingRequest != nullptr)
|
|
PERFORMANCE_HAL_ATRACE_PARAM1("seqId", pendingRequest->sequenceId());
|
|
break;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
status_t CameraStream::reprocess(std::shared_ptr<CameraBuffer> aBuffer,
|
|
Camera3Request* request)
|
|
{
|
|
LOGW("@%s: not implemented", __FUNCTION__);
|
|
UNUSED(aBuffer);
|
|
UNUSED(request);
|
|
return NO_ERROR;
|
|
}
|
|
|
|
status_t CameraStream::processRequest(Camera3Request* request)
|
|
{
|
|
LOGD("@%s %d, capture mProducer:%p, mConsumer:%p", __FUNCTION__, mSeqNo, mProducer, mConsumer);
|
|
int status = NO_ERROR;
|
|
std::shared_ptr<CameraBuffer> buffer;
|
|
if (mProducer == nullptr) {
|
|
LOGE("ERROR @%s: mProducer is nullptr", __FUNCTION__);
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
std::unique_lock<std::mutex> l(mPendingLock);
|
|
mPendingRequests.push_back(request);
|
|
l.unlock();
|
|
|
|
buffer = request->findBuffer(this);
|
|
if (CC_UNLIKELY(buffer == nullptr)) {
|
|
LOGE("@%s No buffer associated with stream.", __FUNCTION__);
|
|
return NO_MEMORY;
|
|
}
|
|
status = mProducer->capture(buffer, request);
|
|
|
|
return status;
|
|
}
|
|
|
|
status_t CameraStream::configure(void)
|
|
{
|
|
LOGI("@%s, %d, mProducer:%p (%p)", __FUNCTION__, mSeqNo, mProducer, this);
|
|
if (!mProducer) {
|
|
LOGE("mProducer = nullptr");
|
|
return BAD_VALUE;
|
|
}
|
|
bool display = false;
|
|
bool videoEnc = false;
|
|
bool zsl = false;
|
|
|
|
display = CHECK_FLAG(mStream3->usage, GRALLOC_USAGE_HW_COMPOSER);
|
|
display |= CHECK_FLAG(mStream3->usage, GRALLOC_USAGE_HW_TEXTURE);
|
|
display |= CHECK_FLAG(mStream3->usage, GRALLOC_USAGE_HW_RENDER);
|
|
|
|
videoEnc = CHECK_FLAG(mStream3->usage, GRALLOC_USAGE_HW_VIDEO_ENCODER);
|
|
zsl = CHECK_FLAG(mStream3->usage, GRALLOC_USAGE_HW_CAMERA_ZSL);
|
|
|
|
/* TODO : video stream type should be judged by
|
|
* GRALLOC_USAGE_HW_VIDEO_ENCODER, but now we make a workround that
|
|
* add this usage to all streams for the gpu bug in
|
|
* configStreams@RKISP1CameraHw.cpp*/
|
|
if (mStream3->format == HAL_PIXEL_FORMAT_BLOB) {
|
|
mStreamType = STREAM_CAPTURE;
|
|
} else if (zsl) {
|
|
mStreamType = STREAM_ZSL;
|
|
} else if (display) {
|
|
mStreamType = STREAM_PREVIEW;
|
|
/* } else if (videoEnc) { */
|
|
} else {
|
|
mStreamType = STREAM_VIDEO;
|
|
}
|
|
|
|
LOGI("%s:%d:CameraStream:%p, mstream3:%p, format %d, usage %d, stream type %d", __func__, __LINE__,
|
|
this, mStream3, mStream3->format, mStream3->usage, mStreamType);
|
|
|
|
FrameInfo info;
|
|
mProducer->query(&info);
|
|
if ((info.width == (int)mStream3->width) &&
|
|
(info.height == (int)mStream3->height) &&
|
|
(info.format == mStream3->format)) {
|
|
return NO_ERROR;
|
|
}
|
|
|
|
LOGE("@%s configure error : w %d x h %d F:%d vs w %d x h %d F:%d", __FUNCTION__,
|
|
mStream3->width, mStream3->height, mStream3->format,
|
|
info.width, info.height, info.format);
|
|
return UNKNOWN_ERROR;
|
|
}
|
|
|
|
void CameraStream::dump(int fd) const
|
|
{
|
|
if (mProducer != nullptr)
|
|
mProducer->dump(fd);
|
|
}
|
|
|
|
} NAMESPACE_DECLARATION_END
|
|
|