Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document an API-way to test for v4l2loopback module presence #397

Open
BenBE opened this issue Feb 2, 2021 · 11 comments
Open

Document an API-way to test for v4l2loopback module presence #397

BenBE opened this issue Feb 2, 2021 · 11 comments
Assignees
Milestone

Comments

@BenBE
Copy link
Contributor

BenBE commented Feb 2, 2021

Environment

  • v4l2loopback version: 0.12.3
  • kernel version: 5.9.0rc6-generic
  • Distribution (+version): Lubuntu 20.04.2 LTS (focal)

Problem:

Steps to reproduce:

  1. Start working on software that uses v4l2loopback in userspace
  2. Try to detect if v4l2loopback is loaded

Observed Results:

I could not find a suitable, documented way how to detect if v4l2loopback is loaded other than trying to look for the module in the list of loaded modules, trying to find its control device file or trying to access some video device in a way only permitted IFF the module is loaded. Unfortunately the documentation that comes with this module documents no easy way for userland tools to check for the kernel module's presence or its version/capabilities.

Expected Results:

Some API or other easy to check means that a user-land application can use to check if v4l2loopback is available and gather information about its capabilities.

A possible solution to this might e.g. providing a standardized file in procfs that the kernel module populates with its configuration once it's loaded or configured. Alternatively a subtree inside sysfs might be provided for capability gathering and configuration purposes.

@BenBE BenBE added the needs triage new issues label Feb 2, 2021
@umlaeute
Copy link
Owner

umlaeute commented Feb 3, 2021

i don't see any benefit apart from what we already have.
just iterate over /dev/video* and use VIDIOC_QUERYCAP to query the capabilities and see if they match your expectations.

@umlaeute umlaeute removed the needs triage new issues label Feb 3, 2021
@BenBE
Copy link
Contributor Author

BenBE commented Feb 3, 2021

So if I see this right, it mostly boils down to:

  1. Try to open /dev/v4l2loopback -> ENOENT == Not loaded
  2. Do a V4L2LOOPBACK_CTL_QUERY``ioctl(2) to query capabilities -> ENOSYS == Not loaded
  3. Check results to contain required capabilities (Output Sink + Pixel Formats). -> None found == No sink devices were created.

Unfortunately it doesn't seem like v4l2loopback.h is installed anywhere (at least with the downstream Debian/Ubuntu packages), thus the kernel structures and constants used are unavailable (unless explicitly linking to the source tree).

So basically there are two things open:

  1. Document the above steps in e.g. the README as a suggested reference implementation (I could do this)
  2. Provide some devel package (e.g. v4l2loopback-dev) that installs required headers to common include paths for users of this module (e.g. /usr/include/v4l2loopback/).

Anything I'm missing?

@umlaeute
Copy link
Owner

umlaeute commented Feb 3, 2021

that's not what i meant.

what i meant is:

  1. check if there is a /dev/video* device with OUTPUT capabilities; if you found one, write data to it
  2. check if there is a /dev/video* device with CAPTURE capabilities; if you found one, read data from it

i don't see a reason to document this. i don't understand why you want to do that in the first place.

there is no "API-way" to detect the presence of a webcam, and yet this is not a problem.

@BenBE
Copy link
Contributor Author

BenBE commented Feb 3, 2021

The question boils down to allow the program e.g. to create additional output devices as necessary (similar to the dynamic cam allocation from v4l2loopback-ctl) for e.g. debugging.

@umlaeute
Copy link
Owner

umlaeute commented Feb 4, 2021

how would "an API-way to test for v4l2loopback module presence" help with that feat?
how would you create "additional output devices" in the first place - as opposed to "dynamic cam allocation from v4l2loopback-ctl"? (I mean: how would that be different?)

@BenBE
Copy link
Contributor Author

BenBE commented Feb 4, 2021

In an ideal world. all those functions would be covered in a small userland library that other tools (like v4l2loopback-ctl) could just call to do things.

