diff options
Diffstat (limited to 'Documentation/video4linux/v4l2-framework.txt')
-rw-r--r-- | Documentation/video4linux/v4l2-framework.txt | 106 |
1 files changed, 88 insertions, 18 deletions
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index 659b2ba12a4f..1f5905270050 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -182,11 +182,11 @@ static int __devinit drv_probe(struct pci_dev *pdev, } If you have multiple device nodes then it can be difficult to know when it is -safe to unregister v4l2_device. For this purpose v4l2_device has refcounting -support. The refcount is increased whenever video_register_device is called and -it is decreased whenever that device node is released. When the refcount reaches -zero, then the v4l2_device release() callback is called. You can do your final -cleanup there. +safe to unregister v4l2_device for hotpluggable devices. For this purpose +v4l2_device has refcounting support. The refcount is increased whenever +video_register_device is called and it is decreased whenever that device node +is released. When the refcount reaches zero, then the v4l2_device release() +callback is called. You can do your final cleanup there. If other device nodes (e.g. ALSA) are created, then you can increase and decrease the refcount manually as well by calling: @@ -197,6 +197,10 @@ or: int v4l2_device_put(struct v4l2_device *v4l2_dev); +Since the initial refcount is 1 you also need to call v4l2_device_put in the +disconnect() callback (for USB devices) or in the remove() callback (for e.g. +PCI devices), otherwise the refcount will never reach 0. + struct v4l2_subdev ------------------ @@ -262,11 +266,16 @@ struct v4l2_subdev_video_ops { ... }; +struct v4l2_subdev_pad_ops { + ... +}; + struct v4l2_subdev_ops { const struct v4l2_subdev_core_ops *core; const struct v4l2_subdev_tuner_ops *tuner; const struct v4l2_subdev_audio_ops *audio; const struct v4l2_subdev_video_ops *video; + const struct v4l2_subdev_pad_ops *video; }; The core ops are common to all subdevs, the other categories are implemented @@ -303,6 +312,22 @@ Don't forget to cleanup the media entity before the sub-device is destroyed: media_entity_cleanup(&sd->entity); +If the subdev driver intends to process video and integrate with the media +framework, it must implement format related functionality using +v4l2_subdev_pad_ops instead of v4l2_subdev_video_ops. + +In that case, the subdev driver may set the link_validate field to provide +its own link validation function. The link validation function is called for +every link in the pipeline where both of the ends of the links are V4L2 +sub-devices. The driver is still responsible for validating the correctness +of the format configuration between sub-devices and video nodes. + +If link_validate op is not set, the default function +v4l2_subdev_link_validate_default() is used instead. This function ensures +that width, height and the media bus pixel code are equal on both source and +sink of the link. Subdev drivers are also free to use this function to +perform the checks mentioned above in addition to their own checks. + A device (bridge) driver needs to register the v4l2_subdev with the v4l2_device: @@ -555,19 +580,25 @@ allocated memory. You should also set these fields: - v4l2_dev: set to the v4l2_device parent device. + - name: set to something descriptive and unique. + - fops: set to the v4l2_file_operations struct. + - ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance (highly recommended to use this and it might become compulsory in the future!), then set this to your v4l2_ioctl_ops struct. + - lock: leave to NULL if you want to do all the locking in the driver. - Otherwise you give it a pointer to a struct mutex_lock and before any - of the v4l2_file_operations is called this lock will be taken by the - core and released afterwards. + Otherwise you give it a pointer to a struct mutex_lock and before the + unlocked_ioctl file operation is called this lock will be taken by the + core and released afterwards. See the next section for more details. + - prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY. If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device. If you want to have a separate priority state per (group of) device node(s), then you can point it to your own struct v4l2_prio_state. + - parent: you only set this if v4l2_device was registered with NULL as the parent device struct. This only happens in cases where one hardware device has multiple PCI devices that all share the same v4l2_device core. @@ -577,6 +608,7 @@ You should also set these fields: (cx8802). Since the v4l2_device cannot be associated with a particular PCI device it is setup without a parent device. But when the struct video_device is setup you do know which parent PCI device to use. + - flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct v4l2_fh. Eventually this flag will disappear once all drivers use the core @@ -587,6 +619,16 @@ in your v4l2_file_operations struct. Do not use .ioctl! This is deprecated and will go away in the future. +In some cases you want to tell the core that a function you had specified in +your v4l2_ioctl_ops should be ignored. You can mark such ioctls by calling this +function before video_device_register is called: + +void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd); + +This tends to be needed if based on external factors (e.g. which card is +being used) you want to turns off certain features in v4l2_ioctl_ops without +having to make a new struct. + The v4l2_file_operations struct is a subset of file_operations. The main difference is that the inode argument is omitted since it is never used. @@ -609,8 +651,22 @@ v4l2_file_operations and locking -------------------------------- You can set a pointer to a mutex_lock in struct video_device. Usually this -will be either a top-level mutex or a mutex per device node. If you want -finer-grained locking then you have to set it to NULL and do you own locking. +will be either a top-level mutex or a mutex per device node. By default this +lock will be used for unlocked_ioctl, but you can disable locking for +selected ioctls by calling: + + void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd); + +E.g.: v4l2_disable_ioctl_locking(vdev, VIDIOC_DQBUF); + +You have to call this before you register the video_device. + +Particularly with USB drivers where certain commands such as setting controls +can take a long time you may want to do your own locking for the buffer queuing +ioctls. + +If you want still finer-grained locking then you have to set mutex_lock to NULL +and do you own locking completely. It is up to the driver developer to decide which method to use. However, if your driver has high-latency operations (for example, changing the exposure @@ -618,7 +674,7 @@ of a USB webcam might take a long time), then you might be better off with doing your own locking if you want to allow the user to do other things with the device while waiting for the high-latency command to finish. -If a lock is specified then all file operations will be serialized on that +If a lock is specified then all ioctl commands will be serialized on that lock. If you use videobuf then you must pass the same lock to the videobuf queue initialize function: if videobuf has to wait for a frame to arrive, then it will temporarily unlock the lock and relock it afterwards. If your driver @@ -941,21 +997,35 @@ fast. Useful functions: -- v4l2_event_queue() +void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev) Queue events to video device. The driver's only responsibility is to fill in the type and the data fields. The other fields will be filled in by V4L2. -- v4l2_event_subscribe() +int v4l2_event_subscribe(struct v4l2_fh *fh, + struct v4l2_event_subscription *sub, unsigned elems, + const struct v4l2_subscribed_event_ops *ops) The video_device->ioctl_ops->vidioc_subscribe_event must check the driver is able to produce events with specified event id. Then it calls - v4l2_event_subscribe() to subscribe the event. The last argument is the - size of the event queue for this event. If it is 0, then the framework - will fill in a default value (this depends on the event type). + v4l2_event_subscribe() to subscribe the event. + + The elems argument is the size of the event queue for this event. If it is 0, + then the framework will fill in a default value (this depends on the event + type). + + The ops argument allows the driver to specify a number of callbacks: + * add: called when a new listener gets added (subscribing to the same + event twice will only cause this callback to get called once) + * del: called when a listener stops listening + * replace: replace event 'old' with event 'new'. + * merge: merge event 'old' into event 'new'. + All 4 callbacks are optional, if you don't want to specify any callbacks + the ops argument itself maybe NULL. -- v4l2_event_unsubscribe() +int v4l2_event_unsubscribe(struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use v4l2_event_unsubscribe() directly unless it wants to be involved in @@ -964,7 +1034,7 @@ Useful functions: The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The drivers may want to handle this in a special way. -- v4l2_event_pending() +int v4l2_event_pending(struct v4l2_fh *fh) Returns the number of pending events. Useful when implementing poll. |