[libcamera-devel,v4,11/12] libcamera: ipu3: Use roles in stream configuration

Message ID 20190409192548.20325-12-jacopo@jmondi.org
State Superseded
Headers show
Series
  • libcamera: ipu3: Multiple streams support
Related show

Commit Message

Jacopo Mondi April 9, 2019, 7:25 p.m. UTC
Use and inspect the stream roles provided by the application to
streamConfiguration() to assign streams to their intended roles and
return a default configuration associated with them.

Support a limited number of usages, as the viewfinder stream can
optionally be used for capturing still images, but the main output
stream cannot be used as viewfinder or for video recording purposes.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 105 ++++++++++++++++++++-------
 1 file changed, 79 insertions(+), 26 deletions(-)

Comments

Niklas Söderlund April 14, 2019, 8:45 p.m. UTC | #1
Hi Jacopo,

Thanks for your work.

On 2019-04-09 21:25:47 +0200, Jacopo Mondi wrote:
> Use and inspect the stream roles provided by the application to
> streamConfiguration() to assign streams to their intended roles and
> return a default configuration associated with them.
> 
> Support a limited number of usages, as the viewfinder stream can
> optionally be used for capturing still images, but the main output
> stream cannot be used as viewfinder or for video recording purposes.
> 
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> ---
>  src/libcamera/pipeline/ipu3/ipu3.cpp | 105 ++++++++++++++++++++-------
>  1 file changed, 79 insertions(+), 26 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 75ffdc56d157..70a92783076f 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -227,36 +227,89 @@ CameraConfiguration
>  PipelineHandlerIPU3::streamConfiguration(Camera *camera,
>  					 const std::vector<StreamUsage> &usages)
>  {
> -	CameraConfiguration configs;
>  	IPU3CameraData *data = cameraData(camera);
> -	StreamConfiguration config = {};
> +	CameraConfiguration configs;
> +	std::vector<IPU3Stream *> availableStreams = {

Using a std::set instead of std::vector here would be useful. As you 
can't have the same stream in the set twice there is no limitation 
moving from a vector to a set.

> +		&data->outStream_,
> +		&data->vfStream_,
> +	};
>  
> -	/*
> -	 * FIXME: Soraka: the maximum resolution reported by both sensors
> -	 * (2592x1944 for ov5670 and 4224x3136 for ov13858) are returned as
> -	 * default configurations but they're not correctly processed by the
> -	 * ImgU. Resolutions up tp 2560x1920 have been validated.
> -	 *
> -	 * \todo Clarify ImgU alignement requirements.
> -	 */
> -	config.width = 2560;
> -	config.height = 1920;
> -	config.pixelFormat = V4L2_PIX_FMT_NV12;
> -	config.bufferCount = IPU3_BUFFER_COUNT;
> -
> -	configs[&data->outStream_] = config;
> -	LOG(IPU3, Debug)
> -		<< "Stream 'output' format set to " << config.width << "x"
> -		<< config.height << "-0x" << std::hex << std::setfill('0')
> -		<< std::setw(8) << config.pixelFormat;
> -
> -	configs[&data->vfStream_] = config;
> -	LOG(IPU3, Debug)
> -		<< "Stream 'viewfinder' format set to " << config.width << "x"
> -		<< config.height << "-0x" << std::hex << std::setfill('0')
> -		<< std::setw(8) << config.pixelFormat;
> +	for (const StreamUsage &usage : usages) {
> +		std::vector<IPU3Stream *>::iterator found;

Can be refactored away if availableStreams is a std::set, see example 
bellow.

> +		enum StreamUsage::Role r = usage.role();

s/enum//

> +		StreamConfiguration config = {};
> +		IPU3Stream *stream = nullptr;
> +
> +		std::vector<IPU3Stream *>::iterator s = availableStreams.begin();
> +		if (r == StreamUsage::Role::StillCapture) {
> +			for (; s < availableStreams.end(); ++s) {
> +				/*
> +				 * We can use the viewfinder stream in case
> +				 * the 'StillCapture' usage is required
> +				 * multiple times.
> +				 */
> +				if (*s == &data->outStream_) {
> +					stream = &data->outStream_;
> +					found = s;
> +					break;
> +				} else {
> +					stream = &data->vfStream_;
> +					found = s;
> +				}
> +			}

The for() loop can be replaced with this if availableStreams is std::set


    if (availableStreams.find(&data->outStream_) != availableStreams.end())
        stream = &data->outStream_;
    else
        stream = &data->vfStream_;

> +
> +			/*
> +			 * FIXME: Soraka: the maximum resolution reported by
> +			 * both sensors (2592x1944 for ov5670 and 4224x3136 for
> +			 * ov13858) are returned as default configurations but
> +			 * they're not correctly processed by the ImgU.
> +			 * Resolutions up tp 2560x1920 have been validated.
> +			 *
> +			 * \todo Clarify ImgU alignment requirements.
> +			 */
> +			config.width = 2560;
> +			config.height = 1920;
> +		} else if (r == StreamUsage::Role::Viewfinder ||
> +			   r == StreamUsage::Role::VideoRecording) {
> +			for (; s < availableStreams.end(); ++s) {
> +				/*
> +				 * We can't use the 'output' stream for
> +				 * viewfinder or video capture usages.
> +				 */
> +				if (*s != &data->vfStream_)
> +					continue;
> +
> +				stream = &data->vfStream_;
> +				found = s;
> +				break;
> +			}
> +
> +			config.width = 640;
> +			config.height = 480;
> +		}
> +
> +		if (stream == nullptr)
> +			goto error;
> +
> +		availableStreams.erase(found);

With std::set

    availableStreams.erase(stream);

> +
> +		config.pixelFormat = V4L2_PIX_FMT_NV12;
> +		config.bufferCount = IPU3_BUFFER_COUNT;
> +
> +		configs[stream] = config;
> +
> +		LOG(IPU3, Debug)
> +			<< "Stream " << stream->name_ << " format set to "
> +			<< config.width << "x" << config.height
> +			<< "-0x" << std::hex << std::setfill('0')
> +			<< std::setw(8) << config.pixelFormat;
> +	}
>  
>  	return configs;
> +
> +error:
> +	LOG(IPU3, Error) << "Requested stream roles not supported";
> +	return CameraConfiguration{};
>  }
>  
>  int PipelineHandlerIPU3::configureStreams(Camera *camera,
> -- 
> 2.21.0
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
Laurent Pinchart April 15, 2019, 2:42 p.m. UTC | #2
Hi Jacopo,

Thank you for the patch.

On Sun, Apr 14, 2019 at 10:45:18PM +0200, Niklas Söderlund wrote:
> On 2019-04-09 21:25:47 +0200, Jacopo Mondi wrote:
> > Use and inspect the stream roles provided by the application to
> > streamConfiguration() to assign streams to their intended roles and
> > return a default configuration associated with them.
> > 
> > Support a limited number of usages, as the viewfinder stream can
> > optionally be used for capturing still images, but the main output
> > stream cannot be used as viewfinder or for video recording purposes.

Is this a limitation of the device, or of the pipeline handler ?

> > 
> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> > ---
> >  src/libcamera/pipeline/ipu3/ipu3.cpp | 105 ++++++++++++++++++++-------
> >  1 file changed, 79 insertions(+), 26 deletions(-)
> > 
> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > index 75ffdc56d157..70a92783076f 100644
> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > @@ -227,36 +227,89 @@ CameraConfiguration
> >  PipelineHandlerIPU3::streamConfiguration(Camera *camera,
> >  					 const std::vector<StreamUsage> &usages)
> >  {
> > -	CameraConfiguration configs;
> >  	IPU3CameraData *data = cameraData(camera);
> > -	StreamConfiguration config = {};
> > +	CameraConfiguration configs;

I wouldn't use the plural for a single object. How about
CameraConfiguration config and StreamConfiguration cfg ? Or
CameraConfiguration ccfg and StreamConfiguration scfg ? There's also the
option of cameraConfig and streamConfig but that may be a bit long.

> > +	std::vector<IPU3Stream *> availableStreams = {
> 
> Using a std::set instead of std::vector here would be useful. As you 
> can't have the same stream in the set twice there is no limitation 
> moving from a vector to a set.
> 
> > +		&data->outStream_,
> > +		&data->vfStream_,
> > +	};
> >  
> > -	/*
> > -	 * FIXME: Soraka: the maximum resolution reported by both sensors
> > -	 * (2592x1944 for ov5670 and 4224x3136 for ov13858) are returned as
> > -	 * default configurations but they're not correctly processed by the
> > -	 * ImgU. Resolutions up tp 2560x1920 have been validated.
> > -	 *
> > -	 * \todo Clarify ImgU alignement requirements.
> > -	 */
> > -	config.width = 2560;
> > -	config.height = 1920;
> > -	config.pixelFormat = V4L2_PIX_FMT_NV12;
> > -	config.bufferCount = IPU3_BUFFER_COUNT;
> > -
> > -	configs[&data->outStream_] = config;
> > -	LOG(IPU3, Debug)
> > -		<< "Stream 'output' format set to " << config.width << "x"
> > -		<< config.height << "-0x" << std::hex << std::setfill('0')
> > -		<< std::setw(8) << config.pixelFormat;
> > -
> > -	configs[&data->vfStream_] = config;
> > -	LOG(IPU3, Debug)
> > -		<< "Stream 'viewfinder' format set to " << config.width << "x"
> > -		<< config.height << "-0x" << std::hex << std::setfill('0')
> > -		<< std::setw(8) << config.pixelFormat;
> > +	for (const StreamUsage &usage : usages) {
> > +		std::vector<IPU3Stream *>::iterator found;
> 
> Can be refactored away if availableStreams is a std::set, see example 
> bellow.
> 
> > +		enum StreamUsage::Role r = usage.role();
> 
> s/enum//

And s/r/role/ ? r is a bit confusing, it also commonly refers to a
rectangle.

> > +		StreamConfiguration config = {};
> > +		IPU3Stream *stream = nullptr;
> > +
> > +		std::vector<IPU3Stream *>::iterator s = availableStreams.begin();
> > +		if (r == StreamUsage::Role::StillCapture) {
> > +			for (; s < availableStreams.end(); ++s) {
> > +				/*
> > +				 * We can use the viewfinder stream in case
> > +				 * the 'StillCapture' usage is required
> > +				 * multiple times.
> > +				 */
> > +				if (*s == &data->outStream_) {
> > +					stream = &data->outStream_;
> > +					found = s;
> > +					break;
> > +				} else {
> > +					stream = &data->vfStream_;
> > +					found = s;
> > +				}
> > +			}
> 
> The for() loop can be replaced with this if availableStreams is std::set
> 
> 
>     if (availableStreams.find(&data->outStream_) != availableStreams.end())
>         stream = &data->outStream_;
>     else
>         stream = &data->vfStream_;
> 
> > +
> > +			/*
> > +			 * FIXME: Soraka: the maximum resolution reported by
> > +			 * both sensors (2592x1944 for ov5670 and 4224x3136 for
> > +			 * ov13858) are returned as default configurations but
> > +			 * they're not correctly processed by the ImgU.
> > +			 * Resolutions up tp 2560x1920 have been validated.
> > +			 *
> > +			 * \todo Clarify ImgU alignment requirements.
> > +			 */
> > +			config.width = 2560;
> > +			config.height = 1920;
> > +		} else if (r == StreamUsage::Role::Viewfinder ||
> > +			   r == StreamUsage::Role::VideoRecording) {
> > +			for (; s < availableStreams.end(); ++s) {
> > +				/*
> > +				 * We can't use the 'output' stream for
> > +				 * viewfinder or video capture usages.
> > +				 */
> > +				if (*s != &data->vfStream_)
> > +					continue;
> > +
> > +				stream = &data->vfStream_;
> > +				found = s;
> > +				break;
> > +			}

And here

			if (availableStreams.find(&data->vfStream_) !=
			    availableStreams.end())
				stream = &data->vfStream_;

You may want to rename availableStreams to streams if it helps
shortening lines, up to you.

> > +
> > +			config.width = 640;
> > +			config.height = 480;

Should you use the resolution requested by the Viewfinder usage ?

> > +		}
> > +
> > +		if (stream == nullptr)
> > +			goto error;
> > +
> > +		availableStreams.erase(found);
> 
> With std::set
> 
>     availableStreams.erase(stream);
> 
> > +
> > +		config.pixelFormat = V4L2_PIX_FMT_NV12;
> > +		config.bufferCount = IPU3_BUFFER_COUNT;
> > +
> > +		configs[stream] = config;
> > +
> > +		LOG(IPU3, Debug)
> > +			<< "Stream " << stream->name_ << " format set to "
> > +			<< config.width << "x" << config.height
> > +			<< "-0x" << std::hex << std::setfill('0')
> > +			<< std::setw(8) << config.pixelFormat;
> > +	}
> >  
> >  	return configs;
> > +
> > +error:
> > +	LOG(IPU3, Error) << "Requested stream roles not supported";
> > +	return CameraConfiguration{};
> >  }
> >  
> >  int PipelineHandlerIPU3::configureStreams(Camera *camera,
Jacopo Mondi April 18, 2019, 10:16 a.m. UTC | #3
Hi Laurent, Niklas,

On Mon, Apr 15, 2019 at 05:42:44PM +0300, Laurent Pinchart wrote:
> Hi Jacopo,
>
> Thank you for the patch.
>
> On Sun, Apr 14, 2019 at 10:45:18PM +0200, Niklas Söderlund wrote:
> > On 2019-04-09 21:25:47 +0200, Jacopo Mondi wrote:
> > > Use and inspect the stream roles provided by the application to
> > > streamConfiguration() to assign streams to their intended roles and
> > > return a default configuration associated with them.
> > >
> > > Support a limited number of usages, as the viewfinder stream can
> > > optionally be used for capturing still images, but the main output
> > > stream cannot be used as viewfinder or for video recording purposes.
>
> Is this a limitation of the device, or of the pipeline handler ?
>

Is a limitation I introduced in the pipeline handler as I assume
viewfinder frame rate cannot be sustained by the still capture
output node. It's an assumption though, but I kept it there to
demonstrate how to use roles in assigning configurations.

> > >
> > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> > > ---
> > >  src/libcamera/pipeline/ipu3/ipu3.cpp | 105 ++++++++++++++++++++-------
> > >  1 file changed, 79 insertions(+), 26 deletions(-)
> > >
> > > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > > index 75ffdc56d157..70a92783076f 100644
> > > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> > > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > > @@ -227,36 +227,89 @@ CameraConfiguration
> > >  PipelineHandlerIPU3::streamConfiguration(Camera *camera,
> > >  					 const std::vector<StreamUsage> &usages)
> > >  {
> > > -	CameraConfiguration configs;
> > >  	IPU3CameraData *data = cameraData(camera);
> > > -	StreamConfiguration config = {};
> > > +	CameraConfiguration configs;
>
> I wouldn't use the plural for a single object. How about
> CameraConfiguration config and StreamConfiguration cfg ? Or
> CameraConfiguration ccfg and StreamConfiguration scfg ? There's also the
> option of cameraConfig and streamConfig but that may be a bit long.
>
> > > +	std::vector<IPU3Stream *> availableStreams = {
> >
> > Using a std::set instead of std::vector here would be useful. As you
> > can't have the same stream in the set twice there is no limitation
> > moving from a vector to a set.
> >
> > > +		&data->outStream_,
> > > +		&data->vfStream_,
> > > +	};
> > >
> > > -	/*
> > > -	 * FIXME: Soraka: the maximum resolution reported by both sensors
> > > -	 * (2592x1944 for ov5670 and 4224x3136 for ov13858) are returned as
> > > -	 * default configurations but they're not correctly processed by the
> > > -	 * ImgU. Resolutions up tp 2560x1920 have been validated.
> > > -	 *
> > > -	 * \todo Clarify ImgU alignement requirements.
> > > -	 */
> > > -	config.width = 2560;
> > > -	config.height = 1920;
> > > -	config.pixelFormat = V4L2_PIX_FMT_NV12;
> > > -	config.bufferCount = IPU3_BUFFER_COUNT;
> > > -
> > > -	configs[&data->outStream_] = config;
> > > -	LOG(IPU3, Debug)
> > > -		<< "Stream 'output' format set to " << config.width << "x"
> > > -		<< config.height << "-0x" << std::hex << std::setfill('0')
> > > -		<< std::setw(8) << config.pixelFormat;
> > > -
> > > -	configs[&data->vfStream_] = config;
> > > -	LOG(IPU3, Debug)
> > > -		<< "Stream 'viewfinder' format set to " << config.width << "x"
> > > -		<< config.height << "-0x" << std::hex << std::setfill('0')
> > > -		<< std::setw(8) << config.pixelFormat;
> > > +	for (const StreamUsage &usage : usages) {
> > > +		std::vector<IPU3Stream *>::iterator found;
> >
> > Can be refactored away if availableStreams is a std::set, see example
> > bellow.
> >
> > > +		enum StreamUsage::Role r = usage.role();
> >
> > s/enum//
>
> And s/r/role/ ? r is a bit confusing, it also commonly refers to a
> rectangle.
>
> > > +		StreamConfiguration config = {};
> > > +		IPU3Stream *stream = nullptr;
> > > +
> > > +		std::vector<IPU3Stream *>::iterator s = availableStreams.begin();
> > > +		if (r == StreamUsage::Role::StillCapture) {
> > > +			for (; s < availableStreams.end(); ++s) {
> > > +				/*
> > > +				 * We can use the viewfinder stream in case
> > > +				 * the 'StillCapture' usage is required
> > > +				 * multiple times.
> > > +				 */
> > > +				if (*s == &data->outStream_) {
> > > +					stream = &data->outStream_;
> > > +					found = s;
> > > +					break;
> > > +				} else {
> > > +					stream = &data->vfStream_;
> > > +					found = s;
> > > +				}
> > > +			}
> >
> > The for() loop can be replaced with this if availableStreams is std::set
> >
> >
> >     if (availableStreams.find(&data->outStream_) != availableStreams.end())
> >         stream = &data->outStream_;
> >     else
> >         stream = &data->vfStream_;
> >

Much better, thanks!
Just one note, this is not enough, as we might get asked for 3
viewfinders, so we have to make sure vfStream_ is available as well,
and fail eventually if it is not.

> > > +
> > > +			/*
> > > +			 * FIXME: Soraka: the maximum resolution reported by
> > > +			 * both sensors (2592x1944 for ov5670 and 4224x3136 for
> > > +			 * ov13858) are returned as default configurations but
> > > +			 * they're not correctly processed by the ImgU.
> > > +			 * Resolutions up tp 2560x1920 have been validated.
> > > +			 *
> > > +			 * \todo Clarify ImgU alignment requirements.
> > > +			 */
> > > +			config.width = 2560;
> > > +			config.height = 1920;
> > > +		} else if (r == StreamUsage::Role::Viewfinder ||
> > > +			   r == StreamUsage::Role::VideoRecording) {
> > > +			for (; s < availableStreams.end(); ++s) {
> > > +				/*
> > > +				 * We can't use the 'output' stream for
> > > +				 * viewfinder or video capture usages.
> > > +				 */
> > > +				if (*s != &data->vfStream_)
> > > +					continue;
> > > +
> > > +				stream = &data->vfStream_;
> > > +				found = s;
> > > +				break;
> > > +			}
>
> And here
>
> 			if (availableStreams.find(&data->vfStream_) !=
> 			    availableStreams.end())
> 				stream = &data->vfStream_;
>
> You may want to rename availableStreams to streams if it helps
> shortening lines, up to you.
>
> > > +
> > > +			config.width = 640;
> > > +			config.height = 480;
>
> Should you use the resolution requested by the Viewfinder usage ?
>

Yes indeed!

Thanks, with Niklas and your suggestions this looks much much better!

> > > +		}
> > > +
> > > +		if (stream == nullptr)
> > > +			goto error;
> > > +
> > > +		availableStreams.erase(found);
> >
> > With std::set
> >
> >     availableStreams.erase(stream);
> >
> > > +
> > > +		config.pixelFormat = V4L2_PIX_FMT_NV12;
> > > +		config.bufferCount = IPU3_BUFFER_COUNT;
> > > +
> > > +		configs[stream] = config;
> > > +
> > > +		LOG(IPU3, Debug)
> > > +			<< "Stream " << stream->name_ << " format set to "
> > > +			<< config.width << "x" << config.height
> > > +			<< "-0x" << std::hex << std::setfill('0')
> > > +			<< std::setw(8) << config.pixelFormat;
> > > +	}
> > >
> > >  	return configs;
> > > +
> > > +error:
> > > +	LOG(IPU3, Error) << "Requested stream roles not supported";
> > > +	return CameraConfiguration{};
> > >  }
> > >
> > >  int PipelineHandlerIPU3::configureStreams(Camera *camera,
>
> --
> Regards,
>
> Laurent Pinchart

Patch

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 75ffdc56d157..70a92783076f 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -227,36 +227,89 @@  CameraConfiguration
 PipelineHandlerIPU3::streamConfiguration(Camera *camera,
 					 const std::vector<StreamUsage> &usages)
 {
-	CameraConfiguration configs;
 	IPU3CameraData *data = cameraData(camera);
-	StreamConfiguration config = {};
+	CameraConfiguration configs;
+	std::vector<IPU3Stream *> availableStreams = {
+		&data->outStream_,
+		&data->vfStream_,
+	};
 
-	/*
-	 * FIXME: Soraka: the maximum resolution reported by both sensors
-	 * (2592x1944 for ov5670 and 4224x3136 for ov13858) are returned as
-	 * default configurations but they're not correctly processed by the
-	 * ImgU. Resolutions up tp 2560x1920 have been validated.
-	 *
-	 * \todo Clarify ImgU alignement requirements.
-	 */
-	config.width = 2560;
-	config.height = 1920;
-	config.pixelFormat = V4L2_PIX_FMT_NV12;
-	config.bufferCount = IPU3_BUFFER_COUNT;
-
-	configs[&data->outStream_] = config;
-	LOG(IPU3, Debug)
-		<< "Stream 'output' format set to " << config.width << "x"
-		<< config.height << "-0x" << std::hex << std::setfill('0')
-		<< std::setw(8) << config.pixelFormat;
-
-	configs[&data->vfStream_] = config;
-	LOG(IPU3, Debug)
-		<< "Stream 'viewfinder' format set to " << config.width << "x"
-		<< config.height << "-0x" << std::hex << std::setfill('0')
-		<< std::setw(8) << config.pixelFormat;
+	for (const StreamUsage &usage : usages) {
+		std::vector<IPU3Stream *>::iterator found;
+		enum StreamUsage::Role r = usage.role();
+		StreamConfiguration config = {};
+		IPU3Stream *stream = nullptr;
+
+		std::vector<IPU3Stream *>::iterator s = availableStreams.begin();
+		if (r == StreamUsage::Role::StillCapture) {
+			for (; s < availableStreams.end(); ++s) {
+				/*
+				 * We can use the viewfinder stream in case
+				 * the 'StillCapture' usage is required
+				 * multiple times.
+				 */
+				if (*s == &data->outStream_) {
+					stream = &data->outStream_;
+					found = s;
+					break;
+				} else {
+					stream = &data->vfStream_;
+					found = s;
+				}
+			}
+
+			/*
+			 * FIXME: Soraka: the maximum resolution reported by
+			 * both sensors (2592x1944 for ov5670 and 4224x3136 for
+			 * ov13858) are returned as default configurations but
+			 * they're not correctly processed by the ImgU.
+			 * Resolutions up tp 2560x1920 have been validated.
+			 *
+			 * \todo Clarify ImgU alignment requirements.
+			 */
+			config.width = 2560;
+			config.height = 1920;
+		} else if (r == StreamUsage::Role::Viewfinder ||
+			   r == StreamUsage::Role::VideoRecording) {
+			for (; s < availableStreams.end(); ++s) {
+				/*
+				 * We can't use the 'output' stream for
+				 * viewfinder or video capture usages.
+				 */
+				if (*s != &data->vfStream_)
+					continue;
+
+				stream = &data->vfStream_;
+				found = s;
+				break;
+			}
+
+			config.width = 640;
+			config.height = 480;
+		}
+
+		if (stream == nullptr)
+			goto error;
+
+		availableStreams.erase(found);
+
+		config.pixelFormat = V4L2_PIX_FMT_NV12;
+		config.bufferCount = IPU3_BUFFER_COUNT;
+
+		configs[stream] = config;
+
+		LOG(IPU3, Debug)
+			<< "Stream " << stream->name_ << " format set to "
+			<< config.width << "x" << config.height
+			<< "-0x" << std::hex << std::setfill('0')
+			<< std::setw(8) << config.pixelFormat;
+	}
 
 	return configs;
+
+error:
+	LOG(IPU3, Error) << "Requested stream roles not supported";
+	return CameraConfiguration{};
 }
 
 int PipelineHandlerIPU3::configureStreams(Camera *camera,