Skip to content

Commit c8f6376

Browse files
fsylvestrepinchartl
authored andcommitted
pipeline: rkisp1: Support raw Bayer capture at runtime
Implement support for raw Bayer capture at runtime, from start() to stop(). Support of raw formats in the camera configuration is split to a subsequent change to ease review. In raw mode, the ISP is bypassed. There is no need to provide parameter buffers, and the ISP will not generate statistics. This requires multiple changes in the buffer handling: - The params and stats buffers don't need to be allocated, and the corresponding video nodes don't need to be started or stopped. - The IPA module fillParamsBuffer() operation must not be called in queueRequestDevice(). As a result, the IPA module thus doesn't emit the paramsBufferReady signal. The main and self path video buffers must thus be queued directly in queueRequestDevice(). - The tryCompleteRequest() function must not to wait until the params buffer has been dequeued. - When the frame buffer has been captured, the IPA module processStatsBuffer() operation must be called directly to fill request metadata. Signed-off-by: Florian Sylvestre <[email protected]> Signed-off-by: Paul Elder <[email protected]> Signed-off-by: Laurent Pinchart <[email protected]> Reviewed-by: Paul Elder <[email protected]> Tested-by: Jacopo Mondi <[email protected]> Reviewed-by: Jacopo Mondi <[email protected]>
1 parent 2447d14 commit c8f6376

File tree

1 file changed

+93
-55
lines changed

1 file changed

+93
-55
lines changed

src/libcamera/pipeline/rkisp1/rkisp1.cpp

Lines changed: 93 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ class RkISP1Frames
6767
public:
6868
RkISP1Frames(PipelineHandler *pipe);
6969

70-
RkISP1FrameInfo *create(const RkISP1CameraData *data, Request *request);
70+
RkISP1FrameInfo *create(const RkISP1CameraData *data, Request *request,
71+
bool isRaw);
7172
int destroy(unsigned int frame);
7273
void clear();
7374

@@ -184,6 +185,7 @@ class PipelineHandlerRkISP1 : public PipelineHandler
184185
std::unique_ptr<V4L2Subdevice> csi_;
185186

186187
bool hasSelfPath_;
188+
bool isRaw_;
187189

188190
RkISP1MainPath mainPath_;
189191
RkISP1SelfPath selfPath_;
@@ -203,28 +205,35 @@ RkISP1Frames::RkISP1Frames(PipelineHandler *pipe)
203205
{
204206
}
205207

206-
RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request)
208+
RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request,
209+
bool isRaw)
207210
{
208211
unsigned int frame = data->frame_;
209212

210-
if (pipe_->availableParamBuffers_.empty()) {
211-
LOG(RkISP1, Error) << "Parameters buffer underrun";
212-
return nullptr;
213-
}
214-
FrameBuffer *paramBuffer = pipe_->availableParamBuffers_.front();
213+
FrameBuffer *paramBuffer = nullptr;
214+
FrameBuffer *statBuffer = nullptr;
215215

216-
if (pipe_->availableStatBuffers_.empty()) {
217-
LOG(RkISP1, Error) << "Statisitc buffer underrun";
218-
return nullptr;
216+
if (!isRaw) {
217+
if (pipe_->availableParamBuffers_.empty()) {
218+
LOG(RkISP1, Error) << "Parameters buffer underrun";
219+
return nullptr;
220+
}
221+
222+
if (pipe_->availableStatBuffers_.empty()) {
223+
LOG(RkISP1, Error) << "Statisitc buffer underrun";
224+
return nullptr;
225+
}
226+
227+
paramBuffer = pipe_->availableParamBuffers_.front();
228+
pipe_->availableParamBuffers_.pop();
229+
230+
statBuffer = pipe_->availableStatBuffers_.front();
231+
pipe_->availableStatBuffers_.pop();
219232
}
220-
FrameBuffer *statBuffer = pipe_->availableStatBuffers_.front();
221233

222234
FrameBuffer *mainPathBuffer = request->findBuffer(&data->mainPathStream_);
223235
FrameBuffer *selfPathBuffer = request->findBuffer(&data->selfPathStream_);
224236

225-
pipe_->availableParamBuffers_.pop();
226-
pipe_->availableStatBuffers_.pop();
227-
228237
RkISP1FrameInfo *info = new RkISP1FrameInfo;
229238

230239
info->frame = frame;
@@ -672,6 +681,8 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
672681
<< "ISP input pad configured with " << format
673682
<< " crop " << rect;
674683

684+
isRaw_ = false;
685+
675686
/* YUYV8_2X8 is required on the ISP source path pad for YUV output. */
676687
format.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8;
677688
LOG(RkISP1, Debug)
@@ -764,13 +775,15 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)
764775
data->selfPathStream_.configuration().bufferCount,
765776
});
766777

767-
ret = param_->allocateBuffers(maxCount, &paramBuffers_);
768-
if (ret < 0)
769-
goto error;
778+
if (!isRaw_) {
779+
ret = param_->allocateBuffers(maxCount, &paramBuffers_);
780+
if (ret < 0)
781+
goto error;
770782

771-
ret = stat_->allocateBuffers(maxCount, &statBuffers_);
772-
if (ret < 0)
773-
goto error;
783+
ret = stat_->allocateBuffers(maxCount, &statBuffers_);
784+
if (ret < 0)
785+
goto error;
786+
}
774787

