1 Index: mythplugins/mythweb/themes/wml/header.php
2 ===================================================================
3 --- mythplugins/mythweb/themes/wml/header.php (.../tags/release-0-19) (revision 10931)
4 +++ mythplugins/mythweb/themes/wml/header.php (.../branches/release-0-19-fixes) (revision 10931)
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 10931)
14 +++ mythplugins/mythweb/themes/default/weather/weather.php (.../branches/release-0-19-fixes) (revision 10931)
16 $tomorrow = date("m/d/Y", mktime(0, 0, 0, date("m") , date("d")+1, date("Y")));
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;
30 Index: mythplugins/mythweb/themes/default/music/music.php
31 ===================================================================
32 --- mythplugins/mythweb/themes/default/music/music.php (.../tags/release-0-19) (revision 10931)
33 +++ mythplugins/mythweb/themes/default/music/music.php (.../branches/release-0-19-fixes) (revision 10931)
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';
48 printf("<form action=\"".root."music\" method=\"GET\" >\n");
49 printf("<input type=\"hidden\" name=\"mode\" value=\"music\" />\n");
51 Index: mythplugins/mythweb/themes/default/tv/detail.php
52 ===================================================================
53 --- mythplugins/mythweb/themes/default/tv/detail.php (.../tags/release-0-19) (revision 10931)
54 +++ mythplugins/mythweb/themes/default/tv/detail.php (.../branches/release-0-19-fixes) (revision 10931)
57 <div id="program_title">
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>
62 <div id="program_time">
64 Index: mythplugins/mythweb/includes/mythbackend.php
65 ===================================================================
66 --- mythplugins/mythweb/includes/mythbackend.php (.../tags/release-0-19) (revision 10931)
67 +++ mythplugins/mythweb/includes/mythbackend.php (.../branches/release-0-19-fixes) (revision 10931)
69 // The character string used by the backend to separate records
70 define('backend_sep', '[]:[]');
72 -// A couple of global variables to keep duplicate queries to a minimum
73 - $Scheduled_Recordings = array();
74 - $Recorded_Programs = array();
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 10931)
82 +++ mythplugins/mythweb/includes/programs.php (.../branches/release-0-19-fixes) (revision 10931)
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();
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
119 LEFT JOIN channel ON program.chanid = channel.chanid
121 // The extra query, if there is one
123 $query .= ' AND '.$extra_query;
124 - // Group, sort and query
126 $query .= ' GROUP BY program.chanid, program.starttime ORDER BY program.starttime';
128 + if ($single_program)
129 + $query .= ' LIMIT 1';
131 $sh = $db->query($query,
132 star_character, max_stars, max_stars);
137 // If channel-specific information was requested, return an array of those programs, or just the first/only one
139 - if ($single_program)
140 - return $channel_hash[$chanid]->programs[0];
142 - return $channel_hash[$chanid]->programs;
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;
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;
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;
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'))
170 + $this->filesize = gmp_strval($size);
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;
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];
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
212 $this->title_pronounce = $data['title_pronounce'];
213 $this->recstatus = $data['recstatus'];
215 - if ($program_data['tsdefault']) {
216 - $this->timestretch = $program_data['tsdefault'];
217 + if ($data['tsdefault']) {
218 + $this->timestretch = $data['tsdefault'];
220 $this->timestretch = 1.0;
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];
232 + if (!$this->channel)
233 + $this->channel =& load_one_channel($this->chanid);
236 // Calculate the duration
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 10931)
242 +++ mythplugins/mythweb/includes/utils.php (.../branches/release-0-19-fixes) (revision 10931)
244 static $first_run=true;
247 - echo '<script type="text/javascript" src="/js/debug.js"></script>';
248 + echo '<script type="text/javascript" src="'.root.'js/debug.js"></script>';
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 10931)
255 +++ mythplugins/mythweb/includes/init.php (.../branches/release-0-19-fixes) (revision 10931)
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.
265 - * @global array $GLOBALS['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']
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"];
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']);
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.
303 + * @global array $GLOBALS['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']
321 // Load the database connection routines
322 require_once 'includes/db.php';
324 Index: mythplugins/mythweb/includes/mobile.php
325 ===================================================================
326 --- mythplugins/mythweb/includes/mobile.php (.../tags/release-0-19) (revision 10931)
327 +++ mythplugins/mythweb/includes/mobile.php (.../branches/release-0-19-fixes) (revision 10931)
329 * If you don't know the screensize of some mobile terminal then use
330 * an empty array or approximate dimensions.
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
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),
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
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
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
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),
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
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)
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 10931)
438 +++ mythplugins/mythweb/includes/recording_schedules.php (.../branches/release-0-19-fixes) (revision 10931)
441 mysql_free_result($result);
444 + global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
445 + $Scheduled_Recordings = array();
446 + $Num_Conflicts = 0;
447 + $Num_Scheduled = 0;
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) {
455 if ($key === 'offset') {
456 Index: mythplugins/mythweb/includes/session.php
457 ===================================================================
458 --- mythplugins/mythweb/includes/session.php (.../tags/release-0-19) (revision 10931)
459 +++ mythplugins/mythweb/includes/session.php (.../branches/release-0-19-fixes) (revision 10931)
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');
471 Index: mythplugins/mythweb/modules/weather/handler.php
472 ===================================================================
473 --- mythplugins/mythweb/modules/weather/handler.php (.../tags/release-0-19) (revision 10931)
474 +++ mythplugins/mythweb/modules/weather/handler.php (.../branches/release-0-19-fixes) (revision 10931)
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 10931)
491 +++ mythplugins/mythweb/modules/status/handler.php (.../branches/release-0-19-fixes) (revision 10931)
493 $masterhost = get_backend_setting('MasterServerIP');
494 $statusport = get_backend_setting('BackendStatusPort');
497 + $xml_param = ($Path[1] == 'xml') ? '/xml' : '';
499 // Make sure the content is interpreted as UTF-8
500 header('Content-Type: text/html; charset=UTF-8');
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");
507 - $status = implode("\n", file("http://$masterhost:$statusport"));
508 + $status = implode("\n", file("http://$masterhost:$statusport$xml_param"));
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 10931)
515 +++ mythplugins/mythweb/modules/backend_log/handler.php (.../branches/release-0-19-fixes) (revision 10931)
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;
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 10931)
528 +++ mythplugins/mythweb/modules/tv/upcoming.php (.../branches/release-0-19-fixes) (revision 10931)
532 // Skip deactivated shows?
533 - elseif (!$_SESSION['scheduled_recordings']['disp_deactivated']) {
535 + elseif ($show->recstatus != 'Recording') {
536 + if (!$_SESSION['scheduled_recordings']['disp_deactivated'])
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 10931)
544 +++ mythplugins/mythweb/modules/tv/recorded.php (.../branches/release-0-19-fixes) (revision 10931)
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')
560 + $Total_Used = gmp_strval(gmp_add($Total_Used, $size));
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];
566 // keep track of their names and how many episodes we have recorded
568 $Groups[$record[30]]++;
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',
579 + gmp_mul('4294967296',
580 + gmp_add($size_high, $size_low < 0 ? '1' : '0'))
583 + define(disk_size, gmp_strval($size));
584 + $size = gmp_mul('1024',
586 + gmp_mul('4294967296',
587 + gmp_add($used_high, $used_low < 0 ? '1' : '0'))
590 + define(disk_used, gmp_strval($size));
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);
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 10931)
603 +++ mythplugins/mythweb/.htaccess (.../branches/release-0-19-fixes) (revision 10931)
606 # AuthDigestFile /var/www/htdigest
608 +# BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On
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
614 php_value memory_limit 32M
616 - php_value session.save_path php_sessions
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 10931)
627 + * A random assortment of javascript debug routines
631 + * @version $Revision$
633 + * @copyright Silicon Mechanics
637 + * @subpackage Javascript
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;">');
648 + debug_window_handle.document.write('<pre>'+string+'</pre><hr>');
651 Property changes on: mythplugins/mythweb/js/debug.js
652 ___________________________________________________________________
658 + Date Revision Author HeadURL
660 Index: mythplugins/mythweb/js/browser.js
661 ===================================================================
662 --- mythplugins/mythweb/js/browser.js (.../tags/release-0-19) (revision 10931)
663 +++ mythplugins/mythweb/js/browser.js (.../branches/release-0-19-fixes) (revision 10931)
664 @@ -215,14 +215,18 @@
665 browser.is_css = (document.body && document.body.style)
666 browser.is_w3c = (browser.is_css && browser.getElementById)
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;
684 - browser.java = navigator.javaEnabled();
685 + browser.java = navigator.javaEnabled();
687 /****************************** Plugin Support ******************************/
689 Index: mythplugins/mythweb/README
690 ===================================================================
691 --- mythplugins/mythweb/README (.../tags/release-0-19) (revision 10931)
692 +++ mythplugins/mythweb/README (.../branches/release-0-19-fixes) (revision 10931)
694 This is the README file for the MythWeb package.
699 -(c) 2002-2006 Thor Sigvaldason <mythtv(a)lamedomainname(o)com>
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)
707 -with contributions from many people including:
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>
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.
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:
731 + <Directory "/var/www/html/mythweb" >
732 + Options FollowSymLinks
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:
743 Index: mythplugins/mythdvd/mtd/jobthread.cpp
744 ===================================================================
745 --- mythplugins/mythdvd/mtd/jobthread.cpp (.../tags/release-0-19) (revision 10931)
746 +++ mythplugins/mythdvd/mtd/jobthread.cpp (.../branches/release-0-19-fixes) (revision 10931)
748 #include <sys/types.h>
749 #include <sys/stat.h>
755 Index: mythplugins/mythdvd/mtd/mtd.cpp
756 ===================================================================
757 --- mythplugins/mythdvd/mtd/mtd.cpp (.../tags/release-0-19) (revision 10931)
758 +++ mythplugins/mythdvd/mtd/mtd.cpp (.../branches/release-0-19-fixes) (revision 10931)
764 #include <qstringlist.h>
767 Index: mythplugins/mythdvd/mtd/logging.cpp
768 ===================================================================
769 --- mythplugins/mythdvd/mtd/logging.cpp (.../tags/release-0-19) (revision 10931)
770 +++ mythplugins/mythdvd/mtd/logging.cpp (.../branches/release-0-19-fixes) (revision 10931)
776 #include <qdatetime.h>
778 #include <mythtv/mythcontext.h>
779 Index: mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp
780 ===================================================================
781 --- mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp (.../tags/release-0-19) (revision 10931)
782 +++ mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
784 #include "metadata.h"
785 #include "metaiooggvorbiscomment.h"
787 +#include <mythtv/mythconfig.h>
788 #include <mythtv/mythcontext.h>
790 // static functions for OggVorbis
795 +#ifdef WORDS_BIGENDIAN
796 + len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 1, 2, 1,
799 len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1,
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 10931)
808 +++ mythplugins/mythmusic/mythmusic/flacdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
810 #include "metadata.h"
811 #include "metaioflacvorbiscomment.h"
813 +#include <mythtv/mythconfig.h>
814 #include <mythtv/mythcontext.h>
818 for (channel = 0; channel < chan; channel++)
820 sample = (FLAC__int8)buffer[channel][cursamp];
821 +#ifdef WORDS_BIGENDIAN
822 + *(output_buf + output_at++) = ((sample >> 8) & 0xff);
824 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
830 for (channel = 0; channel < chan; channel++)
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);
837 + *(output_buf + output_at++) = ((sample >> 0) & 0xff);
838 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
843 Index: mythplugins/mythmusic/mythmusic/maddecoder.cpp
844 ===================================================================
845 --- mythplugins/mythmusic/mythmusic/maddecoder.cpp (.../tags/release-0-19) (revision 10931)
846 +++ mythplugins/mythmusic/mythmusic/maddecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
848 #include <mythtv/audiooutput.h>
849 #include "metaioid3v2.h"
851 +#include <mythtv/mythconfig.h>
852 #include <mythtv/mythcontext.h>
854 #define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
864 @@ -488,15 +489,25 @@
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);
872 + *(output_buf + output_at++) = ((sample >> 0) & 0xff);
873 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
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);
884 + *(output_buf + output_at++) = ((sample >> 0) & 0xff);
885 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
890 Index: mythplugins/mythweather/mythweather/weather.cpp
891 ===================================================================
892 --- mythplugins/mythweather/mythweather/weather.cpp (.../tags/release-0-19) (revision 10931)
893 +++ mythplugins/mythweather/mythweather/weather.cpp (.../branches/release-0-19-fixes) (revision 10931)
894 @@ -2571,6 +2571,14 @@
898 + int imageCount = 5;
899 + QString imagesList = parseData(tempData, "imagenames = new Array( '", ";");
900 + if (imagesList != "<NULL>")
902 + QStringList imageURLs = QStringList::split(",", imagesList);
903 + imageCount = imageURLs.size();
906 QString fileprefix = MythContext::GetConfDir();
908 QDir dir(fileprefix);
909 @@ -2587,13 +2595,13 @@
910 cerr << "MythWeather: Map File Prefix: " << fileprefix << endl;
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));
918 cerr << "MythWeather: Copying Map Files from Server (" << imageLoc << ")...\n";
920 - for (int x = 1; x <= 6; x++)
921 + for (int x = 1; x <= imageCount; x++)
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 10931)
928 +++ mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp (.../branches/release-0-19-fixes) (revision 10931)
930 #include "keygrabber.h"
933 -static QMap<int,QString> FindContexts(const QString &context)
935 - QMap<int,QString> retval;
937 - if (context != JUMP_CONTEXT) retval[-1] = JUMP_CONTEXT;
938 - retval[0] = context;
939 - if (context != JUMP_CONTEXT && context != GLOBAL_CONTEXT)
941 - if (context == "TV Editting")
942 - retval[1] = "TV Playback";
943 - retval[2] = GLOBAL_CONTEXT;
944 - if (context != "qt")
950 static const QString KeyToDisplay(const QString key)
953 refreshKeyInformation();
956 -void MythControls::addBindings(QDict<binding_t> &bindings, const QString &context, const QString &contextParent, int bindlevel)
959 +void MythControls::addBindings(QDict<binding_t> &bindings,
960 + const QString &context,
961 + const QString &contextParent, int bindlevel)
963 QStringList *actions = key_bindings->getActions(context);
965 @@ -872,18 +860,13 @@
967 BindingList *MythControls::getKeyBindings(const QString &context)
970 QDict<binding_t> bindings;
973 - QMap<int,QString> contextList = FindContexts(context);
974 - for (QMap<int,QString>::iterator it = contextList.begin(); it != contextList.end(); ++it)
976 - int level = it.key();
977 - QString curcontext = it.data();
978 - addBindings(bindings, curcontext, context, level);
980 + for (size_t i = 0; i < contexts.size(); i++)
981 + addBindings(bindings, contexts[i], context, i);
985 for (QDictIterator<binding_t> it(bindings); it.current(); ++it)
987 Index: mythplugins/mythcontrols/mythcontrols/actionset.cpp
988 ===================================================================
989 --- mythplugins/mythcontrols/mythcontrols/actionset.cpp (.../tags/release-0-19) (revision 10931)
990 +++ mythplugins/mythcontrols/mythcontrols/actionset.cpp (.../branches/release-0-19-fixes) (revision 10931)
991 @@ -139,13 +139,19 @@
992 /* method description in header */
993 QStringList * ActionSet::actionStrings(const QString &context_name) const
995 - QStringList *action_strings = new QStringList();
996 - QDictIterator<Action> it(*(_contexts[context_name]));
997 + Context *c = _contexts[context_name];
999 - for (; it.current(); ++it)
1000 - action_strings->append(it.currentKey());
1001 + if (c == NULL) return NULL;
1004 + QStringList *action_strings = new QStringList();
1005 + QDictIterator<Action> it(*(_contexts[context_name]));
1007 + for (; it.current(); ++it)
1008 + action_strings->append(it.currentKey());
1010 - return action_strings;
1011 + return action_strings;
1016 Index: mythplugins/mythcontrols/mythcontrols/keybindings.h
1017 ===================================================================
1018 --- mythplugins/mythcontrols/mythcontrols/keybindings.h (.../tags/release-0-19) (revision 10931)
1019 +++ mythplugins/mythcontrols/mythcontrols/keybindings.h (.../branches/release-0-19-fixes) (revision 10931)
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
1027 inline QStringList * getContexts() const
1029 Index: mythplugins/mythvideo/mythvideo/videomanager.h
1030 ===================================================================
1031 --- mythplugins/mythvideo/mythvideo/videomanager.h (.../tags/release-0-19) (revision 10931)
1032 +++ mythplugins/mythvideo/mythvideo/videomanager.h (.../branches/release-0-19-fixes) (revision 10931)
1035 VideoManager(MythMainWindow *parent, const char *name = 0);
1036 ~VideoManager(void);
1037 - void VideoManager::processEvents() { qApp->processEvents(); }
1038 + void processEvents() { qApp->processEvents(); }
1041 void slotManualIMDB();
1042 Index: mythplugins/mythvideo/mythvideo/videoselected.h
1043 ===================================================================
1044 --- mythplugins/mythvideo/mythvideo/videoselected.h (.../tags/release-0-19) (revision 10931)
1045 +++ mythplugins/mythvideo/mythvideo/videoselected.h (.../branches/release-0-19-fixes) (revision 10931)
1047 VideoSelected(VideoList *lvideolist,
1048 MythMainWindow *parent, const char *name = 0, int index = 0);
1050 - void VideoSelected::processEvents() { qApp->processEvents(); }
1051 + void processEvents() { qApp->processEvents(); }
1055 Index: mythplugins/mythphone/mythphone/sipfsm.h
1056 ===================================================================
1057 --- mythplugins/mythphone/mythphone/sipfsm.h (.../tags/release-0-19) (revision 10931)
1058 +++ mythplugins/mythphone/mythphone/sipfsm.h (.../branches/release-0-19-fixes) (revision 10931)
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);
1067 int getPrimaryCall() { return primaryCall; };
1068 Index: mythplugins/mythphone/mythphone/vxml.h
1069 ===================================================================
1070 --- mythplugins/mythphone/mythphone/vxml.h (.../tags/release-0-19) (revision 10931)
1071 +++ mythplugins/mythphone/mythphone/vxml.h (.../branches/release-0-19-fixes) (revision 10931)
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 10931)
1084 +++ mythplugins/mythgame/mythgame/gamehandler.h (.../branches/release-0-19-fixes) (revision 10931)
1088 static GameHandler* GetHandler(RomInfo *rominfo);
1089 - static GameHandler* GameHandler::GetHandlerByName(QString systemname);
1090 + static GameHandler* GetHandlerByName(QString systemname);
1094 Index: mythplugins/mythnews/mythnews/news-sites.xml
1095 ===================================================================
1096 --- mythplugins/mythnews/mythnews/news-sites.xml (.../tags/release-0-19) (revision 10931)
1097 +++ mythplugins/mythnews/mythnews/news-sites.xml (.../branches/release-0-19-fixes) (revision 10931)
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>
1107 Index: mythtv/libs/libmythtv/dvbchannel.h
1108 ===================================================================
1109 --- mythtv/libs/libmythtv/dvbchannel.h (.../tags/release-0-19) (revision 10931)
1110 +++ mythtv/libs/libmythtv/dvbchannel.h (.../branches/release-0-19-fixes) (revision 10931)
1112 { return chan_opts.pmt.HasTelevisionService(); }
1113 /// Returns true iff we have a faulty DVB driver that munges PMT
1114 bool HasCRCBug(void) const { return has_crc_bug; }
1115 + uint GetMinSignalMonitorDelay(void) const { return sigmon_delay; }
1118 bool SwitchToInput(const QString &inputname, const QString &chan);
1119 bool SwitchToInput(int newcapchannel, bool setstarting);
1120 bool Tune(const dvb_channel_t& channel, bool force_reset=false);
1121 + bool Retune(void);
1123 // Set/Get/Command just for SIScan/ScanWizardScanner
1124 void SetMultiplexID(int mplexid) { currentTID = mplexid; };
1125 @@ -109,11 +111,18 @@
1126 volatile int fd_frontend; ///< File descriptor for tuning hardware
1127 int cardnum; ///< DVB Card number
1128 bool has_crc_bug; ///< true iff our driver munges PMT
1129 + uint tuning_delay;///< Extra delay to add for broken drivers
1130 + uint sigmon_delay;///< Minimum delay between FE_LOCK checks
1131 int currentTID; ///< Stores mplexid from database
1133 bool first_tune; ///< Used to force hardware reset
1135 int nextcapchannel; ///< Signal an input change
1137 + /// Last tuning options sent to hardware for retuning
1138 + DVBTuning retune_tuning;
1139 + /// Retuning adjustment, required so drivers don't ignore retune request
1144 Index: mythtv/libs/libmythtv/NuppelVideoPlayer.h
1145 ===================================================================
1146 --- mythtv/libs/libmythtv/NuppelVideoPlayer.h (.../tags/release-0-19) (revision 10931)
1147 +++ mythtv/libs/libmythtv/NuppelVideoPlayer.h (.../branches/release-0-19-fixes) (revision 10931)
1150 long long CalcMaxFFTime(long long ff, bool setjump = true) const;
1151 long long CalcRWTime(long long rw) const;
1152 - void calcSliderPos(struct StatusPosInfo &posInfo);
1153 + void calcSliderPos(struct StatusPosInfo &posInfo,
1154 + bool paddedFields = false);
1157 OSD *GetOSD(void) { return osd; }
1159 bool DecodeFrame(struct rtframeheader *frameheader,
1160 unsigned char *strm, unsigned char *outbuf);
1162 + bool PrebufferEnoughFrames(void);
1163 void CheckPrebuffering(void);
1164 bool GetFrameNormal(int onlyvideo);
1165 bool GetFrameFFREW(void);
1167 bool DoRewind(void);
1169 // Private seeking stuff
1170 - void ClearAfterSeek(void);
1171 + void ClearAfterSeek(bool clearvideobuffers = true);
1172 bool FrameIsInMap(long long frameNumber, QMap<long long, int> &breakMap);
1173 void JumpToFrame(long long frame);
1174 void JumpToNetFrame(long long net) { JumpToFrame(framesPlayed + net); }
1176 QMap<long long, int>::Iterator deleteIter;
1177 QMap<long long, int>::Iterator blankIter;
1178 QMap<long long, int>::Iterator commBreakIter;
1179 + bool forcePositionMapSync;
1181 // Playback (output) speed control
1182 /// Lock for next_play_speed and next_normal_speed
1183 Index: mythtv/libs/libmythtv/osdlistbtntype.h
1184 ===================================================================
1185 --- mythtv/libs/libmythtv/osdlistbtntype.h (.../tags/release-0-19) (revision 10931)
1186 +++ mythtv/libs/libmythtv/osdlistbtntype.h (.../branches/release-0-19-fixes) (revision 10931)
1188 +// -*- Mode: c++ -*-
1189 /* ============================================================
1190 * File : uilistbtntype.h
1191 * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
1193 #ifndef OSDLISTBTNTYPE_H
1194 #define OSDLISTBTNTYPE_H
1196 -#include "osdtypes.h"
1197 -#include "ttfont.h"
1199 +using namespace std;
1203 #include <qptrlist.h>
1206 +#include <qptrvector.h>
1209 +#include "osdtypes.h"
1210 +#include "ttfont.h"
1211 #include "generictree.h"
1213 +class OSDListBtnType;
1214 class OSDListBtnTypeItem;
1215 -class OSDListBtnType;
1216 +typedef vector<OSDListBtnType*> OSDListBtnList;
1217 +typedef vector<OSDListBtnTypeItem*> OSDListBtnItemList;
1219 class OSDGenericTree : public GenericTree
1222 // This class will _not_ delete the image it's given, if any.
1223 - OSDGenericTree(OSDGenericTree *parent, const QString &name,
1224 - const QString &action = "", int check = -1,
1225 - OSDTypeImage *image = NULL, QString group = "");
1226 + OSDGenericTree(OSDGenericTree *parent, const QString &name,
1227 + const QString &action = "", int check = -1,
1228 + OSDTypeImage *image = NULL, QString group = "") :
1229 + GenericTree(name), m_image(image), m_action(action),
1230 + m_group(group), m_checkable(check), m_parentButton(NULL)
1232 + m_group = (m_group.isEmpty()) ? action : m_group;
1233 + setSelectable(!action.isEmpty());
1235 + parent->addNode(this);
1238 - OSDTypeImage *getImage(void) { return m_image; }
1239 - QString getAction(void) { return m_action; }
1240 - int getCheckable(void) { return m_checkable; }
1241 - QString getGroup(void) { return m_group; }
1242 + QString getAction(void) const { return m_action; }
1243 + QString getGroup(void) const { return m_group; }
1244 + int getCheckable(void) const { return m_checkable; }
1246 + OSDTypeImage *getImage(void) { return m_image; }
1247 + OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; }
1249 void setParentButton(OSDListBtnTypeItem *button)
1250 - { m_parentButton = button; };
1251 - OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; };
1252 + { m_parentButton = button; }
1255 - OSDTypeImage *m_image;
1259 + OSDTypeImage *m_image;
1263 OSDListBtnTypeItem *m_parentButton;
1270 - OSDListTreeType(const QString &name, const QRect &area,
1271 - const QRect &levelsize, int levelspacing,
1272 - float wmult, float hmult);
1273 + OSDListTreeType(const QString &name, const QRect &area,
1274 + const QRect &levelsize, int levelspacing,
1275 + float wmult, float hmult);
1276 + ~OSDListTreeType();
1278 - void Reinit(float wchange, float hchange, float wmult, float hmult);
1279 + bool IsVisible(void) const { return m_visible; }
1281 + void SetFontActive(TTFFont *font) { m_active = font; }
1282 + void SetFontInactive(TTFFont *font) { m_inactive = font; }
1284 void SetGroupCheckState(QString group, int newState = 0);
1285 + void SetSpacing(uint spacing)
1286 + { m_unbiasedspacing = (m_spacing = spacing) / m_wmult; }
1287 + void SetMargin(uint margin)
1288 + { m_unbiasedmargin = (m_margin = margin) / m_wmult; }
1289 + void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha)
1290 + { m_itemRegBeg = beg; m_itemRegEnd = end; m_itemRegAlpha = alpha; }
1291 + void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha)
1292 + { m_itemSelBeg = beg; m_itemSelEnd = end; m_itemSelAlpha = alpha; }
1293 + void SetVisible(bool visible) { m_visible = visible; }
1294 + void SetAsTree(OSDGenericTree *toplevel, vector<uint> *select = NULL);
1296 - void SetFontActive(TTFFont *font);
1297 - void SetFontInactive(TTFFont *font);
1298 - void SetSpacing(int spacing);
1299 - void SetMargin(int margin);
1300 - void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha);
1301 - void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha);
1303 - void SetAsTree(OSDGenericTree *toplevel);
1305 - OSDGenericTree *GetCurrentPosition(void);
1307 + void Reinit(float wmult, float hmult);
1308 bool HandleKeypress(QKeyEvent *e);
1310 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
1312 - bool IsVisible(void) { return m_visible; }
1313 - void SetVisible(bool visible) { m_visible = visible; }
1316 void itemSelected(OSDListTreeType *parent, OSDGenericTree *item);
1317 void itemEntered(OSDListTreeType *parent, OSDGenericTree *item);
1320 - void FillLevelFromTree(OSDGenericTree *item, OSDListBtnType *list);
1321 - OSDListBtnType *GetLevel(int levelnum);
1322 - void SetCurrentPosition(void);
1323 + void FillLevelFromTree(OSDGenericTree *item, uint levelnum);
1324 + OSDListBtnType *GetLevel(uint levelnum);
1325 + void EnterItem(void);
1326 + void SelectItem(void);
1331 OSDGenericTree *treetop;
1332 OSDGenericTree *currentpos;
1333 + TTFFont *m_active;
1334 + TTFFont *m_inactive;
1336 - QPtrList<OSDListBtnType> listLevels;
1337 + OSDListBtnList listLevels;
1339 - OSDListBtnType *currentlevel;
1341 - TTFFont *m_active;
1342 - TTFFont *m_inactive;
1344 QColor m_itemRegBeg;
1345 QColor m_itemRegEnd;
1346 QColor m_itemSelBeg;
1347 @@ -116,62 +132,76 @@
1348 uint m_itemRegAlpha;
1349 uint m_itemSelAlpha;
1355 + int m_levelspacing;
1357 - QRect m_totalarea;
1358 - QRect m_levelsize;
1359 - int m_levelspacing;
1360 + QRect m_totalarea;
1361 + QRect m_levelsize;
1365 + float m_unbiasedspacing;
1366 + float m_unbiasedmargin;
1367 + QRect m_unbiasedarea;
1368 + QRect m_unbiasedsize;
1371 - bool m_arrowAccel;
1378 + bool m_arrowAccel;
1381 class OSDListBtnType : public OSDType
1383 + friend class OSDListBtnTypeItem;
1387 OSDListBtnType(const QString &name, const QRect& area,
1388 float wmult, float hmult,
1389 bool showScrollArrows = false);
1392 - void Reinit(float wchange, float hchange, float wmult, float hmult);
1394 + bool IsVisible() const { return m_visible; }
1397 + void SetFontActive(TTFFont *font) { m_fontActive = font; }
1398 + void SetFontInactive(TTFFont *font) { m_fontInactive = font; }
1399 + void SetSpacing(int spacing) { m_itemSpacing = spacing; }
1400 + void SetMargin(int margin) { m_itemMargin = margin; }
1401 + void SetActive(bool active) { m_active = active; }
1402 + void SetVisible(bool vis) { m_visible = vis; }
1403 + void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha)
1404 + { m_itemRegBeg = beg; m_itemRegEnd = end; m_itemRegAlpha = alpha; }
1405 + void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha)
1406 + { m_itemSelBeg = beg; m_itemSelEnd = end; m_itemSelAlpha = alpha; }
1407 void SetGroupCheckState(QString group, int newState = 0);
1408 + void SetItemCurrent(const OSDListBtnTypeItem* item);
1409 + void SetItemCurrent(uint pos);
1411 - void SetFontActive(TTFFont *font);
1412 - void SetFontInactive(TTFFont *font);
1413 - void SetSpacing(int spacing);
1414 - void SetMargin(int margin);
1415 - void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha);
1416 - void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha);
1418 - void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
1420 - void SetActive(bool active);
1423 - void SetItemCurrent(OSDListBtnTypeItem* item);
1424 - void SetItemCurrent(int pos);
1425 - OSDListBtnTypeItem* GetItemCurrent();
1426 - OSDListBtnTypeItem* GetItemFirst();
1427 - OSDListBtnTypeItem* GetItemNext(OSDListBtnTypeItem *item);
1429 + int GetCount(void) const;
1430 + int GetItemPos(const OSDListBtnTypeItem* item) const;
1431 + int GetItemCurrentPos() const;
1432 + OSDListBtnTypeItem* GetItemCurrent(void);
1433 + OSDListBtnTypeItem* GetItemFirst(void);
1434 + OSDListBtnTypeItem* GetItemNext(const OSDListBtnTypeItem *item);
1435 OSDListBtnTypeItem* GetItemAt(int pos);
1436 - int GetItemPos(OSDListBtnTypeItem* item);
1441 + // Item Sets/Commands
1442 + void MoveDown(void);
1443 + void MoveUp(void);
1445 - bool IsVisible() { return m_visible; }
1446 - void SetVisible(bool vis) { m_visible = vis; }
1447 + // General Commands
1448 + void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
1449 + void Reinit(float,float) {}
1456 void InitItem(OSDTypeImage &osdImg, uint width, uint height,
1457 QColor beg, QColor end, int alpha);
1458 void LoadPixmap(OSDTypeImage& pix, const QString& fileName);
1459 @@ -179,24 +209,35 @@
1460 void InsertItem(OSDListBtnTypeItem *item);
1461 void RemoveItem(OSDListBtnTypeItem *item);
1465 - QRect m_contentsRect;
1466 - QRect m_arrowsRect;
1470 + QRect m_contentsRect;
1471 + QRect m_arrowsRect;
1479 - int m_itemSpacing;
1481 - uint m_itemsVisible;
1483 + int m_itemSpacing;
1485 + uint m_itemsVisible;
1488 - bool m_showScrollArrows;
1489 - bool m_showUpArrow;
1490 - bool m_showDnArrow;
1492 + bool m_showScrollArrows;
1493 + bool m_showUpArrow;
1494 + bool m_showDnArrow;
1495 + bool m_initialized;
1499 + QColor m_itemRegBeg;
1500 + QColor m_itemRegEnd;
1501 + QColor m_itemSelBeg;
1502 + QColor m_itemSelEnd;
1503 + uint m_itemRegAlpha;
1504 + uint m_itemSelAlpha;
1506 OSDTypeImage m_itemRegPix;
1507 OSDTypeImage m_itemSelActPix;
1508 OSDTypeImage m_itemSelInactPix;
1509 @@ -209,43 +250,30 @@
1510 OSDTypeImage m_checkHalfPix;
1511 OSDTypeImage m_checkFullPix;
1513 - QColor m_itemRegBeg;
1514 - QColor m_itemRegEnd;
1515 - QColor m_itemSelBeg;
1516 - QColor m_itemSelEnd;
1517 - uint m_itemRegAlpha;
1518 - uint m_itemSelAlpha;
1519 + TTFFont *m_fontActive;
1520 + TTFFont *m_fontInactive;
1522 - TTFFont* m_fontActive;
1523 - TTFFont* m_fontInactive;
1527 - bool m_initialized;
1529 + OSDListBtnItemList m_itemList;
1531 - OSDListBtnTypeItem* m_topItem;
1532 - OSDListBtnTypeItem* m_selItem;
1533 - QPtrList<OSDListBtnTypeItem> m_itemList;
1534 + mutable QMutex m_update;
1540 - friend class OSDListBtnTypeItem;
1544 void itemSelected(OSDListBtnTypeItem* item);
1547 class OSDListBtnTypeItem
1549 + friend class OSDListBtnType;
1563 OSDListBtnTypeItem(OSDListBtnType* lbtype, const QString& text,
1564 @@ -253,41 +281,36 @@
1565 bool showArrow = false, CheckState state = NotChecked);
1566 ~OSDListBtnTypeItem();
1568 - OSDListBtnType* parent() const;
1569 - QString text() const;
1570 - const OSDTypeImage* pixmap() const;
1571 - bool checkable() const;
1572 - CheckState state() const;
1573 + OSDListBtnType* parent(void) const { return m_parent; }
1574 + QString text(void) const { return m_text; }
1575 + const OSDTypeImage* pixmap(void) const { return m_pixmap; }
1576 + bool checkable(void) const { return m_checkable; }
1577 + CheckState state(void) const { return m_state; }
1578 + QString getGroup(void) const { return m_group; }
1579 + void *getData(void) { return m_data; }
1581 - void setChecked(CheckState state);
1582 - void setData(void *data);
1584 - void setGroup(QString group) { m_group = group; };
1585 - QString getGroup(void) { return m_group; }
1586 + void setData(void *data) { m_data = data; }
1587 + void setGroup(QString grp) { m_group = grp; }
1588 + void setChecked(CheckState state)
1589 + { m_state = (m_checkable) ? state : m_state; }
1591 - void Reinit(float wchange, float hchange, float wmult, float hmult);
1593 + void Reinit(float,float) {}
1594 void paint(OSDSurface *surface, TTFFont *font, int fade, int maxfade,
1599 OSDListBtnType *m_parent;
1601 - OSDTypeImage *m_pixmap;
1603 - CheckState m_state;
1607 - QRect m_checkRect;
1608 - QRect m_pixmapRect;
1610 - QRect m_arrowRect;
1614 - friend class OSDListBtnType;
1615 + OSDTypeImage *m_pixmap;
1619 + CheckState m_state;
1622 + QRect m_checkRect;
1623 + QRect m_arrowRect;
1624 + QRect m_pixmapRect;
1629 Index: mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
1630 ===================================================================
1631 --- mythtv/libs/libmythtv/NuppelVideoPlayer.cpp (.../tags/release-0-19) (revision 10931)
1632 +++ mythtv/libs/libmythtv/NuppelVideoPlayer.cpp (.../branches/release-0-19-fixes) (revision 10931)
1634 hascommbreaktable(false),
1635 deleteIter(deleteMap.end()), blankIter(blankMap.end()),
1636 commBreakIter(commBreakMap.end()),
1637 + forcePositionMapSync(false),
1638 // Playback (output) speed control
1640 next_play_speed(1.0f), next_normal_speed(true),
1642 SetDecoder(new IvtvDecoder(this, m_playbackinfo));
1643 no_audio_out = true; // no audio with ivtv.
1645 + audio_samplerate = 44100;
1646 + audio_channels = 2;
1648 else if (forceVideoOutput == kVideoOutput_IVTV)
1650 @@ -1113,7 +1116,7 @@
1651 const unsigned char *NuppelVideoPlayer::GetScaledFrame(QSize &size)
1653 QMutexLocker locker(&yuv_lock);
1654 - yuv_desired_size = size = QSize(size.width() & ~0x3, size.height() & ~0x3);
1655 + yuv_desired_size = size = QSize(size.width() & ~0x7, size.height() & ~0x7);
1657 if ((size.width() > 0) && (size.height() > 0))
1659 @@ -1626,8 +1629,8 @@
1661 // If we are using hardware decoding, so we've already done the
1662 // decoding; display the frame, but don't wait for A/V Sync.
1663 - videoOutput->PrepareFrame(buffer, ps);
1664 - videoOutput->Show(m_scan);
1665 + videoOutput->PrepareFrame(buffer, kScan_Intr2ndField);
1666 + videoOutput->Show(kScan_Intr2ndField);
1667 VERBOSE(VB_PLAYBACK, LOC + dbg + "skipping A/V wait.");
1670 @@ -1685,14 +1688,14 @@
1672 if (diverge > MAXDIVERGE)
1674 - // If audio is way ahead of video, adjust for it...
1675 + // If audio is way behind of video, adjust for it...
1676 // by cutting the frame rate in half for the length of this frame
1678 avsync_adjustment = frame_interval;
1680 VERBOSE(VB_PLAYBACK, LOC +
1681 - QString("Audio is %1 frames ahead of video,\n"
1682 - "\t\t\tdoubling video frame interval.").arg(diverge));
1683 + QString("Video is %1 frames ahead of audio,\n"
1684 + "\t\t\tdoubling video frame interval to slow down.").arg(diverge));
1687 if (audioOutput && normal_speed)
1688 @@ -1811,11 +1814,8 @@
1692 -void NuppelVideoPlayer::DisplayNormalFrame(void)
1693 +bool NuppelVideoPlayer::PrebufferEnoughFrames(void)
1695 - video_actually_paused = false;
1696 - resetvideo = false;
1698 prebuffering_lock.lock();
1701 @@ -1843,14 +1843,29 @@
1703 prebuffering_lock.unlock();
1709 prebuffering_lock.unlock();
1711 //VERBOSE(VB_PLAYBACK, LOC + "fs: " + videoOutput->GetFrameStatus());
1712 if (!videoOutput->EnoughPrebufferedFrames())
1714 - VERBOSE(VB_GENERAL, LOC + "prebuffering pause");
1717 + videoOutput->CheckFrameStates();
1718 + if (videoOutput->hasMCAcceleration() ||
1719 + videoOutput->hasIDCTAcceleration() ||
1720 + videoOutput->hasVLDAcceleration())
1722 + // Prebuffering fails w/XvMC's 8 surfaces..
1727 + VERBOSE(VB_GENERAL, LOC + "prebuffering pause" +
1728 + videoOutput->GetFrameStatus());
1730 SetPrebuffering(true);
1732 if (!m_playing_slower && audio_channels <= 2)
1733 @@ -1861,7 +1876,7 @@
1734 VERBOSE(VB_GENERAL, "playing slower due to falling behind...");
1742 @@ -1877,6 +1892,25 @@
1743 prebuffer_tries = 0;
1744 prebuffering_lock.unlock();
1749 +void NuppelVideoPlayer::DisplayNormalFrame(void)
1751 + video_actually_paused = false;
1752 + resetvideo = false;
1754 + if (!PrebufferEnoughFrames())
1756 + // When going to switch channels
1759 + usleep(frame_interval);
1760 + DisplayPauseFrame();
1765 videoOutput->StartDisplayingFrame();
1767 VideoFrame *frame = videoOutput->GetLastShownFrame();
1768 @@ -1920,7 +1954,7 @@
1772 - else if (osdHasSubtitles || nonDisplayedSubtitles.size() > 20)
1773 + else if (osdHasSubtitles)
1777 @@ -2176,7 +2210,10 @@
1782 discontinuity = true;
1786 livetvchain->SetProgram(pginfo);
1788 @@ -2199,6 +2236,7 @@
1792 + VERBOSE(VB_IMPORTANT, LOC_ERR + "SwitchToProgram failed.");
1796 @@ -2265,6 +2303,8 @@
1797 ringBuffer->Pause();
1798 ringBuffer->WaitForPause();
1802 livetvchain->SetProgram(pginfo);
1804 ringBuffer->Reset(true);
1805 @@ -2284,6 +2324,7 @@
1807 if (errored || !GetDecoder())
1809 + VERBOSE(VB_IMPORTANT, LOC_ERR + "JumpToProgram failed.");
1813 @@ -2471,6 +2512,12 @@
1817 + if (forcePositionMapSync)
1819 + forcePositionMapSync = false;
1820 + GetDecoder()->SyncPositionMap();
1823 if (IsErrored() || (nvr_enc && nvr_enc->GetErrorStatus()))
1825 VERBOSE(VB_IMPORTANT, LOC_ERR + "Unknown error, exiting decoder");
1826 @@ -3246,7 +3293,10 @@
1827 GetDecoder()->DoFastForward(desiredFrame);
1828 GetDecoder()->setExactSeeks(exactseeks);
1831 + // Note: The video output will be reset by what the the decoder
1832 + // does, so we only need to reset the audio, subtitles, etc.
1833 + ClearAfterSeek(false);
1835 lastSkipTime = time(NULL);
1838 @@ -3291,19 +3341,24 @@
1842 -/** \fn NuppelVideoPlayer::ClearAfterSeek(void)
1843 +/** \fn NuppelVideoPlayer::ClearAfterSeek(bool)
1844 * \brief This is to support seeking...
1846 * This resets the output classes and discards all
1847 * frames no longer being used by the decoder class.
1849 * Note: caller should not hold any locks
1851 + * \param clearvideobuffers This clears the videooutput buffers as well,
1852 + * this is only safe if no old frames are
1853 + * required to continue decoding.
1855 -void NuppelVideoPlayer::ClearAfterSeek(void)
1856 +void NuppelVideoPlayer::ClearAfterSeek(bool clearvideobuffers)
1858 - VERBOSE(VB_PLAYBACK, LOC + "ClearAfterSeek()");
1859 + VERBOSE(VB_PLAYBACK, LOC + "ClearAfterSeek("<<clearvideobuffers<<")");
1861 - videoOutput->ClearAfterSeek();
1862 + if (clearvideobuffers)
1863 + videoOutput->ClearAfterSeek();
1865 for (int i = 0; i < MAXTBUFFER; i++)
1866 txtbuffers[i].timecode = 0;
1867 @@ -4398,6 +4453,8 @@
1868 hascommbreaktable = !commBreakMap.isEmpty();
1870 commBreakMapLock.unlock();
1872 + forcePositionMapSync = true;
1875 bool NuppelVideoPlayer::RebuildSeekTable(bool showPercentage, StatusCallback cb, void* cbData)
1876 @@ -4541,7 +4598,8 @@
1877 return (int)((float)(written - played) / video_frame_rate);
1880 -void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo)
1881 +void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo,
1882 + bool paddedFields)
1885 posInfo.position = 0;
1886 @@ -4588,15 +4646,23 @@
1887 int ssecs = (playbackLen - shours * 3600 - smins * 60);
1889 QString text1, text2;
1893 - text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
1894 - text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
1895 + text1.sprintf("%02d:%02d:%02d", phours, pmins, psecs);
1896 + text2.sprintf("%02d:%02d:%02d", shours, smins, ssecs);
1900 - text1.sprintf("%d:%02d", pmins, psecs);
1901 - text2.sprintf("%d:%02d", smins, ssecs);
1904 + text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
1905 + text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
1909 + text1.sprintf("%d:%02d", pmins, psecs);
1910 + text2.sprintf("%d:%02d", smins, ssecs);
1914 posInfo.desc = QObject::tr("%1 of %2").arg(text1).arg(text2);
1915 @@ -4654,6 +4720,7 @@
1917 if (commBreakIter.key() == totalFrames)
1919 + VERBOSE(VB_IMPORTANT, LOC + "Skipping commercial to end of file");
1923 @@ -4721,7 +4788,7 @@
1925 QString message = "COMMFLAG_REQUEST ";
1926 message += m_playbackinfo->chanid + " " +
1927 - m_playbackinfo->startts.toString(Qt::ISODate);
1928 + m_playbackinfo->recstartts.toString(Qt::ISODate);
1929 RemoteSendMessage(message);
1932 @@ -5018,7 +5085,7 @@
1933 QImage scaledImage = qImage.smoothScale(rect->w, rect->h);
1935 OSDTypeImage* image = new OSDTypeImage();
1936 - image->SetPosition(QPoint(rect->x, rect->y));
1937 + image->SetPosition(QPoint(rect->x, rect->y), hmult, vmult);
1938 image->LoadFromQImage(scaledImage);
1940 subtitleOSD->AddType(image);
1941 Index: mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
1942 ===================================================================
1943 --- mythtv/libs/libmythtv/NuppelVideoRecorder.cpp (.../tags/release-0-19) (revision 10931)
1944 +++ mythtv/libs/libmythtv/NuppelVideoRecorder.cpp (.../branches/release-0-19-fixes) (revision 10931)
1945 @@ -216,7 +216,10 @@
1950 + QMutexLocker locker(&avcodeclock);
1951 avcodec_close(mpa_ctx);
1956 @@ -453,8 +456,11 @@
1961 + QMutexLocker locker(&avcodeclock);
1962 avcodec_close(mpa_ctx);
1969 @@ -626,13 +632,14 @@
1970 int frag, blocksize = 4096;
1975 #if !defined (HAVE_SYS_SOUNDCARD_H) && !defined(HAVE_SOUNDCARD_H)
1976 - VERBOSE(VB_IMPORTANT, QString("NVR::AudioInit() This Unix doesn't support"
1977 - " device files for audio access. Skipping"));
1979 + VERBOSE(VB_IMPORTANT,
1980 + QString("NVR::AudioInit() This Unix doesn't support"
1981 + " device files for audio access. Skipping"));
1986 if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK)))
1988 VERBOSE(VB_IMPORTANT, QString("NVR: Error, cannot open DSP '%1'").
1997 audio_bytes_per_sample = audio_channels * audio_bits / 8;
1999 Index: mythtv/libs/libmythtv/signalmonitor.cpp
2000 ===================================================================
2001 --- mythtv/libs/libmythtv/signalmonitor.cpp (.../tags/release-0-19) (revision 10931)
2002 +++ mythtv/libs/libmythtv/signalmonitor.cpp (.../branches/release-0-19-fixes) (revision 10931)
2004 uint wait_for_mask, const char *name)
2005 : QObject(NULL, name), channel(_channel),
2006 capturecardnum(_capturecardnum), flags(wait_for_mask),
2007 - update_rate(25), running(false),
2008 - exit(false), update_done(false),
2009 - notify_frontend(true),
2010 + update_rate(25), minimum_update_rate(5),
2011 + running(false), exit(false),
2012 + update_done(false), notify_frontend(true),
2013 signalLock (QObject::tr("Signal Lock"), "slock",
2015 signalStrength(QObject::tr("Signal Power"), "signal",
2016 Index: mythtv/libs/libmythtv/osdlistbtntype.cpp
2017 ===================================================================
2018 --- mythtv/libs/libmythtv/osdlistbtntype.cpp (.../tags/release-0-19) (revision 10931)
2019 +++ mythtv/libs/libmythtv/osdlistbtntype.cpp (.../branches/release-0-19-fixes) (revision 10931)
2020 @@ -19,206 +19,148 @@
2022 * ============================================================ */
2024 -#include <iostream>
2029 +#include <algorithm>
2030 +using namespace std;
2033 #include <qapplication.h>
2034 #include <qpixmap.h>
2035 #include <qpainter.h>
2040 #include "mythcontext.h"
2041 #include "mythdialogs.h"
2043 #include "osdlistbtntype.h"
2045 +#define LOC QString("OSDListTreeType: ")
2046 +#define LOC_ERR QString("OSDListTreeType, Error: ")
2048 -OSDGenericTree::OSDGenericTree(OSDGenericTree *parent, const QString &name,
2049 - const QString &action, int check,
2050 - OSDTypeImage *image, QString group)
2051 - : GenericTree(name)
2052 +static QRect unbias(QRect rect, float wmult, float hmult)
2054 - m_checkable = check;
2055 - m_action = action;
2057 - m_parentButton = NULL;
2064 - if (!action.isEmpty() && !action.isNull())
2065 - setSelectable(true);
2068 - parent->addNode(this);
2069 + return QRect((int)round(rect.x() / wmult),
2070 + (int)round(rect.y() / hmult),
2071 + (int)ceil( rect.width() / wmult),
2072 + (int)ceil( rect.height() / hmult));
2075 -////////////////////////////////////////////////////////////////////////////
2077 -OSDListTreeType::OSDListTreeType(const QString &name, const QRect &area,
2078 - const QRect &levelsize, int levelspacing,
2079 - float wmult, float hmult)
2081 +static QRect bias(QRect rect, float wmult, float hmult)
2086 - m_totalarea = area;
2087 - m_levelsize = levelsize;
2088 - m_levelspacing = levelspacing;
2090 - if (gContext->GetNumSetting("UseArrowAccels", 1))
2091 - m_arrowAccel = true;
2093 - m_arrowAccel = false;
2099 - currentpos = NULL;
2101 - currentlevel = NULL;
2103 - listLevels.setAutoDelete(true);
2106 - m_inactive = NULL;
2108 - SetItemRegColor(Qt::black,QColor(80,80,80),100);
2109 - SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
2113 + return QRect((int)round(rect.x() * wmult),
2114 + (int)round(rect.y() * hmult),
2115 + (int)ceil( rect.width() * wmult),
2116 + (int)ceil( rect.height() * hmult));
2119 -void OSDListTreeType::Reinit(float wchange, float hchange, float wmult,
2121 +OSDListTreeType::OSDListTreeType(
2122 + const QString &name, const QRect &area,
2123 + const QRect &levelsize, int levelspacing,
2124 + float wmult, float hmult)
2126 + treetop(NULL), currentpos(NULL),
2127 + m_active(NULL), m_inactive(NULL),
2128 + m_itemRegBeg(Qt::black), m_itemRegEnd(QColor(80,80,80)),
2129 + m_itemSelBeg(QColor(82,202,56)), m_itemSelEnd(QColor(52,152,56)),
2130 + m_itemRegAlpha(100), m_itemSelAlpha(255),
2131 + m_spacing(0), m_margin(0),
2132 + m_levelspacing(levelspacing),
2133 + m_totalarea(area), m_levelsize(levelsize),
2134 + m_unbiasedspacing(1.0f), m_unbiasedmargin(1.0f),
2135 + m_unbiasedarea(0,0,0,0), m_unbiasedsize(0,0,0,0),
2136 + m_wmult(wmult), m_hmult(hmult),
2137 + m_depth(0), m_levelnum(-1),
2139 + m_arrowAccel(gContext->GetNumSetting("UseArrowAccels", 1))
2144 - m_spacing = (int)(m_spacing * wchange);
2145 - m_margin = (int)(m_margin * wchange);
2147 - int width = (int)(m_totalarea.width() * wchange);
2148 - int height = (int)(m_totalarea.height() * hchange);
2149 - int x = (int)(m_totalarea.x() * wchange);
2150 - int y = (int)(m_totalarea.y() * hchange);
2152 - m_totalarea = QRect(x, y, width, height);
2154 - width = (int)(m_levelsize.width() * wchange);
2155 - height = (int)(m_levelsize.height() * hchange);
2156 - x = (int)(m_levelsize.x() * wchange);
2157 - y = (int)(m_levelsize.y() * hchange);
2159 - m_levelsize = QRect(x, y, width, height);
2161 - QPtrListIterator<OSDListBtnType> it(listLevels);
2162 - OSDListBtnType *child;
2164 - while ((child = it.current()) != 0)
2166 - child->Reinit(wchange, hchange, wmult, hmult);
2169 + m_wmult = (wmult == 0.0f) ? 1.0f : wmult;
2170 + m_hmult = (hmult == 0.0f) ? 1.0f : hmult;
2171 + m_unbiasedarea = unbias(area, wmult, hmult);
2172 + m_unbiasedsize = unbias(levelsize, wmult, hmult);
2175 -void OSDListTreeType::SetGroupCheckState(QString group, int newState)
2176 +OSDListTreeType::~OSDListTreeType()
2178 - QPtrListIterator<OSDListBtnType> it(listLevels);
2179 - OSDListBtnType *child;
2180 - while ((child = it.current()) != 0)
2182 - child->SetGroupCheckState(group, newState);
2185 + OSDListBtnList::iterator it = listLevels.begin();
2186 + for (; it != listLevels.end(); ++it)
2190 -void OSDListTreeType::SetItemRegColor(const QColor& beg, const QColor& end,
2192 +void OSDListTreeType::Reinit(float wmult, float hmult)
2194 - m_itemRegBeg = beg;
2195 - m_itemRegEnd = end;
2196 - m_itemRegAlpha = alpha;
2198 + m_wmult = (wmult == 0.0f) ? 1.0f : wmult;
2199 + m_hmult = (hmult == 0.0f) ? 1.0f : hmult;
2200 + m_spacing = (uint) round(m_unbiasedspacing * wmult);
2201 + m_margin = (uint) round(m_unbiasedmargin * wmult);
2202 + m_totalarea = bias(m_unbiasedarea, wmult, hmult);
2203 + m_levelsize = bias(m_unbiasedsize, wmult, hmult);
2205 -void OSDListTreeType::SetItemSelColor(const QColor& beg, const QColor& end,
2208 - m_itemSelBeg = beg;
2209 - m_itemSelEnd = end;
2210 - m_itemSelAlpha = alpha;
2212 + if (!treetop || m_levelnum < 0)
2215 -void OSDListTreeType::SetFontActive(TTFFont *font)
2219 + // Save item indices
2220 + vector<uint> list;
2221 + for (uint i = 0; i <= (uint)m_levelnum; i++)
2222 + list.push_back(listLevels[i]->GetItemCurrentPos());
2224 -void OSDListTreeType::SetFontInactive(TTFFont *font)
2226 - m_inactive = font;
2228 + // Delete old OSD items
2229 + OSDListBtnList clone = listLevels;
2230 + listLevels.clear();
2231 + OSDListBtnList::iterator it = clone.begin();
2232 + for (; it != clone.end(); ++it)
2235 -void OSDListTreeType::SetSpacing(int spacing)
2237 - m_spacing = spacing;
2238 + // Create new OSD items
2239 + SetAsTree(treetop, &list);
2242 -void OSDListTreeType::SetMargin(int margin)
2243 +void OSDListTreeType::SetGroupCheckState(QString group, int newState)
2245 - m_margin = margin;
2246 + OSDListBtnList::iterator it = listLevels.begin();
2247 + for (; it != listLevels.end(); ++it)
2248 + (*it)->SetGroupCheckState(group, newState);
2251 -void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel)
2252 +void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel,
2253 + vector<uint> *select_list)
2258 - currentlevel = NULL;
2260 - currentpos = NULL;
2264 + currentpos = NULL;
2269 - levels = toplevel->calculateDepth(0) - 1;
2272 + m_depth = toplevel->calculateDepth(0) - 1;
2275 - cerr << "Need at least one level\n";
2276 + VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need at least one level");
2280 - currentpos = (OSDGenericTree *)toplevel->getChildAt(0);
2282 + currentpos = (OSDGenericTree*) toplevel->getChildAt(0);
2285 - cerr << "No top-level children?\n";
2286 + VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need top-level children");
2290 - treetop = toplevel;
2292 - // just for now, remove later
2296 - for (int i = 0; i < levels; i++)
2297 + // Create OSD buttons for all levels
2298 + for (uint i = 0; i < (uint)m_depth; i++)
2300 QString levelname = QString("level%1").arg(i + 1);
2302 QRect curlevelarea = m_levelsize;
2303 curlevelarea.moveBy(m_totalarea.x(), m_totalarea.y());
2305 curlevelarea.moveBy((m_levelsize.width() + m_levelspacing) * i, 0);
2307 - OSDListBtnType *newlevel = new OSDListBtnType(levelname, curlevelarea,
2308 - m_wmult, m_hmult, true);
2309 + OSDListBtnType *newlevel = new OSDListBtnType(
2310 + levelname, curlevelarea, m_wmult, m_hmult, true);
2312 newlevel->SetFontActive(m_active);
2313 newlevel->SetFontInactive(m_inactive);
2314 @@ -227,229 +169,200 @@
2315 newlevel->SetSpacing(m_spacing);
2316 newlevel->SetMargin(m_margin);
2318 - listLevels.append(newlevel);
2319 + listLevels.push_back(newlevel);
2322 - currentlevel = GetLevel(0);
2323 + // Set up needed levels and selects
2324 + vector<uint> slist;
2325 + slist.push_back(0);
2327 + slist = *select_list;
2329 - if (!currentlevel)
2330 + currentpos = treetop = toplevel;
2331 + for (m_levelnum = 0; m_levelnum < (int)slist.size(); m_levelnum++)
2333 - cerr << "Something is seriously wrong (currentlevel = NULL)\n";
2335 + FillLevelFromTree(currentpos, m_levelnum);
2336 + GetLevel(m_levelnum)->SetActive(true);
2337 + GetLevel(m_levelnum)->SetVisible(true);
2338 + if (slist[m_levelnum])
2339 + GetLevel(m_levelnum)->SetItemCurrent(slist[m_levelnum]);
2340 + EnterItem(); // updates currentpos
2343 - FillLevelFromTree(toplevel, currentlevel);
2345 - currentlevel->SetVisible(true);
2346 - currentlevel->SetActive(true);
2348 - currentpos = (OSDGenericTree *)(currentlevel->GetItemFirst()->getData());
2351 - emit itemEntered(this, currentpos);
2355 -OSDGenericTree *OSDListTreeType::GetCurrentPosition(void)
2356 +static bool has_action(QString action, const QStringList &actions)
2358 - return currentpos;
2359 + QStringList::const_iterator it;
2360 + for (it = actions.begin(); it != actions.end(); ++it)
2362 + if (action == *it)
2368 bool OSDListTreeType::HandleKeypress(QKeyEvent *e)
2370 - if (!currentlevel)
2371 + QStringList actions;
2372 + bool ok = gContext->GetMainWindow()->TranslateKeyPress(
2373 + "TV Playback", e, actions);
2375 + if (!ok || ((uint)m_levelnum >= listLevels.size()))
2377 + else if (has_action("UP", actions))
2379 + GetLevel(m_levelnum)->MoveUp();
2382 + else if (has_action("DOWN", actions))
2384 + GetLevel(m_levelnum)->MoveDown();
2387 + else if (has_action("LEFT", actions) && (m_levelnum > 0))
2389 + GetLevel(m_levelnum)->Reset();
2390 + GetLevel(m_levelnum)->SetVisible(false);
2392 - bool handled = false;
2393 - QStringList actions;
2394 - if (gContext->GetMainWindow()->TranslateKeyPress("TV Playback", e,
2399 + else if ((has_action("LEFT", actions) && m_arrowAccel) ||
2400 + has_action("ESCAPE", actions) ||
2401 + has_action("CLEAROSD", actions) ||
2402 + has_action("MENU", actions))
2404 - for (unsigned int i = 0; i < actions.size() && !handled; i++)
2406 - QString action = actions[i];
2408 + m_visible = false;
2410 + else if (has_action("RIGHT", actions) &&
2411 + (m_levelnum + 1 < m_depth) &&
2412 + (currentpos->childCount() > 0))
2414 + GetLevel(m_levelnum)->SetActive(false);
2417 - if (action == "UP")
2419 - currentlevel->MoveUp();
2420 - SetCurrentPosition();
2422 - else if (action == "DOWN")
2424 - currentlevel->MoveDown();
2425 - SetCurrentPosition();
2427 - else if (action == "LEFT")
2431 - currentlevel->Reset();
2432 - currentlevel->SetVisible(false);
2436 - currentlevel = GetLevel(curlevel);
2437 - currentlevel->SetActive(true);
2438 - SetCurrentPosition();
2440 - else if (m_arrowAccel)
2442 - m_visible = false;
2445 - else if (action == "RIGHT")
2447 - // FIXME: create new levels if needed..
2448 - if (curlevel + 1 < levels && currentpos->childCount() > 0)
2450 - currentlevel->SetActive(false);
2454 - currentlevel = GetLevel(curlevel);
2456 - FillLevelFromTree(currentpos, currentlevel);
2458 - currentlevel->SetVisible(true);
2459 - currentlevel->SetActive(true);
2460 - SetCurrentPosition();
2462 - else if (m_arrowAccel)
2464 - SetGroupCheckState(currentpos->getGroup(),
2465 - OSDListBtnTypeItem::NotChecked);
2466 - currentpos->getParentButton()->setChecked(
2467 - OSDListBtnTypeItem::FullChecked);
2468 - emit itemSelected(this, currentpos);
2471 - else if (action == "ESCAPE" || action == "MENU" ||
2472 - action == "CLEAROSD")
2473 - m_visible = false;
2474 - else if (action == "SELECT")
2476 - SetGroupCheckState(currentpos->getGroup(),
2477 - OSDListBtnTypeItem::NotChecked);
2478 - currentpos->getParentButton()->setChecked(
2479 - OSDListBtnTypeItem::FullChecked);
2480 - emit itemSelected(this, currentpos);
2485 + FillLevelFromTree(currentpos, m_levelnum);
2486 + GetLevel(m_levelnum)->SetVisible(true);
2489 + else if ((has_action("RIGHT", actions) && m_arrowAccel) ||
2490 + has_action("SELECT", actions))
2503 void OSDListTreeType::Draw(OSDSurface *surface, int fade, int maxfade,
2506 - QPtrListIterator<OSDListBtnType> it(listLevels);
2507 - OSDListBtnType *child;
2509 - while ((child = it.current()) != 0)
2511 - child->Draw(surface, fade, maxfade, xoff, yoff);
2514 + OSDListBtnList::iterator it = listLevels.begin();
2515 + for (; it != listLevels.end(); ++it)
2516 + (*it)->Draw(surface, fade, maxfade, xoff, yoff);
2519 void OSDListTreeType::FillLevelFromTree(OSDGenericTree *item,
2520 - OSDListBtnType *list)
2523 + OSDListBtnType *list = GetLevel(level_num);
2526 - VERBOSE(VB_IMPORTANT, "OSDListTreeType::FillLevelFromTree() "
2527 - "called with no list. Ignoring call.");
2528 + VERBOSE(VB_IMPORTANT, LOC_ERR + "FillLevelFromTree() "
2529 + "called with no list, ignoring.");
2534 QPtrList<GenericTree> *itemlist = item->getAllChildren();
2536 QPtrListIterator<GenericTree> it(*itemlist);
2537 - GenericTree *child;
2539 - while ((child = it.current()) != 0)
2540 + OSDGenericTree *child = (OSDGenericTree*) it.current();
2541 + OSDListBtnTypeItem *newitem = NULL;
2542 + for (;(child = (OSDGenericTree*) it.current()); ++it)
2544 - OSDGenericTree *osdchild = (OSDGenericTree *)child;
2545 + OSDTypeImage *im = child->getImage();
2546 + QString label = child->getString();
2547 + QString group = child->getGroup();
2548 + bool canCheck = child->getCheckable() >= 0;
2549 + bool hasCheck = child->getCheckable() == 1;
2550 + bool hasChild = child->childCount() > 0;
2552 - OSDListBtnTypeItem *newitem;
2553 - newitem = new OSDListBtnTypeItem(list, child->getString(),
2554 - osdchild->getImage(),
2555 - (osdchild->getCheckable() >= 0),
2556 - (child->childCount() > 0));
2557 - if (osdchild->getCheckable() == 1)
2558 + newitem = new OSDListBtnTypeItem(list, label, im, canCheck, hasChild);
2561 newitem->setChecked(OSDListBtnTypeItem::FullChecked);
2562 - newitem->setGroup(osdchild->getGroup());
2563 - newitem->setData(osdchild);
2564 - osdchild->setParentButton(newitem);
2565 + newitem->setGroup(group);
2566 + newitem->setData(child);
2569 + child->setParentButton(newitem);
2573 -OSDListBtnType *OSDListTreeType::GetLevel(int levelnum)
2574 +OSDListBtnType *OSDListTreeType::GetLevel(uint levelnum)
2576 - if ((uint)levelnum > listLevels.count())
2578 - cerr << "OOB GetLevel call\n";
2581 + if (levelnum < listLevels.size())
2582 + return listLevels[levelnum];
2584 - return listLevels.at(levelnum);
2585 + VERBOSE(VB_IMPORTANT, LOC_ERR + "GetLevel("<<levelnum<<") "
2586 + "listLevels.size() is only "<<listLevels.size());
2590 -void OSDListTreeType::SetCurrentPosition(void)
2591 +void OSDListTreeType::EnterItem(void)
2593 - if (!currentlevel)
2594 + if ((uint)m_levelnum >= listLevels.size())
2597 - OSDListBtnTypeItem *lbt = currentlevel->GetItemCurrent();
2598 + listLevels[m_levelnum]->SetActive(true);
2599 + OSDListBtnTypeItem *lbt = listLevels[m_levelnum]->GetItemCurrent();
2602 + currentpos = (OSDGenericTree*) (lbt->getData());
2603 + emit itemEntered(this, currentpos);
2608 +void OSDListTreeType::SelectItem(void)
2613 - currentpos = (OSDGenericTree *)(lbt->getData());
2614 - emit itemEntered(this, currentpos);
2615 + SetGroupCheckState(currentpos->getGroup(), OSDListBtnTypeItem::NotChecked);
2616 + currentpos->getParentButton()->setChecked(OSDListBtnTypeItem::FullChecked);
2617 + emit itemSelected(this, currentpos);
2624 //////////////////////////////////////////////////////////////////////////
2626 OSDListBtnType::OSDListBtnType(const QString &name, const QRect &area,
2627 float wmult, float hmult,
2628 bool showScrollArrows)
2631 + m_order(0), m_rect(area),
2632 + m_contentsRect(0,0,0,0), m_arrowsRect(0,0,0,0),
2633 + m_wmult(wmult), m_hmult(hmult),
2634 + m_itemHeight(0), m_itemSpacing(0),
2635 + m_itemMargin(0), m_itemsVisible(0),
2636 + m_active(false), m_showScrollArrows(showScrollArrows),
2637 + m_showUpArrow(false), m_showDnArrow(false),
2638 + m_initialized(false), m_clearing(false),
2640 + m_itemRegBeg(Qt::black), m_itemRegEnd(QColor(80,80,80)),
2641 + m_itemSelBeg(QColor(82,202,56)), m_itemSelEnd(QColor(52,152,56)),
2642 + m_itemRegAlpha(100), m_itemSelAlpha(255),
2643 + m_fontActive(NULL), m_fontInactive(NULL),
2644 + m_topIndx(0), m_selIndx(0),
2652 - m_showScrollArrows = showScrollArrows;
2655 - m_showUpArrow = false;
2656 - m_showDnArrow = false;
2658 - m_itemList.setAutoDelete(false);
2662 - m_initialized = false;
2663 - m_clearing = false;
2664 - m_itemSpacing = 0;
2667 - m_itemsVisible = 0;
2669 - m_fontInactive = 0;
2671 - SetItemRegColor(Qt::black,QColor(80,80,80),100);
2672 - SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
2674 - m_visible = false;
2677 OSDListBtnType::~OSDListBtnType()
2678 @@ -457,316 +370,198 @@
2682 -void OSDListBtnType::Reinit(float wchange, float hchange, float wmult,
2688 - m_itemHeight = (int)(m_itemHeight * hchange);
2689 - m_itemSpacing = (int)(m_itemSpacing * wchange);
2690 - m_itemMargin = (int)(m_itemMargin * wchange);
2692 - int width = (int)(m_rect.width() * wchange);
2693 - int height = (int)(m_rect.height() * hchange);
2694 - int x = (int)(m_rect.x() * wchange);
2695 - int y = (int)(m_rect.y() * hchange);
2697 - m_rect = QRect(x, y, width, height);
2701 - OSDListBtnTypeItem* item = 0;
2702 - for (item = m_itemList.first(); item; item = m_itemList.next()) {
2703 - item->Reinit(wchange, hchange, wmult, hmult);
2708 void OSDListBtnType::SetGroupCheckState(QString group, int newState)
2710 - OSDListBtnTypeItem* item = 0;
2711 - for (item = m_itemList.first(); item; item = m_itemList.next()) {
2712 - if (item->getGroup() == group)
2713 - item->setChecked((OSDListBtnTypeItem::CheckState)newState);
2715 + OSDListBtnItemList::iterator it;
2716 + for (it = m_itemList.begin(); it != m_itemList.end(); ++it)
2717 + if ((*it)->getGroup() == group)
2718 + (*it)->setChecked((OSDListBtnTypeItem::CheckState) newState);
2721 -void OSDListBtnType::SetItemRegColor(const QColor& beg, const QColor& end,
2723 +void OSDListBtnType::Reset(void)
2725 - m_itemRegBeg = beg;
2726 - m_itemRegEnd = end;
2727 - m_itemRegAlpha = alpha;
2730 -void OSDListBtnType::SetItemSelColor(const QColor& beg, const QColor& end,
2733 - m_itemSelBeg = beg;
2734 - m_itemSelEnd = end;
2735 - m_itemSelAlpha = alpha;
2738 -void OSDListBtnType::SetFontActive(TTFFont *font)
2740 - m_fontActive = font;
2743 -void OSDListBtnType::SetFontInactive(TTFFont *font)
2745 - m_fontInactive = font;
2748 -void OSDListBtnType::SetSpacing(int spacing)
2750 - m_itemSpacing = spacing;
2753 -void OSDListBtnType::SetMargin(int margin)
2755 - m_itemMargin = margin;
2758 -void OSDListBtnType::SetActive(bool active)
2760 - m_active = active;
2763 -void OSDListBtnType::Reset()
2765 QMutexLocker lock(&m_update);
2769 - OSDListBtnTypeItem* item = 0;
2770 - for (item = m_itemList.first(); item; item = m_itemList.next()) {
2774 - m_clearing = false;
2775 + OSDListBtnItemList::iterator it;
2776 + OSDListBtnItemList clone = m_itemList;
2781 + for (it = clone.begin(); it != clone.end(); ++it)
2783 + m_clearing = false;
2787 m_showUpArrow = false;
2788 m_showDnArrow = false;
2791 void OSDListBtnType::InsertItem(OSDListBtnTypeItem *item)
2793 - OSDListBtnTypeItem* lastItem = m_itemList.last();
2794 - m_itemList.append(item);
2796 - if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2797 - m_showDnArrow = true;
2799 - m_showDnArrow = false;
2805 + QMutexLocker lock(&m_update);
2806 + m_itemList.push_back(item);
2807 + m_showDnArrow = m_showScrollArrows && m_itemList.size() > m_itemsVisible;
2808 + if (m_itemList.size() == 1)
2809 emit itemSelected(item);
2813 +int find(const OSDListBtnItemList &list, const OSDListBtnTypeItem *item)
2815 + for (uint i = 0; i < list.size(); i++)
2816 + if (list[i] == item)
2821 void OSDListBtnType::RemoveItem(OSDListBtnTypeItem *item)
2823 + QMutexLocker lock(&m_update);
2827 - if (m_itemList.find(item) == -1)
2829 + int i = find(m_itemList, item);
2833 - m_topItem = m_itemList.first();
2834 - m_selItem = m_itemList.first();
2835 + m_itemList.erase(m_itemList.begin()+i);
2837 - m_itemList.remove(item);
2839 m_showUpArrow = false;
2841 - if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2842 - m_showDnArrow = true;
2844 - m_showDnArrow = false;
2845 + m_showDnArrow = m_itemList.size() > m_itemsVisible;
2850 - emit itemSelected(m_selItem);
2852 + if (m_itemList.size())
2853 + emit itemSelected(m_itemList[m_selIndx]);
2856 -void OSDListBtnType::SetItemCurrent(OSDListBtnTypeItem* item)
2857 +void OSDListBtnType::SetItemCurrent(const OSDListBtnTypeItem* item)
2859 - bool locked = m_update.tryLock();
2860 + QMutexLocker lock(&m_update);
2861 + int i = find(m_itemList, item);
2863 + SetItemCurrent(i);
2866 - if (m_itemList.find(item) == -1)
2867 +void OSDListBtnType::SetItemCurrent(uint current)
2869 + QMutexLocker lock(&m_update);
2870 + if (current >= m_itemList.size())
2876 - if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2877 - m_showDnArrow = true;
2879 - m_showDnArrow = false;
2881 - emit itemSelected(m_selItem);
2884 - m_update.unlock();
2885 + m_selIndx = current;
2886 + m_topIndx = max(m_selIndx - (int)m_itemsVisible, 0);
2887 + m_showUpArrow = m_topIndx;
2888 + m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
2889 + emit itemSelected(m_itemList[m_selIndx]);
2892 -void OSDListBtnType::SetItemCurrent(int current)
2893 +int OSDListBtnType::GetItemCurrentPos(void) const
2895 QMutexLocker lock(&m_update);
2897 - OSDListBtnTypeItem* item = m_itemList.at(current);
2899 - item = m_itemList.first();
2901 - SetItemCurrent(item);
2902 + return (m_itemList.size()) ? m_selIndx : -1;
2905 -OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent()
2906 +OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent(void)
2909 + QMutexLocker lock(&m_update);
2910 + if (!m_itemList.size())
2912 + return m_itemList[m_selIndx];
2915 -OSDListBtnTypeItem* OSDListBtnType::GetItemFirst()
2916 +OSDListBtnTypeItem* OSDListBtnType::GetItemFirst(void)
2918 - return m_itemList.first();
2919 + QMutexLocker lock(&m_update);
2920 + if (!m_itemList.size())
2922 + return m_itemList[0];
2925 -OSDListBtnTypeItem* OSDListBtnType::GetItemNext(OSDListBtnTypeItem *item)
2926 +OSDListBtnTypeItem* OSDListBtnType::GetItemNext(const OSDListBtnTypeItem *item)
2928 QMutexLocker lock(&m_update);
2930 - if (m_itemList.find(item) == -1)
2933 - return m_itemList.next();
2934 + int i = find(m_itemList, item) + 1;
2935 + if (i <= 0 || i >= (int)m_itemList.size())
2937 + return m_itemList[i];
2940 -int OSDListBtnType::GetCount()
2941 +int OSDListBtnType::GetCount(void) const
2943 - return m_itemList.count();
2944 + QMutexLocker lock(&m_update);
2945 + return m_itemList.size();
2948 OSDListBtnTypeItem* OSDListBtnType::GetItemAt(int pos)
2950 - return m_itemList.at(pos);
2951 + QMutexLocker lock(&m_update);
2952 + return m_itemList[pos];
2955 -int OSDListBtnType::GetItemPos(OSDListBtnTypeItem* item)
2956 +int OSDListBtnType::GetItemPos(const OSDListBtnTypeItem *item) const
2958 QMutexLocker lock(&m_update);
2960 - return m_itemList.find(item);
2961 + return find(m_itemList, item);
2964 -void OSDListBtnType::MoveUp()
2965 +void OSDListBtnType::MoveUp(void)
2967 QMutexLocker lock(&m_update);
2969 - if (m_itemList.find(m_selItem) == -1)
2970 + if (!m_itemList.size())
2973 - OSDListBtnTypeItem *item = m_itemList.prev();
2975 + if (--m_selIndx < 0)
2977 - item = m_itemList.last();
2981 - if (m_itemList.count() > m_itemsVisible)
2982 - m_topItem = m_itemList.at(m_itemList.count() - m_itemsVisible);
2984 - m_topItem = m_itemList.first();
2985 + m_selIndx = m_itemList.size() - 1;
2986 + m_topIndx = (m_itemList.size() > m_itemsVisible) ?
2987 + m_itemList.size() - m_itemsVisible : 0;
2991 + m_topIndx = (m_selIndx < m_topIndx) ? m_selIndx : m_topIndx;
2992 + m_showUpArrow = m_topIndx;
2993 + m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
2995 - if (m_itemList.find(m_selItem) < m_itemList.find(m_topItem))
2996 - m_topItem = m_selItem;
2998 - if (m_topItem != m_itemList.first())
2999 - m_showUpArrow = true;
3001 - m_showUpArrow = false;
3003 - if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
3004 - m_showDnArrow = true;
3006 - m_showDnArrow = false;
3008 - emit itemSelected(m_selItem);
3009 + emit itemSelected(m_itemList[m_selIndx]);
3012 -void OSDListBtnType::MoveDown()
3013 +void OSDListBtnType::MoveDown(void)
3015 QMutexLocker lock(&m_update);
3017 - if (m_itemList.find(m_selItem) == -1)
3018 + if (!m_itemList.size())
3021 - OSDListBtnTypeItem *item = m_itemList.next();
3024 - item = m_itemList.first();
3027 + if (++m_selIndx >= (int)m_itemList.size())
3028 + m_selIndx = m_topIndx = 0;
3035 - if (m_itemList.find(m_topItem) + m_itemsVisible <=
3036 - (unsigned int)m_itemList.find(m_selItem))
3038 - m_topItem = m_itemList.at(m_itemList.find(m_topItem) + 1);
3040 + bool scroll_down = m_topIndx + (int)m_itemsVisible <= m_selIndx;
3041 + m_topIndx = (scroll_down) ? m_topIndx + 1 : m_topIndx;
3043 + m_showUpArrow = m_topIndx;
3044 + m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
3046 - if (m_topItem != m_itemList.first())
3047 - m_showUpArrow = true;
3049 - m_showUpArrow = false;
3051 - if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
3052 - m_showDnArrow = true;
3054 - m_showDnArrow = false;
3056 - emit itemSelected(m_selItem);
3057 + emit itemSelected(m_itemList[m_selIndx]);
3060 -void OSDListBtnType::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
3062 +void OSDListBtnType::Draw(OSDSurface *surface,
3063 + int fade, int maxfade,
3064 + int xoff, int yoff)
3069 + QMutexLocker lock(&m_update);
3073 - QMutexLocker lock(&m_update);
3078 TTFFont *font = m_active ? m_fontActive : m_fontInactive;
3081 - m_itemList.find(m_topItem);
3082 - OSDListBtnTypeItem *it = m_itemList.current();
3083 - while (it && (y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight))
3084 + for (uint i = m_topIndx; i < m_itemList.size(); i++)
3086 - it->paint(surface, font, fade, maxfade, m_rect.x()+ xoff, y + yoff);
3088 + if (!((y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight)))
3090 + m_itemList[i]->paint(surface, font, fade, maxfade,
3091 + m_rect.x() + xoff, y + yoff);
3092 y += m_itemHeight + m_itemSpacing;
3094 - it = m_itemList.next();
3097 if (m_showScrollArrows)
3098 @@ -792,14 +587,13 @@
3102 -void OSDListBtnType::Init()
3103 +void OSDListBtnType::Init(void)
3105 int sz1 = m_fontActive->Size() * 3 / 2;
3106 int sz2 = m_fontInactive->Size() * 3 / 2;
3107 - m_itemHeight = QMAX(sz1, sz2) + (int)(2 * m_itemMargin);
3108 + m_itemHeight = max(sz1, sz2) + (int)(2 * m_itemMargin);
3109 + m_itemHeight = m_itemHeight & ~0x1;
3111 - m_itemHeight = (m_itemHeight / 2) * 2;
3113 if (m_showScrollArrows)
3115 LoadPixmap(m_upArrowRegPix, "uparrow-reg");
3116 @@ -838,11 +632,7 @@
3117 InitItem(m_itemSelActPix, itemWidth, m_itemHeight,
3118 m_itemSelBeg, m_itemSelEnd, 255);
3120 - if (m_itemList.count() > m_itemsVisible && m_showScrollArrows)
3121 - m_showDnArrow = true;
3123 - m_showDnArrow = false;
3125 + m_showDnArrow = m_itemList.size() > m_itemsVisible && m_showScrollArrows;
3126 m_initialized = true;
3129 @@ -885,68 +675,57 @@
3131 void OSDListBtnType::LoadPixmap(OSDTypeImage& pix, const QString& fileName)
3133 - QString file = gContext->GetThemesParentDir() + "default/lb-" + fileName + ".png";
3134 - pix.LoadImage(file, m_wmult, m_hmult);
3135 + QString path = gContext->GetThemesParentDir() + "default/lb-";
3136 + pix.LoadImage(path + fileName + ".png", m_wmult, m_hmult);
3139 /////////////////////////////////////////////////////////////////////////////
3140 -OSDListBtnTypeItem::OSDListBtnTypeItem(OSDListBtnType* lbtype,
3141 - const QString& text,
3142 - OSDTypeImage *pixmap, bool checkable,
3143 - bool showArrow, CheckState state)
3144 +OSDListBtnTypeItem::OSDListBtnTypeItem(
3145 + OSDListBtnType *lbtype, const QString &text,
3146 + OSDTypeImage *pixmap, bool checkable,
3147 + bool showArrow, CheckState state)
3148 + : m_parent(lbtype), m_pixmap(pixmap),
3149 + m_data(NULL), m_text(text),
3150 + m_group(QString::null), m_state(state),
3151 + m_showArrow(showArrow), m_checkable(checkable),
3152 + m_checkRect(0,0,0,0), m_arrowRect(0,0,0,0),
3153 + m_pixmapRect(0,0,0,0), m_textRect(0,0,0,0)
3155 - m_parent = lbtype;
3157 - m_pixmap = pixmap;
3158 - m_checkable = checkable;
3160 - m_showArrow = showArrow;
3163 if (!m_parent->m_initialized)
3166 - int margin = m_parent->m_itemMargin;
3167 - int width = m_parent->m_rect.width();
3168 - int height = m_parent->m_itemHeight;
3169 + OSDTypeImage &checkPix = m_parent->m_checkNonePix;
3170 + OSDTypeImage &arrowPix = m_parent->m_arrowPix;
3172 - OSDTypeImage& checkPix = m_parent->m_checkNonePix;
3173 - OSDTypeImage& arrowPix = m_parent->m_arrowPix;
3175 - int cw = checkPix.ImageSize().width();
3176 - int ch = checkPix.ImageSize().height();
3177 - int aw = arrowPix.ImageSize().width();
3178 - int ah = arrowPix.ImageSize().height();
3179 - int pw = m_pixmap ? m_pixmap->ImageSize().width() : 0;
3180 - int ph = m_pixmap ? m_pixmap->ImageSize().height() : 0;
3182 + int margin = m_parent->m_itemMargin;
3183 + int width = m_parent->m_rect.width();
3184 + int height = m_parent->m_itemHeight;
3185 + int cw = checkPix.ImageSize().width();
3186 + int ch = checkPix.ImageSize().height();
3187 + int aw = arrowPix.ImageSize().width();
3188 + int ah = arrowPix.ImageSize().height();
3189 + int pw = m_pixmap ? m_pixmap->ImageSize().width() : 0;
3190 + int ph = m_pixmap ? m_pixmap->ImageSize().height() : 0;
3193 - m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
3195 - m_checkRect = QRect(0,0,0,0);
3196 + m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
3199 - m_arrowRect = QRect(width - aw - margin, (height - ah)/2,
3202 - m_arrowRect = QRect(0,0,0,0);
3203 + m_arrowRect = QRect(width - aw - margin, (height - ah)/2, aw, ah);
3206 - m_pixmapRect = QRect(m_checkable ? (2*margin + m_checkRect.width()) :
3207 - margin, (height - ph)/2,
3210 - m_pixmapRect = QRect(0,0,0,0);
3213 + int tmp = (m_checkable) ? (2 * margin + m_checkRect.width()) : margin;
3214 + m_pixmapRect = QRect(tmp, (height - ph)/2, pw, ph);
3217 - m_textRect = QRect(margin +
3218 - (m_checkable ? m_checkRect.width() + margin : 0) +
3219 - (m_pixmap ? m_pixmapRect.width() + margin : 0),
3221 - width - 2*margin -
3222 - (m_checkable ? m_checkRect.width() + margin : 0) -
3223 - (m_showArrow ? m_arrowRect.width() + margin : 0) -
3224 - (m_pixmap ? m_pixmapRect.width() + margin : 0),
3226 + int tx = margin, tw = width - (2 * margin);
3227 + tx += (m_checkable) ? m_checkRect.width() + margin : 0;
3228 + tx += (m_pixmap) ? m_pixmapRect.width() + margin : 0;
3229 + tw -= (m_checkable) ? m_checkRect.width() + margin : 0;
3230 + tw -= (m_showArrow) ? m_arrowRect.width() + margin : 0;
3231 + tw -= (m_pixmap) ? m_pixmapRect.width() + margin : 0;
3232 + m_textRect = QRect(tx, 0, tw, height);
3234 m_parent->InsertItem(this);
3236 @@ -957,52 +736,10 @@
3237 m_parent->RemoveItem(this);
3240 -QString OSDListBtnTypeItem::text() const
3245 -const OSDTypeImage* OSDListBtnTypeItem::pixmap() const
3250 -bool OSDListBtnTypeItem::checkable() const
3252 - return m_checkable;
3255 -OSDListBtnTypeItem::CheckState OSDListBtnTypeItem::state() const
3260 -OSDListBtnType* OSDListBtnTypeItem::parent() const
3265 -void OSDListBtnTypeItem::setChecked(CheckState state)
3272 -void OSDListBtnTypeItem::setData(void *data)
3277 -void* OSDListBtnTypeItem::getData()
3282 void OSDListBtnTypeItem::paint(OSDSurface *surface, TTFFont *font,
3283 int fade, int maxfade, int x, int y)
3285 - if (this == m_parent->m_selItem)
3286 + if (this == m_parent->GetItemCurrent())
3288 if (m_parent->m_active)
3289 m_parent->m_itemSelActPix.Draw(surface, fade, maxfade, x, y);
3290 @@ -1030,11 +767,14 @@
3293 if (m_state == HalfChecked)
3294 - m_parent->m_checkHalfPix.Draw(surface, fade, maxfade, cr.x(), cr.y());
3295 + m_parent->m_checkHalfPix.Draw(surface, fade, maxfade,
3297 else if (m_state == FullChecked)
3298 - m_parent->m_checkFullPix.Draw(surface, fade, maxfade, cr.x(), cr.y());
3299 + m_parent->m_checkFullPix.Draw(surface, fade, maxfade,
3302 - m_parent->m_checkNonePix.Draw(surface, fade, maxfade, cr.x(), cr.y());
3303 + m_parent->m_checkNonePix.Draw(surface, fade, maxfade,
3308 @@ -1049,39 +789,3 @@
3309 tr.moveBy(0, font->Size() / 4);
3310 font->DrawString(surface, tr.x(), tr.y(), m_text, tr.right(), tr.bottom());
3313 -void OSDListBtnTypeItem::Reinit(float wchange, float hchange,
3314 - float wmult, float hmult)
3319 - int width = (int)(m_checkRect.width() * wchange);
3320 - int height = (int)(m_checkRect.height() * hchange);
3321 - int x = (int)(m_checkRect.x() * wchange);
3322 - int y = (int)(m_checkRect.y() * hchange);
3324 - m_checkRect = QRect(x, y, width, height);
3326 - width = (int)(m_pixmapRect.width() * wchange);
3327 - height = (int)(m_pixmapRect.height() * hchange);
3328 - x = (int)(m_pixmapRect.x() * wchange);
3329 - y = (int)(m_pixmapRect.y() * hchange);
3331 - m_pixmapRect = QRect(x, y, width, height);
3333 - width = (int)(m_textRect.width() * wchange);
3334 - height = (int)(m_textRect.height() * hchange);
3335 - x = (int)(m_textRect.x() * wchange);
3336 - y = (int)(m_textRect.y() * hchange);
3338 - m_textRect = QRect(x, y, width, height);
3340 - width = (int)(m_arrowRect.width() * wchange);
3341 - height = (int)(m_arrowRect.height() * hchange);
3342 - x = (int)(m_arrowRect.x() * wchange);
3343 - y = (int)(m_arrowRect.y() * hchange);
3345 - m_arrowRect = QRect(x, y, width, height);
3348 Index: mythtv/libs/libmythtv/RingBuffer.cpp
3349 ===================================================================
3350 --- mythtv/libs/libmythtv/RingBuffer.cpp (.../tags/release-0-19) (revision 10931)
3351 +++ mythtv/libs/libmythtv/RingBuffer.cpp (.../branches/release-0-19-fixes) (revision 10931)
3352 @@ -145,6 +145,12 @@
3353 VERBOSE(VB_PLAYBACK, LOC + QString("OpenFile(%1, %1)")
3354 .arg(lfilename).arg(retryCount));
3356 + if ((filename.right(4).lower() == ".png") ||
3357 + (filename.right(4).lower() == ".gif"))
3362 uint openAttempts = retryCount + 1;
3364 filename = lfilename;
3367 bool is_local = false;
3368 bool is_dvd = false;
3370 if ((filename.left(7) == "myth://") &&
3371 (filename.length() > 7 ))
3373 @@ -271,6 +278,11 @@
3378 + setswitchtonext = false;
3380 + commserror = false;
3384 /** \fn RingBuffer::IsOpen(void) const
3388 pthread_rwlock_rdlock(&rwlock);
3389 - if (totfree > readblocksize && !commserror)
3390 + if (totfree > readblocksize && !commserror && !ateof && !setswitchtonext)
3392 // limit the read size
3393 totfree = readblocksize;
3398 + if (livetvchain && livetvchain->HasNext())
3399 + remotefile->SetTimeout(true);
3401 ret = safe_read(remotefile, readAheadBuffer + rbwpos,
3403 internalreadpos += ret;
3404 @@ -785,8 +800,16 @@
3408 - if (!readsallowed && used >= fill_min)
3409 + if (!readsallowed && (used >= fill_min || setswitchtonext))
3411 readsallowed = true;
3412 + VERBOSE(VB_PLAYBACK, QString("reads allowed (%1 %2)").arg(used)
3415 + else if (!readsallowed)
3416 + VERBOSE(VB_PLAYBACK, QString("buffering (%1 %2 %3)").arg(used)
3420 if (readsallowed && used < fill_min && !ateof && !setswitchtonext)
3422 @@ -808,8 +831,11 @@
3424 pthread_rwlock_unlock(&rwlock);
3426 - if ((used >= fill_threshold || wantseek) && !pausereadthread)
3427 + if ((used >= fill_threshold || wantseek || ateof || setswitchtonext) &&
3434 delete [] readAheadBuffer;
3435 @@ -853,15 +879,15 @@
3436 VERBOSE(VB_IMPORTANT,
3437 LOC + "Taking too long to be allowed to read..");
3441 // HACK Sometimes the readhead thread gets borked on startup.
3442 - /* if ((readErr % 2) && (rbrpos ==0))
3443 + if ((readErr > 2 && readErr % 2) && (rbrpos ==0))
3445 VERBOSE(VB_IMPORTANT, "restarting readhead thread..");
3446 KillReadAheadThread();
3447 StartupReadAheadThread();
3453 VERBOSE(VB_IMPORTANT, LOC_ERR + "Took more than "
3454 @@ -895,6 +921,12 @@
3455 VERBOSE(VB_IMPORTANT, LOC + "Waited " +
3456 QString("%1").arg(elapsed/1000) +
3457 " seconds for data to become available...");
3460 + VERBOSE(VB_IMPORTANT, "Checking to see if there's a "
3461 + "new livetv program to switch to..");
3462 + livetvchain->ReloadAll();
3466 bool quit = livetvchain && (livetvchain->NeedsToSwitch() ||
3468 availWaitMutex.unlock();
3470 avail = ReadBufAvail();
3471 - if (ateof && avail < count)
3472 + if ((ateof || setswitchtonext) && avail < count)
3476 Index: mythtv/libs/libmythtv/hdtvrecorder.cpp
3477 ===================================================================
3478 --- mythtv/libs/libmythtv/hdtvrecorder.cpp (.../tags/release-0-19) (revision 10931)
3479 +++ mythtv/libs/libmythtv/hdtvrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931)
3483 remainder = ProcessData(_buffer, len);
3484 - if (remainder > 0) // leftover bytes
3485 - memmove(_buffer, &(_buffer[_buffer_size - remainder]),
3487 + if (remainder > 0 && (len > remainder)) // leftover bytes
3488 + memmove(_buffer, &(_buffer[len - remainder]), remainder);
3492 Index: mythtv/libs/libmythtv/dummydtvrecorder.cpp
3493 ===================================================================
3494 --- mythtv/libs/libmythtv/dummydtvrecorder.cpp (.../tags/release-0-19) (revision 10931)
3495 +++ mythtv/libs/libmythtv/dummydtvrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931)
3498 while (_request_recording || _frames_seen_count <= 5)
3500 - len = read(_stream_fd, &(_buffer[remainder]), _buffer_size - remainder);
3501 + len = read(_stream_fd, &(_buffer[remainder]),
3502 + _buffer_size - remainder);
3509 remainder = ProcessData(_buffer, len);
3510 - if (remainder > 0) // leftover bytes
3511 - memmove(_buffer, &(_buffer[_buffer_size - remainder]),
3513 + if (remainder > 0 && (len > remainder)) // leftover bytes
3514 + memmove(_buffer, &(_buffer[len - remainder]), remainder);
3518 Index: mythtv/libs/libmythtv/avformatdecoder.cpp
3519 ===================================================================
3520 --- mythtv/libs/libmythtv/avformatdecoder.cpp (.../tags/release-0-19) (revision 10931)
3521 +++ mythtv/libs/libmythtv/avformatdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
3522 @@ -725,7 +725,12 @@
3526 + /* av_find_stream_info() eventually makes calls to avcodec_open() and avcodec_close()
3527 + so we have to use the avcodeclock */
3528 + avcodeclock.lock();
3529 int ret = av_find_stream_info(ic);
3530 + avcodeclock.unlock();
3534 VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not find codec parameters. " +
3535 Index: mythtv/libs/libmythtv/osdtypes.cpp
3536 ===================================================================
3537 --- mythtv/libs/libmythtv/osdtypes.cpp (.../tags/release-0-19) (revision 10931)
3538 +++ mythtv/libs/libmythtv/osdtypes.cpp (.../branches/release-0-19-fixes) (revision 10931)
3541 #include "mythcontext.h"
3543 +/// Shared OSD image cache
3544 +OSDImageCache OSDTypeImage::c_cache;
3546 OSDSet::OSDSet(const QString &name, bool cache, int screenwidth,
3547 int screenheight, float wmult, float hmult, int frint)
3550 int displaywidth, int displayheight,
3551 float wmult, float hmult, int frint)
3553 - float wchange = wmult / m_wmult;
3554 - float hchange = hmult / m_hmult;
3558 m_screenwidth = screenwidth;
3559 @@ -175,57 +175,12 @@
3560 vector<OSDType *>::iterator iter = allTypes->begin();
3561 for (;iter != allTypes->end(); iter++)
3563 - OSDType *type = (*iter);
3564 - if (OSDTypeText *item = dynamic_cast<OSDTypeText*>(type))
3566 - item->Reinit(wchange, hchange);
3568 - else if (OSDTypePositionImage *item =
3569 - dynamic_cast<OSDTypePositionImage*>(type))
3571 - item->Reinit(wchange, hchange, wmult, hmult);
3573 - else if (OSDTypePosSlider *item = dynamic_cast<OSDTypePosSlider*>(type))
3575 - item->Reinit(wchange, hchange, wmult, hmult);
3577 - else if (OSDTypeFillSlider *item =
3578 - dynamic_cast<OSDTypeFillSlider*>(type))
3580 - item->Reinit(wchange, hchange, wmult, hmult);
3582 - else if (OSDTypeEditSlider *item =
3583 - dynamic_cast<OSDTypeEditSlider*>(type))
3585 - item->Reinit(wchange, hchange, wmult, hmult);
3587 - else if (OSDTypeImage *item = dynamic_cast<OSDTypeImage*>(type))
3589 - item->Reinit(wchange, hchange, wmult, hmult);
3591 - else if (OSDTypeBox *item = dynamic_cast<OSDTypeBox*>(type))
3593 - item->Reinit(wchange, hchange);
3595 - else if (OSDTypePositionRectangle *item =
3596 - dynamic_cast<OSDTypePositionRectangle*>(type))
3598 - item->Reinit(wchange, hchange);
3600 - else if (OSDTypeCC *item = dynamic_cast<OSDTypeCC*>(type))
3602 - item->Reinit(xoff, yoff, displaywidth, displayheight);
3604 - else if (OSDListTreeType *item = dynamic_cast<OSDListTreeType*>(type))
3606 - item->Reinit(wchange, hchange, wmult, hmult);
3608 + if (OSDTypeCC *cc608 = dynamic_cast<OSDTypeCC*>(*iter))
3609 + cc608->Reinit(xoff, yoff, displaywidth, displayheight,
3613 - cerr << "Unknown conversion\n";
3615 + (*iter)->Reinit(wmult, hmult);
3620 OSDType *OSDSet::GetType(const QString &name)
3622 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3624 OSDTypeText::OSDTypeText(const QString &name, TTFFont *font,
3625 - const QString &text, QRect displayrect)
3626 + const QString &text, QRect displayrect,
3627 + float wmult, float hmult)
3631 @@ -464,6 +420,12 @@
3632 m_scrollinit = false;
3634 m_linespacing = 1.5;
3637 + QRect((int)round(m_screensize.x() / wmult),
3638 + (int)round(m_screensize.y() / hmult),
3639 + (int)ceil( m_screensize.width() / wmult),
3640 + (int)ceil( m_screensize.height() / hmult));
3643 OSDTypeText::OSDTypeText(const OSDTypeText &other)
3644 @@ -507,14 +469,13 @@
3645 m_scrollinit = false;
3648 -void OSDTypeText::Reinit(float wchange, float hchange)
3649 +void OSDTypeText::Reinit(float wmult, float hmult)
3651 - int width = (int)(m_screensize.width() * wchange);
3652 - int height = (int)(m_screensize.height() * hchange);
3653 - int x = (int)(m_screensize.x() * wchange);
3654 - int y = (int)(m_screensize.y() * hchange);
3656 - m_displaysize = m_screensize = QRect(x, y, width, height);
3657 + m_displaysize = m_screensize =
3658 + QRect((int)round(m_unbiasedsize.x() * wmult),
3659 + (int)round(m_unbiasedsize.y() * hmult),
3660 + (int)ceil( m_unbiasedsize.width() * wmult),
3661 + (int)ceil( m_unbiasedsize.height() * hmult));
3664 void OSDTypeText::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
3666 m_onlyusefirst = false;
3668 m_filename = filename;
3669 - m_displaypos = displaypos;
3670 + SetPosition(displaypos, wmult, hmult);
3672 m_yuv = m_alpha = NULL;
3678 + m_cacheitem = NULL;
3680 LoadImage(filename, wmult, hmult, scalew, scaleh);
3683 m_name = other.m_name;
3684 m_scalew = other.m_scalew;
3685 m_scaleh = other.m_scaleh;
3686 + m_cacheitem = NULL;
3688 m_alpha = m_yuv = NULL;
3691 m_onlyusefirst = false;
3693 m_displaypos = QPoint(0, 0);
3694 + m_unbiasedpos = QPoint(0, 0);
3695 + m_cacheitem = NULL;
3700 m_onlyusefirst = false;
3702 m_displaypos = QPoint(0, 0);
3703 + m_unbiasedpos = QPoint(0, 0);
3704 + m_cacheitem = NULL;
3708 @@ -790,10 +757,14 @@
3710 OSDTypeImage::~OSDTypeImage()
3715 - delete [] m_alpha;
3716 + // In case we have a cache item in hand, it's safe to delete it,
3717 + // as it should not be in OSDImageCache anymore and it should have
3718 + // been written to the file cache for faster access in the future.
3721 + delete m_cacheitem;
3722 + m_cacheitem = NULL;
3726 void OSDTypeImage::SetName(const QString &name)
3727 @@ -801,13 +772,19 @@
3731 -void OSDTypeImage::Reinit(float wchange, float hchange, float wmult, float hmult)
3732 +void OSDTypeImage::SetPosition(QPoint pos, float wmult, float hmult)
3734 - int x = (int)(m_displaypos.x() * wchange);
3735 - int y = (int)(m_displaypos.y() * hchange);
3736 + m_displaypos = pos;
3738 + QPoint((int)round(pos.x() / wmult),
3739 + (int)round(pos.y() / hmult));
3742 - m_displaypos.setX(x);
3743 - m_displaypos.setY(y);
3744 +void OSDTypeImage::Reinit(float wmult, float hmult)
3747 + QPoint((int)round(m_unbiasedpos.x() * wmult),
3748 + (int)round(m_unbiasedpos.y() * hmult));
3750 LoadImage(m_filename, wmult, hmult, m_scalew, m_scaleh);
3752 @@ -815,20 +792,44 @@
3753 void OSDTypeImage::LoadImage(const QString &filename, float wmult, float hmult,
3754 int scalew, int scaleh)
3759 + if (!filename.isEmpty() && filename.length() >= 2)
3764 - delete [] m_alpha;
3766 - m_isvalid = false;
3769 + ckey = OSDImageCache::CreateKey(
3770 + filename, wmult, hmult, scalew, scaleh);
3774 + // this method requires a backing file
3778 + // Get the item from the cache so it's not freed while in use
3779 + OSDImageCacheValue* value = c_cache.Get(ckey, true);
3781 + if (value != NULL)
3783 + m_yuv = value->m_yuv;
3784 + m_ybuffer = value->m_ybuffer;
3785 + m_ubuffer = value->m_ubuffer;
3786 + m_vbuffer = value->m_vbuffer;
3787 + m_alpha = value->m_alpha;
3788 + m_imagesize = value->m_imagesize;
3791 - if (filename.length() < 2)
3792 + // Put the old image back to the cache so it can be reused in the
3793 + // future, and possibly freed by the cache system if the size limit
3796 + c_cache.Insert(m_cacheitem);
3797 + m_cacheitem = value;
3802 + // scaled image was not found in cache, have to create it
3805 QImage tmpimage(filename);
3807 @@ -867,17 +868,32 @@
3808 imwidth, imheight, tmp2.width());
3810 m_imagesize = QRect(0, 0, imwidth, imheight);
3812 + // put the old image back to the cache so it can be reused in the
3813 + // future, and possibly freed by the cache system if the size limit
3816 + c_cache.Insert(m_cacheitem);
3818 + m_cacheitem = new OSDImageCacheValue(
3820 + m_yuv, m_ybuffer, m_ubuffer,
3821 + m_vbuffer, m_alpha, m_imagesize);
3823 + // save the new cache item to the file cache
3824 + if (!filename.isEmpty())
3825 + c_cache.SaveToDisk(m_cacheitem);
3828 void OSDTypeImage::LoadFromQImage(const QImage &img)
3830 + // this method is not cached as it's used mostly for
3831 + // subtitles which are displayed only once anyways, caching
3832 + // would probably only slow things down overall
3838 - delete [] m_alpha;
3840 + delete m_cacheitem;
3841 + m_cacheitem = NULL;
3845 @@ -1043,23 +1059,25 @@
3848 m_displayrect = displayrect;
3850 + QRect((int)round(m_displayrect.x() / wmult),
3851 + (int)round(m_displayrect.y() / hmult),
3852 + (int)ceil( m_displayrect.width() / wmult),
3853 + (int)ceil( m_displayrect.height() / hmult));
3856 OSDTypePosSlider::~OSDTypePosSlider()
3860 -void OSDTypePosSlider::Reinit(float wchange, float hchange, float wmult,
3862 +void OSDTypePosSlider::Reinit(float wmult, float hmult)
3864 - int width = (int)(m_displayrect.width() * wchange);
3865 - int height = (int)(m_displayrect.height() * hchange);
3866 - int x = (int)(m_displayrect.x() * wchange);
3867 - int y = (int)(m_displayrect.y() * hchange);
3869 - m_displayrect = QRect(x, y, width, height);
3871 - OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
3873 + QRect((int)round(m_unbiasedrect.x() * wmult),
3874 + (int)round(m_unbiasedrect.y() * hmult),
3875 + (int)ceil( m_unbiasedrect.width() * wmult),
3876 + (int)ceil( m_unbiasedrect.height() * hmult));
3877 + OSDTypeImage::Reinit(wmult, hmult);
3880 void OSDTypePosSlider::SetPosition(int pos)
3881 @@ -1092,23 +1110,25 @@
3883 m_onlyusefirst = true;
3884 m_displayrect = displayrect;
3886 + QRect((int)round(m_displayrect.x() / wmult),
3887 + (int)round(m_displayrect.y() / hmult),
3888 + (int)ceil( m_displayrect.width() / wmult),
3889 + (int)ceil( m_displayrect.height() / hmult));
3892 OSDTypeFillSlider::~OSDTypeFillSlider()
3896 -void OSDTypeFillSlider::Reinit(float wchange, float hchange, float wmult,
3898 +void OSDTypeFillSlider::Reinit(float wmult, float hmult)
3900 - int width = (int)(m_displayrect.width() * wchange);
3901 - int height = (int)(m_displayrect.height() * hchange);
3902 - int x = (int)(m_displayrect.x() * wchange);
3903 - int y = (int)(m_displayrect.y() * hchange);
3905 - m_displayrect = QRect(x, y, width, height);
3907 - OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
3909 + QRect((int)round(m_unbiasedrect.x() * wmult),
3910 + (int)round(m_unbiasedrect.y() * hmult),
3911 + (int)ceil( m_unbiasedrect.width() * wmult),
3912 + (int)ceil( m_unbiasedrect.height() * hmult));
3913 + OSDTypeImage::Reinit(wmult, hmult);
3916 void OSDTypeFillSlider::SetPosition(int pos)
3917 @@ -1143,6 +1163,11 @@
3920 m_displayrect = displayrect;
3922 + QRect((int)round(m_displayrect.x() / wmult),
3923 + (int)round(m_displayrect.y() / hmult),
3924 + (int)ceil( m_displayrect.width() / wmult),
3925 + (int)ceil( m_displayrect.height() / hmult));
3926 m_drawwidth = displayrect.width();
3928 m_drawMap = new unsigned char[m_drawwidth + 1];
3929 @@ -1162,6 +1187,7 @@
3933 + m_cacheitem = NULL;
3935 LoadImage(m_redname, wmult, hmult, scalew, scaleh);
3937 @@ -1184,22 +1210,16 @@
3938 OSDTypeEditSlider::~OSDTypeEditSlider()
3940 delete [] m_drawMap;
3945 - delete [] m_ralpha;
3948 -void OSDTypeEditSlider::Reinit(float wchange, float hchange, float wmult,
3950 +void OSDTypeEditSlider::Reinit(float wmult, float hmult)
3952 - int width = (int)(m_displayrect.width() * wchange);
3953 - int height = (int)(m_displayrect.height() * hchange);
3954 - int x = (int)(m_displayrect.x() * wchange);
3955 - int y = (int)(m_displayrect.y() * hchange);
3957 + QRect((int)round(m_unbiasedrect.x() * wmult),
3958 + (int)round(m_unbiasedrect.y() * hmult),
3959 + (int)ceil( m_unbiasedrect.width() * wmult),
3960 + (int)ceil( m_unbiasedrect.height() * hmult));
3962 - m_displayrect = QRect(x, y, width, height);
3963 m_drawwidth = m_displayrect.width();
3965 delete [] m_drawMap;
3966 @@ -1210,11 +1230,6 @@
3968 m_displaypos = m_displayrect.topLeft();
3973 - delete [] m_ralpha;
3975 LoadImage(m_redname, wmult, hmult, m_scalew, m_scaleh);
3978 @@ -1360,30 +1375,46 @@
3980 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3982 -OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect)
3984 +OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect,
3985 + float wmult, float hmult)
3990 + QRect((int)round(size.x() / wmult),
3991 + (int)round(size.y() / hmult),
3992 + (int)ceil( size.width() / wmult),
3993 + (int)ceil( size.height() / hmult));
3996 +void OSDTypeBox::SetRect(QRect newrect, float wmult, float hmult)
4000 + QRect((int)round(size.x() / wmult),
4001 + (int)round(size.y() / hmult),
4002 + (int)ceil( size.width() / wmult),
4003 + (int)ceil( size.height() / hmult));
4006 OSDTypeBox::OSDTypeBox(const OSDTypeBox &other)
4007 : OSDType(other.m_name)
4010 + m_unbiasedsize = other.m_unbiasedsize;
4013 OSDTypeBox::~OSDTypeBox()
4017 -void OSDTypeBox::Reinit(float wchange, float hchange)
4018 +void OSDTypeBox::Reinit(float wmult, float hmult)
4020 - int width = (int)(size.width() * wchange);
4021 - int height = (int)(size.height() * hchange);
4022 - int x = (int)(size.x() * wchange);
4023 - int y = (int)(size.y() * hchange);
4025 - size = QRect(x, y, width, height);
4027 + QRect((int)round(m_unbiasedsize.x() * wmult),
4028 + (int)round(m_unbiasedsize.y() * hmult),
4029 + (int)ceil( m_unbiasedsize.width() * wmult),
4030 + (int)ceil( m_unbiasedsize.height() * hmult));
4033 void OSDTypeBox::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
4034 @@ -1498,44 +1529,52 @@
4037 OSDTypePositionRectangle::OSDTypePositionRectangle(
4038 - const OSDTypePositionRectangle &other)
4039 - : OSDType(other.m_name), OSDTypePositionIndicator(other)
4040 + const OSDTypePositionRectangle &other)
4041 + : OSDType(other.m_name), OSDTypePositionIndicator(other)
4043 for (int i = 0; i < m_numpositions; i++)
4045 QRect tmp = other.positions[i];
4046 positions.push_back(tmp);
4048 + for (int i = 0; i < m_numpositions; i++)
4050 + QRect tmp = other.unbiasedpos[i];
4051 + unbiasedpos.push_back(tmp);
4055 OSDTypePositionRectangle::~OSDTypePositionRectangle()
4059 -void OSDTypePositionRectangle::Reinit(float wchange, float hchange)
4060 +void OSDTypePositionRectangle::Reinit(float wmult, float hmult)
4062 for (int i = 0; i < m_numpositions; i++)
4064 - QRect tmp = positions[i];
4066 - int width = (int)(tmp.width() * wchange);
4067 - int height = (int)(tmp.height() * hchange);
4068 - int x = (int)(tmp.x() * wchange);
4069 - int y = (int)(tmp.y() * hchange);
4071 - tmp = QRect(x, y, width, height);
4072 - positions[i] = tmp;
4073 + QRect tmp = unbiasedpos[i];
4075 + QRect((int)round(tmp.x() * wmult),
4076 + (int)round(tmp.y() * hmult),
4077 + (int)ceil( tmp.width() * wmult),
4078 + (int)ceil( tmp.height() * hmult));
4082 -void OSDTypePositionRectangle::AddPosition(QRect rect)
4083 +void OSDTypePositionRectangle::AddPosition(
4084 + QRect rect, float wmult, float hmult)
4086 positions.push_back(rect);
4087 + unbiasedpos.push_back(
4088 + QRect((int)round(rect.x() / wmult),
4089 + (int)round(rect.y() / hmult),
4090 + (int)ceil( rect.width() / wmult),
4091 + (int)ceil( rect.height() / hmult)));
4095 -void OSDTypePositionRectangle::Draw(OSDSurface *surface, int fade, int maxfade,
4096 - int xoff, int yoff)
4097 +void OSDTypePositionRectangle::Draw(
4098 + OSDSurface *surface, int fade, int maxfade, int xoff, int yoff)
4102 @@ -1618,17 +1657,21 @@
4103 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4105 OSDTypePositionImage::OSDTypePositionImage(const QString &name)
4106 - : OSDTypeImage(name), OSDTypePositionIndicator()
4107 + : OSDTypeImage(name), OSDTypePositionIndicator(),
4108 + m_wmult(0.0f), m_hmult(0.0f)
4112 OSDTypePositionImage::OSDTypePositionImage(const OSDTypePositionImage &other)
4113 : OSDTypeImage(other), OSDTypePositionIndicator(other)
4115 + m_wmult = other.m_wmult;
4116 + m_hmult = other.m_hmult;
4118 for (int i = 0; i < m_numpositions; i++)
4120 - QPoint tmp = other.positions[i];
4121 - positions.push_back(tmp);
4122 + positions.push_back(other.positions[i]);
4123 + unbiasedpos.push_back(other.unbiasedpos[i]);
4127 @@ -1636,45 +1679,61 @@
4131 -void OSDTypePositionImage::Reinit(float wchange, float hchange, float wmult,
4133 +void OSDTypePositionImage::Reinit(float wmult, float hmult)
4135 - OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
4139 + OSDTypeImage::Reinit(wmult, hmult);
4141 for (int i = 0; i < m_numpositions; i++)
4143 - QPoint tmp = positions[i];
4145 - int x = (int)(tmp.x() * wchange);
4146 - int y = (int)(tmp.y() * hchange);
4148 - positions[i].setX(x);
4149 - positions[i].setY(y);
4151 + QPoint((int)round(unbiasedpos[i].x() * wmult),
4152 + (int)round(unbiasedpos[i].y() * hmult));
4156 -void OSDTypePositionImage::AddPosition(QPoint pos)
4157 +void OSDTypePositionImage::AddPosition(QPoint pos, float wmult, float hmult)
4159 + if (m_wmult == 0.0f || m_hmult == 0.0f)
4164 positions.push_back(pos);
4165 + unbiasedpos.push_back(
4166 + QPoint((int)round(pos.x() / wmult),
4167 + (int)round(pos.y() / hmult)));
4169 + VERBOSE(VB_IMPORTANT,
4170 + "OSDTypePositionImage::AddPosition["<<m_numpositions<<"]("
4171 + <<pos.x()<<"x"<<pos.y()
4172 + <<" "<<wmult<<", "<<hmult<<")");
4177 void OSDTypePositionImage::Draw(OSDSurface *surface, int fade, int maxfade,
4180 + VERBOSE(VB_IMPORTANT,
4181 + "OSDTypePositionImage::Draw["<<m_curposition<<"]("
4182 + <<m_wmult<<", "<<m_hmult<<")");
4184 if (m_curposition < 0 || m_curposition >= m_numpositions)
4187 QPoint pos = positions[m_curposition];
4189 - OSDTypeImage::SetPosition(pos);
4190 + OSDTypeImage::SetPosition(pos, m_wmult, m_hmult);
4191 OSDTypeImage::Draw(surface, fade, maxfade, xoff, yoff);
4194 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4196 OSDTypeCC::OSDTypeCC(const QString &name, TTFFont *font, int xoff, int yoff,
4197 - int dispw, int disph)
4198 + int dispw, int disph, float wmult, float hmult)
4202 @@ -1683,9 +1742,11 @@
4204 displaywidth = dispw;
4205 displayheight = disph;
4209 QRect rect = QRect(0, 0, 0, 0);
4210 - m_box = new OSDTypeBox("cc_background", rect);
4211 + m_box = new OSDTypeBox("cc_background", rect, wmult, hmult);
4212 m_ccbackground = gContext->GetNumSetting("CCBackground", 0);
4215 @@ -1695,12 +1756,23 @@
4219 -void OSDTypeCC::Reinit(int x, int y, int dispw, int disph)
4220 +void OSDTypeCC::Reinit(float wmult, float hmult)
4224 + VERBOSE(VB_IMPORTANT, "Programmer error: "
4225 + "Call to OSDTypeCC::Reinit(float,float)");
4228 +void OSDTypeCC::Reinit(int x, int y, int dispw, int disph,
4229 + float wmult, float hmult)
4233 displaywidth = dispw;
4234 displayheight = disph;
4239 void OSDTypeCC::AddCCText(const QString &text, int x, int y, int color,
4240 @@ -1875,7 +1947,7 @@
4242 QRect rect = QRect(0, 0, textlength + 4,
4243 (m_font->Size() * 3 / 2) + 3);
4244 - m_box->SetRect(rect);
4245 + m_box->SetRect(rect, m_wmult, m_hmult);
4246 m_box->Draw(surface, 0, 0, x - 2, y - 2);
4249 Index: mythtv/libs/libmythtv/tv_play.cpp
4250 ===================================================================
4251 --- mythtv/libs/libmythtv/tv_play.cpp (.../tags/release-0-19) (revision 10931)
4252 +++ mythtv/libs/libmythtv/tv_play.cpp (.../branches/release-0-19-fixes) (revision 10931)
4254 browsechannum(""), browsechanid(""), browsestarttime(""),
4255 // Program Info for currently playing video
4256 recorderPlaybackInfo(NULL),
4257 - playbackinfo(NULL), inputFilename(""), playbackLen(0),
4258 + playbackinfo(NULL), playbackLen(0),
4259 lastProgram(NULL), jumpToProgram(false),
4261 nvp(NULL), pipnvp(NULL), activenvp(NULL),
4262 @@ -578,19 +578,7 @@
4263 if (!testrec->IsValidRecorder())
4267 - QString title = tr("MythTV is already using all available "
4268 - "inputs for recording. If you want to "
4269 - "watch an in-progress recording, select one "
4270 - "from the playback menu. If you want to "
4271 - "watch live TV, cancel one of the "
4272 - "in-progress recordings from the delete "
4275 - DialogBox diag(gContext->GetMainWindow(), title);
4276 - diag.AddButton(tr("Cancel and go back to the TV menu"));
4279 + ShowNoRecorderDialog();
4284 if (internalState != kState_None)
4287 - inputFilename = rcinfo->pathname;
4289 playbackLen = rcinfo->CalculateLength();
4290 playbackinfo = new ProgramInfo(*rcinfo);
4292 @@ -844,9 +830,10 @@
4296 + QString playbackURL = playbackinfo->GetPlaybackURL();
4298 tvchain->SetProgram(playbackinfo);
4300 - prbuffer = new RingBuffer(playbackinfo->pathname, false);
4301 + prbuffer = new RingBuffer(playbackURL, false);
4302 prbuffer->SetLiveMode(tvchain);
4305 @@ -895,7 +882,14 @@
4306 else if (TRANSITION(kState_None, kState_WatchingPreRecorded) ||
4307 TRANSITION(kState_None, kState_WatchingRecording))
4309 - prbuffer = new RingBuffer(inputFilename, false);
4310 + QString playbackURL;
4311 + if ((playbackinfo->pathname.left(4) == "dvd:") ||
4312 + (playbackinfo->isVideo))
4313 + playbackURL = playbackinfo->pathname;
4315 + playbackURL = playbackinfo->GetPlaybackURL();
4317 + prbuffer = new RingBuffer(playbackURL, false);
4318 if (prbuffer->IsOpen())
4320 gContext->DisableScreensaver();
4323 QString message = "COMMFLAG_REQUEST ";
4324 message += playbackinfo->chanid + " " +
4325 - playbackinfo->startts.toString(Qt::ISODate);
4326 + playbackinfo->recstartts.toString(Qt::ISODate);
4327 RemoteSendMessage(message);
4330 @@ -1222,10 +1216,10 @@
4331 nvp->SetParentPlayer(this);
4332 nvp->SetRingBuffer(prbuffer);
4333 nvp->SetRecorder(recorder);
4334 - nvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate"));
4335 + nvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate", 44100));
4336 nvp->SetAudioDevice(gContext->GetSetting("AudioOutputDevice"));
4337 nvp->SetLength(playbackLen);
4338 - nvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking"));
4339 + nvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking", 0));
4340 nvp->SetAutoCommercialSkip(autoCommercialSkip);
4341 nvp->SetLiveTVChain(tvchain);
4343 @@ -1296,9 +1290,9 @@
4345 pipnvp->SetRingBuffer(piprbuffer);
4346 pipnvp->SetRecorder(piprecorder);
4347 - pipnvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate"));
4348 + pipnvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate", 44100));
4349 pipnvp->SetAudioDevice(gContext->GetSetting("AudioOutputDevice"));
4350 - pipnvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking"));
4351 + pipnvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking", 0));
4352 pipnvp->SetLiveTVChain(piptvchain);
4354 pipnvp->SetLength(playbackLen);
4355 @@ -1454,6 +1448,30 @@
4356 lastSignalMsg.clear();
4358 UpdateOSDTimeoutMessage();
4360 + if (!tvchainUpdate.isEmpty())
4362 + tvchainUpdateLock.lock();
4363 + for (QStringList::Iterator it = tvchainUpdate.begin();
4364 + it != tvchainUpdate.end(); ++it)
4366 + if (tvchain && nvp && *it == tvchain->GetID())
4368 + tvchain->ReloadAll();
4369 + if (nvp->GetTVChain())
4370 + nvp->CheckTVChain();
4372 + if (piptvchain && pipnvp && *it == piptvchain->GetID())
4374 + piptvchain->ReloadAll();
4375 + if (pipnvp->GetTVChain())
4376 + pipnvp->CheckTVChain();
4379 + tvchainUpdate.clear();
4380 + tvchainUpdateLock.unlock();
4386 @@ -2743,7 +2761,7 @@
4387 speedStr = QString("%1X").arg(normal_speed);
4389 struct StatusPosInfo posInfo;
4390 - nvp->calcSliderPos(posInfo);
4391 + nvp->calcSliderPos(posInfo, true);
4393 QDateTime respDate = mythCurrentDateTime();
4394 QString infoStr = "";
4395 @@ -2806,8 +2824,10 @@
4399 + QString playbackURL = playbackinfo->GetPlaybackURL();
4401 piptvchain->SetProgram(playbackinfo);
4402 - piprbuffer = new RingBuffer(playbackinfo->pathname, false);
4403 + piprbuffer = new RingBuffer(playbackURL, false);
4404 piprbuffer->SetLiveMode(piptvchain);
4407 @@ -3472,8 +3492,10 @@
4411 + QString playbackURL = playbackinfo->GetPlaybackURL();
4413 tvchain->SetProgram(playbackinfo);
4414 - prbuffer = new RingBuffer(playbackinfo->pathname, false);
4415 + prbuffer = new RingBuffer(playbackURL, false);
4416 prbuffer->SetLiveMode(tvchain);
4419 @@ -4627,7 +4649,8 @@
4421 normal_speed = new_normal_speed;
4423 - activenvp->Play(normal_speed, true);
4425 + activenvp->Play(normal_speed, true);
4427 QString text = QString(tr("Time Stretch %1X")).arg(normal_speed);
4429 @@ -4911,29 +4934,14 @@
4431 else if (tvchain && message.left(12) == "LIVETV_CHAIN")
4433 - // Get osdlock, while intended for the OSD this ensures that
4434 - // the nvp & pipnvp are not deleted while we are using it..
4435 - while (!osdlock.tryLock() && nvp)
4438 message = message.simplifyWhiteSpace();
4439 QStringList tokens = QStringList::split(" ", message);
4440 if (tokens[1] == "UPDATE")
4442 - if (tvchain && nvp && tokens[2] == tvchain->GetID())
4444 - tvchain->ReloadAll();
4445 - if (nvp->GetTVChain())
4446 - nvp->CheckTVChain();
4448 - if (piptvchain && pipnvp && tokens[2] == piptvchain->GetID())
4450 - piptvchain->ReloadAll();
4451 - if (pipnvp->GetTVChain())
4452 - pipnvp->CheckTVChain();
4454 + tvchainUpdateLock.lock();
4455 + tvchainUpdate += QDeepCopy<QString>(tokens[2]);
4456 + tvchainUpdateLock.unlock();
4460 else if (nvp && message.left(12) == "EXIT_TO_MENU")
4462 @@ -4983,7 +4991,7 @@
4463 QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
4465 if ((playbackinfo->chanid == evchanid) &&
4466 - (playbackinfo->startts == evstartts))
4467 + (playbackinfo->recstartts == evstartts))
4469 QString msg = "COMMFLAG_REQUEST ";
4470 msg += tokens[1] + " " + tokens[2];
4471 @@ -5000,7 +5008,7 @@
4472 QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
4474 if ((playbackinfo->chanid == evchanid) &&
4475 - (playbackinfo->startts == evstartts))
4476 + (playbackinfo->recstartts == evstartts))
4478 QMap<long long, int> newMap;
4480 @@ -6067,9 +6075,22 @@
4481 "in-progress recordings from the delete "
4484 - MythPopupBox::showOkPopup(
4487 + VERBOSE(VB_IMPORTANT, errorText);
4489 + else if (GetOSD())
4491 + dialogname = "infobox";
4492 + QStringList options("OK");
4493 + GetOSD()->NewDialogBox(dialogname, errorText, options, 0);
4497 + MythPopupBox::showOkPopup(
4498 gContext->GetMainWindow(), QObject::tr("Channel Change Error"),
4503 /** \fn TV::PauseLiveTV(void)
4504 Index: mythtv/libs/libmythtv/jobqueue.cpp
4505 ===================================================================
4506 --- mythtv/libs/libmythtv/jobqueue.cpp (.../tags/release-0-19) (revision 10931)
4507 +++ mythtv/libs/libmythtv/jobqueue.cpp (.../branches/release-0-19-fixes) (revision 10931)
4508 @@ -275,6 +275,11 @@
4510 (hostname != m_hostname))
4512 + // Setting the status here will prevent us from processing
4513 + // any other jobs for this recording until this one is
4514 + // completed on the remote host.
4515 + jobStatus[key] = status;
4517 message = QString("JobQueue: Skipping '%1' job for chanid "
4518 "%2 @ %3, should run on '%4' instead")
4520 Index: mythtv/libs/libmythtv/dvbdev/dvbdev.c
4521 ===================================================================
4522 --- mythtv/libs/libmythtv/dvbdev/dvbdev.c (.../tags/release-0-19) (revision 10931)
4523 +++ mythtv/libs/libmythtv/dvbdev/dvbdev.c (.../branches/release-0-19-fixes) (revision 10931)
4526 const char* dvbdevice(int type, int cardnum)
4528 - char* frontenddev[4] =
4529 + char* frontenddev[8] =
4531 "/dev/dvb/adapter0/frontend0",
4532 "/dev/dvb/adapter1/frontend0",
4533 "/dev/dvb/adapter2/frontend0",
4534 - "/dev/dvb/adapter3/frontend0"
4535 + "/dev/dvb/adapter3/frontend0",
4536 + "/dev/dvb/adapter4/frontend0",
4537 + "/dev/dvb/adapter5/frontend0",
4538 + "/dev/dvb/adapter6/frontend0",
4539 + "/dev/dvb/adapter7/frontend0",
4545 "/dev/dvb/adapter0/dvr0",
4546 "/dev/dvb/adapter1/dvr0",
4547 "/dev/dvb/adapter2/dvr0",
4548 - "/dev/dvb/adapter3/dvr0"
4549 + "/dev/dvb/adapter3/dvr0",
4550 + "/dev/dvb/adapter4/dvr0",
4551 + "/dev/dvb/adapter5/dvr0",
4552 + "/dev/dvb/adapter6/dvr0",
4553 + "/dev/dvb/adapter7/dvr0",
4556 - char* demuxdev[4] =
4557 + char* demuxdev[8] =
4559 "/dev/dvb/adapter0/demux0",
4560 "/dev/dvb/adapter1/demux0",
4561 "/dev/dvb/adapter2/demux0",
4562 - "/dev/dvb/adapter3/demux0"
4563 + "/dev/dvb/adapter3/demux0",
4564 + "/dev/dvb/adapter4/demux0",
4565 + "/dev/dvb/adapter5/demux0",
4566 + "/dev/dvb/adapter6/demux0",
4567 + "/dev/dvb/adapter7/demux0",
4573 "/dev/dvb/adapter0/ca0",
4574 "/dev/dvb/adapter1/ca0",
4575 "/dev/dvb/adapter2/ca0",
4576 - "/dev/dvb/adapter3/ca0"
4577 + "/dev/dvb/adapter3/ca0",
4578 + "/dev/dvb/adapter4/ca0",
4579 + "/dev/dvb/adapter5/ca0",
4580 + "/dev/dvb/adapter6/ca0",
4581 + "/dev/dvb/adapter7/ca0",
4584 - char* audiodev[4] =
4585 + char* audiodev[8] =
4587 "/dev/dvb/adapter0/audio0",
4588 "/dev/dvb/adapter1/audio0",
4589 "/dev/dvb/adapter2/audio0",
4590 - "/dev/dvb/adapter3/audio0"
4591 + "/dev/dvb/adapter3/audio0",
4592 + "/dev/dvb/adapter4/audio0",
4593 + "/dev/dvb/adapter5/audio0",
4594 + "/dev/dvb/adapter6/audio0",
4595 + "/dev/dvb/adapter7/audio0",
4598 - char* videodev[4] =
4599 + char* videodev[8] =
4601 "/dev/dvb/adapter0/video0",
4602 "/dev/dvb/adapter1/video0",
4603 "/dev/dvb/adapter2/video0",
4604 - "/dev/dvb/adapter3/video0"
4605 + "/dev/dvb/adapter3/video0",
4606 + "/dev/dvb/adapter4/video0",
4607 + "/dev/dvb/adapter5/video0",
4608 + "/dev/dvb/adapter6/video0",
4609 + "/dev/dvb/adapter7/video0",
4617 Index: mythtv/libs/libmythtv/videosource.h
4618 ===================================================================
4619 --- mythtv/libs/libmythtv/videosource.h (.../tags/release-0-19) (revision 10931)
4620 +++ mythtv/libs/libmythtv/videosource.h (.../branches/release-0-19-fixes) (revision 10931)
4623 static CARD_TYPES GetDVBType(uint device, QString &name, QString &card_type);
4624 static bool HasDVBCRCBug(uint device);
4625 + static uint GetMinSignalMonitoringDelay(uint device);
4626 static QString GetDefaultInput(uint cardid);
4628 static bool IgnoreEncrypted(uint cardid, const QString &inputname);
4629 Index: mythtv/libs/libmythtv/libmythtv.pro
4630 ===================================================================
4631 --- mythtv/libs/libmythtv/libmythtv.pro (.../tags/release-0-19) (revision 10931)
4632 +++ mythtv/libs/libmythtv/libmythtv.pro (.../branches/release-0-19-fixes) (revision 10931)
4633 @@ -119,6 +119,10 @@
4634 SOURCES += playgroup.cpp
4635 SOURCES += progdetails.cpp
4638 +HEADERS += frequencies.h
4639 +SOURCES += frequencies.c
4642 # Recording profile stuff
4643 HEADERS += profilegroup.h
4644 @@ -144,10 +148,10 @@
4645 # On screen display (video output overlay)
4646 HEADERS += osd.h osdtypes.h
4647 HEADERS += osdsurface.h osdlistbtntype.h
4648 - HEADERS += udpnotify.h
4649 + HEADERS += osdimagecache.h udpnotify.h
4650 SOURCES += osd.cpp osdtypes.cpp
4651 SOURCES += osdsurface.cpp osdlistbtntype.cpp
4652 - SOURCES += udpnotify.cpp
4653 + SOURCES += osdimagecache.cpp udpnotify.cpp
4656 HEADERS += videooutbase.h videoout_null.h
4657 @@ -303,10 +307,6 @@
4662 - HEADERS += frequencies.h
4663 - SOURCES += frequencies.c
4665 DEFINES += USING_BACKEND
4668 Index: mythtv/libs/libmythtv/dvbchannel.cpp
4669 ===================================================================
4670 --- mythtv/libs/libmythtv/dvbchannel.cpp (.../tags/release-0-19) (revision 10931)
4671 +++ mythtv/libs/libmythtv/dvbchannel.cpp (.../branches/release-0-19-fixes) (revision 10931)
4673 * \bug Only supports single input cards.
4675 DVBChannel::DVBChannel(int aCardNum, TVRec *parent)
4676 - : QObject(NULL, "DVBChannel"), ChannelBase(parent),
4677 - diseqc(NULL), dvbcam(NULL),
4678 - fd_frontend(-1), cardnum(aCardNum), has_crc_bug(false),
4679 - currentTID(-1), first_tune(true)
4680 + : QObject(NULL, "DVBChannel"), ChannelBase(parent),
4681 + diseqc(NULL), dvbcam(NULL),
4682 + fd_frontend(-1), cardnum(aCardNum),
4683 + has_crc_bug(false),
4684 + tuning_delay(0), sigmon_delay(25),
4685 + currentTID(-1), first_tune(true),
4688 dvbcam = new DVBCam(cardnum);
4689 bzero(&info, sizeof(info));
4690 has_crc_bug = CardUtil::HasDVBCRCBug(aCardNum);
4692 + QString name(""), type("");
4693 + CardUtil::GetDVBType(aCardNum, name, type);
4694 + if ((name == "DiBcom 3000P/M-C DVB-T") ||
4695 + (name == "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"))
4697 + tuning_delay = 200;
4700 + sigmon_delay = CardUtil::GetMinSignalMonitoringDelay(aCardNum);
4703 DVBChannel::~DVBChannel()
4710 while (query.next())
4712 int this_inputid = query.value(4).toInt();
4714 * This is used by DVB Channel Scanner, the EIT Parser, and by TVRec.
4716 * \param channel Info on transport to tune to
4717 - * \param force_reset If true frequency tuning is done even if not strictly needed
4718 + * \param force_reset If true, frequency tuning is done
4719 + * even if it should not be needed.
4720 * \return true on success, false on failure
4722 bool DVBChannel::Tune(const dvb_channel_t& channel, bool force_reset)
4724 bool has_diseq = (FE_QPSK == info.type) && diseqc;
4725 struct dvb_frontend_parameters params = channel.tuning.params;
4727 + retune_tuning = channel.tuning;
4729 if (fd_frontend < 0)
4731 ERROR("DVBChannel::Tune: Card not open!");
4732 @@ -669,15 +685,22 @@
4733 // Adjust for Satelite recievers which offset the frequency.
4734 params.frequency = tuned_frequency(channel.tuning, info.type, NULL);
4736 + params.frequency = params.frequency + (retune_adj = -retune_adj);
4738 if (ioctl(fd_frontend, FE_SET_FRONTEND, ¶ms) < 0)
4740 ERRNO("DVBChannel::Tune: "
4741 "Setting Frontend tuning parameters failed.");
4745 + // Extra delay to add for broken DVB drivers
4747 + usleep(tuning_delay * 1000);
4749 wait_for_backend(fd_frontend, 5 /* msec */);
4751 - prev_tuning.params = params;
4752 + prev_tuning.params = channel.tuning.params;
4756 @@ -686,6 +709,24 @@
4760 +/** \fn DVBChannel::Retune(void)
4761 + * \brief Calls DVBChannel::Tune() with the last known parameters
4763 + * This is used to retune DVB-C hardware. DVB-C hardware
4764 + * sometimes does not successfully tune the first time
4765 + * despite reports of success from the drivers. This is
4766 + * probably a hardware problem and not a driver problem
4767 + * per say, so it is unlikely to be fixed at a lower level.
4769 + * \return true iff drivers report that tuning was successful
4771 +bool DVBChannel::Retune(void)
4773 + dvb_channel_t retune_channel;
4774 + retune_channel.tuning = retune_tuning;
4775 + return Tune(retune_channel, true);
4778 /** \fn DVBChannel::GetTuningParams(DVBTuning& tuning) const
4779 * \brief Fetches DVBTuning params from driver
4780 * \return true on success, false on failure
4782 for (uint i = 0; i < 64 && !tuned; i++)
4783 if (!diseqc->Set(t, reset, tuned))
4787 + // Wait 10 ms, recommended by Marcus Metzler, see #1552
4788 + usleep(10 * 1000);
4792 Index: mythtv/libs/libmythtv/osdtypes.h
4793 ===================================================================
4794 --- mythtv/libs/libmythtv/osdtypes.h (.../tags/release-0-19) (revision 10931)
4795 +++ mythtv/libs/libmythtv/osdtypes.h (.../branches/release-0-19-fixes) (revision 10931)
4798 #include <qobject.h>
4799 #include <qregexp.h>
4800 +#include "osdimagecache.h"
4802 using namespace std;
4806 QString Name() { return m_name; }
4808 + virtual void Reinit(float wmult, float hmult) = 0;
4810 virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
4813 @@ -150,11 +153,11 @@
4816 OSDTypeText(const QString &name, TTFFont *font, const QString &text,
4817 - QRect displayrect);
4818 + QRect displayrect, float wmult, float hmult);
4819 OSDTypeText(const OSDTypeText &text);
4822 - void Reinit(float wchange, float hchange);
4823 + void Reinit(float wmult, float hmult);
4825 void SetAltFont(TTFFont *font);
4826 void SetUseAlt(bool usealt) { m_usingalt = usealt; }
4829 QRect m_displaysize;
4831 + QRect m_unbiasedsize;
4833 QString m_default_msg;
4836 virtual ~OSDTypeImage();
4838 void SetName(const QString &name);
4839 - void Reinit(float wchange, float hchange, float wmult, float hmult);
4840 + void Reinit(float wmult, float hmult);
4842 void LoadImage(const QString &filename, float wmult, float hmult,
4843 int scalew = -1, int scaleh = -1);
4844 @@ -239,21 +243,20 @@
4846 void SetStaticSize(int scalew, int scaleh) { m_scalew = scalew;
4847 m_scaleh = scaleh; }
4848 + void SetPosition(QPoint pos, float wmult, float hmult);
4850 - QPoint DisplayPos() { return m_displaypos; }
4851 - void SetPosition(QPoint pos) { m_displaypos = pos; }
4852 + QPoint DisplayPos() const { return m_displaypos; }
4853 + QRect ImageSize() const { return m_imagesize; }
4854 + int width() const { return m_imagesize.width(); }
4855 + int height() const { return m_imagesize.height(); }
4857 - QRect ImageSize() { return m_imagesize; }
4859 - int width() { return m_imagesize.width(); }
4860 - int height() { return m_imagesize.height(); }
4862 virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
4867 QPoint m_displaypos;
4868 + QPoint m_unbiasedpos;
4875 bool m_onlyusefirst;
4877 + static OSDImageCache c_cache;
4878 + OSDImageCacheValue *m_cacheitem;
4881 class OSDTypePosSlider : public OSDTypeImage
4883 int scalew = -1, int scaleh = -1);
4884 ~OSDTypePosSlider();
4886 - void Reinit(float wchange, float hchange, float wmult, float hmult);
4887 + void Reinit(float wmult, float hmult);
4889 void SetRectangle(QRect rect) { m_displayrect = rect; }
4890 QRect ImageSize() { return m_imagesize; }
4894 QRect m_displayrect;
4895 + QRect m_unbiasedrect;
4900 int scalew = -1, int scaleh = -1);
4901 ~OSDTypeFillSlider();
4903 - void Reinit(float wchange, float hchange, float wmult, float hmult);
4904 + void Reinit(float wmult, float hmult);
4906 void SetRectangle(QRect rect) { m_displayrect = rect; }
4907 QRect ImageSize() { return m_imagesize; }
4911 QRect m_displayrect;
4912 + QRect m_unbiasedrect;
4917 int scalew = -1, int scaleh = -1);
4918 ~OSDTypeEditSlider();
4920 - void Reinit(float wchange, float hchange, float wmult, float hmult);
4921 + void Reinit(float wmult, float hmult);
4923 void SetRectangle(QRect rect) { m_displayrect = rect; }
4924 QRect ImageSize() { return m_imagesize; }
4928 QRect m_displayrect;
4929 + QRect m_unbiasedrect;
4933 @@ -360,17 +369,19 @@
4934 class OSDTypeBox : public OSDType
4937 - OSDTypeBox(const QString &name, QRect displayrect);
4938 + OSDTypeBox(const QString &name, QRect displayrect,
4939 + float wmult, float hmult);
4940 OSDTypeBox(const OSDTypeBox &other);
4943 - void Reinit(float wchange, float hchange);
4944 - void SetRect(QRect newrect) { size = newrect; }
4945 + void Reinit(float wmult, float hmult);
4946 + void SetRect(QRect newrect, float wmult, float hmult);
4948 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4952 + QRect m_unbiasedsize;
4955 class OSDTypePositionIndicator
4956 @@ -403,14 +414,15 @@
4957 OSDTypePositionRectangle(const OSDTypePositionRectangle &other);
4958 ~OSDTypePositionRectangle();
4960 - void AddPosition(QRect rect);
4961 + void AddPosition(QRect rect, float wmult, float hmult);
4963 - void Reinit(float wchange, float hchange);
4964 + void Reinit(float wmult, float hmult);
4966 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4969 - vector<QRect> positions;
4970 + vector<QRect> positions;
4971 + vector<QRect> unbiasedpos;
4974 class OSDTypePositionImage : public virtual OSDTypeImage,
4975 @@ -421,14 +433,17 @@
4976 OSDTypePositionImage(const OSDTypePositionImage &other);
4977 ~OSDTypePositionImage();
4979 - void Reinit(float wchange, float hchange, float wmult, float hmult);
4980 + void Reinit(float wmult, float hmult);
4982 - void AddPosition(QPoint pos);
4983 + void AddPosition(QPoint pos, float wmult, float hmult);
4985 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4988 vector<QPoint> positions;
4989 + vector<QPoint> unbiasedpos;
4995 @@ -445,11 +460,15 @@
4998 OSDTypeCC(const QString &name, TTFFont *font, int xoff, int yoff,
4999 - int dispw, int disph);
5000 + int dispw, int disph, float wmult, float hmult);
5003 - void Reinit(int xoff, int yoff, int dispw, int disph);
5004 + void Reinit(float wmult, float hmult);
5006 + void Reinit(int xoff, int yoff,
5007 + int dispw, int disph,
5008 + float wmult, float hmult);
5010 void AddCCText(const QString &text, int x, int y, int color,
5011 bool teletextmode = false);
5012 void ClearAllCCText();
5014 vector<ccText *> *m_textlist;
5018 + float m_wmult, m_hmult;
5019 int xoffset, yoffset, displaywidth, displayheight;
5022 Index: mythtv/libs/libmythtv/videoout_xv.h
5023 ===================================================================
5024 --- mythtv/libs/libmythtv/videoout_xv.h (.../tags/release-0-19) (revision 10931)
5025 +++ mythtv/libs/libmythtv/videoout_xv.h (.../branches/release-0-19-fixes) (revision 10931)
5027 virtual bool hasVLDAcceleration(void) const
5028 { return XVideoVLD == VideoOutputSubType(); }
5030 + void CheckFrameStates(void);
5032 static MythCodecID GetBestSupportedCodec(uint width, uint height,
5033 uint osd_width, uint osd_height,
5034 uint stream_type, int xvmc_chroma,
5036 static bool IsRendering(VideoFrame* frame);
5037 static void SyncSurface(VideoFrame* frame, int past_future = 0);
5038 static void FlushSurface(VideoFrame* frame);
5039 - void CheckDisplayedFramesForAvailability(void);
5042 XvMCOSD* GetAvailableOSD();
5043 void ReturnAvailableOSD(XvMCOSD*);
5044 Index: mythtv/libs/libmythtv/osdimagecache.h
5045 ===================================================================
5046 --- mythtv/libs/libmythtv/osdimagecache.h (.../tags/release-0-19) (revision 0)
5047 +++ mythtv/libs/libmythtv/osdimagecache.h (.../branches/release-0-19-fixes) (revision 10931)
5049 +// -*- Mode: c++ -*-
5052 +#include <stdint.h>
5057 +#include <qmutex.h>
5058 +#include <qstring.h>
5059 +#include <qasciicache.h>
5061 +class OSDImageCacheValue
5064 + OSDImageCacheValue(QString cacheKey,
5065 + unsigned char *yuv, unsigned char *ybuffer,
5066 + unsigned char *ubuffer, unsigned char *vbuffer,
5067 + unsigned char *alpha, QRect imagesize);
5069 + virtual ~OSDImageCacheValue();
5071 + uint GetSize(void) const { return m_size_in_bytes; }
5072 + QString GetKey(void) const { return m_cacheKey; }
5075 + unsigned char *m_yuv;
5076 + unsigned char *m_ybuffer;
5077 + unsigned char *m_ubuffer;
5078 + unsigned char *m_vbuffer;
5079 + unsigned char *m_alpha;
5080 + QRect m_imagesize;
5083 + uint m_size_in_bytes;
5084 + QString m_cacheKey;
5087 +typedef QAsciiCache<OSDImageCacheValue> img_cache_t;
5089 +class OSDImageCache
5093 + virtual ~OSDImageCache();
5095 + bool InFileCache(const QString &key) const;
5097 + bool Contains(const QString &key, bool useFile) const;
5099 + OSDImageCacheValue *Get(const QString &key, bool useFile);
5101 + void Insert(OSDImageCacheValue* value);
5103 + void SaveToDisk(const OSDImageCacheValue *value);
5107 + static QString CreateKey(const QString &filename,
5108 + float wmult, float hmult,
5109 + int scalew, int scaleh);
5111 + static QString ExtractOriginal(const QString &key);
5114 + mutable QMutex m_cacheLock;
5115 + img_cache_t m_imageCache;
5120 + /// Limit on the maximum total size of OSD images cached in *memory*.
5121 + static uint kMaximumMemoryCacheSize;
5123 Index: mythtv/libs/libmythtv/tv_play.h
5124 ===================================================================
5125 --- mythtv/libs/libmythtv/tv_play.h (.../tags/release-0-19) (revision 10931)
5126 +++ mythtv/libs/libmythtv/tv_play.h (.../branches/release-0-19-fixes) (revision 10931)
5128 ProgramInfo *recorderPlaybackInfo; ///< info requested from recorder
5129 ProgramInfo *playbackinfo; ///< info sent in via Playback()
5131 - QString inputFilename; ///< playbackinfo->pathname
5132 int playbackLen; ///< initial playbackinfo->CalculateLength()
5133 ProgramInfo *lastProgram; ///< last program played with this player
5137 LiveTVChain *tvchain;
5138 LiveTVChain *piptvchain;
5139 + QStringList tvchainUpdate;
5140 + QMutex tvchainUpdateLock;
5143 RingBuffer *prbuffer;
5144 Index: mythtv/libs/libmythtv/videosource.cpp
5145 ===================================================================
5146 --- mythtv/libs/libmythtv/videosource.cpp (.../tags/release-0-19) (revision 10931)
5147 +++ mythtv/libs/libmythtv/videosource.cpp (.../branches/release-0-19-fixes) (revision 10931)
5149 #include "videosource.h"
5150 #include "datadirect.h"
5151 #include "scanwizard.h"
5152 +#include "frequencies.h"
5155 #include <linux/dvb/frontend.h>
5156 @@ -156,6 +157,17 @@
5157 (name == "ST STV0299 DVB-S")); // munges PAT
5160 +uint CardUtil::GetMinSignalMonitoringDelay(uint device)
5162 + QString name(""), type("");
5163 + GetDVBType(device, name, type);
5164 + if (name.find("DVB-S") >= 0)
5166 + if (name == "DiBcom 3000P/M-C DVB-T")
5171 /** \fn CardUtil::GetCardType(uint, QString&, QString&)
5172 * \brief Returns the card type from the video device
5173 * \param nCardID cardid of card to be checked
5174 @@ -574,22 +586,10 @@
5176 setLabel(QObject::tr("Channel frequency table"));
5177 addSelection("default");
5178 - addSelection("us-cable");
5179 - addSelection("us-bcast");
5180 - addSelection("us-cable-hrc");
5181 - addSelection("japan-bcast");
5182 - addSelection("japan-cable");
5183 - addSelection("europe-west");
5184 - addSelection("europe-east");
5185 - addSelection("italy");
5186 - addSelection("newzealand");
5187 - addSelection("australia");
5188 - addSelection("ireland");
5189 - addSelection("france");
5190 - addSelection("china-bcast");
5191 - addSelection("southafrica");
5192 - addSelection("argentina");
5193 - addSelection("australia-optus");
5195 + for (uint i = 0; chanlists[i].name; i++)
5196 + addSelection(chanlists[i].name);
5198 setHelpText(QObject::tr("Use default unless this source uses a "
5199 "different frequency table than the system wide table "
5200 "defined in the General settings."));
5201 Index: mythtv/libs/libmythtv/frequencytables.cpp
5202 ===================================================================
5203 --- mythtv/libs/libmythtv/frequencytables.cpp (.../tags/release-0-19) (revision 10931)
5204 +++ mythtv/libs/libmythtv/frequencytables.cpp (.../branches/release-0-19-fixes) (revision 10931)
5205 @@ -283,104 +283,52 @@
5206 "ATSC Channel %1", 70, 809000000, 887000000, 6000000, VSB_8);
5209 - // USA Cable, QAM 256
5210 - fmap["atsc_qam256_uscable0"] = new FrequencyTable(
5211 - "QAM-256 Channel %1", 1, 75000000,1005000000, 6000000, QAM_256);
5212 - fmap["atsc_qam256_uscable1"] = new FrequencyTable(
5213 - "QAM-256 Channel T-%1", 7, 10000000, 52000000, 6000000, QAM_256);
5214 + QString modStr[] = { "vsb8", "qam256", "qam128", "qam64", };
5215 + uint mod[] = { VSB_8, QAM_256, QAM_128, QAM_64, };
5216 + QString desc[] = { "ATSC ", "QAM-256 ", "QAM-128 ", "QAM-64 ", };
5218 - // USA Cable, QAM 256 ch 78+
5219 - fmap["atsc_qam256_uscablehigh0"] = new FrequencyTable(
5220 - "QAM-256 Channel %1", 78,472000000,1005000000, 6000000, QAM_256);
5221 +#define FREQ(A,B, C,D, E,F,G, H) \
5222 + fmap[QString("atsc_%1_us%2").arg(A).arg(B)] = \
5223 + new FrequencyTable(C+D, E, F, G, 6000000, H);
5225 - // USA Cable HRC, QAM 256
5226 - fmap["atsc_qam256_ushrc0"] = new FrequencyTable(
5227 - "QAM-256 HRC %1", 1, 73750000, 73750001, 6000000, QAM_256);
5228 - fmap["atsc_qam256_ushrc1"] = new FrequencyTable(
5229 - "QAM-256 HRC %1", 2, 55750000, 67750000, 6000000, QAM_256);
5230 - fmap["atsc_qam256_ushrc2"] = new FrequencyTable(
5231 - "QAM-256 HRC %1", 5, 79750000, 85750000, 6000000, QAM_256);
5232 - fmap["atsc_qam256_ushrc3"] = new FrequencyTable(
5233 - "QAM-256 HRC %1", 7, 175750000, 643750000, 6000000, QAM_256);
5234 - fmap["atsc_qam256_ushrc4"] = new FrequencyTable(
5235 - "QAM-256 HRC %1", 95, 91750000, 114000000, 6000000, QAM_256);
5236 - fmap["atsc_qam256_ushrc5"] = new FrequencyTable(
5237 - "QAM-256 HRC %1", 100, 649750000, 799750000, 6000000, QAM_256);
5238 - fmap["atsc_qam256_ushrc6"] = new FrequencyTable(
5239 - "QAM-256 HRC T-%1", 7, 8175000, 50750000, 6000000, QAM_256);
5240 + for (uint i = 0; i < 4; i++)
5242 + // USA Cable, ch 1 to 155 and T.7 to T.14
5243 + FREQ(modStr[i], "cable0", desc[i], "Channel %1",
5244 + 1, 75000000, 1005000000, mod[i]);
5245 + FREQ(modStr[i], "cable1", desc[i], "Channel T-%1",
5246 + 7, 10000000, 52000000, mod[i]);
5247 + // USA Cable, QAM 256 ch 78 to 155
5248 + FREQ(modStr[i], "cablehigh0", desc[i], "Channel %1",
5249 + 78, 537000000,1005000000, mod[i]);
5251 - // USA Cable HRC, QAM 256 ch 78+
5252 - fmap["atsc_qam256_ushrchigh0"] = new FrequencyTable(
5253 - "QAM-256 HRC %1", 78, 601750000, 643750000, 6000000, QAM_256);
5254 - fmap["atsc_qam256_ushrchigh1"] = new FrequencyTable(
5255 - "QAM-256 HRC %1", 100, 649750000, 799750000, 6000000, QAM_256);
5256 + QString std[] = { "hrc", "irc" };
5257 + QString sdesc[] = { "HRC ", "IRC " };
5258 + int off[] = { 0, 1250000 };
5260 + for (uint j = 0; j < 2; j++)
5262 + // USA Cable HRC/IRC, ch 1 to 125
5263 + FREQ(modStr[i], std[j] + "0", desc[i], sdesc[j] + "%1",
5264 + 1, 73750000 + off[j], 73750001 + off[j], mod[i]);
5265 + FREQ(modStr[i], std[j] + "1", desc[i], sdesc[j] + "%1",
5266 + 2, 55750000 + off[j], 67750000 + off[j], mod[i]);
5267 + FREQ(modStr[i], std[j] + "2", desc[i], sdesc[j] + "%1",
5268 + 5, 79750000 + off[j], 85750000 + off[j], mod[i]);
5269 + FREQ(modStr[i], std[j] + "3", desc[i], sdesc[j] + "%1",
5270 + 7, 175750000 + off[j], 643750000 + off[j], mod[i]);
5271 + FREQ(modStr[i], std[j] + "4", desc[i], sdesc[j] + "%1",
5272 + 95, 91750000 + off[j], 114000000 + off[j], mod[i]);
5273 + FREQ(modStr[i], std[j] + "5", desc[i], sdesc[j] + "%1",
5274 + 100, 649750000 + off[j], 799750000 + off[j], mod[i]);
5275 + FREQ(modStr[i], std[j] + "6", desc[i], sdesc[j] + "T-%1",
5276 + 7, 8175000 + off[j], 50750000 + off[j], mod[i]);
5279 - // USA Cable, QAM 128
5280 - fmap["atsc_qam128_uscable0"] = new FrequencyTable(
5281 - "QAM-128 Channel %1", 1, 75000000,1005000000, 6000000, QAM_128);
5282 - fmap["atsc_qam128_uscable1"] = new FrequencyTable(
5283 - "QAM-128 Channel T-%1", 7, 10000000, 52000000, 6000000, QAM_128);
5285 - // USA Cable, QAM 128 ch 78+
5286 - fmap["atsc_qam128_uscablehigh0"] = new FrequencyTable(
5287 - "QAM-128 Channel %1", 78,472000000,1005000000, 6000000, QAM_128);
5289 - // USA Cable HRC, QAM 128
5290 - fmap["atsc_qam128_ushrc0"] = new FrequencyTable(
5291 - "QAM-128 HRC %1", 1, 73750000, 73750001, 6000000, QAM_128);
5292 - fmap["atsc_qam128_ushrc1"] = new FrequencyTable(
5293 - "QAM-128 HRC %1", 2, 55750000, 67750000, 6000000, QAM_128);
5294 - fmap["atsc_qam128_ushrc2"] = new FrequencyTable(
5295 - "QAM-128 HRC %1", 5, 79750000, 85750000, 6000000, QAM_128);
5296 - fmap["atsc_qam128_ushrc3"] = new FrequencyTable(
5297 - "QAM-128 HRC %1", 7, 175750000, 643750000, 6000000, QAM_128);
5298 - fmap["atsc_qam128_ushrc4"] = new FrequencyTable(
5299 - "QAM-128 HRC %1", 95, 91750000, 114000000, 6000000, QAM_128);
5300 - fmap["atsc_qam128_ushrc5"] = new FrequencyTable(
5301 - "QAM-128 HRC %1", 100, 649750000, 799750000, 6000000, QAM_128);
5302 - fmap["atsc_qam128_ushrc6"] = new FrequencyTable(
5303 - "QAM-128 HRC T-%1", 7, 8175000, 50750000, 6000000, QAM_128);
5305 - // USA Cable HRC, QAM 128 ch 78+
5306 - fmap["atsc_qam128_ushrchigh0"] = new FrequencyTable(
5307 - "QAM-128 HRC %1", 78, 601750000, 643750000, 6000000, QAM_128);
5308 - fmap["atsc_qam128_ushrchigh1"] = new FrequencyTable(
5309 - "QAM-128 HRC %1", 100, 649750000, 799750000, 6000000, QAM_128);
5314 - // USA Cable, QAM 64
5315 - fmap["atsc_qam64_uscable0"] = new FrequencyTable(
5316 - "QAM-64 Channel %1", 1, 75000000,1005000000, 6000000, QAM_64);
5317 - fmap["atsc_qam64_uscable1"] = new FrequencyTable(
5318 - "QAM-64 Channel T-%1", 7, 10000000, 52000000, 6000000, QAM_64);
5320 - // USA Cable, QAM 64 ch 78+
5321 - fmap["atsc_qam64_uscablehigh0"] = new FrequencyTable(
5322 - "QAM-64 Channel %1", 78,472000000,1005000000, 6000000, QAM_64);
5324 - // USA Cable HRC, QAM 64
5325 - fmap["atsc_qam64_ushrc0"] = new FrequencyTable(
5326 - "QAM-64 HRC %1", 1, 73750000, 73750001, 6000000, QAM_64);
5327 - fmap["atsc_qam64_ushrc1"] = new FrequencyTable(
5328 - "QAM-64 HRC %1", 2, 55750000, 67750000, 6000000, QAM_64);
5329 - fmap["atsc_qam64_ushrc2"] = new FrequencyTable(
5330 - "QAM-64 HRC %1", 5, 79750000, 85750000, 6000000, QAM_64);
5331 - fmap["atsc_qam64_ushrc3"] = new FrequencyTable(
5332 - "QAM-64 HRC %1", 7, 175750000, 643750000, 6000000, QAM_64);
5333 - fmap["atsc_qam64_ushrc4"] = new FrequencyTable(
5334 - "QAM-64 HRC %1", 95, 91750000, 114000000, 6000000, QAM_64);
5335 - fmap["atsc_qam64_ushrc5"] = new FrequencyTable(
5336 - "QAM-64 HRC %1", 100, 649750000, 799750000, 6000000, QAM_64);
5337 - fmap["atsc_qam64_ushrc6"] = new FrequencyTable(
5338 - "QAM-64 HRC T-%1", 7, 8175000, 50750000, 6000000, QAM_64);
5340 - // USA Cable HRC, QAM 64 ch 78+
5341 - fmap["atsc_qam64_ushrchigh0"] = new FrequencyTable(
5342 - "QAM-64 HRC %1", 78, 601750000, 643750000, 6000000, QAM_64);
5343 - fmap["atsc_qam64_ushrchigh1"] = new FrequencyTable(
5344 - "QAM-64 HRC %1", 100, 649750000, 799750000, 6000000, QAM_64);
5345 + // USA Cable HRC/IRC, ch 67-125
5346 + FREQ(modStr[i], std[j] + "high0", desc[i], sdesc[j] + "%1",
5347 + 67, 535750000 + off[j], 643750000 + off[j], mod[i]);
5348 + FREQ(modStr[i], std[j] + "high1", desc[i], sdesc[j] + "%1",
5349 + 100, 649750000 + off[j], 799750000 + off[j], mod[i]);
5353 Index: mythtv/libs/libmythtv/scanwizardhelpers.h
5354 ===================================================================
5355 --- mythtv/libs/libmythtv/scanwizardhelpers.h (.../tags/release-0-19) (revision 10931)
5356 +++ mythtv/libs/libmythtv/scanwizardhelpers.h (.../branches/release-0-19-fixes) (revision 10931)
5357 @@ -272,11 +272,13 @@
5359 ScanFrequencyTable()
5361 - addSelection(QObject::tr("Broadcast"), "us", true);
5362 - addSelection(QObject::tr("Cable") +" 78+", "uscablehigh", false);
5363 - addSelection(QObject::tr("Cable HRC")+" 78+", "uscablehrchigh",false);
5364 - addSelection(QObject::tr("Cable"), "uscable", false);
5365 - addSelection(QObject::tr("Cable HRC"), "ushrc", false);
5366 + addSelection(QObject::tr("Broadcast"), "us", true);
5367 + addSelection(QObject::tr("Cable") +" 78+", "uscablehigh", false);
5368 + addSelection(QObject::tr("Cable HRC")+" 67+", "ushrchigh", false);
5369 + addSelection(QObject::tr("Cable IRC")+" 67+", "usirchigh", false);
5370 + addSelection(QObject::tr("Cable"), "uscable", false);
5371 + addSelection(QObject::tr("Cable HRC"), "ushrc", false);
5372 + addSelection(QObject::tr("Cable IRC"), "usirc", false);
5374 setLabel(QObject::tr("Frequency Table"));
5375 setHelpText(QObject::tr("Frequency table to use.") + " " +
5376 Index: mythtv/libs/libmythtv/scanwizard.cpp
5377 ===================================================================
5378 --- mythtv/libs/libmythtv/scanwizard.cpp (.../tags/release-0-19) (revision 10931)
5379 +++ mythtv/libs/libmythtv/scanwizard.cpp (.../branches/release-0-19-fixes) (revision 10931)
5381 "SELECT dvb_diseqc_type, diseqc_port, diseqc_pos, "
5382 " lnb_lof_switch, lnb_lof_hi, lnb_lof_lo "
5383 "FROM cardinput, capturecard "
5384 - "WHERE capturecard.cardid=%1 and cardinput.sourceid=%2")
5385 + "WHERE capturecard.cardid = %1 AND "
5386 + " cardinput.sourceid = %2 AND "
5387 + " capturecard.cardid = cardinput.cardid")
5388 .arg(parent->captureCard()).arg(nVideoSource));
5390 if (query.exec() && query.isActive() && query.size() > 0)
5391 Index: mythtv/libs/libmythtv/videoout_xv.cpp
5392 ===================================================================
5393 --- mythtv/libs/libmythtv/videoout_xv.cpp (.../tags/release-0-19) (revision 10931)
5394 +++ mythtv/libs/libmythtv/videoout_xv.cpp (.../branches/release-0-19-fixes) (revision 10931)
5395 @@ -1089,6 +1089,9 @@
5396 bool use_xv = true, use_shm = true;
5398 QString dec = gContext->GetSetting("PreferredMPEG2Decoder", "ffmpeg");
5399 + if (dec != "libmpeg2" && height < 720 &&
5400 + gContext->GetNumSetting("UseXvMCForHDOnly", 0))
5403 use_xvmc_idct = use_xvmc = true;
5404 else if (dec == "xvmc-vld")
5405 @@ -1335,40 +1338,39 @@
5407 X11S(XFree(attributes));
5409 - if (xv_draw_colorkey)
5410 + if (!xv_draw_colorkey)
5413 + QString msg = LOC + "Chromakeying not possible with this XVideo port.";
5414 + X11S(xv_atom = XInternAtom(XJ_disp, "XV_COLORKEY", False));
5415 + if (xv_atom == None)
5417 - X11S(xv_atom = XInternAtom(XJ_disp, "XV_COLORKEY", False));
5418 - if (xv_atom != None)
5420 - X11S(ret = XvGetPortAttribute(XJ_disp, xv_port, xv_atom,
5422 + VERBOSE(VB_PLAYBACK, msg);
5427 - if (ret == Success && xv_colorkey == 0)
5429 - const int default_colorkey = 1;
5430 - X11S(ret = XvSetPortAttribute(XJ_disp, xv_port, xv_atom,
5431 - default_colorkey));
5432 - if (ret == Success)
5434 - VERBOSE(VB_PLAYBACK, LOC +
5435 - "0,0,0 is the only bad color key for MythTV, "
5436 - "using "<<default_colorkey<<" instead.");
5437 - xv_colorkey = default_colorkey;
5442 - if (ret != Success)
5444 - VERBOSE(VB_IMPORTANT, LOC_ERR +
5445 - "Couldn't get the color key color,"
5446 - "\n\t\t\tprobably due to a driver bug or limitation."
5447 - "\n\t\t\tYou might not get any video, "
5448 - "but we'll try anyway.");
5451 + X11S(ret = XvGetPortAttribute(XJ_disp, xv_port, xv_atom, &xv_colorkey));
5452 + if (ret == Success && xv_colorkey == 0)
5454 + const int default_colorkey = 1;
5455 + X11S(ret = XvSetPortAttribute(XJ_disp, xv_port, xv_atom,
5456 + default_colorkey));
5457 + if (ret == Success)
5459 + VERBOSE(VB_PLAYBACK, LOC +
5460 + "0,0,0 is the only bad color key for MythTV, "
5461 + "using "<<default_colorkey<<" instead.");
5462 + xv_colorkey = default_colorkey;
5467 + if (ret != Success)
5469 + VERBOSE(VB_PLAYBACK, msg);
5474 bool VideoOutputXv::SetupDeinterlace(bool interlaced,
5475 @@ -1955,86 +1957,75 @@
5478 void VideoOutputXv::DiscardFrames(bool next_frame_keyframe)
5481 + VERBOSE(VB_PLAYBACK, LOC + "DiscardFrames("<<next_frame_keyframe<<")");
5482 if (VideoOutputSubType() <= XVideo)
5484 vbuffers.DiscardFrames(next_frame_keyframe);
5485 + VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 3: %1 -- done()")
5486 + .arg(vbuffers.GetStatus()));
5491 frame_queue_t::iterator it;
5492 frame_queue_t syncs;
5493 - frame_queue_t ula;
5494 - frame_queue_t discards;
5497 - vbuffers.begin_lock(kVideoBuffer_displayed); // Lock X
5498 - VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 1: %1")
5499 - .arg(vbuffers.GetStatus()));
5500 - vbuffers.end_lock(); // Lock X
5502 + // Print some debugging
5503 + vbuffers.begin_lock(kVideoBuffer_displayed); // Lock X
5504 + VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 1: %1")
5505 + .arg(vbuffers.GetStatus()));
5506 + vbuffers.end_lock(); // Lock X
5508 - CheckDisplayedFramesForAvailability();
5510 + // Finish rendering all these surfaces and move them
5511 + // from the used queue to the displayed queue.
5512 + // This allows us to reuse these surfaces, if they
5513 + // get moved to the used list in CheckFrameStates().
5514 + // This will only happen if avlib isn't using them
5515 + // either and they are not currently being displayed.
5516 + vbuffers.begin_lock(kVideoBuffer_displayed); // Lock Y
5517 + DQ_COPY(syncs, kVideoBuffer_used);
5518 + for (it = syncs.begin(); it != syncs.end(); ++it)
5520 - vbuffers.begin_lock(kVideoBuffer_displayed); // Lock Y
5522 - DQ_COPY(syncs, kVideoBuffer_displayed);
5523 - DQ_COPY(syncs, kVideoBuffer_pause);
5524 - for (it = syncs.begin(); it != syncs.end(); ++it)
5526 - SyncSurface(*it, -1); // sync past
5527 - SyncSurface(*it, +1); // sync future
5528 - SyncSurface(*it, 0); // sync current
5529 - //GetRender(*it)->p_past_surface = NULL;
5530 - //GetRender(*it)->p_future_surface = NULL;
5532 - VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 2: %1")
5533 - .arg(vbuffers.GetStatus()));
5535 - // Remove inheritence of all frames not in displayed or pause
5536 - DQ_COPY(ula, kVideoBuffer_used);
5537 - DQ_COPY(ula, kVideoBuffer_limbo);
5538 - DQ_COPY(ula, kVideoBuffer_avail);
5540 - for (it = ula.begin(); it != ula.end(); ++it)
5541 - vbuffers.RemoveInheritence(*it);
5544 - VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 3: %1")
5545 - .arg(vbuffers.GetStatus()));
5546 - // create discard frame list
5547 - DQ_COPY(discards, kVideoBuffer_used);
5548 - DQ_COPY(discards, kVideoBuffer_limbo);
5550 - vbuffers.end_lock(); // Lock Y
5551 + SyncSurface(*it, -1); // sync past
5552 + SyncSurface(*it, +1); // sync future
5553 + SyncSurface(*it, 0); // sync current
5554 + vbuffers.safeEnqueue(kVideoBuffer_displayed, *it);
5557 + vbuffers.end_lock(); // Lock Y
5559 - for (it = discards.begin(); it != discards.end(); ++it)
5560 - DiscardFrame(*it);
5561 + CheckFrameStates();
5563 + // If the next frame is a keyframe we can clear out a lot more...
5564 + if (next_frame_keyframe)
5566 vbuffers.begin_lock(kVideoBuffer_displayed); // Lock Z
5569 - DQ_COPY(syncs, kVideoBuffer_displayed);
5570 - DQ_COPY(syncs, kVideoBuffer_pause);
5571 + // Move all the limbo and pause frames to displayed
5572 + DQ_COPY(syncs, kVideoBuffer_limbo);
5573 for (it = syncs.begin(); it != syncs.end(); ++it)
5575 SyncSurface(*it, -1); // sync past
5576 SyncSurface(*it, +1); // sync future
5577 SyncSurface(*it, 0); // sync current
5578 - //GetRender(*it)->p_past_surface = NULL;
5579 - //GetRender(*it)->p_future_surface = NULL;
5580 + vbuffers.safeEnqueue(kVideoBuffer_displayed, *it);
5583 - VERBOSE(VB_PLAYBACK, LOC +
5584 - QString("DiscardFrames() 4: %1 -- done() ")
5585 + VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 2: %1")
5586 .arg(vbuffers.GetStatus()));
5589 vbuffers.end_lock(); // Lock Z
5591 + // Now call CheckFrameStates() to remove inheritence and
5592 + // move the surfaces to the used list if possible (i.e.
5593 + // if avlib is not using them and they are not currently
5594 + // being displayed on screen).
5595 + CheckFrameStates();
5597 + VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 3: %1 -- done()")
5598 + .arg(vbuffers.GetStatus()));
5600 #endif // USING_XVMC
5603 @@ -2071,7 +2062,7 @@
5605 DiscardFrame(osdframe);
5607 - CheckDisplayedFramesForAvailability();
5608 + CheckFrameStates();
5612 @@ -2411,7 +2402,7 @@
5613 DiscardFrame(vbuffers.dequeue(kVideoBuffer_pause));
5615 // clear any displayed frames not on screen
5616 - CheckDisplayedFramesForAvailability();
5617 + CheckFrameStates();
5619 // unlock the frame[s]
5620 vbuffers.UnlockFrame(osdframe, "ShowXvMC -- OSD");
5621 @@ -2659,7 +2650,7 @@
5622 .arg(vbuffers.size(kVideoBuffer_pause)));
5623 while (vbuffers.size(kVideoBuffer_pause))
5624 DiscardFrame(vbuffers.dequeue(kVideoBuffer_pause));
5625 - CheckDisplayedFramesForAvailability();
5626 + CheckFrameStates();
5627 } else if (1 == vbuffers.size(kVideoBuffer_pause))
5629 VideoFrame *frame = vbuffers.dequeue(kVideoBuffer_used);
5630 @@ -2791,7 +2782,7 @@
5631 // If there are no available buffer, try to toss old
5632 // displayed frames.
5633 if (!vbuffers.size(kVideoBuffer_avail))
5634 - CheckDisplayedFramesForAvailability();
5635 + CheckFrameStates();
5637 // If tossing doesn't work try hiding showing frames,
5638 // then tossing displayed frames.
5639 @@ -2805,7 +2796,7 @@
5640 GetRender(*it)->p_surface));
5641 vbuffers.end_lock();
5643 - CheckDisplayedFramesForAvailability();
5644 + CheckFrameStates();
5647 // If there is an available buffer grab it.
5648 @@ -3013,7 +3004,7 @@
5652 -void VideoOutputXv::CheckDisplayedFramesForAvailability(void)
5653 +void VideoOutputXv::CheckFrameStates(void)
5656 frame_queue_t::iterator it;
5657 @@ -3084,6 +3075,13 @@
5661 + else if (vbuffers.contains(kVideoBuffer_decode, pframe))
5663 + VERBOSE(VB_PLAYBACK, LOC + QString(
5664 + "Frame %1 is in use by avlib and so is "
5665 + "being held for later discarding.")
5666 + .arg(DebugString(pframe, true)));
5670 vbuffers.RemoveInheritence(pframe);
5671 Index: mythtv/libs/libmythtv/signalmonitor.h
5672 ===================================================================
5673 --- mythtv/libs/libmythtv/signalmonitor.h (.../tags/release-0-19) (revision 10931)
5674 +++ mythtv/libs/libmythtv/signalmonitor.h (.../branches/release-0-19-fixes) (revision 10931)
5677 #include <pthread.h>
5680 +#include <algorithm>
5681 +using namespace std;
5684 #include <qobject.h>
5687 * Defaults to 25 milliseconds.
5688 * \param msec Milliseconds between signal monitoring events.
5690 - void SetUpdateRate(int msec) { update_rate = msec; }
5691 + void SetUpdateRate(int msec)
5692 + { update_rate = max(msec, (int)minimum_update_rate); }
5695 virtual void deleteLater(void);
5700 + uint minimum_update_rate;
5704 Index: mythtv/libs/libmythtv/RingBuffer.h
5705 ===================================================================
5706 --- mythtv/libs/libmythtv/RingBuffer.h (.../tags/release-0-19) (revision 10931)
5707 +++ mythtv/libs/libmythtv/RingBuffer.h (.../branches/release-0-19-fixes) (revision 10931)
5709 long long GetTotalReadPosition(void);
5711 long long SetAdjustFilesize(void);
5712 + void SetTimeout(bool fast) { oldfile = fast; }
5715 static void *StartReader(void *type);
5716 Index: mythtv/libs/libmythtv/dvbtypes.cpp
5717 ===================================================================
5718 --- mythtv/libs/libmythtv/dvbtypes.cpp (.../tags/release-0-19) (revision 10931)
5719 +++ mythtv/libs/libmythtv/dvbtypes.cpp (.../branches/release-0-19-fixes) (revision 10931)
5722 {"TRANSMISSION_MODE_AUTO",TRANSMISSION_MODE_AUTO},
5723 {"TRANSMISSION_MODE_2K",TRANSMISSION_MODE_2K},
5724 - {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_2K},
5725 + {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_8K},
5726 {NULL,TRANSMISSION_MODE_AUTO},
5731 {"999",TRANSMISSION_MODE_AUTO},
5732 {"2",TRANSMISSION_MODE_2K},
5733 - {"8",TRANSMISSION_MODE_2K},
5734 + {"8",TRANSMISSION_MODE_8K},
5735 {NULL,TRANSMISSION_MODE_AUTO},
5740 {"auto",TRANSMISSION_MODE_AUTO},
5741 {"2",TRANSMISSION_MODE_2K},
5742 - {"8",TRANSMISSION_MODE_2K},
5743 + {"8",TRANSMISSION_MODE_8K},
5744 {NULL,TRANSMISSION_MODE_AUTO},
5747 Index: mythtv/libs/libmythtv/mpegrecorder.cpp
5748 ===================================================================
5749 --- mythtv/libs/libmythtv/mpegrecorder.cpp (.../tags/release-0-19) (revision 10931)
5750 +++ mythtv/libs/libmythtv/mpegrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931)
5753 if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
5755 - cerr << "Error setting codec params\n";
5756 + cerr << "Warning, unable to set recording volume\n";
5757 + cerr << "This is normal if you have an AVerMedia M179 card.\n";
5758 perror("VIDIOC_S_CTRL:");
5766 printf("select timeout - ivtv driver has stopped responding\n");
5767 + if(close(readfd) != 0)
5769 + readfd = -1; // Force PVR card to be reopened on next iteration
5773 Index: mythtv/libs/libmythtv/ivtvdecoder.cpp
5774 ===================================================================
5775 --- mythtv/libs/libmythtv/ivtvdecoder.cpp (.../tags/release-0-19) (revision 10931)
5776 +++ mythtv/libs/libmythtv/ivtvdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
5779 GetNVP()->SetVideoParams(720 /*width*/, (ntsc) ? 480 : 576 /*height*/,
5780 (ntsc) ? 29.97f : 25.0f, keyframedist, 1.33);
5783 + fps = (ntsc) ? 29.97f : 25.0f; // save for later length calculations
5785 ringBuffer->UpdateRawBitrate(8000);
5787 if (m_playbackinfo || livetv || watchingrecording)
5788 Index: mythtv/libs/libmythtv/dvbsignalmonitor.cpp
5789 ===================================================================
5790 --- mythtv/libs/libmythtv/dvbsignalmonitor.cpp (.../tags/release-0-19) (revision 10931)
5791 +++ mythtv/libs/libmythtv/dvbsignalmonitor.cpp (.../branches/release-0-19-fixes) (revision 10931)
5792 @@ -100,6 +100,10 @@
5795 DBG_SM("constructor()", QString("initial flags 0x%1").arg(newflags,0,16));
5797 + minimum_update_rate = _channel->GetMinSignalMonitorDelay();
5798 + if (minimum_update_rate > 30)
5799 + usleep(minimum_update_rate * 1000);
5802 /** \fn DVBSignalMonitor::~DVBSignalMonitor()
5806 remainder = GetStreamData()->ProcessData(buffer, len);
5807 - if (remainder > 0) // leftover bytes
5808 - memmove(buffer, &(buffer[buffer_size - remainder]), remainder);
5809 + if (remainder > 0 && (len > remainder)) // leftover bytes
5810 + memmove(buffer, &(buffer[len - remainder]), remainder);
5812 VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorTS(): " + "shutdown");
5814 Index: mythtv/libs/libmythtv/tv_rec.cpp
5815 ===================================================================
5816 --- mythtv/libs/libmythtv/tv_rec.cpp (.../tags/release-0-19) (revision 10931)
5817 +++ mythtv/libs/libmythtv/tv_rec.cpp (.../branches/release-0-19-fixes) (revision 10931)
5818 @@ -130,6 +130,11 @@
5820 ringBuffer(NULL), rbFilePrefix(""), rbFileExt("mpg")
5823 + retune_timer = new TuningTimer();
5824 + retune_timer->setTimeout(10000);
5825 + retune_timer->start();
5826 + retune_requests = 0;
5829 /** \fn TVRec::Init()
5830 @@ -3221,6 +3226,8 @@
5832 void TVRec::HandleTuning(void)
5834 + bool handle_done = false;
5836 if (tuningRequests.size())
5838 const TuningRequest *request = &tuningRequests.front();
5839 @@ -3232,7 +3239,12 @@
5840 kFlagEITScan|kFlagAntennaAdjust))
5844 TuningFrequency(*request);
5845 + retune_timer->restart();
5846 + retune_timer->addMSecs(1);
5847 + retune_requests = 0;
5850 SetFlags(kFlagWaitingForRecPause);
5852 @@ -3261,15 +3273,29 @@
5853 if (HasFlags(kFlagWaitingForSignal))
5855 if (!TuningSignalCheck())
5857 + handle_done = true;
5860 if (HasFlags(kFlagWaitingForSIParser))
5862 if (!TuningPMTCheck())
5864 + handle_done = true;
5868 + // Just because we have signal, we may not have the right transponder
5869 + if ((HasFlags(kFlagWaitingForSignal) ||
5870 + HasFlags(kFlagWaitingForSIParser)) &&
5871 + (!retune_timer->elapsed() && (retune_requests < 30)))
5874 + retune_requests++;
5876 +#endif // USING_DVB
5881 if (HasFlags(kFlagNeedToStartRecorder))
5884 @@ -3354,6 +3380,19 @@
5885 ClearFlags(kFlagPendingActions);
5888 +/** \fn TVRec::RetuneChannel(void)
5889 + * \brief Retunes a DVB channel
5890 + * \return DVBChannel::Retune() or false if ifndef USING_DVB
5892 +bool TVRec::RetuneChannel(void)
5895 + if (GetDVBChannel())
5896 + return GetDVBChannel()->Retune();
5897 +#endif // USING_DVB
5901 /** \fn TVRec::TuningFrequency(const TuningRequest&)
5902 * \brief Performs initial tuning required for any tuning event.
5904 Index: mythtv/libs/libmythtv/videooutbase.h
5905 ===================================================================
5906 --- mythtv/libs/libmythtv/videooutbase.h (.../tags/release-0-19) (revision 10931)
5907 +++ mythtv/libs/libmythtv/videooutbase.h (.../branches/release-0-19-fixes) (revision 10931)
5909 /// onto the queue of frames ready for decoding onto.
5910 virtual void DiscardFrames(bool kf) { vbuffers.DiscardFrames(kf); }
5912 + virtual void CheckFrameStates(void) { }
5914 /// \bug not implemented correctly. vpos is not updated.
5915 VideoFrame *GetLastDecodedFrame(void) { return vbuffers.GetLastDecodedFrame(); }
5917 Index: mythtv/libs/libmythtv/osdimagecache.cpp
5918 ===================================================================
5919 --- mythtv/libs/libmythtv/osdimagecache.cpp (.../tags/release-0-19) (revision 0)
5920 +++ mythtv/libs/libmythtv/osdimagecache.cpp (.../branches/release-0-19-fixes) (revision 10931)
5922 +// -*- Mode: c++ -*-
5924 + * Copyright (c) 2006 by Pekka Jääskeläinen, Daniel Thor Kristjansson
5925 + * Distributed as part of MythTV under GPL v2 and later.
5929 +#include <stdint.h>
5934 +#include <qfileinfo.h>
5935 +#include <qdatastream.h>
5936 +#include <qdeepcopy.h>
5939 +#include "mythcontext.h"
5940 +#include "osdimagecache.h"
5942 +// Print statistics of OSD image access in the destructor of OSDImageCache
5943 +//#define PRINT_OSD_IMAGE_CACHE_STATS
5945 +#define LOC QString("OSDImgCache: ")
5946 +#define LOC_ERR QString("OSDImgCache, Error: ")
5948 +uint OSDImageCache::kMaximumMemoryCacheSize = 5 * 1024 * 1024;
5950 +/** \fn OSDImageCacheValue::OSDImageCacheValue(unsigned char*,unsigned char*,unsighed char*,unsigned char*,unsighed char*, QRect)
5951 + * \brief The main constructor that takes the image data as arguments.
5953 + * The image data becomes property of the OSDImageCacheValue
5954 + * and will be deleted by it.
5956 +OSDImageCacheValue::OSDImageCacheValue(
5958 + unsigned char *yuv, unsigned char *ybuffer,
5959 + unsigned char *ubuffer, unsigned char *vbuffer,
5960 + unsigned char *alpha, QRect imagesize) :
5961 + m_yuv(yuv), m_ybuffer(ybuffer),
5962 + m_ubuffer(ubuffer), m_vbuffer(vbuffer),
5963 + m_alpha(alpha), m_imagesize(imagesize),
5964 + m_cacheKey(QDeepCopy<QString>(cacheKey))
5966 + uint yuv_size = m_imagesize.width() * m_imagesize.height() * 3 / 2;
5968 + (sizeof(OSDImageCacheValue)) + yuv_size +
5969 + (m_imagesize.width() * m_imagesize.height());
5972 +/** \fn OSDImageCacheValue::~OSDImageCacheValue()
5973 + * \brief Destructor, frees the cached bitmaps.
5975 +OSDImageCacheValue::~OSDImageCacheValue()
5979 + delete [] m_alpha;
5983 +/** \fn OSDImageCache::OSDImageCache()
5984 + * \brief Constructor, initializes the internal cache structures.
5986 +OSDImageCache::OSDImageCache() :
5987 + m_cacheLock(true), m_imageCache(kMaximumMemoryCacheSize, 50),
5988 + m_memHits(0), m_diskHits(0), m_misses(0)
5990 + // When the cache gets too large, items are
5991 + // automatically deleted from it in LRU order.
5992 + m_imageCache.setAutoDelete(true);
5995 +/** \fn OSDImageCache::~OSDImageCache()
5996 + * \brief Destructor, frees all cached OSD images.
5998 +OSDImageCache::~OSDImageCache()
6000 +#ifdef PRINT_OSD_IMAGE_CACHE_STATS
6001 + int totalAccess = m_memHits + m_diskHits + m_misses;
6002 + if (totalAccess == 0)
6005 +#define LOG_PREFIX "OSDImageCache: "
6006 + VERBOSE(VB_IMPORTANT, LOC << " Statistics: " << endl
6007 + << LOG_PREFIX << m_imageCache.totalCost() << " bytes in cache\n"
6008 + << LOG_PREFIX << " memory hits: "
6009 + << m_memHits << ", " << m_memHits*100.0/totalAccess << "%\n"
6010 + << LOG_PREFIX << " disk hits: "
6011 + << m_diskHits << ", " << m_diskHits*100.0/totalAccess << "%\n"
6012 + << LOG_PREFIX << " misses: "
6013 + << m_misses << ", " << m_misses*100.0/totalAccess << "%");
6019 +/** \fn OSDImageCache::Contains(const QString&,bool)
6020 + * \brief Returns true if cached OSD image was found in the cache.
6022 + * \param key The key for this image.
6023 + * \param useFile If true, also look from the disk cache.
6025 +bool OSDImageCache::Contains(const QString &key, bool useFile) const
6027 + QMutexLocker locker(&m_cacheLock);
6029 + if (m_imageCache.find(key) != NULL)
6035 + return InFileCache(key);
6038 +bool OSDImageCache::InFileCache(const QString &key) const
6040 + // check if cache file exists
6041 + QDir dir(MythContext::GetConfDir() + "/osdcache/");
6042 + QFileInfo cFile(dir.path() + "/" + key);
6043 + if (!cFile.exists() || !cFile.isReadable())
6046 + // check if backing file exists
6047 + QString orig = ExtractOriginal(key);
6048 + if (orig.isEmpty())
6051 + QFileInfo oFile(orig);
6052 + if (!oFile.exists())
6054 + VERBOSE(VB_IMPORTANT, LOC + QString("Can't find '%1'").arg(orig));
6058 + // if cache file is older than backing file, delete cache file
6059 + if (cFile.lastModified() < oFile.lastModified())
6061 + cFile.dir().remove(cFile.baseName(true));
6068 +/** \fn OSDImageCache::Get(const QString&,bool)
6069 + * \brief Returns OSD image data from cache.
6071 + * This also removes the image from the cache so it won't be deleted
6072 + * while in use. The deletion of the taken item becomes responsibility
6073 + * of the client. Returns NULL if item with the given key is not found.
6075 + * \param key The key for this image.
6076 + * \param useFile If true, also check the disk cache.
6078 +OSDImageCacheValue *OSDImageCache::Get(const QString &key, bool useFile)
6080 + QMutexLocker locker(&m_cacheLock);
6081 + OSDImageCacheValue* item = m_imageCache.find(key);
6085 + return m_imageCache.take(key);
6088 + if (!useFile || !InFileCache(key))
6094 + QDir dir(MythContext::GetConfDir() + "/osdcache/");
6095 + QFile cacheFile(dir.path() + "/" + key);
6096 + cacheFile.open(IO_ReadOnly);
6097 + uint32_t imwidth = 0;
6098 + uint32_t imheight = 0;
6100 + QDataStream stream(&cacheFile);
6101 + stream >> imwidth >> imheight;
6103 + uint yuv_size = imwidth * imheight * 3 / 2;
6104 + uint tot_size = (sizeof(imwidth) * 2) + yuv_size + (imwidth * imheight);
6106 + if (cacheFile.size() != tot_size)
6108 + VERBOSE(VB_IMPORTANT, LOC_ERR + key + " wrong cache file size!"
6109 + << cacheFile.size() << " != " << tot_size);
6113 + unsigned char *yuv = new unsigned char[yuv_size];
6114 + unsigned char *alpha = new unsigned char[imwidth * imheight];
6115 + stream.readRawBytes((char*)yuv, yuv_size);
6116 + stream.readRawBytes((char*)alpha, imwidth * imheight);
6117 + cacheFile.close();
6119 + OSDImageCacheValue* value =
6120 + new OSDImageCacheValue(
6123 + yuv + (imwidth * imheight),
6124 + yuv + (imwidth * imheight * 5 / 4),
6125 + alpha, QRect(0, 0, imwidth, imheight));
6131 +/** \fn OSDImageCache::Insert(OSDImageCacheValue*)
6132 + * \brief Inserts OSD image data to memory cache.
6134 + * The item becomes property of the OSDImageCache and may be
6135 + * deleted any time by it.
6137 + * \param value The cache item.
6139 +void OSDImageCache::Insert(OSDImageCacheValue *value)
6144 + QMutexLocker locker(&m_cacheLock);
6145 + if (!m_imageCache.insert(value->GetKey(), value, value->GetSize()))
6147 + VERBOSE(VB_IMPORTANT,
6148 + LOC_ERR + QString("inserting image to memory cache failed"));
6153 +/** \fn OSDImageCache::SaveToDisk(const OSDImageCacheValue*)
6154 + * \brief Saves OSD image data to disk cache.
6156 + * Item is not written to the memory cache, i.e., it stays as
6157 + * property of the client.
6159 + * \param value The cached OSD image to save.
6161 +void OSDImageCache::SaveToDisk(const OSDImageCacheValue *value)
6163 + if (InFileCache(value->GetKey()))
6166 + QDir dir(MythContext::GetConfDir() + "/osdcache/");
6167 + if (!dir.exists() && !dir.mkdir(dir.path()))
6169 + VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating osdcache directory failed.");
6173 + QFile cacheFile(dir.path() + "/" + value->GetKey());
6174 + if (!cacheFile.open(IO_WriteOnly | IO_Truncate))
6176 + VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating osdcache file failed.");
6180 + uint32_t imwidth = value->m_imagesize.width();
6181 + uint32_t imheight = value->m_imagesize.height();
6182 + uint yuv_size = imwidth * imheight * 3 / 2;
6184 + QDataStream stream(&cacheFile);
6185 + stream << imwidth << imheight;
6186 + stream.writeRawBytes((const char*)value->m_yuv, yuv_size);
6187 + stream.writeRawBytes((const char*)value->m_alpha, imwidth * imheight);
6188 + cacheFile.close();
6191 +/** \fn OSDImageCache::CreateKey(const QString&,float,float,int,int)
6192 + * \brief Generates a cache key from the given OSD image parameters.
6194 + * The returned key is a string that can be safely used as a file name.
6196 +QString OSDImageCache::CreateKey(const QString &filename, float wmult,
6197 + float hmult, int scalew, int scaleh)
6199 + QString tmp = filename;
6200 + return QString("cache_%1@%2_%3_%4_%5").arg(tmp.replace(QChar('/'), "+"))
6201 + .arg(wmult).arg(hmult).arg(scalew).arg(scaleh);
6204 +QString OSDImageCache::ExtractOriginal(const QString &key)
6206 + QString tmp0 = key.mid(6);
6207 + QString tmp1 = tmp0.left(tmp0.find("@"));
6208 + QString tmp2 = tmp1.replace(QChar('+'), "/");
6212 +void OSDImageCache::Reset(void)
6214 + QMutexLocker locker(&m_cacheLock);
6215 + // this also deletes the images due to setAutoDelete(true)
6216 + m_imageCache.clear();
6218 Index: mythtv/libs/libmythtv/osd.cpp
6219 ===================================================================
6220 --- mythtv/libs/libmythtv/osd.cpp (.../tags/release-0-19) (revision 10931)
6221 +++ mythtv/libs/libmythtv/osd.cpp (.../branches/release-0-19-fixes) (revision 10931)
6225 OSDTypeCC *ccpage = new OSDTypeCC(name, ccfont, sub_xoff, sub_yoff,
6226 - sub_dispw, sub_disph);
6227 + sub_dispw, sub_disph,
6229 container->AddType(ccpage);
6236 - OSDTypeBox *box = new OSDTypeBox(name, area);
6237 + OSDTypeBox *box = new OSDTypeBox(name, area, wmult, hmult);
6238 container->AddType(box);
6245 - OSDTypeText *text = new OSDTypeText(name, ttffont, "", area);
6246 + OSDTypeText *text = new OSDTypeText(name, ttffont, "", area, wmult, hmult);
6247 container->AddType(text);
6249 text->SetMultiLine(multiline);
6251 QRect area = parseRect(getFirstText(info));
6252 normalizeRect(area);
6254 - rects->AddPosition(area);
6255 + rects->AddPosition(area, wmult, hmult);
6260 pos.setX((int)(pos.x() * wmult + xoffset));
6261 pos.setY((int)(pos.y() * hmult + yoffset));
6263 - image->AddPosition(pos);
6264 + image->AddPosition(pos, wmult, hmult);
6266 else if (info.tagName() == "staticsize")
6268 @@ -1925,7 +1926,7 @@
6269 image = new OSDTypeImage(*editarrowright);
6272 - image->SetPosition(QPoint(xpos, ypos));
6273 + image->SetPosition(QPoint(xpos, ypos), wmult, hmult);
6275 set->AddType(image);
6277 Index: mythtv/libs/libmythtv/tv_rec.h
6278 ===================================================================
6279 --- mythtv/libs/libmythtv/tv_rec.h (.../tags/release-0-19) (revision 10931)
6280 +++ mythtv/libs/libmythtv/tv_rec.h (.../branches/release-0-19-fixes) (revision 10931)
6282 #include "mythdeque.h"
6283 #include "programinfo.h"
6288 class NuppelVideoRecorder;
6290 BROWSE_FAVORITE ///< Fetch information on the next favorite channel
6298 + void setTimeout(long t) { _timeout = t; }
6299 + long timeout(void) { return _timeout; }
6300 + void start() { t_timer.start(); }
6301 + int restart() { int ret = elapsed();
6302 + t_timer.restart();
6305 + int elapsed() { int ret = t_timer.elapsed();
6306 + if (ret > _timeout) { ret = 0; t_timer.restart(); }
6310 + void addMSecs(int ms) { t_timer.addMSecs(ms); }
6317 class GeneralDBOptions
6321 bool TuningPMTCheck(void);
6322 void TuningNewRecorder(void);
6323 void TuningRestartRecorder(void);
6324 + bool RetuneChannel(void);
6326 void HandleStateChange(void);
6327 void ChangeState(TVState nextState);
6328 @@ -362,6 +388,10 @@
6329 QString rbFilePrefix;
6333 + TuningTimer *retune_timer;
6334 + int retune_requests;
6337 static const uint kEITScanStartTimeout;
6338 static const uint kSignalMonitoringRate;
6339 Index: mythtv/libs/libmythtv/videobuffers.h
6340 ===================================================================
6341 --- mythtv/libs/libmythtv/videobuffers.h (.../tags/release-0-19) (revision 10931)
6342 +++ mythtv/libs/libmythtv/videobuffers.h (.../branches/release-0-19-fixes) (revision 10931)
6344 kVideoBuffer_used = 0x00000004,
6345 kVideoBuffer_pause = 0x00000008,
6346 kVideoBuffer_displayed = 0x00000010,
6347 + kVideoBuffer_decode = 0x00000020,
6348 kVideoBuffer_all = 0x0000001F,
6354 mutable QMutex global_lock;
6355 - QMutex inheritence_lock;
6357 bool use_frame_locks;
6359 Index: mythtv/libs/libmythtv/dvbconfparser.cpp
6360 ===================================================================
6361 --- mythtv/libs/libmythtv/dvbconfparser.cpp (.../tags/release-0-19) (revision 10931)
6362 +++ mythtv/libs/libmythtv/dvbconfparser.cpp (.../branches/release-0-19-fixes) (revision 10931)
6363 @@ -193,10 +193,10 @@
6364 QStringList::Iterator end = tokens.end();
6366 if (i != end) c.name = *i++; else return false;
6367 - if (i != end) c.frequency = (*i++).toInt(); else return false;
6368 + if (i != end) c.frequency = (*i++).toUInt()*1000; else return false;
6369 if (i == end || !c.polarity.parseConf(*i++)) return false;
6370 if (i == end ) return false; else i++; //Sat num
6371 - if (i != end) c.symbolrate = (*i++).toInt(); else return false;
6372 + if (i != end) c.symbolrate = (*i++).toUInt()*1000; else return false;
6373 if (i == end ) return false; else i++;
6374 if (i == end ) return false; else i++;
6375 if (i != end) c.serviceid = (*i++).toInt(); else return false;
6376 Index: mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp
6377 ===================================================================
6378 --- mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp (.../tags/release-0-19) (revision 10931)
6379 +++ mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp (.../branches/release-0-19-fixes) (revision 10931)
6383 remainder = GetStreamData()->ProcessData(buffer, len);
6384 - if (remainder > 0) // leftover bytes
6385 - memmove(buffer, &(buffer[buffer_size - remainder]), remainder);
6386 + if (remainder > 0 && (len > remainder)) // leftover bytes
6387 + memmove(buffer, &(buffer[len - remainder]), remainder);
6389 DBG_SM("RunTableMonitor()", "end");
6391 Index: mythtv/libs/libmythtv/videobuffers.cpp
6392 ===================================================================
6393 --- mythtv/libs/libmythtv/videobuffers.cpp (.../tags/release-0-19) (revision 10931)
6394 +++ mythtv/libs/libmythtv/videobuffers.cpp (.../branches/release-0-19-fixes) (revision 10931)
6396 : numbuffers(0), needfreeframes(0), needprebufferframes(0),
6397 needprebufferframes_normal(0), needprebufferframes_small(0),
6398 keepprebufferframes(0), need_extra_for_pause(false), rpos(0), vpos(0),
6399 - global_lock(true), inheritence_lock(false), use_frame_locks(true),
6400 + global_lock(true), use_frame_locks(true),
6410 uint numcreate = numdecode + ((extra_for_pause) ? 1 : 0);
6412 // make a big reservation, so that things that depend on
6415 else if (type == kVideoBuffer_pause)
6417 + else if (type == kVideoBuffer_decode)
6419 global_lock.unlock();
6424 else if (type == kVideoBuffer_pause)
6426 + else if (type == kVideoBuffer_decode)
6428 global_lock.unlock();
6432 limbo.remove(frame);
6433 if ((type & kVideoBuffer_pause) == kVideoBuffer_pause)
6434 pause.remove(frame);
6435 + if ((type & kVideoBuffer_decode) == kVideoBuffer_decode)
6436 + decode.remove(frame);
6437 global_lock.unlock();
6444 - inheritence_lock.lock();
6445 + global_lock.lock();
6447 frame_map_t::iterator it = parents.find(frame);
6448 if (it == parents.end())
6449 @@ -902,18 +910,18 @@
6450 children[*it].push_back((VideoFrame*)frame);
6453 - inheritence_lock.unlock();
6454 + global_lock.unlock();
6455 #endif // USING_XVMC
6458 void VideoBuffers::RemoveInheritence(const VideoFrame *frame)
6460 - inheritence_lock.lock();
6461 + global_lock.lock();
6463 frame_map_t::iterator it = parents.find(frame);
6464 if (it == parents.end())
6466 - inheritence_lock.unlock();
6467 + global_lock.unlock();
6472 .arg(i).arg(DebugString(*pit)));
6475 - inheritence_lock.unlock();
6476 + global_lock.unlock();
6479 frame_queue_t VideoBuffers::Children(const VideoFrame *frame)
6480 Index: mythtv/libs/libavformat/aviobuf.c
6481 ===================================================================
6482 --- mythtv/libs/libavformat/aviobuf.c (.../tags/release-0-19) (revision 10931)
6483 +++ mythtv/libs/libavformat/aviobuf.c (.../branches/release-0-19-fixes) (revision 10931)
6484 @@ -164,7 +164,13 @@
6486 void url_fskip(ByteIOContext *s, offset_t offset)
6488 - url_fseek(s, offset, SEEK_CUR);
6489 + if (offset < 16384)
6491 + static unsigned char fskipbuf[16384];
6492 + get_buffer(s, fskipbuf, offset);
6495 + url_fseek(s, offset, SEEK_CUR);
6498 offset_t url_ftell(ByteIOContext *s)
6499 Index: mythtv/libs/libmyth/lcddevice.cpp
6500 ===================================================================
6501 --- mythtv/libs/libmyth/lcddevice.cpp (.../tags/release-0-19) (revision 10931)
6502 +++ mythtv/libs/libmyth/lcddevice.cpp (.../branches/release-0-19-fixes) (revision 10931)
6507 - QTextStream os(socket);
6508 + QTextStream os(socket->socketDevice());
6516 - QTextStream os(socket);
6517 + QTextStream os(socket->socketDevice());
6519 last_command = someText;
6523 // Just stream the text out the socket
6525 - os << someText << "\n" << flush;
6526 + os << someText << "\n";
6530 Index: mythtv/libs/libmyth/audiooutputca.cpp
6531 ===================================================================
6532 --- mythtv/libs/libmyth/audiooutputca.cpp (.../tags/release-0-19) (revision 10931)
6533 +++ mythtv/libs/libmyth/audiooutputca.cpp (.../branches/release-0-19-fixes) (revision 10931)
6536 #include "mythcontext.h"
6537 #include "audiooutputca.h"
6538 +#include "config.h"
6540 // this holds Core Audio member variables
6541 struct CoreAudioData {
6542 @@ -107,8 +108,10 @@
6543 bzero(&conv_in_desc, sizeof(AudioStreamBasicDescription));
6544 conv_in_desc.mSampleRate = audio_samplerate;
6545 conv_in_desc.mFormatID = kAudioFormatLinearPCM;
6546 - conv_in_desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
6547 - | kLinearPCMFormatFlagIsBigEndian;
6548 + conv_in_desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
6549 +#ifdef WORDS_BIGENDIAN
6550 + conv_in_desc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
6552 conv_in_desc.mBytesPerPacket = audio_bytes_per_sample;
6553 conv_in_desc.mFramesPerPacket = 1;
6554 conv_in_desc.mBytesPerFrame = audio_bytes_per_sample;
6555 Index: mythtv/libs/libmyth/util.cpp
6556 ===================================================================
6557 --- mythtv/libs/libmyth/util.cpp (.../tags/release-0-19) (revision 10931)
6558 +++ mythtv/libs/libmyth/util.cpp (.../branches/release-0-19-fixes) (revision 10931)
6559 @@ -1006,16 +1006,20 @@
6560 long long freespace = -1;
6561 QCString cstr = file_on_disk.local8Bit();
6563 - if (statfs(cstr, &statbuf) == 0)
6564 + total = used = -1;
6566 + // there are cases where statfs will return 0 (good), but f_blocks and
6567 + // others are invalid and set to 0 (such as when an automounted directory
6568 + // is not mounted but still visible because --ghost was used),
6569 + // so check to make sure we can have a total size > 0
6570 + if ((statfs(cstr, &statbuf) == 0) &&
6571 + (statbuf.f_blocks > 0) &&
6572 + (statbuf.f_bsize > 0))
6574 freespace = statbuf.f_bsize * (statbuf.f_bavail >> 10);
6575 total = statbuf.f_bsize * (statbuf.f_blocks >> 10);
6576 used = total - freespace;
6580 - freespace = total = used = -1;
6585 Index: mythtv/libs/libmyth/mythdialogs.cpp
6586 ===================================================================
6587 --- mythtv/libs/libmyth/mythdialogs.cpp (.../tags/release-0-19) (revision 10931)
6588 +++ mythtv/libs/libmyth/mythdialogs.cpp (.../branches/release-0-19-fixes) (revision 10931)
6589 @@ -2617,6 +2617,7 @@
6590 password_editor->setEchoMode(QLineEdit::Password);
6591 password_editor->setGeometry(textWidth + 20,10,135,30);
6592 password_editor->setBackgroundOrigin(ParentOrigin);
6593 + password_editor->setAllowVirtualKeyboard(false);
6594 connect(password_editor, SIGNAL(textChanged(const QString &)),
6595 this, SLOT(checkPassword(const QString &)));
6597 Index: mythtv/libs/libmyth/mythwidgets.cpp
6598 ===================================================================
6599 --- mythtv/libs/libmyth/mythwidgets.cpp (.../tags/release-0-19) (revision 10931)
6600 +++ mythtv/libs/libmyth/mythwidgets.cpp (.../branches/release-0-19-fixes) (revision 10931)
6602 (e->key() == Qt::Key_Enter) ||
6603 (e->key() == Qt::Key_Return)))
6605 - if (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1)
6606 + if ((allowVirtualKeyboard) &&
6607 + (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1))
6609 popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
6610 gContext->GetMainWindow()->detach(popup);
6611 @@ -726,10 +727,11 @@
6612 QWidget::focusNextPrevChild(true);
6613 emit tryingToLooseFocus(true);
6615 - else if (action == "SELECT" &&
6616 - (e->text().isNull() ||
6617 - (e->key() == Qt::Key_Enter) ||
6618 - (e->key() == Qt::Key_Return)))
6619 + else if ((action == "SELECT") &&
6620 + (!active_cycle) &&
6621 + ((e->text().isNull()) ||
6622 + (e->key() == Qt::Key_Enter) ||
6623 + (e->key() == Qt::Key_Return)))
6625 if (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1)
6631 - if (!handled && popup && popup->isShown())
6632 + if (popup && popup->isShown())
6635 QTextEdit::keyPressEvent(e);
6636 Index: mythtv/libs/libmyth/remotefile.h
6637 ===================================================================
6638 --- mythtv/libs/libmyth/remotefile.h (.../tags/release-0-19) (revision 10931)
6639 +++ mythtv/libs/libmyth/remotefile.h (.../branches/release-0-19-fixes) (revision 10931)
6642 long long GetFileSize(void);
6644 + void SetTimeout(bool fast);
6647 QSocketDevice *openSocket(bool control);
6653 + bool timeoutisfast;
6657 Index: mythtv/libs/libmyth/mythwidgets.h
6658 ===================================================================
6659 --- mythtv/libs/libmyth/mythwidgets.h (.../tags/release-0-19) (revision 10931)
6660 +++ mythtv/libs/libmyth/mythwidgets.h (.../branches/release-0-19-fixes) (revision 10931)
6661 @@ -122,17 +122,21 @@
6664 MythLineEdit(QWidget *parent=NULL, const char* widgetName=0) :
6665 - QLineEdit(parent, widgetName) { rw = true; Init(); };
6666 + QLineEdit(parent, widgetName)
6667 + { rw = true; allowVirtualKeyboard = true; Init(); };
6669 MythLineEdit(const QString& contents, QWidget *parent=NULL,
6670 const char* widgetName=0) :
6671 - QLineEdit(contents, parent, widgetName) { rw = true; Init(); };
6672 + QLineEdit(contents, parent, widgetName)
6673 + { rw = true; allowVirtualKeyboard = true; Init(); };
6675 virtual ~MythLineEdit();
6677 void setHelpText(QString help) { helptext = help; };
6678 void setRW(bool readwrite = true) { rw = readwrite; };
6679 void setRO() { rw = false; };
6680 + void setAllowVirtualKeyboard(bool allowKbd = true)
6681 + { allowVirtualKeyboard = allowKbd; }
6682 void setPopupPosition(PopupPosition pos) { popupPosition = pos; }
6683 PopupPosition getPopupPosition(void) { return popupPosition; }
6686 VirtualKeyboard *popup;
6689 + bool allowVirtualKeyboard;
6690 PopupPosition popupPosition;
6693 Index: mythtv/libs/libmyth/mythcontext.cpp
6694 ===================================================================
6695 --- mythtv/libs/libmyth/mythcontext.cpp (.../tags/release-0-19) (revision 10931)
6696 +++ mythtv/libs/libmyth/mythcontext.cpp (.../branches/release-0-19-fixes) (revision 10931)
6697 @@ -2621,9 +2621,13 @@
6698 d->LoadLogSettings();
6699 if (d->m_logenable == 1)
6701 + QString fullMsg = message;
6702 + if (!details.isEmpty())
6703 + fullMsg += ": " + details;
6705 if (message.left(21) != "Last message repeated")
6707 - if (message == d->lastLogStrings[module])
6708 + if (fullMsg == d->lastLogStrings[module])
6710 d->lastLogCounts[module] += 1;
6712 @@ -2639,7 +2643,7 @@
6715 d->lastLogCounts[module] = 0;
6716 - d->lastLogStrings[module] = message;
6717 + d->lastLogStrings[module] = fullMsg;
6721 @@ -2693,7 +2697,7 @@
6724 if (priority <= d->m_logprintlevel)
6725 - VERBOSE(VB_IMPORTANT, module + ": " + message);
6726 + VERBOSE(VB_IMPORTANT, module + ": " + fullMsg);
6730 Index: mythtv/libs/libmyth/remotefile.cpp
6731 ===================================================================
6732 --- mythtv/libs/libmyth/remotefile.cpp (.../tags/release-0-19) (revision 10931)
6733 +++ mythtv/libs/libmyth/remotefile.cpp (.../branches/release-0-19-fixes) (revision 10931)
6738 + timeoutisfast = false;
6740 query = "QUERY_FILETRANSFER %1";
6742 @@ -295,4 +296,34 @@
6743 Read(data.data(), filesize);
6749 +void RemoteFile::SetTimeout(bool fast)
6751 + if (timeoutisfast == fast)
6756 + VERBOSE(VB_NETWORK, "RemoteFile::Seek(): Called with no socket");
6760 + if (!sock->isOpen() || sock->error())
6763 + if (!controlSock->isOpen() || controlSock->error())
6766 + QStringList strlist = QString(query).arg(recordernum);
6767 + strlist << "SET_TIMEOUT";
6768 + strlist << QString::number((int)fast);
6771 + WriteStringList(controlSock, strlist);
6772 + ReadStringList(controlSock, strlist);
6775 + timeoutisfast = fast;
6778 Index: mythtv/libs/libavcodec/libavcodec.pro
6779 ===================================================================
6780 --- mythtv/libs/libavcodec/libavcodec.pro (.../tags/release-0-19) (revision 10931)
6781 +++ mythtv/libs/libavcodec/libavcodec.pro (.../branches/release-0-19-fixes) (revision 10931)
6784 QMAKE_LFLAGS_SHLIB += -single_module
6785 QMAKE_LFLAGS_SHLIB += -seg1addr 0xC3000000
6786 + QMAKE_LFLAGS_SHLIB += -read_only_relocs warning
6788 Index: mythtv/programs/mythfrontend/playbackbox.cpp
6789 ===================================================================
6790 --- mythtv/programs/mythfrontend/playbackbox.cpp (.../tags/release-0-19) (revision 10931)
6791 +++ mythtv/programs/mythfrontend/playbackbox.cpp (.../branches/release-0-19-fixes) (revision 10931)
6793 #include <qsqldatabase.h>
6801 // Main Recording List support
6802 fillListTimer(new QTimer(this)), connected(false),
6803 titleIndex(0), progIndex(0),
6806 curitem(NULL), delitem(NULL),
6810 gContext->addListener(this);
6812 - if (!recGroupPassword.isEmpty() || (titleList.count() <= 1) || initialFilt)
6813 + if ((!recGroupPassword.isEmpty()) ||
6814 + ((titleList.count() <= 1) && (progsInDB > 0)) ||
6816 showRecGroupChooser();
6818 gContext->addCurrentLocation((type == Delete)? "DeleteBox":"PlaybackBox");
6819 @@ -890,9 +894,13 @@
6822 QSize size = drawVideoBounds.size();
6823 + float saspect = ((float)size.width()) / ((float)size.height());
6824 + float vaspect = previewVideoNVP->GetVideoAspect();
6825 + size.setHeight((int) ceil(size.height() * (saspect / vaspect)));
6826 + size.setHeight(((size.height() + 7) / 8) * 8);
6827 + size.setWidth( ((size.width() + 7) / 8) * 8);
6828 const QImage &img = previewVideoNVP->GetARGBFrame(size);
6829 - uint xoff = max((size.width() - drawVideoBounds.width()) / 2, 0);
6830 - p->drawImage(drawVideoBounds.x() + xoff, drawVideoBounds.y(), img);
6831 + p->drawImage(drawVideoBounds.x(), drawVideoBounds.y(), img);
6834 /* have we timed out waiting for nvp to start? */
6835 @@ -1272,10 +1280,10 @@
6836 paintSkipUpdate = false;
6837 update(drawTotalBounds);
6839 + else if (arrowAccel)
6840 + showActionsSelected();
6841 else if (curitem && curitem->availableStatus != asAvailable)
6842 showAvailablePopup(curitem);
6843 - else if (arrowAccel)
6844 - showActionsSelected();
6847 void PlaybackBox::cursorDown(bool page, bool newview)
6848 @@ -1380,6 +1388,7 @@
6849 asCache[asKey] = p->availableStatus;
6855 // Clear autoDelete for the "all" list since it will share the
6856 @@ -1402,6 +1411,7 @@
6857 vector<ProgramInfo *>::iterator i = infoList->begin();
6858 for ( ; i != infoList->end(); i++)
6862 if ((((p->recgroup == recGroup) ||
6863 ((recGroup == "All Programs") &&
6864 @@ -1886,7 +1896,8 @@
6865 if (inTitle && haveGroupInfoSet)
6868 - if (curitem->availableStatus != asAvailable)
6869 + if ((curitem->availableStatus != asAvailable) &&
6870 + (curitem->availableStatus != asFileNotFound))
6871 showAvailablePopup(curitem);
6873 showActions(curitem);
6874 @@ -2068,7 +2079,21 @@
6876 delitem = new ProgramInfo(*toExp);
6878 - if (delitem->availableStatus != asAvailable)
6879 + if (fileExists(delitem) == false)
6882 + QString("PlaybackBox::showActions(): Error, %1 file not found")
6883 + .arg(delitem->pathname);
6884 + VERBOSE(VB_IMPORTANT, msg);
6886 + ProgramInfo *tmpItem = findMatchingProg(delitem);
6889 + tmpItem->availableStatus = asFileNotFound;
6890 + showFileNotFoundActionPopup(delitem);
6893 + else if (delitem->availableStatus != asAvailable)
6894 showAvailablePopup(delitem);
6896 showActionPopup(delitem);
6897 @@ -2647,6 +2672,34 @@
6898 expectingPopup = true;
6901 +void PlaybackBox::showFileNotFoundActionPopup(ProgramInfo *program)
6903 + if (!curitem || !program)
6906 + popup = new MythPopupBox(gContext->GetMainWindow(), drawPopupSolid,
6907 + drawPopupFgColor, drawPopupBgColor,
6908 + drawPopupSelColor, "action popup");
6910 + QString msg = QObject::tr("Recording Unavailable") + "\n";
6911 + msg += QObject::tr("The file for this recording can "
6912 + "not be found") + "\n";
6914 + initPopup(popup, program, "", msg);
6916 + QButton *detailsButton;
6917 + detailsButton = popup->addButton(tr("Show Program Details"), this,
6918 + SLOT(showProgramDetails()));
6920 + popup->addButton(tr("Delete"), this, SLOT(askDelete()));
6922 + popup->ShowPopup(this, SLOT(doCancel()));
6924 + detailsButton->setFocus();
6926 + expectingPopup = true;
6929 void PlaybackBox::initPopup(MythPopupBox *popup, ProgramInfo *program,
6930 QString message, QString message2)
6932 @@ -4129,8 +4182,7 @@
6933 if (!recGroupListBox)
6937 - recGroupListBox->currentText().section('[', 0, 0).simplifyWhiteSpace();
6938 + QString item = recGroupListBox->currentText().section(" [", 0, 0);
6940 if (item.left(5) == "-----")
6942 @@ -4147,8 +4199,7 @@
6944 void PlaybackBox::setGroupFilter(void)
6947 - recGroupListBox->currentText().section('[', 0, 0).simplifyWhiteSpace();
6948 + recGroup = recGroupListBox->currentText().section(" [", 0, 0);
6950 if (groupnameAsAllProg)
6951 groupDisplayName = recGroup;
6952 Index: mythtv/programs/mythfrontend/customrecord.cpp
6953 ===================================================================
6954 --- mythtv/programs/mythfrontend/customrecord.cpp (.../tags/release-0-19) (revision 10931)
6955 +++ mythtv/programs/mythfrontend/customrecord.cpp (.../branches/release-0-19-fixes) (revision 10931)
6958 m_csql << "program.stars >= 0.75 ";
6960 - m_clause->insertItem(tr("Person named in the credits"));
6961 + m_clause->insertItem(tr("Person named in the credits (Data Direct)"));
6962 m_cfrom << ", people, credits";
6963 m_csql << QString("people.name = 'Tom Hanks' \n"
6964 "AND credits.person = people.person \n"
6968 MSqlQuery query(MSqlQuery::InitCon());
6969 - query.prepare(QString("SELECT NULL FROM program,channel %1 WHERE\n%2")
6970 - .arg(from).arg(desc));
6971 + query.prepare(QString("SELECT NULL FROM (program,channel) "
6972 + "%1 WHERE\n%2").arg(from).arg(desc));
6974 if (query.exec() && query.isActive())
6976 Index: mythtv/programs/mythfrontend/tv_schedule.xml
6977 ===================================================================
6978 --- mythtv/programs/mythfrontend/tv_schedule.xml (.../tags/release-0-19) (revision 10931)
6979 +++ mythtv/programs/mythfrontend/tv_schedule.xml (.../branches/release-0-19-fixes) (revision 10931)
6981 <alttext lang="CA">Guia</alttext>
6982 <alttext lang="DE">EPG</alttext>
6983 <alttext lang="DK">Guide</alttext>
6984 - <alttext lang="DK">Dagskrá</alttext>
6985 + <alttext lang="IS">Dagskrá</alttext>
6986 <alttext lang="NL">Gids</alttext>
6987 <alttext lang="SV">Guide</alttext>
6988 <alttext lang="JA">ガイド</alttext>
6989 Index: mythtv/programs/mythfrontend/playbackbox.h
6990 ===================================================================
6991 --- mythtv/programs/mythfrontend/playbackbox.h (.../tags/release-0-19) (revision 10931)
6992 +++ mythtv/programs/mythfrontend/playbackbox.h (.../branches/release-0-19-fixes) (revision 10931)
6994 void promptEndOfRecording(ProgramInfo *);
6995 void showDeletePopup(ProgramInfo *, deletePopupType);
6996 void showActionPopup(ProgramInfo *program);
6997 + void showFileNotFoundActionPopup(ProgramInfo *program);
6998 void initPopup(MythPopupBox *popup, ProgramInfo *program,
6999 QString message, QString message2);
7002 int progIndex; ///< Index of selected item index on page
7003 QStringList titleList; ///< list of pages
7004 ProgramMap progLists; ///< lists of programs by page
7005 + int progsInDB; ///< total number of recordings in DB
7007 // Play List support
7008 QStringList playList; ///< list of selected items "play list"
7009 Index: mythtv/programs/mythfrontend/networkcontrol.cpp
7010 ===================================================================
7011 --- mythtv/programs/mythfrontend/networkcontrol.cpp (.../tags/release-0-19) (revision 10931)
7012 +++ mythtv/programs/mythfrontend/networkcontrol.cpp (.../branches/release-0-19-fixes) (revision 10931)
7014 message = "NETWORK_CONTROL SEEK BACKWARD";
7015 else if (tokens[2].contains(QRegExp("^\\d\\d:\\d\\d:\\d\\d$")))
7017 - int hours = tokens[2].left(0).toInt();
7018 + int hours = tokens[2].mid(0, 2).toInt();
7019 int minutes = tokens[2].mid(3, 2).toInt();
7020 int seconds = tokens[2].mid(6, 2).toInt();
7021 message = QString("NETWORK_CONTROL SEEK POSITION %1")
7022 Index: mythtv/programs/mythtranscode/mpeg2fix.cpp
7023 ===================================================================
7024 --- mythtv/programs/mythtranscode/mpeg2fix.cpp (.../tags/release-0-19) (revision 10931)
7025 +++ mythtv/programs/mythtranscode/mpeg2fix.cpp (.../branches/release-0-19-fixes) (revision 10931)
7026 @@ -1776,6 +1776,7 @@
7028 if (vFrame.count() && (file_end || vFrame.getLast()->isSequence))
7030 + MPEG2frame *seqFrame;
7031 if (ptsIncrement != vFrame.first()->mpeg2_seq.frame_period / 300)
7033 VERBOSE(MPF_IMPORTANT,
7034 @@ -1786,6 +1787,11 @@
7036 displayFrame->toFirst();
7038 + // since we might reorder the frames when coming out of a cutpoint
7039 + // me need to save the first frame here, as it is gauranteed to
7040 + // have a sequence header.
7041 + seqFrame = vFrame.current();
7043 while (vFrame.current() != vFrame.getLast())
7045 bool ptsorder_eq_dtsorder = false;
7046 @@ -1941,7 +1947,7 @@
7048 if (! new_discard_state)
7050 - AddSequence(markedFrame, vFrame.first());
7051 + AddSequence(markedFrame, seqFrame);
7052 RenumberFrames(frame_pos + Lreorder.at(),
7053 - GetFrameNum(markedFrame));
7055 Index: mythtv/programs/mythcommflag/main.cpp
7056 ===================================================================
7057 --- mythtv/programs/mythcommflag/main.cpp (.../tags/release-0-19) (revision 10931)
7058 +++ mythtv/programs/mythcommflag/main.cpp (.../branches/release-0-19-fixes) (revision 10931)
7060 return COMMFLAG_EXIT_INVALID_CMDLINE;
7063 - if (queueJobInstead)
7064 - return QueueCommFlagJob(chanid, starttime);
7067 return CopySkipListToCutList(chanid, starttime);
7069 @@ -1009,7 +1006,10 @@
7073 - FlagCommercials(chanid, starttime);
7074 + if (queueJobInstead)
7075 + QueueCommFlagJob(chanid, starttime);
7077 + FlagCommercials(chanid, starttime);
7081 @@ -1063,7 +1063,12 @@
7083 if ((flagStatus == COMM_FLAG_NOT_FLAGGED) &&
7085 - FlagCommercials(chanid, starttime);
7087 + if (queueJobInstead)
7088 + QueueCommFlagJob(chanid, starttime);
7090 + FlagCommercials(chanid, starttime);
7095 Index: mythtv/programs/mythbackend/mainserver.cpp
7096 ===================================================================
7097 --- mythtv/programs/mythbackend/mainserver.cpp (.../tags/release-0-19) (revision 10931)
7098 +++ mythtv/programs/mythbackend/mainserver.cpp (.../branches/release-0-19-fixes) (revision 10931)
7099 @@ -1919,11 +1919,8 @@
7101 if (table == "") m_sched->getAllPending(strList);
7103 - // We need a different connection from the scheduler proper
7104 - // DDCon exists, although it's designed for other purposes.
7105 - MSqlQueryInfo dbconn = MSqlQuery::DDCon();
7106 - Scheduler *sched = new Scheduler(false, encoderList,
7107 - table, &dbconn, m_sched);
7108 + Scheduler *sched = new Scheduler(false, encoderList,
7110 sched->FillRecordListFromDB(recordid);
7111 sched->getAllPending(strList);
7113 @@ -2940,6 +2937,12 @@
7114 long long ret = ft->Seek(curpos, pos, whence);
7115 encodeLongLong(retlist, ret);
7117 + else if (command == "SET_TIMEOUT")
7119 + bool fast = slist[2].toInt();
7120 + ft->SetTimeout(fast);
7125 VERBOSE(VB_IMPORTANT, QString("Unknown command: %1").arg(command));
7126 Index: mythtv/programs/mythbackend/scheduler.cpp
7127 ===================================================================
7128 --- mythtv/programs/mythbackend/scheduler.cpp (.../tags/release-0-19) (revision 10931)
7129 +++ mythtv/programs/mythbackend/scheduler.cpp (.../branches/release-0-19-fixes) (revision 10931)
7131 #define LOC_ERR QString("Scheduler, Error: ")
7133 Scheduler::Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
7134 - QString recordTbl, MSqlQueryInfo *databaseConnection,
7135 - Scheduler *master_sched)
7136 + QString recordTbl, Scheduler *master_sched)
7138 hasconflicts = false;
7141 master_sched->getAllPending(&reclist);
7144 - if (databaseConnection) dbConn = *databaseConnection;
7145 - else dbConn = MSqlQuery::SchedCon();
7146 + // Only the master scheduler should use SchedCon()
7148 + dbConn = MSqlQuery::SchedCon();
7150 + dbConn = MSqlQuery::DDCon();
7152 recordTable = recordTbl;
7154 @@ -1136,6 +1138,10 @@
7156 if (reschedQueue.count())
7158 + // We might have been inactive for a long time, so make
7159 + // sure our DB connection is fresh before continuing.
7160 + dbConn = MSqlQuery::SchedCon();
7162 gettimeofday(&fillstart, NULL);
7164 while (reschedQueue.count())
7165 @@ -1827,10 +1833,10 @@
7166 QString query = QString(
7167 "INSERT INTO recordmatch (recordid, chanid, starttime, manualid) "
7168 "SELECT RECTABLE.recordid, program.chanid, program.starttime, "
7169 -" IF(search = %1, recordid, 0) "
7170 -"FROM RECTABLE, program ").arg(kManualSearch) + fromclauses[clause] + QString(
7171 -" INNER JOIN channel ON (channel.chanid = program.chanid) "
7172 -"WHERE ") + whereclauses[clause] + QString(" AND channel.visible = 1 AND "
7173 +" IF(search = %1, recordid, 0) ").arg(kManualSearch) + QString(
7174 +"FROM (RECTABLE, program INNER JOIN channel "
7175 +" ON channel.chanid = program.chanid) ") + fromclauses[clause] + QString(
7176 +" WHERE ") + whereclauses[clause] + QString(" AND channel.visible = 1 AND "
7177 "((RECTABLE.type = %1 " // allrecord
7178 "OR RECTABLE.type = %2 " // findonerecord
7179 "OR RECTABLE.type = %3 " // finddailyrecord
7180 Index: mythtv/programs/mythbackend/housekeeper.cpp
7181 ===================================================================
7182 --- mythtv/programs/mythbackend/housekeeper.cpp (.../tags/release-0-19) (revision 10931)
7183 +++ mythtv/programs/mythbackend/housekeeper.cpp (.../branches/release-0-19-fixes) (revision 10931)
7188 - VERBOSE(VB_IMPORTANT, "Running HouseKeeping");
7189 gContext->LogEntry("mythbackend", LP_DEBUG,
7190 "Running housekeeping thread", "");
7192 Index: mythtv/programs/mythbackend/scheduler.h
7193 ===================================================================
7194 --- mythtv/programs/mythbackend/scheduler.h (.../tags/release-0-19) (revision 10931)
7195 +++ mythtv/programs/mythbackend/scheduler.h (.../branches/release-0-19-fixes) (revision 10931)
7199 Scheduler(bool runthread, QMap<int, EncoderLink *> *tvList,
7200 - QString recordTbl = "record", MSqlQueryInfo *dbConnUse = NULL,
7201 - Scheduler *master_sched = NULL);
7202 + QString recordTbl = "record", Scheduler *master_sched = NULL);
7205 void Reschedule(int recordid);
7206 Index: mythtv/programs/mythbackend/filetransfer.cpp
7207 ===================================================================
7208 --- mythtv/programs/mythbackend/filetransfer.cpp (.../tags/release-0-19) (revision 10931)
7209 +++ mythtv/programs/mythbackend/filetransfer.cpp (.../branches/release-0-19-fixes) (revision 10931)
7215 +void FileTransfer::SetTimeout(bool fast)
7217 + rbuffer->SetTimeout(fast);
7220 Index: mythtv/programs/mythbackend/autoexpire.cpp
7221 ===================================================================
7222 --- mythtv/programs/mythbackend/autoexpire.cpp (.../tags/release-0-19) (revision 10931)
7223 +++ mythtv/programs/mythbackend/autoexpire.cpp (.../branches/release-0-19-fixes) (revision 10931)
7226 if ((availFreeKB = getDiskSpace(record_file_prefix, tKB, uKB)) < 0)
7228 - QString msg = QString("ERROR: Could not calculate free space.");
7229 + QString msg = QString("ERROR: Could not calculate free space for %1.")
7230 + .arg(record_file_prefix);
7231 VERBOSE(VB_IMPORTANT, LOC + msg);
7232 gContext->LogEntry("mythbackend", LP_WARNING,
7233 "Autoexpire Recording", msg);
7234 Index: mythtv/programs/mythbackend/filetransfer.h
7235 ===================================================================
7236 --- mythtv/programs/mythbackend/filetransfer.h (.../tags/release-0-19) (revision 10931)
7237 +++ mythtv/programs/mythbackend/filetransfer.h (.../branches/release-0-19-fixes) (revision 10931)
7240 long long GetFileSize(void);
7242 + void SetTimeout(bool fast);
7245 bool readthreadlive;
7246 QMutex readthreadLock;
7247 Index: mythtv/programs/mythtv/main.cpp
7248 ===================================================================
7249 --- mythtv/programs/mythtv/main.cpp (.../tags/release-0-19) (revision 10931)
7250 +++ mythtv/programs/mythtv/main.cpp (.../branches/release-0-19-fixes) (revision 10931)
7253 using namespace std;
7255 -MythContext *gContext;
7257 static void *run_priv_thread(void *data)
7262 gContext->LoadQtConfig();
7264 +#if defined(Q_OS_MACX)
7265 + // Mac OS X doesn't define the AudioOutputDevice setting
7267 QString auddevice = gContext->GetSetting("AudioOutputDevice");
7268 if (auddevice == "" || auddevice == QString::null)
7271 "to run 'mythfrontend', not 'mythtv'.");
7272 return TV_EXIT_NO_AUDIO;
7276 print_verbose_messages |= VB_PLAYBACK | VB_LIBAV;// | VB_AUDIO;
7279 ProgramInfo *pginfo = new ProgramInfo();
7280 pginfo->endts = QDateTime::currentDateTime().addSecs(-180);
7281 pginfo->pathname = filename;
7282 + pginfo->isVideo = true;
7284 tv->Playback(pginfo);
7286 Index: mythtv/programs/mythfilldatabase/filldata.cpp
7287 ===================================================================
7288 --- mythtv/programs/mythfilldatabase/filldata.cpp (.../tags/release-0-19) (revision 10931)
7289 +++ mythtv/programs/mythfilldatabase/filldata.cpp (.../branches/release-0-19-fixes) (revision 10931)
7292 MSqlQuery query(MSqlQuery::InitCon());
7293 query.prepare("SELECT ch.chanid, nim.url "
7294 - "FROM channel ch, callsignnetworkmap csm "
7295 + "FROM (channel ch, callsignnetworkmap csm) "
7296 "RIGHT JOIN networkiconmap nim ON csm.network = nim.network "
7297 "WHERE ch.callsign = csm.callsign AND "
7298 "(icon = :NOICON OR icon = '') AND ch.sourceid = :SOURCEID");
7299 @@ -2174,7 +2174,8 @@
7300 0 /*service id*/, major, minor,
7301 false /*use on air guide*/, false /*hidden*/,
7302 false /*hidden in guide*/,
7303 - freqid, localfile, (*i).tvformat))
7304 + freqid, localfile, (*i).tvformat,
7307 cout << "### " << endl;
7308 cout << "### Channel inserted" << endl;
7309 @@ -3851,7 +3852,6 @@
7310 VERBOSE(VB_IMPORTANT, "Failed to fetch some program info");
7311 gContext->LogEntry("mythfilldatabase", LP_WARNING,
7312 "Failed to fetch some program info", "");
7313 - return FILLDB_EXIT_DB_ERROR;
7316 VERBOSE(VB_IMPORTANT, "Data fetching complete.");
7317 Index: mythtv/setup/backendsettings.cpp
7318 ===================================================================
7319 --- mythtv/setup/backendsettings.cpp (.../tags/release-0-19) (revision 10931)
7320 +++ mythtv/setup/backendsettings.cpp (.../branches/release-0-19-fixes) (revision 10931)
7324 #include "backendsettings.h"
7325 +#include "frequencies.h"
7326 #include "libmyth/mythcontext.h"
7327 #include "libmyth/settings.h"
7329 @@ -110,23 +111,10 @@
7331 GlobalComboBox *gc = new GlobalComboBox("FreqTable");
7332 gc->setLabel(QObject::tr("Channel frequency table"));
7333 - gc->addSelection("us-cable");
7334 - gc->addSelection("us-bcast");
7335 - gc->addSelection("us-cable-hrc");
7336 - gc->addSelection("us-cable-irc");
7337 - gc->addSelection("japan-bcast");
7338 - gc->addSelection("japan-cable");
7339 - gc->addSelection("europe-west");
7340 - gc->addSelection("europe-east");
7341 - gc->addSelection("italy");
7342 - gc->addSelection("newzealand");
7343 - gc->addSelection("australia");
7344 - gc->addSelection("ireland");
7345 - gc->addSelection("france");
7346 - gc->addSelection("china-bcast");
7347 - gc->addSelection("southafrica");
7348 - gc->addSelection("argentina");
7349 - gc->addSelection("australia-optus");
7351 + for (uint i = 0; chanlists[i].name; i++)
7352 + gc->addSelection(chanlists[i].name);
7354 gc->setHelpText(QObject::tr("Select the appropriate frequency table for "
7355 "your system. If you have an antenna, use a \"-bcast\" "