                             Fxtv (BSD X TV)
                                 Version 1.03

                          Written by Randall Hopper

                    URL:  http://www.freebsd.org/~rhh/fxtv

1. PREPARATION 

1.1 HARDWARE

          To use this application, you need a video capture/tuner card
     that's based on the Brooktree 848 capture chip, such as one of the
     Hauppauge Wincast/TV or Win/TV cards, the STV TV PCI card, or the
     Intel Smart Video Recorder III.  See the BSD Bt848 driver page for
     details:

          http://telepresence.dmem.strath.ac.uk/bt848

1.2 THE DEVICE DRIVER

          Once you have the hardware, you need the FreeBSD Brooktree 848
     (bktr) driver.  This version of fxtv uses the bt848.970604 driver, a
     slightly modified version of the bt848.970424 which has better support
     for the FPS ioctl call for running-video captures and throttled
     display rate.

          Normally, recent driver versions can be found at:

          http://telepresence.dmem.strath.ac.uk/bt848

1.3 BUILD-TIME DEPENDENCIES

       - A BSD OS           (FreeBSD, NetBSD, OpenBSD, or BSDI)
       - bktr driver
       - tiff-3.3
       - Xaw3d-1.3
       - xpm-3.4j
       - gmake-3.75
       - XFree              (tested on v3.2 and higher)
       - VoxWare snd driver (3.0-beta-950506)

1.4 RUN-TIME DEPENDENCIES
     
       - netpbm-94.3.1           (for tifftopnm)
       - sox-12.12               (Audio Stream Conversions)
       - mpeg_encode-1.5b        (MPEG Video Encoder)
       - dist10.tar.gz           (MPEG Audio Encoder)
       - mpg123                  (MPEG Audio Player)
       - mplex-1.1               (Mixes MPEG Audio/Video Streams into a
                                  single MPEG System Stream)

     Though not used by fxtv directly, you may find these useful as well:
     
       - mtv                     (MPEG Video & System Stream Player - Fast!)
       - mpeg_play-2.3           (MPEG Video Player)

     Most of these are existing FreeBSD packages.  The exceptions are
     dist10, mtv, and mpg123.  See Appendix A for info on how to get,
     build, and install dist10.  mtv is a Linux utility that can be had
     from:

               http://www.mpegtv.com/player.html

     and mpg123 source is available at:
 
               http://www.sfs.nphil.uni-tuebingen.de/~hipp/mpg123.html

     Building it is a snap.


1.5 BUILDING AND INSTALLING FXTV

    Installing the port is more desirable because you can then just
    pkg_delete it when you want to upgrade to the next version.
 
    1. Install the port

       > tar -zxovf fxtv-<version>-port.tgz
       > cd fxtv
       > su
       # make install
   
    OR

    2. Installing from the source package

       > tar -zxovf fxtv-<version>.tgz
       > cd fxtv-<version>
       > gmake
       > su
       # gmake install

    NOTE FOR FXTV USERS NOT RUNNING XFREE:  Specify "HAVE_XFREE86=NO"
    on the make command line to compile-out support for XFree86-specific
    features.  For example, when installing from the port:

       # make HAVE_XFREE86=NO install

