]> git.pld-linux.org Git - packages/mythplugins.git/blob - mythtv-branch.diff
- release 0.19 fixes up to svn 10051
[packages/mythplugins.git] / mythtv-branch.diff
1 Index: mythplugins/mythweb/themes/wml/header.php
2 ===================================================================
3 --- mythplugins/mythweb/themes/wml/header.php   (.../tags/release-0-19) (revision 10051)
4 +++ mythplugins/mythweb/themes/wml/header.php   (.../branches/release-0-19-fixes)       (revision 10051)
5 @@ -26,4 +26,4 @@
6  <p><a href="<?php echo root ?>tv/upcoming"><?php echo t('Upcoming Recordings') ?></a></p>
7  <p><a href="<?php echo root ?>tv/recorded"><?php echo t('Recorded Programs') ?></a></p>
8  <p><a href="<?php echo root ?>tv/search"><?php echo t('Search') ?></a></p>
9 -<p><a href="<?php echo root ?>status?xml"><?php echo t('Backend Status') ?></a></p>
10 +<p><a href="<?php echo root ?>status/xml"><?php echo t('Backend Status') ?></a></p>
11 Index: mythplugins/mythweb/themes/default/weather/weather.php
12 ===================================================================
13 --- mythplugins/mythweb/themes/default/weather/weather.php      (.../tags/release-0-19) (revision 10051)
14 +++ mythplugins/mythweb/themes/default/weather/weather.php      (.../branches/release-0-19-fixes)       (revision 10051)
15 @@ -93,13 +93,13 @@
16                  $tomorrow = date("m/d/Y", mktime(0, 0, 0, date("m")  , date("d")+1, date("Y")));
17  
18                  switch($forecast->dayofweek) {
19 +                    case 0:  $day = t('Sunday');        break;
20                      case 1:  $day = t('Monday');        break;
21                      case 2:  $day = t('Tuesday');       break;
22                      case 3:  $day = t('Wednesday');     break;
23                      case 4:  $day = t('Thursday');      break;
24                      case 5:  $day = t('Friday');        break;
25                      case 6:  $day = t('Saturday');      break;
26 -                    case 7:  $day = t('Sunday');        break;
27                      default: $day = $forecast->date;    break;
28                  }
29  
30 Index: mythplugins/mythweb/themes/default/music/music.php
31 ===================================================================
32 --- mythplugins/mythweb/themes/default/music/music.php  (.../tags/release-0-19) (revision 10051)
33 +++ mythplugins/mythweb/themes/default/music/music.php  (.../branches/release-0-19-fixes)       (revision 10051)
34 @@ -164,10 +164,12 @@
35  
36      function print_header($filterPlaylist,$filterArtist,$filterAlbum,$filterGenre) {
37          $this->filterPlaylist=$filterPlaylist;
38 -// Set the desired page title
39 -    $page_title = 'MythWeb - '.t('Music');
40 -// Print the page header
41 -    require_once theme_dir.'/header.php';
42 +    // Set the desired page title
43 +        global $page_title, $Modules, $headers;
44 +        $page_title = 'MythWeb - '.t('Music');
45 +    // Print the page header
46 +        require_once theme_dir.'/header.php';
47 +
48          printf("<form  action=\"".root."music\" method=\"GET\" >\n");
49          printf("<input type=\"hidden\" name=\"mode\" value=\"music\" />\n");
50  
51 Index: mythplugins/mythweb/themes/default/tv/detail.php
52 ===================================================================
53 --- mythplugins/mythweb/themes/default/tv/detail.php    (.../tags/release-0-19) (revision 10051)
54 +++ mythplugins/mythweb/themes/default/tv/detail.php    (.../branches/release-0-19-fixes)       (revision 10051)
55 @@ -51,7 +51,7 @@
56  <?php   } ?>
57              <div id="program_title">
58                  <h1>
59 -                    <a href="<?php echo root ?>tv/search/<?php echo urlencode($program->title) ?>&search_title=yes"><?php echo $schedule->title ?></a>
60 +                    <a href="<?php echo root ?>tv/search/<?php echo str_replace('%2F', '/', rawurlencode($schedule->title)) ?>?search_title=1"><?php echo $schedule->title ?></a>
61                  </h1>
62                  <div id="program_time">
63  <?php
64 Index: mythplugins/mythweb/includes/mythbackend.php
65 ===================================================================
66 --- mythplugins/mythweb/includes/mythbackend.php        (.../tags/release-0-19) (revision 10051)
67 +++ mythplugins/mythweb/includes/mythbackend.php        (.../branches/release-0-19-fixes)       (revision 10051)
68 @@ -15,10 +15,6 @@
69  // The character string used by the backend to separate records
70      define('backend_sep', '[]:[]');
71  
72 -// A couple of global variables to keep duplicate queries to a minimum
73 -    $Scheduled_Recordings = array();
74 -    $Recorded_Programs    = array();
75 -
76  // MYTH_PROTO_VERSION is defined in libmyth in mythtv/libs/libmyth/mythcontext.h
77  // and should be the current MythTV protocol version.
78      define('MYTH_PROTO_VERSION', 26);
79 Index: mythplugins/mythweb/includes/programs.php
80 ===================================================================
81 --- mythplugins/mythweb/includes/programs.php   (.../tags/release-0-19) (revision 10051)
82 +++ mythplugins/mythweb/includes/programs.php   (.../branches/release-0-19-fixes)       (revision 10051)
83 @@ -81,7 +81,9 @@
84  /**/
85      function &load_all_program_data($start_time, $end_time, $chanid = false, $single_program = false, $extra_query = '') {
86          global $Channels, $db;
87 -    // Make a local hash of channel chanid's with references to the actual channel data
88 +    // Make a local hash of channel chanid's with references to the actual
89 +    // channel data (Channels are not indexed by anything in particular, so
90 +    // that the user can sort by chanid or channum).
91          $channel_hash = array();
92      // An array (that later gets converted to a string) containing the id's of channels we want to load
93          $these_channels = array();
94 @@ -104,7 +106,7 @@
95              load_all_channels();
96      // Scan through the channels array and actually assign those references
97          foreach (array_keys($Channels) as $key) {
98 -            $channel_hash[$Channels[$key]->chanid] = &$Channels[$key];
99 +            $channel_hash[$Channels[$key]->chanid] =& $Channels[$key];
100          // Reinitialize the programs array for this channel
101              $Channels[$key]->programs = array();
102          // Keep track of this channel id in case we're only grabbing info for certain channels - workound included to avoid blank chanid's
103 @@ -130,11 +132,13 @@
104                         LEFT JOIN programrating USING (chanid, starttime)
105                         LEFT JOIN oldrecorded
106                                   ON oldrecorded.recstatus IN (-3, 11)
107 -                                    AND IF(oldrecorded.programid OR oldrecorded.seriesid,
108 +                                    AND IF(oldrecorded.programid AND oldrecorded.seriesid,
109                                             oldrecorded.programid = program.programid
110                                               AND oldrecorded.seriesid = program.seriesid,
111 -                                           oldrecorded.title = program.title
112 -                                             AND oldrecorded.subtitle = program.subtitle
113 +                                           oldrecorded.title AND oldrecorded.subtitle
114 +                                             AND oldrecorded.description
115 +                                             AND oldrecorded.title       = program.title
116 +                                             AND oldrecorded.subtitle    = program.subtitle
117                                               AND oldrecorded.description = program.description
118                                            )
119                         LEFT JOIN channel ON program.chanid = channel.chanid
120 @@ -156,8 +160,12 @@
121      // The extra query, if there is one
122          if ($extra_query)
123              $query .= ' AND '.$extra_query;
124 -    // Group, sort and query
125 +    // Group and sort
126          $query .= ' GROUP BY program.chanid, program.starttime ORDER BY program.starttime';
127 +    // Limit
128 +        if ($single_program)
129 +            $query .= ' LIMIT 1';
130 +    // Query
131          $sh = $db->query($query,
132                           star_character, max_stars, max_stars);
133      // No results
134 @@ -188,12 +196,8 @@
135      // Cleanup
136          $sh->finish();
137      // If channel-specific information was requested, return an array of those programs, or just the first/only one
138 -        if ($chanid) {
139 -            if ($single_program)
140 -                return $channel_hash[$chanid]->programs[0];
141 -            else
142 -                return $channel_hash[$chanid]->programs;
143 -        }
144 +        if ($chanid && $single_program)
145 +            return $these_programs[0];
146      // Just in case, return an array of all programs found
147          return $these_programs;
148      }
149 @@ -272,18 +276,18 @@
150              $this->endtime     = $data[12];  # show end-time
151          // Is this a previously-recorded program?  Calculate the filesize
152              if (!empty($this->filename)) {
153 -                $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low;
154 -            }
155 -        // Ah, a scheduled recording - let's load more information about it, to be parsed in below
156 -            elseif ($this->chanid) {
157 -                unset($this->filename);
158 -            // Kludge to avoid redefining the object, which doesn't work in php5
159 -                $tmp = @get_object_vars(load_one_program($this->starttime, $this->chanid));
160 -                if (is_array($tmp) && count($tmp) > 0) {
161 -                    foreach ($tmp as $key => $value) {
162 -                        $this->$key = $value;
163 -                    }
164 +                if (function_exists('gmp_add')) {
165 +                // GMP functions should work better with 64 bit numbers.
166 +                    $size = gmp_add($fs_low,
167 +                                     gmp_mul('4294967296',
168 +                                             gmp_add($fs_high, $fs_low < 0 ? '1' : '0'))
169 +                                   );
170 +                    $this->filesize = gmp_strval($size);
171                  }
172 +                else {
173 +                // This is inaccurate, but it's the best we can get without GMP.
174 +                    $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low;
175 +                }
176              }
177          // Load the remaining info we got from mythbackend
178              $this->title           = $data[0];                  # program name/title
179 @@ -291,14 +295,14 @@
180              $this->description     = $data[2];                  # episode description
181              $this->category        = $data[3];
182              #$chanid               = $data[4];   # Extracted a few lines earlier
183 -            #$channum              = $data[5];
184 -            #$callsign             = $data[6];
185 +            $this->channum         = $data[5];
186 +            $this->callsign        = $data[6];
187              $this->channame        = $data[7];
188              #$pathname             = $data[8];   # Extracted a few lines earlier
189              #$fs_high              = $data[9];   # Extracted a few lines earlier
190              #$fs_low               = $data[10];  # Extracted a few lines earlier
191 -            #$starttime            = $data[11];  # Extracted a few lines earlier
192 -            #$endtime              = $data[12];  # Extracted a few lines earlier
193 +            #$this->starttime      = $data[11];  # Extracted a few lines earlier
194 +            #$this->endtime        = $data[12];  # Extracted a few lines earlier
195              $this->hostname        = $data[16];
196              #$this->sourceid       = $data[17];
197              $this->cardid          = $data[18];
198 @@ -320,9 +324,9 @@
199              $this->programid       = $data[34];
200              $this->lastmodified    = $data[35];
201              $this->recpriority     = $data[36];
202 -            #$this->airdate        = $data[37];
203 -            #$this->hasairdate     = $data[38];
204 -            $this->timestretch     = $program_data[39];
205 +            $this->airdate         = date('Y-m-d', $data[37]);
206 +            $this->hasairdate      = $data[38];
207 +            $this->timestretch     = $data[39];
208              $this->recpriority2    = $data[40];
209          // Assign the program flags
210              $this->has_commflag = ($progflags & 0x01) ? true : false;    // FL_COMMFLAG  = 0x01
211 @@ -363,8 +367,8 @@
212              $this->title_pronounce         = $data['title_pronounce'];
213              $this->recstatus               = $data['recstatus'];
214  
215 -            if ($program_data['tsdefault']) {
216 -                $this->timestretch = $program_data['tsdefault'];
217 +            if ($data['tsdefault']) {
218 +                $this->timestretch = $data['tsdefault'];
219              } else {
220                  $this->timestretch = 1.0;
221              }
222 @@ -387,12 +391,14 @@
223          // Now we really should scan the $Channel array and add a link to this program's channel
224              foreach (array_keys($Channels) as $key) {
225                  if ($Channels[$key]->chanid == $this->chanid) {
226 -                    $this->channel = &$Channels[$key];
227 +                    $this->channel =& $Channels[$key];
228                      break;
229                  }
230              }
231 +        // Not found
232 +            if (!$this->channel)
233 +                $this->channel =& load_one_channel($this->chanid);
234          }
235 -
236      // Calculate the duration
237          if ($this->recendts)
238              $this->length = $this->recendts - $this->recstartts;
239 Index: mythplugins/mythweb/includes/utils.php
240 ===================================================================
241 --- mythplugins/mythweb/includes/utils.php      (.../tags/release-0-19) (revision 10051)
242 +++ mythplugins/mythweb/includes/utils.php      (.../branches/release-0-19-fixes)       (revision 10051)
243 @@ -276,7 +276,7 @@
244          static $first_run=true;
245          if($first_run) {
246              $first_run=false;
247 -            echo '<script type="text/javascript" src="/js/debug.js"></script>';
248 +            echo '<script type="text/javascript" src="'.root.'js/debug.js"></script>';
249          }
250      // Put our data into a string
251          if (is_array($data) || is_object($data))
252 Index: mythplugins/mythweb/includes/init.php
253 ===================================================================
254 --- mythplugins/mythweb/includes/init.php       (.../tags/release-0-19) (revision 10051)
255 +++ mythplugins/mythweb/includes/init.php       (.../branches/release-0-19-fixes)       (revision 10051)
256 @@ -16,28 +16,15 @@
257   *
258  /**/
259  
260 -/**
261 - * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some
262 - * other lesser means.  It contains most of the information required for
263 - * figuring out what functions the user wants to access.
264 - *
265 - * @global  array   $GLOBALS['Path']
266 - * @name    $Path
267 -/**/
268 -    global $Path;
269 -    $Path = explode('/', preg_replace('/^\/+/',   '',    // Remove leading slashes
270 -                         preg_replace('/[\s]+/', ' ',    // Convert extra whitespace
271 -                                                         // Grab the path info from various different places.
272 -                             array_key_exists('PATH_INFO', $_SERVER)
273 -                             && $_SERVER['PATH_INFO']
274 -                                ? $_SERVER['PATH_INFO']
275 -                                : (array_key_exists('PATH_INFO', $_ENV)
276 -                                   && $_ENV['PATH_INFO']
277 -                                    ? $_ENV['PATH_INFO']
278 -                                    : $_GET['PATH_INFO']
279 -                                  )
280 -                         ))
281 -                   );
282 +// mod_redirect can do some weird things when php is run in cgi mode
283 +    $keys = preg_grep('/^REDIRECT_/', array_keys($_SERVER));
284 +    if (!empty($keys)) {
285 +        foreach ($keys as $key) {
286 +            $key = substr($key, 9);
287 +            if (!array_key_exists($key, $_SERVER))
288 +                $_SERVER[$key] = $_SERVER["REDIRECT_$key"];
289 +        }
290 +    }
291  
292  // Clean the document root variable and make sure it doesn't have a trailing slash
293      $_SERVER['DOCUMENT_ROOT'] = preg_replace('/\/+$/', '', $_SERVER['DOCUMENT_ROOT']);
294 @@ -94,6 +81,29 @@
295          exit;
296      }
297  
298 +/**
299 + * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some
300 + * other lesser means.  It contains most of the information required for
301 + * figuring out what functions the user wants to access.
302 + *
303 + * @global  array   $GLOBALS['Path']
304 + * @name    $Path
305 +/**/
306 +    global $Path;
307 +    $Path = explode('/', preg_replace('/^\/+/',   '',    // Remove leading slashes
308 +                         preg_replace('/[\s]+/', ' ',    // Convert extra whitespace
309 +                                                         // Grab the path info from various different places.
310 +                             array_key_exists('PATH_INFO', $_SERVER)
311 +                             && $_SERVER['PATH_INFO']
312 +                                ? $_SERVER['PATH_INFO']
313 +                                : (array_key_exists('PATH_INFO', $_ENV)
314 +                                   && $_ENV['PATH_INFO']
315 +                                    ? $_ENV['PATH_INFO']
316 +                                    : $_GET['PATH_INFO']
317 +                                  )
318 +                         ))
319 +                   );
320 +
321  // Load the database connection routines
322      require_once 'includes/db.php';
323  
324 Index: mythplugins/mythweb/includes/mobile.php
325 ===================================================================
326 --- mythplugins/mythweb/includes/mobile.php     (.../tags/release-0-19) (revision 10051)
327 +++ mythplugins/mythweb/includes/mobile.php     (.../branches/release-0-19-fixes)       (revision 10051)
328 @@ -74,58 +74,56 @@
329       * If you don't know the screensize of some mobile terminal then use
330       * an empty array or approximate dimensions.
331       */
332 -    $mobiles = array(/* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */
333 -             'Series 60' => array('width' => 176, 'height' => 208),
334 -             'Series60' => array('width' => 176, 'height' => 208),
335 -             'C500' => array('width'=>176, 'height'=> 220), // SPV C500
336 +    $mobiles = array(
337 +                /* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */
338 +                     'Series 60' => array('width' => 176, 'height' => 208),
339 +                     'Series60'  => array('width' => 176, 'height' => 208),
340 +                     'C500'      => array('width'=>176, 'height'=> 220), // SPV C500
341 +                /* Phones using the Series 90 platform, e.g. Nokia 7710. */
342 +                     'Series 90' => array('width' => 640, 'height' => 320),
343 +                     'Series90' => array('width' => 640, 'height' => 320),
344 +                /* The following strings are added for the Palm browser WebPro
345 +                 * WebPro sometimes supplies the screen dimensions, but sometimes not
346 +                 * but we try to detect the best as possible */
347 +                     '240x320'    => array('width' => 240, 'height' => 320), // PocketPC IE
348 +                     '320x320'    => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
349 +                     '320x480'    => array('width' => 320, 'height' => 480), // For Palm Tungsten T
350 +                     '480x320'    => array('width' => 480, 'height' => 320), // For Palm Tungsten T
351 +                     '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
352 +                     '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
353 +                     '320x320x16' => array('width' => 320, 'height' => 320),
354 +                     'WebPro'     => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
355 +                 /* A generic mobile phone using Symbian OS. All Symbian phones don't
356 +                  * necessarily have the same screen size so if you want to include
357 +                  * some specific Symbian phones then place them above this line. */
358 +                     'Symbian' => array('width' => 176, 'height' => 208),
359  
360 -             /* Phones using the Series 90 platform, e.g. Nokia 7710. */
361 -             'Series 90' => array('width' => 640, 'height' => 320),
362 -             'Series90' => array('width' => 640, 'height' => 320),
363 +                     'Nokia' => array(), // Nokia phones and emulators
364 +                     'Eric' => array(), // Ericsson WAP phones and emulators
365 +                     'WapI' => array(), // Ericsson WapIDE 2.0
366 +                     'MC21' => array(), // Ericsson MC218
367 +                     'AUR ' => array(), // Ericsson R320
368 +                     'R380' => array(), // Ericsson R380
369 +                     'UP.B' => array(), // UP.Browser
370 +                     'WinW' => array(), // WinWAP browser
371 +                     'UPG1' => array(), // UP.SDK 4.0
372 +                     'upsi' => array(), // another kind of UP.Browser ??
373 +                     'QWAP' => array(), // unknown QWAPPER browser
374 +                     'Jigs' => array(), // unknown JigSaw browser
375 +                     'Java' => array(), // unknown Java based browser
376 +                     'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?)
377 +                     'MITS' => array(), // unknown Mitsubishi browser
378 +                     'MOT-' => array(), // unknown browser (UP based?)
379 +                     'My S' => array(), // unknown Ericsson devkit browser ?
380 +                     'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de
381 +                     'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de
382 +                     'ALAV' => array(), // yet another unknown UP based browser ?
383 +                     'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?)
384 +                     'LGE-' => array(), // LG phones
385  
386 -            /* The following strings are added for the Palm browser WebPro
387 -              * WebPro sometimes supplies the screen dimensions, but sometimes not
388 -             * but we try to detect the best as possible
389 -              */
390 -            '320x480' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
391 -            '480x320' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
392 -            '320x320' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
393 -            '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
394 -            '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
395 -            '320x320x16' => array('width' => 320, 'height' => 320),
396 -            'WebPro' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
397 -
398 -             /* A generic mobile phone using Symbian OS. All Symbian phones don't
399 -              * necessarily have the same screen size so if you want to include
400 -              * some specific Symbian phones then place them above this line. */
401 -             'Symbian' => array('width' => 176, 'height' => 208),
402 -
403 -             'Nokia' => array(), // Nokia phones and emulators
404 -             'Eric' => array(), // Ericsson WAP phones and emulators
405 -             'WapI' => array(), // Ericsson WapIDE 2.0
406 -             'MC21' => array(), // Ericsson MC218
407 -             'AUR ' => array(), // Ericsson R320
408 -             'R380' => array(), // Ericsson R380
409 -             'UP.B' => array(), // UP.Browser
410 -             'WinW' => array(), // WinWAP browser
411 -             'UPG1' => array(), // UP.SDK 4.0
412 -             'upsi' => array(), // another kind of UP.Browser ??
413 -             'QWAP' => array(), // unknown QWAPPER browser
414 -             'Jigs' => array(), // unknown JigSaw browser
415 -             'Java' => array(), // unknown Java based browser
416 -             'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?)
417 -             'MITS' => array(), // unknown Mitsubishi browser
418 -             'MOT-' => array(), // unknown browser (UP based?)
419 -             'My S' => array(), // unknown Ericsson devkit browser ?
420 -             'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de
421 -             'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de
422 -             'ALAV' => array(), // yet another unknown UP based browser ?
423 -             'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?)
424 -             'LGE-' => array(), // LG phones
425 -
426 -             /* For debugging: you can try out the mobile mode without a mobile phone.
427 -              * Replace 'Opera' with your browser. Comment out for release version. */
428 -             //'Opera' => array('width' => 176, 'height' => 208)
429 +                 /* For debugging: you can try out the mobile mode without a mobile phone.
430 +                  * Replace 'Opera' with your browser. Comment out for release version. */
431 +                     //'Opera' => array('width' => 176, 'height' => 208)
432               );
433  
434      /* Scan through $mobiles and try to find matching user agent. */
435 Index: mythplugins/mythweb/includes/recording_schedules.php
436 ===================================================================
437 --- mythplugins/mythweb/includes/recording_schedules.php        (.../tags/release-0-19) (revision 10051)
438 +++ mythplugins/mythweb/includes/recording_schedules.php        (.../branches/release-0-19-fixes)       (revision 10051)
439 @@ -68,10 +68,14 @@
440  // Cleanup
441      mysql_free_result($result);
442  
443 +// Initialize
444 +    global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
445 +    $Scheduled_Recordings = array();
446 +    $Num_Conflicts        = 0;
447 +    $Num_Scheduled        = 0;
448 +
449  // Load all of the scheduled recordings.  We will need them at some point, so we
450  // might as well get it overwith here.
451 -    global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
452 -    $Scheduled_Recordings = array();
453      foreach (get_backend_rows('QUERY_GETALLPENDING', 2) as $key => $program) {
454      // The offset entry
455          if ($key === 'offset') {
456 Index: mythplugins/mythweb/includes/session.php
457 ===================================================================
458 --- mythplugins/mythweb/includes/session.php    (.../tags/release-0-19) (revision 10051)
459 +++ mythplugins/mythweb/includes/session.php    (.../branches/release-0-19-fixes)       (revision 10051)
460 @@ -19,8 +19,8 @@
461  
462  // Start the session
463      session_name('mythweb_id');
464 -    session_set_cookie_params(60 * 60 * 30, '/');       // 30 day timeout on cookies
465 -    ini_set('session.gc_maxlifetime', 60 * 60 * 30);    // ... and sessions
466 +    session_set_cookie_params(60 * 60 * 24 * 365, '/');     // 1 year timeout on cookies
467 +    ini_set('session.gc_maxlifetime', 60 * 60 * 24 * 30);   // 30 day timeout on sessions
468      session_set_save_handler('sess_do_nothing', 'sess_do_nothing', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc');
469      session_start();
470  
471 Index: mythplugins/mythweb/modules/weather/handler.php
472 ===================================================================
473 --- mythplugins/mythweb/modules/weather/handler.php     (.../tags/release-0-19) (revision 10051)
474 +++ mythplugins/mythweb/modules/weather/handler.php     (.../branches/release-0-19-fixes)       (revision 10051)
475 @@ -222,8 +222,10 @@
476  
477      $data = explode("|", $data);
478      for($i = 0;$i<5;$i++) {
479 -        $forecast = new Forecast($data[5 + $i],$data[$i]);
480 -        $forecast->dayofweek = $data[$i];
481 +       # mktime uses 0-6;  msnbc gives us 1-7;  adjust msnbc to match mktime
482 +       $dayofweek = $data[$i] - 1;
483 +        $forecast = new Forecast($data[5 + $i],$dayofweek);
484 +        $forecast->dayofweek = $dayofweek;
485          list($forecast->DescImage,$forecast->DescText) = getImageAndDescFromId($data[15 + $i]);
486          $forecast->DescImage = (strlen($forecast->DescImage) > 0) ? $forecast->DescImage : "unknown.png";
487          $forecast->DescText = (strlen($forecast->DescText) > 0) ? $forecast->DescText : t('Unknown') . " (" . $data[15+$i] . ")";
488 Index: mythplugins/mythweb/modules/status/handler.php
489 ===================================================================
490 --- mythplugins/mythweb/modules/status/handler.php      (.../tags/release-0-19) (revision 10051)
491 +++ mythplugins/mythweb/modules/status/handler.php      (.../branches/release-0-19-fixes)       (revision 10051)
492 @@ -18,14 +18,17 @@
493      $masterhost = get_backend_setting('MasterServerIP');
494      $statusport = get_backend_setting('BackendStatusPort');
495  
496 +// XML mode?
497 +    $xml_param = ($Path[1] == 'xml') ? '/xml' : '';
498 +
499  // Make sure the content is interpreted as UTF-8
500      header('Content-Type:  text/html; charset=UTF-8');
501  
502  // Load the status page
503      if (function_exists('file_get_contents'))
504 -        $status = file_get_contents("http://$masterhost:$statusport");
505 +        $status = file_get_contents("http://$masterhost:$statusport$xml_param");
506      else
507 -        $status = implode("\n", file("http://$masterhost:$statusport"));
508 +        $status = implode("\n", file("http://$masterhost:$statusport$xml_param"));
509  
510  // Extract the page title
511      preg_match('#<title>(.+?)</title>#s', $status, $title);
512 Index: mythplugins/mythweb/modules/backend_log/handler.php
513 ===================================================================
514 --- mythplugins/mythweb/modules/backend_log/handler.php (.../tags/release-0-19) (revision 10051)
515 +++ mythplugins/mythweb/modules/backend_log/handler.php (.../branches/release-0-19-fixes)       (revision 10051)
516 @@ -16,7 +16,7 @@
517  // Where to start searching from
518      $_GET['start'] = intVal($_GET['start']);
519      if ($_GET['start'] < 1)
520 -        $_GET['start'] = 1;
521 +        $_GET['start'] = 0;
522  
523  // How many entries to show?
524      $_GET['show'] = intVal($_GET['show']);
525 Index: mythplugins/mythweb/modules/tv/upcoming.php
526 ===================================================================
527 --- mythplugins/mythweb/modules/tv/upcoming.php (.../tags/release-0-19) (revision 10051)
528 +++ mythplugins/mythweb/modules/tv/upcoming.php (.../branches/release-0-19-fixes)       (revision 10051)
529 @@ -103,8 +103,9 @@
530                          continue;
531                  }
532              // Skip deactivated shows?
533 -                elseif (!$_SESSION['scheduled_recordings']['disp_deactivated']) {
534 -                    continue;
535 +                elseif ($show->recstatus != 'Recording') {
536 +                    if (!$_SESSION['scheduled_recordings']['disp_deactivated'])
537 +                        continue;
538                  }
539              // Assign a reference to this show to the various arrays
540                  $all_shows[] =& $Scheduled_Recordings[$channum][$starttime][$key];
541 Index: mythplugins/mythweb/modules/tv/recorded.php
542 ===================================================================
543 --- mythplugins/mythweb/modules/tv/recorded.php (.../tags/release-0-19) (revision 10051)
544 +++ mythplugins/mythweb/modules/tv/recorded.php (.../branches/release-0-19-fixes)       (revision 10051)
545 @@ -128,9 +128,21 @@
546                  continue;
547          // Get the length (27 == recendts; 26 == recstartts)
548              $length = $record[27] - $record[26];
549 -        // Keep track of the total time and disk space used
550 +        // Keep track of the total time and disk space used (9 == fs_high; 10 == fs_low)
551              $Total_Time += $length;
552 -            $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10];  // 9 == fs_high; 10 == fs_low;
553 +            if (function_exists('gmp_add')) {
554 +            // GMP functions should work better with 64 bit numbers.
555 +                $size = gmp_add($record[10],
556 +                                gmp_mul('4294967296',
557 +                                        gmp_add($record[9], $record[10] < 0 ? '1' : '0')
558 +                                       )
559 +                               );
560 +                $Total_Used = gmp_strval(gmp_add($Total_Used, $size));
561 +            }
562 +            else {
563 +            // This is inaccurate, but it's the best we can get without GMP.
564 +                $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10];
565 +            }
566          // keep track of their names and how many episodes we have recorded
567              $Total_Programs++;
568              $Groups[$record[30]]++;
569 @@ -223,8 +235,28 @@
570  
571  // How much free disk space on the backend machine?
572      list($size_high, $size_low, $used_high, $used_low) = explode(backend_sep, backend_command('QUERY_FREE_SPACE'));
573 -    define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024);
574 -    define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024);
575 +    if (function_exists('gmp_add')) {
576 +    // GMP functions should work better with 64 bit numbers.
577 +        $size = gmp_mul('1024',
578 +                        gmp_add($size_low,
579 +                                gmp_mul('4294967296',
580 +                                        gmp_add($size_high, $size_low < 0 ? '1' : '0'))
581 +                               )
582 +                       );
583 +        define(disk_size, gmp_strval($size));
584 +        $size = gmp_mul('1024',
585 +                        gmp_add($used_low,
586 +                                gmp_mul('4294967296',
587 +                                        gmp_add($used_high, $used_low < 0 ? '1' : '0'))
588 +                               )
589 +                       );
590 +        define(disk_used, gmp_strval($size));
591 +    }
592 +    else {
593 +    // This is inaccurate, but it's the best we can get without GMP.
594 +        define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024);
595 +        define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024);
596 +    }
597  
598  // Load the class for this page
599      require_once theme_dir.'tv/recorded.php';
600 Index: mythplugins/mythweb/.htaccess
601 ===================================================================
602 --- mythplugins/mythweb/.htaccess       (.../tags/release-0-19) (revision 10051)
603 +++ mythplugins/mythweb/.htaccess       (.../branches/release-0-19-fixes)       (revision 10051)
604 @@ -22,6 +22,7 @@
605  #    AuthName           "MythTV"
606  #    AuthDigestFile     /var/www/htdigest
607  #    Require            valid-user
608 +#    BrowserMatch       "MSIE"      AuthDigestEnableQueryStringHack=On
609  
610  # MythTV now uses the correct file suffix for mpeg files, so all .nuv files
611  # should actually be NuppleVideo.  However, apache probably doesn't know what
612 @@ -66,8 +67,6 @@
613  
614          php_value memory_limit                  32M
615  
616 -        php_value session.save_path             php_sessions
617 -
618          php_value output_buffering              4096
619          php_value register_globals              0
620          php_value magic_quotes_gpc              0
621 Index: mythplugins/mythweb/js/debug.js
622 ===================================================================
623 --- mythplugins/mythweb/js/debug.js     (.../tags/release-0-19) (revision 0)
624 +++ mythplugins/mythweb/js/debug.js     (.../branches/release-0-19-fixes)       (revision 10051)
625 @@ -0,0 +1,24 @@
626 +/**
627 + * A random assortment of javascript debug routines
628 + *
629 + * @url         $URL$
630 + * @date        $Date$
631 + * @version     $Revision$
632 + * @author      $Author$
633 + * @copyright   Silicon Mechanics
634 + * @license     LGPL
635 + *
636 + * @package     SiMech
637 + * @subpackage  Javascript
638 + *
639 +/**/
640 +
641 +    var debug_window_handle;
642 +// Create a debug window and debug into it
643 +    function debug_window(string) {
644 +        if (!debug_window_handle || debug_window_handle.closed) {
645 +            debug_window_handle = window.open('', 'Debug Window','scrollbars, resizable, width=400, height=600');
646 +            debug_window_handle.document.write('<html><body style="font-size: 9pt; background-color: #f88;">');
647 +        }
648 +        debug_window_handle.document.write('<pre>'+string+'</pre><hr>');
649 +    }
650
651 Property changes on: mythplugins/mythweb/js/debug.js
652 ___________________________________________________________________
653 Name: svn:eol-style
654    + native
655 Name: svn:mime-type
656    + text/x-javascript
657 Name: svn:keywords
658    + Date Revision Author HeadURL
659
660 Index: mythplugins/mythweb/js/browser.js
661 ===================================================================
662 --- mythplugins/mythweb/js/browser.js   (.../tags/release-0-19) (revision 10051)
663 +++ mythplugins/mythweb/js/browser.js   (.../branches/release-0-19-fixes)       (revision 10051)
664 @@ -215,14 +215,18 @@
665      browser.is_css = (document.body  && document.body.style)
666      browser.is_w3c = (browser.is_css && browser.getElementById)
667  
668 -// Cookie support
669 -    var tmp = document.cookie;
670 -       document.cookie = 'cookies=true';
671 -       browser.cookies = (document.cookie) ? true : false;
672 -    document.cookie = tmp;
673 +// Cookie support -- only create a cookie if there isn't one already.  It seems
674 +// that doing this can override the exipiration info in existing cookies.
675 +    browser.cookies = (document.cookie) ? true : false;
676 +    if (!browser.cookies) {
677 +        var tmp = document.cookie;
678 +        document.cookie = 'cookie_test=true';
679 +        browser.cookies = (document.cookie) ? true : false;
680 +        document.cookie = tmp;
681 +    }
682  
683  // Java support
684 -       browser.java = navigator.javaEnabled();
685 +    browser.java = navigator.javaEnabled();
686  
687  /****************************** Plugin Support ******************************/
688  
689 Index: mythplugins/mythweb/README
690 ===================================================================
691 --- mythplugins/mythweb/README  (.../tags/release-0-19) (revision 10051)
692 +++ mythplugins/mythweb/README  (.../branches/release-0-19-fixes)       (revision 10051)
693 @@ -1,18 +1,12 @@
694  This is the README file for the MythWeb package.
695 -January 17, 2006
696 +March 6, 2006
697  
698 -Version: .19 pre
699 -(c) 2002-2006  Thor Sigvaldason <mythtv(a)lamedomainname(o)com>
700 +Version: .19
701 +(c) 2002-2006  Chris Petersen   <mythweb(a)forevermore(o)net>
702                 Isaac Richards   <ijr(a)po(o)cwru(o)edu>
703 -               Chris Petersen   <mythweb(a)forevermore(o)net>
704 +               Thor Sigvaldason <mythtv(a)lamedomainname(o)com>
705 +               and others... (see mythtv.org commit logs for details)
706  
707 -with contributions from many people including:
708 -
709 -Michael Kedl   <kedlm(a)knology(o)net>
710 -Jonathan Kolb  <jkolb(a)greyshift(o)net
711 -Ed Wildgoose   <edward(o)wildgoose(a)frmhedge(o)com>
712 -Kenneth Aafloy <ke-aa(a)frisurf(o)no>
713 -
714  MythWeb is distributed under the GNU GENERAL PUBLIC LICENSE version 2, and where
715  noted with the @license tag, the LESSER GENERAL PUBLIC LICENSE version 2.
716  Please see http://www.gnu.org for details and the specific text of the license.
717 @@ -63,10 +57,22 @@
718  
719      In order for the included .htaccess to work properly, you will need to
720  set apache's "AllowOverride" setting to "All" (or at least "Options") for
721 -the root mythweb directory.  This directive lives within <Directory/> tags,
722 -so make sure you're changing the setting for the correct directory.  You will
723 -also need to make sure that the following apache modules are enabled:
724 +the root mythweb directory.  This directive lives within <Directory> tags,
725 +so make sure you're changing the setting for the correct directory.  Please
726 +keep in mind that most distros correctly disable everything for <Directory />,
727 +and then later override those with something like <Directory /var/www/html>.
728 +The simplest way to do this is to put a file into /etc/httpd/conf.d (or
729 +whatever your distro calls it) containing something like:
730  
731 +    <Directory "/var/www/html/mythweb" >
732 +        Options         FollowSymLinks
733 +        AllowOverride   All
734 +    </Directory>
735 +
736 +Just make sure that the path points to your MythWeb installation, since that
737 +will likely differ from system to system.  You will also need to make sure that
738 +the following apache modules are enabled:
739 +
740      mod_env
741      mod_rewrite
742  
743 Index: mythplugins/mythdvd/mtd/jobthread.cpp
744 ===================================================================
745 --- mythplugins/mythdvd/mtd/jobthread.cpp       (.../tags/release-0-19) (revision 10051)
746 +++ mythplugins/mythdvd/mtd/jobthread.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
747 @@ -11,6 +11,7 @@
748  #include <sys/types.h>
749  #include <sys/stat.h>
750  #include <fcntl.h>
751 +#include <unistd.h>
752  
753  #include <iostream>
754  using namespace std;
755 Index: mythplugins/mythdvd/mtd/mtd.cpp
756 ===================================================================
757 --- mythplugins/mythdvd/mtd/mtd.cpp     (.../tags/release-0-19) (revision 10051)
758 +++ mythplugins/mythdvd/mtd/mtd.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
759 @@ -8,6 +8,7 @@
760  
761  */
762  
763 +#include <unistd.h>
764  #include <qstringlist.h>
765  #include <qregexp.h>
766  #include <qdir.h>
767 Index: mythplugins/mythdvd/mtd/logging.cpp
768 ===================================================================
769 --- mythplugins/mythdvd/mtd/logging.cpp (.../tags/release-0-19) (revision 10051)
770 +++ mythplugins/mythdvd/mtd/logging.cpp (.../branches/release-0-19-fixes)       (revision 10051)
771 @@ -9,6 +9,7 @@
772  */
773  #include "logging.h"
774  
775 +#include <unistd.h>
776  #include <qdatetime.h>
777  
778  #include <mythtv/mythcontext.h>
779 Index: mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp
780 ===================================================================
781 --- mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp   (.../tags/release-0-19) (revision 10051)
782 +++ mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp   (.../branches/release-0-19-fixes)       (revision 10051)
783 @@ -12,6 +12,7 @@
784  #include "metadata.h"
785  #include "metaiooggvorbiscomment.h"
786  
787 +#include <mythtv/mythconfig.h>
788  #include <mythtv/mythcontext.h>
789  
790  // static functions for OggVorbis
791 @@ -240,8 +241,13 @@
792              seekTime = -1.0;
793          }
794  
795 +#ifdef WORDS_BIGENDIAN
796 +        len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 1, 2, 1,
797 +                      &section);
798 +#else
799          len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1,
800                        &section);
801 +#endif
802  
803          if (len > 0) {
804              bitrate = ov_bitrate_instant(&oggfile) / 1000;
805 Index: mythplugins/mythmusic/mythmusic/flacdecoder.cpp
806 ===================================================================
807 --- mythplugins/mythmusic/mythmusic/flacdecoder.cpp     (.../tags/release-0-19) (revision 10051)
808 +++ mythplugins/mythmusic/mythmusic/flacdecoder.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
809 @@ -12,6 +12,7 @@
810  #include "metadata.h"
811  #include "metaioflacvorbiscomment.h"
812  
813 +#include <mythtv/mythconfig.h>
814  #include <mythtv/mythcontext.h>
815  
816  #include <qtimer.h>
817 @@ -102,7 +103,11 @@
818              for (channel = 0; channel < chan; channel++)
819              {
820                 sample = (FLAC__int8)buffer[channel][cursamp];
821 +#ifdef WORDS_BIGENDIAN
822 +               *(output_buf + output_at++) = ((sample >> 8) & 0xff);
823 +#else
824                 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
825 +#endif
826                 output_bytes += 1;
827              }
828          }   
829 @@ -114,8 +119,13 @@
830              for (channel = 0; channel < chan; channel++)
831              { 
832                 sample = (FLAC__int16)buffer[channel][cursamp];             
833 +#ifdef WORDS_BIGENDIAN
834 +               *(output_buf + output_at++) = ((sample >> 8) & 0xff);
835                 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
836 +#else
837 +               *(output_buf + output_at++) = ((sample >> 0) & 0xff);
838                 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
839 +#endif
840                 output_bytes += 2;
841              }
842          }
843 Index: mythplugins/mythmusic/mythmusic/maddecoder.cpp
844 ===================================================================
845 --- mythplugins/mythmusic/mythmusic/maddecoder.cpp      (.../tags/release-0-19) (revision 10051)
846 +++ mythplugins/mythmusic/mythmusic/maddecoder.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
847 @@ -16,6 +16,7 @@
848  #include <mythtv/audiooutput.h>
849  #include "metaioid3v2.h"
850  
851 +#include <mythtv/mythconfig.h>
852  #include <mythtv/mythcontext.h>
853  
854  #define XING_MAGIC     (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
855 @@ -407,7 +408,7 @@
856          flush(TRUE);
857  
858          if (output()) {
859 -           output()->Drain();
860 +            output()->Drain();
861          }
862  
863          done = TRUE;
864 @@ -488,15 +489,25 @@
865              flush();
866          }
867          sample = fix_sample(16, *left++);
868 +#ifdef WORDS_BIGENDIAN
869 +        *(output_buf + output_at++) = ((sample >> 8) & 0xff);
870          *(output_buf + output_at++) = ((sample >> 0) & 0xff);
871 +#else
872 +        *(output_buf + output_at++) = ((sample >> 0) & 0xff);
873          *(output_buf + output_at++) = ((sample >> 8) & 0xff);
874 +#endif
875          output_bytes += 2;
876  
877          if (channels == 2)
878          {
879              sample = fix_sample(16, *right++);
880 +#ifdef WORDS_BIGENDIAN
881 +            *(output_buf + output_at++) = ((sample >> 8) & 0xff);
882              *(output_buf + output_at++) = ((sample >> 0) & 0xff);
883 +#else
884 +            *(output_buf + output_at++) = ((sample >> 0) & 0xff);
885              *(output_buf + output_at++) = ((sample >> 8) & 0xff);
886 +#endif
887              output_bytes += 2;
888          }
889      }
890 Index: mythplugins/mythweather/mythweather/weather.cpp
891 ===================================================================
892 --- mythplugins/mythweather/mythweather/weather.cpp     (.../tags/release-0-19) (revision 10051)
893 +++ mythplugins/mythweather/mythweather/weather.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
894 @@ -2571,6 +2571,14 @@
895           return false;
896       }
897  
898 +     int imageCount = 5;
899 +     QString imagesList = parseData(tempData, "imagenames = new Array( '", ";");
900 +     if (imagesList != "<NULL>")
901 +     {
902 +         QStringList imageURLs = QStringList::split(",", imagesList);
903 +         imageCount = imageURLs.size();
904 +     }
905 +
906       QString fileprefix = MythContext::GetConfDir();
907  
908       QDir dir(fileprefix);
909 @@ -2587,13 +2595,13 @@
910           cerr << "MythWeather: Map File Prefix: " << fileprefix << endl;
911  
912       // delete existing radar maps
913 -     for (int x = 1; x <= 6; x++)
914 +     for (int x = 1; x <= 10; x++)
915           QFile::remove(QString(fileprefix + "/radar%1.jpg").arg(x));
916  
917       if (debug)
918           cerr << "MythWeather: Copying Map Files from Server (" << imageLoc << ")...\n";
919  
920 -     for (int x = 1; x <= 6; x++)
921 +     for (int x = 1; x <= imageCount; x++)
922       {
923           QString sFile = QString(fileprefix + "/radar%1.jpg").arg(x);
924           sURL = QString("http://image.weather.com" + imageLoc + "%1L.jpg").arg(x);
925 Index: mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp
926 ===================================================================
927 --- mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp      (.../tags/release-0-19) (revision 10051)
928 +++ mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
929 @@ -46,22 +46,6 @@
930  #include "keygrabber.h"
931  
932  
933 -static QMap<int,QString> FindContexts(const QString &context)
934 -{
935 -    QMap<int,QString> retval;
936 -    retval.clear();
937 -    if (context != JUMP_CONTEXT) retval[-1] = JUMP_CONTEXT;
938 -    retval[0] = context;
939 -    if (context != JUMP_CONTEXT && context != GLOBAL_CONTEXT)
940 -    {
941 -        if (context == "TV Editting")
942 -            retval[1] = "TV Playback";
943 -        retval[2] = GLOBAL_CONTEXT;
944 -        if (context != "qt")
945 -            retval[3] = "qt";
946 -    }
947 -    return retval;
948 -}
949  
950  static const QString KeyToDisplay(const QString key)
951  {
952 @@ -838,7 +822,11 @@
953      refreshKeyInformation();
954  }
955  
956 -void MythControls::addBindings(QDict<binding_t> &bindings, const QString &context, const QString &contextParent, int bindlevel)
957 +
958 +
959 +void MythControls::addBindings(QDict<binding_t> &bindings,
960 +                               const QString &context,
961 +                               const QString &contextParent, int bindlevel)
962  {
963      QStringList *actions = key_bindings->getActions(context);
964  
965 @@ -872,18 +860,13 @@
966  
967  BindingList *MythControls::getKeyBindings(const QString &context)
968  {
969 +    QStringList keys;
970      QDict<binding_t> bindings;
971      bindings.clear();
972  
973 -    QMap<int,QString> contextList = FindContexts(context);
974 -    for (QMap<int,QString>::iterator it = contextList.begin(); it != contextList.end(); ++it)
975 -    {
976 -        int level = it.key();
977 -        QString curcontext = it.data();
978 -        addBindings(bindings, curcontext, context, level);
979 -    }
980 +    for (size_t i = 0; i < contexts.size(); i++)
981 +        addBindings(bindings, contexts[i], context, i);
982  
983 -    QStringList keys;
984  
985      for (QDictIterator<binding_t> it(bindings); it.current(); ++it)
986      {
987 Index: mythplugins/mythcontrols/mythcontrols/actionset.cpp
988 ===================================================================
989 --- mythplugins/mythcontrols/mythcontrols/actionset.cpp (.../tags/release-0-19) (revision 10051)
990 +++ mythplugins/mythcontrols/mythcontrols/actionset.cpp (.../branches/release-0-19-fixes)       (revision 10051)
991 @@ -139,13 +139,19 @@
992  /* method description in header */
993  QStringList * ActionSet::actionStrings(const QString &context_name) const
994  {
995 -    QStringList *action_strings = new QStringList();
996 -    QDictIterator<Action> it(*(_contexts[context_name]));
997 +    Context *c = _contexts[context_name];
998  
999 -    for (; it.current(); ++it)
1000 -        action_strings->append(it.currentKey());
1001 +    if (c == NULL) return NULL;
1002 +    else
1003 +    {
1004 +        QStringList *action_strings = new QStringList();
1005 +        QDictIterator<Action> it(*(_contexts[context_name]));
1006 +
1007 +        for (; it.current(); ++it)
1008 +            action_strings->append(it.currentKey());
1009      
1010 -    return action_strings;
1011 +        return action_strings;
1012 +    }
1013  }
1014  
1015  
1016 Index: mythplugins/mythcontrols/mythcontrols/keybindings.h
1017 ===================================================================
1018 --- mythplugins/mythcontrols/mythcontrols/keybindings.h (.../tags/release-0-19) (revision 10051)
1019 +++ mythplugins/mythcontrols/mythcontrols/keybindings.h (.../branches/release-0-19-fixes)       (revision 10051)
1020 @@ -65,6 +65,8 @@
1021      /**
1022       * @brief Get a list of the context names.
1023       * @return A list of the context names.
1024 +     * @note The returned list is a copy and can be modified without
1025 +     * side-effects.
1026       */
1027      inline QStringList * getContexts() const
1028      {
1029 Index: mythplugins/mythvideo/mythvideo/videomanager.h
1030 ===================================================================
1031 --- mythplugins/mythvideo/mythvideo/videomanager.h      (.../tags/release-0-19) (revision 10051)
1032 +++ mythplugins/mythvideo/mythvideo/videomanager.h      (.../branches/release-0-19-fixes)       (revision 10051)
1033 @@ -30,7 +30,7 @@
1034    public:
1035      VideoManager(MythMainWindow *parent, const char *name = 0);
1036      ~VideoManager(void);
1037 -    void VideoManager::processEvents() { qApp->processEvents(); }
1038 +    void processEvents() { qApp->processEvents(); }
1039      
1040    public slots:
1041      void slotManualIMDB();
1042 Index: mythplugins/mythvideo/mythvideo/videoselected.h
1043 ===================================================================
1044 --- mythplugins/mythvideo/mythvideo/videoselected.h     (.../tags/release-0-19) (revision 10051)
1045 +++ mythplugins/mythvideo/mythvideo/videoselected.h     (.../branches/release-0-19-fixes)       (revision 10051)
1046 @@ -35,7 +35,7 @@
1047      VideoSelected(VideoList *lvideolist,
1048                   MythMainWindow *parent, const char *name = 0, int index = 0);
1049      ~VideoSelected();
1050 -    void VideoSelected::processEvents() { qApp->processEvents(); }
1051 +    void processEvents() { qApp->processEvents(); }
1052      
1053  
1054    protected slots:
1055 Index: mythplugins/mythphone/mythphone/sipfsm.h
1056 ===================================================================
1057 --- mythplugins/mythphone/mythphone/sipfsm.h    (.../tags/release-0-19) (revision 10051)
1058 +++ mythplugins/mythphone/mythphone/sipfsm.h    (.../branches/release-0-19-fixes)       (revision 10051)
1059 @@ -618,7 +618,7 @@
1060      SipWatcher *CreateWatcherFsm(QString Url);
1061      SipIM *CreateIMFsm(QString Url="", QString callIdStr="");
1062      void StopWatchers();
1063 -    void SipFsm::KickWatcher(SipUrl *Url);
1064 +    void KickWatcher(SipUrl *Url);
1065      void SendIM(QString destUrl, QString CallId, QString imMsg);
1066      int numCalls();
1067      int getPrimaryCall() { return primaryCall; };
1068 Index: mythplugins/mythphone/mythphone/vxml.h
1069 ===================================================================
1070 --- mythplugins/mythphone/mythphone/vxml.h      (.../tags/release-0-19) (revision 10051)
1071 +++ mythplugins/mythphone/mythphone/vxml.h      (.../branches/release-0-19-fixes)       (revision 10051)
1072 @@ -10,7 +10,7 @@
1073  {
1074    public:
1075      vxmlVariable(QString N, QString V);             
1076 -    vxmlVariable::vxmlVariable(QString N, short *wav, int S);
1077 +    vxmlVariable(QString N, short *wav, int S);
1078      virtual ~vxmlVariable() {}; 
1079      bool isType(QString t) { return (t == Type); };
1080      QString getName() { return Name; };
1081 Index: mythplugins/mythgame/mythgame/gamehandler.h
1082 ===================================================================
1083 --- mythplugins/mythgame/mythgame/gamehandler.h (.../tags/release-0-19) (revision 10051)
1084 +++ mythplugins/mythgame/mythgame/gamehandler.h (.../branches/release-0-19-fixes)       (revision 10051)
1085 @@ -106,7 +106,7 @@
1086  
1087    protected:
1088      static GameHandler* GetHandler(RomInfo *rominfo);
1089 -    static GameHandler* GameHandler::GetHandlerByName(QString systemname);
1090 +    static GameHandler* GetHandlerByName(QString systemname);
1091  
1092      bool rebuild;
1093      int spandisks;
1094 Index: mythplugins/mythnews/mythnews/news-sites.xml
1095 ===================================================================
1096 --- mythplugins/mythnews/mythnews/news-sites.xml        (.../tags/release-0-19) (revision 10051)
1097 +++ mythplugins/mythnews/mythnews/news-sites.xml        (.../branches/release-0-19-fixes)       (revision 10051)
1098 @@ -119,7 +119,7 @@
1099  
1100      <item>
1101          <title>Slashdot</title>
1102 -        <url>http://slashdot.org/slashdot.rss</url>
1103 +        <url>http://rss.slashdot.org/Slashdot/slashdot</url>
1104          <ico>http://slashdot.org/favicon.ico</ico>
1105      </item>
1106  
1107 Index: mythtv/libs/libmythtv/NuppelVideoPlayer.h
1108 ===================================================================
1109 --- mythtv/libs/libmythtv/NuppelVideoPlayer.h   (.../tags/release-0-19) (revision 10051)
1110 +++ mythtv/libs/libmythtv/NuppelVideoPlayer.h   (.../branches/release-0-19-fixes)       (revision 10051)
1111 @@ -150,7 +150,8 @@
1112      // Complicated gets
1113      long long CalcMaxFFTime(long long ff, bool setjump = true) const;
1114      long long CalcRWTime(long long rw) const;
1115 -    void      calcSliderPos(struct StatusPosInfo &posInfo);
1116 +    void      calcSliderPos(struct StatusPosInfo &posInfo,
1117 +                            bool paddedFields = false);
1118  
1119      /// Non-const gets
1120      OSD         *GetOSD(void)                 { return osd; }
1121 @@ -543,6 +544,7 @@
1122      QMap<long long, int>::Iterator deleteIter;
1123      QMap<long long, int>::Iterator blankIter;
1124      QMap<long long, int>::Iterator commBreakIter;
1125 +    bool       forcePositionMapSync;
1126  
1127      // Playback (output) speed control
1128      /// Lock for next_play_speed and next_normal_speed
1129 Index: mythtv/libs/libmythtv/osdlistbtntype.h
1130 ===================================================================
1131 --- mythtv/libs/libmythtv/osdlistbtntype.h      (.../tags/release-0-19) (revision 10051)
1132 +++ mythtv/libs/libmythtv/osdlistbtntype.h      (.../branches/release-0-19-fixes)       (revision 10051)
1133 @@ -1,3 +1,4 @@
1134 +// -*- Mode: c++ -*-
1135  /* ============================================================
1136   * File  : uilistbtntype.h
1137   * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
1138 @@ -22,38 +23,57 @@
1139  #ifndef OSDLISTBTNTYPE_H
1140  #define OSDLISTBTNTYPE_H
1141  
1142 -#include "osdtypes.h"
1143 -#include "ttfont.h"
1144 +#include <vector>
1145 +using namespace std;
1146 +
1147 +// Qt headers
1148  #include <qcolor.h>
1149  #include <qptrlist.h>
1150  #include <qevent.h>
1151  #include <qmutex.h>
1152 +#include <qptrvector.h>
1153 +
1154 +// MythTV headers
1155 +#include "osdtypes.h"
1156 +#include "ttfont.h"
1157  #include "generictree.h"
1158  
1159 +class OSDListBtnType;
1160  class OSDListBtnTypeItem;
1161 -class OSDListBtnType;
1162 +typedef vector<OSDListBtnType*> OSDListBtnList;
1163 +typedef vector<OSDListBtnTypeItem*> OSDListBtnItemList;
1164  
1165  class OSDGenericTree : public GenericTree
1166  {
1167    public:
1168      // This class will _not_ delete the image it's given, if any.
1169 -    OSDGenericTree(OSDGenericTree *parent, const QString &name, 
1170 -                   const QString &action = "", int check = -1, 
1171 -                   OSDTypeImage *image = NULL, QString group = "");
1172 +    OSDGenericTree(OSDGenericTree *parent,        const QString &name, 
1173 +                   const QString  &action = "",   int            check = -1, 
1174 +                   OSDTypeImage   *image  = NULL, QString        group = "") :
1175 +        GenericTree(name), m_image(image),     m_action(action),
1176 +        m_group(group),    m_checkable(check), m_parentButton(NULL)
1177 +    {
1178 +        m_group = (m_group.isEmpty()) ? action : m_group;
1179 +        setSelectable(!action.isEmpty());
1180 +        if (parent)
1181 +            parent->addNode(this);
1182 +    }
1183  
1184 -    OSDTypeImage *getImage(void) { return m_image; }
1185 -    QString getAction(void) { return m_action; }
1186 -    int getCheckable(void) { return m_checkable; }
1187 -    QString getGroup(void) { return m_group; }
1188 +    QString getAction(void)    const { return m_action;    }
1189 +    QString getGroup(void)     const { return m_group;     }
1190 +    int     getCheckable(void) const { return m_checkable; }
1191 +
1192 +    OSDTypeImage       *getImage(void)        { return m_image;        }
1193 +    OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; }
1194 +
1195      void setParentButton(OSDListBtnTypeItem *button)
1196 -                         { m_parentButton = button; };
1197 -    OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; };
1198 +        { m_parentButton = button; }
1199  
1200    private:
1201 -    OSDTypeImage *m_image;
1202 -    QString m_action;
1203 -    int m_checkable;
1204 -    QString m_group;
1205 +    OSDTypeImage       *m_image;
1206 +    QString             m_action;
1207 +    QString             m_group;
1208 +    int                 m_checkable;
1209      OSDListBtnTypeItem *m_parentButton;
1210  };
1211  
1212 @@ -62,53 +82,49 @@
1213  {
1214      Q_OBJECT
1215    public:
1216 -    OSDListTreeType(const QString &name, const QRect &area, 
1217 -                    const QRect &levelsize, int levelspacing,
1218 -                    float wmult, float hmult);
1219 +    OSDListTreeType(const QString &name,      const QRect &area,
1220 +                    const QRect   &levelsize, int          levelspacing,
1221 +                    float          wmult,     float        hmult);
1222 +    ~OSDListTreeType();
1223  
1224 -    void Reinit(float wchange, float hchange, float wmult, float hmult);
1225 +    bool IsVisible(void)          const { return m_visible;  }
1226
1227 +    void SetFontActive(TTFFont *font)   { m_active   = font; }
1228 +    void SetFontInactive(TTFFont *font) { m_inactive = font; }
1229 +
1230      void SetGroupCheckState(QString group, int newState = 0);
1231 +    void SetSpacing(uint spacing)
1232 +        { m_unbiasedspacing = (m_spacing = spacing) / m_wmult; }
1233 +    void SetMargin(uint margin)
1234 +        { m_unbiasedmargin  = (m_margin  = margin)  / m_wmult; }
1235 +    void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha)
1236 +        { m_itemRegBeg = beg; m_itemRegEnd = end; m_itemRegAlpha = alpha; }
1237 +    void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha)
1238 +        { m_itemSelBeg = beg; m_itemSelEnd = end; m_itemSelAlpha = alpha; }
1239 +    void SetVisible(bool visible) { m_visible = visible; }
1240 +    void SetAsTree(OSDGenericTree *toplevel, vector<uint> *select = NULL);
1241  
1242 -    void SetFontActive(TTFFont *font);
1243 -    void SetFontInactive(TTFFont *font);
1244 -    void SetSpacing(int spacing);
1245 -    void SetMargin(int margin);
1246 -    void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha);
1247 -    void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha);
1248 -
1249 -    void SetAsTree(OSDGenericTree *toplevel);
1250 -
1251 -    OSDGenericTree *GetCurrentPosition(void);
1252
1253 +    void Reinit(float wmult, float hmult);
1254      bool HandleKeypress(QKeyEvent *e);
1255 -
1256      void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
1257  
1258 -    bool IsVisible(void) { return m_visible; }
1259 -    void SetVisible(bool visible) { m_visible = visible; }
1260 -
1261    signals:
1262      void itemSelected(OSDListTreeType *parent, OSDGenericTree *item);
1263      void itemEntered(OSDListTreeType *parent, OSDGenericTree *item);
1264  
1265    private:
1266 -    void FillLevelFromTree(OSDGenericTree *item, OSDListBtnType *list);
1267 -    OSDListBtnType *GetLevel(int levelnum);
1268 -    void SetCurrentPosition(void);
1269 +    void FillLevelFromTree(OSDGenericTree *item, uint levelnum);
1270 +    OSDListBtnType *GetLevel(uint levelnum);
1271 +    void EnterItem(void);
1272 +    void SelectItem(void);
1273  
1274 -    int levels;
1275 -    int curlevel;
1276 -
1277      OSDGenericTree *treetop;
1278      OSDGenericTree *currentpos;
1279 +    TTFFont        *m_active;
1280 +    TTFFont        *m_inactive;
1281  
1282 -    QPtrList<OSDListBtnType> listLevels;
1283 +    OSDListBtnList  listLevels;
1284  
1285 -    OSDListBtnType *currentlevel;
1286 -
1287 -    TTFFont *m_active;
1288 -    TTFFont *m_inactive;
1289 -
1290      QColor    m_itemRegBeg;
1291      QColor    m_itemRegEnd;
1292      QColor    m_itemSelBeg;
1293 @@ -116,62 +132,76 @@
1294      uint      m_itemRegAlpha;
1295      uint      m_itemSelAlpha;
1296     
1297 -    int m_spacing;
1298 -    int m_margin;
1299 +    uint      m_spacing;
1300 +    uint      m_margin;
1301 +    int       m_levelspacing;
1302  
1303 -    QRect m_totalarea;
1304 -    QRect m_levelsize;
1305 -    int m_levelspacing;
1306 +    QRect     m_totalarea;
1307 +    QRect     m_levelsize;
1308  
1309 -    float m_wmult;
1310 -    float m_hmult;
1311 +    float     m_unbiasedspacing;
1312 +    float     m_unbiasedmargin;
1313 +    QRect     m_unbiasedarea;
1314 +    QRect     m_unbiasedsize;
1315  
1316 -    bool m_visible;
1317 -    bool m_arrowAccel;
1318 +    float     m_wmult;
1319 +    float     m_hmult;
1320 +
1321 +    int       m_depth;
1322 +    int       m_levelnum;
1323 +    bool      m_visible;
1324 +    bool      m_arrowAccel;
1325  };
1326   
1327  class OSDListBtnType : public OSDType
1328  {
1329 +    friend class OSDListBtnTypeItem;
1330      Q_OBJECT
1331 +
1332    public:
1333      OSDListBtnType(const QString &name, const QRect& area,
1334                     float wmult, float hmult,
1335                     bool showScrollArrows = false);
1336      ~OSDListBtnType();
1337  
1338 -    void  Reinit(float wchange, float hchange, float wmult, float hmult);
1339 +    // General Gets
1340 +    bool  IsVisible() const { return m_visible; }
1341 +
1342 +    // General Sets
1343 +    void  SetFontActive(TTFFont *font)   { m_fontActive   = font;    }
1344 +    void  SetFontInactive(TTFFont *font) { m_fontInactive = font;    }
1345 +    void  SetSpacing(int spacing)        { m_itemSpacing  = spacing; }
1346 +    void  SetMargin(int margin)          { m_itemMargin   = margin;  }
1347 +    void  SetActive(bool active)         { m_active       = active;  }
1348 +    void  SetVisible(bool vis)           { m_visible = vis; }
1349 +    void  SetItemRegColor(const QColor& beg, const QColor& end, uint alpha)
1350 +        { m_itemRegBeg = beg; m_itemRegEnd = end; m_itemRegAlpha = alpha; }
1351 +    void  SetItemSelColor(const QColor& beg, const QColor& end, uint alpha)
1352 +        { m_itemSelBeg = beg; m_itemSelEnd = end; m_itemSelAlpha = alpha; }
1353      void  SetGroupCheckState(QString group, int newState = 0);
1354 +    void  SetItemCurrent(const OSDListBtnTypeItem* item);
1355 +    void  SetItemCurrent(uint pos);
1356  
1357 -    void  SetFontActive(TTFFont *font);
1358 -    void  SetFontInactive(TTFFont *font);
1359 -    void  SetSpacing(int spacing);
1360 -    void  SetMargin(int margin);
1361 -    void  SetItemRegColor(const QColor& beg, const QColor& end, uint alpha);
1362 -    void  SetItemSelColor(const QColor& beg, const QColor& end, uint alpha);
1363 -    
1364 -    void  Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
1365 -
1366 -    void  SetActive(bool active);
1367 -    void  Reset();
1368 -
1369 -    void  SetItemCurrent(OSDListBtnTypeItem* item);
1370 -    void  SetItemCurrent(int pos);
1371 -    OSDListBtnTypeItem* GetItemCurrent();
1372 -    OSDListBtnTypeItem* GetItemFirst();
1373 -    OSDListBtnTypeItem* GetItemNext(OSDListBtnTypeItem *item);
1374 +    // Item Gets
1375 +    int   GetCount(void) const;
1376 +    int   GetItemPos(const OSDListBtnTypeItem* item) const;
1377 +    int   GetItemCurrentPos() const;
1378 +    OSDListBtnTypeItem* GetItemCurrent(void);
1379 +    OSDListBtnTypeItem* GetItemFirst(void);
1380 +    OSDListBtnTypeItem* GetItemNext(const OSDListBtnTypeItem *item);
1381      OSDListBtnTypeItem* GetItemAt(int pos);
1382 -    int   GetItemPos(OSDListBtnTypeItem* item);
1383 -    int   GetCount();
1384  
1385 -    void  MoveDown();
1386 -    void  MoveUp();
1387 +    // Item Sets/Commands
1388 +    void  MoveDown(void);
1389 +    void  MoveUp(void);
1390  
1391 -    bool  IsVisible() { return m_visible; }
1392 -    void  SetVisible(bool vis) { m_visible = vis; }
1393 +    // General Commands
1394 +    void  Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
1395 +    void  Reinit(float,float) {}
1396 +    void  Reset(void);
1397  
1398    private:
1399 -
1400 -    void  Init();
1401 +    void  Init(void);
1402      void  InitItem(OSDTypeImage &osdImg, uint width, uint height,
1403                     QColor beg, QColor end, int alpha);
1404      void  LoadPixmap(OSDTypeImage& pix, const QString& fileName);
1405 @@ -179,24 +209,35 @@
1406      void  InsertItem(OSDListBtnTypeItem *item);
1407      void  RemoveItem(OSDListBtnTypeItem *item);
1408  
1409 -    int   m_order;
1410 -    QRect m_rect;
1411 -    QRect m_contentsRect;
1412 -    QRect m_arrowsRect;
1413 +  private:
1414 +    int            m_order;
1415 +    QRect          m_rect;
1416 +    QRect          m_contentsRect;
1417 +    QRect          m_arrowsRect;
1418  
1419 -    float m_wmult;
1420 -    float m_hmult;
1421 +    float          m_wmult;
1422 +    float          m_hmult;
1423  
1424 -    int   m_itemHeight;
1425 -    int   m_itemSpacing;
1426 -    int   m_itemMargin;
1427 -    uint  m_itemsVisible;
1428 +    int            m_itemHeight;
1429 +    int            m_itemSpacing;
1430 +    int            m_itemMargin;
1431 +    uint           m_itemsVisible;
1432  
1433 -    bool  m_active;
1434 -    bool  m_showScrollArrows;
1435 -    bool  m_showUpArrow;
1436 -    bool  m_showDnArrow;
1437 +    bool           m_active;
1438 +    bool           m_showScrollArrows;
1439 +    bool           m_showUpArrow;
1440 +    bool           m_showDnArrow;
1441 +    bool           m_initialized;
1442 +    bool           m_clearing;
1443 +    bool           m_visible;
1444  
1445 +    QColor         m_itemRegBeg;
1446 +    QColor         m_itemRegEnd;
1447 +    QColor         m_itemSelBeg;
1448 +    QColor         m_itemSelEnd;
1449 +    uint           m_itemRegAlpha;
1450 +    uint           m_itemSelAlpha;
1451 +
1452      OSDTypeImage   m_itemRegPix;
1453      OSDTypeImage   m_itemSelActPix;
1454      OSDTypeImage   m_itemSelInactPix;
1455 @@ -209,43 +250,30 @@
1456      OSDTypeImage   m_checkHalfPix;
1457      OSDTypeImage   m_checkFullPix;
1458  
1459 -    QColor    m_itemRegBeg;
1460 -    QColor    m_itemRegEnd;
1461 -    QColor    m_itemSelBeg;
1462 -    QColor    m_itemSelEnd;
1463 -    uint      m_itemRegAlpha;
1464 -    uint      m_itemSelAlpha;
1465 +    TTFFont       *m_fontActive;
1466 +    TTFFont       *m_fontInactive;
1467  
1468 -    TTFFont* m_fontActive;
1469 -    TTFFont* m_fontInactive;
1470 +    int            m_topIndx;
1471 +    int            m_selIndx;
1472  
1473 -    bool      m_initialized;
1474 -    bool      m_clearing;
1475 +    OSDListBtnItemList m_itemList;
1476  
1477 -    OSDListBtnTypeItem* m_topItem;
1478 -    OSDListBtnTypeItem* m_selItem;
1479 -    QPtrList<OSDListBtnTypeItem> m_itemList;
1480 +    mutable QMutex m_update;
1481  
1482 -    QMutex    m_update;
1483 -
1484 -    bool      m_visible;
1485 -
1486 -    friend class OSDListBtnTypeItem;
1487 -    
1488    signals:
1489 -
1490      void itemSelected(OSDListBtnTypeItem* item);
1491  };
1492  
1493  class OSDListBtnTypeItem
1494  {
1495 +    friend class OSDListBtnType;
1496  
1497    public:
1498 -
1499 -    enum CheckState {
1500 -        NotChecked=0,
1501 +    enum CheckState
1502 +    {
1503 +        NotChecked  = 0,
1504          HalfChecked,
1505 -        FullChecked
1506 +        FullChecked,
1507      };
1508  
1509      OSDListBtnTypeItem(OSDListBtnType* lbtype, const QString& text,
1510 @@ -253,41 +281,36 @@
1511                         bool showArrow = false, CheckState state = NotChecked);
1512      ~OSDListBtnTypeItem();
1513  
1514 -    OSDListBtnType*   parent() const;
1515 -    QString           text() const;
1516 -    const OSDTypeImage*   pixmap() const;
1517 -    bool              checkable() const;
1518 -    CheckState        state() const;
1519 +    OSDListBtnType*     parent(void)    const { return m_parent;    }
1520 +    QString             text(void)      const { return m_text;      }
1521 +    const OSDTypeImage* pixmap(void)    const { return m_pixmap;    }
1522 +    bool                checkable(void) const { return m_checkable; }
1523 +    CheckState          state(void)     const { return m_state;     }
1524 +    QString             getGroup(void)  const { return m_group;     }
1525 +    void               *getData(void)         { return m_data;      }
1526  
1527 -    void  setChecked(CheckState state);
1528 -    void  setData(void *data);
1529 -    void* getData();
1530 -    void  setGroup(QString group) { m_group = group; };
1531 -    QString getGroup(void) { return m_group; }
1532 +    void setData(void *data)          { m_data = data; }
1533 +    void setGroup(QString grp)        { m_group = grp; }
1534 +    void setChecked(CheckState state)
1535 +        { m_state = (m_checkable) ? state : m_state; }
1536  
1537 -    void  Reinit(float wchange, float hchange, float wmult, float hmult);
1538 -    
1539 +    void  Reinit(float,float) {}
1540      void  paint(OSDSurface *surface, TTFFont *font, int fade, int maxfade, 
1541                  int x, int y);
1542      
1543    protected:
1544 -
1545      OSDListBtnType *m_parent;
1546 -    QString        m_text;
1547 -    OSDTypeImage  *m_pixmap;
1548 -    bool           m_checkable;
1549 -    CheckState     m_state;
1550 -    void          *m_data;
1551 -    QString        m_group;
1552 -
1553 -    QRect          m_checkRect;
1554 -    QRect          m_pixmapRect;
1555 -    QRect          m_textRect;
1556 -    QRect          m_arrowRect;
1557 -
1558 -    bool           m_showArrow;    
1559 -
1560 -    friend class OSDListBtnType;
1561 +    OSDTypeImage   *m_pixmap;
1562 +    void           *m_data;
1563 +    QString         m_text;
1564 +    QString         m_group;
1565 +    CheckState      m_state;
1566 +    bool            m_showArrow;
1567 +    bool            m_checkable;
1568 +    QRect           m_checkRect;
1569 +    QRect           m_arrowRect;
1570 +    QRect           m_pixmapRect;
1571 +    QRect           m_textRect;
1572  };
1573  
1574  
1575 Index: mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
1576 ===================================================================
1577 --- mythtv/libs/libmythtv/NuppelVideoPlayer.cpp (.../tags/release-0-19) (revision 10051)
1578 +++ mythtv/libs/libmythtv/NuppelVideoPlayer.cpp (.../branches/release-0-19-fixes)       (revision 10051)
1579 @@ -147,6 +147,7 @@
1580        hascommbreaktable(false),
1581        deleteIter(deleteMap.end()),  blankIter(blankMap.end()),
1582        commBreakIter(commBreakMap.end()),
1583 +      forcePositionMapSync(false),
1584        // Playback (output) speed control
1585        decoder_lock(true),
1586        next_play_speed(1.0f),        next_normal_speed(true),
1587 @@ -747,6 +748,8 @@
1588          SetDecoder(new IvtvDecoder(this, m_playbackinfo));
1589          no_audio_out = true; // no audio with ivtv.
1590          audio_bits = 16;
1591 +        audio_samplerate = 44100;
1592 +        audio_channels = 2;
1593      }
1594      else if (forceVideoOutput == kVideoOutput_IVTV)
1595      {
1596 @@ -1113,7 +1116,7 @@
1597  const unsigned char *NuppelVideoPlayer::GetScaledFrame(QSize &size)
1598  {
1599      QMutexLocker locker(&yuv_lock);
1600 -    yuv_desired_size = size = QSize(size.width() & ~0x3, size.height() & ~0x3);
1601 +    yuv_desired_size = size = QSize(size.width() & ~0x7, size.height() & ~0x7);
1602  
1603      if ((size.width() > 0) && (size.height() > 0))
1604      {
1605 @@ -1920,7 +1923,7 @@
1606          ShowText();
1607          DisplaySubtitles();
1608      }
1609 -    else if (osdHasSubtitles || nonDisplayedSubtitles.size() > 20)
1610 +    else if (osdHasSubtitles)
1611      {
1612          ClearSubtitles();
1613      }
1614 @@ -2176,7 +2179,10 @@
1615      }
1616  
1617      if (eof)
1618 +    {
1619          discontinuity = true;
1620 +        ClearSubtitles();
1621 +    }
1622  
1623      livetvchain->SetProgram(pginfo);
1624  
1625 @@ -2199,6 +2205,7 @@
1626      }
1627      if (IsErrored())
1628      {
1629 +        VERBOSE(VB_IMPORTANT, LOC_ERR + "SwitchToProgram failed.");
1630          eof = true;
1631          return;
1632      }
1633 @@ -2265,6 +2272,8 @@
1634      ringBuffer->Pause();
1635      ringBuffer->WaitForPause();
1636  
1637 +    ClearSubtitles();
1638 +
1639      livetvchain->SetProgram(pginfo);
1640  
1641      ringBuffer->Reset(true);
1642 @@ -2284,6 +2293,7 @@
1643  
1644      if (errored || !GetDecoder())
1645      {
1646 +        VERBOSE(VB_IMPORTANT, LOC_ERR + "JumpToProgram failed.");
1647          errored = true;
1648          return;
1649      }
1650 @@ -2471,6 +2481,12 @@
1651                  JumpToProgram();
1652          }
1653  
1654 +        if (forcePositionMapSync)
1655 +        {
1656 +            forcePositionMapSync = false;
1657 +            GetDecoder()->SyncPositionMap();
1658 +        }
1659 +
1660          if (IsErrored() || (nvr_enc && nvr_enc->GetErrorStatus()))
1661          {
1662              VERBOSE(VB_IMPORTANT, LOC_ERR + "Unknown error, exiting decoder");
1663 @@ -4398,6 +4414,8 @@
1664      hascommbreaktable = !commBreakMap.isEmpty();
1665      SetCommBreakIter();
1666      commBreakMapLock.unlock();
1667 +
1668 +    forcePositionMapSync = true;
1669  }
1670  
1671  bool NuppelVideoPlayer::RebuildSeekTable(bool showPercentage, StatusCallback cb, void* cbData)
1672 @@ -4541,7 +4559,8 @@
1673      return (int)((float)(written - played) / video_frame_rate);
1674  }
1675  
1676 -void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo)
1677 +void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo,
1678 +                                      bool paddedFields)
1679  {
1680      posInfo.desc = "";
1681      posInfo.position = 0;
1682 @@ -4588,15 +4607,23 @@
1683      int ssecs = (playbackLen - shours * 3600 - smins * 60);
1684  
1685      QString text1, text2;
1686 -    if (shours > 0)
1687 +    if (paddedFields)
1688      {
1689 -        text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
1690 -        text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
1691 +        text1.sprintf("%02d:%02d:%02d", phours, pmins, psecs);
1692 +        text2.sprintf("%02d:%02d:%02d", shours, smins, ssecs);
1693      }
1694      else
1695      {
1696 -        text1.sprintf("%d:%02d", pmins, psecs);
1697 -        text2.sprintf("%d:%02d", smins, ssecs);
1698 +        if (shours > 0)
1699 +        {
1700 +            text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
1701 +            text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
1702 +        }
1703 +        else
1704 +        {
1705 +            text1.sprintf("%d:%02d", pmins, psecs);
1706 +            text2.sprintf("%d:%02d", smins, ssecs);
1707 +        }
1708      }
1709  
1710      posInfo.desc = QObject::tr("%1 of %2").arg(text1).arg(text2);
1711 @@ -4654,6 +4681,7 @@
1712  
1713              if (commBreakIter.key() == totalFrames)
1714              {
1715 +                VERBOSE(VB_IMPORTANT, LOC + "Skipping commercial to end of file");
1716                  eof = true;
1717              }
1718              else
1719 @@ -4721,7 +4749,7 @@
1720  
1721          QString message = "COMMFLAG_REQUEST ";
1722          message += m_playbackinfo->chanid + " " +
1723 -                   m_playbackinfo->startts.toString(Qt::ISODate);
1724 +                   m_playbackinfo->recstartts.toString(Qt::ISODate);
1725          RemoteSendMessage(message);
1726  
1727          return false;
1728 @@ -5018,7 +5046,7 @@
1729                  QImage scaledImage = qImage.smoothScale(rect->w, rect->h);
1730  
1731                  OSDTypeImage* image = new OSDTypeImage();
1732 -                image->SetPosition(QPoint(rect->x, rect->y));
1733 +                image->SetPosition(QPoint(rect->x, rect->y), hmult, vmult);
1734                  image->LoadFromQImage(scaledImage);
1735  
1736                  subtitleOSD->AddType(image);
1737 Index: mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
1738 ===================================================================
1739 --- mythtv/libs/libmythtv/NuppelVideoRecorder.cpp       (.../tags/release-0-19) (revision 10051)
1740 +++ mythtv/libs/libmythtv/NuppelVideoRecorder.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
1741 @@ -216,7 +216,10 @@
1742      }
1743  
1744      if (mpa_codec)
1745 +    {
1746 +        QMutexLocker locker(&avcodeclock);
1747          avcodec_close(mpa_ctx);
1748 +    }
1749  
1750      if (mpa_ctx)
1751          av_free(mpa_ctx);
1752 @@ -453,8 +456,11 @@
1753          useavcodec = true;
1754  
1755      if (mpa_codec)
1756 +    {
1757 +        QMutexLocker locker(&avcodeclock);
1758          avcodec_close(mpa_ctx);
1759 -    
1760 +    }
1761 +
1762      if (mpa_ctx)
1763          av_free(mpa_ctx);
1764      mpa_ctx = NULL;
1765 @@ -626,13 +632,14 @@
1766      int frag, blocksize = 4096;
1767      int tmp;
1768  
1769 +    if (!skipdevice)
1770 +    {
1771  #if !defined (HAVE_SYS_SOUNDCARD_H) && !defined(HAVE_SOUNDCARD_H)
1772 -    VERBOSE(VB_IMPORTANT, QString("NVR::AudioInit() This Unix doesn't support"
1773 -                                  " device files for audio access. Skipping"));
1774 -    return 1;
1775 +        VERBOSE(VB_IMPORTANT,
1776 +                QString("NVR::AudioInit() This Unix doesn't support"
1777 +                        " device files for audio access. Skipping"));
1778 +        return 1;
1779  #else
1780 -    if (!skipdevice)
1781 -    {
1782          if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK)))
1783          {
1784              VERBOSE(VB_IMPORTANT, QString("NVR: Error, cannot open DSP '%1'").
1785 @@ -678,8 +685,8 @@
1786          }
1787  
1788          close(afd);
1789 +#endif
1790      }
1791 -#endif
1792  
1793      audio_bytes_per_sample = audio_channels * audio_bits / 8;
1794      blocksize *= 4;
1795 Index: mythtv/libs/libmythtv/osdlistbtntype.cpp
1796 ===================================================================
1797 --- mythtv/libs/libmythtv/osdlistbtntype.cpp    (.../tags/release-0-19) (revision 10051)
1798 +++ mythtv/libs/libmythtv/osdlistbtntype.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
1799 @@ -19,206 +19,148 @@
1800   * 
1801   * ============================================================ */
1802  
1803 -#include <iostream>
1804 +// ANSI C headers
1805 +#include <cmath>
1806  
1807 +// C++ headers
1808 +#include <algorithm>
1809 +using namespace std;
1810 +
1811 +// Qt headers
1812  #include <qapplication.h>
1813  #include <qpixmap.h>
1814  #include <qpainter.h>
1815  #include <qimage.h>
1816  #include <qcolor.h>
1817  
1818 +// MythTV headers
1819  #include "mythcontext.h"
1820  #include "mythdialogs.h"
1821 -
1822  #include "osdlistbtntype.h"
1823  
1824 +#define LOC QString("OSDListTreeType: ")
1825 +#define LOC_ERR QString("OSDListTreeType, Error: ")
1826  
1827 -OSDGenericTree::OSDGenericTree(OSDGenericTree *parent, const QString &name, 
1828 -                               const QString &action, int check, 
1829 -                               OSDTypeImage *image, QString group)
1830 -              : GenericTree(name)
1831 +static QRect unbias(QRect rect, float wmult, float hmult)
1832  {
1833 -    m_checkable = check;
1834 -    m_action = action;
1835 -    m_image = image;
1836 -    m_parentButton = NULL;
1837 -
1838 -    if (group != "")
1839 -        m_group = group;
1840 -    else
1841 -        m_group = action;
1842 -
1843 -    if (!action.isEmpty() && !action.isNull())
1844 -        setSelectable(true);
1845 -
1846 -    if (parent)
1847 -        parent->addNode(this);
1848 +    return QRect((int)round(rect.x()      / wmult),
1849 +                 (int)round(rect.y()      / hmult),
1850 +                 (int)ceil( rect.width()  / wmult),
1851 +                 (int)ceil( rect.height() / hmult));
1852  }
1853  
1854 -////////////////////////////////////////////////////////////////////////////
1855 -
1856 -OSDListTreeType::OSDListTreeType(const QString &name, const QRect &area,
1857 -                                 const QRect &levelsize, int levelspacing,
1858 -                                 float wmult, float hmult)
1859 -               : OSDType(name)
1860 +static QRect bias(QRect rect, float wmult, float hmult)
1861  {
1862 -    m_wmult = wmult;
1863 -    m_hmult = hmult;
1864 -
1865 -    m_totalarea = area;
1866 -    m_levelsize = levelsize;
1867 -    m_levelspacing = levelspacing;
1868 -
1869 -    if (gContext->GetNumSetting("UseArrowAccels", 1))
1870 -        m_arrowAccel = true;
1871 -    else
1872 -        m_arrowAccel = false;
1873 -    
1874 -    levels = 0;
1875 -    curlevel = -1;
1876 -
1877 -    treetop = NULL;
1878 -    currentpos = NULL;
1879 -
1880 -    currentlevel = NULL;
1881 -
1882 -    listLevels.setAutoDelete(true);
1883 -
1884 -    m_active = NULL;
1885 -    m_inactive = NULL;
1886 -
1887 -    SetItemRegColor(Qt::black,QColor(80,80,80),100);
1888 -    SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
1889 -
1890 -    m_spacing = 0;
1891 -    m_margin = 0;
1892 +    return QRect((int)round(rect.x()      * wmult),
1893 +                 (int)round(rect.y()      * hmult),
1894 +                 (int)ceil( rect.width()  * wmult),
1895 +                 (int)ceil( rect.height() * hmult));
1896  }
1897  
1898 -void OSDListTreeType::Reinit(float wchange, float hchange, float wmult,
1899 -                             float hmult)
1900 +OSDListTreeType::OSDListTreeType(
1901 +    const QString &name,      const QRect &area,
1902 +    const QRect   &levelsize, int          levelspacing,
1903 +    float          wmult,     float        hmult)
1904 +    : OSDType(name),
1905 +      treetop(NULL),                    currentpos(NULL),
1906 +      m_active(NULL),                   m_inactive(NULL),
1907 +      m_itemRegBeg(Qt::black),          m_itemRegEnd(QColor(80,80,80)),
1908 +      m_itemSelBeg(QColor(82,202,56)),  m_itemSelEnd(QColor(52,152,56)),
1909 +      m_itemRegAlpha(100),              m_itemSelAlpha(255),
1910 +      m_spacing(0),                     m_margin(0),
1911 +      m_levelspacing(levelspacing),
1912 +      m_totalarea(area),                m_levelsize(levelsize),
1913 +      m_unbiasedspacing(1.0f),          m_unbiasedmargin(1.0f),
1914 +      m_unbiasedarea(0,0,0,0),          m_unbiasedsize(0,0,0,0),
1915 +      m_wmult(wmult),                   m_hmult(hmult),
1916 +      m_depth(0),                        m_levelnum(-1),
1917 +      m_visible(true),
1918 +      m_arrowAccel(gContext->GetNumSetting("UseArrowAccels", 1))
1919  {
1920 -    m_wmult = wmult;
1921 -    m_hmult = hmult;
1922 -
1923 -    m_spacing = (int)(m_spacing * wchange);
1924 -    m_margin = (int)(m_margin * wchange);
1925 -
1926 -    int width = (int)(m_totalarea.width() * wchange);
1927 -    int height = (int)(m_totalarea.height() * hchange);
1928 -    int x = (int)(m_totalarea.x() * wchange);
1929 -    int y = (int)(m_totalarea.y() * hchange);
1930 -
1931 -    m_totalarea = QRect(x, y, width, height);
1932 -
1933 -    width = (int)(m_levelsize.width() * wchange);
1934 -    height = (int)(m_levelsize.height() * hchange);
1935 -    x = (int)(m_levelsize.x() * wchange);
1936 -    y = (int)(m_levelsize.y() * hchange);
1937 -
1938 -    m_levelsize = QRect(x, y, width, height);
1939 -
1940 -    QPtrListIterator<OSDListBtnType> it(listLevels);
1941 -    OSDListBtnType *child;
1942 -
1943 -    while ((child = it.current()) != 0)
1944 -    {
1945 -        child->Reinit(wchange, hchange, wmult, hmult);
1946 -        ++it;
1947 -    }
1948 +    m_wmult        = (wmult == 0.0f) ? 1.0f : wmult;
1949 +    m_hmult        = (hmult == 0.0f) ? 1.0f : hmult;
1950 +    m_unbiasedarea = unbias(area,      wmult, hmult);
1951 +    m_unbiasedsize = unbias(levelsize, wmult, hmult);
1952  }
1953  
1954 -void OSDListTreeType::SetGroupCheckState(QString group, int newState)
1955 +OSDListTreeType::~OSDListTreeType()
1956  {
1957 -    QPtrListIterator<OSDListBtnType> it(listLevels);
1958 -    OSDListBtnType *child;
1959 -    while ((child = it.current()) != 0)
1960 -    {
1961 -        child->SetGroupCheckState(group, newState);
1962 -        ++it;
1963 -    }
1964 +    OSDListBtnList::iterator it = listLevels.begin();
1965 +    for (; it != listLevels.end(); ++it)
1966 +        delete *it;    
1967  }
1968  
1969 -void OSDListTreeType::SetItemRegColor(const QColor& beg, const QColor& end,
1970 -                                      uint alpha)
1971 +void OSDListTreeType::Reinit(float wmult, float hmult)
1972  {
1973 -    m_itemRegBeg   = beg;
1974 -    m_itemRegEnd   = end;
1975 -    m_itemRegAlpha = alpha;
1976 -}
1977 +    m_wmult     = (wmult == 0.0f) ? 1.0f : wmult;
1978 +    m_hmult     = (hmult == 0.0f) ? 1.0f : hmult;
1979 +    m_spacing   = (uint) round(m_unbiasedspacing * wmult);
1980 +    m_margin    = (uint) round(m_unbiasedmargin  * wmult);
1981 +    m_totalarea = bias(m_unbiasedarea, wmult, hmult);
1982 +    m_levelsize = bias(m_unbiasedsize, wmult, hmult);
1983  
1984 -void OSDListTreeType::SetItemSelColor(const QColor& beg, const QColor& end,
1985 -                                      uint alpha)
1986 -{
1987 -    m_itemSelBeg   = beg;
1988 -    m_itemSelEnd   = end;
1989 -    m_itemSelAlpha = alpha;
1990 -}
1991 +    if (!treetop || m_levelnum < 0)
1992 +        return;
1993  
1994 -void OSDListTreeType::SetFontActive(TTFFont *font)
1995 -{
1996 -    m_active = font;
1997 -}
1998 +    // Save item indices
1999 +    vector<uint> list;
2000 +    for (uint i = 0; i <= (uint)m_levelnum; i++)
2001 +        list.push_back(listLevels[i]->GetItemCurrentPos());
2002  
2003 -void OSDListTreeType::SetFontInactive(TTFFont *font)
2004 -{
2005 -    m_inactive = font;
2006 -}
2007 +    // Delete old OSD items
2008 +    OSDListBtnList clone = listLevels;
2009 +    listLevels.clear();
2010 +    OSDListBtnList::iterator it = clone.begin();
2011 +    for (; it != clone.end(); ++it)
2012 +        delete *it;
2013  
2014 -void OSDListTreeType::SetSpacing(int spacing)
2015 -{
2016 -    m_spacing = spacing;
2017 +    // Create new OSD items
2018 +    SetAsTree(treetop, &list);
2019  }
2020  
2021 -void OSDListTreeType::SetMargin(int margin)
2022 +void OSDListTreeType::SetGroupCheckState(QString group, int newState)
2023  {
2024 -    m_margin = margin;
2025 +    OSDListBtnList::iterator it = listLevels.begin();
2026 +    for (; it != listLevels.end(); ++it)
2027 +        (*it)->SetGroupCheckState(group, newState);
2028  }
2029  
2030 -void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel)
2031 +void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel,
2032 +                                vector<uint> *select_list)
2033  {
2034      if (treetop)
2035      {
2036          listLevels.clear();
2037 -        currentlevel = NULL;
2038 -        treetop = NULL;
2039 -        currentpos = NULL;
2040 -        levels = 0;
2041 -        curlevel = -1;
2042 +        treetop      = NULL;
2043 +        currentpos   = NULL;
2044 +        m_depth      = 0;
2045 +        m_levelnum   = -1;
2046      }
2047  
2048 -    levels = toplevel->calculateDepth(0) - 1;
2049 -
2050 -    if (levels <= 0)
2051 +    m_depth = toplevel->calculateDepth(0) - 1;
2052 +    if (m_depth <= 0)
2053      {
2054 -        cerr << "Need at least one level\n";
2055 +        VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need at least one level");
2056          return;
2057      }
2058  
2059 -    currentpos = (OSDGenericTree *)toplevel->getChildAt(0);
2060 -
2061 +    currentpos = (OSDGenericTree*) toplevel->getChildAt(0);
2062      if (!currentpos)
2063      {
2064 -        cerr << "No top-level children?\n";
2065 +        VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need top-level children");
2066          return;
2067      }
2068  
2069 -    treetop = toplevel;
2070 -
2071 -    // just for now, remove later
2072 -    if (levels > 2)
2073 -        levels = 3;
2074 -
2075 -    for (int i = 0; i < levels; i++)
2076 +    // Create OSD buttons for all levels
2077 +    for (uint i = 0; i < (uint)m_depth; i++)
2078      {
2079          QString levelname = QString("level%1").arg(i + 1);
2080 -
2081          QRect curlevelarea = m_levelsize;
2082          curlevelarea.moveBy(m_totalarea.x(), m_totalarea.y());
2083 -
2084          curlevelarea.moveBy((m_levelsize.width() + m_levelspacing) * i, 0);
2085  
2086 -        OSDListBtnType *newlevel = new OSDListBtnType(levelname, curlevelarea,
2087 -                                                      m_wmult, m_hmult, true);
2088 +        OSDListBtnType *newlevel = new OSDListBtnType(
2089 +            levelname, curlevelarea, m_wmult, m_hmult, true);
2090  
2091          newlevel->SetFontActive(m_active);
2092          newlevel->SetFontInactive(m_inactive);
2093 @@ -227,229 +169,200 @@
2094          newlevel->SetSpacing(m_spacing);
2095          newlevel->SetMargin(m_margin);
2096  
2097 -        listLevels.append(newlevel);
2098 +        listLevels.push_back(newlevel);
2099      }
2100  
2101 -    currentlevel = GetLevel(0);
2102 +    // Set up needed levels and selects
2103 +    vector<uint> slist;
2104 +    slist.push_back(0);
2105 +    if (select_list)
2106 +        slist = *select_list;
2107  
2108 -    if (!currentlevel)
2109 +    currentpos = treetop = toplevel;
2110 +    for (m_levelnum = 0; m_levelnum < (int)slist.size(); m_levelnum++)
2111      {
2112 -        cerr << "Something is seriously wrong (currentlevel = NULL)\n";
2113 -        return;
2114 +        FillLevelFromTree(currentpos, m_levelnum);
2115 +        GetLevel(m_levelnum)->SetActive(true);
2116 +        GetLevel(m_levelnum)->SetVisible(true);
2117 +        if (slist[m_levelnum])
2118 +            GetLevel(m_levelnum)->SetItemCurrent(slist[m_levelnum]);
2119 +        EnterItem(); // updates currentpos
2120      }
2121 -
2122 -    FillLevelFromTree(toplevel, currentlevel);
2123 -
2124 -    currentlevel->SetVisible(true);
2125 -    currentlevel->SetActive(true);
2126 -
2127 -    currentpos = (OSDGenericTree *)(currentlevel->GetItemFirst()->getData());
2128 -    curlevel = 0;
2129 -
2130 -    emit itemEntered(this, currentpos);
2131 +    m_levelnum--;
2132  }
2133  
2134 -OSDGenericTree *OSDListTreeType::GetCurrentPosition(void)
2135 +static bool has_action(QString action, const QStringList &actions)
2136  {
2137 -    return currentpos;
2138 +    QStringList::const_iterator it;
2139 +    for (it = actions.begin(); it != actions.end(); ++it)
2140 +    {
2141 +        if (action == *it)
2142 +            return true;
2143 +    }
2144 +    return false;
2145  }
2146  
2147  bool OSDListTreeType::HandleKeypress(QKeyEvent *e)
2148  {
2149 -    if (!currentlevel)
2150 +    QStringList actions;
2151 +    bool ok = gContext->GetMainWindow()->TranslateKeyPress(
2152 +        "TV Playback", e, actions);
2153 +
2154 +    if (!ok || ((uint)m_levelnum >= listLevels.size()))
2155          return false;
2156 +    else if (has_action("UP", actions))
2157 +    {
2158 +        GetLevel(m_levelnum)->MoveUp();
2159 +        EnterItem();
2160 +    }
2161 +    else if (has_action("DOWN", actions))
2162 +    {
2163 +        GetLevel(m_levelnum)->MoveDown();
2164 +        EnterItem();
2165 +    }
2166 +    else if (has_action("LEFT", actions) && (m_levelnum > 0))
2167 +    {
2168 +        GetLevel(m_levelnum)->Reset();
2169 +        GetLevel(m_levelnum)->SetVisible(false);
2170  
2171 -    bool handled = false;
2172 -    QStringList actions;
2173 -    if (gContext->GetMainWindow()->TranslateKeyPress("TV Playback", e, 
2174 -                                                     actions))
2175 +        m_levelnum--;
2176 +        EnterItem();
2177 +    }
2178 +    else if ((has_action("LEFT", actions) && m_arrowAccel) ||
2179 +             has_action("ESCAPE",   actions) ||
2180 +             has_action("CLEAROSD", actions) ||
2181 +             has_action("MENU",     actions))
2182      {
2183 -        for (unsigned int i = 0; i < actions.size() && !handled; i++)
2184 -        {
2185 -            QString action = actions[i];
2186 -            handled = true;
2187 +        m_visible = false;
2188 +    }
2189 +    else if (has_action("RIGHT", actions) &&
2190 +             (m_levelnum + 1 < m_depth) &&
2191 +             (currentpos->childCount() > 0))
2192 +    {
2193 +        GetLevel(m_levelnum)->SetActive(false);
2194 +        m_levelnum++;
2195  
2196 -            if (action == "UP")
2197 -            {
2198 -                currentlevel->MoveUp();
2199 -                SetCurrentPosition();
2200 -            }
2201 -            else if (action == "DOWN")
2202 -            {
2203 -                currentlevel->MoveDown();
2204 -                SetCurrentPosition();
2205 -            }
2206 -            else if (action == "LEFT")
2207 -            {
2208 -                if (curlevel > 0)
2209 -                {
2210 -                    currentlevel->Reset();
2211 -                    currentlevel->SetVisible(false);
2212 -
2213 -                    curlevel--;
2214 -
2215 -                    currentlevel = GetLevel(curlevel);
2216 -                    currentlevel->SetActive(true);
2217 -                    SetCurrentPosition();
2218 -                }
2219 -                else if (m_arrowAccel)
2220 -                {
2221 -                    m_visible = false;
2222 -                }
2223 -            }
2224 -            else if (action == "RIGHT")
2225 -            {
2226 -                // FIXME: create new levels if needed..
2227 -                if (curlevel + 1 < levels && currentpos->childCount() > 0)
2228 -                {
2229 -                    currentlevel->SetActive(false);
2230 -
2231 -                    curlevel++;
2232 -
2233 -                    currentlevel = GetLevel(curlevel);
2234 -
2235 -                    FillLevelFromTree(currentpos, currentlevel);
2236 -
2237 -                    currentlevel->SetVisible(true);
2238 -                    currentlevel->SetActive(true);
2239 -                    SetCurrentPosition();
2240 -                }
2241 -                else if (m_arrowAccel)
2242 -                {
2243 -                    SetGroupCheckState(currentpos->getGroup(),
2244 -                                       OSDListBtnTypeItem::NotChecked);
2245 -                    currentpos->getParentButton()->setChecked(
2246 -                                       OSDListBtnTypeItem::FullChecked);
2247 -                    emit itemSelected(this, currentpos);
2248 -                }
2249 -            }
2250 -            else if (action == "ESCAPE" || action == "MENU" ||
2251 -                     action == "CLEAROSD")
2252 -                m_visible = false;
2253 -            else if (action == "SELECT")
2254 -            {
2255 -                SetGroupCheckState(currentpos->getGroup(),
2256 -                                   OSDListBtnTypeItem::NotChecked);
2257 -                currentpos->getParentButton()->setChecked(
2258 -                                   OSDListBtnTypeItem::FullChecked);
2259 -                emit itemSelected(this, currentpos);
2260 -            }
2261 -            else
2262 -                handled = false;
2263 -        }
2264 +        FillLevelFromTree(currentpos, m_levelnum);
2265 +        GetLevel(m_levelnum)->SetVisible(true);
2266 +        EnterItem();
2267      }
2268 +    else if ((has_action("RIGHT", actions) && m_arrowAccel) ||
2269 +             has_action("SELECT", actions))
2270 +    {
2271 +        SelectItem();
2272 +    }
2273 +    else
2274 +    {
2275 +        return false;
2276 +    }
2277  
2278 -    return handled;
2279 +    return true;
2280  }
2281  
2282  void OSDListTreeType::Draw(OSDSurface *surface, int fade, int maxfade, 
2283                             int xoff, int yoff)
2284  {
2285 -    QPtrListIterator<OSDListBtnType> it(listLevels);
2286 -    OSDListBtnType *child;
2287 -
2288 -    while ((child = it.current()) != 0)
2289 -    {
2290 -        child->Draw(surface, fade, maxfade, xoff, yoff);
2291 -        ++it;
2292 -    }
2293 +    OSDListBtnList::iterator it = listLevels.begin();
2294 +    for (; it != listLevels.end(); ++it)
2295 +        (*it)->Draw(surface, fade, maxfade, xoff, yoff);
2296  }
2297  
2298  void OSDListTreeType::FillLevelFromTree(OSDGenericTree *item, 
2299 -                                        OSDListBtnType *list)
2300 +                                        uint level_num)
2301  {
2302 +    OSDListBtnType *list = GetLevel(level_num);
2303      if (!list)
2304      {
2305 -        VERBOSE(VB_IMPORTANT, "OSDListTreeType::FillLevelFromTree() "
2306 -                "called with no list. Ignoring call.");
2307 +        VERBOSE(VB_IMPORTANT, LOC_ERR + "FillLevelFromTree() "
2308 +                "called with no list, ignoring.");
2309          return;
2310      }
2311      list->Reset();
2312  
2313      QPtrList<GenericTree> *itemlist = item->getAllChildren();
2314 -
2315      QPtrListIterator<GenericTree> it(*itemlist);
2316 -    GenericTree *child;
2317  
2318 -    while ((child = it.current()) != 0)
2319 +    OSDGenericTree     *child   = (OSDGenericTree*) it.current();
2320 +    OSDListBtnTypeItem *newitem = NULL;
2321 +    for (;(child = (OSDGenericTree*) it.current()); ++it)
2322      {
2323 -        OSDGenericTree *osdchild = (OSDGenericTree *)child;
2324 +        OSDTypeImage *im = child->getImage();
2325 +        QString label    = child->getString();
2326 +        QString group    = child->getGroup();
2327 +        bool    canCheck = child->getCheckable() >= 0;
2328 +        bool    hasCheck = child->getCheckable() == 1;
2329 +        bool    hasChild = child->childCount()   >  0;
2330  
2331 -        OSDListBtnTypeItem *newitem;
2332 -        newitem = new OSDListBtnTypeItem(list, child->getString(),
2333 -                                         osdchild->getImage(), 
2334 -                                         (osdchild->getCheckable() >= 0),
2335 -                                         (child->childCount() > 0));
2336 -        if (osdchild->getCheckable() == 1)
2337 +        newitem = new OSDListBtnTypeItem(list, label, im, canCheck, hasChild);
2338 +
2339 +        if (hasCheck)
2340              newitem->setChecked(OSDListBtnTypeItem::FullChecked);
2341 -        newitem->setGroup(osdchild->getGroup());
2342 -        newitem->setData(osdchild);
2343 -        osdchild->setParentButton(newitem);
2344 +        newitem->setGroup(group);
2345 +        newitem->setData(child);
2346  
2347 -        ++it;
2348 +        child->setParentButton(newitem);
2349      }
2350  }
2351  
2352 -OSDListBtnType *OSDListTreeType::GetLevel(int levelnum)
2353 +OSDListBtnType *OSDListTreeType::GetLevel(uint levelnum)
2354  {
2355 -    if ((uint)levelnum > listLevels.count())
2356 -    {
2357 -        cerr << "OOB GetLevel call\n";
2358 -        return NULL;
2359 -    }
2360 +    if (levelnum < listLevels.size())
2361 +        return listLevels[levelnum];
2362  
2363 -    return listLevels.at(levelnum);
2364 +    VERBOSE(VB_IMPORTANT, LOC_ERR + "GetLevel("<<levelnum<<") "
2365 +            "listLevels.size() is only "<<listLevels.size());
2366 +    return NULL;
2367  }
2368  
2369 -void OSDListTreeType::SetCurrentPosition(void)
2370 +void OSDListTreeType::EnterItem(void)
2371  {
2372 -    if (!currentlevel)
2373 +    if ((uint)m_levelnum >= listLevels.size())
2374          return;
2375  
2376 -    OSDListBtnTypeItem *lbt = currentlevel->GetItemCurrent();
2377 +    listLevels[m_levelnum]->SetActive(true);
2378 +    OSDListBtnTypeItem *lbt = listLevels[m_levelnum]->GetItemCurrent();
2379 +    if (lbt)
2380 +    {
2381 +        currentpos = (OSDGenericTree*) (lbt->getData());
2382 +        emit itemEntered(this, currentpos);
2383 +    }
2384 +}
2385  
2386 -    if (!lbt)
2387 +void OSDListTreeType::SelectItem(void)
2388 +{
2389 +    if (!currentpos)
2390          return;
2391  
2392 -    currentpos = (OSDGenericTree *)(lbt->getData());
2393 -    emit itemEntered(this, currentpos);
2394 +    SetGroupCheckState(currentpos->getGroup(), OSDListBtnTypeItem::NotChecked);
2395 +    currentpos->getParentButton()->setChecked(OSDListBtnTypeItem::FullChecked);
2396 +    emit itemSelected(this, currentpos);
2397  }
2398
2399 +
2400 +#undef LOC_ERR
2401 +#undef LOC
2402 +
2403  //////////////////////////////////////////////////////////////////////////
2404  
2405  OSDListBtnType::OSDListBtnType(const QString &name, const QRect &area,
2406                                 float wmult, float hmult,
2407                                 bool showScrollArrows)
2408 -              : OSDType(name)
2409 +    : OSDType(name),
2410 +      m_order(0),                       m_rect(area),
2411 +      m_contentsRect(0,0,0,0),          m_arrowsRect(0,0,0,0),
2412 +      m_wmult(wmult),                   m_hmult(hmult),
2413 +      m_itemHeight(0),                  m_itemSpacing(0),
2414 +      m_itemMargin(0),                  m_itemsVisible(0),
2415 +      m_active(false),                  m_showScrollArrows(showScrollArrows),
2416 +      m_showUpArrow(false),             m_showDnArrow(false),
2417 +      m_initialized(false),             m_clearing(false),
2418 +      m_visible(false),
2419 +      m_itemRegBeg(Qt::black),          m_itemRegEnd(QColor(80,80,80)),
2420 +      m_itemSelBeg(QColor(82,202,56)),  m_itemSelEnd(QColor(52,152,56)),
2421 +      m_itemRegAlpha(100),              m_itemSelAlpha(255),
2422 +      m_fontActive(NULL),               m_fontInactive(NULL),
2423 +      m_topIndx(0),                     m_selIndx(0),
2424 +      m_update(true)
2425  {
2426 -    m_rect             = area;
2427 -
2428 -    m_wmult            = wmult;
2429 -    m_hmult            = hmult;
2430 -
2431 -    m_showScrollArrows = showScrollArrows;
2432 -
2433 -    m_active           = false;
2434 -    m_showUpArrow      = false;
2435 -    m_showDnArrow      = false;
2436 -
2437 -    m_itemList.setAutoDelete(false);
2438 -    m_topItem = 0;
2439 -    m_selItem = 0;
2440 -
2441 -    m_initialized     = false;
2442 -    m_clearing        = false;
2443 -    m_itemSpacing     = 0;
2444 -    m_itemMargin      = 0;
2445 -    m_itemHeight      = 0;
2446 -    m_itemsVisible    = 0;
2447 -    m_fontActive      = 0;
2448 -    m_fontInactive    = 0;
2449 -
2450 -    SetItemRegColor(Qt::black,QColor(80,80,80),100);
2451 -    SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
2452 -
2453 -    m_visible = false;
2454  }
2455  
2456  OSDListBtnType::~OSDListBtnType()
2457 @@ -457,316 +370,198 @@
2458      Reset();
2459  }
2460  
2461 -void OSDListBtnType::Reinit(float wchange, float hchange, float wmult,
2462 -                            float hmult)
2463 -{
2464 -    m_wmult = wmult;
2465 -    m_hmult = hmult;
2466 -
2467 -    m_itemHeight = (int)(m_itemHeight * hchange);
2468 -    m_itemSpacing = (int)(m_itemSpacing * wchange);
2469 -    m_itemMargin = (int)(m_itemMargin * wchange);
2470 -
2471 -    int width = (int)(m_rect.width() * wchange);
2472 -    int height = (int)(m_rect.height() * hchange);
2473 -    int x = (int)(m_rect.x() * wchange);
2474 -    int y = (int)(m_rect.y() * hchange);
2475 -
2476 -    m_rect = QRect(x, y, width, height);
2477 -
2478 -    Init();
2479 -
2480 -    OSDListBtnTypeItem* item = 0;
2481 -    for (item = m_itemList.first(); item; item = m_itemList.next()) {
2482 -        item->Reinit(wchange, hchange, wmult, hmult);
2483 -    }
2484 -
2485 -}
2486 -
2487  void OSDListBtnType::SetGroupCheckState(QString group, int newState)
2488  {
2489 -    OSDListBtnTypeItem* item = 0;
2490 -    for (item = m_itemList.first(); item; item = m_itemList.next()) {
2491 -        if (item->getGroup() == group)
2492 -            item->setChecked((OSDListBtnTypeItem::CheckState)newState);
2493 -    }
2494 +    OSDListBtnItemList::iterator it;
2495 +    for (it = m_itemList.begin(); it != m_itemList.end(); ++it)
2496 +        if ((*it)->getGroup() == group)
2497 +            (*it)->setChecked((OSDListBtnTypeItem::CheckState) newState);
2498  }
2499  
2500 -void OSDListBtnType::SetItemRegColor(const QColor& beg, const QColor& end, 
2501 -                                     uint alpha)
2502 +void OSDListBtnType::Reset(void)
2503  {
2504 -    m_itemRegBeg   = beg;
2505 -    m_itemRegEnd   = end;
2506 -    m_itemRegAlpha = alpha;
2507 -}
2508 -
2509 -void OSDListBtnType::SetItemSelColor(const QColor& beg, const QColor& end,
2510 -                                     uint alpha)
2511 -{
2512 -    m_itemSelBeg   = beg;
2513 -    m_itemSelEnd   = end;
2514 -    m_itemSelAlpha = alpha;
2515 -}
2516 -
2517 -void OSDListBtnType::SetFontActive(TTFFont *font)
2518 -{
2519 -    m_fontActive   = font;
2520 -}
2521 -
2522 -void OSDListBtnType::SetFontInactive(TTFFont *font)
2523 -{
2524 -    m_fontInactive = font;
2525 -}
2526 -
2527 -void OSDListBtnType::SetSpacing(int spacing)
2528 -{
2529 -    m_itemSpacing = spacing;    
2530 -}
2531 -
2532 -void OSDListBtnType::SetMargin(int margin)
2533 -{
2534 -    m_itemMargin = margin;    
2535 -}
2536 -
2537 -void OSDListBtnType::SetActive(bool active)
2538 -{
2539 -    m_active = active;
2540 -}
2541 -
2542 -void OSDListBtnType::Reset()
2543 -{
2544      QMutexLocker lock(&m_update);
2545  
2546      m_clearing = true;
2547 -
2548 -    OSDListBtnTypeItem* item = 0;
2549 -    for (item = m_itemList.first(); item; item = m_itemList.next()) {
2550 -        delete item;
2551 -    }
2552 -
2553 -    m_clearing = false;
2554 +    OSDListBtnItemList::iterator it;
2555 +    OSDListBtnItemList clone = m_itemList;
2556      m_itemList.clear();
2557 -    
2558 -    m_topItem     = 0;
2559 -    m_selItem     = 0;
2560 +    for (it = clone.begin(); it != clone.end(); ++it)
2561 +        delete (*it);
2562 +    m_clearing = false;
2563 +
2564 +    m_topIndx     = 0;
2565 +    m_selIndx     = 0;
2566      m_showUpArrow = false;
2567      m_showDnArrow = false;
2568  }
2569  
2570  void OSDListBtnType::InsertItem(OSDListBtnTypeItem *item)
2571  {
2572 -    OSDListBtnTypeItem* lastItem = m_itemList.last();
2573 -    m_itemList.append(item);
2574 -
2575 -    if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2576 -        m_showDnArrow = true;
2577 -    else
2578 -        m_showDnArrow = false;
2579 -
2580 -    if (!lastItem) 
2581 -    {
2582 -        m_topItem = item;
2583 -        m_selItem = item;
2584 +    QMutexLocker lock(&m_update);
2585 +    m_itemList.push_back(item);
2586 +    m_showDnArrow = m_showScrollArrows && m_itemList.size() > m_itemsVisible;
2587 +    if (m_itemList.size() == 1)
2588          emit itemSelected(item);
2589 -    }
2590  }
2591  
2592 +int find(const OSDListBtnItemList &list, const OSDListBtnTypeItem *item)
2593 +{
2594 +    for (uint i = 0; i < list.size(); i++)
2595 +        if (list[i] == item)
2596 +            return i;
2597 +    return -1;
2598 +}
2599 +
2600  void OSDListBtnType::RemoveItem(OSDListBtnTypeItem *item)
2601  {
2602 +    QMutexLocker lock(&m_update);
2603      if (m_clearing)
2604          return;
2605 -    
2606 -    if (m_itemList.find(item) == -1)
2607 +
2608 +    int i = find(m_itemList, item);
2609 +    if (i < 0)
2610          return;
2611  
2612 -    m_topItem = m_itemList.first();
2613 -    m_selItem = m_itemList.first();
2614 +    m_itemList.erase(m_itemList.begin()+i);
2615  
2616 -    m_itemList.remove(item);
2617 -
2618      m_showUpArrow = false;
2619 -    
2620 -    if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2621 -        m_showDnArrow = true;
2622 -    else
2623 -        m_showDnArrow = false;
2624 +    m_showDnArrow = m_itemList.size() > m_itemsVisible;
2625 +    m_selIndx     = 0;
2626 +    m_topIndx     = 0;
2627  
2628 -    if (m_selItem) {
2629 -        emit itemSelected(m_selItem);
2630 -    }
2631 +    if (m_itemList.size())
2632 +        emit itemSelected(m_itemList[m_selIndx]);
2633  }
2634  
2635 -void OSDListBtnType::SetItemCurrent(OSDListBtnTypeItem* item)
2636 +void OSDListBtnType::SetItemCurrent(const OSDListBtnTypeItem* item)
2637  {
2638 -    bool locked = m_update.tryLock();
2639 +    QMutexLocker lock(&m_update);
2640 +    int i = find(m_itemList, item);
2641 +    if (i >= 0)
2642 +        SetItemCurrent(i);
2643 +}
2644  
2645 -    if (m_itemList.find(item) == -1)
2646 +void OSDListBtnType::SetItemCurrent(uint current)
2647 +{
2648 +    QMutexLocker lock(&m_update);
2649 +    if (current >= m_itemList.size())
2650          return;
2651  
2652 -    m_topItem = item;
2653 -    m_selItem = item;
2654 -
2655 -    if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2656 -        m_showDnArrow = true;
2657 -    else
2658 -        m_showDnArrow = false;
2659 -
2660 -    emit itemSelected(m_selItem);
2661 -
2662 -    if (locked)
2663 -        m_update.unlock();
2664 +    m_selIndx     = current;
2665 +    m_topIndx     = max(m_selIndx - (int)m_itemsVisible, 0);
2666 +    m_showUpArrow = m_topIndx;
2667 +    m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
2668 +    emit itemSelected(m_itemList[m_selIndx]);
2669  }
2670  
2671 -void OSDListBtnType::SetItemCurrent(int current)
2672 +int OSDListBtnType::GetItemCurrentPos(void) const
2673  {
2674      QMutexLocker lock(&m_update);
2675 -
2676 -    OSDListBtnTypeItem* item = m_itemList.at(current);
2677 -    if (!item)
2678 -        item = m_itemList.first();
2679 -
2680 -    SetItemCurrent(item);
2681 +    return (m_itemList.size()) ? m_selIndx : -1;
2682  }
2683  
2684 -OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent()
2685 +OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent(void)
2686  {
2687 -    return m_selItem;
2688 +    QMutexLocker lock(&m_update);
2689 +    if (!m_itemList.size())
2690 +        return NULL;
2691 +    return m_itemList[m_selIndx];
2692  }
2693  
2694 -OSDListBtnTypeItem* OSDListBtnType::GetItemFirst()
2695 +OSDListBtnTypeItem* OSDListBtnType::GetItemFirst(void)
2696  {
2697 -    return m_itemList.first();    
2698 +    QMutexLocker lock(&m_update);
2699 +    if (!m_itemList.size())
2700 +        return NULL;
2701 +    return m_itemList[0];    
2702  }
2703  
2704 -OSDListBtnTypeItem* OSDListBtnType::GetItemNext(OSDListBtnTypeItem *item)
2705 +OSDListBtnTypeItem* OSDListBtnType::GetItemNext(const OSDListBtnTypeItem *item)
2706  {
2707      QMutexLocker lock(&m_update);
2708 -
2709 -    if (m_itemList.find(item) == -1)
2710 -        return 0;
2711 -
2712 -    return m_itemList.next();
2713 +    int i = find(m_itemList, item) + 1;
2714 +    if (i <= 0 || i >= (int)m_itemList.size())
2715 +        return NULL;
2716 +    return m_itemList[i];
2717  }
2718  
2719 -int OSDListBtnType::GetCount()
2720 +int OSDListBtnType::GetCount(void) const
2721  {
2722 -    return m_itemList.count();
2723 +    QMutexLocker lock(&m_update);
2724 +    return m_itemList.size();
2725  }
2726  
2727  OSDListBtnTypeItem* OSDListBtnType::GetItemAt(int pos)
2728  {
2729 -    return m_itemList.at(pos);    
2730 +    QMutexLocker lock(&m_update);
2731 +    return m_itemList[pos];    
2732  }
2733  
2734 -int OSDListBtnType::GetItemPos(OSDListBtnTypeItem* item)
2735 +int OSDListBtnType::GetItemPos(const OSDListBtnTypeItem *item) const
2736  {
2737      QMutexLocker lock(&m_update);
2738 -
2739 -    return m_itemList.find(item);    
2740 +    return find(m_itemList, item);
2741  }
2742  
2743 -void OSDListBtnType::MoveUp()
2744 +void OSDListBtnType::MoveUp(void)
2745  {
2746      QMutexLocker lock(&m_update);
2747 -
2748 -    if (m_itemList.find(m_selItem) == -1)
2749 +    if (!m_itemList.size())
2750          return;
2751  
2752 -    OSDListBtnTypeItem *item = m_itemList.prev();
2753 -    if (!item)
2754 +    if (--m_selIndx < 0)
2755      {
2756 -        item = m_itemList.last();
2757 -        if (!item)
2758 -            return;
2759 -
2760 -        if (m_itemList.count() > m_itemsVisible)
2761 -            m_topItem = m_itemList.at(m_itemList.count() - m_itemsVisible);
2762 -        else
2763 -            m_topItem = m_itemList.first();
2764 +        m_selIndx = m_itemList.size() - 1;
2765 +        m_topIndx = (m_itemList.size() > m_itemsVisible) ?
2766 +            m_itemList.size() - m_itemsVisible : 0;
2767      }
2768  
2769 -    m_selItem = item;
2770 +    m_topIndx     = (m_selIndx < m_topIndx) ? m_selIndx : m_topIndx;
2771 +    m_showUpArrow = m_topIndx;
2772 +    m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
2773  
2774 -    if (m_itemList.find(m_selItem) < m_itemList.find(m_topItem))
2775 -        m_topItem = m_selItem;
2776 -
2777 -    if (m_topItem != m_itemList.first())
2778 -        m_showUpArrow = true;
2779 -    else
2780 -        m_showUpArrow = false;
2781 -
2782 -    if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
2783 -        m_showDnArrow = true;
2784 -    else
2785 -        m_showDnArrow = false;
2786 -
2787 -    emit itemSelected(m_selItem);
2788 +    emit itemSelected(m_itemList[m_selIndx]);
2789  }
2790  
2791 -void OSDListBtnType::MoveDown()
2792 +void OSDListBtnType::MoveDown(void)
2793  {
2794      QMutexLocker lock(&m_update);
2795 -
2796 -    if (m_itemList.find(m_selItem) == -1)
2797 +    if (!m_itemList.size())
2798          return;
2799  
2800 -    OSDListBtnTypeItem *item = m_itemList.next();
2801 -    if (!item)
2802 -    {
2803 -        item = m_itemList.first();
2804 -        if (!item)
2805 -            return;
2806 +    if (++m_selIndx >= (int)m_itemList.size())
2807 +        m_selIndx = m_topIndx = 0;
2808  
2809 -        m_topItem = item;
2810 -    }
2811 -
2812 -    m_selItem = item;
2813 -
2814 -    if (m_itemList.find(m_topItem) + m_itemsVisible <=
2815 -        (unsigned int)m_itemList.find(m_selItem)) 
2816 -    {
2817 -        m_topItem = m_itemList.at(m_itemList.find(m_topItem) + 1);
2818 -    }
2819 +    bool scroll_down = m_topIndx + (int)m_itemsVisible <= m_selIndx;
2820 +    m_topIndx = (scroll_down) ? m_topIndx + 1 : m_topIndx;
2821 +        
2822 +    m_showUpArrow = m_topIndx;
2823 +    m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
2824      
2825 -    if (m_topItem != m_itemList.first())
2826 -        m_showUpArrow = true;
2827 -    else
2828 -        m_showUpArrow = false;
2829 -
2830 -    if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
2831 -        m_showDnArrow = true;
2832 -    else
2833 -        m_showDnArrow = false;
2834 -    
2835 -    emit itemSelected(m_selItem);
2836 +    emit itemSelected(m_itemList[m_selIndx]);
2837  }
2838  
2839 -void OSDListBtnType::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
2840 -                          int yoff)
2841 +void OSDListBtnType::Draw(OSDSurface *surface,
2842 +                          int fade, int maxfade,
2843 +                          int xoff, int yoff)
2844  {
2845 -    (void)xoff;
2846 -    (void)yoff;
2847 -
2848 +    QMutexLocker lock(&m_update);
2849      if (!m_visible)
2850          return;
2851 -
2852 -    QMutexLocker lock(&m_update);
2853 -
2854      if (!m_initialized)
2855          Init();
2856  
2857      TTFFont *font = m_active ? m_fontActive : m_fontInactive;
2858      
2859      int y = m_rect.y();
2860 -    m_itemList.find(m_topItem);
2861 -    OSDListBtnTypeItem *it = m_itemList.current();
2862 -    while (it && (y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight)) 
2863 +    for (uint i = m_topIndx; i < m_itemList.size(); i++)
2864      {
2865 -        it->paint(surface, font, fade, maxfade, m_rect.x()+ xoff, y + yoff);
2866 -
2867 +        if (!((y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight)))
2868 +            break;
2869 +        m_itemList[i]->paint(surface, font, fade, maxfade,
2870 +                             m_rect.x() + xoff, y + yoff);
2871          y += m_itemHeight + m_itemSpacing;
2872 -
2873 -        it = m_itemList.next();
2874      }
2875  
2876      if (m_showScrollArrows) 
2877 @@ -792,14 +587,13 @@
2878      }
2879  }
2880  
2881 -void OSDListBtnType::Init()
2882 +void OSDListBtnType::Init(void)
2883  {
2884      int sz1 = m_fontActive->Size() * 3 / 2;
2885      int sz2 = m_fontInactive->Size() * 3 / 2;
2886 -    m_itemHeight = QMAX(sz1, sz2) + (int)(2 * m_itemMargin);
2887 +    m_itemHeight = max(sz1, sz2) + (int)(2 * m_itemMargin);
2888 +    m_itemHeight = m_itemHeight & ~0x1;
2889  
2890 -    m_itemHeight = (m_itemHeight / 2) * 2;
2891 -
2892      if (m_showScrollArrows) 
2893      {
2894          LoadPixmap(m_upArrowRegPix, "uparrow-reg");
2895 @@ -838,11 +632,7 @@
2896      InitItem(m_itemSelActPix,   itemWidth,    m_itemHeight,
2897               m_itemSelBeg,      m_itemSelEnd, 255);
2898  
2899 -    if (m_itemList.count() > m_itemsVisible && m_showScrollArrows)
2900 -        m_showDnArrow = true;
2901 -    else
2902 -        m_showDnArrow = false;
2903 -
2904 +    m_showDnArrow = m_itemList.size() > m_itemsVisible && m_showScrollArrows;
2905      m_initialized = true;
2906  }
2907  
2908 @@ -885,68 +675,57 @@
2909  
2910  void OSDListBtnType::LoadPixmap(OSDTypeImage& pix, const QString& fileName)
2911  {
2912 -    QString file = gContext->GetThemesParentDir() + "default/lb-" + fileName + ".png";
2913 -    pix.LoadImage(file, m_wmult, m_hmult);
2914 +    QString path = gContext->GetThemesParentDir() + "default/lb-";
2915 +    pix.LoadImage(path + fileName + ".png", m_wmult, m_hmult);
2916  }
2917  
2918  /////////////////////////////////////////////////////////////////////////////
2919 -OSDListBtnTypeItem::OSDListBtnTypeItem(OSDListBtnType* lbtype, 
2920 -                                       const QString& text,
2921 -                                       OSDTypeImage *pixmap, bool checkable,
2922 -                                       bool showArrow, CheckState state)
2923 +OSDListBtnTypeItem::OSDListBtnTypeItem(
2924 +    OSDListBtnType *lbtype,     const QString  &text,
2925 +    OSDTypeImage   *pixmap,     bool            checkable,
2926 +    bool            showArrow,  CheckState      state)
2927 +    : m_parent(lbtype),       m_pixmap(pixmap),
2928 +      m_data(NULL),           m_text(text),
2929 +      m_group(QString::null), m_state(state),
2930 +      m_showArrow(showArrow), m_checkable(checkable),
2931 +      m_checkRect(0,0,0,0),   m_arrowRect(0,0,0,0),
2932 +      m_pixmapRect(0,0,0,0),  m_textRect(0,0,0,0)
2933  {
2934 -    m_parent    = lbtype;
2935 -    m_text      = text;
2936 -    m_pixmap    = pixmap;
2937 -    m_checkable = checkable;
2938 -    m_state     = state;
2939 -    m_showArrow = showArrow;
2940 -    m_data      = 0;
2941 -
2942      if (!m_parent->m_initialized)
2943          m_parent->Init();
2944  
2945 -    int  margin    = m_parent->m_itemMargin;
2946 -    int  width     = m_parent->m_rect.width();
2947 -    int  height    = m_parent->m_itemHeight;
2948 +    OSDTypeImage &checkPix = m_parent->m_checkNonePix;
2949 +    OSDTypeImage &arrowPix = m_parent->m_arrowPix;
2950  
2951 -    OSDTypeImage& checkPix = m_parent->m_checkNonePix;
2952 -    OSDTypeImage& arrowPix = m_parent->m_arrowPix;
2953 -    
2954 -    int cw = checkPix.ImageSize().width();
2955 -    int ch = checkPix.ImageSize().height();
2956 -    int aw = arrowPix.ImageSize().width();
2957 -    int ah = arrowPix.ImageSize().height();
2958 -    int pw = m_pixmap ? m_pixmap->ImageSize().width() : 0;
2959 -    int ph = m_pixmap ? m_pixmap->ImageSize().height() : 0;
2960 -    
2961 +    int margin = m_parent->m_itemMargin;
2962 +    int width  = m_parent->m_rect.width();
2963 +    int height = m_parent->m_itemHeight;
2964 +    int cw     = checkPix.ImageSize().width();
2965 +    int ch     = checkPix.ImageSize().height();
2966 +    int aw     = arrowPix.ImageSize().width();
2967 +    int ah     = arrowPix.ImageSize().height();
2968 +    int pw     = m_pixmap ? m_pixmap->ImageSize().width() : 0;
2969 +    int ph     = m_pixmap ? m_pixmap->ImageSize().height() : 0;
2970 +
2971      if (m_checkable) 
2972 -        m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
2973 -    else
2974 -        m_checkRect = QRect(0,0,0,0);
2975 +        m_checkRect  = QRect(margin, (height - ch)/2, cw, ch);
2976  
2977      if (m_showArrow) 
2978 -        m_arrowRect = QRect(width - aw - margin, (height - ah)/2,
2979 -                            aw, ah);
2980 -    else
2981 -        m_arrowRect = QRect(0,0,0,0);
2982 +        m_arrowRect  = QRect(width - aw - margin, (height - ah)/2, aw, ah);
2983  
2984 -    if (m_pixmap) 
2985 -        m_pixmapRect = QRect(m_checkable ? (2*margin + m_checkRect.width()) :
2986 -                             margin, (height - ph)/2,
2987 -                             pw, ph);
2988 -    else
2989 -        m_pixmapRect = QRect(0,0,0,0);
2990 +    if (m_pixmap)
2991 +    {
2992 +        int tmp = (m_checkable) ? (2 * margin + m_checkRect.width()) : margin;
2993 +        m_pixmapRect = QRect(tmp, (height - ph)/2, pw, ph);
2994 +    }
2995  
2996 -    m_textRect = QRect(margin +
2997 -                       (m_checkable ? m_checkRect.width() + margin : 0) +
2998 -                       (m_pixmap    ? m_pixmapRect.width() + margin : 0),
2999 -                       0,
3000 -                       width - 2*margin -
3001 -                       (m_checkable ? m_checkRect.width() + margin : 0) -
3002 -                       (m_showArrow ? m_arrowRect.width() + margin : 0) -
3003 -                       (m_pixmap ? m_pixmapRect.width() + margin : 0),
3004 -                       height);
3005 +    int tx = margin, tw = width - (2 * margin);
3006 +    tx += (m_checkable) ? m_checkRect.width()  + margin : 0;
3007 +    tx += (m_pixmap)    ? m_pixmapRect.width() + margin : 0;
3008 +    tw -= (m_checkable) ? m_checkRect.width()  + margin : 0;
3009 +    tw -= (m_showArrow) ? m_arrowRect.width()  + margin : 0;
3010 +    tw -= (m_pixmap)    ? m_pixmapRect.width() + margin : 0;
3011 +    m_textRect = QRect(tx, 0, tw, height);
3012  
3013      m_parent->InsertItem(this);
3014  }
3015 @@ -957,52 +736,10 @@
3016          m_parent->RemoveItem(this);
3017  }
3018  
3019 -QString OSDListBtnTypeItem::text() const
3020 -{
3021 -    return m_text;
3022 -}
3023 -
3024 -const OSDTypeImage* OSDListBtnTypeItem::pixmap() const
3025 -{
3026 -    return m_pixmap;
3027 -}
3028 -
3029 -bool OSDListBtnTypeItem::checkable() const
3030 -{
3031 -    return m_checkable;
3032 -}
3033 -
3034 -OSDListBtnTypeItem::CheckState OSDListBtnTypeItem::state() const
3035 -{
3036 -    return m_state;
3037 -}
3038 -
3039 -OSDListBtnType* OSDListBtnTypeItem::parent() const
3040 -{
3041 -    return m_parent;
3042 -}
3043 -
3044 -void OSDListBtnTypeItem::setChecked(CheckState state)
3045 -{
3046 -    if (!m_checkable)
3047 -        return;
3048 -    m_state = state;
3049 -}
3050 -
3051 -void OSDListBtnTypeItem::setData(void *data)
3052 -{
3053 -    m_data = data;    
3054 -}
3055 -
3056 -void* OSDListBtnTypeItem::getData()
3057 -{
3058 -    return m_data;
3059 -}
3060 -
3061  void OSDListBtnTypeItem::paint(OSDSurface *surface, TTFFont *font, 
3062                                 int fade, int maxfade, int x, int y)
3063  {
3064 -    if (this == m_parent->m_selItem)
3065 +    if (this == m_parent->GetItemCurrent())
3066      {
3067          if (m_parent->m_active)
3068              m_parent->m_itemSelActPix.Draw(surface, fade, maxfade, x, y);
3069 @@ -1030,11 +767,14 @@
3070          cr.moveBy(x, y);
3071          
3072          if (m_state == HalfChecked)
3073 -            m_parent->m_checkHalfPix.Draw(surface, fade, maxfade, cr.x(), cr.y());
3074 +            m_parent->m_checkHalfPix.Draw(surface, fade, maxfade,
3075 +                                          cr.x(), cr.y());
3076          else if (m_state == FullChecked)
3077 -            m_parent->m_checkFullPix.Draw(surface, fade, maxfade, cr.x(), cr.y());
3078 +            m_parent->m_checkFullPix.Draw(surface, fade, maxfade,
3079 +                                          cr.x(), cr.y());
3080          else
3081 -            m_parent->m_checkNonePix.Draw(surface, fade, maxfade, cr.x(), cr.y());
3082 +            m_parent->m_checkNonePix.Draw(surface, fade, maxfade,
3083 +                                          cr.x(), cr.y());
3084      }
3085  
3086      if (m_pixmap)
3087 @@ -1049,39 +789,3 @@
3088      tr.moveBy(0, font->Size() / 4);
3089      font->DrawString(surface, tr.x(), tr.y(), m_text, tr.right(), tr.bottom());
3090  }
3091 -
3092 -void OSDListBtnTypeItem::Reinit(float wchange, float hchange, 
3093 -                                float wmult, float hmult)
3094 -{
3095 -    (void)wmult;
3096 -    (void)hmult;
3097 -
3098 -    int width = (int)(m_checkRect.width() * wchange);
3099 -    int height = (int)(m_checkRect.height() * hchange);
3100 -    int x = (int)(m_checkRect.x() * wchange);
3101 -    int y = (int)(m_checkRect.y() * hchange);
3102 -
3103 -    m_checkRect = QRect(x, y, width, height);
3104 -
3105 -    width = (int)(m_pixmapRect.width() * wchange);
3106 -    height = (int)(m_pixmapRect.height() * hchange);
3107 -    x = (int)(m_pixmapRect.x() * wchange);
3108 -    y = (int)(m_pixmapRect.y() * hchange);
3109 -
3110 -    m_pixmapRect = QRect(x, y, width, height);
3111 -
3112 -    width = (int)(m_textRect.width() * wchange);
3113 -    height = (int)(m_textRect.height() * hchange);
3114 -    x = (int)(m_textRect.x() * wchange);
3115 -    y = (int)(m_textRect.y() * hchange);
3116 -
3117 -    m_textRect = QRect(x, y, width, height);
3118 -
3119 -    width = (int)(m_arrowRect.width() * wchange);
3120 -    height = (int)(m_arrowRect.height() * hchange);
3121 -    x = (int)(m_arrowRect.x() * wchange);
3122 -    y = (int)(m_arrowRect.y() * hchange);
3123 -
3124 -    m_arrowRect = QRect(x, y, width, height);
3125 -}
3126 -
3127 Index: mythtv/libs/libmythtv/RingBuffer.cpp
3128 ===================================================================
3129 --- mythtv/libs/libmythtv/RingBuffer.cpp        (.../tags/release-0-19) (revision 10051)
3130 +++ mythtv/libs/libmythtv/RingBuffer.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
3131 @@ -145,6 +145,12 @@
3132      VERBOSE(VB_PLAYBACK, LOC + QString("OpenFile(%1, %1)")
3133              .arg(lfilename).arg(retryCount));
3134  
3135 +    if ((filename.right(4).lower() == ".png") ||
3136 +        (filename.right(4).lower() == ".gif"))
3137 +    {
3138 +        retryCount = 0;
3139 +    }
3140 +
3141      uint openAttempts = retryCount + 1;
3142  
3143      filename = lfilename;
3144 @@ -162,6 +168,7 @@
3145  
3146      bool is_local = false;
3147      bool is_dvd = false;
3148 +
3149      if ((filename.left(7) == "myth://") &&
3150          (filename.length() > 7 ))
3151      {
3152 @@ -271,6 +278,11 @@
3153              remotefile = NULL;
3154          }
3155      }
3156 +
3157 +    setswitchtonext = false;
3158 +    ateof = false;
3159 +    commserror = false;
3160 +    numfailures = 0;
3161  }
3162  
3163  /** \fn RingBuffer::IsOpen(void) const
3164 @@ -727,7 +739,7 @@
3165          loops = 0;
3166  
3167          pthread_rwlock_rdlock(&rwlock);
3168 -        if (totfree > readblocksize && !commserror)
3169 +        if (totfree > readblocksize && !commserror && !ateof && !setswitchtonext)
3170          {
3171              // limit the read size
3172              totfree = readblocksize;
3173 @@ -737,6 +749,9 @@
3174  
3175              if (remotefile)
3176              {
3177 +                if (livetvchain && livetvchain->HasNext())
3178 +                    remotefile->SetTimeout(true);
3179 +
3180                  ret = safe_read(remotefile, readAheadBuffer + rbwpos,
3181                                  totfree);
3182                  internalreadpos += ret;
3183 @@ -785,8 +800,16 @@
3184              totfree = 0;
3185          }
3186  
3187 -        if (!readsallowed && used >= fill_min)
3188 +        if (!readsallowed && (used >= fill_min || setswitchtonext))
3189 +        {
3190              readsallowed = true;
3191 +            VERBOSE(VB_PLAYBACK, QString("reads allowed (%1 %2)").arg(used)
3192 +                                                                .arg(fill_min));
3193 +        }
3194 +        else if (!readsallowed)
3195 +            VERBOSE(VB_PLAYBACK, QString("buffering (%1 %2 %3)").arg(used)
3196 +                                                                .arg(fill_min)
3197 +                                                                .arg(ret));
3198  
3199          if (readsallowed && used < fill_min && !ateof && !setswitchtonext)
3200          {
3201 @@ -808,8 +831,11 @@
3202  
3203          pthread_rwlock_unlock(&rwlock);
3204  
3205 -        if ((used >= fill_threshold || wantseek) && !pausereadthread)
3206 +        if ((used >= fill_threshold || wantseek || ateof || setswitchtonext) &&
3207 +            !pausereadthread)
3208 +        {
3209              usleep(500);
3210 +        }
3211      }
3212  
3213      delete [] readAheadBuffer;
3214 @@ -853,15 +879,15 @@
3215                   VERBOSE(VB_IMPORTANT,
3216                           LOC + "Taking too long to be allowed to read..");
3217                   readErr++;
3218 -                 
3219 +
3220                   // HACK Sometimes the readhead thread gets borked on startup.
3221 -               /*  if ((readErr % 2) && (rbrpos ==0))
3222 +                 if ((readErr > 2 && readErr % 2) && (rbrpos ==0))
3223                   {
3224                      VERBOSE(VB_IMPORTANT, "restarting readhead thread..");
3225                      KillReadAheadThread();
3226                      StartupReadAheadThread();
3227                   }                    
3228 -                   */ 
3229
3230                   if (readErr > 10)
3231                   {
3232                       VERBOSE(VB_IMPORTANT, LOC_ERR + "Took more than "
3233 @@ -895,6 +921,12 @@
3234                  VERBOSE(VB_IMPORTANT, LOC + "Waited " +
3235                          QString("%1").arg(elapsed/1000) +
3236                          " seconds for data to become available...");
3237 +                if (livetvchain)
3238 +                {
3239 +                    VERBOSE(VB_IMPORTANT, "Checking to see if there's a "
3240 +                                          "new livetv program to switch to..");
3241 +                    livetvchain->ReloadAll();
3242 +                }
3243              }
3244  
3245              bool quit = livetvchain && (livetvchain->NeedsToSwitch() || 
3246 @@ -923,7 +955,7 @@
3247          availWaitMutex.unlock();
3248  
3249          avail = ReadBufAvail();
3250 -        if (ateof && avail < count)
3251 +        if ((ateof || setswitchtonext) && avail < count)
3252              count = avail;
3253  
3254          if (commserror)
3255 Index: mythtv/libs/libmythtv/hdtvrecorder.cpp
3256 ===================================================================
3257 --- mythtv/libs/libmythtv/hdtvrecorder.cpp      (.../tags/release-0-19) (revision 10051)
3258 +++ mythtv/libs/libmythtv/hdtvrecorder.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
3259 @@ -627,9 +627,8 @@
3260  
3261          len += remainder;
3262          remainder = ProcessData(_buffer, len);
3263 -        if (remainder > 0) // leftover bytes
3264 -            memmove(_buffer, &(_buffer[_buffer_size - remainder]),
3265 -                    remainder);
3266 +        if (remainder > 0 && (len > remainder)) // leftover bytes
3267 +            memmove(_buffer, &(_buffer[len - remainder]), remainder);
3268      }
3269  
3270      FinishRecording();
3271 Index: mythtv/libs/libmythtv/dummydtvrecorder.cpp
3272 ===================================================================
3273 --- mythtv/libs/libmythtv/dummydtvrecorder.cpp  (.../tags/release-0-19) (revision 10051)
3274 +++ mythtv/libs/libmythtv/dummydtvrecorder.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
3275 @@ -125,7 +125,8 @@
3276      // TRANSFER DATA
3277      while (_request_recording || _frames_seen_count <= 5)
3278      {
3279 -        len = read(_stream_fd, &(_buffer[remainder]), _buffer_size - remainder);
3280 +        len = read(_stream_fd, &(_buffer[remainder]),
3281 +                   _buffer_size - remainder);
3282  
3283          if (len == 0)
3284          {
3285 @@ -137,9 +138,8 @@
3286  
3287          len += remainder;
3288          remainder = ProcessData(_buffer, len);
3289 -        if (remainder > 0) // leftover bytes
3290 -            memmove(_buffer, &(_buffer[_buffer_size - remainder]),
3291 -                    remainder);
3292 +        if (remainder > 0 && (len > remainder)) // leftover bytes
3293 +            memmove(_buffer, &(_buffer[len - remainder]), remainder);
3294      }
3295  
3296      FinishRecording();
3297 Index: mythtv/libs/libmythtv/avformatdecoder.cpp
3298 ===================================================================
3299 --- mythtv/libs/libmythtv/avformatdecoder.cpp   (.../tags/release-0-19) (revision 10051)
3300 +++ mythtv/libs/libmythtv/avformatdecoder.cpp   (.../branches/release-0-19-fixes)       (revision 10051)
3301 @@ -725,7 +725,12 @@
3302          return -1;
3303      }
3304  
3305 +    /* av_find_stream_info() eventually makes calls to avcodec_open() and avcodec_close() 
3306 +       so we have to use the avcodeclock */
3307 +    avcodeclock.lock();
3308      int ret = av_find_stream_info(ic);
3309 +    avcodeclock.unlock();
3310 +
3311      if (ret < 0)
3312      {
3313          VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not find codec parameters. " +
3314 Index: mythtv/libs/libmythtv/osdtypes.cpp
3315 ===================================================================
3316 --- mythtv/libs/libmythtv/osdtypes.cpp  (.../tags/release-0-19) (revision 10051)
3317 +++ mythtv/libs/libmythtv/osdtypes.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
3318 @@ -14,6 +14,9 @@
3319  
3320  #include "mythcontext.h"
3321  
3322 +/// Shared OSD image cache
3323 +OSDImageCache OSDTypeImage::c_cache;
3324 +
3325  OSDSet::OSDSet(const QString &name, bool cache, int screenwidth, 
3326                 int screenheight, float wmult, float hmult, int frint)
3327        : QObject()
3328 @@ -160,9 +163,6 @@
3329                      int displaywidth, int displayheight, 
3330                      float wmult, float hmult, int frint)
3331  {
3332 -    float wchange = wmult / m_wmult;
3333 -    float hchange = hmult / m_hmult;
3334 -
3335      m_frameint = frint;
3336  
3337      m_screenwidth = screenwidth;
3338 @@ -175,57 +175,12 @@
3339      vector<OSDType *>::iterator iter = allTypes->begin();
3340      for (;iter != allTypes->end(); iter++)
3341      {
3342 -        OSDType *type = (*iter);
3343 -        if (OSDTypeText *item = dynamic_cast<OSDTypeText*>(type))
3344 -        {
3345 -            item->Reinit(wchange, hchange);
3346 -        }
3347 -        else if (OSDTypePositionImage *item =
3348 -                 dynamic_cast<OSDTypePositionImage*>(type))
3349 -        {
3350 -            item->Reinit(wchange, hchange, wmult, hmult);
3351 -        }
3352 -        else if (OSDTypePosSlider *item = dynamic_cast<OSDTypePosSlider*>(type))
3353 -        {
3354 -            item->Reinit(wchange, hchange, wmult, hmult);
3355 -        }
3356 -        else if (OSDTypeFillSlider *item = 
3357 -                 dynamic_cast<OSDTypeFillSlider*>(type))
3358 -        {
3359 -            item->Reinit(wchange, hchange, wmult, hmult);
3360 -        }
3361 -        else if (OSDTypeEditSlider *item =
3362 -                 dynamic_cast<OSDTypeEditSlider*>(type))
3363 -        {
3364 -            item->Reinit(wchange, hchange, wmult, hmult);
3365 -        }
3366 -        else if (OSDTypeImage *item = dynamic_cast<OSDTypeImage*>(type))
3367 -        {
3368 -            item->Reinit(wchange, hchange, wmult, hmult);
3369 -        }
3370 -        else if (OSDTypeBox *item = dynamic_cast<OSDTypeBox*>(type))
3371 -        {
3372 -            item->Reinit(wchange, hchange);
3373 -        }
3374 -        else if (OSDTypePositionRectangle *item =
3375 -                  dynamic_cast<OSDTypePositionRectangle*>(type))
3376 -        {
3377 -            item->Reinit(wchange, hchange);
3378 -        }
3379 -        else if (OSDTypeCC *item = dynamic_cast<OSDTypeCC*>(type))
3380 -        {
3381 -            item->Reinit(xoff, yoff, displaywidth, displayheight);
3382 -        }
3383 -        else if (OSDListTreeType *item = dynamic_cast<OSDListTreeType*>(type))
3384 -        {
3385 -            item->Reinit(wchange, hchange, wmult, hmult);
3386 -        }
3387 +        if (OSDTypeCC *cc608 = dynamic_cast<OSDTypeCC*>(*iter))
3388 +            cc608->Reinit(xoff, yoff, displaywidth, displayheight,
3389 +                          wmult, hmult);
3390          else
3391 -        {
3392 -            cerr << "Unknown conversion\n";
3393 -        }
3394 +            (*iter)->Reinit(wmult, hmult);
3395      }
3396 -
3397  }
3398  
3399  OSDType *OSDSet::GetType(const QString &name)
3400 @@ -443,7 +398,8 @@
3401  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3402  
3403  OSDTypeText::OSDTypeText(const QString &name, TTFFont *font, 
3404 -                         const QString &text, QRect displayrect)
3405 +                         const QString &text, QRect displayrect,
3406 +                         float wmult, float hmult)
3407             : OSDType(name)
3408  {
3409      m_message = text;
3410 @@ -464,6 +420,12 @@
3411      m_scrollinit = false;
3412  
3413      m_linespacing = 1.5;
3414 +
3415 +    m_unbiasedsize =
3416 +        QRect((int)round(m_screensize.x()      / wmult),
3417 +              (int)round(m_screensize.y()      / hmult),
3418 +              (int)ceil( m_screensize.width()  / wmult),
3419 +              (int)ceil( m_screensize.height() / hmult));
3420  }
3421  
3422  OSDTypeText::OSDTypeText(const OSDTypeText &other)
3423 @@ -507,14 +469,13 @@
3424      m_scrollinit = false;
3425  }
3426  
3427 -void OSDTypeText::Reinit(float wchange, float hchange)
3428 +void OSDTypeText::Reinit(float wmult, float hmult)
3429  {
3430 -    int width = (int)(m_screensize.width() * wchange);
3431 -    int height = (int)(m_screensize.height() * hchange);
3432 -    int x = (int)(m_screensize.x() * wchange);
3433 -    int y = (int)(m_screensize.y() * hchange);
3434 -
3435 -    m_displaysize = m_screensize = QRect(x, y, width, height);
3436 +    m_displaysize = m_screensize =
3437 +        QRect((int)round(m_unbiasedsize.x()      * wmult),
3438 +              (int)round(m_unbiasedsize.y()      * hmult),
3439 +              (int)ceil( m_unbiasedsize.width()  * wmult),
3440 +              (int)ceil( m_unbiasedsize.height() * hmult));
3441  }
3442  
3443  void OSDTypeText::Draw(OSDSurface *surface, int fade, int maxfade, int xoff, 
3444 @@ -708,7 +669,7 @@
3445      m_onlyusefirst = false;
3446  
3447      m_filename = filename;
3448 -    m_displaypos = displaypos;
3449 +    SetPosition(displaypos, wmult, hmult);
3450  
3451      m_yuv = m_alpha = NULL;
3452      m_isvalid = false;
3453 @@ -716,6 +677,7 @@
3454  
3455      m_scalew = scalew;
3456      m_scaleh = scaleh;
3457 +    m_cacheitem = NULL;
3458  
3459      LoadImage(filename, wmult, hmult, scalew, scaleh);
3460  }
3461 @@ -733,6 +695,7 @@
3462      m_name = other.m_name;
3463      m_scalew = other.m_scalew;
3464      m_scaleh = other.m_scaleh;
3465 +    m_cacheitem = NULL;
3466  
3467      m_alpha = m_yuv = NULL;
3468      if (m_isvalid)
3469 @@ -760,6 +723,8 @@
3470      m_onlyusefirst = false;
3471  
3472      m_displaypos = QPoint(0, 0);
3473 +    m_unbiasedpos = QPoint(0, 0);
3474 +    m_cacheitem = NULL;
3475  
3476      m_yuv = NULL;
3477      m_alpha = NULL;
3478 @@ -778,6 +743,8 @@
3479      m_onlyusefirst = false;
3480  
3481      m_displaypos = QPoint(0, 0);
3482 +    m_unbiasedpos = QPoint(0, 0);
3483 +    m_cacheitem = NULL;
3484  
3485      m_yuv = NULL;
3486      m_alpha = NULL;
3487 @@ -790,10 +757,14 @@
3488  
3489  OSDTypeImage::~OSDTypeImage()
3490  {
3491 -    if (m_yuv)
3492 -        delete [] m_yuv;
3493 -    if (m_alpha)
3494 -        delete [] m_alpha;
3495 +    // In case we have a cache item in hand, it's safe to delete it,
3496 +    // as it should not be in OSDImageCache anymore and it should have
3497 +    // been written to the file cache for faster access in the future.
3498 +    if (m_cacheitem)
3499 +    {
3500 +        delete m_cacheitem;
3501 +        m_cacheitem = NULL;
3502 +    }
3503  }
3504  
3505  void OSDTypeImage::SetName(const QString &name)
3506 @@ -801,13 +772,19 @@
3507      m_name = name;
3508  }
3509  
3510 -void OSDTypeImage::Reinit(float wchange, float hchange, float wmult, float hmult)
3511 +void OSDTypeImage::SetPosition(QPoint pos, float wmult, float hmult)
3512  {
3513 -    int x = (int)(m_displaypos.x() * wchange);
3514 -    int y = (int)(m_displaypos.y() * hchange);
3515 +    m_displaypos  = pos;
3516 +    m_unbiasedpos =
3517 +        QPoint((int)round(pos.x() / wmult),
3518 +               (int)round(pos.y() / hmult));
3519 +}
3520  
3521 -    m_displaypos.setX(x);
3522 -    m_displaypos.setY(y);
3523 +void OSDTypeImage::Reinit(float wmult, float hmult)
3524 +{
3525 +    m_displaypos =
3526 +        QPoint((int)round(m_unbiasedpos.x() * wmult),
3527 +               (int)round(m_unbiasedpos.y() * hmult));
3528  
3529      LoadImage(m_filename, wmult, hmult, m_scalew, m_scaleh);
3530  }
3531 @@ -815,20 +792,44 @@
3532  void OSDTypeImage::LoadImage(const QString &filename, float wmult, float hmult,
3533                               int scalew, int scaleh)
3534  {
3535 -    if (m_isvalid)
3536 +    QString ckey;
3537 +   
3538 +    if (!filename.isEmpty() && filename.length() >= 2)
3539      {
3540 -        if (m_yuv)
3541 -            delete [] m_yuv;
3542 -        if (m_alpha)
3543 -            delete [] m_alpha;
3544 -
3545 -        m_isvalid = false;
3546 -        m_yuv = NULL;
3547 -        m_alpha = NULL;
3548 +        ckey = OSDImageCache::CreateKey(
3549 +            filename, wmult, hmult, scalew, scaleh);
3550      }
3551 +    else 
3552 +    {
3553 +        // this method requires a backing file
3554 +        return;
3555 +    }
3556 +  
3557 +    // Get the item from the cache so it's not freed while in use
3558 +    OSDImageCacheValue* value = c_cache.Get(ckey, true);
3559 +  
3560 +    if (value != NULL)
3561 +    {
3562 +        m_yuv       = value->m_yuv;
3563 +        m_ybuffer   = value->m_ybuffer;
3564 +        m_ubuffer   = value->m_ubuffer;
3565 +        m_vbuffer   = value->m_vbuffer;
3566 +        m_alpha     = value->m_alpha;
3567 +        m_imagesize = value->m_imagesize;
3568 +        m_isvalid   = true;
3569  
3570 -    if (filename.length() < 2)
3571 +        // Put the old image back to the cache so it can be reused in the
3572 +        // future, and possibly freed by the cache system if the size limit
3573 +        // is reached
3574 +        if (!m_cacheitem)
3575 +            c_cache.Insert(m_cacheitem);
3576 +        m_cacheitem = value;
3577 +
3578          return;
3579 +    }
3580 +   
3581 +    // scaled image was not found in cache, have to create it
3582 +  
3583  
3584      QImage tmpimage(filename);
3585  
3586 @@ -867,17 +868,32 @@
3587                       imwidth, imheight, tmp2.width());
3588  
3589      m_imagesize = QRect(0, 0, imwidth, imheight);
3590 +
3591 +    // put the old image back to the cache so it can be reused in the
3592 +    // future, and possibly freed by the cache system if the size limit
3593 +    // is reached
3594 +    if (m_cacheitem)
3595 +        c_cache.Insert(m_cacheitem);
3596 +  
3597 +    m_cacheitem = new OSDImageCacheValue(
3598 +        ckey,
3599 +        m_yuv,     m_ybuffer, m_ubuffer,
3600 +        m_vbuffer, m_alpha,   m_imagesize);
3601
3602 +    // save the new cache item to the file cache
3603 +    if (!filename.isEmpty())
3604 +        c_cache.SaveToDisk(m_cacheitem);
3605  }
3606  
3607  void OSDTypeImage::LoadFromQImage(const QImage &img)
3608  {
3609 +    // this method is not cached as it's used mostly for
3610 +    // subtitles which are displayed only once anyways, caching
3611 +    // would probably only slow things down overall
3612      if (m_isvalid)
3613      {
3614 -        if (m_yuv)
3615 -            delete [] m_yuv;
3616 -        if (m_alpha)
3617 -            delete [] m_alpha;
3618 -
3619 +        delete m_cacheitem;
3620 +        m_cacheitem = NULL;
3621          m_isvalid = false;
3622          m_yuv = NULL;
3623          m_alpha = NULL;
3624 @@ -1043,23 +1059,25 @@
3625      m_maxval = 1000;
3626      m_curval = 0;
3627      m_displayrect = displayrect;
3628 +    m_unbiasedrect =
3629 +        QRect((int)round(m_displayrect.x()      / wmult),
3630 +              (int)round(m_displayrect.y()      / hmult),
3631 +              (int)ceil( m_displayrect.width()  / wmult),
3632 +              (int)ceil( m_displayrect.height() / hmult));
3633  }
3634  
3635  OSDTypePosSlider::~OSDTypePosSlider()
3636  {
3637  }
3638  
3639 -void OSDTypePosSlider::Reinit(float wchange, float hchange, float wmult,
3640 -                              float hmult)
3641 +void OSDTypePosSlider::Reinit(float wmult, float hmult)
3642  {
3643 -    int width = (int)(m_displayrect.width() * wchange);
3644 -    int height = (int)(m_displayrect.height() * hchange);
3645 -    int x = (int)(m_displayrect.x() * wchange);
3646 -    int y = (int)(m_displayrect.y() * hchange);
3647 -
3648 -    m_displayrect = QRect(x, y, width, height);
3649 -
3650 -    OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
3651 +    m_displayrect =
3652 +        QRect((int)round(m_unbiasedrect.x()      * wmult),
3653 +              (int)round(m_unbiasedrect.y()      * hmult),
3654 +              (int)ceil( m_unbiasedrect.width()  * wmult),
3655 +              (int)ceil( m_unbiasedrect.height() * hmult));
3656 +    OSDTypeImage::Reinit(wmult, hmult);
3657  }
3658  
3659  void OSDTypePosSlider::SetPosition(int pos)
3660 @@ -1092,23 +1110,25 @@
3661      m_drawwidth = 0;
3662      m_onlyusefirst = true;
3663      m_displayrect = displayrect;
3664 +    m_unbiasedrect =
3665 +        QRect((int)round(m_displayrect.x()      / wmult),
3666 +              (int)round(m_displayrect.y()      / hmult),
3667 +              (int)ceil( m_displayrect.width()  / wmult),
3668 +              (int)ceil( m_displayrect.height() / hmult));
3669  }
3670  
3671  OSDTypeFillSlider::~OSDTypeFillSlider()
3672  {
3673  }
3674  
3675 -void OSDTypeFillSlider::Reinit(float wchange, float hchange, float wmult,
3676 -                               float hmult)
3677 +void OSDTypeFillSlider::Reinit(float wmult, float hmult)
3678  {
3679 -    int width = (int)(m_displayrect.width() * wchange);
3680 -    int height = (int)(m_displayrect.height() * hchange);
3681 -    int x = (int)(m_displayrect.x() * wchange);
3682 -    int y = (int)(m_displayrect.y() * hchange);
3683 -
3684 -    m_displayrect = QRect(x, y, width, height);
3685 -
3686 -    OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
3687 +    m_displayrect =
3688 +        QRect((int)round(m_unbiasedrect.x()      * wmult),
3689 +              (int)round(m_unbiasedrect.y()      * hmult),
3690 +              (int)ceil( m_unbiasedrect.width()  * wmult),
3691 +              (int)ceil( m_unbiasedrect.height() * hmult));
3692 +    OSDTypeImage::Reinit(wmult, hmult);
3693  }
3694  
3695  void OSDTypeFillSlider::SetPosition(int pos)
3696 @@ -1143,6 +1163,11 @@
3697      m_maxval = 1000;
3698      m_curval = 0;
3699      m_displayrect = displayrect;
3700 +    m_unbiasedrect =
3701 +        QRect((int)round(m_displayrect.x()      / wmult),
3702 +              (int)round(m_displayrect.y()      / hmult),
3703 +              (int)ceil( m_displayrect.width()  / wmult),
3704 +              (int)ceil( m_displayrect.height() / hmult));
3705      m_drawwidth = displayrect.width();
3706  
3707      m_drawMap = new unsigned char[m_drawwidth + 1];
3708 @@ -1162,6 +1187,7 @@
3709  
3710      m_scalew = scalew;
3711      m_scaleh = scaleh;
3712 +    m_cacheitem = NULL;
3713  
3714      LoadImage(m_redname, wmult, hmult, scalew, scaleh);
3715      if (m_isvalid)
3716 @@ -1184,22 +1210,16 @@
3717  OSDTypeEditSlider::~OSDTypeEditSlider()
3718  {
3719      delete [] m_drawMap;
3720 -
3721 -    if (m_ryuv)
3722 -        delete [] m_ryuv;
3723 -    if (m_ralpha)
3724 -        delete [] m_ralpha;
3725  }
3726  
3727 -void OSDTypeEditSlider::Reinit(float wchange, float hchange, float wmult,
3728 -                               float hmult)
3729 +void OSDTypeEditSlider::Reinit(float wmult, float hmult)
3730  {
3731 -    int width = (int)(m_displayrect.width() * wchange);
3732 -    int height = (int)(m_displayrect.height() * hchange);
3733 -    int x = (int)(m_displayrect.x() * wchange);
3734 -    int y = (int)(m_displayrect.y() * hchange);
3735 +    m_displayrect =
3736 +        QRect((int)round(m_unbiasedrect.x()      * wmult),
3737 +              (int)round(m_unbiasedrect.y()      * hmult),
3738 +              (int)ceil( m_unbiasedrect.width()  * wmult),
3739 +              (int)ceil( m_unbiasedrect.height() * hmult));
3740  
3741 -    m_displayrect = QRect(x, y, width, height);
3742      m_drawwidth = m_displayrect.width();
3743  
3744      delete [] m_drawMap;
3745 @@ -1210,11 +1230,6 @@
3746  
3747      m_displaypos = m_displayrect.topLeft();
3748  
3749 -    if (m_ryuv)
3750 -        delete [] m_ryuv;
3751 -    if (m_ralpha)
3752 -        delete [] m_ralpha;
3753 -
3754      LoadImage(m_redname, wmult, hmult, m_scalew, m_scaleh);
3755      if (m_isvalid)
3756      {
3757 @@ -1360,30 +1375,46 @@
3758  
3759  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3760  
3761 -OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect) 
3762 -          : OSDType(name)
3763 +OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect,
3764 +                       float wmult, float hmult)
3765 +    : OSDType(name)
3766  {
3767      size = displayrect;
3768 +    m_unbiasedsize =
3769 +        QRect((int)round(size.x()      / wmult),
3770 +              (int)round(size.y()      / hmult),
3771 +              (int)ceil( size.width()  / wmult),
3772 +              (int)ceil( size.height() / hmult));
3773  }
3774  
3775 +void OSDTypeBox::SetRect(QRect newrect, float wmult, float hmult)
3776 +{
3777 +    size = newrect;
3778 +    m_unbiasedsize =
3779 +        QRect((int)round(size.x()      / wmult),
3780 +              (int)round(size.y()      / hmult),
3781 +              (int)ceil( size.width()  / wmult),
3782 +              (int)ceil( size.height() / hmult));
3783 +}
3784 +
3785  OSDTypeBox::OSDTypeBox(const OSDTypeBox &other)
3786            : OSDType(other.m_name)
3787  {
3788      size = other.size;
3789 +    m_unbiasedsize = other.m_unbiasedsize;
3790  }
3791  
3792  OSDTypeBox::~OSDTypeBox()
3793  {
3794  }
3795  
3796 -void OSDTypeBox::Reinit(float wchange, float hchange)
3797 +void OSDTypeBox::Reinit(float wmult, float hmult)
3798  {
3799 -    int width = (int)(size.width() * wchange);
3800 -    int height = (int)(size.height() * hchange);
3801 -    int x = (int)(size.x() * wchange);
3802 -    int y = (int)(size.y() * hchange);
3803 -
3804 -    size = QRect(x, y, width, height);
3805 +    size =
3806 +        QRect((int)round(m_unbiasedsize.x()      * wmult),
3807 +              (int)round(m_unbiasedsize.y()      * hmult),
3808 +              (int)ceil( m_unbiasedsize.width()  * wmult),
3809 +              (int)ceil( m_unbiasedsize.height() * hmult));
3810  }
3811  
3812  void OSDTypeBox::Draw(OSDSurface *surface, int fade, int maxfade, int xoff, 
3813 @@ -1498,44 +1529,52 @@
3814  }       
3815     
3816  OSDTypePositionRectangle::OSDTypePositionRectangle(
3817 -                                        const OSDTypePositionRectangle &other) 
3818 -                        : OSDType(other.m_name), OSDTypePositionIndicator(other)
3819 +    const OSDTypePositionRectangle &other) 
3820 +    : OSDType(other.m_name), OSDTypePositionIndicator(other)
3821  {
3822      for (int i = 0; i < m_numpositions; i++)
3823      {
3824          QRect tmp = other.positions[i];
3825          positions.push_back(tmp);
3826      }
3827 +    for (int i = 0; i < m_numpositions; i++)
3828 +    {
3829 +        QRect tmp = other.unbiasedpos[i];
3830 +        unbiasedpos.push_back(tmp);
3831 +    }
3832  }
3833  
3834  OSDTypePositionRectangle::~OSDTypePositionRectangle()
3835  {
3836  }
3837  
3838 -void OSDTypePositionRectangle::Reinit(float wchange, float hchange)
3839 +void OSDTypePositionRectangle::Reinit(float wmult, float hmult)
3840  {
3841      for (int i = 0; i < m_numpositions; i++)
3842      {
3843 -        QRect tmp = positions[i];
3844 -
3845 -        int width = (int)(tmp.width() * wchange);
3846 -        int height = (int)(tmp.height() * hchange);
3847 -        int x = (int)(tmp.x() * wchange);
3848 -        int y = (int)(tmp.y() * hchange);
3849 -
3850 -        tmp = QRect(x, y, width, height);
3851 -        positions[i] = tmp;
3852 +        QRect tmp = unbiasedpos[i];
3853 +        positions[i] =
3854 +            QRect((int)round(tmp.x()      * wmult),
3855 +                  (int)round(tmp.y()      * hmult),
3856 +                  (int)ceil( tmp.width()  * wmult),
3857 +                  (int)ceil( tmp.height() * hmult));
3858      }
3859  }
3860  
3861 -void OSDTypePositionRectangle::AddPosition(QRect rect)
3862 +void OSDTypePositionRectangle::AddPosition(
3863 +    QRect rect, float wmult, float hmult)
3864  {
3865      positions.push_back(rect);
3866 +    unbiasedpos.push_back(
3867 +        QRect((int)round(rect.x()      / wmult),
3868 +              (int)round(rect.y()      / hmult),
3869 +              (int)ceil( rect.width()  / wmult),
3870 +              (int)ceil( rect.height() / hmult)));
3871      m_numpositions++;
3872  }
3873  
3874 -void OSDTypePositionRectangle::Draw(OSDSurface *surface, int fade, int maxfade, 
3875 -                                    int xoff, int yoff)
3876 +void OSDTypePositionRectangle::Draw(
3877 +    OSDSurface *surface, int fade, int maxfade, int xoff, int yoff)
3878  {
3879      fade = fade;
3880      maxfade = maxfade;
3881 @@ -1618,17 +1657,21 @@
3882  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3883  
3884  OSDTypePositionImage::OSDTypePositionImage(const QString &name)
3885 -                    : OSDTypeImage(name), OSDTypePositionIndicator()
3886 +    : OSDTypeImage(name), OSDTypePositionIndicator(),
3887 +      m_wmult(0.0f), m_hmult(0.0f)
3888  {
3889  }
3890  
3891  OSDTypePositionImage::OSDTypePositionImage(const OSDTypePositionImage &other)
3892                      : OSDTypeImage(other), OSDTypePositionIndicator(other)
3893  {
3894 +    m_wmult = other.m_wmult;
3895 +    m_hmult = other.m_hmult;
3896 +
3897      for (int i = 0; i < m_numpositions; i++)
3898      {
3899 -        QPoint tmp = other.positions[i];
3900 -        positions.push_back(tmp);
3901 +        positions.push_back(other.positions[i]);
3902 +        unbiasedpos.push_back(other.unbiasedpos[i]);
3903      }
3904  }
3905  
3906 @@ -1636,45 +1679,61 @@
3907  {
3908  }
3909  
3910 -void OSDTypePositionImage::Reinit(float wchange, float hchange, float wmult, 
3911 -                                  float hmult)
3912 +void OSDTypePositionImage::Reinit(float wmult, float hmult)
3913  {
3914 -    OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
3915 +    m_wmult = wmult;
3916 +    m_hmult = hmult;
3917 +    
3918 +    OSDTypeImage::Reinit(wmult, hmult);
3919  
3920      for (int i = 0; i < m_numpositions; i++)
3921      {
3922 -        QPoint tmp = positions[i];
3923 -
3924 -        int x = (int)(tmp.x() * wchange);
3925 -        int y = (int)(tmp.y() * hchange);
3926 -
3927 -        positions[i].setX(x);
3928 -        positions[i].setY(y);
3929 +        positions[i] =
3930 +            QPoint((int)round(unbiasedpos[i].x() * wmult),
3931 +                   (int)round(unbiasedpos[i].y() * hmult));
3932      }
3933  }
3934  
3935 -void OSDTypePositionImage::AddPosition(QPoint pos)
3936 +void OSDTypePositionImage::AddPosition(QPoint pos, float wmult, float hmult)
3937  {
3938 +    if (m_wmult == 0.0f || m_hmult == 0.0f)
3939 +    {
3940 +        m_wmult = wmult;
3941 +        m_hmult = hmult;
3942 +    }
3943      positions.push_back(pos);
3944 +    unbiasedpos.push_back(
3945 +        QPoint((int)round(pos.x() / wmult),
3946 +               (int)round(pos.y() / hmult)));
3947 +
3948 +    VERBOSE(VB_IMPORTANT,
3949 +            "OSDTypePositionImage::AddPosition["<<m_numpositions<<"]("
3950 +            <<pos.x()<<"x"<<pos.y()
3951 +            <<"  "<<wmult<<", "<<hmult<<")");
3952 +
3953      m_numpositions++;
3954  }
3955  
3956  void OSDTypePositionImage::Draw(OSDSurface *surface, int fade, int maxfade,
3957                                  int xoff, int yoff)
3958  {
3959 +    VERBOSE(VB_IMPORTANT,
3960 +            "OSDTypePositionImage::Draw["<<m_curposition<<"]("
3961 +            <<m_wmult<<", "<<m_hmult<<")");
3962 +
3963      if (m_curposition < 0 || m_curposition >= m_numpositions)
3964          return;
3965  
3966      QPoint pos = positions[m_curposition];
3967  
3968 -    OSDTypeImage::SetPosition(pos);
3969 +    OSDTypeImage::SetPosition(pos, m_wmult, m_hmult);
3970      OSDTypeImage::Draw(surface, fade, maxfade, xoff, yoff);
3971  }
3972  
3973  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3974  
3975  OSDTypeCC::OSDTypeCC(const QString &name, TTFFont *font, int xoff, int yoff,
3976 -                     int dispw, int disph)
3977 +                     int dispw, int disph, float wmult, float hmult)
3978           : OSDType(name)
3979  {
3980      m_font = font;
3981 @@ -1683,9 +1742,11 @@
3982      yoffset = yoff;
3983      displaywidth = dispw;
3984      displayheight = disph;
3985 +    m_wmult = wmult;
3986 +    m_hmult = hmult;
3987  
3988      QRect rect = QRect(0, 0, 0, 0);
3989 -    m_box = new OSDTypeBox("cc_background", rect);
3990 +    m_box = new OSDTypeBox("cc_background", rect, wmult, hmult);
3991      m_ccbackground = gContext->GetNumSetting("CCBackground", 0);
3992  }
3993  
3994 @@ -1695,12 +1756,23 @@
3995      delete m_box;
3996  }
3997  
3998 -void OSDTypeCC::Reinit(int x, int y, int dispw, int disph)
3999 +void OSDTypeCC::Reinit(float wmult, float hmult)
4000  {
4001 +    (void) wmult;
4002 +    (void) hmult;
4003 +    VERBOSE(VB_IMPORTANT, "Programmer error: "
4004 +            "Call to OSDTypeCC::Reinit(float,float)");
4005 +}
4006 +
4007 +void OSDTypeCC::Reinit(int x, int y, int dispw, int disph,
4008 +                       float wmult, float hmult)
4009 +{
4010      xoffset = x;
4011      yoffset = y;
4012      displaywidth = dispw;
4013      displayheight = disph;
4014 +    m_wmult = wmult;
4015 +    m_hmult = hmult;    
4016  }
4017  
4018  void OSDTypeCC::AddCCText(const QString &text, int x, int y, int color, 
4019 @@ -1875,7 +1947,7 @@
4020              {
4021                  QRect rect = QRect(0, 0, textlength + 4, 
4022                                     (m_font->Size() * 3 / 2) + 3);
4023 -                m_box->SetRect(rect);
4024 +                m_box->SetRect(rect, m_wmult, m_hmult);
4025                  m_box->Draw(surface, 0, 0, x - 2, y - 2);
4026              }
4027  
4028 Index: mythtv/libs/libmythtv/tv_play.cpp
4029 ===================================================================
4030 --- mythtv/libs/libmythtv/tv_play.cpp   (.../tags/release-0-19) (revision 10051)
4031 +++ mythtv/libs/libmythtv/tv_play.cpp   (.../branches/release-0-19-fixes)       (revision 10051)
4032 @@ -247,7 +247,7 @@
4033        browsechannum(""), browsechanid(""), browsestarttime(""),
4034        // Program Info for currently playing video
4035        recorderPlaybackInfo(NULL),
4036 -      playbackinfo(NULL), inputFilename(""), playbackLen(0),
4037 +      playbackinfo(NULL), playbackLen(0),
4038        lastProgram(NULL), jumpToProgram(false),
4039        // Video Players
4040        nvp(NULL), pipnvp(NULL), activenvp(NULL),
4041 @@ -578,19 +578,7 @@
4042      if (!testrec->IsValidRecorder())
4043      {
4044          if (showDialogs)
4045 -        {
4046 -            QString title = tr("MythTV is already using all available "
4047 -                               "inputs for recording.  If you want to "
4048 -                               "watch an in-progress recording, select one "
4049 -                               "from the playback menu.  If you want to "
4050 -                               "watch live TV, cancel one of the "
4051 -                               "in-progress recordings from the delete "
4052 -                               "menu.");
4053 -            
4054 -            DialogBox diag(gContext->GetMainWindow(), title);
4055 -            diag.AddButton(tr("Cancel and go back to the TV menu"));
4056 -            diag.exec();
4057 -        }        
4058 +            ShowNoRecorderDialog();
4059          
4060          delete testrec;
4061          
4062 @@ -659,8 +647,6 @@
4063      if (internalState != kState_None)
4064          return 0;
4065  
4066 -    inputFilename = rcinfo->pathname;
4067 -
4068      playbackLen = rcinfo->CalculateLength();
4069      playbackinfo = new ProgramInfo(*rcinfo);
4070  
4071 @@ -844,9 +830,10 @@
4072          }
4073          else
4074          {
4075 +            QString playbackURL = playbackinfo->GetPlaybackURL();
4076 +
4077              tvchain->SetProgram(playbackinfo);
4078 -
4079 -            prbuffer = new RingBuffer(playbackinfo->pathname, false);
4080 +            prbuffer = new RingBuffer(playbackURL, false);
4081              prbuffer->SetLiveMode(tvchain);
4082          }
4083  
4084 @@ -895,7 +882,14 @@
4085      else if (TRANSITION(kState_None, kState_WatchingPreRecorded) ||
4086               TRANSITION(kState_None, kState_WatchingRecording))
4087      {
4088 -        prbuffer = new RingBuffer(inputFilename, false);
4089 +        QString playbackURL;
4090 +        if ((playbackinfo->pathname.left(4) == "dvd:") ||
4091 +            (playbackinfo->isVideo))
4092 +            playbackURL = playbackinfo->pathname;
4093 +        else
4094 +            playbackURL = playbackinfo->GetPlaybackURL();
4095 +
4096 +        prbuffer = new RingBuffer(playbackURL, false);
4097          if (prbuffer->IsOpen())
4098          {
4099              gContext->DisableScreensaver();
4100 @@ -924,7 +918,7 @@
4101              {
4102                  QString message = "COMMFLAG_REQUEST ";
4103                  message += playbackinfo->chanid + " " +
4104 -                           playbackinfo->startts.toString(Qt::ISODate);
4105 +                           playbackinfo->recstartts.toString(Qt::ISODate);
4106                  RemoteSendMessage(message);
4107              }                
4108          }
4109 @@ -1222,10 +1216,10 @@
4110      nvp->SetParentPlayer(this);
4111      nvp->SetRingBuffer(prbuffer);
4112      nvp->SetRecorder(recorder);
4113 -    nvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate"));
4114 +    nvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate", 44100));
4115      nvp->SetAudioDevice(gContext->GetSetting("AudioOutputDevice"));
4116      nvp->SetLength(playbackLen);
4117 -    nvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking"));
4118 +    nvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking", 0));
4119      nvp->SetAutoCommercialSkip(autoCommercialSkip);
4120      nvp->SetLiveTVChain(tvchain);
4121  
4122 @@ -1296,9 +1290,9 @@
4123      pipnvp->SetAsPIP();
4124      pipnvp->SetRingBuffer(piprbuffer);
4125      pipnvp->SetRecorder(piprecorder);
4126 -    pipnvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate"));
4127 +    pipnvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate", 44100));
4128      pipnvp->SetAudioDevice(gContext->GetSetting("AudioOutputDevice"));
4129 -    pipnvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking"));
4130 +    pipnvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking", 0));
4131      pipnvp->SetLiveTVChain(piptvchain);
4132  
4133      pipnvp->SetLength(playbackLen);
4134 @@ -1454,6 +1448,30 @@
4135                  lastSignalMsg.clear();
4136              }
4137              UpdateOSDTimeoutMessage();
4138 +
4139 +            if (!tvchainUpdate.isEmpty())
4140 +            {
4141 +                tvchainUpdateLock.lock();
4142 +                for (QStringList::Iterator it = tvchainUpdate.begin();
4143 +                     it != tvchainUpdate.end(); ++it)
4144 +                {
4145 +                    if (tvchain && nvp && *it == tvchain->GetID())
4146 +                    {
4147 +                        tvchain->ReloadAll();
4148 +                        if (nvp->GetTVChain())
4149 +                            nvp->CheckTVChain();
4150 +                    }
4151 +                    if (piptvchain && pipnvp && *it == piptvchain->GetID())
4152 +                    {
4153 +                        piptvchain->ReloadAll();
4154 +                        if (pipnvp->GetTVChain())
4155 +                            pipnvp->CheckTVChain();
4156 +                    }
4157 +                }
4158 +                tvchainUpdate.clear();
4159 +                tvchainUpdateLock.unlock();
4160 +            }
4161 +
4162              osdlock.unlock();
4163          }
4164  
4165 @@ -2743,7 +2761,7 @@
4166                  speedStr = QString("%1X").arg(normal_speed);
4167  
4168              struct StatusPosInfo posInfo;
4169 -            nvp->calcSliderPos(posInfo);
4170 +            nvp->calcSliderPos(posInfo, true);
4171  
4172              QDateTime respDate = mythCurrentDateTime();
4173              QString infoStr = "";
4174 @@ -2806,8 +2824,10 @@
4175          }
4176          else
4177          {
4178 +            QString playbackURL = playbackinfo->GetPlaybackURL();
4179 +
4180              piptvchain->SetProgram(playbackinfo);
4181 -            piprbuffer = new RingBuffer(playbackinfo->pathname, false);
4182 +            piprbuffer = new RingBuffer(playbackURL, false);
4183              piprbuffer->SetLiveMode(piptvchain);
4184          }
4185  
4186 @@ -3472,8 +3492,10 @@
4187          }
4188          else
4189          {
4190 +            QString playbackURL = playbackinfo->GetPlaybackURL();
4191 +
4192              tvchain->SetProgram(playbackinfo);
4193 -            prbuffer = new RingBuffer(playbackinfo->pathname, false);
4194 +            prbuffer = new RingBuffer(playbackURL, false);
4195              prbuffer->SetLiveMode(tvchain);
4196          }
4197  
4198 @@ -4627,7 +4649,8 @@
4199  
4200      normal_speed = new_normal_speed;
4201  
4202 -    activenvp->Play(normal_speed, true);
4203 +    if (!paused)
4204 +        activenvp->Play(normal_speed, true);
4205  
4206      QString text = QString(tr("Time Stretch %1X")).arg(normal_speed);
4207  
4208 @@ -4911,29 +4934,14 @@
4209          }
4210          else if (tvchain && message.left(12) == "LIVETV_CHAIN")
4211          {
4212 -            // Get osdlock, while intended for the OSD this ensures that
4213 -            // the nvp & pipnvp are not deleted while we are using it..
4214 -            while (!osdlock.tryLock() && nvp)
4215 -                usleep(2500);
4216 -
4217              message = message.simplifyWhiteSpace();
4218              QStringList tokens = QStringList::split(" ", message);
4219              if (tokens[1] == "UPDATE")
4220              {
4221 -                if (tvchain && nvp && tokens[2] == tvchain->GetID())
4222 -                {
4223 -                    tvchain->ReloadAll();
4224 -                    if (nvp->GetTVChain())
4225 -                        nvp->CheckTVChain();
4226 -                }
4227 -                if (piptvchain && pipnvp && tokens[2] == piptvchain->GetID())
4228 -                {
4229 -                    piptvchain->ReloadAll();
4230 -                    if (pipnvp->GetTVChain())
4231 -                        pipnvp->CheckTVChain();
4232 -                }
4233 +                tvchainUpdateLock.lock();
4234 +                tvchainUpdate += QDeepCopy<QString>(tokens[2]);
4235 +                tvchainUpdateLock.unlock();
4236              }
4237 -            osdlock.unlock();
4238          }
4239          else if (nvp && message.left(12) == "EXIT_TO_MENU")
4240          {
4241 @@ -4983,7 +4991,7 @@
4242              QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
4243  
4244              if ((playbackinfo->chanid == evchanid) &&
4245 -                (playbackinfo->startts == evstartts))
4246 +                (playbackinfo->recstartts == evstartts))
4247              {
4248                  QString msg = "COMMFLAG_REQUEST ";
4249                  msg += tokens[1] + " " + tokens[2];
4250 @@ -5000,7 +5008,7 @@
4251              QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
4252  
4253              if ((playbackinfo->chanid == evchanid) &&
4254 -                (playbackinfo->startts == evstartts))
4255 +                (playbackinfo->recstartts == evstartts))
4256              {
4257                  QMap<long long, int> newMap;
4258                  QStringList mark;
4259 @@ -6067,9 +6075,22 @@
4260                             "in-progress recordings from the delete "
4261                             "menu.");
4262  
4263 -    MythPopupBox::showOkPopup(
4264 +    if (embedWinID)
4265 +    {
4266 +        VERBOSE(VB_IMPORTANT, errorText);
4267 +    }
4268 +    else if (GetOSD())
4269 +    {
4270 +        dialogname = "infobox";
4271 +        QStringList options("OK");
4272 +        GetOSD()->NewDialogBox(dialogname, errorText, options, 0);
4273 +    }
4274 +    else
4275 +    {
4276 +        MythPopupBox::showOkPopup(
4277              gContext->GetMainWindow(), QObject::tr("Channel Change Error"),
4278              errorText);
4279 +    }
4280  }
4281  
4282  /** \fn TV::PauseLiveTV(void)
4283 Index: mythtv/libs/libmythtv/jobqueue.cpp
4284 ===================================================================
4285 --- mythtv/libs/libmythtv/jobqueue.cpp  (.../tags/release-0-19) (revision 10051)
4286 +++ mythtv/libs/libmythtv/jobqueue.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
4287 @@ -275,6 +275,11 @@
4288                      (hostname != "") &&
4289                      (hostname != m_hostname))
4290                  {
4291 +                    // Setting the status here will prevent us from processing
4292 +                    // any other jobs for this recording until this one is
4293 +                    // completed on the remote host.
4294 +                    jobStatus[key] = status;
4295 +
4296                      message = QString("JobQueue: Skipping '%1' job for chanid "
4297                                        "%2 @ %3, should run on '%4' instead")
4298                                        .arg(JobText(type))
4299 Index: mythtv/libs/libmythtv/dvbdev/dvbdev.c
4300 ===================================================================
4301 --- mythtv/libs/libmythtv/dvbdev/dvbdev.c       (.../tags/release-0-19) (revision 10051)
4302 +++ mythtv/libs/libmythtv/dvbdev/dvbdev.c       (.../branches/release-0-19-fixes)       (revision 10051)
4303 @@ -29,55 +29,79 @@
4304  
4305  const char* dvbdevice(int type, int cardnum)
4306  {
4307 -    char* frontenddev[4] =
4308 +    char* frontenddev[8] =
4309      {
4310          "/dev/dvb/adapter0/frontend0",
4311          "/dev/dvb/adapter1/frontend0",
4312          "/dev/dvb/adapter2/frontend0",
4313 -        "/dev/dvb/adapter3/frontend0"
4314 +        "/dev/dvb/adapter3/frontend0",
4315 +        "/dev/dvb/adapter4/frontend0",
4316 +        "/dev/dvb/adapter5/frontend0",
4317 +        "/dev/dvb/adapter6/frontend0",
4318 +        "/dev/dvb/adapter7/frontend0",
4319      };
4320  
4321 -    char* dvrdev[4] =
4322 +    char* dvrdev[8] =
4323      {
4324          "/dev/dvb/adapter0/dvr0",
4325          "/dev/dvb/adapter1/dvr0",
4326          "/dev/dvb/adapter2/dvr0",
4327 -        "/dev/dvb/adapter3/dvr0"
4328 +        "/dev/dvb/adapter3/dvr0",
4329 +        "/dev/dvb/adapter4/dvr0",
4330 +        "/dev/dvb/adapter5/dvr0",
4331 +        "/dev/dvb/adapter6/dvr0",
4332 +        "/dev/dvb/adapter7/dvr0",
4333      };
4334  
4335 -    char* demuxdev[4] =
4336 +    char* demuxdev[8] =
4337      {
4338          "/dev/dvb/adapter0/demux0",
4339          "/dev/dvb/adapter1/demux0",
4340          "/dev/dvb/adapter2/demux0",
4341 -        "/dev/dvb/adapter3/demux0"
4342 +        "/dev/dvb/adapter3/demux0",
4343 +        "/dev/dvb/adapter4/demux0",
4344 +        "/dev/dvb/adapter5/demux0",
4345 +        "/dev/dvb/adapter6/demux0",
4346 +        "/dev/dvb/adapter7/demux0",
4347      };
4348  
4349 -    char* cadev[4] =
4350 +    char* cadev[8] =
4351      {
4352          "/dev/dvb/adapter0/ca0",
4353          "/dev/dvb/adapter1/ca0",
4354          "/dev/dvb/adapter2/ca0",
4355 -        "/dev/dvb/adapter3/ca0"
4356 +        "/dev/dvb/adapter3/ca0",
4357 +        "/dev/dvb/adapter4/ca0",
4358 +        "/dev/dvb/adapter5/ca0",
4359 +        "/dev/dvb/adapter6/ca0",
4360 +        "/dev/dvb/adapter7/ca0",
4361      };
4362  
4363 -    char* audiodev[4] =
4364 +    char* audiodev[8] =
4365      {
4366          "/dev/dvb/adapter0/audio0",
4367          "/dev/dvb/adapter1/audio0",
4368          "/dev/dvb/adapter2/audio0",
4369 -        "/dev/dvb/adapter3/audio0"
4370 +        "/dev/dvb/adapter3/audio0",
4371 +        "/dev/dvb/adapter4/audio0",
4372 +        "/dev/dvb/adapter5/audio0",
4373 +        "/dev/dvb/adapter6/audio0",
4374 +        "/dev/dvb/adapter7/audio0",
4375      };
4376  
4377 -    char* videodev[4] =
4378 +    char* videodev[8] =
4379      {
4380          "/dev/dvb/adapter0/video0",
4381          "/dev/dvb/adapter1/video0",
4382          "/dev/dvb/adapter2/video0",
4383 -        "/dev/dvb/adapter3/video0"
4384 +        "/dev/dvb/adapter3/video0",
4385 +        "/dev/dvb/adapter4/video0",
4386 +        "/dev/dvb/adapter5/video0",
4387 +        "/dev/dvb/adapter6/video0",
4388 +        "/dev/dvb/adapter7/video0",
4389      };
4390  
4391 -    if (cardnum > 3)
4392 +    if (cardnum > 7)
4393          return 0;
4394  
4395      switch(type)
4396 Index: mythtv/libs/libmythtv/libmythtv.pro
4397 ===================================================================
4398 --- mythtv/libs/libmythtv/libmythtv.pro (.../tags/release-0-19) (revision 10051)
4399 +++ mythtv/libs/libmythtv/libmythtv.pro (.../branches/release-0-19-fixes)       (revision 10051)
4400 @@ -144,10 +144,10 @@
4401      # On screen display (video output overlay)
4402      HEADERS += osd.h                    osdtypes.h
4403      HEADERS += osdsurface.h             osdlistbtntype.h
4404 -    HEADERS += udpnotify.h 
4405 +    HEADERS += osdimagecache.h          udpnotify.h 
4406      SOURCES += osd.cpp                  osdtypes.cpp
4407      SOURCES += osdsurface.cpp           osdlistbtntype.cpp
4408 -    SOURCES += udpnotify.cpp 
4409 +    SOURCES += osdimagecache.cpp        udpnotify.cpp 
4410  
4411      # Video output
4412      HEADERS += videooutbase.h           videoout_null.h
4413 Index: mythtv/libs/libmythtv/osdtypes.h
4414 ===================================================================
4415 --- mythtv/libs/libmythtv/osdtypes.h    (.../tags/release-0-19) (revision 10051)
4416 +++ mythtv/libs/libmythtv/osdtypes.h    (.../branches/release-0-19-fixes)       (revision 10051)
4417 @@ -8,6 +8,7 @@
4418  #include <vector>
4419  #include <qobject.h>
4420  #include <qregexp.h>
4421 +#include "osdimagecache.h"
4422  
4423  using namespace std;
4424  
4425 @@ -137,6 +138,8 @@
4426  
4427      QString Name() { return m_name; }
4428  
4429 +    virtual void Reinit(float wmult, float hmult) = 0;
4430 +
4431      virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
4432                        int yoff) = 0;
4433  
4434 @@ -150,11 +153,11 @@
4435  {
4436    public:
4437      OSDTypeText(const QString &name, TTFFont *font, const QString &text,
4438 -                QRect displayrect);
4439 +                QRect displayrect, float wmult, float hmult);
4440      OSDTypeText(const OSDTypeText &text);
4441     ~OSDTypeText();
4442  
4443 -    void Reinit(float wchange, float hchange);
4444 +    void Reinit(float wmult, float hmult);
4445  
4446      void SetAltFont(TTFFont *font);
4447      void SetUseAlt(bool usealt) { m_usingalt = usealt; }
4448 @@ -190,6 +193,7 @@
4449  
4450      QRect m_displaysize;
4451      QRect m_screensize;
4452 +    QRect m_unbiasedsize;
4453      QString m_message;
4454      QString m_default_msg;
4455  
4456 @@ -231,7 +235,7 @@
4457      virtual ~OSDTypeImage();
4458  
4459      void SetName(const QString &name);
4460 -    void Reinit(float wchange, float hchange, float wmult, float hmult);
4461 +    void Reinit(float wmult, float hmult);
4462  
4463      void LoadImage(const QString &filename, float wmult, float hmult, 
4464                     int scalew = -1, int scaleh = -1);
4465 @@ -239,21 +243,20 @@
4466  
4467      void SetStaticSize(int scalew, int scaleh) { m_scalew = scalew;
4468                                                   m_scaleh = scaleh; }
4469 +    void SetPosition(QPoint pos, float wmult, float hmult);
4470  
4471 -    QPoint DisplayPos() { return m_displaypos; }
4472 -    void SetPosition(QPoint pos) { m_displaypos = pos; }
4473 +    QPoint DisplayPos() const { return m_displaypos;         }
4474 +    QRect  ImageSize()  const { return m_imagesize;          }
4475 +    int    width()      const { return m_imagesize.width();  }
4476 +    int    height()     const { return m_imagesize.height(); }
4477  
4478 -    QRect ImageSize() { return m_imagesize; }
4479 -
4480 -    int width() { return m_imagesize.width(); }
4481 -    int height() { return m_imagesize.height(); }
4482 -
4483      virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, 
4484                        int yoff);
4485  
4486    protected:
4487      QRect m_imagesize;
4488      QPoint m_displaypos;
4489 +    QPoint m_unbiasedpos;
4490  
4491      QString m_filename;
4492  
4493 @@ -270,6 +273,9 @@
4494  
4495      int m_drawwidth;
4496      bool m_onlyusefirst;
4497 +
4498 +    static OSDImageCache  c_cache;
4499 +    OSDImageCacheValue   *m_cacheitem;
4500  };
4501  
4502  class OSDTypePosSlider : public OSDTypeImage
4503 @@ -280,7 +286,7 @@
4504                        int scalew = -1, int scaleh = -1);
4505     ~OSDTypePosSlider();
4506  
4507 -    void Reinit(float wchange, float hchange, float wmult, float hmult);
4508 +    void Reinit(float wmult, float hmult);
4509  
4510      void SetRectangle(QRect rect) { m_displayrect = rect; }
4511      QRect ImageSize() { return m_imagesize; }
4512 @@ -290,6 +296,7 @@
4513  
4514    private:
4515      QRect m_displayrect;
4516 +    QRect m_unbiasedrect;
4517      int m_maxval;
4518      int m_curval;
4519  };
4520 @@ -302,7 +309,7 @@
4521                        int scalew = -1, int scaleh = -1);
4522     ~OSDTypeFillSlider();
4523  
4524 -    void Reinit(float wchange, float hchange, float wmult, float hmult);
4525 +    void Reinit(float wmult, float hmult);
4526  
4527      void SetRectangle(QRect rect) { m_displayrect = rect; }
4528      QRect ImageSize() { return m_imagesize; }
4529 @@ -314,6 +321,7 @@
4530  
4531    private:
4532      QRect m_displayrect;
4533 +    QRect m_unbiasedrect;
4534      int m_maxval;
4535      int m_curval;
4536  };
4537 @@ -327,7 +335,7 @@
4538                        int scalew = -1, int scaleh = -1);
4539     ~OSDTypeEditSlider();
4540  
4541 -    void Reinit(float wchange, float hchange, float wmult, float hmult);
4542 +    void Reinit(float wmult, float hmult);
4543  
4544      void SetRectangle(QRect rect) { m_displayrect = rect; }
4545      QRect ImageSize() { return m_imagesize; }
4546 @@ -339,6 +347,7 @@
4547  
4548    private:
4549      QRect m_displayrect;
4550 +    QRect m_unbiasedrect;
4551      int m_maxval;
4552      int m_curval;
4553  
4554 @@ -360,17 +369,19 @@
4555  class OSDTypeBox : public OSDType
4556  {
4557    public:
4558 -    OSDTypeBox(const QString &name, QRect displayrect); 
4559 +    OSDTypeBox(const QString &name, QRect displayrect,
4560 +               float wmult, float hmult);
4561      OSDTypeBox(const OSDTypeBox &other);
4562     ~OSDTypeBox();
4563  
4564 -    void Reinit(float wchange, float hchange);
4565 -    void SetRect(QRect newrect) { size = newrect; }
4566 +    void Reinit(float wmult, float hmult);
4567 +    void SetRect(QRect newrect, float wmult, float hmult);
4568  
4569      void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4570  
4571    private:
4572      QRect size;
4573 +    QRect m_unbiasedsize;
4574  };
4575  
4576  class OSDTypePositionIndicator
4577 @@ -403,14 +414,15 @@
4578      OSDTypePositionRectangle(const OSDTypePositionRectangle &other);
4579     ~OSDTypePositionRectangle();
4580  
4581 -    void AddPosition(QRect rect);
4582 +    void AddPosition(QRect rect, float wmult, float hmult);
4583  
4584 -    void Reinit(float wchange, float hchange);
4585 +    void Reinit(float wmult, float hmult);
4586  
4587      void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4588  
4589    private:
4590 -    vector<QRect> positions; 
4591 +    vector<QRect> positions;
4592 +    vector<QRect> unbiasedpos;
4593  };
4594  
4595  class OSDTypePositionImage : public virtual OSDTypeImage, 
4596 @@ -421,14 +433,17 @@
4597      OSDTypePositionImage(const OSDTypePositionImage &other);
4598     ~OSDTypePositionImage();
4599  
4600 -    void Reinit(float wchange, float hchange, float wmult, float hmult);
4601 +    void Reinit(float wmult, float hmult);
4602  
4603 -    void AddPosition(QPoint pos);
4604 +    void AddPosition(QPoint pos, float wmult, float hmult);
4605  
4606      void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4607  
4608    private:
4609      vector<QPoint> positions;
4610 +    vector<QPoint> unbiasedpos;
4611 +    float m_wmult;
4612 +    float m_hmult;
4613  };
4614  
4615  class ccText
4616 @@ -445,11 +460,15 @@
4617  {
4618    public:
4619      OSDTypeCC(const QString &name, TTFFont *font, int xoff, int yoff,
4620 -              int dispw, int disph);
4621 +              int dispw, int disph, float wmult, float hmult);
4622     ~OSDTypeCC();
4623  
4624 -    void Reinit(int xoff, int yoff, int dispw, int disph);
4625 +    void Reinit(float wmult, float hmult);
4626  
4627 +    void Reinit(int xoff, int yoff,
4628 +                int dispw, int disph,
4629 +                float wmult, float hmult);
4630 +
4631      void AddCCText(const QString &text, int x, int y, int color, 
4632                     bool teletextmode = false);
4633      void ClearAllCCText();
4634 @@ -464,7 +483,7 @@
4635      vector<ccText *> *m_textlist;
4636      OSDTypeBox *m_box;
4637      int m_ccbackground;
4638 -
4639 +    float m_wmult, m_hmult;
4640      int xoffset, yoffset, displaywidth, displayheight;
4641  };
4642  
4643 Index: mythtv/libs/libmythtv/osdimagecache.h
4644 ===================================================================
4645 --- mythtv/libs/libmythtv/osdimagecache.h       (.../tags/release-0-19) (revision 0)
4646 +++ mythtv/libs/libmythtv/osdimagecache.h       (.../branches/release-0-19-fixes)       (revision 10051)
4647 @@ -0,0 +1,74 @@
4648 +// -*- Mode: c++ -*-
4649 +
4650 +// POSIX headers
4651 +#include <stdint.h>
4652 +
4653 +// Qt headers
4654 +#include <qmap.h>
4655 +#include <qrect.h>
4656 +#include <qmutex.h>
4657 +#include <qstring.h>
4658 +#include <qasciicache.h>
4659 +
4660 +class OSDImageCacheValue
4661 +{
4662 +  public:
4663 +    OSDImageCacheValue(QString cacheKey,
4664 +                      unsigned char *yuv,     unsigned char *ybuffer,
4665 +                       unsigned char *ubuffer, unsigned char *vbuffer,
4666 +                       unsigned char *alpha,   QRect imagesize);
4667 +
4668 +    virtual ~OSDImageCacheValue();
4669 +
4670 +    uint    GetSize(void) const { return m_size_in_bytes; }
4671 +    QString GetKey(void)  const { return m_cacheKey;      }
4672 +
4673 +  public:
4674 +    unsigned char *m_yuv;
4675 +    unsigned char *m_ybuffer;
4676 +    unsigned char *m_ubuffer;
4677 +    unsigned char *m_vbuffer;
4678 +    unsigned char *m_alpha;
4679 +    QRect          m_imagesize;
4680 +
4681 +  private:
4682 +    uint           m_size_in_bytes;
4683 +    QString        m_cacheKey;
4684 +};
4685 +
4686 +typedef QAsciiCache<OSDImageCacheValue> img_cache_t;
4687 +
4688 +class OSDImageCache
4689 +{
4690 +  public:
4691 +    OSDImageCache();
4692 +    virtual ~OSDImageCache();
4693 +
4694 +    bool InFileCache(const QString &key) const;
4695 +
4696 +    bool Contains(const QString &key, bool useFile) const;
4697 +
4698 +    OSDImageCacheValue *Get(const QString &key, bool useFile);
4699 +
4700 +    void Insert(OSDImageCacheValue* value);
4701 +
4702 +    void SaveToDisk(const OSDImageCacheValue *value);
4703 +
4704 +    void Reset(void);
4705 +
4706 +    static QString CreateKey(const QString &filename,
4707 +                             float wmult, float hmult,
4708 +                             int scalew,  int scaleh);
4709 +
4710 +    static QString ExtractOriginal(const QString &key);
4711 +
4712 +  private:
4713 +    mutable QMutex m_cacheLock;
4714 +    img_cache_t    m_imageCache;
4715 +    int            m_memHits;
4716 +    int            m_diskHits;
4717 +    int            m_misses;
4718 +
4719 +    /// Limit on the maximum total size of OSD images cached in *memory*.
4720 +    static uint    kMaximumMemoryCacheSize;
4721 +};
4722 Index: mythtv/libs/libmythtv/tv_play.h
4723 ===================================================================
4724 --- mythtv/libs/libmythtv/tv_play.h     (.../tags/release-0-19) (revision 10051)
4725 +++ mythtv/libs/libmythtv/tv_play.h     (.../branches/release-0-19-fixes)       (revision 10051)
4726 @@ -456,7 +456,6 @@
4727      ProgramInfo *recorderPlaybackInfo; ///< info requested from recorder
4728      ProgramInfo *playbackinfo;  ///< info sent in via Playback()
4729      QMutex       pbinfoLock;
4730 -    QString      inputFilename; ///< playbackinfo->pathname
4731      int          playbackLen;   ///< initial playbackinfo->CalculateLength()
4732      ProgramInfo *lastProgram;   ///< last program played with this player
4733      bool         jumpToProgram;
4734 @@ -485,6 +484,8 @@
4735      // LiveTVChain
4736      LiveTVChain *tvchain;
4737      LiveTVChain *piptvchain;
4738 +    QStringList tvchainUpdate;
4739 +    QMutex tvchainUpdateLock;
4740  
4741      // RingBuffers
4742      RingBuffer *prbuffer;
4743 Index: mythtv/libs/libmythtv/videosource.cpp
4744 ===================================================================
4745 --- mythtv/libs/libmythtv/videosource.cpp       (.../tags/release-0-19) (revision 10051)
4746 +++ mythtv/libs/libmythtv/videosource.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
4747 @@ -32,6 +32,7 @@
4748  #include "videosource.h"
4749  #include "datadirect.h"
4750  #include "scanwizard.h"
4751 +#include "frequencies.h"
4752  
4753  #ifdef USING_DVB
4754  #include <linux/dvb/frontend.h>
4755 @@ -574,22 +575,10 @@
4756  {
4757      setLabel(QObject::tr("Channel frequency table"));
4758      addSelection("default");
4759 -    addSelection("us-cable");
4760 -    addSelection("us-bcast");
4761 -    addSelection("us-cable-hrc");
4762 -    addSelection("japan-bcast");
4763 -    addSelection("japan-cable");
4764 -    addSelection("europe-west");
4765 -    addSelection("europe-east");
4766 -    addSelection("italy");
4767 -    addSelection("newzealand");
4768 -    addSelection("australia");
4769 -    addSelection("ireland");
4770 -    addSelection("france");
4771 -    addSelection("china-bcast");
4772 -    addSelection("southafrica");
4773 -    addSelection("argentina");
4774 -    addSelection("australia-optus");
4775 +
4776 +    for (uint i = 0; chanlists[i].name; i++)
4777 +        addSelection(chanlists[i].name);
4778 +
4779      setHelpText(QObject::tr("Use default unless this source uses a "
4780                  "different frequency table than the system wide table "
4781                  "defined in the General settings."));
4782 Index: mythtv/libs/libmythtv/frequencytables.cpp
4783 ===================================================================
4784 --- mythtv/libs/libmythtv/frequencytables.cpp   (.../tags/release-0-19) (revision 10051)
4785 +++ mythtv/libs/libmythtv/frequencytables.cpp   (.../branches/release-0-19-fixes)       (revision 10051)
4786 @@ -283,104 +283,52 @@
4787          "ATSC Channel %1", 70, 809000000, 887000000, 6000000, VSB_8);
4788  #endif // USING_DVB
4789  
4790 -    // USA Cable, QAM 256
4791 -    fmap["atsc_qam256_uscable0"] = new FrequencyTable(
4792 -        "QAM-256 Channel %1",   1, 75000000,1005000000, 6000000, QAM_256);
4793 -    fmap["atsc_qam256_uscable1"] = new FrequencyTable(
4794 -        "QAM-256 Channel T-%1", 7, 10000000,  52000000, 6000000, QAM_256);
4795 +    QString modStr[] = { "vsb8",  "qam256",   "qam128",   "qam64",   };
4796 +    uint    mod[]    = { VSB_8,    QAM_256,    QAM_128,    QAM_64,   };
4797 +    QString desc[]   = { "ATSC ", "QAM-256 ", "QAM-128 ", "QAM-64 ", };
4798  
4799 -    // USA Cable, QAM 256 ch 78+
4800 -    fmap["atsc_qam256_uscablehigh0"] = new FrequencyTable(
4801 -        "QAM-256 Channel %1",  78,472000000,1005000000, 6000000, QAM_256);
4802 +#define FREQ(A,B, C,D, E,F,G, H) \
4803 +    fmap[QString("atsc_%1_us%2").arg(A).arg(B)] = \
4804 +        new FrequencyTable(C+D, E, F, G, 6000000, H);
4805  
4806 -    // USA Cable HRC, QAM 256
4807 -    fmap["atsc_qam256_ushrc0"] = new FrequencyTable(
4808 -        "QAM-256 HRC %1",   1,  73750000,  73750001, 6000000, QAM_256);
4809 -    fmap["atsc_qam256_ushrc1"] = new FrequencyTable(
4810 -        "QAM-256 HRC %1",   2,  55750000,  67750000, 6000000, QAM_256);
4811 -    fmap["atsc_qam256_ushrc2"] = new FrequencyTable(
4812 -        "QAM-256 HRC %1",   5,  79750000,  85750000, 6000000, QAM_256);
4813 -    fmap["atsc_qam256_ushrc3"] = new FrequencyTable(
4814 -        "QAM-256 HRC %1",   7, 175750000, 643750000, 6000000, QAM_256);
4815 -    fmap["atsc_qam256_ushrc4"] = new FrequencyTable(
4816 -        "QAM-256 HRC %1",  95,  91750000, 114000000, 6000000, QAM_256);
4817 -    fmap["atsc_qam256_ushrc5"] = new FrequencyTable(
4818 -        "QAM-256 HRC %1", 100, 649750000, 799750000, 6000000, QAM_256);
4819 -    fmap["atsc_qam256_ushrc6"] = new FrequencyTable(
4820 -        "QAM-256 HRC T-%1", 7,   8175000,  50750000, 6000000, QAM_256);
4821 +    for (uint i = 0; i < 3; i++)
4822 +    {
4823 +        // USA Cable, ch 1 to 155 and T.7 to T.14
4824 +        FREQ(modStr[i], "cable0", desc[i], "Channel %1",
4825 +             1, 75000000, 1005000000, mod[i]);
4826 +        FREQ(modStr[i], "cable1", desc[i], "Channel T-%1",
4827 +             7, 10000000,   52000000, mod[i]);
4828 +        // USA Cable, QAM 256 ch 78 to 155
4829 +        FREQ(modStr[i], "cablehigh0", desc[i], "Channel %1",
4830 +             78, 537000000,1005000000, mod[i]);
4831  
4832 -    // USA Cable HRC, QAM 256 ch 78+
4833 -    fmap["atsc_qam256_ushrchigh0"] = new FrequencyTable(
4834 -        "QAM-256 HRC %1",  78, 601750000, 643750000, 6000000, QAM_256);
4835 -    fmap["atsc_qam256_ushrchigh1"] = new FrequencyTable(
4836 -        "QAM-256 HRC %1", 100, 649750000, 799750000, 6000000, QAM_256);
4837 +        QString std[]   = { "hrc",  "irc"   };
4838 +        QString sdesc[] = { "HRC ", "IRC "  };
4839 +        int     off[]   = { 0,      1250000 };
4840  
4841 +        for (uint j = 0; j < 2; j++)
4842 +        {
4843 +            // USA Cable HRC/IRC, ch 1 to 125
4844 +            FREQ(modStr[i], std[j] + "0", desc[i], sdesc[j] + "%1",
4845 +                 1,   73750000 + off[j],  73750001 + off[j], mod[i]);
4846 +            FREQ(modStr[i], std[j] + "1", desc[i], sdesc[j] + "%1",
4847 +                 2,   55750000 + off[j],  67750000 + off[j], mod[i]);
4848 +            FREQ(modStr[i], std[j] + "2", desc[i], sdesc[j] + "%1",
4849 +                 5,   79750000 + off[j],  85750000 + off[j], mod[i]);
4850 +            FREQ(modStr[i], std[j] + "3", desc[i], sdesc[j] + "%1",
4851 +                 7,  175750000 + off[j], 643750000 + off[j], mod[i]);
4852 +            FREQ(modStr[i], std[j] + "4", desc[i], sdesc[j] + "%1",
4853 +                 95,  91750000 + off[j], 114000000 + off[j], mod[i]);
4854 +            FREQ(modStr[i], std[j] + "5", desc[i], sdesc[j] + "%1",
4855 +                 100, 649750000 + off[j], 799750000 + off[j], mod[i]);
4856 +            FREQ(modStr[i], std[j] + "6", desc[i], sdesc[j] + "T-%1",
4857 +                 7,     8175000 + off[j],  50750000 + off[j], mod[i]);
4858  
4859 -
4860 -    // USA Cable, QAM 128
4861 -    fmap["atsc_qam128_uscable0"] = new FrequencyTable(
4862 -        "QAM-128 Channel %1",   1, 75000000,1005000000, 6000000, QAM_128);
4863 -    fmap["atsc_qam128_uscable1"] = new FrequencyTable(
4864 -        "QAM-128 Channel T-%1", 7, 10000000,  52000000, 6000000, QAM_128);
4865 -
4866 -    // USA Cable, QAM 128 ch 78+
4867 -    fmap["atsc_qam128_uscablehigh0"] = new FrequencyTable(
4868 -        "QAM-128 Channel %1",  78,472000000,1005000000, 6000000, QAM_128);
4869 -
4870 -    // USA Cable HRC, QAM 128
4871 -    fmap["atsc_qam128_ushrc0"] = new FrequencyTable(
4872 -        "QAM-128 HRC %1",   1,  73750000,  73750001, 6000000, QAM_128);
4873 -    fmap["atsc_qam128_ushrc1"] = new FrequencyTable(
4874 -        "QAM-128 HRC %1",   2,  55750000,  67750000, 6000000, QAM_128);
4875 -    fmap["atsc_qam128_ushrc2"] = new FrequencyTable(
4876 -        "QAM-128 HRC %1",   5,  79750000,  85750000, 6000000, QAM_128);
4877 -    fmap["atsc_qam128_ushrc3"] = new FrequencyTable(
4878 -        "QAM-128 HRC %1",   7, 175750000, 643750000, 6000000, QAM_128);
4879 -    fmap["atsc_qam128_ushrc4"] = new FrequencyTable(
4880 -        "QAM-128 HRC %1",  95,  91750000, 114000000, 6000000, QAM_128);
4881 -    fmap["atsc_qam128_ushrc5"] = new FrequencyTable(
4882 -        "QAM-128 HRC %1", 100, 649750000, 799750000, 6000000, QAM_128);
4883 -    fmap["atsc_qam128_ushrc6"] = new FrequencyTable(
4884 -        "QAM-128 HRC T-%1", 7,   8175000,  50750000, 6000000, QAM_128);
4885 -
4886 -    // USA Cable HRC, QAM 128 ch 78+
4887 -    fmap["atsc_qam128_ushrchigh0"] = new FrequencyTable(
4888 -        "QAM-128 HRC %1",  78, 601750000, 643750000, 6000000, QAM_128);
4889 -    fmap["atsc_qam128_ushrchigh1"] = new FrequencyTable(
4890 -        "QAM-128 HRC %1", 100, 649750000, 799750000, 6000000, QAM_128);
4891 -
4892 -
4893 -
4894 -
4895 -    // USA Cable, QAM 64
4896 -    fmap["atsc_qam64_uscable0"] = new FrequencyTable(
4897 -        "QAM-64 Channel %1",    1, 75000000,1005000000, 6000000, QAM_64);
4898 -    fmap["atsc_qam64_uscable1"] = new FrequencyTable(
4899 -        "QAM-64 Channel T-%1",  7, 10000000,  52000000, 6000000, QAM_64);
4900 -
4901 -    // USA Cable, QAM 64 ch 78+
4902 -    fmap["atsc_qam64_uscablehigh0"] = new FrequencyTable(
4903 -        "QAM-64 Channel %1",   78,472000000,1005000000, 6000000, QAM_64);
4904 -
4905 -    // USA Cable HRC, QAM 64
4906 -    fmap["atsc_qam64_ushrc0"] = new FrequencyTable(
4907 -        "QAM-64 HRC %1",   1,  73750000,  73750001, 6000000, QAM_64);
4908 -    fmap["atsc_qam64_ushrc1"] = new FrequencyTable(
4909 -        "QAM-64 HRC %1",   2,  55750000,  67750000, 6000000, QAM_64);
4910 -    fmap["atsc_qam64_ushrc2"] = new FrequencyTable(
4911 -        "QAM-64 HRC %1",   5,  79750000,  85750000, 6000000, QAM_64);
4912 -    fmap["atsc_qam64_ushrc3"] = new FrequencyTable(
4913 -        "QAM-64 HRC %1",   7, 175750000, 643750000, 6000000, QAM_64);
4914 -    fmap["atsc_qam64_ushrc4"] = new FrequencyTable(
4915 -        "QAM-64 HRC %1",  95,  91750000, 114000000, 6000000, QAM_64);
4916 -    fmap["atsc_qam64_ushrc5"] = new FrequencyTable(
4917 -        "QAM-64 HRC %1", 100, 649750000, 799750000, 6000000, QAM_64);
4918 -    fmap["atsc_qam64_ushrc6"] = new FrequencyTable(
4919 -        "QAM-64 HRC T-%1", 7,   8175000,  50750000, 6000000, QAM_64);
4920 -
4921 -    // USA Cable HRC, QAM 64 ch 78+
4922 -    fmap["atsc_qam64_ushrchigh0"] = new FrequencyTable(
4923 -        "QAM-64 HRC %1",  78, 601750000, 643750000, 6000000, QAM_64);
4924 -    fmap["atsc_qam64_ushrchigh1"] = new FrequencyTable(
4925 -        "QAM-64 HRC %1", 100, 649750000, 799750000, 6000000, QAM_64);
4926 +            // USA Cable HRC/IRC, ch 67-125
4927 +            FREQ(modStr[i], std[j] + "high0", desc[i], sdesc[j] + "%1",
4928 +                 67,  535750000 + off[j], 643750000 + off[j], mod[i]);
4929 +            FREQ(modStr[i], std[j] + "high1", desc[i], sdesc[j] + "%1",
4930 +                 100, 649750000 + off[j], 799750000 + off[j], mod[i]);
4931 +        }
4932 +    }
4933  }
4934 Index: mythtv/libs/libmythtv/scanwizardhelpers.h
4935 ===================================================================
4936 --- mythtv/libs/libmythtv/scanwizardhelpers.h   (.../tags/release-0-19) (revision 10051)
4937 +++ mythtv/libs/libmythtv/scanwizardhelpers.h   (.../branches/release-0-19-fixes)       (revision 10051)
4938 @@ -272,11 +272,13 @@
4939    public:
4940      ScanFrequencyTable()
4941      {
4942 -        addSelection(QObject::tr("Broadcast"),        "us",            true);
4943 -        addSelection(QObject::tr("Cable")    +" 78+", "uscablehigh",   false);
4944 -        addSelection(QObject::tr("Cable HRC")+" 78+", "uscablehrchigh",false);
4945 -        addSelection(QObject::tr("Cable"),            "uscable",       false);
4946 -        addSelection(QObject::tr("Cable HRC"),        "ushrc",         false);
4947 +        addSelection(QObject::tr("Broadcast"),        "us",          true);
4948 +        addSelection(QObject::tr("Cable")    +" 78+", "uscablehigh", false);
4949 +        addSelection(QObject::tr("Cable HRC")+" 67+", "ushrchigh",   false);
4950 +        addSelection(QObject::tr("Cable IRC")+" 67+", "usirchigh",   false);
4951 +        addSelection(QObject::tr("Cable"),            "uscable",     false);
4952 +        addSelection(QObject::tr("Cable HRC"),        "ushrc",       false);
4953 +        addSelection(QObject::tr("Cable IRC"),        "usirc",       false);
4954  
4955          setLabel(QObject::tr("Frequency Table"));
4956          setHelpText(QObject::tr("Frequency table to use.") + " " +
4957 Index: mythtv/libs/libmythtv/scanwizard.cpp
4958 ===================================================================
4959 --- mythtv/libs/libmythtv/scanwizard.cpp        (.../tags/release-0-19) (revision 10051)
4960 +++ mythtv/libs/libmythtv/scanwizard.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
4961 @@ -518,7 +518,9 @@
4962                      "SELECT dvb_diseqc_type, diseqc_port,  diseqc_pos, "
4963                      "       lnb_lof_switch,  lnb_lof_hi,   lnb_lof_lo "
4964                      "FROM cardinput, capturecard "
4965 -                    "WHERE capturecard.cardid=%1 and cardinput.sourceid=%2")
4966 +                    "WHERE capturecard.cardid = %1 AND "
4967 +                    "      cardinput.sourceid = %2 AND "
4968 +                    "      capturecard.cardid = cardinput.cardid")
4969                  .arg(parent->captureCard()).arg(nVideoSource));
4970  
4971              if (query.exec() && query.isActive() && query.size() > 0)
4972 Index: mythtv/libs/libmythtv/RingBuffer.h
4973 ===================================================================
4974 --- mythtv/libs/libmythtv/RingBuffer.h  (.../tags/release-0-19) (revision 10051)
4975 +++ mythtv/libs/libmythtv/RingBuffer.h  (.../branches/release-0-19-fixes)       (revision 10051)
4976 @@ -91,6 +91,7 @@
4977      long long GetTotalReadPosition(void);
4978  
4979      long long SetAdjustFilesize(void);
4980 +    void SetTimeout(bool fast) { oldfile = fast; }
4981      
4982    protected:
4983      static void *StartReader(void *type);
4984 Index: mythtv/libs/libmythtv/dvbtypes.cpp
4985 ===================================================================
4986 --- mythtv/libs/libmythtv/dvbtypes.cpp  (.../tags/release-0-19) (revision 10051)
4987 +++ mythtv/libs/libmythtv/dvbtypes.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
4988 @@ -202,7 +202,7 @@
4989  {
4990     {"TRANSMISSION_MODE_AUTO",TRANSMISSION_MODE_AUTO},
4991     {"TRANSMISSION_MODE_2K",TRANSMISSION_MODE_2K},
4992 -   {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_2K},
4993 +   {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_8K},
4994     {NULL,TRANSMISSION_MODE_AUTO},
4995  };
4996  
4997 @@ -210,7 +210,7 @@
4998  {
4999     {"999",TRANSMISSION_MODE_AUTO},
5000     {"2",TRANSMISSION_MODE_2K},
5001 -   {"8",TRANSMISSION_MODE_2K},
5002 +   {"8",TRANSMISSION_MODE_8K},
5003     {NULL,TRANSMISSION_MODE_AUTO},
5004  };
5005  
5006 @@ -218,7 +218,7 @@
5007  {
5008     {"auto",TRANSMISSION_MODE_AUTO},
5009     {"2",TRANSMISSION_MODE_2K},
5010 -   {"8",TRANSMISSION_MODE_2K},
5011 +   {"8",TRANSMISSION_MODE_8K},
5012     {NULL,TRANSMISSION_MODE_AUTO},
5013  };
5014  
5015 Index: mythtv/libs/libmythtv/mpegrecorder.cpp
5016 ===================================================================
5017 --- mythtv/libs/libmythtv/mpegrecorder.cpp      (.../tags/release-0-19) (revision 10051)
5018 +++ mythtv/libs/libmythtv/mpegrecorder.cpp      (.../branches/release-0-19-fixes)       (revision 10051)
5019 @@ -363,9 +363,9 @@
5020  
5021      if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
5022      {
5023 -        cerr << "Error setting codec params\n";
5024 +        cerr << "Warning, unable to set recording volume\n";
5025 +        cerr << "This is normal if you have an AVerMedia M179 card.\n";
5026          perror("VIDIOC_S_CTRL:");
5027 -        return false;
5028      }
5029  
5030      if (vbimode) {
5031 @@ -481,6 +481,9 @@
5032                  continue;
5033              case 0:
5034                  printf("select timeout - ivtv driver has stopped responding\n");
5035 +                if(close(readfd) != 0)
5036 +                    perror("close");
5037 +                readfd = -1; // Force PVR card to be reopened on next iteration
5038                  continue;
5039             default: break;
5040          }
5041 Index: mythtv/libs/libmythtv/ivtvdecoder.cpp
5042 ===================================================================
5043 --- mythtv/libs/libmythtv/ivtvdecoder.cpp       (.../tags/release-0-19) (revision 10051)
5044 +++ mythtv/libs/libmythtv/ivtvdecoder.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
5045 @@ -270,7 +270,9 @@
5046  
5047      GetNVP()->SetVideoParams(720 /*width*/, (ntsc) ? 480 : 576 /*height*/,
5048                               (ntsc) ? 29.97f : 25.0f, keyframedist, 1.33);
5049 -     
5050 +
5051 +    fps = (ntsc) ? 29.97f : 25.0f; // save for later length calculations
5052 +
5053      ringBuffer->UpdateRawBitrate(8000);
5054  
5055      if (m_playbackinfo || livetv || watchingrecording)
5056 Index: mythtv/libs/libmythtv/dvbsignalmonitor.cpp
5057 ===================================================================
5058 --- mythtv/libs/libmythtv/dvbsignalmonitor.cpp  (.../tags/release-0-19) (revision 10051)
5059 +++ mythtv/libs/libmythtv/dvbsignalmonitor.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
5060 @@ -348,8 +348,8 @@
5061  
5062          len += remainder;
5063          remainder = GetStreamData()->ProcessData(buffer, len);
5064 -        if (remainder > 0) // leftover bytes
5065 -            memmove(buffer, &(buffer[buffer_size - remainder]), remainder);
5066 +        if (remainder > 0 && (len > remainder)) // leftover bytes
5067 +            memmove(buffer, &(buffer[len - remainder]), remainder);
5068      }
5069      VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorTS(): " + "shutdown");
5070  
5071 Index: mythtv/libs/libmythtv/osdimagecache.cpp
5072 ===================================================================
5073 --- mythtv/libs/libmythtv/osdimagecache.cpp     (.../tags/release-0-19) (revision 0)
5074 +++ mythtv/libs/libmythtv/osdimagecache.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
5075 @@ -0,0 +1,296 @@
5076 +// -*- Mode: c++ -*-
5077 +/** OSDImageCache
5078 + *  Copyright (c) 2006 by Pekka Jääskeläinen, Daniel Thor Kristjansson
5079 + *  Distributed as part of MythTV under GPL v2 and later.
5080 + */
5081 +
5082 +// POSIX headers
5083 +#include <stdint.h>
5084 +
5085 +// Qt headers
5086 +#include <qdir.h>
5087 +#include <qfile.h>
5088 +#include <qfileinfo.h>
5089 +#include <qdatastream.h>
5090 +#include <qdeepcopy.h>
5091 +
5092 +// MythTV headers
5093 +#include "mythcontext.h"
5094 +#include "osdimagecache.h"
5095 +
5096 +// Print statistics of OSD image access in the destructor of OSDImageCache
5097 +//#define PRINT_OSD_IMAGE_CACHE_STATS
5098 +
5099 +#define LOC QString("OSDImgCache: ")
5100 +#define LOC_ERR QString("OSDImgCache, Error: ")
5101 +
5102 +uint OSDImageCache::kMaximumMemoryCacheSize = 5 * 1024 * 1024;
5103 +
5104 +/** \fn OSDImageCacheValue::OSDImageCacheValue(unsigned char*,unsigned char*,unsighed char*,unsigned char*,unsighed char*, QRect)
5105 + *  \brief The main constructor that takes the image data as arguments.
5106 + *
5107 + *   The image data becomes property of the OSDImageCacheValue 
5108 + *   and will be deleted by it.
5109 + */
5110 +OSDImageCacheValue::OSDImageCacheValue(
5111 +    QString cacheKey,
5112 +    unsigned char *yuv,     unsigned char *ybuffer,
5113 +    unsigned char *ubuffer, unsigned char *vbuffer,
5114 +    unsigned char *alpha,   QRect imagesize) :
5115 +    m_yuv(yuv),         m_ybuffer(ybuffer),
5116 +    m_ubuffer(ubuffer), m_vbuffer(vbuffer),
5117 +    m_alpha(alpha),     m_imagesize(imagesize),
5118 +    m_cacheKey(QDeepCopy<QString>(cacheKey))
5119 +{
5120 +    uint yuv_size = m_imagesize.width() * m_imagesize.height() * 3 / 2;
5121 +    m_size_in_bytes =
5122 +        (sizeof(OSDImageCacheValue)) + yuv_size + 
5123 +        (m_imagesize.width() * m_imagesize.height());
5124 +}
5125 +
5126 +/** \fn OSDImageCacheValue::~OSDImageCacheValue()
5127 + *  \brief Destructor, frees the cached bitmaps.
5128 + */
5129 +OSDImageCacheValue::~OSDImageCacheValue()
5130 +{
5131 +    delete [] m_yuv;
5132 +    m_yuv = NULL;
5133 +    delete [] m_alpha;
5134 +    m_alpha = NULL;
5135 +}
5136 +
5137 +/** \fn OSDImageCache::OSDImageCache()
5138 + *  \brief Constructor, initializes the internal cache structures.
5139 + */
5140 +OSDImageCache::OSDImageCache() : 
5141 +    m_cacheLock(true), m_imageCache(kMaximumMemoryCacheSize, 50),
5142 +    m_memHits(0), m_diskHits(0), m_misses(0) 
5143 +{
5144 +    // When the cache gets too large, items are
5145 +    // automatically deleted from it in LRU order.
5146 +    m_imageCache.setAutoDelete(true);
5147 +}
5148 +
5149 +/** \fn OSDImageCache::~OSDImageCache()
5150 + *  \brief Destructor, frees all cached OSD images.
5151 + */
5152 +OSDImageCache::~OSDImageCache() 
5153 +{
5154 +#ifdef PRINT_OSD_IMAGE_CACHE_STATS
5155 +    int totalAccess = m_memHits + m_diskHits + m_misses;
5156 +    if (totalAccess == 0)
5157 +        return;
5158 +
5159 +#define LOG_PREFIX "OSDImageCache: "
5160 +    VERBOSE(VB_IMPORTANT, LOC << " Statistics: " << endl
5161 +            << LOG_PREFIX << m_imageCache.totalCost() << " bytes in cache\n" 
5162 +            << LOG_PREFIX << " memory hits: " 
5163 +            << m_memHits << ", " << m_memHits*100.0/totalAccess << "%\n"
5164 +            << LOG_PREFIX << "   disk hits: " 
5165 +            << m_diskHits << ", " << m_diskHits*100.0/totalAccess << "%\n"
5166 +            << LOG_PREFIX << "      misses: " 
5167 +            << m_misses << ", " << m_misses*100.0/totalAccess << "%");
5168 +#undef LOC_PREFIX
5169 +#endif
5170 +    Reset();
5171 +}
5172 +
5173 +/** \fn OSDImageCache::Contains(const QString&,bool)
5174 + *  \brief Returns true if cached OSD image was found in the cache.
5175 + *
5176 + *  \param key The key for this image.
5177 + *  \param useFile If true, also look from the disk cache.
5178 + */
5179 +bool OSDImageCache::Contains(const QString &key, bool useFile) const
5180 +{
5181 +    QMutexLocker locker(&m_cacheLock);
5182 +
5183 +    if (m_imageCache.find(key) != NULL)
5184 +        return true;
5185 +
5186 +    if (!useFile)
5187 +        return false;
5188 +
5189 +    return InFileCache(key);
5190 +}
5191 +
5192 +bool OSDImageCache::InFileCache(const QString &key) const
5193 +{
5194 +    // check if cache file exists
5195 +    QDir dir(MythContext::GetConfDir() + "/osdcache/");
5196 +    QFileInfo cFile(dir.path() + "/" + key);
5197 +    if (!cFile.exists() || !cFile.isReadable())
5198 +        return false;
5199 +
5200 +    // check if backing file exists
5201 +    QString orig = ExtractOriginal(key);
5202 +    if (orig.isEmpty())
5203 +        return false;
5204 +
5205 +    QFileInfo oFile(orig);
5206 +    if (!oFile.exists())
5207 +    {
5208 +        VERBOSE(VB_IMPORTANT, LOC + QString("Can't find '%1'").arg(orig));
5209 +        return false;
5210 +    }
5211 +
5212 +    // if cache file is older than backing file, delete cache file
5213 +    if (cFile.lastModified() < oFile.lastModified())
5214 +    {
5215 +        cFile.dir().remove(cFile.baseName(true));
5216 +        return false;
5217 +    } 
5218 +
5219 +    return true;
5220 +}
5221 +
5222 +/** \fn OSDImageCache::Get(const QString&,bool)
5223 + *  \brief Returns OSD image data from cache.
5224 + *
5225 + *   This also removes the image from the cache so it won't be deleted
5226 + *   while in use. The deletion of the taken item becomes responsibility
5227 + *   of the client. Returns NULL if item with the given key is not found.
5228 + *
5229 + *  \param key The key for this image.
5230 + *  \param useFile If true, also check the disk cache.
5231 + */
5232 +OSDImageCacheValue *OSDImageCache::Get(const QString &key, bool useFile)
5233 +{
5234 +    QMutexLocker locker(&m_cacheLock);
5235 +    OSDImageCacheValue* item = m_imageCache.find(key);
5236 +    if (item)
5237 +    {
5238 +        m_memHits++;
5239 +        return m_imageCache.take(key);
5240 +    }
5241 +
5242 +    if (!useFile || !InFileCache(key))
5243 +    {
5244 +        m_misses++;
5245 +        return NULL;
5246 +    }
5247 +
5248 +    QDir dir(MythContext::GetConfDir() + "/osdcache/");
5249 +    QFile cacheFile(dir.path() + "/" + key);
5250 +    cacheFile.open(IO_ReadOnly);
5251 +    uint32_t imwidth  = 0;
5252 +    uint32_t imheight = 0;
5253 +
5254 +    QDataStream stream(&cacheFile);
5255 +    stream >> imwidth >> imheight;   
5256 +
5257 +    uint yuv_size = imwidth * imheight * 3 / 2;
5258 +    uint tot_size = (sizeof(imwidth) * 2) + yuv_size + (imwidth * imheight);
5259 +
5260 +    if (cacheFile.size() != tot_size)
5261 +    {
5262 +        VERBOSE(VB_IMPORTANT, LOC_ERR + key + " wrong cache file size!"
5263 +                << cacheFile.size() << " != " << tot_size);
5264 +        return NULL;
5265 +    }
5266 +
5267 +    unsigned char *yuv = new unsigned char[yuv_size];
5268 +    unsigned char *alpha = new unsigned char[imwidth * imheight];
5269 +    stream.readRawBytes((char*)yuv,   yuv_size);
5270 +    stream.readRawBytes((char*)alpha, imwidth * imheight);
5271 +    cacheFile.close();
5272 +
5273 +    OSDImageCacheValue* value = 
5274 +        new OSDImageCacheValue(
5275 +            key,
5276 +            yuv, yuv,
5277 +            yuv + (imwidth * imheight),
5278 +            yuv + (imwidth * imheight * 5 / 4),
5279 +            alpha, QRect(0, 0, imwidth, imheight));
5280 +
5281 +    m_diskHits++;
5282 +    return value;
5283 +}
5284 +
5285 +/** \fn OSDImageCache::Insert(OSDImageCacheValue*)
5286 + *  \brief Inserts OSD image data to memory cache.
5287 + *
5288 + *   The item becomes property of the OSDImageCache and may be 
5289 + *   deleted any time by it.
5290 + *
5291 + *  \param value The cache item.
5292 + */
5293 +void OSDImageCache::Insert(OSDImageCacheValue *value)
5294 +{
5295 +    if (!value)
5296 +        return;
5297 +
5298 +    QMutexLocker locker(&m_cacheLock);
5299 +    if (!m_imageCache.insert(value->GetKey(), value, value->GetSize()))
5300 +    {
5301 +        VERBOSE(VB_IMPORTANT, 
5302 +                LOC_ERR + QString("inserting image to memory cache failed"));
5303 +    }
5304 +}
5305 +
5306 +
5307 +/** \fn OSDImageCache::SaveToDisk(const OSDImageCacheValue*)
5308 + *  \brief Saves OSD image data to disk cache.
5309 + *
5310 + *   Item is not written to the memory cache, i.e., it stays as
5311 + *   property of the client.
5312 + *
5313 + *  \param value The cached OSD image to save.
5314 + */
5315 +void OSDImageCache::SaveToDisk(const OSDImageCacheValue *value)
5316 +{
5317 +    if (InFileCache(value->GetKey()))
5318 +        return;
5319 +
5320 +    QDir dir(MythContext::GetConfDir() + "/osdcache/");
5321 +    if (!dir.exists() && !dir.mkdir(dir.path()))
5322 +    {
5323 +        VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating osdcache directory failed.");
5324 +        return;
5325 +    }
5326 +
5327 +    QFile cacheFile(dir.path() + "/" + value->GetKey());
5328 +    if (!cacheFile.open(IO_WriteOnly | IO_Truncate))
5329 +    {
5330 +        VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating osdcache file failed.");
5331 +        return;
5332 +    }
5333 +
5334 +    uint32_t imwidth  = value->m_imagesize.width();
5335 +    uint32_t imheight = value->m_imagesize.height();
5336 +    uint     yuv_size = imwidth * imheight * 3 / 2;
5337 +
5338 +    QDataStream stream(&cacheFile);
5339 +    stream << imwidth << imheight;   
5340 +    stream.writeRawBytes((const char*)value->m_yuv, yuv_size);
5341 +    stream.writeRawBytes((const char*)value->m_alpha, imwidth * imheight);
5342 +    cacheFile.close();
5343 +}
5344 +
5345 +/** \fn OSDImageCache::CreateKey(const QString&,float,float,int,int)
5346 + *  \brief Generates a cache key from the given OSD image parameters.
5347 + *
5348 + *   The returned key is a string that can be safely used as a file name.
5349 + */
5350 +QString OSDImageCache::CreateKey(const QString &filename, float wmult, 
5351 +                                 float hmult, int scalew, int scaleh)
5352 +{
5353 +    QString tmp = filename;
5354 +    return QString("cache_%1@%2_%3_%4_%5").arg(tmp.replace(QChar('/'), "+"))
5355 +        .arg(wmult).arg(hmult).arg(scalew).arg(scaleh);
5356 +}
5357 +
5358 +QString OSDImageCache::ExtractOriginal(const QString &key)
5359 +{
5360 +    QString tmp0 = key.mid(6);
5361 +    QString tmp1 = tmp0.left(tmp0.find("@"));
5362 +    QString tmp2 = tmp1.replace(QChar('+'), "/");
5363 +    return tmp2;
5364 +}
5365 +
5366 +void OSDImageCache::Reset(void)
5367 +{
5368 +    QMutexLocker locker(&m_cacheLock);
5369 +    // this also deletes the images due to setAutoDelete(true)
5370 +    m_imageCache.clear();
5371 +}
5372 Index: mythtv/libs/libmythtv/osd.cpp
5373 ===================================================================
5374 --- mythtv/libs/libmythtv/osd.cpp       (.../tags/release-0-19) (revision 10051)
5375 +++ mythtv/libs/libmythtv/osd.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
5376 @@ -154,7 +154,8 @@
5377          }
5378  
5379          OSDTypeCC *ccpage = new OSDTypeCC(name, ccfont, sub_xoff, sub_yoff,
5380 -                                          sub_dispw, sub_disph);
5381 +                                          sub_dispw, sub_disph,
5382 +                                          wmult, hmult);
5383          container->AddType(ccpage);
5384      }
5385  
5386 @@ -517,7 +518,7 @@
5387          }
5388      }
5389  
5390 -    OSDTypeBox *box = new OSDTypeBox(name, area);
5391 +    OSDTypeBox *box = new OSDTypeBox(name, area, wmult, hmult);
5392      container->AddType(box);
5393  }
5394  
5395 @@ -658,7 +659,7 @@
5396          return;
5397      }
5398  
5399 -    OSDTypeText *text = new OSDTypeText(name, ttffont, "", area);
5400 +    OSDTypeText *text = new OSDTypeText(name, ttffont, "", area, wmult, hmult);
5401      container->AddType(text);
5402  
5403      text->SetMultiLine(multiline);
5404 @@ -875,7 +876,7 @@
5405                  QRect area = parseRect(getFirstText(info));
5406                  normalizeRect(area);
5407  
5408 -                rects->AddPosition(area);
5409 +                rects->AddPosition(area, wmult, hmult);
5410              }
5411              else
5412              {
5413 @@ -919,7 +920,7 @@
5414                  pos.setX((int)(pos.x() * wmult + xoffset));
5415                  pos.setY((int)(pos.y() * hmult + yoffset));
5416  
5417 -                image->AddPosition(pos);
5418 +                image->AddPosition(pos, wmult, hmult);
5419              }
5420              else if (info.tagName() == "staticsize")
5421              {
5422 @@ -1925,7 +1926,7 @@
5423          image = new OSDTypeImage(*editarrowright);
5424      }
5425  
5426 -    image->SetPosition(QPoint(xpos, ypos));
5427 +    image->SetPosition(QPoint(xpos, ypos), wmult, hmult);
5428  
5429      set->AddType(image);
5430      set->Display();
5431 Index: mythtv/libs/libmythtv/dvbconfparser.cpp
5432 ===================================================================
5433 --- mythtv/libs/libmythtv/dvbconfparser.cpp     (.../tags/release-0-19) (revision 10051)
5434 +++ mythtv/libs/libmythtv/dvbconfparser.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
5435 @@ -193,10 +193,10 @@
5436      QStringList::Iterator end = tokens.end();
5437  
5438      if (i != end) c.name = *i++; else return false;
5439 -    if (i != end) c.frequency = (*i++).toInt(); else return false;
5440 +    if (i != end) c.frequency = (*i++).toUInt()*1000; else return false;
5441      if (i == end || !c.polarity.parseConf(*i++)) return false;
5442      if (i == end ) return false; else i++; //Sat num
5443 -    if (i != end) c.symbolrate = (*i++).toInt(); else return false;
5444 +    if (i != end) c.symbolrate = (*i++).toUInt()*1000; else return false;
5445      if (i == end ) return false; else i++;
5446      if (i == end ) return false; else i++;
5447      if (i != end) c.serviceid = (*i++).toInt(); else return false;
5448 Index: mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp
5449 ===================================================================
5450 --- mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp       (.../tags/release-0-19) (revision 10051)
5451 +++ mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
5452 @@ -108,8 +108,8 @@
5453  
5454          len += remainder;
5455          remainder = GetStreamData()->ProcessData(buffer, len);
5456 -        if (remainder > 0) // leftover bytes
5457 -            memmove(buffer, &(buffer[buffer_size - remainder]), remainder);
5458 +        if (remainder > 0 && (len > remainder)) // leftover bytes
5459 +            memmove(buffer, &(buffer[len - remainder]), remainder);
5460      }
5461      DBG_SM("RunTableMonitor()", "end");
5462  }
5463 Index: mythtv/libs/libavformat/aviobuf.c
5464 ===================================================================
5465 --- mythtv/libs/libavformat/aviobuf.c   (.../tags/release-0-19) (revision 10051)
5466 +++ mythtv/libs/libavformat/aviobuf.c   (.../branches/release-0-19-fixes)       (revision 10051)
5467 @@ -164,7 +164,13 @@
5468  
5469  void url_fskip(ByteIOContext *s, offset_t offset)
5470  {
5471 -    url_fseek(s, offset, SEEK_CUR);
5472 +    if (offset < 16384) 
5473 +    {
5474 +        static unsigned char fskipbuf[16384];
5475 +        get_buffer(s, fskipbuf, offset);
5476 +    }
5477 +    else
5478 +        url_fseek(s, offset, SEEK_CUR);
5479  }
5480  
5481  offset_t url_ftell(ByteIOContext *s)
5482 Index: mythtv/libs/libmyth/lcddevice.cpp
5483 ===================================================================
5484 --- mythtv/libs/libmyth/lcddevice.cpp   (.../tags/release-0-19) (revision 10051)
5485 +++ mythtv/libs/libmyth/lcddevice.cpp   (.../branches/release-0-19-fixes)       (revision 10051)
5486 @@ -150,7 +150,7 @@
5487  
5488      if (!connected)
5489      {
5490 -        QTextStream os(socket);
5491 +        QTextStream os(socket->socketDevice());
5492  
5493          int count = 0;
5494          do
5495 @@ -213,7 +213,7 @@
5496          return;
5497      }
5498  
5499 -    QTextStream os(socket);
5500 +    QTextStream os(socket->socketDevice());
5501     
5502      last_command = someText;
5503   
5504 @@ -224,7 +224,7 @@
5505  #endif
5506          // Just stream the text out the socket
5507  
5508 -        os << someText << "\n" << flush;
5509 +        os << someText << "\n";
5510      }
5511      else
5512      {
5513 Index: mythtv/libs/libmyth/audiooutputca.cpp
5514 ===================================================================
5515 --- mythtv/libs/libmyth/audiooutputca.cpp       (.../tags/release-0-19) (revision 10051)
5516 +++ mythtv/libs/libmyth/audiooutputca.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
5517 @@ -107,8 +107,10 @@
5518      bzero(&conv_in_desc, sizeof(AudioStreamBasicDescription));
5519      conv_in_desc.mSampleRate       = audio_samplerate;
5520      conv_in_desc.mFormatID         = kAudioFormatLinearPCM;
5521 -    conv_in_desc.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger
5522 -                                     | kLinearPCMFormatFlagIsBigEndian;
5523 +    conv_in_desc.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger;
5524 +#ifdef WORDS_BIGENDIAN
5525 +    conv_in_desc.mFormatFlags     |= kLinearPCMFormatFlagIsBigEndian;
5526 +#endif
5527      conv_in_desc.mBytesPerPacket   = audio_bytes_per_sample;
5528      conv_in_desc.mFramesPerPacket  = 1;
5529      conv_in_desc.mBytesPerFrame    = audio_bytes_per_sample;
5530 Index: mythtv/libs/libmyth/util.cpp
5531 ===================================================================
5532 --- mythtv/libs/libmyth/util.cpp        (.../tags/release-0-19) (revision 10051)
5533 +++ mythtv/libs/libmyth/util.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
5534 @@ -1006,16 +1006,20 @@
5535      long long freespace = -1;
5536      QCString cstr = file_on_disk.local8Bit();
5537  
5538 -    if (statfs(cstr, &statbuf) == 0)
5539 +    total = used = -1;
5540 +
5541 +    // there are cases where statfs will return 0 (good), but f_blocks and
5542 +    // others are invalid and set to 0 (such as when an automounted directory
5543 +    // is not mounted but still visible because --ghost was used),
5544 +    // so check to make sure we can have a total size > 0
5545 +    if ((statfs(cstr, &statbuf) == 0) &&
5546 +        (statbuf.f_blocks > 0) &&
5547 +        (statbuf.f_bsize > 0))
5548      {
5549          freespace = statbuf.f_bsize * (statbuf.f_bavail >> 10);
5550          total = statbuf.f_bsize * (statbuf.f_blocks >> 10);
5551          used  = total - freespace;
5552      }
5553 -    else
5554 -    {
5555 -        freespace = total = used = -1;
5556 -    }
5557  
5558      return freespace;
5559  }
5560 Index: mythtv/libs/libmyth/mythdialogs.cpp
5561 ===================================================================
5562 --- mythtv/libs/libmyth/mythdialogs.cpp (.../tags/release-0-19) (revision 10051)
5563 +++ mythtv/libs/libmyth/mythdialogs.cpp (.../branches/release-0-19-fixes)       (revision 10051)
5564 @@ -2617,6 +2617,7 @@
5565      password_editor->setEchoMode(QLineEdit::Password);
5566      password_editor->setGeometry(textWidth + 20,10,135,30);
5567      password_editor->setBackgroundOrigin(ParentOrigin);
5568 +    password_editor->setAllowVirtualKeyboard(false);
5569      connect(password_editor, SIGNAL(textChanged(const QString &)),
5570              this, SLOT(checkPassword(const QString &)));
5571  
5572 Index: mythtv/libs/libmyth/mythwidgets.cpp
5573 ===================================================================
5574 --- mythtv/libs/libmyth/mythwidgets.cpp (.../tags/release-0-19) (revision 10051)
5575 +++ mythtv/libs/libmyth/mythwidgets.cpp (.../branches/release-0-19-fixes)       (revision 10051)
5576 @@ -353,7 +353,8 @@
5577                      (e->key() == Qt::Key_Enter) ||
5578                      (e->key() == Qt::Key_Return)))
5579              {
5580 -                if (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1)
5581 +                if ((allowVirtualKeyboard) &&
5582 +                                   (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1))
5583                  {
5584                      popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
5585                      gContext->GetMainWindow()->detach(popup);
5586 @@ -726,10 +727,11 @@
5587                  QWidget::focusNextPrevChild(true);
5588                  emit tryingToLooseFocus(true);
5589              }
5590 -            else if (action == "SELECT" &&
5591 -                    (e->text().isNull() ||
5592 -                    (e->key() == Qt::Key_Enter) || 
5593 -                    (e->key() == Qt::Key_Return)))
5594 +            else if ((action == "SELECT") &&
5595 +                     (!active_cycle) &&
5596 +                     ((e->text().isNull()) ||
5597 +                      (e->key() == Qt::Key_Enter) || 
5598 +                      (e->key() == Qt::Key_Return)))
5599              {
5600                  if (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1)
5601                  {
5602 @@ -749,7 +751,7 @@
5603      if (handled)
5604          return;
5605  
5606 -    if (!handled && popup && popup->isShown())
5607 +    if (popup && popup->isShown())
5608      {
5609          endCycle();
5610          QTextEdit::keyPressEvent(e);
5611 Index: mythtv/libs/libmyth/remotefile.h
5612 ===================================================================
5613 --- mythtv/libs/libmyth/remotefile.h    (.../tags/release-0-19) (revision 10051)
5614 +++ mythtv/libs/libmyth/remotefile.h    (.../branches/release-0-19-fixes)       (revision 10051)
5615 @@ -27,6 +27,8 @@
5616  
5617      long long GetFileSize(void);
5618  
5619 +    void SetTimeout(bool fast);
5620 +
5621    private:
5622      QSocketDevice *openSocket(bool control);
5623  
5624 @@ -43,6 +45,7 @@
5625      QMutex lock;
5626  
5627      long long filesize;
5628 +    bool timeoutisfast;
5629  };
5630  
5631  #endif
5632 Index: mythtv/libs/libmyth/mythwidgets.h
5633 ===================================================================
5634 --- mythtv/libs/libmyth/mythwidgets.h   (.../tags/release-0-19) (revision 10051)
5635 +++ mythtv/libs/libmyth/mythwidgets.h   (.../branches/release-0-19-fixes)       (revision 10051)
5636 @@ -122,17 +122,21 @@
5637      Q_OBJECT
5638    public:
5639      MythLineEdit(QWidget *parent=NULL, const char* widgetName=0) :
5640 -      QLineEdit(parent, widgetName) { rw = true; Init(); };
5641 +      QLineEdit(parent, widgetName)
5642 +           { rw = true; allowVirtualKeyboard = true; Init(); };
5643  
5644      MythLineEdit(const QString& contents, QWidget *parent=NULL, 
5645                   const char* widgetName=0) :
5646 -      QLineEdit(contents, parent, widgetName) { rw = true; Init(); };
5647 +      QLineEdit(contents, parent, widgetName)
5648 +           { rw = true; allowVirtualKeyboard = true; Init(); };
5649  
5650      virtual ~MythLineEdit();
5651  
5652      void setHelpText(QString help) { helptext = help; };
5653      void setRW(bool readwrite = true) { rw = readwrite; };
5654      void setRO() { rw = false; };
5655 +    void setAllowVirtualKeyboard(bool allowKbd = true)
5656 +              { allowVirtualKeyboard = allowKbd; }
5657      void setPopupPosition(PopupPosition pos) { popupPosition = pos; }
5658      PopupPosition getPopupPosition(void) { return popupPosition; }
5659  
5660 @@ -154,6 +158,7 @@
5661      VirtualKeyboard *popup;
5662      QString helptext;
5663      bool rw;
5664 +    bool allowVirtualKeyboard;
5665      PopupPosition popupPosition;
5666  };
5667  
5668 Index: mythtv/libs/libmyth/mythcontext.cpp
5669 ===================================================================
5670 --- mythtv/libs/libmyth/mythcontext.cpp (.../tags/release-0-19) (revision 10051)
5671 +++ mythtv/libs/libmyth/mythcontext.cpp (.../branches/release-0-19-fixes)       (revision 10051)
5672 @@ -2621,9 +2621,13 @@
5673          d->LoadLogSettings();
5674      if (d->m_logenable == 1)
5675      {
5676 +        QString fullMsg = message;
5677 +        if (!details.isEmpty())
5678 +            fullMsg += ": " + details;
5679 +
5680          if (message.left(21) != "Last message repeated")
5681          {
5682 -            if (message == d->lastLogStrings[module])
5683 +            if (fullMsg == d->lastLogStrings[module])
5684              {
5685                  d->lastLogCounts[module] += 1;
5686                  return;
5687 @@ -2639,7 +2643,7 @@
5688                  }
5689  
5690                  d->lastLogCounts[module] = 0;
5691 -                d->lastLogStrings[module] = message;
5692 +                d->lastLogStrings[module] = fullMsg;
5693              }
5694          }
5695  
5696 @@ -2693,7 +2697,7 @@
5697          }
5698  
5699          if (priority <= d->m_logprintlevel)
5700 -            VERBOSE(VB_IMPORTANT, module + ": " + message);
5701 +            VERBOSE(VB_IMPORTANT, module + ": " + fullMsg);
5702      }
5703  }
5704  
5705 Index: mythtv/libs/libmyth/remotefile.cpp
5706 ===================================================================
5707 --- mythtv/libs/libmyth/remotefile.cpp  (.../tags/release-0-19) (revision 10051)
5708 +++ mythtv/libs/libmyth/remotefile.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
5709 @@ -15,6 +15,7 @@
5710      path = url;
5711      readposition = 0;
5712      filesize = -1;
5713 +    timeoutisfast = false;
5714  
5715      query = "QUERY_FILETRANSFER %1";
5716  
5717 @@ -295,4 +296,34 @@
5718      Read(data.data(), filesize);
5719  
5720      return true;
5721 -} 
5722 +}
5723 +
5724 +void RemoteFile::SetTimeout(bool fast)
5725 +{
5726 +    if (timeoutisfast == fast)
5727 +        return;
5728 +
5729 +    if (!sock)
5730 +    {
5731 +        VERBOSE(VB_NETWORK, "RemoteFile::Seek(): Called with no socket");
5732 +        return;
5733 +    }
5734 +
5735 +    if (!sock->isOpen() || sock->error())
5736 +        return;
5737 +
5738 +    if (!controlSock->isOpen() || controlSock->error())
5739 +        return;
5740 +
5741 +    QStringList strlist = QString(query).arg(recordernum);
5742 +    strlist << "SET_TIMEOUT";
5743 +    strlist << QString::number((int)fast);
5744 +
5745 +    lock.lock();
5746 +    WriteStringList(controlSock, strlist);
5747 +    ReadStringList(controlSock, strlist);
5748 +    lock.unlock();
5749 +
5750 +    timeoutisfast = fast;
5751 +}
5752 +
5753 Index: mythtv/libs/libavcodec/libavcodec.pro
5754 ===================================================================
5755 --- mythtv/libs/libavcodec/libavcodec.pro       (.../tags/release-0-19) (revision 10051)
5756 +++ mythtv/libs/libavcodec/libavcodec.pro       (.../branches/release-0-19-fixes)       (revision 10051)
5757 @@ -430,4 +430,5 @@
5758      LIBS               += -lz
5759      QMAKE_LFLAGS_SHLIB += -single_module
5760      QMAKE_LFLAGS_SHLIB += -seg1addr 0xC3000000
5761 +    QMAKE_LFLAGS_SHLIB += -read_only_relocs warning
5762  }
5763 Index: mythtv/programs/mythfrontend/playbackbox.cpp
5764 ===================================================================
5765 --- mythtv/programs/mythfrontend/playbackbox.cpp        (.../tags/release-0-19) (revision 10051)
5766 +++ mythtv/programs/mythfrontend/playbackbox.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
5767 @@ -17,6 +17,7 @@
5768  #include <qsqldatabase.h>
5769  #include <qmap.h>
5770  
5771 +#include <cmath>
5772  #include <unistd.h>
5773  
5774  #include <iostream>
5775 @@ -140,6 +141,7 @@
5776        // Main Recording List support
5777        fillListTimer(new QTimer(this)),  connected(false),
5778        titleIndex(0),                    progIndex(0),
5779 +      progsInDB(0),
5780        // Other state
5781        curitem(NULL),                    delitem(NULL),
5782        lastProgram(NULL),
5783 @@ -261,7 +263,9 @@
5784      setNoErase();
5785      gContext->addListener(this);
5786  
5787 -    if (!recGroupPassword.isEmpty() || (titleList.count() <= 1) || initialFilt)
5788 +    if ((!recGroupPassword.isEmpty()) ||
5789 +        ((titleList.count() <= 1) && (progsInDB > 0)) ||
5790 +        (initialFilt))
5791          showRecGroupChooser();
5792  
5793      gContext->addCurrentLocation((type == Delete)? "DeleteBox":"PlaybackBox");
5794 @@ -890,9 +894,13 @@
5795          !playingSomething)
5796      {
5797          QSize size = drawVideoBounds.size();
5798 +        float saspect = ((float)size.width()) / ((float)size.height());
5799 +        float vaspect = previewVideoNVP->GetVideoAspect();
5800 +        size.setHeight((int) ceil(size.height() * (saspect / vaspect)));
5801 +        size.setHeight(((size.height() + 7) / 8) * 8);
5802 +        size.setWidth( ((size.width()  + 7) / 8) * 8);
5803          const QImage &img = previewVideoNVP->GetARGBFrame(size);
5804 -        uint xoff = max((size.width() - drawVideoBounds.width()) / 2, 0);
5805 -        p->drawImage(drawVideoBounds.x() + xoff, drawVideoBounds.y(), img);
5806 +        p->drawImage(drawVideoBounds.x(), drawVideoBounds.y(), img);
5807      }
5808  
5809      /* have we timed out waiting for nvp to start? */
5810 @@ -1380,6 +1388,7 @@
5811          asCache[asKey] = p->availableStatus;
5812      }
5813  
5814 +    progsInDB = 0;
5815      titleList.clear();
5816      progLists.clear();
5817      // Clear autoDelete for the "all" list since it will share the
5818 @@ -1402,6 +1411,7 @@
5819          vector<ProgramInfo *>::iterator i = infoList->begin();
5820          for ( ; i != infoList->end(); i++)
5821          {
5822 +            progsInDB++;
5823              p = *i;
5824              if ((((p->recgroup == recGroup) ||
5825                    ((recGroup == "All Programs") &&
5826 @@ -4129,8 +4139,7 @@
5827      if (!recGroupListBox)
5828          return;
5829  
5830 -    QString item = 
5831 -        recGroupListBox->currentText().section('[', 0, 0).simplifyWhiteSpace();
5832 +    QString item = recGroupListBox->currentText().section(" [", 0, 0);
5833  
5834      if (item.left(5) == "-----")
5835      {
5836 @@ -4147,8 +4156,7 @@
5837  
5838  void PlaybackBox::setGroupFilter(void)
5839  {
5840 -    recGroup =
5841 -        recGroupListBox->currentText().section('[', 0, 0).simplifyWhiteSpace();
5842 +    recGroup = recGroupListBox->currentText().section(" [", 0, 0);
5843  
5844      if (groupnameAsAllProg)
5845          groupDisplayName = recGroup;
5846 Index: mythtv/programs/mythfrontend/customrecord.cpp
5847 ===================================================================
5848 --- mythtv/programs/mythfrontend/customrecord.cpp       (.../tags/release-0-19) (revision 10051)
5849 +++ mythtv/programs/mythfrontend/customrecord.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
5850 @@ -149,7 +149,7 @@
5851      m_cfrom << "";
5852      m_csql << "program.stars >= 0.75 ";
5853  
5854 -    m_clause->insertItem(tr("Person named in the credits"));
5855 +    m_clause->insertItem(tr("Person named in the credits (Data Direct)"));
5856      m_cfrom << ", people, credits";
5857      m_csql << QString("people.name = 'Tom Hanks' \n"
5858                        "AND credits.person = people.person \n"
5859 @@ -447,8 +447,8 @@
5860      else
5861      {
5862          MSqlQuery query(MSqlQuery::InitCon());
5863 -        query.prepare(QString("SELECT NULL FROM program,channel %1 WHERE\n%2") 
5864 -                              .arg(from).arg(desc));
5865 +        query.prepare(QString("SELECT NULL FROM (program,channel) "
5866 +                              "%1 WHERE\n%2").arg(from).arg(desc));
5867  
5868          if (query.exec() && query.isActive())
5869          {
5870 Index: mythtv/programs/mythfrontend/tv_schedule.xml
5871 ===================================================================
5872 --- mythtv/programs/mythfrontend/tv_schedule.xml        (.../tags/release-0-19) (revision 10051)
5873 +++ mythtv/programs/mythfrontend/tv_schedule.xml        (.../branches/release-0-19-fixes)       (revision 10051)
5874 @@ -26,7 +26,7 @@
5875        <alttext lang="CA">Guia</alttext>
5876        <alttext lang="DE">EPG</alttext>
5877        <alttext lang="DK">Guide</alttext>
5878 -      <alttext lang="DK">Dagskrá</alttext>
5879 +      <alttext lang="IS">Dagskrá</alttext>
5880        <alttext lang="NL">Gids</alttext>
5881        <alttext lang="SV">Guide</alttext>
5882        <alttext lang="JA">ガイド</alttext>
5883 Index: mythtv/programs/mythfrontend/playbackbox.h
5884 ===================================================================
5885 --- mythtv/programs/mythfrontend/playbackbox.h  (.../tags/release-0-19) (revision 10051)
5886 +++ mythtv/programs/mythfrontend/playbackbox.h  (.../branches/release-0-19-fixes)       (revision 10051)
5887 @@ -337,6 +337,7 @@
5888      int                 progIndex;  ///< Index of selected item index on page
5889      QStringList         titleList;  ///< list of pages
5890      ProgramMap          progLists;  ///< lists of programs by page        
5891 +    int                 progsInDB;  ///< total number of recordings in DB
5892  
5893      // Play List support
5894      QStringList         playList;   ///< list of selected items "play list"
5895 Index: mythtv/programs/mythfrontend/networkcontrol.cpp
5896 ===================================================================
5897 --- mythtv/programs/mythfrontend/networkcontrol.cpp     (.../tags/release-0-19) (revision 10051)
5898 +++ mythtv/programs/mythfrontend/networkcontrol.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
5899 @@ -469,7 +469,7 @@
5900              message = "NETWORK_CONTROL SEEK BACKWARD";
5901          else if (tokens[2].contains(QRegExp("^\\d\\d:\\d\\d:\\d\\d$")))
5902          {
5903 -            int hours = tokens[2].left(0).toInt();
5904 +            int hours   = tokens[2].mid(0, 2).toInt();
5905              int minutes = tokens[2].mid(3, 2).toInt();
5906              int seconds = tokens[2].mid(6, 2).toInt();
5907              message = QString("NETWORK_CONTROL SEEK POSITION %1")
5908 Index: mythtv/programs/mythtranscode/mpeg2fix.cpp
5909 ===================================================================
5910 --- mythtv/programs/mythtranscode/mpeg2fix.cpp  (.../tags/release-0-19) (revision 10051)
5911 +++ mythtv/programs/mythtranscode/mpeg2fix.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
5912 @@ -1776,6 +1776,7 @@
5913  
5914          if (vFrame.count() && (file_end || vFrame.getLast()->isSequence))
5915          {
5916 +            MPEG2frame *seqFrame;
5917              if (ptsIncrement != vFrame.first()->mpeg2_seq.frame_period / 300)
5918              {
5919                  VERBOSE(MPF_IMPORTANT,
5920 @@ -1786,6 +1787,11 @@
5921              }
5922              displayFrame->toFirst();
5923  
5924 +            // since we might reorder the frames when coming out of a cutpoint
5925 +            // me need to save the first frame here, as it is gauranteed to
5926 +            // have a sequence header.
5927 +            seqFrame = vFrame.current();
5928 +
5929              while (vFrame.current() != vFrame.getLast())
5930              {
5931                  bool ptsorder_eq_dtsorder = false;
5932 @@ -1941,7 +1947,7 @@
5933  
5934                          if (! new_discard_state)
5935                          {
5936 -                            AddSequence(markedFrame, vFrame.first());
5937 +                            AddSequence(markedFrame, seqFrame);
5938                              RenumberFrames(frame_pos + Lreorder.at(),
5939                                              - GetFrameNum(markedFrame));
5940                          }
5941 Index: mythtv/programs/mythcommflag/main.cpp
5942 ===================================================================
5943 --- mythtv/programs/mythcommflag/main.cpp       (.../tags/release-0-19) (revision 10051)
5944 +++ mythtv/programs/mythcommflag/main.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
5945 @@ -895,9 +895,6 @@
5946          return COMMFLAG_EXIT_INVALID_CMDLINE;
5947      }
5948  
5949 -    if (queueJobInstead)
5950 -        return QueueCommFlagJob(chanid, starttime);
5951 -
5952      if (copyToCutlist)
5953          return CopySkipListToCutList(chanid, starttime);
5954  
5955 @@ -1009,7 +1006,10 @@
5956  
5957                  if ( allRecorded )
5958                  {
5959 -                    FlagCommercials(chanid, starttime);
5960 +                    if (queueJobInstead)
5961 +                        QueueCommFlagJob(chanid, starttime);
5962 +                    else
5963 +                        FlagCommercials(chanid, starttime);
5964                  }
5965                  else
5966                  {
5967 @@ -1063,7 +1063,12 @@
5968  
5969                              if ((flagStatus == COMM_FLAG_NOT_FLAGGED) &&
5970                                  (marksFound == 0))
5971 -                                FlagCommercials(chanid, starttime);
5972 +                            {
5973 +                                if (queueJobInstead)
5974 +                                    QueueCommFlagJob(chanid, starttime);
5975 +                                else
5976 +                                    FlagCommercials(chanid, starttime);
5977 +                            }
5978                          }
5979                      }
5980                  }
5981 Index: mythtv/programs/mythbackend/mainserver.cpp
5982 ===================================================================
5983 --- mythtv/programs/mythbackend/mainserver.cpp  (.../tags/release-0-19) (revision 10051)
5984 +++ mythtv/programs/mythbackend/mainserver.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
5985 @@ -1919,11 +1919,8 @@
5986      if (m_sched) {
5987          if (table == "") m_sched->getAllPending(strList);
5988          else {
5989 -            // We need a different connection from the scheduler proper
5990 -            // DDCon exists, although it's designed for other purposes.
5991 -            MSqlQueryInfo dbconn = MSqlQuery::DDCon();
5992 -            Scheduler *sched = new Scheduler(false, encoderList,
5993 -                                             table, &dbconn, m_sched);
5994 +            Scheduler *sched = new Scheduler(false, encoderList, 
5995 +                                             table, m_sched);
5996              sched->FillRecordListFromDB(recordid);
5997              sched->getAllPending(strList);
5998              delete sched;
5999 @@ -2940,6 +2937,12 @@
6000          long long ret = ft->Seek(curpos, pos, whence);
6001          encodeLongLong(retlist, ret);
6002      }
6003 +    else if (command == "SET_TIMEOUT")
6004 +    {
6005 +        bool fast = slist[2].toInt();
6006 +        ft->SetTimeout(fast);
6007 +        retlist << "ok";
6008 +    }
6009      else 
6010      {
6011          VERBOSE(VB_IMPORTANT, QString("Unknown command: %1").arg(command));
6012 Index: mythtv/programs/mythbackend/scheduler.cpp
6013 ===================================================================
6014 --- mythtv/programs/mythbackend/scheduler.cpp   (.../tags/release-0-19) (revision 10051)
6015 +++ mythtv/programs/mythbackend/scheduler.cpp   (.../branches/release-0-19-fixes)       (revision 10051)
6016 @@ -35,8 +35,7 @@
6017  #define LOC_ERR QString("Scheduler, Error: ")
6018  
6019  Scheduler::Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
6020 -                     QString recordTbl, MSqlQueryInfo *databaseConnection,
6021 -                     Scheduler *master_sched)
6022 +                     QString recordTbl, Scheduler *master_sched)
6023  {
6024      hasconflicts = false;
6025      m_tvList = tvList;
6026 @@ -48,8 +47,11 @@
6027          master_sched->getAllPending(&reclist);
6028      }
6029  
6030 -    if (databaseConnection) dbConn = *databaseConnection;
6031 -    else dbConn = MSqlQuery::SchedCon();
6032 +    // Only the master scheduler should use SchedCon()
6033 +    if (runthread)
6034 +        dbConn = MSqlQuery::SchedCon();
6035 +    else
6036 +        dbConn = MSqlQuery::DDCon();
6037  
6038      recordTable = recordTbl;
6039  
6040 @@ -1136,6 +1138,10 @@
6041              
6042          if (reschedQueue.count())
6043          {
6044 +            // We might have been inactive for a long time, so make
6045 +            // sure our DB connection is fresh before continuing.
6046 +            dbConn = MSqlQuery::SchedCon();
6047 +
6048              gettimeofday(&fillstart, NULL);
6049              QString msg;
6050              while (reschedQueue.count())
6051 @@ -1827,10 +1833,10 @@
6052          QString query = QString(
6053  "INSERT INTO recordmatch (recordid, chanid, starttime, manualid) "
6054  "SELECT RECTABLE.recordid, program.chanid, program.starttime, "
6055 -" IF(search = %1, recordid, 0) "
6056 -"FROM RECTABLE, program ").arg(kManualSearch) + fromclauses[clause] + QString(
6057 -" INNER JOIN channel ON (channel.chanid = program.chanid) "
6058 -"WHERE ") + whereclauses[clause] + QString(" AND channel.visible = 1 AND "
6059 +" IF(search = %1, recordid, 0) ").arg(kManualSearch) + QString(
6060 +"FROM (RECTABLE, program INNER JOIN channel "
6061 +"      ON channel.chanid = program.chanid) ") + fromclauses[clause] + QString(
6062 +" WHERE ") + whereclauses[clause] + QString(" AND channel.visible = 1 AND "
6063  "((RECTABLE.type = %1 " // allrecord
6064  "OR RECTABLE.type = %2 " // findonerecord
6065  "OR RECTABLE.type = %3 " // finddailyrecord
6066 Index: mythtv/programs/mythbackend/housekeeper.cpp
6067 ===================================================================
6068 --- mythtv/programs/mythbackend/housekeeper.cpp (.../tags/release-0-19) (revision 10051)
6069 +++ mythtv/programs/mythbackend/housekeeper.cpp (.../branches/release-0-19-fixes)       (revision 10051)
6070 @@ -138,7 +138,6 @@
6071  
6072      while (1)
6073      {
6074 -        VERBOSE(VB_IMPORTANT, "Running HouseKeeping");
6075          gContext->LogEntry("mythbackend", LP_DEBUG,
6076                             "Running housekeeping thread", "");
6077  
6078 Index: mythtv/programs/mythbackend/scheduler.h
6079 ===================================================================
6080 --- mythtv/programs/mythbackend/scheduler.h     (.../tags/release-0-19) (revision 10051)
6081 +++ mythtv/programs/mythbackend/scheduler.h     (.../branches/release-0-19-fixes)       (revision 10051)
6082 @@ -23,8 +23,7 @@
6083  {
6084    public:
6085      Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
6086 -              QString recordTbl = "record", MSqlQueryInfo *dbConnUse = NULL,
6087 -              Scheduler *master_sched = NULL);
6088 +              QString recordTbl = "record", Scheduler *master_sched = NULL);
6089      ~Scheduler();
6090  
6091      void Reschedule(int recordid);
6092 Index: mythtv/programs/mythbackend/filetransfer.cpp
6093 ===================================================================
6094 --- mythtv/programs/mythbackend/filetransfer.cpp        (.../tags/release-0-19) (revision 10051)
6095 +++ mythtv/programs/mythbackend/filetransfer.cpp        (.../branches/release-0-19-fixes)       (revision 10051)
6096 @@ -131,3 +131,9 @@
6097  
6098      return size;
6099  }
6100 +
6101 +void FileTransfer::SetTimeout(bool fast)
6102 +{
6103 +    rbuffer->SetTimeout(fast);
6104 +}
6105 +
6106 Index: mythtv/programs/mythbackend/autoexpire.cpp
6107 ===================================================================
6108 --- mythtv/programs/mythbackend/autoexpire.cpp  (.../tags/release-0-19) (revision 10051)
6109 +++ mythtv/programs/mythbackend/autoexpire.cpp  (.../branches/release-0-19-fixes)       (revision 10051)
6110 @@ -291,7 +291,8 @@
6111  
6112      if ((availFreeKB = getDiskSpace(record_file_prefix, tKB, uKB)) < 0)
6113      {
6114 -        QString msg = QString("ERROR: Could not calculate free space.");
6115 +        QString msg = QString("ERROR: Could not calculate free space for %1.")
6116 +                              .arg(record_file_prefix);
6117          VERBOSE(VB_IMPORTANT, LOC + msg);
6118          gContext->LogEntry("mythbackend", LP_WARNING,
6119                             "Autoexpire Recording", msg);
6120 Index: mythtv/programs/mythbackend/filetransfer.h
6121 ===================================================================
6122 --- mythtv/programs/mythbackend/filetransfer.h  (.../tags/release-0-19) (revision 10051)
6123 +++ mythtv/programs/mythbackend/filetransfer.h  (.../branches/release-0-19-fixes)       (revision 10051)
6124 @@ -35,6 +35,8 @@
6125  
6126      long long GetFileSize(void);
6127  
6128 +    void SetTimeout(bool fast);
6129 +
6130    private:
6131      bool readthreadlive;
6132      QMutex readthreadLock;
6133 Index: mythtv/programs/mythtv/main.cpp
6134 ===================================================================
6135 --- mythtv/programs/mythtv/main.cpp     (.../tags/release-0-19) (revision 10051)
6136 +++ mythtv/programs/mythtv/main.cpp     (.../branches/release-0-19-fixes)       (revision 10051)
6137 @@ -132,6 +132,7 @@
6138          ProgramInfo *pginfo = new ProgramInfo();
6139          pginfo->endts = QDateTime::currentDateTime().addSecs(-180);
6140          pginfo->pathname = filename;
6141 +        pginfo->isVideo = true;
6142      
6143          tv->Playback(pginfo);
6144      }
6145 Index: mythtv/programs/mythfilldatabase/filldata.cpp
6146 ===================================================================
6147 --- mythtv/programs/mythfilldatabase/filldata.cpp       (.../tags/release-0-19) (revision 10051)
6148 +++ mythtv/programs/mythfilldatabase/filldata.cpp       (.../branches/release-0-19-fixes)       (revision 10051)
6149 @@ -337,7 +337,7 @@
6150  
6151      MSqlQuery query(MSqlQuery::InitCon());
6152      query.prepare("SELECT ch.chanid, nim.url "
6153 -            "FROM channel ch, callsignnetworkmap csm "
6154 +            "FROM (channel ch, callsignnetworkmap csm) "
6155              "RIGHT JOIN networkiconmap nim ON csm.network = nim.network "
6156              "WHERE ch.callsign = csm.callsign AND "
6157              "(icon = :NOICON OR icon = '') AND ch.sourceid = :SOURCEID");
6158 @@ -2174,7 +2174,8 @@
6159                          0 /*service id*/, major,            minor,
6160                          false /*use on air guide*/, false /*hidden*/,
6161                          false /*hidden in guide*/,
6162 -                        freqid,           localfile,        (*i).tvformat))
6163 +                        freqid,           localfile,        (*i).tvformat,
6164 +                        (*i).xmltvid))
6165                  {
6166                      cout << "### " << endl;
6167                      cout << "### Channel inserted" << endl;
6168 @@ -3851,7 +3852,6 @@
6169               VERBOSE(VB_IMPORTANT, "Failed to fetch some program info");
6170               gContext->LogEntry("mythfilldatabase", LP_WARNING,
6171                                  "Failed to fetch some program info", "");
6172 -             return FILLDB_EXIT_DB_ERROR;
6173          }
6174          else
6175              VERBOSE(VB_IMPORTANT, "Data fetching complete.");
6176 Index: mythtv/setup/backendsettings.cpp
6177 ===================================================================
6178 --- mythtv/setup/backendsettings.cpp    (.../tags/release-0-19) (revision 10051)
6179 +++ mythtv/setup/backendsettings.cpp    (.../branches/release-0-19-fixes)       (revision 10051)
6180 @@ -1,6 +1,7 @@
6181  #include <cstdio>
6182  
6183  #include "backendsettings.h"
6184 +#include "frequencies.h"
6185  #include "libmyth/mythcontext.h"
6186  #include "libmyth/settings.h"
6187  #include <unistd.h>
6188 @@ -110,23 +111,10 @@
6189  {
6190      GlobalComboBox *gc = new GlobalComboBox("FreqTable");
6191      gc->setLabel(QObject::tr("Channel frequency table"));
6192 -    gc->addSelection("us-cable");
6193 -    gc->addSelection("us-bcast");
6194 -    gc->addSelection("us-cable-hrc");
6195 -    gc->addSelection("us-cable-irc");
6196 -    gc->addSelection("japan-bcast");
6197 -    gc->addSelection("japan-cable");
6198 -    gc->addSelection("europe-west");
6199 -    gc->addSelection("europe-east");
6200 -    gc->addSelection("italy");
6201 -    gc->addSelection("newzealand");
6202 -    gc->addSelection("australia");
6203 -    gc->addSelection("ireland");
6204 -    gc->addSelection("france");
6205 -    gc->addSelection("china-bcast");
6206 -    gc->addSelection("southafrica");
6207 -    gc->addSelection("argentina");
6208 -    gc->addSelection("australia-optus");
6209 +
6210 +    for (uint i = 0; chanlists[i].name; i++)
6211 +        gc->addSelection(chanlists[i].name);
6212 +
6213      gc->setHelpText(QObject::tr("Select the appropriate frequency table for "
6214                      "your system.  If you have an antenna, use a \"-bcast\" "
6215                      "frequency."));
This page took 0.552044 seconds and 4 git commands to generate.