aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-dqevent.xml33
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml20
-rw-r--r--drivers/media/v4l2-core/v4l2-event.c36
-rw-r--r--include/media/v4l2-event.h4
-rw-r--r--include/uapi/linux/videodev2.h8
5 files changed, 101 insertions, 0 deletions
diff --git a/Documentation/DocBook/media/v4l/vidioc-dqevent.xml b/Documentation/DocBook/media/v4l/vidioc-dqevent.xml
index 89891adb928a..820f86e8744b 100644
--- a/Documentation/DocBook/media/v4l/vidioc-dqevent.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-dqevent.xml
@@ -242,6 +242,22 @@
242 </tgroup> 242 </tgroup>
243 </table> 243 </table>
244 244
245 <table frame="none" pgwide="1" id="v4l2-event-src-change">
246 <title>struct <structname>v4l2_event_src_change</structname></title>
247 <tgroup cols="3">
248 &cs-str;
249 <tbody valign="top">
250 <row>
251 <entry>__u32</entry>
252 <entry><structfield>changes</structfield></entry>
253 <entry>
254 A bitmask that tells what has changed. See <xref linkend="src-changes-flags" />.
255 </entry>
256 </row>
257 </tbody>
258 </tgroup>
259 </table>
260
245 <table pgwide="1" frame="none" id="changes-flags"> 261 <table pgwide="1" frame="none" id="changes-flags">
246 <title>Changes</title> 262 <title>Changes</title>
247 <tgroup cols="3"> 263 <tgroup cols="3">
@@ -270,6 +286,23 @@
270 </tbody> 286 </tbody>
271 </tgroup> 287 </tgroup>
272 </table> 288 </table>
289
290 <table pgwide="1" frame="none" id="src-changes-flags">
291 <title>Source Changes</title>
292 <tgroup cols="3">
293 &cs-def;
294 <tbody valign="top">
295 <row>
296 <entry><constant>V4L2_EVENT_SRC_CH_RESOLUTION</constant></entry>
297 <entry>0x0001</entry>
298 <entry>This event gets triggered when a resolution change is
299 detected at an input. This can come from an input connector or
300 from a video decoder.
301 </entry>
302 </row>
303 </tbody>
304 </tgroup>
305 </table>
273 </refsect1> 306 </refsect1>
274 <refsect1> 307 <refsect1>
275 &return-value; 308 &return-value;
diff --git a/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml b/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
index 5c70b616d818..f016254377aa 100644
--- a/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
@@ -155,6 +155,26 @@
155 </entry> 155 </entry>
156 </row> 156 </row>
157 <row> 157 <row>
158 <entry><constant>V4L2_EVENT_SOURCE_CHANGE</constant></entry>
159 <entry>5</entry>
160 <entry>
161 <para>This event is triggered when a source parameter change is
162 detected during runtime by the video device. It can be a
163 runtime resolution change triggered by a video decoder or the
164 format change happening on an input connector.
165 This event requires that the <structfield>id</structfield>
166 matches the input index (when used with a video device node)
167 or the pad index (when used with a subdevice node) from which
168 you want to receive events.</para>
169
170 <para>This event has a &v4l2-event-source-change; associated
171 with it. The <structfield>changes</structfield> bitfield denotes
172 what has changed for the subscribed pad. If multiple events
173 occurred before application could dequeue them, then the changes
174 will have the ORed value of all the events generated.</para>
175 </entry>
176 </row>
177 <row>
158 <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry> 178 <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
159 <entry>0x08000000</entry> 179 <entry>0x08000000</entry>
160 <entry>Base event number for driver-private events.</entry> 180 <entry>Base event number for driver-private events.</entry>
diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c
index 86dcb5483c42..8761aab99de9 100644
--- a/drivers/media/v4l2-core/v4l2-event.c
+++ b/drivers/media/v4l2-core/v4l2-event.c
@@ -318,3 +318,39 @@ int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh,
318 return v4l2_event_unsubscribe(fh, sub); 318 return v4l2_event_unsubscribe(fh, sub);
319} 319}
320EXPORT_SYMBOL_GPL(v4l2_event_subdev_unsubscribe); 320EXPORT_SYMBOL_GPL(v4l2_event_subdev_unsubscribe);
321
322static void v4l2_event_src_replace(struct v4l2_event *old,
323 const struct v4l2_event *new)
324{
325 u32 old_changes = old->u.src_change.changes;
326
327 old->u.src_change = new->u.src_change;
328 old->u.src_change.changes |= old_changes;
329}
330
331static void v4l2_event_src_merge(const struct v4l2_event *old,
332 struct v4l2_event *new)
333{
334 new->u.src_change.changes |= old->u.src_change.changes;
335}
336
337static const struct v4l2_subscribed_event_ops v4l2_event_src_ch_ops = {
338 .replace = v4l2_event_src_replace,
339 .merge = v4l2_event_src_merge,
340};
341
342int v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
343 const struct v4l2_event_subscription *sub)
344{
345 if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
346 return v4l2_event_subscribe(fh, sub, 0, &v4l2_event_src_ch_ops);
347 return -EINVAL;
348}
349EXPORT_SYMBOL_GPL(v4l2_src_change_event_subscribe);
350
351int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
352 struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
353{
354 return v4l2_src_change_event_subscribe(fh, sub);
355}
356EXPORT_SYMBOL_GPL(v4l2_src_change_event_subdev_subscribe);
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
index be05d019de25..1ab9045e52e3 100644
--- a/include/media/v4l2-event.h
+++ b/include/media/v4l2-event.h
@@ -132,4 +132,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
132void v4l2_event_unsubscribe_all(struct v4l2_fh *fh); 132void v4l2_event_unsubscribe_all(struct v4l2_fh *fh);
133int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh, 133int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh,
134 struct v4l2_event_subscription *sub); 134 struct v4l2_event_subscription *sub);
135int v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
136 const struct v4l2_event_subscription *sub);
137int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
138 struct v4l2_fh *fh, struct v4l2_event_subscription *sub);
135#endif /* V4L2_EVENT_H */ 139#endif /* V4L2_EVENT_H */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index db4aebd8baba..00259d2baa10 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1764,6 +1764,7 @@ struct v4l2_streamparm {
1764#define V4L2_EVENT_EOS 2 1764#define V4L2_EVENT_EOS 2
1765#define V4L2_EVENT_CTRL 3 1765#define V4L2_EVENT_CTRL 3
1766#define V4L2_EVENT_FRAME_SYNC 4 1766#define V4L2_EVENT_FRAME_SYNC 4
1767#define V4L2_EVENT_SOURCE_CHANGE 5
1767#define V4L2_EVENT_PRIVATE_START 0x08000000 1768#define V4L2_EVENT_PRIVATE_START 0x08000000
1768 1769
1769/* Payload for V4L2_EVENT_VSYNC */ 1770/* Payload for V4L2_EVENT_VSYNC */
@@ -1795,12 +1796,19 @@ struct v4l2_event_frame_sync {
1795 __u32 frame_sequence; 1796 __u32 frame_sequence;
1796}; 1797};
1797 1798
1799#define V4L2_EVENT_SRC_CH_RESOLUTION (1 << 0)
1800
1801struct v4l2_event_src_change {
1802 __u32 changes;
1803};
1804
1798struct v4l2_event { 1805struct v4l2_event {
1799 __u32 type; 1806 __u32 type;
1800 union { 1807 union {
1801 struct v4l2_event_vsync vsync; 1808 struct v4l2_event_vsync vsync;
1802 struct v4l2_event_ctrl ctrl; 1809 struct v4l2_event_ctrl ctrl;
1803 struct v4l2_event_frame_sync frame_sync; 1810 struct v4l2_event_frame_sync frame_sync;
1811 struct v4l2_event_src_change src_change;
1804 __u8 data[64]; 1812 __u8 data[64];
1805 } u; 1813 } u;
1806 __u32 pending; 1814 __u32 pending;