Posts
3951
Following
256
Followers
410
OpenPGP: 3AB05486C7752FE1
Codeberg is pretty good social Git for this type project. I'm willing to accept outside influence but Github is a bit too noisy for this.
0
0
0
I thought that I've been doing this for ages but realized that mostly I've been active with this only through out this year with long break.

Definitely not giving up :-) It starts to materialize slowly. At least I have a hobby for this year...
1
0
0

Jarkko Sakkinen

Edited 1 hour ago
$ git -P log --oneline v6.13..
102e81a4ca67 (HEAD -> v4l2-loopback, origin/v4l2-loopback, origin/HEAD) Use _IO*() for declaring the ioctls
b23722b0cd42 Rename ready_for_capture as active_writers
e61f00594c83 Open code free_devices()
599291c9d3ee Remove V4L2LOOPBACK_CTL_QUERY
5cc9d24a3171 Set video_set_drvdata(dev->vdev, dev) directly
3b13a59d5144 Remove HAVE_TIMER_SETUP
743149844edb Remove sysfs device attributes
84ee7af7394b Remove redundant module parameters
29bb94896aa4 Do not create a device in module_init()
122ddd353ccb Remove redundant module information
37955369d9f2 Remove LINUX_VERSION_CODE checks
e87cf1bb681a Reburnish file headers and SPDX identifiers
497e4575d495 Remove clang-format comments
7b4bb35c0be3 Remove dprintk*()
353e603c9d3c Remove MARK()
6009806fe555 media: v4l2-loopback

The point of all these small tweaks:

  1. Open knots to fit VB2.
  2. Open knots to split driver and clients.

I’ve also tested that every commit is still running version, except the top most break ABI (not API).

The first thing to do with fd based model is to make capabilities a static creation time thing:

diff --git a/drivers/media/v4l2-core/v4l2-loopback.c b/drivers/media/v4l2-core/v4l2-loopback.c
index 2f5b81628e7c..f643d5dd9dca 100644
--- a/drivers/media/v4l2-core/v4l2-loopback.c
+++ b/drivers/media/v4l2-core/v4l2-loopback.c
@@ -232,9 +232,11 @@ struct v4l2_loopback_device {
                               * this differs slightly from !ready_for_capture,
                               * e.g. when using fallback images */
        int active_readers; /* increase if any reader starts streaming */
-       int announce_all_caps; /* set to false, if device caps (OUTPUT/CAPTURE)
-                                * should only be announced if the resp. "ready"
-                                * flag is set; default=TRUE */
+
+        /*
+         * Any subset of V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT.
+         */
+       __u32 capabilities;

        int min_width, max_width;
        int min_height, max_height;
@@ -777,22 +779,10 @@ static int vidioc_querycap(struct file *file, void *priv,
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "platform:v4l2loopback-%03d", dev->device_nr);

-       if (dev->announce_all_caps) {
-               capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
-       } else {
-               if (dev->ready_for_capture) {
-                       capabilities |= V4L2_CAP_VIDEO_CAPTURE;
-               }
-               if (dev->ready_for_output) {
-                       capabilities |= V4L2_CAP_VIDEO_OUTPUT;
-               }
-       }
-
-       dev->vdev->device_caps =
-               cap->device_caps = cap->capabilities = capabilities;
-
-       cap->capabilities |= V4L2_CAP_DEVICE_CAPS;
-
+       capabilities |= dev->capabilities;
+       dev->vdev->device_caps = capabilities;
+       cap->device_caps = capabilities;
+       cap->capabilities = capabilities | V4L2_CAP_DEVICE_CAPS;
        memset(cap->reserved, 0, sizeof(cap->reserved));
        return 0;
 }
