@@ -104,6 +104,16 @@ class Vc4CameraData final : public RPi::CameraData
104
104
* minTotalUnicamBuffers >= minUnicamBuffers
105
105
*/
106
106
unsigned int minTotalUnicamBuffers;
107
+ /*
108
+ * The application will always provide a request buffer for the
109
+ * RAW stream, if it has been configured.
110
+ */
111
+ bool rawMandatoryStream;
112
+ /*
113
+ * The application will always provide a request buffer for the
114
+ * Output 0 stream, if it has been configured.
115
+ */
116
+ bool output0MandatoryStream;
107
117
};
108
118
109
119
Config config_;
@@ -218,42 +228,74 @@ bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator)
218
228
int PipelineHandlerVc4::prepareBuffers (Camera *camera)
219
229
{
220
230
Vc4CameraData *data = cameraData (camera);
221
- unsigned int numRawBuffers = 0 ;
231
+ unsigned int minUnicamBuffers = data->config_ .minUnicamBuffers ;
232
+ unsigned int minTotalUnicamBuffers = data->config_ .minTotalUnicamBuffers ;
233
+ unsigned int numRawBuffers = 0 , minIspBuffers = 1 ;
222
234
int ret;
223
235
224
- for (Stream *s : camera->streams ()) {
225
- if (BayerFormat::fromPixelFormat (s->configuration ().pixelFormat ).isValid ()) {
226
- numRawBuffers = s->configuration ().bufferCount ;
227
- break ;
236
+ if (data->unicam_ [Unicam::Image].getFlags () & StreamFlag::External) {
237
+ numRawBuffers = data->unicam_ [Unicam::Image].getBuffers ().size ();
238
+ /*
239
+ * If the application provides a guarantees that Unicam
240
+ * image buffers will always be provided for the RAW stream
241
+ * in a Request, we need:
242
+ * - at least 1 internal Unicam buffer to handle startup frame drops,
243
+ * - no internal Unicam buffers if there are no startup frame drops.
244
+ */
245
+ if (data->config_ .rawMandatoryStream ) {
246
+ if (data->dropFrameCount_ ) {
247
+ minUnicamBuffers = 2 ;
248
+ minTotalUnicamBuffers = 2 ;
249
+ } else {
250
+ minUnicamBuffers = 0 ;
251
+ minTotalUnicamBuffers = 0 ;
252
+ }
228
253
}
229
254
}
230
255
256
+ if (data->isp_ [Isp::Output0].getFlags () & StreamFlag::External) {
257
+ /*
258
+ * Since the ISP runs synchronous with the IPA and requests,
259
+ * we only ever need a maximum of one internal buffer. Any
260
+ * buffers the application wants to hold onto will already
261
+ * be exported through PipelineHandlerRPi::exportFrameBuffers().
262
+ *
263
+ * However, as above, if the application provides a guarantee
264
+ * that the buffer will always be provided for the ISP Output0
265
+ * stream in a Request, we don't need any internal buffers
266
+ * allocated.
267
+ */
268
+ if (!data->dropFrameCount_ && data->config_ .output0MandatoryStream )
269
+ minIspBuffers = 0 ;
270
+ }
271
+
231
272
/* Decide how many internal buffers to allocate. */
232
273
for (auto const stream : data->streams_ ) {
233
274
unsigned int numBuffers;
234
275
/*
235
276
* For Unicam, allocate a minimum number of buffers for internal
236
277
* use as we want to avoid any frame drops.
237
278
*/
238
- const unsigned int minBuffers = data->config_ .minTotalUnicamBuffers ;
239
279
if (stream == &data->unicam_ [Unicam::Image]) {
240
280
/*
241
281
* If an application has configured a RAW stream, allocate
242
282
* additional buffers to make up the minimum, but ensure
243
283
* we have at least minUnicamBuffers of internal buffers
244
284
* to use to minimise frame drops.
245
285
*/
246
- numBuffers = std::max<int >(data->config_ .minUnicamBuffers ,
247
- minBuffers - numRawBuffers);
286
+ numBuffers = std::max<int >(minUnicamBuffers,
287
+ minTotalUnicamBuffers - numRawBuffers);
288
+ LOG (RPI, Debug) << " Unicam::Image numBuffers " << numBuffers;
248
289
} else if (stream == &data->isp_ [Isp::Input]) {
249
290
/*
250
291
* ISP input buffers are imported from Unicam, so follow
251
292
* similar logic as above to count all the RAW buffers
252
293
* available.
253
294
*/
254
295
numBuffers = numRawBuffers +
255
- std::max<int >(data->config_ .minUnicamBuffers ,
256
- minBuffers - numRawBuffers);
296
+ std::max<int >(minUnicamBuffers,
297
+ minTotalUnicamBuffers - numRawBuffers);
298
+ LOG (RPI, Debug) << " Isp::Input numBuffers " << numBuffers;
257
299
258
300
} else if (stream == &data->unicam_ [Unicam::Embedded]) {
259
301
/*
@@ -272,14 +314,18 @@ int PipelineHandlerVc4::prepareBuffers(Camera *camera)
272
314
* buffers, as these will be recycled quicker.
273
315
*/
274
316
numBuffers = 12 ;
317
+ } else if (stream == &data->isp_ [Isp::Output0]) {
318
+ /* Buffer count for this is handled in the earlier loop above. */
319
+ numBuffers = minIspBuffers;
320
+ LOG (RPI, Debug) << " Isp::Output0 numBuffers " << numBuffers;
275
321
} else {
276
322
/*
277
- * Since the ISP runs synchronous with the IPA and requests,
278
- * we only ever need one set of internal buffers. Any buffers
279
- * the application wants to hold onto will already be exported
280
- * through PipelineHandlerRPi::exportFrameBuffers().
323
+ * Same reasoning as for ISP Output 0, we only ever need
324
+ * a maximum of one internal buffer for Output1 (required
325
+ * for colour denoise) and ISP statistics.
281
326
*/
282
327
numBuffers = 1 ;
328
+ LOG (RPI, Debug) << " Other numBuffers " << numBuffers;
283
329
}
284
330
285
331
LOG (RPI, Debug) << " Preparing " << numBuffers
@@ -497,6 +543,8 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &
497
543
config_ = {
498
544
.minUnicamBuffers = 2 ,
499
545
.minTotalUnicamBuffers = 4 ,
546
+ .rawMandatoryStream = false ,
547
+ .output0MandatoryStream = false ,
500
548
};
501
549
502
550
if (!root)
@@ -520,6 +568,10 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &
520
568
phConfig[" min_unicam_buffers" ].get <unsigned int >(config_.minUnicamBuffers );
521
569
config_.minTotalUnicamBuffers =
522
570
phConfig[" min_total_unicam_buffers" ].get <unsigned int >(config_.minTotalUnicamBuffers );
571
+ config_.rawMandatoryStream =
572
+ phConfig[" raw_mandatory_stream" ].get <bool >(config_.rawMandatoryStream );
573
+ config_.output0MandatoryStream =
574
+ phConfig[" output0_mandatory_stream" ].get <bool >(config_.output0MandatoryStream );
523
575
524
576
if (config_.minTotalUnicamBuffers < config_.minUnicamBuffers ) {
525
577
LOG (RPI, Error) << " Invalid configuration: min_total_unicam_buffers must be >= min_unicam_buffers" ;
0 commit comments