1.6 CUSTOMIZING FXTV

    Modifying Fxtv's default behavior can be accomplished in one of two
    ways:  1) modifying the Fxtv X resources (see the sample Fxtv resource
    file, or 2) specifying command-line options.

    Note that the command-line options in most cases have the same names 
    as the X resources.  Refer to the delivered global Fxtv resource file
    for resource file examples, and run:

         fxtv -help

    to display all the supported command-line options:

    -driverDefaults             - Use appearance parms from driver on startup
    -colorbars                  - Turn on colorbar display (for testing)
    -hue [-90...90]             - Initial Hue           ; def=0
    -brightness [-50..50]       - Initial Brightness (%); def=0
    -contrast [0..200]          - Initial Contrast   (%); def=100
    -satU [0..200]              - U Saturation       (%); def=100
    -satV [0..284]              - V Saturation       (%); def=100
    -fps <#>                    - Display Speed (frames per second)
    -noaspectlock               - Disable 4:3 aspect lock on video window
    
    -deviceNumber <#>           - bktr/tuner device numbers; def=0      
    -inputFormat [pal|ntsc]     - Tuner signal input format
    -tunerMode [cable|antenna]  - Tuner Mode
    -defaultInput <input>       - Startup tuner signal input 
                                    [tuner|video|svideo|csvideo|dev3]
    -defaultAudioInput <input>  - Startup TV card audio input 
                                    [tuner|external|internal|auto]
    -defaultChannel <#>         - Startup Channel Number
    -cableStationList   <...>   - List of cable stations presets(see rsrc file)
    -antennaStationList <...>   - List of antenna stations presets
    -cableFreqSet   <freqset>   - Freq set for cable   (def = cableirc)
                                    [nabcst|cableirc|cablehrc|weurope|
                                     jpnbcst|jpncable|xussr|australia|france]
    -antennaFreqSet <freqset>   - Freq set for antenna (def = nabcst)
    
    -noAudio                    - Suppress playing audio through soundcard
    -dspDevice                  - Override default DSP device   (/dev/audio)
    -mixerDevice                - Override default mixer device (/dev/mixer)
    -mixerChannel               - Audio mixer (line,line1/2/3,cd,mic,video)

    -stationInWinTitle          - Display station text in window title
    -stationInWinIcon           - Display station text in window icon

    -stationAnnotFont <fontpat> - Font pattern for station annot (see rsrcfile)
    -stationAnnotColor <color>  - Color for station annot
    -stationAnnotDelay <msec>   - How long to display (0 = never; -1 = always)
    -stationAnnotIDOnly         - Display station ID alone (when available)

    -remoteType                 - Type of attached remote control
                                  [None|X10|Hauppauge|PixelView]

    -recCmdMpeg2                - MPEG-2 Audio record command 
    -recCmdMpeg3                - MPEG-3 Audio record command
    -playCmdMpeg2               - MPEG-2 Audio play   command
    -playCmdMpeg3               - MPEG-3 Audio play   command
    
    -videoCnvtScript            - Video convers workhorse script for vid encod.

    -bswap2Bpp                  - Byte/word swap options for direct video
    -nobswap2Bpp                  (used to match driver's pixel format with
    -bswap3Bpp                    the video card's)
    -nobswap3Bpp
    -bswap4Bpp                        2Bpp - 15/16-bpp modes
    -nobswap4Bpp                      3Bpp - packed 24bpp modes
    -bwwap4Bpp                        4Bpp - unpacked 24bpp modes
    -nowswap4Bpp
    
    -Bpp24bit [3|4]             - Set frame buff Bytes-per-pixel for 24bpp mode
    -Bpp32bit [3|4]             - Set frame buff Bytes-per-pixel for 32bpp mode

    -videoCapFile[1-4]          - Optional paths (0-4) to scratch file paths 
                                  to use for vid capt; spread load across disks

    -noafc                      - Disable AFC
    -disableDirectV             - Disable DMA transfers straight to video card
    -debug <area>               - Debug Msgs 
                                  {startup,subproc,events,subproc,video,frame}
    -help                       - Display program options


1.6.1 CUSTOMIZING STATION PRESETS

    ---INTRODUCTION:---

    Fxtv supports two tuner modes: "cable" and "antenna".  Each of these
    two modes can be assigned a frequency set, which determines the
    frequency-to-channel-number mapping for the tuner mode (which are set
    via the antennaFreqSet and cableFreqSet resources).  The frequency set
    you choose for each tuner mode will depend on where you live and who
    your NTSC or PAL signal providers are.  For example, in the US (NTSC),
    you probably want to use:

        Fxtv.antennaFreqSet:     nabcst
        Fxtv.cableFreqSet:       cableirc

    As with any standard NTSC or PAL TV or VCR, Fxtv supports "station
    preset lists" for each tuner mode (cable and antenna), which
    effectively define the hot-list of stations you will be surfing.
    Station preset lists are specified via the:

        Fxtv.antennaStationList: <preset list>
        Fxtv.cableStationList: <preset list>

    resources.  

    Here's how Fxtv models preset lists: Each <preset> in a <preset list>
    is associated with a specific <channel-num> or a specific <frequency>.
    Optionally, each <preset> may be also associated with a <station-id>,
    which is a convenience name used to refer to the station preset
    (e.g. "E10","ITD",... for the PAL folks; or "FOX","CBS",... for the US
    folks).  

    When specified, <station-id>s can be used for keying-in station changes
    and will also be displayed on the Fxtv window to reflect the current
    station.  Whether <station-id>s are specified or not, <channel-num>s
    and <frequency>s can be used to key-in station changes, and will be
    used for display in the absense of a <station-id>.

    If you associate a preset with a <channel-num>, when the preset is made
    active, that channel number is passed to the Bt848 driver which in-turn
    maps it to a frequency (using the frequency set you configured for that
    tuner mode).  This frequency is used to configure the tuner.

    If, on the other hand, you associate a preset with a <frequency>, the
    frequency itself is passed to the Bt848 driver, bypassing its
    channel-to-freq conversion.  Again, this frequency is used to configure
    the tuner.

    Specifying a station in terms of its frequency can be useful when the
    driver doesn't have an accurate channel-to-freq mapping for all
    of the stations used in your area.


    ---SYNTAX:---

    With that preamble, here's the Fxtv syntax for encoding a <preset list>:
        
         <preset list>       := [<preset>|<preset-chan-range>] ...
         <preset>            := <channel-num>
                                F<frequency>
                                <station-id>(<channel-num>)
                                <station-id>(F<frequency>)
         <preset-chan-range> := <channel-num>-<channel-num>
         <channel-num>       := a positive integer
         <frequency>         := a floating point number, in MHz

    Note that <station-id>s are treated as case insensitive.

    ---EXAMPLES:---

    And here are some StationList examples:

         1)  Fxtv.antennaStationList: ITA(f471.25) ITC(15) E32(21) 22-24 99
         2)  Fxtv.antennaStationList: 3 ABC(5) PBS(f169.00) 83(f61.25)
         3)  Fxtv.cableStationList:   3-5 19-21 23

    In the first example, the station-id "ITA" is associated with the
    frequency 471.25 Mhz (with this, either "ITA" or "f471.25" may be used
    to key-in a station change to this station).  The station ID "ITC" is
    associated with channel "15" in the frequency set configured for the
    "antenna" tuner mode.  "E32" is associated with channel "21".  And
    the channels 22, 23, 24, and 99 are also defined without explicit
    station IDs (and thus the station-ids are defaulted to be the channel
    numbers themselves).  The first example is equivalent to the following
    resource definition:

             Fxtv.antennaStationList: ITA(f471.25) ITC(15) E32(21) 22(22) \
                                      23(23) 24(24) 99(99)

    The second example is like the first.  Notice station-id 83 though.
    With station IDs you can override the default channel-num-to-frequency
    mappings (or put some into place where they didn't exist before -- the
    more likely case).  And yes, you can also drive yourself nuts by
    remapping channel numbers to other channel numbers if you want
    (e.g. "3(5) 5(3)" seemingly swaps channels 3 and 5).
        
    Note that these examples are a bit contrived just to demonstrate the
    syntax.  For instance, you probably won't associate station presets
    directly with frequencies unless the driver doesn't have channel
    presets for all the stations you receive.  When the driver does have
    the needed channel presets, with AFC on and presets associated with
    channel numbers, the tuner will usually be able to zero-in on the
    station if its slightly off of the channel frequency (the same as if
    you define a preset with a frequency that's slightly off).

1.6.2 CHANGING STATIONS

    Fxtv provides several ways for the user to change stations:
        
        1) Station Up/Down Arrow Buttons (on taskbar)
        2) Station Text Widget Key-in    (on taskbar)
        3) Video Window Key-ins
        4) Video Window Action Routines

    The Station Up & Down buttons are straightforward.  These move through
    your predefined station list for the currently selected tuner mode in
    the direction indicated by the button icon.

    The Station Text Key-in allows you to change to any predefined station
    or arbitrary channel number or frequency.  Acceptable values are: 
        
        1) the station IDs you've defined in your station list, 
        2) channel numbers, and
        3) frequencies (prefix with "F" when entering).  

    Examples:  "E1", "FOX", "23", "f61.25".

    Video Window Key-in allows you to type in channel numbers directly on
    top of the video window.  The format is the same as with the text
    key-in, except that station ID entry should be prefixed by "C".  This
    is for compatibility with action routines.  Examples: "cE1", "cFOX",
    "23", "f61.25".

    And finally, Video Window Action Routines provide the user a way to
    redefine the keys on their keyboard to change stations the way the user
    prefers when the X pointer is over the video window.  Station changes
    may be specified both relative to the current station, or absolutely
    (by specifying a station ID, channel number, or frequency).  An example
    first, followed by explanation:

         Fxtv*videoWin.translations: #override            \
            <Key>+           : TVSetStation( +1 )         \n\
            <Key>-           : TVSetStation( -1 )         \n\
            <Key>KP_Add      : TVSetStation( +1 )         \n\
            <Key>KP_Subtract : TVSetStation( -1 )         \n\
            <Key>F6          : TVSetStation( FOX )        \n\
            <Key>F7          : TVSetStation( 23 )         \n\ 
            <Key>F8          : TVSetStation( f61.25 )     \n\
            <Key>F9          : TVSetStation( -f )         \n\
            <Key>F10         : TVSetStation( +f )         \n

    The first 4 bind both pairs of "+" and "-" keys to perform relative
    station changes. The 5th defines F6 to set the station to the one with
    the station ID "FOX".  The 6th defines F7 to change to the station to
    channel 23 (assuming no station with an ID of "23" exists, in which
    case it would take precedence).  The 7th defines F8 to change station 
    to a frequency of 61.25 MHz.  And the last two bind F9 and F10 to
    increment and decrement frequency in small increments.

    Note that "no-op()" has been registered as a valid action routine
    for convenient unbinding of translations.

    Having read 1.6.1 and customized your station presets (key in: "ITC" or
    "15").