@@ -1273,7 +1263,7 @@ static int vidioc_enum_output(struct file *file, void *fh,
        struct v4l2_loopback_device *dev = video_drvdata(file);
        __u32 index = outp->index;

-       if (!dev->announce_all_caps && !dev->ready_for_output)
+       if (!dev->capabilities && !dev->ready_for_output)
                return -ENOTTY;

        if (0 != index)
@@ -1304,7 +1294,7 @@ static int vidioc_g_output(struct file *file, void *fh, unsigned int *i)
 {
        struct v4l2_loopback_device *dev = video_drvdata(file);

-       if (!dev->announce_all_caps && !dev->ready_for_output)
+       if (!dev->capabilities && !dev->ready_for_output)
                return -ENOTTY;
        if (i)
                *i = 0;
@@ -1318,7 +1308,7 @@ static int vidioc_s_output(struct file *file, void *fh, unsigned int i)
 {
        struct v4l2_loopback_device *dev = video_drvdata(file);

-       if (!dev->announce_all_caps && !dev->ready_for_output)
+       if (!dev->capabilities && !dev->ready_for_output)
                return -ENOTTY;

        if (i)
@@ -1372,7 +1362,7 @@ static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
 {
        struct v4l2_loopback_device *dev = video_drvdata(file);

-       if (!dev->announce_all_caps && !dev->ready_for_capture)
+       if (!dev->capabilities && !dev->ready_for_capture)
                return -ENOTTY;
        if (i)
                *i = 0;
@@ -1386,7 +1376,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
 {
        struct v4l2_loopback_device *dev = video_drvdata(file);

-       if (!dev->announce_all_caps && !dev->ready_for_capture)
+       if (!dev->capabilities && !dev->ready_for_capture)
                return -ENOTTY;
        if (i == 0)
                return 0;
@@ -2383,7 +2373,7 @@ static int v4l2_loopback_add(struct v4l2_loopback_config *conf, int *ret_nr)
        struct v4l2_ctrl_handler *hdl;
        int err = -ENOMEM;

-       if (conf->announce_all_caps != 0 && conf->announce_all_caps != 1)
+       if (conf->capabilities & ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT))
                return -EINVAL;

        if (conf->max_buffers > 0)
@@ -2488,7 +2478,7 @@ static int v4l2_loopback_add(struct v4l2_loopback_config *conf, int *ret_nr)
        dev->keep_format = 0;
        dev->sustain_framerate = 0;

-       dev->announce_all_caps = conf->announce_all_caps;
+       dev->capabilities = conf->capabilities;
        dev->min_width = min_width;
        dev->min_height = min_height;
        dev->max_width = max_width;
diff --git a/include/uapi/linux/v4l2-loopback.h b/include/uapi/linux/v4l2-loopback.h
index 74527dd3676c..d10270548f84 100644
--- a/include/uapi/linux/v4l2-loopback.h
+++ b/include/uapi/linux/v4l2-loopback.h
@@ -58,14 +58,10 @@ struct v4l2_loopback_config {
          */
        int debug;

-       /**
-         * whether to announce OUTPUT/CAPTURE capabilities exclusively
-         * for this device or not
-         * (!exclusive_caps)
-        * NOTE: this is going to be removed once separate output/capture
-        *       devices are implemented
+        /*
+         * Any subset of V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT.
          */
-       int announce_all_caps;
+       __u32 capabilities;
 };

 #define V4L2LOOPBACK_CTL_ADD _IOW('v', 0x00, struct v4l2_loopback_config)

The driver side will then respect these and clients will be “sort of” mirror of the capabilities. And most likely exclusive per streamon. Internals need some clean ups and some add-ons. Perhaps quickest PoC is to just add DRIVER enum opener_type at first, which the fd returned by ioctl will receive.

Still need to clean up and clear the path a bit :-) I just did the above beginnings of a patch to get idea what the other end will look like and where I just converge into…

https://codeberg.org/jarkko/linux-v4l2-loopback.git

1
0
0

Free Software Foundation

is almost here, and we wanted to kick off the celebrations with a little 💗 When was the term "" created?

See if you can answer this correctly before your friends :D

Answer will be posted tomorrow morning.

0% 1973
100% 1986
0% 1994
0% 2001
0
1
0
Obviously for "co-developed-by" if you do a one-line random fix, not going to add co-developed-by, but for bunch of actually useful changes, yes I will do that. I'll use my judgement on this (which is usually more eager to give credit than don't).
1
0
0
So the person who created issue created bunch of actually useful fixes for the OOT driver so I opened up a tree for collaborative work:

https://codeberg.org/jarkko/linux-v4l2-loopback

I explained the process in the Github issue. I'll document it later on to the Codeberg wiki:

https://docs.codeberg.org/getting-started/wiki/
1
1
1

Jarkko Sakkinen

Edited yesterday
It's a non-Rust related principle in kernel that:

1. No code shall pass without a caller.
2. No code shall be more generic than its callers require it to be (because we don't hold API/ABI compatibility per version for in-kernel API's).
0
1
0

Jarkko Sakkinen

A non-rustianated opinion about DMA patches: it should be part of patch set that requires DMA.

I.e. I was eager to try it out but there is no payload to test. I did add lei filter to get everything from rust-for-linux matching DMA so looking forward to do this in future :-)

#rust #linux #kernel #dma
1
1
1

Jarkko Sakkinen

Edited yesterday
It's good to have some discussion on topic and find out the blockers. Better to do in community than isolated as far as I'm concerned.
1
0
1

Jarkko Sakkinen

On v4l2-loopback, always open for collaboration instead of sole ownership of the end artifacts if it makes sense: https://github.com/v4l2loopback/v4l2loopback/discussions/617#discussioncomment-12109699
1
0
0

An Open Letter to All European Politicians and Leaders to Abandon X/Twitter:

"By abandoning X/Twitter, leaders can reduce its credibility, promote fairer alternatives, and take a stand against the spread of disinformation, ensuring democratic principles are upheld."

H/T to @everton137 for organizing this - already close to 1,000 signatures:

https://www.openpetition.eu/petition/online/an-open-letter-to-all-european-politicians-and-leaders-to-abandon-x-twitter

1
12
0
@pinkforest I personally buy my music from Bandcamp rather than stream it from Spotify so doing at least in that sense my part :-) And still buy printed books etc.
0
0
0
@josh yeah, it is super convenient
0
0
0
OK, writing that down helped me to realize how it works: ready_for_output is zeroed once there is at least a vidioc_streamon for writer and its never set to one again before all file handles have been closed.

