@@ -104,6 +104,16 @@ class Vc4CameraData final : public RPi::CameraData
104104 * minTotalUnicamBuffers >= minUnicamBuffers
105105 */
106106 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;
107117 };
108118
109119 Config config_;
@@ -218,42 +228,74 @@ bool PipelineHandlerVc4::match(DeviceEnumerator *enumerator)
218228int PipelineHandlerVc4::prepareBuffers (Camera *camera)
219229{
220230 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 ;
222234 int ret;
223235
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+ }
228253 }
229254 }
230255
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+
231272 /* Decide how many internal buffers to allocate. */
232273 for (auto const stream : data->streams_ ) {
233274 unsigned int numBuffers;
234275 /*
235276 * For Unicam, allocate a minimum number of buffers for internal
236277 * use as we want to avoid any frame drops.
237278 */
238- const unsigned int minBuffers = data->config_ .minTotalUnicamBuffers ;
239279 if (stream == &data->unicam_ [Unicam::Image]) {
240280 /*
241281 * If an application has configured a RAW stream, allocate
242282 * additional buffers to make up the minimum, but ensure
243283 * we have at least minUnicamBuffers of internal buffers
244284 * to use to minimise frame drops.
245285 */
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;
248289 } else if (stream == &data->isp_ [Isp::Input]) {
249290 /*
250291 * ISP input buffers are imported from Unicam, so follow
251292 * similar logic as above to count all the RAW buffers
252293 * available.
253294 */
254295 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;
257299
258300 } else if (stream == &data->unicam_ [Unicam::Embedded]) {
259301 /*
@@ -272,14 +314,18 @@ int PipelineHandlerVc4::prepareBuffers(Camera *camera)
272314 * buffers, as these will be recycled quicker.
273315 */
274316 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;
275321 } else {
276322 /*
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.
281326 */
282327 numBuffers = 1 ;
328+ LOG (RPI, Debug) << " Other numBuffers " << numBuffers;
283329 }
284330
285331 LOG (RPI, Debug) << " Preparing " << numBuffers
@@ -497,6 +543,8 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &
497543 config_ = {
498544 .minUnicamBuffers = 2 ,
499545 .minTotalUnicamBuffers = 4 ,
546+ .rawMandatoryStream = false ,
547+ .output0MandatoryStream = false ,
500548 };
501549
502550 if (!root)
@@ -520,6 +568,10 @@ int Vc4CameraData::platformPipelineConfigure(const std::unique_ptr<YamlObject> &
520568 phConfig[" min_unicam_buffers" ].get <unsigned int >(config_.minUnicamBuffers );
521569 config_.minTotalUnicamBuffers =
522570 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 );
523575
524576 if (config_.minTotalUnicamBuffers < config_.minUnicamBuffers ) {
525577 LOG (RPI, Error) << " Invalid configuration: min_total_unicam_buffers must be >= min_unicam_buffers" ;
0 commit comments