An "API-way to test module presence" could (in absense of a usermode library) be a quick sanity check a program could perform (#397 (comment), steps 1+2) and would ideally know after those steps succeeded, that (except for operations not permitted) the remaining tasks are likely to also succeed.

View it from the UX perspective: Giving an user the error "Required kernel functions provided by module XY are not available." is much better, than replying with "Failed to open video device" (for a device name the user supplied).

Another aspect why a documented way to check for the presence of the module is strongly encouraged are interoperability and backward compatibility: As long as I can maintain a minimal interface that users of my functionality can rely on, I can change whatever else I like and always allow the user to figure out, how to react in a particular situation. And if I even try to keep most of my interface stable, I have high chances that even really old software can use the most recent releases without need for recompilation.

@umlaeute
Copy link
Owner

umlaeute commented Feb 4, 2021

it seems you cannot really make up your mind what you actually want - at least, I cannot make up my mind what you actually want.

afaiu, "to allow the program e.g. to create additional output devices" is totally unrelated to "loopback device not available" (which is how I read your UX example).

my argument is really you should not depend on a given module, but on a given functionality.
examples:

  • if the module is built into the kernel (right now this is obviously not working out-of-the box; but consider submit v4l2loopback to the upstream kernel #268) rather than a separate module, then testing whether the v4l2loopback module is loaded doesn't answer your question at all
  • likewise if you use one of the forks of v4l2loopback (or a competing module)

so the question is still: what is it that you do want to detect?

as for "a small userland library that other tools (like v4l2loopback-ctl) could just call to do things.":

the v4l2loopback-ctl tool does exactly this: it uses a small well-defined API to access the stuff it needs. this API is ioctl.
i don't see a need to add another layer of indirection (the only purpose of which (as i see it) would be to add an artificial dependency)

@BenBE
Copy link
Contributor Author

BenBE commented Feb 4, 2021

it seems you cannot really make up your mind what you actually want - at least, I cannot make up my mind what you actually want.

afaiu, "to allow the program e.g. to create additional output devices" is totally unrelated to "loopback device not available" (which is how I read your UX example).

my argument is really you should not depend on a given module, but on a given functionality.

ACK.

as for "a small userland library that other tools (like v4l2loopback-ctl) could just call to do things.":

the v4l2loopback-ctl tool does exactly this: it uses a small well-defined API to access the stuff it needs. this API is ioctl.

Okay. And for those ioctls I need the proper values. These are in a header (v4l2loopback.h) that is AFAIC not exposed outside the current source tree for other applications to use.
--> Provide this header in a default location (e.g. /usr/include/v4l2loopback/v4l2loopback.h) so applications can use this.
Documentation for using the API then would boil down to "call the ioctls from this header and ENOSYS means they're unavailable. I can live with that.

i don't see a need to add another layer of indirection (the only purpose of which (as i see it) would be to add an artificial dependency)

Granted. The userland library doesn't need to do much normally. One purpose it can have is to work around API changes in the module or with different versions/forks of the module. A second (probably more interesting usecase) is abstraction to simplify common tasks for users of the functionality, like iterating devices, get/set properties, etc …

The userland library is fully optional and not part of what I want to have as a result of this PR. What I'm aiming at is getting a well-defined interface, with everything I need to use it, in header files, that are properly available for use through programs not part of this repository's source tree.

If you say this API is the ioctl interface. That's fine with me. Just make sure there's a header providing all the ioctl constants, enums, types etc.pp. that a program needs (that part is IMHO missing). The second thing that's missing is maybe a oneliner in the docs saying "The module can be used in your own software by including file XY.h".

FWIW: On Debian/Ubuntu I'm basically just missing a package v4l2loopback-dev pushing v4l2loopback.h to /usr/include/v4l2loopback/v4l2loopback.h. And maybe a line in the docs pointing you to that header for your user-space applications.

@umlaeute
Copy link
Owner

umlaeute commented Feb 4, 2021

you are missing the headers because there hasn't been a release of v4l2loopback yet that actually has these headers (nor the possibility to dynamically manage devices)

@BenBE
Copy link
Contributor Author

BenBE commented Feb 4, 2021

Is such a release planned already? Any rough timescale maybe?

TIA.

@umlaeute
Copy link
Owner

umlaeute commented Feb 4, 2021

i'd like to have #359 implemented first, as i figure the API will change a bit.

@umlaeute umlaeute added this to the release 0.13 milestone Feb 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants