chanid] = &$Channels[$key];
+ $channel_hash[$Channels[$key]->chanid] =& $Channels[$key];
// Reinitialize the programs array for this channel
$Channels[$key]->programs = array();
// Keep track of this channel id in case we're only grabbing info for certain channels - workound included to avoid blank chanid's
@@ -130,11 +132,13 @@
LEFT JOIN programrating USING (chanid, starttime)
LEFT JOIN oldrecorded
ON oldrecorded.recstatus IN (-3, 11)
- AND IF(oldrecorded.programid OR oldrecorded.seriesid,
+ AND IF(oldrecorded.programid AND oldrecorded.seriesid,
oldrecorded.programid = program.programid
AND oldrecorded.seriesid = program.seriesid,
- oldrecorded.title = program.title
- AND oldrecorded.subtitle = program.subtitle
+ oldrecorded.title AND oldrecorded.subtitle
+ AND oldrecorded.description
+ AND oldrecorded.title = program.title
+ AND oldrecorded.subtitle = program.subtitle
AND oldrecorded.description = program.description
)
LEFT JOIN channel ON program.chanid = channel.chanid
@@ -156,8 +160,12 @@
// The extra query, if there is one
if ($extra_query)
$query .= ' AND '.$extra_query;
- // Group, sort and query
+ // Group and sort
$query .= ' GROUP BY program.chanid, program.starttime ORDER BY program.starttime';
+ // Limit
+ if ($single_program)
+ $query .= ' LIMIT 1';
+ // Query
$sh = $db->query($query,
star_character, max_stars, max_stars);
// No results
@@ -188,12 +196,8 @@
// Cleanup
$sh->finish();
// If channel-specific information was requested, return an array of those programs, or just the first/only one
- if ($chanid) {
- if ($single_program)
- return $channel_hash[$chanid]->programs[0];
- else
- return $channel_hash[$chanid]->programs;
- }
+ if ($chanid && $single_program)
+ return $these_programs[0];
// Just in case, return an array of all programs found
return $these_programs;
}
@@ -272,18 +276,18 @@
$this->endtime = $data[12]; # show end-time
// Is this a previously-recorded program? Calculate the filesize
if (!empty($this->filename)) {
- $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low;
- }
- // Ah, a scheduled recording - let's load more information about it, to be parsed in below
- elseif ($this->chanid) {
- unset($this->filename);
- // Kludge to avoid redefining the object, which doesn't work in php5
- $tmp = @get_object_vars(load_one_program($this->starttime, $this->chanid));
- if (is_array($tmp) && count($tmp) > 0) {
- foreach ($tmp as $key => $value) {
- $this->$key = $value;
- }
+ if (function_exists('gmp_add')) {
+ // GMP functions should work better with 64 bit numbers.
+ $size = gmp_add($fs_low,
+ gmp_mul('4294967296',
+ gmp_add($fs_high, $fs_low < 0 ? '1' : '0'))
+ );
+ $this->filesize = gmp_strval($size);
}
+ else {
+ // This is inaccurate, but it's the best we can get without GMP.
+ $this->filesize = ($fs_high + ($fs_low < 0)) * 4294967296 + $fs_low;
+ }
}
// Load the remaining info we got from mythbackend
$this->title = $data[0]; # program name/title
@@ -291,14 +295,14 @@
$this->description = $data[2]; # episode description
$this->category = $data[3];
#$chanid = $data[4]; # Extracted a few lines earlier
- #$channum = $data[5];
- #$callsign = $data[6];
+ $this->channum = $data[5];
+ $this->callsign = $data[6];
$this->channame = $data[7];
#$pathname = $data[8]; # Extracted a few lines earlier
#$fs_high = $data[9]; # Extracted a few lines earlier
#$fs_low = $data[10]; # Extracted a few lines earlier
- #$starttime = $data[11]; # Extracted a few lines earlier
- #$endtime = $data[12]; # Extracted a few lines earlier
+ #$this->starttime = $data[11]; # Extracted a few lines earlier
+ #$this->endtime = $data[12]; # Extracted a few lines earlier
$this->hostname = $data[16];
#$this->sourceid = $data[17];
$this->cardid = $data[18];
@@ -320,9 +324,9 @@
$this->programid = $data[34];
$this->lastmodified = $data[35];
$this->recpriority = $data[36];
- #$this->airdate = $data[37];
- #$this->hasairdate = $data[38];
- $this->timestretch = $program_data[39];
+ $this->airdate = date('Y-m-d', $data[37]);
+ $this->hasairdate = $data[38];
+ $this->timestretch = $data[39];
$this->recpriority2 = $data[40];
// Assign the program flags
$this->has_commflag = ($progflags & 0x01) ? true : false; // FL_COMMFLAG = 0x01
@@ -363,8 +367,8 @@
$this->title_pronounce = $data['title_pronounce'];
$this->recstatus = $data['recstatus'];
- if ($program_data['tsdefault']) {
- $this->timestretch = $program_data['tsdefault'];
+ if ($data['tsdefault']) {
+ $this->timestretch = $data['tsdefault'];
} else {
$this->timestretch = 1.0;
}
@@ -387,12 +391,14 @@
// Now we really should scan the $Channel array and add a link to this program's channel
foreach (array_keys($Channels) as $key) {
if ($Channels[$key]->chanid == $this->chanid) {
- $this->channel = &$Channels[$key];
+ $this->channel =& $Channels[$key];
break;
}
}
+ // Not found
+ if (!$this->channel)
+ $this->channel =& load_one_channel($this->chanid);
}
-
// Calculate the duration
if ($this->recendts)
$this->length = $this->recendts - $this->recstartts;
Index: mythplugins/mythweb/includes/utils.php
===================================================================
--- mythplugins/mythweb/includes/utils.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/includes/utils.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -276,7 +276,7 @@
static $first_run=true;
if($first_run) {
$first_run=false;
- echo '';
+ echo '';
}
// Put our data into a string
if (is_array($data) || is_object($data))
Index: mythplugins/mythweb/includes/init.php
===================================================================
--- mythplugins/mythweb/includes/init.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/includes/init.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -16,28 +16,15 @@
*
/**/
-/**
- * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some
- * other lesser means. It contains most of the information required for
- * figuring out what functions the user wants to access.
- *
- * @global array $GLOBALS['Path']
- * @name $Path
-/**/
- global $Path;
- $Path = explode('/', preg_replace('/^\/+/', '', // Remove leading slashes
- preg_replace('/[\s]+/', ' ', // Convert extra whitespace
- // Grab the path info from various different places.
- array_key_exists('PATH_INFO', $_SERVER)
- && $_SERVER['PATH_INFO']
- ? $_SERVER['PATH_INFO']
- : (array_key_exists('PATH_INFO', $_ENV)
- && $_ENV['PATH_INFO']
- ? $_ENV['PATH_INFO']
- : $_GET['PATH_INFO']
- )
- ))
- );
+// mod_redirect can do some weird things when php is run in cgi mode
+ $keys = preg_grep('/^REDIRECT_/', array_keys($_SERVER));
+ if (!empty($keys)) {
+ foreach ($keys as $key) {
+ $key = substr($key, 9);
+ if (!array_key_exists($key, $_SERVER))
+ $_SERVER[$key] = $_SERVER["REDIRECT_$key"];
+ }
+ }
// Clean the document root variable and make sure it doesn't have a trailing slash
$_SERVER['DOCUMENT_ROOT'] = preg_replace('/\/+$/', '', $_SERVER['DOCUMENT_ROOT']);
@@ -94,6 +81,29 @@
exit;
}
+/**
+ * $Path is an array of PATH_INFO passed into the script via mod_rewrite or some
+ * other lesser means. It contains most of the information required for
+ * figuring out what functions the user wants to access.
+ *
+ * @global array $GLOBALS['Path']
+ * @name $Path
+/**/
+ global $Path;
+ $Path = explode('/', preg_replace('/^\/+/', '', // Remove leading slashes
+ preg_replace('/[\s]+/', ' ', // Convert extra whitespace
+ // Grab the path info from various different places.
+ array_key_exists('PATH_INFO', $_SERVER)
+ && $_SERVER['PATH_INFO']
+ ? $_SERVER['PATH_INFO']
+ : (array_key_exists('PATH_INFO', $_ENV)
+ && $_ENV['PATH_INFO']
+ ? $_ENV['PATH_INFO']
+ : $_GET['PATH_INFO']
+ )
+ ))
+ );
+
// Load the database connection routines
require_once 'includes/db.php';
Index: mythplugins/mythweb/includes/mobile.php
===================================================================
--- mythplugins/mythweb/includes/mobile.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/includes/mobile.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -74,58 +74,56 @@
* If you don't know the screensize of some mobile terminal then use
* an empty array or approximate dimensions.
*/
- $mobiles = array(/* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */
- 'Series 60' => array('width' => 176, 'height' => 208),
- 'Series60' => array('width' => 176, 'height' => 208),
- 'C500' => array('width'=>176, 'height'=> 220), // SPV C500
+ $mobiles = array(
+ /* Phones using the Series 60 platform, e.g. Nokia 3650 and 6600. */
+ 'Series 60' => array('width' => 176, 'height' => 208),
+ 'Series60' => array('width' => 176, 'height' => 208),
+ 'C500' => array('width'=>176, 'height'=> 220), // SPV C500
+ /* Phones using the Series 90 platform, e.g. Nokia 7710. */
+ 'Series 90' => array('width' => 640, 'height' => 320),
+ 'Series90' => array('width' => 640, 'height' => 320),
+ /* The following strings are added for the Palm browser WebPro
+ * WebPro sometimes supplies the screen dimensions, but sometimes not
+ * but we try to detect the best as possible */
+ '240x320' => array('width' => 240, 'height' => 320), // PocketPC IE
+ '320x320' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
+ '320x480' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
+ '480x320' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
+ '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
+ '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
+ '320x320x16' => array('width' => 320, 'height' => 320),
+ 'WebPro' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
+ /* A generic mobile phone using Symbian OS. All Symbian phones don't
+ * necessarily have the same screen size so if you want to include
+ * some specific Symbian phones then place them above this line. */
+ 'Symbian' => array('width' => 176, 'height' => 208),
- /* Phones using the Series 90 platform, e.g. Nokia 7710. */
- 'Series 90' => array('width' => 640, 'height' => 320),
- 'Series90' => array('width' => 640, 'height' => 320),
+ 'Nokia' => array(), // Nokia phones and emulators
+ 'Eric' => array(), // Ericsson WAP phones and emulators
+ 'WapI' => array(), // Ericsson WapIDE 2.0
+ 'MC21' => array(), // Ericsson MC218
+ 'AUR ' => array(), // Ericsson R320
+ 'R380' => array(), // Ericsson R380
+ 'UP.B' => array(), // UP.Browser
+ 'WinW' => array(), // WinWAP browser
+ 'UPG1' => array(), // UP.SDK 4.0
+ 'upsi' => array(), // another kind of UP.Browser ??
+ 'QWAP' => array(), // unknown QWAPPER browser
+ 'Jigs' => array(), // unknown JigSaw browser
+ 'Java' => array(), // unknown Java based browser
+ 'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?)
+ 'MITS' => array(), // unknown Mitsubishi browser
+ 'MOT-' => array(), // unknown browser (UP based?)
+ 'My S' => array(), // unknown Ericsson devkit browser ?
+ 'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de
+ 'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de
+ 'ALAV' => array(), // yet another unknown UP based browser ?
+ 'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?)
+ 'LGE-' => array(), // LG phones
- /* The following strings are added for the Palm browser WebPro
- * WebPro sometimes supplies the screen dimensions, but sometimes not
- * but we try to detect the best as possible
- */
- '320x480' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
- '480x320' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
- '320x320' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
- '320x480x16' => array('width' => 320, 'height' => 480), // For Palm Tungsten T
- '480x320x16' => array('width' => 480, 'height' => 320), // For Palm Tungsten T
- '320x320x16' => array('width' => 320, 'height' => 320),
- 'WebPro' => array('width' => 320, 'height' => 320), // For all Palm Tungsten models
-
- /* A generic mobile phone using Symbian OS. All Symbian phones don't
- * necessarily have the same screen size so if you want to include
- * some specific Symbian phones then place them above this line. */
- 'Symbian' => array('width' => 176, 'height' => 208),
-
- 'Nokia' => array(), // Nokia phones and emulators
- 'Eric' => array(), // Ericsson WAP phones and emulators
- 'WapI' => array(), // Ericsson WapIDE 2.0
- 'MC21' => array(), // Ericsson MC218
- 'AUR ' => array(), // Ericsson R320
- 'R380' => array(), // Ericsson R380
- 'UP.B' => array(), // UP.Browser
- 'WinW' => array(), // WinWAP browser
- 'UPG1' => array(), // UP.SDK 4.0
- 'upsi' => array(), // another kind of UP.Browser ??
- 'QWAP' => array(), // unknown QWAPPER browser
- 'Jigs' => array(), // unknown JigSaw browser
- 'Java' => array(), // unknown Java based browser
- 'Alca' => array(), // unknown Alcatel-BE3 browser (UP based?)
- 'MITS' => array(), // unknown Mitsubishi browser
- 'MOT-' => array(), // unknown browser (UP based?)
- 'My S' => array(), // unknown Ericsson devkit browser ?
- 'WAPJ' => array(), // Virtual WAPJAG www.wapjag.de
- 'fetc' => array(), // fetchpage.cgi Perl script from www.wapcab.de
- 'ALAV' => array(), // yet another unknown UP based browser ?
- 'Wapa' => array(), // another unknown browser (Web based "Wapalyzer"?)
- 'LGE-' => array(), // LG phones
-
- /* For debugging: you can try out the mobile mode without a mobile phone.
- * Replace 'Opera' with your browser. Comment out for release version. */
- //'Opera' => array('width' => 176, 'height' => 208)
+ /* For debugging: you can try out the mobile mode without a mobile phone.
+ * Replace 'Opera' with your browser. Comment out for release version. */
+ //'Opera' => array('width' => 176, 'height' => 208)
);
/* Scan through $mobiles and try to find matching user agent. */
Index: mythplugins/mythweb/includes/recording_schedules.php
===================================================================
--- mythplugins/mythweb/includes/recording_schedules.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/includes/recording_schedules.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -68,10 +68,14 @@
// Cleanup
mysql_free_result($result);
+// Initialize
+ global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
+ $Scheduled_Recordings = array();
+ $Num_Conflicts = 0;
+ $Num_Scheduled = 0;
+
// Load all of the scheduled recordings. We will need them at some point, so we
// might as well get it overwith here.
- global $Scheduled_Recordings, $Num_Conflicts, $Num_Scheduled;
- $Scheduled_Recordings = array();
foreach (get_backend_rows('QUERY_GETALLPENDING', 2) as $key => $program) {
// The offset entry
if ($key === 'offset') {
Index: mythplugins/mythweb/includes/session.php
===================================================================
--- mythplugins/mythweb/includes/session.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/includes/session.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -19,8 +19,8 @@
// Start the session
session_name('mythweb_id');
- session_set_cookie_params(60 * 60 * 30, '/'); // 30 day timeout on cookies
- ini_set('session.gc_maxlifetime', 60 * 60 * 30); // ... and sessions
+ session_set_cookie_params(60 * 60 * 24 * 365, '/'); // 1 year timeout on cookies
+ ini_set('session.gc_maxlifetime', 60 * 60 * 24 * 30); // 30 day timeout on sessions
session_set_save_handler('sess_do_nothing', 'sess_do_nothing', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc');
session_start();
Index: mythplugins/mythweb/modules/weather/handler.php
===================================================================
--- mythplugins/mythweb/modules/weather/handler.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/modules/weather/handler.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -222,8 +222,10 @@
$data = explode("|", $data);
for($i = 0;$i<5;$i++) {
- $forecast = new Forecast($data[5 + $i],$data[$i]);
- $forecast->dayofweek = $data[$i];
+ # mktime uses 0-6; msnbc gives us 1-7; adjust msnbc to match mktime
+ $dayofweek = $data[$i] - 1;
+ $forecast = new Forecast($data[5 + $i],$dayofweek);
+ $forecast->dayofweek = $dayofweek;
list($forecast->DescImage,$forecast->DescText) = getImageAndDescFromId($data[15 + $i]);
$forecast->DescImage = (strlen($forecast->DescImage) > 0) ? $forecast->DescImage : "unknown.png";
$forecast->DescText = (strlen($forecast->DescText) > 0) ? $forecast->DescText : t('Unknown') . " (" . $data[15+$i] . ")";
Index: mythplugins/mythweb/modules/status/handler.php
===================================================================
--- mythplugins/mythweb/modules/status/handler.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/modules/status/handler.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -18,14 +18,17 @@
$masterhost = get_backend_setting('MasterServerIP');
$statusport = get_backend_setting('BackendStatusPort');
+// XML mode?
+ $xml_param = ($Path[1] == 'xml') ? '/xml' : '';
+
// Make sure the content is interpreted as UTF-8
header('Content-Type: text/html; charset=UTF-8');
// Load the status page
if (function_exists('file_get_contents'))
- $status = file_get_contents("http://$masterhost:$statusport");
+ $status = file_get_contents("http://$masterhost:$statusport$xml_param");
else
- $status = implode("\n", file("http://$masterhost:$statusport"));
+ $status = implode("\n", file("http://$masterhost:$statusport$xml_param"));
// Extract the page title
preg_match('#
(.+?)#s', $status, $title);
Index: mythplugins/mythweb/modules/backend_log/handler.php
===================================================================
--- mythplugins/mythweb/modules/backend_log/handler.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/modules/backend_log/handler.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -16,7 +16,7 @@
// Where to start searching from
$_GET['start'] = intVal($_GET['start']);
if ($_GET['start'] < 1)
- $_GET['start'] = 1;
+ $_GET['start'] = 0;
// How many entries to show?
$_GET['show'] = intVal($_GET['show']);
Index: mythplugins/mythweb/modules/tv/upcoming.php
===================================================================
--- mythplugins/mythweb/modules/tv/upcoming.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/modules/tv/upcoming.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -103,8 +103,9 @@
continue;
}
// Skip deactivated shows?
- elseif (!$_SESSION['scheduled_recordings']['disp_deactivated']) {
- continue;
+ elseif ($show->recstatus != 'Recording') {
+ if (!$_SESSION['scheduled_recordings']['disp_deactivated'])
+ continue;
}
// Assign a reference to this show to the various arrays
$all_shows[] =& $Scheduled_Recordings[$channum][$starttime][$key];
Index: mythplugins/mythweb/modules/tv/recorded.php
===================================================================
--- mythplugins/mythweb/modules/tv/recorded.php (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/modules/tv/recorded.php (.../branches/release-0-19-fixes) (revision 10931)
@@ -128,9 +128,21 @@
continue;
// Get the length (27 == recendts; 26 == recstartts)
$length = $record[27] - $record[26];
- // Keep track of the total time and disk space used
+ // Keep track of the total time and disk space used (9 == fs_high; 10 == fs_low)
$Total_Time += $length;
- $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10]; // 9 == fs_high; 10 == fs_low;
+ if (function_exists('gmp_add')) {
+ // GMP functions should work better with 64 bit numbers.
+ $size = gmp_add($record[10],
+ gmp_mul('4294967296',
+ gmp_add($record[9], $record[10] < 0 ? '1' : '0')
+ )
+ );
+ $Total_Used = gmp_strval(gmp_add($Total_Used, $size));
+ }
+ else {
+ // This is inaccurate, but it's the best we can get without GMP.
+ $Total_Used += ($record[9] + ($record[10] < 0)) * 4294967296 + $record[10];
+ }
// keep track of their names and how many episodes we have recorded
$Total_Programs++;
$Groups[$record[30]]++;
@@ -223,8 +235,28 @@
// How much free disk space on the backend machine?
list($size_high, $size_low, $used_high, $used_low) = explode(backend_sep, backend_command('QUERY_FREE_SPACE'));
- define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024);
- define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024);
+ if (function_exists('gmp_add')) {
+ // GMP functions should work better with 64 bit numbers.
+ $size = gmp_mul('1024',
+ gmp_add($size_low,
+ gmp_mul('4294967296',
+ gmp_add($size_high, $size_low < 0 ? '1' : '0'))
+ )
+ );
+ define(disk_size, gmp_strval($size));
+ $size = gmp_mul('1024',
+ gmp_add($used_low,
+ gmp_mul('4294967296',
+ gmp_add($used_high, $used_low < 0 ? '1' : '0'))
+ )
+ );
+ define(disk_used, gmp_strval($size));
+ }
+ else {
+ // This is inaccurate, but it's the best we can get without GMP.
+ define(disk_size, (($size_high + ($size_low < 0)) * 4294967296 + $size_low) * 1024);
+ define(disk_used, (($used_high + ($used_low < 0)) * 4294967296 + $used_low) * 1024);
+ }
// Load the class for this page
require_once theme_dir.'tv/recorded.php';
Index: mythplugins/mythweb/.htaccess
===================================================================
--- mythplugins/mythweb/.htaccess (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/.htaccess (.../branches/release-0-19-fixes) (revision 10931)
@@ -22,6 +22,7 @@
# AuthName "MythTV"
# AuthDigestFile /var/www/htdigest
# Require valid-user
+# BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On
# MythTV now uses the correct file suffix for mpeg files, so all .nuv files
# should actually be NuppleVideo. However, apache probably doesn't know what
@@ -66,8 +67,6 @@
php_value memory_limit 32M
- php_value session.save_path php_sessions
-
php_value output_buffering 4096
php_value register_globals 0
php_value magic_quotes_gpc 0
Index: mythplugins/mythweb/js/debug.js
===================================================================
--- mythplugins/mythweb/js/debug.js (.../tags/release-0-19) (revision 0)
+++ mythplugins/mythweb/js/debug.js (.../branches/release-0-19-fixes) (revision 10931)
@@ -0,0 +1,24 @@
+/**
+ * A random assortment of javascript debug routines
+ *
+ * @url $URL$
+ * @date $Date$
+ * @version $Revision$
+ * @author $Author$
+ * @copyright Silicon Mechanics
+ * @license LGPL
+ *
+ * @package SiMech
+ * @subpackage Javascript
+ *
+/**/
+
+ var debug_window_handle;
+// Create a debug window and debug into it
+ function debug_window(string) {
+ if (!debug_window_handle || debug_window_handle.closed) {
+ debug_window_handle = window.open('', 'Debug Window','scrollbars, resizable, width=400, height=600');
+ debug_window_handle.document.write('');
+ }
+ debug_window_handle.document.write('
'+string+'
');
+ }
Property changes on: mythplugins/mythweb/js/debug.js
___________________________________________________________________
Name: svn:eol-style
+ native
Name: svn:mime-type
+ text/x-javascript
Name: svn:keywords
+ Date Revision Author HeadURL
Index: mythplugins/mythweb/js/browser.js
===================================================================
--- mythplugins/mythweb/js/browser.js (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/js/browser.js (.../branches/release-0-19-fixes) (revision 10931)
@@ -215,14 +215,18 @@
browser.is_css = (document.body && document.body.style)
browser.is_w3c = (browser.is_css && browser.getElementById)
-// Cookie support
- var tmp = document.cookie;
- document.cookie = 'cookies=true';
- browser.cookies = (document.cookie) ? true : false;
- document.cookie = tmp;
+// Cookie support -- only create a cookie if there isn't one already. It seems
+// that doing this can override the exipiration info in existing cookies.
+ browser.cookies = (document.cookie) ? true : false;
+ if (!browser.cookies) {
+ var tmp = document.cookie;
+ document.cookie = 'cookie_test=true';
+ browser.cookies = (document.cookie) ? true : false;
+ document.cookie = tmp;
+ }
// Java support
- browser.java = navigator.javaEnabled();
+ browser.java = navigator.javaEnabled();
/****************************** Plugin Support ******************************/
Index: mythplugins/mythweb/README
===================================================================
--- mythplugins/mythweb/README (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweb/README (.../branches/release-0-19-fixes) (revision 10931)
@@ -1,18 +1,12 @@
This is the README file for the MythWeb package.
-January 17, 2006
+March 6, 2006
-Version: .19 pre
-(c) 2002-2006 Thor Sigvaldason
+Version: .19
+(c) 2002-2006 Chris Petersen
Isaac Richards
- Chris Petersen
+ Thor Sigvaldason
+ and others... (see mythtv.org commit logs for details)
-with contributions from many people including:
-
-Michael Kedl
-Jonathan Kolb
-Kenneth Aafloy
-
MythWeb is distributed under the GNU GENERAL PUBLIC LICENSE version 2, and where
noted with the @license tag, the LESSER GENERAL PUBLIC LICENSE version 2.
Please see http://www.gnu.org for details and the specific text of the license.
@@ -63,10 +57,22 @@
In order for the included .htaccess to work properly, you will need to
set apache's "AllowOverride" setting to "All" (or at least "Options") for
-the root mythweb directory. This directive lives within tags,
-so make sure you're changing the setting for the correct directory. You will
-also need to make sure that the following apache modules are enabled:
+the root mythweb directory. This directive lives within tags,
+so make sure you're changing the setting for the correct directory. Please
+keep in mind that most distros correctly disable everything for ,
+and then later override those with something like .
+The simplest way to do this is to put a file into /etc/httpd/conf.d (or
+whatever your distro calls it) containing something like:
+
+ Options FollowSymLinks
+ AllowOverride All
+
+
+Just make sure that the path points to your MythWeb installation, since that
+will likely differ from system to system. You will also need to make sure that
+the following apache modules are enabled:
+
mod_env
mod_rewrite
Index: mythplugins/mythdvd/mtd/jobthread.cpp
===================================================================
--- mythplugins/mythdvd/mtd/jobthread.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythdvd/mtd/jobthread.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
using namespace std;
Index: mythplugins/mythdvd/mtd/mtd.cpp
===================================================================
--- mythplugins/mythdvd/mtd/mtd.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythdvd/mtd/mtd.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -8,6 +8,7 @@
*/
+#include
#include
#include
#include
Index: mythplugins/mythdvd/mtd/logging.cpp
===================================================================
--- mythplugins/mythdvd/mtd/logging.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythdvd/mtd/logging.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -9,6 +9,7 @@
*/
#include "logging.h"
+#include
#include
#include
Index: mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp
===================================================================
--- mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -12,6 +12,7 @@
#include "metadata.h"
#include "metaiooggvorbiscomment.h"
+#include
#include
// static functions for OggVorbis
@@ -240,8 +241,13 @@
seekTime = -1.0;
}
+#ifdef WORDS_BIGENDIAN
+ len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 1, 2, 1,
+ §ion);
+#else
len = ov_read(&oggfile, (char *) (output_buf + output_at), bks, 0, 2, 1,
§ion);
+#endif
if (len > 0) {
bitrate = ov_bitrate_instant(&oggfile) / 1000;
Index: mythplugins/mythmusic/mythmusic/flacdecoder.cpp
===================================================================
--- mythplugins/mythmusic/mythmusic/flacdecoder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythmusic/mythmusic/flacdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -12,6 +12,7 @@
#include "metadata.h"
#include "metaioflacvorbiscomment.h"
+#include
#include
#include
@@ -102,7 +103,11 @@
for (channel = 0; channel < chan; channel++)
{
sample = (FLAC__int8)buffer[channel][cursamp];
+#ifdef WORDS_BIGENDIAN
+ *(output_buf + output_at++) = ((sample >> 8) & 0xff);
+#else
*(output_buf + output_at++) = ((sample >> 0) & 0xff);
+#endif
output_bytes += 1;
}
}
@@ -114,8 +119,13 @@
for (channel = 0; channel < chan; channel++)
{
sample = (FLAC__int16)buffer[channel][cursamp];
+#ifdef WORDS_BIGENDIAN
+ *(output_buf + output_at++) = ((sample >> 8) & 0xff);
*(output_buf + output_at++) = ((sample >> 0) & 0xff);
+#else
+ *(output_buf + output_at++) = ((sample >> 0) & 0xff);
*(output_buf + output_at++) = ((sample >> 8) & 0xff);
+#endif
output_bytes += 2;
}
}
Index: mythplugins/mythmusic/mythmusic/maddecoder.cpp
===================================================================
--- mythplugins/mythmusic/mythmusic/maddecoder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythmusic/mythmusic/maddecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -16,6 +16,7 @@
#include
#include "metaioid3v2.h"
+#include
#include
#define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
@@ -407,7 +408,7 @@
flush(TRUE);
if (output()) {
- output()->Drain();
+ output()->Drain();
}
done = TRUE;
@@ -488,15 +489,25 @@
flush();
}
sample = fix_sample(16, *left++);
+#ifdef WORDS_BIGENDIAN
+ *(output_buf + output_at++) = ((sample >> 8) & 0xff);
*(output_buf + output_at++) = ((sample >> 0) & 0xff);
+#else
+ *(output_buf + output_at++) = ((sample >> 0) & 0xff);
*(output_buf + output_at++) = ((sample >> 8) & 0xff);
+#endif
output_bytes += 2;
if (channels == 2)
{
sample = fix_sample(16, *right++);
+#ifdef WORDS_BIGENDIAN
+ *(output_buf + output_at++) = ((sample >> 8) & 0xff);
*(output_buf + output_at++) = ((sample >> 0) & 0xff);
+#else
+ *(output_buf + output_at++) = ((sample >> 0) & 0xff);
*(output_buf + output_at++) = ((sample >> 8) & 0xff);
+#endif
output_bytes += 2;
}
}
Index: mythplugins/mythweather/mythweather/weather.cpp
===================================================================
--- mythplugins/mythweather/mythweather/weather.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythweather/mythweather/weather.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -2571,6 +2571,14 @@
return false;
}
+ int imageCount = 5;
+ QString imagesList = parseData(tempData, "imagenames = new Array( '", ";");
+ if (imagesList != "")
+ {
+ QStringList imageURLs = QStringList::split(",", imagesList);
+ imageCount = imageURLs.size();
+ }
+
QString fileprefix = MythContext::GetConfDir();
QDir dir(fileprefix);
@@ -2587,13 +2595,13 @@
cerr << "MythWeather: Map File Prefix: " << fileprefix << endl;
// delete existing radar maps
- for (int x = 1; x <= 6; x++)
+ for (int x = 1; x <= 10; x++)
QFile::remove(QString(fileprefix + "/radar%1.jpg").arg(x));
if (debug)
cerr << "MythWeather: Copying Map Files from Server (" << imageLoc << ")...\n";
- for (int x = 1; x <= 6; x++)
+ for (int x = 1; x <= imageCount; x++)
{
QString sFile = QString(fileprefix + "/radar%1.jpg").arg(x);
sURL = QString("http://image.weather.com" + imageLoc + "%1L.jpg").arg(x);
Index: mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp
===================================================================
--- mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythcontrols/mythcontrols/mythcontrols.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -46,22 +46,6 @@
#include "keygrabber.h"
-static QMap FindContexts(const QString &context)
-{
- QMap retval;
- retval.clear();
- if (context != JUMP_CONTEXT) retval[-1] = JUMP_CONTEXT;
- retval[0] = context;
- if (context != JUMP_CONTEXT && context != GLOBAL_CONTEXT)
- {
- if (context == "TV Editting")
- retval[1] = "TV Playback";
- retval[2] = GLOBAL_CONTEXT;
- if (context != "qt")
- retval[3] = "qt";
- }
- return retval;
-}
static const QString KeyToDisplay(const QString key)
{
@@ -838,7 +822,11 @@
refreshKeyInformation();
}
-void MythControls::addBindings(QDict &bindings, const QString &context, const QString &contextParent, int bindlevel)
+
+
+void MythControls::addBindings(QDict &bindings,
+ const QString &context,
+ const QString &contextParent, int bindlevel)
{
QStringList *actions = key_bindings->getActions(context);
@@ -872,18 +860,13 @@
BindingList *MythControls::getKeyBindings(const QString &context)
{
+ QStringList keys;
QDict bindings;
bindings.clear();
- QMap contextList = FindContexts(context);
- for (QMap::iterator it = contextList.begin(); it != contextList.end(); ++it)
- {
- int level = it.key();
- QString curcontext = it.data();
- addBindings(bindings, curcontext, context, level);
- }
+ for (size_t i = 0; i < contexts.size(); i++)
+ addBindings(bindings, contexts[i], context, i);
- QStringList keys;
for (QDictIterator it(bindings); it.current(); ++it)
{
Index: mythplugins/mythcontrols/mythcontrols/actionset.cpp
===================================================================
--- mythplugins/mythcontrols/mythcontrols/actionset.cpp (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythcontrols/mythcontrols/actionset.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -139,13 +139,19 @@
/* method description in header */
QStringList * ActionSet::actionStrings(const QString &context_name) const
{
- QStringList *action_strings = new QStringList();
- QDictIterator it(*(_contexts[context_name]));
+ Context *c = _contexts[context_name];
- for (; it.current(); ++it)
- action_strings->append(it.currentKey());
+ if (c == NULL) return NULL;
+ else
+ {
+ QStringList *action_strings = new QStringList();
+ QDictIterator it(*(_contexts[context_name]));
+
+ for (; it.current(); ++it)
+ action_strings->append(it.currentKey());
- return action_strings;
+ return action_strings;
+ }
}
Index: mythplugins/mythcontrols/mythcontrols/keybindings.h
===================================================================
--- mythplugins/mythcontrols/mythcontrols/keybindings.h (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythcontrols/mythcontrols/keybindings.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -65,6 +65,8 @@
/**
* @brief Get a list of the context names.
* @return A list of the context names.
+ * @note The returned list is a copy and can be modified without
+ * side-effects.
*/
inline QStringList * getContexts() const
{
Index: mythplugins/mythvideo/mythvideo/videomanager.h
===================================================================
--- mythplugins/mythvideo/mythvideo/videomanager.h (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythvideo/mythvideo/videomanager.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -30,7 +30,7 @@
public:
VideoManager(MythMainWindow *parent, const char *name = 0);
~VideoManager(void);
- void VideoManager::processEvents() { qApp->processEvents(); }
+ void processEvents() { qApp->processEvents(); }
public slots:
void slotManualIMDB();
Index: mythplugins/mythvideo/mythvideo/videoselected.h
===================================================================
--- mythplugins/mythvideo/mythvideo/videoselected.h (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythvideo/mythvideo/videoselected.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -35,7 +35,7 @@
VideoSelected(VideoList *lvideolist,
MythMainWindow *parent, const char *name = 0, int index = 0);
~VideoSelected();
- void VideoSelected::processEvents() { qApp->processEvents(); }
+ void processEvents() { qApp->processEvents(); }
protected slots:
Index: mythplugins/mythphone/mythphone/sipfsm.h
===================================================================
--- mythplugins/mythphone/mythphone/sipfsm.h (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythphone/mythphone/sipfsm.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -618,7 +618,7 @@
SipWatcher *CreateWatcherFsm(QString Url);
SipIM *CreateIMFsm(QString Url="", QString callIdStr="");
void StopWatchers();
- void SipFsm::KickWatcher(SipUrl *Url);
+ void KickWatcher(SipUrl *Url);
void SendIM(QString destUrl, QString CallId, QString imMsg);
int numCalls();
int getPrimaryCall() { return primaryCall; };
Index: mythplugins/mythphone/mythphone/vxml.h
===================================================================
--- mythplugins/mythphone/mythphone/vxml.h (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythphone/mythphone/vxml.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -10,7 +10,7 @@
{
public:
vxmlVariable(QString N, QString V);
- vxmlVariable::vxmlVariable(QString N, short *wav, int S);
+ vxmlVariable(QString N, short *wav, int S);
virtual ~vxmlVariable() {};
bool isType(QString t) { return (t == Type); };
QString getName() { return Name; };
Index: mythplugins/mythgame/mythgame/gamehandler.h
===================================================================
--- mythplugins/mythgame/mythgame/gamehandler.h (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythgame/mythgame/gamehandler.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -106,7 +106,7 @@
protected:
static GameHandler* GetHandler(RomInfo *rominfo);
- static GameHandler* GameHandler::GetHandlerByName(QString systemname);
+ static GameHandler* GetHandlerByName(QString systemname);
bool rebuild;
int spandisks;
Index: mythplugins/mythnews/mythnews/news-sites.xml
===================================================================
--- mythplugins/mythnews/mythnews/news-sites.xml (.../tags/release-0-19) (revision 10931)
+++ mythplugins/mythnews/mythnews/news-sites.xml (.../branches/release-0-19-fixes) (revision 10931)
@@ -119,7 +119,7 @@
-
Slashdot
- http://slashdot.org/slashdot.rss
+ http://rss.slashdot.org/Slashdot/slashdot
http://slashdot.org/favicon.ico
Index: mythtv/libs/libmythtv/dvbchannel.h
===================================================================
--- mythtv/libs/libmythtv/dvbchannel.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/dvbchannel.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -60,11 +60,13 @@
{ return chan_opts.pmt.HasTelevisionService(); }
/// Returns true iff we have a faulty DVB driver that munges PMT
bool HasCRCBug(void) const { return has_crc_bug; }
+ uint GetMinSignalMonitorDelay(void) const { return sigmon_delay; }
// Commands
bool SwitchToInput(const QString &inputname, const QString &chan);
bool SwitchToInput(int newcapchannel, bool setstarting);
bool Tune(const dvb_channel_t& channel, bool force_reset=false);
+ bool Retune(void);
// Set/Get/Command just for SIScan/ScanWizardScanner
void SetMultiplexID(int mplexid) { currentTID = mplexid; };
@@ -109,11 +111,18 @@
volatile int fd_frontend; ///< File descriptor for tuning hardware
int cardnum; ///< DVB Card number
bool has_crc_bug; ///< true iff our driver munges PMT
+ uint tuning_delay;///< Extra delay to add for broken drivers
+ uint sigmon_delay;///< Minimum delay between FE_LOCK checks
int currentTID; ///< Stores mplexid from database
bool first_tune; ///< Used to force hardware reset
int nextcapchannel; ///< Signal an input change
+
+ /// Last tuning options sent to hardware for retuning
+ DVBTuning retune_tuning;
+ /// Retuning adjustment, required so drivers don't ignore retune request
+ int retune_adj;
};
#endif
Index: mythtv/libs/libmythtv/NuppelVideoPlayer.h
===================================================================
--- mythtv/libs/libmythtv/NuppelVideoPlayer.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/NuppelVideoPlayer.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -150,7 +150,8 @@
// Complicated gets
long long CalcMaxFFTime(long long ff, bool setjump = true) const;
long long CalcRWTime(long long rw) const;
- void calcSliderPos(struct StatusPosInfo &posInfo);
+ void calcSliderPos(struct StatusPosInfo &posInfo,
+ bool paddedFields = false);
/// Non-const gets
OSD *GetOSD(void) { return osd; }
@@ -297,6 +298,7 @@
bool DecodeFrame(struct rtframeheader *frameheader,
unsigned char *strm, unsigned char *outbuf);
+ bool PrebufferEnoughFrames(void);
void CheckPrebuffering(void);
bool GetFrameNormal(int onlyvideo);
bool GetFrameFFREW(void);
@@ -309,7 +311,7 @@
bool DoRewind(void);
// Private seeking stuff
- void ClearAfterSeek(void);
+ void ClearAfterSeek(bool clearvideobuffers = true);
bool FrameIsInMap(long long frameNumber, QMap &breakMap);
void JumpToFrame(long long frame);
void JumpToNetFrame(long long net) { JumpToFrame(framesPlayed + net); }
@@ -543,6 +545,7 @@
QMap::Iterator deleteIter;
QMap::Iterator blankIter;
QMap::Iterator commBreakIter;
+ bool forcePositionMapSync;
// Playback (output) speed control
/// Lock for next_play_speed and next_normal_speed
Index: mythtv/libs/libmythtv/osdlistbtntype.h
===================================================================
--- mythtv/libs/libmythtv/osdlistbtntype.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/osdlistbtntype.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -1,3 +1,4 @@
+// -*- Mode: c++ -*-
/* ============================================================
* File : uilistbtntype.h
* Author: Renchi Raju
@@ -22,38 +23,57 @@
#ifndef OSDLISTBTNTYPE_H
#define OSDLISTBTNTYPE_H
-#include "osdtypes.h"
-#include "ttfont.h"
+#include
+using namespace std;
+
+// Qt headers
#include
#include
#include
#include
+#include
+
+// MythTV headers
+#include "osdtypes.h"
+#include "ttfont.h"
#include "generictree.h"
+class OSDListBtnType;
class OSDListBtnTypeItem;
-class OSDListBtnType;
+typedef vector OSDListBtnList;
+typedef vector OSDListBtnItemList;
class OSDGenericTree : public GenericTree
{
public:
// This class will _not_ delete the image it's given, if any.
- OSDGenericTree(OSDGenericTree *parent, const QString &name,
- const QString &action = "", int check = -1,
- OSDTypeImage *image = NULL, QString group = "");
+ OSDGenericTree(OSDGenericTree *parent, const QString &name,
+ const QString &action = "", int check = -1,
+ OSDTypeImage *image = NULL, QString group = "") :
+ GenericTree(name), m_image(image), m_action(action),
+ m_group(group), m_checkable(check), m_parentButton(NULL)
+ {
+ m_group = (m_group.isEmpty()) ? action : m_group;
+ setSelectable(!action.isEmpty());
+ if (parent)
+ parent->addNode(this);
+ }
- OSDTypeImage *getImage(void) { return m_image; }
- QString getAction(void) { return m_action; }
- int getCheckable(void) { return m_checkable; }
- QString getGroup(void) { return m_group; }
+ QString getAction(void) const { return m_action; }
+ QString getGroup(void) const { return m_group; }
+ int getCheckable(void) const { return m_checkable; }
+
+ OSDTypeImage *getImage(void) { return m_image; }
+ OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; }
+
void setParentButton(OSDListBtnTypeItem *button)
- { m_parentButton = button; };
- OSDListBtnTypeItem *getParentButton(void) { return m_parentButton; };
+ { m_parentButton = button; }
private:
- OSDTypeImage *m_image;
- QString m_action;
- int m_checkable;
- QString m_group;
+ OSDTypeImage *m_image;
+ QString m_action;
+ QString m_group;
+ int m_checkable;
OSDListBtnTypeItem *m_parentButton;
};
@@ -62,53 +82,49 @@
{
Q_OBJECT
public:
- OSDListTreeType(const QString &name, const QRect &area,
- const QRect &levelsize, int levelspacing,
- float wmult, float hmult);
+ OSDListTreeType(const QString &name, const QRect &area,
+ const QRect &levelsize, int levelspacing,
+ float wmult, float hmult);
+ ~OSDListTreeType();
- void Reinit(float wchange, float hchange, float wmult, float hmult);
+ bool IsVisible(void) const { return m_visible; }
+
+ void SetFontActive(TTFFont *font) { m_active = font; }
+ void SetFontInactive(TTFFont *font) { m_inactive = font; }
+
void SetGroupCheckState(QString group, int newState = 0);
+ void SetSpacing(uint spacing)
+ { m_unbiasedspacing = (m_spacing = spacing) / m_wmult; }
+ void SetMargin(uint margin)
+ { m_unbiasedmargin = (m_margin = margin) / m_wmult; }
+ void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha)
+ { m_itemRegBeg = beg; m_itemRegEnd = end; m_itemRegAlpha = alpha; }
+ void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha)
+ { m_itemSelBeg = beg; m_itemSelEnd = end; m_itemSelAlpha = alpha; }
+ void SetVisible(bool visible) { m_visible = visible; }
+ void SetAsTree(OSDGenericTree *toplevel, vector *select = NULL);
- void SetFontActive(TTFFont *font);
- void SetFontInactive(TTFFont *font);
- void SetSpacing(int spacing);
- void SetMargin(int margin);
- void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha);
- void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha);
-
- void SetAsTree(OSDGenericTree *toplevel);
-
- OSDGenericTree *GetCurrentPosition(void);
-
+ void Reinit(float wmult, float hmult);
bool HandleKeypress(QKeyEvent *e);
-
void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
- bool IsVisible(void) { return m_visible; }
- void SetVisible(bool visible) { m_visible = visible; }
-
signals:
void itemSelected(OSDListTreeType *parent, OSDGenericTree *item);
void itemEntered(OSDListTreeType *parent, OSDGenericTree *item);
private:
- void FillLevelFromTree(OSDGenericTree *item, OSDListBtnType *list);
- OSDListBtnType *GetLevel(int levelnum);
- void SetCurrentPosition(void);
+ void FillLevelFromTree(OSDGenericTree *item, uint levelnum);
+ OSDListBtnType *GetLevel(uint levelnum);
+ void EnterItem(void);
+ void SelectItem(void);
- int levels;
- int curlevel;
-
OSDGenericTree *treetop;
OSDGenericTree *currentpos;
+ TTFFont *m_active;
+ TTFFont *m_inactive;
- QPtrList listLevels;
+ OSDListBtnList listLevels;
- OSDListBtnType *currentlevel;
-
- TTFFont *m_active;
- TTFFont *m_inactive;
-
QColor m_itemRegBeg;
QColor m_itemRegEnd;
QColor m_itemSelBeg;
@@ -116,62 +132,76 @@
uint m_itemRegAlpha;
uint m_itemSelAlpha;
- int m_spacing;
- int m_margin;
+ uint m_spacing;
+ uint m_margin;
+ int m_levelspacing;
- QRect m_totalarea;
- QRect m_levelsize;
- int m_levelspacing;
+ QRect m_totalarea;
+ QRect m_levelsize;
- float m_wmult;
- float m_hmult;
+ float m_unbiasedspacing;
+ float m_unbiasedmargin;
+ QRect m_unbiasedarea;
+ QRect m_unbiasedsize;
- bool m_visible;
- bool m_arrowAccel;
+ float m_wmult;
+ float m_hmult;
+
+ int m_depth;
+ int m_levelnum;
+ bool m_visible;
+ bool m_arrowAccel;
};
class OSDListBtnType : public OSDType
{
+ friend class OSDListBtnTypeItem;
Q_OBJECT
+
public:
OSDListBtnType(const QString &name, const QRect& area,
float wmult, float hmult,
bool showScrollArrows = false);
~OSDListBtnType();
- void Reinit(float wchange, float hchange, float wmult, float hmult);
+ // General Gets
+ bool IsVisible() const { return m_visible; }
+
+ // General Sets
+ void SetFontActive(TTFFont *font) { m_fontActive = font; }
+ void SetFontInactive(TTFFont *font) { m_fontInactive = font; }
+ void SetSpacing(int spacing) { m_itemSpacing = spacing; }
+ void SetMargin(int margin) { m_itemMargin = margin; }
+ void SetActive(bool active) { m_active = active; }
+ void SetVisible(bool vis) { m_visible = vis; }
+ void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha)
+ { m_itemRegBeg = beg; m_itemRegEnd = end; m_itemRegAlpha = alpha; }
+ void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha)
+ { m_itemSelBeg = beg; m_itemSelEnd = end; m_itemSelAlpha = alpha; }
void SetGroupCheckState(QString group, int newState = 0);
+ void SetItemCurrent(const OSDListBtnTypeItem* item);
+ void SetItemCurrent(uint pos);
- void SetFontActive(TTFFont *font);
- void SetFontInactive(TTFFont *font);
- void SetSpacing(int spacing);
- void SetMargin(int margin);
- void SetItemRegColor(const QColor& beg, const QColor& end, uint alpha);
- void SetItemSelColor(const QColor& beg, const QColor& end, uint alpha);
-
- void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
-
- void SetActive(bool active);
- void Reset();
-
- void SetItemCurrent(OSDListBtnTypeItem* item);
- void SetItemCurrent(int pos);
- OSDListBtnTypeItem* GetItemCurrent();
- OSDListBtnTypeItem* GetItemFirst();
- OSDListBtnTypeItem* GetItemNext(OSDListBtnTypeItem *item);
+ // Item Gets
+ int GetCount(void) const;
+ int GetItemPos(const OSDListBtnTypeItem* item) const;
+ int GetItemCurrentPos() const;
+ OSDListBtnTypeItem* GetItemCurrent(void);
+ OSDListBtnTypeItem* GetItemFirst(void);
+ OSDListBtnTypeItem* GetItemNext(const OSDListBtnTypeItem *item);
OSDListBtnTypeItem* GetItemAt(int pos);
- int GetItemPos(OSDListBtnTypeItem* item);
- int GetCount();
- void MoveDown();
- void MoveUp();
+ // Item Sets/Commands
+ void MoveDown(void);
+ void MoveUp(void);
- bool IsVisible() { return m_visible; }
- void SetVisible(bool vis) { m_visible = vis; }
+ // General Commands
+ void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
+ void Reinit(float,float) {}
+ void Reset(void);
private:
-
- void Init();
+ void Init(void);
void InitItem(OSDTypeImage &osdImg, uint width, uint height,
QColor beg, QColor end, int alpha);
void LoadPixmap(OSDTypeImage& pix, const QString& fileName);
@@ -179,24 +209,35 @@
void InsertItem(OSDListBtnTypeItem *item);
void RemoveItem(OSDListBtnTypeItem *item);
- int m_order;
- QRect m_rect;
- QRect m_contentsRect;
- QRect m_arrowsRect;
+ private:
+ int m_order;
+ QRect m_rect;
+ QRect m_contentsRect;
+ QRect m_arrowsRect;
- float m_wmult;
- float m_hmult;
+ float m_wmult;
+ float m_hmult;
- int m_itemHeight;
- int m_itemSpacing;
- int m_itemMargin;
- uint m_itemsVisible;
+ int m_itemHeight;
+ int m_itemSpacing;
+ int m_itemMargin;
+ uint m_itemsVisible;
- bool m_active;
- bool m_showScrollArrows;
- bool m_showUpArrow;
- bool m_showDnArrow;
+ bool m_active;
+ bool m_showScrollArrows;
+ bool m_showUpArrow;
+ bool m_showDnArrow;
+ bool m_initialized;
+ bool m_clearing;
+ bool m_visible;
+ QColor m_itemRegBeg;
+ QColor m_itemRegEnd;
+ QColor m_itemSelBeg;
+ QColor m_itemSelEnd;
+ uint m_itemRegAlpha;
+ uint m_itemSelAlpha;
+
OSDTypeImage m_itemRegPix;
OSDTypeImage m_itemSelActPix;
OSDTypeImage m_itemSelInactPix;
@@ -209,43 +250,30 @@
OSDTypeImage m_checkHalfPix;
OSDTypeImage m_checkFullPix;
- QColor m_itemRegBeg;
- QColor m_itemRegEnd;
- QColor m_itemSelBeg;
- QColor m_itemSelEnd;
- uint m_itemRegAlpha;
- uint m_itemSelAlpha;
+ TTFFont *m_fontActive;
+ TTFFont *m_fontInactive;
- TTFFont* m_fontActive;
- TTFFont* m_fontInactive;
+ int m_topIndx;
+ int m_selIndx;
- bool m_initialized;
- bool m_clearing;
+ OSDListBtnItemList m_itemList;
- OSDListBtnTypeItem* m_topItem;
- OSDListBtnTypeItem* m_selItem;
- QPtrList m_itemList;
+ mutable QMutex m_update;
- QMutex m_update;
-
- bool m_visible;
-
- friend class OSDListBtnTypeItem;
-
signals:
-
void itemSelected(OSDListBtnTypeItem* item);
};
class OSDListBtnTypeItem
{
+ friend class OSDListBtnType;
public:
-
- enum CheckState {
- NotChecked=0,
+ enum CheckState
+ {
+ NotChecked = 0,
HalfChecked,
- FullChecked
+ FullChecked,
};
OSDListBtnTypeItem(OSDListBtnType* lbtype, const QString& text,
@@ -253,41 +281,36 @@
bool showArrow = false, CheckState state = NotChecked);
~OSDListBtnTypeItem();
- OSDListBtnType* parent() const;
- QString text() const;
- const OSDTypeImage* pixmap() const;
- bool checkable() const;
- CheckState state() const;
+ OSDListBtnType* parent(void) const { return m_parent; }
+ QString text(void) const { return m_text; }
+ const OSDTypeImage* pixmap(void) const { return m_pixmap; }
+ bool checkable(void) const { return m_checkable; }
+ CheckState state(void) const { return m_state; }
+ QString getGroup(void) const { return m_group; }
+ void *getData(void) { return m_data; }
- void setChecked(CheckState state);
- void setData(void *data);
- void* getData();
- void setGroup(QString group) { m_group = group; };
- QString getGroup(void) { return m_group; }
+ void setData(void *data) { m_data = data; }
+ void setGroup(QString grp) { m_group = grp; }
+ void setChecked(CheckState state)
+ { m_state = (m_checkable) ? state : m_state; }
- void Reinit(float wchange, float hchange, float wmult, float hmult);
-
+ void Reinit(float,float) {}
void paint(OSDSurface *surface, TTFFont *font, int fade, int maxfade,
int x, int y);
protected:
-
OSDListBtnType *m_parent;
- QString m_text;
- OSDTypeImage *m_pixmap;
- bool m_checkable;
- CheckState m_state;
- void *m_data;
- QString m_group;
-
- QRect m_checkRect;
- QRect m_pixmapRect;
- QRect m_textRect;
- QRect m_arrowRect;
-
- bool m_showArrow;
-
- friend class OSDListBtnType;
+ OSDTypeImage *m_pixmap;
+ void *m_data;
+ QString m_text;
+ QString m_group;
+ CheckState m_state;
+ bool m_showArrow;
+ bool m_checkable;
+ QRect m_checkRect;
+ QRect m_arrowRect;
+ QRect m_pixmapRect;
+ QRect m_textRect;
};
Index: mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- mythtv/libs/libmythtv/NuppelVideoPlayer.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/NuppelVideoPlayer.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -147,6 +147,7 @@
hascommbreaktable(false),
deleteIter(deleteMap.end()), blankIter(blankMap.end()),
commBreakIter(commBreakMap.end()),
+ forcePositionMapSync(false),
// Playback (output) speed control
decoder_lock(true),
next_play_speed(1.0f), next_normal_speed(true),
@@ -747,6 +748,8 @@
SetDecoder(new IvtvDecoder(this, m_playbackinfo));
no_audio_out = true; // no audio with ivtv.
audio_bits = 16;
+ audio_samplerate = 44100;
+ audio_channels = 2;
}
else if (forceVideoOutput == kVideoOutput_IVTV)
{
@@ -1113,7 +1116,7 @@
const unsigned char *NuppelVideoPlayer::GetScaledFrame(QSize &size)
{
QMutexLocker locker(&yuv_lock);
- yuv_desired_size = size = QSize(size.width() & ~0x3, size.height() & ~0x3);
+ yuv_desired_size = size = QSize(size.width() & ~0x7, size.height() & ~0x7);
if ((size.width() > 0) && (size.height() > 0))
{
@@ -1626,8 +1629,8 @@
{
// If we are using hardware decoding, so we've already done the
// decoding; display the frame, but don't wait for A/V Sync.
- videoOutput->PrepareFrame(buffer, ps);
- videoOutput->Show(m_scan);
+ videoOutput->PrepareFrame(buffer, kScan_Intr2ndField);
+ videoOutput->Show(kScan_Intr2ndField);
VERBOSE(VB_PLAYBACK, LOC + dbg + "skipping A/V wait.");
}
else
@@ -1685,14 +1688,14 @@
if (diverge > MAXDIVERGE)
{
- // If audio is way ahead of video, adjust for it...
+ // If audio is way behind of video, adjust for it...
// by cutting the frame rate in half for the length of this frame
avsync_adjustment = frame_interval;
lastsync = true;
VERBOSE(VB_PLAYBACK, LOC +
- QString("Audio is %1 frames ahead of video,\n"
- "\t\t\tdoubling video frame interval.").arg(diverge));
+ QString("Video is %1 frames ahead of audio,\n"
+ "\t\t\tdoubling video frame interval to slow down.").arg(diverge));
}
if (audioOutput && normal_speed)
@@ -1811,11 +1814,8 @@
videosync->Start();
}
-void NuppelVideoPlayer::DisplayNormalFrame(void)
+bool NuppelVideoPlayer::PrebufferEnoughFrames(void)
{
- video_actually_paused = false;
- resetvideo = false;
-
prebuffering_lock.lock();
if (prebuffering)
{
@@ -1843,14 +1843,29 @@
}
prebuffering_lock.unlock();
videosync->Start();
- return;
+
+ return false;
}
prebuffering_lock.unlock();
//VERBOSE(VB_PLAYBACK, LOC + "fs: " + videoOutput->GetFrameStatus());
if (!videoOutput->EnoughPrebufferedFrames())
{
- VERBOSE(VB_GENERAL, LOC + "prebuffering pause");
+ if (videoOutput)
+ {
+ videoOutput->CheckFrameStates();
+ if (videoOutput->hasMCAcceleration() ||
+ videoOutput->hasIDCTAcceleration() ||
+ videoOutput->hasVLDAcceleration())
+ {
+ // Prebuffering fails w/XvMC's 8 surfaces..
+ usleep(5000);
+ return false;
+ }
+ }
+ VERBOSE(VB_GENERAL, LOC + "prebuffering pause" +
+ videoOutput->GetFrameStatus());
+
SetPrebuffering(true);
#if FAST_RESTART
if (!m_playing_slower && audio_channels <= 2)
@@ -1861,7 +1876,7 @@
VERBOSE(VB_GENERAL, "playing slower due to falling behind...");
}
#endif
- return;
+ return false;
}
#if FAST_RESTART
@@ -1877,6 +1892,25 @@
prebuffer_tries = 0;
prebuffering_lock.unlock();
+ return true;
+}
+
+void NuppelVideoPlayer::DisplayNormalFrame(void)
+{
+ video_actually_paused = false;
+ resetvideo = false;
+
+ if (!PrebufferEnoughFrames())
+ {
+ // When going to switch channels
+ if (paused)
+ {
+ usleep(frame_interval);
+ DisplayPauseFrame();
+ }
+ return;
+ }
+
videoOutput->StartDisplayingFrame();
VideoFrame *frame = videoOutput->GetLastShownFrame();
@@ -1920,7 +1954,7 @@
ShowText();
DisplaySubtitles();
}
- else if (osdHasSubtitles || nonDisplayedSubtitles.size() > 20)
+ else if (osdHasSubtitles)
{
ClearSubtitles();
}
@@ -2176,7 +2210,10 @@
}
if (eof)
+ {
discontinuity = true;
+ ClearSubtitles();
+ }
livetvchain->SetProgram(pginfo);
@@ -2199,6 +2236,7 @@
}
if (IsErrored())
{
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "SwitchToProgram failed.");
eof = true;
return;
}
@@ -2265,6 +2303,8 @@
ringBuffer->Pause();
ringBuffer->WaitForPause();
+ ClearSubtitles();
+
livetvchain->SetProgram(pginfo);
ringBuffer->Reset(true);
@@ -2284,6 +2324,7 @@
if (errored || !GetDecoder())
{
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "JumpToProgram failed.");
errored = true;
return;
}
@@ -2471,6 +2512,12 @@
JumpToProgram();
}
+ if (forcePositionMapSync)
+ {
+ forcePositionMapSync = false;
+ GetDecoder()->SyncPositionMap();
+ }
+
if (IsErrored() || (nvr_enc && nvr_enc->GetErrorStatus()))
{
VERBOSE(VB_IMPORTANT, LOC_ERR + "Unknown error, exiting decoder");
@@ -3246,7 +3293,10 @@
GetDecoder()->DoFastForward(desiredFrame);
GetDecoder()->setExactSeeks(exactseeks);
- ClearAfterSeek();
+ // Note: The video output will be reset by what the the decoder
+ // does, so we only need to reset the audio, subtitles, etc.
+ ClearAfterSeek(false);
+
lastSkipTime = time(NULL);
return true;
}
@@ -3291,19 +3341,24 @@
}
#endif
-/** \fn NuppelVideoPlayer::ClearAfterSeek(void)
+/** \fn NuppelVideoPlayer::ClearAfterSeek(bool)
* \brief This is to support seeking...
*
* This resets the output classes and discards all
* frames no longer being used by the decoder class.
*
* Note: caller should not hold any locks
+ *
+ * \param clearvideobuffers This clears the videooutput buffers as well,
+ * this is only safe if no old frames are
+ * required to continue decoding.
*/
-void NuppelVideoPlayer::ClearAfterSeek(void)
+void NuppelVideoPlayer::ClearAfterSeek(bool clearvideobuffers)
{
- VERBOSE(VB_PLAYBACK, LOC + "ClearAfterSeek()");
+ VERBOSE(VB_PLAYBACK, LOC + "ClearAfterSeek("<ClearAfterSeek();
+ if (clearvideobuffers)
+ videoOutput->ClearAfterSeek();
for (int i = 0; i < MAXTBUFFER; i++)
txtbuffers[i].timecode = 0;
@@ -4398,6 +4453,8 @@
hascommbreaktable = !commBreakMap.isEmpty();
SetCommBreakIter();
commBreakMapLock.unlock();
+
+ forcePositionMapSync = true;
}
bool NuppelVideoPlayer::RebuildSeekTable(bool showPercentage, StatusCallback cb, void* cbData)
@@ -4541,7 +4598,8 @@
return (int)((float)(written - played) / video_frame_rate);
}
-void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo)
+void NuppelVideoPlayer::calcSliderPos(struct StatusPosInfo &posInfo,
+ bool paddedFields)
{
posInfo.desc = "";
posInfo.position = 0;
@@ -4588,15 +4646,23 @@
int ssecs = (playbackLen - shours * 3600 - smins * 60);
QString text1, text2;
- if (shours > 0)
+ if (paddedFields)
{
- text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
- text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
+ text1.sprintf("%02d:%02d:%02d", phours, pmins, psecs);
+ text2.sprintf("%02d:%02d:%02d", shours, smins, ssecs);
}
else
{
- text1.sprintf("%d:%02d", pmins, psecs);
- text2.sprintf("%d:%02d", smins, ssecs);
+ if (shours > 0)
+ {
+ text1.sprintf("%d:%02d:%02d", phours, pmins, psecs);
+ text2.sprintf("%d:%02d:%02d", shours, smins, ssecs);
+ }
+ else
+ {
+ text1.sprintf("%d:%02d", pmins, psecs);
+ text2.sprintf("%d:%02d", smins, ssecs);
+ }
}
posInfo.desc = QObject::tr("%1 of %2").arg(text1).arg(text2);
@@ -4654,6 +4720,7 @@
if (commBreakIter.key() == totalFrames)
{
+ VERBOSE(VB_IMPORTANT, LOC + "Skipping commercial to end of file");
eof = true;
}
else
@@ -4721,7 +4788,7 @@
QString message = "COMMFLAG_REQUEST ";
message += m_playbackinfo->chanid + " " +
- m_playbackinfo->startts.toString(Qt::ISODate);
+ m_playbackinfo->recstartts.toString(Qt::ISODate);
RemoteSendMessage(message);
return false;
@@ -5018,7 +5085,7 @@
QImage scaledImage = qImage.smoothScale(rect->w, rect->h);
OSDTypeImage* image = new OSDTypeImage();
- image->SetPosition(QPoint(rect->x, rect->y));
+ image->SetPosition(QPoint(rect->x, rect->y), hmult, vmult);
image->LoadFromQImage(scaledImage);
subtitleOSD->AddType(image);
Index: mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
===================================================================
--- mythtv/libs/libmythtv/NuppelVideoRecorder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/NuppelVideoRecorder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -216,7 +216,10 @@
}
if (mpa_codec)
+ {
+ QMutexLocker locker(&avcodeclock);
avcodec_close(mpa_ctx);
+ }
if (mpa_ctx)
av_free(mpa_ctx);
@@ -453,8 +456,11 @@
useavcodec = true;
if (mpa_codec)
+ {
+ QMutexLocker locker(&avcodeclock);
avcodec_close(mpa_ctx);
-
+ }
+
if (mpa_ctx)
av_free(mpa_ctx);
mpa_ctx = NULL;
@@ -626,13 +632,14 @@
int frag, blocksize = 4096;
int tmp;
+ if (!skipdevice)
+ {
#if !defined (HAVE_SYS_SOUNDCARD_H) && !defined(HAVE_SOUNDCARD_H)
- VERBOSE(VB_IMPORTANT, QString("NVR::AudioInit() This Unix doesn't support"
- " device files for audio access. Skipping"));
- return 1;
+ VERBOSE(VB_IMPORTANT,
+ QString("NVR::AudioInit() This Unix doesn't support"
+ " device files for audio access. Skipping"));
+ return 1;
#else
- if (!skipdevice)
- {
if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY | O_NONBLOCK)))
{
VERBOSE(VB_IMPORTANT, QString("NVR: Error, cannot open DSP '%1'").
@@ -678,8 +685,8 @@
}
close(afd);
+#endif
}
-#endif
audio_bytes_per_sample = audio_channels * audio_bits / 8;
blocksize *= 4;
Index: mythtv/libs/libmythtv/signalmonitor.cpp
===================================================================
--- mythtv/libs/libmythtv/signalmonitor.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/signalmonitor.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -100,9 +100,9 @@
uint wait_for_mask, const char *name)
: QObject(NULL, name), channel(_channel),
capturecardnum(_capturecardnum), flags(wait_for_mask),
- update_rate(25), running(false),
- exit(false), update_done(false),
- notify_frontend(true),
+ update_rate(25), minimum_update_rate(5),
+ running(false), exit(false),
+ update_done(false), notify_frontend(true),
signalLock (QObject::tr("Signal Lock"), "slock",
1, true, 0, 1, 0),
signalStrength(QObject::tr("Signal Power"), "signal",
Index: mythtv/libs/libmythtv/osdlistbtntype.cpp
===================================================================
--- mythtv/libs/libmythtv/osdlistbtntype.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/osdlistbtntype.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -19,206 +19,148 @@
*
* ============================================================ */
-#include
+// ANSI C headers
+#include
+// C++ headers
+#include
+using namespace std;
+
+// Qt headers
#include
#include
#include
#include
#include
+// MythTV headers
#include "mythcontext.h"
#include "mythdialogs.h"
-
#include "osdlistbtntype.h"
+#define LOC QString("OSDListTreeType: ")
+#define LOC_ERR QString("OSDListTreeType, Error: ")
-OSDGenericTree::OSDGenericTree(OSDGenericTree *parent, const QString &name,
- const QString &action, int check,
- OSDTypeImage *image, QString group)
- : GenericTree(name)
+static QRect unbias(QRect rect, float wmult, float hmult)
{
- m_checkable = check;
- m_action = action;
- m_image = image;
- m_parentButton = NULL;
-
- if (group != "")
- m_group = group;
- else
- m_group = action;
-
- if (!action.isEmpty() && !action.isNull())
- setSelectable(true);
-
- if (parent)
- parent->addNode(this);
+ return QRect((int)round(rect.x() / wmult),
+ (int)round(rect.y() / hmult),
+ (int)ceil( rect.width() / wmult),
+ (int)ceil( rect.height() / hmult));
}
-////////////////////////////////////////////////////////////////////////////
-
-OSDListTreeType::OSDListTreeType(const QString &name, const QRect &area,
- const QRect &levelsize, int levelspacing,
- float wmult, float hmult)
- : OSDType(name)
+static QRect bias(QRect rect, float wmult, float hmult)
{
- m_wmult = wmult;
- m_hmult = hmult;
-
- m_totalarea = area;
- m_levelsize = levelsize;
- m_levelspacing = levelspacing;
-
- if (gContext->GetNumSetting("UseArrowAccels", 1))
- m_arrowAccel = true;
- else
- m_arrowAccel = false;
-
- levels = 0;
- curlevel = -1;
-
- treetop = NULL;
- currentpos = NULL;
-
- currentlevel = NULL;
-
- listLevels.setAutoDelete(true);
-
- m_active = NULL;
- m_inactive = NULL;
-
- SetItemRegColor(Qt::black,QColor(80,80,80),100);
- SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
-
- m_spacing = 0;
- m_margin = 0;
+ return QRect((int)round(rect.x() * wmult),
+ (int)round(rect.y() * hmult),
+ (int)ceil( rect.width() * wmult),
+ (int)ceil( rect.height() * hmult));
}
-void OSDListTreeType::Reinit(float wchange, float hchange, float wmult,
- float hmult)
+OSDListTreeType::OSDListTreeType(
+ const QString &name, const QRect &area,
+ const QRect &levelsize, int levelspacing,
+ float wmult, float hmult)
+ : OSDType(name),
+ treetop(NULL), currentpos(NULL),
+ m_active(NULL), m_inactive(NULL),
+ m_itemRegBeg(Qt::black), m_itemRegEnd(QColor(80,80,80)),
+ m_itemSelBeg(QColor(82,202,56)), m_itemSelEnd(QColor(52,152,56)),
+ m_itemRegAlpha(100), m_itemSelAlpha(255),
+ m_spacing(0), m_margin(0),
+ m_levelspacing(levelspacing),
+ m_totalarea(area), m_levelsize(levelsize),
+ m_unbiasedspacing(1.0f), m_unbiasedmargin(1.0f),
+ m_unbiasedarea(0,0,0,0), m_unbiasedsize(0,0,0,0),
+ m_wmult(wmult), m_hmult(hmult),
+ m_depth(0), m_levelnum(-1),
+ m_visible(true),
+ m_arrowAccel(gContext->GetNumSetting("UseArrowAccels", 1))
{
- m_wmult = wmult;
- m_hmult = hmult;
-
- m_spacing = (int)(m_spacing * wchange);
- m_margin = (int)(m_margin * wchange);
-
- int width = (int)(m_totalarea.width() * wchange);
- int height = (int)(m_totalarea.height() * hchange);
- int x = (int)(m_totalarea.x() * wchange);
- int y = (int)(m_totalarea.y() * hchange);
-
- m_totalarea = QRect(x, y, width, height);
-
- width = (int)(m_levelsize.width() * wchange);
- height = (int)(m_levelsize.height() * hchange);
- x = (int)(m_levelsize.x() * wchange);
- y = (int)(m_levelsize.y() * hchange);
-
- m_levelsize = QRect(x, y, width, height);
-
- QPtrListIterator it(listLevels);
- OSDListBtnType *child;
-
- while ((child = it.current()) != 0)
- {
- child->Reinit(wchange, hchange, wmult, hmult);
- ++it;
- }
+ m_wmult = (wmult == 0.0f) ? 1.0f : wmult;
+ m_hmult = (hmult == 0.0f) ? 1.0f : hmult;
+ m_unbiasedarea = unbias(area, wmult, hmult);
+ m_unbiasedsize = unbias(levelsize, wmult, hmult);
}
-void OSDListTreeType::SetGroupCheckState(QString group, int newState)
+OSDListTreeType::~OSDListTreeType()
{
- QPtrListIterator it(listLevels);
- OSDListBtnType *child;
- while ((child = it.current()) != 0)
- {
- child->SetGroupCheckState(group, newState);
- ++it;
- }
+ OSDListBtnList::iterator it = listLevels.begin();
+ for (; it != listLevels.end(); ++it)
+ delete *it;
}
-void OSDListTreeType::SetItemRegColor(const QColor& beg, const QColor& end,
- uint alpha)
+void OSDListTreeType::Reinit(float wmult, float hmult)
{
- m_itemRegBeg = beg;
- m_itemRegEnd = end;
- m_itemRegAlpha = alpha;
-}
+ m_wmult = (wmult == 0.0f) ? 1.0f : wmult;
+ m_hmult = (hmult == 0.0f) ? 1.0f : hmult;
+ m_spacing = (uint) round(m_unbiasedspacing * wmult);
+ m_margin = (uint) round(m_unbiasedmargin * wmult);
+ m_totalarea = bias(m_unbiasedarea, wmult, hmult);
+ m_levelsize = bias(m_unbiasedsize, wmult, hmult);
-void OSDListTreeType::SetItemSelColor(const QColor& beg, const QColor& end,
- uint alpha)
-{
- m_itemSelBeg = beg;
- m_itemSelEnd = end;
- m_itemSelAlpha = alpha;
-}
+ if (!treetop || m_levelnum < 0)
+ return;
-void OSDListTreeType::SetFontActive(TTFFont *font)
-{
- m_active = font;
-}
+ // Save item indices
+ vector list;
+ for (uint i = 0; i <= (uint)m_levelnum; i++)
+ list.push_back(listLevels[i]->GetItemCurrentPos());
-void OSDListTreeType::SetFontInactive(TTFFont *font)
-{
- m_inactive = font;
-}
+ // Delete old OSD items
+ OSDListBtnList clone = listLevels;
+ listLevels.clear();
+ OSDListBtnList::iterator it = clone.begin();
+ for (; it != clone.end(); ++it)
+ delete *it;
-void OSDListTreeType::SetSpacing(int spacing)
-{
- m_spacing = spacing;
+ // Create new OSD items
+ SetAsTree(treetop, &list);
}
-void OSDListTreeType::SetMargin(int margin)
+void OSDListTreeType::SetGroupCheckState(QString group, int newState)
{
- m_margin = margin;
+ OSDListBtnList::iterator it = listLevels.begin();
+ for (; it != listLevels.end(); ++it)
+ (*it)->SetGroupCheckState(group, newState);
}
-void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel)
+void OSDListTreeType::SetAsTree(OSDGenericTree *toplevel,
+ vector *select_list)
{
if (treetop)
{
listLevels.clear();
- currentlevel = NULL;
- treetop = NULL;
- currentpos = NULL;
- levels = 0;
- curlevel = -1;
+ treetop = NULL;
+ currentpos = NULL;
+ m_depth = 0;
+ m_levelnum = -1;
}
- levels = toplevel->calculateDepth(0) - 1;
-
- if (levels <= 0)
+ m_depth = toplevel->calculateDepth(0) - 1;
+ if (m_depth <= 0)
{
- cerr << "Need at least one level\n";
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need at least one level");
return;
}
- currentpos = (OSDGenericTree *)toplevel->getChildAt(0);
-
+ currentpos = (OSDGenericTree*) toplevel->getChildAt(0);
if (!currentpos)
{
- cerr << "No top-level children?\n";
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "SetAsTree: Need top-level children");
return;
}
- treetop = toplevel;
-
- // just for now, remove later
- if (levels > 2)
- levels = 3;
-
- for (int i = 0; i < levels; i++)
+ // Create OSD buttons for all levels
+ for (uint i = 0; i < (uint)m_depth; i++)
{
QString levelname = QString("level%1").arg(i + 1);
-
QRect curlevelarea = m_levelsize;
curlevelarea.moveBy(m_totalarea.x(), m_totalarea.y());
-
curlevelarea.moveBy((m_levelsize.width() + m_levelspacing) * i, 0);
- OSDListBtnType *newlevel = new OSDListBtnType(levelname, curlevelarea,
- m_wmult, m_hmult, true);
+ OSDListBtnType *newlevel = new OSDListBtnType(
+ levelname, curlevelarea, m_wmult, m_hmult, true);
newlevel->SetFontActive(m_active);
newlevel->SetFontInactive(m_inactive);
@@ -227,229 +169,200 @@
newlevel->SetSpacing(m_spacing);
newlevel->SetMargin(m_margin);
- listLevels.append(newlevel);
+ listLevels.push_back(newlevel);
}
- currentlevel = GetLevel(0);
+ // Set up needed levels and selects
+ vector slist;
+ slist.push_back(0);
+ if (select_list)
+ slist = *select_list;
- if (!currentlevel)
+ currentpos = treetop = toplevel;
+ for (m_levelnum = 0; m_levelnum < (int)slist.size(); m_levelnum++)
{
- cerr << "Something is seriously wrong (currentlevel = NULL)\n";
- return;
+ FillLevelFromTree(currentpos, m_levelnum);
+ GetLevel(m_levelnum)->SetActive(true);
+ GetLevel(m_levelnum)->SetVisible(true);
+ if (slist[m_levelnum])
+ GetLevel(m_levelnum)->SetItemCurrent(slist[m_levelnum]);
+ EnterItem(); // updates currentpos
}
-
- FillLevelFromTree(toplevel, currentlevel);
-
- currentlevel->SetVisible(true);
- currentlevel->SetActive(true);
-
- currentpos = (OSDGenericTree *)(currentlevel->GetItemFirst()->getData());
- curlevel = 0;
-
- emit itemEntered(this, currentpos);
+ m_levelnum--;
}
-OSDGenericTree *OSDListTreeType::GetCurrentPosition(void)
+static bool has_action(QString action, const QStringList &actions)
{
- return currentpos;
+ QStringList::const_iterator it;
+ for (it = actions.begin(); it != actions.end(); ++it)
+ {
+ if (action == *it)
+ return true;
+ }
+ return false;
}
bool OSDListTreeType::HandleKeypress(QKeyEvent *e)
{
- if (!currentlevel)
+ QStringList actions;
+ bool ok = gContext->GetMainWindow()->TranslateKeyPress(
+ "TV Playback", e, actions);
+
+ if (!ok || ((uint)m_levelnum >= listLevels.size()))
return false;
+ else if (has_action("UP", actions))
+ {
+ GetLevel(m_levelnum)->MoveUp();
+ EnterItem();
+ }
+ else if (has_action("DOWN", actions))
+ {
+ GetLevel(m_levelnum)->MoveDown();
+ EnterItem();
+ }
+ else if (has_action("LEFT", actions) && (m_levelnum > 0))
+ {
+ GetLevel(m_levelnum)->Reset();
+ GetLevel(m_levelnum)->SetVisible(false);
- bool handled = false;
- QStringList actions;
- if (gContext->GetMainWindow()->TranslateKeyPress("TV Playback", e,
- actions))
+ m_levelnum--;
+ EnterItem();
+ }
+ else if ((has_action("LEFT", actions) && m_arrowAccel) ||
+ has_action("ESCAPE", actions) ||
+ has_action("CLEAROSD", actions) ||
+ has_action("MENU", actions))
{
- for (unsigned int i = 0; i < actions.size() && !handled; i++)
- {
- QString action = actions[i];
- handled = true;
+ m_visible = false;
+ }
+ else if (has_action("RIGHT", actions) &&
+ (m_levelnum + 1 < m_depth) &&
+ (currentpos->childCount() > 0))
+ {
+ GetLevel(m_levelnum)->SetActive(false);
+ m_levelnum++;
- if (action == "UP")
- {
- currentlevel->MoveUp();
- SetCurrentPosition();
- }
- else if (action == "DOWN")
- {
- currentlevel->MoveDown();
- SetCurrentPosition();
- }
- else if (action == "LEFT")
- {
- if (curlevel > 0)
- {
- currentlevel->Reset();
- currentlevel->SetVisible(false);
-
- curlevel--;
-
- currentlevel = GetLevel(curlevel);
- currentlevel->SetActive(true);
- SetCurrentPosition();
- }
- else if (m_arrowAccel)
- {
- m_visible = false;
- }
- }
- else if (action == "RIGHT")
- {
- // FIXME: create new levels if needed..
- if (curlevel + 1 < levels && currentpos->childCount() > 0)
- {
- currentlevel->SetActive(false);
-
- curlevel++;
-
- currentlevel = GetLevel(curlevel);
-
- FillLevelFromTree(currentpos, currentlevel);
-
- currentlevel->SetVisible(true);
- currentlevel->SetActive(true);
- SetCurrentPosition();
- }
- else if (m_arrowAccel)
- {
- SetGroupCheckState(currentpos->getGroup(),
- OSDListBtnTypeItem::NotChecked);
- currentpos->getParentButton()->setChecked(
- OSDListBtnTypeItem::FullChecked);
- emit itemSelected(this, currentpos);
- }
- }
- else if (action == "ESCAPE" || action == "MENU" ||
- action == "CLEAROSD")
- m_visible = false;
- else if (action == "SELECT")
- {
- SetGroupCheckState(currentpos->getGroup(),
- OSDListBtnTypeItem::NotChecked);
- currentpos->getParentButton()->setChecked(
- OSDListBtnTypeItem::FullChecked);
- emit itemSelected(this, currentpos);
- }
- else
- handled = false;
- }
+ FillLevelFromTree(currentpos, m_levelnum);
+ GetLevel(m_levelnum)->SetVisible(true);
+ EnterItem();
}
+ else if ((has_action("RIGHT", actions) && m_arrowAccel) ||
+ has_action("SELECT", actions))
+ {
+ SelectItem();
+ }
+ else
+ {
+ return false;
+ }
- return handled;
+ return true;
}
void OSDListTreeType::Draw(OSDSurface *surface, int fade, int maxfade,
int xoff, int yoff)
{
- QPtrListIterator it(listLevels);
- OSDListBtnType *child;
-
- while ((child = it.current()) != 0)
- {
- child->Draw(surface, fade, maxfade, xoff, yoff);
- ++it;
- }
+ OSDListBtnList::iterator it = listLevels.begin();
+ for (; it != listLevels.end(); ++it)
+ (*it)->Draw(surface, fade, maxfade, xoff, yoff);
}
void OSDListTreeType::FillLevelFromTree(OSDGenericTree *item,
- OSDListBtnType *list)
+ uint level_num)
{
+ OSDListBtnType *list = GetLevel(level_num);
if (!list)
{
- VERBOSE(VB_IMPORTANT, "OSDListTreeType::FillLevelFromTree() "
- "called with no list. Ignoring call.");
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "FillLevelFromTree() "
+ "called with no list, ignoring.");
return;
}
list->Reset();
QPtrList *itemlist = item->getAllChildren();
-
QPtrListIterator it(*itemlist);
- GenericTree *child;
- while ((child = it.current()) != 0)
+ OSDGenericTree *child = (OSDGenericTree*) it.current();
+ OSDListBtnTypeItem *newitem = NULL;
+ for (;(child = (OSDGenericTree*) it.current()); ++it)
{
- OSDGenericTree *osdchild = (OSDGenericTree *)child;
+ OSDTypeImage *im = child->getImage();
+ QString label = child->getString();
+ QString group = child->getGroup();
+ bool canCheck = child->getCheckable() >= 0;
+ bool hasCheck = child->getCheckable() == 1;
+ bool hasChild = child->childCount() > 0;
- OSDListBtnTypeItem *newitem;
- newitem = new OSDListBtnTypeItem(list, child->getString(),
- osdchild->getImage(),
- (osdchild->getCheckable() >= 0),
- (child->childCount() > 0));
- if (osdchild->getCheckable() == 1)
+ newitem = new OSDListBtnTypeItem(list, label, im, canCheck, hasChild);
+
+ if (hasCheck)
newitem->setChecked(OSDListBtnTypeItem::FullChecked);
- newitem->setGroup(osdchild->getGroup());
- newitem->setData(osdchild);
- osdchild->setParentButton(newitem);
+ newitem->setGroup(group);
+ newitem->setData(child);
- ++it;
+ child->setParentButton(newitem);
}
}
-OSDListBtnType *OSDListTreeType::GetLevel(int levelnum)
+OSDListBtnType *OSDListTreeType::GetLevel(uint levelnum)
{
- if ((uint)levelnum > listLevels.count())
- {
- cerr << "OOB GetLevel call\n";
- return NULL;
- }
+ if (levelnum < listLevels.size())
+ return listLevels[levelnum];
- return listLevels.at(levelnum);
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "GetLevel("<= listLevels.size())
return;
- OSDListBtnTypeItem *lbt = currentlevel->GetItemCurrent();
+ listLevels[m_levelnum]->SetActive(true);
+ OSDListBtnTypeItem *lbt = listLevels[m_levelnum]->GetItemCurrent();
+ if (lbt)
+ {
+ currentpos = (OSDGenericTree*) (lbt->getData());
+ emit itemEntered(this, currentpos);
+ }
+}
- if (!lbt)
+void OSDListTreeType::SelectItem(void)
+{
+ if (!currentpos)
return;
- currentpos = (OSDGenericTree *)(lbt->getData());
- emit itemEntered(this, currentpos);
+ SetGroupCheckState(currentpos->getGroup(), OSDListBtnTypeItem::NotChecked);
+ currentpos->getParentButton()->setChecked(OSDListBtnTypeItem::FullChecked);
+ emit itemSelected(this, currentpos);
}
-
+
+#undef LOC_ERR
+#undef LOC
+
//////////////////////////////////////////////////////////////////////////
OSDListBtnType::OSDListBtnType(const QString &name, const QRect &area,
float wmult, float hmult,
bool showScrollArrows)
- : OSDType(name)
+ : OSDType(name),
+ m_order(0), m_rect(area),
+ m_contentsRect(0,0,0,0), m_arrowsRect(0,0,0,0),
+ m_wmult(wmult), m_hmult(hmult),
+ m_itemHeight(0), m_itemSpacing(0),
+ m_itemMargin(0), m_itemsVisible(0),
+ m_active(false), m_showScrollArrows(showScrollArrows),
+ m_showUpArrow(false), m_showDnArrow(false),
+ m_initialized(false), m_clearing(false),
+ m_visible(false),
+ m_itemRegBeg(Qt::black), m_itemRegEnd(QColor(80,80,80)),
+ m_itemSelBeg(QColor(82,202,56)), m_itemSelEnd(QColor(52,152,56)),
+ m_itemRegAlpha(100), m_itemSelAlpha(255),
+ m_fontActive(NULL), m_fontInactive(NULL),
+ m_topIndx(0), m_selIndx(0),
+ m_update(true)
{
- m_rect = area;
-
- m_wmult = wmult;
- m_hmult = hmult;
-
- m_showScrollArrows = showScrollArrows;
-
- m_active = false;
- m_showUpArrow = false;
- m_showDnArrow = false;
-
- m_itemList.setAutoDelete(false);
- m_topItem = 0;
- m_selItem = 0;
-
- m_initialized = false;
- m_clearing = false;
- m_itemSpacing = 0;
- m_itemMargin = 0;
- m_itemHeight = 0;
- m_itemsVisible = 0;
- m_fontActive = 0;
- m_fontInactive = 0;
-
- SetItemRegColor(Qt::black,QColor(80,80,80),100);
- SetItemSelColor(QColor(82,202,56),QColor(52,152,56),255);
-
- m_visible = false;
}
OSDListBtnType::~OSDListBtnType()
@@ -457,316 +370,198 @@
Reset();
}
-void OSDListBtnType::Reinit(float wchange, float hchange, float wmult,
- float hmult)
-{
- m_wmult = wmult;
- m_hmult = hmult;
-
- m_itemHeight = (int)(m_itemHeight * hchange);
- m_itemSpacing = (int)(m_itemSpacing * wchange);
- m_itemMargin = (int)(m_itemMargin * wchange);
-
- int width = (int)(m_rect.width() * wchange);
- int height = (int)(m_rect.height() * hchange);
- int x = (int)(m_rect.x() * wchange);
- int y = (int)(m_rect.y() * hchange);
-
- m_rect = QRect(x, y, width, height);
-
- Init();
-
- OSDListBtnTypeItem* item = 0;
- for (item = m_itemList.first(); item; item = m_itemList.next()) {
- item->Reinit(wchange, hchange, wmult, hmult);
- }
-
-}
-
void OSDListBtnType::SetGroupCheckState(QString group, int newState)
{
- OSDListBtnTypeItem* item = 0;
- for (item = m_itemList.first(); item; item = m_itemList.next()) {
- if (item->getGroup() == group)
- item->setChecked((OSDListBtnTypeItem::CheckState)newState);
- }
+ OSDListBtnItemList::iterator it;
+ for (it = m_itemList.begin(); it != m_itemList.end(); ++it)
+ if ((*it)->getGroup() == group)
+ (*it)->setChecked((OSDListBtnTypeItem::CheckState) newState);
}
-void OSDListBtnType::SetItemRegColor(const QColor& beg, const QColor& end,
- uint alpha)
+void OSDListBtnType::Reset(void)
{
- m_itemRegBeg = beg;
- m_itemRegEnd = end;
- m_itemRegAlpha = alpha;
-}
-
-void OSDListBtnType::SetItemSelColor(const QColor& beg, const QColor& end,
- uint alpha)
-{
- m_itemSelBeg = beg;
- m_itemSelEnd = end;
- m_itemSelAlpha = alpha;
-}
-
-void OSDListBtnType::SetFontActive(TTFFont *font)
-{
- m_fontActive = font;
-}
-
-void OSDListBtnType::SetFontInactive(TTFFont *font)
-{
- m_fontInactive = font;
-}
-
-void OSDListBtnType::SetSpacing(int spacing)
-{
- m_itemSpacing = spacing;
-}
-
-void OSDListBtnType::SetMargin(int margin)
-{
- m_itemMargin = margin;
-}
-
-void OSDListBtnType::SetActive(bool active)
-{
- m_active = active;
-}
-
-void OSDListBtnType::Reset()
-{
QMutexLocker lock(&m_update);
m_clearing = true;
-
- OSDListBtnTypeItem* item = 0;
- for (item = m_itemList.first(); item; item = m_itemList.next()) {
- delete item;
- }
-
- m_clearing = false;
+ OSDListBtnItemList::iterator it;
+ OSDListBtnItemList clone = m_itemList;
m_itemList.clear();
-
- m_topItem = 0;
- m_selItem = 0;
+ for (it = clone.begin(); it != clone.end(); ++it)
+ delete (*it);
+ m_clearing = false;
+
+ m_topIndx = 0;
+ m_selIndx = 0;
m_showUpArrow = false;
m_showDnArrow = false;
}
void OSDListBtnType::InsertItem(OSDListBtnTypeItem *item)
{
- OSDListBtnTypeItem* lastItem = m_itemList.last();
- m_itemList.append(item);
-
- if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
- m_showDnArrow = true;
- else
- m_showDnArrow = false;
-
- if (!lastItem)
- {
- m_topItem = item;
- m_selItem = item;
+ QMutexLocker lock(&m_update);
+ m_itemList.push_back(item);
+ m_showDnArrow = m_showScrollArrows && m_itemList.size() > m_itemsVisible;
+ if (m_itemList.size() == 1)
emit itemSelected(item);
- }
}
+int find(const OSDListBtnItemList &list, const OSDListBtnTypeItem *item)
+{
+ for (uint i = 0; i < list.size(); i++)
+ if (list[i] == item)
+ return i;
+ return -1;
+}
+
void OSDListBtnType::RemoveItem(OSDListBtnTypeItem *item)
{
+ QMutexLocker lock(&m_update);
if (m_clearing)
return;
-
- if (m_itemList.find(item) == -1)
+
+ int i = find(m_itemList, item);
+ if (i < 0)
return;
- m_topItem = m_itemList.first();
- m_selItem = m_itemList.first();
+ m_itemList.erase(m_itemList.begin()+i);
- m_itemList.remove(item);
-
m_showUpArrow = false;
-
- if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
- m_showDnArrow = true;
- else
- m_showDnArrow = false;
+ m_showDnArrow = m_itemList.size() > m_itemsVisible;
+ m_selIndx = 0;
+ m_topIndx = 0;
- if (m_selItem) {
- emit itemSelected(m_selItem);
- }
+ if (m_itemList.size())
+ emit itemSelected(m_itemList[m_selIndx]);
}
-void OSDListBtnType::SetItemCurrent(OSDListBtnTypeItem* item)
+void OSDListBtnType::SetItemCurrent(const OSDListBtnTypeItem* item)
{
- bool locked = m_update.tryLock();
+ QMutexLocker lock(&m_update);
+ int i = find(m_itemList, item);
+ if (i >= 0)
+ SetItemCurrent(i);
+}
- if (m_itemList.find(item) == -1)
+void OSDListBtnType::SetItemCurrent(uint current)
+{
+ QMutexLocker lock(&m_update);
+ if (current >= m_itemList.size())
return;
- m_topItem = item;
- m_selItem = item;
-
- if (m_showScrollArrows && m_itemList.count() > m_itemsVisible)
- m_showDnArrow = true;
- else
- m_showDnArrow = false;
-
- emit itemSelected(m_selItem);
-
- if (locked)
- m_update.unlock();
+ m_selIndx = current;
+ m_topIndx = max(m_selIndx - (int)m_itemsVisible, 0);
+ m_showUpArrow = m_topIndx;
+ m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
+ emit itemSelected(m_itemList[m_selIndx]);
}
-void OSDListBtnType::SetItemCurrent(int current)
+int OSDListBtnType::GetItemCurrentPos(void) const
{
QMutexLocker lock(&m_update);
-
- OSDListBtnTypeItem* item = m_itemList.at(current);
- if (!item)
- item = m_itemList.first();
-
- SetItemCurrent(item);
+ return (m_itemList.size()) ? m_selIndx : -1;
}
-OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent()
+OSDListBtnTypeItem* OSDListBtnType::GetItemCurrent(void)
{
- return m_selItem;
+ QMutexLocker lock(&m_update);
+ if (!m_itemList.size())
+ return NULL;
+ return m_itemList[m_selIndx];
}
-OSDListBtnTypeItem* OSDListBtnType::GetItemFirst()
+OSDListBtnTypeItem* OSDListBtnType::GetItemFirst(void)
{
- return m_itemList.first();
+ QMutexLocker lock(&m_update);
+ if (!m_itemList.size())
+ return NULL;
+ return m_itemList[0];
}
-OSDListBtnTypeItem* OSDListBtnType::GetItemNext(OSDListBtnTypeItem *item)
+OSDListBtnTypeItem* OSDListBtnType::GetItemNext(const OSDListBtnTypeItem *item)
{
QMutexLocker lock(&m_update);
-
- if (m_itemList.find(item) == -1)
- return 0;
-
- return m_itemList.next();
+ int i = find(m_itemList, item) + 1;
+ if (i <= 0 || i >= (int)m_itemList.size())
+ return NULL;
+ return m_itemList[i];
}
-int OSDListBtnType::GetCount()
+int OSDListBtnType::GetCount(void) const
{
- return m_itemList.count();
+ QMutexLocker lock(&m_update);
+ return m_itemList.size();
}
OSDListBtnTypeItem* OSDListBtnType::GetItemAt(int pos)
{
- return m_itemList.at(pos);
+ QMutexLocker lock(&m_update);
+ return m_itemList[pos];
}
-int OSDListBtnType::GetItemPos(OSDListBtnTypeItem* item)
+int OSDListBtnType::GetItemPos(const OSDListBtnTypeItem *item) const
{
QMutexLocker lock(&m_update);
-
- return m_itemList.find(item);
+ return find(m_itemList, item);
}
-void OSDListBtnType::MoveUp()
+void OSDListBtnType::MoveUp(void)
{
QMutexLocker lock(&m_update);
-
- if (m_itemList.find(m_selItem) == -1)
+ if (!m_itemList.size())
return;
- OSDListBtnTypeItem *item = m_itemList.prev();
- if (!item)
+ if (--m_selIndx < 0)
{
- item = m_itemList.last();
- if (!item)
- return;
-
- if (m_itemList.count() > m_itemsVisible)
- m_topItem = m_itemList.at(m_itemList.count() - m_itemsVisible);
- else
- m_topItem = m_itemList.first();
+ m_selIndx = m_itemList.size() - 1;
+ m_topIndx = (m_itemList.size() > m_itemsVisible) ?
+ m_itemList.size() - m_itemsVisible : 0;
}
- m_selItem = item;
+ m_topIndx = (m_selIndx < m_topIndx) ? m_selIndx : m_topIndx;
+ m_showUpArrow = m_topIndx;
+ m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
- if (m_itemList.find(m_selItem) < m_itemList.find(m_topItem))
- m_topItem = m_selItem;
-
- if (m_topItem != m_itemList.first())
- m_showUpArrow = true;
- else
- m_showUpArrow = false;
-
- if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
- m_showDnArrow = true;
- else
- m_showDnArrow = false;
-
- emit itemSelected(m_selItem);
+ emit itemSelected(m_itemList[m_selIndx]);
}
-void OSDListBtnType::MoveDown()
+void OSDListBtnType::MoveDown(void)
{
QMutexLocker lock(&m_update);
-
- if (m_itemList.find(m_selItem) == -1)
+ if (!m_itemList.size())
return;
- OSDListBtnTypeItem *item = m_itemList.next();
- if (!item)
- {
- item = m_itemList.first();
- if (!item)
- return;
+ if (++m_selIndx >= (int)m_itemList.size())
+ m_selIndx = m_topIndx = 0;
- m_topItem = item;
- }
-
- m_selItem = item;
-
- if (m_itemList.find(m_topItem) + m_itemsVisible <=
- (unsigned int)m_itemList.find(m_selItem))
- {
- m_topItem = m_itemList.at(m_itemList.find(m_topItem) + 1);
- }
+ bool scroll_down = m_topIndx + (int)m_itemsVisible <= m_selIndx;
+ m_topIndx = (scroll_down) ? m_topIndx + 1 : m_topIndx;
+
+ m_showUpArrow = m_topIndx;
+ m_showDnArrow = m_topIndx + m_itemsVisible < m_itemList.size();
- if (m_topItem != m_itemList.first())
- m_showUpArrow = true;
- else
- m_showUpArrow = false;
-
- if (m_itemList.find(m_topItem) + m_itemsVisible < m_itemList.count())
- m_showDnArrow = true;
- else
- m_showDnArrow = false;
-
- emit itemSelected(m_selItem);
+ emit itemSelected(m_itemList[m_selIndx]);
}
-void OSDListBtnType::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
- int yoff)
+void OSDListBtnType::Draw(OSDSurface *surface,
+ int fade, int maxfade,
+ int xoff, int yoff)
{
- (void)xoff;
- (void)yoff;
-
+ QMutexLocker lock(&m_update);
if (!m_visible)
return;
-
- QMutexLocker lock(&m_update);
-
if (!m_initialized)
Init();
TTFFont *font = m_active ? m_fontActive : m_fontInactive;
int y = m_rect.y();
- m_itemList.find(m_topItem);
- OSDListBtnTypeItem *it = m_itemList.current();
- while (it && (y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight))
+ for (uint i = m_topIndx; i < m_itemList.size(); i++)
{
- it->paint(surface, font, fade, maxfade, m_rect.x()+ xoff, y + yoff);
-
+ if (!((y - m_rect.y()) <= (m_contentsRect.height() - m_itemHeight)))
+ break;
+ m_itemList[i]->paint(surface, font, fade, maxfade,
+ m_rect.x() + xoff, y + yoff);
y += m_itemHeight + m_itemSpacing;
-
- it = m_itemList.next();
}
if (m_showScrollArrows)
@@ -792,14 +587,13 @@
}
}
-void OSDListBtnType::Init()
+void OSDListBtnType::Init(void)
{
int sz1 = m_fontActive->Size() * 3 / 2;
int sz2 = m_fontInactive->Size() * 3 / 2;
- m_itemHeight = QMAX(sz1, sz2) + (int)(2 * m_itemMargin);
+ m_itemHeight = max(sz1, sz2) + (int)(2 * m_itemMargin);
+ m_itemHeight = m_itemHeight & ~0x1;
- m_itemHeight = (m_itemHeight / 2) * 2;
-
if (m_showScrollArrows)
{
LoadPixmap(m_upArrowRegPix, "uparrow-reg");
@@ -838,11 +632,7 @@
InitItem(m_itemSelActPix, itemWidth, m_itemHeight,
m_itemSelBeg, m_itemSelEnd, 255);
- if (m_itemList.count() > m_itemsVisible && m_showScrollArrows)
- m_showDnArrow = true;
- else
- m_showDnArrow = false;
-
+ m_showDnArrow = m_itemList.size() > m_itemsVisible && m_showScrollArrows;
m_initialized = true;
}
@@ -885,68 +675,57 @@
void OSDListBtnType::LoadPixmap(OSDTypeImage& pix, const QString& fileName)
{
- QString file = gContext->GetThemesParentDir() + "default/lb-" + fileName + ".png";
- pix.LoadImage(file, m_wmult, m_hmult);
+ QString path = gContext->GetThemesParentDir() + "default/lb-";
+ pix.LoadImage(path + fileName + ".png", m_wmult, m_hmult);
}
/////////////////////////////////////////////////////////////////////////////
-OSDListBtnTypeItem::OSDListBtnTypeItem(OSDListBtnType* lbtype,
- const QString& text,
- OSDTypeImage *pixmap, bool checkable,
- bool showArrow, CheckState state)
+OSDListBtnTypeItem::OSDListBtnTypeItem(
+ OSDListBtnType *lbtype, const QString &text,
+ OSDTypeImage *pixmap, bool checkable,
+ bool showArrow, CheckState state)
+ : m_parent(lbtype), m_pixmap(pixmap),
+ m_data(NULL), m_text(text),
+ m_group(QString::null), m_state(state),
+ m_showArrow(showArrow), m_checkable(checkable),
+ m_checkRect(0,0,0,0), m_arrowRect(0,0,0,0),
+ m_pixmapRect(0,0,0,0), m_textRect(0,0,0,0)
{
- m_parent = lbtype;
- m_text = text;
- m_pixmap = pixmap;
- m_checkable = checkable;
- m_state = state;
- m_showArrow = showArrow;
- m_data = 0;
-
if (!m_parent->m_initialized)
m_parent->Init();
- int margin = m_parent->m_itemMargin;
- int width = m_parent->m_rect.width();
- int height = m_parent->m_itemHeight;
+ OSDTypeImage &checkPix = m_parent->m_checkNonePix;
+ OSDTypeImage &arrowPix = m_parent->m_arrowPix;
- OSDTypeImage& checkPix = m_parent->m_checkNonePix;
- OSDTypeImage& arrowPix = m_parent->m_arrowPix;
-
- int cw = checkPix.ImageSize().width();
- int ch = checkPix.ImageSize().height();
- int aw = arrowPix.ImageSize().width();
- int ah = arrowPix.ImageSize().height();
- int pw = m_pixmap ? m_pixmap->ImageSize().width() : 0;
- int ph = m_pixmap ? m_pixmap->ImageSize().height() : 0;
-
+ int margin = m_parent->m_itemMargin;
+ int width = m_parent->m_rect.width();
+ int height = m_parent->m_itemHeight;
+ int cw = checkPix.ImageSize().width();
+ int ch = checkPix.ImageSize().height();
+ int aw = arrowPix.ImageSize().width();
+ int ah = arrowPix.ImageSize().height();
+ int pw = m_pixmap ? m_pixmap->ImageSize().width() : 0;
+ int ph = m_pixmap ? m_pixmap->ImageSize().height() : 0;
+
if (m_checkable)
- m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
- else
- m_checkRect = QRect(0,0,0,0);
+ m_checkRect = QRect(margin, (height - ch)/2, cw, ch);
if (m_showArrow)
- m_arrowRect = QRect(width - aw - margin, (height - ah)/2,
- aw, ah);
- else
- m_arrowRect = QRect(0,0,0,0);
+ m_arrowRect = QRect(width - aw - margin, (height - ah)/2, aw, ah);
- if (m_pixmap)
- m_pixmapRect = QRect(m_checkable ? (2*margin + m_checkRect.width()) :
- margin, (height - ph)/2,
- pw, ph);
- else
- m_pixmapRect = QRect(0,0,0,0);
+ if (m_pixmap)
+ {
+ int tmp = (m_checkable) ? (2 * margin + m_checkRect.width()) : margin;
+ m_pixmapRect = QRect(tmp, (height - ph)/2, pw, ph);
+ }
- m_textRect = QRect(margin +
- (m_checkable ? m_checkRect.width() + margin : 0) +
- (m_pixmap ? m_pixmapRect.width() + margin : 0),
- 0,
- width - 2*margin -
- (m_checkable ? m_checkRect.width() + margin : 0) -
- (m_showArrow ? m_arrowRect.width() + margin : 0) -
- (m_pixmap ? m_pixmapRect.width() + margin : 0),
- height);
+ int tx = margin, tw = width - (2 * margin);
+ tx += (m_checkable) ? m_checkRect.width() + margin : 0;
+ tx += (m_pixmap) ? m_pixmapRect.width() + margin : 0;
+ tw -= (m_checkable) ? m_checkRect.width() + margin : 0;
+ tw -= (m_showArrow) ? m_arrowRect.width() + margin : 0;
+ tw -= (m_pixmap) ? m_pixmapRect.width() + margin : 0;
+ m_textRect = QRect(tx, 0, tw, height);
m_parent->InsertItem(this);
}
@@ -957,52 +736,10 @@
m_parent->RemoveItem(this);
}
-QString OSDListBtnTypeItem::text() const
-{
- return m_text;
-}
-
-const OSDTypeImage* OSDListBtnTypeItem::pixmap() const
-{
- return m_pixmap;
-}
-
-bool OSDListBtnTypeItem::checkable() const
-{
- return m_checkable;
-}
-
-OSDListBtnTypeItem::CheckState OSDListBtnTypeItem::state() const
-{
- return m_state;
-}
-
-OSDListBtnType* OSDListBtnTypeItem::parent() const
-{
- return m_parent;
-}
-
-void OSDListBtnTypeItem::setChecked(CheckState state)
-{
- if (!m_checkable)
- return;
- m_state = state;
-}
-
-void OSDListBtnTypeItem::setData(void *data)
-{
- m_data = data;
-}
-
-void* OSDListBtnTypeItem::getData()
-{
- return m_data;
-}
-
void OSDListBtnTypeItem::paint(OSDSurface *surface, TTFFont *font,
int fade, int maxfade, int x, int y)
{
- if (this == m_parent->m_selItem)
+ if (this == m_parent->GetItemCurrent())
{
if (m_parent->m_active)
m_parent->m_itemSelActPix.Draw(surface, fade, maxfade, x, y);
@@ -1030,11 +767,14 @@
cr.moveBy(x, y);
if (m_state == HalfChecked)
- m_parent->m_checkHalfPix.Draw(surface, fade, maxfade, cr.x(), cr.y());
+ m_parent->m_checkHalfPix.Draw(surface, fade, maxfade,
+ cr.x(), cr.y());
else if (m_state == FullChecked)
- m_parent->m_checkFullPix.Draw(surface, fade, maxfade, cr.x(), cr.y());
+ m_parent->m_checkFullPix.Draw(surface, fade, maxfade,
+ cr.x(), cr.y());
else
- m_parent->m_checkNonePix.Draw(surface, fade, maxfade, cr.x(), cr.y());
+ m_parent->m_checkNonePix.Draw(surface, fade, maxfade,
+ cr.x(), cr.y());
}
if (m_pixmap)
@@ -1049,39 +789,3 @@
tr.moveBy(0, font->Size() / 4);
font->DrawString(surface, tr.x(), tr.y(), m_text, tr.right(), tr.bottom());
}
-
-void OSDListBtnTypeItem::Reinit(float wchange, float hchange,
- float wmult, float hmult)
-{
- (void)wmult;
- (void)hmult;
-
- int width = (int)(m_checkRect.width() * wchange);
- int height = (int)(m_checkRect.height() * hchange);
- int x = (int)(m_checkRect.x() * wchange);
- int y = (int)(m_checkRect.y() * hchange);
-
- m_checkRect = QRect(x, y, width, height);
-
- width = (int)(m_pixmapRect.width() * wchange);
- height = (int)(m_pixmapRect.height() * hchange);
- x = (int)(m_pixmapRect.x() * wchange);
- y = (int)(m_pixmapRect.y() * hchange);
-
- m_pixmapRect = QRect(x, y, width, height);
-
- width = (int)(m_textRect.width() * wchange);
- height = (int)(m_textRect.height() * hchange);
- x = (int)(m_textRect.x() * wchange);
- y = (int)(m_textRect.y() * hchange);
-
- m_textRect = QRect(x, y, width, height);
-
- width = (int)(m_arrowRect.width() * wchange);
- height = (int)(m_arrowRect.height() * hchange);
- x = (int)(m_arrowRect.x() * wchange);
- y = (int)(m_arrowRect.y() * hchange);
-
- m_arrowRect = QRect(x, y, width, height);
-}
-
Index: mythtv/libs/libmythtv/RingBuffer.cpp
===================================================================
--- mythtv/libs/libmythtv/RingBuffer.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/RingBuffer.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -145,6 +145,12 @@
VERBOSE(VB_PLAYBACK, LOC + QString("OpenFile(%1, %1)")
.arg(lfilename).arg(retryCount));
+ if ((filename.right(4).lower() == ".png") ||
+ (filename.right(4).lower() == ".gif"))
+ {
+ retryCount = 0;
+ }
+
uint openAttempts = retryCount + 1;
filename = lfilename;
@@ -162,6 +168,7 @@
bool is_local = false;
bool is_dvd = false;
+
if ((filename.left(7) == "myth://") &&
(filename.length() > 7 ))
{
@@ -271,6 +278,11 @@
remotefile = NULL;
}
}
+
+ setswitchtonext = false;
+ ateof = false;
+ commserror = false;
+ numfailures = 0;
}
/** \fn RingBuffer::IsOpen(void) const
@@ -727,7 +739,7 @@
loops = 0;
pthread_rwlock_rdlock(&rwlock);
- if (totfree > readblocksize && !commserror)
+ if (totfree > readblocksize && !commserror && !ateof && !setswitchtonext)
{
// limit the read size
totfree = readblocksize;
@@ -737,6 +749,9 @@
if (remotefile)
{
+ if (livetvchain && livetvchain->HasNext())
+ remotefile->SetTimeout(true);
+
ret = safe_read(remotefile, readAheadBuffer + rbwpos,
totfree);
internalreadpos += ret;
@@ -785,8 +800,16 @@
totfree = 0;
}
- if (!readsallowed && used >= fill_min)
+ if (!readsallowed && (used >= fill_min || setswitchtonext))
+ {
readsallowed = true;
+ VERBOSE(VB_PLAYBACK, QString("reads allowed (%1 %2)").arg(used)
+ .arg(fill_min));
+ }
+ else if (!readsallowed)
+ VERBOSE(VB_PLAYBACK, QString("buffering (%1 %2 %3)").arg(used)
+ .arg(fill_min)
+ .arg(ret));
if (readsallowed && used < fill_min && !ateof && !setswitchtonext)
{
@@ -808,8 +831,11 @@
pthread_rwlock_unlock(&rwlock);
- if ((used >= fill_threshold || wantseek) && !pausereadthread)
+ if ((used >= fill_threshold || wantseek || ateof || setswitchtonext) &&
+ !pausereadthread)
+ {
usleep(500);
+ }
}
delete [] readAheadBuffer;
@@ -853,15 +879,15 @@
VERBOSE(VB_IMPORTANT,
LOC + "Taking too long to be allowed to read..");
readErr++;
-
+
// HACK Sometimes the readhead thread gets borked on startup.
- /* if ((readErr % 2) && (rbrpos ==0))
+ if ((readErr > 2 && readErr % 2) && (rbrpos ==0))
{
VERBOSE(VB_IMPORTANT, "restarting readhead thread..");
KillReadAheadThread();
StartupReadAheadThread();
}
- */
+
if (readErr > 10)
{
VERBOSE(VB_IMPORTANT, LOC_ERR + "Took more than "
@@ -895,6 +921,12 @@
VERBOSE(VB_IMPORTANT, LOC + "Waited " +
QString("%1").arg(elapsed/1000) +
" seconds for data to become available...");
+ if (livetvchain)
+ {
+ VERBOSE(VB_IMPORTANT, "Checking to see if there's a "
+ "new livetv program to switch to..");
+ livetvchain->ReloadAll();
+ }
}
bool quit = livetvchain && (livetvchain->NeedsToSwitch() ||
@@ -923,7 +955,7 @@
availWaitMutex.unlock();
avail = ReadBufAvail();
- if (ateof && avail < count)
+ if ((ateof || setswitchtonext) && avail < count)
count = avail;
if (commserror)
Index: mythtv/libs/libmythtv/hdtvrecorder.cpp
===================================================================
--- mythtv/libs/libmythtv/hdtvrecorder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/hdtvrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -627,9 +627,8 @@
len += remainder;
remainder = ProcessData(_buffer, len);
- if (remainder > 0) // leftover bytes
- memmove(_buffer, &(_buffer[_buffer_size - remainder]),
- remainder);
+ if (remainder > 0 && (len > remainder)) // leftover bytes
+ memmove(_buffer, &(_buffer[len - remainder]), remainder);
}
FinishRecording();
Index: mythtv/libs/libmythtv/dummydtvrecorder.cpp
===================================================================
--- mythtv/libs/libmythtv/dummydtvrecorder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/dummydtvrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -125,7 +125,8 @@
// TRANSFER DATA
while (_request_recording || _frames_seen_count <= 5)
{
- len = read(_stream_fd, &(_buffer[remainder]), _buffer_size - remainder);
+ len = read(_stream_fd, &(_buffer[remainder]),
+ _buffer_size - remainder);
if (len == 0)
{
@@ -137,9 +138,8 @@
len += remainder;
remainder = ProcessData(_buffer, len);
- if (remainder > 0) // leftover bytes
- memmove(_buffer, &(_buffer[_buffer_size - remainder]),
- remainder);
+ if (remainder > 0 && (len > remainder)) // leftover bytes
+ memmove(_buffer, &(_buffer[len - remainder]), remainder);
}
FinishRecording();
Index: mythtv/libs/libmythtv/avformatdecoder.cpp
===================================================================
--- mythtv/libs/libmythtv/avformatdecoder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/avformatdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -725,7 +725,12 @@
return -1;
}
+ /* av_find_stream_info() eventually makes calls to avcodec_open() and avcodec_close()
+ so we have to use the avcodeclock */
+ avcodeclock.lock();
int ret = av_find_stream_info(ic);
+ avcodeclock.unlock();
+
if (ret < 0)
{
VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not find codec parameters. " +
Index: mythtv/libs/libmythtv/osdtypes.cpp
===================================================================
--- mythtv/libs/libmythtv/osdtypes.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/osdtypes.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -14,6 +14,9 @@
#include "mythcontext.h"
+/// Shared OSD image cache
+OSDImageCache OSDTypeImage::c_cache;
+
OSDSet::OSDSet(const QString &name, bool cache, int screenwidth,
int screenheight, float wmult, float hmult, int frint)
: QObject()
@@ -160,9 +163,6 @@
int displaywidth, int displayheight,
float wmult, float hmult, int frint)
{
- float wchange = wmult / m_wmult;
- float hchange = hmult / m_hmult;
-
m_frameint = frint;
m_screenwidth = screenwidth;
@@ -175,57 +175,12 @@
vector::iterator iter = allTypes->begin();
for (;iter != allTypes->end(); iter++)
{
- OSDType *type = (*iter);
- if (OSDTypeText *item = dynamic_cast(type))
- {
- item->Reinit(wchange, hchange);
- }
- else if (OSDTypePositionImage *item =
- dynamic_cast(type))
- {
- item->Reinit(wchange, hchange, wmult, hmult);
- }
- else if (OSDTypePosSlider *item = dynamic_cast(type))
- {
- item->Reinit(wchange, hchange, wmult, hmult);
- }
- else if (OSDTypeFillSlider *item =
- dynamic_cast(type))
- {
- item->Reinit(wchange, hchange, wmult, hmult);
- }
- else if (OSDTypeEditSlider *item =
- dynamic_cast(type))
- {
- item->Reinit(wchange, hchange, wmult, hmult);
- }
- else if (OSDTypeImage *item = dynamic_cast(type))
- {
- item->Reinit(wchange, hchange, wmult, hmult);
- }
- else if (OSDTypeBox *item = dynamic_cast(type))
- {
- item->Reinit(wchange, hchange);
- }
- else if (OSDTypePositionRectangle *item =
- dynamic_cast(type))
- {
- item->Reinit(wchange, hchange);
- }
- else if (OSDTypeCC *item = dynamic_cast(type))
- {
- item->Reinit(xoff, yoff, displaywidth, displayheight);
- }
- else if (OSDListTreeType *item = dynamic_cast(type))
- {
- item->Reinit(wchange, hchange, wmult, hmult);
- }
+ if (OSDTypeCC *cc608 = dynamic_cast(*iter))
+ cc608->Reinit(xoff, yoff, displaywidth, displayheight,
+ wmult, hmult);
else
- {
- cerr << "Unknown conversion\n";
- }
+ (*iter)->Reinit(wmult, hmult);
}
-
}
OSDType *OSDSet::GetType(const QString &name)
@@ -443,7 +398,8 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSDTypeText::OSDTypeText(const QString &name, TTFFont *font,
- const QString &text, QRect displayrect)
+ const QString &text, QRect displayrect,
+ float wmult, float hmult)
: OSDType(name)
{
m_message = text;
@@ -464,6 +420,12 @@
m_scrollinit = false;
m_linespacing = 1.5;
+
+ m_unbiasedsize =
+ QRect((int)round(m_screensize.x() / wmult),
+ (int)round(m_screensize.y() / hmult),
+ (int)ceil( m_screensize.width() / wmult),
+ (int)ceil( m_screensize.height() / hmult));
}
OSDTypeText::OSDTypeText(const OSDTypeText &other)
@@ -507,14 +469,13 @@
m_scrollinit = false;
}
-void OSDTypeText::Reinit(float wchange, float hchange)
+void OSDTypeText::Reinit(float wmult, float hmult)
{
- int width = (int)(m_screensize.width() * wchange);
- int height = (int)(m_screensize.height() * hchange);
- int x = (int)(m_screensize.x() * wchange);
- int y = (int)(m_screensize.y() * hchange);
-
- m_displaysize = m_screensize = QRect(x, y, width, height);
+ m_displaysize = m_screensize =
+ QRect((int)round(m_unbiasedsize.x() * wmult),
+ (int)round(m_unbiasedsize.y() * hmult),
+ (int)ceil( m_unbiasedsize.width() * wmult),
+ (int)ceil( m_unbiasedsize.height() * hmult));
}
void OSDTypeText::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
@@ -708,7 +669,7 @@
m_onlyusefirst = false;
m_filename = filename;
- m_displaypos = displaypos;
+ SetPosition(displaypos, wmult, hmult);
m_yuv = m_alpha = NULL;
m_isvalid = false;
@@ -716,6 +677,7 @@
m_scalew = scalew;
m_scaleh = scaleh;
+ m_cacheitem = NULL;
LoadImage(filename, wmult, hmult, scalew, scaleh);
}
@@ -733,6 +695,7 @@
m_name = other.m_name;
m_scalew = other.m_scalew;
m_scaleh = other.m_scaleh;
+ m_cacheitem = NULL;
m_alpha = m_yuv = NULL;
if (m_isvalid)
@@ -760,6 +723,8 @@
m_onlyusefirst = false;
m_displaypos = QPoint(0, 0);
+ m_unbiasedpos = QPoint(0, 0);
+ m_cacheitem = NULL;
m_yuv = NULL;
m_alpha = NULL;
@@ -778,6 +743,8 @@
m_onlyusefirst = false;
m_displaypos = QPoint(0, 0);
+ m_unbiasedpos = QPoint(0, 0);
+ m_cacheitem = NULL;
m_yuv = NULL;
m_alpha = NULL;
@@ -790,10 +757,14 @@
OSDTypeImage::~OSDTypeImage()
{
- if (m_yuv)
- delete [] m_yuv;
- if (m_alpha)
- delete [] m_alpha;
+ // In case we have a cache item in hand, it's safe to delete it,
+ // as it should not be in OSDImageCache anymore and it should have
+ // been written to the file cache for faster access in the future.
+ if (m_cacheitem)
+ {
+ delete m_cacheitem;
+ m_cacheitem = NULL;
+ }
}
void OSDTypeImage::SetName(const QString &name)
@@ -801,13 +772,19 @@
m_name = name;
}
-void OSDTypeImage::Reinit(float wchange, float hchange, float wmult, float hmult)
+void OSDTypeImage::SetPosition(QPoint pos, float wmult, float hmult)
{
- int x = (int)(m_displaypos.x() * wchange);
- int y = (int)(m_displaypos.y() * hchange);
+ m_displaypos = pos;
+ m_unbiasedpos =
+ QPoint((int)round(pos.x() / wmult),
+ (int)round(pos.y() / hmult));
+}
- m_displaypos.setX(x);
- m_displaypos.setY(y);
+void OSDTypeImage::Reinit(float wmult, float hmult)
+{
+ m_displaypos =
+ QPoint((int)round(m_unbiasedpos.x() * wmult),
+ (int)round(m_unbiasedpos.y() * hmult));
LoadImage(m_filename, wmult, hmult, m_scalew, m_scaleh);
}
@@ -815,20 +792,44 @@
void OSDTypeImage::LoadImage(const QString &filename, float wmult, float hmult,
int scalew, int scaleh)
{
- if (m_isvalid)
+ QString ckey;
+
+ if (!filename.isEmpty() && filename.length() >= 2)
{
- if (m_yuv)
- delete [] m_yuv;
- if (m_alpha)
- delete [] m_alpha;
-
- m_isvalid = false;
- m_yuv = NULL;
- m_alpha = NULL;
+ ckey = OSDImageCache::CreateKey(
+ filename, wmult, hmult, scalew, scaleh);
}
+ else
+ {
+ // this method requires a backing file
+ return;
+ }
+
+ // Get the item from the cache so it's not freed while in use
+ OSDImageCacheValue* value = c_cache.Get(ckey, true);
+
+ if (value != NULL)
+ {
+ m_yuv = value->m_yuv;
+ m_ybuffer = value->m_ybuffer;
+ m_ubuffer = value->m_ubuffer;
+ m_vbuffer = value->m_vbuffer;
+ m_alpha = value->m_alpha;
+ m_imagesize = value->m_imagesize;
+ m_isvalid = true;
- if (filename.length() < 2)
+ // Put the old image back to the cache so it can be reused in the
+ // future, and possibly freed by the cache system if the size limit
+ // is reached
+ if (!m_cacheitem)
+ c_cache.Insert(m_cacheitem);
+ m_cacheitem = value;
+
return;
+ }
+
+ // scaled image was not found in cache, have to create it
+
QImage tmpimage(filename);
@@ -867,17 +868,32 @@
imwidth, imheight, tmp2.width());
m_imagesize = QRect(0, 0, imwidth, imheight);
+
+ // put the old image back to the cache so it can be reused in the
+ // future, and possibly freed by the cache system if the size limit
+ // is reached
+ if (m_cacheitem)
+ c_cache.Insert(m_cacheitem);
+
+ m_cacheitem = new OSDImageCacheValue(
+ ckey,
+ m_yuv, m_ybuffer, m_ubuffer,
+ m_vbuffer, m_alpha, m_imagesize);
+
+ // save the new cache item to the file cache
+ if (!filename.isEmpty())
+ c_cache.SaveToDisk(m_cacheitem);
}
void OSDTypeImage::LoadFromQImage(const QImage &img)
{
+ // this method is not cached as it's used mostly for
+ // subtitles which are displayed only once anyways, caching
+ // would probably only slow things down overall
if (m_isvalid)
{
- if (m_yuv)
- delete [] m_yuv;
- if (m_alpha)
- delete [] m_alpha;
-
+ delete m_cacheitem;
+ m_cacheitem = NULL;
m_isvalid = false;
m_yuv = NULL;
m_alpha = NULL;
@@ -1043,23 +1059,25 @@
m_maxval = 1000;
m_curval = 0;
m_displayrect = displayrect;
+ m_unbiasedrect =
+ QRect((int)round(m_displayrect.x() / wmult),
+ (int)round(m_displayrect.y() / hmult),
+ (int)ceil( m_displayrect.width() / wmult),
+ (int)ceil( m_displayrect.height() / hmult));
}
OSDTypePosSlider::~OSDTypePosSlider()
{
}
-void OSDTypePosSlider::Reinit(float wchange, float hchange, float wmult,
- float hmult)
+void OSDTypePosSlider::Reinit(float wmult, float hmult)
{
- int width = (int)(m_displayrect.width() * wchange);
- int height = (int)(m_displayrect.height() * hchange);
- int x = (int)(m_displayrect.x() * wchange);
- int y = (int)(m_displayrect.y() * hchange);
-
- m_displayrect = QRect(x, y, width, height);
-
- OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
+ m_displayrect =
+ QRect((int)round(m_unbiasedrect.x() * wmult),
+ (int)round(m_unbiasedrect.y() * hmult),
+ (int)ceil( m_unbiasedrect.width() * wmult),
+ (int)ceil( m_unbiasedrect.height() * hmult));
+ OSDTypeImage::Reinit(wmult, hmult);
}
void OSDTypePosSlider::SetPosition(int pos)
@@ -1092,23 +1110,25 @@
m_drawwidth = 0;
m_onlyusefirst = true;
m_displayrect = displayrect;
+ m_unbiasedrect =
+ QRect((int)round(m_displayrect.x() / wmult),
+ (int)round(m_displayrect.y() / hmult),
+ (int)ceil( m_displayrect.width() / wmult),
+ (int)ceil( m_displayrect.height() / hmult));
}
OSDTypeFillSlider::~OSDTypeFillSlider()
{
}
-void OSDTypeFillSlider::Reinit(float wchange, float hchange, float wmult,
- float hmult)
+void OSDTypeFillSlider::Reinit(float wmult, float hmult)
{
- int width = (int)(m_displayrect.width() * wchange);
- int height = (int)(m_displayrect.height() * hchange);
- int x = (int)(m_displayrect.x() * wchange);
- int y = (int)(m_displayrect.y() * hchange);
-
- m_displayrect = QRect(x, y, width, height);
-
- OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
+ m_displayrect =
+ QRect((int)round(m_unbiasedrect.x() * wmult),
+ (int)round(m_unbiasedrect.y() * hmult),
+ (int)ceil( m_unbiasedrect.width() * wmult),
+ (int)ceil( m_unbiasedrect.height() * hmult));
+ OSDTypeImage::Reinit(wmult, hmult);
}
void OSDTypeFillSlider::SetPosition(int pos)
@@ -1143,6 +1163,11 @@
m_maxval = 1000;
m_curval = 0;
m_displayrect = displayrect;
+ m_unbiasedrect =
+ QRect((int)round(m_displayrect.x() / wmult),
+ (int)round(m_displayrect.y() / hmult),
+ (int)ceil( m_displayrect.width() / wmult),
+ (int)ceil( m_displayrect.height() / hmult));
m_drawwidth = displayrect.width();
m_drawMap = new unsigned char[m_drawwidth + 1];
@@ -1162,6 +1187,7 @@
m_scalew = scalew;
m_scaleh = scaleh;
+ m_cacheitem = NULL;
LoadImage(m_redname, wmult, hmult, scalew, scaleh);
if (m_isvalid)
@@ -1184,22 +1210,16 @@
OSDTypeEditSlider::~OSDTypeEditSlider()
{
delete [] m_drawMap;
-
- if (m_ryuv)
- delete [] m_ryuv;
- if (m_ralpha)
- delete [] m_ralpha;
}
-void OSDTypeEditSlider::Reinit(float wchange, float hchange, float wmult,
- float hmult)
+void OSDTypeEditSlider::Reinit(float wmult, float hmult)
{
- int width = (int)(m_displayrect.width() * wchange);
- int height = (int)(m_displayrect.height() * hchange);
- int x = (int)(m_displayrect.x() * wchange);
- int y = (int)(m_displayrect.y() * hchange);
+ m_displayrect =
+ QRect((int)round(m_unbiasedrect.x() * wmult),
+ (int)round(m_unbiasedrect.y() * hmult),
+ (int)ceil( m_unbiasedrect.width() * wmult),
+ (int)ceil( m_unbiasedrect.height() * hmult));
- m_displayrect = QRect(x, y, width, height);
m_drawwidth = m_displayrect.width();
delete [] m_drawMap;
@@ -1210,11 +1230,6 @@
m_displaypos = m_displayrect.topLeft();
- if (m_ryuv)
- delete [] m_ryuv;
- if (m_ralpha)
- delete [] m_ralpha;
-
LoadImage(m_redname, wmult, hmult, m_scalew, m_scaleh);
if (m_isvalid)
{
@@ -1360,30 +1375,46 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect)
- : OSDType(name)
+OSDTypeBox::OSDTypeBox(const QString &name, QRect displayrect,
+ float wmult, float hmult)
+ : OSDType(name)
{
size = displayrect;
+ m_unbiasedsize =
+ QRect((int)round(size.x() / wmult),
+ (int)round(size.y() / hmult),
+ (int)ceil( size.width() / wmult),
+ (int)ceil( size.height() / hmult));
}
+void OSDTypeBox::SetRect(QRect newrect, float wmult, float hmult)
+{
+ size = newrect;
+ m_unbiasedsize =
+ QRect((int)round(size.x() / wmult),
+ (int)round(size.y() / hmult),
+ (int)ceil( size.width() / wmult),
+ (int)ceil( size.height() / hmult));
+}
+
OSDTypeBox::OSDTypeBox(const OSDTypeBox &other)
: OSDType(other.m_name)
{
size = other.size;
+ m_unbiasedsize = other.m_unbiasedsize;
}
OSDTypeBox::~OSDTypeBox()
{
}
-void OSDTypeBox::Reinit(float wchange, float hchange)
+void OSDTypeBox::Reinit(float wmult, float hmult)
{
- int width = (int)(size.width() * wchange);
- int height = (int)(size.height() * hchange);
- int x = (int)(size.x() * wchange);
- int y = (int)(size.y() * hchange);
-
- size = QRect(x, y, width, height);
+ size =
+ QRect((int)round(m_unbiasedsize.x() * wmult),
+ (int)round(m_unbiasedsize.y() * hmult),
+ (int)ceil( m_unbiasedsize.width() * wmult),
+ (int)ceil( m_unbiasedsize.height() * hmult));
}
void OSDTypeBox::Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
@@ -1498,44 +1529,52 @@
}
OSDTypePositionRectangle::OSDTypePositionRectangle(
- const OSDTypePositionRectangle &other)
- : OSDType(other.m_name), OSDTypePositionIndicator(other)
+ const OSDTypePositionRectangle &other)
+ : OSDType(other.m_name), OSDTypePositionIndicator(other)
{
for (int i = 0; i < m_numpositions; i++)
{
QRect tmp = other.positions[i];
positions.push_back(tmp);
}
+ for (int i = 0; i < m_numpositions; i++)
+ {
+ QRect tmp = other.unbiasedpos[i];
+ unbiasedpos.push_back(tmp);
+ }
}
OSDTypePositionRectangle::~OSDTypePositionRectangle()
{
}
-void OSDTypePositionRectangle::Reinit(float wchange, float hchange)
+void OSDTypePositionRectangle::Reinit(float wmult, float hmult)
{
for (int i = 0; i < m_numpositions; i++)
{
- QRect tmp = positions[i];
-
- int width = (int)(tmp.width() * wchange);
- int height = (int)(tmp.height() * hchange);
- int x = (int)(tmp.x() * wchange);
- int y = (int)(tmp.y() * hchange);
-
- tmp = QRect(x, y, width, height);
- positions[i] = tmp;
+ QRect tmp = unbiasedpos[i];
+ positions[i] =
+ QRect((int)round(tmp.x() * wmult),
+ (int)round(tmp.y() * hmult),
+ (int)ceil( tmp.width() * wmult),
+ (int)ceil( tmp.height() * hmult));
}
}
-void OSDTypePositionRectangle::AddPosition(QRect rect)
+void OSDTypePositionRectangle::AddPosition(
+ QRect rect, float wmult, float hmult)
{
positions.push_back(rect);
+ unbiasedpos.push_back(
+ QRect((int)round(rect.x() / wmult),
+ (int)round(rect.y() / hmult),
+ (int)ceil( rect.width() / wmult),
+ (int)ceil( rect.height() / hmult)));
m_numpositions++;
}
-void OSDTypePositionRectangle::Draw(OSDSurface *surface, int fade, int maxfade,
- int xoff, int yoff)
+void OSDTypePositionRectangle::Draw(
+ OSDSurface *surface, int fade, int maxfade, int xoff, int yoff)
{
fade = fade;
maxfade = maxfade;
@@ -1618,17 +1657,21 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSDTypePositionImage::OSDTypePositionImage(const QString &name)
- : OSDTypeImage(name), OSDTypePositionIndicator()
+ : OSDTypeImage(name), OSDTypePositionIndicator(),
+ m_wmult(0.0f), m_hmult(0.0f)
{
}
OSDTypePositionImage::OSDTypePositionImage(const OSDTypePositionImage &other)
: OSDTypeImage(other), OSDTypePositionIndicator(other)
{
+ m_wmult = other.m_wmult;
+ m_hmult = other.m_hmult;
+
for (int i = 0; i < m_numpositions; i++)
{
- QPoint tmp = other.positions[i];
- positions.push_back(tmp);
+ positions.push_back(other.positions[i]);
+ unbiasedpos.push_back(other.unbiasedpos[i]);
}
}
@@ -1636,45 +1679,61 @@
{
}
-void OSDTypePositionImage::Reinit(float wchange, float hchange, float wmult,
- float hmult)
+void OSDTypePositionImage::Reinit(float wmult, float hmult)
{
- OSDTypeImage::Reinit(wchange, hchange, wmult, hmult);
+ m_wmult = wmult;
+ m_hmult = hmult;
+
+ OSDTypeImage::Reinit(wmult, hmult);
for (int i = 0; i < m_numpositions; i++)
{
- QPoint tmp = positions[i];
-
- int x = (int)(tmp.x() * wchange);
- int y = (int)(tmp.y() * hchange);
-
- positions[i].setX(x);
- positions[i].setY(y);
+ positions[i] =
+ QPoint((int)round(unbiasedpos[i].x() * wmult),
+ (int)round(unbiasedpos[i].y() * hmult));
}
}
-void OSDTypePositionImage::AddPosition(QPoint pos)
+void OSDTypePositionImage::AddPosition(QPoint pos, float wmult, float hmult)
{
+ if (m_wmult == 0.0f || m_hmult == 0.0f)
+ {
+ m_wmult = wmult;
+ m_hmult = hmult;
+ }
positions.push_back(pos);
+ unbiasedpos.push_back(
+ QPoint((int)round(pos.x() / wmult),
+ (int)round(pos.y() / hmult)));
+
+ VERBOSE(VB_IMPORTANT,
+ "OSDTypePositionImage::AddPosition["<= m_numpositions)
return;
QPoint pos = positions[m_curposition];
- OSDTypeImage::SetPosition(pos);
+ OSDTypeImage::SetPosition(pos, m_wmult, m_hmult);
OSDTypeImage::Draw(surface, fade, maxfade, xoff, yoff);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OSDTypeCC::OSDTypeCC(const QString &name, TTFFont *font, int xoff, int yoff,
- int dispw, int disph)
+ int dispw, int disph, float wmult, float hmult)
: OSDType(name)
{
m_font = font;
@@ -1683,9 +1742,11 @@
yoffset = yoff;
displaywidth = dispw;
displayheight = disph;
+ m_wmult = wmult;
+ m_hmult = hmult;
QRect rect = QRect(0, 0, 0, 0);
- m_box = new OSDTypeBox("cc_background", rect);
+ m_box = new OSDTypeBox("cc_background", rect, wmult, hmult);
m_ccbackground = gContext->GetNumSetting("CCBackground", 0);
}
@@ -1695,12 +1756,23 @@
delete m_box;
}
-void OSDTypeCC::Reinit(int x, int y, int dispw, int disph)
+void OSDTypeCC::Reinit(float wmult, float hmult)
{
+ (void) wmult;
+ (void) hmult;
+ VERBOSE(VB_IMPORTANT, "Programmer error: "
+ "Call to OSDTypeCC::Reinit(float,float)");
+}
+
+void OSDTypeCC::Reinit(int x, int y, int dispw, int disph,
+ float wmult, float hmult)
+{
xoffset = x;
yoffset = y;
displaywidth = dispw;
displayheight = disph;
+ m_wmult = wmult;
+ m_hmult = hmult;
}
void OSDTypeCC::AddCCText(const QString &text, int x, int y, int color,
@@ -1875,7 +1947,7 @@
{
QRect rect = QRect(0, 0, textlength + 4,
(m_font->Size() * 3 / 2) + 3);
- m_box->SetRect(rect);
+ m_box->SetRect(rect, m_wmult, m_hmult);
m_box->Draw(surface, 0, 0, x - 2, y - 2);
}
Index: mythtv/libs/libmythtv/tv_play.cpp
===================================================================
--- mythtv/libs/libmythtv/tv_play.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/tv_play.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -247,7 +247,7 @@
browsechannum(""), browsechanid(""), browsestarttime(""),
// Program Info for currently playing video
recorderPlaybackInfo(NULL),
- playbackinfo(NULL), inputFilename(""), playbackLen(0),
+ playbackinfo(NULL), playbackLen(0),
lastProgram(NULL), jumpToProgram(false),
// Video Players
nvp(NULL), pipnvp(NULL), activenvp(NULL),
@@ -578,19 +578,7 @@
if (!testrec->IsValidRecorder())
{
if (showDialogs)
- {
- QString title = tr("MythTV is already using all available "
- "inputs for recording. If you want to "
- "watch an in-progress recording, select one "
- "from the playback menu. If you want to "
- "watch live TV, cancel one of the "
- "in-progress recordings from the delete "
- "menu.");
-
- DialogBox diag(gContext->GetMainWindow(), title);
- diag.AddButton(tr("Cancel and go back to the TV menu"));
- diag.exec();
- }
+ ShowNoRecorderDialog();
delete testrec;
@@ -659,8 +647,6 @@
if (internalState != kState_None)
return 0;
- inputFilename = rcinfo->pathname;
-
playbackLen = rcinfo->CalculateLength();
playbackinfo = new ProgramInfo(*rcinfo);
@@ -844,9 +830,10 @@
}
else
{
+ QString playbackURL = playbackinfo->GetPlaybackURL();
+
tvchain->SetProgram(playbackinfo);
-
- prbuffer = new RingBuffer(playbackinfo->pathname, false);
+ prbuffer = new RingBuffer(playbackURL, false);
prbuffer->SetLiveMode(tvchain);
}
@@ -895,7 +882,14 @@
else if (TRANSITION(kState_None, kState_WatchingPreRecorded) ||
TRANSITION(kState_None, kState_WatchingRecording))
{
- prbuffer = new RingBuffer(inputFilename, false);
+ QString playbackURL;
+ if ((playbackinfo->pathname.left(4) == "dvd:") ||
+ (playbackinfo->isVideo))
+ playbackURL = playbackinfo->pathname;
+ else
+ playbackURL = playbackinfo->GetPlaybackURL();
+
+ prbuffer = new RingBuffer(playbackURL, false);
if (prbuffer->IsOpen())
{
gContext->DisableScreensaver();
@@ -924,7 +918,7 @@
{
QString message = "COMMFLAG_REQUEST ";
message += playbackinfo->chanid + " " +
- playbackinfo->startts.toString(Qt::ISODate);
+ playbackinfo->recstartts.toString(Qt::ISODate);
RemoteSendMessage(message);
}
}
@@ -1222,10 +1216,10 @@
nvp->SetParentPlayer(this);
nvp->SetRingBuffer(prbuffer);
nvp->SetRecorder(recorder);
- nvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate"));
+ nvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate", 44100));
nvp->SetAudioDevice(gContext->GetSetting("AudioOutputDevice"));
nvp->SetLength(playbackLen);
- nvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking"));
+ nvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking", 0));
nvp->SetAutoCommercialSkip(autoCommercialSkip);
nvp->SetLiveTVChain(tvchain);
@@ -1296,9 +1290,9 @@
pipnvp->SetAsPIP();
pipnvp->SetRingBuffer(piprbuffer);
pipnvp->SetRecorder(piprecorder);
- pipnvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate"));
+ pipnvp->SetAudioSampleRate(gContext->GetNumSetting("AudioSampleRate", 44100));
pipnvp->SetAudioDevice(gContext->GetSetting("AudioOutputDevice"));
- pipnvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking"));
+ pipnvp->SetExactSeeks(gContext->GetNumSetting("ExactSeeking", 0));
pipnvp->SetLiveTVChain(piptvchain);
pipnvp->SetLength(playbackLen);
@@ -1454,6 +1448,30 @@
lastSignalMsg.clear();
}
UpdateOSDTimeoutMessage();
+
+ if (!tvchainUpdate.isEmpty())
+ {
+ tvchainUpdateLock.lock();
+ for (QStringList::Iterator it = tvchainUpdate.begin();
+ it != tvchainUpdate.end(); ++it)
+ {
+ if (tvchain && nvp && *it == tvchain->GetID())
+ {
+ tvchain->ReloadAll();
+ if (nvp->GetTVChain())
+ nvp->CheckTVChain();
+ }
+ if (piptvchain && pipnvp && *it == piptvchain->GetID())
+ {
+ piptvchain->ReloadAll();
+ if (pipnvp->GetTVChain())
+ pipnvp->CheckTVChain();
+ }
+ }
+ tvchainUpdate.clear();
+ tvchainUpdateLock.unlock();
+ }
+
osdlock.unlock();
}
@@ -2743,7 +2761,7 @@
speedStr = QString("%1X").arg(normal_speed);
struct StatusPosInfo posInfo;
- nvp->calcSliderPos(posInfo);
+ nvp->calcSliderPos(posInfo, true);
QDateTime respDate = mythCurrentDateTime();
QString infoStr = "";
@@ -2806,8 +2824,10 @@
}
else
{
+ QString playbackURL = playbackinfo->GetPlaybackURL();
+
piptvchain->SetProgram(playbackinfo);
- piprbuffer = new RingBuffer(playbackinfo->pathname, false);
+ piprbuffer = new RingBuffer(playbackURL, false);
piprbuffer->SetLiveMode(piptvchain);
}
@@ -3472,8 +3492,10 @@
}
else
{
+ QString playbackURL = playbackinfo->GetPlaybackURL();
+
tvchain->SetProgram(playbackinfo);
- prbuffer = new RingBuffer(playbackinfo->pathname, false);
+ prbuffer = new RingBuffer(playbackURL, false);
prbuffer->SetLiveMode(tvchain);
}
@@ -4627,7 +4649,8 @@
normal_speed = new_normal_speed;
- activenvp->Play(normal_speed, true);
+ if (!paused)
+ activenvp->Play(normal_speed, true);
QString text = QString(tr("Time Stretch %1X")).arg(normal_speed);
@@ -4911,29 +4934,14 @@
}
else if (tvchain && message.left(12) == "LIVETV_CHAIN")
{
- // Get osdlock, while intended for the OSD this ensures that
- // the nvp & pipnvp are not deleted while we are using it..
- while (!osdlock.tryLock() && nvp)
- usleep(2500);
-
message = message.simplifyWhiteSpace();
QStringList tokens = QStringList::split(" ", message);
if (tokens[1] == "UPDATE")
{
- if (tvchain && nvp && tokens[2] == tvchain->GetID())
- {
- tvchain->ReloadAll();
- if (nvp->GetTVChain())
- nvp->CheckTVChain();
- }
- if (piptvchain && pipnvp && tokens[2] == piptvchain->GetID())
- {
- piptvchain->ReloadAll();
- if (pipnvp->GetTVChain())
- pipnvp->CheckTVChain();
- }
+ tvchainUpdateLock.lock();
+ tvchainUpdate += QDeepCopy(tokens[2]);
+ tvchainUpdateLock.unlock();
}
- osdlock.unlock();
}
else if (nvp && message.left(12) == "EXIT_TO_MENU")
{
@@ -4983,7 +4991,7 @@
QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
if ((playbackinfo->chanid == evchanid) &&
- (playbackinfo->startts == evstartts))
+ (playbackinfo->recstartts == evstartts))
{
QString msg = "COMMFLAG_REQUEST ";
msg += tokens[1] + " " + tokens[2];
@@ -5000,7 +5008,7 @@
QDateTime evstartts = QDateTime::fromString(tokens[2], Qt::ISODate);
if ((playbackinfo->chanid == evchanid) &&
- (playbackinfo->startts == evstartts))
+ (playbackinfo->recstartts == evstartts))
{
QMap newMap;
QStringList mark;
@@ -6067,9 +6075,22 @@
"in-progress recordings from the delete "
"menu.");
- MythPopupBox::showOkPopup(
+ if (embedWinID)
+ {
+ VERBOSE(VB_IMPORTANT, errorText);
+ }
+ else if (GetOSD())
+ {
+ dialogname = "infobox";
+ QStringList options("OK");
+ GetOSD()->NewDialogBox(dialogname, errorText, options, 0);
+ }
+ else
+ {
+ MythPopupBox::showOkPopup(
gContext->GetMainWindow(), QObject::tr("Channel Change Error"),
errorText);
+ }
}
/** \fn TV::PauseLiveTV(void)
Index: mythtv/libs/libmythtv/jobqueue.cpp
===================================================================
--- mythtv/libs/libmythtv/jobqueue.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/jobqueue.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -275,6 +275,11 @@
(hostname != "") &&
(hostname != m_hostname))
{
+ // Setting the status here will prevent us from processing
+ // any other jobs for this recording until this one is
+ // completed on the remote host.
+ jobStatus[key] = status;
+
message = QString("JobQueue: Skipping '%1' job for chanid "
"%2 @ %3, should run on '%4' instead")
.arg(JobText(type))
Index: mythtv/libs/libmythtv/dvbdev/dvbdev.c
===================================================================
--- mythtv/libs/libmythtv/dvbdev/dvbdev.c (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/dvbdev/dvbdev.c (.../branches/release-0-19-fixes) (revision 10931)
@@ -29,55 +29,79 @@
const char* dvbdevice(int type, int cardnum)
{
- char* frontenddev[4] =
+ char* frontenddev[8] =
{
"/dev/dvb/adapter0/frontend0",
"/dev/dvb/adapter1/frontend0",
"/dev/dvb/adapter2/frontend0",
- "/dev/dvb/adapter3/frontend0"
+ "/dev/dvb/adapter3/frontend0",
+ "/dev/dvb/adapter4/frontend0",
+ "/dev/dvb/adapter5/frontend0",
+ "/dev/dvb/adapter6/frontend0",
+ "/dev/dvb/adapter7/frontend0",
};
- char* dvrdev[4] =
+ char* dvrdev[8] =
{
"/dev/dvb/adapter0/dvr0",
"/dev/dvb/adapter1/dvr0",
"/dev/dvb/adapter2/dvr0",
- "/dev/dvb/adapter3/dvr0"
+ "/dev/dvb/adapter3/dvr0",
+ "/dev/dvb/adapter4/dvr0",
+ "/dev/dvb/adapter5/dvr0",
+ "/dev/dvb/adapter6/dvr0",
+ "/dev/dvb/adapter7/dvr0",
};
- char* demuxdev[4] =
+ char* demuxdev[8] =
{
"/dev/dvb/adapter0/demux0",
"/dev/dvb/adapter1/demux0",
"/dev/dvb/adapter2/demux0",
- "/dev/dvb/adapter3/demux0"
+ "/dev/dvb/adapter3/demux0",
+ "/dev/dvb/adapter4/demux0",
+ "/dev/dvb/adapter5/demux0",
+ "/dev/dvb/adapter6/demux0",
+ "/dev/dvb/adapter7/demux0",
};
- char* cadev[4] =
+ char* cadev[8] =
{
"/dev/dvb/adapter0/ca0",
"/dev/dvb/adapter1/ca0",
"/dev/dvb/adapter2/ca0",
- "/dev/dvb/adapter3/ca0"
+ "/dev/dvb/adapter3/ca0",
+ "/dev/dvb/adapter4/ca0",
+ "/dev/dvb/adapter5/ca0",
+ "/dev/dvb/adapter6/ca0",
+ "/dev/dvb/adapter7/ca0",
};
- char* audiodev[4] =
+ char* audiodev[8] =
{
"/dev/dvb/adapter0/audio0",
"/dev/dvb/adapter1/audio0",
"/dev/dvb/adapter2/audio0",
- "/dev/dvb/adapter3/audio0"
+ "/dev/dvb/adapter3/audio0",
+ "/dev/dvb/adapter4/audio0",
+ "/dev/dvb/adapter5/audio0",
+ "/dev/dvb/adapter6/audio0",
+ "/dev/dvb/adapter7/audio0",
};
- char* videodev[4] =
+ char* videodev[8] =
{
"/dev/dvb/adapter0/video0",
"/dev/dvb/adapter1/video0",
"/dev/dvb/adapter2/video0",
- "/dev/dvb/adapter3/video0"
+ "/dev/dvb/adapter3/video0",
+ "/dev/dvb/adapter4/video0",
+ "/dev/dvb/adapter5/video0",
+ "/dev/dvb/adapter6/video0",
+ "/dev/dvb/adapter7/video0",
};
- if (cardnum > 3)
+ if (cardnum > 7)
return 0;
switch(type)
Index: mythtv/libs/libmythtv/videosource.h
===================================================================
--- mythtv/libs/libmythtv/videosource.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/videosource.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -75,6 +75,7 @@
static CARD_TYPES GetDVBType(uint device, QString &name, QString &card_type);
static bool HasDVBCRCBug(uint device);
+ static uint GetMinSignalMonitoringDelay(uint device);
static QString GetDefaultInput(uint cardid);
static bool IgnoreEncrypted(uint cardid, const QString &inputname);
Index: mythtv/libs/libmythtv/libmythtv.pro
===================================================================
--- mythtv/libs/libmythtv/libmythtv.pro (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/libmythtv.pro (.../branches/release-0-19-fixes) (revision 10931)
@@ -119,6 +119,10 @@
SOURCES += playgroup.cpp
SOURCES += progdetails.cpp
+# C stuff
+HEADERS += frequencies.h
+SOURCES += frequencies.c
+
using_frontend {
# Recording profile stuff
HEADERS += profilegroup.h
@@ -144,10 +148,10 @@
# On screen display (video output overlay)
HEADERS += osd.h osdtypes.h
HEADERS += osdsurface.h osdlistbtntype.h
- HEADERS += udpnotify.h
+ HEADERS += osdimagecache.h udpnotify.h
SOURCES += osd.cpp osdtypes.cpp
SOURCES += osdsurface.cpp osdlistbtntype.cpp
- SOURCES += udpnotify.cpp
+ SOURCES += osdimagecache.cpp udpnotify.cpp
# Video output
HEADERS += videooutbase.h videoout_null.h
@@ -303,10 +307,6 @@
}
}
- # C stuff
- HEADERS += frequencies.h
- SOURCES += frequencies.c
-
DEFINES += USING_BACKEND
}
Index: mythtv/libs/libmythtv/dvbchannel.cpp
===================================================================
--- mythtv/libs/libmythtv/dvbchannel.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/dvbchannel.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -74,14 +74,27 @@
* \bug Only supports single input cards.
*/
DVBChannel::DVBChannel(int aCardNum, TVRec *parent)
- : QObject(NULL, "DVBChannel"), ChannelBase(parent),
- diseqc(NULL), dvbcam(NULL),
- fd_frontend(-1), cardnum(aCardNum), has_crc_bug(false),
- currentTID(-1), first_tune(true)
+ : QObject(NULL, "DVBChannel"), ChannelBase(parent),
+ diseqc(NULL), dvbcam(NULL),
+ fd_frontend(-1), cardnum(aCardNum),
+ has_crc_bug(false),
+ tuning_delay(0), sigmon_delay(25),
+ currentTID(-1), first_tune(true),
+ retune_adj(-10)
{
dvbcam = new DVBCam(cardnum);
bzero(&info, sizeof(info));
has_crc_bug = CardUtil::HasDVBCRCBug(aCardNum);
+
+ QString name(""), type("");
+ CardUtil::GetDVBType(aCardNum, name, type);
+ if ((name == "DiBcom 3000P/M-C DVB-T") ||
+ (name == "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"))
+ {
+ tuning_delay = 200;
+ }
+
+ sigmon_delay = CardUtil::GetMinSignalMonitoringDelay(aCardNum);
}
DVBChannel::~DVBChannel()
@@ -367,7 +380,7 @@
}
bool found = false;
- int mplexid;
+ int mplexid = 0;
while (query.next())
{
int this_inputid = query.value(4).toInt();
@@ -633,7 +646,8 @@
* This is used by DVB Channel Scanner, the EIT Parser, and by TVRec.
*
* \param channel Info on transport to tune to
- * \param force_reset If true frequency tuning is done even if not strictly needed
+ * \param force_reset If true, frequency tuning is done
+ * even if it should not be needed.
* \return true on success, false on failure
*/
bool DVBChannel::Tune(const dvb_channel_t& channel, bool force_reset)
@@ -642,6 +656,8 @@
bool has_diseq = (FE_QPSK == info.type) && diseqc;
struct dvb_frontend_parameters params = channel.tuning.params;
+ retune_tuning = channel.tuning;
+
if (fd_frontend < 0)
{
ERROR("DVBChannel::Tune: Card not open!");
@@ -669,15 +685,22 @@
// Adjust for Satelite recievers which offset the frequency.
params.frequency = tuned_frequency(channel.tuning, info.type, NULL);
+ params.frequency = params.frequency + (retune_adj = -retune_adj);
+
if (ioctl(fd_frontend, FE_SET_FRONTEND, ¶ms) < 0)
{
ERRNO("DVBChannel::Tune: "
"Setting Frontend tuning parameters failed.");
return false;
}
+
+ // Extra delay to add for broken DVB drivers
+ if (tuning_delay)
+ usleep(tuning_delay * 1000);
+
wait_for_backend(fd_frontend, 5 /* msec */);
- prev_tuning.params = params;
+ prev_tuning.params = channel.tuning.params;
first_tune = false;
}
@@ -686,6 +709,24 @@
return true;
}
+/** \fn DVBChannel::Retune(void)
+ * \brief Calls DVBChannel::Tune() with the last known parameters
+ *
+ * This is used to retune DVB-C hardware. DVB-C hardware
+ * sometimes does not successfully tune the first time
+ * despite reports of success from the drivers. This is
+ * probably a hardware problem and not a driver problem
+ * per say, so it is unlikely to be fixed at a lower level.
+ *
+ * \return true iff drivers report that tuning was successful
+ */
+bool DVBChannel::Retune(void)
+{
+ dvb_channel_t retune_channel;
+ retune_channel.tuning = retune_tuning;
+ return Tune(retune_channel, true);
+}
+
/** \fn DVBChannel::GetTuningParams(DVBTuning& tuning) const
* \brief Fetches DVBTuning params from driver
* \return true on success, false on failure
@@ -855,6 +896,9 @@
for (uint i = 0; i < 64 && !tuned; i++)
if (!diseqc->Set(t, reset, tuned))
return false;
-
+
+ // Wait 10 ms, recommended by Marcus Metzler, see #1552
+ usleep(10 * 1000);
+
return true;
}
Index: mythtv/libs/libmythtv/osdtypes.h
===================================================================
--- mythtv/libs/libmythtv/osdtypes.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/osdtypes.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -8,6 +8,7 @@
#include
#include
#include
+#include "osdimagecache.h"
using namespace std;
@@ -137,6 +138,8 @@
QString Name() { return m_name; }
+ virtual void Reinit(float wmult, float hmult) = 0;
+
virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
int yoff) = 0;
@@ -150,11 +153,11 @@
{
public:
OSDTypeText(const QString &name, TTFFont *font, const QString &text,
- QRect displayrect);
+ QRect displayrect, float wmult, float hmult);
OSDTypeText(const OSDTypeText &text);
~OSDTypeText();
- void Reinit(float wchange, float hchange);
+ void Reinit(float wmult, float hmult);
void SetAltFont(TTFFont *font);
void SetUseAlt(bool usealt) { m_usingalt = usealt; }
@@ -190,6 +193,7 @@
QRect m_displaysize;
QRect m_screensize;
+ QRect m_unbiasedsize;
QString m_message;
QString m_default_msg;
@@ -231,7 +235,7 @@
virtual ~OSDTypeImage();
void SetName(const QString &name);
- void Reinit(float wchange, float hchange, float wmult, float hmult);
+ void Reinit(float wmult, float hmult);
void LoadImage(const QString &filename, float wmult, float hmult,
int scalew = -1, int scaleh = -1);
@@ -239,21 +243,20 @@
void SetStaticSize(int scalew, int scaleh) { m_scalew = scalew;
m_scaleh = scaleh; }
+ void SetPosition(QPoint pos, float wmult, float hmult);
- QPoint DisplayPos() { return m_displaypos; }
- void SetPosition(QPoint pos) { m_displaypos = pos; }
+ QPoint DisplayPos() const { return m_displaypos; }
+ QRect ImageSize() const { return m_imagesize; }
+ int width() const { return m_imagesize.width(); }
+ int height() const { return m_imagesize.height(); }
- QRect ImageSize() { return m_imagesize; }
-
- int width() { return m_imagesize.width(); }
- int height() { return m_imagesize.height(); }
-
virtual void Draw(OSDSurface *surface, int fade, int maxfade, int xoff,
int yoff);
protected:
QRect m_imagesize;
QPoint m_displaypos;
+ QPoint m_unbiasedpos;
QString m_filename;
@@ -270,6 +273,9 @@
int m_drawwidth;
bool m_onlyusefirst;
+
+ static OSDImageCache c_cache;
+ OSDImageCacheValue *m_cacheitem;
};
class OSDTypePosSlider : public OSDTypeImage
@@ -280,7 +286,7 @@
int scalew = -1, int scaleh = -1);
~OSDTypePosSlider();
- void Reinit(float wchange, float hchange, float wmult, float hmult);
+ void Reinit(float wmult, float hmult);
void SetRectangle(QRect rect) { m_displayrect = rect; }
QRect ImageSize() { return m_imagesize; }
@@ -290,6 +296,7 @@
private:
QRect m_displayrect;
+ QRect m_unbiasedrect;
int m_maxval;
int m_curval;
};
@@ -302,7 +309,7 @@
int scalew = -1, int scaleh = -1);
~OSDTypeFillSlider();
- void Reinit(float wchange, float hchange, float wmult, float hmult);
+ void Reinit(float wmult, float hmult);
void SetRectangle(QRect rect) { m_displayrect = rect; }
QRect ImageSize() { return m_imagesize; }
@@ -314,6 +321,7 @@
private:
QRect m_displayrect;
+ QRect m_unbiasedrect;
int m_maxval;
int m_curval;
};
@@ -327,7 +335,7 @@
int scalew = -1, int scaleh = -1);
~OSDTypeEditSlider();
- void Reinit(float wchange, float hchange, float wmult, float hmult);
+ void Reinit(float wmult, float hmult);
void SetRectangle(QRect rect) { m_displayrect = rect; }
QRect ImageSize() { return m_imagesize; }
@@ -339,6 +347,7 @@
private:
QRect m_displayrect;
+ QRect m_unbiasedrect;
int m_maxval;
int m_curval;
@@ -360,17 +369,19 @@
class OSDTypeBox : public OSDType
{
public:
- OSDTypeBox(const QString &name, QRect displayrect);
+ OSDTypeBox(const QString &name, QRect displayrect,
+ float wmult, float hmult);
OSDTypeBox(const OSDTypeBox &other);
~OSDTypeBox();
- void Reinit(float wchange, float hchange);
- void SetRect(QRect newrect) { size = newrect; }
+ void Reinit(float wmult, float hmult);
+ void SetRect(QRect newrect, float wmult, float hmult);
void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
private:
QRect size;
+ QRect m_unbiasedsize;
};
class OSDTypePositionIndicator
@@ -403,14 +414,15 @@
OSDTypePositionRectangle(const OSDTypePositionRectangle &other);
~OSDTypePositionRectangle();
- void AddPosition(QRect rect);
+ void AddPosition(QRect rect, float wmult, float hmult);
- void Reinit(float wchange, float hchange);
+ void Reinit(float wmult, float hmult);
void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
private:
- vector positions;
+ vector positions;
+ vector unbiasedpos;
};
class OSDTypePositionImage : public virtual OSDTypeImage,
@@ -421,14 +433,17 @@
OSDTypePositionImage(const OSDTypePositionImage &other);
~OSDTypePositionImage();
- void Reinit(float wchange, float hchange, float wmult, float hmult);
+ void Reinit(float wmult, float hmult);
- void AddPosition(QPoint pos);
+ void AddPosition(QPoint pos, float wmult, float hmult);
void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff);
private:
vector positions;
+ vector unbiasedpos;
+ float m_wmult;
+ float m_hmult;
};
class ccText
@@ -445,11 +460,15 @@
{
public:
OSDTypeCC(const QString &name, TTFFont *font, int xoff, int yoff,
- int dispw, int disph);
+ int dispw, int disph, float wmult, float hmult);
~OSDTypeCC();
- void Reinit(int xoff, int yoff, int dispw, int disph);
+ void Reinit(float wmult, float hmult);
+ void Reinit(int xoff, int yoff,
+ int dispw, int disph,
+ float wmult, float hmult);
+
void AddCCText(const QString &text, int x, int y, int color,
bool teletextmode = false);
void ClearAllCCText();
@@ -464,7 +483,7 @@
vector *m_textlist;
OSDTypeBox *m_box;
int m_ccbackground;
-
+ float m_wmult, m_hmult;
int xoffset, yoffset, displaywidth, displayheight;
};
Index: mythtv/libs/libmythtv/videoout_xv.h
===================================================================
--- mythtv/libs/libmythtv/videoout_xv.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/videoout_xv.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -80,6 +80,8 @@
virtual bool hasVLDAcceleration(void) const
{ return XVideoVLD == VideoOutputSubType(); }
+ void CheckFrameStates(void);
+
static MythCodecID GetBestSupportedCodec(uint width, uint height,
uint osd_width, uint osd_height,
uint stream_type, int xvmc_chroma,
@@ -141,7 +143,7 @@
static bool IsRendering(VideoFrame* frame);
static void SyncSurface(VideoFrame* frame, int past_future = 0);
static void FlushSurface(VideoFrame* frame);
- void CheckDisplayedFramesForAvailability(void);
+
#ifdef USING_XVMC
XvMCOSD* GetAvailableOSD();
void ReturnAvailableOSD(XvMCOSD*);
Index: mythtv/libs/libmythtv/osdimagecache.h
===================================================================
--- mythtv/libs/libmythtv/osdimagecache.h (.../tags/release-0-19) (revision 0)
+++ mythtv/libs/libmythtv/osdimagecache.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -0,0 +1,74 @@
+// -*- Mode: c++ -*-
+
+// POSIX headers
+#include
+
+// Qt headers
+#include
+#include
+#include
+#include
+#include
+
+class OSDImageCacheValue
+{
+ public:
+ OSDImageCacheValue(QString cacheKey,
+ unsigned char *yuv, unsigned char *ybuffer,
+ unsigned char *ubuffer, unsigned char *vbuffer,
+ unsigned char *alpha, QRect imagesize);
+
+ virtual ~OSDImageCacheValue();
+
+ uint GetSize(void) const { return m_size_in_bytes; }
+ QString GetKey(void) const { return m_cacheKey; }
+
+ public:
+ unsigned char *m_yuv;
+ unsigned char *m_ybuffer;
+ unsigned char *m_ubuffer;
+ unsigned char *m_vbuffer;
+ unsigned char *m_alpha;
+ QRect m_imagesize;
+
+ private:
+ uint m_size_in_bytes;
+ QString m_cacheKey;
+};
+
+typedef QAsciiCache img_cache_t;
+
+class OSDImageCache
+{
+ public:
+ OSDImageCache();
+ virtual ~OSDImageCache();
+
+ bool InFileCache(const QString &key) const;
+
+ bool Contains(const QString &key, bool useFile) const;
+
+ OSDImageCacheValue *Get(const QString &key, bool useFile);
+
+ void Insert(OSDImageCacheValue* value);
+
+ void SaveToDisk(const OSDImageCacheValue *value);
+
+ void Reset(void);
+
+ static QString CreateKey(const QString &filename,
+ float wmult, float hmult,
+ int scalew, int scaleh);
+
+ static QString ExtractOriginal(const QString &key);
+
+ private:
+ mutable QMutex m_cacheLock;
+ img_cache_t m_imageCache;
+ int m_memHits;
+ int m_diskHits;
+ int m_misses;
+
+ /// Limit on the maximum total size of OSD images cached in *memory*.
+ static uint kMaximumMemoryCacheSize;
+};
Index: mythtv/libs/libmythtv/tv_play.h
===================================================================
--- mythtv/libs/libmythtv/tv_play.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/tv_play.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -456,7 +456,6 @@
ProgramInfo *recorderPlaybackInfo; ///< info requested from recorder
ProgramInfo *playbackinfo; ///< info sent in via Playback()
QMutex pbinfoLock;
- QString inputFilename; ///< playbackinfo->pathname
int playbackLen; ///< initial playbackinfo->CalculateLength()
ProgramInfo *lastProgram; ///< last program played with this player
bool jumpToProgram;
@@ -485,6 +484,8 @@
// LiveTVChain
LiveTVChain *tvchain;
LiveTVChain *piptvchain;
+ QStringList tvchainUpdate;
+ QMutex tvchainUpdateLock;
// RingBuffers
RingBuffer *prbuffer;
Index: mythtv/libs/libmythtv/videosource.cpp
===================================================================
--- mythtv/libs/libmythtv/videosource.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/videosource.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -32,6 +32,7 @@
#include "videosource.h"
#include "datadirect.h"
#include "scanwizard.h"
+#include "frequencies.h"
#ifdef USING_DVB
#include
@@ -156,6 +157,17 @@
(name == "ST STV0299 DVB-S")); // munges PAT
}
+uint CardUtil::GetMinSignalMonitoringDelay(uint device)
+{
+ QString name(""), type("");
+ GetDVBType(device, name, type);
+ if (name.find("DVB-S") >= 0)
+ return 300;
+ if (name == "DiBcom 3000P/M-C DVB-T")
+ return 100;
+ return 25;
+}
+
/** \fn CardUtil::GetCardType(uint, QString&, QString&)
* \brief Returns the card type from the video device
* \param nCardID cardid of card to be checked
@@ -574,22 +586,10 @@
{
setLabel(QObject::tr("Channel frequency table"));
addSelection("default");
- addSelection("us-cable");
- addSelection("us-bcast");
- addSelection("us-cable-hrc");
- addSelection("japan-bcast");
- addSelection("japan-cable");
- addSelection("europe-west");
- addSelection("europe-east");
- addSelection("italy");
- addSelection("newzealand");
- addSelection("australia");
- addSelection("ireland");
- addSelection("france");
- addSelection("china-bcast");
- addSelection("southafrica");
- addSelection("argentina");
- addSelection("australia-optus");
+
+ for (uint i = 0; chanlists[i].name; i++)
+ addSelection(chanlists[i].name);
+
setHelpText(QObject::tr("Use default unless this source uses a "
"different frequency table than the system wide table "
"defined in the General settings."));
Index: mythtv/libs/libmythtv/frequencytables.cpp
===================================================================
--- mythtv/libs/libmythtv/frequencytables.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/frequencytables.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -283,104 +283,52 @@
"ATSC Channel %1", 70, 809000000, 887000000, 6000000, VSB_8);
#endif // USING_DVB
- // USA Cable, QAM 256
- fmap["atsc_qam256_uscable0"] = new FrequencyTable(
- "QAM-256 Channel %1", 1, 75000000,1005000000, 6000000, QAM_256);
- fmap["atsc_qam256_uscable1"] = new FrequencyTable(
- "QAM-256 Channel T-%1", 7, 10000000, 52000000, 6000000, QAM_256);
+ QString modStr[] = { "vsb8", "qam256", "qam128", "qam64", };
+ uint mod[] = { VSB_8, QAM_256, QAM_128, QAM_64, };
+ QString desc[] = { "ATSC ", "QAM-256 ", "QAM-128 ", "QAM-64 ", };
- // USA Cable, QAM 256 ch 78+
- fmap["atsc_qam256_uscablehigh0"] = new FrequencyTable(
- "QAM-256 Channel %1", 78,472000000,1005000000, 6000000, QAM_256);
+#define FREQ(A,B, C,D, E,F,G, H) \
+ fmap[QString("atsc_%1_us%2").arg(A).arg(B)] = \
+ new FrequencyTable(C+D, E, F, G, 6000000, H);
- // USA Cable HRC, QAM 256
- fmap["atsc_qam256_ushrc0"] = new FrequencyTable(
- "QAM-256 HRC %1", 1, 73750000, 73750001, 6000000, QAM_256);
- fmap["atsc_qam256_ushrc1"] = new FrequencyTable(
- "QAM-256 HRC %1", 2, 55750000, 67750000, 6000000, QAM_256);
- fmap["atsc_qam256_ushrc2"] = new FrequencyTable(
- "QAM-256 HRC %1", 5, 79750000, 85750000, 6000000, QAM_256);
- fmap["atsc_qam256_ushrc3"] = new FrequencyTable(
- "QAM-256 HRC %1", 7, 175750000, 643750000, 6000000, QAM_256);
- fmap["atsc_qam256_ushrc4"] = new FrequencyTable(
- "QAM-256 HRC %1", 95, 91750000, 114000000, 6000000, QAM_256);
- fmap["atsc_qam256_ushrc5"] = new FrequencyTable(
- "QAM-256 HRC %1", 100, 649750000, 799750000, 6000000, QAM_256);
- fmap["atsc_qam256_ushrc6"] = new FrequencyTable(
- "QAM-256 HRC T-%1", 7, 8175000, 50750000, 6000000, QAM_256);
+ for (uint i = 0; i < 4; i++)
+ {
+ // USA Cable, ch 1 to 155 and T.7 to T.14
+ FREQ(modStr[i], "cable0", desc[i], "Channel %1",
+ 1, 75000000, 1005000000, mod[i]);
+ FREQ(modStr[i], "cable1", desc[i], "Channel T-%1",
+ 7, 10000000, 52000000, mod[i]);
+ // USA Cable, QAM 256 ch 78 to 155
+ FREQ(modStr[i], "cablehigh0", desc[i], "Channel %1",
+ 78, 537000000,1005000000, mod[i]);
- // USA Cable HRC, QAM 256 ch 78+
- fmap["atsc_qam256_ushrchigh0"] = new FrequencyTable(
- "QAM-256 HRC %1", 78, 601750000, 643750000, 6000000, QAM_256);
- fmap["atsc_qam256_ushrchigh1"] = new FrequencyTable(
- "QAM-256 HRC %1", 100, 649750000, 799750000, 6000000, QAM_256);
+ QString std[] = { "hrc", "irc" };
+ QString sdesc[] = { "HRC ", "IRC " };
+ int off[] = { 0, 1250000 };
+ for (uint j = 0; j < 2; j++)
+ {
+ // USA Cable HRC/IRC, ch 1 to 125
+ FREQ(modStr[i], std[j] + "0", desc[i], sdesc[j] + "%1",
+ 1, 73750000 + off[j], 73750001 + off[j], mod[i]);
+ FREQ(modStr[i], std[j] + "1", desc[i], sdesc[j] + "%1",
+ 2, 55750000 + off[j], 67750000 + off[j], mod[i]);
+ FREQ(modStr[i], std[j] + "2", desc[i], sdesc[j] + "%1",
+ 5, 79750000 + off[j], 85750000 + off[j], mod[i]);
+ FREQ(modStr[i], std[j] + "3", desc[i], sdesc[j] + "%1",
+ 7, 175750000 + off[j], 643750000 + off[j], mod[i]);
+ FREQ(modStr[i], std[j] + "4", desc[i], sdesc[j] + "%1",
+ 95, 91750000 + off[j], 114000000 + off[j], mod[i]);
+ FREQ(modStr[i], std[j] + "5", desc[i], sdesc[j] + "%1",
+ 100, 649750000 + off[j], 799750000 + off[j], mod[i]);
+ FREQ(modStr[i], std[j] + "6", desc[i], sdesc[j] + "T-%1",
+ 7, 8175000 + off[j], 50750000 + off[j], mod[i]);
-
- // USA Cable, QAM 128
- fmap["atsc_qam128_uscable0"] = new FrequencyTable(
- "QAM-128 Channel %1", 1, 75000000,1005000000, 6000000, QAM_128);
- fmap["atsc_qam128_uscable1"] = new FrequencyTable(
- "QAM-128 Channel T-%1", 7, 10000000, 52000000, 6000000, QAM_128);
-
- // USA Cable, QAM 128 ch 78+
- fmap["atsc_qam128_uscablehigh0"] = new FrequencyTable(
- "QAM-128 Channel %1", 78,472000000,1005000000, 6000000, QAM_128);
-
- // USA Cable HRC, QAM 128
- fmap["atsc_qam128_ushrc0"] = new FrequencyTable(
- "QAM-128 HRC %1", 1, 73750000, 73750001, 6000000, QAM_128);
- fmap["atsc_qam128_ushrc1"] = new FrequencyTable(
- "QAM-128 HRC %1", 2, 55750000, 67750000, 6000000, QAM_128);
- fmap["atsc_qam128_ushrc2"] = new FrequencyTable(
- "QAM-128 HRC %1", 5, 79750000, 85750000, 6000000, QAM_128);
- fmap["atsc_qam128_ushrc3"] = new FrequencyTable(
- "QAM-128 HRC %1", 7, 175750000, 643750000, 6000000, QAM_128);
- fmap["atsc_qam128_ushrc4"] = new FrequencyTable(
- "QAM-128 HRC %1", 95, 91750000, 114000000, 6000000, QAM_128);
- fmap["atsc_qam128_ushrc5"] = new FrequencyTable(
- "QAM-128 HRC %1", 100, 649750000, 799750000, 6000000, QAM_128);
- fmap["atsc_qam128_ushrc6"] = new FrequencyTable(
- "QAM-128 HRC T-%1", 7, 8175000, 50750000, 6000000, QAM_128);
-
- // USA Cable HRC, QAM 128 ch 78+
- fmap["atsc_qam128_ushrchigh0"] = new FrequencyTable(
- "QAM-128 HRC %1", 78, 601750000, 643750000, 6000000, QAM_128);
- fmap["atsc_qam128_ushrchigh1"] = new FrequencyTable(
- "QAM-128 HRC %1", 100, 649750000, 799750000, 6000000, QAM_128);
-
-
-
-
- // USA Cable, QAM 64
- fmap["atsc_qam64_uscable0"] = new FrequencyTable(
- "QAM-64 Channel %1", 1, 75000000,1005000000, 6000000, QAM_64);
- fmap["atsc_qam64_uscable1"] = new FrequencyTable(
- "QAM-64 Channel T-%1", 7, 10000000, 52000000, 6000000, QAM_64);
-
- // USA Cable, QAM 64 ch 78+
- fmap["atsc_qam64_uscablehigh0"] = new FrequencyTable(
- "QAM-64 Channel %1", 78,472000000,1005000000, 6000000, QAM_64);
-
- // USA Cable HRC, QAM 64
- fmap["atsc_qam64_ushrc0"] = new FrequencyTable(
- "QAM-64 HRC %1", 1, 73750000, 73750001, 6000000, QAM_64);
- fmap["atsc_qam64_ushrc1"] = new FrequencyTable(
- "QAM-64 HRC %1", 2, 55750000, 67750000, 6000000, QAM_64);
- fmap["atsc_qam64_ushrc2"] = new FrequencyTable(
- "QAM-64 HRC %1", 5, 79750000, 85750000, 6000000, QAM_64);
- fmap["atsc_qam64_ushrc3"] = new FrequencyTable(
- "QAM-64 HRC %1", 7, 175750000, 643750000, 6000000, QAM_64);
- fmap["atsc_qam64_ushrc4"] = new FrequencyTable(
- "QAM-64 HRC %1", 95, 91750000, 114000000, 6000000, QAM_64);
- fmap["atsc_qam64_ushrc5"] = new FrequencyTable(
- "QAM-64 HRC %1", 100, 649750000, 799750000, 6000000, QAM_64);
- fmap["atsc_qam64_ushrc6"] = new FrequencyTable(
- "QAM-64 HRC T-%1", 7, 8175000, 50750000, 6000000, QAM_64);
-
- // USA Cable HRC, QAM 64 ch 78+
- fmap["atsc_qam64_ushrchigh0"] = new FrequencyTable(
- "QAM-64 HRC %1", 78, 601750000, 643750000, 6000000, QAM_64);
- fmap["atsc_qam64_ushrchigh1"] = new FrequencyTable(
- "QAM-64 HRC %1", 100, 649750000, 799750000, 6000000, QAM_64);
+ // USA Cable HRC/IRC, ch 67-125
+ FREQ(modStr[i], std[j] + "high0", desc[i], sdesc[j] + "%1",
+ 67, 535750000 + off[j], 643750000 + off[j], mod[i]);
+ FREQ(modStr[i], std[j] + "high1", desc[i], sdesc[j] + "%1",
+ 100, 649750000 + off[j], 799750000 + off[j], mod[i]);
+ }
+ }
}
Index: mythtv/libs/libmythtv/scanwizardhelpers.h
===================================================================
--- mythtv/libs/libmythtv/scanwizardhelpers.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/scanwizardhelpers.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -272,11 +272,13 @@
public:
ScanFrequencyTable()
{
- addSelection(QObject::tr("Broadcast"), "us", true);
- addSelection(QObject::tr("Cable") +" 78+", "uscablehigh", false);
- addSelection(QObject::tr("Cable HRC")+" 78+", "uscablehrchigh",false);
- addSelection(QObject::tr("Cable"), "uscable", false);
- addSelection(QObject::tr("Cable HRC"), "ushrc", false);
+ addSelection(QObject::tr("Broadcast"), "us", true);
+ addSelection(QObject::tr("Cable") +" 78+", "uscablehigh", false);
+ addSelection(QObject::tr("Cable HRC")+" 67+", "ushrchigh", false);
+ addSelection(QObject::tr("Cable IRC")+" 67+", "usirchigh", false);
+ addSelection(QObject::tr("Cable"), "uscable", false);
+ addSelection(QObject::tr("Cable HRC"), "ushrc", false);
+ addSelection(QObject::tr("Cable IRC"), "usirc", false);
setLabel(QObject::tr("Frequency Table"));
setHelpText(QObject::tr("Frequency table to use.") + " " +
Index: mythtv/libs/libmythtv/scanwizard.cpp
===================================================================
--- mythtv/libs/libmythtv/scanwizard.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/scanwizard.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -518,7 +518,9 @@
"SELECT dvb_diseqc_type, diseqc_port, diseqc_pos, "
" lnb_lof_switch, lnb_lof_hi, lnb_lof_lo "
"FROM cardinput, capturecard "
- "WHERE capturecard.cardid=%1 and cardinput.sourceid=%2")
+ "WHERE capturecard.cardid = %1 AND "
+ " cardinput.sourceid = %2 AND "
+ " capturecard.cardid = cardinput.cardid")
.arg(parent->captureCard()).arg(nVideoSource));
if (query.exec() && query.isActive() && query.size() > 0)
Index: mythtv/libs/libmythtv/videoout_xv.cpp
===================================================================
--- mythtv/libs/libmythtv/videoout_xv.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/videoout_xv.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -1089,6 +1089,9 @@
bool use_xv = true, use_shm = true;
QString dec = gContext->GetSetting("PreferredMPEG2Decoder", "ffmpeg");
+ if (dec != "libmpeg2" && height < 720 &&
+ gContext->GetNumSetting("UseXvMCForHDOnly", 0))
+ dec = "ffmpeg";
if (dec == "xvmc")
use_xvmc_idct = use_xvmc = true;
else if (dec == "xvmc-vld")
@@ -1335,40 +1338,39 @@
if (attributes)
X11S(XFree(attributes));
- if (xv_draw_colorkey)
+ if (!xv_draw_colorkey)
+ return;
+
+ QString msg = LOC + "Chromakeying not possible with this XVideo port.";
+ X11S(xv_atom = XInternAtom(XJ_disp, "XV_COLORKEY", False));
+ if (xv_atom == None)
{
- X11S(xv_atom = XInternAtom(XJ_disp, "XV_COLORKEY", False));
- if (xv_atom != None)
- {
- X11S(ret = XvGetPortAttribute(XJ_disp, xv_port, xv_atom,
- &xv_colorkey));
+ VERBOSE(VB_PLAYBACK, msg);
+ xv_colorkey = 0;
+ return;
+ }
- if (ret == Success && xv_colorkey == 0)
- {
- const int default_colorkey = 1;
- X11S(ret = XvSetPortAttribute(XJ_disp, xv_port, xv_atom,
- default_colorkey));
- if (ret == Success)
- {
- VERBOSE(VB_PLAYBACK, LOC +
- "0,0,0 is the only bad color key for MythTV, "
- "using "<p_past_surface = NULL;
- //GetRender(*it)->p_future_surface = NULL;
- }
- VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 2: %1")
- .arg(vbuffers.GetStatus()));
-#if 0
- // Remove inheritence of all frames not in displayed or pause
- DQ_COPY(ula, kVideoBuffer_used);
- DQ_COPY(ula, kVideoBuffer_limbo);
- DQ_COPY(ula, kVideoBuffer_avail);
-
- for (it = ula.begin(); it != ula.end(); ++it)
- vbuffers.RemoveInheritence(*it);
-#endif
-
- VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 3: %1")
- .arg(vbuffers.GetStatus()));
- // create discard frame list
- DQ_COPY(discards, kVideoBuffer_used);
- DQ_COPY(discards, kVideoBuffer_limbo);
-
- vbuffers.end_lock(); // Lock Y
+ SyncSurface(*it, -1); // sync past
+ SyncSurface(*it, +1); // sync future
+ SyncSurface(*it, 0); // sync current
+ vbuffers.safeEnqueue(kVideoBuffer_displayed, *it);
}
+ syncs.clear();
+ vbuffers.end_lock(); // Lock Y
- for (it = discards.begin(); it != discards.end(); ++it)
- DiscardFrame(*it);
+ CheckFrameStates();
+ // If the next frame is a keyframe we can clear out a lot more...
+ if (next_frame_keyframe)
{
vbuffers.begin_lock(kVideoBuffer_displayed); // Lock Z
- syncs.clear();
- DQ_COPY(syncs, kVideoBuffer_displayed);
- DQ_COPY(syncs, kVideoBuffer_pause);
+ // Move all the limbo and pause frames to displayed
+ DQ_COPY(syncs, kVideoBuffer_limbo);
for (it = syncs.begin(); it != syncs.end(); ++it)
{
SyncSurface(*it, -1); // sync past
SyncSurface(*it, +1); // sync future
SyncSurface(*it, 0); // sync current
- //GetRender(*it)->p_past_surface = NULL;
- //GetRender(*it)->p_future_surface = NULL;
+ vbuffers.safeEnqueue(kVideoBuffer_displayed, *it);
}
- VERBOSE(VB_PLAYBACK, LOC +
- QString("DiscardFrames() 4: %1 -- done() ")
+ VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 2: %1")
.arg(vbuffers.GetStatus()));
-
+
vbuffers.end_lock(); // Lock Z
+
+ // Now call CheckFrameStates() to remove inheritence and
+ // move the surfaces to the used list if possible (i.e.
+ // if avlib is not using them and they are not currently
+ // being displayed on screen).
+ CheckFrameStates();
}
+ VERBOSE(VB_PLAYBACK, LOC + QString("DiscardFrames() 3: %1 -- done()")
+ .arg(vbuffers.GetStatus()));
+
#endif // USING_XVMC
}
@@ -2071,7 +2062,7 @@
if (osdframe)
DiscardFrame(osdframe);
}
- CheckDisplayedFramesForAvailability();
+ CheckFrameStates();
#endif
}
@@ -2411,7 +2402,7 @@
DiscardFrame(vbuffers.dequeue(kVideoBuffer_pause));
}
// clear any displayed frames not on screen
- CheckDisplayedFramesForAvailability();
+ CheckFrameStates();
// unlock the frame[s]
vbuffers.UnlockFrame(osdframe, "ShowXvMC -- OSD");
@@ -2659,7 +2650,7 @@
.arg(vbuffers.size(kVideoBuffer_pause)));
while (vbuffers.size(kVideoBuffer_pause))
DiscardFrame(vbuffers.dequeue(kVideoBuffer_pause));
- CheckDisplayedFramesForAvailability();
+ CheckFrameStates();
} else if (1 == vbuffers.size(kVideoBuffer_pause))
{
VideoFrame *frame = vbuffers.dequeue(kVideoBuffer_used);
@@ -2791,7 +2782,7 @@
// If there are no available buffer, try to toss old
// displayed frames.
if (!vbuffers.size(kVideoBuffer_avail))
- CheckDisplayedFramesForAvailability();
+ CheckFrameStates();
// If tossing doesn't work try hiding showing frames,
// then tossing displayed frames.
@@ -2805,7 +2796,7 @@
GetRender(*it)->p_surface));
vbuffers.end_lock();
- CheckDisplayedFramesForAvailability();
+ CheckFrameStates();
}
// If there is an available buffer grab it.
@@ -3013,7 +3004,7 @@
return -1;
}
-void VideoOutputXv::CheckDisplayedFramesForAvailability(void)
+void VideoOutputXv::CheckFrameStates(void)
{
#ifdef USING_XVMC
frame_queue_t::iterator it;
@@ -3084,6 +3075,13 @@
}
}
}
+ else if (vbuffers.contains(kVideoBuffer_decode, pframe))
+ {
+ VERBOSE(VB_PLAYBACK, LOC + QString(
+ "Frame %1 is in use by avlib and so is "
+ "being held for later discarding.")
+ .arg(DebugString(pframe, true)));
+ }
else
{
vbuffers.RemoveInheritence(pframe);
Index: mythtv/libs/libmythtv/signalmonitor.h
===================================================================
--- mythtv/libs/libmythtv/signalmonitor.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/signalmonitor.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -7,6 +7,10 @@
// C headers
#include
+// C++ headers
+#include
+using namespace std;
+
// Qt headers
#include
#include
@@ -125,7 +129,8 @@
* Defaults to 25 milliseconds.
* \param msec Milliseconds between signal monitoring events.
*/
- void SetUpdateRate(int msec) { update_rate = msec; }
+ void SetUpdateRate(int msec)
+ { update_rate = max(msec, (int)minimum_update_rate); }
public slots:
virtual void deleteLater(void);
@@ -164,6 +169,7 @@
int capturecardnum;
uint flags;
int update_rate;
+ uint minimum_update_rate;
bool running;
bool exit;
bool update_done;
Index: mythtv/libs/libmythtv/RingBuffer.h
===================================================================
--- mythtv/libs/libmythtv/RingBuffer.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/RingBuffer.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -91,6 +91,7 @@
long long GetTotalReadPosition(void);
long long SetAdjustFilesize(void);
+ void SetTimeout(bool fast) { oldfile = fast; }
protected:
static void *StartReader(void *type);
Index: mythtv/libs/libmythtv/dvbtypes.cpp
===================================================================
--- mythtv/libs/libmythtv/dvbtypes.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/dvbtypes.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -202,7 +202,7 @@
{
{"TRANSMISSION_MODE_AUTO",TRANSMISSION_MODE_AUTO},
{"TRANSMISSION_MODE_2K",TRANSMISSION_MODE_2K},
- {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_2K},
+ {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_8K},
{NULL,TRANSMISSION_MODE_AUTO},
};
@@ -210,7 +210,7 @@
{
{"999",TRANSMISSION_MODE_AUTO},
{"2",TRANSMISSION_MODE_2K},
- {"8",TRANSMISSION_MODE_2K},
+ {"8",TRANSMISSION_MODE_8K},
{NULL,TRANSMISSION_MODE_AUTO},
};
@@ -218,7 +218,7 @@
{
{"auto",TRANSMISSION_MODE_AUTO},
{"2",TRANSMISSION_MODE_2K},
- {"8",TRANSMISSION_MODE_2K},
+ {"8",TRANSMISSION_MODE_8K},
{NULL,TRANSMISSION_MODE_AUTO},
};
Index: mythtv/libs/libmythtv/mpegrecorder.cpp
===================================================================
--- mythtv/libs/libmythtv/mpegrecorder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/mpegrecorder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -363,9 +363,9 @@
if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
{
- cerr << "Error setting codec params\n";
+ cerr << "Warning, unable to set recording volume\n";
+ cerr << "This is normal if you have an AVerMedia M179 card.\n";
perror("VIDIOC_S_CTRL:");
- return false;
}
if (vbimode) {
@@ -481,6 +481,9 @@
continue;
case 0:
printf("select timeout - ivtv driver has stopped responding\n");
+ if(close(readfd) != 0)
+ perror("close");
+ readfd = -1; // Force PVR card to be reopened on next iteration
continue;
default: break;
}
Index: mythtv/libs/libmythtv/ivtvdecoder.cpp
===================================================================
--- mythtv/libs/libmythtv/ivtvdecoder.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/ivtvdecoder.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -270,7 +270,9 @@
GetNVP()->SetVideoParams(720 /*width*/, (ntsc) ? 480 : 576 /*height*/,
(ntsc) ? 29.97f : 25.0f, keyframedist, 1.33);
-
+
+ fps = (ntsc) ? 29.97f : 25.0f; // save for later length calculations
+
ringBuffer->UpdateRawBitrate(8000);
if (m_playbackinfo || livetv || watchingrecording)
Index: mythtv/libs/libmythtv/dvbsignalmonitor.cpp
===================================================================
--- mythtv/libs/libmythtv/dvbsignalmonitor.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/dvbsignalmonitor.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -100,6 +100,10 @@
#undef DVB_IO
AddFlags(newflags);
DBG_SM("constructor()", QString("initial flags 0x%1").arg(newflags,0,16));
+
+ minimum_update_rate = _channel->GetMinSignalMonitorDelay();
+ if (minimum_update_rate > 30)
+ usleep(minimum_update_rate * 1000);
}
/** \fn DVBSignalMonitor::~DVBSignalMonitor()
@@ -348,8 +352,8 @@
len += remainder;
remainder = GetStreamData()->ProcessData(buffer, len);
- if (remainder > 0) // leftover bytes
- memmove(buffer, &(buffer[buffer_size - remainder]), remainder);
+ if (remainder > 0 && (len > remainder)) // leftover bytes
+ memmove(buffer, &(buffer[len - remainder]), remainder);
}
VERBOSE(VB_CHANNEL, LOC + "RunTableMonitorTS(): " + "shutdown");
Index: mythtv/libs/libmythtv/tv_rec.cpp
===================================================================
--- mythtv/libs/libmythtv/tv_rec.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/tv_rec.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -130,6 +130,11 @@
// RingBuffer info
ringBuffer(NULL), rbFilePrefix(""), rbFileExt("mpg")
{
+ // Retune stuff
+ retune_timer = new TuningTimer();
+ retune_timer->setTimeout(10000);
+ retune_timer->start();
+ retune_requests = 0;
}
/** \fn TVRec::Init()
@@ -3221,6 +3226,8 @@
*/
void TVRec::HandleTuning(void)
{
+ bool handle_done = false;
+
if (tuningRequests.size())
{
const TuningRequest *request = &tuningRequests.front();
@@ -3232,7 +3239,12 @@
kFlagEITScan|kFlagAntennaAdjust))
{
if (!recorder)
+ {
TuningFrequency(*request);
+ retune_timer->restart();
+ retune_timer->addMSecs(1);
+ retune_requests = 0;
+ }
else
SetFlags(kFlagWaitingForRecPause);
}
@@ -3261,15 +3273,29 @@
if (HasFlags(kFlagWaitingForSignal))
{
if (!TuningSignalCheck())
- return;
+ handle_done = true;
}
if (HasFlags(kFlagWaitingForSIParser))
{
if (!TuningPMTCheck())
- return;
+ handle_done = true;
}
+#ifdef USING_DVB
+ // Just because we have signal, we may not have the right transponder
+ if ((HasFlags(kFlagWaitingForSignal) ||
+ HasFlags(kFlagWaitingForSIParser)) &&
+ (!retune_timer->elapsed() && (retune_requests < 30)))
+ {
+ RetuneChannel();
+ retune_requests++;
+ }
+#endif // USING_DVB
+
+ if (handle_done)
+ return;
+
if (HasFlags(kFlagNeedToStartRecorder))
{
if (recorder)
@@ -3354,6 +3380,19 @@
ClearFlags(kFlagPendingActions);
}
+/** \fn TVRec::RetuneChannel(void)
+ * \brief Retunes a DVB channel
+ * \return DVBChannel::Retune() or false if ifndef USING_DVB
+ */
+bool TVRec::RetuneChannel(void)
+{
+#ifdef USING_DVB
+ if (GetDVBChannel())
+ return GetDVBChannel()->Retune();
+#endif // USING_DVB
+ return false;
+}
+
/** \fn TVRec::TuningFrequency(const TuningRequest&)
* \brief Performs initial tuning required for any tuning event.
*
Index: mythtv/libs/libmythtv/videooutbase.h
===================================================================
--- mythtv/libs/libmythtv/videooutbase.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/videooutbase.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -256,6 +256,8 @@
/// onto the queue of frames ready for decoding onto.
virtual void DiscardFrames(bool kf) { vbuffers.DiscardFrames(kf); }
+ virtual void CheckFrameStates(void) { }
+
/// \bug not implemented correctly. vpos is not updated.
VideoFrame *GetLastDecodedFrame(void) { return vbuffers.GetLastDecodedFrame(); }
Index: mythtv/libs/libmythtv/osdimagecache.cpp
===================================================================
--- mythtv/libs/libmythtv/osdimagecache.cpp (.../tags/release-0-19) (revision 0)
+++ mythtv/libs/libmythtv/osdimagecache.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -0,0 +1,296 @@
+// -*- Mode: c++ -*-
+/** OSDImageCache
+ * Copyright (c) 2006 by Pekka Jääskeläinen, Daniel Thor Kristjansson
+ * Distributed as part of MythTV under GPL v2 and later.
+ */
+
+// POSIX headers
+#include
+
+// Qt headers
+#include
+#include
+#include
+#include
+#include
+
+// MythTV headers
+#include "mythcontext.h"
+#include "osdimagecache.h"
+
+// Print statistics of OSD image access in the destructor of OSDImageCache
+//#define PRINT_OSD_IMAGE_CACHE_STATS
+
+#define LOC QString("OSDImgCache: ")
+#define LOC_ERR QString("OSDImgCache, Error: ")
+
+uint OSDImageCache::kMaximumMemoryCacheSize = 5 * 1024 * 1024;
+
+/** \fn OSDImageCacheValue::OSDImageCacheValue(unsigned char*,unsigned char*,unsighed char*,unsigned char*,unsighed char*, QRect)
+ * \brief The main constructor that takes the image data as arguments.
+ *
+ * The image data becomes property of the OSDImageCacheValue
+ * and will be deleted by it.
+ */
+OSDImageCacheValue::OSDImageCacheValue(
+ QString cacheKey,
+ unsigned char *yuv, unsigned char *ybuffer,
+ unsigned char *ubuffer, unsigned char *vbuffer,
+ unsigned char *alpha, QRect imagesize) :
+ m_yuv(yuv), m_ybuffer(ybuffer),
+ m_ubuffer(ubuffer), m_vbuffer(vbuffer),
+ m_alpha(alpha), m_imagesize(imagesize),
+ m_cacheKey(QDeepCopy(cacheKey))
+{
+ uint yuv_size = m_imagesize.width() * m_imagesize.height() * 3 / 2;
+ m_size_in_bytes =
+ (sizeof(OSDImageCacheValue)) + yuv_size +
+ (m_imagesize.width() * m_imagesize.height());
+}
+
+/** \fn OSDImageCacheValue::~OSDImageCacheValue()
+ * \brief Destructor, frees the cached bitmaps.
+ */
+OSDImageCacheValue::~OSDImageCacheValue()
+{
+ delete [] m_yuv;
+ m_yuv = NULL;
+ delete [] m_alpha;
+ m_alpha = NULL;
+}
+
+/** \fn OSDImageCache::OSDImageCache()
+ * \brief Constructor, initializes the internal cache structures.
+ */
+OSDImageCache::OSDImageCache() :
+ m_cacheLock(true), m_imageCache(kMaximumMemoryCacheSize, 50),
+ m_memHits(0), m_diskHits(0), m_misses(0)
+{
+ // When the cache gets too large, items are
+ // automatically deleted from it in LRU order.
+ m_imageCache.setAutoDelete(true);
+}
+
+/** \fn OSDImageCache::~OSDImageCache()
+ * \brief Destructor, frees all cached OSD images.
+ */
+OSDImageCache::~OSDImageCache()
+{
+#ifdef PRINT_OSD_IMAGE_CACHE_STATS
+ int totalAccess = m_memHits + m_diskHits + m_misses;
+ if (totalAccess == 0)
+ return;
+
+#define LOG_PREFIX "OSDImageCache: "
+ VERBOSE(VB_IMPORTANT, LOC << " Statistics: " << endl
+ << LOG_PREFIX << m_imageCache.totalCost() << " bytes in cache\n"
+ << LOG_PREFIX << " memory hits: "
+ << m_memHits << ", " << m_memHits*100.0/totalAccess << "%\n"
+ << LOG_PREFIX << " disk hits: "
+ << m_diskHits << ", " << m_diskHits*100.0/totalAccess << "%\n"
+ << LOG_PREFIX << " misses: "
+ << m_misses << ", " << m_misses*100.0/totalAccess << "%");
+#undef LOC_PREFIX
+#endif
+ Reset();
+}
+
+/** \fn OSDImageCache::Contains(const QString&,bool)
+ * \brief Returns true if cached OSD image was found in the cache.
+ *
+ * \param key The key for this image.
+ * \param useFile If true, also look from the disk cache.
+ */
+bool OSDImageCache::Contains(const QString &key, bool useFile) const
+{
+ QMutexLocker locker(&m_cacheLock);
+
+ if (m_imageCache.find(key) != NULL)
+ return true;
+
+ if (!useFile)
+ return false;
+
+ return InFileCache(key);
+}
+
+bool OSDImageCache::InFileCache(const QString &key) const
+{
+ // check if cache file exists
+ QDir dir(MythContext::GetConfDir() + "/osdcache/");
+ QFileInfo cFile(dir.path() + "/" + key);
+ if (!cFile.exists() || !cFile.isReadable())
+ return false;
+
+ // check if backing file exists
+ QString orig = ExtractOriginal(key);
+ if (orig.isEmpty())
+ return false;
+
+ QFileInfo oFile(orig);
+ if (!oFile.exists())
+ {
+ VERBOSE(VB_IMPORTANT, LOC + QString("Can't find '%1'").arg(orig));
+ return false;
+ }
+
+ // if cache file is older than backing file, delete cache file
+ if (cFile.lastModified() < oFile.lastModified())
+ {
+ cFile.dir().remove(cFile.baseName(true));
+ return false;
+ }
+
+ return true;
+}
+
+/** \fn OSDImageCache::Get(const QString&,bool)
+ * \brief Returns OSD image data from cache.
+ *
+ * This also removes the image from the cache so it won't be deleted
+ * while in use. The deletion of the taken item becomes responsibility
+ * of the client. Returns NULL if item with the given key is not found.
+ *
+ * \param key The key for this image.
+ * \param useFile If true, also check the disk cache.
+ */
+OSDImageCacheValue *OSDImageCache::Get(const QString &key, bool useFile)
+{
+ QMutexLocker locker(&m_cacheLock);
+ OSDImageCacheValue* item = m_imageCache.find(key);
+ if (item)
+ {
+ m_memHits++;
+ return m_imageCache.take(key);
+ }
+
+ if (!useFile || !InFileCache(key))
+ {
+ m_misses++;
+ return NULL;
+ }
+
+ QDir dir(MythContext::GetConfDir() + "/osdcache/");
+ QFile cacheFile(dir.path() + "/" + key);
+ cacheFile.open(IO_ReadOnly);
+ uint32_t imwidth = 0;
+ uint32_t imheight = 0;
+
+ QDataStream stream(&cacheFile);
+ stream >> imwidth >> imheight;
+
+ uint yuv_size = imwidth * imheight * 3 / 2;
+ uint tot_size = (sizeof(imwidth) * 2) + yuv_size + (imwidth * imheight);
+
+ if (cacheFile.size() != tot_size)
+ {
+ VERBOSE(VB_IMPORTANT, LOC_ERR + key + " wrong cache file size!"
+ << cacheFile.size() << " != " << tot_size);
+ return NULL;
+ }
+
+ unsigned char *yuv = new unsigned char[yuv_size];
+ unsigned char *alpha = new unsigned char[imwidth * imheight];
+ stream.readRawBytes((char*)yuv, yuv_size);
+ stream.readRawBytes((char*)alpha, imwidth * imheight);
+ cacheFile.close();
+
+ OSDImageCacheValue* value =
+ new OSDImageCacheValue(
+ key,
+ yuv, yuv,
+ yuv + (imwidth * imheight),
+ yuv + (imwidth * imheight * 5 / 4),
+ alpha, QRect(0, 0, imwidth, imheight));
+
+ m_diskHits++;
+ return value;
+}
+
+/** \fn OSDImageCache::Insert(OSDImageCacheValue*)
+ * \brief Inserts OSD image data to memory cache.
+ *
+ * The item becomes property of the OSDImageCache and may be
+ * deleted any time by it.
+ *
+ * \param value The cache item.
+ */
+void OSDImageCache::Insert(OSDImageCacheValue *value)
+{
+ if (!value)
+ return;
+
+ QMutexLocker locker(&m_cacheLock);
+ if (!m_imageCache.insert(value->GetKey(), value, value->GetSize()))
+ {
+ VERBOSE(VB_IMPORTANT,
+ LOC_ERR + QString("inserting image to memory cache failed"));
+ }
+}
+
+
+/** \fn OSDImageCache::SaveToDisk(const OSDImageCacheValue*)
+ * \brief Saves OSD image data to disk cache.
+ *
+ * Item is not written to the memory cache, i.e., it stays as
+ * property of the client.
+ *
+ * \param value The cached OSD image to save.
+ */
+void OSDImageCache::SaveToDisk(const OSDImageCacheValue *value)
+{
+ if (InFileCache(value->GetKey()))
+ return;
+
+ QDir dir(MythContext::GetConfDir() + "/osdcache/");
+ if (!dir.exists() && !dir.mkdir(dir.path()))
+ {
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating osdcache directory failed.");
+ return;
+ }
+
+ QFile cacheFile(dir.path() + "/" + value->GetKey());
+ if (!cacheFile.open(IO_WriteOnly | IO_Truncate))
+ {
+ VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating osdcache file failed.");
+ return;
+ }
+
+ uint32_t imwidth = value->m_imagesize.width();
+ uint32_t imheight = value->m_imagesize.height();
+ uint yuv_size = imwidth * imheight * 3 / 2;
+
+ QDataStream stream(&cacheFile);
+ stream << imwidth << imheight;
+ stream.writeRawBytes((const char*)value->m_yuv, yuv_size);
+ stream.writeRawBytes((const char*)value->m_alpha, imwidth * imheight);
+ cacheFile.close();
+}
+
+/** \fn OSDImageCache::CreateKey(const QString&,float,float,int,int)
+ * \brief Generates a cache key from the given OSD image parameters.
+ *
+ * The returned key is a string that can be safely used as a file name.
+ */
+QString OSDImageCache::CreateKey(const QString &filename, float wmult,
+ float hmult, int scalew, int scaleh)
+{
+ QString tmp = filename;
+ return QString("cache_%1@%2_%3_%4_%5").arg(tmp.replace(QChar('/'), "+"))
+ .arg(wmult).arg(hmult).arg(scalew).arg(scaleh);
+}
+
+QString OSDImageCache::ExtractOriginal(const QString &key)
+{
+ QString tmp0 = key.mid(6);
+ QString tmp1 = tmp0.left(tmp0.find("@"));
+ QString tmp2 = tmp1.replace(QChar('+'), "/");
+ return tmp2;
+}
+
+void OSDImageCache::Reset(void)
+{
+ QMutexLocker locker(&m_cacheLock);
+ // this also deletes the images due to setAutoDelete(true)
+ m_imageCache.clear();
+}
Index: mythtv/libs/libmythtv/osd.cpp
===================================================================
--- mythtv/libs/libmythtv/osd.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/osd.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -154,7 +154,8 @@
}
OSDTypeCC *ccpage = new OSDTypeCC(name, ccfont, sub_xoff, sub_yoff,
- sub_dispw, sub_disph);
+ sub_dispw, sub_disph,
+ wmult, hmult);
container->AddType(ccpage);
}
@@ -517,7 +518,7 @@
}
}
- OSDTypeBox *box = new OSDTypeBox(name, area);
+ OSDTypeBox *box = new OSDTypeBox(name, area, wmult, hmult);
container->AddType(box);
}
@@ -658,7 +659,7 @@
return;
}
- OSDTypeText *text = new OSDTypeText(name, ttffont, "", area);
+ OSDTypeText *text = new OSDTypeText(name, ttffont, "", area, wmult, hmult);
container->AddType(text);
text->SetMultiLine(multiline);
@@ -875,7 +876,7 @@
QRect area = parseRect(getFirstText(info));
normalizeRect(area);
- rects->AddPosition(area);
+ rects->AddPosition(area, wmult, hmult);
}
else
{
@@ -919,7 +920,7 @@
pos.setX((int)(pos.x() * wmult + xoffset));
pos.setY((int)(pos.y() * hmult + yoffset));
- image->AddPosition(pos);
+ image->AddPosition(pos, wmult, hmult);
}
else if (info.tagName() == "staticsize")
{
@@ -1925,7 +1926,7 @@
image = new OSDTypeImage(*editarrowright);
}
- image->SetPosition(QPoint(xpos, ypos));
+ image->SetPosition(QPoint(xpos, ypos), wmult, hmult);
set->AddType(image);
set->Display();
Index: mythtv/libs/libmythtv/tv_rec.h
===================================================================
--- mythtv/libs/libmythtv/tv_rec.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/tv_rec.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -13,6 +13,7 @@
#include "mythdeque.h"
#include "programinfo.h"
#include "tv.h"
+#include "util.h"
class QSocket;
class NuppelVideoRecorder;
@@ -48,6 +49,30 @@
BROWSE_FAVORITE ///< Fetch information on the next favorite channel
} BrowseDirections;
+class TuningTimer
+{
+ public:
+ TuningTimer() {}
+
+ void setTimeout(long t) { _timeout = t; }
+ long timeout(void) { return _timeout; }
+ void start() { t_timer.start(); }
+ int restart() { int ret = elapsed();
+ t_timer.restart();
+ return ret;
+ }
+ int elapsed() { int ret = t_timer.elapsed();
+ if (ret > _timeout) { ret = 0; t_timer.restart(); }
+ return ret;
+ }
+
+ void addMSecs(int ms) { t_timer.addMSecs(ms); }
+
+ private:
+ QTime t_timer;
+ long _timeout;
+};
+
class GeneralDBOptions
{
public:
@@ -275,6 +300,7 @@
bool TuningPMTCheck(void);
void TuningNewRecorder(void);
void TuningRestartRecorder(void);
+ bool RetuneChannel(void);
void HandleStateChange(void);
void ChangeState(TVState nextState);
@@ -362,6 +388,10 @@
QString rbFilePrefix;
QString rbFileExt;
+ // Retune stuff
+ TuningTimer *retune_timer;
+ int retune_requests;
+
public:
static const uint kEITScanStartTimeout;
static const uint kSignalMonitoringRate;
Index: mythtv/libs/libmythtv/videobuffers.h
===================================================================
--- mythtv/libs/libmythtv/videobuffers.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/videobuffers.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -40,6 +40,7 @@
kVideoBuffer_used = 0x00000004,
kVideoBuffer_pause = 0x00000008,
kVideoBuffer_displayed = 0x00000010,
+ kVideoBuffer_decode = 0x00000020,
kVideoBuffer_all = 0x0000001F,
};
@@ -159,7 +160,6 @@
uint vpos;
mutable QMutex global_lock;
- QMutex inheritence_lock;
bool use_frame_locks;
QMutex frame_lock;
Index: mythtv/libs/libmythtv/dvbconfparser.cpp
===================================================================
--- mythtv/libs/libmythtv/dvbconfparser.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/dvbconfparser.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -193,10 +193,10 @@
QStringList::Iterator end = tokens.end();
if (i != end) c.name = *i++; else return false;
- if (i != end) c.frequency = (*i++).toInt(); else return false;
+ if (i != end) c.frequency = (*i++).toUInt()*1000; else return false;
if (i == end || !c.polarity.parseConf(*i++)) return false;
if (i == end ) return false; else i++; //Sat num
- if (i != end) c.symbolrate = (*i++).toInt(); else return false;
+ if (i != end) c.symbolrate = (*i++).toUInt()*1000; else return false;
if (i == end ) return false; else i++;
if (i == end ) return false; else i++;
if (i != end) c.serviceid = (*i++).toInt(); else return false;
Index: mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp
===================================================================
--- mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/pchdtvsignalmonitor.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -108,8 +108,8 @@
len += remainder;
remainder = GetStreamData()->ProcessData(buffer, len);
- if (remainder > 0) // leftover bytes
- memmove(buffer, &(buffer[buffer_size - remainder]), remainder);
+ if (remainder > 0 && (len > remainder)) // leftover bytes
+ memmove(buffer, &(buffer[len - remainder]), remainder);
}
DBG_SM("RunTableMonitor()", "end");
}
Index: mythtv/libs/libmythtv/videobuffers.cpp
===================================================================
--- mythtv/libs/libmythtv/videobuffers.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmythtv/videobuffers.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -84,7 +84,7 @@
: numbuffers(0), needfreeframes(0), needprebufferframes(0),
needprebufferframes_normal(0), needprebufferframes_small(0),
keepprebufferframes(0), need_extra_for_pause(false), rpos(0), vpos(0),
- global_lock(true), inheritence_lock(false), use_frame_locks(true),
+ global_lock(true), use_frame_locks(true),
frame_lock(true)
{
}
@@ -125,6 +125,8 @@
{
global_lock.lock();
+ Reset();
+
uint numcreate = numdecode + ((extra_for_pause) ? 1 : 0);
// make a big reservation, so that things that depend on
@@ -409,6 +411,8 @@
q = &limbo;
else if (type == kVideoBuffer_pause)
q = &pause;
+ else if (type == kVideoBuffer_decode)
+ q = &decode;
global_lock.unlock();
return q;
@@ -429,6 +433,8 @@
q = &limbo;
else if (type == kVideoBuffer_pause)
q = &pause;
+ else if (type == kVideoBuffer_decode)
+ q = &decode;
global_lock.unlock();
return q;
@@ -503,6 +509,8 @@
limbo.remove(frame);
if ((type & kVideoBuffer_pause) == kVideoBuffer_pause)
pause.remove(frame);
+ if ((type & kVideoBuffer_decode) == kVideoBuffer_decode)
+ decode.remove(frame);
global_lock.unlock();
}
}
@@ -857,7 +865,7 @@
{
(void)frame;
#ifdef USING_XVMC
- inheritence_lock.lock();
+ global_lock.lock();
frame_map_t::iterator it = parents.find(frame);
if (it == parents.end())
@@ -902,18 +910,18 @@
children[*it].push_back((VideoFrame*)frame);
}
- inheritence_lock.unlock();
+ global_lock.unlock();
#endif // USING_XVMC
}
void VideoBuffers::RemoveInheritence(const VideoFrame *frame)
{
- inheritence_lock.lock();
+ global_lock.lock();
frame_map_t::iterator it = parents.find(frame);
if (it == parents.end())
{
- inheritence_lock.unlock();
+ global_lock.unlock();
return;
}
@@ -945,7 +953,7 @@
.arg(i).arg(DebugString(*pit)));
}
- inheritence_lock.unlock();
+ global_lock.unlock();
}
frame_queue_t VideoBuffers::Children(const VideoFrame *frame)
Index: mythtv/libs/libavformat/aviobuf.c
===================================================================
--- mythtv/libs/libavformat/aviobuf.c (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libavformat/aviobuf.c (.../branches/release-0-19-fixes) (revision 10931)
@@ -164,7 +164,13 @@
void url_fskip(ByteIOContext *s, offset_t offset)
{
- url_fseek(s, offset, SEEK_CUR);
+ if (offset < 16384)
+ {
+ static unsigned char fskipbuf[16384];
+ get_buffer(s, fskipbuf, offset);
+ }
+ else
+ url_fseek(s, offset, SEEK_CUR);
}
offset_t url_ftell(ByteIOContext *s)
Index: mythtv/libs/libmyth/lcddevice.cpp
===================================================================
--- mythtv/libs/libmyth/lcddevice.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/lcddevice.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -150,7 +150,7 @@
if (!connected)
{
- QTextStream os(socket);
+ QTextStream os(socket->socketDevice());
int count = 0;
do
@@ -213,7 +213,7 @@
return;
}
- QTextStream os(socket);
+ QTextStream os(socket->socketDevice());
last_command = someText;
@@ -224,7 +224,7 @@
#endif
// Just stream the text out the socket
- os << someText << "\n" << flush;
+ os << someText << "\n";
}
else
{
Index: mythtv/libs/libmyth/audiooutputca.cpp
===================================================================
--- mythtv/libs/libmyth/audiooutputca.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/audiooutputca.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -21,6 +21,7 @@
#include "mythcontext.h"
#include "audiooutputca.h"
+#include "config.h"
// this holds Core Audio member variables
struct CoreAudioData {
@@ -107,8 +108,10 @@
bzero(&conv_in_desc, sizeof(AudioStreamBasicDescription));
conv_in_desc.mSampleRate = audio_samplerate;
conv_in_desc.mFormatID = kAudioFormatLinearPCM;
- conv_in_desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
- | kLinearPCMFormatFlagIsBigEndian;
+ conv_in_desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
+#ifdef WORDS_BIGENDIAN
+ conv_in_desc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
+#endif
conv_in_desc.mBytesPerPacket = audio_bytes_per_sample;
conv_in_desc.mFramesPerPacket = 1;
conv_in_desc.mBytesPerFrame = audio_bytes_per_sample;
Index: mythtv/libs/libmyth/util.cpp
===================================================================
--- mythtv/libs/libmyth/util.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/util.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -1006,16 +1006,20 @@
long long freespace = -1;
QCString cstr = file_on_disk.local8Bit();
- if (statfs(cstr, &statbuf) == 0)
+ total = used = -1;
+
+ // there are cases where statfs will return 0 (good), but f_blocks and
+ // others are invalid and set to 0 (such as when an automounted directory
+ // is not mounted but still visible because --ghost was used),
+ // so check to make sure we can have a total size > 0
+ if ((statfs(cstr, &statbuf) == 0) &&
+ (statbuf.f_blocks > 0) &&
+ (statbuf.f_bsize > 0))
{
freespace = statbuf.f_bsize * (statbuf.f_bavail >> 10);
total = statbuf.f_bsize * (statbuf.f_blocks >> 10);
used = total - freespace;
}
- else
- {
- freespace = total = used = -1;
- }
return freespace;
}
Index: mythtv/libs/libmyth/mythdialogs.cpp
===================================================================
--- mythtv/libs/libmyth/mythdialogs.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/mythdialogs.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -2617,6 +2617,7 @@
password_editor->setEchoMode(QLineEdit::Password);
password_editor->setGeometry(textWidth + 20,10,135,30);
password_editor->setBackgroundOrigin(ParentOrigin);
+ password_editor->setAllowVirtualKeyboard(false);
connect(password_editor, SIGNAL(textChanged(const QString &)),
this, SLOT(checkPassword(const QString &)));
Index: mythtv/libs/libmyth/mythwidgets.cpp
===================================================================
--- mythtv/libs/libmyth/mythwidgets.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/mythwidgets.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -353,7 +353,8 @@
(e->key() == Qt::Key_Enter) ||
(e->key() == Qt::Key_Return)))
{
- if (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1)
+ if ((allowVirtualKeyboard) &&
+ (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1))
{
popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
gContext->GetMainWindow()->detach(popup);
@@ -726,10 +727,11 @@
QWidget::focusNextPrevChild(true);
emit tryingToLooseFocus(true);
}
- else if (action == "SELECT" &&
- (e->text().isNull() ||
- (e->key() == Qt::Key_Enter) ||
- (e->key() == Qt::Key_Return)))
+ else if ((action == "SELECT") &&
+ (!active_cycle) &&
+ ((e->text().isNull()) ||
+ (e->key() == Qt::Key_Enter) ||
+ (e->key() == Qt::Key_Return)))
{
if (gContext->GetNumSetting("UseVirtualKeyboard", 1) == 1)
{
@@ -749,7 +751,7 @@
if (handled)
return;
- if (!handled && popup && popup->isShown())
+ if (popup && popup->isShown())
{
endCycle();
QTextEdit::keyPressEvent(e);
Index: mythtv/libs/libmyth/remotefile.h
===================================================================
--- mythtv/libs/libmyth/remotefile.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/remotefile.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -27,6 +27,8 @@
long long GetFileSize(void);
+ void SetTimeout(bool fast);
+
private:
QSocketDevice *openSocket(bool control);
@@ -43,6 +45,7 @@
QMutex lock;
long long filesize;
+ bool timeoutisfast;
};
#endif
Index: mythtv/libs/libmyth/mythwidgets.h
===================================================================
--- mythtv/libs/libmyth/mythwidgets.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/mythwidgets.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -122,17 +122,21 @@
Q_OBJECT
public:
MythLineEdit(QWidget *parent=NULL, const char* widgetName=0) :
- QLineEdit(parent, widgetName) { rw = true; Init(); };
+ QLineEdit(parent, widgetName)
+ { rw = true; allowVirtualKeyboard = true; Init(); };
MythLineEdit(const QString& contents, QWidget *parent=NULL,
const char* widgetName=0) :
- QLineEdit(contents, parent, widgetName) { rw = true; Init(); };
+ QLineEdit(contents, parent, widgetName)
+ { rw = true; allowVirtualKeyboard = true; Init(); };
virtual ~MythLineEdit();
void setHelpText(QString help) { helptext = help; };
void setRW(bool readwrite = true) { rw = readwrite; };
void setRO() { rw = false; };
+ void setAllowVirtualKeyboard(bool allowKbd = true)
+ { allowVirtualKeyboard = allowKbd; }
void setPopupPosition(PopupPosition pos) { popupPosition = pos; }
PopupPosition getPopupPosition(void) { return popupPosition; }
@@ -154,6 +158,7 @@
VirtualKeyboard *popup;
QString helptext;
bool rw;
+ bool allowVirtualKeyboard;
PopupPosition popupPosition;
};
Index: mythtv/libs/libmyth/mythcontext.cpp
===================================================================
--- mythtv/libs/libmyth/mythcontext.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/mythcontext.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -2621,9 +2621,13 @@
d->LoadLogSettings();
if (d->m_logenable == 1)
{
+ QString fullMsg = message;
+ if (!details.isEmpty())
+ fullMsg += ": " + details;
+
if (message.left(21) != "Last message repeated")
{
- if (message == d->lastLogStrings[module])
+ if (fullMsg == d->lastLogStrings[module])
{
d->lastLogCounts[module] += 1;
return;
@@ -2639,7 +2643,7 @@
}
d->lastLogCounts[module] = 0;
- d->lastLogStrings[module] = message;
+ d->lastLogStrings[module] = fullMsg;
}
}
@@ -2693,7 +2697,7 @@
}
if (priority <= d->m_logprintlevel)
- VERBOSE(VB_IMPORTANT, module + ": " + message);
+ VERBOSE(VB_IMPORTANT, module + ": " + fullMsg);
}
}
Index: mythtv/libs/libmyth/remotefile.cpp
===================================================================
--- mythtv/libs/libmyth/remotefile.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libmyth/remotefile.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -15,6 +15,7 @@
path = url;
readposition = 0;
filesize = -1;
+ timeoutisfast = false;
query = "QUERY_FILETRANSFER %1";
@@ -295,4 +296,34 @@
Read(data.data(), filesize);
return true;
-}
+}
+
+void RemoteFile::SetTimeout(bool fast)
+{
+ if (timeoutisfast == fast)
+ return;
+
+ if (!sock)
+ {
+ VERBOSE(VB_NETWORK, "RemoteFile::Seek(): Called with no socket");
+ return;
+ }
+
+ if (!sock->isOpen() || sock->error())
+ return;
+
+ if (!controlSock->isOpen() || controlSock->error())
+ return;
+
+ QStringList strlist = QString(query).arg(recordernum);
+ strlist << "SET_TIMEOUT";
+ strlist << QString::number((int)fast);
+
+ lock.lock();
+ WriteStringList(controlSock, strlist);
+ ReadStringList(controlSock, strlist);
+ lock.unlock();
+
+ timeoutisfast = fast;
+}
+
Index: mythtv/libs/libavcodec/libavcodec.pro
===================================================================
--- mythtv/libs/libavcodec/libavcodec.pro (.../tags/release-0-19) (revision 10931)
+++ mythtv/libs/libavcodec/libavcodec.pro (.../branches/release-0-19-fixes) (revision 10931)
@@ -430,4 +430,5 @@
LIBS += -lz
QMAKE_LFLAGS_SHLIB += -single_module
QMAKE_LFLAGS_SHLIB += -seg1addr 0xC3000000
+ QMAKE_LFLAGS_SHLIB += -read_only_relocs warning
}
Index: mythtv/programs/mythfrontend/playbackbox.cpp
===================================================================
--- mythtv/programs/mythfrontend/playbackbox.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythfrontend/playbackbox.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -17,6 +17,7 @@
#include
#include
+#include
#include
#include
@@ -140,6 +141,7 @@
// Main Recording List support
fillListTimer(new QTimer(this)), connected(false),
titleIndex(0), progIndex(0),
+ progsInDB(0),
// Other state
curitem(NULL), delitem(NULL),
lastProgram(NULL),
@@ -261,7 +263,9 @@
setNoErase();
gContext->addListener(this);
- if (!recGroupPassword.isEmpty() || (titleList.count() <= 1) || initialFilt)
+ if ((!recGroupPassword.isEmpty()) ||
+ ((titleList.count() <= 1) && (progsInDB > 0)) ||
+ (initialFilt))
showRecGroupChooser();
gContext->addCurrentLocation((type == Delete)? "DeleteBox":"PlaybackBox");
@@ -890,9 +894,13 @@
!playingSomething)
{
QSize size = drawVideoBounds.size();
+ float saspect = ((float)size.width()) / ((float)size.height());
+ float vaspect = previewVideoNVP->GetVideoAspect();
+ size.setHeight((int) ceil(size.height() * (saspect / vaspect)));
+ size.setHeight(((size.height() + 7) / 8) * 8);
+ size.setWidth( ((size.width() + 7) / 8) * 8);
const QImage &img = previewVideoNVP->GetARGBFrame(size);
- uint xoff = max((size.width() - drawVideoBounds.width()) / 2, 0);
- p->drawImage(drawVideoBounds.x() + xoff, drawVideoBounds.y(), img);
+ p->drawImage(drawVideoBounds.x(), drawVideoBounds.y(), img);
}
/* have we timed out waiting for nvp to start? */
@@ -1272,10 +1280,10 @@
paintSkipUpdate = false;
update(drawTotalBounds);
}
+ else if (arrowAccel)
+ showActionsSelected();
else if (curitem && curitem->availableStatus != asAvailable)
showAvailablePopup(curitem);
- else if (arrowAccel)
- showActionsSelected();
}
void PlaybackBox::cursorDown(bool page, bool newview)
@@ -1380,6 +1388,7 @@
asCache[asKey] = p->availableStatus;
}
+ progsInDB = 0;
titleList.clear();
progLists.clear();
// Clear autoDelete for the "all" list since it will share the
@@ -1402,6 +1411,7 @@
vector::iterator i = infoList->begin();
for ( ; i != infoList->end(); i++)
{
+ progsInDB++;
p = *i;
if ((((p->recgroup == recGroup) ||
((recGroup == "All Programs") &&
@@ -1886,7 +1896,8 @@
if (inTitle && haveGroupInfoSet)
return;
- if (curitem->availableStatus != asAvailable)
+ if ((curitem->availableStatus != asAvailable) &&
+ (curitem->availableStatus != asFileNotFound))
showAvailablePopup(curitem);
else
showActions(curitem);
@@ -2068,7 +2079,21 @@
delitem = new ProgramInfo(*toExp);
- if (delitem->availableStatus != asAvailable)
+ if (fileExists(delitem) == false)
+ {
+ QString msg =
+ QString("PlaybackBox::showActions(): Error, %1 file not found")
+ .arg(delitem->pathname);
+ VERBOSE(VB_IMPORTANT, msg);
+
+ ProgramInfo *tmpItem = findMatchingProg(delitem);
+ if (tmpItem)
+ {
+ tmpItem->availableStatus = asFileNotFound;
+ showFileNotFoundActionPopup(delitem);
+ }
+ }
+ else if (delitem->availableStatus != asAvailable)
showAvailablePopup(delitem);
else
showActionPopup(delitem);
@@ -2647,6 +2672,34 @@
expectingPopup = true;
}
+void PlaybackBox::showFileNotFoundActionPopup(ProgramInfo *program)
+{
+ if (!curitem || !program)
+ return;
+
+ popup = new MythPopupBox(gContext->GetMainWindow(), drawPopupSolid,
+ drawPopupFgColor, drawPopupBgColor,
+ drawPopupSelColor, "action popup");
+
+ QString msg = QObject::tr("Recording Unavailable") + "\n";
+ msg += QObject::tr("The file for this recording can "
+ "not be found") + "\n";
+
+ initPopup(popup, program, "", msg);
+
+ QButton *detailsButton;
+ detailsButton = popup->addButton(tr("Show Program Details"), this,
+ SLOT(showProgramDetails()));
+
+ popup->addButton(tr("Delete"), this, SLOT(askDelete()));
+
+ popup->ShowPopup(this, SLOT(doCancel()));
+
+ detailsButton->setFocus();
+
+ expectingPopup = true;
+}
+
void PlaybackBox::initPopup(MythPopupBox *popup, ProgramInfo *program,
QString message, QString message2)
{
@@ -4129,8 +4182,7 @@
if (!recGroupListBox)
return;
- QString item =
- recGroupListBox->currentText().section('[', 0, 0).simplifyWhiteSpace();
+ QString item = recGroupListBox->currentText().section(" [", 0, 0);
if (item.left(5) == "-----")
{
@@ -4147,8 +4199,7 @@
void PlaybackBox::setGroupFilter(void)
{
- recGroup =
- recGroupListBox->currentText().section('[', 0, 0).simplifyWhiteSpace();
+ recGroup = recGroupListBox->currentText().section(" [", 0, 0);
if (groupnameAsAllProg)
groupDisplayName = recGroup;
Index: mythtv/programs/mythfrontend/customrecord.cpp
===================================================================
--- mythtv/programs/mythfrontend/customrecord.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythfrontend/customrecord.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -149,7 +149,7 @@
m_cfrom << "";
m_csql << "program.stars >= 0.75 ";
- m_clause->insertItem(tr("Person named in the credits"));
+ m_clause->insertItem(tr("Person named in the credits (Data Direct)"));
m_cfrom << ", people, credits";
m_csql << QString("people.name = 'Tom Hanks' \n"
"AND credits.person = people.person \n"
@@ -447,8 +447,8 @@
else
{
MSqlQuery query(MSqlQuery::InitCon());
- query.prepare(QString("SELECT NULL FROM program,channel %1 WHERE\n%2")
- .arg(from).arg(desc));
+ query.prepare(QString("SELECT NULL FROM (program,channel) "
+ "%1 WHERE\n%2").arg(from).arg(desc));
if (query.exec() && query.isActive())
{
Index: mythtv/programs/mythfrontend/tv_schedule.xml
===================================================================
--- mythtv/programs/mythfrontend/tv_schedule.xml (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythfrontend/tv_schedule.xml (.../branches/release-0-19-fixes) (revision 10931)
@@ -26,7 +26,7 @@
Guia
EPG
Guide
- Dagskrá
+ Dagskrá
Gids
Guide
ガイド
Index: mythtv/programs/mythfrontend/playbackbox.h
===================================================================
--- mythtv/programs/mythfrontend/playbackbox.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythfrontend/playbackbox.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -237,6 +237,7 @@
void promptEndOfRecording(ProgramInfo *);
void showDeletePopup(ProgramInfo *, deletePopupType);
void showActionPopup(ProgramInfo *program);
+ void showFileNotFoundActionPopup(ProgramInfo *program);
void initPopup(MythPopupBox *popup, ProgramInfo *program,
QString message, QString message2);
void cancelPopup();
@@ -337,6 +338,7 @@
int progIndex; ///< Index of selected item index on page
QStringList titleList; ///< list of pages
ProgramMap progLists; ///< lists of programs by page
+ int progsInDB; ///< total number of recordings in DB
// Play List support
QStringList playList; ///< list of selected items "play list"
Index: mythtv/programs/mythfrontend/networkcontrol.cpp
===================================================================
--- mythtv/programs/mythfrontend/networkcontrol.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythfrontend/networkcontrol.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -469,7 +469,7 @@
message = "NETWORK_CONTROL SEEK BACKWARD";
else if (tokens[2].contains(QRegExp("^\\d\\d:\\d\\d:\\d\\d$")))
{
- int hours = tokens[2].left(0).toInt();
+ int hours = tokens[2].mid(0, 2).toInt();
int minutes = tokens[2].mid(3, 2).toInt();
int seconds = tokens[2].mid(6, 2).toInt();
message = QString("NETWORK_CONTROL SEEK POSITION %1")
Index: mythtv/programs/mythtranscode/mpeg2fix.cpp
===================================================================
--- mythtv/programs/mythtranscode/mpeg2fix.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythtranscode/mpeg2fix.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -1776,6 +1776,7 @@
if (vFrame.count() && (file_end || vFrame.getLast()->isSequence))
{
+ MPEG2frame *seqFrame;
if (ptsIncrement != vFrame.first()->mpeg2_seq.frame_period / 300)
{
VERBOSE(MPF_IMPORTANT,
@@ -1786,6 +1787,11 @@
}
displayFrame->toFirst();
+ // since we might reorder the frames when coming out of a cutpoint
+ // me need to save the first frame here, as it is gauranteed to
+ // have a sequence header.
+ seqFrame = vFrame.current();
+
while (vFrame.current() != vFrame.getLast())
{
bool ptsorder_eq_dtsorder = false;
@@ -1941,7 +1947,7 @@
if (! new_discard_state)
{
- AddSequence(markedFrame, vFrame.first());
+ AddSequence(markedFrame, seqFrame);
RenumberFrames(frame_pos + Lreorder.at(),
- GetFrameNum(markedFrame));
}
Index: mythtv/programs/mythcommflag/main.cpp
===================================================================
--- mythtv/programs/mythcommflag/main.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythcommflag/main.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -895,9 +895,6 @@
return COMMFLAG_EXIT_INVALID_CMDLINE;
}
- if (queueJobInstead)
- return QueueCommFlagJob(chanid, starttime);
-
if (copyToCutlist)
return CopySkipListToCutList(chanid, starttime);
@@ -1009,7 +1006,10 @@
if ( allRecorded )
{
- FlagCommercials(chanid, starttime);
+ if (queueJobInstead)
+ QueueCommFlagJob(chanid, starttime);
+ else
+ FlagCommercials(chanid, starttime);
}
else
{
@@ -1063,7 +1063,12 @@
if ((flagStatus == COMM_FLAG_NOT_FLAGGED) &&
(marksFound == 0))
- FlagCommercials(chanid, starttime);
+ {
+ if (queueJobInstead)
+ QueueCommFlagJob(chanid, starttime);
+ else
+ FlagCommercials(chanid, starttime);
+ }
}
}
}
Index: mythtv/programs/mythbackend/mainserver.cpp
===================================================================
--- mythtv/programs/mythbackend/mainserver.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythbackend/mainserver.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -1919,11 +1919,8 @@
if (m_sched) {
if (table == "") m_sched->getAllPending(strList);
else {
- // We need a different connection from the scheduler proper
- // DDCon exists, although it's designed for other purposes.
- MSqlQueryInfo dbconn = MSqlQuery::DDCon();
- Scheduler *sched = new Scheduler(false, encoderList,
- table, &dbconn, m_sched);
+ Scheduler *sched = new Scheduler(false, encoderList,
+ table, m_sched);
sched->FillRecordListFromDB(recordid);
sched->getAllPending(strList);
delete sched;
@@ -2940,6 +2937,12 @@
long long ret = ft->Seek(curpos, pos, whence);
encodeLongLong(retlist, ret);
}
+ else if (command == "SET_TIMEOUT")
+ {
+ bool fast = slist[2].toInt();
+ ft->SetTimeout(fast);
+ retlist << "ok";
+ }
else
{
VERBOSE(VB_IMPORTANT, QString("Unknown command: %1").arg(command));
Index: mythtv/programs/mythbackend/scheduler.cpp
===================================================================
--- mythtv/programs/mythbackend/scheduler.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythbackend/scheduler.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -35,8 +35,7 @@
#define LOC_ERR QString("Scheduler, Error: ")
Scheduler::Scheduler(bool runthread, QMap *tvList,
- QString recordTbl, MSqlQueryInfo *databaseConnection,
- Scheduler *master_sched)
+ QString recordTbl, Scheduler *master_sched)
{
hasconflicts = false;
m_tvList = tvList;
@@ -48,8 +47,11 @@
master_sched->getAllPending(&reclist);
}
- if (databaseConnection) dbConn = *databaseConnection;
- else dbConn = MSqlQuery::SchedCon();
+ // Only the master scheduler should use SchedCon()
+ if (runthread)
+ dbConn = MSqlQuery::SchedCon();
+ else
+ dbConn = MSqlQuery::DDCon();
recordTable = recordTbl;
@@ -1136,6 +1138,10 @@
if (reschedQueue.count())
{
+ // We might have been inactive for a long time, so make
+ // sure our DB connection is fresh before continuing.
+ dbConn = MSqlQuery::SchedCon();
+
gettimeofday(&fillstart, NULL);
QString msg;
while (reschedQueue.count())
@@ -1827,10 +1833,10 @@
QString query = QString(
"INSERT INTO recordmatch (recordid, chanid, starttime, manualid) "
"SELECT RECTABLE.recordid, program.chanid, program.starttime, "
-" IF(search = %1, recordid, 0) "
-"FROM RECTABLE, program ").arg(kManualSearch) + fromclauses[clause] + QString(
-" INNER JOIN channel ON (channel.chanid = program.chanid) "
-"WHERE ") + whereclauses[clause] + QString(" AND channel.visible = 1 AND "
+" IF(search = %1, recordid, 0) ").arg(kManualSearch) + QString(
+"FROM (RECTABLE, program INNER JOIN channel "
+" ON channel.chanid = program.chanid) ") + fromclauses[clause] + QString(
+" WHERE ") + whereclauses[clause] + QString(" AND channel.visible = 1 AND "
"((RECTABLE.type = %1 " // allrecord
"OR RECTABLE.type = %2 " // findonerecord
"OR RECTABLE.type = %3 " // finddailyrecord
Index: mythtv/programs/mythbackend/housekeeper.cpp
===================================================================
--- mythtv/programs/mythbackend/housekeeper.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythbackend/housekeeper.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -138,7 +138,6 @@
while (1)
{
- VERBOSE(VB_IMPORTANT, "Running HouseKeeping");
gContext->LogEntry("mythbackend", LP_DEBUG,
"Running housekeeping thread", "");
Index: mythtv/programs/mythbackend/scheduler.h
===================================================================
--- mythtv/programs/mythbackend/scheduler.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythbackend/scheduler.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -23,8 +23,7 @@
{
public:
Scheduler(bool runthread, QMap *tvList,
- QString recordTbl = "record", MSqlQueryInfo *dbConnUse = NULL,
- Scheduler *master_sched = NULL);
+ QString recordTbl = "record", Scheduler *master_sched = NULL);
~Scheduler();
void Reschedule(int recordid);
Index: mythtv/programs/mythbackend/filetransfer.cpp
===================================================================
--- mythtv/programs/mythbackend/filetransfer.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythbackend/filetransfer.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -131,3 +131,9 @@
return size;
}
+
+void FileTransfer::SetTimeout(bool fast)
+{
+ rbuffer->SetTimeout(fast);
+}
+
Index: mythtv/programs/mythbackend/autoexpire.cpp
===================================================================
--- mythtv/programs/mythbackend/autoexpire.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythbackend/autoexpire.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -291,7 +291,8 @@
if ((availFreeKB = getDiskSpace(record_file_prefix, tKB, uKB)) < 0)
{
- QString msg = QString("ERROR: Could not calculate free space.");
+ QString msg = QString("ERROR: Could not calculate free space for %1.")
+ .arg(record_file_prefix);
VERBOSE(VB_IMPORTANT, LOC + msg);
gContext->LogEntry("mythbackend", LP_WARNING,
"Autoexpire Recording", msg);
Index: mythtv/programs/mythbackend/filetransfer.h
===================================================================
--- mythtv/programs/mythbackend/filetransfer.h (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythbackend/filetransfer.h (.../branches/release-0-19-fixes) (revision 10931)
@@ -35,6 +35,8 @@
long long GetFileSize(void);
+ void SetTimeout(bool fast);
+
private:
bool readthreadlive;
QMutex readthreadLock;
Index: mythtv/programs/mythtv/main.cpp
===================================================================
--- mythtv/programs/mythtv/main.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythtv/main.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -13,8 +13,6 @@
#include
using namespace std;
-MythContext *gContext;
-
static void *run_priv_thread(void *data)
{
(void)data;
@@ -102,6 +100,9 @@
gContext->LoadQtConfig();
+#if defined(Q_OS_MACX)
+ // Mac OS X doesn't define the AudioOutputDevice setting
+#else
QString auddevice = gContext->GetSetting("AudioOutputDevice");
if (auddevice == "" || auddevice == QString::null)
{
@@ -109,6 +110,7 @@
"to run 'mythfrontend', not 'mythtv'.");
return TV_EXIT_NO_AUDIO;
}
+#endif
print_verbose_messages |= VB_PLAYBACK | VB_LIBAV;// | VB_AUDIO;
@@ -132,6 +134,7 @@
ProgramInfo *pginfo = new ProgramInfo();
pginfo->endts = QDateTime::currentDateTime().addSecs(-180);
pginfo->pathname = filename;
+ pginfo->isVideo = true;
tv->Playback(pginfo);
}
Index: mythtv/programs/mythfilldatabase/filldata.cpp
===================================================================
--- mythtv/programs/mythfilldatabase/filldata.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/programs/mythfilldatabase/filldata.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -337,7 +337,7 @@
MSqlQuery query(MSqlQuery::InitCon());
query.prepare("SELECT ch.chanid, nim.url "
- "FROM channel ch, callsignnetworkmap csm "
+ "FROM (channel ch, callsignnetworkmap csm) "
"RIGHT JOIN networkiconmap nim ON csm.network = nim.network "
"WHERE ch.callsign = csm.callsign AND "
"(icon = :NOICON OR icon = '') AND ch.sourceid = :SOURCEID");
@@ -2174,7 +2174,8 @@
0 /*service id*/, major, minor,
false /*use on air guide*/, false /*hidden*/,
false /*hidden in guide*/,
- freqid, localfile, (*i).tvformat))
+ freqid, localfile, (*i).tvformat,
+ (*i).xmltvid))
{
cout << "### " << endl;
cout << "### Channel inserted" << endl;
@@ -3851,7 +3852,6 @@
VERBOSE(VB_IMPORTANT, "Failed to fetch some program info");
gContext->LogEntry("mythfilldatabase", LP_WARNING,
"Failed to fetch some program info", "");
- return FILLDB_EXIT_DB_ERROR;
}
else
VERBOSE(VB_IMPORTANT, "Data fetching complete.");
Index: mythtv/setup/backendsettings.cpp
===================================================================
--- mythtv/setup/backendsettings.cpp (.../tags/release-0-19) (revision 10931)
+++ mythtv/setup/backendsettings.cpp (.../branches/release-0-19-fixes) (revision 10931)
@@ -1,6 +1,7 @@
#include
#include "backendsettings.h"
+#include "frequencies.h"
#include "libmyth/mythcontext.h"
#include "libmyth/settings.h"
#include
@@ -110,23 +111,10 @@
{
GlobalComboBox *gc = new GlobalComboBox("FreqTable");
gc->setLabel(QObject::tr("Channel frequency table"));
- gc->addSelection("us-cable");
- gc->addSelection("us-bcast");
- gc->addSelection("us-cable-hrc");
- gc->addSelection("us-cable-irc");
- gc->addSelection("japan-bcast");
- gc->addSelection("japan-cable");
- gc->addSelection("europe-west");
- gc->addSelection("europe-east");
- gc->addSelection("italy");
- gc->addSelection("newzealand");
- gc->addSelection("australia");
- gc->addSelection("ireland");
- gc->addSelection("france");
- gc->addSelection("china-bcast");
- gc->addSelection("southafrica");
- gc->addSelection("argentina");
- gc->addSelection("australia-optus");
+
+ for (uint i = 0; chanlists[i].name; i++)
+ gc->addSelection(chanlists[i].name);
+
gc->setHelpText(QObject::tr("Select the appropriate frequency table for "
"your system. If you have an antenna, use a \"-bcast\" "
"frequency."));