775788
for (std::unique_ptr<FrameBuffer> &buffer : paramBuffers_) {
776789
buffer->setCookie(ipaBufferId++);
@@ -846,23 +859,25 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL
846859

847860
data->frame_ = 0;
848861

849-
ret = param_->streamOn();
850-
if (ret) {
851-
data->ipa_->stop();
852-
freeBuffers(camera);
853-
LOG(RkISP1, Error)
854-
<< "Failed to start parameters " << camera->id();
855-
return ret;
856-
}
862+
if (!isRaw_) {
863+
ret = param_->streamOn();
864+
if (ret) {
865+
data->ipa_->stop();
866+
freeBuffers(camera);
867+
LOG(RkISP1, Error)
868+
<< "Failed to start parameters " << camera->id();
869+
return ret;
870+
}
857871

858-
ret = stat_->streamOn();
859-
if (ret) {
860-
param_->streamOff();
861-
data->ipa_->stop();
862-
freeBuffers(camera);
863-
LOG(RkISP1, Error)
864-
<< "Failed to start statistics " << camera->id();
865-
return ret;
872+
ret = stat_->streamOn();
873+
if (ret) {
874+
param_->streamOff();
875+
data->ipa_->stop();
876+
freeBuffers(camera);
877+
LOG(RkISP1, Error)
878+
<< "Failed to start statistics " << camera->id();
879+
return ret;
880+
}
866881
}
867882

868883
if (data->mainPath_->isEnabled()) {
@@ -907,15 +922,17 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera)
907922
selfPath_.stop();
908923
mainPath_.stop();
909924

910-
ret = stat_->streamOff();
911-
if (ret)
912-
LOG(RkISP1, Warning)
913-
<< "Failed to stop statistics for " << camera->id();
925+
if (!isRaw_) {
926+
ret = stat_->streamOff();
927+
if (ret)
928+
LOG(RkISP1, Warning)
929+
<< "Failed to stop statistics for " << camera->id();
914930

915-
ret = param_->streamOff();
916-
if (ret)
917-
LOG(RkISP1, Warning)
918-
<< "Failed to stop parameters for " << camera->id();
931+
ret = param_->streamOff();
932+
if (ret)
933+
LOG(RkISP1, Warning)
934+
<< "Failed to stop parameters for " << camera->id();
935+
}
919936

920937
ASSERT(data->queuedRequests_.empty());
921938
data->frameInfo_.clear();
@@ -929,12 +946,21 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
929946
{
930947
RkISP1CameraData *data = cameraData(camera);
931948

932-
RkISP1FrameInfo *info = data->frameInfo_.create(data, request);
949+
RkISP1FrameInfo *info = data->frameInfo_.create(data, request, isRaw_);
933950
if (!info)
934951
return -ENOENT;
935952

936953
data->ipa_->queueRequest(data->frame_, request->controls());
937-
data->ipa_->fillParamsBuffer(data->frame_, info->paramBuffer->cookie());
954+
if (isRaw_) {
955+
if (info->mainPathBuffer)
956+
data->mainPath_->queueBuffer(info->mainPathBuffer);
957+
958+
if (data->selfPath_ && info->selfPathBuffer)
959+
data->selfPath_->queueBuffer(info->selfPathBuffer);
960+
} else {
961+
data->ipa_->fillParamsBuffer(data->frame_,
962+
info->paramBuffer->cookie());
963+
}
938964

939965
data->frame_++;
940966

@@ -1139,7 +1165,7 @@ void PipelineHandlerRkISP1::tryCompleteRequest(RkISP1FrameInfo *info)
11391165
if (!info->metadataProcessed)
11401166
return;
11411167

1142-
if (!info->paramDequeued)
1168+
if (!isRaw_ && !info->paramDequeued)
11431169
return;
11441170

11451171
data->frameInfo_.destroy(info->frame);
@@ -1156,16 +1182,28 @@ void PipelineHandlerRkISP1::bufferReady(FrameBuffer *buffer)
11561182
if (!info)
11571183
return;
11581184

1185+
const FrameMetadata &metadata = buffer->metadata();
11591186
Request *request = buffer->request();
11601187

1161-
/*
1162-
* Record the sensor's timestamp in the request metadata.
1163-
*
1164-
* \todo The sensor timestamp should be better estimated by connecting
1165-
* to the V4L2Device::frameStart signal.
1166-
*/
1167-
request->metadata().set(controls::SensorTimestamp,
1168-
buffer->metadata().timestamp);
1188+
if (metadata.status != FrameMetadata::FrameCancelled) {
1189+
/*
1190+
* Record the sensor's timestamp in the request metadata.
1191+
*
1192+
* \todo The sensor timestamp should be better estimated by connecting
1193+
* to the V4L2Device::frameStart signal.
1194+
*/
1195+
request->metadata().set(controls::SensorTimestamp,
1196+
metadata.timestamp);
1197+
1198+
if (isRaw_) {
1199+
const ControlList &ctrls =
1200+
data->delayedCtrls_->get(metadata.sequence);
1201+
data->ipa_->processStatsBuffer(info->frame, 0, ctrls);
1202+
}
1203+
} else {
1204+
if (isRaw_)
1205+
info->metadataProcessed = true;
1206+
}
11691207

11701208
completeBuffer(request, buffer);
11711209
tryCompleteRequest(info);

0 commit comments

Comments
 (0)