From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Mauro Carvalho Chehab <mchehab@osg.samsung.com>,
Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,
linux-media@vger.kernel.org,
Sakari Ailus <sakari.ailus@linux.intel.com>
Subject: Re: [PATCH v5 1/2] media: Add obj_type field to struct media_entity
Date: Wed, 23 Mar 2016 16:45:01 +0200 [thread overview]
Message-ID: <3511467.97gkNM9KCE@avalon> (raw)
In-Reply-To: <56F2A2B5.80206@xs4all.nl>
Hi Hans,
On Wednesday 23 Mar 2016 15:05:41 Hans Verkuil wrote:
> On 03/23/2016 11:35 AM, Mauro Carvalho Chehab wrote:
> > Em Wed, 23 Mar 2016 10:45:55 +0200 Laurent Pinchart escreveu:
> >> Code that processes media entities can require knowledge of the
> >> structure type that embeds a particular media entity instance in order
> >> to cast the entity to the proper object type. This needs is shown by the
> >> presence of the is_media_entity_v4l2_io and is_media_entity_v4l2_subdev
> >> functions.
> >>
> >> The implementation of those two functions relies on the entity function
> >> field, which is both a wrong and an inefficient design, without even
> >> mentioning the maintenance issue involved in updating the functions
> >> every time a new entity function is added. Fix this by adding add an
> >> obj_type field to the media entity structure to carry the information.
> >>
> >> Signed-off-by: Laurent Pinchart
> >> <laurent.pinchart+renesas@ideasonboard.com>
> >> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
> >> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> >> ---
> >>
> >> drivers/media/media-device.c | 2 +
> >> drivers/media/v4l2-core/v4l2-dev.c | 1 +
> >> drivers/media/v4l2-core/v4l2-subdev.c | 1 +
> >> include/media/media-entity.h | 79 ++++++++++++++++-------------
> >> 4 files changed, 46 insertions(+), 37 deletions(-)
> >>
> >> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
> >> index 4a97d92a7e7d..88d8de3b7a4f 100644
> >> --- a/drivers/media/media-device.c
> >> +++ b/drivers/media/media-device.c
> >> @@ -580,6 +580,8 @@ int __must_check media_device_register_entity(struct
> >> media_device *mdev,
> >> "Entity type for entity %s was not initialized!\n",
> >> entity->name);
> >>
> >> + WARN_ON(entity->obj_type == MEDIA_ENTITY_TYPE_INVALID);
> >> +
> >
> > This is not ok. There are valid cases where the entity is not embedded
> > on some other struct. That's the case of connectors/connections, for
> > example: a connector/connection entity doesn't need anything else but
> > struct media device.
>
> Once connectors are enabled, then we do need a MEDIA_ENTITY_TYPE_CONNECTOR
> or MEDIA_ENTITY_TYPE_STANDALONE or something along those lines.
MEDIA_ENTITY_TYPE_CONNECTOR would make sense, but only if we add a struct
media_connector. I believe that can be a good idea, at least to simplify
management of the entity and the connector pad(s).
> > Also, this is V4L2 specific. Neither ALSA nor DVB need to use
> > container_of(). Actually, this won't even work there, as the entity is
> > stored as a pointer, and not as an embedded data.
That's sounds like a strange design decision at the very least. There can be
valid cases that require creation of bare entities, but I don't think they
should be that common.
> Any other subsystem that *does* embed this can use obj_type. If it doesn't
> embed it in anything, then MEDIA_ENTITY_TYPE_STANDALONE should be used (or
> whatever name we give it). I agree that we need a type define for the case
> where it is not embedded.
I'd like to point out that I had defined MEDIA_ENTITY_TYPE_MEDIA_ENTITY for
that purpose in v4, and was requested to drop it.
I can submit a v6 with MEDIA_ENTITY_TYPE_MEDIA_ENTITY added back. I'd like a
confirmation that it won't be rejected straight away though.
The WARN_ON() is in my opinion useful, but I'm ready to leave it out for now
until we fix the connectors mess if it can help getting this patch merged
faster.
> > So, if we're willing to do this, then it should, instead, create
> > something like:
> >
> > struct embedded_media_entity {
> > struct media_entity entity;
> > enum media_entity_type obj_type;
> > };
>
> It's not v4l2 specific. It is just that v4l2 is the only subsystem that
> requires this information at the moment. I see no reason at all to create
> such an ugly struct.
I totally agree.
> I very strongly suspect that other subsystems will also embed this in their
> own internal structs. I actually wonder why it isn't embedded in struct
> dvb_device, but I have to admit that I didn't take a close look at that.
> The pads are embedded there, so it is somewhat odd that the entity isn't.
>
> > And then replace the occurrences of embedded media_entity by
> > embedded_media_entity at the V4L2 subsystem only, in the places where
> > the struct is embeded on another one.
> >
> >> /* Warn if we apparently re-register an entity */
> >> WARN_ON(entity->graph_obj.mdev != NULL);
> >> entity->graph_obj.mdev = mdev;
> >>
> >> diff --git a/drivers/media/v4l2-core/v4l2-dev.c
> >> b/drivers/media/v4l2-core/v4l2-dev.c index d8e5994cccf1..70b559d7ca80
> >> 100644
> >> --- a/drivers/media/v4l2-core/v4l2-dev.c
> >> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> >> @@ -735,6 +735,7 @@ static int video_register_media_controller(struct
> >> video_device *vdev, int type)>>
> >> if (!vdev->v4l2_dev->mdev)
> >>
> >> return 0;
> >>
> >> + vdev->entity.obj_type = MEDIA_ENTITY_TYPE_VIDEO_DEVICE;
> >>
> >> vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
> >>
> >> switch (type) {
> >>
> >> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c
> >> b/drivers/media/v4l2-core/v4l2-subdev.c index d63083803144..0fa60801a428
> >> 100644
> >> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> >> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> >> @@ -584,6 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const
> >> struct v4l2_subdev_ops *ops)>>
> >> sd->host_priv = NULL;
> >>
> >> #if defined(CONFIG_MEDIA_CONTROLLER)
> >>
> >> sd->entity.name = sd->name;
> >>
> >> + sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV;
> >>
> >> sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
> >>
> >> #endif
> >> }
> >>
> >> diff --git a/include/media/media-entity.h b/include/media/media-entity.h
> >> index 6dc9e4e8cbd4..5cea57955a3a 100644
> >> --- a/include/media/media-entity.h
> >> +++ b/include/media/media-entity.h
> >> @@ -188,10 +188,41 @@ struct media_entity_operations {
> >>
> >> };
> >>
> >> /**
> >>
> >> + * enum media_entity_type - Media entity type
> >> + *
> >> + * @MEDIA_ENTITY_TYPE_INVALID:
> >> + * Invalid type, used to catch uninitialized fields.
> >> + * @MEDIA_ENTITY_TYPE_VIDEO_DEVICE:
> >> + * The entity is embedded in a struct video_device instance.
> >> + * @MEDIA_ENTITY_TYPE_V4L2_SUBDEV:
> >> + * The entity is embedded in a struct v4l2_subdev instance.
> >> + *
> >> + * Media entity objects are not instantiated directly,
> >
> > As I said before, this is not true (nor even at V4L2 subsystem, due to
> > the connectors/connections).
> >
> > As before, you should call this as:
> > enum embedded_media_entity_type
> >
> > And then change the test to:
> > "Media entity objects declared via struct embedded_media_device are not
> >
> > instantiated directly,"
> >
> > and fix the text below accordingly.
> >
> >> but the media entity
> >> + * structure is inherited by (through embedding) other
> >> subsystem-specific
> >> + * structures. The media entity type identifies the type of the subclass
> >> + * structure that implements a media entity instance.
> >> + *
> >> + * This allows runtime type identification of media entities and safe
> >> casting to + * the correct object type. For instance, a media entity
> >> structure instance + * embedded in a v4l2_subdev structure instance will
> >> have the type + * MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast
> >> to a v4l2_subdev + * structure using the container_of() macro.
> >> + *
> >> + * The MEDIA_ENTITY_TYPE_INVALID type should never be set as an entity
> >> type, it + * only serves to catch uninitialized fields when registering
> >> entities. + */
> >> +enum media_entity_type {
> >> + MEDIA_ENTITY_TYPE_INVALID,
> >> + MEDIA_ENTITY_TYPE_VIDEO_DEVICE,
> >> + MEDIA_ENTITY_TYPE_V4L2_SUBDEV,
> >> +};
> >> +
> >> +/**
> >>
> >> * struct media_entity - A media entity graph object.
> >> *
> >> * @graph_obj: Embedded structure containing the media object common
> >> data.
> >> * @name: Entity name.
> >>
> >> + * @obj_type: Type of the object that implements the media_entity.
> >>
> >> * @function: Entity main function, as defined in uapi/media.h
> >> * (MEDIA_ENT_F_*)
> >> * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*)
> >>
> >> @@ -220,6 +251,7 @@ struct media_entity_operations {
> >>
> >> struct media_entity {
> >>
> >> struct media_gobj graph_obj; /* must be first field in struct */
> >> const char *name;
> >>
> >> + enum media_entity_type obj_type;
> >
> > See above. This doesn't below to the generic media entity struct,
> > but to an special type that is meant to be embedded on some places.
> >
> >> u32 function;
> >> unsigned long flags;
> >>
> >> @@ -329,56 +361,29 @@ static inline u32 media_gobj_gen_id(enum
> >> media_gobj_type type, u64 local_id)>>
> >> }
> >>
> >> /**
> >>
> >> - * is_media_entity_v4l2_io() - identify if the entity main function
> >> - * is a V4L2 I/O
> >> - *
> >> + * is_media_entity_v4l2_io() - Check if the entity is a video_device
> >>
> >> * @entity: pointer to entity
> >> *
> >>
> >> - * Return: true if the entity main function is one of the V4L2 I/O types
> >> - * (video, VBI or SDR radio); false otherwise.
> >> + * Return: true if the entity is an instance of a video_device object
> >> and can + * safely be cast to a struct video_device using the
> >> container_of() macro, or + * false otherwise.
> >>
> >> */
> >>
> >> static inline bool is_media_entity_v4l2_io(struct media_entity *entity)
> >> {
> >>
> >> - if (!entity)
> >> - return false;
> >> -
> >> - switch (entity->function) {
> >> - case MEDIA_ENT_F_IO_V4L:
> >> - case MEDIA_ENT_F_IO_VBI:
> >> - case MEDIA_ENT_F_IO_SWRADIO:
> >> - return true;
> >> - default:
> >> - return false;
> >> - }
> >> + return entity && entity->obj_type == MEDIA_ENTITY_TYPE_VIDEO_DEVICE;
> >>
> >> }
> >>
> >> /**
> >>
> >> - * is_media_entity_v4l2_subdev - return true if the entity main function
> >> is - * associated with the V4L2 API subdev usage
> >> - *
> >> + * is_media_entity_v4l2_subdev() - Check if the entity is a v4l2_subdev
> >>
> >> * @entity: pointer to entity
> >> *
> >>
> >> - * This is an ancillary function used by subdev-based V4L2 drivers.
> >> - * It checks if the entity function is one of functions used by a V4L2
> >> subdev, - * e. g. camera-relatef functions, analog TV decoder, TV tuner,
> >> V4L2 DSPs. + * Return: true if the entity is an instance of a
> >> v4l2_subdev object and can + * safely be cast to a struct v4l2_subdev
> >> using the container_of() macro, or + * false otherwise.
> >>
> >> */
> >>
> >> static inline bool is_media_entity_v4l2_subdev(struct media_entity
> >> *entity)
> >> {
> >>
> >> - if (!entity)
> >> - return false;
> >> -
> >> - switch (entity->function) {
> >> - case MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN:
> >> - case MEDIA_ENT_F_CAM_SENSOR:
> >> - case MEDIA_ENT_F_FLASH:
> >> - case MEDIA_ENT_F_LENS:
> >> - case MEDIA_ENT_F_ATV_DECODER:
> >> - case MEDIA_ENT_F_TUNER:
> >> - return true;
> >> -
> >> - default:
> >> - return false;
> >> - }
> >> + return entity && entity->obj_type == MEDIA_ENTITY_TYPE_V4L2_SUBDEV;
> >>
> >> }
> >>
> >> /**
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2016-03-23 14:45 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-23 8:45 [PATCH v5 0/2] media: Add entity types Laurent Pinchart
2016-03-23 8:45 ` [PATCH v5 1/2] media: Add obj_type field to struct media_entity Laurent Pinchart
2016-03-23 10:35 ` Mauro Carvalho Chehab
2016-03-23 14:05 ` Hans Verkuil
2016-03-23 14:45 ` Laurent Pinchart [this message]
2016-03-23 14:57 ` Hans Verkuil
2016-03-23 15:04 ` Laurent Pinchart
2016-03-23 15:17 ` Mauro Carvalho Chehab
2016-03-23 15:41 ` Laurent Pinchart
2016-03-23 17:29 ` Mauro Carvalho Chehab
2016-03-24 8:15 ` Laurent Pinchart
2016-03-23 15:00 ` Mauro Carvalho Chehab
2016-03-23 15:11 ` Laurent Pinchart
2016-03-23 15:20 ` Hans Verkuil
2016-03-23 15:24 ` Mauro Carvalho Chehab
2016-03-23 16:30 ` Laurent Pinchart
2016-03-23 17:06 ` Mauro Carvalho Chehab
2016-03-23 16:17 ` Sakari Ailus
2016-03-23 16:47 ` Mauro Carvalho Chehab
2016-03-23 23:42 ` Sakari Ailus
2016-03-24 7:51 ` Laurent Pinchart
2016-03-23 8:45 ` [PATCH v5 2/2] media: Rename is_media_entity_v4l2_io to is_media_entity_v4l2_video_device Laurent Pinchart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3511467.97gkNM9KCE@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=hverkuil@xs4all.nl \
--cc=laurent.pinchart+renesas@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@osg.samsung.com \
--cc=sakari.ailus@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.