On Sat, 22 Dec 2012, Helmut Jarausch wrote: > > Last time I've been using my PVRUSB2 (one or two years ago) > this wasn't necessary. And neither VLC nor MPLAYER2 are able > to read /dev/video0 unless I issue that control in advance.
Well I can't exactly explain why it's different for you now. But I can explain a few other things which hopefully should allow you to find a good solution. This might get lengthy, requiring some history... Way way back apparently in the early days of V4L there was a concept of a single video standard setting. That was an enumeration. The V4L API had a means whereby an app could get a list of the possible settings and then the app could choose one, communicating the choice back into the driver. Some time later (this is still before the pvrusb2 driver showed up), a concept arose in the V4L subsystem whereby the "video standard" was represented as a set of flags, implemented as a collection of bits in a bit mask. I think the rationale at the time was that this became a means for controlling / setting what subset of possible video standards a given driver / piece of hardware supports or was allowed to select from. There is a "video standard" bit mask concept throughout V4L; this mask is a 64 bit integer and there are well over 32 possible different standards defined / represented within that bit mask. This actually makes some sense when you realize that a lot of video hardware is more or less able to detect things correctly anyway, so it does sort of follow that you need a way to describe multiple possible standards at once... Some time after that, the pvrusb2 driver arrived on the scene and I chose to reconcile this dual-mechanism in the driver. Yes, it seems like something that every V4L should have to deal with, but at the time I was still learning how all this work, so I naively just "made it work". So what I did was to expose "both" mechanisms, which unfortunately seemed confusing. But within the driver what basically happened was that it computed the full set of available video standards as the bit mask, based on the detected hardware and some other bits of inference in the driver. The driver then used that subset to generate the old-style enumerated list which then also became available to applications that wanted to work in that format. Now, an aside about the sysfs interface: That sysfs driver interface is not a "real" V4L API of course, but it does make available at the shell all the "knobs" that can be adjusted in the driver. The part of the pvrusb2 driver that implements the sysfs interface doesn't "implicitly know" what all the controls are. Rather what that code does is it queries the rest of the driver for the set of controls and then makes each one appropriately visible (as an integer, enumeration, bit mask, etc) under /sys/class/pvrusb2/.... The nice thing about this approach is that now when the underlying controls change, there's no need to change the sysfs code in the driver because it automatically tracks. But this also means that as the underlying API changes, the sysfs representation can change as well... For this dicussion, the sysfs controls in question are: ctl_video_standard - enumerated list of standards ctl_video_standard_mask_available - bit mask of available standards ctl_video_standard_mask_active - bit mask of active standards ctl_video_standard_mask_detected - bit mask of detected standards More explained about this further down... The control that is simplest to understand of course is just ctl_video_standard, but it is based on that computed enumerated list that dates from the early days of the driver. The other three work from bit masks. The pvrusb2 driver internally ensures that they all stay in sync with one another. Keep reading... Now because the sysfs part of the pvrusb2 driver doesn't "know" all the controls, it will only export what it finds. And what's happened is that within V4L that old concept of enumerated standards has gone obsolete and disappeared from the V4L core. And when that happened, I removed from the pvrusb2 driver all the old logic that generated that enumerated list. The removal happened roughly coincident with the 3.0 kernel. With the removal of that logic, the underlying enumeration is gone and THAT is why the simple-to-understand ctl_video_standard is no longer present when you're running under a recent-enough kernel. However you can still control things with the *_mask_active sysfs control. Bit masks, as operated through the driver's sysfs interface, are a little wierd. Each defined bit in a bit mask is just a token, e.g. "NTSC-M" or "PAL-B1". You can retrieve a list of the legal tokens just by cat'ing the bit_val file. For example, assuming you are sitting in the pvrusb2 driver's sysfs control directory at the shell prompt, then: cat ctl_video_standard_mask_active/bit_val will spit back a list of legal tokens, each on its own line. If you just echo some set of whitespace-separated tokens into the control, then that set replaces what was there. For example, this: echo "NTSC-M PAL-M" >ctl_video_standard_mask_active/cur_val will replace the current bit mask with a new bit mask with just NTSC-M and PAL-M set. But this can get clumsy. There's a second syntax you can use to set and clear bits. This works for *ALL* sysfs controls which happen to be bit masks. Just prefix each token with "+" or "-". Use "+" to add that token to the set, and "-" to remove that token from the set. For the video standards, here's how you can just turn on, say, SECAM-B: echo "+SECAM-B" >ctl_video_standard_mask_active/cur_val Likewise, to turn off NTSC-M, assuming of course that it was on before: echo "-NTSC-M" >ctl_video_standard_mask_active/cur_val I said earlier there were three controls of interest here. They are inter-related: ctl_video_standard_mask_active - This controls the actual video standard bits that are enabled and that the rest of V4L sees. This is the bit mask that gets directly adjusted via the V4L2 API, and this is what you have to change to affect the hardware. (Note that when the old video standard enumeration was changed, the driver sync'ed this control to that enumeration's state and then used the resulting set bits to pass the information down into the rest of V4L.) ctl_video_standard_mask_detected - This is just the set of video standards available that was detected by the hardware. Not that unlike *_mask_active, this one is read-only in the file system. You can't change it. It's really just for informational purposes. This "detected set" is used to help determine the default video mode - however if the device reports ability to support "too many" standards, then that leaves an ambiguity. The driver will pick "something" as the starting default bit it might not be what you want. (This is more of an issue for European multi-standard devices, then North American variants where there's really only one standard anyway.) ctl_video_standard_mask_available - This is the set of actual available video standards, which is normally a superset of *_mask_detected. The driver uses the detected set as a hint for enabling additional potential video standards. You can change this, which causes the driver to constrain what standards an app is allowed to set as active (or to expand the available list). This is useful to override cases where the driver might be too cautious. Everyone still follow? There's one more sysfs control field of interest "custom_val". This is a different string representation for a given control that is more compact. Yes, you can echo into that as well, but honestly right now I've forgotten the exact mechanics there so I'll leave that for now as an exercise to the reader :-) So, in short, to set a different video standard via sysfs, then you need to enumerate the list of tokens by doing: cat ctl_video_standard_mask_active/bit_val Then pick what you want and echo the desired token(s) as a whitespace-separated list into the cur_val field. No, you really can't set them all at once. Well, I mean you *can*, but the hardware probably won't like it very much. Some subsets do make sense when combined together, like probably PAL-B and PAL-G, but the answer of what works with what is really a hardware thing that the pvrusb2 driver can't know. Just pick what you want and set it. Or better still, if you are really running with a V4L2 app, then set the desired standard in the app and let the app control the driver appropriately. I hope that helps clear things up. I know there's a few other pending questions on this list. More later... -Mike -- Mike Isely isely @ isely (dot) net PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8 _______________________________________________ pvrusb2 mailing list [email protected] http://www.isely.net/cgi-bin/mailman/listinfo/pvrusb2
