[media] v4l: Add source change event
authorArun Kumar K <arun.kk@samsung.com>
Wed, 14 May 2014 06:59:42 +0000 (03:59 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Fri, 23 May 2014 22:50:40 +0000 (19:50 -0300)
This event indicates that the video device has encountered
a source parameter change during runtime. This can typically be a
resolution change detected by a video decoder OR a format change
detected by an input connector.

This needs to be nofified to the userspace and the application may
be expected to reallocate buffers before proceeding. The application
can subscribe to events on a specific pad or input port which
it is interested in.

Signed-off-by: Arun Kumar K <arun.kk@samsung.com>
Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Documentation/DocBook/media/v4l/vidioc-dqevent.xml
Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
drivers/media/v4l2-core/v4l2-event.c
include/media/v4l2-event.h
include/uapi/linux/videodev2.h

index 89891adb928a327ddca0aad20a6297563bbfce54..820f86e8744b356ae5a59144e25d4ee5edf57900 100644 (file)
       </tgroup>
     </table>
 
+    <table frame="none" pgwide="1" id="v4l2-event-src-change">
+      <title>struct <structname>v4l2_event_src_change</structname></title>
+      <tgroup cols="3">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>changes</structfield></entry>
+           <entry>
+             A bitmask that tells what has changed. See <xref linkend="src-changes-flags" />.
+           </entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+
     <table pgwide="1" frame="none" id="changes-flags">
       <title>Changes</title>
       <tgroup cols="3">
        </tbody>
       </tgroup>
     </table>
+
+    <table pgwide="1" frame="none" id="src-changes-flags">
+      <title>Source Changes</title>
+      <tgroup cols="3">
+       &cs-def;
+       <tbody valign="top">
+         <row>
+           <entry><constant>V4L2_EVENT_SRC_CH_RESOLUTION</constant></entry>
+           <entry>0x0001</entry>
+           <entry>This event gets triggered when a resolution change is
+           detected at an input. This can come from an input connector or
+           from a video decoder.
+           </entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
   </refsect1>
   <refsect1>
     &return-value;
index 5c70b616d8185c0645044b0e270398932a0d28c9..f016254377aad2bf1c4be3d7c4e19f7e591b527f 100644 (file)
              frame interval in between them.</para>
            </entry>
          </row>
+         <row>
+           <entry><constant>V4L2_EVENT_SOURCE_CHANGE</constant></entry>
+           <entry>5</entry>
+           <entry>
+             <para>This event is triggered when a source parameter change is
+              detected during runtime by the video device. It can be a
+              runtime resolution change triggered by a video decoder or the
+              format change happening on an input connector.
+              This event requires that the <structfield>id</structfield>
+              matches the input index (when used with a video device node)
+              or the pad index (when used with a subdevice node) from which
+              you want to receive events.</para>
+
+              <para>This event has a &v4l2-event-source-change; associated
+             with it. The <structfield>changes</structfield> bitfield denotes
+             what has changed for the subscribed pad. If multiple events
+             occurred before application could dequeue them, then the changes
+             will have the ORed value of all the events generated.</para>
+           </entry>
+         </row>
          <row>
            <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
            <entry>0x08000000</entry>
index 86dcb5483c4219da6d86d2c3423a8c857449256b..8761aab99de95b2f6e0efc80e2a4d9780b62e9b3 100644 (file)
@@ -318,3 +318,39 @@ int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh,
        return v4l2_event_unsubscribe(fh, sub);
 }
 EXPORT_SYMBOL_GPL(v4l2_event_subdev_unsubscribe);
+
+static void v4l2_event_src_replace(struct v4l2_event *old,
+                               const struct v4l2_event *new)
+{
+       u32 old_changes = old->u.src_change.changes;
+
+       old->u.src_change = new->u.src_change;
+       old->u.src_change.changes |= old_changes;
+}
+
+static void v4l2_event_src_merge(const struct v4l2_event *old,
+                               struct v4l2_event *new)
+{
+       new->u.src_change.changes |= old->u.src_change.changes;
+}
+
+static const struct v4l2_subscribed_event_ops v4l2_event_src_ch_ops = {
+       .replace = v4l2_event_src_replace,
+       .merge = v4l2_event_src_merge,
+};
+
+int v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
+                               const struct v4l2_event_subscription *sub)
+{
+       if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
+               return v4l2_event_subscribe(fh, sub, 0, &v4l2_event_src_ch_ops);
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(v4l2_src_change_event_subscribe);
+
+int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
+               struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
+{
+       return v4l2_src_change_event_subscribe(fh, sub);
+}
+EXPORT_SYMBOL_GPL(v4l2_src_change_event_subdev_subscribe);
index be05d019de25e17f8aa3f5ec4698810f17ec4795..1ab9045e52e3815f88702cc91469a3646e2b46b6 100644 (file)
@@ -132,4 +132,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
 void v4l2_event_unsubscribe_all(struct v4l2_fh *fh);
 int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh,
                                  struct v4l2_event_subscription *sub);
+int v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
+                               const struct v4l2_event_subscription *sub);
+int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
+               struct v4l2_fh *fh, struct v4l2_event_subscription *sub);
 #endif /* V4L2_EVENT_H */
index db4aebd8babaa09bdefed4bd43184927d6d0faf3..00259d2baa101dd197c7fe76231c8a5b0d958b90 100644 (file)
@@ -1764,6 +1764,7 @@ struct v4l2_streamparm {
 #define V4L2_EVENT_EOS                         2
 #define V4L2_EVENT_CTRL                                3
 #define V4L2_EVENT_FRAME_SYNC                  4
+#define V4L2_EVENT_SOURCE_CHANGE               5
 #define V4L2_EVENT_PRIVATE_START               0x08000000
 
 /* Payload for V4L2_EVENT_VSYNC */
@@ -1795,12 +1796,19 @@ struct v4l2_event_frame_sync {
        __u32 frame_sequence;
 };
 
+#define V4L2_EVENT_SRC_CH_RESOLUTION           (1 << 0)
+
+struct v4l2_event_src_change {
+       __u32 changes;
+};
+
 struct v4l2_event {
        __u32                           type;
        union {
                struct v4l2_event_vsync         vsync;
                struct v4l2_event_ctrl          ctrl;
                struct v4l2_event_frame_sync    frame_sync;
+               struct v4l2_event_src_change    src_change;
                __u8                            data[64];
        } u;
        __u32                           pending;