[pvrusb2] Video standards [was: New driver snapshot: pvrusb2-mci-20080210]
Mike Isely
isely at isely.net
Tue Mar 11 23:25:23 CDT 2008
On Tue, 11 Mar 2008, Mark Goldberg wrote:
> On Mon, Mar 10, 2008 at 2:41 PM, Mike Isely <isely at isely.net> wrote:
> > Sorry I'm not ignoring you; just working on other things (like my actual
> > job)...
>
> Yes, I have a real job also.
>
> >
> > Yes you can force a different standard as a module option.
>
> > Another strategy you can do is
> > let the driver load with the defaults then use the sysfs interface to
> > then force the standard to whatever you want. In that case you can then
> > use symbolic values. I suggest you explore this now, but I may likely
> > have to provide more information there. But I won't really get a chance
> > to help at that level until Tuesday night at the earliest.
>
> It does not seem to be consistant with the three interfaces, as in the
> standard reported
> by the three may not match. I tried many different things and the
> results seem the same.
Video standard handling is, well, kind of messy. It used to be a lot
worse with this driver; I've tried to improve matters over time. Maybe
it's not actually simpler, but it is more flexible and automatically
adaptable now than it used to be. There is a fair amount of complexity
here, but for what it's worth, I haven't had to explain it much so I
guess that means it must be hiding itself pretty well :-) So bear with
me here as I try to explain...
The pvrusb2 driver actually tracks 3 different quantities that have to
do with the concept of "video standard". Two quantities are bit masks,
and one is an enumeration. Roughly, they are:
1. A bit mask representing the "currently set" video standard.
Normally this mask will only ever have a single bit set, but in a few
PAL configurations there can be two bits set.
2. A bit mask representing the complete set of "supported" video
standards. This will have many bits set and its initial value depends
on what comes out of the eeprom in your device, which in turn is
influenced by which exact nationalized variant you have. An argument
can actually be made that nearly all these bits should always be set
since for some situations the device technically can support all
possible standards - but right now this is initialized based primarily
on eeprom contents.
3. An enumeration representing a non-overlapping set of possible
standard choices.
The enumeration business is strange, but it is a part of the V4L API and
I believe it dates from the bad old days of V4L1 history. Basically the
V4L API has a means where the app can enumerate a list of available,
supported standard choices. It's entirely up to the driver what to
return here. Each enumerated value is defined by a struct filling in
various things that describe attributes for that value (frame rate,
number of scan lines, etc).
The pvrusb2 driver internally really only cares about bit masks not that
enumeration. Everything it does internally is really in terms of the
"currently set" bit mask. But the enumeration is how the app learns
what can actually be set. To support the part of the V4L API which
wants to deal with the enumeration (VIDIOC_ENUMSTD), the pvrusb2 driver
first figures out what the value of that "supported" bit mask should be
(more on that later). Given that value then the driver proceeds to
synthesize a set of enumeration values that make sense (pvrusb2-std.c).
It uses some fairly generic heuristics to figure this out, but in the
end a list of enumerated standards are calculated and made available.
(I would guess that early simpler/less understood single-standard V4L
devices probably just returned hardcoded data here, but we're dealing
with modern hardware that can support various groups of standards so the
results are more dynamic.) From that point forward the driver will
parallel-track the current standard both as a bitmask value and as one
of these enumeration values - if there is a valid correspondence.
So, putting the enumeration aside for the moment, then how does the
driver deal with the "currently set" and "supported" bit masks?
The "supported" bit mask is computed during driver instance
initialization. Three sources of input are used: the eeprom contents, a
module option and, (for just the standalone driver) a "fudge" table.
The primary source is the eeprom contents. From that is computed an
initial bit mask. Then - if running the standalone driver - the "fudge"
table is checked (std_hacks[] in pvrusb2-hdw.c). The table is used to
look for certain sets of bits set from the eeprom, and based on what is
found there, additional "supported" bits might be set. For example, if
NTSC-M is reported by the eeprom, we also know therefore that NTSC-Mj
will explicitly work so that bit is turned on as well. Then the
video_std module option is examined (remember this is a decimal number
but it is interpreted as a bit mask). The "supported" mask is expanded
to include any bits set in the video_std option (i.e. if you set a
particular standard then it is also assumed to be supported). The
resulting value is then considered to be the set of video standards
supported by the driver.
The "currently set" value is whatever the "current" video standard is
that you want to use. Its initial value can come from one of three
sources (in order): If you set the video_std module option, then that
is used. Otherwise if the device attributes table for the hardware
device you are using declares a preferred default, then that is used.
Otherwise another table is consulted to guess a good starting standard
(std_eeprom_maps[] in pvrusb2-hdw.c). The idea for that table is the
same as the fudge table - pattern match what the eeprom reported as
"supported" in order to infer a reasonable default. (In reality a V4L
app should always set the standard anyway so this shouldn't matter, but
since you're dealing with issues of initialization then this is
something you should understand.)
So, while the driver is operating, the 3 quantities are treated thusly:
The "currently set" bit mask value is made available (always) unmolested
to the various low level modules. This is what cx25840 gets told. If
you attempt to change this bit mask's value (which can be done either
through sysfs or via the V4L API), then the driver will validate it
against the "supported" bit mask before setting it. Once set, the
driver will also go through its synthesized enumeration and if it finds
a match, will also set the current enumeration value accordingly. But
that enumeration value is never seen by any low level modules - just
this "currently set" bit mask is used.
The "supported" bit mask is considered to be a constant. Though IIRC I
think I implemented logic via sysfs such that you can actually change
this on-the-fly if you wanted. The only effect from changing this is to
change the behavior of the validation for the "currently set" bit mask.
The enumeration list and its current value are accessible via sysfs.
You can read the current value at any time; if there isn't a valid value
available (i.e. the "currently set" bit mask doesn't match any
enumeration value) then this will read back as "none". You can also set
the enumeration value - this is essentially what a V4L app logically
does when you set the standard, though it's indirect through the bit
mask. When choose a different enumeration value here, it is of course
updated, and the "currently set" bit mask is also updated to track the
change. And of course when the "currently set" bit mask value is
changed, everybody else is told about it too.
Via the syfs interface, you can find these controls:
ctl_video_standard - This is the enumeration.
ctl_video_standard_mask_active - This is the "currently set" bit mask.
ctl_video_standard_mask_available - This is the "supported" bit mask.
Hope this helps.
[...]
> I got mythtv upgraded to .21 also. It was not too painful.
I'm still going to wait a while. Been burned too much in the past to
jump right away...
>
> Whenever you get to looking at this more or making suggestions is
> fine. I can use it fine as it is.
I don't have any specific suggestions WRT the cx25840 module itself, but
perhaps the above information should at least make the pvrusb2 driver's
role in this more transparent. See above :-)
-Mike
--
Mike Isely
isely @ pobox (dot) com
PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8
More information about the pvrusb2
mailing list