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