Re: [PATCH v2 1/2] docs-rst: media: Document s_stream() video op usage for MC enabled devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Em Tue, 22 Aug 2017 02:44:00 +0200
Niklas Söderlund <niklas.soderlund@xxxxxxxxxxxx> escreveu:

> On 2017-08-21 11:01:00 -0300, Mauro Carvalho Chehab wrote:
> > Em Mon, 21 Aug 2017 15:52:17 +0200
> > Hans Verkuil <hverkuil@xxxxxxxxx> escreveu:
> > 
> > > On 08/21/2017 02:07 PM, Mauro Carvalho Chehab wrote:
> > > > Em Mon, 21 Aug 2017 12:14:18 +0200
> > > > Hans Verkuil <hverkuil@xxxxxxxxx> escreveu:
> > > >   
> > > >> On 08/21/2017 11:08 AM, Mauro Carvalho Chehab wrote:  
> > > >>> Em Mon, 21 Aug 2017 09:36:49 +0300
> > > >>> Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> escreveu:
> > > >>>     
> > > >>>> Hi Mauro,
> > > >>>>
> > > >>>> Mauro Carvalho Chehab wrote:    
> > > >>>>> Hi Sakari,
> > > >>>>>
> > > >>>>> Em Wed, 16 Aug 2017 15:20:17 +0300
> > > >>>>> Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> escreveu:
> > > >>>>>      
> > > >>>>>> As we begin to add support for systems with Media controller pipelines
> > > >>>>>> controlled by more than one device driver, it is essential that we
> > > >>>>>> precisely define the responsibilities of each component in the stream
> > > >>>>>> control and common practices.
> > > >>>>>>
> > > >>>>>> Specifically, streaming control is done per sub-device and sub-device
> > > >>>>>> drivers themselves are responsible for streaming setup in upstream
> > > >>>>>> sub-devices.      
> > > >>>>>
> > > >>>>> IMO, before this patch, we need something like this:
> > > >>>>> 	https://patchwork.linuxtv.org/patch/43325/      
> > > >>>>
> > > >>>> Thanks. I'll reply separately to that thread.
> > > >>>>    
> > > >>>>>      
> > > >>>>>>
> > > >>>>>> Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
> > > >>>>>> Acked-by: Niklas Söderlund <niklas.soderlund+renesas@xxxxxxxxxxxx>
> > > >>>>>> ---
> > > >>>>>>  Documentation/media/kapi/v4l2-subdev.rst | 29 +++++++++++++++++++++++++++++
> > > >>>>>>  1 file changed, 29 insertions(+)
> > > >>>>>>
> > > >>>>>> diff --git a/Documentation/media/kapi/v4l2-subdev.rst b/Documentation/media/kapi/v4l2-subdev.rst
> > > >>>>>> index e1f0b72..45088ad 100644
> > > >>>>>> --- a/Documentation/media/kapi/v4l2-subdev.rst
> > > >>>>>> +++ b/Documentation/media/kapi/v4l2-subdev.rst
> > > >>>>>> @@ -262,6 +262,35 @@ is called. After all subdevices have been located the .complete() callback is
> > > >>>>>>  called. When a subdevice is removed from the system the .unbind() method is
> > > >>>>>>  called. All three callbacks are optional.
> > > >>>>>>
> > > >>>>>> +Streaming control on Media controller enabled devices
> > > >>>>>> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > >>>>>> +
> > > >>>>>> +Starting and stopping the stream are somewhat complex operations that
> > > >>>>>> +often require walking the media graph to enable streaming on
> > > >>>>>> +sub-devices which the pipeline consists of. This involves interaction
> > > >>>>>> +between multiple drivers, sometimes more than two.      
> > > >>>>>
> > > >>>>> That's still not ok, as it creates a black hole for devnode-based
> > > >>>>> devices.
> > > >>>>>
> > > >>>>> I would change it to something like:
> > > >>>>>
> > > >>>>> 	Streaming control
> > > >>>>> 	^^^^^^^^^^^^^^^^^
> > > >>>>>
> > > >>>>> 	Starting and stopping the stream are somewhat complex operations that
> > > >>>>> 	often require to enable streaming on sub-devices which the pipeline
> > > >>>>> 	consists of. This involves interaction between multiple drivers, sometimes
> > > >>>>> 	more than two.
> > > >>>>>
> > > >>>>> 	The ``.s_stream()`` op in :c:type:`v4l2_subdev_video_ops` is responsible
> > > >>>>> 	for starting and stopping the stream on the sub-device it is called
> > > >>>>> 	on.
> > > >>>>>
> > > >>>>> 	Streaming control on devnode-centric devices
> > > >>>>> 	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > >>>>>
> > > >>>>> 	On **devnode-centric** devices, the main driver is responsible enable
> > > >>>>> 	stream all all sub-devices. On most cases, all the main driver need
> > > >>>>> 	to do is to broadcast s_stream to all connected sub-devices by calling
> > > >>>>> 	:c:func:`v4l2_device_call_all`, e. g.::
> > > >>>>>
> > > >>>>> 		v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);      
> > > >>>>
> > > >>>> Looks good to me.
> > > >>>>    
> > > >>>>>
> > > >>>>> 	Streaming control on mc-centric devices
> > > >>>>> 	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > >>>>>
> > > >>>>> 	On **mc-centric** devices, it usually requires walking the media graph
> > > >>>>> 	to enable streaming only at the sub-devices which the pipeline consists
> > > >>>>> 	of.
> > > >>>>>
> > > >>>>> 	(place here the details for such scenario)      
> > > >>>>
> > > >>>> This part requires a more detailed description of the problem area. What 
> > > >>>> makes a difference here is that there's a pipeline this pipeline may be 
> > > >>>> controlled more than one driver. (More elaborate discussion below.)
> > > >>>>    
> > > >>>>>      
> > > >>>>>> +The ``.s_stream()`` op in :c:type:`v4l2_subdev_video_ops` is responsible
> > > >>>>>> +for starting and stopping the stream on the sub-device it is called
> > > >>>>>> +on. A device driver is only responsible for calling the ``.s_stream()`` ops
> > > >>>>>> +of the adjacent sub-devices that are connected to its sink pads
> > > >>>>>> +through an enabled link. A driver may not call ``.s_stream()`` op
> > > >>>>>> +of any other sub-device further up in the pipeline, for instance.
> > > >>>>>> +
> > > >>>>>> +This means that a sub-device driver is thus in direct control of
> > > >>>>>> +whether the upstream sub-devices start (or stop) streaming before or
> > > >>>>>> +after the sub-device itself is set up for streaming.
> > > >>>>>> +
> > > >>>>>> +.. note::
> > > >>>>>> +
> > > >>>>>> +   As the ``.s_stream()`` callback is called recursively through the
> > > >>>>>> +   sub-devices along the pipeline, it is important to keep the
> > > >>>>>> +   recursion as short as possible. To this end, drivers are encouraged
> > > >>>>>> +   to avoid recursively calling ``.s_stream()`` internally to reduce
> > > >>>>>> +   stack usage. Instead, the ``.s_stream()`` op of the directly
> > > >>>>>> +   connected sub-devices should come from the callback through which
> > > >>>>>> +   the driver was first called.
> > > >>>>>> +      
> > > >>>>>
> > > >>>>> That sounds too complex, and can lead into troubles, if the same
> > > >>>>> sub-device driver is used on completely different devices.
> > > >>>>>
> > > >>>>> IMHO, it should be up to the main driver to navigate at the MC
> > > >>>>> pipeline and call s_stream(), and not to the sub-drivers.      
> > > >>>>
> > > >>>> I would agree with the above statement *if* we had no devices that 
> > > >>>> require doing this in a different way.
> > > >>>>
> > > >>>> Consider the following case:
> > > >>>>
> > > >>>> 	sensor   -> CSI-2 receiver -> ISP (DMA)
> > > >>>> 	subdev A -> subdev B	   -> video node    
> > > >>>
> > > >>> Let me be clearer about the issue I see.
> > > >>>
> > > >>> In the above example, what subdevs are supposed to multicast the
> > > >>> s_stream() to their neighbors, and how they will know that they
> > > >>> need to multicast it.
> > > >>>
> > > >>> Let's say, that, in the first pipeline, it would be the sensor
> > > >>> and subdev A. How "sensor" and "subdev A" will know that they're
> > > >>> meant to broadcast s_stream(), and the other entities know they
> > > >>> won't?    
> > > >>
> > > >> So my understanding is that the bridge driver (ISP) will call s_stream
> > > >> for the CSI-2 receiver, and that in turn calls s_stream of the sensor.  
> > > > 
> > > > Alternatively, the ISP driver could call s_stream for both CSI-2 and
> > > > sensor.
> > > >   
> > > >> This should only be done for mc-centric devices, so we need a clear
> > > >> property telling a subdev whether it is part of an mc-centric pipeline
> > > >> or a devnode-centric pipeline. Since in the latter case it should not
> > > >> call s_stream in this way. For devnode-centric pipelines the bridge
> > > >> driver broadcasts s_stream to all subdevs.  
> > > > 
> > > > It would be easier to have a logic called by the ISP driver that would
> > > > get all elements from an active pipeline and call s_stream() there.
> > > > 
> > > > That would keep the flexibility that would be needed by devices with a
> > > > separate CSI-2 receiver, while preventing the addition of an extra
> > > > logic on every sub-device to teach them that s_stream() should be
> > > > called to communicate with some specific sub-device.
> > > > 
> > > > The thing is that, if you have a pipeline like:
> > > > 
> > > > source subdev -> subdev A -> subdev B -> subdev C -> subdev D -> DMA
> > > > 
> > > > due to PM constraints, all subdevs on such pipeline may require s_stream()
> > > > to control its power consumption. So, it is not just a CSI-2 device that
> > > > would need to enable power at the sensor, but an entire pipeline that
> > > > would need to receive s_stream() calls.  
> > > 
> > > So? If DMA calls s_stream for subdev D, which calls s_stream for subdev C, etc.
> > > until the source subdev's s_stream is called, then they are all powered up,
> > > aren't they?
> > > 
> > > I don't see the difference between this and the DMA calling s_stream for all
> > > subdevs.
> > > 
> > > One clear difference is (as Sakari mentioned) stack usage. There having the
> > > DMA call s_stream is clearly better. See below for more comments...
> > 
> > That's not the only difference. If we pass this to subdevs, they
> > need to know that they're working on a mc-centric way.
> 
> Another difference is that in a mc-centric driver more information might 
> be needed in the s_stream call then currently is available and would be 
> harder to do if the DMA driver calls s_stream on all subdevices. One 
> example of this is in the patch series '[PATCH 00/20] Add multiplexed 
> media pads to support CSI-2 virtual channels' which tries to add 
> multiplexed pads which can contain more then one stream.

