]> git.pld-linux.org Git - packages/mythtv.git/blame - mythtv-branch.diff
- obsolete
[packages/mythtv.git] / mythtv-branch.diff
CommitLineData
ecca4c51
ER
1Index: mythplugins/mythweb/themes/wml/header.php
2===================================================================
56a97e74
ER
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)
ecca4c51
ER
5@@ -26,4 +26,4 @@
6 <p><a href="<?php echo root ?>tv/upcoming"><?php echo t('Upcoming Recordings') ?></a></p>
7 <p><a href="<?php echo root ?>tv/recorded"><?php echo t('Recorded Programs') ?></a></p>
8 <p><a href="<?php echo root ?>tv/search"><?php echo t('Search') ?></a></p>
9-<p><a href="<?php echo root ?>status?xml"><?php echo t('Backend Status') ?></a></p>
10+<p><a href="<?php echo root ?>status/xml"><?php echo t('Backend Status') ?></a></p>
11Index: mythplugins/mythweb/themes/default/weather/weather.php
12===================================================================
56a97e74
ER
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)
ecca4c51
ER
15@@ -93,13 +93,13 @@
16 $tomorrow = date("m/d/Y", mktime(0, 0, 0, date("m") , date("d")+1, date("Y")));
17
18 switch($forecast->dayofweek) {
19+ case 0: $day = t('Sunday'); break;
20 case 1: $day = t('Monday'); break;
21 case 2: $day = t('Tuesday'); break;
22 case 3: $day = t('Wednesday'); break;
23 case 4: $day = t('Thursday'); break;
24 case 5: $day = t('Friday'); break;
25 case 6: $day = t('Saturday'); break;
26- case 7: $day = t('Sunday'); break;
27 default: $day = $forecast->date; break;
28 }
29
30Index: mythplugins/mythweb/themes/default/music/music.php
31===================================================================
56a97e74
ER
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)
ecca4c51
ER
34@@ -164,10 +164,12 @@
35
36 function print_header($filterPlaylist,$filterArtist,$filterAlbum,$filterGenre) {
37 $this->filterPlaylist=$filterPlaylist;
38-// Set the desired page title
39- $page_title = 'MythWeb - '.t('Music');
40-// Print the page header
41- require_once theme_dir.'/header.php';
42+ // Set the desired page title
43+ global $page_title, $Modules, $headers;
44+ $page_title = 'MythWeb - '.t('Music');
45+ // Print the page header
46+ require_once theme_dir.'/header.php';
47+
48 printf("<form action=\"".root."music\" method=\"GET\" >\n");
49 printf("<input type=\"hidden\" name=\"mode\" value=\"music\" />\n");
50
51Index: mythplugins/mythweb/themes/default/tv/detail.php
52===================================================================
56a97e74
ER
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)
ecca4c51
ER
55@@ -51,7 +51,7 @@
56 <?php } ?>
57 <div id="program_title">
58 <h1>
59- <a href="<?php echo root ?>tv/search/<?php echo urlencode($program->title) ?>&search_title=yes"><?php echo $schedule->title ?></a>
60+ <a href="<?php echo root ?>tv/search/<?php echo str_replace('%2F', '/', rawurlencode($schedule->title)) ?>?search_title=1"><?php echo $schedule->title ?></a>
61 </h1>
62 <div id="program_time">
63 <?php
64Index: mythplugins/mythweb/includes/mythbackend.php
65===================================================================
56a97e74
ER
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)
ecca4c51
ER
68@@ -15,10 +15,6 @@
69 // The character string used by the backend to separate records
70 define('backend_sep', '[]:[]');
71
72-// A couple of global variables to keep duplicate queries to a minimum
73- $Scheduled_Recordings = array();
74- $Recorded_Programs = array();
75-
76 // MYTH_PROTO_VERSION is defined in libmyth in mythtv/libs/libmyth/mythcontext.h
77 // and should be the current MythTV protocol version.
78 define('MYTH_PROTO_VERSION', 26);
79Index: mythplugins/mythweb/includes/programs.php
80===================================================================
56a97e74
ER
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)
ecca4c51
ER
83@@ -81,7 +81,9 @@
84 /**/
85 function &load_all_program_data($start_time, $end_time, $chanid = false, $single_program = false, $extra_query = '') {
86 global $Channels, $db;
87- // Make a local hash of channel chanid's with references to the actual channel data
88+ // Make a local hash of channel chanid's with references to the actual
89+ // channel data (Channels are not indexed by anything in particular, so
90+ // that the user can sort by chanid or channum).
91 $channel_hash = array();
92 // An array (that later gets converted to a string) containing the id's of channels we want to load
93 $these_channels = array();
94@@ -104,7 +106,7 @@
95 load_all_channels();
96 // Scan through the channels array and actually assign those references
97 foreach (array_keys($Channels) as $key) {
98- $channel_hash[$Channels[$key]->chanid] = &$Channels[$key];
99+ $channel_hash[$Channels[$key]->chanid] =& $Channels[$key];
100 // Reinitialize the programs array for this channel
101 $Channels[$key]->programs = array();
102 // Keep track of this channel id in case we're only grabbing info for certain channels - workound included to avoid blank chanid's
103@@ -130,11 +132,13 @@
104 LEFT JOIN programrating USING (chanid, starttime)
105 LEFT JOIN oldrecorded
106 ON oldrecorded.recstatus IN (-3, 11)
107- AND IF(oldrecorded.programid OR oldrecorded.seriesid,
108+ AND IF(oldrecorded.programid AND oldrecorded.seriesid,
109 oldrecorded.programid = program.programid
110 AND oldrecorded.seriesid = program.seriesid,
111- oldrecorded.title = program.title
112- AND oldrecorded.subtitle = program.subtitle
113+ oldrecorded.title AND oldrecorded.subtitle
114+ AND oldrecorded.description
115+ AND oldrecorded.title = program.title
116+ AND oldrecorded.subtitle = program.subtitle
117 AND oldrecorded.description = program.description
118 )
119 LEFT JOIN channel ON program.chanid = channel.chanid
120@@ -156,8 +160,12 @@
121 // The extra query, if there is one
122 if ($extra_query)
123 $query .= ' AND '.$extra_query;
124- // Group, sort and query
125+ // Group and sort
126 $query .= ' GROUP BY program.chanid, program.starttime ORDER BY program.starttime';
127+ // Limit
128+ if ($single_program)
129+ $query .= ' LIMIT 1';
130+ // Query
131 $sh = $db->query($query,
132 star_character, max_stars, max_stars);
133 // No results
134@@ -188,12 +196,8 @@
135 // Cleanup
136 $sh->finish();
137 // If channel-specific information was requested, return an array of those programs, or just the first/only one
138- if ($chanid) {
139- if ($single_program)
140- return $channel_hash[$chanid]->programs[0];
141- else
142- return $channel_hash[$chanid]->programs;
143- }
144+ if ($chanid && $single_program)
145+ return $these_programs[0];
146 // Just in case, return an array of all programs found
147 return $these_programs;
148 }
149@@ -272,18 +276,18 @@
150 $this->endtime = $data[12]; # show end-time
151 // Is this a previously-recorded program? Calculate the filesize
152 if (!empty($this->filename)) {
153- $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low;
154- }
155- // Ah, a scheduled recording - let's load more information about it, to be parsed in below
156- elseif ($this->chanid) {
157- unset($this->filename);
158- // Kludge to avoid redefining the object, which doesn't work in php5
159- $tmp = @get_object_vars(load_one_program($this->starttime, $this->chanid));
160- if (is_array($tmp) && count($tmp) > 0) {
161- foreach ($tmp as $key => $value) {
162- $this->$key = $value;
163- }
164+ if (function_exists('gmp_add')) {
165+ // GMP functions should work better with 64 bit numbers.
166+ $size = gmp_add($fs_low,
167+ gmp_mul('4294967296',
168+ gmp_add($fs_high, $fs_low < 0 ? '1' : '0'))
169+ );
170+ $this->filesize = gmp_strval($size);
171 }
172+ else {
173+ // This is inaccurate, but it's the best we can get without GMP.
174+ $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low;
175+ }
176 }
177 // Load the remaining info we got from mythbackend
178 $this->title = $data[0]; # program name/title
179@@ -291,14 +295,14 @@
180 $this->description = $data[2]; # episode description
181 $this->category = $data[3];
182 #$chanid = $data[4]; # Extracted a few lines earlier
183- #$channum = $data[5];
184- #$callsign = $data[6];
185+ $this->channum = $data[5];
186+ $this->callsign = $data[6];
187 $this->channame = $data[7];
188 #$pathname = $data[8]; # Extracted a few lines earlier
189 #$fs_high = $data[9]; # Extracted a few lines earlier
190 #$fs_low = $data[10]; # Extracted a few lines earlier
191- #$starttime = $data[11]; # Extracted a few lines earlier
192- #$endtime = $data[12]; # Extracted a few lines earlier
193+ #$this->starttime = $data[11]; # Extracted a few lines earlier
194+ #$this->endtime = $data[12]; # Extracted a few lines earlier
195 $this->hostname = $data[16];
196 #$this->sourceid = $data[17];
197 $this->cardid = $data[18];
198@@ -320,9 +324,9 @@
199 $this->programid = $data[34];
200 $this->lastmodified = $data[35];
201 $this->recpriority = $data[36];
202- #$this->airdate = $data[37];
203- #$this->hasairdate = $data[38];
204- $this->timestretch = $program_data[39];
205+ $this->airdate = date('Y-m-d', $data[37]);
206+ $this->hasairdate = $data[38];
207+ $this->timestretch = $data[39];
208 $this->recpriority2 = $data[40];
209 // Assign the program flags
210 $this->has_commflag = ($progflags & 0x01) ? true : false; // FL_COMMFLAG = 0x01
211@@ -363,8 +367,8 @@
212 $this->title_pronounce = $data['title_pronounce'];
213 $this->recstatus = $data['recstatus'];
214
215- if ($program_data['tsdefault']) {
216- $this->timestretch = $program_data['tsdefault'];
217+ if ($data['tsdefault']) {
218+ $this->timestretch = $data['tsdefault'];
219 } else {
220 $this->timestretch = 1.0;
221 }
222@@ -387,12 +391,14 @@
223 // Now we really should scan the $Channel array and add a link to this program's channel
224 foreach (array_keys($Channels) as $key) {
225 if ($Channels[$key]->chanid == $this->chanid) {
226- $this->channel = &$Channels[$key];
227+ $this->channel =& $Channels[$key];
228 break;
229 }
230 }
231+ // Not found
232+ if (!$this->channel)
233+ $this->channel =& load_one_channel($this->chanid);
234 }
235-
236 // Calculate the duration
237 if ($this->recendts)
238 $this->length = $this->recendts - $this->recstartts;
239Index: mythplugins/mythweb/includes/utils.php
240===================================================================
56a97e74
ER
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)
ecca4c51
ER
243@@ -276,7 +276,7 @@
244 static $first_run=true;
245 if($first_run) {
246 $first_run=false;
247- echo '<script type="text/javascript" src="/js/debug.js"></script>';
248+ echo '<script type="text/javascript" src="'.root.'js/debug.js"></script>';
249 }
250 // Put our data into a string
251 if (is_array($data) || is_object($data))
252Index: mythplugins/mythweb/includes/init.php
253===================================================================
56a97e74
ER
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)
ecca4c51
ER
256@@ -16,28 +16,15 @@
257 *
258 /**/
259
260-/**
261- * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some
262- * other lesser means. It contains most of the information required for
263- * figuring out what functions the user wants to access.
264- *
265- * @global array $GLOBALS['Path']
266- * @name $Path
267-/**/
268- global $Path;
269- $Path = explode('/', preg_replace('/^\/+/', '', // Remove leading slashes
270- preg_replace('/[\s]+/', ' ', // Convert extra whitespace
271- // Grab the path info from various different places.
272- array_key_exists('PATH_INFO', $_SERVER)
273- && $_SERVER['PATH_INFO']
274- ? $_SERVER['PATH_INFO']
275- : (array_key_exists('PATH_INFO', $_ENV)
276- && $_ENV['PATH_INFO']
277- ? $_ENV['PATH_INFO']
278- : $_GET['PATH_INFO']
279- )
280- ))
281- );
282+// mod_redirect can do some weird things when php is run in cgi mode
283+ $keys = preg_grep('/^REDIRECT_/', array_keys($_SERVER));
284+ if (!empty($keys)) {
285+ foreach ($keys as $key) {
286+ $key = substr($key, 9);
287+ if (!array_key_exists($key, $_SERVER))
288+ $_SERVER[$key] = $_SERVER["REDIRECT_$key"];
289+ }
290+ }
291
292 // Clean the document root variable and make sure it doesn't have a trailing slash
293 $_SERVER['DOCUMENT_ROOT'] = preg_replace('/\/+$/', '', $_SERVER['DOCUMENT_ROOT']);
294@@ -94,6 +81,29 @@
295 exit;
296 }
297
298+/**
299+ * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some
300+ * other lesser means. It contains most of the information required for
301+ * figuring out what functions the user wants to access.
302+ *
303+ * @global array $GLOBALS['Path']
304+ * @name $Path
305+/**/
306+ global $Path;
307+ $Path = explode('/', preg_replace('/^\/+/', '', // Remove leading slashes
308+ preg_replace('/[\s]+/', ' ', // Convert extra whitespace
309+ // Grab the path info from various different places.
310+ array_key_exists('PATH_INFO', $_SERVER)
311+ && $_SERVER['PATH_INFO']
312+ ? $_SERVER['PATH_INFO']
313+ : (array_key_exists('PATH_INFO', $_ENV)
314+ && $_ENV['PATH_INFO']
315+ ? $_ENV['PATH_INFO']
316+ : $_GET['PATH_INFO']
317+ )
318+ ))
319+ );
320+
321 // Load the database connection routines
322 require_once 'includes/db.php';
323
324Index: mythplugins/mythweb/includes/mobile.php
325===================================================================
56a97e74
ER
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)
ecca4c51
ER
328@@ -74,58 +74,56 @@
329 * If you don't know the screensize of some mobile terminal then use
330 * an empty array or approximate dimensions.
331 */
332- $mobiles = array(/* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */
333- 'Series 60' => array('width' => 176, 'height' => 208),
334- 'Series60' => array('width' => 176, 'height' => 208),
335- 'C500' => array('width'=>176, 'height'=> 220), // SPV C500
336+ $mobiles = array(
337+ /* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */
338+ 'Series 60' => array('width' => 176, 'height' => 208),
339+ 'Series60' => array('width' => 176, 'height' => 208),
340+ 'C500' => array('width'=>176, 'height'=> 220), // SPV C500
341+ /* Phones using the Series 90 platform, e.g. Nokia 7710. */
342+ 'Series 90' => array('width' => 640, 'height' => 320),
343+ 'Series90' => array('width' => 640, 'height' => 320),
344+ /* The following strings are added for the Palm browser WebPro
345+ * WebPro sometimes supplies the screen dimensions, but sometimes not
346+ * but we try to detect the best as possible */
347+ '240x320' => array('width' => 240, 'height' => 320), // PocketPC IE
348+ '320x320' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
349+ '320x480' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
350+ '480x320' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
351+ '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
352+ '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
353+ '320x320x16' => array('width' => 320, 'height' => 320),
354+ 'WebPro' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
355+ /* A generic mobile phone using Symbian OS. All Symbian phones don't
356+ * necessarily have the same screen size so if you want to include
357+ * some specific Symbian phones then place them above this line. */
358+ 'Symbian' => array('width' => 176, 'height' => 208),
359
360- /* Phones using the Series 90 platform, e.g. Nokia 7710. */
361- 'Series 90' => array('width' => 640, 'height' => 320),
362- 'Series90' => array('width' => 640, 'height' => 320),
363+ 'Nokia' => array(), // Nokia phones and emulators
364+ 'Eric' => array(), // Ericsson WAP phones and emulators
365+ 'WapI' => array(), // Ericsson WapIDE 2.0
366+ 'MC21' => array(), // Ericsson MC218
367+ 'AUR ' => array(), // Ericsson R320
368+ 'R380' => array(), // Ericsson R380
369+ 'UP.B' => array(), // UP.Browser
370+ 'WinW' => array(), // WinWAP browser
371+ 'UPG1' => array(), // UP.SDK 4.0
372+ 'upsi' => array(), // another kind of UP.Browser ??
373+ 'QWAP' => array(), // unknown QWAPPER browser
374+ 'Jigs' => array(), // unknown JigSaw browser
375+ 'Java' => array(), // unknown Java based browser
376+ 'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?)
377+ 'MITS' => array(), // unknown Mitsubishi browser
378+ 'MOT-' => array(), // unknown browser (UP based?)
379+ 'My S' => array(), // unknown Ericsson devkit browser ?
380+ 'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de
381+ 'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de
382+ 'ALAV' => array(), // yet another unknown UP based browser ?
383+ 'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?)
384+ 'LGE-' => array(), // LG phones
385
386- /* The following strings are added for the Palm browser WebPro
387- * WebPro sometimes supplies the screen dimensions, but sometimes not
388- * but we try to detect the best as possible
389- */
390- '320x480' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
391- '480x320' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
392- '320x320' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
393- '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
394- '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
395- '320x320x16' => array('width' => 320, 'height' => 320),
396- 'WebPro' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
397-
398- /* A generic mobile phone using Symbian OS. All Symbian phones don't
399- * necessarily have the same screen size so if you want to include
400- * some specific Symbian phones then place them above this line. */
401- 'Symbian' => array('width' => 176, 'height' => 208),
402-
403- 'Nokia' => array(), // Nokia phones and emulators
404- 'Eric' => array(), // Ericsson WAP phones and emulators
405- 'WapI' => array(), // Ericsson WapIDE 2.0
406- 'MC21' => array(), // Ericsson MC218
407- 'AUR ' => array(), // Ericsson R320
408- 'R380' => array(), // Ericsson R380
409- 'UP.B' => array(), // UP.Browser
410- 'WinW' => array(), // WinWAP browser
411- 'UPG1' => array(), // UP.SDK 4.0
412- 'upsi' => array(), // another kind of UP.Browser ??
413- 'QWAP' => array(), // unknown QWAPPER browser
414- 'Jigs' => array(), // unknown JigSaw browser
415- 'Java' => array(), // unknown Java based browser
416- 'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?)
417- 'MITS' => array(), // unknown Mitsubishi browser
418- 'MOT-' => array(), // unknown browser (UP based?)
419- 'My S' => array(), // unknown Ericsson devkit browser ?
420- 'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de
421- 'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de
422- 'ALAV' => array(), // yet another unknown UP based browser ?
423- 'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?)
424- 'LGE-' => array(), // LG phones
425-
426- /* For debugging: you can try out the mobile mode without a mobile phone.
427- * Replace 'Opera' with your browser. Comment out for release version. */
428- //'Opera' => array('width' => 176, 'height' => 208)
429+ /* For debugging: you can try out the mobile mode without a mobile phone.
430+ * Replace 'Opera' with your browser. Comment out for release version. */
431+ //'Opera' => array('width' => 176, 'height' => 208)
432 );
433
434 /* Scan through $mobiles and try to find matching user agent. */
435Index: mythplugins/mythweb/includes/recording_schedules.php
436===================================================================
56a97e74
ER
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)
ecca4c51
ER
439@@ -68,10 +68,14 @@
440 // Cleanup
441 mysql_free_result($result);
442
443+// Initialize
444+ global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
445+ $Scheduled_Recordings = array();
446+ $Num_Conflicts = 0;
447+ $Num_Scheduled = 0;
448+
449 // Load all of the scheduled recordings. We will need them at some point, so we
450 // might as well get it overwith here.
451- global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
452- $Scheduled_Recordings = array();
453 foreach (get_backend_rows('QUERY_GETALLPENDING', 2) as $key => $program) {
454 // The offset entry
455 if ($key === 'offset') {
456Index: mythplugins/mythweb/includes/session.php
457===================================================================
56a97e74
ER
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)
ecca4c51
ER
460@@ -19,8 +19,8 @@
461
462 // Start the session
463 session_name('mythweb_id');
464- session_set_cookie_params(60 * 60 * 30, '/'); // 30 day timeout on cookies
465- ini_set('session.gc_maxlifetime', 60 * 60 * 30); // ... and sessions
466+ session_set_cookie_params(60 * 60 * 24 * 365, '/'); // 1 year timeout on cookies
467+ ini_set('session.gc_maxlifetime', 60 * 60 * 24 * 30); // 30 day timeout on sessions
468 session_set_save_handler('sess_do_nothing', 'sess_do_nothing', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc');
469 session_start();
470
471Index: mythplugins/mythweb/modules/weather/handler.php
472===================================================================
56a97e74
ER
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)
ecca4c51
ER
475@@ -222,8 +222,10 @@
476
477 $data = explode("|", $data);
478 for($i = 0;$i<5;$i++) {
479- $forecast = new Forecast($data[5 + $i],$data[$i]);
480- $forecast->dayofweek = $data[$i];
481+ # mktime uses 0-6; msnbc gives us 1-7; adjust msnbc to match mktime
482+ $dayofweek = $data[$i] - 1;
483+ $forecast = new Forecast($data[5 + $i],$dayofweek);
484+ $forecast->dayofweek = $dayofweek;
485 list($forecast->DescImage,$forecast->DescText) = getImageAndDescFromId($data[15 + $i]);
486 $forecast->DescImage = (strlen($forecast->DescImage) > 0) ? $forecast->DescImage : "unknown.png";
487 $forecast->DescText = (strlen($forecast->DescText) > 0) ? $forecast->DescText : t('Unknown') . " (" . $data[15+$i] . ")";
488Index: mythplugins/mythweb/modules/status/handler.php
489===================================================================
56a97e74
ER
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)
ecca4c51
ER
492@@ -18,14 +18,17 @@
493 $masterhost = get_backend_setting('MasterServerIP');
494 $statusport = get_backend_setting('BackendStatusPort');
495
496+// XML mode?
497+ $xml_param = ($Path[1] == 'xml') ? '/xml' : '';
498+
499 // Make sure the content is interpreted as UTF-8
500 header('Content-Type: text/html; charset=UTF-8');
501
502 // Load the status page
503 if (function_exists('file_get_contents'))
504- $status = file_get_contents("http://$masterhost:$statusport");
505+ $status = file_get_contents("http://$masterhost:$statusport$xml_param");
506 else
507- $status = implode("\n", file("http://$masterhost:$statusport"));
508+ $status = implode("\n", file("http://$masterhost:$statusport$xml_param"));
509
510 // Extract the page title
511 preg_match('#<title>(.+?)</title>#s', $status, $title);
512Index: mythplugins/mythweb/modules/backend_log/handler.php
513===================================================================
56a97e74
ER
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)
ecca4c51
ER
516@@ -16,7 +16,7 @@
517 // Where to start searching from
518 $_GET['start'] = intVal($_GET['start']);
519 if ($_GET['start'] < 1)
520- $_GET['start'] = 1;
521+ $_GET['start'] = 0;
522
523 // How many entries to show?
524 $_GET['show'] = intVal($_GET['show']);
525Index: mythplugins/mythweb/modules/tv/upcoming.php
526===================================================================
56a97e74
ER
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)
ecca4c51
ER
529@@ -103,8 +103,9 @@
530 continue;
531 }
532 // Skip deactivated shows?
533- elseif (!$_SESSION['scheduled_recordings']['disp_deactivated']) {
534- continue;
535+ elseif ($show->recstatus != 'Recording') {
536+ if (!$_SESSION['scheduled_recordings']['disp_deactivated'])
537+ continue;
538 }
539 // Assign a reference to this show to the various arrays
540 $all_shows[] =& $Scheduled_Recordings[$channum][$starttime][$key];
541Index: mythplugins/mythweb/modules/tv/recorded.php
542===================================================================
56a97e74
ER
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)
ecca4c51
ER
545@@ -128,9 +128,21 @@
546 continue;
547 // Get the length (27 == recendts; 26 == recstartts)
548 $length = $record[27] - $record[26];
549- // Keep track of the total time and disk space used
550+ // Keep track of the total time and disk space used (9 == fs_high; 10 == fs_low)
551 $Total_Time += $length;
552- $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10]; // 9 == fs_high; 10 == fs_low;
553+ if (function_exists('gmp_add')) {
554+ // GMP functions should work better with 64 bit numbers.
555+ $size = gmp_add($record[10],
556+ gmp_mul('4294967296',
557+ gmp_add($record[9], $record[10] < 0 ? '1' : '0')
558+ )
559+ );
560+ $Total_Used = gmp_strval(gmp_add($Total_Used, $size));
561+ }
562+ else {
563+ // This is inaccurate, but it's the best we can get without GMP.
564+ $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10];
565+ }
566 // keep track of their names and how many episodes we have recorded
567 $Total_Programs++;
568 $Groups[$record[30]]++;
569@@ -223,8 +235,28 @@
570
571 // How much free disk space on the backend machine?
572 list($size_high, $size_low, $used_high, $used_low) = explode(backend_sep, backend_command('QUERY_FREE_SPACE'));
573- define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024);
574- define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024);
575+ if (function_exists('gmp_add')) {
576+ // GMP functions should work better with 64 bit numbers.
577+ $size = gmp_mul('1024',
578+ gmp_add($size_low,
579+ gmp_mul('4294967296',
580+ gmp_add($size_high, $size_low < 0 ? '1' : '0'))
581+ )
582+ );
583+ define(disk_size, gmp_strval($size));
584+ $size = gmp_mul('1024',
585+ gmp_add($used_low,
586+ gmp_mul('4294967296',
587+ gmp_add($used_high, $used_low < 0 ? '1' : '0'))
588+ )
589+ );
590+ define(disk_used, gmp_strval($size));
591+ }
592+ else {
593+ // This is inaccurate, but it's the best we can get without GMP.
594+ define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024);
595+ define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024);
596+ }
597
598 // Load the class for this page
599 require_once theme_dir.'tv/recorded.php';
600Index: mythplugins/mythweb/.htaccess
601===================================================================
56a97e74
ER
602--- mythplugins/mythweb/.htaccess (.../tags/release-0-19) (revision 10931)
603+++ mythplugins/mythweb/.htaccess (.../branches/release-0-19-fixes) (revision 10931)
ecca4c51
ER
604@@ -22,6 +22,7 @@
605 # AuthName "MythTV"
606 # AuthDigestFile /var/www/htdigest
607 # Require valid-user
608+# BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On
609
610 # MythTV now uses the correct file suffix for mpeg files, so all .nuv files
611 # should actually be NuppleVideo. However, apache probably doesn't know what
612@@ -66,8 +67,6 @@
613
614 php_value memory_limit 32M
615
616- php_value session.save_path php_sessions
617-
618 php_value output_buffering 4096
619 php_value register_globals 0
620 php_value magic_quotes_gpc 0
621Index: mythplugins/mythweb/js/debug.js
622===================================================================
623--- mythplugins/mythweb/js/debug.js (.../tags/release-0-19) (revision 0)
56a97e74 624+++ mythplugins/mythweb/js/debug.js (.../branches/release-0-19-fixes) (revision 10931)
ecca4c51
ER
625@@ -0,0 +1,24 @@
626+/**
627+ * A random assortment of javascript debug routines
628+ *
629+ * @url $URL$
630+ * @date $Date$
631+ * @version $Revision$
632+ * @author $Author$
633+ * @copyright Silicon Mechanics
634+ * @license LGPL
635+ *
636+ * @package SiMech
637+ * @subpackage Javascript
638+ *
639+/**/
640+
641+ var debug_window_handle;
642+// Create a debug window and debug into it
643+ function debug_window(string) {
644+ if (!debug_window_handle || debug_window_handle.closed) {
645+ debug_window_handle = window.open('', 'Debug Window','scrollbars, resizable, width=400, height=600');
646+ debug_window_handle.document.write('<html><body style="font-size: 9pt; background-color: #f88;">');
647+ }
648+ debug_window_handle.document.write('<pre>'+string+'</pre><hr>');
649+ }
650
651Property changes on: mythplugins/mythweb/js/debug.js
652___________________________________________________________________
653Name: svn:eol-style
654 + native
655Name: svn:mime-type
656 + text/x-javascript
657Name: svn:keywords
658 + Date Revision Author HeadURL
659
660Index: mythplugins/mythweb/js/browser.js
661===================================================================
56a97e74
ER
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)
ecca4c51
ER
664@@ -215,14 +215,18 @@
665 browser.is_css = (document.body && document.body.style)
666 browser.is_w3c = (browser.is_css && browser.getElementById)
667
668-// Cookie support
669- var tmp = document.cookie;
670- document.cookie = 'cookies=true';
671- browser.cookies = (document.cookie) ? true : false;
672- document.cookie = tmp;
673+// Cookie support -- only create a cookie if there isn't one already. It seems
674+// that doing this can override the exipiration info in existing cookies.
675+ browser.cookies = (document.cookie) ? true : false;
676+ if (!browser.cookies) {
677+ var tmp = document.cookie;
678+ document.cookie = 'cookie_test=true';
679+ browser.cookies = (document.cookie) ? true : false;
680+ document.cookie = tmp;
681+ }
682
683 // Java support
684- browser.java = navigator.javaEnabled();
685+ browser.java = navigator.javaEnabled();
686
687 /****************************** Plugin Support ******************************/
688
689Index: mythplugins/mythweb/README
690===================================================================
56a97e74
ER
691--- mythplugins/mythweb/README (.../tags/release-0-19) (revision 10931)
692+++ mythplugins/mythweb/README (.../branches/release-0-19-fixes) (revision 10931)
ecca4c51
ER
693@@ -1,18 +1,12 @@
694 This is the README file for the MythWeb package.
695-January 17, 2006
696+March 6, 2006
697
698-Version: .19 pre
699-(c) 2002-2006 Thor Sigvaldason <mythtv(a)lamedomainname(o)com>
700+Version: .19
701+(c) 2002-2006 Chris Petersen <mythweb(a)forevermore(o)net>
702 Isaac Richards <ijr(a)po(o)cwru(o)edu>
703- Chris Petersen <mythweb(a)forevermore(o)net>
704+ Thor Sigvaldason <mythtv(a)lamedomainname(o)com>
705+ and others... (see mythtv.org commit logs for details)
706
707-with contributions from many people including:
708-
709-Michael Kedl <kedlm(a)knology(o)net>
710-Jonathan Kolb <jkolb(a)greyshift(o)net
711-Ed Wildgoose <edward(o)wildgoose(a)frmhedge(o)com>
712-Kenneth Aafloy <ke-aa(a)frisurf(o)no>
713-
714 MythWeb is distributed under the GNU GENERAL PUBLIC LICENSE version 2, and where
715 noted with the @license tag, the LESSER GENERAL PUBLIC LICENSE version 2.
716 Please see http://www.gnu.org for details and the specific text of the license.
717@@ -63,10 +57,22 @@
718
719 In order for the included .htaccess to work properly, you will need to
720 set apache's "AllowOverride" setting to "All" (or at least "Options") for
721-the root mythweb directory. This directive lives within <Directory/> tags,
722-so make sure you're changing the setting for the correct directory. You will
723-also need to make sure that the following apache modules are enabled:
724+the root mythweb directory. This directive lives within <Directory> tags,
725+so make sure you're changing the setting for the correct directory. Please
726+keep in mind that most distros correctly disable everything for <Directory />,
727+and then later override those with something like <Directory /var/www/html>.
728+The simplest way to do this is to put a file into /etc/httpd/conf.d (or
729+whatever your distro calls it) containing something like:
730
731+ <Directory "/var/www/html/mythweb" >
732+ Options FollowSymLinks
733+ AllowOverride All
734+ </Directory>
735+
736+Just make sure that the path points to your MythWeb installation, since that
737+will likely differ from system to system. You will also need to make sure that
738+the following apache modules are enabled:
739+
740 mod_env
741 mod_rewrite
742
743Index: mythplugins/mythdvd/mtd/jobthread.cpp
744===================================================================
56a97e74
ER
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)
ecca4c51
ER
747@@ -11,6 +11,7 @@
748 #include <sys/types.h>
749 #include <sys/stat.h>
750 #include <fcntl.h>
751+#include <unistd.h>
752
753 #include <iostream>
754 using namespace std;
755Index: mythplugins/mythdvd/mtd/mtd.cpp
756===================================================================
56a97e74
ER
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)
ecca4c51
ER
759@@ -8,6 +8,7 @@
760
761 */
762
763+#include <unistd.h>
764 #include <qstringlist.h>
765 #include <qregexp.h>
766 #include <qdir.h>
767Index: mythplugins/mythdvd/mtd/logging.cpp
768===================================================================
56a97e74
ER
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)
ecca4c51
ER
771@@ -9,6 +9,7 @@
772 */
773 #include "logging.h"
774
775+#include <unistd.h>
776 #include <qdatetime.h>
777
778 #include <mythtv/mythcontext.h>
779Index: mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp
780===================================================================
56a97e74
ER
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)
ecca4c51
ER
783@@ -12,6 +12,7 @@
784 #include "metadata.h"
785 #include "metaiooggvorbiscomment.h"
786
787+#include <mythtv/mythconfig.h>
788 #include <mythtv/mythcontext.h>
789
790 // static functions for OggVorbis
791@@ -240,8 +241,13 @@
792 seekTime = -1.0;
793 }
794
795+#ifdef WORDS_BIGENDIAN
796+ len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 1, 2, 1,
797+ &section);
798+#else
799 len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1,
800 &section);
801+#endif
802
803 if (len > 0) {
804 bitrate = ov_bitrate_instant(&oggfile) / 1000;
805Index: mythplugins/mythmusic/mythmusic/flacdecoder.cpp
806===================================================================
56a97e74
ER
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)
ecca4c51
ER
809@@ -12,6 +12,7 @@
810 #include "metadata.h"
811 #include "metaioflacvorbiscomment.h"
812
813+#include <mythtv/mythconfig.h>
814 #include <mythtv/mythcontext.h>
815
816 #include <qtimer.h>
817@@ -102,7 +103,11 @@
818 for (channel = 0; channel < chan; channel++)
819 {
820 sample = (FLAC__int8)buffer[channel][cursamp];
821+#ifdef WORDS_BIGENDIAN
822+ *(output_buf + output_at++) = ((sample >> 8) & 0xff);
823+#else
824 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
825+#endif
826 output_bytes += 1;
827 }
828 }
829@@ -114,8 +119,13 @@
830 for (channel = 0; channel < chan; channel++)
831 {
832 sample = (FLAC__int16)buffer[channel][cursamp];
833+#ifdef WORDS_BIGENDIAN
834+ *(output_buf + output_at++) = ((sample >> 8) & 0xff);
835 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
836+#else
837+ *(output_buf + output_at++) = ((sample >> 0) & 0xff);
838 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
839+#endif
840 output_bytes += 2;
841 }
842 }
843Index: mythplugins/mythmusic/mythmusic/maddecoder.cpp
844===================================================================
56a97e74
ER
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)
ecca4c51
ER
847@@ -16,6 +16,7 @@
848 #include <mythtv/audiooutput.h>
849 #include "metaioid3v2.h"
850
851+#include <mythtv/mythconfig.h>
852 #include <mythtv/mythcontext.h>
853
854 #define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
855@@ -407,7 +408,7 @@
856 flush(TRUE);
857
858 if (output()) {
859- output()->Drain();
860+ output()->Drain();
861 }
862
863 done = TRUE;
864@@ -488,15 +489,25 @@
865 flush();
866 }
867 sample = fix_sample(16, *left++);
868+#ifdef WORDS_BIGENDIAN
869+ *(output_buf + output_at++) = ((sample >> 8) & 0xff);
870 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
871+#else
872+ *(output_buf + output_at++) = ((sample >> 0) & 0xff);
873 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
874+#endif
875 output_bytes += 2;
876
877 if (channels == 2)
878 {
879 sample = fix_sample(16, *right++);
880+#ifdef WORDS_BIGENDIAN
881+ *(output_buf + output_at++) = ((sample >> 8) & 0xff);
882 *(output_buf + output_at++) = ((sample >> 0) & 0xff);
883+#else
884+ *(output_buf + output_at++) = ((sample >> 0) & 0xff);
885 *(output_buf + output_at++) = ((sample >> 8) & 0xff);
886+#endif
887 output_bytes += 2;
888 }
889 }
890Index: mythplugins/mythweather/mythweather/weather.cpp
891===================================================================
56a97e74
ER
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)
ecca4c51
ER
894@@ -2571,6 +2571,14 @@
895 return false;
896 }
897
898+ int imageCount = 5;
899+ QString imagesList = parseData(tempData, "imagenames = new Array( '", ";");
900+ if (imagesList != "<NULL>")
901+ {
902+ QStringList imageURLs = QStringList::split(",", imagesList);
903+ imageCount = imageURLs.size();
904+ }
905+
906 QString fileprefix = MythContext::GetConfDir();
907
908 QDir dir(fileprefix);
909@@ -2587,13 +2595,13 @@
910 cerr << "MythWeather: Map File Prefix: " << fileprefix << endl;
911
912 // delete existing radar maps
913- for (int x = 1; x <= 6; x++)
914+ for (int x = 1; x <= 10; x++)
915 QFile::remove(QString(fileprefix + "/radar%1.jpg").arg(x));
916
917 if (debug)
918 cerr << "MythWeather: Copying Map Files from Server (" << imageLoc << ")...\n";
919
920- for (int x = 1; x <= 6; x++)
921+ for (int x = 1; x <= imageCount; x++)
922 {
923 QString sFile = QString(fileprefix + "/radar%1.jpg").arg(x);
924 sURL = QString("http://image.weather.com" + imageLoc + "%1L.jpg").arg(x);
925Index: mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp
926===================================================================
56a97e74
ER
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)
ecca4c51
ER
929@@ -46,22 +46,6 @@
930 #include "keygrabber.h"
931
932
933-static QMap<int,QString> FindContexts(const QString &context)
934-{
935- QMap<int,QString> retval;
936- retval.clear();
937- if (context != JUMP_CONTEXT) retval[-1] = JUMP_CONTEXT;
938- retval[0] = context;
939- if (context != JUMP_CONTEXT && context != GLOBAL_CONTEXT)
940- {
941- if (context == "TV Editting")
942- retval[1] = "TV Playback";
943- retval[2] = GLOBAL_CONTEXT;
944- if (context != "qt")
945- retval[3] = "qt";
946- }
947- return retval;
948-}
949
950 static const QString KeyToDisplay(const QString key)
951 {
952@@ -838,7 +822,11 @@
953 refreshKeyInformation();
954 }
955
956-void MythControls::addBindings(QDict<binding_t> &bindings, const QString &context, const QString &contextParent, int bindlevel)
957+
958+
959+void MythControls::addBindings(QDict<binding_t> &bindings,
960+ const QString &context,
961+ const QString &contextParent, int bindlevel)
962 {
963 QStringList *actions = key_bindings->getActions(context);
964
965@@ -872,18 +860,13 @@
966
967 BindingList *MythControls::getKeyBindings(const QString &context)
968 {
969+ QStringList keys;
970 QDict<binding_t> bindings;
971 bindings.clear();
972
973- QMap<int,QString> contextList = FindContexts(context);
974- for (QMap<int,QString>::iterator it = contextList.begin(); it != contextList.end(); ++it)
975- {
976- int level = it.key();
977- QString curcontext = it.data();
978- addBindings(bindings, curcontext, context, level);
979- }
980+ for (size_t i = 0; i < contexts.size(); i++)
981+ addBindings(bindings, contexts[i], context, i);
982
983- QStringList keys;
984
985 for (QDictIterator<binding_t> it(bindings); it.current(); ++it)
986 {
987Index: mythplugins/mythcontrols/mythcontrols/actionset.cpp
988===================================================================
56a97e74
ER
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)
ecca4c51
ER
991@@ -139,13 +139,19 @@
992 /* method description in header */
993 QStringList * ActionSet::actionStrings(const QString &context_name) const
994 {
995- QStringList *action_strings = new QStringList();
996- QDictIterator<Action> it(*(_contexts[context_name]));
997+ Context *c = _contexts[context_name];
998
999- for (; it.current(); ++it)
1000- action_strings->append(it.currentKey());
1001+ if (c == NULL) return NULL;
1002+ else
1003+ {
1004+ QStringList *action_strings = new QStringList();
1005+ QDictIterator<Action> it(*(_contexts[context_name]));
1006+
1007+ for (; it.current(); ++it)
1008+ action_strings->append(it.currentKey());
1009
1010- return action_strings;
1011+ return action_strings;
1012+ }
1013 }
1014
1015
1016Index: mythplugins/mythcontrols/mythcontrols/keybindings.h
1017===================================================================
56a97e74
ER
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)
ecca4c51
ER
1020@@ -65,6 +65,8 @@
1021 /**
1022 * @brief Get a list of the context names.
1023 * @return A list of the context names.
1024+ * @note The returned list is a copy and can be modified without
1025+ * side-effects.
1026 */
1027 inline QStringList * getContexts() const
1028 {
1029Index: mythplugins/mythvideo/mythvideo/videomanager.h
1030===================================================================
56a97e74
ER
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)
ecca4c51
ER
1033@@ -30,7 +30,7 @@
1034 public:
1035 VideoManager(MythMainWindow *parent, const char *name = 0);
1036 ~VideoManager(void);
1037- void VideoManager::processEvents() { qApp->processEvents(); }
1038+ void processEvents() { qApp->processEvents(); }
1039
1040 public slots:
1041 void slotManualIMDB();
1042Index: mythplugins/mythvideo/mythvideo/videoselected.h
1043===================================================================
56a97e74
ER
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)
ecca4c51
ER
1046@@ -35,7 +35,7 @@
1047 VideoSelected(VideoList *lvideolist,
1048 MythMainWindow *parent, const char *name = 0, int index = 0);
1049 ~VideoSelected();
1050- void VideoSelected::processEvents() { qApp->processEvents(); }
1051+ void processEvents() { qApp->processEvents(); }
1052
1053
1054 protected slots:
1055Index: mythplugins/mythphone/mythphone/sipfsm.h
1056===================================================================
56a97e74
ER
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)
ecca4c51
ER
1059@@ -618,7 +618,7 @@
1060 SipWatcher *CreateWatcherFsm(QString Url);
1061 SipIM *CreateIMFsm(QString Url="", QString callIdStr="");
1062 void StopWatchers();
1063- void SipFsm::KickWatcher(SipUrl *Url);
1064+ void KickWatcher(SipUrl *Url);
1065 void SendIM(QString destUrl, QString CallId, QString imMsg);
1066 int numCalls();
1067 int getPrimaryCall() { return primaryCall; };
1068Index: mythplugins/mythphone/mythphone/vxml.h
1069===================================================================
56a97e74
ER
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)
ecca4c51
ER
1072@@ -10,7 +10,7 @@
1073 {
1074 public:
1075 vxmlVariable(QString N, QString V);
1076- vxmlVariable::vxmlVariable(QString N, short *wav, int S);
1077+ vxmlVariable(QString N, short *wav, int S);
1078 virtual ~vxmlVariable() {};
1079 bool isType(QString t) { return (t == Type); };
1080 QString getName() { return Name; };
1081Index: mythplugins/mythgame/mythgame/gamehandler.h
1082===================================================================
56a97e74
ER
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)
ecca4c51
ER
1085@@ -106,7 +106,7 @@
1086
1087 protected:
1088 static GameHandler* GetHandler(RomInfo *rominfo);
1089- static GameHandler* GameHandler::GetHandlerByName(QString systemname);
1090+ static GameHandler* GetHandlerByName(QString systemname);
1091
1092 bool rebuild;
1093 int spandisks;
1094Index: mythplugins/mythnews/mythnews/news-sites.xml
1095===================================================================
56a97e74
ER
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)
ecca4c51
ER
1098@@ -119,7 +119,7 @@
1099
1100 <item>
1101 <title>Slashdot</title>
1102- <url>http://slashdot.org/slashdot.rss</url>
1103+ <url>http://rss.slashdot.org/Slashdot/slashdot</url>
1104 <ico>http://slashdot.org/favicon.ico</ico>
1105 </item>
1106
73e9aca0
ER
1107Index: mythtv/libs/libmythtv/dvbchannel.h
1108===================================================================
56a97e74
ER
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)
73e9aca0
ER
1111@@ -60,11 +60,13 @@
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; }
1116
1117 // Commands
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);
1122
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
1132
1133 bool first_tune; ///< Used to force hardware reset
1134
1135 int nextcapchannel; ///< Signal an input change
1136+
1137+ /// Last tuning options sent to hardware for retuning
1138+ DVBTuning retune_tuning;
1139+ /// Retuning adjustment, required so drivers don't ignore retune request
1140+ int retune_adj;
1141 };
1142
1143 #endif
ecca4c51
ER
1144Index: mythtv/libs/libmythtv/NuppelVideoPlayer.h
1145===================================================================
56a97e74
ER
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)
ecca4c51
ER
1148@@ -150,7 +150,8 @@
1149 // Complicated gets
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);
1155
1156 /// Non-const gets
1157 OSD *GetOSD(void) { return osd; }
73e9aca0
ER
1158@@ -297,6 +298,7 @@
1159 bool DecodeFrame(struct rtframeheader *frameheader,
1160 unsigned char *strm, unsigned char *outbuf);
1161
1162+ bool PrebufferEnoughFrames(void);
1163 void CheckPrebuffering(void);
1164 bool GetFrameNormal(int onlyvideo);
1165 bool GetFrameFFREW(void);
1166@@ -309,7 +311,7 @@
1167 bool DoRewind(void);
1168
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); }
1175@@ -543,6 +545,7 @@
ecca4c51
ER
1176 QMap<long long, int>::Iterator deleteIter;
1177 QMap<long long, int>::Iterator blankIter;
1178 QMap<long long, int>::Iterator commBreakIter;
1179+ bool forcePositionMapSync;
1180
1181 // Playback (output) speed control
1182 /// Lock for next_play_speed and next_normal_speed
1183Index: mythtv/libs/libmythtv/osdlistbtntype.h
1184===================================================================
56a97e74
ER
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)
ecca4c51
ER
1187@@ -1,3 +1,4 @@
1188+// -*- Mode: c++ -*-
1189 /* ============================================================
1190 * File : uilistbtntype.h
1191 * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
1192@@ -22,38 +23,57 @@
1193 #ifndef OSDLISTBTNTYPE_H
1194 #define OSDLISTBTNTYPE_H
1195
1196-#include "osdtypes.h"
1197-#include "ttfont.h"
1198+#include <vector>
1199+using namespace std;
1200+
1201+// Qt headers
1202 #include <qcolor.h>
1203 #include <qptrlist.h>
1204 #include <qevent.h>
1205 #include <qmutex.h>
1206+#include <qptrvector.h>
1207+
1208+// MythTV headers
1209+#include "osdtypes.h"
1210+#include "ttfont.h"
1211 #include "generictree.h"
1212
1213+class OSDListBtnType;
1214 class OSDListBtnTypeItem;
1215-class OSDListBtnType;
1216+typedef vector<OSDListBtnType*> OSDListBtnList;
1217+typedef vector<OSDListBtnTypeItem*> OSDListBtnItemList;
1218
1219 class OSDGenericTree : public GenericTree
1220 {
1221 public:
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)
1231+ {
1232+ m_group = (m_group.isEmpty()) ? action : m_group;
1233+ setSelectable(!action.isEmpty());
1234+ if (parent)
1235+ parent->addNode(this);
1236+ }
1237
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; }
1245+
1246+ OSDTypeImage *getImage(void) { return m_image; }
1247+ OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; }
1248+
1249 void setParentButton(OSDListBtnTypeItem *button)
1250- { m_parentButton = button; };
1251- OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; };
1252+ { m_parentButton = button; }
1253
1254 private:
1255- OSDTypeImage *m_image;
1256- QString m_action;
1257- int m_checkable;
1258- QString m_group;
1259+ OSDTypeImage *m_image;
1260+ QString m_action;
1261+ QString m_group;
1262+ int m_checkable;
1263 OSDListBtnTypeItem *m_parentButton;
1264 };
1265
1266@@ -62,53 +82,49 @@
1267 {
1268 Q_OBJECT
1269 public:
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();
1277
1278- void Reinit(float wchange, float hchange, float wmult, float hmult);
1279+ bool IsVisible(void) const { return m_visible; }
1280+
1281+ void SetFontActive(TTFFont *font) { m_active = font; }
1282+ void SetFontInactive(TTFFont *font) { m_inactive = font; }
1283+
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);
1295
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);
1302-
1303- void SetAsTree(OSDGenericTree *toplevel);
1304-
1305- OSDGenericTree *GetCurrentPosition(void);
1306-
1307+ void Reinit(float wmult, float hmult);
1308 bool HandleKeypress(QKeyEvent *e);
1309-
1310 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
1311
1312- bool IsVisible(void) { return m_visible; }
1313- void SetVisible(bool visible) { m_visible = visible; }
1314-
1315 signals:
1316 void itemSelected(OSDListTreeType *parent, OSDGenericTree *item);
1317 void itemEntered(OSDListTreeType *parent, OSDGenericTree *item);
1318
1319 private:
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);
1327
1328- int levels;
1329- int curlevel;
1330-
1331 OSDGenericTree *treetop;
1332 OSDGenericTree *currentpos;
1333+ TTFFont *m_active;
1334+ TTFFont *m_inactive;
1335
1336- QPtrList<OSDListBtnType> listLevels;
1337+ OSDListBtnList listLevels;
1338
1339- OSDListBtnType *currentlevel;
1340-
1341- TTFFont *m_active;
1342- TTFFont *m_inactive;
1343-
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;
1350
1351- int m_spacing;
1352- int m_margin;
1353+ uint m_spacing;
1354+ uint m_margin;
1355+ int m_levelspacing;
1356
1357- QRect m_totalarea;
1358- QRect m_levelsize;
1359- int m_levelspacing;
1360+ QRect m_totalarea;
1361+ QRect m_levelsize;
1362
1363- float m_wmult;
1364- float m_hmult;
1365+ float m_unbiasedspacing;
1366+ float m_unbiasedmargin;
1367+ QRect m_unbiasedarea;
1368+ QRect m_unbiasedsize;
1369
1370- bool m_visible;
1371- bool m_arrowAccel;
1372+ float m_wmult;
1373+ float m_hmult;
1374+
1375+ int m_depth;
1376+ int m_levelnum;
1377+ bool m_visible;
1378+ bool m_arrowAccel;
1379 };
1380
1381 class OSDListBtnType : public OSDType
1382 {
1383+ friend class OSDListBtnTypeItem;
1384 Q_OBJECT
1385+
1386 public:
1387 OSDListBtnType(const QString &name, const QRect& area,
1388 float wmult, float hmult,
1389 bool showScrollArrows = false);
1390 ~OSDListBtnType();
1391
1392- void Reinit(float wchange, float hchange, float wmult, float hmult);
1393+ // General Gets
1394+ bool IsVisible() const { return m_visible; }
1395+
1396+ // General Sets
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);
1410
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);
1417-
1418- void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
1419-
1420- void SetActive(bool active);
1421- void Reset();
1422-
1423- void SetItemCurrent(OSDListBtnTypeItem* item);
1424- void SetItemCurrent(int pos);
1425- OSDListBtnTypeItem* GetItemCurrent();
1426- OSDListBtnTypeItem* GetItemFirst();
1427- OSDListBtnTypeItem* GetItemNext(OSDListBtnTypeItem *item);
1428+ // Item Gets
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);
1437- int GetCount();
1438
1439- void MoveDown();
1440- void MoveUp();
1441+ // Item Sets/Commands
1442+ void MoveDown(void);
1443+ void MoveUp(void);
1444
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) {}
1450+ void Reset(void);
1451
1452 private:
1453-
1454- void Init();
1455+ void Init(void);
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);
1462
1463- int m_order;
1464- QRect m_rect;
1465- QRect m_contentsRect;
1466- QRect m_arrowsRect;
1467+ private:
1468+ int m_order;
1469+ QRect m_rect;
1470+ QRect m_contentsRect;
1471+ QRect m_arrowsRect;
1472
1473- float m_wmult;
1474- float m_hmult;
1475+ float m_wmult;
1476+ float m_hmult;
1477
1478- int m_itemHeight;
1479- int m_itemSpacing;
1480- int m_itemMargin;
1481- uint m_itemsVisible;
1482+ int m_itemHeight;
1483+ int m_itemSpacing;
1484+ int m_itemMargin;
1485+ uint m_itemsVisible;
1486
1487- bool m_active;
1488- bool m_showScrollArrows;
1489- bool m_showUpArrow;
1490- bool m_showDnArrow;
1491+ bool m_active;
1492+ bool m_showScrollArrows;
1493+ bool m_showUpArrow;
1494+ bool m_showDnArrow;
1495+ bool m_initialized;
1496+ bool m_clearing;
1497+ bool m_visible;
1498
1499+ QColor m_itemRegBeg;
1500+ QColor m_itemRegEnd;
1501+ QColor m_itemSelBeg;
1502+ QColor m_itemSelEnd;
1503+ uint m_itemRegAlpha;
1504+ uint m_itemSelAlpha;
1505+
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;
1512
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;
1521
1522- TTFFont* m_fontActive;
1523- TTFFont* m_fontInactive;
1524+ int m_topIndx;
1525+ int m_selIndx;
1526
1527- bool m_initialized;
1528- bool m_clearing;
1529+ OSDListBtnItemList m_itemList;
1530
1531- OSDListBtnTypeItem* m_topItem;
1532- OSDListBtnTypeItem* m_selItem;
1533- QPtrList<OSDListBtnTypeItem> m_itemList;
1534+ mutable QMutex m_update;
1535
1536- QMutex m_update;
1537-
1538- bool m_visible;
1539-
1540- friend class OSDListBtnTypeItem;
1541-
1542 signals:
1543-
1544 void itemSelected(OSDListBtnTypeItem* item);
1545 };
1546
1547 class OSDListBtnTypeItem
1548 {
1549+ friend class OSDListBtnType;
1550
1551 public:
1552-
1553- enum CheckState {
1554- NotChecked=0,
1555+ enum CheckState
1556+ {
1557+ NotChecked = 0,
1558 HalfChecked,
1559- FullChecked
1560+ FullChecked,
1561 };
1562
1563 OSDListBtnTypeItem(OSDListBtnType* lbtype, const QString& text,
1564@@ -253,41 +281,36 @@
1565 bool showArrow = false, CheckState state = NotChecked);
1566 ~OSDListBtnTypeItem();
1567
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; }
1580
1581- void setChecked(CheckState state);
1582- void setData(void *data);
1583- void* getData();
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; }
1590
1591- void Reinit(float wchange, float hchange, float wmult, float hmult);
1592-
1593+ void Reinit(float,float) {}
1594 void paint(OSDSurface *surface, TTFFont *font, int fade, int maxfade,
1595 int x, int y);
1596
1597 protected:
1598-
1599 OSDListBtnType *m_parent;
1600- QString m_text;
1601- OSDTypeImage *m_pixmap;
1602- bool m_checkable;
1603- CheckState m_state;
1604- void *m_data;
1605- QString m_group;
1606-
1607- QRect m_checkRect;
1608- QRect m_pixmapRect;
1609- QRect m_textRect;
1610- QRect m_arrowRect;
1611-
1612- bool m_showArrow;
1613-
1614- friend class OSDListBtnType;
1615+ OSDTypeImage *m_pixmap;
1616+ void *m_data;
1617+ QString m_text;
1618+ QString m_group;
1619+ CheckState m_state;
1620+ bool m_showArrow;
1621+ bool m_checkable;
1622+ QRect m_checkRect;
1623+ QRect m_arrowRect;
1624+ QRect m_pixmapRect;
1625+ QRect m_textRect;
1626 };
1627
1628
1629Index: mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
1630===================================================================
56a97e74
ER
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)
ecca4c51
ER
1633@@ -147,6 +147,7 @@
1634 hascommbreaktable(false),
1635 deleteIter(deleteMap.end()), blankIter(blankMap.end()),
1636 commBreakIter(commBreakMap.end()),
1637+ forcePositionMapSync(false),
1638 // Playback (output) speed control
1639 decoder_lock(true),
1640 next_play_speed(1.0f), next_normal_speed(true),
1641@@ -747,6 +748,8 @@
1642 SetDecoder(new IvtvDecoder(this, m_playbackinfo));
1643 no_audio_out = true; // no audio with ivtv.
1644 audio_bits = 16;
1645+ audio_samplerate = 44100;
1646+ audio_channels = 2;
1647 }
1648 else if (forceVideoOutput == kVideoOutput_IVTV)
1649 {
1650@@ -1113,7 +1116,7 @@
1651 const unsigned char *NuppelVideoPlayer::GetScaledFrame(QSize &size)
1652 {
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);
1656
1657 if ((size.width() > 0) && (size.height() > 0))
1658 {
73e9aca0
ER
1659@@ -1626,8 +1629,8 @@
1660 {
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.");
1668 }
1669 else
1670@@ -1685,14 +1688,14 @@
1671
1672 if (diverge > MAXDIVERGE)
1673 {
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
1677
1678 avsync_adjustment = frame_interval;
1679 lastsync = true;
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));
1685 }
1686
1687 if (audioOutput && normal_speed)
1688@@ -1811,11 +1814,8 @@
1689 videosync->Start();
1690 }
1691
1692-void NuppelVideoPlayer::DisplayNormalFrame(void)
1693+bool NuppelVideoPlayer::PrebufferEnoughFrames(void)
1694 {
1695- video_actually_paused = false;
1696- resetvideo = false;
1697-
1698 prebuffering_lock.lock();
1699 if (prebuffering)
1700 {
1701@@ -1843,14 +1843,29 @@
1702 }
1703 prebuffering_lock.unlock();
1704 videosync->Start();
1705- return;
1706+
1707+ return false;
1708 }
1709 prebuffering_lock.unlock();
1710
1711 //VERBOSE(VB_PLAYBACK, LOC + "fs: " + videoOutput->GetFrameStatus());
1712 if (!videoOutput->EnoughPrebufferedFrames())
1713 {
1714- VERBOSE(VB_GENERAL, LOC + "prebuffering pause");
1715+ if (videoOutput)
1716+ {
1717+ videoOutput->CheckFrameStates();
1718+ if (videoOutput->hasMCAcceleration() ||
1719+ videoOutput->hasIDCTAcceleration() ||
1720+ videoOutput->hasVLDAcceleration())
1721+ {
1722+ // Prebuffering fails w/XvMC's 8 surfaces..
1723+ usleep(5000);
1724+ return false;
1725+ }
1726+ }
1727+ VERBOSE(VB_GENERAL, LOC + "prebuffering pause" +
1728+ videoOutput->GetFrameStatus());
1729+
1730 SetPrebuffering(true);
1731 #if FAST_RESTART
1732 if (!m_playing_slower && audio_channels <= 2)
1733@@ -1861,7 +1876,7 @@
1734 VERBOSE(VB_GENERAL, "playing slower due to falling behind...");
1735 }
1736 #endif
1737- return;
1738+ return false;
1739 }
1740
1741 #if FAST_RESTART
1742@@ -1877,6 +1892,25 @@
1743 prebuffer_tries = 0;
1744 prebuffering_lock.unlock();
1745
1746+ return true;
1747+}
1748+
1749+void NuppelVideoPlayer::DisplayNormalFrame(void)
1750+{
1751+ video_actually_paused = false;
1752+ resetvideo = false;
1753+
1754+ if (!PrebufferEnoughFrames())
1755+ {
1756+ // When going to switch channels
1757+ if (paused)
1758+ {
1759+ usleep(frame_interval);
1760+ DisplayPauseFrame();
1761+ }
1762+ return;
1763+ }
1764+
1765 videoOutput->StartDisplayingFrame();
1766
1767 VideoFrame *frame = videoOutput->GetLastShownFrame();
1768@@ -1920,7 +1954,7 @@
ecca4c51
ER
1769 ShowText();
1770 DisplaySubtitles();
1771 }
1772- else if (osdHasSubtitles || nonDisplayedSubtitles.size() > 20)
1773+ else if (osdHasSubtitles)
1774 {
1775 ClearSubtitles();
1776 }
73e9aca0 1777@@ -2176,7 +2210,10 @@
ecca4c51
ER
1778 }
1779
1780 if (eof)
1781+ {
1782 discontinuity = true;
1783+ ClearSubtitles();
1784+ }
1785
1786 livetvchain->SetProgram(pginfo);
1787
73e9aca0 1788@@ -2199,6 +2236,7 @@
ecca4c51
ER
1789 }
1790 if (IsErrored())
1791 {
1792+ VERBOSE(VB_IMPORTANT, LOC_ERR + "SwitchToProgram failed.");
1793 eof = true;
1794 return;
1795 }
73e9aca0 1796@@ -2265,6 +2303,8 @@
ecca4c51
ER
1797 ringBuffer->Pause();
1798 ringBuffer->WaitForPause();
1799
1800+ ClearSubtitles();
1801+
1802 livetvchain->SetProgram(pginfo);
1803
1804 ringBuffer->Reset(true);
73e9aca0 1805@@ -2284,6 +2324,7 @@
ecca4c51
ER
1806
1807 if (errored || !GetDecoder())
1808 {
1809+ VERBOSE(VB_IMPORTANT, LOC_ERR + "JumpToProgram failed.");
1810 errored = true;
1811 return;
1812 }
73e9aca0 1813@@ -2471,6 +2512,12 @@
ecca4c51
ER
1814 JumpToProgram();
1815 }
1816
1817+ if (forcePositionMapSync)
1818+ {
1819+ forcePositionMapSync = false;
1820+ GetDecoder()->SyncPositionMap();
1821+ }
1822+
1823 if (IsErrored() || (nvr_enc && nvr_enc->GetErrorStatus()))
1824 {
1825 VERBOSE(VB_IMPORTANT, LOC_ERR + "Unknown error, exiting decoder");
73e9aca0
ER
1826@@ -3246,7 +3293,10 @@
1827 GetDecoder()->DoFastForward(desiredFrame);
1828 GetDecoder()->setExactSeeks(exactseeks);
1829
1830- ClearAfterSeek();
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);
1834+
1835 lastSkipTime = time(NULL);
1836 return true;
1837 }
1838@@ -3291,19 +3341,24 @@
1839 }
1840 #endif
1841
1842-/** \fn NuppelVideoPlayer::ClearAfterSeek(void)
1843+/** \fn NuppelVideoPlayer::ClearAfterSeek(bool)
1844 * \brief This is to support seeking...
1845 *
1846 * This resets the output classes and discards all
1847 * frames no longer being used by the decoder class.
1848 *
1849 * Note: caller should not hold any locks
1850+ *
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.
1854 */
1855-void NuppelVideoPlayer::ClearAfterSeek(void)
1856+void NuppelVideoPlayer::ClearAfterSeek(bool clearvideobuffers)
1857 {
1858- VERBOSE(VB_PLAYBACK, LOC + "ClearAfterSeek()");
1859+ VERBOSE(VB_PLAYBACK, LOC + "ClearAfterSeek("<<clearvideobuffers<<")");
1860
1861- videoOutput->ClearAfterSeek();
1862+ if (clearvideobuffers)
1863+ videoOutput->ClearAfterSeek();
1864
1865 for (int i = 0; i < MAXTBUFFER; i++)
1866 txtbuffers[i].timecode = 0;
1867@@ -4398,6 +4453,8 @@
ecca4c51
ER
1868 hascommbreaktable = !commBreakMap.isEmpty();
1869 SetCommBreakIter();
1870 commBreakMapLock.unlock();
1871+
1872+ forcePositionMapSync = true;
1873 }
1874
1875 bool NuppelVideoPlayer::RebuildSeekTable(bool showPercentage, StatusCallback cb, void* cbData)
73e9aca0 1876@@ -4541,7 +4598,8 @@
ecca4c51
ER
1877 return (int)((float)(written - played) / video_frame_rate);
1878 }
1879
1880-void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo)
1881+void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo,
1882+ bool paddedFields)
1883 {
1884 posInfo.desc = "";
1885 posInfo.position = 0;
73e9aca0 1886@@ -4588,15 +4646,23 @@
ecca4c51
ER
1887 int ssecs = (playbackLen - shours * 3600 - smins * 60);
1888
1889 QString text1, text2;
1890- if (shours > 0)
1891+ if (paddedFields)
1892 {
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);
1897 }
1898 else
1899 {
1900- text1.sprintf("%d:%02d", pmins, psecs);
1901- text2.sprintf("%d:%02d", smins, ssecs);
1902+ if (shours > 0)
1903+ {
1904+ text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
1905+ text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
1906+ }
1907+ else
1908+ {
1909+ text1.sprintf("%d:%02d", pmins, psecs);
1910+ text2.sprintf("%d:%02d", smins, ssecs);
1911+ }
1912 }
1913
1914 posInfo.desc = QObject::tr("%1 of %2").arg(text1).arg(text2);
73e9aca0 1915@@ -4654,6 +4720,7 @@
ecca4c51
ER
1916
1917 if (commBreakIter.key() == totalFrames)
1918 {
1919+ VERBOSE(VB_IMPORTANT, LOC + "Skipping commercial to end of file");
1920 eof = true;
1921 }
1922 else
73e9aca0 1923@@ -4721,7 +4788,7 @@
ecca4c51
ER
1924
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);
1930
1931 return false;
73e9aca0 1932@@ -5018,7 +5085,7 @@
ecca4c51
ER
1933 QImage scaledImage = qImage.smoothScale(rect->w, rect->h);
1934
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);
1939
1940 subtitleOSD->AddType(image);
1941Index: mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
1942===================================================================
56a97e74
ER
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)
ecca4c51
ER
1945@@ -216,7 +216,10 @@
1946 }
1947
1948 if (mpa_codec)
1949+ {
1950+ QMutexLocker locker(&avcodeclock);
1951 avcodec_close(mpa_ctx);
1952+ }
1953
1954 if (mpa_ctx)
1955 av_free(mpa_ctx);
1956@@ -453,8 +456,11 @@
1957 useavcodec = true;
1958
1959 if (mpa_codec)
1960+ {
1961+ QMutexLocker locker(&avcodeclock);
1962 avcodec_close(mpa_ctx);
1963-
1964+ }
1965+
1966 if (mpa_ctx)
1967 av_free(mpa_ctx);
1968 mpa_ctx = NULL;
1969@@ -626,13 +632,14 @@
1970 int frag, blocksize = 4096;
1971 int tmp;
1972
1973+ if (!skipdevice)
1974+ {
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"));
1978- return 1;
1979+ VERBOSE(VB_IMPORTANT,
1980+ QString("NVR::AudioInit() This Unix doesn't support"
1981+ " device files for audio access. Skipping"));
1982+ return 1;
1983 #else
1984- if (!skipdevice)
1985- {
1986 if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK)))
1987 {
1988 VERBOSE(VB_IMPORTANT, QString("NVR: Error, cannot open DSP '%1'").
1989@@ -678,8 +685,8 @@
1990 }
1991
1992 close(afd);
1993+#endif
1994 }
1995-#endif
1996
1997 audio_bytes_per_sample = audio_channels * audio_bits / 8;
1998 blocksize *= 4;
73e9aca0
ER
1999Index: mythtv/libs/libmythtv/signalmonitor.cpp
2000===================================================================
56a97e74
ER
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)
73e9aca0
ER
2003@@ -100,9 +100,9 @@
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",
2014 1, true, 0, 1, 0),
2015 signalStrength(QObject::tr("Signal Power"), "signal",
ecca4c51
ER
2016Index: mythtv/libs/libmythtv/osdlistbtntype.cpp
2017===================================================================
56a97e74
ER
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)
ecca4c51
ER
2020@@ -19,206 +19,148 @@
2021 *
2022 * ============================================================ */
2023
2024-#include <iostream>
2025+// ANSI C headers
2026+#include <cmath>
2027
2028+// C++ headers
2029+#include <algorithm>
2030+using namespace std;
2031+
2032+// Qt headers
2033 #include <qapplication.h>
2034 #include <qpixmap.h>
2035 #include <qpainter.h>
2036 #include <qimage.h>
2037 #include <qcolor.h>
2038
2039+// MythTV headers
2040 #include "mythcontext.h"
2041 #include "mythdialogs.h"
2042-
2043 #include "osdlistbtntype.h"
2044
2045+#define LOC QString("OSDListTreeType: ")
2046+#define LOC_ERR QString("OSDListTreeType, Error: ")
2047
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)
2053 {
2054- m_checkable = check;
2055- m_action = action;
2056- m_image = image;
2057- m_parentButton = NULL;
2058-
2059- if (group != "")
2060- m_group = group;
2061- else
2062- m_group = action;
2063-
2064- if (!action.isEmpty() && !action.isNull())
2065- setSelectable(true);
2066-
2067- if (parent)
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));
2073 }
2074
2075-////////////////////////////////////////////////////////////////////////////
2076-
2077-OSDListTreeType::OSDListTreeType(const QString &name, const QRect &area,
2078- const QRect &levelsize, int levelspacing,
2079- float wmult, float hmult)
2080- : OSDType(name)
2081+static QRect bias(QRect rect, float wmult, float hmult)
2082 {
2083- m_wmult = wmult;
2084- m_hmult = hmult;
2085-
2086- m_totalarea = area;
2087- m_levelsize = levelsize;
2088- m_levelspacing = levelspacing;
2089-
2090- if (gContext->GetNumSetting("UseArrowAccels", 1))
2091- m_arrowAccel = true;
2092- else
2093- m_arrowAccel = false;
2094-
2095- levels = 0;
2096- curlevel = -1;
2097-
2098- treetop = NULL;
2099- currentpos = NULL;
2100-
2101- currentlevel = NULL;
2102-
2103- listLevels.setAutoDelete(true);
2104-
2105- m_active = NULL;
2106- m_inactive = NULL;
2107-
2108- SetItemRegColor(Qt::black,QColor(80,80,80),100);
2109- SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
2110-
2111- m_spacing = 0;
2112- m_margin = 0;
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));
2117 }
2118
2119-void OSDListTreeType::Reinit(float wchange, float hchange, float wmult,
2120- float hmult)
2121+OSDListTreeType::OSDListTreeType(
2122+ const QString &name, const QRect &area,
2123+ const QRect &levelsize, int levelspacing,
2124+ float wmult, float hmult)
2125+ : OSDType(name),
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),
2138+ m_visible(true),
2139+ m_arrowAccel(gContext->GetNumSetting("UseArrowAccels", 1))
2140 {
2141- m_wmult = wmult;
2142- m_hmult = hmult;
2143-
2144- m_spacing = (int)(m_spacing * wchange);
2145- m_margin = (int)(m_margin * wchange);
2146-
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);
2151-
2152- m_totalarea = QRect(x, y, width, height);
2153-
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);
2158-
2159- m_levelsize = QRect(x, y, width, height);
2160-
2161- QPtrListIterator<OSDListBtnType> it(listLevels);
2162- OSDListBtnType *child;
2163-
2164- while ((child = it.current()) != 0)
2165- {
2166- child->Reinit(wchange, hchange, wmult, hmult);
2167- ++it;
2168- }
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);
2173 }
2174
2175-void OSDListTreeType::SetGroupCheckState(QString group, int newState)
2176+OSDListTreeType::~OSDListTreeType()
2177 {
2178- QPtrListIterator<OSDListBtnType> it(listLevels);
2179- OSDListBtnType *child;
2180- while ((child = it.current()) != 0)
2181- {
2182- child->SetGroupCheckState(group, newState);
2183- ++it;
2184- }
2185+ OSDListBtnList::iterator it = listLevels.begin();
2186+ for (; it != listLevels.end(); ++it)
2187+ delete *it;
2188 }
2189
2190-void OSDListTreeType::SetItemRegColor(const QColor& beg, const QColor& end,
2191- uint alpha)
2192+void OSDListTreeType::Reinit(float wmult, float hmult)
2193 {
2194- m_itemRegBeg = beg;
2195- m_itemRegEnd = end;
2196- m_itemRegAlpha = alpha;
2197-}
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);
2204
2205-void OSDListTreeType::SetItemSelColor(const QColor& beg, const QColor& end,
2206- uint alpha)
2207-{
2208- m_itemSelBeg = beg;
2209- m_itemSelEnd = end;
2210- m_itemSelAlpha = alpha;
2211-}
2212+ if (!treetop || m_levelnum < 0)
2213+ return;
2214
2215-void OSDListTreeType::SetFontActive(TTFFont *font)
2216-{
2217- m_active = font;
2218-}
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());
2223
2224-void OSDListTreeType::SetFontInactive(TTFFont *font)
2225-{
2226- m_inactive = font;
2227-}
2228+ // Delete old OSD items
2229+ OSDListBtnList clone = listLevels;
2230+ listLevels.clear();
2231+ OSDListBtnList::iterator it = clone.begin();
2232+ for (; it != clone.end(); ++it)
2233+ delete *it;
2234
2235-void OSDListTreeType::SetSpacing(int spacing)
2236-{
2237- m_spacing = spacing;
2238+ // Create new OSD items
2239+ SetAsTree(treetop, &list);
2240 }
2241
2242-void OSDListTreeType::SetMargin(int margin)
2243+void OSDListTreeType::SetGroupCheckState(QString group, int newState)
2244 {
2245- m_margin = margin;
2246+ OSDListBtnList::iterator it = listLevels.begin();
2247+ for (; it != listLevels.end(); ++it)
2248+ (*it)->SetGroupCheckState(group, newState);
2249 }
2250
2251-void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel)
2252+void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel,
2253+ vector<uint> *select_list)
2254 {
2255 if (treetop)
2256 {
2257 listLevels.clear();
2258- currentlevel = NULL;
2259- treetop = NULL;
2260- currentpos = NULL;
2261- levels = 0;
2262- curlevel = -1;
2263+ treetop = NULL;
2264+ currentpos = NULL;
2265+ m_depth = 0;
2266+ m_levelnum = -1;
2267 }
2268
2269- levels = toplevel->calculateDepth(0) - 1;
2270-
2271- if (levels <= 0)
2272+ m_depth = toplevel->calculateDepth(0) - 1;
2273+ if (m_depth <= 0)
2274 {
2275- cerr << "Need at least one level\n";
2276+ VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need at least one level");
2277 return;
2278 }
2279
2280- currentpos = (OSDGenericTree *)toplevel->getChildAt(0);
2281-
2282+ currentpos = (OSDGenericTree*) toplevel->getChildAt(0);
2283 if (!currentpos)
2284 {
2285- cerr << "No top-level children?\n";
2286+ VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need top-level children");
2287 return;
2288 }
2289
2290- treetop = toplevel;
2291-
2292- // just for now, remove later
2293- if (levels > 2)
2294- levels = 3;
2295-
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++)
2299 {
2300 QString levelname = QString("level%1").arg(i + 1);
2301-
2302 QRect curlevelarea = m_levelsize;
2303 curlevelarea.moveBy(m_totalarea.x(), m_totalarea.y());
2304-
2305 curlevelarea.moveBy((m_levelsize.width() + m_levelspacing) * i, 0);
2306
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);
2311
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);
2317
2318- listLevels.append(newlevel);
2319+ listLevels.push_back(newlevel);
2320 }
2321
2322- currentlevel = GetLevel(0);
2323+ // Set up needed levels and selects
2324+ vector<uint> slist;
2325+ slist.push_back(0);
2326+ if (select_list)
2327+ slist = *select_list;
2328
2329- if (!currentlevel)
2330+ currentpos = treetop = toplevel;
2331+ for (m_levelnum = 0; m_levelnum < (int)slist.size(); m_levelnum++)
2332 {
2333- cerr << "Something is seriously wrong (currentlevel = NULL)\n";
2334- return;
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
2341 }
2342-
2343- FillLevelFromTree(toplevel, currentlevel);
2344-
2345- currentlevel->SetVisible(true);
2346- currentlevel->SetActive(true);
2347-
2348- currentpos = (OSDGenericTree *)(currentlevel->GetItemFirst()->getData());
2349- curlevel = 0;
2350-
2351- emit itemEntered(this, currentpos);
2352+ m_levelnum--;
2353 }
2354
2355-OSDGenericTree *OSDListTreeType::GetCurrentPosition(void)
2356+static bool has_action(QString action, const QStringList &actions)
2357 {
2358- return currentpos;
2359+ QStringList::const_iterator it;
2360+ for (it = actions.begin(); it != actions.end(); ++it)
2361+ {
2362+ if (action == *it)
2363+ return true;
2364+ }
2365+ return false;
2366 }
2367
2368 bool OSDListTreeType::HandleKeypress(QKeyEvent *e)
2369 {
2370- if (!currentlevel)
2371+ QStringList actions;
2372+ bool ok = gContext->GetMainWindow()->TranslateKeyPress(
2373+ "TV Playback", e, actions);
2374+
2375+ if (!ok || ((uint)m_levelnum >= listLevels.size()))
2376 return false;
2377+ else if (has_action("UP", actions))
2378+ {
2379+ GetLevel(m_levelnum)->MoveUp();
2380+ EnterItem();
2381+ }
2382+ else if (has_action("DOWN", actions))
2383+ {
2384+ GetLevel(m_levelnum)->MoveDown();
2385+ EnterItem();
2386+ }
2387+ else if (has_action("LEFT", actions) && (m_levelnum > 0))
2388+ {
2389+ GetLevel(m_levelnum)->Reset();
2390+ GetLevel(m_levelnum)->SetVisible(false);
2391
2392- bool handled = false;
2393- QStringList actions;
2394- if (gContext->GetMainWindow()->TranslateKeyPress("TV Playback", e,
2395- actions))
2396+ m_levelnum--;
2397+ EnterItem();
2398+ }
2399+ else if ((has_action("LEFT", actions) && m_arrowAccel) ||
2400+ has_action("ESCAPE", actions) ||
2401+ has_action("CLEAROSD", actions) ||
2402+ has_action("MENU", actions))
2403 {
2404- for (unsigned int i = 0; i < actions.size() && !handled; i++)
2405- {
2406- QString action = actions[i];
2407- handled = true;
2408+ m_visible = false;
2409+ }
2410+ else if (has_action("RIGHT", actions) &&
2411+ (m_levelnum + 1 < m_depth) &&
2412+ (currentpos->childCount() > 0))
2413+ {
2414+ GetLevel(m_levelnum)->SetActive(false);
2415+ m_levelnum++;
2416
2417- if (action == "UP")
2418- {
2419- currentlevel->MoveUp();
2420- SetCurrentPosition();
2421- }
2422- else if (action == "DOWN")
2423- {
2424- currentlevel->MoveDown();
2425- SetCurrentPosition();
2426- }
2427- else if (action == "LEFT")
2428- {
2429- if (curlevel > 0)
2430- {
2431- currentlevel->Reset();
2432- currentlevel->SetVisible(false);
2433-
2434- curlevel--;
2435-
2436- currentlevel = GetLevel(curlevel);
2437- currentlevel->SetActive(true);
2438- SetCurrentPosition();
2439- }
2440- else if (m_arrowAccel)
2441- {
2442- m_visible = false;
2443- }
2444- }
2445- else if (action == "RIGHT")
2446- {
2447- // FIXME: create new levels if needed..
2448- if (curlevel + 1 < levels && currentpos->childCount() > 0)
2449- {
2450- currentlevel->SetActive(false);
2451-
2452- curlevel++;
2453-
2454- currentlevel = GetLevel(curlevel);
2455-
2456- FillLevelFromTree(currentpos, currentlevel);
2457-
2458- currentlevel->SetVisible(true);
2459- currentlevel->SetActive(true);
2460- SetCurrentPosition();
2461- }
2462- else if (m_arrowAccel)
2463- {
2464- SetGroupCheckState(currentpos->getGroup(),
2465- OSDListBtnTypeItem::NotChecked);
2466- currentpos->getParentButton()->setChecked(
2467- OSDListBtnTypeItem::FullChecked);
2468- emit itemSelected(this, currentpos);
2469- }
2470- }
2471- else if (action == "ESCAPE" || action == "MENU" ||
2472- action == "CLEAROSD")
2473- m_visible = false;
2474- else if (action == "SELECT")
2475- {
2476- SetGroupCheckState(currentpos->getGroup(),
2477- OSDListBtnTypeItem::NotChecked);
2478- currentpos->getParentButton()->setChecked(
2479- OSDListBtnTypeItem::FullChecked);
2480- emit itemSelected(this, currentpos);
2481- }
2482- else
2483- handled = false;
2484- }
2485+ FillLevelFromTree(currentpos, m_levelnum);
2486+ GetLevel(m_levelnum)->SetVisible(true);
2487+ EnterItem();
2488 }
2489+ else if ((has_action("RIGHT", actions) && m_arrowAccel) ||
2490+ has_action("SELECT", actions))
2491+ {
2492+ SelectItem();
2493+ }
2494+ else
2495+ {
2496+ return false;
2497+ }
2498
2499- return handled;
2500+ return true;
2501 }
2502
2503 void OSDListTreeType::Draw(OSDSurface *surface, int fade, int maxfade,
2504 int xoff, int yoff)
2505 {
2506- QPtrListIterator<OSDListBtnType> it(listLevels);
2507- OSDListBtnType *child;
2508-
2509- while ((child = it.current()) != 0)
2510- {
2511- child->Draw(surface, fade, maxfade, xoff, yoff);
2512- ++it;
2513- }
2514+ OSDListBtnList::iterator it = listLevels.begin();
2515+ for (; it != listLevels.end(); ++it)
2516+ (*it)->Draw(surface, fade, maxfade, xoff, yoff);
2517 }
2518
2519 void OSDListTreeType::FillLevelFromTree(OSDGenericTree *item,
2520- OSDListBtnType *list)
2521+ uint level_num)
2522 {
2523+ OSDListBtnType *list = GetLevel(level_num);
2524 if (!list)
2525 {
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.");
2530 return;
2531 }
2532 list->Reset();
2533
2534 QPtrList<GenericTree> *itemlist = item->getAllChildren();
2535-
2536 QPtrListIterator<GenericTree> it(*itemlist);
2537- GenericTree *child;
2538
2539- while ((child = it.current()) != 0)
2540+ OSDGenericTree *child = (OSDGenericTree*) it.current();
2541+ OSDListBtnTypeItem *newitem = NULL;
2542+ for (;(child = (OSDGenericTree*) it.current()); ++it)
2543 {
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;
2551
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);
2559+
2560+ if (hasCheck)
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);
2567
2568- ++it;
2569+ child->setParentButton(newitem);
2570 }
2571 }
2572
2573-OSDListBtnType *OSDListTreeType::GetLevel(int levelnum)
2574+OSDListBtnType *OSDListTreeType::GetLevel(uint levelnum)
2575 {
2576- if ((uint)levelnum > listLevels.count())
2577- {
2578- cerr << "OOB GetLevel call\n";
2579- return NULL;
2580- }
2581+ if (levelnum < listLevels.size())
2582+ return listLevels[levelnum];
2583
2584- return listLevels.at(levelnum);
2585+ VERBOSE(VB_IMPORTANT, LOC_ERR + "GetLevel("<<levelnum<<") "
2586+ "listLevels.size() is only "<<listLevels.size());
2587+ return NULL;
2588 }
2589
2590-void OSDListTreeType::SetCurrentPosition(void)
2591+void OSDListTreeType::EnterItem(void)
2592 {
2593- if (!currentlevel)
2594+ if ((uint)m_levelnum >= listLevels.size())
2595 return;
2596
2597- OSDListBtnTypeItem *lbt = currentlevel->GetItemCurrent();
2598+ listLevels[m_levelnum]->SetActive(true);
2599+ OSDListBtnTypeItem *lbt = listLevels[m_levelnum]->GetItemCurrent();
2600+ if (lbt)
2601+ {
2602+ currentpos = (OSDGenericTree*) (lbt->getData());
2603+ emit itemEntered(this, currentpos);
2604+ }
2605+}
2606
2607- if (!lbt)
2608+void OSDListTreeType::SelectItem(void)
2609+{
2610+ if (!currentpos)
2611 return;
2612
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);
2618 }
2619-
2620+
2621+#undef LOC_ERR
2622+#undef LOC
2623+
2624 //////////////////////////////////////////////////////////////////////////
2625
2626 OSDListBtnType::OSDListBtnType(const QString &name, const QRect &area,
2627 float wmult, float hmult,
2628 bool showScrollArrows)
2629- : OSDType(name)
2630+ : OSDType(name),
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),
2639+ m_visible(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),
2645+ m_update(true)
2646 {
2647- m_rect = area;
2648-
2649- m_wmult = wmult;
2650- m_hmult = hmult;
2651-
2652- m_showScrollArrows = showScrollArrows;
2653-
2654- m_active = false;
2655- m_showUpArrow = false;
2656- m_showDnArrow = false;
2657-
2658- m_itemList.setAutoDelete(false);
2659- m_topItem = 0;
2660- m_selItem = 0;
2661-
2662- m_initialized = false;
2663- m_clearing = false;
2664- m_itemSpacing = 0;
2665- m_itemMargin = 0;
2666- m_itemHeight = 0;
2667- m_itemsVisible = 0;
2668- m_fontActive = 0;
2669- m_fontInactive = 0;
2670-
2671- SetItemRegColor(Qt::black,QColor(80,80,80),100);
2672- SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
2673-
2674- m_visible = false;
2675 }
2676
2677 OSDListBtnType::~OSDListBtnType()
2678@@ -457,316 +370,198 @@
2679 Reset();
2680 }
2681
2682-void OSDListBtnType::Reinit(float wchange, float hchange, float wmult,
2683- float hmult)
2684-{
2685- m_wmult = wmult;
2686- m_hmult = hmult;
2687-
2688- m_itemHeight = (int)(m_itemHeight * hchange);
2689- m_itemSpacing = (int)(m_itemSpacing * wchange);
2690- m_itemMargin = (int)(m_itemMargin * wchange);
2691-
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);
2696-
2697- m_rect = QRect(x, y, width, height);
2698-
2699- Init();
2700-
2701- OSDListBtnTypeItem* item = 0;
2702- for (item = m_itemList.first(); item; item = m_itemList.next()) {
2703- item->Reinit(wchange, hchange, wmult, hmult);
2704- }
2705-
2706-}
2707-
2708 void OSDListBtnType::SetGroupCheckState(QString group, int newState)
2709 {
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);
2714- }
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);
2719 }
2720
2721-void OSDListBtnType::SetItemRegColor(const QColor& beg, const QColor& end,
2722- uint alpha)
2723+void OSDListBtnType::Reset(void)
2724 {
2725- m_itemRegBeg = beg;
2726- m_itemRegEnd = end;
2727- m_itemRegAlpha = alpha;
2728-}
2729-
2730-void OSDListBtnType::SetItemSelColor(const QColor& beg, const QColor& end,
2731- uint alpha)
2732-{
2733- m_itemSelBeg = beg;
2734- m_itemSelEnd = end;
2735- m_itemSelAlpha = alpha;
2736-}
2737-
2738-void OSDListBtnType::SetFontActive(TTFFont *font)
2739-{
2740- m_fontActive = font;
2741-}
2742-
2743-void OSDListBtnType::SetFontInactive(TTFFont *font)
2744-{
2745- m_fontInactive = font;
2746-}
2747-
2748-void OSDListBtnType::SetSpacing(int spacing)
2749-{
2750- m_itemSpacing = spacing;
2751-}
2752-
2753-void OSDListBtnType::SetMargin(int margin)
2754-{
2755- m_itemMargin = margin;
2756-}
2757-
2758-void OSDListBtnType::SetActive(bool active)
2759-{
2760- m_active = active;
2761-}
2762-
2763-void OSDListBtnType::Reset()
2764-{
2765 QMutexLocker lock(&m_update);
2766
2767 m_clearing = true;
2768-
2769- OSDListBtnTypeItem* item = 0;
2770- for (item = m_itemList.first(); item; item = m_itemList.next()) {
2771- delete item;
2772- }
2773-
2774- m_clearing = false;
2775+ OSDListBtnItemList::iterator it;
2776+ OSDListBtnItemList clone = m_itemList;
2777 m_itemList.clear();
2778-
2779- m_topItem = 0;
2780- m_selItem = 0;
2781+ for (it = clone.begin(); it != clone.end(); ++it)
2782+ delete (*it);
2783+ m_clearing = false;
2784+
2785+ m_topIndx = 0;
2786+ m_selIndx = 0;
2787 m_showUpArrow = false;
2788 m_showDnArrow = false;
2789 }
2790
2791 void OSDListBtnType::InsertItem(OSDListBtnTypeItem *item)
2792 {
2793- OSDListBtnTypeItem* lastItem = m_itemList.last();
2794- m_itemList.append(item);
2795-
2796- if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2797- m_showDnArrow = true;
2798- else
2799- m_showDnArrow = false;
2800-
2801- if (!lastItem)
2802- {
2803- m_topItem = item;
2804- m_selItem = item;
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);
2810- }
2811 }
2812
2813+int find(const OSDListBtnItemList &list, const OSDListBtnTypeItem *item)
2814+{
2815+ for (uint i = 0; i < list.size(); i++)
2816+ if (list[i] == item)
2817+ return i;
2818+ return -1;
2819+}
2820+
2821 void OSDListBtnType::RemoveItem(OSDListBtnTypeItem *item)
2822 {
2823+ QMutexLocker lock(&m_update);
2824 if (m_clearing)
2825 return;
2826-
2827- if (m_itemList.find(item) == -1)
2828+
2829+ int i = find(m_itemList, item);
2830+ if (i < 0)
2831 return;
2832
2833- m_topItem = m_itemList.first();
2834- m_selItem = m_itemList.first();
2835+ m_itemList.erase(m_itemList.begin()+i);
2836
2837- m_itemList.remove(item);
2838-
2839 m_showUpArrow = false;
2840-
2841- if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2842- m_showDnArrow = true;
2843- else
2844- m_showDnArrow = false;
2845+ m_showDnArrow = m_itemList.size() > m_itemsVisible;
2846+ m_selIndx = 0;
2847+ m_topIndx = 0;
2848
2849- if (m_selItem) {
2850- emit itemSelected(m_selItem);
2851- }
2852+ if (m_itemList.size())
2853+ emit itemSelected(m_itemList[m_selIndx]);
2854 }
2855
2856-void OSDListBtnType::SetItemCurrent(OSDListBtnTypeItem* item)
2857+void OSDListBtnType::SetItemCurrent(const OSDListBtnTypeItem* item)
2858 {
2859- bool locked = m_update.tryLock();
2860+ QMutexLocker lock(&m_update);
2861+ int i = find(m_itemList, item);
2862+ if (i >= 0)
2863+ SetItemCurrent(i);
2864+}
2865
2866- if (m_itemList.find(item) == -1)
2867+void OSDListBtnType::SetItemCurrent(uint current)
2868+{
2869+ QMutexLocker lock(&m_update);
2870+ if (current >= m_itemList.size())
2871 return;
2872
2873- m_topItem = item;
2874- m_selItem = item;
2875-
2876- if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
2877- m_showDnArrow = true;
2878- else
2879- m_showDnArrow = false;
2880-
2881- emit itemSelected(m_selItem);
2882-
2883- if (locked)
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]);
2890 }
2891
2892-void OSDListBtnType::SetItemCurrent(int current)
2893+int OSDListBtnType::GetItemCurrentPos(void) const
2894 {
2895 QMutexLocker lock(&m_update);
2896-
2897- OSDListBtnTypeItem* item = m_itemList.at(current);
2898- if (!item)
2899- item = m_itemList.first();
2900-
2901- SetItemCurrent(item);
2902+ return (m_itemList.size()) ? m_selIndx : -1;
2903 }
2904
2905-OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent()
2906+OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent(void)
2907 {
2908- return m_selItem;
2909+ QMutexLocker lock(&m_update);
2910+ if (!m_itemList.size())
2911+ return NULL;
2912+ return m_itemList[m_selIndx];
2913 }
2914
2915-OSDListBtnTypeItem* OSDListBtnType::GetItemFirst()
2916+OSDListBtnTypeItem* OSDListBtnType::GetItemFirst(void)
2917 {
2918- return m_itemList.first();
2919+ QMutexLocker lock(&m_update);
2920+ if (!m_itemList.size())
2921+ return NULL;
2922+ return m_itemList[0];
2923 }
2924
2925-OSDListBtnTypeItem* OSDListBtnType::GetItemNext(OSDListBtnTypeItem *item)
2926+OSDListBtnTypeItem* OSDListBtnType::GetItemNext(const OSDListBtnTypeItem *item)
2927 {
2928 QMutexLocker lock(&m_update);
2929-
2930- if (m_itemList.find(item) == -1)
2931- return 0;
2932-
2933- return m_itemList.next();
2934+ int i = find(m_itemList, item) + 1;
2935+ if (i <= 0 || i >= (int)m_itemList.size())
2936+ return NULL;
2937+ return m_itemList[i];
2938 }
2939
2940-int OSDListBtnType::GetCount()
2941+int OSDListBtnType::GetCount(void) const
2942 {
2943- return m_itemList.count();
2944+ QMutexLocker lock(&m_update);
2945+ return m_itemList.size();
2946 }
2947
2948 OSDListBtnTypeItem* OSDListBtnType::GetItemAt(int pos)
2949 {
2950- return m_itemList.at(pos);
2951+ QMutexLocker lock(&m_update);
2952+ return m_itemList[pos];
2953 }
2954
2955-int OSDListBtnType::GetItemPos(OSDListBtnTypeItem* item)
2956+int OSDListBtnType::GetItemPos(const OSDListBtnTypeItem *item) const
2957 {
2958 QMutexLocker lock(&m_update);
2959-
2960- return m_itemList.find(item);
2961+ return find(m_itemList, item);
2962 }
2963
2964-void OSDListBtnType::MoveUp()
2965+void OSDListBtnType::MoveUp(void)
2966 {
2967 QMutexLocker lock(&m_update);
2968-
2969- if (m_itemList.find(m_selItem) == -1)
2970+ if (!m_itemList.size())
2971 return;
2972
2973- OSDListBtnTypeItem *item = m_itemList.prev();
2974- if (!item)
2975+ if (--m_selIndx < 0)
2976 {
2977- item = m_itemList.last();
2978- if (!item)
2979- return;
2980-
2981- if (m_itemList.count() > m_itemsVisible)
2982- m_topItem = m_itemList.at(m_itemList.count() - m_itemsVisible);
2983- else
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;
2988 }
2989
2990- m_selItem = item;
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();
2994
2995- if (m_itemList.find(m_selItem) < m_itemList.find(m_topItem))
2996- m_topItem = m_selItem;
2997-
2998- if (m_topItem != m_itemList.first())
2999- m_showUpArrow = true;
3000- else
3001- m_showUpArrow = false;
3002-
3003- if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
3004- m_showDnArrow = true;
3005- else
3006- m_showDnArrow = false;
3007-
3008- emit itemSelected(m_selItem);
3009+ emit itemSelected(m_itemList[m_selIndx]);
3010 }
3011
3012-void OSDListBtnType::MoveDown()
3013+void OSDListBtnType::MoveDown(void)
3014 {
3015 QMutexLocker lock(&m_update);
3016-
3017- if (m_itemList.find(m_selItem) == -1)
3018+ if (!m_itemList.size())
3019 return;
3020
3021- OSDListBtnTypeItem *item = m_itemList.next();
3022- if (!item)
3023- {
3024- item = m_itemList.first();
3025- if (!item)
3026- return;
3027+ if (++m_selIndx >= (int)m_itemList.size())
3028+ m_selIndx = m_topIndx = 0;
3029
3030- m_topItem = item;
3031- }
3032-
3033- m_selItem = item;
3034-
3035- if (m_itemList.find(m_topItem) + m_itemsVisible <=
3036- (unsigned int)m_itemList.find(m_selItem))
3037- {
3038- m_topItem = m_itemList.at(m_itemList.find(m_topItem) + 1);
3039- }
3040+ bool scroll_down = m_topIndx + (int)m_itemsVisible <= m_selIndx;
3041+ m_topIndx = (scroll_down) ? m_topIndx + 1 : m_topIndx;
3042+
3043+ m_showUpArrow = m_topIndx;
3044+ m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
3045
3046- if (m_topItem != m_itemList.first())
3047- m_showUpArrow = true;
3048- else
3049- m_showUpArrow = false;
3050-
3051- if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
3052- m_showDnArrow = true;
3053- else
3054- m_showDnArrow = false;
3055-
3056- emit itemSelected(m_selItem);
3057+ emit itemSelected(m_itemList[m_selIndx]);
3058 }
3059
3060-void OSDListBtnType::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
3061- int yoff)
3062+void OSDListBtnType::Draw(OSDSurface *surface,
3063+ int fade, int maxfade,
3064+ int xoff, int yoff)
3065 {
3066- (void)xoff;
3067- (void)yoff;
3068-
3069+ QMutexLocker lock(&m_update);
3070 if (!m_visible)
3071 return;
3072-
3073- QMutexLocker lock(&m_update);
3074-
3075 if (!m_initialized)
3076 Init();
3077
3078 TTFFont *font = m_active ? m_fontActive : m_fontInactive;
3079
3080 int y = m_rect.y();
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++)
3085 {
3086- it->paint(surface, font, fade, maxfade, m_rect.x()+ xoff, y + yoff);
3087-
3088+ if (!((y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight)))
3089+ break;
3090+ m_itemList[i]->paint(surface, font, fade, maxfade,
3091+ m_rect.x() + xoff, y + yoff);
3092 y += m_itemHeight + m_itemSpacing;
3093-
3094- it = m_itemList.next();
3095 }
3096
3097 if (m_showScrollArrows)
3098@@ -792,14 +587,13 @@
3099 }
3100 }
3101
3102-void OSDListBtnType::Init()
3103+void OSDListBtnType::Init(void)
3104 {
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;
3110
3111- m_itemHeight = (m_itemHeight / 2) * 2;
3112-
3113 if (m_showScrollArrows)
3114 {
3115 LoadPixmap(m_upArrowRegPix, "uparrow-reg");
3116@@ -838,11 +632,7 @@
3117 InitItem(m_itemSelActPix, itemWidth, m_itemHeight,
3118 m_itemSelBeg, m_itemSelEnd, 255);
3119
3120- if (m_itemList.count() > m_itemsVisible && m_showScrollArrows)
3121- m_showDnArrow = true;
3122- else
3123- m_showDnArrow = false;
3124-
3125+ m_showDnArrow = m_itemList.size() > m_itemsVisible && m_showScrollArrows;
3126 m_initialized = true;
3127 }
3128
3129@@ -885,68 +675,57 @@
3130
3131 void OSDListBtnType::LoadPixmap(OSDTypeImage& pix, const QString& fileName)
3132 {
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);
3137 }
3138
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)
3154 {
3155- m_parent = lbtype;
3156- m_text = text;
3157- m_pixmap = pixmap;
3158- m_checkable = checkable;
3159- m_state = state;
3160- m_showArrow = showArrow;
3161- m_data = 0;
3162-
3163 if (!m_parent->m_initialized)
3164 m_parent->Init();
3165
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;
3171
3172- OSDTypeImage& checkPix = m_parent->m_checkNonePix;
3173- OSDTypeImage& arrowPix = m_parent->m_arrowPix;
3174-
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;
3181-
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;
3191+
3192 if (m_checkable)
3193- m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
3194- else
3195- m_checkRect = QRect(0,0,0,0);
3196+ m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
3197
3198 if (m_showArrow)
3199- m_arrowRect = QRect(width - aw - margin, (height - ah)/2,
3200- aw, ah);
3201- else
3202- m_arrowRect = QRect(0,0,0,0);
3203+ m_arrowRect = QRect(width - aw - margin, (height - ah)/2, aw, ah);
3204
3205- if (m_pixmap)
3206- m_pixmapRect = QRect(m_checkable ? (2*margin + m_checkRect.width()) :
3207- margin, (height - ph)/2,
3208- pw, ph);
3209- else
3210- m_pixmapRect = QRect(0,0,0,0);
3211+ if (m_pixmap)
3212+ {
3213+ int tmp = (m_checkable) ? (2 * margin + m_checkRect.width()) : margin;
3214+ m_pixmapRect = QRect(tmp, (height - ph)/2, pw, ph);
3215+ }
3216
3217- m_textRect = QRect(margin +
3218- (m_checkable ? m_checkRect.width() + margin : 0) +
3219- (m_pixmap ? m_pixmapRect.width() + margin : 0),
3220- 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),
3225- height);
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);
3233
3234 m_parent->InsertItem(this);
3235 }
3236@@ -957,52 +736,10 @@
3237 m_parent->RemoveItem(this);
3238 }
3239
3240-QString OSDListBtnTypeItem::text() const
3241-{
3242- return m_text;
3243-}
3244-
3245-const OSDTypeImage* OSDListBtnTypeItem::pixmap() const
3246-{
3247- return m_pixmap;
3248-}
3249-
3250-bool OSDListBtnTypeItem::checkable() const
3251-{
3252- return m_checkable;
3253-}
3254-
3255-OSDListBtnTypeItem::CheckState OSDListBtnTypeItem::state() const
3256-{
3257- return m_state;
3258-}
3259-
3260-OSDListBtnType* OSDListBtnTypeItem::parent() const
3261-{
3262- return m_parent;
3263-}
3264-
3265-void OSDListBtnTypeItem::setChecked(CheckState state)
3266-{
3267- if (!m_checkable)
3268- return;
3269- m_state = state;
3270-}
3271-
3272-void OSDListBtnTypeItem::setData(void *data)
3273-{
3274- m_data = data;
3275-}
3276-
3277-void* OSDListBtnTypeItem::getData()
3278-{
3279- return m_data;
3280-}
3281-
3282 void OSDListBtnTypeItem::paint(OSDSurface *surface, TTFFont *font,
3283 int fade, int maxfade, int x, int y)
3284 {
3285- if (this == m_parent->m_selItem)
3286+ if (this == m_parent->GetItemCurrent())
3287 {
3288 if (m_parent->m_active)
3289 m_parent->m_itemSelActPix.Draw(surface, fade, maxfade, x, y);
3290@@ -1030,11 +767,14 @@
3291 cr.moveBy(x, y);
3292
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,
3296+ cr.x(), cr.y());
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,
3300+ cr.x(), cr.y());
3301 else
3302- m_parent->m_checkNonePix.Draw(surface, fade, maxfade, cr.x(), cr.y());
3303+ m_parent->m_checkNonePix.Draw(surface, fade, maxfade,
3304+ cr.x(), cr.y());
3305 }
3306
3307 if (m_pixmap)
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());
3311 }
3312-
3313-void OSDListBtnTypeItem::Reinit(float wchange, float hchange,
3314- float wmult, float hmult)
3315-{
3316- (void)wmult;
3317- (void)hmult;
3318-
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);
3323-
3324- m_checkRect = QRect(x, y, width, height);
3325-
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);
3330-
3331- m_pixmapRect = QRect(x, y, width, height);
3332-
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);
3337-
3338- m_textRect = QRect(x, y, width, height);
3339-
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);
3344-
3345- m_arrowRect = QRect(x, y, width, height);
3346-}
3347-
3348Index: mythtv/libs/libmythtv/RingBuffer.cpp
3349===================================================================
56a97e74
ER
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)
ecca4c51
ER
3352@@ -145,6 +145,12 @@
3353 VERBOSE(VB_PLAYBACK, LOC + QString("OpenFile(%1, %1)")
3354 .arg(lfilename).arg(retryCount));
3355
3356+ if ((filename.right(4).lower() == ".png") ||
3357+ (filename.right(4).lower() == ".gif"))
3358+ {
3359+ retryCount = 0;
3360+ }
3361+
3362 uint openAttempts = retryCount + 1;
3363
3364 filename = lfilename;
3365@@ -162,6 +168,7 @@
3366
3367 bool is_local = false;
3368 bool is_dvd = false;
3369+
3370 if ((filename.left(7) == "myth://") &&
3371 (filename.length() > 7 ))
3372 {
3373@@ -271,6 +278,11 @@
3374 remotefile = NULL;
3375 }
3376 }
3377+
3378+ setswitchtonext = false;
3379+ ateof = false;
3380+ commserror = false;
3381+ numfailures = 0;
3382 }
3383
3384 /** \fn RingBuffer::IsOpen(void) const
3385@@ -727,7 +739,7 @@
3386 loops = 0;
3387
3388 pthread_rwlock_rdlock(&rwlock);
3389- if (totfree > readblocksize && !commserror)
3390+ if (totfree > readblocksize && !commserror && !ateof && !setswitchtonext)
3391 {
3392 // limit the read size
3393 totfree = readblocksize;
3394@@ -737,6 +749,9 @@
3395
3396 if (remotefile)
3397 {
3398+ if (livetvchain && livetvchain->HasNext())
3399+ remotefile->SetTimeout(true);
3400+
3401 ret = safe_read(remotefile, readAheadBuffer + rbwpos,
3402 totfree);
3403 internalreadpos += ret;
3404@@ -785,8 +800,16 @@
3405 totfree = 0;
3406 }
3407
3408- if (!readsallowed && used >= fill_min)
3409+ if (!readsallowed && (used >= fill_min || setswitchtonext))
3410+ {
3411 readsallowed = true;
3412+ VERBOSE(VB_PLAYBACK, QString("reads allowed (%1 %2)").arg(used)
3413+ .arg(fill_min));
3414+ }
3415+ else if (!readsallowed)
3416+ VERBOSE(VB_PLAYBACK, QString("buffering (%1 %2 %3)").arg(used)
3417+ .arg(fill_min)
3418+ .arg(ret));
3419
3420 if (readsallowed && used < fill_min && !ateof && !setswitchtonext)
3421 {
3422@@ -808,8 +831,11 @@
3423
3424 pthread_rwlock_unlock(&rwlock);
3425
3426- if ((used >= fill_threshold || wantseek) && !pausereadthread)
3427+ if ((used >= fill_threshold || wantseek || ateof || setswitchtonext) &&
3428+ !pausereadthread)
3429+ {
3430 usleep(500);
3431+ }
3432 }
3433
3434 delete [] readAheadBuffer;
3435@@ -853,15 +879,15 @@
3436 VERBOSE(VB_IMPORTANT,
3437 LOC + "Taking too long to be allowed to read..");
3438 readErr++;
3439-
3440+
3441 // HACK Sometimes the readhead thread gets borked on startup.
3442- /* if ((readErr % 2) && (rbrpos ==0))
3443+ if ((readErr > 2 && readErr % 2) && (rbrpos ==0))
3444 {
3445 VERBOSE(VB_IMPORTANT, "restarting readhead thread..");
3446 KillReadAheadThread();
3447 StartupReadAheadThread();
3448 }
3449- */
3450+
3451 if (readErr > 10)
3452 {
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...");
3458+ if (livetvchain)
3459+ {
3460+ VERBOSE(VB_IMPORTANT, "Checking to see if there's a "
3461+ "new livetv program to switch to..");
3462+ livetvchain->ReloadAll();
3463+ }
3464 }
3465
3466 bool quit = livetvchain && (livetvchain->NeedsToSwitch() ||
3467@@ -923,7 +955,7 @@
3468 availWaitMutex.unlock();
3469
3470 avail = ReadBufAvail();
3471- if (ateof && avail < count)
3472+ if ((ateof || setswitchtonext) && avail < count)
3473 count = avail;
3474
3475 if (commserror)
3476Index: mythtv/libs/libmythtv/hdtvrecorder.cpp
3477===================================================================
56a97e74
ER
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)
ecca4c51
ER
3480@@ -627,9 +627,8 @@
3481
3482 len += remainder;
3483 remainder = ProcessData(_buffer, len);
3484- if (remainder > 0) // leftover bytes
3485- memmove(_buffer, &(_buffer[_buffer_size - remainder]),
3486- remainder);
3487+ if (remainder > 0 && (len > remainder)) // leftover bytes
3488+ memmove(_buffer, &(_buffer[len - remainder]), remainder);
3489 }
3490
3491 FinishRecording();
3492Index: mythtv/libs/libmythtv/dummydtvrecorder.cpp
3493===================================================================
56a97e74
ER
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)
ecca4c51
ER
3496@@ -125,7 +125,8 @@
3497 // TRANSFER DATA
3498 while (_request_recording || _frames_seen_count <= 5)
3499 {
3500- len = read(_stream_fd, &(_buffer[remainder]), _buffer_size - remainder);
3501+ len = read(_stream_fd, &(_buffer[remainder]),
3502+ _buffer_size - remainder);
3503
3504 if (len == 0)
3505 {
3506@@ -137,9 +138,8 @@
3507
3508 len += remainder;
3509 remainder = ProcessData(_buffer, len);
3510- if (remainder > 0) // leftover bytes
3511- memmove(_buffer, &(_buffer[_buffer_size - remainder]),
3512- remainder);
3513+ if (remainder > 0 && (len > remainder)) // leftover bytes
3514+ memmove(_buffer, &(_buffer[len - remainder]), remainder);
3515 }
3516
3517 FinishRecording();
3518Index: mythtv/libs/libmythtv/avformatdecoder.cpp
3519===================================================================
56a97e74
ER
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)
ecca4c51
ER
3522@@ -725,7 +725,12 @@
3523 return -1;
3524 }
3525
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();
3531+
3532 if (ret < 0)
3533 {
3534 VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not find codec parameters. " +
3535Index: mythtv/libs/libmythtv/osdtypes.cpp
3536===================================================================
56a97e74
ER
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)
ecca4c51
ER
3539@@ -14,6 +14,9 @@
3540
3541 #include "mythcontext.h"
3542
3543+/// Shared OSD image cache
3544+OSDImageCache OSDTypeImage::c_cache;
3545+
3546 OSDSet::OSDSet(const QString &name, bool cache, int screenwidth,
3547 int screenheight, float wmult, float hmult, int frint)
3548 : QObject()
3549@@ -160,9 +163,6 @@
3550 int displaywidth, int displayheight,
3551 float wmult, float hmult, int frint)
3552 {
3553- float wchange = wmult / m_wmult;
3554- float hchange = hmult / m_hmult;
3555-
3556 m_frameint = frint;
3557
3558 m_screenwidth = screenwidth;
3559@@ -175,57 +175,12 @@
3560 vector<OSDType *>::iterator iter = allTypes->begin();
3561 for (;iter != allTypes->end(); iter++)
3562 {
3563- OSDType *type = (*iter);
3564- if (OSDTypeText *item = dynamic_cast<OSDTypeText*>(type))
3565- {
3566- item->Reinit(wchange, hchange);
3567- }
3568- else if (OSDTypePositionImage *item =
3569- dynamic_cast<OSDTypePositionImage*>(type))
3570- {
3571- item->Reinit(wchange, hchange, wmult, hmult);
3572- }
3573- else if (OSDTypePosSlider *item = dynamic_cast<OSDTypePosSlider*>(type))
3574- {
3575- item->Reinit(wchange, hchange, wmult, hmult);
3576- }
3577- else if (OSDTypeFillSlider *item =
3578- dynamic_cast<OSDTypeFillSlider*>(type))
3579- {
3580- item->Reinit(wchange, hchange, wmult, hmult);
3581- }
3582- else if (OSDTypeEditSlider *item =
3583- dynamic_cast<OSDTypeEditSlider*>(type))
3584- {
3585- item->Reinit(wchange, hchange, wmult, hmult);
3586- }
3587- else if (OSDTypeImage *item = dynamic_cast<OSDTypeImage*>(type))
3588- {
3589- item->Reinit(wchange, hchange, wmult, hmult);
3590- }
3591- else if (OSDTypeBox *item = dynamic_cast<OSDTypeBox*>(type))
3592- {
3593- item->Reinit(wchange, hchange);
3594- }
3595- else if (OSDTypePositionRectangle *item =
3596- dynamic_cast<OSDTypePositionRectangle*>(type))
3597- {
3598- item->Reinit(wchange, hchange);
3599- }
3600- else if (OSDTypeCC *item = dynamic_cast<OSDTypeCC*>(type))
3601- {
3602- item->Reinit(xoff, yoff, displaywidth, displayheight);
3603- }
3604- else if (OSDListTreeType *item = dynamic_cast<OSDListTreeType*>(type))
3605- {
3606- item->Reinit(wchange, hchange, wmult, hmult);
3607- }
3608+ if (OSDTypeCC *cc608 = dynamic_cast<OSDTypeCC*>(*iter))
3609+ cc608->Reinit(xoff, yoff, displaywidth, displayheight,
3610+ wmult, hmult);
3611 else
3612- {
3613- cerr << "Unknown conversion\n";
3614- }
3615+ (*iter)->Reinit(wmult, hmult);
3616 }
3617-
3618 }
3619
3620 OSDType *OSDSet::GetType(const QString &name)
3621@@ -443,7 +398,8 @@
3622 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3623
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)
3628 : OSDType(name)
3629 {
3630 m_message = text;
3631@@ -464,6 +420,12 @@
3632 m_scrollinit = false;
3633
3634 m_linespacing = 1.5;
3635+
3636+ m_unbiasedsize =
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));
3641 }
3642
3643 OSDTypeText::OSDTypeText(const OSDTypeText &other)
3644@@ -507,14 +469,13 @@
3645 m_scrollinit = false;
3646 }
3647
3648-void OSDTypeText::Reinit(float wchange, float hchange)
3649+void OSDTypeText::Reinit(float wmult, float hmult)
3650 {
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);
3655-
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));
3662 }
3663
3664 void OSDTypeText::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
3665@@ -708,7 +669,7 @@
3666 m_onlyusefirst = false;
3667
3668 m_filename = filename;
3669- m_displaypos = displaypos;
3670+ SetPosition(displaypos, wmult, hmult);
3671
3672 m_yuv = m_alpha = NULL;
3673 m_isvalid = false;
3674@@ -716,6 +677,7 @@
3675
3676 m_scalew = scalew;
3677 m_scaleh = scaleh;
3678+ m_cacheitem = NULL;
3679
3680 LoadImage(filename, wmult, hmult, scalew, scaleh);
3681 }
3682@@ -733,6 +695,7 @@
3683 m_name = other.m_name;
3684 m_scalew = other.m_scalew;
3685 m_scaleh = other.m_scaleh;
3686+ m_cacheitem = NULL;
3687
3688 m_alpha = m_yuv = NULL;
3689 if (m_isvalid)
3690@@ -760,6 +723,8 @@
3691 m_onlyusefirst = false;
3692
3693 m_displaypos = QPoint(0, 0);
3694+ m_unbiasedpos = QPoint(0, 0);
3695+ m_cacheitem = NULL;
3696
3697 m_yuv = NULL;
3698 m_alpha = NULL;
3699@@ -778,6 +743,8 @@
3700 m_onlyusefirst = false;
3701
3702 m_displaypos = QPoint(0, 0);
3703+ m_unbiasedpos = QPoint(0, 0);
3704+ m_cacheitem = NULL;
3705
3706 m_yuv = NULL;
3707 m_alpha = NULL;
3708@@ -790,10 +757,14 @@
3709
3710 OSDTypeImage::~OSDTypeImage()
3711 {
3712- if (m_yuv)
3713- delete [] m_yuv;
3714- if (m_alpha)
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.
3719+ if (m_cacheitem)
3720+ {
3721+ delete m_cacheitem;
3722+ m_cacheitem = NULL;
3723+ }
3724 }
3725
3726 void OSDTypeImage::SetName(const QString &name)
3727@@ -801,13 +772,19 @@
3728 m_name = name;
3729 }
3730
3731-void OSDTypeImage::Reinit(float wchange, float hchange, float wmult, float hmult)
3732+void OSDTypeImage::SetPosition(QPoint pos, float wmult, float hmult)
3733 {
3734- int x = (int)(m_displaypos.x() * wchange);
3735- int y = (int)(m_displaypos.y() * hchange);
3736+ m_displaypos = pos;
3737+ m_unbiasedpos =
3738+ QPoint((int)round(pos.x() / wmult),
3739+ (int)round(pos.y() / hmult));
3740+}
3741
3742- m_displaypos.setX(x);
3743- m_displaypos.setY(y);
3744+void OSDTypeImage::Reinit(float wmult, float hmult)
3745+{
3746+ m_displaypos =
3747+ QPoint((int)round(m_unbiasedpos.x() * wmult),
3748+ (int)round(m_unbiasedpos.y() * hmult));
3749
3750 LoadImage(m_filename, wmult, hmult, m_scalew, m_scaleh);
3751 }
3752@@ -815,20 +792,44 @@
3753 void OSDTypeImage::LoadImage(const QString &filename, float wmult, float hmult,
3754 int scalew, int scaleh)
3755 {
3756- if (m_isvalid)
3757+ QString ckey;
3758+
3759+ if (!filename.isEmpty() && filename.length() >= 2)
3760 {
3761- if (m_yuv)
3762- delete [] m_yuv;
3763- if (m_alpha)
3764- delete [] m_alpha;
3765-
3766- m_isvalid = false;
3767- m_yuv = NULL;
3768- m_alpha = NULL;
3769+ ckey = OSDImageCache::CreateKey(
3770+ filename, wmult, hmult, scalew, scaleh);
3771 }
3772+ else
3773+ {
3774+ // this method requires a backing file
3775+ return;
3776+ }
3777+
3778+ // Get the item from the cache so it's not freed while in use
3779+ OSDImageCacheValue* value = c_cache.Get(ckey, true);
3780+
3781+ if (value != NULL)
3782+ {
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;
3789+ m_isvalid = true;
3790
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
3794+ // is reached
3795+ if (!m_cacheitem)
3796+ c_cache.Insert(m_cacheitem);
3797+ m_cacheitem = value;
3798+
3799 return;
3800+ }
3801+
3802+ // scaled image was not found in cache, have to create it
3803+
3804
3805 QImage tmpimage(filename);
3806
3807@@ -867,17 +868,32 @@
3808 imwidth, imheight, tmp2.width());
3809
3810 m_imagesize = QRect(0, 0, imwidth, imheight);
3811+
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
3814+ // is reached
3815+ if (m_cacheitem)
3816+ c_cache.Insert(m_cacheitem);
3817+
3818+ m_cacheitem = new OSDImageCacheValue(
3819+ ckey,
3820+ m_yuv, m_ybuffer, m_ubuffer,
3821+ m_vbuffer, m_alpha, m_imagesize);
3822+
3823+ // save the new cache item to the file cache
3824+ if (!filename.isEmpty())
3825+ c_cache.SaveToDisk(m_cacheitem);
3826 }
3827
3828 void OSDTypeImage::LoadFromQImage(const QImage &img)
3829 {
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
3833 if (m_isvalid)
3834 {
3835- if (m_yuv)
3836- delete [] m_yuv;
3837- if (m_alpha)
3838- delete [] m_alpha;
3839-
3840+ delete m_cacheitem;
3841+ m_cacheitem = NULL;
3842 m_isvalid = false;
3843 m_yuv = NULL;
3844 m_alpha = NULL;
3845@@ -1043,23 +1059,25 @@
3846 m_maxval = 1000;
3847 m_curval = 0;
3848 m_displayrect = displayrect;
3849+ m_unbiasedrect =
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));
3854 }
3855
3856 OSDTypePosSlider::~OSDTypePosSlider()
3857 {
3858 }
3859
3860-void OSDTypePosSlider::Reinit(float wchange, float hchange, float wmult,
3861- float hmult)
3862+void OSDTypePosSlider::Reinit(float wmult, float hmult)
3863 {
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);
3868-
3869- m_displayrect = QRect(x, y, width, height);
3870-
3871- OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
3872+ m_displayrect =
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);
3878 }
3879
3880 void OSDTypePosSlider::SetPosition(int pos)
3881@@ -1092,23 +1110,25 @@
3882 m_drawwidth = 0;
3883 m_onlyusefirst = true;
3884 m_displayrect = displayrect;
3885+ m_unbiasedrect =
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));
3890 }
3891
3892 OSDTypeFillSlider::~OSDTypeFillSlider()
3893 {
3894 }
3895
3896-void OSDTypeFillSlider::Reinit(float wchange, float hchange, float wmult,
3897- float hmult)
3898+void OSDTypeFillSlider::Reinit(float wmult, float hmult)
3899 {
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);
3904-
3905- m_displayrect = QRect(x, y, width, height);
3906-
3907- OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
3908+ m_displayrect =
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);
3914 }
3915
3916 void OSDTypeFillSlider::SetPosition(int pos)
3917@@ -1143,6 +1163,11 @@
3918 m_maxval = 1000;
3919 m_curval = 0;
3920 m_displayrect = displayrect;
3921+ m_unbiasedrect =
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();
3927
3928 m_drawMap = new unsigned char[m_drawwidth + 1];
3929@@ -1162,6 +1187,7 @@
3930
3931 m_scalew = scalew;
3932 m_scaleh = scaleh;
3933+ m_cacheitem = NULL;
3934
3935 LoadImage(m_redname, wmult, hmult, scalew, scaleh);
3936 if (m_isvalid)
3937@@ -1184,22 +1210,16 @@
3938 OSDTypeEditSlider::~OSDTypeEditSlider()
3939 {
3940 delete [] m_drawMap;
3941-
3942- if (m_ryuv)
3943- delete [] m_ryuv;
3944- if (m_ralpha)
3945- delete [] m_ralpha;
3946 }
3947
3948-void OSDTypeEditSlider::Reinit(float wchange, float hchange, float wmult,
3949- float hmult)
3950+void OSDTypeEditSlider::Reinit(float wmult, float hmult)
3951 {
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);
3956+ m_displayrect =
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));
3961
3962- m_displayrect = QRect(x, y, width, height);
3963 m_drawwidth = m_displayrect.width();
3964
3965 delete [] m_drawMap;
3966@@ -1210,11 +1230,6 @@
3967
3968 m_displaypos = m_displayrect.topLeft();
3969
3970- if (m_ryuv)
3971- delete [] m_ryuv;
3972- if (m_ralpha)
3973- delete [] m_ralpha;
3974-
3975 LoadImage(m_redname, wmult, hmult, m_scalew, m_scaleh);
3976 if (m_isvalid)
3977 {
3978@@ -1360,30 +1375,46 @@
3979
3980 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3981
3982-OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect)
3983- : OSDType(name)
3984+OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect,
3985+ float wmult, float hmult)
3986+ : OSDType(name)
3987 {
3988 size = displayrect;
3989+ m_unbiasedsize =
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));
3994 }
3995
3996+void OSDTypeBox::SetRect(QRect newrect, float wmult, float hmult)
3997+{
3998+ size = newrect;
3999+ m_unbiasedsize =
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));
4004+}
4005+
4006 OSDTypeBox::OSDTypeBox(const OSDTypeBox &other)
4007 : OSDType(other.m_name)
4008 {
4009 size = other.size;
4010+ m_unbiasedsize = other.m_unbiasedsize;
4011 }
4012
4013 OSDTypeBox::~OSDTypeBox()
4014 {
4015 }
4016
4017-void OSDTypeBox::Reinit(float wchange, float hchange)
4018+void OSDTypeBox::Reinit(float wmult, float hmult)
4019 {
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);
4024-
4025- size = QRect(x, y, width, height);
4026+ size =
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));
4031 }
4032
4033 void OSDTypeBox::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
4034@@ -1498,44 +1529,52 @@
4035 }
4036
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)
4042 {
4043 for (int i = 0; i < m_numpositions; i++)
4044 {
4045 QRect tmp = other.positions[i];
4046 positions.push_back(tmp);
4047 }
4048+ for (int i = 0; i < m_numpositions; i++)
4049+ {
4050+ QRect tmp = other.unbiasedpos[i];
4051+ unbiasedpos.push_back(tmp);
4052+ }
4053 }
4054
4055 OSDTypePositionRectangle::~OSDTypePositionRectangle()
4056 {
4057 }
4058
4059-void OSDTypePositionRectangle::Reinit(float wchange, float hchange)
4060+void OSDTypePositionRectangle::Reinit(float wmult, float hmult)
4061 {
4062 for (int i = 0; i < m_numpositions; i++)
4063 {
4064- QRect tmp = positions[i];
4065-
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);
4070-
4071- tmp = QRect(x, y, width, height);
4072- positions[i] = tmp;
4073+ QRect tmp = unbiasedpos[i];
4074+ positions[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));
4079 }
4080 }
4081
4082-void OSDTypePositionRectangle::AddPosition(QRect rect)
4083+void OSDTypePositionRectangle::AddPosition(
4084+ QRect rect, float wmult, float hmult)
4085 {
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)));
4092 m_numpositions++;
4093 }
4094
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)
4099 {
4100 fade = fade;
4101 maxfade = maxfade;
4102@@ -1618,17 +1657,21 @@
4103 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4104
4105 OSDTypePositionImage::OSDTypePositionImage(const QString &name)
4106- : OSDTypeImage(name), OSDTypePositionIndicator()
4107+ : OSDTypeImage(name), OSDTypePositionIndicator(),
4108+ m_wmult(0.0f), m_hmult(0.0f)
4109 {
4110 }
4111
4112 OSDTypePositionImage::OSDTypePositionImage(const OSDTypePositionImage &other)
4113 : OSDTypeImage(other), OSDTypePositionIndicator(other)
4114 {
4115+ m_wmult = other.m_wmult;
4116+ m_hmult = other.m_hmult;
4117+
4118 for (int i = 0; i < m_numpositions; i++)
4119 {
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]);
4124 }
4125 }
4126
4127@@ -1636,45 +1679,61 @@
4128 {
4129 }
4130
4131-void OSDTypePositionImage::Reinit(float wchange, float hchange, float wmult,
4132- float hmult)
4133+void OSDTypePositionImage::Reinit(float wmult, float hmult)
4134 {
4135- OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
4136+ m_wmult = wmult;
4137+ m_hmult = hmult;
4138+
4139+ OSDTypeImage::Reinit(wmult, hmult);
4140
4141 for (int i = 0; i < m_numpositions; i++)
4142 {
4143- QPoint tmp = positions[i];
4144-
4145- int x = (int)(tmp.x() * wchange);
4146- int y = (int)(tmp.y() * hchange);
4147-
4148- positions[i].setX(x);
4149- positions[i].setY(y);
4150+ positions[i] =
4151+ QPoint((int)round(unbiasedpos[i].x() * wmult),
4152+ (int)round(unbiasedpos[i].y() * hmult));
4153 }
4154 }
4155
4156-void OSDTypePositionImage::AddPosition(QPoint pos)
4157+void OSDTypePositionImage::AddPosition(QPoint pos, float wmult, float hmult)
4158 {
4159+ if (m_wmult == 0.0f || m_hmult == 0.0f)
4160+ {
4161+ m_wmult = wmult;
4162+ m_hmult = hmult;
4163+ }
4164 positions.push_back(pos);
4165+ unbiasedpos.push_back(
4166+ QPoint((int)round(pos.x() / wmult),
4167+ (int)round(pos.y() / hmult)));
4168+
4169+ VERBOSE(VB_IMPORTANT,
4170+ "OSDTypePositionImage::AddPosition["<<m_numpositions<<"]("
4171+ <<pos.x()<<"x"<<pos.y()
4172+ <<" "<<wmult<<", "<<hmult<<")");
4173+
4174 m_numpositions++;
4175 }
4176
4177 void OSDTypePositionImage::Draw(OSDSurface *surface, int fade, int maxfade,
4178 int xoff, int yoff)
4179 {
4180+ VERBOSE(VB_IMPORTANT,
4181+ "OSDTypePositionImage::Draw["<<m_curposition<<"]("
4182+ <<m_wmult<<", "<<m_hmult<<")");
4183+
4184 if (m_curposition < 0 || m_curposition >= m_numpositions)
4185 return;
4186
4187 QPoint pos = positions[m_curposition];
4188
4189- OSDTypeImage::SetPosition(pos);
4190+ OSDTypeImage::SetPosition(pos, m_wmult, m_hmult);
4191 OSDTypeImage::Draw(surface, fade, maxfade, xoff, yoff);
4192 }
4193
4194 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4195
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)
4199 : OSDType(name)
4200 {
4201 m_font = font;
4202@@ -1683,9 +1742,11 @@
4203 yoffset = yoff;
4204 displaywidth = dispw;
4205 displayheight = disph;
4206+ m_wmult = wmult;
4207+ m_hmult = hmult;
4208
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);
4213 }
4214
4215@@ -1695,12 +1756,23 @@
4216 delete m_box;
4217 }
4218
4219-void OSDTypeCC::Reinit(int x, int y, int dispw, int disph)
4220+void OSDTypeCC::Reinit(float wmult, float hmult)
4221 {
4222+ (void) wmult;
4223+ (void) hmult;
4224+ VERBOSE(VB_IMPORTANT, "Programmer error: "
4225+ "Call to OSDTypeCC::Reinit(float,float)");
4226+}
4227+
4228+void OSDTypeCC::Reinit(int x, int y, int dispw, int disph,
4229+ float wmult, float hmult)
4230+{
4231 xoffset = x;
4232 yoffset = y;
4233 displaywidth = dispw;
4234 displayheight = disph;
4235+ m_wmult = wmult;
4236+ m_hmult = hmult;
4237 }
4238
4239 void OSDTypeCC::AddCCText(const QString &text, int x, int y, int color,
4240@@ -1875,7 +1947,7 @@
4241 {
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);
4247 }
4248
4249Index: mythtv/libs/libmythtv/tv_play.cpp
4250===================================================================
56a97e74
ER
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)
ecca4c51
ER
4253@@ -247,7 +247,7 @@
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),
4260 // Video Players
4261 nvp(NULL), pipnvp(NULL), activenvp(NULL),
4262@@ -578,19 +578,7 @@
4263 if (!testrec->IsValidRecorder())
4264 {
4265 if (showDialogs)
4266- {
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 "
4273- "menu.");
4274-
4275- DialogBox diag(gContext->GetMainWindow(), title);
4276- diag.AddButton(tr("Cancel and go back to the TV menu"));
4277- diag.exec();
4278- }
4279+ ShowNoRecorderDialog();
4280
4281 delete testrec;
4282
4283@@ -659,8 +647,6 @@
4284 if (internalState != kState_None)
4285 return 0;
4286
4287- inputFilename = rcinfo->pathname;
4288-
4289 playbackLen = rcinfo->CalculateLength();
4290 playbackinfo = new ProgramInfo(*rcinfo);
4291
4292@@ -844,9 +830,10 @@
4293 }
4294 else
4295 {
4296+ QString playbackURL = playbackinfo->GetPlaybackURL();
4297+
4298 tvchain->SetProgram(playbackinfo);
4299-
4300- prbuffer = new RingBuffer(playbackinfo->pathname, false);
4301+ prbuffer = new RingBuffer(playbackURL, false);
4302 prbuffer->SetLiveMode(tvchain);
4303 }
4304
4305@@ -895,7 +882,14 @@
4306 else if (TRANSITION(kState_None, kState_WatchingPreRecorded) ||
4307 TRANSITION(kState_None, kState_WatchingRecording))
4308 {
4309- prbuffer = new RingBuffer(inputFilename, false);
4310+ QString playbackURL;
4311+ if ((playbackinfo->pathname.left(4) == "dvd:") ||
4312+ (playbackinfo->isVideo))
4313+ playbackURL = playbackinfo->pathname;
4314+ else
4315+ playbackURL = playbackinfo->GetPlaybackURL();
4316+
4317+ prbuffer = new RingBuffer(playbackURL, false);
4318 if (prbuffer->IsOpen())
4319 {
4320 gContext->DisableScreensaver();
4321@@ -924,7 +918,7 @@
4322 {
4323 QString message = "COMMFLAG_REQUEST ";
4324 message += playbackinfo->chanid + " " +
4325- playbackinfo->startts.toString(Qt::ISODate);
4326+ playbackinfo->recstartts.toString(Qt::ISODate);
4327 RemoteSendMessage(message);
4328 }
4329 }
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);
4342
4343@@ -1296,9 +1290,9 @@
4344 pipnvp->SetAsPIP();
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);
4353
4354 pipnvp->SetLength(playbackLen);
4355@@ -1454,6 +1448,30 @@
4356 lastSignalMsg.clear();
4357 }
4358 UpdateOSDTimeoutMessage();
4359+
4360+ if (!tvchainUpdate.isEmpty())
4361+ {
4362+ tvchainUpdateLock.lock();
4363+ for (QStringList::Iterator it = tvchainUpdate.begin();
4364+ it != tvchainUpdate.end(); ++it)
4365+ {
4366+ if (tvchain && nvp && *it == tvchain->GetID())
4367+ {
4368+ tvchain->ReloadAll();
4369+ if (nvp->GetTVChain())
4370+ nvp->CheckTVChain();
4371+ }
4372+ if (piptvchain && pipnvp && *it == piptvchain->GetID())
4373+ {
4374+ piptvchain->ReloadAll();
4375+ if (pipnvp->GetTVChain())
4376+ pipnvp->CheckTVChain();
4377+ }
4378+ }
4379+ tvchainUpdate.clear();
4380+ tvchainUpdateLock.unlock();
4381+ }
4382+
4383 osdlock.unlock();
4384 }
4385
4386@@ -2743,7 +2761,7 @@
4387 speedStr = QString("%1X").arg(normal_speed);
4388
4389 struct StatusPosInfo posInfo;
4390- nvp->calcSliderPos(posInfo);
4391+ nvp->calcSliderPos(posInfo, true);
4392
4393 QDateTime respDate = mythCurrentDateTime();
4394 QString infoStr = "";
4395@@ -2806,8 +2824,10 @@
4396 }
4397 else
4398 {
4399+ QString playbackURL = playbackinfo->GetPlaybackURL();
4400+
4401 piptvchain->SetProgram(playbackinfo);
4402- piprbuffer = new RingBuffer(playbackinfo->pathname, false);
4403+ piprbuffer = new RingBuffer(playbackURL, false);
4404 piprbuffer->SetLiveMode(piptvchain);
4405 }
4406
4407@@ -3472,8 +3492,10 @@
4408 }
4409 else
4410 {
4411+ QString playbackURL = playbackinfo->GetPlaybackURL();
4412+
4413 tvchain->SetProgram(playbackinfo);
4414- prbuffer = new RingBuffer(playbackinfo->pathname, false);
4415+ prbuffer = new RingBuffer(playbackURL, false);
4416 prbuffer->SetLiveMode(tvchain);
4417 }
4418
4419@@ -4627,7 +4649,8 @@
4420
4421 normal_speed = new_normal_speed;
4422
4423- activenvp->Play(normal_speed, true);
4424+ if (!paused)
4425+ activenvp->Play(normal_speed, true);
4426
4427 QString text = QString(tr("Time Stretch %1X")).arg(normal_speed);
4428
4429@@ -4911,29 +4934,14 @@
4430 }
4431 else if (tvchain && message.left(12) == "LIVETV_CHAIN")
4432 {
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)
4436- usleep(2500);
4437-
4438 message = message.simplifyWhiteSpace();
4439 QStringList tokens = QStringList::split(" ", message);
4440 if (tokens[1] == "UPDATE")
4441 {
4442- if (tvchain && nvp && tokens[2] == tvchain->GetID())
4443- {
4444- tvchain->ReloadAll();
4445- if (nvp->GetTVChain())
4446- nvp->CheckTVChain();
4447- }
4448- if (piptvchain && pipnvp && tokens[2] == piptvchain->GetID())
4449- {
4450- piptvchain->ReloadAll();
4451- if (pipnvp->GetTVChain())
4452- pipnvp->CheckTVChain();
4453- }
4454+ tvchainUpdateLock.lock();
4455+ tvchainUpdate += QDeepCopy<QString>(tokens[2]);
4456+ tvchainUpdateLock.unlock();
4457 }
4458- osdlock.unlock();
4459 }
4460 else if (nvp && message.left(12) == "EXIT_TO_MENU")
4461 {
4462@@ -4983,7 +4991,7 @@
4463 QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
4464
4465 if ((playbackinfo->chanid == evchanid) &&
4466- (playbackinfo->startts == evstartts))
4467+ (playbackinfo->recstartts == evstartts))
4468 {
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);
4473
4474 if ((playbackinfo->chanid == evchanid) &&
4475- (playbackinfo->startts == evstartts))
4476+ (playbackinfo->recstartts == evstartts))
4477 {
4478 QMap<long long, int> newMap;
4479 QStringList mark;
4480@@ -6067,9 +6075,22 @@
4481 "in-progress recordings from the delete "
4482 "menu.");
4483
4484- MythPopupBox::showOkPopup(
4485+ if (embedWinID)
4486+ {
4487+ VERBOSE(VB_IMPORTANT, errorText);
4488+ }
4489+ else if (GetOSD())
4490+ {
4491+ dialogname = "infobox";
4492+ QStringList options("OK");
4493+ GetOSD()->NewDialogBox(dialogname, errorText, options, 0);
4494+ }
4495+ else
4496+ {
4497+ MythPopupBox::showOkPopup(
4498 gContext->GetMainWindow(), QObject::tr("Channel Change Error"),
4499 errorText);
4500+ }
4501 }
4502
4503 /** \fn TV::PauseLiveTV(void)
4504Index: mythtv/libs/libmythtv/jobqueue.cpp
4505===================================================================
56a97e74
ER
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)
ecca4c51
ER
4508@@ -275,6 +275,11 @@
4509 (hostname != "") &&
4510 (hostname != m_hostname))
4511 {
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;
4516+
4517 message = QString("JobQueue: Skipping '%1' job for chanid "
4518 "%2 @ %3, should run on '%4' instead")
4519 .arg(JobText(type))
4520Index: mythtv/libs/libmythtv/dvbdev/dvbdev.c
4521===================================================================
56a97e74
ER
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)
ecca4c51
ER
4524@@ -29,55 +29,79 @@
4525
4526 const char* dvbdevice(int type, int cardnum)
4527 {
4528- char* frontenddev[4] =
4529+ char* frontenddev[8] =
4530 {
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",
4540 };
4541
4542- char* dvrdev[4] =
4543+ char* dvrdev[8] =
4544 {
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",
4554 };
4555
4556- char* demuxdev[4] =
4557+ char* demuxdev[8] =
4558 {
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",
4568 };
4569
4570- char* cadev[4] =
4571+ char* cadev[8] =
4572 {
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",
4582 };
4583
4584- char* audiodev[4] =
4585+ char* audiodev[8] =
4586 {
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",
4596 };
4597
4598- char* videodev[4] =
4599+ char* videodev[8] =
4600 {
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",
4610 };
4611
4612- if (cardnum > 3)
4613+ if (cardnum > 7)
4614 return 0;
4615
4616 switch(type)
73e9aca0
ER
4617Index: mythtv/libs/libmythtv/videosource.h
4618===================================================================
56a97e74
ER
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)
73e9aca0
ER
4621@@ -75,6 +75,7 @@
4622
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);
4627
4628 static bool IgnoreEncrypted(uint cardid, const QString &inputname);
ecca4c51
ER
4629Index: mythtv/libs/libmythtv/libmythtv.pro
4630===================================================================
56a97e74
ER
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
4636
4637+# C stuff
4638+HEADERS += frequencies.h
4639+SOURCES += frequencies.c
4640+
4641 using_frontend {
4642 # Recording profile stuff
4643 HEADERS += profilegroup.h
4644@@ -144,10 +148,10 @@
ecca4c51
ER
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
4654
4655 # Video output
4656 HEADERS += videooutbase.h videoout_null.h
56a97e74
ER
4657@@ -303,10 +307,6 @@
4658 }
4659 }
4660
4661- # C stuff
4662- HEADERS += frequencies.h
4663- SOURCES += frequencies.c
4664-
4665 DEFINES += USING_BACKEND
4666 }
4667
73e9aca0
ER
4668Index: mythtv/libs/libmythtv/dvbchannel.cpp
4669===================================================================
56a97e74
ER
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)
73e9aca0
ER
4672@@ -74,14 +74,27 @@
4673 * \bug Only supports single input cards.
4674 */
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),
4686+ retune_adj(-10)
4687 {
4688 dvbcam = new DVBCam(cardnum);
4689 bzero(&info, sizeof(info));
4690 has_crc_bug = CardUtil::HasDVBCRCBug(aCardNum);
4691+
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"))
4696+ {
4697+ tuning_delay = 200;
4698+ }
4699+
4700+ sigmon_delay = CardUtil::GetMinSignalMonitoringDelay(aCardNum);
4701 }
4702
4703 DVBChannel::~DVBChannel()
4704@@ -367,7 +380,7 @@
4705 }
4706
4707 bool found = false;
4708- int mplexid;
4709+ int mplexid = 0;
4710 while (query.next())
4711 {
4712 int this_inputid = query.value(4).toInt();
4713@@ -633,7 +646,8 @@
4714 * This is used by DVB Channel Scanner, the EIT Parser, and by TVRec.
4715 *
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
4721 */
4722 bool DVBChannel::Tune(const dvb_channel_t& channel, bool force_reset)
4723@@ -642,6 +656,8 @@
4724 bool has_diseq = (FE_QPSK == info.type) && diseqc;
4725 struct dvb_frontend_parameters params = channel.tuning.params;
4726
4727+ retune_tuning = channel.tuning;
4728+
4729 if (fd_frontend < 0)
4730 {
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);
4735
4736+ params.frequency = params.frequency + (retune_adj = -retune_adj);
4737+
4738 if (ioctl(fd_frontend, FE_SET_FRONTEND, &params) < 0)
4739 {
4740 ERRNO("DVBChannel::Tune: "
4741 "Setting Frontend tuning parameters failed.");
4742 return false;
4743 }
4744+
4745+ // Extra delay to add for broken DVB drivers
4746+ if (tuning_delay)
4747+ usleep(tuning_delay * 1000);
4748+
4749 wait_for_backend(fd_frontend, 5 /* msec */);
4750
4751- prev_tuning.params = params;
4752+ prev_tuning.params = channel.tuning.params;
4753 first_tune = false;
4754 }
4755
4756@@ -686,6 +709,24 @@
4757 return true;
4758 }
4759
4760+/** \fn DVBChannel::Retune(void)
4761+ * \brief Calls DVBChannel::Tune() with the last known parameters
4762+ *
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.
4768+ *
4769+ * \return true iff drivers report that tuning was successful
4770+ */
4771+bool DVBChannel::Retune(void)
4772+{
4773+ dvb_channel_t retune_channel;
4774+ retune_channel.tuning = retune_tuning;
4775+ return Tune(retune_channel, true);
4776+}
4777+
4778 /** \fn DVBChannel::GetTuningParams(DVBTuning& tuning) const
4779 * \brief Fetches DVBTuning params from driver
4780 * \return true on success, false on failure
4781@@ -855,6 +896,9 @@
4782 for (uint i = 0; i < 64 && !tuned; i++)
4783 if (!diseqc->Set(t, reset, tuned))
4784 return false;
4785-
4786+
4787+ // Wait 10 ms, recommended by Marcus Metzler, see #1552
4788+ usleep(10 * 1000);
4789+
4790 return true;
4791 }
ecca4c51
ER
4792Index: mythtv/libs/libmythtv/osdtypes.h
4793===================================================================
56a97e74
ER
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)
ecca4c51
ER
4796@@ -8,6 +8,7 @@
4797 #include <vector>
4798 #include <qobject.h>
4799 #include <qregexp.h>
4800+#include "osdimagecache.h"
4801
4802 using namespace std;
4803
4804@@ -137,6 +138,8 @@
4805
4806 QString Name() { return m_name; }
4807
4808+ virtual void Reinit(float wmult, float hmult) = 0;
4809+
4810 virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
4811 int yoff) = 0;
4812
4813@@ -150,11 +153,11 @@
4814 {
4815 public:
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);
4820 ~OSDTypeText();
4821
4822- void Reinit(float wchange, float hchange);
4823+ void Reinit(float wmult, float hmult);
4824
4825 void SetAltFont(TTFFont *font);
4826 void SetUseAlt(bool usealt) { m_usingalt = usealt; }
4827@@ -190,6 +193,7 @@
4828
4829 QRect m_displaysize;
4830 QRect m_screensize;
4831+ QRect m_unbiasedsize;
4832 QString m_message;
4833 QString m_default_msg;
4834
4835@@ -231,7 +235,7 @@
4836 virtual ~OSDTypeImage();
4837
4838 void SetName(const QString &name);
4839- void Reinit(float wchange, float hchange, float wmult, float hmult);
4840+ void Reinit(float wmult, float hmult);
4841
4842 void LoadImage(const QString &filename, float wmult, float hmult,
4843 int scalew = -1, int scaleh = -1);
4844@@ -239,21 +243,20 @@
4845
4846 void SetStaticSize(int scalew, int scaleh) { m_scalew = scalew;
4847 m_scaleh = scaleh; }
4848+ void SetPosition(QPoint pos, float wmult, float hmult);
4849
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(); }
4856
4857- QRect ImageSize() { return m_imagesize; }
4858-
4859- int width() { return m_imagesize.width(); }
4860- int height() { return m_imagesize.height(); }
4861-
4862 virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
4863 int yoff);
4864
4865 protected:
4866 QRect m_imagesize;
4867 QPoint m_displaypos;
4868+ QPoint m_unbiasedpos;
4869
4870 QString m_filename;
4871
4872@@ -270,6 +273,9 @@
4873
4874 int m_drawwidth;
4875 bool m_onlyusefirst;
4876+
4877+ static OSDImageCache c_cache;
4878+ OSDImageCacheValue *m_cacheitem;
4879 };
4880
4881 class OSDTypePosSlider : public OSDTypeImage
4882@@ -280,7 +286,7 @@
4883 int scalew = -1, int scaleh = -1);
4884 ~OSDTypePosSlider();
4885
4886- void Reinit(float wchange, float hchange, float wmult, float hmult);
4887+ void Reinit(float wmult, float hmult);
4888
4889 void SetRectangle(QRect rect) { m_displayrect = rect; }
4890 QRect ImageSize() { return m_imagesize; }
4891@@ -290,6 +296,7 @@
4892
4893 private:
4894 QRect m_displayrect;
4895+ QRect m_unbiasedrect;
4896 int m_maxval;
4897 int m_curval;
4898 };
4899@@ -302,7 +309,7 @@
4900 int scalew = -1, int scaleh = -1);
4901 ~OSDTypeFillSlider();
4902
4903- void Reinit(float wchange, float hchange, float wmult, float hmult);
4904+ void Reinit(float wmult, float hmult);
4905
4906 void SetRectangle(QRect rect) { m_displayrect = rect; }
4907 QRect ImageSize() { return m_imagesize; }
4908@@ -314,6 +321,7 @@
4909
4910 private:
4911 QRect m_displayrect;
4912+ QRect m_unbiasedrect;
4913 int m_maxval;
4914 int m_curval;
4915 };
4916@@ -327,7 +335,7 @@
4917 int scalew = -1, int scaleh = -1);
4918 ~OSDTypeEditSlider();
4919
4920- void Reinit(float wchange, float hchange, float wmult, float hmult);
4921+ void Reinit(float wmult, float hmult);
4922
4923 void SetRectangle(QRect rect) { m_displayrect = rect; }
4924 QRect ImageSize() { return m_imagesize; }
4925@@ -339,6 +347,7 @@
4926
4927 private:
4928 QRect m_displayrect;
4929+ QRect m_unbiasedrect;
4930 int m_maxval;
4931 int m_curval;
4932
4933@@ -360,17 +369,19 @@
4934 class OSDTypeBox : public OSDType
4935 {
4936 public:
4937- OSDTypeBox(const QString &name, QRect displayrect);
4938+ OSDTypeBox(const QString &name, QRect displayrect,
4939+ float wmult, float hmult);
4940 OSDTypeBox(const OSDTypeBox &other);
4941 ~OSDTypeBox();
4942
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);
4947
4948 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4949
4950 private:
4951 QRect size;
4952+ QRect m_unbiasedsize;
4953 };
4954
4955 class OSDTypePositionIndicator
4956@@ -403,14 +414,15 @@
4957 OSDTypePositionRectangle(const OSDTypePositionRectangle &other);
4958 ~OSDTypePositionRectangle();
4959
4960- void AddPosition(QRect rect);
4961+ void AddPosition(QRect rect, float wmult, float hmult);
4962
4963- void Reinit(float wchange, float hchange);
4964+ void Reinit(float wmult, float hmult);
4965
4966 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4967
4968 private:
4969- vector<QRect> positions;
4970+ vector<QRect> positions;
4971+ vector<QRect> unbiasedpos;
4972 };
4973
4974 class OSDTypePositionImage : public virtual OSDTypeImage,
4975@@ -421,14 +433,17 @@
4976 OSDTypePositionImage(const OSDTypePositionImage &other);
4977 ~OSDTypePositionImage();
4978
4979- void Reinit(float wchange, float hchange, float wmult, float hmult);
4980+ void Reinit(float wmult, float hmult);
4981
4982- void AddPosition(QPoint pos);
4983+ void AddPosition(QPoint pos, float wmult, float hmult);
4984
4985 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
4986
4987 private:
4988 vector<QPoint> positions;
4989+ vector<QPoint> unbiasedpos;
4990+ float m_wmult;
4991+ float m_hmult;
4992 };
4993
4994 class ccText
4995@@ -445,11 +460,15 @@
4996 {
4997 public:
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);
5001 ~OSDTypeCC();
5002
5003- void Reinit(int xoff, int yoff, int dispw, int disph);
5004+ void Reinit(float wmult, float hmult);
5005
5006+ void Reinit(int xoff, int yoff,
5007+ int dispw, int disph,
5008+ float wmult, float hmult);
5009+
5010 void AddCCText(const QString &text, int x, int y, int color,
5011 bool teletextmode = false);
5012 void ClearAllCCText();
5013@@ -464,7 +483,7 @@
5014 vector<ccText *> *m_textlist;
5015 OSDTypeBox *m_box;
5016 int m_ccbackground;
5017-
5018+ float m_wmult, m_hmult;
5019 int xoffset, yoffset, displaywidth, displayheight;
5020 };
5021
73e9aca0
ER
5022Index: mythtv/libs/libmythtv/videoout_xv.h
5023===================================================================
56a97e74
ER
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)
73e9aca0
ER
5026@@ -80,6 +80,8 @@
5027 virtual bool hasVLDAcceleration(void) const
5028 { return XVideoVLD == VideoOutputSubType(); }
5029
5030+ void CheckFrameStates(void);
5031+
5032 static MythCodecID GetBestSupportedCodec(uint width, uint height,
5033 uint osd_width, uint osd_height,
5034 uint stream_type, int xvmc_chroma,
5035@@ -141,7 +143,7 @@
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);
5040+
5041 #ifdef USING_XVMC
5042 XvMCOSD* GetAvailableOSD();
5043 void ReturnAvailableOSD(XvMCOSD*);
ecca4c51
ER
5044Index: mythtv/libs/libmythtv/osdimagecache.h
5045===================================================================
5046--- mythtv/libs/libmythtv/osdimagecache.h (.../tags/release-0-19) (revision 0)
56a97e74 5047+++ mythtv/libs/libmythtv/osdimagecache.h (.../branches/release-0-19-fixes) (revision 10931)
ecca4c51
ER
5048@@ -0,0 +1,74 @@
5049+// -*- Mode: c++ -*-
5050+
5051+// POSIX headers
5052+#include <stdint.h>
5053+
5054+// Qt headers
5055+#include <qmap.h>
5056+#include <qrect.h>
5057+#include <qmutex.h>
5058+#include <qstring.h>
5059+#include <qasciicache.h>
5060+
5061+class OSDImageCacheValue
5062+{
5063+ public:
5064+ OSDImageCacheValue(QString cacheKey,
5065+ unsigned char *yuv, unsigned char *ybuffer,
5066+ unsigned char *ubuffer, unsigned char *vbuffer,
5067+ unsigned char *alpha, QRect imagesize);
5068+
5069+ virtual ~OSDImageCacheValue();
5070+
5071+ uint GetSize(void) const { return m_size_in_bytes; }
5072+ QString GetKey(void) const { return m_cacheKey; }
5073+
5074+ public:
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;
5081+
5082+ private:
5083+ uint m_size_in_bytes;
5084+ QString m_cacheKey;
5085+};
5086+
5087+typedef QAsciiCache<OSDImageCacheValue> img_cache_t;
5088+
5089+class OSDImageCache
5090+{
5091+ public:
5092+ OSDImageCache();
5093+ virtual ~OSDImageCache();
5094+
5095+ bool InFileCache(const QString &key) const;
5096+
5097+ bool Contains(const QString &key, bool useFile) const;
5098+
5099+ OSDImageCacheValue *Get(const QString &key, bool useFile);
5100+
5101+ void Insert(OSDImageCacheValue* value);
5102+
5103+ void SaveToDisk(const OSDImageCacheValue *value);
5104+
5105+ void Reset(void);
5106+
5107+ static QString CreateKey(const QString &filename,
5108+ float wmult, float hmult,
5109+ int scalew, int scaleh);
5110+
5111+ static QString ExtractOriginal(const QString &key);
5112+
5113+ private:
5114+ mutable QMutex m_cacheLock;
5115+ img_cache_t m_imageCache;
5116+ int m_memHits;
5117+ int m_diskHits;
5118+ int m_misses;
5119+
5120+ /// Limit on the maximum total size of OSD images cached in *memory*.
5121+ static uint kMaximumMemoryCacheSize;
5122+};
5123Index: mythtv/libs/libmythtv/tv_play.h
5124===================================================================
56a97e74
ER
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)
ecca4c51
ER
5127@@ -456,7 +456,6 @@
5128 ProgramInfo *recorderPlaybackInfo; ///< info requested from recorder
5129 ProgramInfo *playbackinfo; ///< info sent in via Playback()
5130 QMutex pbinfoLock;
5131- QString inputFilename; ///< playbackinfo->pathname
5132 int playbackLen; ///< initial playbackinfo->CalculateLength()
5133 ProgramInfo *lastProgram; ///< last program played with this player
5134 bool jumpToProgram;
5135@@ -485,6 +484,8 @@
5136 // LiveTVChain
5137 LiveTVChain *tvchain;
5138 LiveTVChain *piptvchain;
5139+ QStringList tvchainUpdate;
5140+ QMutex tvchainUpdateLock;
5141
5142 // RingBuffers
5143 RingBuffer *prbuffer;
5144Index: mythtv/libs/libmythtv/videosource.cpp
5145===================================================================
56a97e74
ER
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)
ecca4c51
ER
5148@@ -32,6 +32,7 @@
5149 #include "videosource.h"
5150 #include "datadirect.h"
5151 #include "scanwizard.h"
5152+#include "frequencies.h"
5153
5154 #ifdef USING_DVB
5155 #include <linux/dvb/frontend.h>
73e9aca0
ER
5156@@ -156,6 +157,17 @@
5157 (name == "ST STV0299 DVB-S")); // munges PAT
5158 }
5159
5160+uint CardUtil::GetMinSignalMonitoringDelay(uint device)
5161+{
5162+ QString name(""), type("");
5163+ GetDVBType(device, name, type);
5164+ if (name.find("DVB-S") >= 0)
5165+ return 300;
5166+ if (name == "DiBcom 3000P/M-C DVB-T")
5167+ return 100;
5168+ return 25;
5169+}
5170+
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 @@
ecca4c51
ER
5175 {
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");
5194+
5195+ for (uint i = 0; chanlists[i].name; i++)
5196+ addSelection(chanlists[i].name);
5197+
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."));
5201Index: mythtv/libs/libmythtv/frequencytables.cpp
5202===================================================================
56a97e74
ER
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)
ecca4c51
ER
5205@@ -283,104 +283,52 @@
5206 "ATSC Channel %1", 70, 809000000, 887000000, 6000000, VSB_8);
5207 #endif // USING_DVB
5208
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 ", };
5217
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);
5224
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);
56a97e74 5240+ for (uint i = 0; i < 4; i++)
ecca4c51
ER
5241+ {
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]);
5250
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 };
5259
5260+ for (uint j = 0; j < 2; j++)
5261+ {
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]);
5277
5278-
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);
5284-
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);
5288-
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);
5304-
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);
5310-
5311-
5312-
5313-
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);
5319-
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);
5323-
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);
5339-
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]);
5350+ }
5351+ }
5352 }
5353Index: mythtv/libs/libmythtv/scanwizardhelpers.h
5354===================================================================
56a97e74
ER
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)
ecca4c51
ER
5357@@ -272,11 +272,13 @@
5358 public:
5359 ScanFrequencyTable()
5360 {
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);
5373
5374 setLabel(QObject::tr("Frequency Table"));
5375 setHelpText(QObject::tr("Frequency table to use.") + " " +
5376Index: mythtv/libs/libmythtv/scanwizard.cpp
5377===================================================================
56a97e74
ER
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)
ecca4c51
ER
5380@@ -518,7 +518,9 @@
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));
5389
5390 if (query.exec() && query.isActive() && query.size() > 0)
73e9aca0
ER
5391Index: mythtv/libs/libmythtv/videoout_xv.cpp
5392===================================================================
56a97e74
ER
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)
73e9aca0
ER
5395@@ -1089,6 +1089,9 @@
5396 bool use_xv = true, use_shm = true;
5397
5398 QString dec = gContext->GetSetting("PreferredMPEG2Decoder", "ffmpeg");
5399+ if (dec != "libmpeg2" && height < 720 &&
5400+ gContext->GetNumSetting("UseXvMCForHDOnly", 0))
5401+ dec = "ffmpeg";
5402 if (dec == "xvmc")
5403 use_xvmc_idct = use_xvmc = true;
5404 else if (dec == "xvmc-vld")
5405@@ -1335,40 +1338,39 @@
5406 if (attributes)
5407 X11S(XFree(attributes));
5408
5409- if (xv_draw_colorkey)
5410+ if (!xv_draw_colorkey)
5411+ return;
5412+
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)
5416 {
5417- X11S(xv_atom = XInternAtom(XJ_disp, "XV_COLORKEY", False));
5418- if (xv_atom != None)
5419- {
5420- X11S(ret = XvGetPortAttribute(XJ_disp, xv_port, xv_atom,
5421- &xv_colorkey));
5422+ VERBOSE(VB_PLAYBACK, msg);
5423+ xv_colorkey = 0;
5424+ return;
5425+ }
5426
5427- if (ret == Success && xv_colorkey == 0)
5428- {
5429- const int default_colorkey = 1;
5430- X11S(ret = XvSetPortAttribute(XJ_disp, xv_port, xv_atom,
5431- default_colorkey));
5432- if (ret == Success)
5433- {
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;
5438- }
5439- ret = Success;
5440- }
5441-
5442- if (ret != Success)
5443- {
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.");
5449- xv_colorkey = 0;
5450- }
5451+ X11S(ret = XvGetPortAttribute(XJ_disp, xv_port, xv_atom, &xv_colorkey));
5452+ if (ret == Success && xv_colorkey == 0)
5453+ {
5454+ const int default_colorkey = 1;
5455+ X11S(ret = XvSetPortAttribute(XJ_disp, xv_port, xv_atom,
5456+ default_colorkey));
5457+ if (ret == Success)
5458+ {
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;
5463 }
5464+ ret = Success;
5465 }
5466+
5467+ if (ret != Success)
5468+ {
5469+ VERBOSE(VB_PLAYBACK, msg);
5470+ xv_colorkey = 0;
5471+ }
5472 }
5473
5474 bool VideoOutputXv::SetupDeinterlace(bool interlaced,
5475@@ -1955,86 +1957,75 @@
5476 } while (0)
5477
5478 void VideoOutputXv::DiscardFrames(bool next_frame_keyframe)
5479-{
5480+{
5481+ VERBOSE(VB_PLAYBACK, LOC + "DiscardFrames("<<next_frame_keyframe<<")");
5482 if (VideoOutputSubType() <= XVideo)
5483 {
5484 vbuffers.DiscardFrames(next_frame_keyframe);
5485+ VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 3: %1 -- done()")
5486+ .arg(vbuffers.GetStatus()));
5487 return;
5488 }
5489
5490 #ifdef USING_XVMC
5491 frame_queue_t::iterator it;
5492 frame_queue_t syncs;
5493- frame_queue_t ula;
5494- frame_queue_t discards;
5495
5496- {
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
5501- }
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
5507
5508- CheckDisplayedFramesForAvailability();
5509-
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)
5519 {
5520- vbuffers.begin_lock(kVideoBuffer_displayed); // Lock Y
5521-
5522- DQ_COPY(syncs, kVideoBuffer_displayed);
5523- DQ_COPY(syncs, kVideoBuffer_pause);
5524- for (it = syncs.begin(); it != syncs.end(); ++it)
5525- {
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;
5531- }
5532- VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 2: %1")
5533- .arg(vbuffers.GetStatus()));
5534-#if 0
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);
5539-
5540- for (it = ula.begin(); it != ula.end(); ++it)
5541- vbuffers.RemoveInheritence(*it);
5542-#endif
5543-
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);
5549-
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);
5555 }
5556+ syncs.clear();
5557+ vbuffers.end_lock(); // Lock Y
5558
5559- for (it = discards.begin(); it != discards.end(); ++it)
5560- DiscardFrame(*it);
5561+ CheckFrameStates();
5562
5563+ // If the next frame is a keyframe we can clear out a lot more...
5564+ if (next_frame_keyframe)
5565 {
5566 vbuffers.begin_lock(kVideoBuffer_displayed); // Lock Z
5567
5568- syncs.clear();
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)
5574 {
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);
5581 }
5582
5583- VERBOSE(VB_PLAYBACK, LOC +
5584- QString("DiscardFrames() 4: %1 -- done() ")
5585+ VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 2: %1")
5586 .arg(vbuffers.GetStatus()));
5587-
5588+
5589 vbuffers.end_lock(); // Lock Z
5590+
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();
5596 }
5597+ VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 3: %1 -- done()")
5598+ .arg(vbuffers.GetStatus()));
5599+
5600 #endif // USING_XVMC
5601 }
5602
5603@@ -2071,7 +2062,7 @@
5604 if (osdframe)
5605 DiscardFrame(osdframe);
5606 }
5607- CheckDisplayedFramesForAvailability();
5608+ CheckFrameStates();
5609 #endif
5610 }
5611
5612@@ -2411,7 +2402,7 @@
5613 DiscardFrame(vbuffers.dequeue(kVideoBuffer_pause));
5614 }
5615 // clear any displayed frames not on screen
5616- CheckDisplayedFramesForAvailability();
5617+ CheckFrameStates();
5618
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))
5628 {
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();
5636
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();
5642
5643- CheckDisplayedFramesForAvailability();
5644+ CheckFrameStates();
5645 }
5646
5647 // If there is an available buffer grab it.
5648@@ -3013,7 +3004,7 @@
5649 return -1;
5650 }
5651
5652-void VideoOutputXv::CheckDisplayedFramesForAvailability(void)
5653+void VideoOutputXv::CheckFrameStates(void)
5654 {
5655 #ifdef USING_XVMC
5656 frame_queue_t::iterator it;
5657@@ -3084,6 +3075,13 @@
5658 }
5659 }
5660 }
5661+ else if (vbuffers.contains(kVideoBuffer_decode, pframe))
5662+ {
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)));
5667+ }
5668 else
5669 {
5670 vbuffers.RemoveInheritence(pframe);
5671Index: mythtv/libs/libmythtv/signalmonitor.h
5672===================================================================
56a97e74
ER
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)
73e9aca0
ER
5675@@ -7,6 +7,10 @@
5676 // C headers
5677 #include <pthread.h>
5678
5679+// C++ headers
5680+#include <algorithm>
5681+using namespace std;
5682+
5683 // Qt headers
5684 #include <qobject.h>
5685 #include <qmutex.h>
5686@@ -125,7 +129,8 @@
5687 * Defaults to 25 milliseconds.
5688 * \param msec Milliseconds between signal monitoring events.
5689 */
5690- void SetUpdateRate(int msec) { update_rate = msec; }
5691+ void SetUpdateRate(int msec)
5692+ { update_rate = max(msec, (int)minimum_update_rate); }
5693
5694 public slots:
5695 virtual void deleteLater(void);
5696@@ -164,6 +169,7 @@
5697 int capturecardnum;
5698 uint flags;
5699 int update_rate;
5700+ uint minimum_update_rate;
5701 bool running;
5702 bool exit;
5703 bool update_done;
ecca4c51
ER
5704Index: mythtv/libs/libmythtv/RingBuffer.h
5705===================================================================
56a97e74
ER
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)
ecca4c51
ER
5708@@ -91,6 +91,7 @@
5709 long long GetTotalReadPosition(void);
5710
5711 long long SetAdjustFilesize(void);
5712+ void SetTimeout(bool fast) { oldfile = fast; }
5713
5714 protected:
5715 static void *StartReader(void *type);
5716Index: mythtv/libs/libmythtv/dvbtypes.cpp
5717===================================================================
56a97e74
ER
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)
ecca4c51
ER
5720@@ -202,7 +202,7 @@
5721 {
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},
5727 };
5728
5729@@ -210,7 +210,7 @@
5730 {
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},
5736 };
5737
5738@@ -218,7 +218,7 @@
5739 {
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},
5745 };
5746
5747Index: mythtv/libs/libmythtv/mpegrecorder.cpp
5748===================================================================
56a97e74
ER
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)
ecca4c51
ER
5751@@ -363,9 +363,9 @@
5752
5753 if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
5754 {
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:");
5759- return false;
5760 }
5761
5762 if (vbimode) {
5763@@ -481,6 +481,9 @@
5764 continue;
5765 case 0:
5766 printf("select timeout - ivtv driver has stopped responding\n");
5767+ if(close(readfd) != 0)
5768+ perror("close");
5769+ readfd = -1; // Force PVR card to be reopened on next iteration
5770 continue;
5771 default: break;
5772 }
5773Index: mythtv/libs/libmythtv/ivtvdecoder.cpp
5774===================================================================
56a97e74
ER
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)
ecca4c51
ER
5777@@ -270,7 +270,9 @@
5778
5779 GetNVP()->SetVideoParams(720 /*width*/, (ntsc) ? 480 : 576 /*height*/,
5780 (ntsc) ? 29.97f : 25.0f, keyframedist, 1.33);
5781-
5782+
5783+ fps = (ntsc) ? 29.97f : 25.0f; // save for later length calculations
5784+
5785 ringBuffer->UpdateRawBitrate(8000);
5786
5787 if (m_playbackinfo || livetv || watchingrecording)
5788Index: mythtv/libs/libmythtv/dvbsignalmonitor.cpp
5789===================================================================
56a97e74
ER
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)
73e9aca0
ER
5792@@ -100,6 +100,10 @@
5793 #undef DVB_IO
5794 AddFlags(newflags);
5795 DBG_SM("constructor()", QString("initial flags 0x%1").arg(newflags,0,16));
5796+
5797+ minimum_update_rate = _channel->GetMinSignalMonitorDelay();
5798+ if (minimum_update_rate > 30)
5799+ usleep(minimum_update_rate * 1000);
5800 }
5801
5802 /** \fn DVBSignalMonitor::~DVBSignalMonitor()
5803@@ -348,8 +352,8 @@
ecca4c51
ER
5804
5805 len += remainder;
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);
5811 }
5812 VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorTS(): " + "shutdown");
5813
73e9aca0
ER
5814Index: mythtv/libs/libmythtv/tv_rec.cpp
5815===================================================================
56a97e74
ER
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)
73e9aca0
ER
5818@@ -130,6 +130,11 @@
5819 // RingBuffer info
5820 ringBuffer(NULL), rbFilePrefix(""), rbFileExt("mpg")
5821 {
5822+ // Retune stuff
5823+ retune_timer = new TuningTimer();
5824+ retune_timer->setTimeout(10000);
5825+ retune_timer->start();
5826+ retune_requests = 0;
5827 }
5828
5829 /** \fn TVRec::Init()
5830@@ -3221,6 +3226,8 @@
5831 */
5832 void TVRec::HandleTuning(void)
5833 {
5834+ bool handle_done = false;
5835+
5836 if (tuningRequests.size())
5837 {
5838 const TuningRequest *request = &tuningRequests.front();
5839@@ -3232,7 +3239,12 @@
5840 kFlagEITScan|kFlagAntennaAdjust))
5841 {
5842 if (!recorder)
5843+ {
5844 TuningFrequency(*request);
5845+ retune_timer->restart();
5846+ retune_timer->addMSecs(1);
5847+ retune_requests = 0;
5848+ }
5849 else
5850 SetFlags(kFlagWaitingForRecPause);
5851 }
5852@@ -3261,15 +3273,29 @@
5853 if (HasFlags(kFlagWaitingForSignal))
5854 {
5855 if (!TuningSignalCheck())
5856- return;
5857+ handle_done = true;
5858 }
5859
5860 if (HasFlags(kFlagWaitingForSIParser))
5861 {
5862 if (!TuningPMTCheck())
5863- return;
5864+ handle_done = true;
5865 }
5866
5867+#ifdef USING_DVB
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)))
5872+ {
5873+ RetuneChannel();
5874+ retune_requests++;
5875+ }
5876+#endif // USING_DVB
5877+
5878+ if (handle_done)
5879+ return;
5880+
5881 if (HasFlags(kFlagNeedToStartRecorder))
5882 {
5883 if (recorder)
5884@@ -3354,6 +3380,19 @@
5885 ClearFlags(kFlagPendingActions);
5886 }
5887
5888+/** \fn TVRec::RetuneChannel(void)
5889+ * \brief Retunes a DVB channel
5890+ * \return DVBChannel::Retune() or false if ifndef USING_DVB
5891+ */
5892+bool TVRec::RetuneChannel(void)
5893+{
5894+#ifdef USING_DVB
5895+ if (GetDVBChannel())
5896+ return GetDVBChannel()->Retune();
5897+#endif // USING_DVB
5898+ return false;
5899+}
5900+
5901 /** \fn TVRec::TuningFrequency(const TuningRequest&)
5902 * \brief Performs initial tuning required for any tuning event.
5903 *
5904Index: mythtv/libs/libmythtv/videooutbase.h
5905===================================================================
56a97e74
ER
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)
73e9aca0
ER
5908@@ -256,6 +256,8 @@
5909 /// onto the queue of frames ready for decoding onto.
5910 virtual void DiscardFrames(bool kf) { vbuffers.DiscardFrames(kf); }
5911
5912+ virtual void CheckFrameStates(void) { }
5913+
5914 /// \bug not implemented correctly. vpos is not updated.
5915 VideoFrame *GetLastDecodedFrame(void) { return vbuffers.GetLastDecodedFrame(); }
5916
ecca4c51
ER
5917Index: mythtv/libs/libmythtv/osdimagecache.cpp
5918===================================================================
5919--- mythtv/libs/libmythtv/osdimagecache.cpp (.../tags/release-0-19) (revision 0)
56a97e74 5920+++ mythtv/libs/libmythtv/osdimagecache.cpp (.../branches/release-0-19-fixes) (revision 10931)
ecca4c51
ER
5921@@ -0,0 +1,296 @@
5922+// -*- Mode: c++ -*-
5923+/** OSDImageCache
5924