
tvtime design doc
-----------------

This document describes some of the basic design of tvtime: the code
structure and organization, the coding style, philosophies, etc.


Program structure
-----------------


Initialization

1. Startup and load configuration
2. Steal performance as much as possible
3. Open video input
4. Start the main loop


/**
 * Explination of the loop:
 *
 * We want to build frames so that they look like this:
 *  Top field:      Bot field:
 *     Copy            Blank
 *     Interp          Copy
 *     Copy            Interp
 *     Interp          Copy
 *     Copy            --
 *     --              --
 *     --              Interp
 *     Blank           Copy
 *
 *  So, say a frame is n high.
 *  For the bottom field, the first scanline is blank (special case).
 *  For the top field, the final scanline is blank (special case).
 *  For the rest of the scanlines, we alternate between Copy then Interpolate.
 *
 *  To do the loop, I go 'Interp then Copy', and handle the first copy
 *  outside the loop for both top and bottom.
 *  The top field therefore handles n-2 scanlines in the loop.
 *  The bot field handles n-2 scanlines in the loop.
 *
 * What we pass to the deinterlacing routines:
 *
 * Each deinterlacing routine can require data from up to four fields.
 * The current field is being output is Field 4:
 *
 * | Field 1 | Field 2 | Field 3 | Field 4 |
 * |         |   T0    |         |   T1    |
 * |   M0    |         |    M1   |         |
 * |         |   B0    |         |   B1    |
 *
 * So, since we currently get frames not individual fields from V4L, there
 * are two possibilities for where these come from:
 *
 * CASE 1: Deinterlacing the top field:
 * | Field 0 | Field 1 | Field 2 | Field 3 | Field 4 |
 * |   T-1   |         |   T0    |         |   T1    |
 * |         |   M0    |         |    M1   |         |
 * |   B-1   |         |   B0    |         |   B1    |
 *  [--  secondlast --] [--  lastframe  --] [--  curframe   --]
 *
 * CASE 2: Deinterlacing the bottom field:
 * | Field 0 | Field 1 | Field 2 | Field 3 | Field 4 |
 * |   T-1   |         |   T0    |         |   T1    |
 * |         |   M0    |         |    M1   |         |
 * |   B-1   |         |   B0    |         |   B1    |
 * ndlast --] [--  lastframe  --] [--  curframe   --]
 *
 * So, in case 1, we need the previous 2 frames as well as the current
 * frame, and in case 2, we only need the previous frame, since the
 * current frame contains both Field 3 and Field 4.
 */



Tuner state

  Happy State  - Tuner signal is high, input unheld

1)              Happy
                  |
     Fine       ChChange     Lose Signal
                  |
          Save last input frame
        Interpolate to field height
2)   Hold that frame as input, last and secondlast

                |
3)  a) Signal detected
        - Wait for 2 input frames, then show input

   b) No signal for four frames, begin fade to colour bars


HAS_SIGNAL
SIGNAL_DETECTED
SIGNAL_LOST
NO_SIGNAL

if signal
  switch state
      case NO_SIGNAL
      case LOST_SIGNAL
          state = SIGNAL_DETECTED
          aquire_wait = AQUIRE_DELAY
          recover_wait = 0

      case SIGNAL_DETECTED
          if aquire_wait
              aquire_wait--
          else
             state = HAVE_SIGNAL

else no signal
  switch state
      case HAVE_SIGNAL
          save last frame
      case SIGNAL_DETECTED
          state = LOST_SIGNAL
          recover_wait = RECOVER_DELAY

      case LOST_SIGNAL
          if recover_wait
              recover_wait--
          else
              state = NO_SIGNAL
              osd says no signal
  fade bars


if state = HAVE_SIGNAL
  show_frame
else
  show (current bars/save fade)


/** Handling changes to frame size
    (not overscan, norm changes though, and half-size mode?)

   Need to update:
  1. output layer
  2. menu ?  yeah.
  3. osd definitely

*/


Rendering
  Foreach scanline
    Filter input scanline to temporary memory



Buffering
---------


 20  InputBot
 20  BufferedTop

 20  LastBot
 20  LastTop

 20  DrawnBot
 20  DrawnTop

 20  QueuedBot
 20  DisplayedTop
---
180ms


 Current frame based processing pipe

    Input    WaitQueue Processing  Displaying
    -------  --------- ----------  ----------
    Top                                        bttv gets Top field
    Bot Top                                    bttv gets Bot field
    Top      Bot       Top                     bttv sends frame, Top deinterlaced
    Bot Top            Bot         Top         Bot gets deinterlaced while Top shown
    Top      Bot       Top         Bot
    Bot Top            Bot         Top
    Top      Bot       Top         Bot
    Bot Top            Bot         Top
    Top      Bot       Top         Bot

  Lag = 60ms


 V4L2 gives us field buffers, no more wait queue needed

    Input    Processing  Displaying
    -------  ----------  ----------
    Top                              bttv gets Top field
    Bot      Top                     bttv gets Bot field, Top deinterlaced
    Top      Bot         Top
    Bot      Top         Bot
    Top      Bot         Top
    Bot      Top         Bot

  Lag = 40ms

  In both of these methods though, we assume that we're kinda clocked
by our input, or do we?   Well, in the bottom case it's totally viable
for deinterlacing on each field to not take the same time, so we don't
necessarily have a constant output clock.  This is necessary if our
output is at field rate.

    Input    Processing  Queued  Displaying
    -------  ----------  ------  ----------
    Top
    Bot      Top
    Top      Bot         Top
    Bot      Top         Bot     Top
    Top      Bot         Top     Bot
    Bot      Top         Bot     Top

  Lag = 60ms

--
menusystem


menu:

  - screens
  - each screen has a background png
  - each menu button is two images


Screen Foobar
  Background = backdrop.png

  Button
    Position x, y
    Image foo.png
    Hilighted bar.png