I'll try to take a look on such patch series later this week.

> 
> In that series the s_stream() operation is extended to carry information 
> about both which pad and which stream the s_stream() operation intends 
> to start.

If you change it, it won't likely work anymore for existing devices, as, 
on all currently implemented usecases, s_stream() doesn't care about pads. 
The hole idea behind the original implementations for s_stream() is to
actually power on the device as a hole.

Also, I can't see how this would work on broadcast mode[1].

[1] On devnode-centric devices, s_stream() is just broadcasted to all
audio and video devices, in order to wake them up.

Btw, devnode-centric may even be compiled with MC disabled - so, there
won't be a MC graph with pads information.

So, it sounds that we'll need to have a different callback instead of
changing s_stream() - something like s_stream_subdev() or s_stream_pad().

> Then each subdevice is responsible to call s_stream() on it's 
> neighbor providing which pad and stream of the remote it wants to start 
> based on which of its own pads and possibly stream s_stream() as called 
> up on itself. This propagation by each subdevice then becomes much more 
> useful as it's only the subdevice itself that knows about the internal 
> subdevice routing from its sink to source pad(s). Maybe this can also be 
> covered by some generic v4l2 helper to start the stream, but it feels 
> like such implementations could become complex.

Even with a new callback, recursion can be very bad. The pipeline might
have a loop. Even if it doesn't, some protection may be needed to avoid
too long pipelines that could cause stack overflow.

Thanks,
Mauro



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux