]>
Commit | Line | Data |
---|---|---|
b9965e1c | 1 | Index: mythplugins/mythweb/themes/wml/header.php |
2 | =================================================================== | |
3 | --- mythplugins/mythweb/themes/wml/header.php (.../tags/release-0-19) (revision 10931) | |
4 | +++ mythplugins/mythweb/themes/wml/header.php (.../branches/release-0-19-fixes) (revision 10931) | |
5 | @@ -26,4 +26,4 @@ | |
6 | <p><a href="<?php echo root ?>tv/upcoming"><?php echo t('Upcoming Recordings') ?></a></p> | |
7 | <p><a href="<?php echo root ?>tv/recorded"><?php echo t('Recorded Programs') ?></a></p> | |
8 | <p><a href="<?php echo root ?>tv/search"><?php echo t('Search') ?></a></p> | |
9 | -<p><a href="<?php echo root ?>status?xml"><?php echo t('Backend Status') ?></a></p> | |
10 | +<p><a href="<?php echo root ?>status/xml"><?php echo t('Backend Status') ?></a></p> | |
11 | Index: mythplugins/mythweb/themes/default/weather/weather.php | |
12 | =================================================================== | |
13 | --- mythplugins/mythweb/themes/default/weather/weather.php (.../tags/release-0-19) (revision 10931) | |
14 | +++ mythplugins/mythweb/themes/default/weather/weather.php (.../branches/release-0-19-fixes) (revision 10931) | |
15 | @@ -93,13 +93,13 @@ | |
16 | $tomorrow = date("m/d/Y", mktime(0, 0, 0, date("m") , date("d")+1, date("Y"))); | |
17 | ||
18 | switch($forecast->dayofweek) { | |
19 | + case 0: $day = t('Sunday'); break; | |
20 | case 1: $day = t('Monday'); break; | |
21 | case 2: $day = t('Tuesday'); break; | |
22 | case 3: $day = t('Wednesday'); break; | |
23 | case 4: $day = t('Thursday'); break; | |
24 | case 5: $day = t('Friday'); break; | |
25 | case 6: $day = t('Saturday'); break; | |
26 | - case 7: $day = t('Sunday'); break; | |
27 | default: $day = $forecast->date; break; | |
28 | } | |
29 | ||
30 | Index: mythplugins/mythweb/themes/default/music/music.php | |
31 | =================================================================== | |
32 | --- mythplugins/mythweb/themes/default/music/music.php (.../tags/release-0-19) (revision 10931) | |
33 | +++ mythplugins/mythweb/themes/default/music/music.php (.../branches/release-0-19-fixes) (revision 10931) | |
34 | @@ -164,10 +164,12 @@ | |
35 | ||
36 | function print_header($filterPlaylist,$filterArtist,$filterAlbum,$filterGenre) { | |
37 | $this->filterPlaylist=$filterPlaylist; | |
38 | -// Set the desired page title | |
39 | - $page_title = 'MythWeb - '.t('Music'); | |
40 | -// Print the page header | |
41 | - require_once theme_dir.'/header.php'; | |
42 | + // Set the desired page title | |
43 | + global $page_title, $Modules, $headers; | |
44 | + $page_title = 'MythWeb - '.t('Music'); | |
45 | + // Print the page header | |
46 | + require_once theme_dir.'/header.php'; | |
47 | + | |
48 | printf("<form action=\"".root."music\" method=\"GET\" >\n"); | |
49 | printf("<input type=\"hidden\" name=\"mode\" value=\"music\" />\n"); | |
50 | ||
51 | Index: mythplugins/mythweb/themes/default/tv/detail.php | |
52 | =================================================================== | |
53 | --- mythplugins/mythweb/themes/default/tv/detail.php (.../tags/release-0-19) (revision 10931) | |
54 | +++ mythplugins/mythweb/themes/default/tv/detail.php (.../branches/release-0-19-fixes) (revision 10931) | |
55 | @@ -51,7 +51,7 @@ | |
56 | <?php } ?> | |
57 | <div id="program_title"> | |
58 | <h1> | |
59 | - <a href="<?php echo root ?>tv/search/<?php echo urlencode($program->title) ?>&search_title=yes"><?php echo $schedule->title ?></a> | |
60 | + <a href="<?php echo root ?>tv/search/<?php echo str_replace('%2F', '/', rawurlencode($schedule->title)) ?>?search_title=1"><?php echo $schedule->title ?></a> | |
61 | </h1> | |
62 | <div id="program_time"> | |
63 | <?php | |
64 | Index: mythplugins/mythweb/includes/mythbackend.php | |
65 | =================================================================== | |
66 | --- mythplugins/mythweb/includes/mythbackend.php (.../tags/release-0-19) (revision 10931) | |
67 | +++ mythplugins/mythweb/includes/mythbackend.php (.../branches/release-0-19-fixes) (revision 10931) | |
68 | @@ -15,10 +15,6 @@ | |
69 | // The character string used by the backend to separate records | |
70 | define('backend_sep', '[]:[]'); | |
71 | ||
72 | -// A couple of global variables to keep duplicate queries to a minimum | |
73 | - $Scheduled_Recordings = array(); | |
74 | - $Recorded_Programs = array(); | |
75 | - | |
76 | // MYTH_PROTO_VERSION is defined in libmyth in mythtv/libs/libmyth/mythcontext.h | |
77 | // and should be the current MythTV protocol version. | |
78 | define('MYTH_PROTO_VERSION', 26); | |
79 | Index: mythplugins/mythweb/includes/programs.php | |
80 | =================================================================== | |
81 | --- mythplugins/mythweb/includes/programs.php (.../tags/release-0-19) (revision 10931) | |
82 | +++ mythplugins/mythweb/includes/programs.php (.../branches/release-0-19-fixes) (revision 10931) | |
83 | @@ -81,7 +81,9 @@ | |
84 | /**/ | |
85 | function &load_all_program_data($start_time, $end_time, $chanid = false, $single_program = false, $extra_query = '') { | |
86 | global $Channels, $db; | |
87 | - // Make a local hash of channel chanid's with references to the actual channel data | |
88 | + // Make a local hash of channel chanid's with references to the actual | |
89 | + // channel data (Channels are not indexed by anything in particular, so | |
90 | + // that the user can sort by chanid or channum). | |
91 | $channel_hash = array(); | |
92 | // An array (that later gets converted to a string) containing the id's of channels we want to load | |
93 | $these_channels = array(); | |
94 | @@ -104,7 +106,7 @@ | |
95 | load_all_channels(); | |
96 | // Scan through the channels array and actually assign those references | |
97 | foreach (array_keys($Channels) as $key) { | |
98 | - $channel_hash[$Channels[$key]->chanid] = &$Channels[$key]; | |
99 | + $channel_hash[$Channels[$key]->chanid] =& $Channels[$key]; | |
100 | // Reinitialize the programs array for this channel | |
101 | $Channels[$key]->programs = array(); | |
102 | // Keep track of this channel id in case we're only grabbing info for certain channels - workound included to avoid blank chanid's | |
103 | @@ -130,11 +132,13 @@ | |
104 | LEFT JOIN programrating USING (chanid, starttime) | |
105 | LEFT JOIN oldrecorded | |
106 | ON oldrecorded.recstatus IN (-3, 11) | |
107 | - AND IF(oldrecorded.programid OR oldrecorded.seriesid, | |
108 | + AND IF(oldrecorded.programid AND oldrecorded.seriesid, | |
109 | oldrecorded.programid = program.programid | |
110 | AND oldrecorded.seriesid = program.seriesid, | |
111 | - oldrecorded.title = program.title | |
112 | - AND oldrecorded.subtitle = program.subtitle | |
113 | + oldrecorded.title AND oldrecorded.subtitle | |
114 | + AND oldrecorded.description | |
115 | + AND oldrecorded.title = program.title | |
116 | + AND oldrecorded.subtitle = program.subtitle | |
117 | AND oldrecorded.description = program.description | |
118 | ) | |
119 | LEFT JOIN channel ON program.chanid = channel.chanid | |
120 | @@ -156,8 +160,12 @@ | |
121 | // The extra query, if there is one | |
122 | if ($extra_query) | |
123 | $query .= ' AND '.$extra_query; | |
124 | - // Group, sort and query | |
125 | + // Group and sort | |
126 | $query .= ' GROUP BY program.chanid, program.starttime ORDER BY program.starttime'; | |
127 | + // Limit | |
128 | + if ($single_program) | |
129 | + $query .= ' LIMIT 1'; | |
130 | + // Query | |
131 | $sh = $db->query($query, | |
132 | star_character, max_stars, max_stars); | |
133 | // No results | |
134 | @@ -188,12 +196,8 @@ | |
135 | // Cleanup | |
136 | $sh->finish(); | |
137 | // If channel-specific information was requested, return an array of those programs, or just the first/only one | |
138 | - if ($chanid) { | |
139 | - if ($single_program) | |
140 | - return $channel_hash[$chanid]->programs[0]; | |
141 | - else | |
142 | - return $channel_hash[$chanid]->programs; | |
143 | - } | |
144 | + if ($chanid && $single_program) | |
145 | + return $these_programs[0]; | |
146 | // Just in case, return an array of all programs found | |
147 | return $these_programs; | |
148 | } | |
149 | @@ -272,18 +276,18 @@ | |
150 | $this->endtime = $data[12]; # show end-time | |
151 | // Is this a previously-recorded program? Calculate the filesize | |
152 | if (!empty($this->filename)) { | |
153 | - $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low; | |
154 | - } | |
155 | - // Ah, a scheduled recording - let's load more information about it, to be parsed in below | |
156 | - elseif ($this->chanid) { | |
157 | - unset($this->filename); | |
158 | - // Kludge to avoid redefining the object, which doesn't work in php5 | |
159 | - $tmp = @get_object_vars(load_one_program($this->starttime, $this->chanid)); | |
160 | - if (is_array($tmp) && count($tmp) > 0) { | |
161 | - foreach ($tmp as $key => $value) { | |
162 | - $this->$key = $value; | |
163 | - } | |
164 | + if (function_exists('gmp_add')) { | |
165 | + // GMP functions should work better with 64 bit numbers. | |
166 | + $size = gmp_add($fs_low, | |
167 | + gmp_mul('4294967296', | |
168 | + gmp_add($fs_high, $fs_low < 0 ? '1' : '0')) | |
169 | + ); | |
170 | + $this->filesize = gmp_strval($size); | |
171 | } | |
172 | + else { | |
173 | + // This is inaccurate, but it's the best we can get without GMP. | |
174 | + $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low; | |
175 | + } | |
176 | } | |
177 | // Load the remaining info we got from mythbackend | |
178 | $this->title = $data[0]; # program name/title | |
179 | @@ -291,14 +295,14 @@ | |
180 | $this->description = $data[2]; # episode description | |
181 | $this->category = $data[3]; | |
182 | #$chanid = $data[4]; # Extracted a few lines earlier | |
183 | - #$channum = $data[5]; | |
184 | - #$callsign = $data[6]; | |
185 | + $this->channum = $data[5]; | |
186 | + $this->callsign = $data[6]; | |
187 | $this->channame = $data[7]; | |
188 | #$pathname = $data[8]; # Extracted a few lines earlier | |
189 | #$fs_high = $data[9]; # Extracted a few lines earlier | |
190 | #$fs_low = $data[10]; # Extracted a few lines earlier | |
191 | - #$starttime = $data[11]; # Extracted a few lines earlier | |
192 | - #$endtime = $data[12]; # Extracted a few lines earlier | |
193 | + #$this->starttime = $data[11]; # Extracted a few lines earlier | |
194 | + #$this->endtime = $data[12]; # Extracted a few lines earlier | |
195 | $this->hostname = $data[16]; | |
196 | #$this->sourceid = $data[17]; | |
197 | $this->cardid = $data[18]; | |
198 | @@ -320,9 +324,9 @@ | |
199 | $this->programid = $data[34]; | |
200 | $this->lastmodified = $data[35]; | |
201 | $this->recpriority = $data[36]; | |
202 | - #$this->airdate = $data[37]; | |
203 | - #$this->hasairdate = $data[38]; | |
204 | - $this->timestretch = $program_data[39]; | |
205 | + $this->airdate = date('Y-m-d', $data[37]); | |
206 | + $this->hasairdate = $data[38]; | |
207 | + $this->timestretch = $data[39]; | |
208 | $this->recpriority2 = $data[40]; | |
209 | // Assign the program flags | |
210 | $this->has_commflag = ($progflags & 0x01) ? true : false; // FL_COMMFLAG = 0x01 | |
211 | @@ -363,8 +367,8 @@ | |
212 | $this->title_pronounce = $data['title_pronounce']; | |
213 | $this->recstatus = $data['recstatus']; | |
214 | ||
215 | - if ($program_data['tsdefault']) { | |
216 | - $this->timestretch = $program_data['tsdefault']; | |
217 | + if ($data['tsdefault']) { | |
218 | + $this->timestretch = $data['tsdefault']; | |
219 | } else { | |
220 | $this->timestretch = 1.0; | |
221 | } | |
222 | @@ -387,12 +391,14 @@ | |
223 | // Now we really should scan the $Channel array and add a link to this program's channel | |
224 | foreach (array_keys($Channels) as $key) { | |
225 | if ($Channels[$key]->chanid == $this->chanid) { | |
226 | - $this->channel = &$Channels[$key]; | |
227 | + $this->channel =& $Channels[$key]; | |
228 | break; | |
229 | } | |
230 | } | |
231 | + // Not found | |
232 | + if (!$this->channel) | |
233 | + $this->channel =& load_one_channel($this->chanid); | |
234 | } | |
235 | - | |
236 | // Calculate the duration | |
237 | if ($this->recendts) | |
238 | $this->length = $this->recendts - $this->recstartts; | |
239 | Index: mythplugins/mythweb/includes/utils.php | |
240 | =================================================================== | |
241 | --- mythplugins/mythweb/includes/utils.php (.../tags/release-0-19) (revision 10931) | |
242 | +++ mythplugins/mythweb/includes/utils.php (.../branches/release-0-19-fixes) (revision 10931) | |
243 | @@ -276,7 +276,7 @@ | |
244 | static $first_run=true; | |
245 | if($first_run) { | |
246 | $first_run=false; | |
247 | - echo '<script type="text/javascript" src="/js/debug.js"></script>'; | |
248 | + echo '<script type="text/javascript" src="'.root.'js/debug.js"></script>'; | |
249 | } | |
250 | // Put our data into a string | |
251 | if (is_array($data) || is_object($data)) | |
252 | Index: mythplugins/mythweb/includes/init.php | |
253 | =================================================================== | |
254 | --- mythplugins/mythweb/includes/init.php (.../tags/release-0-19) (revision 10931) | |
255 | +++ mythplugins/mythweb/includes/init.php (.../branches/release-0-19-fixes) (revision 10931) | |
256 | @@ -16,28 +16,15 @@ | |
257 | * | |
258 | /**/ | |
259 | ||
260 | -/** | |
261 | - * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some | |
262 | - * other lesser means. It contains most of the information required for | |
263 | - * figuring out what functions the user wants to access. | |
264 | - * | |
265 | - * @global array $GLOBALS['Path'] | |
266 | - * @name $Path | |
267 | -/**/ | |
268 | - global $Path; | |
269 | - $Path = explode('/', preg_replace('/^\/+/', '', // Remove leading slashes | |
270 | - preg_replace('/[\s]+/', ' ', // Convert extra whitespace | |
271 | - // Grab the path info from various different places. | |
272 | - array_key_exists('PATH_INFO', $_SERVER) | |
273 | - && $_SERVER['PATH_INFO'] | |
274 | - ? $_SERVER['PATH_INFO'] | |
275 | - : (array_key_exists('PATH_INFO', $_ENV) | |
276 | - && $_ENV['PATH_INFO'] | |
277 | - ? $_ENV['PATH_INFO'] | |
278 | - : $_GET['PATH_INFO'] | |
279 | - ) | |
280 | - )) | |
281 | - ); | |
282 | +// mod_redirect can do some weird things when php is run in cgi mode | |
283 | + $keys = preg_grep('/^REDIRECT_/', array_keys($_SERVER)); | |
284 | + if (!empty($keys)) { | |
285 | + foreach ($keys as $key) { | |
286 | + $key = substr($key, 9); | |
287 | + if (!array_key_exists($key, $_SERVER)) | |
288 | + $_SERVER[$key] = $_SERVER["REDIRECT_$key"]; | |
289 | + } | |
290 | + } | |
291 | ||
292 | // Clean the document root variable and make sure it doesn't have a trailing slash | |
293 | $_SERVER['DOCUMENT_ROOT'] = preg_replace('/\/+$/', '', $_SERVER['DOCUMENT_ROOT']); | |
294 | @@ -94,6 +81,29 @@ | |
295 | exit; | |
296 | } | |
297 | ||
298 | +/** | |
299 | + * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some | |
300 | + * other lesser means. It contains most of the information required for | |
301 | + * figuring out what functions the user wants to access. | |
302 | + * | |
303 | + * @global array $GLOBALS['Path'] | |
304 | + * @name $Path | |
305 | +/**/ | |
306 | + global $Path; | |
307 | + $Path = explode('/', preg_replace('/^\/+/', '', // Remove leading slashes | |
308 | + preg_replace('/[\s]+/', ' ', // Convert extra whitespace | |
309 | + // Grab the path info from various different places. | |
310 | + array_key_exists('PATH_INFO', $_SERVER) | |
311 | + && $_SERVER['PATH_INFO'] | |
312 | + ? $_SERVER['PATH_INFO'] | |
313 | + : (array_key_exists('PATH_INFO', $_ENV) | |
314 | + && $_ENV['PATH_INFO'] | |
315 | + ? $_ENV['PATH_INFO'] | |
316 | + : $_GET['PATH_INFO'] | |
317 | + ) | |
318 | + )) | |
319 | + ); | |
320 | + | |
321 | // Load the database connection routines | |
322 | require_once 'includes/db.php'; | |
323 | ||
324 | Index: mythplugins/mythweb/includes/mobile.php | |
325 | =================================================================== | |
326 | --- mythplugins/mythweb/includes/mobile.php (.../tags/release-0-19) (revision 10931) | |
327 | +++ mythplugins/mythweb/includes/mobile.php (.../branches/release-0-19-fixes) (revision 10931) | |
328 | @@ -74,58 +74,56 @@ | |
329 | * If you don't know the screensize of some mobile terminal then use | |
330 | * an empty array or approximate dimensions. | |
331 | */ | |
332 | - $mobiles = array(/* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */ | |
333 | - 'Series 60' => array('width' => 176, 'height' => 208), | |
334 | - 'Series60' => array('width' => 176, 'height' => 208), | |
335 | - 'C500' => array('width'=>176, 'height'=> 220), // SPV C500 | |
336 | + $mobiles = array( | |
337 | + /* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */ | |
338 | + 'Series 60' => array('width' => 176, 'height' => 208), | |
339 | + 'Series60' => array('width' => 176, 'height' => 208), | |
340 | + 'C500' => array('width'=>176, 'height'=> 220), // SPV C500 | |
341 | + /* Phones using the Series 90 platform, e.g. Nokia 7710. */ | |
342 | + 'Series 90' => array('width' => 640, 'height' => 320), | |
343 | + 'Series90' => array('width' => 640, 'height' => 320), | |
344 | + /* The following strings are added for the Palm browser WebPro | |
345 | + * WebPro sometimes supplies the screen dimensions, but sometimes not | |
346 | + * but we try to detect the best as possible */ | |
347 | + '240x320' => array('width' => 240, 'height' => 320), // PocketPC IE | |
348 | + '320x320' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models | |
349 | + '320x480' => array('width' => 320, 'height' => 480), // For Palm Tungsten T | |
350 | + '480x320' => array('width' => 480, 'height' => 320), // For Palm Tungsten T | |
351 | + '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T | |
352 | + '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T | |
353 | + '320x320x16' => array('width' => 320, 'height' => 320), | |
354 | + 'WebPro' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models | |
355 | + /* A generic mobile phone using Symbian OS. All Symbian phones don't | |
356 | + * necessarily have the same screen size so if you want to include | |
357 | + * some specific Symbian phones then place them above this line. */ | |
358 | + 'Symbian' => array('width' => 176, 'height' => 208), | |
359 | ||
360 | - /* Phones using the Series 90 platform, e.g. Nokia 7710. */ | |
361 | - 'Series 90' => array('width' => 640, 'height' => 320), | |
362 | - 'Series90' => array('width' => 640, 'height' => 320), | |
363 | + 'Nokia' => array(), // Nokia phones and emulators | |
364 | + 'Eric' => array(), // Ericsson WAP phones and emulators | |
365 | + 'WapI' => array(), // Ericsson WapIDE 2.0 | |
366 | + 'MC21' => array(), // Ericsson MC218 | |
367 | + 'AUR ' => array(), // Ericsson R320 | |
368 | + 'R380' => array(), // Ericsson R380 | |
369 | + 'UP.B' => array(), // UP.Browser | |
370 | + 'WinW' => array(), // WinWAP browser | |
371 | + 'UPG1' => array(), // UP.SDK 4.0 | |
372 | + 'upsi' => array(), // another kind of UP.Browser ?? | |
373 | + 'QWAP' => array(), // unknown QWAPPER browser | |
374 | + 'Jigs' => array(), // unknown JigSaw browser | |
375 | + 'Java' => array(), // unknown Java based browser | |
376 | + 'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?) | |
377 | + 'MITS' => array(), // unknown Mitsubishi browser | |
378 | + 'MOT-' => array(), // unknown browser (UP based?) | |
379 | + 'My S' => array(), // unknown Ericsson devkit browser ? | |
380 | + 'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de | |
381 | + 'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de | |
382 | + 'ALAV' => array(), // yet another unknown UP based browser ? | |
383 | + 'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?) | |
384 | + 'LGE-' => array(), // LG phones | |
385 | ||
386 | - /* The following strings are added for the Palm browser WebPro | |
387 | - * WebPro sometimes supplies the screen dimensions, but sometimes not | |
388 | - * but we try to detect the best as possible | |
389 | - */ | |
390 | - '320x480' => array('width' => 320, 'height' => 480), // For Palm Tungsten T | |
391 | - '480x320' => array('width' => 480, 'height' => 320), // For Palm Tungsten T | |
392 | - '320x320' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models | |
393 | - '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T | |
394 | - '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T | |
395 | - '320x320x16' => array('width' => 320, 'height' => 320), | |
396 | - 'WebPro' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models | |
397 | - | |
398 | - /* A generic mobile phone using Symbian OS. All Symbian phones don't | |
399 | - * necessarily have the same screen size so if you want to include | |
400 | - * some specific Symbian phones then place them above this line. */ | |
401 | - 'Symbian' => array('width' => 176, 'height' => 208), | |
402 | - | |
403 | - 'Nokia' => array(), // Nokia phones and emulators | |
404 | - 'Eric' => array(), // Ericsson WAP phones and emulators | |
405 | - 'WapI' => array(), // Ericsson WapIDE 2.0 | |
406 | - 'MC21' => array(), // Ericsson MC218 | |
407 | - 'AUR ' => array(), // Ericsson R320 | |
408 | - 'R380' => array(), // Ericsson R380 | |
409 | - 'UP.B' => array(), // UP.Browser | |
410 | - 'WinW' => array(), // WinWAP browser | |
411 | - 'UPG1' => array(), // UP.SDK 4.0 | |
412 | - 'upsi' => array(), // another kind of UP.Browser ?? | |
413 | - 'QWAP' => array(), // unknown QWAPPER browser | |
414 | - 'Jigs' => array(), // unknown JigSaw browser | |
415 | - 'Java' => array(), // unknown Java based browser | |
416 | - 'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?) | |
417 | - 'MITS' => array(), // unknown Mitsubishi browser | |
418 | - 'MOT-' => array(), // unknown browser (UP based?) | |
419 | - 'My S' => array(), // unknown Ericsson devkit browser ? | |
420 | - 'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de | |
421 | - 'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de | |
422 | - 'ALAV' => array(), // yet another unknown UP based browser ? | |
423 | - 'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?) | |
424 | - 'LGE-' => array(), // LG phones | |
425 | - | |
426 | - /* For debugging: you can try out the mobile mode without a mobile phone. | |
427 | - * Replace 'Opera' with your browser. Comment out for release version. */ | |
428 | - //'Opera' => array('width' => 176, 'height' => 208) | |
429 | + /* For debugging: you can try out the mobile mode without a mobile phone. | |
430 | + * Replace 'Opera' with your browser. Comment out for release version. */ | |
431 | + //'Opera' => array('width' => 176, 'height' => 208) | |
432 | ); | |
433 | ||
434 | /* Scan through $mobiles and try to find matching user agent. */ | |
435 | Index: mythplugins/mythweb/includes/recording_schedules.php | |
436 | =================================================================== | |
437 | --- mythplugins/mythweb/includes/recording_schedules.php (.../tags/release-0-19) (revision 10931) | |
438 | +++ mythplugins/mythweb/includes/recording_schedules.php (.../branches/release-0-19-fixes) (revision 10931) | |
439 | @@ -68,10 +68,14 @@ | |
440 | // Cleanup | |
441 | mysql_free_result($result); | |
442 | ||
443 | +// Initialize | |
444 | + global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled; | |
445 | + $Scheduled_Recordings = array(); | |
446 | + $Num_Conflicts = 0; | |
447 | + $Num_Scheduled = 0; | |
448 | + | |
449 | // Load all of the scheduled recordings. We will need them at some point, so we | |
450 | // might as well get it overwith here. | |
451 | - global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled; | |
452 | - $Scheduled_Recordings = array(); | |
453 | foreach (get_backend_rows('QUERY_GETALLPENDING', 2) as $key => $program) { | |
454 | // The offset entry | |
455 | if ($key === 'offset') { | |
456 | Index: mythplugins/mythweb/includes/session.php | |
457 | =================================================================== | |
458 | --- mythplugins/mythweb/includes/session.php (.../tags/release-0-19) (revision 10931) | |
459 | +++ mythplugins/mythweb/includes/session.php (.../branches/release-0-19-fixes) (revision 10931) | |
460 | @@ -19,8 +19,8 @@ | |
461 | ||
462 | // Start the session | |
463 | session_name('mythweb_id'); | |
464 | - session_set_cookie_params(60 * 60 * 30, '/'); // 30 day timeout on cookies | |
465 | - ini_set('session.gc_maxlifetime', 60 * 60 * 30); // ... and sessions | |
466 | + session_set_cookie_params(60 * 60 * 24 * 365, '/'); // 1 year timeout on cookies | |
467 | + ini_set('session.gc_maxlifetime', 60 * 60 * 24 * 30); // 30 day timeout on sessions | |
468 | session_set_save_handler('sess_do_nothing', 'sess_do_nothing', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc'); | |
469 | session_start(); | |
470 | ||
471 | Index: mythplugins/mythweb/modules/weather/handler.php | |
472 | =================================================================== | |
473 | --- mythplugins/mythweb/modules/weather/handler.php (.../tags/release-0-19) (revision 10931) | |
474 | +++ mythplugins/mythweb/modules/weather/handler.php (.../branches/release-0-19-fixes) (revision 10931) | |
475 | @@ -222,8 +222,10 @@ | |
476 | ||
477 | $data = explode("|", $data); | |
478 | for($i = 0;$i<5;$i++) { | |
479 | - $forecast = new Forecast($data[5 + $i],$data[$i]); | |
480 | - $forecast->dayofweek = $data[$i]; | |
481 | + # mktime uses 0-6; msnbc gives us 1-7; adjust msnbc to match mktime | |
482 | + $dayofweek = $data[$i] - 1; | |
483 | + $forecast = new Forecast($data[5 + $i],$dayofweek); | |
484 | + $forecast->dayofweek = $dayofweek; | |
485 | list($forecast->DescImage,$forecast->DescText) = getImageAndDescFromId($data[15 + $i]); | |
486 | $forecast->DescImage = (strlen($forecast->DescImage) > 0) ? $forecast->DescImage : "unknown.png"; | |
487 | $forecast->DescText = (strlen($forecast->DescText) > 0) ? $forecast->DescText : t('Unknown') . " (" . $data[15+$i] . ")"; | |
488 | Index: mythplugins/mythweb/modules/status/handler.php | |
489 | =================================================================== | |
490 | --- mythplugins/mythweb/modules/status/handler.php (.../tags/release-0-19) (revision 10931) | |
491 | +++ mythplugins/mythweb/modules/status/handler.php (.../branches/release-0-19-fixes) (revision 10931) | |
492 | @@ -18,14 +18,17 @@ | |
493 | $masterhost = get_backend_setting('MasterServerIP'); | |
494 | $statusport = get_backend_setting('BackendStatusPort'); | |
495 | ||
496 | +// XML mode? | |
497 | + $xml_param = ($Path[1] == 'xml') ? '/xml' : ''; | |
498 | + | |
499 | // Make sure the content is interpreted as UTF-8 | |
500 | header('Content-Type: text/html; charset=UTF-8'); | |
501 | ||
502 | // Load the status page | |
503 | if (function_exists('file_get_contents')) | |
504 | - $status = file_get_contents("http://$masterhost:$statusport"); | |
505 | + $status = file_get_contents("http://$masterhost:$statusport$xml_param"); | |
506 | else | |
507 | - $status = implode("\n", file("http://$masterhost:$statusport")); | |
508 | + $status = implode("\n", file("http://$masterhost:$statusport$xml_param")); | |
509 | ||
510 | // Extract the page title | |
511 | preg_match('#<title>(.+?)</title>#s', $status, $title); | |
512 | Index: mythplugins/mythweb/modules/backend_log/handler.php | |
513 | =================================================================== | |
514 | --- mythplugins/mythweb/modules/backend_log/handler.php (.../tags/release-0-19) (revision 10931) | |
515 | +++ mythplugins/mythweb/modules/backend_log/handler.php (.../branches/release-0-19-fixes) (revision 10931) | |
516 | @@ -16,7 +16,7 @@ | |
517 | // Where to start searching from | |
518 | $_GET['start'] = intVal($_GET['start']); | |
519 | if ($_GET['start'] < 1) | |
520 | - $_GET['start'] = 1; | |
521 | + $_GET['start'] = 0; | |
522 | ||
523 | // How many entries to show? | |
524 | $_GET['show'] = intVal($_GET['show']); | |
525 | Index: mythplugins/mythweb/modules/tv/upcoming.php | |
526 | =================================================================== | |
527 | --- mythplugins/mythweb/modules/tv/upcoming.php (.../tags/release-0-19) (revision 10931) | |
528 | +++ mythplugins/mythweb/modules/tv/upcoming.php (.../branches/release-0-19-fixes) (revision 10931) | |
529 | @@ -103,8 +103,9 @@ | |
530 | continue; | |
531 | } | |
532 | // Skip deactivated shows? | |
533 | - elseif (!$_SESSION['scheduled_recordings']['disp_deactivated']) { | |
534 | - continue; | |
535 | + elseif ($show->recstatus != 'Recording') { | |
536 | + if (!$_SESSION['scheduled_recordings']['disp_deactivated']) | |
537 | + continue; | |
538 | } | |
539 | // Assign a reference to this show to the various arrays | |
540 | $all_shows[] =& $Scheduled_Recordings[$channum][$starttime][$key]; | |
541 | Index: mythplugins/mythweb/modules/tv/recorded.php | |
542 | =================================================================== | |
543 | --- mythplugins/mythweb/modules/tv/recorded.php (.../tags/release-0-19) (revision 10931) | |
544 | +++ mythplugins/mythweb/modules/tv/recorded.php (.../branches/release-0-19-fixes) (revision 10931) | |
545 | @@ -128,9 +128,21 @@ | |
546 | continue; | |
547 | // Get the length (27 == recendts; 26 == recstartts) | |
548 | $length = $record[27] - $record[26]; | |
549 | - // Keep track of the total time and disk space used | |
550 | + // Keep track of the total time and disk space used (9 == fs_high; 10 == fs_low) | |
551 | $Total_Time += $length; | |
552 | - $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10]; // 9 == fs_high; 10 == fs_low; | |
553 | + if (function_exists('gmp_add')) { | |
554 | + // GMP functions should work better with 64 bit numbers. | |
555 | + $size = gmp_add($record[10], | |
556 | + gmp_mul('4294967296', | |
557 | + gmp_add($record[9], $record[10] < 0 ? '1' : '0') | |
558 | + ) | |
559 | + ); | |
560 | + $Total_Used = gmp_strval(gmp_add($Total_Used, $size)); | |
561 | + } | |
562 | + else { | |
563 | + // This is inaccurate, but it's the best we can get without GMP. | |
564 | + $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10]; | |
565 | + } | |
566 | // keep track of their names and how many episodes we have recorded | |
567 | $Total_Programs++; | |
568 | $Groups[$record[30]]++; | |
569 | @@ -223,8 +235,28 @@ | |
570 | ||
571 | // How much free disk space on the backend machine? | |
572 | list($size_high, $size_low, $used_high, $used_low) = explode(backend_sep, backend_command('QUERY_FREE_SPACE')); | |
573 | - define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024); | |
574 | - define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024); | |
575 | + if (function_exists('gmp_add')) { | |
576 | + // GMP functions should work better with 64 bit numbers. | |
577 | + $size = gmp_mul('1024', | |
578 | + gmp_add($size_low, | |
579 | + gmp_mul('4294967296', | |
580 | + gmp_add($size_high, $size_low < 0 ? '1' : '0')) | |
581 | + ) | |
582 | + ); | |
583 | + define(disk_size, gmp_strval($size)); | |
584 | + $size = gmp_mul('1024', | |
585 | + gmp_add($used_low, | |
586 | + gmp_mul('4294967296', | |
587 | + gmp_add($used_high, $used_low < 0 ? '1' : '0')) | |
588 | + ) | |
589 | + ); | |
590 | + define(disk_used, gmp_strval($size)); | |
591 | + } | |
592 | + else { | |
593 | + // This is inaccurate, but it's the best we can get without GMP. | |
594 | + define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024); | |
595 | + define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024); | |
596 | + } | |
597 | ||
598 | // Load the class for this page | |
599 | require_once theme_dir.'tv/recorded.php'; | |
600 | Index: mythplugins/mythweb/.htaccess | |
601 | =================================================================== | |
602 | --- mythplugins/mythweb/.htaccess (.../tags/release-0-19) (revision 10931) | |
603 | +++ mythplugins/mythweb/.htaccess (.../branches/release-0-19-fixes) (revision 10931) | |
604 | @@ -22,6 +22,7 @@ | |
605 | # AuthName "MythTV" | |
606 | # AuthDigestFile /var/www/htdigest | |
607 | # Require valid-user | |
608 | +# BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On | |
609 | ||
610 | # MythTV now uses the correct file suffix for mpeg files, so all .nuv files | |
611 | # should actually be NuppleVideo. However, apache probably doesn't know what | |
612 | @@ -66,8 +67,6 @@ | |
613 | ||
614 | php_value memory_limit 32M | |
615 | ||
616 | - php_value session.save_path php_sessions | |
617 | - | |
618 | php_value output_buffering 4096 | |
619 | php_value register_globals 0 | |
620 | php_value magic_quotes_gpc 0 | |
621 | Index: mythplugins/mythweb/js/debug.js | |
622 | =================================================================== | |
623 | --- mythplugins/mythweb/js/debug.js (.../tags/release-0-19) (revision 0) | |
624 | +++ mythplugins/mythweb/js/debug.js (.../branches/release-0-19-fixes) (revision 10931) | |
625 | @@ -0,0 +1,24 @@ | |
626 | +/** | |
627 | + * A random assortment of javascript debug routines | |
628 | + * | |
629 | + * @url $URL$ | |
630 | + * @date $Date$ | |
631 | + * @version $Revision$ | |
632 | + * @author $Author$ | |
633 | + * @copyright Silicon Mechanics | |
634 | + * @license LGPL | |
635 | + * | |
636 | + * @package SiMech | |
637 | + * @subpackage Javascript | |
638 | + * | |
639 | +/**/ | |
640 | + | |
641 | + var debug_window_handle; | |
642 | +// Create a debug window and debug into it | |
643 | + function debug_window(string) { | |
644 | + if (!debug_window_handle || debug_window_handle.closed) { | |
645 | + debug_window_handle = window.open('', 'Debug Window','scrollbars, resizable, width=400, height=600'); | |
646 | + debug_window_handle.document.write('<html><body style="font-size: 9pt; background-color: #f88;">'); | |
647 | + } | |
648 | + debug_window_handle.document.write('<pre>'+string+'</pre><hr>'); | |
649 | + } | |
650 | ||
651 | Property changes on: mythplugins/mythweb/js/debug.js | |
652 | ___________________________________________________________________ | |
653 | Name: svn:eol-style | |
654 | + native | |
655 | Name: svn:mime-type | |
656 | + text/x-javascript | |
657 | Name: svn:keywords | |
658 | + Date Revision Author HeadURL | |
659 | ||
660 | Index: mythplugins/mythweb/js/browser.js | |
661 | =================================================================== | |
662 | --- mythplugins/mythweb/js/browser.js (.../tags/release-0-19) (revision 10931) | |
663 | +++ mythplugins/mythweb/js/browser.js (.../branches/release-0-19-fixes) (revision 10931) | |
664 | @@ -215,14 +215,18 @@ | |
665 | browser.is_css = (document.body && document.body.style) | |
666 | browser.is_w3c = (browser.is_css && browser.getElementById) | |
667 | ||
668 | -// Cookie support | |
669 | - var tmp = document.cookie; | |
670 | - document.cookie = 'cookies=true'; | |
671 | - browser.cookies = (document.cookie) ? true : false; | |
672 | - document.cookie = tmp; | |
673 | +// Cookie support -- only create a cookie if there isn't one already. It seems | |
674 | +// that doing this can override the exipiration info in existing cookies. | |
675 | + browser.cookies = (document.cookie) ? true : false; | |
676 | + if (!browser.cookies) { | |
677 | + var tmp = document.cookie; | |
678 | + document.cookie = 'cookie_test=true'; | |
679 | + browser.cookies = (document.cookie) ? true : false; | |
680 | + document.cookie = tmp; | |
681 | + } | |
682 | ||
683 | // Java support | |
684 | - browser.java = navigator.javaEnabled(); | |
685 | + browser.java = navigator.javaEnabled(); | |
686 | ||
687 | /****************************** Plugin Support ******************************/ | |
688 | ||
689 | Index: mythplugins/mythweb/README | |
690 | =================================================================== | |
691 | --- mythplugins/mythweb/README (.../tags/release-0-19) (revision 10931) | |
692 | +++ mythplugins/mythweb/README (.../branches/release-0-19-fixes) (revision 10931) | |
693 | @@ -1,18 +1,12 @@ | |
694 | This is the README file for the MythWeb package. | |
695 | -January 17, 2006 | |
696 | +March 6, 2006 | |
697 | ||
698 | -Version: .19 pre | |
699 | -(c) 2002-2006 Thor Sigvaldason <mythtv(a)lamedomainname(o)com> | |
700 | +Version: .19 | |
701 | +(c) 2002-2006 Chris Petersen <mythweb(a)forevermore(o)net> | |
702 | Isaac Richards <ijr(a)po(o)cwru(o)edu> | |
703 | - Chris Petersen <mythweb(a)forevermore(o)net> | |
704 | + Thor Sigvaldason <mythtv(a)lamedomainname(o)com> | |
705 | + and others... (see mythtv.org commit logs for details) | |
706 | ||
707 | -with contributions from many people including: | |
708 | - | |
709 | -Michael Kedl <kedlm(a)knology(o)net> | |
710 | -Jonathan Kolb <jkolb(a)greyshift(o)net | |
711 | -Ed Wildgoose <edward(o)wildgoose(a)frmhedge(o)com> | |
712 | -Kenneth Aafloy <ke-aa(a)frisurf(o)no> | |
713 | - | |
714 | MythWeb is distributed under the GNU GENERAL PUBLIC LICENSE version 2, and where | |
715 | noted with the @license tag, the LESSER GENERAL PUBLIC LICENSE version 2. | |
716 | Please see http://www.gnu.org for details and the specific text of the license. | |
717 | @@ -63,10 +57,22 @@ | |
718 | ||
719 | In order for the included .htaccess to work properly, you will need to | |
720 | set apache's "AllowOverride" setting to "All" (or at least "Options") for | |
721 | -the root mythweb directory. This directive lives within <Directory/> tags, | |
722 | -so make sure you're changing the setting for the correct directory. You will | |
723 | -also need to make sure that the following apache modules are enabled: | |
724 | +the root mythweb directory. This directive lives within <Directory> tags, | |
725 | +so make sure you're changing the setting for the correct directory. Please | |
726 | +keep in mind that most distros correctly disable everything for <Directory />, | |
727 | +and then later override those with something like <Directory /var/www/html>. | |
728 | +The simplest way to do this is to put a file into /etc/httpd/conf.d (or | |
729 | +whatever your distro calls it) containing something like: | |
730 | ||
731 | + <Directory "/var/www/html/mythweb" > | |
732 | + Options FollowSymLinks | |
733 | + AllowOverride All | |
734 | + </Directory> | |
735 | + | |
736 | +Just make sure that the path points to your MythWeb installation, since that | |
737 | +will likely differ from system to system. You will also need to make sure that | |
738 | +the following apache modules are enabled: | |
739 | + | |
740 | mod_env | |
741 | mod_rewrite | |
742 | ||
743 | Index: mythplugins/mythdvd/mtd/jobthread.cpp | |
744 | =================================================================== | |
745 | --- mythplugins/mythdvd/mtd/jobthread.cpp (.../tags/release-0-19) (revision 10931) | |
746 | +++ mythplugins/mythdvd/mtd/jobthread.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
747 | @@ -11,6 +11,7 @@ | |
748 | #include <sys/types.h> | |
749 | #include <sys/stat.h> | |
750 | #include <fcntl.h> | |
751 | +#include <unistd.h> | |
752 | ||
753 | #include <iostream> | |
754 | using namespace std; | |
755 | Index: mythplugins/mythdvd/mtd/mtd.cpp | |
756 | =================================================================== | |
757 | --- mythplugins/mythdvd/mtd/mtd.cpp (.../tags/release-0-19) (revision 10931) | |
758 | +++ mythplugins/mythdvd/mtd/mtd.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
759 | @@ -8,6 +8,7 @@ | |
760 | ||
761 | */ | |
762 | ||
763 | +#include <unistd.h> | |
764 | #include <qstringlist.h> | |
765 | #include <qregexp.h> | |
766 | #include <qdir.h> | |
767 | Index: mythplugins/mythdvd/mtd/logging.cpp | |
768 | =================================================================== | |
769 | --- mythplugins/mythdvd/mtd/logging.cpp (.../tags/release-0-19) (revision 10931) | |
770 | +++ mythplugins/mythdvd/mtd/logging.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
771 | @@ -9,6 +9,7 @@ | |
772 | */ | |
773 | #include "logging.h" | |
774 | ||
775 | +#include <unistd.h> | |
776 | #include <qdatetime.h> | |
777 | ||
778 | #include <mythtv/mythcontext.h> | |
779 | Index: mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp | |
780 | =================================================================== | |
781 | --- mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp (.../tags/release-0-19) (revision 10931) | |
782 | +++ mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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 | + §ion); | |
798 | +#else | |
799 | len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1, | |
800 | §ion); | |
801 | +#endif | |
802 | ||
803 | if (len > 0) { | |
804 | bitrate = ov_bitrate_instant(&oggfile) / 1000; | |
805 | Index: mythplugins/mythmusic/mythmusic/flacdecoder.cpp | |
806 | =================================================================== | |
807 | --- mythplugins/mythmusic/mythmusic/flacdecoder.cpp (.../tags/release-0-19) (revision 10931) | |
808 | +++ mythplugins/mythmusic/mythmusic/flacdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
809 | @@ -12,6 +12,7 @@ | |
810 | #include "metadata.h" | |
811 | #include "metaioflacvorbiscomment.h" | |
812 | ||
813 | +#include <mythtv/mythconfig.h> | |
814 | #include <mythtv/mythcontext.h> | |
815 | ||
816 | #include <qtimer.h> | |
817 | @@ -102,7 +103,11 @@ | |
818 | for (channel = 0; channel < chan; channel++) | |
819 | { | |
820 | sample = (FLAC__int8)buffer[channel][cursamp]; | |
821 | +#ifdef WORDS_BIGENDIAN | |
822 | + *(output_buf + output_at++) = ((sample >> 8) & 0xff); | |
823 | +#else | |
824 | *(output_buf + output_at++) = ((sample >> 0) & 0xff); | |
825 | +#endif | |
826 | output_bytes += 1; | |
827 | } | |
828 | } | |
829 | @@ -114,8 +119,13 @@ | |
830 | for (channel = 0; channel < chan; channel++) | |
831 | { | |
832 | sample = (FLAC__int16)buffer[channel][cursamp]; | |
833 | +#ifdef WORDS_BIGENDIAN | |
834 | + *(output_buf + output_at++) = ((sample >> 8) & 0xff); | |
835 | *(output_buf + output_at++) = ((sample >> 0) & 0xff); | |
836 | +#else | |
837 | + *(output_buf + output_at++) = ((sample >> 0) & 0xff); | |
838 | *(output_buf + output_at++) = ((sample >> 8) & 0xff); | |
839 | +#endif | |
840 | output_bytes += 2; | |
841 | } | |
842 | } | |
843 | Index: mythplugins/mythmusic/mythmusic/maddecoder.cpp | |
844 | =================================================================== | |
845 | --- mythplugins/mythmusic/mythmusic/maddecoder.cpp (.../tags/release-0-19) (revision 10931) | |
846 | +++ mythplugins/mythmusic/mythmusic/maddecoder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
847 | @@ -16,6 +16,7 @@ | |
848 | #include <mythtv/audiooutput.h> | |
849 | #include "metaioid3v2.h" | |
850 | ||
851 | +#include <mythtv/mythconfig.h> | |
852 | #include <mythtv/mythcontext.h> | |
853 | ||
854 | #define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g') | |
855 | @@ -407,7 +408,7 @@ | |
856 | flush(TRUE); | |
857 | ||
858 | if (output()) { | |
859 | - output()->Drain(); | |
860 | + output()->Drain(); | |
861 | } | |
862 | ||
863 | done = TRUE; | |
864 | @@ -488,15 +489,25 @@ | |
865 | flush(); | |
866 | } | |
867 | sample = fix_sample(16, *left++); | |
868 | +#ifdef WORDS_BIGENDIAN | |
869 | + *(output_buf + output_at++) = ((sample >> 8) & 0xff); | |
870 | *(output_buf + output_at++) = ((sample >> 0) & 0xff); | |
871 | +#else | |
872 | + *(output_buf + output_at++) = ((sample >> 0) & 0xff); | |
873 | *(output_buf + output_at++) = ((sample >> 8) & 0xff); | |
874 | +#endif | |
875 | output_bytes += 2; | |
876 | ||
877 | if (channels == 2) | |
878 | { | |
879 | sample = fix_sample(16, *right++); | |
880 | +#ifdef WORDS_BIGENDIAN | |
881 | + *(output_buf + output_at++) = ((sample >> 8) & 0xff); | |
882 | *(output_buf + output_at++) = ((sample >> 0) & 0xff); | |
883 | +#else | |
884 | + *(output_buf + output_at++) = ((sample >> 0) & 0xff); | |
885 | *(output_buf + output_at++) = ((sample >> 8) & 0xff); | |
886 | +#endif | |
887 | output_bytes += 2; | |
888 | } | |
889 | } | |
890 | Index: mythplugins/mythweather/mythweather/weather.cpp | |
891 | =================================================================== | |
892 | --- mythplugins/mythweather/mythweather/weather.cpp (.../tags/release-0-19) (revision 10931) | |
893 | +++ mythplugins/mythweather/mythweather/weather.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
894 | @@ -2571,6 +2571,14 @@ | |
895 | return false; | |
896 | } | |
897 | ||
898 | + int imageCount = 5; | |
899 | + QString imagesList = parseData(tempData, "imagenames = new Array( '", ";"); | |
900 | + if (imagesList != "<NULL>") | |
901 | + { | |
902 | + QStringList imageURLs = QStringList::split(",", imagesList); | |
903 | + imageCount = imageURLs.size(); | |
904 | + } | |
905 | + | |
906 | QString fileprefix = MythContext::GetConfDir(); | |
907 | ||
908 | QDir dir(fileprefix); | |
909 | @@ -2587,13 +2595,13 @@ | |
910 | cerr << "MythWeather: Map File Prefix: " << fileprefix << endl; | |
911 | ||
912 | // delete existing radar maps | |
913 | - for (int x = 1; x <= 6; x++) | |
914 | + for (int x = 1; x <= 10; x++) | |
915 | QFile::remove(QString(fileprefix + "/radar%1.jpg").arg(x)); | |
916 | ||
917 | if (debug) | |
918 | cerr << "MythWeather: Copying Map Files from Server (" << imageLoc << ")...\n"; | |
919 | ||
920 | - for (int x = 1; x <= 6; x++) | |
921 | + for (int x = 1; x <= imageCount; x++) | |
922 | { | |
923 | QString sFile = QString(fileprefix + "/radar%1.jpg").arg(x); | |
924 | sURL = QString("http://image.weather.com" + imageLoc + "%1L.jpg").arg(x); | |
925 | Index: mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp | |
926 | =================================================================== | |
927 | --- mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp (.../tags/release-0-19) (revision 10931) | |
928 | +++ mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
929 | @@ -46,22 +46,6 @@ | |
930 | #include "keygrabber.h" | |
931 | ||
932 | ||
933 | -static QMap<int,QString> FindContexts(const QString &context) | |
934 | -{ | |
935 | - QMap<int,QString> retval; | |
936 | - retval.clear(); | |
937 | - if (context != JUMP_CONTEXT) retval[-1] = JUMP_CONTEXT; | |
938 | - retval[0] = context; | |
939 | - if (context != JUMP_CONTEXT && context != GLOBAL_CONTEXT) | |
940 | - { | |
941 | - if (context == "TV Editting") | |
942 | - retval[1] = "TV Playback"; | |
943 | - retval[2] = GLOBAL_CONTEXT; | |
944 | - if (context != "qt") | |
945 | - retval[3] = "qt"; | |
946 | - } | |
947 | - return retval; | |
948 | -} | |
949 | ||
950 | static const QString KeyToDisplay(const QString key) | |
951 | { | |
952 | @@ -838,7 +822,11 @@ | |
953 | refreshKeyInformation(); | |
954 | } | |
955 | ||
956 | -void MythControls::addBindings(QDict<binding_t> &bindings, const QString &context, const QString &contextParent, int bindlevel) | |
957 | + | |
958 | + | |
959 | +void MythControls::addBindings(QDict<binding_t> &bindings, | |
960 | + const QString &context, | |
961 | + const QString &contextParent, int bindlevel) | |
962 | { | |
963 | QStringList *actions = key_bindings->getActions(context); | |
964 | ||
965 | @@ -872,18 +860,13 @@ | |
966 | ||
967 | BindingList *MythControls::getKeyBindings(const QString &context) | |
968 | { | |
969 | + QStringList keys; | |
970 | QDict<binding_t> bindings; | |
971 | bindings.clear(); | |
972 | ||
973 | - QMap<int,QString> contextList = FindContexts(context); | |
974 | - for (QMap<int,QString>::iterator it = contextList.begin(); it != contextList.end(); ++it) | |
975 | - { | |
976 | - int level = it.key(); | |
977 | - QString curcontext = it.data(); | |
978 | - addBindings(bindings, curcontext, context, level); | |
979 | - } | |
980 | + for (size_t i = 0; i < contexts.size(); i++) | |
981 | + addBindings(bindings, contexts[i], context, i); | |
982 | ||
983 | - QStringList keys; | |
984 | ||
985 | for (QDictIterator<binding_t> it(bindings); it.current(); ++it) | |
986 | { | |
987 | Index: mythplugins/mythcontrols/mythcontrols/actionset.cpp | |
988 | =================================================================== | |
989 | --- mythplugins/mythcontrols/mythcontrols/actionset.cpp (.../tags/release-0-19) (revision 10931) | |
990 | +++ mythplugins/mythcontrols/mythcontrols/actionset.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
991 | @@ -139,13 +139,19 @@ | |
992 | /* method description in header */ | |
993 | QStringList * ActionSet::actionStrings(const QString &context_name) const | |
994 | { | |
995 | - QStringList *action_strings = new QStringList(); | |
996 | - QDictIterator<Action> it(*(_contexts[context_name])); | |
997 | + Context *c = _contexts[context_name]; | |
998 | ||
999 | - for (; it.current(); ++it) | |
1000 | - action_strings->append(it.currentKey()); | |
1001 | + if (c == NULL) return NULL; | |
1002 | + else | |
1003 | + { | |
1004 | + QStringList *action_strings = new QStringList(); | |
1005 | + QDictIterator<Action> it(*(_contexts[context_name])); | |
1006 | + | |
1007 | + for (; it.current(); ++it) | |
1008 | + action_strings->append(it.currentKey()); | |
1009 | ||
1010 | - return action_strings; | |
1011 | + return action_strings; | |
1012 | + } | |
1013 | } | |
1014 | ||
1015 | ||
1016 | Index: mythplugins/mythcontrols/mythcontrols/keybindings.h | |
1017 | =================================================================== | |
1018 | --- mythplugins/mythcontrols/mythcontrols/keybindings.h (.../tags/release-0-19) (revision 10931) | |
1019 | +++ mythplugins/mythcontrols/mythcontrols/keybindings.h (.../branches/release-0-19-fixes) (revision 10931) | |
1020 | @@ -65,6 +65,8 @@ | |
1021 | /** | |
1022 | * @brief Get a list of the context names. | |
1023 | * @return A list of the context names. | |
1024 | + * @note The returned list is a copy and can be modified without | |
1025 | + * side-effects. | |
1026 | */ | |
1027 | inline QStringList * getContexts() const | |
1028 | { | |
1029 | Index: mythplugins/mythvideo/mythvideo/videomanager.h | |
1030 | =================================================================== | |
1031 | --- mythplugins/mythvideo/mythvideo/videomanager.h (.../tags/release-0-19) (revision 10931) | |
1032 | +++ mythplugins/mythvideo/mythvideo/videomanager.h (.../branches/release-0-19-fixes) (revision 10931) | |
1033 | @@ -30,7 +30,7 @@ | |
1034 | public: | |
1035 | VideoManager(MythMainWindow *parent, const char *name = 0); | |
1036 | ~VideoManager(void); | |
1037 | - void VideoManager::processEvents() { qApp->processEvents(); } | |
1038 | + void processEvents() { qApp->processEvents(); } | |
1039 | ||
1040 | public slots: | |
1041 | void slotManualIMDB(); | |
1042 | Index: mythplugins/mythvideo/mythvideo/videoselected.h | |
1043 | =================================================================== | |
1044 | --- mythplugins/mythvideo/mythvideo/videoselected.h (.../tags/release-0-19) (revision 10931) | |
1045 | +++ mythplugins/mythvideo/mythvideo/videoselected.h (.../branches/release-0-19-fixes) (revision 10931) | |
1046 | @@ -35,7 +35,7 @@ | |
1047 | VideoSelected(VideoList *lvideolist, | |
1048 | MythMainWindow *parent, const char *name = 0, int index = 0); | |
1049 | ~VideoSelected(); | |
1050 | - void VideoSelected::processEvents() { qApp->processEvents(); } | |
1051 | + void processEvents() { qApp->processEvents(); } | |
1052 | ||
1053 | ||
1054 | protected slots: | |
1055 | Index: mythplugins/mythphone/mythphone/sipfsm.h | |
1056 | =================================================================== | |
1057 | --- mythplugins/mythphone/mythphone/sipfsm.h (.../tags/release-0-19) (revision 10931) | |
1058 | +++ mythplugins/mythphone/mythphone/sipfsm.h (.../branches/release-0-19-fixes) (revision 10931) | |
1059 | @@ -618,7 +618,7 @@ | |
1060 | SipWatcher *CreateWatcherFsm(QString Url); | |
1061 | SipIM *CreateIMFsm(QString Url="", QString callIdStr=""); | |
1062 | void StopWatchers(); | |
1063 | - void SipFsm::KickWatcher(SipUrl *Url); | |
1064 | + void KickWatcher(SipUrl *Url); | |
1065 | void SendIM(QString destUrl, QString CallId, QString imMsg); | |
1066 | int numCalls(); | |
1067 | int getPrimaryCall() { return primaryCall; }; | |
1068 | Index: mythplugins/mythphone/mythphone/vxml.h | |
1069 | =================================================================== | |
1070 | --- mythplugins/mythphone/mythphone/vxml.h (.../tags/release-0-19) (revision 10931) | |
1071 | +++ mythplugins/mythphone/mythphone/vxml.h (.../branches/release-0-19-fixes) (revision 10931) | |
1072 | @@ -10,7 +10,7 @@ | |
1073 | { | |
1074 | public: | |
1075 | vxmlVariable(QString N, QString V); | |
1076 | - vxmlVariable::vxmlVariable(QString N, short *wav, int S); | |
1077 | + vxmlVariable(QString N, short *wav, int S); | |
1078 | virtual ~vxmlVariable() {}; | |
1079 | bool isType(QString t) { return (t == Type); }; | |
1080 | QString getName() { return Name; }; | |
1081 | Index: mythplugins/mythgame/mythgame/gamehandler.h | |
1082 | =================================================================== | |
1083 | --- mythplugins/mythgame/mythgame/gamehandler.h (.../tags/release-0-19) (revision 10931) | |
1084 | +++ mythplugins/mythgame/mythgame/gamehandler.h (.../branches/release-0-19-fixes) (revision 10931) | |
1085 | @@ -106,7 +106,7 @@ | |
1086 | ||
1087 | protected: | |
1088 | static GameHandler* GetHandler(RomInfo *rominfo); | |
1089 | - static GameHandler* GameHandler::GetHandlerByName(QString systemname); | |
1090 | + static GameHandler* GetHandlerByName(QString systemname); | |
1091 | ||
1092 | bool rebuild; | |
1093 | int spandisks; | |
1094 | Index: mythplugins/mythnews/mythnews/news-sites.xml | |
1095 | =================================================================== | |
1096 | --- mythplugins/mythnews/mythnews/news-sites.xml (.../tags/release-0-19) (revision 10931) | |
1097 | +++ mythplugins/mythnews/mythnews/news-sites.xml (.../branches/release-0-19-fixes) (revision 10931) | |
1098 | @@ -119,7 +119,7 @@ | |
1099 | ||
1100 | <item> | |
1101 | <title>Slashdot</title> | |
1102 | - <url>http://slashdot.org/slashdot.rss</url> | |
1103 | + <url>http://rss.slashdot.org/Slashdot/slashdot</url> | |
1104 | <ico>http://slashdot.org/favicon.ico</ico> | |
1105 | </item> | |
1106 | ||
1107 | Index: mythtv/libs/libmythtv/dvbchannel.h | |
1108 | =================================================================== | |
1109 | --- mythtv/libs/libmythtv/dvbchannel.h (.../tags/release-0-19) (revision 10931) | |
1110 | +++ mythtv/libs/libmythtv/dvbchannel.h (.../branches/release-0-19-fixes) (revision 10931) | |
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 | |
1144 | Index: mythtv/libs/libmythtv/NuppelVideoPlayer.h | |
1145 | =================================================================== | |
1146 | --- mythtv/libs/libmythtv/NuppelVideoPlayer.h (.../tags/release-0-19) (revision 10931) | |
1147 | +++ mythtv/libs/libmythtv/NuppelVideoPlayer.h (.../branches/release-0-19-fixes) (revision 10931) | |
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; } | |
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 @@ | |
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 | |
1183 | Index: mythtv/libs/libmythtv/osdlistbtntype.h | |
1184 | =================================================================== | |
1185 | --- mythtv/libs/libmythtv/osdlistbtntype.h (.../tags/release-0-19) (revision 10931) | |
1186 | +++ mythtv/libs/libmythtv/osdlistbtntype.h (.../branches/release-0-19-fixes) (revision 10931) | |
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 | ||
1629 | Index: mythtv/libs/libmythtv/NuppelVideoPlayer.cpp | |
1630 | =================================================================== | |
1631 | --- mythtv/libs/libmythtv/NuppelVideoPlayer.cpp (.../tags/release-0-19) (revision 10931) | |
1632 | +++ mythtv/libs/libmythtv/NuppelVideoPlayer.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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 | { | |
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 @@ | |
1769 | ShowText(); | |
1770 | DisplaySubtitles(); | |
1771 | } | |
1772 | - else if (osdHasSubtitles || nonDisplayedSubtitles.size() > 20) | |
1773 | + else if (osdHasSubtitles) | |
1774 | { | |
1775 | ClearSubtitles(); | |
1776 | } | |
1777 | @@ -2176,7 +2210,10 @@ | |
1778 | } | |
1779 | ||
1780 | if (eof) | |
1781 | + { | |
1782 | discontinuity = true; | |
1783 | + ClearSubtitles(); | |
1784 | + } | |
1785 | ||
1786 | livetvchain->SetProgram(pginfo); | |
1787 | ||
1788 | @@ -2199,6 +2236,7 @@ | |
1789 | } | |
1790 | if (IsErrored()) | |
1791 | { | |
1792 | + VERBOSE(VB_IMPORTANT, LOC_ERR + "SwitchToProgram failed."); | |
1793 | eof = true; | |
1794 | return; | |
1795 | } | |
1796 | @@ -2265,6 +2303,8 @@ | |
1797 | ringBuffer->Pause(); | |
1798 | ringBuffer->WaitForPause(); | |
1799 | ||
1800 | + ClearSubtitles(); | |
1801 | + | |
1802 | livetvchain->SetProgram(pginfo); | |
1803 | ||
1804 | ringBuffer->Reset(true); | |
1805 | @@ -2284,6 +2324,7 @@ | |
1806 | ||
1807 | if (errored || !GetDecoder()) | |
1808 | { | |
1809 | + VERBOSE(VB_IMPORTANT, LOC_ERR + "JumpToProgram failed."); | |
1810 | errored = true; | |
1811 | return; | |
1812 | } | |
1813 | @@ -2471,6 +2512,12 @@ | |
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"); | |
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 @@ | |
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) | |
1876 | @@ -4541,7 +4598,8 @@ | |
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; | |
1886 | @@ -4588,15 +4646,23 @@ | |
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); | |
1915 | @@ -4654,6 +4720,7 @@ | |
1916 | ||
1917 | if (commBreakIter.key() == totalFrames) | |
1918 | { | |
1919 | + VERBOSE(VB_IMPORTANT, LOC + "Skipping commercial to end of file"); | |
1920 | eof = true; | |
1921 | } | |
1922 | else | |
1923 | @@ -4721,7 +4788,7 @@ | |
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; | |
1932 | @@ -5018,7 +5085,7 @@ | |
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); | |
1941 | Index: mythtv/libs/libmythtv/NuppelVideoRecorder.cpp | |
1942 | =================================================================== | |
1943 | --- mythtv/libs/libmythtv/NuppelVideoRecorder.cpp (.../tags/release-0-19) (revision 10931) | |
1944 | +++ mythtv/libs/libmythtv/NuppelVideoRecorder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
1945 | @@ -216,7 +216,10 @@ | |
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; | |
1999 | Index: mythtv/libs/libmythtv/signalmonitor.cpp | |
2000 | =================================================================== | |
2001 | --- mythtv/libs/libmythtv/signalmonitor.cpp (.../tags/release-0-19) (revision 10931) | |
2002 | +++ mythtv/libs/libmythtv/signalmonitor.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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", | |
2016 | Index: mythtv/libs/libmythtv/osdlistbtntype.cpp | |
2017 | =================================================================== | |
2018 | --- mythtv/libs/libmythtv/osdlistbtntype.cpp (.../tags/release-0-19) (revision 10931) | |
2019 | +++ mythtv/libs/libmythtv/osdlistbtntype.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
2020 | @@ -19,206 +19,148 @@ | |
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 | - | |
3348 | Index: mythtv/libs/libmythtv/RingBuffer.cpp | |
3349 | =================================================================== | |
3350 | --- mythtv/libs/libmythtv/RingBuffer.cpp (.../tags/release-0-19) (revision 10931) | |
3351 | +++ mythtv/libs/libmythtv/RingBuffer.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
3352 | @@ -145,6 +145,12 @@ | |
3353 | VERBOSE(VB_PLAYBACK, LOC + QString("OpenFile(%1, %1)") | |
3354 | .arg(lfilename).arg(retryCount)); | |
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) | |
3476 | Index: mythtv/libs/libmythtv/hdtvrecorder.cpp | |
3477 | =================================================================== | |
3478 | --- mythtv/libs/libmythtv/hdtvrecorder.cpp (.../tags/release-0-19) (revision 10931) | |
3479 | +++ mythtv/libs/libmythtv/hdtvrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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(); | |
3492 | Index: mythtv/libs/libmythtv/dummydtvrecorder.cpp | |
3493 | =================================================================== | |
3494 | --- mythtv/libs/libmythtv/dummydtvrecorder.cpp (.../tags/release-0-19) (revision 10931) | |
3495 | +++ mythtv/libs/libmythtv/dummydtvrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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(); | |
3518 | Index: mythtv/libs/libmythtv/avformatdecoder.cpp | |
3519 | =================================================================== | |
3520 | --- mythtv/libs/libmythtv/avformatdecoder.cpp (.../tags/release-0-19) (revision 10931) | |
3521 | +++ mythtv/libs/libmythtv/avformatdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
3522 | @@ -725,7 +725,12 @@ | |
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. " + | |
3535 | Index: mythtv/libs/libmythtv/osdtypes.cpp | |
3536 | =================================================================== | |
3537 | --- mythtv/libs/libmythtv/osdtypes.cpp (.../tags/release-0-19) (revision 10931) | |
3538 | +++ mythtv/libs/libmythtv/osdtypes.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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 | ||
4249 | Index: mythtv/libs/libmythtv/tv_play.cpp | |
4250 | =================================================================== | |
4251 | --- mythtv/libs/libmythtv/tv_play.cpp (.../tags/release-0-19) (revision 10931) | |
4252 | +++ mythtv/libs/libmythtv/tv_play.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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) | |
4504 | Index: mythtv/libs/libmythtv/jobqueue.cpp | |
4505 | =================================================================== | |
4506 | --- mythtv/libs/libmythtv/jobqueue.cpp (.../tags/release-0-19) (revision 10931) | |
4507 | +++ mythtv/libs/libmythtv/jobqueue.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
4508 | @@ -275,6 +275,11 @@ | |
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)) | |
4520 | Index: mythtv/libs/libmythtv/dvbdev/dvbdev.c | |
4521 | =================================================================== | |
4522 | --- mythtv/libs/libmythtv/dvbdev/dvbdev.c (.../tags/release-0-19) (revision 10931) | |
4523 | +++ mythtv/libs/libmythtv/dvbdev/dvbdev.c (.../branches/release-0-19-fixes) (revision 10931) | |
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) | |
4617 | Index: mythtv/libs/libmythtv/videosource.h | |
4618 | =================================================================== | |
4619 | --- mythtv/libs/libmythtv/videosource.h (.../tags/release-0-19) (revision 10931) | |
4620 | +++ mythtv/libs/libmythtv/videosource.h (.../branches/release-0-19-fixes) (revision 10931) | |
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); | |
4629 | Index: mythtv/libs/libmythtv/libmythtv.pro | |
4630 | =================================================================== | |
4631 | --- mythtv/libs/libmythtv/libmythtv.pro (.../tags/release-0-19) (revision 10931) | |
4632 | +++ mythtv/libs/libmythtv/libmythtv.pro (.../branches/release-0-19-fixes) (revision 10931) | |
4633 | @@ -119,6 +119,10 @@ | |
4634 | SOURCES += playgroup.cpp | |
4635 | SOURCES += progdetails.cpp | |
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 @@ | |
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 | |
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 | ||
4668 | Index: mythtv/libs/libmythtv/dvbchannel.cpp | |
4669 | =================================================================== | |
4670 | --- mythtv/libs/libmythtv/dvbchannel.cpp (.../tags/release-0-19) (revision 10931) | |
4671 | +++ mythtv/libs/libmythtv/dvbchannel.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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, ¶ms) < 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 | } | |
4792 | Index: mythtv/libs/libmythtv/osdtypes.h | |
4793 | =================================================================== | |
4794 | --- mythtv/libs/libmythtv/osdtypes.h (.../tags/release-0-19) (revision 10931) | |
4795 | +++ mythtv/libs/libmythtv/osdtypes.h (.../branches/release-0-19-fixes) (revision 10931) | |
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 | ||
5022 | Index: mythtv/libs/libmythtv/videoout_xv.h | |
5023 | =================================================================== | |
5024 | --- mythtv/libs/libmythtv/videoout_xv.h (.../tags/release-0-19) (revision 10931) | |
5025 | +++ mythtv/libs/libmythtv/videoout_xv.h (.../branches/release-0-19-fixes) (revision 10931) | |
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*); | |
5044 | Index: mythtv/libs/libmythtv/osdimagecache.h | |
5045 | =================================================================== | |
5046 | --- mythtv/libs/libmythtv/osdimagecache.h (.../tags/release-0-19) (revision 0) | |
5047 | +++ mythtv/libs/libmythtv/osdimagecache.h (.../branches/release-0-19-fixes) (revision 10931) | |
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 | +}; | |
5123 | Index: mythtv/libs/libmythtv/tv_play.h | |
5124 | =================================================================== | |
5125 | --- mythtv/libs/libmythtv/tv_play.h (.../tags/release-0-19) (revision 10931) | |
5126 | +++ mythtv/libs/libmythtv/tv_play.h (.../branches/release-0-19-fixes) (revision 10931) | |
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; | |
5144 | Index: mythtv/libs/libmythtv/videosource.cpp | |
5145 | =================================================================== | |
5146 | --- mythtv/libs/libmythtv/videosource.cpp (.../tags/release-0-19) (revision 10931) | |
5147 | +++ mythtv/libs/libmythtv/videosource.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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> | |
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 @@ | |
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.")); | |
5201 | Index: mythtv/libs/libmythtv/frequencytables.cpp | |
5202 | =================================================================== | |
5203 | --- mythtv/libs/libmythtv/frequencytables.cpp (.../tags/release-0-19) (revision 10931) | |
5204 | +++ mythtv/libs/libmythtv/frequencytables.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
5205 | @@ -283,104 +283,52 @@ | |
5206 | "ATSC Channel %1", 70, 809000000, 887000000, 6000000, VSB_8); | |
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); | |
5240 | + for (uint i = 0; i < 4; i++) | |
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 | } | |
5353 | Index: mythtv/libs/libmythtv/scanwizardhelpers.h | |
5354 | =================================================================== | |
5355 | --- mythtv/libs/libmythtv/scanwizardhelpers.h (.../tags/release-0-19) (revision 10931) | |
5356 | +++ mythtv/libs/libmythtv/scanwizardhelpers.h (.../branches/release-0-19-fixes) (revision 10931) | |
5357 | @@ -272,11 +272,13 @@ | |
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.") + " " + | |
5376 | Index: mythtv/libs/libmythtv/scanwizard.cpp | |
5377 | =================================================================== | |
5378 | --- mythtv/libs/libmythtv/scanwizard.cpp (.../tags/release-0-19) (revision 10931) | |
5379 | +++ mythtv/libs/libmythtv/scanwizard.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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) | |
5391 | Index: mythtv/libs/libmythtv/videoout_xv.cpp | |
5392 | =================================================================== | |
5393 | --- mythtv/libs/libmythtv/videoout_xv.cpp (.../tags/release-0-19) (revision 10931) | |
5394 | +++ mythtv/libs/libmythtv/videoout_xv.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
5395 | @@ -1089,6 +1089,9 @@ | |
5396 | bool use_xv = true, use_shm = true; | |
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); | |
5671 | Index: mythtv/libs/libmythtv/signalmonitor.h | |
5672 | =================================================================== | |
5673 | --- mythtv/libs/libmythtv/signalmonitor.h (.../tags/release-0-19) (revision 10931) | |
5674 | +++ mythtv/libs/libmythtv/signalmonitor.h (.../branches/release-0-19-fixes) (revision 10931) | |
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; | |
5704 | Index: mythtv/libs/libmythtv/RingBuffer.h | |
5705 | =================================================================== | |
5706 | --- mythtv/libs/libmythtv/RingBuffer.h (.../tags/release-0-19) (revision 10931) | |
5707 | +++ mythtv/libs/libmythtv/RingBuffer.h (.../branches/release-0-19-fixes) (revision 10931) | |
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); | |
5716 | Index: mythtv/libs/libmythtv/dvbtypes.cpp | |
5717 | =================================================================== | |
5718 | --- mythtv/libs/libmythtv/dvbtypes.cpp (.../tags/release-0-19) (revision 10931) | |
5719 | +++ mythtv/libs/libmythtv/dvbtypes.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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 | ||
5747 | Index: mythtv/libs/libmythtv/mpegrecorder.cpp | |
5748 | =================================================================== | |
5749 | --- mythtv/libs/libmythtv/mpegrecorder.cpp (.../tags/release-0-19) (revision 10931) | |
5750 | +++ mythtv/libs/libmythtv/mpegrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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 | } | |
5773 | Index: mythtv/libs/libmythtv/ivtvdecoder.cpp | |
5774 | =================================================================== | |
5775 | --- mythtv/libs/libmythtv/ivtvdecoder.cpp (.../tags/release-0-19) (revision 10931) | |
5776 | +++ mythtv/libs/libmythtv/ivtvdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
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) | |
5788 | Index: mythtv/libs/libmythtv/dvbsignalmonitor.cpp | |
5789 | =================================================================== | |
5790 | --- mythtv/libs/libmythtv/dvbsignalmonitor.cpp (.../tags/release-0-19) (revision 10931) | |
5791 | +++ mythtv/libs/libmythtv/dvbsignalmonitor.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
5792 | @@ -100,6 +100,10 @@ | |
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 @@ | |
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 | ||
5814 | Index: mythtv/libs/libmythtv/tv_rec.cpp | |
5815 | =================================================================== | |
5816 | --- mythtv/libs/libmythtv/tv_rec.cpp (.../tags/release-0-19) (revision 10931) | |
5817 | +++ mythtv/libs/libmythtv/tv_rec.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
5818 | @@ -130,6 +130,11 @@ | |
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 | * | |
5904 | Index: mythtv/libs/libmythtv/videooutbase.h | |
5905 | =================================================================== | |
5906 | --- mythtv/libs/libmythtv/videooutbase.h (.../tags/release-0-19) (revision 10931) | |
5907 | +++ mythtv/libs/libmythtv/videooutbase.h (.../branches/release-0-19-fixes) (revision 10931) | |
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 | ||
5917 | Index: mythtv/libs/libmythtv/osdimagecache.cpp | |
5918 | =================================================================== | |
5919 | --- mythtv/libs/libmythtv/osdimagecache.cpp (.../tags/release-0-19) (revision 0) | |
5920 | +++ mythtv/libs/libmythtv/osdimagecache.cpp (.../branches/release-0-19-fixes) (revision 10931) | |
5921 | @@ -0,0 +1,296 @@ | |
5922 | +// -*- Mode: c++ -*- | |
5923 | +/** OSDImageCache | |
5924 |