]> git.pld-linux.org Git - packages/mythplugins.git/commitdiff
- release 0.19 fixes up to svn 10051
authorElan Ruusamäe <glen@pld-linux.org>
Sun, 28 May 2006 11:58:59 +0000 (11:58 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    mythtv-branch.diff -> 1.1

mythtv-branch.diff [new file with mode: 0644]

diff --git a/mythtv-branch.diff b/mythtv-branch.diff
new file mode 100644 (file)
index 0000000..5ba7747
--- /dev/null
@@ -0,0 +1,6215 @@
+Index: mythplugins/mythweb/themes/wml/header.php
+===================================================================
+--- mythplugins/mythweb/themes/wml/header.php  (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/themes/wml/header.php  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -26,4 +26,4 @@
+ <p><a href="<?php echo root ?>tv/upcoming"><?php echo t('Upcoming Recordings') ?></a></p>
+ <p><a href="<?php echo root ?>tv/recorded"><?php echo t('Recorded Programs') ?></a></p>
+ <p><a href="<?php echo root ?>tv/search"><?php echo t('Search') ?></a></p>
+-<p><a href="<?php echo root ?>status?xml"><?php echo t('Backend Status') ?></a></p>
++<p><a href="<?php echo root ?>status/xml"><?php echo t('Backend Status') ?></a></p>
+Index: mythplugins/mythweb/themes/default/weather/weather.php
+===================================================================
+--- mythplugins/mythweb/themes/default/weather/weather.php     (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/themes/default/weather/weather.php     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -93,13 +93,13 @@
+                 $tomorrow = date("m/d/Y", mktime(0, 0, 0, date("m")  , date("d")+1, date("Y")));
+                 switch($forecast->dayofweek) {
++                    case 0:  $day = t('Sunday');        break;
+                     case 1:  $day = t('Monday');        break;
+                     case 2:  $day = t('Tuesday');       break;
+                     case 3:  $day = t('Wednesday');     break;
+                     case 4:  $day = t('Thursday');      break;
+                     case 5:  $day = t('Friday');        break;
+                     case 6:  $day = t('Saturday');      break;
+-                    case 7:  $day = t('Sunday');        break;
+                     default: $day = $forecast->date;    break;
+                 }
+Index: mythplugins/mythweb/themes/default/music/music.php
+===================================================================
+--- mythplugins/mythweb/themes/default/music/music.php (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/themes/default/music/music.php (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -164,10 +164,12 @@
+     function print_header($filterPlaylist,$filterArtist,$filterAlbum,$filterGenre) {
+         $this->filterPlaylist=$filterPlaylist;
+-// Set the desired page title
+-    $page_title = 'MythWeb - '.t('Music');
+-// Print the page header
+-    require_once theme_dir.'/header.php';
++    // Set the desired page title
++        global $page_title, $Modules, $headers;
++        $page_title = 'MythWeb - '.t('Music');
++    // Print the page header
++        require_once theme_dir.'/header.php';
++
+         printf("<form  action=\"".root."music\" method=\"GET\" >\n");
+         printf("<input type=\"hidden\" name=\"mode\" value=\"music\" />\n");
+Index: mythplugins/mythweb/themes/default/tv/detail.php
+===================================================================
+--- mythplugins/mythweb/themes/default/tv/detail.php   (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/themes/default/tv/detail.php   (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -51,7 +51,7 @@
+ <?php   } ?>
+             <div id="program_title">
+                 <h1>
+-                    <a href="<?php echo root ?>tv/search/<?php echo urlencode($program->title) ?>&search_title=yes"><?php echo $schedule->title ?></a>
++                    <a href="<?php echo root ?>tv/search/<?php echo str_replace('%2F', '/', rawurlencode($schedule->title)) ?>?search_title=1"><?php echo $schedule->title ?></a>
+                 </h1>
+                 <div id="program_time">
+ <?php
+Index: mythplugins/mythweb/includes/mythbackend.php
+===================================================================
+--- mythplugins/mythweb/includes/mythbackend.php       (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/includes/mythbackend.php       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -15,10 +15,6 @@
+ // The character string used by the backend to separate records
+     define('backend_sep', '[]:[]');
+-// A couple of global variables to keep duplicate queries to a minimum
+-    $Scheduled_Recordings = array();
+-    $Recorded_Programs    = array();
+-
+ // MYTH_PROTO_VERSION is defined in libmyth in mythtv/libs/libmyth/mythcontext.h
+ // and should be the current MythTV protocol version.
+     define('MYTH_PROTO_VERSION', 26);
+Index: mythplugins/mythweb/includes/programs.php
+===================================================================
+--- mythplugins/mythweb/includes/programs.php  (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/includes/programs.php  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -81,7 +81,9 @@
+ /**/
+     function &load_all_program_data($start_time, $end_time, $chanid = false, $single_program = false, $extra_query = '') {
+         global $Channels, $db;
+-    // Make a local hash of channel chanid's with references to the actual channel data
++    // Make a local hash of channel chanid's with references to the actual
++    // channel data (Channels are not indexed by anything in particular, so
++    // that the user can sort by chanid or channum).
+         $channel_hash = array();
+     // An array (that later gets converted to a string) containing the id's of channels we want to load
+         $these_channels = array();
+@@ -104,7 +106,7 @@
+             load_all_channels();
+     // Scan through the channels array and actually assign those references
+         foreach (array_keys($Channels) as $key) {
+-            $channel_hash[$Channels[$key]->chanid] = &$Channels[$key];
++            $channel_hash[$Channels[$key]->chanid] =& $Channels[$key];
+         // Reinitialize the programs array for this channel
+             $Channels[$key]->programs = array();
+         // Keep track of this channel id in case we're only grabbing info for certain channels - workound included to avoid blank chanid's
+@@ -130,11 +132,13 @@
+                        LEFT JOIN programrating USING (chanid, starttime)
+                        LEFT JOIN oldrecorded
+                                  ON oldrecorded.recstatus IN (-3, 11)
+-                                    AND IF(oldrecorded.programid OR oldrecorded.seriesid,
++                                    AND IF(oldrecorded.programid AND oldrecorded.seriesid,
+                                            oldrecorded.programid = program.programid
+                                              AND oldrecorded.seriesid = program.seriesid,
+-                                           oldrecorded.title = program.title
+-                                             AND oldrecorded.subtitle = program.subtitle
++                                           oldrecorded.title AND oldrecorded.subtitle
++                                             AND oldrecorded.description
++                                             AND oldrecorded.title       = program.title
++                                             AND oldrecorded.subtitle    = program.subtitle
+                                              AND oldrecorded.description = program.description
+                                           )
+                        LEFT JOIN channel ON program.chanid = channel.chanid
+@@ -156,8 +160,12 @@
+     // The extra query, if there is one
+         if ($extra_query)
+             $query .= ' AND '.$extra_query;
+-    // Group, sort and query
++    // Group and sort
+         $query .= ' GROUP BY program.chanid, program.starttime ORDER BY program.starttime';
++    // Limit
++        if ($single_program)
++            $query .= ' LIMIT 1';
++    // Query
+         $sh = $db->query($query,
+                          star_character, max_stars, max_stars);
+     // No results
+@@ -188,12 +196,8 @@
+     // Cleanup
+         $sh->finish();
+     // If channel-specific information was requested, return an array of those programs, or just the first/only one
+-        if ($chanid) {
+-            if ($single_program)
+-                return $channel_hash[$chanid]->programs[0];
+-            else
+-                return $channel_hash[$chanid]->programs;
+-        }
++        if ($chanid && $single_program)
++            return $these_programs[0];
+     // Just in case, return an array of all programs found
+         return $these_programs;
+     }
+@@ -272,18 +276,18 @@
+             $this->endtime     = $data[12];  # show end-time
+         // Is this a previously-recorded program?  Calculate the filesize
+             if (!empty($this->filename)) {
+-                $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low;
+-            }
+-        // Ah, a scheduled recording - let's load more information about it, to be parsed in below
+-            elseif ($this->chanid) {
+-                unset($this->filename);
+-            // Kludge to avoid redefining the object, which doesn't work in php5
+-                $tmp = @get_object_vars(load_one_program($this->starttime, $this->chanid));
+-                if (is_array($tmp) && count($tmp) > 0) {
+-                    foreach ($tmp as $key => $value) {
+-                        $this->$key = $value;
+-                    }
++                if (function_exists('gmp_add')) {
++                // GMP functions should work better with 64 bit numbers.
++                    $size = gmp_add($fs_low,
++                                     gmp_mul('4294967296',
++                                             gmp_add($fs_high, $fs_low < 0 ? '1' : '0'))
++                                   );
++                    $this->filesize = gmp_strval($size);
+                 }
++                else {
++                // This is inaccurate, but it's the best we can get without GMP.
++                    $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low;
++                }
+             }
+         // Load the remaining info we got from mythbackend
+             $this->title           = $data[0];                  # program name/title
+@@ -291,14 +295,14 @@
+             $this->description     = $data[2];                  # episode description
+             $this->category        = $data[3];
+             #$chanid               = $data[4];   # Extracted a few lines earlier
+-            #$channum              = $data[5];
+-            #$callsign             = $data[6];
++            $this->channum         = $data[5];
++            $this->callsign        = $data[6];
+             $this->channame        = $data[7];
+             #$pathname             = $data[8];   # Extracted a few lines earlier
+             #$fs_high              = $data[9];   # Extracted a few lines earlier
+             #$fs_low               = $data[10];  # Extracted a few lines earlier
+-            #$starttime            = $data[11];  # Extracted a few lines earlier
+-            #$endtime              = $data[12];  # Extracted a few lines earlier
++            #$this->starttime      = $data[11];  # Extracted a few lines earlier
++            #$this->endtime        = $data[12];  # Extracted a few lines earlier
+             $this->hostname        = $data[16];
+             #$this->sourceid       = $data[17];
+             $this->cardid          = $data[18];
+@@ -320,9 +324,9 @@
+             $this->programid       = $data[34];
+             $this->lastmodified    = $data[35];
+             $this->recpriority     = $data[36];
+-            #$this->airdate        = $data[37];
+-            #$this->hasairdate     = $data[38];
+-            $this->timestretch     = $program_data[39];
++            $this->airdate         = date('Y-m-d', $data[37]);
++            $this->hasairdate      = $data[38];
++            $this->timestretch     = $data[39];
+             $this->recpriority2    = $data[40];
+         // Assign the program flags
+             $this->has_commflag = ($progflags & 0x01) ? true : false;    // FL_COMMFLAG  = 0x01
+@@ -363,8 +367,8 @@
+             $this->title_pronounce         = $data['title_pronounce'];
+             $this->recstatus               = $data['recstatus'];
+-            if ($program_data['tsdefault']) {
+-                $this->timestretch = $program_data['tsdefault'];
++            if ($data['tsdefault']) {
++                $this->timestretch = $data['tsdefault'];
+             } else {
+                 $this->timestretch = 1.0;
+             }
+@@ -387,12 +391,14 @@
+         // Now we really should scan the $Channel array and add a link to this program's channel
+             foreach (array_keys($Channels) as $key) {
+                 if ($Channels[$key]->chanid == $this->chanid) {
+-                    $this->channel = &$Channels[$key];
++                    $this->channel =& $Channels[$key];
+                     break;
+                 }
+             }
++        // Not found
++            if (!$this->channel)
++                $this->channel =& load_one_channel($this->chanid);
+         }
+-
+     // Calculate the duration
+         if ($this->recendts)
+             $this->length = $this->recendts - $this->recstartts;
+Index: mythplugins/mythweb/includes/utils.php
+===================================================================
+--- mythplugins/mythweb/includes/utils.php     (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/includes/utils.php     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -276,7 +276,7 @@
+         static $first_run=true;
+         if($first_run) {
+             $first_run=false;
+-            echo '<script type="text/javascript" src="/js/debug.js"></script>';
++            echo '<script type="text/javascript" src="'.root.'js/debug.js"></script>';
+         }
+     // Put our data into a string
+         if (is_array($data) || is_object($data))
+Index: mythplugins/mythweb/includes/init.php
+===================================================================
+--- mythplugins/mythweb/includes/init.php      (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/includes/init.php      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -16,28 +16,15 @@
+  *
+ /**/
+-/**
+- * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some
+- * other lesser means.  It contains most of the information required for
+- * figuring out what functions the user wants to access.
+- *
+- * @global  array   $GLOBALS['Path']
+- * @name    $Path
+-/**/
+-    global $Path;
+-    $Path = explode('/', preg_replace('/^\/+/',   '',    // Remove leading slashes
+-                         preg_replace('/[\s]+/', ' ',    // Convert extra whitespace
+-                                                         // Grab the path info from various different places.
+-                             array_key_exists('PATH_INFO', $_SERVER)
+-                             && $_SERVER['PATH_INFO']
+-                                ? $_SERVER['PATH_INFO']
+-                                : (array_key_exists('PATH_INFO', $_ENV)
+-                                   && $_ENV['PATH_INFO']
+-                                    ? $_ENV['PATH_INFO']
+-                                    : $_GET['PATH_INFO']
+-                                  )
+-                         ))
+-                   );
++// mod_redirect can do some weird things when php is run in cgi mode
++    $keys = preg_grep('/^REDIRECT_/', array_keys($_SERVER));
++    if (!empty($keys)) {
++        foreach ($keys as $key) {
++            $key = substr($key, 9);
++            if (!array_key_exists($key, $_SERVER))
++                $_SERVER[$key] = $_SERVER["REDIRECT_$key"];
++        }
++    }
+ // Clean the document root variable and make sure it doesn't have a trailing slash
+     $_SERVER['DOCUMENT_ROOT'] = preg_replace('/\/+$/', '', $_SERVER['DOCUMENT_ROOT']);
+@@ -94,6 +81,29 @@
+         exit;
+     }
++/**
++ * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some
++ * other lesser means.  It contains most of the information required for
++ * figuring out what functions the user wants to access.
++ *
++ * @global  array   $GLOBALS['Path']
++ * @name    $Path
++/**/
++    global $Path;
++    $Path = explode('/', preg_replace('/^\/+/',   '',    // Remove leading slashes
++                         preg_replace('/[\s]+/', ' ',    // Convert extra whitespace
++                                                         // Grab the path info from various different places.
++                             array_key_exists('PATH_INFO', $_SERVER)
++                             && $_SERVER['PATH_INFO']
++                                ? $_SERVER['PATH_INFO']
++                                : (array_key_exists('PATH_INFO', $_ENV)
++                                   && $_ENV['PATH_INFO']
++                                    ? $_ENV['PATH_INFO']
++                                    : $_GET['PATH_INFO']
++                                  )
++                         ))
++                   );
++
+ // Load the database connection routines
+     require_once 'includes/db.php';
+Index: mythplugins/mythweb/includes/mobile.php
+===================================================================
+--- mythplugins/mythweb/includes/mobile.php    (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/includes/mobile.php    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -74,58 +74,56 @@
+      * If you don't know the screensize of some mobile terminal then use
+      * an empty array or approximate dimensions.
+      */
+-    $mobiles = array(/* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */
+-             'Series 60' => array('width' => 176, 'height' => 208),
+-             'Series60' => array('width' => 176, 'height' => 208),
+-             'C500' => array('width'=>176, 'height'=> 220), // SPV C500
++    $mobiles = array(
++                /* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */
++                     'Series 60' => array('width' => 176, 'height' => 208),
++                     'Series60'  => array('width' => 176, 'height' => 208),
++                     'C500'      => array('width'=>176, 'height'=> 220), // SPV C500
++                /* Phones using the Series 90 platform, e.g. Nokia 7710. */
++                     'Series 90' => array('width' => 640, 'height' => 320),
++                     'Series90' => array('width' => 640, 'height' => 320),
++                /* The following strings are added for the Palm browser WebPro
++                 * WebPro sometimes supplies the screen dimensions, but sometimes not
++                 * but we try to detect the best as possible */
++                     '240x320'    => array('width' => 240, 'height' => 320), // PocketPC IE
++                     '320x320'    => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
++                     '320x480'    => array('width' => 320, 'height' => 480), // For Palm Tungsten T
++                     '480x320'    => array('width' => 480, 'height' => 320), // For Palm Tungsten T
++                     '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
++                     '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
++                     '320x320x16' => array('width' => 320, 'height' => 320),
++                     'WebPro'     => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
++                 /* A generic mobile phone using Symbian OS. All Symbian phones don't
++                  * necessarily have the same screen size so if you want to include
++                  * some specific Symbian phones then place them above this line. */
++                     'Symbian' => array('width' => 176, 'height' => 208),
+-             /* Phones using the Series 90 platform, e.g. Nokia 7710. */
+-             'Series 90' => array('width' => 640, 'height' => 320),
+-             'Series90' => array('width' => 640, 'height' => 320),
++                     'Nokia' => array(), // Nokia phones and emulators
++                     'Eric' => array(), // Ericsson WAP phones and emulators
++                     'WapI' => array(), // Ericsson WapIDE 2.0
++                     'MC21' => array(), // Ericsson MC218
++                     'AUR ' => array(), // Ericsson R320
++                     'R380' => array(), // Ericsson R380
++                     'UP.B' => array(), // UP.Browser
++                     'WinW' => array(), // WinWAP browser
++                     'UPG1' => array(), // UP.SDK 4.0
++                     'upsi' => array(), // another kind of UP.Browser ??
++                     'QWAP' => array(), // unknown QWAPPER browser
++                     'Jigs' => array(), // unknown JigSaw browser
++                     'Java' => array(), // unknown Java based browser
++                     'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?)
++                     'MITS' => array(), // unknown Mitsubishi browser
++                     'MOT-' => array(), // unknown browser (UP based?)
++                     'My S' => array(), // unknown Ericsson devkit browser ?
++                     'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de
++                     'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de
++                     'ALAV' => array(), // yet another unknown UP based browser ?
++                     'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?)
++                     'LGE-' => array(), // LG phones
+-           /* The following strings are added for the Palm browser WebPro
+-              * WebPro sometimes supplies the screen dimensions, but sometimes not
+-            * but we try to detect the best as possible
+-              */
+-           '320x480' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
+-           '480x320' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
+-           '320x320' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
+-           '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
+-           '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
+-           '320x320x16' => array('width' => 320, 'height' => 320),
+-           'WebPro' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
+-
+-             /* A generic mobile phone using Symbian OS. All Symbian phones don't
+-              * necessarily have the same screen size so if you want to include
+-              * some specific Symbian phones then place them above this line. */
+-             'Symbian' => array('width' => 176, 'height' => 208),
+-
+-             'Nokia' => array(), // Nokia phones and emulators
+-             'Eric' => array(), // Ericsson WAP phones and emulators
+-             'WapI' => array(), // Ericsson WapIDE 2.0
+-             'MC21' => array(), // Ericsson MC218
+-             'AUR ' => array(), // Ericsson R320
+-             'R380' => array(), // Ericsson R380
+-             'UP.B' => array(), // UP.Browser
+-             'WinW' => array(), // WinWAP browser
+-             'UPG1' => array(), // UP.SDK 4.0
+-             'upsi' => array(), // another kind of UP.Browser ??
+-             'QWAP' => array(), // unknown QWAPPER browser
+-             'Jigs' => array(), // unknown JigSaw browser
+-             'Java' => array(), // unknown Java based browser
+-             'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?)
+-             'MITS' => array(), // unknown Mitsubishi browser
+-             'MOT-' => array(), // unknown browser (UP based?)
+-             'My S' => array(), // unknown Ericsson devkit browser ?
+-             'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de
+-             'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de
+-             'ALAV' => array(), // yet another unknown UP based browser ?
+-             'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?)
+-             'LGE-' => array(), // LG phones
+-
+-             /* For debugging: you can try out the mobile mode without a mobile phone.
+-              * Replace 'Opera' with your browser. Comment out for release version. */
+-             //'Opera' => array('width' => 176, 'height' => 208)
++                 /* For debugging: you can try out the mobile mode without a mobile phone.
++                  * Replace 'Opera' with your browser. Comment out for release version. */
++                     //'Opera' => array('width' => 176, 'height' => 208)
+              );
+     /* Scan through $mobiles and try to find matching user agent. */
+Index: mythplugins/mythweb/includes/recording_schedules.php
+===================================================================
+--- mythplugins/mythweb/includes/recording_schedules.php       (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/includes/recording_schedules.php       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -68,10 +68,14 @@
+ // Cleanup
+     mysql_free_result($result);
++// Initialize
++    global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
++    $Scheduled_Recordings = array();
++    $Num_Conflicts        = 0;
++    $Num_Scheduled        = 0;
++
+ // Load all of the scheduled recordings.  We will need them at some point, so we
+ // might as well get it overwith here.
+-    global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
+-    $Scheduled_Recordings = array();
+     foreach (get_backend_rows('QUERY_GETALLPENDING', 2) as $key => $program) {
+     // The offset entry
+         if ($key === 'offset') {
+Index: mythplugins/mythweb/includes/session.php
+===================================================================
+--- mythplugins/mythweb/includes/session.php   (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/includes/session.php   (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -19,8 +19,8 @@
+ // Start the session
+     session_name('mythweb_id');
+-    session_set_cookie_params(60 * 60 * 30, '/');       // 30 day timeout on cookies
+-    ini_set('session.gc_maxlifetime', 60 * 60 * 30);    // ... and sessions
++    session_set_cookie_params(60 * 60 * 24 * 365, '/');     // 1 year timeout on cookies
++    ini_set('session.gc_maxlifetime', 60 * 60 * 24 * 30);   // 30 day timeout on sessions
+     session_set_save_handler('sess_do_nothing', 'sess_do_nothing', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc');
+     session_start();
+Index: mythplugins/mythweb/modules/weather/handler.php
+===================================================================
+--- mythplugins/mythweb/modules/weather/handler.php    (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/modules/weather/handler.php    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -222,8 +222,10 @@
+     $data = explode("|", $data);
+     for($i = 0;$i<5;$i++) {
+-        $forecast = new Forecast($data[5 + $i],$data[$i]);
+-        $forecast->dayofweek = $data[$i];
++      # mktime uses 0-6;  msnbc gives us 1-7;  adjust msnbc to match mktime
++      $dayofweek = $data[$i] - 1;
++        $forecast = new Forecast($data[5 + $i],$dayofweek);
++        $forecast->dayofweek = $dayofweek;
+         list($forecast->DescImage,$forecast->DescText) = getImageAndDescFromId($data[15 + $i]);
+         $forecast->DescImage = (strlen($forecast->DescImage) > 0) ? $forecast->DescImage : "unknown.png";
+         $forecast->DescText = (strlen($forecast->DescText) > 0) ? $forecast->DescText : t('Unknown') . " (" . $data[15+$i] . ")";
+Index: mythplugins/mythweb/modules/status/handler.php
+===================================================================
+--- mythplugins/mythweb/modules/status/handler.php     (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/modules/status/handler.php     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -18,14 +18,17 @@
+     $masterhost = get_backend_setting('MasterServerIP');
+     $statusport = get_backend_setting('BackendStatusPort');
++// XML mode?
++    $xml_param = ($Path[1] == 'xml') ? '/xml' : '';
++
+ // Make sure the content is interpreted as UTF-8
+     header('Content-Type:  text/html; charset=UTF-8');
+ // Load the status page
+     if (function_exists('file_get_contents'))
+-        $status = file_get_contents("http://$masterhost:$statusport");
++        $status = file_get_contents("http://$masterhost:$statusport$xml_param");
+     else
+-        $status = implode("\n", file("http://$masterhost:$statusport"));
++        $status = implode("\n", file("http://$masterhost:$statusport$xml_param"));
+ // Extract the page title
+     preg_match('#<title>(.+?)</title>#s', $status, $title);
+Index: mythplugins/mythweb/modules/backend_log/handler.php
+===================================================================
+--- mythplugins/mythweb/modules/backend_log/handler.php        (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/modules/backend_log/handler.php        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -16,7 +16,7 @@
+ // Where to start searching from
+     $_GET['start'] = intVal($_GET['start']);
+     if ($_GET['start'] < 1)
+-        $_GET['start'] = 1;
++        $_GET['start'] = 0;
+ // How many entries to show?
+     $_GET['show'] = intVal($_GET['show']);
+Index: mythplugins/mythweb/modules/tv/upcoming.php
+===================================================================
+--- mythplugins/mythweb/modules/tv/upcoming.php        (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/modules/tv/upcoming.php        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -103,8 +103,9 @@
+                         continue;
+                 }
+             // Skip deactivated shows?
+-                elseif (!$_SESSION['scheduled_recordings']['disp_deactivated']) {
+-                    continue;
++                elseif ($show->recstatus != 'Recording') {
++                    if (!$_SESSION['scheduled_recordings']['disp_deactivated'])
++                        continue;
+                 }
+             // Assign a reference to this show to the various arrays
+                 $all_shows[] =& $Scheduled_Recordings[$channum][$starttime][$key];
+Index: mythplugins/mythweb/modules/tv/recorded.php
+===================================================================
+--- mythplugins/mythweb/modules/tv/recorded.php        (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/modules/tv/recorded.php        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -128,9 +128,21 @@
+                 continue;
+         // Get the length (27 == recendts; 26 == recstartts)
+             $length = $record[27] - $record[26];
+-        // Keep track of the total time and disk space used
++        // Keep track of the total time and disk space used (9 == fs_high; 10 == fs_low)
+             $Total_Time += $length;
+-            $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10];  // 9 == fs_high; 10 == fs_low;
++            if (function_exists('gmp_add')) {
++            // GMP functions should work better with 64 bit numbers.
++                $size = gmp_add($record[10],
++                                gmp_mul('4294967296',
++                                        gmp_add($record[9], $record[10] < 0 ? '1' : '0')
++                                       )
++                               );
++                $Total_Used = gmp_strval(gmp_add($Total_Used, $size));
++            }
++            else {
++            // This is inaccurate, but it's the best we can get without GMP.
++                $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10];
++            }
+         // keep track of their names and how many episodes we have recorded
+             $Total_Programs++;
+             $Groups[$record[30]]++;
+@@ -223,8 +235,28 @@
+ // How much free disk space on the backend machine?
+     list($size_high, $size_low, $used_high, $used_low) = explode(backend_sep, backend_command('QUERY_FREE_SPACE'));
+-    define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024);
+-    define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024);
++    if (function_exists('gmp_add')) {
++    // GMP functions should work better with 64 bit numbers.
++        $size = gmp_mul('1024',
++                        gmp_add($size_low,
++                                gmp_mul('4294967296',
++                                        gmp_add($size_high, $size_low < 0 ? '1' : '0'))
++                               )
++                       );
++        define(disk_size, gmp_strval($size));
++        $size = gmp_mul('1024',
++                        gmp_add($used_low,
++                                gmp_mul('4294967296',
++                                        gmp_add($used_high, $used_low < 0 ? '1' : '0'))
++                               )
++                       );
++        define(disk_used, gmp_strval($size));
++    }
++    else {
++    // This is inaccurate, but it's the best we can get without GMP.
++        define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024);
++        define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024);
++    }
+ // Load the class for this page
+     require_once theme_dir.'tv/recorded.php';
+Index: mythplugins/mythweb/.htaccess
+===================================================================
+--- mythplugins/mythweb/.htaccess      (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/.htaccess      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -22,6 +22,7 @@
+ #    AuthName           "MythTV"
+ #    AuthDigestFile     /var/www/htdigest
+ #    Require            valid-user
++#    BrowserMatch       "MSIE"      AuthDigestEnableQueryStringHack=On
+ # MythTV now uses the correct file suffix for mpeg files, so all .nuv files
+ # should actually be NuppleVideo.  However, apache probably doesn't know what
+@@ -66,8 +67,6 @@
+         php_value memory_limit                  32M
+-        php_value session.save_path             php_sessions
+-
+         php_value output_buffering              4096
+         php_value register_globals              0
+         php_value magic_quotes_gpc              0
+Index: mythplugins/mythweb/js/debug.js
+===================================================================
+--- mythplugins/mythweb/js/debug.js    (.../tags/release-0-19) (revision 0)
++++ mythplugins/mythweb/js/debug.js    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -0,0 +1,24 @@
++/**
++ * A random assortment of javascript debug routines
++ *
++ * @url         $URL$
++ * @date        $Date$
++ * @version     $Revision$
++ * @author      $Author$
++ * @copyright   Silicon Mechanics
++ * @license     LGPL
++ *
++ * @package     SiMech
++ * @subpackage  Javascript
++ *
++/**/
++
++    var debug_window_handle;
++// Create a debug window and debug into it
++    function debug_window(string) {
++        if (!debug_window_handle || debug_window_handle.closed) {
++            debug_window_handle = window.open('', 'Debug Window','scrollbars, resizable, width=400, height=600');
++            debug_window_handle.document.write('<html><body style="font-size: 9pt; background-color: #f88;">');
++        }
++        debug_window_handle.document.write('<pre>'+string+'</pre><hr>');
++    }
+
+Property changes on: mythplugins/mythweb/js/debug.js
+___________________________________________________________________
+Name: svn:eol-style
+   + native
+Name: svn:mime-type
+   + text/x-javascript
+Name: svn:keywords
+   + Date Revision Author HeadURL
+
+Index: mythplugins/mythweb/js/browser.js
+===================================================================
+--- mythplugins/mythweb/js/browser.js  (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/js/browser.js  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -215,14 +215,18 @@
+     browser.is_css = (document.body  && document.body.style)
+     browser.is_w3c = (browser.is_css && browser.getElementById)
+-// Cookie support
+-    var tmp = document.cookie;
+-      document.cookie = 'cookies=true';
+-      browser.cookies = (document.cookie) ? true : false;
+-    document.cookie = tmp;
++// Cookie support -- only create a cookie if there isn't one already.  It seems
++// that doing this can override the exipiration info in existing cookies.
++    browser.cookies = (document.cookie) ? true : false;
++    if (!browser.cookies) {
++        var tmp = document.cookie;
++        document.cookie = 'cookie_test=true';
++        browser.cookies = (document.cookie) ? true : false;
++        document.cookie = tmp;
++    }
+ // Java support
+-      browser.java = navigator.javaEnabled();
++    browser.java = navigator.javaEnabled();
+ /****************************** Plugin Support ******************************/
+Index: mythplugins/mythweb/README
+===================================================================
+--- mythplugins/mythweb/README (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweb/README (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -1,18 +1,12 @@
+ This is the README file for the MythWeb package.
+-January 17, 2006
++March 6, 2006
+-Version: .19 pre
+-(c) 2002-2006  Thor Sigvaldason <mythtv(a)lamedomainname(o)com>
++Version: .19
++(c) 2002-2006  Chris Petersen   <mythweb(a)forevermore(o)net>
+                Isaac Richards   <ijr(a)po(o)cwru(o)edu>
+-               Chris Petersen   <mythweb(a)forevermore(o)net>
++               Thor Sigvaldason <mythtv(a)lamedomainname(o)com>
++               and others... (see mythtv.org commit logs for details)
+-with contributions from many people including:
+-
+-Michael Kedl   <kedlm(a)knology(o)net>
+-Jonathan Kolb  <jkolb(a)greyshift(o)net
+-Ed Wildgoose   <edward(o)wildgoose(a)frmhedge(o)com>
+-Kenneth Aafloy <ke-aa(a)frisurf(o)no>
+-
+ MythWeb is distributed under the GNU GENERAL PUBLIC LICENSE version 2, and where
+ noted with the @license tag, the LESSER GENERAL PUBLIC LICENSE version 2.
+ Please see http://www.gnu.org for details and the specific text of the license.
+@@ -63,10 +57,22 @@
+     In order for the included .htaccess to work properly, you will need to
+ set apache's "AllowOverride" setting to "All" (or at least "Options") for
+-the root mythweb directory.  This directive lives within <Directory/> tags,
+-so make sure you're changing the setting for the correct directory.  You will
+-also need to make sure that the following apache modules are enabled:
++the root mythweb directory.  This directive lives within <Directory> tags,
++so make sure you're changing the setting for the correct directory.  Please
++keep in mind that most distros correctly disable everything for <Directory />,
++and then later override those with something like <Directory /var/www/html>.
++The simplest way to do this is to put a file into /etc/httpd/conf.d (or
++whatever your distro calls it) containing something like:
++    <Directory "/var/www/html/mythweb" >
++        Options         FollowSymLinks
++        AllowOverride   All
++    </Directory>
++
++Just make sure that the path points to your MythWeb installation, since that
++will likely differ from system to system.  You will also need to make sure that
++the following apache modules are enabled:
++
+     mod_env
+     mod_rewrite
+Index: mythplugins/mythdvd/mtd/jobthread.cpp
+===================================================================
+--- mythplugins/mythdvd/mtd/jobthread.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythdvd/mtd/jobthread.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -11,6 +11,7 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
++#include <unistd.h>
+ #include <iostream>
+ using namespace std;
+Index: mythplugins/mythdvd/mtd/mtd.cpp
+===================================================================
+--- mythplugins/mythdvd/mtd/mtd.cpp    (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythdvd/mtd/mtd.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -8,6 +8,7 @@
+ */
++#include <unistd.h>
+ #include <qstringlist.h>
+ #include <qregexp.h>
+ #include <qdir.h>
+Index: mythplugins/mythdvd/mtd/logging.cpp
+===================================================================
+--- mythplugins/mythdvd/mtd/logging.cpp        (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythdvd/mtd/logging.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -9,6 +9,7 @@
+ */
+ #include "logging.h"
++#include <unistd.h>
+ #include <qdatetime.h>
+ #include <mythtv/mythcontext.h>
+Index: mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp
+===================================================================
+--- mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp  (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -12,6 +12,7 @@
+ #include "metadata.h"
+ #include "metaiooggvorbiscomment.h"
++#include <mythtv/mythconfig.h>
+ #include <mythtv/mythcontext.h>
+ // static functions for OggVorbis
+@@ -240,8 +241,13 @@
+             seekTime = -1.0;
+         }
++#ifdef WORDS_BIGENDIAN
++        len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 1, 2, 1,
++                      &section);
++#else
+         len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1,
+                       &section);
++#endif
+         if (len > 0) {
+             bitrate = ov_bitrate_instant(&oggfile) / 1000;
+Index: mythplugins/mythmusic/mythmusic/flacdecoder.cpp
+===================================================================
+--- mythplugins/mythmusic/mythmusic/flacdecoder.cpp    (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythmusic/mythmusic/flacdecoder.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -12,6 +12,7 @@
+ #include "metadata.h"
+ #include "metaioflacvorbiscomment.h"
++#include <mythtv/mythconfig.h>
+ #include <mythtv/mythcontext.h>
+ #include <qtimer.h>
+@@ -102,7 +103,11 @@
+             for (channel = 0; channel < chan; channel++)
+             {
+                sample = (FLAC__int8)buffer[channel][cursamp];
++#ifdef WORDS_BIGENDIAN
++               *(output_buf + output_at++) = ((sample >> 8) & 0xff);
++#else
+                *(output_buf + output_at++) = ((sample >> 0) & 0xff);
++#endif
+                output_bytes += 1;
+             }
+         }   
+@@ -114,8 +119,13 @@
+             for (channel = 0; channel < chan; channel++)
+             { 
+                sample = (FLAC__int16)buffer[channel][cursamp];             
++#ifdef WORDS_BIGENDIAN
++               *(output_buf + output_at++) = ((sample >> 8) & 0xff);
+                *(output_buf + output_at++) = ((sample >> 0) & 0xff);
++#else
++               *(output_buf + output_at++) = ((sample >> 0) & 0xff);
+                *(output_buf + output_at++) = ((sample >> 8) & 0xff);
++#endif
+                output_bytes += 2;
+             }
+         }
+Index: mythplugins/mythmusic/mythmusic/maddecoder.cpp
+===================================================================
+--- mythplugins/mythmusic/mythmusic/maddecoder.cpp     (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythmusic/mythmusic/maddecoder.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -16,6 +16,7 @@
+ #include <mythtv/audiooutput.h>
+ #include "metaioid3v2.h"
++#include <mythtv/mythconfig.h>
+ #include <mythtv/mythcontext.h>
+ #define XING_MAGIC     (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
+@@ -407,7 +408,7 @@
+         flush(TRUE);
+         if (output()) {
+-          output()->Drain();
++            output()->Drain();
+         }
+         done = TRUE;
+@@ -488,15 +489,25 @@
+             flush();
+         }
+         sample = fix_sample(16, *left++);
++#ifdef WORDS_BIGENDIAN
++        *(output_buf + output_at++) = ((sample >> 8) & 0xff);
+         *(output_buf + output_at++) = ((sample >> 0) & 0xff);
++#else
++        *(output_buf + output_at++) = ((sample >> 0) & 0xff);
+         *(output_buf + output_at++) = ((sample >> 8) & 0xff);
++#endif
+         output_bytes += 2;
+         if (channels == 2)
+         {
+             sample = fix_sample(16, *right++);
++#ifdef WORDS_BIGENDIAN
++            *(output_buf + output_at++) = ((sample >> 8) & 0xff);
+             *(output_buf + output_at++) = ((sample >> 0) & 0xff);
++#else
++            *(output_buf + output_at++) = ((sample >> 0) & 0xff);
+             *(output_buf + output_at++) = ((sample >> 8) & 0xff);
++#endif
+             output_bytes += 2;
+         }
+     }
+Index: mythplugins/mythweather/mythweather/weather.cpp
+===================================================================
+--- mythplugins/mythweather/mythweather/weather.cpp    (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythweather/mythweather/weather.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -2571,6 +2571,14 @@
+          return false;
+      }
++     int imageCount = 5;
++     QString imagesList = parseData(tempData, "imagenames = new Array( '", ";");
++     if (imagesList != "<NULL>")
++     {
++         QStringList imageURLs = QStringList::split(",", imagesList);
++         imageCount = imageURLs.size();
++     }
++
+      QString fileprefix = MythContext::GetConfDir();
+      QDir dir(fileprefix);
+@@ -2587,13 +2595,13 @@
+          cerr << "MythWeather: Map File Prefix: " << fileprefix << endl;
+      // delete existing radar maps
+-     for (int x = 1; x <= 6; x++)
++     for (int x = 1; x <= 10; x++)
+          QFile::remove(QString(fileprefix + "/radar%1.jpg").arg(x));
+      if (debug)
+          cerr << "MythWeather: Copying Map Files from Server (" << imageLoc << ")...\n";
+-     for (int x = 1; x <= 6; x++)
++     for (int x = 1; x <= imageCount; x++)
+      {
+          QString sFile = QString(fileprefix + "/radar%1.jpg").arg(x);
+          sURL = QString("http://image.weather.com" + imageLoc + "%1L.jpg").arg(x);
+Index: mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp
+===================================================================
+--- mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp     (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -46,22 +46,6 @@
+ #include "keygrabber.h"
+-static QMap<int,QString> FindContexts(const QString &context)
+-{
+-    QMap<int,QString> retval;
+-    retval.clear();
+-    if (context != JUMP_CONTEXT) retval[-1] = JUMP_CONTEXT;
+-    retval[0] = context;
+-    if (context != JUMP_CONTEXT && context != GLOBAL_CONTEXT)
+-    {
+-        if (context == "TV Editting")
+-            retval[1] = "TV Playback";
+-        retval[2] = GLOBAL_CONTEXT;
+-        if (context != "qt")
+-            retval[3] = "qt";
+-    }
+-    return retval;
+-}
+ static const QString KeyToDisplay(const QString key)
+ {
+@@ -838,7 +822,11 @@
+     refreshKeyInformation();
+ }
+-void MythControls::addBindings(QDict<binding_t> &bindings, const QString &context, const QString &contextParent, int bindlevel)
++
++
++void MythControls::addBindings(QDict<binding_t> &bindings,
++                               const QString &context,
++                               const QString &contextParent, int bindlevel)
+ {
+     QStringList *actions = key_bindings->getActions(context);
+@@ -872,18 +860,13 @@
+ BindingList *MythControls::getKeyBindings(const QString &context)
+ {
++    QStringList keys;
+     QDict<binding_t> bindings;
+     bindings.clear();
+-    QMap<int,QString> contextList = FindContexts(context);
+-    for (QMap<int,QString>::iterator it = contextList.begin(); it != contextList.end(); ++it)
+-    {
+-        int level = it.key();
+-        QString curcontext = it.data();
+-        addBindings(bindings, curcontext, context, level);
+-    }
++    for (size_t i = 0; i < contexts.size(); i++)
++        addBindings(bindings, contexts[i], context, i);
+-    QStringList keys;
+     for (QDictIterator<binding_t> it(bindings); it.current(); ++it)
+     {
+Index: mythplugins/mythcontrols/mythcontrols/actionset.cpp
+===================================================================
+--- mythplugins/mythcontrols/mythcontrols/actionset.cpp        (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythcontrols/mythcontrols/actionset.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -139,13 +139,19 @@
+ /* method description in header */
+ QStringList * ActionSet::actionStrings(const QString &context_name) const
+ {
+-    QStringList *action_strings = new QStringList();
+-    QDictIterator<Action> it(*(_contexts[context_name]));
++    Context *c = _contexts[context_name];
+-    for (; it.current(); ++it)
+-        action_strings->append(it.currentKey());
++    if (c == NULL) return NULL;
++    else
++    {
++        QStringList *action_strings = new QStringList();
++        QDictIterator<Action> it(*(_contexts[context_name]));
++
++        for (; it.current(); ++it)
++            action_strings->append(it.currentKey());
+     
+-    return action_strings;
++        return action_strings;
++    }
+ }
+Index: mythplugins/mythcontrols/mythcontrols/keybindings.h
+===================================================================
+--- mythplugins/mythcontrols/mythcontrols/keybindings.h        (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythcontrols/mythcontrols/keybindings.h        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -65,6 +65,8 @@
+     /**
+      * @brief Get a list of the context names.
+      * @return A list of the context names.
++     * @note The returned list is a copy and can be modified without
++     * side-effects.
+      */
+     inline QStringList * getContexts() const
+     {
+Index: mythplugins/mythvideo/mythvideo/videomanager.h
+===================================================================
+--- mythplugins/mythvideo/mythvideo/videomanager.h     (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythvideo/mythvideo/videomanager.h     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -30,7 +30,7 @@
+   public:
+     VideoManager(MythMainWindow *parent, const char *name = 0);
+     ~VideoManager(void);
+-    void VideoManager::processEvents() { qApp->processEvents(); }
++    void processEvents() { qApp->processEvents(); }
+     
+   public slots:
+     void slotManualIMDB();
+Index: mythplugins/mythvideo/mythvideo/videoselected.h
+===================================================================
+--- mythplugins/mythvideo/mythvideo/videoselected.h    (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythvideo/mythvideo/videoselected.h    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -35,7 +35,7 @@
+     VideoSelected(VideoList *lvideolist,
+                  MythMainWindow *parent, const char *name = 0, int index = 0);
+     ~VideoSelected();
+-    void VideoSelected::processEvents() { qApp->processEvents(); }
++    void processEvents() { qApp->processEvents(); }
+     
+   protected slots:
+Index: mythplugins/mythphone/mythphone/sipfsm.h
+===================================================================
+--- mythplugins/mythphone/mythphone/sipfsm.h   (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythphone/mythphone/sipfsm.h   (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -618,7 +618,7 @@
+     SipWatcher *CreateWatcherFsm(QString Url);
+     SipIM *CreateIMFsm(QString Url="", QString callIdStr="");
+     void StopWatchers();
+-    void SipFsm::KickWatcher(SipUrl *Url);
++    void KickWatcher(SipUrl *Url);
+     void SendIM(QString destUrl, QString CallId, QString imMsg);
+     int numCalls();
+     int getPrimaryCall() { return primaryCall; };
+Index: mythplugins/mythphone/mythphone/vxml.h
+===================================================================
+--- mythplugins/mythphone/mythphone/vxml.h     (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythphone/mythphone/vxml.h     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -10,7 +10,7 @@
+ {
+   public:
+     vxmlVariable(QString N, QString V);             
+-    vxmlVariable::vxmlVariable(QString N, short *wav, int S);
++    vxmlVariable(QString N, short *wav, int S);
+     virtual ~vxmlVariable() {}; 
+     bool isType(QString t) { return (t == Type); };
+     QString getName() { return Name; };
+Index: mythplugins/mythgame/mythgame/gamehandler.h
+===================================================================
+--- mythplugins/mythgame/mythgame/gamehandler.h        (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythgame/mythgame/gamehandler.h        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -106,7 +106,7 @@
+   protected:
+     static GameHandler* GetHandler(RomInfo *rominfo);
+-    static GameHandler* GameHandler::GetHandlerByName(QString systemname);
++    static GameHandler* GetHandlerByName(QString systemname);
+     bool rebuild;
+     int spandisks;
+Index: mythplugins/mythnews/mythnews/news-sites.xml
+===================================================================
+--- mythplugins/mythnews/mythnews/news-sites.xml       (.../tags/release-0-19) (revision 10051)
++++ mythplugins/mythnews/mythnews/news-sites.xml       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -119,7 +119,7 @@
+     <item>
+         <title>Slashdot</title>
+-        <url>http://slashdot.org/slashdot.rss</url>
++        <url>http://rss.slashdot.org/Slashdot/slashdot</url>
+         <ico>http://slashdot.org/favicon.ico</ico>
+     </item>
+Index: mythtv/libs/libmythtv/NuppelVideoPlayer.h
+===================================================================
+--- mythtv/libs/libmythtv/NuppelVideoPlayer.h  (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/NuppelVideoPlayer.h  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -150,7 +150,8 @@
+     // Complicated gets
+     long long CalcMaxFFTime(long long ff, bool setjump = true) const;
+     long long CalcRWTime(long long rw) const;
+-    void      calcSliderPos(struct StatusPosInfo &posInfo);
++    void      calcSliderPos(struct StatusPosInfo &posInfo,
++                            bool paddedFields = false);
+     /// Non-const gets
+     OSD         *GetOSD(void)                 { return osd; }
+@@ -543,6 +544,7 @@
+     QMap<long long, int>::Iterator deleteIter;
+     QMap<long long, int>::Iterator blankIter;
+     QMap<long long, int>::Iterator commBreakIter;
++    bool       forcePositionMapSync;
+     // Playback (output) speed control
+     /// Lock for next_play_speed and next_normal_speed
+Index: mythtv/libs/libmythtv/osdlistbtntype.h
+===================================================================
+--- mythtv/libs/libmythtv/osdlistbtntype.h     (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/osdlistbtntype.h     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -1,3 +1,4 @@
++// -*- Mode: c++ -*-
+ /* ============================================================
+  * File  : uilistbtntype.h
+  * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
+@@ -22,38 +23,57 @@
+ #ifndef OSDLISTBTNTYPE_H
+ #define OSDLISTBTNTYPE_H
+-#include "osdtypes.h"
+-#include "ttfont.h"
++#include <vector>
++using namespace std;
++
++// Qt headers
+ #include <qcolor.h>
+ #include <qptrlist.h>
+ #include <qevent.h>
+ #include <qmutex.h>
++#include <qptrvector.h>
++
++// MythTV headers
++#include "osdtypes.h"
++#include "ttfont.h"
+ #include "generictree.h"
++class OSDListBtnType;
+ class OSDListBtnTypeItem;
+-class OSDListBtnType;
++typedef vector<OSDListBtnType*> OSDListBtnList;
++typedef vector<OSDListBtnTypeItem*> OSDListBtnItemList;
+ class OSDGenericTree : public GenericTree
+ {
+   public:
+     // This class will _not_ delete the image it's given, if any.
+-    OSDGenericTree(OSDGenericTree *parent, const QString &name, 
+-                   const QString &action = "", int check = -1, 
+-                   OSDTypeImage *image = NULL, QString group = "");
++    OSDGenericTree(OSDGenericTree *parent,        const QString &name, 
++                   const QString  &action = "",   int            check = -1, 
++                   OSDTypeImage   *image  = NULL, QString        group = "") :
++        GenericTree(name), m_image(image),     m_action(action),
++        m_group(group),    m_checkable(check), m_parentButton(NULL)
++    {
++        m_group = (m_group.isEmpty()) ? action : m_group;
++        setSelectable(!action.isEmpty());
++        if (parent)
++            parent->addNode(this);
++    }
+-    OSDTypeImage *getImage(void) { return m_image; }
+-    QString getAction(void) { return m_action; }
+-    int getCheckable(void) { return m_checkable; }
+-    QString getGroup(void) { return m_group; }
++    QString getAction(void)    const { return m_action;    }
++    QString getGroup(void)     const { return m_group;     }
++    int     getCheckable(void) const { return m_checkable; }
++
++    OSDTypeImage       *getImage(void)        { return m_image;        }
++    OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; }
++
+     void setParentButton(OSDListBtnTypeItem *button)
+-                         { m_parentButton = button; };
+-    OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; };
++        { m_parentButton = button; }
+   private:
+-    OSDTypeImage *m_image;
+-    QString m_action;
+-    int m_checkable;
+-    QString m_group;
++    OSDTypeImage       *m_image;
++    QString             m_action;
++    QString             m_group;
++    int                 m_checkable;
+     OSDListBtnTypeItem *m_parentButton;
+ };
+@@ -62,53 +82,49 @@
+ {
+     Q_OBJECT
+   public:
+-    OSDListTreeType(const QString &name, const QRect &area, 
+-                    const QRect &levelsize, int levelspacing,
+-                    float wmult, float hmult);
++    OSDListTreeType(const QString &name,      const QRect &area,
++                    const QRect   &levelsize, int          levelspacing,
++                    float          wmult,     float        hmult);
++    ~OSDListTreeType();
+-    void Reinit(float wchange, float hchange, float wmult, float hmult);
++    bool IsVisible(void)          const { return m_visible;  }
++ 
++    void SetFontActive(TTFFont *font)   { m_active   = font; }
++    void SetFontInactive(TTFFont *font) { m_inactive = font; }
++
+     void SetGroupCheckState(QString group, int newState = 0);
++    void SetSpacing(uint spacing)
++        { m_unbiasedspacing = (m_spacing = spacing) / m_wmult; }
++    void SetMargin(uint margin)
++        { m_unbiasedmargin  = (m_margin  = margin)  / m_wmult; }
++    void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha)
++        { m_itemRegBeg = beg; m_itemRegEnd = end; m_itemRegAlpha = alpha; }
++    void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha)
++        { m_itemSelBeg = beg; m_itemSelEnd = end; m_itemSelAlpha = alpha; }
++    void SetVisible(bool visible) { m_visible = visible; }
++    void SetAsTree(OSDGenericTree *toplevel, vector<uint> *select = NULL);
+-    void SetFontActive(TTFFont *font);
+-    void SetFontInactive(TTFFont *font);
+-    void SetSpacing(int spacing);
+-    void SetMargin(int margin);
+-    void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha);
+-    void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha);
+-
+-    void SetAsTree(OSDGenericTree *toplevel);
+-
+-    OSDGenericTree *GetCurrentPosition(void);
+- 
++    void Reinit(float wmult, float hmult);
+     bool HandleKeypress(QKeyEvent *e);
+-
+     void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
+-    bool IsVisible(void) { return m_visible; }
+-    void SetVisible(bool visible) { m_visible = visible; }
+-
+   signals:
+     void itemSelected(OSDListTreeType *parent, OSDGenericTree *item);
+     void itemEntered(OSDListTreeType *parent, OSDGenericTree *item);
+   private:
+-    void FillLevelFromTree(OSDGenericTree *item, OSDListBtnType *list);
+-    OSDListBtnType *GetLevel(int levelnum);
+-    void SetCurrentPosition(void);
++    void FillLevelFromTree(OSDGenericTree *item, uint levelnum);
++    OSDListBtnType *GetLevel(uint levelnum);
++    void EnterItem(void);
++    void SelectItem(void);
+-    int levels;
+-    int curlevel;
+-
+     OSDGenericTree *treetop;
+     OSDGenericTree *currentpos;
++    TTFFont        *m_active;
++    TTFFont        *m_inactive;
+-    QPtrList<OSDListBtnType> listLevels;
++    OSDListBtnList  listLevels;
+-    OSDListBtnType *currentlevel;
+-
+-    TTFFont *m_active;
+-    TTFFont *m_inactive;
+-
+     QColor    m_itemRegBeg;
+     QColor    m_itemRegEnd;
+     QColor    m_itemSelBeg;
+@@ -116,62 +132,76 @@
+     uint      m_itemRegAlpha;
+     uint      m_itemSelAlpha;
+    
+-    int m_spacing;
+-    int m_margin;
++    uint      m_spacing;
++    uint      m_margin;
++    int       m_levelspacing;
+-    QRect m_totalarea;
+-    QRect m_levelsize;
+-    int m_levelspacing;
++    QRect     m_totalarea;
++    QRect     m_levelsize;
+-    float m_wmult;
+-    float m_hmult;
++    float     m_unbiasedspacing;
++    float     m_unbiasedmargin;
++    QRect     m_unbiasedarea;
++    QRect     m_unbiasedsize;
+-    bool m_visible;
+-    bool m_arrowAccel;
++    float     m_wmult;
++    float     m_hmult;
++
++    int       m_depth;
++    int       m_levelnum;
++    bool      m_visible;
++    bool      m_arrowAccel;
+ };
+  
+ class OSDListBtnType : public OSDType
+ {
++    friend class OSDListBtnTypeItem;
+     Q_OBJECT
++
+   public:
+     OSDListBtnType(const QString &name, const QRect& area,
+                    float wmult, float hmult,
+                    bool showScrollArrows = false);
+     ~OSDListBtnType();
+-    void  Reinit(float wchange, float hchange, float wmult, float hmult);
++    // General Gets
++    bool  IsVisible() const { return m_visible; }
++
++    // General Sets
++    void  SetFontActive(TTFFont *font)   { m_fontActive   = font;    }
++    void  SetFontInactive(TTFFont *font) { m_fontInactive = font;    }
++    void  SetSpacing(int spacing)        { m_itemSpacing  = spacing; }
++    void  SetMargin(int margin)          { m_itemMargin   = margin;  }
++    void  SetActive(bool active)         { m_active       = active;  }
++    void  SetVisible(bool vis)           { m_visible = vis; }
++    void  SetItemRegColor(const QColor& beg, const QColor& end, uint alpha)
++        { m_itemRegBeg = beg; m_itemRegEnd = end; m_itemRegAlpha = alpha; }
++    void  SetItemSelColor(const QColor& beg, const QColor& end, uint alpha)
++        { m_itemSelBeg = beg; m_itemSelEnd = end; m_itemSelAlpha = alpha; }
+     void  SetGroupCheckState(QString group, int newState = 0);
++    void  SetItemCurrent(const OSDListBtnTypeItem* item);
++    void  SetItemCurrent(uint pos);
+-    void  SetFontActive(TTFFont *font);
+-    void  SetFontInactive(TTFFont *font);
+-    void  SetSpacing(int spacing);
+-    void  SetMargin(int margin);
+-    void  SetItemRegColor(const QColor& beg, const QColor& end, uint alpha);
+-    void  SetItemSelColor(const QColor& beg, const QColor& end, uint alpha);
+-    
+-    void  Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
+-
+-    void  SetActive(bool active);
+-    void  Reset();
+-
+-    void  SetItemCurrent(OSDListBtnTypeItem* item);
+-    void  SetItemCurrent(int pos);
+-    OSDListBtnTypeItem* GetItemCurrent();
+-    OSDListBtnTypeItem* GetItemFirst();
+-    OSDListBtnTypeItem* GetItemNext(OSDListBtnTypeItem *item);
++    // Item Gets
++    int   GetCount(void) const;
++    int   GetItemPos(const OSDListBtnTypeItem* item) const;
++    int   GetItemCurrentPos() const;
++    OSDListBtnTypeItem* GetItemCurrent(void);
++    OSDListBtnTypeItem* GetItemFirst(void);
++    OSDListBtnTypeItem* GetItemNext(const OSDListBtnTypeItem *item);
+     OSDListBtnTypeItem* GetItemAt(int pos);
+-    int   GetItemPos(OSDListBtnTypeItem* item);
+-    int   GetCount();
+-    void  MoveDown();
+-    void  MoveUp();
++    // Item Sets/Commands
++    void  MoveDown(void);
++    void  MoveUp(void);
+-    bool  IsVisible() { return m_visible; }
+-    void  SetVisible(bool vis) { m_visible = vis; }
++    // General Commands
++    void  Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
++    void  Reinit(float,float) {}
++    void  Reset(void);
+   private:
+-
+-    void  Init();
++    void  Init(void);
+     void  InitItem(OSDTypeImage &osdImg, uint width, uint height,
+                    QColor beg, QColor end, int alpha);
+     void  LoadPixmap(OSDTypeImage& pix, const QString& fileName);
+@@ -179,24 +209,35 @@
+     void  InsertItem(OSDListBtnTypeItem *item);
+     void  RemoveItem(OSDListBtnTypeItem *item);
+-    int   m_order;
+-    QRect m_rect;
+-    QRect m_contentsRect;
+-    QRect m_arrowsRect;
++  private:
++    int            m_order;
++    QRect          m_rect;
++    QRect          m_contentsRect;
++    QRect          m_arrowsRect;
+-    float m_wmult;
+-    float m_hmult;
++    float          m_wmult;
++    float          m_hmult;
+-    int   m_itemHeight;
+-    int   m_itemSpacing;
+-    int   m_itemMargin;
+-    uint  m_itemsVisible;
++    int            m_itemHeight;
++    int            m_itemSpacing;
++    int            m_itemMargin;
++    uint           m_itemsVisible;
+-    bool  m_active;
+-    bool  m_showScrollArrows;
+-    bool  m_showUpArrow;
+-    bool  m_showDnArrow;
++    bool           m_active;
++    bool           m_showScrollArrows;
++    bool           m_showUpArrow;
++    bool           m_showDnArrow;
++    bool           m_initialized;
++    bool           m_clearing;
++    bool           m_visible;
++    QColor         m_itemRegBeg;
++    QColor         m_itemRegEnd;
++    QColor         m_itemSelBeg;
++    QColor         m_itemSelEnd;
++    uint           m_itemRegAlpha;
++    uint           m_itemSelAlpha;
++
+     OSDTypeImage   m_itemRegPix;
+     OSDTypeImage   m_itemSelActPix;
+     OSDTypeImage   m_itemSelInactPix;
+@@ -209,43 +250,30 @@
+     OSDTypeImage   m_checkHalfPix;
+     OSDTypeImage   m_checkFullPix;
+-    QColor    m_itemRegBeg;
+-    QColor    m_itemRegEnd;
+-    QColor    m_itemSelBeg;
+-    QColor    m_itemSelEnd;
+-    uint      m_itemRegAlpha;
+-    uint      m_itemSelAlpha;
++    TTFFont       *m_fontActive;
++    TTFFont       *m_fontInactive;
+-    TTFFont* m_fontActive;
+-    TTFFont* m_fontInactive;
++    int            m_topIndx;
++    int            m_selIndx;
+-    bool      m_initialized;
+-    bool      m_clearing;
++    OSDListBtnItemList m_itemList;
+-    OSDListBtnTypeItem* m_topItem;
+-    OSDListBtnTypeItem* m_selItem;
+-    QPtrList<OSDListBtnTypeItem> m_itemList;
++    mutable QMutex m_update;
+-    QMutex    m_update;
+-
+-    bool      m_visible;
+-
+-    friend class OSDListBtnTypeItem;
+-    
+   signals:
+-
+     void itemSelected(OSDListBtnTypeItem* item);
+ };
+ class OSDListBtnTypeItem
+ {
++    friend class OSDListBtnType;
+   public:
+-
+-    enum CheckState {
+-        NotChecked=0,
++    enum CheckState
++    {
++        NotChecked  = 0,
+         HalfChecked,
+-        FullChecked
++        FullChecked,
+     };
+     OSDListBtnTypeItem(OSDListBtnType* lbtype, const QString& text,
+@@ -253,41 +281,36 @@
+                        bool showArrow = false, CheckState state = NotChecked);
+     ~OSDListBtnTypeItem();
+-    OSDListBtnType*   parent() const;
+-    QString           text() const;
+-    const OSDTypeImage*   pixmap() const;
+-    bool              checkable() const;
+-    CheckState        state() const;
++    OSDListBtnType*     parent(void)    const { return m_parent;    }
++    QString             text(void)      const { return m_text;      }
++    const OSDTypeImage* pixmap(void)    const { return m_pixmap;    }
++    bool                checkable(void) const { return m_checkable; }
++    CheckState          state(void)     const { return m_state;     }
++    QString             getGroup(void)  const { return m_group;     }
++    void               *getData(void)         { return m_data;      }
+-    void  setChecked(CheckState state);
+-    void  setData(void *data);
+-    void* getData();
+-    void  setGroup(QString group) { m_group = group; };
+-    QString getGroup(void) { return m_group; }
++    void setData(void *data)          { m_data = data; }
++    void setGroup(QString grp)        { m_group = grp; }
++    void setChecked(CheckState state)
++        { m_state = (m_checkable) ? state : m_state; }
+-    void  Reinit(float wchange, float hchange, float wmult, float hmult);
+-    
++    void  Reinit(float,float) {}
+     void  paint(OSDSurface *surface, TTFFont *font, int fade, int maxfade, 
+                 int x, int y);
+     
+   protected:
+-
+     OSDListBtnType *m_parent;
+-    QString        m_text;
+-    OSDTypeImage  *m_pixmap;
+-    bool           m_checkable;
+-    CheckState     m_state;
+-    void          *m_data;
+-    QString        m_group;
+-
+-    QRect          m_checkRect;
+-    QRect          m_pixmapRect;
+-    QRect          m_textRect;
+-    QRect          m_arrowRect;
+-
+-    bool           m_showArrow;    
+-
+-    friend class OSDListBtnType;
++    OSDTypeImage   *m_pixmap;
++    void           *m_data;
++    QString         m_text;
++    QString         m_group;
++    CheckState      m_state;
++    bool            m_showArrow;
++    bool            m_checkable;
++    QRect           m_checkRect;
++    QRect           m_arrowRect;
++    QRect           m_pixmapRect;
++    QRect           m_textRect;
+ };
+Index: mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
+===================================================================
+--- mythtv/libs/libmythtv/NuppelVideoPlayer.cpp        (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/NuppelVideoPlayer.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -147,6 +147,7 @@
+       hascommbreaktable(false),
+       deleteIter(deleteMap.end()),  blankIter(blankMap.end()),
+       commBreakIter(commBreakMap.end()),
++      forcePositionMapSync(false),
+       // Playback (output) speed control
+       decoder_lock(true),
+       next_play_speed(1.0f),        next_normal_speed(true),
+@@ -747,6 +748,8 @@
+         SetDecoder(new IvtvDecoder(this, m_playbackinfo));
+         no_audio_out = true; // no audio with ivtv.
+         audio_bits = 16;
++        audio_samplerate = 44100;
++        audio_channels = 2;
+     }
+     else if (forceVideoOutput == kVideoOutput_IVTV)
+     {
+@@ -1113,7 +1116,7 @@
+ const unsigned char *NuppelVideoPlayer::GetScaledFrame(QSize &size)
+ {
+     QMutexLocker locker(&yuv_lock);
+-    yuv_desired_size = size = QSize(size.width() & ~0x3, size.height() & ~0x3);
++    yuv_desired_size = size = QSize(size.width() & ~0x7, size.height() & ~0x7);
+     if ((size.width() > 0) && (size.height() > 0))
+     {
+@@ -1920,7 +1923,7 @@
+         ShowText();
+         DisplaySubtitles();
+     }
+-    else if (osdHasSubtitles || nonDisplayedSubtitles.size() > 20)
++    else if (osdHasSubtitles)
+     {
+         ClearSubtitles();
+     }
+@@ -2176,7 +2179,10 @@
+     }
+     if (eof)
++    {
+         discontinuity = true;
++        ClearSubtitles();
++    }
+     livetvchain->SetProgram(pginfo);
+@@ -2199,6 +2205,7 @@
+     }
+     if (IsErrored())
+     {
++        VERBOSE(VB_IMPORTANT, LOC_ERR + "SwitchToProgram failed.");
+         eof = true;
+         return;
+     }
+@@ -2265,6 +2272,8 @@
+     ringBuffer->Pause();
+     ringBuffer->WaitForPause();
++    ClearSubtitles();
++
+     livetvchain->SetProgram(pginfo);
+     ringBuffer->Reset(true);
+@@ -2284,6 +2293,7 @@
+     if (errored || !GetDecoder())
+     {
++        VERBOSE(VB_IMPORTANT, LOC_ERR + "JumpToProgram failed.");
+         errored = true;
+         return;
+     }
+@@ -2471,6 +2481,12 @@
+                 JumpToProgram();
+         }
++        if (forcePositionMapSync)
++        {
++            forcePositionMapSync = false;
++            GetDecoder()->SyncPositionMap();
++        }
++
+         if (IsErrored() || (nvr_enc && nvr_enc->GetErrorStatus()))
+         {
+             VERBOSE(VB_IMPORTANT, LOC_ERR + "Unknown error, exiting decoder");
+@@ -4398,6 +4414,8 @@
+     hascommbreaktable = !commBreakMap.isEmpty();
+     SetCommBreakIter();
+     commBreakMapLock.unlock();
++
++    forcePositionMapSync = true;
+ }
+ bool NuppelVideoPlayer::RebuildSeekTable(bool showPercentage, StatusCallback cb, void* cbData)
+@@ -4541,7 +4559,8 @@
+     return (int)((float)(written - played) / video_frame_rate);
+ }
+-void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo)
++void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo,
++                                      bool paddedFields)
+ {
+     posInfo.desc = "";
+     posInfo.position = 0;
+@@ -4588,15 +4607,23 @@
+     int ssecs = (playbackLen - shours * 3600 - smins * 60);
+     QString text1, text2;
+-    if (shours > 0)
++    if (paddedFields)
+     {
+-        text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
+-        text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
++        text1.sprintf("%02d:%02d:%02d", phours, pmins, psecs);
++        text2.sprintf("%02d:%02d:%02d", shours, smins, ssecs);
+     }
+     else
+     {
+-        text1.sprintf("%d:%02d", pmins, psecs);
+-        text2.sprintf("%d:%02d", smins, ssecs);
++        if (shours > 0)
++        {
++            text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
++            text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
++        }
++        else
++        {
++            text1.sprintf("%d:%02d", pmins, psecs);
++            text2.sprintf("%d:%02d", smins, ssecs);
++        }
+     }
+     posInfo.desc = QObject::tr("%1 of %2").arg(text1).arg(text2);
+@@ -4654,6 +4681,7 @@
+             if (commBreakIter.key() == totalFrames)
+             {
++                VERBOSE(VB_IMPORTANT, LOC + "Skipping commercial to end of file");
+                 eof = true;
+             }
+             else
+@@ -4721,7 +4749,7 @@
+         QString message = "COMMFLAG_REQUEST ";
+         message += m_playbackinfo->chanid + " " +
+-                   m_playbackinfo->startts.toString(Qt::ISODate);
++                   m_playbackinfo->recstartts.toString(Qt::ISODate);
+         RemoteSendMessage(message);
+         return false;
+@@ -5018,7 +5046,7 @@
+                 QImage scaledImage = qImage.smoothScale(rect->w, rect->h);
+                 OSDTypeImage* image = new OSDTypeImage();
+-                image->SetPosition(QPoint(rect->x, rect->y));
++                image->SetPosition(QPoint(rect->x, rect->y), hmult, vmult);
+                 image->LoadFromQImage(scaledImage);
+                 subtitleOSD->AddType(image);
+Index: mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
+===================================================================
+--- mythtv/libs/libmythtv/NuppelVideoRecorder.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/NuppelVideoRecorder.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -216,7 +216,10 @@
+     }
+     if (mpa_codec)
++    {
++        QMutexLocker locker(&avcodeclock);
+         avcodec_close(mpa_ctx);
++    }
+     if (mpa_ctx)
+         av_free(mpa_ctx);
+@@ -453,8 +456,11 @@
+         useavcodec = true;
+     if (mpa_codec)
++    {
++        QMutexLocker locker(&avcodeclock);
+         avcodec_close(mpa_ctx);
+-    
++    }
++
+     if (mpa_ctx)
+         av_free(mpa_ctx);
+     mpa_ctx = NULL;
+@@ -626,13 +632,14 @@
+     int frag, blocksize = 4096;
+     int tmp;
++    if (!skipdevice)
++    {
+ #if !defined (HAVE_SYS_SOUNDCARD_H) && !defined(HAVE_SOUNDCARD_H)
+-    VERBOSE(VB_IMPORTANT, QString("NVR::AudioInit() This Unix doesn't support"
+-                                  " device files for audio access. Skipping"));
+-    return 1;
++        VERBOSE(VB_IMPORTANT,
++                QString("NVR::AudioInit() This Unix doesn't support"
++                        " device files for audio access. Skipping"));
++        return 1;
+ #else
+-    if (!skipdevice)
+-    {
+         if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK)))
+         {
+             VERBOSE(VB_IMPORTANT, QString("NVR: Error, cannot open DSP '%1'").
+@@ -678,8 +685,8 @@
+         }
+         close(afd);
++#endif
+     }
+-#endif
+     audio_bytes_per_sample = audio_channels * audio_bits / 8;
+     blocksize *= 4;
+Index: mythtv/libs/libmythtv/osdlistbtntype.cpp
+===================================================================
+--- mythtv/libs/libmythtv/osdlistbtntype.cpp   (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/osdlistbtntype.cpp   (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -19,206 +19,148 @@
+  * 
+  * ============================================================ */
+-#include <iostream>
++// ANSI C headers
++#include <cmath>
++// C++ headers
++#include <algorithm>
++using namespace std;
++
++// Qt headers
+ #include <qapplication.h>
+ #include <qpixmap.h>
+ #include <qpainter.h>
+ #include <qimage.h>
+ #include <qcolor.h>
++// MythTV headers
+ #include "mythcontext.h"
+ #include "mythdialogs.h"
+-
+ #include "osdlistbtntype.h"
++#define LOC QString("OSDListTreeType: ")
++#define LOC_ERR QString("OSDListTreeType, Error: ")
+-OSDGenericTree::OSDGenericTree(OSDGenericTree *parent, const QString &name, 
+-                               const QString &action, int check, 
+-                               OSDTypeImage *image, QString group)
+-              : GenericTree(name)
++static QRect unbias(QRect rect, float wmult, float hmult)
+ {
+-    m_checkable = check;
+-    m_action = action;
+-    m_image = image;
+-    m_parentButton = NULL;
+-
+-    if (group != "")
+-        m_group = group;
+-    else
+-        m_group = action;
+-
+-    if (!action.isEmpty() && !action.isNull())
+-        setSelectable(true);
+-
+-    if (parent)
+-        parent->addNode(this);
++    return QRect((int)round(rect.x()      / wmult),
++                 (int)round(rect.y()      / hmult),
++                 (int)ceil( rect.width()  / wmult),
++                 (int)ceil( rect.height() / hmult));
+ }
+-////////////////////////////////////////////////////////////////////////////
+-
+-OSDListTreeType::OSDListTreeType(const QString &name, const QRect &area,
+-                                 const QRect &levelsize, int levelspacing,
+-                                 float wmult, float hmult)
+-               : OSDType(name)
++static QRect bias(QRect rect, float wmult, float hmult)
+ {
+-    m_wmult = wmult;
+-    m_hmult = hmult;
+-
+-    m_totalarea = area;
+-    m_levelsize = levelsize;
+-    m_levelspacing = levelspacing;
+-
+-    if (gContext->GetNumSetting("UseArrowAccels", 1))
+-        m_arrowAccel = true;
+-    else
+-        m_arrowAccel = false;
+-    
+-    levels = 0;
+-    curlevel = -1;
+-
+-    treetop = NULL;
+-    currentpos = NULL;
+-
+-    currentlevel = NULL;
+-
+-    listLevels.setAutoDelete(true);
+-
+-    m_active = NULL;
+-    m_inactive = NULL;
+-
+-    SetItemRegColor(Qt::black,QColor(80,80,80),100);
+-    SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
+-
+-    m_spacing = 0;
+-    m_margin = 0;
++    return QRect((int)round(rect.x()      * wmult),
++                 (int)round(rect.y()      * hmult),
++                 (int)ceil( rect.width()  * wmult),
++                 (int)ceil( rect.height() * hmult));
+ }
+-void OSDListTreeType::Reinit(float wchange, float hchange, float wmult,
+-                             float hmult)
++OSDListTreeType::OSDListTreeType(
++    const QString &name,      const QRect &area,
++    const QRect   &levelsize, int          levelspacing,
++    float          wmult,     float        hmult)
++    : OSDType(name),
++      treetop(NULL),                    currentpos(NULL),
++      m_active(NULL),                   m_inactive(NULL),
++      m_itemRegBeg(Qt::black),          m_itemRegEnd(QColor(80,80,80)),
++      m_itemSelBeg(QColor(82,202,56)),  m_itemSelEnd(QColor(52,152,56)),
++      m_itemRegAlpha(100),              m_itemSelAlpha(255),
++      m_spacing(0),                     m_margin(0),
++      m_levelspacing(levelspacing),
++      m_totalarea(area),                m_levelsize(levelsize),
++      m_unbiasedspacing(1.0f),          m_unbiasedmargin(1.0f),
++      m_unbiasedarea(0,0,0,0),          m_unbiasedsize(0,0,0,0),
++      m_wmult(wmult),                   m_hmult(hmult),
++      m_depth(0),                        m_levelnum(-1),
++      m_visible(true),
++      m_arrowAccel(gContext->GetNumSetting("UseArrowAccels", 1))
+ {
+-    m_wmult = wmult;
+-    m_hmult = hmult;
+-
+-    m_spacing = (int)(m_spacing * wchange);
+-    m_margin = (int)(m_margin * wchange);
+-
+-    int width = (int)(m_totalarea.width() * wchange);
+-    int height = (int)(m_totalarea.height() * hchange);
+-    int x = (int)(m_totalarea.x() * wchange);
+-    int y = (int)(m_totalarea.y() * hchange);
+-
+-    m_totalarea = QRect(x, y, width, height);
+-
+-    width = (int)(m_levelsize.width() * wchange);
+-    height = (int)(m_levelsize.height() * hchange);
+-    x = (int)(m_levelsize.x() * wchange);
+-    y = (int)(m_levelsize.y() * hchange);
+-
+-    m_levelsize = QRect(x, y, width, height);
+-
+-    QPtrListIterator<OSDListBtnType> it(listLevels);
+-    OSDListBtnType *child;
+-
+-    while ((child = it.current()) != 0)
+-    {
+-        child->Reinit(wchange, hchange, wmult, hmult);
+-        ++it;
+-    }
++    m_wmult        = (wmult == 0.0f) ? 1.0f : wmult;
++    m_hmult        = (hmult == 0.0f) ? 1.0f : hmult;
++    m_unbiasedarea = unbias(area,      wmult, hmult);
++    m_unbiasedsize = unbias(levelsize, wmult, hmult);
+ }
+-void OSDListTreeType::SetGroupCheckState(QString group, int newState)
++OSDListTreeType::~OSDListTreeType()
+ {
+-    QPtrListIterator<OSDListBtnType> it(listLevels);
+-    OSDListBtnType *child;
+-    while ((child = it.current()) != 0)
+-    {
+-        child->SetGroupCheckState(group, newState);
+-        ++it;
+-    }
++    OSDListBtnList::iterator it = listLevels.begin();
++    for (; it != listLevels.end(); ++it)
++        delete *it;    
+ }
+-void OSDListTreeType::SetItemRegColor(const QColor& beg, const QColor& end,
+-                                      uint alpha)
++void OSDListTreeType::Reinit(float wmult, float hmult)
+ {
+-    m_itemRegBeg   = beg;
+-    m_itemRegEnd   = end;
+-    m_itemRegAlpha = alpha;
+-}
++    m_wmult     = (wmult == 0.0f) ? 1.0f : wmult;
++    m_hmult     = (hmult == 0.0f) ? 1.0f : hmult;
++    m_spacing   = (uint) round(m_unbiasedspacing * wmult);
++    m_margin    = (uint) round(m_unbiasedmargin  * wmult);
++    m_totalarea = bias(m_unbiasedarea, wmult, hmult);
++    m_levelsize = bias(m_unbiasedsize, wmult, hmult);
+-void OSDListTreeType::SetItemSelColor(const QColor& beg, const QColor& end,
+-                                      uint alpha)
+-{
+-    m_itemSelBeg   = beg;
+-    m_itemSelEnd   = end;
+-    m_itemSelAlpha = alpha;
+-}
++    if (!treetop || m_levelnum < 0)
++        return;
+-void OSDListTreeType::SetFontActive(TTFFont *font)
+-{
+-    m_active = font;
+-}
++    // Save item indices
++    vector<uint> list;
++    for (uint i = 0; i <= (uint)m_levelnum; i++)
++        list.push_back(listLevels[i]->GetItemCurrentPos());
+-void OSDListTreeType::SetFontInactive(TTFFont *font)
+-{
+-    m_inactive = font;
+-}
++    // Delete old OSD items
++    OSDListBtnList clone = listLevels;
++    listLevels.clear();
++    OSDListBtnList::iterator it = clone.begin();
++    for (; it != clone.end(); ++it)
++        delete *it;
+-void OSDListTreeType::SetSpacing(int spacing)
+-{
+-    m_spacing = spacing;
++    // Create new OSD items
++    SetAsTree(treetop, &list);
+ }
+-void OSDListTreeType::SetMargin(int margin)
++void OSDListTreeType::SetGroupCheckState(QString group, int newState)
+ {
+-    m_margin = margin;
++    OSDListBtnList::iterator it = listLevels.begin();
++    for (; it != listLevels.end(); ++it)
++        (*it)->SetGroupCheckState(group, newState);
+ }
+-void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel)
++void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel,
++                                vector<uint> *select_list)
+ {
+     if (treetop)
+     {
+         listLevels.clear();
+-        currentlevel = NULL;
+-        treetop = NULL;
+-        currentpos = NULL;
+-        levels = 0;
+-        curlevel = -1;
++        treetop      = NULL;
++        currentpos   = NULL;
++        m_depth      = 0;
++        m_levelnum   = -1;
+     }
+-    levels = toplevel->calculateDepth(0) - 1;
+-
+-    if (levels <= 0)
++    m_depth = toplevel->calculateDepth(0) - 1;
++    if (m_depth <= 0)
+     {
+-        cerr << "Need at least one level\n";
++        VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need at least one level");
+         return;
+     }
+-    currentpos = (OSDGenericTree *)toplevel->getChildAt(0);
+-
++    currentpos = (OSDGenericTree*) toplevel->getChildAt(0);
+     if (!currentpos)
+     {
+-        cerr << "No top-level children?\n";
++        VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need top-level children");
+         return;
+     }
+-    treetop = toplevel;
+-
+-    // just for now, remove later
+-    if (levels > 2)
+-        levels = 3;
+-
+-    for (int i = 0; i < levels; i++)
++    // Create OSD buttons for all levels
++    for (uint i = 0; i < (uint)m_depth; i++)
+     {
+         QString levelname = QString("level%1").arg(i + 1);
+-
+         QRect curlevelarea = m_levelsize;
+         curlevelarea.moveBy(m_totalarea.x(), m_totalarea.y());
+-
+         curlevelarea.moveBy((m_levelsize.width() + m_levelspacing) * i, 0);
+-        OSDListBtnType *newlevel = new OSDListBtnType(levelname, curlevelarea,
+-                                                      m_wmult, m_hmult, true);
++        OSDListBtnType *newlevel = new OSDListBtnType(
++            levelname, curlevelarea, m_wmult, m_hmult, true);
+         newlevel->SetFontActive(m_active);
+         newlevel->SetFontInactive(m_inactive);
+@@ -227,229 +169,200 @@
+         newlevel->SetSpacing(m_spacing);
+         newlevel->SetMargin(m_margin);
+-        listLevels.append(newlevel);
++        listLevels.push_back(newlevel);
+     }
+-    currentlevel = GetLevel(0);
++    // Set up needed levels and selects
++    vector<uint> slist;
++    slist.push_back(0);
++    if (select_list)
++        slist = *select_list;
+-    if (!currentlevel)
++    currentpos = treetop = toplevel;
++    for (m_levelnum = 0; m_levelnum < (int)slist.size(); m_levelnum++)
+     {
+-        cerr << "Something is seriously wrong (currentlevel = NULL)\n";
+-        return;
++        FillLevelFromTree(currentpos, m_levelnum);
++        GetLevel(m_levelnum)->SetActive(true);
++        GetLevel(m_levelnum)->SetVisible(true);
++        if (slist[m_levelnum])
++            GetLevel(m_levelnum)->SetItemCurrent(slist[m_levelnum]);
++        EnterItem(); // updates currentpos
+     }
+-
+-    FillLevelFromTree(toplevel, currentlevel);
+-
+-    currentlevel->SetVisible(true);
+-    currentlevel->SetActive(true);
+-
+-    currentpos = (OSDGenericTree *)(currentlevel->GetItemFirst()->getData());
+-    curlevel = 0;
+-
+-    emit itemEntered(this, currentpos);
++    m_levelnum--;
+ }
+-OSDGenericTree *OSDListTreeType::GetCurrentPosition(void)
++static bool has_action(QString action, const QStringList &actions)
+ {
+-    return currentpos;
++    QStringList::const_iterator it;
++    for (it = actions.begin(); it != actions.end(); ++it)
++    {
++        if (action == *it)
++            return true;
++    }
++    return false;
+ }
+ bool OSDListTreeType::HandleKeypress(QKeyEvent *e)
+ {
+-    if (!currentlevel)
++    QStringList actions;
++    bool ok = gContext->GetMainWindow()->TranslateKeyPress(
++        "TV Playback", e, actions);
++
++    if (!ok || ((uint)m_levelnum >= listLevels.size()))
+         return false;
++    else if (has_action("UP", actions))
++    {
++        GetLevel(m_levelnum)->MoveUp();
++        EnterItem();
++    }
++    else if (has_action("DOWN", actions))
++    {
++        GetLevel(m_levelnum)->MoveDown();
++        EnterItem();
++    }
++    else if (has_action("LEFT", actions) && (m_levelnum > 0))
++    {
++        GetLevel(m_levelnum)->Reset();
++        GetLevel(m_levelnum)->SetVisible(false);
+-    bool handled = false;
+-    QStringList actions;
+-    if (gContext->GetMainWindow()->TranslateKeyPress("TV Playback", e, 
+-                                                     actions))
++        m_levelnum--;
++        EnterItem();
++    }
++    else if ((has_action("LEFT", actions) && m_arrowAccel) ||
++             has_action("ESCAPE",   actions) ||
++             has_action("CLEAROSD", actions) ||
++             has_action("MENU",     actions))
+     {
+-        for (unsigned int i = 0; i < actions.size() && !handled; i++)
+-        {
+-            QString action = actions[i];
+-            handled = true;
++        m_visible = false;
++    }
++    else if (has_action("RIGHT", actions) &&
++             (m_levelnum + 1 < m_depth) &&
++             (currentpos->childCount() > 0))
++    {
++        GetLevel(m_levelnum)->SetActive(false);
++        m_levelnum++;
+-            if (action == "UP")
+-            {
+-                currentlevel->MoveUp();
+-                SetCurrentPosition();
+-            }
+-            else if (action == "DOWN")
+-            {
+-                currentlevel->MoveDown();
+-                SetCurrentPosition();
+-            }
+-            else if (action == "LEFT")
+-            {
+-                if (curlevel > 0)
+-                {
+-                    currentlevel->Reset();
+-                    currentlevel->SetVisible(false);
+-
+-                    curlevel--;
+-
+-                    currentlevel = GetLevel(curlevel);
+-                    currentlevel->SetActive(true);
+-                    SetCurrentPosition();
+-                }
+-                else if (m_arrowAccel)
+-                {
+-                    m_visible = false;
+-                }
+-            }
+-            else if (action == "RIGHT")
+-            {
+-                // FIXME: create new levels if needed..
+-                if (curlevel + 1 < levels && currentpos->childCount() > 0)
+-                {
+-                    currentlevel->SetActive(false);
+-
+-                    curlevel++;
+-
+-                    currentlevel = GetLevel(curlevel);
+-
+-                    FillLevelFromTree(currentpos, currentlevel);
+-
+-                    currentlevel->SetVisible(true);
+-                    currentlevel->SetActive(true);
+-                    SetCurrentPosition();
+-                }
+-                else if (m_arrowAccel)
+-                {
+-                    SetGroupCheckState(currentpos->getGroup(),
+-                                       OSDListBtnTypeItem::NotChecked);
+-                    currentpos->getParentButton()->setChecked(
+-                                       OSDListBtnTypeItem::FullChecked);
+-                    emit itemSelected(this, currentpos);
+-                }
+-            }
+-            else if (action == "ESCAPE" || action == "MENU" ||
+-                     action == "CLEAROSD")
+-                m_visible = false;
+-            else if (action == "SELECT")
+-            {
+-                SetGroupCheckState(currentpos->getGroup(),
+-                                   OSDListBtnTypeItem::NotChecked);
+-                currentpos->getParentButton()->setChecked(
+-                                   OSDListBtnTypeItem::FullChecked);
+-                emit itemSelected(this, currentpos);
+-            }
+-            else
+-                handled = false;
+-        }
++        FillLevelFromTree(currentpos, m_levelnum);
++        GetLevel(m_levelnum)->SetVisible(true);
++        EnterItem();
+     }
++    else if ((has_action("RIGHT", actions) && m_arrowAccel) ||
++             has_action("SELECT", actions))
++    {
++        SelectItem();
++    }
++    else
++    {
++        return false;
++    }
+-    return handled;
++    return true;
+ }
+ void OSDListTreeType::Draw(OSDSurface *surface, int fade, int maxfade, 
+                            int xoff, int yoff)
+ {
+-    QPtrListIterator<OSDListBtnType> it(listLevels);
+-    OSDListBtnType *child;
+-
+-    while ((child = it.current()) != 0)
+-    {
+-        child->Draw(surface, fade, maxfade, xoff, yoff);
+-        ++it;
+-    }
++    OSDListBtnList::iterator it = listLevels.begin();
++    for (; it != listLevels.end(); ++it)
++        (*it)->Draw(surface, fade, maxfade, xoff, yoff);
+ }
+ void OSDListTreeType::FillLevelFromTree(OSDGenericTree *item, 
+-                                        OSDListBtnType *list)
++                                        uint level_num)
+ {
++    OSDListBtnType *list = GetLevel(level_num);
+     if (!list)
+     {
+-        VERBOSE(VB_IMPORTANT, "OSDListTreeType::FillLevelFromTree() "
+-                "called with no list. Ignoring call.");
++        VERBOSE(VB_IMPORTANT, LOC_ERR + "FillLevelFromTree() "
++                "called with no list, ignoring.");
+         return;
+     }
+     list->Reset();
+     QPtrList<GenericTree> *itemlist = item->getAllChildren();
+-
+     QPtrListIterator<GenericTree> it(*itemlist);
+-    GenericTree *child;
+-    while ((child = it.current()) != 0)
++    OSDGenericTree     *child   = (OSDGenericTree*) it.current();
++    OSDListBtnTypeItem *newitem = NULL;
++    for (;(child = (OSDGenericTree*) it.current()); ++it)
+     {
+-        OSDGenericTree *osdchild = (OSDGenericTree *)child;
++        OSDTypeImage *im = child->getImage();
++        QString label    = child->getString();
++        QString group    = child->getGroup();
++        bool    canCheck = child->getCheckable() >= 0;
++        bool    hasCheck = child->getCheckable() == 1;
++        bool    hasChild = child->childCount()   >  0;
+-        OSDListBtnTypeItem *newitem;
+-        newitem = new OSDListBtnTypeItem(list, child->getString(),
+-                                         osdchild->getImage(), 
+-                                         (osdchild->getCheckable() >= 0),
+-                                         (child->childCount() > 0));
+-        if (osdchild->getCheckable() == 1)
++        newitem = new OSDListBtnTypeItem(list, label, im, canCheck, hasChild);
++
++        if (hasCheck)
+             newitem->setChecked(OSDListBtnTypeItem::FullChecked);
+-        newitem->setGroup(osdchild->getGroup());
+-        newitem->setData(osdchild);
+-        osdchild->setParentButton(newitem);
++        newitem->setGroup(group);
++        newitem->setData(child);
+-        ++it;
++        child->setParentButton(newitem);
+     }
+ }
+-OSDListBtnType *OSDListTreeType::GetLevel(int levelnum)
++OSDListBtnType *OSDListTreeType::GetLevel(uint levelnum)
+ {
+-    if ((uint)levelnum > listLevels.count())
+-    {
+-        cerr << "OOB GetLevel call\n";
+-        return NULL;
+-    }
++    if (levelnum < listLevels.size())
++        return listLevels[levelnum];
+-    return listLevels.at(levelnum);
++    VERBOSE(VB_IMPORTANT, LOC_ERR + "GetLevel("<<levelnum<<") "
++            "listLevels.size() is only "<<listLevels.size());
++    return NULL;
+ }
+-void OSDListTreeType::SetCurrentPosition(void)
++void OSDListTreeType::EnterItem(void)
+ {
+-    if (!currentlevel)
++    if ((uint)m_levelnum >= listLevels.size())
+         return;
+-    OSDListBtnTypeItem *lbt = currentlevel->GetItemCurrent();
++    listLevels[m_levelnum]->SetActive(true);
++    OSDListBtnTypeItem *lbt = listLevels[m_levelnum]->GetItemCurrent();
++    if (lbt)
++    {
++        currentpos = (OSDGenericTree*) (lbt->getData());
++        emit itemEntered(this, currentpos);
++    }
++}
+-    if (!lbt)
++void OSDListTreeType::SelectItem(void)
++{
++    if (!currentpos)
+         return;
+-    currentpos = (OSDGenericTree *)(lbt->getData());
+-    emit itemEntered(this, currentpos);
++    SetGroupCheckState(currentpos->getGroup(), OSDListBtnTypeItem::NotChecked);
++    currentpos->getParentButton()->setChecked(OSDListBtnTypeItem::FullChecked);
++    emit itemSelected(this, currentpos);
+ }
+- 
++
++#undef LOC_ERR
++#undef LOC
++
+ //////////////////////////////////////////////////////////////////////////
+ OSDListBtnType::OSDListBtnType(const QString &name, const QRect &area,
+                                float wmult, float hmult,
+                                bool showScrollArrows)
+-              : OSDType(name)
++    : OSDType(name),
++      m_order(0),                       m_rect(area),
++      m_contentsRect(0,0,0,0),          m_arrowsRect(0,0,0,0),
++      m_wmult(wmult),                   m_hmult(hmult),
++      m_itemHeight(0),                  m_itemSpacing(0),
++      m_itemMargin(0),                  m_itemsVisible(0),
++      m_active(false),                  m_showScrollArrows(showScrollArrows),
++      m_showUpArrow(false),             m_showDnArrow(false),
++      m_initialized(false),             m_clearing(false),
++      m_visible(false),
++      m_itemRegBeg(Qt::black),          m_itemRegEnd(QColor(80,80,80)),
++      m_itemSelBeg(QColor(82,202,56)),  m_itemSelEnd(QColor(52,152,56)),
++      m_itemRegAlpha(100),              m_itemSelAlpha(255),
++      m_fontActive(NULL),               m_fontInactive(NULL),
++      m_topIndx(0),                     m_selIndx(0),
++      m_update(true)
+ {
+-    m_rect             = area;
+-
+-    m_wmult            = wmult;
+-    m_hmult            = hmult;
+-
+-    m_showScrollArrows = showScrollArrows;
+-
+-    m_active           = false;
+-    m_showUpArrow      = false;
+-    m_showDnArrow      = false;
+-
+-    m_itemList.setAutoDelete(false);
+-    m_topItem = 0;
+-    m_selItem = 0;
+-
+-    m_initialized     = false;
+-    m_clearing        = false;
+-    m_itemSpacing     = 0;
+-    m_itemMargin      = 0;
+-    m_itemHeight      = 0;
+-    m_itemsVisible    = 0;
+-    m_fontActive      = 0;
+-    m_fontInactive    = 0;
+-
+-    SetItemRegColor(Qt::black,QColor(80,80,80),100);
+-    SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
+-
+-    m_visible = false;
+ }
+ OSDListBtnType::~OSDListBtnType()
+@@ -457,316 +370,198 @@
+     Reset();
+ }
+-void OSDListBtnType::Reinit(float wchange, float hchange, float wmult,
+-                            float hmult)
+-{
+-    m_wmult = wmult;
+-    m_hmult = hmult;
+-
+-    m_itemHeight = (int)(m_itemHeight * hchange);
+-    m_itemSpacing = (int)(m_itemSpacing * wchange);
+-    m_itemMargin = (int)(m_itemMargin * wchange);
+-
+-    int width = (int)(m_rect.width() * wchange);
+-    int height = (int)(m_rect.height() * hchange);
+-    int x = (int)(m_rect.x() * wchange);
+-    int y = (int)(m_rect.y() * hchange);
+-
+-    m_rect = QRect(x, y, width, height);
+-
+-    Init();
+-
+-    OSDListBtnTypeItem* item = 0;
+-    for (item = m_itemList.first(); item; item = m_itemList.next()) {
+-        item->Reinit(wchange, hchange, wmult, hmult);
+-    }
+-
+-}
+-
+ void OSDListBtnType::SetGroupCheckState(QString group, int newState)
+ {
+-    OSDListBtnTypeItem* item = 0;
+-    for (item = m_itemList.first(); item; item = m_itemList.next()) {
+-        if (item->getGroup() == group)
+-            item->setChecked((OSDListBtnTypeItem::CheckState)newState);
+-    }
++    OSDListBtnItemList::iterator it;
++    for (it = m_itemList.begin(); it != m_itemList.end(); ++it)
++        if ((*it)->getGroup() == group)
++            (*it)->setChecked((OSDListBtnTypeItem::CheckState) newState);
+ }
+-void OSDListBtnType::SetItemRegColor(const QColor& beg, const QColor& end, 
+-                                     uint alpha)
++void OSDListBtnType::Reset(void)
+ {
+-    m_itemRegBeg   = beg;
+-    m_itemRegEnd   = end;
+-    m_itemRegAlpha = alpha;
+-}
+-
+-void OSDListBtnType::SetItemSelColor(const QColor& beg, const QColor& end,
+-                                     uint alpha)
+-{
+-    m_itemSelBeg   = beg;
+-    m_itemSelEnd   = end;
+-    m_itemSelAlpha = alpha;
+-}
+-
+-void OSDListBtnType::SetFontActive(TTFFont *font)
+-{
+-    m_fontActive   = font;
+-}
+-
+-void OSDListBtnType::SetFontInactive(TTFFont *font)
+-{
+-    m_fontInactive = font;
+-}
+-
+-void OSDListBtnType::SetSpacing(int spacing)
+-{
+-    m_itemSpacing = spacing;    
+-}
+-
+-void OSDListBtnType::SetMargin(int margin)
+-{
+-    m_itemMargin = margin;    
+-}
+-
+-void OSDListBtnType::SetActive(bool active)
+-{
+-    m_active = active;
+-}
+-
+-void OSDListBtnType::Reset()
+-{
+     QMutexLocker lock(&m_update);
+     m_clearing = true;
+-
+-    OSDListBtnTypeItem* item = 0;
+-    for (item = m_itemList.first(); item; item = m_itemList.next()) {
+-        delete item;
+-    }
+-
+-    m_clearing = false;
++    OSDListBtnItemList::iterator it;
++    OSDListBtnItemList clone = m_itemList;
+     m_itemList.clear();
+-    
+-    m_topItem     = 0;
+-    m_selItem     = 0;
++    for (it = clone.begin(); it != clone.end(); ++it)
++        delete (*it);
++    m_clearing = false;
++
++    m_topIndx     = 0;
++    m_selIndx     = 0;
+     m_showUpArrow = false;
+     m_showDnArrow = false;
+ }
+ void OSDListBtnType::InsertItem(OSDListBtnTypeItem *item)
+ {
+-    OSDListBtnTypeItem* lastItem = m_itemList.last();
+-    m_itemList.append(item);
+-
+-    if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
+-        m_showDnArrow = true;
+-    else
+-        m_showDnArrow = false;
+-
+-    if (!lastItem) 
+-    {
+-        m_topItem = item;
+-        m_selItem = item;
++    QMutexLocker lock(&m_update);
++    m_itemList.push_back(item);
++    m_showDnArrow = m_showScrollArrows && m_itemList.size() > m_itemsVisible;
++    if (m_itemList.size() == 1)
+         emit itemSelected(item);
+-    }
+ }
++int find(const OSDListBtnItemList &list, const OSDListBtnTypeItem *item)
++{
++    for (uint i = 0; i < list.size(); i++)
++        if (list[i] == item)
++            return i;
++    return -1;
++}
++
+ void OSDListBtnType::RemoveItem(OSDListBtnTypeItem *item)
+ {
++    QMutexLocker lock(&m_update);
+     if (m_clearing)
+         return;
+-    
+-    if (m_itemList.find(item) == -1)
++
++    int i = find(m_itemList, item);
++    if (i < 0)
+         return;
+-    m_topItem = m_itemList.first();
+-    m_selItem = m_itemList.first();
++    m_itemList.erase(m_itemList.begin()+i);
+-    m_itemList.remove(item);
+-
+     m_showUpArrow = false;
+-    
+-    if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
+-        m_showDnArrow = true;
+-    else
+-        m_showDnArrow = false;
++    m_showDnArrow = m_itemList.size() > m_itemsVisible;
++    m_selIndx     = 0;
++    m_topIndx     = 0;
+-    if (m_selItem) {
+-        emit itemSelected(m_selItem);
+-    }
++    if (m_itemList.size())
++        emit itemSelected(m_itemList[m_selIndx]);
+ }
+-void OSDListBtnType::SetItemCurrent(OSDListBtnTypeItem* item)
++void OSDListBtnType::SetItemCurrent(const OSDListBtnTypeItem* item)
+ {
+-    bool locked = m_update.tryLock();
++    QMutexLocker lock(&m_update);
++    int i = find(m_itemList, item);
++    if (i >= 0)
++        SetItemCurrent(i);
++}
+-    if (m_itemList.find(item) == -1)
++void OSDListBtnType::SetItemCurrent(uint current)
++{
++    QMutexLocker lock(&m_update);
++    if (current >= m_itemList.size())
+         return;
+-    m_topItem = item;
+-    m_selItem = item;
+-
+-    if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
+-        m_showDnArrow = true;
+-    else
+-        m_showDnArrow = false;
+-
+-    emit itemSelected(m_selItem);
+-
+-    if (locked)
+-        m_update.unlock();
++    m_selIndx     = current;
++    m_topIndx     = max(m_selIndx - (int)m_itemsVisible, 0);
++    m_showUpArrow = m_topIndx;
++    m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
++    emit itemSelected(m_itemList[m_selIndx]);
+ }
+-void OSDListBtnType::SetItemCurrent(int current)
++int OSDListBtnType::GetItemCurrentPos(void) const
+ {
+     QMutexLocker lock(&m_update);
+-
+-    OSDListBtnTypeItem* item = m_itemList.at(current);
+-    if (!item)
+-        item = m_itemList.first();
+-
+-    SetItemCurrent(item);
++    return (m_itemList.size()) ? m_selIndx : -1;
+ }
+-OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent()
++OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent(void)
+ {
+-    return m_selItem;
++    QMutexLocker lock(&m_update);
++    if (!m_itemList.size())
++        return NULL;
++    return m_itemList[m_selIndx];
+ }
+-OSDListBtnTypeItem* OSDListBtnType::GetItemFirst()
++OSDListBtnTypeItem* OSDListBtnType::GetItemFirst(void)
+ {
+-    return m_itemList.first();    
++    QMutexLocker lock(&m_update);
++    if (!m_itemList.size())
++        return NULL;
++    return m_itemList[0];    
+ }
+-OSDListBtnTypeItem* OSDListBtnType::GetItemNext(OSDListBtnTypeItem *item)
++OSDListBtnTypeItem* OSDListBtnType::GetItemNext(const OSDListBtnTypeItem *item)
+ {
+     QMutexLocker lock(&m_update);
+-
+-    if (m_itemList.find(item) == -1)
+-        return 0;
+-
+-    return m_itemList.next();
++    int i = find(m_itemList, item) + 1;
++    if (i <= 0 || i >= (int)m_itemList.size())
++        return NULL;
++    return m_itemList[i];
+ }
+-int OSDListBtnType::GetCount()
++int OSDListBtnType::GetCount(void) const
+ {
+-    return m_itemList.count();
++    QMutexLocker lock(&m_update);
++    return m_itemList.size();
+ }
+ OSDListBtnTypeItem* OSDListBtnType::GetItemAt(int pos)
+ {
+-    return m_itemList.at(pos);    
++    QMutexLocker lock(&m_update);
++    return m_itemList[pos];    
+ }
+-int OSDListBtnType::GetItemPos(OSDListBtnTypeItem* item)
++int OSDListBtnType::GetItemPos(const OSDListBtnTypeItem *item) const
+ {
+     QMutexLocker lock(&m_update);
+-
+-    return m_itemList.find(item);    
++    return find(m_itemList, item);
+ }
+-void OSDListBtnType::MoveUp()
++void OSDListBtnType::MoveUp(void)
+ {
+     QMutexLocker lock(&m_update);
+-
+-    if (m_itemList.find(m_selItem) == -1)
++    if (!m_itemList.size())
+         return;
+-    OSDListBtnTypeItem *item = m_itemList.prev();
+-    if (!item)
++    if (--m_selIndx < 0)
+     {
+-        item = m_itemList.last();
+-        if (!item)
+-            return;
+-
+-        if (m_itemList.count() > m_itemsVisible)
+-            m_topItem = m_itemList.at(m_itemList.count() - m_itemsVisible);
+-        else
+-            m_topItem = m_itemList.first();
++        m_selIndx = m_itemList.size() - 1;
++        m_topIndx = (m_itemList.size() > m_itemsVisible) ?
++            m_itemList.size() - m_itemsVisible : 0;
+     }
+-    m_selItem = item;
++    m_topIndx     = (m_selIndx < m_topIndx) ? m_selIndx : m_topIndx;
++    m_showUpArrow = m_topIndx;
++    m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
+-    if (m_itemList.find(m_selItem) < m_itemList.find(m_topItem))
+-        m_topItem = m_selItem;
+-
+-    if (m_topItem != m_itemList.first())
+-        m_showUpArrow = true;
+-    else
+-        m_showUpArrow = false;
+-
+-    if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
+-        m_showDnArrow = true;
+-    else
+-        m_showDnArrow = false;
+-
+-    emit itemSelected(m_selItem);
++    emit itemSelected(m_itemList[m_selIndx]);
+ }
+-void OSDListBtnType::MoveDown()
++void OSDListBtnType::MoveDown(void)
+ {
+     QMutexLocker lock(&m_update);
+-
+-    if (m_itemList.find(m_selItem) == -1)
++    if (!m_itemList.size())
+         return;
+-    OSDListBtnTypeItem *item = m_itemList.next();
+-    if (!item)
+-    {
+-        item = m_itemList.first();
+-        if (!item)
+-            return;
++    if (++m_selIndx >= (int)m_itemList.size())
++        m_selIndx = m_topIndx = 0;
+-        m_topItem = item;
+-    }
+-
+-    m_selItem = item;
+-
+-    if (m_itemList.find(m_topItem) + m_itemsVisible <=
+-        (unsigned int)m_itemList.find(m_selItem)) 
+-    {
+-        m_topItem = m_itemList.at(m_itemList.find(m_topItem) + 1);
+-    }
++    bool scroll_down = m_topIndx + (int)m_itemsVisible <= m_selIndx;
++    m_topIndx = (scroll_down) ? m_topIndx + 1 : m_topIndx;
++        
++    m_showUpArrow = m_topIndx;
++    m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
+     
+-    if (m_topItem != m_itemList.first())
+-        m_showUpArrow = true;
+-    else
+-        m_showUpArrow = false;
+-
+-    if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
+-        m_showDnArrow = true;
+-    else
+-        m_showDnArrow = false;
+-    
+-    emit itemSelected(m_selItem);
++    emit itemSelected(m_itemList[m_selIndx]);
+ }
+-void OSDListBtnType::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
+-                          int yoff)
++void OSDListBtnType::Draw(OSDSurface *surface,
++                          int fade, int maxfade,
++                          int xoff, int yoff)
+ {
+-    (void)xoff;
+-    (void)yoff;
+-
++    QMutexLocker lock(&m_update);
+     if (!m_visible)
+         return;
+-
+-    QMutexLocker lock(&m_update);
+-
+     if (!m_initialized)
+         Init();
+     TTFFont *font = m_active ? m_fontActive : m_fontInactive;
+     
+     int y = m_rect.y();
+-    m_itemList.find(m_topItem);
+-    OSDListBtnTypeItem *it = m_itemList.current();
+-    while (it && (y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight)) 
++    for (uint i = m_topIndx; i < m_itemList.size(); i++)
+     {
+-        it->paint(surface, font, fade, maxfade, m_rect.x()+ xoff, y + yoff);
+-
++        if (!((y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight)))
++            break;
++        m_itemList[i]->paint(surface, font, fade, maxfade,
++                             m_rect.x() + xoff, y + yoff);
+         y += m_itemHeight + m_itemSpacing;
+-
+-        it = m_itemList.next();
+     }
+     if (m_showScrollArrows) 
+@@ -792,14 +587,13 @@
+     }
+ }
+-void OSDListBtnType::Init()
++void OSDListBtnType::Init(void)
+ {
+     int sz1 = m_fontActive->Size() * 3 / 2;
+     int sz2 = m_fontInactive->Size() * 3 / 2;
+-    m_itemHeight = QMAX(sz1, sz2) + (int)(2 * m_itemMargin);
++    m_itemHeight = max(sz1, sz2) + (int)(2 * m_itemMargin);
++    m_itemHeight = m_itemHeight & ~0x1;
+-    m_itemHeight = (m_itemHeight / 2) * 2;
+-
+     if (m_showScrollArrows) 
+     {
+         LoadPixmap(m_upArrowRegPix, "uparrow-reg");
+@@ -838,11 +632,7 @@
+     InitItem(m_itemSelActPix,   itemWidth,    m_itemHeight,
+              m_itemSelBeg,      m_itemSelEnd, 255);
+-    if (m_itemList.count() > m_itemsVisible && m_showScrollArrows)
+-        m_showDnArrow = true;
+-    else
+-        m_showDnArrow = false;
+-
++    m_showDnArrow = m_itemList.size() > m_itemsVisible && m_showScrollArrows;
+     m_initialized = true;
+ }
+@@ -885,68 +675,57 @@
+ void OSDListBtnType::LoadPixmap(OSDTypeImage& pix, const QString& fileName)
+ {
+-    QString file = gContext->GetThemesParentDir() + "default/lb-" + fileName + ".png";
+-    pix.LoadImage(file, m_wmult, m_hmult);
++    QString path = gContext->GetThemesParentDir() + "default/lb-";
++    pix.LoadImage(path + fileName + ".png", m_wmult, m_hmult);
+ }
+ /////////////////////////////////////////////////////////////////////////////
+-OSDListBtnTypeItem::OSDListBtnTypeItem(OSDListBtnType* lbtype, 
+-                                       const QString& text,
+-                                       OSDTypeImage *pixmap, bool checkable,
+-                                       bool showArrow, CheckState state)
++OSDListBtnTypeItem::OSDListBtnTypeItem(
++    OSDListBtnType *lbtype,     const QString  &text,
++    OSDTypeImage   *pixmap,     bool            checkable,
++    bool            showArrow,  CheckState      state)
++    : m_parent(lbtype),       m_pixmap(pixmap),
++      m_data(NULL),           m_text(text),
++      m_group(QString::null), m_state(state),
++      m_showArrow(showArrow), m_checkable(checkable),
++      m_checkRect(0,0,0,0),   m_arrowRect(0,0,0,0),
++      m_pixmapRect(0,0,0,0),  m_textRect(0,0,0,0)
+ {
+-    m_parent    = lbtype;
+-    m_text      = text;
+-    m_pixmap    = pixmap;
+-    m_checkable = checkable;
+-    m_state     = state;
+-    m_showArrow = showArrow;
+-    m_data      = 0;
+-
+     if (!m_parent->m_initialized)
+         m_parent->Init();
+-    int  margin    = m_parent->m_itemMargin;
+-    int  width     = m_parent->m_rect.width();
+-    int  height    = m_parent->m_itemHeight;
++    OSDTypeImage &checkPix = m_parent->m_checkNonePix;
++    OSDTypeImage &arrowPix = m_parent->m_arrowPix;
+-    OSDTypeImage& checkPix = m_parent->m_checkNonePix;
+-    OSDTypeImage& arrowPix = m_parent->m_arrowPix;
+-    
+-    int cw = checkPix.ImageSize().width();
+-    int ch = checkPix.ImageSize().height();
+-    int aw = arrowPix.ImageSize().width();
+-    int ah = arrowPix.ImageSize().height();
+-    int pw = m_pixmap ? m_pixmap->ImageSize().width() : 0;
+-    int ph = m_pixmap ? m_pixmap->ImageSize().height() : 0;
+-    
++    int margin = m_parent->m_itemMargin;
++    int width  = m_parent->m_rect.width();
++    int height = m_parent->m_itemHeight;
++    int cw     = checkPix.ImageSize().width();
++    int ch     = checkPix.ImageSize().height();
++    int aw     = arrowPix.ImageSize().width();
++    int ah     = arrowPix.ImageSize().height();
++    int pw     = m_pixmap ? m_pixmap->ImageSize().width() : 0;
++    int ph     = m_pixmap ? m_pixmap->ImageSize().height() : 0;
++
+     if (m_checkable) 
+-        m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
+-    else
+-        m_checkRect = QRect(0,0,0,0);
++        m_checkRect  = QRect(margin, (height - ch)/2, cw, ch);
+     if (m_showArrow) 
+-        m_arrowRect = QRect(width - aw - margin, (height - ah)/2,
+-                            aw, ah);
+-    else
+-        m_arrowRect = QRect(0,0,0,0);
++        m_arrowRect  = QRect(width - aw - margin, (height - ah)/2, aw, ah);
+-    if (m_pixmap) 
+-        m_pixmapRect = QRect(m_checkable ? (2*margin + m_checkRect.width()) :
+-                             margin, (height - ph)/2,
+-                             pw, ph);
+-    else
+-        m_pixmapRect = QRect(0,0,0,0);
++    if (m_pixmap)
++    {
++        int tmp = (m_checkable) ? (2 * margin + m_checkRect.width()) : margin;
++        m_pixmapRect = QRect(tmp, (height - ph)/2, pw, ph);
++    }
+-    m_textRect = QRect(margin +
+-                       (m_checkable ? m_checkRect.width() + margin : 0) +
+-                       (m_pixmap    ? m_pixmapRect.width() + margin : 0),
+-                       0,
+-                       width - 2*margin -
+-                       (m_checkable ? m_checkRect.width() + margin : 0) -
+-                       (m_showArrow ? m_arrowRect.width() + margin : 0) -
+-                       (m_pixmap ? m_pixmapRect.width() + margin : 0),
+-                       height);
++    int tx = margin, tw = width - (2 * margin);
++    tx += (m_checkable) ? m_checkRect.width()  + margin : 0;
++    tx += (m_pixmap)    ? m_pixmapRect.width() + margin : 0;
++    tw -= (m_checkable) ? m_checkRect.width()  + margin : 0;
++    tw -= (m_showArrow) ? m_arrowRect.width()  + margin : 0;
++    tw -= (m_pixmap)    ? m_pixmapRect.width() + margin : 0;
++    m_textRect = QRect(tx, 0, tw, height);
+     m_parent->InsertItem(this);
+ }
+@@ -957,52 +736,10 @@
+         m_parent->RemoveItem(this);
+ }
+-QString OSDListBtnTypeItem::text() const
+-{
+-    return m_text;
+-}
+-
+-const OSDTypeImage* OSDListBtnTypeItem::pixmap() const
+-{
+-    return m_pixmap;
+-}
+-
+-bool OSDListBtnTypeItem::checkable() const
+-{
+-    return m_checkable;
+-}
+-
+-OSDListBtnTypeItem::CheckState OSDListBtnTypeItem::state() const
+-{
+-    return m_state;
+-}
+-
+-OSDListBtnType* OSDListBtnTypeItem::parent() const
+-{
+-    return m_parent;
+-}
+-
+-void OSDListBtnTypeItem::setChecked(CheckState state)
+-{
+-    if (!m_checkable)
+-        return;
+-    m_state = state;
+-}
+-
+-void OSDListBtnTypeItem::setData(void *data)
+-{
+-    m_data = data;    
+-}
+-
+-void* OSDListBtnTypeItem::getData()
+-{
+-    return m_data;
+-}
+-
+ void OSDListBtnTypeItem::paint(OSDSurface *surface, TTFFont *font, 
+                                int fade, int maxfade, int x, int y)
+ {
+-    if (this == m_parent->m_selItem)
++    if (this == m_parent->GetItemCurrent())
+     {
+         if (m_parent->m_active)
+             m_parent->m_itemSelActPix.Draw(surface, fade, maxfade, x, y);
+@@ -1030,11 +767,14 @@
+         cr.moveBy(x, y);
+         
+         if (m_state == HalfChecked)
+-            m_parent->m_checkHalfPix.Draw(surface, fade, maxfade, cr.x(), cr.y());
++            m_parent->m_checkHalfPix.Draw(surface, fade, maxfade,
++                                          cr.x(), cr.y());
+         else if (m_state == FullChecked)
+-            m_parent->m_checkFullPix.Draw(surface, fade, maxfade, cr.x(), cr.y());
++            m_parent->m_checkFullPix.Draw(surface, fade, maxfade,
++                                          cr.x(), cr.y());
+         else
+-            m_parent->m_checkNonePix.Draw(surface, fade, maxfade, cr.x(), cr.y());
++            m_parent->m_checkNonePix.Draw(surface, fade, maxfade,
++                                          cr.x(), cr.y());
+     }
+     if (m_pixmap)
+@@ -1049,39 +789,3 @@
+     tr.moveBy(0, font->Size() / 4);
+     font->DrawString(surface, tr.x(), tr.y(), m_text, tr.right(), tr.bottom());
+ }
+-
+-void OSDListBtnTypeItem::Reinit(float wchange, float hchange, 
+-                                float wmult, float hmult)
+-{
+-    (void)wmult;
+-    (void)hmult;
+-
+-    int width = (int)(m_checkRect.width() * wchange);
+-    int height = (int)(m_checkRect.height() * hchange);
+-    int x = (int)(m_checkRect.x() * wchange);
+-    int y = (int)(m_checkRect.y() * hchange);
+-
+-    m_checkRect = QRect(x, y, width, height);
+-
+-    width = (int)(m_pixmapRect.width() * wchange);
+-    height = (int)(m_pixmapRect.height() * hchange);
+-    x = (int)(m_pixmapRect.x() * wchange);
+-    y = (int)(m_pixmapRect.y() * hchange);
+-
+-    m_pixmapRect = QRect(x, y, width, height);
+-
+-    width = (int)(m_textRect.width() * wchange);
+-    height = (int)(m_textRect.height() * hchange);
+-    x = (int)(m_textRect.x() * wchange);
+-    y = (int)(m_textRect.y() * hchange);
+-
+-    m_textRect = QRect(x, y, width, height);
+-
+-    width = (int)(m_arrowRect.width() * wchange);
+-    height = (int)(m_arrowRect.height() * hchange);
+-    x = (int)(m_arrowRect.x() * wchange);
+-    y = (int)(m_arrowRect.y() * hchange);
+-
+-    m_arrowRect = QRect(x, y, width, height);
+-}
+-
+Index: mythtv/libs/libmythtv/RingBuffer.cpp
+===================================================================
+--- mythtv/libs/libmythtv/RingBuffer.cpp       (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/RingBuffer.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -145,6 +145,12 @@
+     VERBOSE(VB_PLAYBACK, LOC + QString("OpenFile(%1, %1)")
+             .arg(lfilename).arg(retryCount));
++    if ((filename.right(4).lower() == ".png") ||
++        (filename.right(4).lower() == ".gif"))
++    {
++        retryCount = 0;
++    }
++
+     uint openAttempts = retryCount + 1;
+     filename = lfilename;
+@@ -162,6 +168,7 @@
+     bool is_local = false;
+     bool is_dvd = false;
++
+     if ((filename.left(7) == "myth://") &&
+         (filename.length() > 7 ))
+     {
+@@ -271,6 +278,11 @@
+             remotefile = NULL;
+         }
+     }
++
++    setswitchtonext = false;
++    ateof = false;
++    commserror = false;
++    numfailures = 0;
+ }
+ /** \fn RingBuffer::IsOpen(void) const
+@@ -727,7 +739,7 @@
+         loops = 0;
+         pthread_rwlock_rdlock(&rwlock);
+-        if (totfree > readblocksize && !commserror)
++        if (totfree > readblocksize && !commserror && !ateof && !setswitchtonext)
+         {
+             // limit the read size
+             totfree = readblocksize;
+@@ -737,6 +749,9 @@
+             if (remotefile)
+             {
++                if (livetvchain && livetvchain->HasNext())
++                    remotefile->SetTimeout(true);
++
+                 ret = safe_read(remotefile, readAheadBuffer + rbwpos,
+                                 totfree);
+                 internalreadpos += ret;
+@@ -785,8 +800,16 @@
+             totfree = 0;
+         }
+-        if (!readsallowed && used >= fill_min)
++        if (!readsallowed && (used >= fill_min || setswitchtonext))
++        {
+             readsallowed = true;
++            VERBOSE(VB_PLAYBACK, QString("reads allowed (%1 %2)").arg(used)
++                                                                .arg(fill_min));
++        }
++        else if (!readsallowed)
++            VERBOSE(VB_PLAYBACK, QString("buffering (%1 %2 %3)").arg(used)
++                                                                .arg(fill_min)
++                                                                .arg(ret));
+         if (readsallowed && used < fill_min && !ateof && !setswitchtonext)
+         {
+@@ -808,8 +831,11 @@
+         pthread_rwlock_unlock(&rwlock);
+-        if ((used >= fill_threshold || wantseek) && !pausereadthread)
++        if ((used >= fill_threshold || wantseek || ateof || setswitchtonext) &&
++            !pausereadthread)
++        {
+             usleep(500);
++        }
+     }
+     delete [] readAheadBuffer;
+@@ -853,15 +879,15 @@
+                  VERBOSE(VB_IMPORTANT,
+                          LOC + "Taking too long to be allowed to read..");
+                  readErr++;
+-                 
++
+                  // HACK Sometimes the readhead thread gets borked on startup.
+-               /*  if ((readErr % 2) && (rbrpos ==0))
++                 if ((readErr > 2 && readErr % 2) && (rbrpos ==0))
+                  {
+                     VERBOSE(VB_IMPORTANT, "restarting readhead thread..");
+                     KillReadAheadThread();
+                     StartupReadAheadThread();
+                  }                    
+-                   */ 
++ 
+                  if (readErr > 10)
+                  {
+                      VERBOSE(VB_IMPORTANT, LOC_ERR + "Took more than "
+@@ -895,6 +921,12 @@
+                 VERBOSE(VB_IMPORTANT, LOC + "Waited " +
+                         QString("%1").arg(elapsed/1000) +
+                         " seconds for data to become available...");
++                if (livetvchain)
++                {
++                    VERBOSE(VB_IMPORTANT, "Checking to see if there's a "
++                                          "new livetv program to switch to..");
++                    livetvchain->ReloadAll();
++                }
+             }
+             bool quit = livetvchain && (livetvchain->NeedsToSwitch() || 
+@@ -923,7 +955,7 @@
+         availWaitMutex.unlock();
+         avail = ReadBufAvail();
+-        if (ateof && avail < count)
++        if ((ateof || setswitchtonext) && avail < count)
+             count = avail;
+         if (commserror)
+Index: mythtv/libs/libmythtv/hdtvrecorder.cpp
+===================================================================
+--- mythtv/libs/libmythtv/hdtvrecorder.cpp     (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/hdtvrecorder.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -627,9 +627,8 @@
+         len += remainder;
+         remainder = ProcessData(_buffer, len);
+-        if (remainder > 0) // leftover bytes
+-            memmove(_buffer, &(_buffer[_buffer_size - remainder]),
+-                    remainder);
++        if (remainder > 0 && (len > remainder)) // leftover bytes
++            memmove(_buffer, &(_buffer[len - remainder]), remainder);
+     }
+     FinishRecording();
+Index: mythtv/libs/libmythtv/dummydtvrecorder.cpp
+===================================================================
+--- mythtv/libs/libmythtv/dummydtvrecorder.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/dummydtvrecorder.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -125,7 +125,8 @@
+     // TRANSFER DATA
+     while (_request_recording || _frames_seen_count <= 5)
+     {
+-        len = read(_stream_fd, &(_buffer[remainder]), _buffer_size - remainder);
++        len = read(_stream_fd, &(_buffer[remainder]),
++                   _buffer_size - remainder);
+         if (len == 0)
+         {
+@@ -137,9 +138,8 @@
+         len += remainder;
+         remainder = ProcessData(_buffer, len);
+-        if (remainder > 0) // leftover bytes
+-            memmove(_buffer, &(_buffer[_buffer_size - remainder]),
+-                    remainder);
++        if (remainder > 0 && (len > remainder)) // leftover bytes
++            memmove(_buffer, &(_buffer[len - remainder]), remainder);
+     }
+     FinishRecording();
+Index: mythtv/libs/libmythtv/avformatdecoder.cpp
+===================================================================
+--- mythtv/libs/libmythtv/avformatdecoder.cpp  (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/avformatdecoder.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -725,7 +725,12 @@
+         return -1;
+     }
++    /* av_find_stream_info() eventually makes calls to avcodec_open() and avcodec_close() 
++       so we have to use the avcodeclock */
++    avcodeclock.lock();
+     int ret = av_find_stream_info(ic);
++    avcodeclock.unlock();
++
+     if (ret < 0)
+     {
+         VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not find codec parameters. " +
+Index: mythtv/libs/libmythtv/osdtypes.cpp
+===================================================================
+--- mythtv/libs/libmythtv/osdtypes.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/osdtypes.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -14,6 +14,9 @@
+ #include "mythcontext.h"
++/// Shared OSD image cache
++OSDImageCache OSDTypeImage::c_cache;
++
+ OSDSet::OSDSet(const QString &name, bool cache, int screenwidth, 
+                int screenheight, float wmult, float hmult, int frint)
+       : QObject()
+@@ -160,9 +163,6 @@
+                     int displaywidth, int displayheight, 
+                     float wmult, float hmult, int frint)
+ {
+-    float wchange = wmult / m_wmult;
+-    float hchange = hmult / m_hmult;
+-
+     m_frameint = frint;
+     m_screenwidth = screenwidth;
+@@ -175,57 +175,12 @@
+     vector<OSDType *>::iterator iter = allTypes->begin();
+     for (;iter != allTypes->end(); iter++)
+     {
+-        OSDType *type = (*iter);
+-        if (OSDTypeText *item = dynamic_cast<OSDTypeText*>(type))
+-        {
+-            item->Reinit(wchange, hchange);
+-        }
+-        else if (OSDTypePositionImage *item =
+-                 dynamic_cast<OSDTypePositionImage*>(type))
+-        {
+-            item->Reinit(wchange, hchange, wmult, hmult);
+-        }
+-        else if (OSDTypePosSlider *item = dynamic_cast<OSDTypePosSlider*>(type))
+-        {
+-            item->Reinit(wchange, hchange, wmult, hmult);
+-        }
+-        else if (OSDTypeFillSlider *item = 
+-                 dynamic_cast<OSDTypeFillSlider*>(type))
+-        {
+-            item->Reinit(wchange, hchange, wmult, hmult);
+-        }
+-        else if (OSDTypeEditSlider *item =
+-                 dynamic_cast<OSDTypeEditSlider*>(type))
+-        {
+-            item->Reinit(wchange, hchange, wmult, hmult);
+-        }
+-        else if (OSDTypeImage *item = dynamic_cast<OSDTypeImage*>(type))
+-        {
+-            item->Reinit(wchange, hchange, wmult, hmult);
+-        }
+-        else if (OSDTypeBox *item = dynamic_cast<OSDTypeBox*>(type))
+-        {
+-            item->Reinit(wchange, hchange);
+-        }
+-        else if (OSDTypePositionRectangle *item =
+-                  dynamic_cast<OSDTypePositionRectangle*>(type))
+-        {
+-            item->Reinit(wchange, hchange);
+-        }
+-        else if (OSDTypeCC *item = dynamic_cast<OSDTypeCC*>(type))
+-        {
+-            item->Reinit(xoff, yoff, displaywidth, displayheight);
+-        }
+-        else if (OSDListTreeType *item = dynamic_cast<OSDListTreeType*>(type))
+-        {
+-            item->Reinit(wchange, hchange, wmult, hmult);
+-        }
++        if (OSDTypeCC *cc608 = dynamic_cast<OSDTypeCC*>(*iter))
++            cc608->Reinit(xoff, yoff, displaywidth, displayheight,
++                          wmult, hmult);
+         else
+-        {
+-            cerr << "Unknown conversion\n";
+-        }
++            (*iter)->Reinit(wmult, hmult);
+     }
+-
+ }
+ OSDType *OSDSet::GetType(const QString &name)
+@@ -443,7 +398,8 @@
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ OSDTypeText::OSDTypeText(const QString &name, TTFFont *font, 
+-                         const QString &text, QRect displayrect)
++                         const QString &text, QRect displayrect,
++                         float wmult, float hmult)
+            : OSDType(name)
+ {
+     m_message = text;
+@@ -464,6 +420,12 @@
+     m_scrollinit = false;
+     m_linespacing = 1.5;
++
++    m_unbiasedsize =
++        QRect((int)round(m_screensize.x()      / wmult),
++              (int)round(m_screensize.y()      / hmult),
++              (int)ceil( m_screensize.width()  / wmult),
++              (int)ceil( m_screensize.height() / hmult));
+ }
+ OSDTypeText::OSDTypeText(const OSDTypeText &other)
+@@ -507,14 +469,13 @@
+     m_scrollinit = false;
+ }
+-void OSDTypeText::Reinit(float wchange, float hchange)
++void OSDTypeText::Reinit(float wmult, float hmult)
+ {
+-    int width = (int)(m_screensize.width() * wchange);
+-    int height = (int)(m_screensize.height() * hchange);
+-    int x = (int)(m_screensize.x() * wchange);
+-    int y = (int)(m_screensize.y() * hchange);
+-
+-    m_displaysize = m_screensize = QRect(x, y, width, height);
++    m_displaysize = m_screensize =
++        QRect((int)round(m_unbiasedsize.x()      * wmult),
++              (int)round(m_unbiasedsize.y()      * hmult),
++              (int)ceil( m_unbiasedsize.width()  * wmult),
++              (int)ceil( m_unbiasedsize.height() * hmult));
+ }
+ void OSDTypeText::Draw(OSDSurface *surface, int fade, int maxfade, int xoff, 
+@@ -708,7 +669,7 @@
+     m_onlyusefirst = false;
+     m_filename = filename;
+-    m_displaypos = displaypos;
++    SetPosition(displaypos, wmult, hmult);
+     m_yuv = m_alpha = NULL;
+     m_isvalid = false;
+@@ -716,6 +677,7 @@
+     m_scalew = scalew;
+     m_scaleh = scaleh;
++    m_cacheitem = NULL;
+     LoadImage(filename, wmult, hmult, scalew, scaleh);
+ }
+@@ -733,6 +695,7 @@
+     m_name = other.m_name;
+     m_scalew = other.m_scalew;
+     m_scaleh = other.m_scaleh;
++    m_cacheitem = NULL;
+     m_alpha = m_yuv = NULL;
+     if (m_isvalid)
+@@ -760,6 +723,8 @@
+     m_onlyusefirst = false;
+     m_displaypos = QPoint(0, 0);
++    m_unbiasedpos = QPoint(0, 0);
++    m_cacheitem = NULL;
+     m_yuv = NULL;
+     m_alpha = NULL;
+@@ -778,6 +743,8 @@
+     m_onlyusefirst = false;
+     m_displaypos = QPoint(0, 0);
++    m_unbiasedpos = QPoint(0, 0);
++    m_cacheitem = NULL;
+     m_yuv = NULL;
+     m_alpha = NULL;
+@@ -790,10 +757,14 @@
+ OSDTypeImage::~OSDTypeImage()
+ {
+-    if (m_yuv)
+-        delete [] m_yuv;
+-    if (m_alpha)
+-        delete [] m_alpha;
++    // In case we have a cache item in hand, it's safe to delete it,
++    // as it should not be in OSDImageCache anymore and it should have
++    // been written to the file cache for faster access in the future.
++    if (m_cacheitem)
++    {
++        delete m_cacheitem;
++        m_cacheitem = NULL;
++    }
+ }
+ void OSDTypeImage::SetName(const QString &name)
+@@ -801,13 +772,19 @@
+     m_name = name;
+ }
+-void OSDTypeImage::Reinit(float wchange, float hchange, float wmult, float hmult)
++void OSDTypeImage::SetPosition(QPoint pos, float wmult, float hmult)
+ {
+-    int x = (int)(m_displaypos.x() * wchange);
+-    int y = (int)(m_displaypos.y() * hchange);
++    m_displaypos  = pos;
++    m_unbiasedpos =
++        QPoint((int)round(pos.x() / wmult),
++               (int)round(pos.y() / hmult));
++}
+-    m_displaypos.setX(x);
+-    m_displaypos.setY(y);
++void OSDTypeImage::Reinit(float wmult, float hmult)
++{
++    m_displaypos =
++        QPoint((int)round(m_unbiasedpos.x() * wmult),
++               (int)round(m_unbiasedpos.y() * hmult));
+     LoadImage(m_filename, wmult, hmult, m_scalew, m_scaleh);
+ }
+@@ -815,20 +792,44 @@
+ void OSDTypeImage::LoadImage(const QString &filename, float wmult, float hmult,
+                              int scalew, int scaleh)
+ {
+-    if (m_isvalid)
++    QString ckey;
++   
++    if (!filename.isEmpty() && filename.length() >= 2)
+     {
+-        if (m_yuv)
+-            delete [] m_yuv;
+-        if (m_alpha)
+-            delete [] m_alpha;
+-
+-        m_isvalid = false;
+-        m_yuv = NULL;
+-        m_alpha = NULL;
++        ckey = OSDImageCache::CreateKey(
++            filename, wmult, hmult, scalew, scaleh);
+     }
++    else 
++    {
++        // this method requires a backing file
++        return;
++    }
++  
++    // Get the item from the cache so it's not freed while in use
++    OSDImageCacheValue* value = c_cache.Get(ckey, true);
++  
++    if (value != NULL)
++    {
++        m_yuv       = value->m_yuv;
++        m_ybuffer   = value->m_ybuffer;
++        m_ubuffer   = value->m_ubuffer;
++        m_vbuffer   = value->m_vbuffer;
++        m_alpha     = value->m_alpha;
++        m_imagesize = value->m_imagesize;
++        m_isvalid   = true;
+-    if (filename.length() < 2)
++        // Put the old image back to the cache so it can be reused in the
++        // future, and possibly freed by the cache system if the size limit
++        // is reached
++        if (!m_cacheitem)
++            c_cache.Insert(m_cacheitem);
++        m_cacheitem = value;
++
+         return;
++    }
++   
++    // scaled image was not found in cache, have to create it
++  
+     QImage tmpimage(filename);
+@@ -867,17 +868,32 @@
+                      imwidth, imheight, tmp2.width());
+     m_imagesize = QRect(0, 0, imwidth, imheight);
++
++    // put the old image back to the cache so it can be reused in the
++    // future, and possibly freed by the cache system if the size limit
++    // is reached
++    if (m_cacheitem)
++        c_cache.Insert(m_cacheitem);
++  
++    m_cacheitem = new OSDImageCacheValue(
++        ckey,
++        m_yuv,     m_ybuffer, m_ubuffer,
++        m_vbuffer, m_alpha,   m_imagesize);
++ 
++    // save the new cache item to the file cache
++    if (!filename.isEmpty())
++        c_cache.SaveToDisk(m_cacheitem);
+ }
+ void OSDTypeImage::LoadFromQImage(const QImage &img)
+ {
++    // this method is not cached as it's used mostly for
++    // subtitles which are displayed only once anyways, caching
++    // would probably only slow things down overall
+     if (m_isvalid)
+     {
+-        if (m_yuv)
+-            delete [] m_yuv;
+-        if (m_alpha)
+-            delete [] m_alpha;
+-
++        delete m_cacheitem;
++        m_cacheitem = NULL;
+         m_isvalid = false;
+         m_yuv = NULL;
+         m_alpha = NULL;
+@@ -1043,23 +1059,25 @@
+     m_maxval = 1000;
+     m_curval = 0;
+     m_displayrect = displayrect;
++    m_unbiasedrect =
++        QRect((int)round(m_displayrect.x()      / wmult),
++              (int)round(m_displayrect.y()      / hmult),
++              (int)ceil( m_displayrect.width()  / wmult),
++              (int)ceil( m_displayrect.height() / hmult));
+ }
+ OSDTypePosSlider::~OSDTypePosSlider()
+ {
+ }
+-void OSDTypePosSlider::Reinit(float wchange, float hchange, float wmult,
+-                              float hmult)
++void OSDTypePosSlider::Reinit(float wmult, float hmult)
+ {
+-    int width = (int)(m_displayrect.width() * wchange);
+-    int height = (int)(m_displayrect.height() * hchange);
+-    int x = (int)(m_displayrect.x() * wchange);
+-    int y = (int)(m_displayrect.y() * hchange);
+-
+-    m_displayrect = QRect(x, y, width, height);
+-
+-    OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
++    m_displayrect =
++        QRect((int)round(m_unbiasedrect.x()      * wmult),
++              (int)round(m_unbiasedrect.y()      * hmult),
++              (int)ceil( m_unbiasedrect.width()  * wmult),
++              (int)ceil( m_unbiasedrect.height() * hmult));
++    OSDTypeImage::Reinit(wmult, hmult);
+ }
+ void OSDTypePosSlider::SetPosition(int pos)
+@@ -1092,23 +1110,25 @@
+     m_drawwidth = 0;
+     m_onlyusefirst = true;
+     m_displayrect = displayrect;
++    m_unbiasedrect =
++        QRect((int)round(m_displayrect.x()      / wmult),
++              (int)round(m_displayrect.y()      / hmult),
++              (int)ceil( m_displayrect.width()  / wmult),
++              (int)ceil( m_displayrect.height() / hmult));
+ }
+ OSDTypeFillSlider::~OSDTypeFillSlider()
+ {
+ }
+-void OSDTypeFillSlider::Reinit(float wchange, float hchange, float wmult,
+-                               float hmult)
++void OSDTypeFillSlider::Reinit(float wmult, float hmult)
+ {
+-    int width = (int)(m_displayrect.width() * wchange);
+-    int height = (int)(m_displayrect.height() * hchange);
+-    int x = (int)(m_displayrect.x() * wchange);
+-    int y = (int)(m_displayrect.y() * hchange);
+-
+-    m_displayrect = QRect(x, y, width, height);
+-
+-    OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
++    m_displayrect =
++        QRect((int)round(m_unbiasedrect.x()      * wmult),
++              (int)round(m_unbiasedrect.y()      * hmult),
++              (int)ceil( m_unbiasedrect.width()  * wmult),
++              (int)ceil( m_unbiasedrect.height() * hmult));
++    OSDTypeImage::Reinit(wmult, hmult);
+ }
+ void OSDTypeFillSlider::SetPosition(int pos)
+@@ -1143,6 +1163,11 @@
+     m_maxval = 1000;
+     m_curval = 0;
+     m_displayrect = displayrect;
++    m_unbiasedrect =
++        QRect((int)round(m_displayrect.x()      / wmult),
++              (int)round(m_displayrect.y()      / hmult),
++              (int)ceil( m_displayrect.width()  / wmult),
++              (int)ceil( m_displayrect.height() / hmult));
+     m_drawwidth = displayrect.width();
+     m_drawMap = new unsigned char[m_drawwidth + 1];
+@@ -1162,6 +1187,7 @@
+     m_scalew = scalew;
+     m_scaleh = scaleh;
++    m_cacheitem = NULL;
+     LoadImage(m_redname, wmult, hmult, scalew, scaleh);
+     if (m_isvalid)
+@@ -1184,22 +1210,16 @@
+ OSDTypeEditSlider::~OSDTypeEditSlider()
+ {
+     delete [] m_drawMap;
+-
+-    if (m_ryuv)
+-        delete [] m_ryuv;
+-    if (m_ralpha)
+-        delete [] m_ralpha;
+ }
+-void OSDTypeEditSlider::Reinit(float wchange, float hchange, float wmult,
+-                               float hmult)
++void OSDTypeEditSlider::Reinit(float wmult, float hmult)
+ {
+-    int width = (int)(m_displayrect.width() * wchange);
+-    int height = (int)(m_displayrect.height() * hchange);
+-    int x = (int)(m_displayrect.x() * wchange);
+-    int y = (int)(m_displayrect.y() * hchange);
++    m_displayrect =
++        QRect((int)round(m_unbiasedrect.x()      * wmult),
++              (int)round(m_unbiasedrect.y()      * hmult),
++              (int)ceil( m_unbiasedrect.width()  * wmult),
++              (int)ceil( m_unbiasedrect.height() * hmult));
+-    m_displayrect = QRect(x, y, width, height);
+     m_drawwidth = m_displayrect.width();
+     delete [] m_drawMap;
+@@ -1210,11 +1230,6 @@
+     m_displaypos = m_displayrect.topLeft();
+-    if (m_ryuv)
+-        delete [] m_ryuv;
+-    if (m_ralpha)
+-        delete [] m_ralpha;
+-
+     LoadImage(m_redname, wmult, hmult, m_scalew, m_scaleh);
+     if (m_isvalid)
+     {
+@@ -1360,30 +1375,46 @@
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect) 
+-          : OSDType(name)
++OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect,
++                       float wmult, float hmult)
++    : OSDType(name)
+ {
+     size = displayrect;
++    m_unbiasedsize =
++        QRect((int)round(size.x()      / wmult),
++              (int)round(size.y()      / hmult),
++              (int)ceil( size.width()  / wmult),
++              (int)ceil( size.height() / hmult));
+ }
++void OSDTypeBox::SetRect(QRect newrect, float wmult, float hmult)
++{
++    size = newrect;
++    m_unbiasedsize =
++        QRect((int)round(size.x()      / wmult),
++              (int)round(size.y()      / hmult),
++              (int)ceil( size.width()  / wmult),
++              (int)ceil( size.height() / hmult));
++}
++
+ OSDTypeBox::OSDTypeBox(const OSDTypeBox &other)
+           : OSDType(other.m_name)
+ {
+     size = other.size;
++    m_unbiasedsize = other.m_unbiasedsize;
+ }
+ OSDTypeBox::~OSDTypeBox()
+ {
+ }
+-void OSDTypeBox::Reinit(float wchange, float hchange)
++void OSDTypeBox::Reinit(float wmult, float hmult)
+ {
+-    int width = (int)(size.width() * wchange);
+-    int height = (int)(size.height() * hchange);
+-    int x = (int)(size.x() * wchange);
+-    int y = (int)(size.y() * hchange);
+-
+-    size = QRect(x, y, width, height);
++    size =
++        QRect((int)round(m_unbiasedsize.x()      * wmult),
++              (int)round(m_unbiasedsize.y()      * hmult),
++              (int)ceil( m_unbiasedsize.width()  * wmult),
++              (int)ceil( m_unbiasedsize.height() * hmult));
+ }
+ void OSDTypeBox::Draw(OSDSurface *surface, int fade, int maxfade, int xoff, 
+@@ -1498,44 +1529,52 @@
+ }       
+    
+ OSDTypePositionRectangle::OSDTypePositionRectangle(
+-                                        const OSDTypePositionRectangle &other) 
+-                        : OSDType(other.m_name), OSDTypePositionIndicator(other)
++    const OSDTypePositionRectangle &other) 
++    : OSDType(other.m_name), OSDTypePositionIndicator(other)
+ {
+     for (int i = 0; i < m_numpositions; i++)
+     {
+         QRect tmp = other.positions[i];
+         positions.push_back(tmp);
+     }
++    for (int i = 0; i < m_numpositions; i++)
++    {
++        QRect tmp = other.unbiasedpos[i];
++        unbiasedpos.push_back(tmp);
++    }
+ }
+ OSDTypePositionRectangle::~OSDTypePositionRectangle()
+ {
+ }
+-void OSDTypePositionRectangle::Reinit(float wchange, float hchange)
++void OSDTypePositionRectangle::Reinit(float wmult, float hmult)
+ {
+     for (int i = 0; i < m_numpositions; i++)
+     {
+-        QRect tmp = positions[i];
+-
+-        int width = (int)(tmp.width() * wchange);
+-        int height = (int)(tmp.height() * hchange);
+-        int x = (int)(tmp.x() * wchange);
+-        int y = (int)(tmp.y() * hchange);
+-
+-        tmp = QRect(x, y, width, height);
+-        positions[i] = tmp;
++        QRect tmp = unbiasedpos[i];
++        positions[i] =
++            QRect((int)round(tmp.x()      * wmult),
++                  (int)round(tmp.y()      * hmult),
++                  (int)ceil( tmp.width()  * wmult),
++                  (int)ceil( tmp.height() * hmult));
+     }
+ }
+-void OSDTypePositionRectangle::AddPosition(QRect rect)
++void OSDTypePositionRectangle::AddPosition(
++    QRect rect, float wmult, float hmult)
+ {
+     positions.push_back(rect);
++    unbiasedpos.push_back(
++        QRect((int)round(rect.x()      / wmult),
++              (int)round(rect.y()      / hmult),
++              (int)ceil( rect.width()  / wmult),
++              (int)ceil( rect.height() / hmult)));
+     m_numpositions++;
+ }
+-void OSDTypePositionRectangle::Draw(OSDSurface *surface, int fade, int maxfade, 
+-                                    int xoff, int yoff)
++void OSDTypePositionRectangle::Draw(
++    OSDSurface *surface, int fade, int maxfade, int xoff, int yoff)
+ {
+     fade = fade;
+     maxfade = maxfade;
+@@ -1618,17 +1657,21 @@
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ OSDTypePositionImage::OSDTypePositionImage(const QString &name)
+-                    : OSDTypeImage(name), OSDTypePositionIndicator()
++    : OSDTypeImage(name), OSDTypePositionIndicator(),
++      m_wmult(0.0f), m_hmult(0.0f)
+ {
+ }
+ OSDTypePositionImage::OSDTypePositionImage(const OSDTypePositionImage &other)
+                     : OSDTypeImage(other), OSDTypePositionIndicator(other)
+ {
++    m_wmult = other.m_wmult;
++    m_hmult = other.m_hmult;
++
+     for (int i = 0; i < m_numpositions; i++)
+     {
+-        QPoint tmp = other.positions[i];
+-        positions.push_back(tmp);
++        positions.push_back(other.positions[i]);
++        unbiasedpos.push_back(other.unbiasedpos[i]);
+     }
+ }
+@@ -1636,45 +1679,61 @@
+ {
+ }
+-void OSDTypePositionImage::Reinit(float wchange, float hchange, float wmult, 
+-                                  float hmult)
++void OSDTypePositionImage::Reinit(float wmult, float hmult)
+ {
+-    OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
++    m_wmult = wmult;
++    m_hmult = hmult;
++    
++    OSDTypeImage::Reinit(wmult, hmult);
+     for (int i = 0; i < m_numpositions; i++)
+     {
+-        QPoint tmp = positions[i];
+-
+-        int x = (int)(tmp.x() * wchange);
+-        int y = (int)(tmp.y() * hchange);
+-
+-        positions[i].setX(x);
+-        positions[i].setY(y);
++        positions[i] =
++            QPoint((int)round(unbiasedpos[i].x() * wmult),
++                   (int)round(unbiasedpos[i].y() * hmult));
+     }
+ }
+-void OSDTypePositionImage::AddPosition(QPoint pos)
++void OSDTypePositionImage::AddPosition(QPoint pos, float wmult, float hmult)
+ {
++    if (m_wmult == 0.0f || m_hmult == 0.0f)
++    {
++        m_wmult = wmult;
++        m_hmult = hmult;
++    }
+     positions.push_back(pos);
++    unbiasedpos.push_back(
++        QPoint((int)round(pos.x() / wmult),
++               (int)round(pos.y() / hmult)));
++
++    VERBOSE(VB_IMPORTANT,
++            "OSDTypePositionImage::AddPosition["<<m_numpositions<<"]("
++            <<pos.x()<<"x"<<pos.y()
++            <<"  "<<wmult<<", "<<hmult<<")");
++
+     m_numpositions++;
+ }
+ void OSDTypePositionImage::Draw(OSDSurface *surface, int fade, int maxfade,
+                                 int xoff, int yoff)
+ {
++    VERBOSE(VB_IMPORTANT,
++            "OSDTypePositionImage::Draw["<<m_curposition<<"]("
++            <<m_wmult<<", "<<m_hmult<<")");
++
+     if (m_curposition < 0 || m_curposition >= m_numpositions)
+         return;
+     QPoint pos = positions[m_curposition];
+-    OSDTypeImage::SetPosition(pos);
++    OSDTypeImage::SetPosition(pos, m_wmult, m_hmult);
+     OSDTypeImage::Draw(surface, fade, maxfade, xoff, yoff);
+ }
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ OSDTypeCC::OSDTypeCC(const QString &name, TTFFont *font, int xoff, int yoff,
+-                     int dispw, int disph)
++                     int dispw, int disph, float wmult, float hmult)
+          : OSDType(name)
+ {
+     m_font = font;
+@@ -1683,9 +1742,11 @@
+     yoffset = yoff;
+     displaywidth = dispw;
+     displayheight = disph;
++    m_wmult = wmult;
++    m_hmult = hmult;
+     QRect rect = QRect(0, 0, 0, 0);
+-    m_box = new OSDTypeBox("cc_background", rect);
++    m_box = new OSDTypeBox("cc_background", rect, wmult, hmult);
+     m_ccbackground = gContext->GetNumSetting("CCBackground", 0);
+ }
+@@ -1695,12 +1756,23 @@
+     delete m_box;
+ }
+-void OSDTypeCC::Reinit(int x, int y, int dispw, int disph)
++void OSDTypeCC::Reinit(float wmult, float hmult)
+ {
++    (void) wmult;
++    (void) hmult;
++    VERBOSE(VB_IMPORTANT, "Programmer error: "
++            "Call to OSDTypeCC::Reinit(float,float)");
++}
++
++void OSDTypeCC::Reinit(int x, int y, int dispw, int disph,
++                       float wmult, float hmult)
++{
+     xoffset = x;
+     yoffset = y;
+     displaywidth = dispw;
+     displayheight = disph;
++    m_wmult = wmult;
++    m_hmult = hmult;    
+ }
+ void OSDTypeCC::AddCCText(const QString &text, int x, int y, int color, 
+@@ -1875,7 +1947,7 @@
+             {
+                 QRect rect = QRect(0, 0, textlength + 4, 
+                                    (m_font->Size() * 3 / 2) + 3);
+-                m_box->SetRect(rect);
++                m_box->SetRect(rect, m_wmult, m_hmult);
+                 m_box->Draw(surface, 0, 0, x - 2, y - 2);
+             }
+Index: mythtv/libs/libmythtv/tv_play.cpp
+===================================================================
+--- mythtv/libs/libmythtv/tv_play.cpp  (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/tv_play.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -247,7 +247,7 @@
+       browsechannum(""), browsechanid(""), browsestarttime(""),
+       // Program Info for currently playing video
+       recorderPlaybackInfo(NULL),
+-      playbackinfo(NULL), inputFilename(""), playbackLen(0),
++      playbackinfo(NULL), playbackLen(0),
+       lastProgram(NULL), jumpToProgram(false),
+       // Video Players
+       nvp(NULL), pipnvp(NULL), activenvp(NULL),
+@@ -578,19 +578,7 @@
+     if (!testrec->IsValidRecorder())
+     {
+         if (showDialogs)
+-        {
+-            QString title = tr("MythTV is already using all available "
+-                               "inputs for recording.  If you want to "
+-                               "watch an in-progress recording, select one "
+-                               "from the playback menu.  If you want to "
+-                               "watch live TV, cancel one of the "
+-                               "in-progress recordings from the delete "
+-                               "menu.");
+-            
+-            DialogBox diag(gContext->GetMainWindow(), title);
+-            diag.AddButton(tr("Cancel and go back to the TV menu"));
+-            diag.exec();
+-        }        
++            ShowNoRecorderDialog();
+         
+         delete testrec;
+         
+@@ -659,8 +647,6 @@
+     if (internalState != kState_None)
+         return 0;
+-    inputFilename = rcinfo->pathname;
+-
+     playbackLen = rcinfo->CalculateLength();
+     playbackinfo = new ProgramInfo(*rcinfo);
+@@ -844,9 +830,10 @@
+         }
+         else
+         {
++            QString playbackURL = playbackinfo->GetPlaybackURL();
++
+             tvchain->SetProgram(playbackinfo);
+-
+-            prbuffer = new RingBuffer(playbackinfo->pathname, false);
++            prbuffer = new RingBuffer(playbackURL, false);
+             prbuffer->SetLiveMode(tvchain);
+         }
+@@ -895,7 +882,14 @@
+     else if (TRANSITION(kState_None, kState_WatchingPreRecorded) ||
+              TRANSITION(kState_None, kState_WatchingRecording))
+     {
+-        prbuffer = new RingBuffer(inputFilename, false);
++        QString playbackURL;
++        if ((playbackinfo->pathname.left(4) == "dvd:") ||
++            (playbackinfo->isVideo))
++            playbackURL = playbackinfo->pathname;
++        else
++            playbackURL = playbackinfo->GetPlaybackURL();
++
++        prbuffer = new RingBuffer(playbackURL, false);
+         if (prbuffer->IsOpen())
+         {
+             gContext->DisableScreensaver();
+@@ -924,7 +918,7 @@
+             {
+                 QString message = "COMMFLAG_REQUEST ";
+                 message += playbackinfo->chanid + " " +
+-                           playbackinfo->startts.toString(Qt::ISODate);
++                           playbackinfo->recstartts.toString(Qt::ISODate);
+                 RemoteSendMessage(message);
+             }                
+         }
+@@ -1222,10 +1216,10 @@
+     nvp->SetParentPlayer(this);
+     nvp->SetRingBuffer(prbuffer);
+     nvp->SetRecorder(recorder);
+-    nvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate"));
++    nvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate", 44100));
+     nvp->SetAudioDevice(gContext->GetSetting("AudioOutputDevice"));
+     nvp->SetLength(playbackLen);
+-    nvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking"));
++    nvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking", 0));
+     nvp->SetAutoCommercialSkip(autoCommercialSkip);
+     nvp->SetLiveTVChain(tvchain);
+@@ -1296,9 +1290,9 @@
+     pipnvp->SetAsPIP();
+     pipnvp->SetRingBuffer(piprbuffer);
+     pipnvp->SetRecorder(piprecorder);
+-    pipnvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate"));
++    pipnvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate", 44100));
+     pipnvp->SetAudioDevice(gContext->GetSetting("AudioOutputDevice"));
+-    pipnvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking"));
++    pipnvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking", 0));
+     pipnvp->SetLiveTVChain(piptvchain);
+     pipnvp->SetLength(playbackLen);
+@@ -1454,6 +1448,30 @@
+                 lastSignalMsg.clear();
+             }
+             UpdateOSDTimeoutMessage();
++
++            if (!tvchainUpdate.isEmpty())
++            {
++                tvchainUpdateLock.lock();
++                for (QStringList::Iterator it = tvchainUpdate.begin();
++                     it != tvchainUpdate.end(); ++it)
++                {
++                    if (tvchain && nvp && *it == tvchain->GetID())
++                    {
++                        tvchain->ReloadAll();
++                        if (nvp->GetTVChain())
++                            nvp->CheckTVChain();
++                    }
++                    if (piptvchain && pipnvp && *it == piptvchain->GetID())
++                    {
++                        piptvchain->ReloadAll();
++                        if (pipnvp->GetTVChain())
++                            pipnvp->CheckTVChain();
++                    }
++                }
++                tvchainUpdate.clear();
++                tvchainUpdateLock.unlock();
++            }
++
+             osdlock.unlock();
+         }
+@@ -2743,7 +2761,7 @@
+                 speedStr = QString("%1X").arg(normal_speed);
+             struct StatusPosInfo posInfo;
+-            nvp->calcSliderPos(posInfo);
++            nvp->calcSliderPos(posInfo, true);
+             QDateTime respDate = mythCurrentDateTime();
+             QString infoStr = "";
+@@ -2806,8 +2824,10 @@
+         }
+         else
+         {
++            QString playbackURL = playbackinfo->GetPlaybackURL();
++
+             piptvchain->SetProgram(playbackinfo);
+-            piprbuffer = new RingBuffer(playbackinfo->pathname, false);
++            piprbuffer = new RingBuffer(playbackURL, false);
+             piprbuffer->SetLiveMode(piptvchain);
+         }
+@@ -3472,8 +3492,10 @@
+         }
+         else
+         {
++            QString playbackURL = playbackinfo->GetPlaybackURL();
++
+             tvchain->SetProgram(playbackinfo);
+-            prbuffer = new RingBuffer(playbackinfo->pathname, false);
++            prbuffer = new RingBuffer(playbackURL, false);
+             prbuffer->SetLiveMode(tvchain);
+         }
+@@ -4627,7 +4649,8 @@
+     normal_speed = new_normal_speed;
+-    activenvp->Play(normal_speed, true);
++    if (!paused)
++        activenvp->Play(normal_speed, true);
+     QString text = QString(tr("Time Stretch %1X")).arg(normal_speed);
+@@ -4911,29 +4934,14 @@
+         }
+         else if (tvchain && message.left(12) == "LIVETV_CHAIN")
+         {
+-            // Get osdlock, while intended for the OSD this ensures that
+-            // the nvp & pipnvp are not deleted while we are using it..
+-            while (!osdlock.tryLock() && nvp)
+-                usleep(2500);
+-
+             message = message.simplifyWhiteSpace();
+             QStringList tokens = QStringList::split(" ", message);
+             if (tokens[1] == "UPDATE")
+             {
+-                if (tvchain && nvp && tokens[2] == tvchain->GetID())
+-                {
+-                    tvchain->ReloadAll();
+-                    if (nvp->GetTVChain())
+-                        nvp->CheckTVChain();
+-                }
+-                if (piptvchain && pipnvp && tokens[2] == piptvchain->GetID())
+-                {
+-                    piptvchain->ReloadAll();
+-                    if (pipnvp->GetTVChain())
+-                        pipnvp->CheckTVChain();
+-                }
++                tvchainUpdateLock.lock();
++                tvchainUpdate += QDeepCopy<QString>(tokens[2]);
++                tvchainUpdateLock.unlock();
+             }
+-            osdlock.unlock();
+         }
+         else if (nvp && message.left(12) == "EXIT_TO_MENU")
+         {
+@@ -4983,7 +4991,7 @@
+             QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
+             if ((playbackinfo->chanid == evchanid) &&
+-                (playbackinfo->startts == evstartts))
++                (playbackinfo->recstartts == evstartts))
+             {
+                 QString msg = "COMMFLAG_REQUEST ";
+                 msg += tokens[1] + " " + tokens[2];
+@@ -5000,7 +5008,7 @@
+             QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
+             if ((playbackinfo->chanid == evchanid) &&
+-                (playbackinfo->startts == evstartts))
++                (playbackinfo->recstartts == evstartts))
+             {
+                 QMap<long long, int> newMap;
+                 QStringList mark;
+@@ -6067,9 +6075,22 @@
+                            "in-progress recordings from the delete "
+                            "menu.");
+-    MythPopupBox::showOkPopup(
++    if (embedWinID)
++    {
++        VERBOSE(VB_IMPORTANT, errorText);
++    }
++    else if (GetOSD())
++    {
++        dialogname = "infobox";
++        QStringList options("OK");
++        GetOSD()->NewDialogBox(dialogname, errorText, options, 0);
++    }
++    else
++    {
++        MythPopupBox::showOkPopup(
+             gContext->GetMainWindow(), QObject::tr("Channel Change Error"),
+             errorText);
++    }
+ }
+ /** \fn TV::PauseLiveTV(void)
+Index: mythtv/libs/libmythtv/jobqueue.cpp
+===================================================================
+--- mythtv/libs/libmythtv/jobqueue.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/jobqueue.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -275,6 +275,11 @@
+                     (hostname != "") &&
+                     (hostname != m_hostname))
+                 {
++                    // Setting the status here will prevent us from processing
++                    // any other jobs for this recording until this one is
++                    // completed on the remote host.
++                    jobStatus[key] = status;
++
+                     message = QString("JobQueue: Skipping '%1' job for chanid "
+                                       "%2 @ %3, should run on '%4' instead")
+                                       .arg(JobText(type))
+Index: mythtv/libs/libmythtv/dvbdev/dvbdev.c
+===================================================================
+--- mythtv/libs/libmythtv/dvbdev/dvbdev.c      (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/dvbdev/dvbdev.c      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -29,55 +29,79 @@
+ const char* dvbdevice(int type, int cardnum)
+ {
+-    char* frontenddev[4] =
++    char* frontenddev[8] =
+     {
+         "/dev/dvb/adapter0/frontend0",
+         "/dev/dvb/adapter1/frontend0",
+         "/dev/dvb/adapter2/frontend0",
+-        "/dev/dvb/adapter3/frontend0"
++        "/dev/dvb/adapter3/frontend0",
++        "/dev/dvb/adapter4/frontend0",
++        "/dev/dvb/adapter5/frontend0",
++        "/dev/dvb/adapter6/frontend0",
++        "/dev/dvb/adapter7/frontend0",
+     };
+-    char* dvrdev[4] =
++    char* dvrdev[8] =
+     {
+         "/dev/dvb/adapter0/dvr0",
+         "/dev/dvb/adapter1/dvr0",
+         "/dev/dvb/adapter2/dvr0",
+-        "/dev/dvb/adapter3/dvr0"
++        "/dev/dvb/adapter3/dvr0",
++        "/dev/dvb/adapter4/dvr0",
++        "/dev/dvb/adapter5/dvr0",
++        "/dev/dvb/adapter6/dvr0",
++        "/dev/dvb/adapter7/dvr0",
+     };
+-    char* demuxdev[4] =
++    char* demuxdev[8] =
+     {
+         "/dev/dvb/adapter0/demux0",
+         "/dev/dvb/adapter1/demux0",
+         "/dev/dvb/adapter2/demux0",
+-        "/dev/dvb/adapter3/demux0"
++        "/dev/dvb/adapter3/demux0",
++        "/dev/dvb/adapter4/demux0",
++        "/dev/dvb/adapter5/demux0",
++        "/dev/dvb/adapter6/demux0",
++        "/dev/dvb/adapter7/demux0",
+     };
+-    char* cadev[4] =
++    char* cadev[8] =
+     {
+         "/dev/dvb/adapter0/ca0",
+         "/dev/dvb/adapter1/ca0",
+         "/dev/dvb/adapter2/ca0",
+-        "/dev/dvb/adapter3/ca0"
++        "/dev/dvb/adapter3/ca0",
++        "/dev/dvb/adapter4/ca0",
++        "/dev/dvb/adapter5/ca0",
++        "/dev/dvb/adapter6/ca0",
++        "/dev/dvb/adapter7/ca0",
+     };
+-    char* audiodev[4] =
++    char* audiodev[8] =
+     {
+         "/dev/dvb/adapter0/audio0",
+         "/dev/dvb/adapter1/audio0",
+         "/dev/dvb/adapter2/audio0",
+-        "/dev/dvb/adapter3/audio0"
++        "/dev/dvb/adapter3/audio0",
++        "/dev/dvb/adapter4/audio0",
++        "/dev/dvb/adapter5/audio0",
++        "/dev/dvb/adapter6/audio0",
++        "/dev/dvb/adapter7/audio0",
+     };
+-    char* videodev[4] =
++    char* videodev[8] =
+     {
+         "/dev/dvb/adapter0/video0",
+         "/dev/dvb/adapter1/video0",
+         "/dev/dvb/adapter2/video0",
+-        "/dev/dvb/adapter3/video0"
++        "/dev/dvb/adapter3/video0",
++        "/dev/dvb/adapter4/video0",
++        "/dev/dvb/adapter5/video0",
++        "/dev/dvb/adapter6/video0",
++        "/dev/dvb/adapter7/video0",
+     };
+-    if (cardnum > 3)
++    if (cardnum > 7)
+         return 0;
+     switch(type)
+Index: mythtv/libs/libmythtv/libmythtv.pro
+===================================================================
+--- mythtv/libs/libmythtv/libmythtv.pro        (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/libmythtv.pro        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -144,10 +144,10 @@
+     # On screen display (video output overlay)
+     HEADERS += osd.h                    osdtypes.h
+     HEADERS += osdsurface.h             osdlistbtntype.h
+-    HEADERS += udpnotify.h 
++    HEADERS += osdimagecache.h          udpnotify.h 
+     SOURCES += osd.cpp                  osdtypes.cpp
+     SOURCES += osdsurface.cpp           osdlistbtntype.cpp
+-    SOURCES += udpnotify.cpp 
++    SOURCES += osdimagecache.cpp        udpnotify.cpp 
+     # Video output
+     HEADERS += videooutbase.h           videoout_null.h
+Index: mythtv/libs/libmythtv/osdtypes.h
+===================================================================
+--- mythtv/libs/libmythtv/osdtypes.h   (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/osdtypes.h   (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -8,6 +8,7 @@
+ #include <vector>
+ #include <qobject.h>
+ #include <qregexp.h>
++#include "osdimagecache.h"
+ using namespace std;
+@@ -137,6 +138,8 @@
+     QString Name() { return m_name; }
++    virtual void Reinit(float wmult, float hmult) = 0;
++
+     virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
+                       int yoff) = 0;
+@@ -150,11 +153,11 @@
+ {
+   public:
+     OSDTypeText(const QString &name, TTFFont *font, const QString &text,
+-                QRect displayrect);
++                QRect displayrect, float wmult, float hmult);
+     OSDTypeText(const OSDTypeText &text);
+    ~OSDTypeText();
+-    void Reinit(float wchange, float hchange);
++    void Reinit(float wmult, float hmult);
+     void SetAltFont(TTFFont *font);
+     void SetUseAlt(bool usealt) { m_usingalt = usealt; }
+@@ -190,6 +193,7 @@
+     QRect m_displaysize;
+     QRect m_screensize;
++    QRect m_unbiasedsize;
+     QString m_message;
+     QString m_default_msg;
+@@ -231,7 +235,7 @@
+     virtual ~OSDTypeImage();
+     void SetName(const QString &name);
+-    void Reinit(float wchange, float hchange, float wmult, float hmult);
++    void Reinit(float wmult, float hmult);
+     void LoadImage(const QString &filename, float wmult, float hmult, 
+                    int scalew = -1, int scaleh = -1);
+@@ -239,21 +243,20 @@
+     void SetStaticSize(int scalew, int scaleh) { m_scalew = scalew;
+                                                  m_scaleh = scaleh; }
++    void SetPosition(QPoint pos, float wmult, float hmult);
+-    QPoint DisplayPos() { return m_displaypos; }
+-    void SetPosition(QPoint pos) { m_displaypos = pos; }
++    QPoint DisplayPos() const { return m_displaypos;         }
++    QRect  ImageSize()  const { return m_imagesize;          }
++    int    width()      const { return m_imagesize.width();  }
++    int    height()     const { return m_imagesize.height(); }
+-    QRect ImageSize() { return m_imagesize; }
+-
+-    int width() { return m_imagesize.width(); }
+-    int height() { return m_imagesize.height(); }
+-
+     virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, 
+                       int yoff);
+   protected:
+     QRect m_imagesize;
+     QPoint m_displaypos;
++    QPoint m_unbiasedpos;
+     QString m_filename;
+@@ -270,6 +273,9 @@
+     int m_drawwidth;
+     bool m_onlyusefirst;
++
++    static OSDImageCache  c_cache;
++    OSDImageCacheValue   *m_cacheitem;
+ };
+ class OSDTypePosSlider : public OSDTypeImage
+@@ -280,7 +286,7 @@
+                       int scalew = -1, int scaleh = -1);
+    ~OSDTypePosSlider();
+-    void Reinit(float wchange, float hchange, float wmult, float hmult);
++    void Reinit(float wmult, float hmult);
+     void SetRectangle(QRect rect) { m_displayrect = rect; }
+     QRect ImageSize() { return m_imagesize; }
+@@ -290,6 +296,7 @@
+   private:
+     QRect m_displayrect;
++    QRect m_unbiasedrect;
+     int m_maxval;
+     int m_curval;
+ };
+@@ -302,7 +309,7 @@
+                       int scalew = -1, int scaleh = -1);
+    ~OSDTypeFillSlider();
+-    void Reinit(float wchange, float hchange, float wmult, float hmult);
++    void Reinit(float wmult, float hmult);
+     void SetRectangle(QRect rect) { m_displayrect = rect; }
+     QRect ImageSize() { return m_imagesize; }
+@@ -314,6 +321,7 @@
+   private:
+     QRect m_displayrect;
++    QRect m_unbiasedrect;
+     int m_maxval;
+     int m_curval;
+ };
+@@ -327,7 +335,7 @@
+                       int scalew = -1, int scaleh = -1);
+    ~OSDTypeEditSlider();
+-    void Reinit(float wchange, float hchange, float wmult, float hmult);
++    void Reinit(float wmult, float hmult);
+     void SetRectangle(QRect rect) { m_displayrect = rect; }
+     QRect ImageSize() { return m_imagesize; }
+@@ -339,6 +347,7 @@
+   private:
+     QRect m_displayrect;
++    QRect m_unbiasedrect;
+     int m_maxval;
+     int m_curval;
+@@ -360,17 +369,19 @@
+ class OSDTypeBox : public OSDType
+ {
+   public:
+-    OSDTypeBox(const QString &name, QRect displayrect); 
++    OSDTypeBox(const QString &name, QRect displayrect,
++               float wmult, float hmult);
+     OSDTypeBox(const OSDTypeBox &other);
+    ~OSDTypeBox();
+-    void Reinit(float wchange, float hchange);
+-    void SetRect(QRect newrect) { size = newrect; }
++    void Reinit(float wmult, float hmult);
++    void SetRect(QRect newrect, float wmult, float hmult);
+     void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
+   private:
+     QRect size;
++    QRect m_unbiasedsize;
+ };
+ class OSDTypePositionIndicator
+@@ -403,14 +414,15 @@
+     OSDTypePositionRectangle(const OSDTypePositionRectangle &other);
+    ~OSDTypePositionRectangle();
+-    void AddPosition(QRect rect);
++    void AddPosition(QRect rect, float wmult, float hmult);
+-    void Reinit(float wchange, float hchange);
++    void Reinit(float wmult, float hmult);
+     void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
+   private:
+-    vector<QRect> positions; 
++    vector<QRect> positions;
++    vector<QRect> unbiasedpos;
+ };
+ class OSDTypePositionImage : public virtual OSDTypeImage, 
+@@ -421,14 +433,17 @@
+     OSDTypePositionImage(const OSDTypePositionImage &other);
+    ~OSDTypePositionImage();
+-    void Reinit(float wchange, float hchange, float wmult, float hmult);
++    void Reinit(float wmult, float hmult);
+-    void AddPosition(QPoint pos);
++    void AddPosition(QPoint pos, float wmult, float hmult);
+     void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
+   private:
+     vector<QPoint> positions;
++    vector<QPoint> unbiasedpos;
++    float m_wmult;
++    float m_hmult;
+ };
+ class ccText
+@@ -445,11 +460,15 @@
+ {
+   public:
+     OSDTypeCC(const QString &name, TTFFont *font, int xoff, int yoff,
+-              int dispw, int disph);
++              int dispw, int disph, float wmult, float hmult);
+    ~OSDTypeCC();
+-    void Reinit(int xoff, int yoff, int dispw, int disph);
++    void Reinit(float wmult, float hmult);
++    void Reinit(int xoff, int yoff,
++                int dispw, int disph,
++                float wmult, float hmult);
++
+     void AddCCText(const QString &text, int x, int y, int color, 
+                    bool teletextmode = false);
+     void ClearAllCCText();
+@@ -464,7 +483,7 @@
+     vector<ccText *> *m_textlist;
+     OSDTypeBox *m_box;
+     int m_ccbackground;
+-
++    float m_wmult, m_hmult;
+     int xoffset, yoffset, displaywidth, displayheight;
+ };
+Index: mythtv/libs/libmythtv/osdimagecache.h
+===================================================================
+--- mythtv/libs/libmythtv/osdimagecache.h      (.../tags/release-0-19) (revision 0)
++++ mythtv/libs/libmythtv/osdimagecache.h      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -0,0 +1,74 @@
++// -*- Mode: c++ -*-
++
++// POSIX headers
++#include <stdint.h>
++
++// Qt headers
++#include <qmap.h>
++#include <qrect.h>
++#include <qmutex.h>
++#include <qstring.h>
++#include <qasciicache.h>
++
++class OSDImageCacheValue
++{
++  public:
++    OSDImageCacheValue(QString cacheKey,
++                     unsigned char *yuv,     unsigned char *ybuffer,
++                       unsigned char *ubuffer, unsigned char *vbuffer,
++                       unsigned char *alpha,   QRect imagesize);
++
++    virtual ~OSDImageCacheValue();
++
++    uint    GetSize(void) const { return m_size_in_bytes; }
++    QString GetKey(void)  const { return m_cacheKey;      }
++
++  public:
++    unsigned char *m_yuv;
++    unsigned char *m_ybuffer;
++    unsigned char *m_ubuffer;
++    unsigned char *m_vbuffer;
++    unsigned char *m_alpha;
++    QRect          m_imagesize;
++
++  private:
++    uint           m_size_in_bytes;
++    QString        m_cacheKey;
++};
++
++typedef QAsciiCache<OSDImageCacheValue> img_cache_t;
++
++class OSDImageCache
++{
++  public:
++    OSDImageCache();
++    virtual ~OSDImageCache();
++
++    bool InFileCache(const QString &key) const;
++
++    bool Contains(const QString &key, bool useFile) const;
++
++    OSDImageCacheValue *Get(const QString &key, bool useFile);
++
++    void Insert(OSDImageCacheValue* value);
++
++    void SaveToDisk(const OSDImageCacheValue *value);
++
++    void Reset(void);
++
++    static QString CreateKey(const QString &filename,
++                             float wmult, float hmult,
++                             int scalew,  int scaleh);
++
++    static QString ExtractOriginal(const QString &key);
++
++  private:
++    mutable QMutex m_cacheLock;
++    img_cache_t    m_imageCache;
++    int            m_memHits;
++    int            m_diskHits;
++    int            m_misses;
++
++    /// Limit on the maximum total size of OSD images cached in *memory*.
++    static uint    kMaximumMemoryCacheSize;
++};
+Index: mythtv/libs/libmythtv/tv_play.h
+===================================================================
+--- mythtv/libs/libmythtv/tv_play.h    (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/tv_play.h    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -456,7 +456,6 @@
+     ProgramInfo *recorderPlaybackInfo; ///< info requested from recorder
+     ProgramInfo *playbackinfo;  ///< info sent in via Playback()
+     QMutex       pbinfoLock;
+-    QString      inputFilename; ///< playbackinfo->pathname
+     int          playbackLen;   ///< initial playbackinfo->CalculateLength()
+     ProgramInfo *lastProgram;   ///< last program played with this player
+     bool         jumpToProgram;
+@@ -485,6 +484,8 @@
+     // LiveTVChain
+     LiveTVChain *tvchain;
+     LiveTVChain *piptvchain;
++    QStringList tvchainUpdate;
++    QMutex tvchainUpdateLock;
+     // RingBuffers
+     RingBuffer *prbuffer;
+Index: mythtv/libs/libmythtv/videosource.cpp
+===================================================================
+--- mythtv/libs/libmythtv/videosource.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/videosource.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -32,6 +32,7 @@
+ #include "videosource.h"
+ #include "datadirect.h"
+ #include "scanwizard.h"
++#include "frequencies.h"
+ #ifdef USING_DVB
+ #include <linux/dvb/frontend.h>
+@@ -574,22 +575,10 @@
+ {
+     setLabel(QObject::tr("Channel frequency table"));
+     addSelection("default");
+-    addSelection("us-cable");
+-    addSelection("us-bcast");
+-    addSelection("us-cable-hrc");
+-    addSelection("japan-bcast");
+-    addSelection("japan-cable");
+-    addSelection("europe-west");
+-    addSelection("europe-east");
+-    addSelection("italy");
+-    addSelection("newzealand");
+-    addSelection("australia");
+-    addSelection("ireland");
+-    addSelection("france");
+-    addSelection("china-bcast");
+-    addSelection("southafrica");
+-    addSelection("argentina");
+-    addSelection("australia-optus");
++
++    for (uint i = 0; chanlists[i].name; i++)
++        addSelection(chanlists[i].name);
++
+     setHelpText(QObject::tr("Use default unless this source uses a "
+                 "different frequency table than the system wide table "
+                 "defined in the General settings."));
+Index: mythtv/libs/libmythtv/frequencytables.cpp
+===================================================================
+--- mythtv/libs/libmythtv/frequencytables.cpp  (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/frequencytables.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -283,104 +283,52 @@
+         "ATSC Channel %1", 70, 809000000, 887000000, 6000000, VSB_8);
+ #endif // USING_DVB
+-    // USA Cable, QAM 256
+-    fmap["atsc_qam256_uscable0"] = new FrequencyTable(
+-        "QAM-256 Channel %1",   1, 75000000,1005000000, 6000000, QAM_256);
+-    fmap["atsc_qam256_uscable1"] = new FrequencyTable(
+-        "QAM-256 Channel T-%1", 7, 10000000,  52000000, 6000000, QAM_256);
++    QString modStr[] = { "vsb8",  "qam256",   "qam128",   "qam64",   };
++    uint    mod[]    = { VSB_8,    QAM_256,    QAM_128,    QAM_64,   };
++    QString desc[]   = { "ATSC ", "QAM-256 ", "QAM-128 ", "QAM-64 ", };
+-    // USA Cable, QAM 256 ch 78+
+-    fmap["atsc_qam256_uscablehigh0"] = new FrequencyTable(
+-        "QAM-256 Channel %1",  78,472000000,1005000000, 6000000, QAM_256);
++#define FREQ(A,B, C,D, E,F,G, H) \
++    fmap[QString("atsc_%1_us%2").arg(A).arg(B)] = \
++        new FrequencyTable(C+D, E, F, G, 6000000, H);
+-    // USA Cable HRC, QAM 256
+-    fmap["atsc_qam256_ushrc0"] = new FrequencyTable(
+-        "QAM-256 HRC %1",   1,  73750000,  73750001, 6000000, QAM_256);
+-    fmap["atsc_qam256_ushrc1"] = new FrequencyTable(
+-        "QAM-256 HRC %1",   2,  55750000,  67750000, 6000000, QAM_256);
+-    fmap["atsc_qam256_ushrc2"] = new FrequencyTable(
+-        "QAM-256 HRC %1",   5,  79750000,  85750000, 6000000, QAM_256);
+-    fmap["atsc_qam256_ushrc3"] = new FrequencyTable(
+-        "QAM-256 HRC %1",   7, 175750000, 643750000, 6000000, QAM_256);
+-    fmap["atsc_qam256_ushrc4"] = new FrequencyTable(
+-        "QAM-256 HRC %1",  95,  91750000, 114000000, 6000000, QAM_256);
+-    fmap["atsc_qam256_ushrc5"] = new FrequencyTable(
+-        "QAM-256 HRC %1", 100, 649750000, 799750000, 6000000, QAM_256);
+-    fmap["atsc_qam256_ushrc6"] = new FrequencyTable(
+-        "QAM-256 HRC T-%1", 7,   8175000,  50750000, 6000000, QAM_256);
++    for (uint i = 0; i < 3; i++)
++    {
++        // USA Cable, ch 1 to 155 and T.7 to T.14
++        FREQ(modStr[i], "cable0", desc[i], "Channel %1",
++             1, 75000000, 1005000000, mod[i]);
++        FREQ(modStr[i], "cable1", desc[i], "Channel T-%1",
++             7, 10000000,   52000000, mod[i]);
++        // USA Cable, QAM 256 ch 78 to 155
++        FREQ(modStr[i], "cablehigh0", desc[i], "Channel %1",
++             78, 537000000,1005000000, mod[i]);
+-    // USA Cable HRC, QAM 256 ch 78+
+-    fmap["atsc_qam256_ushrchigh0"] = new FrequencyTable(
+-        "QAM-256 HRC %1",  78, 601750000, 643750000, 6000000, QAM_256);
+-    fmap["atsc_qam256_ushrchigh1"] = new FrequencyTable(
+-        "QAM-256 HRC %1", 100, 649750000, 799750000, 6000000, QAM_256);
++        QString std[]   = { "hrc",  "irc"   };
++        QString sdesc[] = { "HRC ", "IRC "  };
++        int     off[]   = { 0,      1250000 };
++        for (uint j = 0; j < 2; j++)
++        {
++            // USA Cable HRC/IRC, ch 1 to 125
++            FREQ(modStr[i], std[j] + "0", desc[i], sdesc[j] + "%1",
++                 1,   73750000 + off[j],  73750001 + off[j], mod[i]);
++            FREQ(modStr[i], std[j] + "1", desc[i], sdesc[j] + "%1",
++                 2,   55750000 + off[j],  67750000 + off[j], mod[i]);
++            FREQ(modStr[i], std[j] + "2", desc[i], sdesc[j] + "%1",
++                 5,   79750000 + off[j],  85750000 + off[j], mod[i]);
++            FREQ(modStr[i], std[j] + "3", desc[i], sdesc[j] + "%1",
++                 7,  175750000 + off[j], 643750000 + off[j], mod[i]);
++            FREQ(modStr[i], std[j] + "4", desc[i], sdesc[j] + "%1",
++                 95,  91750000 + off[j], 114000000 + off[j], mod[i]);
++            FREQ(modStr[i], std[j] + "5", desc[i], sdesc[j] + "%1",
++                 100, 649750000 + off[j], 799750000 + off[j], mod[i]);
++            FREQ(modStr[i], std[j] + "6", desc[i], sdesc[j] + "T-%1",
++                 7,     8175000 + off[j],  50750000 + off[j], mod[i]);
+-
+-    // USA Cable, QAM 128
+-    fmap["atsc_qam128_uscable0"] = new FrequencyTable(
+-        "QAM-128 Channel %1",   1, 75000000,1005000000, 6000000, QAM_128);
+-    fmap["atsc_qam128_uscable1"] = new FrequencyTable(
+-        "QAM-128 Channel T-%1", 7, 10000000,  52000000, 6000000, QAM_128);
+-
+-    // USA Cable, QAM 128 ch 78+
+-    fmap["atsc_qam128_uscablehigh0"] = new FrequencyTable(
+-        "QAM-128 Channel %1",  78,472000000,1005000000, 6000000, QAM_128);
+-
+-    // USA Cable HRC, QAM 128
+-    fmap["atsc_qam128_ushrc0"] = new FrequencyTable(
+-        "QAM-128 HRC %1",   1,  73750000,  73750001, 6000000, QAM_128);
+-    fmap["atsc_qam128_ushrc1"] = new FrequencyTable(
+-        "QAM-128 HRC %1",   2,  55750000,  67750000, 6000000, QAM_128);
+-    fmap["atsc_qam128_ushrc2"] = new FrequencyTable(
+-        "QAM-128 HRC %1",   5,  79750000,  85750000, 6000000, QAM_128);
+-    fmap["atsc_qam128_ushrc3"] = new FrequencyTable(
+-        "QAM-128 HRC %1",   7, 175750000, 643750000, 6000000, QAM_128);
+-    fmap["atsc_qam128_ushrc4"] = new FrequencyTable(
+-        "QAM-128 HRC %1",  95,  91750000, 114000000, 6000000, QAM_128);
+-    fmap["atsc_qam128_ushrc5"] = new FrequencyTable(
+-        "QAM-128 HRC %1", 100, 649750000, 799750000, 6000000, QAM_128);
+-    fmap["atsc_qam128_ushrc6"] = new FrequencyTable(
+-        "QAM-128 HRC T-%1", 7,   8175000,  50750000, 6000000, QAM_128);
+-
+-    // USA Cable HRC, QAM 128 ch 78+
+-    fmap["atsc_qam128_ushrchigh0"] = new FrequencyTable(
+-        "QAM-128 HRC %1",  78, 601750000, 643750000, 6000000, QAM_128);
+-    fmap["atsc_qam128_ushrchigh1"] = new FrequencyTable(
+-        "QAM-128 HRC %1", 100, 649750000, 799750000, 6000000, QAM_128);
+-
+-
+-
+-
+-    // USA Cable, QAM 64
+-    fmap["atsc_qam64_uscable0"] = new FrequencyTable(
+-        "QAM-64 Channel %1",    1, 75000000,1005000000, 6000000, QAM_64);
+-    fmap["atsc_qam64_uscable1"] = new FrequencyTable(
+-        "QAM-64 Channel T-%1",  7, 10000000,  52000000, 6000000, QAM_64);
+-
+-    // USA Cable, QAM 64 ch 78+
+-    fmap["atsc_qam64_uscablehigh0"] = new FrequencyTable(
+-        "QAM-64 Channel %1",   78,472000000,1005000000, 6000000, QAM_64);
+-
+-    // USA Cable HRC, QAM 64
+-    fmap["atsc_qam64_ushrc0"] = new FrequencyTable(
+-        "QAM-64 HRC %1",   1,  73750000,  73750001, 6000000, QAM_64);
+-    fmap["atsc_qam64_ushrc1"] = new FrequencyTable(
+-        "QAM-64 HRC %1",   2,  55750000,  67750000, 6000000, QAM_64);
+-    fmap["atsc_qam64_ushrc2"] = new FrequencyTable(
+-        "QAM-64 HRC %1",   5,  79750000,  85750000, 6000000, QAM_64);
+-    fmap["atsc_qam64_ushrc3"] = new FrequencyTable(
+-        "QAM-64 HRC %1",   7, 175750000, 643750000, 6000000, QAM_64);
+-    fmap["atsc_qam64_ushrc4"] = new FrequencyTable(
+-        "QAM-64 HRC %1",  95,  91750000, 114000000, 6000000, QAM_64);
+-    fmap["atsc_qam64_ushrc5"] = new FrequencyTable(
+-        "QAM-64 HRC %1", 100, 649750000, 799750000, 6000000, QAM_64);
+-    fmap["atsc_qam64_ushrc6"] = new FrequencyTable(
+-        "QAM-64 HRC T-%1", 7,   8175000,  50750000, 6000000, QAM_64);
+-
+-    // USA Cable HRC, QAM 64 ch 78+
+-    fmap["atsc_qam64_ushrchigh0"] = new FrequencyTable(
+-        "QAM-64 HRC %1",  78, 601750000, 643750000, 6000000, QAM_64);
+-    fmap["atsc_qam64_ushrchigh1"] = new FrequencyTable(
+-        "QAM-64 HRC %1", 100, 649750000, 799750000, 6000000, QAM_64);
++            // USA Cable HRC/IRC, ch 67-125
++            FREQ(modStr[i], std[j] + "high0", desc[i], sdesc[j] + "%1",
++                 67,  535750000 + off[j], 643750000 + off[j], mod[i]);
++            FREQ(modStr[i], std[j] + "high1", desc[i], sdesc[j] + "%1",
++                 100, 649750000 + off[j], 799750000 + off[j], mod[i]);
++        }
++    }
+ }
+Index: mythtv/libs/libmythtv/scanwizardhelpers.h
+===================================================================
+--- mythtv/libs/libmythtv/scanwizardhelpers.h  (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/scanwizardhelpers.h  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -272,11 +272,13 @@
+   public:
+     ScanFrequencyTable()
+     {
+-        addSelection(QObject::tr("Broadcast"),        "us",            true);
+-        addSelection(QObject::tr("Cable")    +" 78+", "uscablehigh",   false);
+-        addSelection(QObject::tr("Cable HRC")+" 78+", "uscablehrchigh",false);
+-        addSelection(QObject::tr("Cable"),            "uscable",       false);
+-        addSelection(QObject::tr("Cable HRC"),        "ushrc",         false);
++        addSelection(QObject::tr("Broadcast"),        "us",          true);
++        addSelection(QObject::tr("Cable")    +" 78+", "uscablehigh", false);
++        addSelection(QObject::tr("Cable HRC")+" 67+", "ushrchigh",   false);
++        addSelection(QObject::tr("Cable IRC")+" 67+", "usirchigh",   false);
++        addSelection(QObject::tr("Cable"),            "uscable",     false);
++        addSelection(QObject::tr("Cable HRC"),        "ushrc",       false);
++        addSelection(QObject::tr("Cable IRC"),        "usirc",       false);
+         setLabel(QObject::tr("Frequency Table"));
+         setHelpText(QObject::tr("Frequency table to use.") + " " +
+Index: mythtv/libs/libmythtv/scanwizard.cpp
+===================================================================
+--- mythtv/libs/libmythtv/scanwizard.cpp       (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/scanwizard.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -518,7 +518,9 @@
+                     "SELECT dvb_diseqc_type, diseqc_port,  diseqc_pos, "
+                     "       lnb_lof_switch,  lnb_lof_hi,   lnb_lof_lo "
+                     "FROM cardinput, capturecard "
+-                    "WHERE capturecard.cardid=%1 and cardinput.sourceid=%2")
++                    "WHERE capturecard.cardid = %1 AND "
++                    "      cardinput.sourceid = %2 AND "
++                    "      capturecard.cardid = cardinput.cardid")
+                 .arg(parent->captureCard()).arg(nVideoSource));
+             if (query.exec() && query.isActive() && query.size() > 0)
+Index: mythtv/libs/libmythtv/RingBuffer.h
+===================================================================
+--- mythtv/libs/libmythtv/RingBuffer.h (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/RingBuffer.h (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -91,6 +91,7 @@
+     long long GetTotalReadPosition(void);
+     long long SetAdjustFilesize(void);
++    void SetTimeout(bool fast) { oldfile = fast; }
+     
+   protected:
+     static void *StartReader(void *type);
+Index: mythtv/libs/libmythtv/dvbtypes.cpp
+===================================================================
+--- mythtv/libs/libmythtv/dvbtypes.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/dvbtypes.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -202,7 +202,7 @@
+ {
+    {"TRANSMISSION_MODE_AUTO",TRANSMISSION_MODE_AUTO},
+    {"TRANSMISSION_MODE_2K",TRANSMISSION_MODE_2K},
+-   {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_2K},
++   {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_8K},
+    {NULL,TRANSMISSION_MODE_AUTO},
+ };
+@@ -210,7 +210,7 @@
+ {
+    {"999",TRANSMISSION_MODE_AUTO},
+    {"2",TRANSMISSION_MODE_2K},
+-   {"8",TRANSMISSION_MODE_2K},
++   {"8",TRANSMISSION_MODE_8K},
+    {NULL,TRANSMISSION_MODE_AUTO},
+ };
+@@ -218,7 +218,7 @@
+ {
+    {"auto",TRANSMISSION_MODE_AUTO},
+    {"2",TRANSMISSION_MODE_2K},
+-   {"8",TRANSMISSION_MODE_2K},
++   {"8",TRANSMISSION_MODE_8K},
+    {NULL,TRANSMISSION_MODE_AUTO},
+ };
+Index: mythtv/libs/libmythtv/mpegrecorder.cpp
+===================================================================
+--- mythtv/libs/libmythtv/mpegrecorder.cpp     (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/mpegrecorder.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -363,9 +363,9 @@
+     if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
+     {
+-        cerr << "Error setting codec params\n";
++        cerr << "Warning, unable to set recording volume\n";
++        cerr << "This is normal if you have an AVerMedia M179 card.\n";
+         perror("VIDIOC_S_CTRL:");
+-        return false;
+     }
+     if (vbimode) {
+@@ -481,6 +481,9 @@
+                 continue;
+             case 0:
+                 printf("select timeout - ivtv driver has stopped responding\n");
++                if(close(readfd) != 0)
++                    perror("close");
++                readfd = -1; // Force PVR card to be reopened on next iteration
+                 continue;
+            default: break;
+         }
+Index: mythtv/libs/libmythtv/ivtvdecoder.cpp
+===================================================================
+--- mythtv/libs/libmythtv/ivtvdecoder.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/ivtvdecoder.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -270,7 +270,9 @@
+     GetNVP()->SetVideoParams(720 /*width*/, (ntsc) ? 480 : 576 /*height*/,
+                              (ntsc) ? 29.97f : 25.0f, keyframedist, 1.33);
+-     
++
++    fps = (ntsc) ? 29.97f : 25.0f; // save for later length calculations
++
+     ringBuffer->UpdateRawBitrate(8000);
+     if (m_playbackinfo || livetv || watchingrecording)
+Index: mythtv/libs/libmythtv/dvbsignalmonitor.cpp
+===================================================================
+--- mythtv/libs/libmythtv/dvbsignalmonitor.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/dvbsignalmonitor.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -348,8 +348,8 @@
+         len += remainder;
+         remainder = GetStreamData()->ProcessData(buffer, len);
+-        if (remainder > 0) // leftover bytes
+-            memmove(buffer, &(buffer[buffer_size - remainder]), remainder);
++        if (remainder > 0 && (len > remainder)) // leftover bytes
++            memmove(buffer, &(buffer[len - remainder]), remainder);
+     }
+     VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorTS(): " + "shutdown");
+Index: mythtv/libs/libmythtv/osdimagecache.cpp
+===================================================================
+--- mythtv/libs/libmythtv/osdimagecache.cpp    (.../tags/release-0-19) (revision 0)
++++ mythtv/libs/libmythtv/osdimagecache.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -0,0 +1,296 @@
++// -*- Mode: c++ -*-
++/** OSDImageCache
++ *  Copyright (c) 2006 by Pekka Jääskeläinen, Daniel Thor Kristjansson
++ *  Distributed as part of MythTV under GPL v2 and later.
++ */
++
++// POSIX headers
++#include <stdint.h>
++
++// Qt headers
++#include <qdir.h>
++#include <qfile.h>
++#include <qfileinfo.h>
++#include <qdatastream.h>
++#include <qdeepcopy.h>
++
++// MythTV headers
++#include "mythcontext.h"
++#include "osdimagecache.h"
++
++// Print statistics of OSD image access in the destructor of OSDImageCache
++//#define PRINT_OSD_IMAGE_CACHE_STATS
++
++#define LOC QString("OSDImgCache: ")
++#define LOC_ERR QString("OSDImgCache, Error: ")
++
++uint OSDImageCache::kMaximumMemoryCacheSize = 5 * 1024 * 1024;
++
++/** \fn OSDImageCacheValue::OSDImageCacheValue(unsigned char*,unsigned char*,unsighed char*,unsigned char*,unsighed char*, QRect)
++ *  \brief The main constructor that takes the image data as arguments.
++ *
++ *   The image data becomes property of the OSDImageCacheValue 
++ *   and will be deleted by it.
++ */
++OSDImageCacheValue::OSDImageCacheValue(
++    QString cacheKey,
++    unsigned char *yuv,     unsigned char *ybuffer,
++    unsigned char *ubuffer, unsigned char *vbuffer,
++    unsigned char *alpha,   QRect imagesize) :
++    m_yuv(yuv),         m_ybuffer(ybuffer),
++    m_ubuffer(ubuffer), m_vbuffer(vbuffer),
++    m_alpha(alpha),     m_imagesize(imagesize),
++    m_cacheKey(QDeepCopy<QString>(cacheKey))
++{
++    uint yuv_size = m_imagesize.width() * m_imagesize.height() * 3 / 2;
++    m_size_in_bytes =
++        (sizeof(OSDImageCacheValue)) + yuv_size + 
++        (m_imagesize.width() * m_imagesize.height());
++}
++
++/** \fn OSDImageCacheValue::~OSDImageCacheValue()
++ *  \brief Destructor, frees the cached bitmaps.
++ */
++OSDImageCacheValue::~OSDImageCacheValue()
++{
++    delete [] m_yuv;
++    m_yuv = NULL;
++    delete [] m_alpha;
++    m_alpha = NULL;
++}
++
++/** \fn OSDImageCache::OSDImageCache()
++ *  \brief Constructor, initializes the internal cache structures.
++ */
++OSDImageCache::OSDImageCache() : 
++    m_cacheLock(true), m_imageCache(kMaximumMemoryCacheSize, 50),
++    m_memHits(0), m_diskHits(0), m_misses(0) 
++{
++    // When the cache gets too large, items are
++    // automatically deleted from it in LRU order.
++    m_imageCache.setAutoDelete(true);
++}
++
++/** \fn OSDImageCache::~OSDImageCache()
++ *  \brief Destructor, frees all cached OSD images.
++ */
++OSDImageCache::~OSDImageCache() 
++{
++#ifdef PRINT_OSD_IMAGE_CACHE_STATS
++    int totalAccess = m_memHits + m_diskHits + m_misses;
++    if (totalAccess == 0)
++        return;
++
++#define LOG_PREFIX "OSDImageCache: "
++    VERBOSE(VB_IMPORTANT, LOC << " Statistics: " << endl
++            << LOG_PREFIX << m_imageCache.totalCost() << " bytes in cache\n" 
++            << LOG_PREFIX << " memory hits: " 
++            << m_memHits << ", " << m_memHits*100.0/totalAccess << "%\n"
++            << LOG_PREFIX << "   disk hits: " 
++            << m_diskHits << ", " << m_diskHits*100.0/totalAccess << "%\n"
++            << LOG_PREFIX << "      misses: " 
++            << m_misses << ", " << m_misses*100.0/totalAccess << "%");
++#undef LOC_PREFIX
++#endif
++    Reset();
++}
++
++/** \fn OSDImageCache::Contains(const QString&,bool)
++ *  \brief Returns true if cached OSD image was found in the cache.
++ *
++ *  \param key The key for this image.
++ *  \param useFile If true, also look from the disk cache.
++ */
++bool OSDImageCache::Contains(const QString &key, bool useFile) const
++{
++    QMutexLocker locker(&m_cacheLock);
++
++    if (m_imageCache.find(key) != NULL)
++        return true;
++
++    if (!useFile)
++        return false;
++
++    return InFileCache(key);
++}
++
++bool OSDImageCache::InFileCache(const QString &key) const
++{
++    // check if cache file exists
++    QDir dir(MythContext::GetConfDir() + "/osdcache/");
++    QFileInfo cFile(dir.path() + "/" + key);
++    if (!cFile.exists() || !cFile.isReadable())
++        return false;
++
++    // check if backing file exists
++    QString orig = ExtractOriginal(key);
++    if (orig.isEmpty())
++        return false;
++
++    QFileInfo oFile(orig);
++    if (!oFile.exists())
++    {
++        VERBOSE(VB_IMPORTANT, LOC + QString("Can't find '%1'").arg(orig));
++        return false;
++    }
++
++    // if cache file is older than backing file, delete cache file
++    if (cFile.lastModified() < oFile.lastModified())
++    {
++        cFile.dir().remove(cFile.baseName(true));
++        return false;
++    } 
++
++    return true;
++}
++
++/** \fn OSDImageCache::Get(const QString&,bool)
++ *  \brief Returns OSD image data from cache.
++ *
++ *   This also removes the image from the cache so it won't be deleted
++ *   while in use. The deletion of the taken item becomes responsibility
++ *   of the client. Returns NULL if item with the given key is not found.
++ *
++ *  \param key The key for this image.
++ *  \param useFile If true, also check the disk cache.
++ */
++OSDImageCacheValue *OSDImageCache::Get(const QString &key, bool useFile)
++{
++    QMutexLocker locker(&m_cacheLock);
++    OSDImageCacheValue* item = m_imageCache.find(key);
++    if (item)
++    {
++        m_memHits++;
++        return m_imageCache.take(key);
++    }
++
++    if (!useFile || !InFileCache(key))
++    {
++        m_misses++;
++        return NULL;
++    }
++
++    QDir dir(MythContext::GetConfDir() + "/osdcache/");
++    QFile cacheFile(dir.path() + "/" + key);
++    cacheFile.open(IO_ReadOnly);
++    uint32_t imwidth  = 0;
++    uint32_t imheight = 0;
++
++    QDataStream stream(&cacheFile);
++    stream >> imwidth >> imheight;   
++
++    uint yuv_size = imwidth * imheight * 3 / 2;
++    uint tot_size = (sizeof(imwidth) * 2) + yuv_size + (imwidth * imheight);
++
++    if (cacheFile.size() != tot_size)
++    {
++        VERBOSE(VB_IMPORTANT, LOC_ERR + key + " wrong cache file size!"
++                << cacheFile.size() << " != " << tot_size);
++        return NULL;
++    }
++
++    unsigned char *yuv = new unsigned char[yuv_size];
++    unsigned char *alpha = new unsigned char[imwidth * imheight];
++    stream.readRawBytes((char*)yuv,   yuv_size);
++    stream.readRawBytes((char*)alpha, imwidth * imheight);
++    cacheFile.close();
++
++    OSDImageCacheValue* value = 
++        new OSDImageCacheValue(
++            key,
++            yuv, yuv,
++            yuv + (imwidth * imheight),
++            yuv + (imwidth * imheight * 5 / 4),
++            alpha, QRect(0, 0, imwidth, imheight));
++
++    m_diskHits++;
++    return value;
++}
++
++/** \fn OSDImageCache::Insert(OSDImageCacheValue*)
++ *  \brief Inserts OSD image data to memory cache.
++ *
++ *   The item becomes property of the OSDImageCache and may be 
++ *   deleted any time by it.
++ *
++ *  \param value The cache item.
++ */
++void OSDImageCache::Insert(OSDImageCacheValue *value)
++{
++    if (!value)
++        return;
++
++    QMutexLocker locker(&m_cacheLock);
++    if (!m_imageCache.insert(value->GetKey(), value, value->GetSize()))
++    {
++        VERBOSE(VB_IMPORTANT, 
++                LOC_ERR + QString("inserting image to memory cache failed"));
++    }
++}
++
++
++/** \fn OSDImageCache::SaveToDisk(const OSDImageCacheValue*)
++ *  \brief Saves OSD image data to disk cache.
++ *
++ *   Item is not written to the memory cache, i.e., it stays as
++ *   property of the client.
++ *
++ *  \param value The cached OSD image to save.
++ */
++void OSDImageCache::SaveToDisk(const OSDImageCacheValue *value)
++{
++    if (InFileCache(value->GetKey()))
++        return;
++
++    QDir dir(MythContext::GetConfDir() + "/osdcache/");
++    if (!dir.exists() && !dir.mkdir(dir.path()))
++    {
++        VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating osdcache directory failed.");
++        return;
++    }
++
++    QFile cacheFile(dir.path() + "/" + value->GetKey());
++    if (!cacheFile.open(IO_WriteOnly | IO_Truncate))
++    {
++        VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating osdcache file failed.");
++        return;
++    }
++
++    uint32_t imwidth  = value->m_imagesize.width();
++    uint32_t imheight = value->m_imagesize.height();
++    uint     yuv_size = imwidth * imheight * 3 / 2;
++
++    QDataStream stream(&cacheFile);
++    stream << imwidth << imheight;   
++    stream.writeRawBytes((const char*)value->m_yuv, yuv_size);
++    stream.writeRawBytes((const char*)value->m_alpha, imwidth * imheight);
++    cacheFile.close();
++}
++
++/** \fn OSDImageCache::CreateKey(const QString&,float,float,int,int)
++ *  \brief Generates a cache key from the given OSD image parameters.
++ *
++ *   The returned key is a string that can be safely used as a file name.
++ */
++QString OSDImageCache::CreateKey(const QString &filename, float wmult, 
++                                 float hmult, int scalew, int scaleh)
++{
++    QString tmp = filename;
++    return QString("cache_%1@%2_%3_%4_%5").arg(tmp.replace(QChar('/'), "+"))
++        .arg(wmult).arg(hmult).arg(scalew).arg(scaleh);
++}
++
++QString OSDImageCache::ExtractOriginal(const QString &key)
++{
++    QString tmp0 = key.mid(6);
++    QString tmp1 = tmp0.left(tmp0.find("@"));
++    QString tmp2 = tmp1.replace(QChar('+'), "/");
++    return tmp2;
++}
++
++void OSDImageCache::Reset(void)
++{
++    QMutexLocker locker(&m_cacheLock);
++    // this also deletes the images due to setAutoDelete(true)
++    m_imageCache.clear();
++}
+Index: mythtv/libs/libmythtv/osd.cpp
+===================================================================
+--- mythtv/libs/libmythtv/osd.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/osd.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -154,7 +154,8 @@
+         }
+         OSDTypeCC *ccpage = new OSDTypeCC(name, ccfont, sub_xoff, sub_yoff,
+-                                          sub_dispw, sub_disph);
++                                          sub_dispw, sub_disph,
++                                          wmult, hmult);
+         container->AddType(ccpage);
+     }
+@@ -517,7 +518,7 @@
+         }
+     }
+-    OSDTypeBox *box = new OSDTypeBox(name, area);
++    OSDTypeBox *box = new OSDTypeBox(name, area, wmult, hmult);
+     container->AddType(box);
+ }
+@@ -658,7 +659,7 @@
+         return;
+     }
+-    OSDTypeText *text = new OSDTypeText(name, ttffont, "", area);
++    OSDTypeText *text = new OSDTypeText(name, ttffont, "", area, wmult, hmult);
+     container->AddType(text);
+     text->SetMultiLine(multiline);
+@@ -875,7 +876,7 @@
+                 QRect area = parseRect(getFirstText(info));
+                 normalizeRect(area);
+-                rects->AddPosition(area);
++                rects->AddPosition(area, wmult, hmult);
+             }
+             else
+             {
+@@ -919,7 +920,7 @@
+                 pos.setX((int)(pos.x() * wmult + xoffset));
+                 pos.setY((int)(pos.y() * hmult + yoffset));
+-                image->AddPosition(pos);
++                image->AddPosition(pos, wmult, hmult);
+             }
+             else if (info.tagName() == "staticsize")
+             {
+@@ -1925,7 +1926,7 @@
+         image = new OSDTypeImage(*editarrowright);
+     }
+-    image->SetPosition(QPoint(xpos, ypos));
++    image->SetPosition(QPoint(xpos, ypos), wmult, hmult);
+     set->AddType(image);
+     set->Display();
+Index: mythtv/libs/libmythtv/dvbconfparser.cpp
+===================================================================
+--- mythtv/libs/libmythtv/dvbconfparser.cpp    (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/dvbconfparser.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -193,10 +193,10 @@
+     QStringList::Iterator end = tokens.end();
+     if (i != end) c.name = *i++; else return false;
+-    if (i != end) c.frequency = (*i++).toInt(); else return false;
++    if (i != end) c.frequency = (*i++).toUInt()*1000; else return false;
+     if (i == end || !c.polarity.parseConf(*i++)) return false;
+     if (i == end ) return false; else i++; //Sat num
+-    if (i != end) c.symbolrate = (*i++).toInt(); else return false;
++    if (i != end) c.symbolrate = (*i++).toUInt()*1000; else return false;
+     if (i == end ) return false; else i++;
+     if (i == end ) return false; else i++;
+     if (i != end) c.serviceid = (*i++).toInt(); else return false;
+Index: mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp
+===================================================================
+--- mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -108,8 +108,8 @@
+         len += remainder;
+         remainder = GetStreamData()->ProcessData(buffer, len);
+-        if (remainder > 0) // leftover bytes
+-            memmove(buffer, &(buffer[buffer_size - remainder]), remainder);
++        if (remainder > 0 && (len > remainder)) // leftover bytes
++            memmove(buffer, &(buffer[len - remainder]), remainder);
+     }
+     DBG_SM("RunTableMonitor()", "end");
+ }
+Index: mythtv/libs/libavformat/aviobuf.c
+===================================================================
+--- mythtv/libs/libavformat/aviobuf.c  (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libavformat/aviobuf.c  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -164,7 +164,13 @@
+ void url_fskip(ByteIOContext *s, offset_t offset)
+ {
+-    url_fseek(s, offset, SEEK_CUR);
++    if (offset < 16384) 
++    {
++        static unsigned char fskipbuf[16384];
++        get_buffer(s, fskipbuf, offset);
++    }
++    else
++        url_fseek(s, offset, SEEK_CUR);
+ }
+ offset_t url_ftell(ByteIOContext *s)
+Index: mythtv/libs/libmyth/lcddevice.cpp
+===================================================================
+--- mythtv/libs/libmyth/lcddevice.cpp  (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/lcddevice.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -150,7 +150,7 @@
+     if (!connected)
+     {
+-        QTextStream os(socket);
++        QTextStream os(socket->socketDevice());
+         int count = 0;
+         do
+@@ -213,7 +213,7 @@
+         return;
+     }
+-    QTextStream os(socket);
++    QTextStream os(socket->socketDevice());
+    
+     last_command = someText;
+  
+@@ -224,7 +224,7 @@
+ #endif
+         // Just stream the text out the socket
+-        os << someText << "\n" << flush;
++        os << someText << "\n";
+     }
+     else
+     {
+Index: mythtv/libs/libmyth/audiooutputca.cpp
+===================================================================
+--- mythtv/libs/libmyth/audiooutputca.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/audiooutputca.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -107,8 +107,10 @@
+     bzero(&conv_in_desc, sizeof(AudioStreamBasicDescription));
+     conv_in_desc.mSampleRate       = audio_samplerate;
+     conv_in_desc.mFormatID         = kAudioFormatLinearPCM;
+-    conv_in_desc.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger
+-                                     | kLinearPCMFormatFlagIsBigEndian;
++    conv_in_desc.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger;
++#ifdef WORDS_BIGENDIAN
++    conv_in_desc.mFormatFlags     |= kLinearPCMFormatFlagIsBigEndian;
++#endif
+     conv_in_desc.mBytesPerPacket   = audio_bytes_per_sample;
+     conv_in_desc.mFramesPerPacket  = 1;
+     conv_in_desc.mBytesPerFrame    = audio_bytes_per_sample;
+Index: mythtv/libs/libmyth/util.cpp
+===================================================================
+--- mythtv/libs/libmyth/util.cpp       (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/util.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -1006,16 +1006,20 @@
+     long long freespace = -1;
+     QCString cstr = file_on_disk.local8Bit();
+-    if (statfs(cstr, &statbuf) == 0)
++    total = used = -1;
++
++    // there are cases where statfs will return 0 (good), but f_blocks and
++    // others are invalid and set to 0 (such as when an automounted directory
++    // is not mounted but still visible because --ghost was used),
++    // so check to make sure we can have a total size > 0
++    if ((statfs(cstr, &statbuf) == 0) &&
++        (statbuf.f_blocks > 0) &&
++        (statbuf.f_bsize > 0))
+     {
+         freespace = statbuf.f_bsize * (statbuf.f_bavail >> 10);
+         total = statbuf.f_bsize * (statbuf.f_blocks >> 10);
+         used  = total - freespace;
+     }
+-    else
+-    {
+-        freespace = total = used = -1;
+-    }
+     return freespace;
+ }
+Index: mythtv/libs/libmyth/mythdialogs.cpp
+===================================================================
+--- mythtv/libs/libmyth/mythdialogs.cpp        (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/mythdialogs.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -2617,6 +2617,7 @@
+     password_editor->setEchoMode(QLineEdit::Password);
+     password_editor->setGeometry(textWidth + 20,10,135,30);
+     password_editor->setBackgroundOrigin(ParentOrigin);
++    password_editor->setAllowVirtualKeyboard(false);
+     connect(password_editor, SIGNAL(textChanged(const QString &)),
+             this, SLOT(checkPassword(const QString &)));
+Index: mythtv/libs/libmyth/mythwidgets.cpp
+===================================================================
+--- mythtv/libs/libmyth/mythwidgets.cpp        (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/mythwidgets.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -353,7 +353,8 @@
+                     (e->key() == Qt::Key_Enter) ||
+                     (e->key() == Qt::Key_Return)))
+             {
+-                if (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1)
++                if ((allowVirtualKeyboard) &&
++                                  (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1))
+                 {
+                     popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
+                     gContext->GetMainWindow()->detach(popup);
+@@ -726,10 +727,11 @@
+                 QWidget::focusNextPrevChild(true);
+                 emit tryingToLooseFocus(true);
+             }
+-            else if (action == "SELECT" &&
+-                    (e->text().isNull() ||
+-                    (e->key() == Qt::Key_Enter) || 
+-                    (e->key() == Qt::Key_Return)))
++            else if ((action == "SELECT") &&
++                     (!active_cycle) &&
++                     ((e->text().isNull()) ||
++                      (e->key() == Qt::Key_Enter) || 
++                      (e->key() == Qt::Key_Return)))
+             {
+                 if (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1)
+                 {
+@@ -749,7 +751,7 @@
+     if (handled)
+         return;
+-    if (!handled && popup && popup->isShown())
++    if (popup && popup->isShown())
+     {
+         endCycle();
+         QTextEdit::keyPressEvent(e);
+Index: mythtv/libs/libmyth/remotefile.h
+===================================================================
+--- mythtv/libs/libmyth/remotefile.h   (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/remotefile.h   (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -27,6 +27,8 @@
+     long long GetFileSize(void);
++    void SetTimeout(bool fast);
++
+   private:
+     QSocketDevice *openSocket(bool control);
+@@ -43,6 +45,7 @@
+     QMutex lock;
+     long long filesize;
++    bool timeoutisfast;
+ };
+ #endif
+Index: mythtv/libs/libmyth/mythwidgets.h
+===================================================================
+--- mythtv/libs/libmyth/mythwidgets.h  (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/mythwidgets.h  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -122,17 +122,21 @@
+     Q_OBJECT
+   public:
+     MythLineEdit(QWidget *parent=NULL, const char* widgetName=0) :
+-      QLineEdit(parent, widgetName) { rw = true; Init(); };
++      QLineEdit(parent, widgetName)
++          { rw = true; allowVirtualKeyboard = true; Init(); };
+     MythLineEdit(const QString& contents, QWidget *parent=NULL, 
+                  const char* widgetName=0) :
+-      QLineEdit(contents, parent, widgetName) { rw = true; Init(); };
++      QLineEdit(contents, parent, widgetName)
++          { rw = true; allowVirtualKeyboard = true; Init(); };
+     virtual ~MythLineEdit();
+     void setHelpText(QString help) { helptext = help; };
+     void setRW(bool readwrite = true) { rw = readwrite; };
+     void setRO() { rw = false; };
++    void setAllowVirtualKeyboard(bool allowKbd = true)
++             { allowVirtualKeyboard = allowKbd; }
+     void setPopupPosition(PopupPosition pos) { popupPosition = pos; }
+     PopupPosition getPopupPosition(void) { return popupPosition; }
+@@ -154,6 +158,7 @@
+     VirtualKeyboard *popup;
+     QString helptext;
+     bool rw;
++    bool allowVirtualKeyboard;
+     PopupPosition popupPosition;
+ };
+Index: mythtv/libs/libmyth/mythcontext.cpp
+===================================================================
+--- mythtv/libs/libmyth/mythcontext.cpp        (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/mythcontext.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -2621,9 +2621,13 @@
+         d->LoadLogSettings();
+     if (d->m_logenable == 1)
+     {
++        QString fullMsg = message;
++        if (!details.isEmpty())
++            fullMsg += ": " + details;
++
+         if (message.left(21) != "Last message repeated")
+         {
+-            if (message == d->lastLogStrings[module])
++            if (fullMsg == d->lastLogStrings[module])
+             {
+                 d->lastLogCounts[module] += 1;
+                 return;
+@@ -2639,7 +2643,7 @@
+                 }
+                 d->lastLogCounts[module] = 0;
+-                d->lastLogStrings[module] = message;
++                d->lastLogStrings[module] = fullMsg;
+             }
+         }
+@@ -2693,7 +2697,7 @@
+         }
+         if (priority <= d->m_logprintlevel)
+-            VERBOSE(VB_IMPORTANT, module + ": " + message);
++            VERBOSE(VB_IMPORTANT, module + ": " + fullMsg);
+     }
+ }
+Index: mythtv/libs/libmyth/remotefile.cpp
+===================================================================
+--- mythtv/libs/libmyth/remotefile.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libmyth/remotefile.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -15,6 +15,7 @@
+     path = url;
+     readposition = 0;
+     filesize = -1;
++    timeoutisfast = false;
+     query = "QUERY_FILETRANSFER %1";
+@@ -295,4 +296,34 @@
+     Read(data.data(), filesize);
+     return true;
+-} 
++}
++
++void RemoteFile::SetTimeout(bool fast)
++{
++    if (timeoutisfast == fast)
++        return;
++
++    if (!sock)
++    {
++        VERBOSE(VB_NETWORK, "RemoteFile::Seek(): Called with no socket");
++        return;
++    }
++
++    if (!sock->isOpen() || sock->error())
++        return;
++
++    if (!controlSock->isOpen() || controlSock->error())
++        return;
++
++    QStringList strlist = QString(query).arg(recordernum);
++    strlist << "SET_TIMEOUT";
++    strlist << QString::number((int)fast);
++
++    lock.lock();
++    WriteStringList(controlSock, strlist);
++    ReadStringList(controlSock, strlist);
++    lock.unlock();
++
++    timeoutisfast = fast;
++}
++
+Index: mythtv/libs/libavcodec/libavcodec.pro
+===================================================================
+--- mythtv/libs/libavcodec/libavcodec.pro      (.../tags/release-0-19) (revision 10051)
++++ mythtv/libs/libavcodec/libavcodec.pro      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -430,4 +430,5 @@
+     LIBS               += -lz
+     QMAKE_LFLAGS_SHLIB += -single_module
+     QMAKE_LFLAGS_SHLIB += -seg1addr 0xC3000000
++    QMAKE_LFLAGS_SHLIB += -read_only_relocs warning
+ }
+Index: mythtv/programs/mythfrontend/playbackbox.cpp
+===================================================================
+--- mythtv/programs/mythfrontend/playbackbox.cpp       (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythfrontend/playbackbox.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -17,6 +17,7 @@
+ #include <qsqldatabase.h>
+ #include <qmap.h>
++#include <cmath>
+ #include <unistd.h>
+ #include <iostream>
+@@ -140,6 +141,7 @@
+       // Main Recording List support
+       fillListTimer(new QTimer(this)),  connected(false),
+       titleIndex(0),                    progIndex(0),
++      progsInDB(0),
+       // Other state
+       curitem(NULL),                    delitem(NULL),
+       lastProgram(NULL),
+@@ -261,7 +263,9 @@
+     setNoErase();
+     gContext->addListener(this);
+-    if (!recGroupPassword.isEmpty() || (titleList.count() <= 1) || initialFilt)
++    if ((!recGroupPassword.isEmpty()) ||
++        ((titleList.count() <= 1) && (progsInDB > 0)) ||
++        (initialFilt))
+         showRecGroupChooser();
+     gContext->addCurrentLocation((type == Delete)? "DeleteBox":"PlaybackBox");
+@@ -890,9 +894,13 @@
+         !playingSomething)
+     {
+         QSize size = drawVideoBounds.size();
++        float saspect = ((float)size.width()) / ((float)size.height());
++        float vaspect = previewVideoNVP->GetVideoAspect();
++        size.setHeight((int) ceil(size.height() * (saspect / vaspect)));
++        size.setHeight(((size.height() + 7) / 8) * 8);
++        size.setWidth( ((size.width()  + 7) / 8) * 8);
+         const QImage &img = previewVideoNVP->GetARGBFrame(size);
+-        uint xoff = max((size.width() - drawVideoBounds.width()) / 2, 0);
+-        p->drawImage(drawVideoBounds.x() + xoff, drawVideoBounds.y(), img);
++        p->drawImage(drawVideoBounds.x(), drawVideoBounds.y(), img);
+     }
+     /* have we timed out waiting for nvp to start? */
+@@ -1380,6 +1388,7 @@
+         asCache[asKey] = p->availableStatus;
+     }
++    progsInDB = 0;
+     titleList.clear();
+     progLists.clear();
+     // Clear autoDelete for the "all" list since it will share the
+@@ -1402,6 +1411,7 @@
+         vector<ProgramInfo *>::iterator i = infoList->begin();
+         for ( ; i != infoList->end(); i++)
+         {
++            progsInDB++;
+             p = *i;
+             if ((((p->recgroup == recGroup) ||
+                   ((recGroup == "All Programs") &&
+@@ -4129,8 +4139,7 @@
+     if (!recGroupListBox)
+         return;
+-    QString item = 
+-        recGroupListBox->currentText().section('[', 0, 0).simplifyWhiteSpace();
++    QString item = recGroupListBox->currentText().section(" [", 0, 0);
+     if (item.left(5) == "-----")
+     {
+@@ -4147,8 +4156,7 @@
+ void PlaybackBox::setGroupFilter(void)
+ {
+-    recGroup =
+-        recGroupListBox->currentText().section('[', 0, 0).simplifyWhiteSpace();
++    recGroup = recGroupListBox->currentText().section(" [", 0, 0);
+     if (groupnameAsAllProg)
+         groupDisplayName = recGroup;
+Index: mythtv/programs/mythfrontend/customrecord.cpp
+===================================================================
+--- mythtv/programs/mythfrontend/customrecord.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythfrontend/customrecord.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -149,7 +149,7 @@
+     m_cfrom << "";
+     m_csql << "program.stars >= 0.75 ";
+-    m_clause->insertItem(tr("Person named in the credits"));
++    m_clause->insertItem(tr("Person named in the credits (Data Direct)"));
+     m_cfrom << ", people, credits";
+     m_csql << QString("people.name = 'Tom Hanks' \n"
+                       "AND credits.person = people.person \n"
+@@ -447,8 +447,8 @@
+     else
+     {
+         MSqlQuery query(MSqlQuery::InitCon());
+-        query.prepare(QString("SELECT NULL FROM program,channel %1 WHERE\n%2") 
+-                              .arg(from).arg(desc));
++        query.prepare(QString("SELECT NULL FROM (program,channel) "
++                              "%1 WHERE\n%2").arg(from).arg(desc));
+         if (query.exec() && query.isActive())
+         {
+Index: mythtv/programs/mythfrontend/tv_schedule.xml
+===================================================================
+--- mythtv/programs/mythfrontend/tv_schedule.xml       (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythfrontend/tv_schedule.xml       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -26,7 +26,7 @@
+       <alttext lang="CA">Guia</alttext>
+       <alttext lang="DE">EPG</alttext>
+       <alttext lang="DK">Guide</alttext>
+-      <alttext lang="DK">Dagskrá</alttext>
++      <alttext lang="IS">Dagskrá</alttext>
+       <alttext lang="NL">Gids</alttext>
+       <alttext lang="SV">Guide</alttext>
+       <alttext lang="JA">ガイド</alttext>
+Index: mythtv/programs/mythfrontend/playbackbox.h
+===================================================================
+--- mythtv/programs/mythfrontend/playbackbox.h (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythfrontend/playbackbox.h (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -337,6 +337,7 @@
+     int                 progIndex;  ///< Index of selected item index on page
+     QStringList         titleList;  ///< list of pages
+     ProgramMap          progLists;  ///< lists of programs by page        
++    int                 progsInDB;  ///< total number of recordings in DB
+     // Play List support
+     QStringList         playList;   ///< list of selected items "play list"
+Index: mythtv/programs/mythfrontend/networkcontrol.cpp
+===================================================================
+--- mythtv/programs/mythfrontend/networkcontrol.cpp    (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythfrontend/networkcontrol.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -469,7 +469,7 @@
+             message = "NETWORK_CONTROL SEEK BACKWARD";
+         else if (tokens[2].contains(QRegExp("^\\d\\d:\\d\\d:\\d\\d$")))
+         {
+-            int hours = tokens[2].left(0).toInt();
++            int hours   = tokens[2].mid(0, 2).toInt();
+             int minutes = tokens[2].mid(3, 2).toInt();
+             int seconds = tokens[2].mid(6, 2).toInt();
+             message = QString("NETWORK_CONTROL SEEK POSITION %1")
+Index: mythtv/programs/mythtranscode/mpeg2fix.cpp
+===================================================================
+--- mythtv/programs/mythtranscode/mpeg2fix.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythtranscode/mpeg2fix.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -1776,6 +1776,7 @@
+         if (vFrame.count() && (file_end || vFrame.getLast()->isSequence))
+         {
++            MPEG2frame *seqFrame;
+             if (ptsIncrement != vFrame.first()->mpeg2_seq.frame_period / 300)
+             {
+                 VERBOSE(MPF_IMPORTANT,
+@@ -1786,6 +1787,11 @@
+             }
+             displayFrame->toFirst();
++            // since we might reorder the frames when coming out of a cutpoint
++            // me need to save the first frame here, as it is gauranteed to
++            // have a sequence header.
++            seqFrame = vFrame.current();
++
+             while (vFrame.current() != vFrame.getLast())
+             {
+                 bool ptsorder_eq_dtsorder = false;
+@@ -1941,7 +1947,7 @@
+                         if (! new_discard_state)
+                         {
+-                            AddSequence(markedFrame, vFrame.first());
++                            AddSequence(markedFrame, seqFrame);
+                             RenumberFrames(frame_pos + Lreorder.at(),
+                                             - GetFrameNum(markedFrame));
+                         }
+Index: mythtv/programs/mythcommflag/main.cpp
+===================================================================
+--- mythtv/programs/mythcommflag/main.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythcommflag/main.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -895,9 +895,6 @@
+         return COMMFLAG_EXIT_INVALID_CMDLINE;
+     }
+-    if (queueJobInstead)
+-        return QueueCommFlagJob(chanid, starttime);
+-
+     if (copyToCutlist)
+         return CopySkipListToCutList(chanid, starttime);
+@@ -1009,7 +1006,10 @@
+                 if ( allRecorded )
+                 {
+-                    FlagCommercials(chanid, starttime);
++                    if (queueJobInstead)
++                        QueueCommFlagJob(chanid, starttime);
++                    else
++                        FlagCommercials(chanid, starttime);
+                 }
+                 else
+                 {
+@@ -1063,7 +1063,12 @@
+                             if ((flagStatus == COMM_FLAG_NOT_FLAGGED) &&
+                                 (marksFound == 0))
+-                                FlagCommercials(chanid, starttime);
++                            {
++                                if (queueJobInstead)
++                                    QueueCommFlagJob(chanid, starttime);
++                                else
++                                    FlagCommercials(chanid, starttime);
++                            }
+                         }
+                     }
+                 }
+Index: mythtv/programs/mythbackend/mainserver.cpp
+===================================================================
+--- mythtv/programs/mythbackend/mainserver.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythbackend/mainserver.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -1919,11 +1919,8 @@
+     if (m_sched) {
+         if (table == "") m_sched->getAllPending(strList);
+         else {
+-            // We need a different connection from the scheduler proper
+-            // DDCon exists, although it's designed for other purposes.
+-            MSqlQueryInfo dbconn = MSqlQuery::DDCon();
+-            Scheduler *sched = new Scheduler(false, encoderList,
+-                                             table, &dbconn, m_sched);
++            Scheduler *sched = new Scheduler(false, encoderList, 
++                                             table, m_sched);
+             sched->FillRecordListFromDB(recordid);
+             sched->getAllPending(strList);
+             delete sched;
+@@ -2940,6 +2937,12 @@
+         long long ret = ft->Seek(curpos, pos, whence);
+         encodeLongLong(retlist, ret);
+     }
++    else if (command == "SET_TIMEOUT")
++    {
++        bool fast = slist[2].toInt();
++        ft->SetTimeout(fast);
++        retlist << "ok";
++    }
+     else 
+     {
+         VERBOSE(VB_IMPORTANT, QString("Unknown command: %1").arg(command));
+Index: mythtv/programs/mythbackend/scheduler.cpp
+===================================================================
+--- mythtv/programs/mythbackend/scheduler.cpp  (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythbackend/scheduler.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -35,8 +35,7 @@
+ #define LOC_ERR QString("Scheduler, Error: ")
+ Scheduler::Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
+-                     QString recordTbl, MSqlQueryInfo *databaseConnection,
+-                     Scheduler *master_sched)
++                     QString recordTbl, Scheduler *master_sched)
+ {
+     hasconflicts = false;
+     m_tvList = tvList;
+@@ -48,8 +47,11 @@
+         master_sched->getAllPending(&reclist);
+     }
+-    if (databaseConnection) dbConn = *databaseConnection;
+-    else dbConn = MSqlQuery::SchedCon();
++    // Only the master scheduler should use SchedCon()
++    if (runthread)
++        dbConn = MSqlQuery::SchedCon();
++    else
++        dbConn = MSqlQuery::DDCon();
+     recordTable = recordTbl;
+@@ -1136,6 +1138,10 @@
+             
+         if (reschedQueue.count())
+         {
++            // We might have been inactive for a long time, so make
++            // sure our DB connection is fresh before continuing.
++            dbConn = MSqlQuery::SchedCon();
++
+             gettimeofday(&fillstart, NULL);
+             QString msg;
+             while (reschedQueue.count())
+@@ -1827,10 +1833,10 @@
+         QString query = QString(
+ "INSERT INTO recordmatch (recordid, chanid, starttime, manualid) "
+ "SELECT RECTABLE.recordid, program.chanid, program.starttime, "
+-" IF(search = %1, recordid, 0) "
+-"FROM RECTABLE, program ").arg(kManualSearch) + fromclauses[clause] + QString(
+-" INNER JOIN channel ON (channel.chanid = program.chanid) "
+-"WHERE ") + whereclauses[clause] + QString(" AND channel.visible = 1 AND "
++" IF(search = %1, recordid, 0) ").arg(kManualSearch) + QString(
++"FROM (RECTABLE, program INNER JOIN channel "
++"      ON channel.chanid = program.chanid) ") + fromclauses[clause] + QString(
++" WHERE ") + whereclauses[clause] + QString(" AND channel.visible = 1 AND "
+ "((RECTABLE.type = %1 " // allrecord
+ "OR RECTABLE.type = %2 " // findonerecord
+ "OR RECTABLE.type = %3 " // finddailyrecord
+Index: mythtv/programs/mythbackend/housekeeper.cpp
+===================================================================
+--- mythtv/programs/mythbackend/housekeeper.cpp        (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythbackend/housekeeper.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -138,7 +138,6 @@
+     while (1)
+     {
+-        VERBOSE(VB_IMPORTANT, "Running HouseKeeping");
+         gContext->LogEntry("mythbackend", LP_DEBUG,
+                            "Running housekeeping thread", "");
+Index: mythtv/programs/mythbackend/scheduler.h
+===================================================================
+--- mythtv/programs/mythbackend/scheduler.h    (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythbackend/scheduler.h    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -23,8 +23,7 @@
+ {
+   public:
+     Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
+-              QString recordTbl = "record", MSqlQueryInfo *dbConnUse = NULL,
+-              Scheduler *master_sched = NULL);
++              QString recordTbl = "record", Scheduler *master_sched = NULL);
+     ~Scheduler();
+     void Reschedule(int recordid);
+Index: mythtv/programs/mythbackend/filetransfer.cpp
+===================================================================
+--- mythtv/programs/mythbackend/filetransfer.cpp       (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythbackend/filetransfer.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -131,3 +131,9 @@
+     return size;
+ }
++
++void FileTransfer::SetTimeout(bool fast)
++{
++    rbuffer->SetTimeout(fast);
++}
++
+Index: mythtv/programs/mythbackend/autoexpire.cpp
+===================================================================
+--- mythtv/programs/mythbackend/autoexpire.cpp (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythbackend/autoexpire.cpp (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -291,7 +291,8 @@
+     if ((availFreeKB = getDiskSpace(record_file_prefix, tKB, uKB)) < 0)
+     {
+-        QString msg = QString("ERROR: Could not calculate free space.");
++        QString msg = QString("ERROR: Could not calculate free space for %1.")
++                              .arg(record_file_prefix);
+         VERBOSE(VB_IMPORTANT, LOC + msg);
+         gContext->LogEntry("mythbackend", LP_WARNING,
+                            "Autoexpire Recording", msg);
+Index: mythtv/programs/mythbackend/filetransfer.h
+===================================================================
+--- mythtv/programs/mythbackend/filetransfer.h (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythbackend/filetransfer.h (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -35,6 +35,8 @@
+     long long GetFileSize(void);
++    void SetTimeout(bool fast);
++
+   private:
+     bool readthreadlive;
+     QMutex readthreadLock;
+Index: mythtv/programs/mythtv/main.cpp
+===================================================================
+--- mythtv/programs/mythtv/main.cpp    (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythtv/main.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -132,6 +132,7 @@
+         ProgramInfo *pginfo = new ProgramInfo();
+         pginfo->endts = QDateTime::currentDateTime().addSecs(-180);
+         pginfo->pathname = filename;
++        pginfo->isVideo = true;
+     
+         tv->Playback(pginfo);
+     }
+Index: mythtv/programs/mythfilldatabase/filldata.cpp
+===================================================================
+--- mythtv/programs/mythfilldatabase/filldata.cpp      (.../tags/release-0-19) (revision 10051)
++++ mythtv/programs/mythfilldatabase/filldata.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -337,7 +337,7 @@
+     MSqlQuery query(MSqlQuery::InitCon());
+     query.prepare("SELECT ch.chanid, nim.url "
+-            "FROM channel ch, callsignnetworkmap csm "
++            "FROM (channel ch, callsignnetworkmap csm) "
+             "RIGHT JOIN networkiconmap nim ON csm.network = nim.network "
+             "WHERE ch.callsign = csm.callsign AND "
+             "(icon = :NOICON OR icon = '') AND ch.sourceid = :SOURCEID");
+@@ -2174,7 +2174,8 @@
+                         0 /*service id*/, major,            minor,
+                         false /*use on air guide*/, false /*hidden*/,
+                         false /*hidden in guide*/,
+-                        freqid,           localfile,        (*i).tvformat))
++                        freqid,           localfile,        (*i).tvformat,
++                        (*i).xmltvid))
+                 {
+                     cout << "### " << endl;
+                     cout << "### Channel inserted" << endl;
+@@ -3851,7 +3852,6 @@
+              VERBOSE(VB_IMPORTANT, "Failed to fetch some program info");
+              gContext->LogEntry("mythfilldatabase", LP_WARNING,
+                                 "Failed to fetch some program info", "");
+-             return FILLDB_EXIT_DB_ERROR;
+         }
+         else
+             VERBOSE(VB_IMPORTANT, "Data fetching complete.");
+Index: mythtv/setup/backendsettings.cpp
+===================================================================
+--- mythtv/setup/backendsettings.cpp   (.../tags/release-0-19) (revision 10051)
++++ mythtv/setup/backendsettings.cpp   (.../branches/release-0-19-fixes)       (revision 10051)
+@@ -1,6 +1,7 @@
+ #include <cstdio>
+ #include "backendsettings.h"
++#include "frequencies.h"
+ #include "libmyth/mythcontext.h"
+ #include "libmyth/settings.h"
+ #include <unistd.h>
+@@ -110,23 +111,10 @@
+ {
+     GlobalComboBox *gc = new GlobalComboBox("FreqTable");
+     gc->setLabel(QObject::tr("Channel frequency table"));
+-    gc->addSelection("us-cable");
+-    gc->addSelection("us-bcast");
+-    gc->addSelection("us-cable-hrc");
+-    gc->addSelection("us-cable-irc");
+-    gc->addSelection("japan-bcast");
+-    gc->addSelection("japan-cable");
+-    gc->addSelection("europe-west");
+-    gc->addSelection("europe-east");
+-    gc->addSelection("italy");
+-    gc->addSelection("newzealand");
+-    gc->addSelection("australia");
+-    gc->addSelection("ireland");
+-    gc->addSelection("france");
+-    gc->addSelection("china-bcast");
+-    gc->addSelection("southafrica");
+-    gc->addSelection("argentina");
+-    gc->addSelection("australia-optus");
++
++    for (uint i = 0; chanlists[i].name; i++)
++        gc->addSelection(chanlists[i].name);
++
+     gc->setHelpText(QObject::tr("Select the appropriate frequency table for "
+                     "your system.  If you have an antenna, use a \"-bcast\" "
+                     "frequency."));
This page took 0.725262 seconds and 4 git commands to generate.