[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