[media] v4l2-ctrls.c: add support for V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK
authorHans Verkuil <hans.verkuil@cisco.com>
Wed, 29 Jun 2011 11:56:22 +0000 (08:56 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 27 Jul 2011 20:53:34 +0000 (17:53 -0300)
Normally no control events will go to the filehandle that called the
VIDIOC_S_CTRL/VIDIOC_S_EXT_CTRLS ioctls. This is to prevent a feedback
loop.

This can now be overridden by setting the new V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK
flag.

Based on suggestions from Mauro Carvalho Chehab <mchehab@redhat.com> and
Laurent Pinchart <laurent.pinchart@ideasonboard.com>.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
drivers/media/video/v4l2-ctrls.c
include/linux/videodev2.h

index 039a9694fd1d410d5d45d9fb1f37f5ab1cd78575..25471e8e5da57096db02691a8603e51fb59227a2 100644 (file)
          <row>
            <entry><constant>V4L2_EVENT_CTRL</constant></entry>
            <entry>3</entry>
-           <entry>This event requires that the <structfield>id</structfield>
+           <entry><para>This event requires that the <structfield>id</structfield>
                matches the control ID from which you want to receive events.
                This event is triggered if the control's value changes, if a
                button control is pressed or if the control's flags change.
                This event has a &v4l2-event-ctrl; associated with it. This struct
                contains much of the same information as &v4l2-queryctrl; and
-               &v4l2-control;.
+               &v4l2-control;.</para>
 
-               If the event is generated due to a call to &VIDIOC-S-CTRL; or
-               &VIDIOC-S-EXT-CTRLS;, then the event will not be sent to
+               <para>If the event is generated due to a call to &VIDIOC-S-CTRL; or
+               &VIDIOC-S-EXT-CTRLS;, then the event will <emphasis>not</emphasis> be sent to
                the file handle that called the ioctl function. This prevents
-               nasty feedback loops.
+               nasty feedback loops. If you <emphasis>do</emphasis> want to get the
+               event, then set the <constant>V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK</constant>
+               flag.
+               </para>
 
-               This event type will ensure that no information is lost when
+               <para>This event type will ensure that no information is lost when
                more events are raised than there is room internally. In that
                case the &v4l2-event-ctrl; of the second-oldest event is kept,
                but the <structfield>changes</structfield> field of the
                second-oldest event is ORed with the <structfield>changes</structfield>
-               field of the oldest event.
+               field of the oldest event.</para>
            </entry>
          </row>
          <row>
                that are triggered by a status change such as <constant>V4L2_EVENT_CTRL</constant>.
                Other events will ignore this flag.</entry>
          </row>
+         <row>
+           <entry><constant>V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK</constant></entry>
+           <entry>0x0002</entry>
+           <entry><para>If set, then events directly caused by an ioctl will also be sent to
+               the filehandle that called that ioctl. For example, changing a control using
+               &VIDIOC-S-CTRL; will cause a V4L2_EVENT_CTRL to be sent back to that same
+               filehandle. Normally such events are suppressed to prevent feedback loops
+               where an application changes a control to a one value and then another, and
+               then receives an event telling it that that control has changed to the first
+               value.</para>
+
+               <para>Since it can't tell whether that event was caused by another application
+               or by the &VIDIOC-S-CTRL; call it is hard to decide whether to set the
+               control to the value in the event, or ignore it.</para>
+
+               <para>Think carefully when you set this flag so you won't get into situations
+               like that.</para>
+           </entry>
+         </row>
        </tbody>
       </tgroup>
     </table>
index a037739868e06bb7f98c00b0d09983a203a272d4..37a50e57f22293ab57b8e94324efb3cc103bc397 100644 (file)
@@ -590,7 +590,8 @@ static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
        fill_event(&ev, ctrl, changes);
 
        list_for_each_entry(sev, &ctrl->ev_subs, node)
-               if (sev->fh && sev->fh != fh)
+               if (sev->fh && (sev->fh != fh ||
+                               (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)))
                        v4l2_event_queue_fh(sev->fh, &ev);
 }
 
index baafe2f2e02a2d8fee9632dc6b1ce5dae14a06a4..2c4e83796301186c476a3bc85751a1b02b28e722 100644 (file)
@@ -1832,7 +1832,8 @@ struct v4l2_event {
        __u32                           reserved[8];
 };
 
-#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0)
+#define V4L2_EVENT_SUB_FL_SEND_INITIAL         (1 << 0)
+#define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK       (1 << 1)
 
 struct v4l2_event_subscription {
        __u32                           type;