1.6.3 CONFIGURING A REMOTE CONTROL

    At this time, the X10 MouseRemote, Hauppauge, and PixelView remote
    controls are supported.

1.6.3.1 X10-SPECIFIC CONFIGURATION

    Both stand-alone and system-mouse pass-through configuration are
    supported in X.  Both require an updated version of moused (see
    moused(8)), which has support for the X10 MouseRemote.

    My moused patch for X10 remote support is included with this verions of
    Fxtv, though it may already be incorporated into your moused.  You can
    determine whether it has by running moused as follows:

        moused -p /dev/cuaa0 -t x10mouseremote -3 

    substituting the path to the serial port your mouse is attached to
    in place of /dev/cuaa0.  If you see:

        moused: no such mouse type `x10mouseremote'

    It hasn't and you need to rebuild moused with the patch.  Get it here:

        http://www.freebsd.org/~rhh/fxtv/moused.x10remote.patch

    And apply it like this:
        
        # cd /usr/src/usr.sbin/moused
        # patch < moused.x10remote.patch
        # make

    Now you're ready to go.  Kick off moused on the MouseRemote serial
    port (if you haven't already).  For example, if your MouseRemote is 
    plugged into COM1 (cuaa0):

           moused -p /dev/cuaa0 -t x10mouseremote -3

    You may just want to configure this into your rc.conf so it's run each
    time you boot up.

    Next, insert these lines in your Fxtv resource file:

         Fxtv.remoteType:    X10

    You're ready to use your remote control!  Run Fxtv and play around with
    it to make sure things are working.  If you have trouble, 
    run "fxtv -debug remote" to see whether fxtv is getting any remote
    events.

1.6.3.2 HAUPPAUGE-SPECIFIC CONFIGURATION

    Simply insert these lines in your Fxtv resource file:

         Fxtv.remoteType:    Hauppauge

    and you're ready to use your remote control!  Run Fxtv and play around
    with it to make sure things are working.  If you have trouble, run
    "fxtv -debug remote" to see whether fxtv is getting any remote events.

1.6.3.3 PIXELVIEW-SPECIFIC CONFIGURATION

    Simply insert these lines in your Fxtv resource file:

         Fxtv.remoteType:    PixelView

    and you're ready to use your remote control!  Run Fxtv and play around
    with it to make sure things are working.  If you have trouble, run
    "fxtv -debug remote" to see whether fxtv is getting any remote events.

1.6.3.4 COMMON CONFIGURATION

    Now that you've played with it, you probably will want to custom
    configure some of the buttons to behave differently than the default
    configuration.  To do so, set up the remoteTranslations resource in
    your Fxtv resource file.  You can map any button to any provided
    Fxtv action routine, similar to the way you can for mouse events
    and keyboard keys.  For example:

          ! User-defined Remote Control Translations
          Fxtv.remoteTranslations: \
             <Remote>ChanUp   : TVSetStation( +1 )         \n\
             <Remote>ChanDn   : TVSetStation( -1 )         \n\
             <Remote>VolUp    : TVSetVolume( +1 )          \n\
             <Remote>VolDn    : TVSetVolume( -1 )          \n\
             <Remote>Mute     : TVToggleMute()             \n\
             <Remote>Disp     : TVToggleZoom( fullscreen ) \n\
             <Remote>A-B      : TVSetCaptureInput( +1 )    \n\
             <Remote>Pause    : TVToggleFreeze()           \n\
             <Remote>Rec      : TVVideoRecordStart()       \n\
             <Remote>Stop     : TVVideoRecordStop()        \n\
             <Remote>Power    : TVQuit()                   \n

    Here is the list of <Remote> key names supported by the X10 Remote
    (case insensitive):

          Power,AllOn,PC,CD,Web,DVD,Phone,0,1,Home,2,Up,3,PgUp,4,Left,5,6,
          Right,7,End,8,Down,9,PgDn,ENTER,VolUp,BrightUp,VolDn,BrightDn,
          ChanUp,On,ChanDn,Off,MUTE,AllOff,A-B,DISP,PLAY,REW,FF,STOP,REC,
          PAUSE,LAST

    Here is the list of <Remote> key names supported by the Hauppauge
    Remote (case insensitive):

          0,1,2,3,4,5,6,7,8,9,Radio,Mute,Tv,VolUp,VolDn,Reserved,
          ChanUp,ChanDn,Source,Minimize,FullScreen

2.0 SAVING IMAGES -- TIPS

    Fxtv now supports saving of the last frozen image to disk.  

    Saving in TIFF and PPM formats is supported.

    Fxtv can save the pic in the filename you specify, or that filename
    with an image number appended.  The latter is useful when you want to
    capture a lot of stills on-demand (freeze, snap, freeze, snap, ...).

    The action routine TVSaveImage() is provided for binding image save to
    keyboard key or mouse button for repetitive on-demand image captures.


3.0 SAVING AUDIO -- TIPS

    Saving audio streams to disk (and playing the resulting streams) is now
    supported in the following formats:
                
           RAW             WAV                
           AU              AIFF               
           VOC             MPEG (Levels 2 & 3)

    The capture sample format, frequency, and number of channels can be
    specified as well.

    RAW and AU are supported without the aid of external programs.  The
    rest require that "sox" be installed (and in the PATH).  

    In addition, MPEG Level 2 & 3 support also require that MPEG audio
    encoder and player utilities be installed.  The recommended player is
    "mpg123", and the recommended encoder is the one from dist10 (see
    RUN-TIME DEPENDENCIES above).

    The MPEG player and encoder utilities are identified to Fxtv via X
    resources in the Fxtv resource file:

          ! Custom MPEG record and play commands
          Fxtv.recCmdMpeg2:       mpeg_musicin -l 2 -p 1
          Fxtv.recCmdMpeg3:       mpeg_musicin -l 3 -p 2
          Fxtv.playCmdMpeg2:      mpg123
          Fxtv.playCmdMpeg3:      mpg123

    TIP:  If audio save and/or play doesn't seem to be working, fxtv 
          probably can't find "sox" or the mpeg encoder/player programs.
          Try:
                       fxtv -debug subproc

          for more verbose output.


3.0 SAVING VIDEO -- TIPS

    Three useful video targets are supported:

             Images
             MPEG Ready
             MPEG

    With each, audio may optionally be saved at the same time.
    The image format, capture resolution, capture rate, audio format, and
    audio rate can also be specified.  A simple frame rate optimizer is 
    provided as well.

    Selecting the "Images" target causes Fxtv to convert the captured
    video stream into a sequence of numbered images in the specified format.
    If audio save is enabled, audio will be simultaneously captured, and
    post-converted to the specified format.

    Selecting the "MPEG Ready" target causes Fxtv to capture images and
    audio as with "Images", with a few additions.  The frame rate
    is buffered to 30 frames per second, and an mpeg_encode parameter file
    and convenience "go" shell script are created so the user is ready
    to tweak the encoding parameters and kick it off on their own.

    Finally, selecting "MPEG" is like "MPEG Ready" except that Fxtv manages
    the entire process of running the conversion and encoding programs, 
    informing the user of the current encoding status via dialogs.
    This is useful for grabbing video and building an MPEG as quickly and 
    simply as possible.

    TIP #1 -- IF VIDEO SAVE/ENCODE DOESN'T WORK
 
       As with audio save, if video save doesn't seem to be working,
       try:
                 fxtv -debug subproc

    TIP #2 -- MPEG_ENCODE FRAME RATE LIMITATIONS

       mpeg_encode, used to convert a sequence of images into an MPEG-1
       video stream, is limited to frame rates of:

           {23.976,  24,  25,  29.97,  30,  50, 59.94, 60}

       So in general you'll get better results if you choose frame rates of
       24, 25, or 30.

    TIP #3 -- OPTIMIZING FRAME RATE

       First, use the "Fxtv.videoCapFile[1-4]" resources to specify up to
       four different files to interleave raw video/audio capture to.  If
       you point these resources to paths on different disks, you'll get
       much higher bandwidth than you would with just one disk (the default).

       The "Optimize" control provided here is a first-cut and too
       simplistic.  It blasts 100 frames at 30 fps to the disk at the
       target resolution, and (averaging across blocking disk writes) it
       looks at how long this process took to estimate the approximate
       frame rate your disk might sustain without long hickups.

       For now, you can probably eyeball a better estimate by running fxtv
       like this:
      
                fxtv -debug video
     
       and doing RAW format captures at your target resolution and frame
       rate.  Watch the output fly by in your xterm.  If you see half- to
       whole-second delay "hickups", back the frame rate off a bit and
       repeat until you see a fairly constant "gate" in skipped frames.

    TIP #4 -- DRIVER BUG

       Temporal decimation doesn't work perfectly in the driver yet.  As
       before, 30 fps will work fine at any resolution.  With the 970604
       driver, FPS adjustment < 30 should work OK for single-field captures
       (i.e. num pixel rows <= 240).  However, double-field captures
       (i.e. num pixel rows > 240) at < 30fps don't work yet, so avoid that
       combination.  With a driver rev dated  pre-970604, don't even bother
       with anything other than 30fps.
    

APPENDIX A - BUILDING MPEG LAYER 2 & 3 ENCODER SOFTWARE

  First, grab dist10.tar.gz from:

  http://www.pagesz.net/~aa8vb/fxtv, or
  ftp://ftp.tnt.uni-hannover.de/pub/MPEG/audio/mpeg2/software/technical_report

  Then:

  tar -zxovf dist10.tar.gz
  cd dist10/lsf/encoder
  ./configure
  gmake
  mv encode /usr/local/bin/mpeg_musicin
  find tables -print | cpio -dumpv /usr/local/lib/mpegaudio
  cd ../decoder
  ./configure
  gmake
  mv decode /usr/local/bin/mpeg_musicout

  and finally, put this env var setting in your profile:
 
  MPEGTABLES=/usr/local/lib/mpegaudio/tables

  NOTE:  For every last pinch of speed, after each "configure", modify
  the Makefiles and change "-O" to "-O3 -ffast-math -mfancy-math-387".

  NOTE:  An older version of this software is packaged as the FreeBSD
  "mpeg_audio" port, but it doesn't like some AIFF files (byte order
  problems), and it doesn't seem to do Level 3 audio.  dist10 does.
  

APPENDIX B - MINIMIZING SCREEN CORRUPTION WHEN USING DIRECT VIDEO

   Disable SaveUnders and BackingStore in your Window Manager configuration
   to minimize the occurance of stray video trash that may appear on your 
   desktop when moving and resizing the Fxtv window while Fxtv is
   in direct video mode.

   Note that you can also use the "Refresh Screen" window manager function
   to clean up any spurious trash as well.

   FWIW, the author uses the AfterStep window manager and hardly ever sees
   stray video trash left on the desktop or another client window.

APPENDEX C - LICENSING AND DISTRIBUTION DETAILS

The license and distribution terms for any publically available version or
derivative of this code cannot be changed.  i.e. this code cannot simply be
copied and put under another distribution license
[including the GNU Public License.]

______________________________________________________________________________
______________________________________________________________________________


Have fun!

All suggestions, bug reports, fixes, and enhancements welcome.  Please
mail to multimedia@freebsd.org.
