@@ -105,6 +105,16 @@ class Vc4CameraData final : public RPi::CameraData
105105 * minTotalUnicamBuffers >= minUnicamBuffers
106106 */
107107 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;
108118 };
109119
110120 Config config_;
@@ -219,42 +229,74 @@ bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator)
219229int PipelineHandlerVc4::prepareBuffers (Camera *camera)
220230{
221231 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 ;
223235 int ret;
224236
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+ }
229254 }
230255 }
231256
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+
232273 /* Decide how many internal buffers to allocate. */
233274 for (auto const stream : data->streams_ ) {
234275 unsigned int numBuffers;
235276 /*
236277 * For Unicam, allocate a minimum number of buffers for internal
237278 * use as we want to avoid any frame drops.
238279 */
239- const unsigned int minBuffers = data->config_ .minTotalUnicamBuffers ;
240280 if (stream == &data->unicam_ [Unicam::Image]) {
241281 /*
242282 * If an application has configured a RAW stream, allocate
243283 * additional buffers to make up the minimum, but ensure
244284 * we have at least minUnicamBuffers of internal buffers
245285 * to use to minimise frame drops.
246286 */
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;
249290 } else if (stream == &data->isp_ [Isp::Input]) {
250291 /*
251292 * ISP input buffers are imported from Unicam, so follow
252293 * similar logic as above to count all the RAW buffers
253294 * available.
254295 */
255296 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;
258300
259301 } else if (stream == &data->unicam_ [Unicam::Embedded]) {
260302 /*
@@ -273,14 +315,18 @@ int PipelineHandlerVc4::prepareBuffers(Camera *camera)
273315 * buffers, as these will be recycled quicker.
274316 */
275317 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;
276322 } else {
277323 /*
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.
282327 */
283328 numBuffers = 1 ;
329+ LOG (RPI, Debug) << " Other numBuffers " << numBuffers;
284330 }
285331
286332 ret = stream->prepareBuffers (numBuffers);
@@ -484,6 +530,8 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &
484530 config_ = {
485531 .minUnicamBuffers = 2 ,
486532 .minTotalUnicamBuffers = 4 ,
533+ .rawMandatoryStream = false ,
534+ .output0MandatoryStream = false ,
487535 };
488536
489537 if (!root)
@@ -507,6 +555,10 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &
507555 phConfig[" min_unicam_buffers" ].get <unsigned int >(config_.minUnicamBuffers );
508556 config_.minTotalUnicamBuffers =
509557 phConfig[" min_total_unicam_buffers" ].get <unsigned int >(config_.minTotalUnicamBuffers );
558+ config_.rawMandatoryStream =
559+ phConfig[" raw_mandatory_stream" ].get <bool >(config_.rawMandatoryStream );
560+ config_.output0MandatoryStream =
561+ phConfig[" output0_mandatory_stream" ].get <bool >(config_.output0MandatoryStream );
510562
511563 if (config_.minTotalUnicamBuffers < config_.minUnicamBuffers ) {
512564 LOG (RPI, Error) << " Invalid configuration: min_total_unicam_buffers must be >= min_unicam_buffers" ;
0 commit comments