I.e. that locks down the stream settings up until to the point that no one has the file open.

Awesome... This unlocked the worst knot to move forward in separating the driver and clients and not break anything.
0
0
0

Jarkko Sakkinen

Edited 2 days ago
Reverse engineering v4l2-loopback state variables and making sense of insanity:

1. active_readers: number of read streams on, which can be at most one.
2. ready_for_capture: number of writer streams on, despite the name implying being a boolean. Probably I should for now rename this as "active_writers" to add a bit of clarity.
3. ready_for_output: actually a boolean, which tells whether ready_for_capture is zero

Getting motivated into even trying figuring out these state variables has been a huge struggle. I take baby step at a time, and then have a recovery period ;-)

Now that I figured those out I though now I can get rid of ready_for_output given that it can be mapped to ready_for_capture, BUT there is a comment describing ready_for_output that fucks my brain:

"set to true when no writer is currently attached this differs slightly from !ready_for_capture, e.g. when using fallback images"

I can only see ready_for_output zeroed in vidioc_streamon(). I don't get this and I don't actually know what fallback images are and when they are used.

After all this trouble what an anticlimax moment. Before I decipher that comment I'm too scared to remove the state variable. I did check all the sites it is used and do not see any obvious harm that could do.
1
0
1
@vitaut good. competition rules. not having death wishes for C++.
0
0
0
I've been for a while planning for a while to add anonymous inodes but every time I start doing that I noticed similar step as the commits below the top-most are. It's better to work like this up until pieces go to right by themselves.

There's also still too much mess to take any bold actions on the use of locks. It also would need much cleaner starting point :-) This is time-consuming, unproductive but also fun...
0
0
0

Jarkko Sakkinen

We meet again after three week break:

https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/log/?h=v4l2-loopback

I collect below the top-most commits that are locked in as pretty much dead obvious changes and the top-most commit (whatever its name happens to be) is the dumpster.

I started this by unpurging the top-most just to recall where I was at. Commit ID's live as I might add a new commit in any position (as deep down in history as possible as it makes sense).
1
0
0
Show older