From pouchintv-dev at baysse.fr Thu Aug 6 19:55:45 2009
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: Thu, 06 Aug 2009 17:55:45 -0000
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r199 - in trunk: . docs
docs/scripts_serveur
Message-ID: <20090806175526.4EE7986AC1@mail.baysse.fr>
Author: gingko
Date: 2009-08-06 19:55:25 +0200 (jeu 06 aoû 2009)
New Revision: 199
Added:
trunk/docs/scripts_serveur/
trunk/docs/scripts_serveur/commun_xml.inc.old.php
trunk/docs/scripts_serveur/commun_xml.inc.php
trunk/docs/scripts_serveur/version.php
trunk/docs/scripts_serveur/version_debug.php
trunk/docs/scripts_serveur/version_old.php
trunk/make_lzma.cmd
Modified:
trunk/Pouchin TV_2005.vcproj
trunk/Pouchin TV_2008.vcproj
trunk/base.cpp
trunk/base.h
trunk/channels.cpp
trunk/console.cpp
trunk/graph.cpp
trunk/graph.h
trunk/ini.cpp
trunk/ini.h
trunk/internet.cpp
trunk/main.cpp
trunk/main.h
trunk/parse.cpp
trunk/res.rc
trunk/resource.h
trunk/settings.cpp
trunk/update.cpp
trunk/utils.cpp
trunk/utils.h
trunk/xml.cpp
Log:
Mise à jour du systeme de ... euh ... mise à jour de Pouchin TV Mod.
update.cpp, resource.h, res.rc:
* Remaniement de la fonctionnalité de mise à jour par Internet, incluant
diverses factorisations.
* La mise à jour distingue maintenant entre les versions 32 et 64 bits de
l'application.
* La mise à jour des versions beta (ou expérimentales) est maintenant prise en
charge. L'utilisateur peut choisir de mettre à jour avec ces versions, ou pas.
* Les fichiers mis à jour par ce biais se voient assigner la date et l'heure de
dernière modification du fichier distant (telle qu'incluse dans les en-têtes
HTTP).
* Les versions "debug" réfèrent à un script distinct sur le serveur de mise à jour.
* Ajout d'une vérification pour empêcher de demander une mise à jour si une mise
à jour qui vient d'être faite n'a pas été suivie d'un redémarrage de PTVM.
* Utilisation d'objets STL "vector" et "string" / "tstring" pour éviter des
allocations "malloc" / "free".
* La fonction "AddStatut" est éclatée en deux fonctions "AddMsg" et "AddProgress",
ces deux aspects étant suffisamment indépendants pour que leur mélange soit plus
gênant qu'avantageux.
* Diverses réorganisations pour rendre le code plus modulaire et faciliter les
changement présents et à venir.
internet.cpp :
* Les requêtes de téléchargement par Internet indiquent un paramètre "User Agent"
contenant davantage d'informations sur l'application utilisée.
utils.h, utils.cpp :
* Ajout de macros utilitaires "ITERATE_XML_CHILDREN", "ITERATE_XML_ELEMENTS" et
"ITERATE_XML_ELEMENTS_NAMED" pour naviquer dans les noeuds TiXML.
* Ajout d'une macro utilitaire "FMT_BUF" pour faciliter l'encapsulation de
fonctionnalités de style "printf" dans des fonctions qui les requièrent
fréquemment.
* Ajout d'une fonction StringToEnum, réalisant la fonctionnalité inverse
de la fonction EnumToString précédemment existante.
* Les deux fonctions "FindFileRecur" sont remaniées et généralisées avec
un paramétrage pour la récursivité ou la recherche de répertoires. La
récursivité étant maintenant une option, ces fonctions sont en conséquence
renommées en "FindFile".
* Les fonctions "ConvertChar2UTF8" sont remaniées afin de retourner une
chaîne de caractères "string" ou "tstring", au lieu d'allouer leur résultat
avec "malloc" (requérant libération par "free"). La version "un caractère" de
"ConvertChar2UTF8" renvoie sont résultat dans un buffer plutôt que de l'allouer
avec "malloc".
* Ajout d'une fonction "RTrimStr" pour nettoyer les espaces et caractères spéciaux
à la fin d'une chaîne de caractères.
* "WChar2Char" (en version SBCS) utilise maintenant un objet std::string.
* Ajout d'une structure "TempPathName" pour faciliter la création de fichiers dans
le répertoire "%TEMP%".
ini.h, ini.cpp :
* Ajout d'une fonction "FindAppFile", spécialisation du "FindFile", pour rechercher
des fichiers ou dossiers dans les dossiers de PTVM.
channels.cpp :
* "cherche_icone" utilise maintenant la fonction "FindAppFile" décrit plus haut. Du
coup, cette fonction "cherche_icone" ne requiert plus d'être appelée qu'une seule fois.
base.h, base.cpp, graph.h, graph.cpp, utils.h, utils.cpp :
* La fonction GetErrorText est déplacée dans graph.h/cpp et renommée
au passage en DShowErrorToString.
* Ajout dans utils.h/cpp d'une fonction analogue pour traduire en clair
les codes d'erreur système renvoyés par GetErrorCode.
base.cpp, console.cpp, graph.cpp, parse.cpp, xml.cpp :
* Changement divers exploitant la factorisation permise par les nouveaux objets ajoutés
dans utils.h/cpp.
main.h, main.cpp, settings.cpp :
* Implémentation d'une fonction de redémarrage de l'application complète, en
en remplacement de celle qui existait dans "update.cpp", et destinée au même
usage. Cette fonction réplique, si nécessaire, le préfixe d'instance d'application.
* Ajout d'une variable globale contenant le nom et le chemin d'exécution de
l'application PTVM.
Pouchin TV_2005.vcproj, Pouchin TV_2008.vcproj, make_lzma.cmd :
* La génération des versions "Release" Unicode 32 et 64 bits produit également un
fichier "lzma" destiné aux mises à jour par Internet.
* Ajout d'un script "make_lzma.cmd" pour faciliter cette génération.
Ces changements sont associés à une mise à jour des scripts "version.php" et
"commun_xml.inc.php" sur le serveur pour prendre en charge les fonctionnalités
ajoutées à la mise à jour Internet de l'application. Un script jumeau "version_debug.php" y est
également ajouté pour le debugging. Pour référence, j'inclus aussi dans la présente
livraison une copie des scripts du serveur (ancien et nouveau).
Modifié: trunk/Pouchin TV_2005.vcproj
===================================================================
--- trunk/Pouchin TV_2005.vcproj 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/Pouchin TV_2005.vcproj 2009-08-06 17:55:25 UTC (rev 199)
@@ -283,9 +283,8 @@
/>
0 && UINT(szBuffer[--nLen])<=' ')
- szBuffer[nLen]=0;
-
- return tstring(szBuffer);
-};
-
-/**
* Met en file d'attente le message d'erreur passé en paramètre pour un affichage ultérieur
*
* \param[in] str Le message à stocker, et pouvant être passé à un printf
@@ -112,23 +91,18 @@
// Utile simplement si on passe un message d'erreur personnalisé
if (str) {
// Buffer de stockage temporaire
- TCHAR buffer[0x200];
- va_list argptr;
+ FMT_BUF(buffer, 200, str, hr);
- va_start(argptr, hr);
- _vstprintf_s(buffer, str, argptr);
- va_end(argptr);
-
if (!strErrBuf.empty())
strErrBuf += TEXT("\n");
strErrBuf += buffer;
- // Logue le message d'erreur
+ // Enregistre le message d'erreur
myprintferror(buffer);
}
if (FAILED(hr) && hr!=lastRes) {
- erreur(TEXT("%s (code 0x%08x)"), S_OK, GetErrorText(hr).c_str(), hr);
+ erreur(TEXT("%s (code 0x%08x)"), S_OK, DShowErrorToString(hr).c_str(), hr);
lastRes = hr;
}
Modifié: trunk/base.h
===================================================================
--- trunk/base.h 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/base.h 2009-08-06 17:55:25 UTC (rev 199)
@@ -203,15 +203,6 @@
};
/**
- * Obtenir, en clair, le message d'erreur correspondant à un code retour HRESULT.
- *
- * \param[in] hr Code retour à décoder
- * \return Une chaîne de caractères, format \p tstring (= \p string ou \p wstring),
- * contenant le message d'erreur correspondant
- **/
-tstring GetErrorText(HRESULT hr);
-
-/**
* Met en file d'attente le message d'erreur passé en paramètre pour un affichage ultérieur
*
* \param[in] str Le message à stocker, et pouvant être passé à un printf
Modifié: trunk/channels.cpp
===================================================================
--- trunk/channels.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/channels.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -47,26 +47,19 @@
// Taille des images des chaînes (largeur et longueur)
#define TAILLE_IMAGE_CHAINE 16
-static HBITMAP cherche_icone(LPCTSTR dir, LPCTSTR nom)
+static HBITMAP cherche_icone(LPCTSTR nom)
{
- TCHAR pathName[MAX_PATH],
- fileName[MAX_PATH];
- HBITMAP hImage = NULL;
- LPTSTR szChemin = NULL;
+ TCHAR fileName[MAX_PATH];
+ HBITMAP hImage = NULL;
+ tstring strChemin;
// Concaténation chemin et chaîne
- _stprintf_s(fileName, _countof(fileName), TEXT("%s.bmp"), nom);
- _stprintf_s(pathName, _countof(pathName), TEXT("%sIcones\\"), dir);
+ _stprintf_s(fileName, TEXT("%s.bmp"), nom);
- //myprintf(TEXT("FindFileRecur(\n\t\"%s\",\n\t\"%s\",\n\t"), pathName, fileName);
- if (FindFileRecur(pathName, fileName, &szChemin)) {
- //myprintf(TEXT("\"%s\")\n"),szChemin);
- hImage = (HBITMAP)LoadImage(NULL, szChemin, IMAGE_BITMAP,
+ if (FindAppFile(TEXT("Icones"), fileName, strChemin)!=pd_notfound) {
+ hImage = (HBITMAP)LoadImage(NULL, strChemin.c_str(), IMAGE_BITMAP,
TAILLE_IMAGE_CHAINE, TAILLE_IMAGE_CHAINE, LR_LOADFROMFILE | LR_LOADTRANSPARENT);
}
- //else
- // myprintf(TEXT("[échec])\n"),szChemin);
- free(szChemin);
return hImage;
}
@@ -148,19 +141,11 @@
**/
NomProtege nom_canal(nom, '_');
- hImage = cherche_icone(pouchindir_conf, nom_canal.nom);
-
- // Ne recherche que si le dossier de config est différent du dossier du programme
- if (hImage == NULL && _tcscmp(pouchindir_conf, pouchindir_prog) != 0) {
- // Le fichier n'a pas été trouvé dans le dossier des configs.
- // Recherche dans le dossier de Pouchin TV Mod
-
- hImage = cherche_icone(pouchindir_prog, nom_canal.nom);
- if (hImage == NULL) {
- // Toujours pas trouvé : on met INVALID_HANDLE_VALUE pour se rappeler de ne plus le
- // rechercher avant le prochain lancement du programme.
- hImage = (HBITMAP)INVALID_HANDLE_VALUE;
- }
+ hImage = cherche_icone(nom_canal.nom);
+ if (hImage == NULL) {
+ // Pas trouvé : on met INVALID_HANDLE_VALUE pour se rappeler de ne plus le
+ // rechercher avant le prochain lancement du programme.
+ hImage = (HBITMAP)INVALID_HANDLE_VALUE;
}
}
Modifié: trunk/console.cpp
===================================================================
--- trunk/console.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/console.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -85,17 +85,11 @@
// leur propre système de capture, alors il est moins utile d'avoir
// une copie dans "pouchin.log".
#else // #if USE_CONSOLE==-1
- static TCHAR szLogFileName[MAX_PATH] = {0};
+ // Initialisation à la première exécution, seulement
+ static TempPathName sLogFileName("pouchin.log");
- if (!*szLogFileName) {
- GetTempPath(_countof(szLogFileName), szLogFileName);
-
- // Initialisation à la première exécution, seulement
- strcat_T(szLogFileName, TEXT("pouchin.log"));
- }
-
FILE * f;
- errno_t nRes = _tfopen_s(&f, szLogFileName, TEXT("a"));
+ errno_t nRes = _tfopen_s(&f, sLogFileName, TEXT("a"));
if (nRes==0) {
_fputts(s, f);
Property changes on: trunk/docs/scripts_serveur
___________________________________________________________________
Ajouté : tsvn:logminsize
+ 25
Ajouté: trunk/docs/scripts_serveur/commun_xml.inc.old.php
===================================================================
--- trunk/docs/scripts_serveur/commun_xml.inc.old.php (rev 0)
+++ trunk/docs/scripts_serveur/commun_xml.inc.old.php 2009-08-06 17:55:25 UTC (rev 199)
@@ -0,0 +1,131 @@
+
+ * @param string nom du fichier à inclure
+ * @param string langue à utiliser dans le fichier de sortie
+ **/
+ function __construct() {
+ // Document
+// $this->_dom = new DOMDocument('1.0', 'ISO-8859-15');
+ $this->_dom = new DOMDocument('1.0', 'UTF-8');
+
+ // Racine du document
+ $this->_racine = $this->_dom->createElement('Versions');
+ $this->_dom->appendChild($this->_racine);
+ // On demande l'indentation
+ $this->_dom->formatOutput = true;
+ } // function __construct($fichier, $lang='fr')
+
+ /**
+ * Définit la version
+ *
+ * @param integer identifiant de la carte
+ * @param string nom litéral de la carte à charger
+ * @param integer largeur de l'image
+ * @param integer hauteur de l'image
+ **/
+ function setAppVersion($release, $subrelease, $major, $minor, $revision, $url, $compress=true) {
+ $this->_versions[$release][$subrelease] = array(
+ 'major' => $major,
+ 'minor' => $minor,
+ 'rev' => $revision,
+ 'compress' => $compress,
+ 'url' => $url);
+ }
+
+ function addIcons() {
+ // Génère la liste des icônes
+ $icones_dir = scandir('autoupd/Icones');
+
+ $icones = array();
+ $i = 0;
+ foreach( $icones_dir as $icone) {
+ // Répertoires administratifs
+ if ($icone == '.svn' || $icone == '.' || $icone == '..')
+ continue;
+
+ // C'est une icône à la racine
+ if (! is_dir('autoupd/Icones/'. $icone)) {
+ $icones['France'][$i++] = substr($icone, 0, -4);
+ } else {
+ // Icône dans un sous réspertoire
+ $icones_cathegorie = scandir('autoupd/Icones/'. $icone);
+ $j = 0;
+ foreach( $icones_cathegorie as $ic) {
+ if ($ic == '.svn' || $ic == '.' || $ic == '..')
+ continue;
+ $icones[$icone][$j++] = substr($ic, 0, -4);
+ }
+ }
+ }
+
+ $this->_icones = $icones;
+ }
+
+ /**
+ * renvoie le fichier
+ *
+ * @return object objet dom à envoyer
+ **/
+ function recup() {
+ $dom = $this->_dom;
+ $racine = $dom->getElementsByTagName('Versions')->item(0);
+
+ // Traite les revisions
+ foreach ($this->_versions as $version_key => $version_data) {
+ $v = $dom->createElement('version');
+ $v->setAttribute('version', '1');
+ $v->setAttribute('type', $version_key);
+ foreach ($version_data as $subversion_key => $subversion_data) {
+ $elem = $dom->createElement($subversion_key);
+ $elem->setAttribute('major', $subversion_data['major']);
+ $elem->setAttribute('minor', $subversion_data['minor']);
+ $elem->setAttribute('rev', $subversion_data['rev']);
+ $elem->setAttribute('c', $subversion_data['compress']);
+ $elem->appendChild($dom->createTextNode($subversion_data['url']));
+ $v->appendChild($elem);
+ }
+ $racine->appendChild($v);
+ }
+
+ // Commun à toutes les versions
+ $commun = $dom->createElement('version');
+ $commun->setAttribute('version', '1');
+ $commun->setAttribute('type', 'common');
+ $racine->appendChild($commun);
+
+ // Traite les icones
+ $icones = $dom->createElement('icones');
+ $icones->setAttribute('base', 'http://pouchintv.baysse.fr/autoupd/Icones/');
+ $commun->appendChild($icones);
+ foreach ($this->_icones as $icone_key => $icone_data) {
+ $pack = $dom->createElement('pack');
+ $pack->setAttribute('pays', $icone_key);
+ $pack->setAttribute('path', ($icone_key == 'France' ? '/' : $icone_key));
+ foreach ($icone_data as $bmp) {
+ $ic = $dom->createElement('icone');
+ $ic->appendChild($dom->createTextNode($bmp));
+ $pack->appendChild($ic);
+ }
+ $icones->appendChild($pack);
+ }
+
+ $dom->normalize();
+ return $dom;
+ }
+}
+
+?>
Ajouté: trunk/docs/scripts_serveur/commun_xml.inc.php
===================================================================
--- trunk/docs/scripts_serveur/commun_xml.inc.php (rev 0)
+++ trunk/docs/scripts_serveur/commun_xml.inc.php 2009-08-06 17:55:25 UTC (rev 199)
@@ -0,0 +1,123 @@
+
+ * @param string nom du fichier à inclure
+ * @param string langue à utiliser dans le fichier de sortie
+ **/
+ function __construct() {
+ // Document
+// $this->_dom = new DOMDocument('1.0', 'ISO-8859-15');
+ $this->_dom = new DOMDocument('1.0', 'UTF-8');
+
+ // Racine du document
+ $this->_racine = $this->_dom->createElement('Versions');
+ $this->_dom->appendChild($this->_racine);
+ // On demande l'indentation
+ $this->_dom->formatOutput = true;
+ } // function __construct($fichier, $lang='fr')
+
+ function setAppVersion($release, $subrelease, $arvers) {
+ $this->_versions[$release][$subrelease] = $arvers;
+ }
+
+ function addIcons() {
+ // Génère la liste des icônes
+ $icones_dir = scandir('autoupd/Icones');
+
+ $icones = array();
+ $i = 0;
+ foreach( $icones_dir as $icone) {
+ // Répertoires administratifs
+ if ($icone == '.svn' || $icone == '.' || $icone == '..')
+ continue;
+
+ // C'est une icône à la racine
+ if (! is_dir('autoupd/Icones/'. $icone)) {
+ $icones['France'][$i++] = 'autoupd/Icones/'. $icone;
+ } else {
+ // Icône dans un sous réspertoire
+ $icones_categorie = scandir('autoupd/Icones/'. $icone);
+ $j = 0;
+ foreach( $icones_categorie as $ic) {
+ if ($ic{0} == '.')
+ continue;
+ $icones[$icone][$j++] = "autoupd/Icones/$icone/$ic";
+ }
+ }
+ }
+
+ $this->_icones = $icones;
+ }
+
+ /**
+ * renvoie le fichier
+ *
+ * @param baseurl URL de base
+ * @param version Version des noeuds XML des versions
+ * @return object objet dom à envoyer
+ **/
+ function recup($baseurl, $version) {
+ $dom = $this->_dom;
+ $racine = $dom->getElementsByTagName('Versions')->item(0);
+
+ // Traite les revisions
+ foreach ($this->_versions as $version_key => $version_data) {
+ $v = $dom->createElement('version');
+ $v->setAttribute('version', $version);
+ $v->setAttribute('type', $version_key);
+ foreach ($version_data as $subversion_key => $subversion_data) {
+ $elem = $dom->createElement($subversion_key);
+ $elem->setAttribute('major', $subversion_data['major']);
+ $elem->setAttribute('minor', $subversion_data['minor']);
+ $elem->setAttribute('rev', $subversion_data['rev']);
+ $elem->setAttribute('svn', $subversion_data['svn']);
+ $elem->setAttribute('c', $subversion_data['compress']);
+ $elem->appendChild($dom->createTextNode($subversion_data['url']));
+ $v->appendChild($elem);
+ }
+ $racine->appendChild($v);
+ }
+
+ // Commun à toutes les versions
+ $commun = $dom->createElement('version');
+ $commun->setAttribute('version', $version);
+ $commun->setAttribute('type', 'common');
+ $racine->appendChild($commun);
+
+ // Traite les icones
+ $icones = $dom->createElement('icones');
+ $icones->setAttribute('base', $baseurl.'Icones/');
+ $commun->appendChild($icones);
+ foreach ($this->_icones as $icone_key => $icone_data) {
+ $pack = $dom->createElement('pack');
+ $pack->setAttribute('pays', $icone_key);
+ $pack->setAttribute('path', ($icone_key == 'France' ? '/' : $icone_key));
+ foreach ($icone_data as $bmp) {
+ $icdate = date("Y-m-d", filemtime($bmp));
+ $ic = $dom->createElement('icone');
+ $ic->setAttribute('date', $icdate);
+ $ic->appendChild($dom->createTextNode(basename($bmp, ".bmp")));
+ $pack->appendChild($ic);
+ }
+ $icones->appendChild($pack);
+ }
+
+ $dom->normalize();
+ return $dom;
+ }
+}
+
+?>
Ajouté: trunk/docs/scripts_serveur/version.php
===================================================================
--- trunk/docs/scripts_serveur/version.php (rev 0)
+++ trunk/docs/scripts_serveur/version.php 2009-08-06 17:55:25 UTC (rev 199)
@@ -0,0 +1,98 @@
+\n".
+ "\n".
+ " \n".
+ " stable\n".
+ " ". 0 ."\n".
+ " ". 4 ."\n".
+ " ". 131 ."\n".
+ " \n".
+ " \n".
+ " beta\n".
+ " ". 0 ."\n".
+ " ". 4 ."\n".
+ " ~svn-r". 130 ."\n".
+ " \n".
+ "";
+
+} else {
+ require 'commun_xml.inc.php';
+
+ $dom = new monDOM();
+
+ // Ajoute les définitions des nouvelles versions de PTVM
+
+ // Avant la révision 199, des noeuds 'app' étaient utilisés, au lieu de 'app32' et 'app64'.
+ // Il convient de ne pas utiliser ces noeuds 'app' ici, car faute de moyen de savoir quelle
+ // version de plateforme de PTVM requiert la mise à jour, ils risqueraient de provoquer
+ // le remplacement d'applications 64 bits avec des applications 32 bits.
+
+ // Stable 32 bits
+ $dom->setAppVersion('stable', 'app32', array(
+ "major" => UPDATE_STABLE_MAJOR, "minor" => UPDATE_STABLE_MINOR,
+ "rev" => UPDATE_STABLE_REV, "svn" => UPDATE_STABLE_SVN,
+ "url" => UPDATE_SITE.UPDATE_ROOT.UPDATE_STABLE_X86, "compress" => true));
+
+ // Stable 64 bits
+ $dom->setAppVersion('stable', 'app64', array(
+ "major" => UPDATE_STABLE_MAJOR, "minor" => UPDATE_STABLE_MINOR,
+ "rev" => UPDATE_STABLE_REV, "svn" => UPDATE_STABLE_SVN,
+ "url" => UPDATE_SITE.UPDATE_ROOT.UPDATE_STABLE_X64, "compress" => true));
+
+ // Beta 32 bits
+ $dom->setAppVersion('beta', 'app32', array(
+ "major" => UPDATE_BETA_MAJOR, "minor" => UPDATE_BETA_MINOR,
+ "rev" => UPDATE_BETA_REV, "svn" => UPDATE_BETA_SVN,
+ "url" => UPDATE_SITE.UPDATE_ROOT.UPDATE_BETA_X86, "compress" => true));
+
+ // Beta 64 bits
+ $dom->setAppVersion('beta', 'app64', array(
+ "major" => UPDATE_BETA_MAJOR, "minor" => UPDATE_BETA_MINOR,
+ "rev" => UPDATE_BETA_REV, "svn" => UPDATE_BETA_SVN,
+ "url" => UPDATE_SITE.UPDATE_ROOT.UPDATE_BETA_X64, "compress" => true));
+
+ $dom->addIcons();
+
+ // Génère, et affiche le document XML à l'utilisateur
+ echo $dom->recup(UPDATE_SITE.UPDATE_ROOT, UPDATE_VERSION)->saveXML();
+}
+?>
Ajouté: trunk/docs/scripts_serveur/version_debug.php
===================================================================
--- trunk/docs/scripts_serveur/version_debug.php (rev 0)
+++ trunk/docs/scripts_serveur/version_debug.php 2009-08-06 17:55:25 UTC (rev 199)
@@ -0,0 +1,98 @@
+\n".
+ "\n".
+ " \n".
+ " stable\n".
+ " ". 0 ."\n".
+ " ". 4 ."\n".
+ " ". 131 ."\n".
+ " \n".
+ " \n".
+ " beta\n".
+ " ". 0 ."\n".
+ " ". 4 ."\n".
+ " ~svn-r". 130 ."\n".
+ " \n".
+ "";
+
+} else {
+ require 'commun_xml.inc.php';
+
+ $dom = new monDOM();
+
+ // Ajoute les définitions des nouvelles versions de PTVM
+
+ // Avant la révision 199, des noeuds 'app' étaient utilisés, au lieu de 'app32' et 'app64'.
+ // Il convient de ne pas utiliser ces noeuds 'app' ici, car faute de moyen de savoir quelle
+ // version de plateforme de PTVM requiert la mise à jour, ils risqueraient de provoquer
+ // le remplacement d'applications 64 bits avec des applications 32 bits.
+
+ // Stable 32 bits
+ $dom->setAppVersion('stable', 'app32', array(
+ "major" => UPDATE_STABLE_MAJOR, "minor" => UPDATE_STABLE_MINOR,
+ "rev" => UPDATE_STABLE_REV, "svn" => UPDATE_STABLE_SVN,
+ "url" => UPDATE_SITE.UPDATE_ROOT.UPDATE_STABLE_X86, "compress" => true));
+
+ // Stable 64 bits
+ $dom->setAppVersion('stable', 'app64', array(
+ "major" => UPDATE_STABLE_MAJOR, "minor" => UPDATE_STABLE_MINOR,
+ "rev" => UPDATE_STABLE_REV, "svn" => UPDATE_STABLE_SVN,
+ "url" => UPDATE_SITE.UPDATE_ROOT.UPDATE_STABLE_X64, "compress" => true));
+
+ // Beta 32 bits
+ $dom->setAppVersion('beta', 'app32', array(
+ "major" => UPDATE_BETA_MAJOR, "minor" => UPDATE_BETA_MINOR,
+ "rev" => UPDATE_BETA_REV, "svn" => UPDATE_BETA_SVN,
+ "url" => UPDATE_SITE.UPDATE_ROOT.UPDATE_BETA_X86, "compress" => true));
+
+ // Beta 64 bits
+ $dom->setAppVersion('beta', 'app64', array(
+ "major" => UPDATE_BETA_MAJOR, "minor" => UPDATE_BETA_MINOR,
+ "rev" => UPDATE_BETA_REV, "svn" => UPDATE_BETA_SVN,
+ "url" => UPDATE_SITE.UPDATE_ROOT.UPDATE_BETA_X64, "compress" => true));
+
+ $dom->addIcons();
+
+ // Génère, et affiche le document XML à l'utilisateur
+ echo $dom->recup(UPDATE_SITE.UPDATE_ROOT, UPDATE_VERSION)->saveXML();
+}
+?>
Ajouté: trunk/docs/scripts_serveur/version_old.php
===================================================================
--- trunk/docs/scripts_serveur/version_old.php (rev 0)
+++ trunk/docs/scripts_serveur/version_old.php 2009-08-06 17:55:25 UTC (rev 199)
@@ -0,0 +1,31 @@
+
+ stable'. $major .''. $minor .''. $rev .'beta'. $major .''. $minor .'~svn-r'. $rev .'';
+
+} else {
+ require 'commun_xml.inc.php';
+
+ $dom = new monDOM();
+
+ // Ajoute une nouvelle version de PTVM
+ $dom->setAppVersion('stable', 'app',
+ $major, $minor,
+// 300
+ $rev
+ ,
+ 'http://pouchintv.baysse.fr/autoupd/PouchinTVMod.exe.upd');
+
+ $dom->addIcons();
+
+ // Gérère, et affiche le document XML à l'utilisateur
+ echo $dom->recup()->saveXML();
+}
+?>
Modifié: trunk/graph.cpp
===================================================================
--- trunk/graph.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/graph.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -427,12 +427,9 @@
#if LOG_DSHOW
HRESULT CPTvM_GraphBase::AddLog(LPCTSTR pszLogBaseFileName)
{
- TCHAR szLogFileName[MAX_PATH];
+ TempPathName sLogFileName(pszLogBaseFileName);
- GetTempPath(_countof(szLogFileName), szLogFileName);
- strcat_T(szLogFileName, pszLogBaseFileName);
-
- logFile = CreateFile(szLogFileName, GENERIC_WRITE, FILE_SHARE_READ,
+ logFile = CreateFile(sLogFileName, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (logFile != INVALID_HANDLE_VALUE)
return pGraph->SetLogFile((DWORD_PTR)logFile);
@@ -1397,7 +1394,7 @@
#if USE_CONSOLE
case EC_ERRORABORT: // 0x03
myprintf(TEXT("EC_ERRORABORT, raison=%08x: %s\n"), HRESULT(param1),
- GetErrorText(HRESULT(param1)).c_str());
+ DShowErrorToString(HRESULT(param1)).c_str());
break;
#endif
@@ -1406,7 +1403,7 @@
http://www.eggheadcafe.com/conversation.aspx?messageid=29757074&threadid=29757074 */
#if USE_CONSOLE
myprintf(TEXT("EC_PAUSED, raison=0x%08x: %s\n"), HRESULT(param1),
- GetErrorText(HRESULT(param1)).c_str());
+ DShowErrorToString(HRESULT(param1)).c_str());
#endif
#if USE_AUTO_RETUNE
bSendTuneCmd = auto_resyntonisation;
@@ -1418,7 +1415,7 @@
#if USE_CONSOLE
myprintf(TEXT("EC_STREAM_ERROR_STILLPLAYING, code=0x%08x: %s, minor=0x%08x\n"),
HRESULT(param1),
- GetErrorText(HRESULT(param1)).c_str(), DWORD(param2));
+ DShowErrorToString(HRESULT(param1)).c_str(), DWORD(param2));
#endif
#ifdef USE_AUTO_RETUNE
if (auto_resyntonisation) {
@@ -1659,15 +1656,10 @@
if (!pstr)
return;
- TCHAR szBuffer[96];
-
- va_list args;
- va_start(args, pszFmt);
- _vstprintf_s(szBuffer, pszFmt, args);
- va_end(args);
if (!pstr->empty())
*pstr += TEXT("; ");
- *pstr += szBuffer;
+ FMT_BUF(szBuf, 96, pszFmt, pszFmt);
+ *pstr += szBuf;
}
/**
@@ -2086,3 +2078,22 @@
lastSection = ((const SI_hdr *)data)->last_section_number;
return true;
}
+
+// ====================================================================================
+// Conversion de code d'erreur
+// ====================================================================================
+
+/**
+ * Conversion d'un code d'erreur DirectShow en une chaîne de caractères affichable.
+ *
+ * \param[in] hr Code d'erreur à convertir
+ * \return Une chaîne de caractères, format \p tstring (= \p string ou \p wstring),
+ * contenant le message d'erreur correspondant
+ **/
+tstring DShowErrorToString(HRESULT hr)
+{
+ TCHAR szBuffer[MAX_ERROR_TEXT_LEN];
+
+ AMGetErrorText(hr, szBuffer, _countof(szBuffer));
+ return RTrimStr(szBuffer); // Conversion implicite en tstring
+};
Modifié: trunk/graph.h
===================================================================
--- trunk/graph.h 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/graph.h 2009-08-06 17:55:25 UTC (rev 199)
@@ -271,6 +271,15 @@
return false;
}
+/**
+ * Conversion d'un code d'erreur DirectShow en une chaîne de caractères affichable.
+ *
+ * \param[in] hr Code d'erreur à convertir
+ * \return Une chaîne de caractères, format \p tstring (= \p string ou \p wstring),
+ * contenant le message d'erreur correspondant
+ **/
+tstring DShowErrorToString(HRESULT hr);
+
// ====================================================================================
// Qualité du signal
// ====================================================================================
Modifié: trunk/ini.cpp
===================================================================
--- trunk/ini.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/ini.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -2251,6 +2251,39 @@
CreateDirectory(pouchindir_conf, NULL);
}
+
+/**
+ * Recherche (optionnellement récursive) d'un fichier correspondant au nom passé en paramètre,
+ * dans les répertoires de l'application.
+ *
+ * \param[in] pszSubDir sous-répertoire initial pour la recherche
+ * \param[in] pszFile fichier, ou motif de recherche en codage UTF-8
+ * \param[out] strResult Nom du premier fichier trouvé avec le chemin
+ * \param[in] dwFlags Options de recherche (FF_RECURSIVE, FF_DIRECTORY)
+ * \return Valeur indiquant si le fichier a été trouvé ou pas, et dans quel répertoire
+ **/
+FapfResult FindAppFile(LPCTSTR pszSubDir, LPCTSTR pszFile, tstring & strResult, DWORD dwFlags)
+{
+ TCHAR pathName[MAX_PATH];
+
+ // Recherche dans le répertoire de configuration (%AppData%) :
+ strcpy_T(pathName, pouchindir_conf);
+ if (pszSubDir)
+ strcat_T(pathName, pszSubDir);
+ if (!(strResult = FindFile(pathName, pszFile, dwFlags)).empty())
+ return pd_conf;
+
+ if (_tcscmp(pouchindir_conf, pouchindir_prog)!=0) {
+ // Recherche dans le répertoire de l'application (si ce n'est pas le même) :
+ strcpy_T(pathName, pouchindir_prog);
+ if (pszSubDir)
+ strcat_T(pathName, pszSubDir);
+ if (!(strResult = FindFile(pathName, pszFile, dwFlags)).empty())
+ return pd_prog;
+ }
+ return pd_notfound;
+}
+
// ====================================================================================
// Membres de la classe d'accès aux fichiers d'initialisation (.ini) - chargement
// ====================================================================================
Modifié: trunk/ini.h
===================================================================
--- trunk/ini.h 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/ini.h 2009-08-06 17:55:25 UTC (rev 199)
@@ -274,6 +274,26 @@
**/
void ini_app_paths();
+/// Résultat de recherche dans les répertoires
+enum FapfResult
+{
+ pd_notfound, //!< Pas trouvé
+ pd_prog, //!< Trouvé dans le répertoire de configuration
+ pd_conf //!< Trouvé dans le épertoire du programme
+};
+
+/**
+ * Recherche (optionnellement récursive) d'un fichier correspondant au nom passé en paramètre,
+ * dans les répertoires de l'application.
+ *
+ * \param[in] pszSubDir sous-répertoire initial pour la recherche
+ * \param[in] pszFile fichier, ou motif de recherche en codage UTF-8
+ * \param[out] strResult Nom du premier fichier trouvé avec le chemin
+ * \param[in] dwFlags Options de recherche (FF_RECURSIVE, FF_DIRECTORY)
+ * \return Valeur indiquant si le fichier a été trouvé ou pas, et dans quel répertoire
+ **/
+FapfResult FindAppFile(LPCTSTR pszSubDir, LPCTSTR pszFile, tstring & strResult, DWORD dwFlags=FF_RECURSIVE);
+
/// Nom de fichier situé avec les données de l'application
struct NomFichierConf
{
Modifié: trunk/internet.cpp
===================================================================
--- trunk/internet.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/internet.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -39,9 +39,6 @@
#include "internet.h"
#include "version.h"
-/// User-Agent utilisé par défaut
-#define USER_AGENT TEXT("Pouchin TV Mod/") TEXT(PTVM_VERSION_STR)
-
/**
* Initialise les valeurs par défaut, l'User-Agent, la méthode à GET et le type de fichiers accepté
*
@@ -57,7 +54,9 @@
m_recupere(0),
m_content_type(0)
{
- SetUserAgent(USER_AGENT);
+ // Définition du "User Agent" (nom de l'application avec version détaillée)
+ SetUserAgent(tstr_printf(TEXT("%s / %s"), szAppName, szAppVersion).c_str());
+
SetMethodeGet();
strcpy_T(this->m_accept_type, TEXT("*/*"));
Modifié: trunk/main.cpp
===================================================================
--- trunk/main.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/main.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -75,6 +75,9 @@
#endif
TEXT(")");
+/// Nom du binaire de PTVM
+TCHAR szAppFileName[MAX_PATH];
+
HINSTANCE hAppInstance; //!< Handle d'instance de l'application
HMENU hMainMenu = NULL; //!< Handle de la barre de menus de l'application
HWND hMainWnd = NULL; //!< Handle de la fenêtre principale de l'application
@@ -126,7 +129,7 @@
HACCEL hMainAccel = 0;
-bool bNeedRestart = false; //!< \p true si l'application doit être relancée
+NeedRestart eNeedRestart = nr_None; //!< Indique si (et comment) l'application doit être relancée
static bool shutdown_on_quit = false;
#ifdef USE_LOGITECH_LCD
@@ -1614,14 +1617,14 @@
update_record_menus(hMainWnd); // Mise à jour des menus "Chaînes" et "Programme"
// Si les changements dans la configuration requièrent que l'application soit relancée,
// on quitte (la relance sera automatique)
- if (bNeedRestart) {
+ if (eNeedRestart != nr_None) {
if (enregistrements_actuels.recording()!=0) {
MessageBox(hMainWnd,
TEXT("Au moins un enregistrement est en cours :\n")
TEXT("Certaines des modifications apportées à la configuration\n")
TEXT("ne s'appliqueront qu'après redémarrage de l'application."),
TEXT("Paramètres modifiés"), MB_ICONINFORMATION);
- bNeedRestart = false;
+ eNeedRestart = nr_None;
} else
// Redémarrage (partiel) de l'application
PostMessage(hMainWnd, WM_COMMAND, IDM_APP_RESTART, 0);
@@ -1890,7 +1893,7 @@
case IDM_APP_RESTART:
save_config();
- bNeedRestart = true;
+ eNeedRestart = lParam!=0 ? nr_Full : nr_Partial;
PostQuitMessage(0);
break;
@@ -2080,7 +2083,7 @@
if (enregistrements_actuels.recording()!=0) {
// Si on enregistre, affiche la fenêtre de confirmation
if (DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_CLOSE_CONFIRM), hWnd, ConfirmCloseProc) == 0) {
- bNeedRestart = false; // (précaution, car déjà protégé ailleurs)
+ eNeedRestart = nr_None; // (précaution, car déjà protégé ailleurs)
break; // On a appuyé sur Annuler, donc, on ne quitte pas
}
}
@@ -2993,10 +2996,36 @@
return (int)msg.wParam;
}
+/**
+ * Création d'une instance de redémarrage de l'application (en principe après
+ * remplacement de l'exécutable suite à une mise à jour), juste avant de quitter
+ **/
+void Restart()
+{
+ STARTUPINFO si = { sizeof(STARTUPINFO) };
+ PROCESS_INFORMATION pi;
+ TCHAR szTmp[MAX_PATH];
+
+ _stprintf_s(szTmp, TEXT("\"%s\""), szAppFileName);
+
+ // Ajout du préfixe si on est en train de redémarrer une instance secondaire de l'application
+ // (il restera quand même à l'utilisateur la responsabilité de redémarrer les éventuelles autres ...)
+ if (*prefix_conf) {
+ strcat_T(szTmp, TEXT(" --prefix "));
+ strcat_T(szTmp, prefix_conf);
+ }
+
+ if (!CreateProcess(NULL, szTmp, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi))
+ affiche_erreurs(SystemErrorToString(GetLastError()).c_str(), 0, TEXT("Erreur redémarrage"));
+}
+
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
hAppInstance = hInstance;
+ /// Récupération du nom de l'application
+ GetModuleFileName(NULL, szAppFileName, _countof(szAppFileName));
+
// Définition des répertoires de base de l'application
ini_app_paths();
@@ -3066,7 +3095,7 @@
int nRetCode;
do {
- bNeedRestart = false;
+ eNeedRestart = nr_None;
nRetCode = MainTask(cmdOptions);
@@ -3074,8 +3103,8 @@
delete [] cmdOptions;
cmdOptions = NULL; // Pas d'options en cas de redémarrage du programme
- myprintf(TEXT("%?\n############### (Redémarrage interne de l'application) #################\n\n"), bNeedRestart);
- } while (bNeedRestart);
+ myprintf(TEXT("%?\n############### (Redémarrage interne de l'application) #################\n\n"), eNeedRestart == nr_Partial);
+ } while (eNeedRestart == nr_Partial);
CleanInstance();
@@ -3085,7 +3114,13 @@
}
}
- // Pour témoigner qu'on est bien passés par ici en quittant :
- myprintf(TEXT("On quitte !\n"));
+ if (eNeedRestart == nr_Full) {
+ // Redémarrage demandé
+ myprintf(TEXT("On redémarre !\n"));
+ Restart();
+ } else
+ // Pour témoigner qu'on est bien passés par ici en quittant :
+ myprintf(TEXT("On quitte !\n"));
+
return nRetCode;
}
Modifié: trunk/main.h
===================================================================
--- trunk/main.h 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/main.h 2009-08-06 17:55:25 UTC (rev 199)
@@ -32,6 +32,7 @@
extern TCHAR szAppName[]; //!< Nom de l'application (pour le titre de la fenêtre)
extern TCHAR szAppVersion[]; //!< Numéro de version de l'application
+extern TCHAR szAppFileName[]; //!< Nom du binaire de PTVM
extern HINSTANCE hAppInstance; //!< Handle d'instance de l'application
extern HWND hMainWnd; //!< Handle de la fenêtre principale de l'application
@@ -43,8 +44,16 @@
extern HICON hRecIcon; //!< Icône utilisée en mode enregistrement
extern bool is_vista; //!< \p true si on est sous Windows Vista
-extern bool bNeedRestart; //!< \p true si l'application doit être relancée
+enum NeedRestart
+{
+ nr_None,
+ nr_Partial,
+ nr_Full
+};
+
+extern NeedRestart eNeedRestart; //!< Indique si (et comment) l'application doit être relancée
+
/// Diverses informations sur la version de Windows
extern OSVERSIONINFOEX windows_version;
Ajouté: trunk/make_lzma.cmd
===================================================================
--- trunk/make_lzma.cmd (rev 0)
+++ trunk/make_lzma.cmd 2009-08-06 17:55:25 UTC (rev 199)
@@ -0,0 +1,65 @@
+ at echo off
+rem
+rem make_lzma.cmd
+rem Copyright (C) 2009 gingko - http://gingko.homeip.net/
+rem
+rem This file is part of Pouchin TV Mod, a free DVB-T viewer.
+rem See http://pouchintv.baysse.fr/ for updates.
+rem
+rem Pouchin TV Mod is free software; you can redistribute it and/or modify
+rem it under the terms of the GNU General Public License as published by
+rem the Free Software Foundation; either version 2 of the License, or
+rem (at your option) any later version.
+rem
+rem Pouchin TV Mod is distributed in the hope that it will be useful,
+rem but WITHOUT ANY WARRANTY; without even the implied warranty of
+rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+rem GNU General Public License for more details.
+rem
+rem You should have received a copy of the GNU General Public License
+rem along with this program; if not, write to the Free Software
+rem Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+rem
+rem
+rem Most files of this project have been changed from the Pouchin TV
+rem project (Copyright (C) 2006 Pouchin ),
+rem to use with a modified version of this software.
+rem See http://pouchinteve.free.fr/ for the original project.
+rem
+
+rem Nettoyage pr‚liminaire par pr‚caution :
+if exist version_$temp$.txt del version_$temp$.txt
+
+echo ####
+rem Cherche si on est dans un repository
+if exist .svn\nul (
+ rem Extrait la version du SVN utilis‚e
+ svnversion -cn 2>NUL > version_$temp$.txt
+ if errorlevel 1 (
+ echo #### L'utilitaire "svnversion", qui fait partie de "Subversion", n'est pas disponible,
+ echo #### ou bien mal install‚ : le num‚ro de version ne peut pas ˆtre g‚n‚r‚ correctement.
+ echo #### Pour disposer de cet utilitaire, veuillez t‚l‚charger et installer un package
+ echo #### binaire de "Subversion" … l'adresse suivante : http://subversion.tigris.org/
+ echo #### Suite … cette installation, vous devrez alors avoir la commande "svnversion"
+ echo #### disponible dans le "PATH" en ligne de commande.
+ echo #### N'utilisez pas celui de "Cygwin" car problŠme avec les caractŠres accentu‚s.
+ echo ####
+ if exist version_$temp$.txt del version_$temp$.txt
+ )
+)
+
+rem G‚n‚ration du num‚ro de version dans un fichier "version_$temp$.h",
+rem ainsi que dans une variable d'environnement :
+if exist version_$temp$.txt (
+ type version_$temp$.txt | tools\GeneRealVersion.exe version_$temp$.h version "SET SVN_VERSION=" > set_version_$temp$.cmd
+ del version_$temp$.txt
+) else (
+ rem Version export‚e, tout est d‚j… OK
+ echo nS | tools\GeneRealVersion.exe version_$temp$.h version "SET SVN_VERSION=" > set_version_$temp$.cmd
+)
+call set_version_$temp$.cmd
+del set_version_$temp$.cmd
+
+echo ### G‚n‚ration de la mise … jour LZMA : %1.%SVN_VERSION%.lzma
+tools\lzmac e %1\%2.exe %1\%2.%SVN_VERSION%.lzma
+tools\lzmac e changelog.html %1\changelog.lzma
Modifié: trunk/parse.cpp
===================================================================
--- trunk/parse.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/parse.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -971,18 +971,14 @@
void ChannelsScanner::log(LPCTSTR pszFmt, ...) const
{
- TCHAR szWrk[512];
- va_list argptr;
+ FMT_BUF(szBuf, 512, pszFmt, pszFmt);
- va_start(argptr, pszFmt);
- _vstprintf_s(szWrk, pszFmt, argptr);
- va_end(argptr);
- myprintf(TEXT("%s"), szWrk);
+ myprintf(TEXT("%s"), szBuf);
if (fLog)
- _fputts(szWrk, fLog);
+ _fputts(szBuf, fLog);
}
- /// Destructeur
+/// Destructeur
ChannelsScanner::~ChannelsScanner()
{
if (fLog)
Modifié: trunk/res.rc
===================================================================
--- trunk/res.rc 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/res.rc 2009-08-06 17:55:25 UTC (rev 199)
@@ -66,22 +66,22 @@
BEGIN
POPUP "&Fichier"
BEGIN
- MENUITEM "&Configuration…", IDM_CONFIG
+ MENUITEM "&Configuration…", IDM_CONFIG
MENUITEM SEPARATOR
MENUITEM "&Quitter", IDM_QUIT
END
POPUP "Fi<res"
BEGIN
- MENUITEM "Codec &MPEG2…", IDM_MPEG2
- MENUITEM "C&odec H264…", IDM_H264
- MENUITEM "Codec a&udio…", IDM_AUDIO
- MENUITEM "Codec &AC3…", IDM_AC3
+ MENUITEM "Codec &MPEG2…", IDM_MPEG2
+ MENUITEM "C&odec H264…", IDM_H264
+ MENUITEM "Codec a&udio…", IDM_AUDIO
+ MENUITEM "Codec &AC3…", IDM_AC3
MENUITEM SEPARATOR
- MENUITEM "&Rendu vidéo…", IDM_VMR
- MENUITEM "&Audio MPEG2…", IDM_DSOUND
- MENUITEM "Audio A&C3…", IDM_DSOUNDAC3
+ MENUITEM "&Rendu vidéo…", IDM_VMR
+ MENUITEM "&Audio MPEG2…", IDM_DSOUND
+ MENUITEM "Audio A&C3…", IDM_DSOUNDAC3
MENUITEM SEPARATOR
- MENUITEM "D&emux…", IDM_DEMUX
+ MENUITEM "D&emux…", IDM_DEMUX
END
POPUP "C&ommandes"
BEGIN
@@ -123,14 +123,14 @@
MENUITEM "&Inférieure à la normale", IDM_BELOW_NORMAL_PRIORITY
END
MENUITEM SEPARATOR
- MENUITEM "&Guide des programmes…", IDM_EPG
+ MENUITEM "&Guide des programmes…", IDM_EPG
MENUITEM SEPARATOR
- MENUITEM "&Qualité du signal…", IDM_SIGNAL
+ MENUITEM "&Qualité du signal…", IDM_SIGNAL
END
POPUP "&Aide"
BEGIN
MENUITEM "Vérifier les &mises à jour…", IDM_UPDATE
- MENUITEM "À &propos…", IDM_ABOUT
+ MENUITEM "À &propos…", IDM_ABOUT
END
END
@@ -432,16 +432,18 @@
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,197,137,10
END
-IDD_UPDATE DIALOGEX 0, 0, 251, 155
+IDD_UPDATE DIALOGEX 0, 0, 251, 163
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Vérification des mises à jour"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
GROUPBOX "Statut de la mise à jour",IDC_STATIC,7,7,237,98
LISTBOX IDC_UPDATE_LIST,14,16,223,82,LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
- PUSHBUTTON "&Vérifier",IDC_UPDATE_CHECK,57,112,50,14,WS_GROUP
- DEFPUSHBUTTON "&Fermer",IDCANCEL,143,112,50,14
- CONTROL "",IDC_UPDATE_PROGRESS,"msctls_progress32",WS_BORDER | WS_GROUP,7,134,237,14
+ CONTROL "Inclure les versions beta dans la mise à jour",IDC_UPDATE_BETA,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,46,107,157,10
+ PUSHBUTTON "&Vérifier",IDC_UPDATE_CHECK,57,121,50,14,WS_GROUP
+ DEFPUSHBUTTON "&Fermer",IDCANCEL,143,121,50,14
+ CONTROL "",IDC_UPDATE_PROGRESS,"msctls_progress32",WS_BORDER | WS_GROUP,7,142,237,14
END
IDD_SCAN_OPTIONS DIALOGEX 0, 0, 390, 142
@@ -627,7 +629,7 @@
LEFTMARGIN, 7
RIGHTMARGIN, 244
TOPMARGIN, 7
- BOTTOMMARGIN, 148
+ BOTTOMMARGIN, 156
END
IDD_SCAN_OPTIONS, DIALOG
Modifié: trunk/resource.h
===================================================================
--- trunk/resource.h 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/resource.h 2009-08-06 17:55:25 UTC (rev 199)
@@ -152,6 +152,7 @@
#define IDC_UPDATE_PROGRESS 1160
#define IDC_UPDATE_CHECK 1161
#define IDC_UPDATE_LIST 1162
+#define IDC_UPDATE_BETA 1163
#define IDC_SUSPEND 1170
#define IDC_SYSTEM_TRAY 1171
Modifié: trunk/settings.cpp
===================================================================
--- trunk/settings.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/settings.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -1562,7 +1562,7 @@
case PSN_APPLY: // Application des changements
if (drivers_apply(hDlg)) {
save_config_tuner();
- bNeedRestart = true;
+ eNeedRestart = nr_Partial;
}
return psn_result(hDlg, PSNRET_NOERROR);
}
@@ -3048,7 +3048,7 @@
// Avertir de la nécessité de relancer l'application si un des paramètres
// de sortie vidéo a été modifié :
if (vmr_mode!=old_vmr_mode || use_osd!=old_use_osd)
- bNeedRestart = true;
+ eNeedRestart = nr_Partial;
return psn_result(hDlg, PSNRET_NOERROR); }
}
return FALSE;
Modifié: trunk/update.cpp
===================================================================
--- trunk/update.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/update.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -46,15 +46,17 @@
/// Structure définissant l'allocateur/libérateur
static ISzAlloc lzmaAlloc = { SzAlloc, SzFree };
-/// Version maximale suportée pour les mises à jours
-#define UPDATE_VERSION_MAX (1)
+/// Version maximale supportée pour les mises à jour
+#define UPDATE_VERSION_MAX 1
/// Handle de la liste indiquant la progression
-HWND hUpdateStatut = 0;
+static HWND hUpdateStatut = NULL;
/// Handle de la barre de progression
-HWND hProgressStatut = 0;
+static HWND hProgressStatut = NULL;
/// Handle du bouton "Mettre à jour"
-HWND hUpdateButton = 0;
+static HWND hUpdateButton = NULL;
+/// Handle du bouton "Mettre à jour"
+static HWND hUpdateBetaCheckBox = NULL;
/// Texte affiché lors de la vérification de la mise à jour
static TCHAR szButtonUpdateCheck[] = TEXT("Vérifier");
/// Texte affiché si une mise à jour est disponible, pour la télécharger
@@ -62,16 +64,91 @@
/// Texte affiché si la mise à jour nécessite un redémarrage
static TCHAR szButtonUpdateRestart[]= TEXT("Redémarrer");
/// Arrête le téléchargement des fichiers
-bool stop_maj;
-/// Nom du binaire de PTVM
-TCHAR szAppFileName[MAX_PATH];
+static bool stop_maj = false;
+/// Indique si une mise à jour est en attente de redémarrage
+static bool bUpdateNeedRestart = false;
/// Objet TinyXML pour traiter le fichier XML reçu
-TiXmlDocument xmlVersionDocument;
+static TiXmlDocument xmlVersionDocument;
+typedef std::vector ByteStream;
+
+/// Structure associant un document téléchargé à sa date de dernière modification.
+struct InternetFile : public ByteStream
+{
+ SYSTEMTIME sTime; // Date et heure du fichier
+};
+
/// URL pour la mise à jour
-#define UPDATE_URL TEXT("http://pouchintv.baysse.fr/version.php")
+#ifdef _DEBUG
+ #define UPDATE_URL "http://pouchintv.baysse.fr/version_debug.php"
+#else
+ #define UPDATE_URL "http://pouchintv.baysse.fr/version.php"
+#endif
+#ifdef _WIN64
+ #define REQ_APP_TYPE "app64"
+#else
+ #define REQ_APP_TYPE "app32"
+#endif
+
+/// Structure décrivant une version de l'application
+struct AppVersion
+{
+ int nMajor;
+ int nMinor;
+ int nRev;
+ CHAR szSvn[8]; // Des caractères alphanumériques peuvent exister sur ce champ
+
+ /// Constructeur chargeant la version avec une chaîne de version
+ AppVersion(LPCSTR pszVersion) :
+ nMajor(0),
+ nMinor(0),
+ nRev(0)
+ {
+ szSvn[0] = '0'; szSvn[1] = 0;
+ // On récupère la version de PTVM fonctionnant actuellement
+ sscanf_s(PTVM_VERSION_STR, "%i.%i.%i.%s", &nMajor, &nMinor, &nRev, szSvn, _countof(szSvn));
+ }
+
+ /// Constructeur chargeant la version avec les attributs d'un élément TiXML
+ AppVersion(const TiXmlElement & sTiXml) :
+ nMajor(0),
+ nMinor(0),
+ nRev(0)
+ {
+ szSvn[0] = '0'; szSvn[1] = 0;
+ sTiXml.QueryIntAttribute("major", &nMajor);
+ sTiXml.QueryIntAttribute("minor", &nMinor);
+ sTiXml.QueryIntAttribute("rev", &nRev);
+
+ LPCSTR pszSvn = sTiXml.Attribute("svn");
+
+ if (pszSvn && *pszSvn)
+ strcpy_T(szSvn, pszSvn);
+ }
+
+ bool operator > (const AppVersion & sV2) const {
+ return
+ nMajor>sV2.nMajor ||
+ nMajor==sV2.nMajor && (
+ nMinor>sV2.nMinor ||
+ nMinor==sV2.nMinor &&
+ nRev>sV2.nRev);
+ }
+
+ bool operator < (const AppVersion & sV2) const {
+ return ! operator > (sV2);}
+
+ /// Conversion en chaîne (le résultat étant maintenu sur une variable statique,
+ /// ne pas utiliser cette fonction deux fois dans la même instruction)
+ LPCTSTR toString() const {
+ static TCHAR szTmp[20];
+
+ _stprintf_s(szTmp, TEXT("%d.%d.%d.%") A2t, nMajor, nMinor, nRev, szSvn);
+ return szTmp;}
+};
+
/// Action effectuée durant l'analyse de la version
enum eUPDATE_ACTION {
eUpda_Check, ///< Vérification seulement
@@ -84,11 +161,11 @@
* \param[in] nouveau nom du fichier venant d'être téléchargé
* \param[in] original ancien fichier devant être remplacé
* \param[in] backup si true, on ne sauvegarde pas l'ancien fichier, on l'efface tout simplement
- * \retval true si tout s'est bien déroulé
- * \retval false en cas d'erreur
+ * \retval 0 si tout s'est bien déroulé
+ * \retval Code d'erreur système en cas d'erreur
**/
-bool RemplaceFichier(LPCTSTR nouveau, LPCTSTR original, bool backup) {
- bool ret = true; // prend le parti que tout est OK
+static DWORD RemplaceFichier(LPCTSTR nouveau, LPCTSTR original, bool backup)
+{
TCHAR fichierBackup[MAX_PATH]; // Fichier temporaire
myprintf(TEXT("Remplace «%s» par «%s» en %s\n"), original, nouveau, backup ? TEXT("sauvegardant") : TEXT("effaçant"));
@@ -98,100 +175,111 @@
strcat_T(fichierBackup, TEXT("_"));
// On renome l'actuel PTVM
- ret = (ReplaceFile(original,
- nouveau,
- backup ? fichierBackup : NULL,
- REPLACEFILE_WRITE_THROUGH|REPLACEFILE_IGNORE_MERGE_ERRORS,
- 0,
- 0) != 0);
+ BOOL ret =
+ ReplaceFile(
+ original, nouveau,
+ backup ? fichierBackup : NULL,
+ REPLACEFILE_WRITE_THROUGH|REPLACEFILE_IGNORE_MERGE_ERRORS,
+ 0, 0);
- return ret;
+ if (!ret)
+ return GetLastError();
+
+ return 0;
}
/**
* Enregistre un fichier depuis un tableau d'octets
*
- * \param[in] contenu tableau d'octets à écrire
- * \param[in] taille nombre de caractères à écrire
- * \param[in] nom nom du fichier à sauvegarder
- * \retval true si tout s'est bien déroulé
- * \retval false en cas d'erreur
+ * \param[in] vContenu Vecteur d'octets à écrire
+ * \param[in] nom Nom du fichier à sauvegarder
+ * \retval 0 si tout s'est bien déroulé
+ * \retval Code d'erreur système en cas d'erreur
**/
-static bool SauveFichier(BYTE* contenu, UINT taille, LPCTSTR nom) {
- bool ret = true; // prend le partie que tout est OK
- DWORD dwEcrit; // Nombre d'octets écrits
+static DWORD SauveFichier(const InternetFile & vContenu, LPCTSTR nom)
+{
+ DWORD dwEcrit; // Variable recevant le nombre d'octets écrits
- myprintf(TEXT("Sauvegarde «%s» depuis un téléchargement de %u octets\n"), nom, taille);
+ myprintf(TEXT("Sauvegarde «%s» depuis un téléchargement de %u octets\n"), nom, vContenu.size());
// Sauvegarde du fichier
HANDLE hFile = CreateFile(nom, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
- ret = (WriteFile(hFile, contenu, taille, &dwEcrit, NULL) != 0);
+ BOOL ret = WriteFile(hFile, &vContenu[0], (DWORD)vContenu.size(), &dwEcrit, NULL);
+
+ if (ret) {
+ FILETIME sFTime;
+
+ // Ajustement de la date du fichier
+ if (SystemTimeToFileTime(&vContenu.sTime, &sFTime))
+ SetFileTime(hFile, &sFTime, NULL, &sFTime);
+ }
CloseHandle(hFile);
- } else
- ret = false;
+ if (ret)
+ return 0; // Ok
+ }
- return ret;
+ return GetLastError();
}
/**
* Remplace le fichier par le nouveau, en sauvegardant l'ancien
*
- * \param[in] contenu tableau d'octets à écrire
- * \param[in] taille nombre de caractères à écrire
- * \param[in] original ancien fichier devant être remplacé
- * \param[in] backup si true, on ne sauvegarde pas l'ancien fichier, on l'efface tout simplement
- * \retval true si tout s'est bien déroulé
- * \retval false en cas d'erreur
+ * \param[in] vContenu Vecteur d'octets à écrire
+ * \param[in] original Ancien fichier devant être remplacé
+ * \param[in] backup Si true, on ne sauvegarde pas l'ancien fichier, on l'efface tout simplement
+ * \retval 0 si tout s'est bien déroulé
+ * \retval Code d'erreur système en cas d'erreur
**/
-static bool RemplaceFichier(BYTE* contenu, UINT taille, LPCTSTR original, bool backup) {
- bool ret = true; // prend le partie que tout est OK
+static DWORD RemplaceFichier(const InternetFile & vContenu, LPCTSTR original, bool backup)
+{
TCHAR fichierTemp[MAX_PATH]; // Fichier temporaire
- myprintf(TEXT("Remplace «%s» depuis un téléchargement de %u octets\n"), original, taille);
+ myprintf(TEXT("Remplace «%s» depuis un téléchargement de %u octets\n"), original, vContenu.size());
- // Nom du fichier de backup
- strcpy_T(fichierTemp, pouchindir_conf);
- strcat_T(fichierTemp, TEXT("XXX"));
+ // Nom du fichier de mise à jour
+ strcpy_T(fichierTemp, original);
+ strcat_T(fichierTemp, TEXT(".update"));
- ret = SauveFichier(contenu, taille, fichierTemp);
+ DWORD nRes = SauveFichier(vContenu, fichierTemp);
- if (ret)
- ret = RemplaceFichier(fichierTemp, original, backup);
+ if (nRes==0)
+ nRes = RemplaceFichier(fichierTemp, original, backup);
- return ret;
+ return nRes;
}
/**
* Décompresse les données LZMA
*
- * \param[out] decompresse tableau d'octets initialisés das la fonction contenant les données décompressées
- * \param[out] tailleDecompresse nombre d'octets une fois décompressé
- * \param[in] compresse tableau d'octets des données compressées
- * \param[in] tailleCompresse nombre d'octets à traiter
- * \return indique le status de la décompression
+ * \param[out] vDecompresse Vecteur d'octets initialisés dans la fonction contenant les données décompressées
+ * \param[in] vCompresse Vecteur d'octets des données compressées
+ * \return Indique le statut de la décompression
**/
-ELzmaStatus DecompressLzma(BYTE** decompresse, UInt32 *tailleDecompresse, BYTE* compresse, size_t tailleCompresse) {
- SRes res; // Résultat des fonctions
- SizeT outTraite = 0; // Nombre d'octets en sortie traités
- const int tailleHeader= LZMA_PROPS_SIZE + 8; // Taille de l'en tête (à ignorer pour les données)
- SizeT inTraite =tailleCompresse;// Nombre d'octets en lecture traités
- CLzmaDec state; // État de la décompression
- ELzmaStatus status; // Statut de la décompression
+static ELzmaStatus DecompressLzma(ByteStream & vDecompresse, const ByteStream & vCompresse)
+{
+ SRes res; // Résultat des fonctions
+ SizeT outTraite = 0; // Nombre d'octets en sortie traités
+ const int tailleHeader = LZMA_PROPS_SIZE +8; // Taille de l'en tête (à ignorer pour les données)
+ SizeT inTraite = vCompresse.size(); // Nombre d'octets en lecture traités
+ CLzmaDec state; // État de la décompression
+ ELzmaStatus status; // Statut de la décompression
// On récupère la taille du fichier décompressé
+ UInt32 tailleDecompresse = 0;
+
for (int i = 0; i < 8; i++)
- *tailleDecompresse += (UInt32)compresse[LZMA_PROPS_SIZE + i] << (i * 8);
- outTraite = *tailleDecompresse;
+ tailleDecompresse += (UInt32)vCompresse[LZMA_PROPS_SIZE + i] << (i * 8);
+ outTraite = tailleDecompresse;
- *decompresse = (LPBYTE)malloc(*tailleDecompresse);
+ vDecompresse.resize(tailleDecompresse);
// Initialise le décodeur
LzmaDec_Construct(&state);
- res = LzmaDec_Allocate(&state, compresse, LZMA_PROPS_SIZE, &lzmaAlloc);
+ res = LzmaDec_Allocate(&state, &vCompresse[0], LZMA_PROPS_SIZE, &lzmaAlloc);
LzmaDec_Init(&state);
// On décode
- res = LzmaDec_DecodeToBuf(&state, *decompresse, &outTraite, compresse+tailleHeader, &inTraite, LZMA_FINISH_END, &status);
+ res = LzmaDec_DecodeToBuf(&state, &vDecompresse[0], &outTraite, &vCompresse[tailleHeader], &inTraite, LZMA_FINISH_END, &status);
// On nettoye la mémoire
LzmaDec_Free(&state, &lzmaAlloc);
@@ -199,327 +287,401 @@
}
/**
- * Ajoute le message dabs la liste, et incrémente la barre de progression
+ * Ajoute le message dans la liste
*
- * \param[in] szMessage message devant être affiché dans la liste de statut
- * \param[in] iNewDeltaPos index indiquant la nouvelle position de la barre de progression
+ * \param[in] pszFmt message ou chaîne de formatage devant être affiché dans la liste de statut
**/
-void AddStatut(LPCTSTR szMessage, int iNewDeltaPos) {
- // Permet d'incrémenter la barre de progression sans rien afficher
- if (szMessage != 0 && szMessage[0] != 0)
- AddLineToList(hUpdateStatut, szMessage);
+static void AddMsg(LPCTSTR pszFmt, ...)
+{
+ FMT_BUF(szBuf, 128, pszFmt, pszFmt);
- SendMessage(hProgressStatut, PBM_DELTAPOS, iNewDeltaPos, 0);
+ AddLineToList(hUpdateStatut, szBuf);
}
/**
+ * Incrémente la barre de progression
+ *
+ * \param[in] nMaxPos Index maximal
+ **/
+static void InitProgress(int nMaxPos)
+{
+ if (hProgressStatut) {
+ // On met les étapes
+ SendMessage(hProgressStatut, PBM_SETRANGE, 0, MAKELPARAM(0, nMaxPos));
+
+ // On se positionne au début de la barre de progression
+ SendMessage(hProgressStatut, PBM_SETPOS, 0, 0);
+ }
+}
+
+/**
+ * Incrémente la barre de progression
+ *
+ * \param[in] iNewDeltaPos index indiquant la nouvelle position de la barre de progression
+ * (utiliser -1 pour aller à la valeur maximale)
+ **/
+static void AddProgress(int iNewDeltaPos=1)
+{
+ int nMax = (int)SendMessage(hProgressStatut, PBM_GETRANGE, false, 0);
+ int nPos = (int)SendMessage(hProgressStatut, PBM_GETPOS, 0, 0);
+ int nDif = nMax-nPos;
+
+ if (iNewDeltaPos < 0 || nDif < iNewDeltaPos)
+ iNewDeltaPos = nMax-nPos;
+ if (iNewDeltaPos > 0)
+ SendMessage(hProgressStatut, PBM_DELTAPOS, iNewDeltaPos, 0);
+}
+
+/**
* Lance la récupération du fichier, dont l'url est passée en paramètre,
- * et stocke le fichier récupéré dans data
+ * et stocke le fichier récupéré dans \p vData
*
- * \param[in] url adresse contenant les fichiers à récupérer
- * \param[out] data tableau d'octets contenant le fichier récupéré, initialisé dans la fonction
- * \param[in] statut affiche la progression ?
+ * \param[in] url Adresse contenant les fichiers à récupérer
+ * \param[out] vData Vecteur d'octets contenant le fichier récupéré, initialisé dans la fonction
+ * \param[in] statut Affiche la progression
+ * \return Taille du fichier récupéré ( = vData.size() )
**/
-DWORD GetInternetFile(LPCTSTR url, BYTE **data, eUPDATE_ACTION statut) {
- // Si data est renseigné, on quitte
- if (*data != NULL)
+static DWORD GetInternetFile(LPCTSTR url, InternetFile & vData, eUPDATE_ACTION statut)
+{
+ // Si vData est renseigné, on quitte
+ if (!vData.empty())
return 0;
bool stoppe = false;
- const int iTailleBuffer = 8*1024; // Buffer de 8 Ko
+
+#ifdef _UNICODE
+ // En version Unicode, la conversion en UTF-8 est implicite
ConnexionInternet maj(url); // Objet traitant de la connexion Internet
+#else
+ ConnexionInternet maj(ConvertChar2UTF8(url).c_str()); // Objet traitant de la connexion Internet
+#endif
myprintf(TEXT("Téléchargement de «%s»\n"), url);
- //
int http_statut = maj.EnvoieRequete();
- if (http_statut == maj.HTTP_ERR_OK) {
- } else if (http_statut == 0) {
- AddStatut(TEXT("Erreur lors de l'établissement de la connexion."), 4294967295);
+ if (http_statut != maj.HTTP_ERR_OK) {
+ if (http_statut == 0) {
+ AddMsg(TEXT("Erreur lors de l'établissement de la connexion."));
myprintf(TEXT("Erreur connexion\n"));
- stoppe = true;
- } else {
- AddStatut(TEXT("Erreur, lors du téléchargement du fichier."), 0);
- AddStatut(TEXT("Veuillez réessayer ultérieurement..."), 4294967295);
+ } else {
+ AddMsg(TEXT("Erreur %d lors du téléchargement du fichier."), http_statut);
+ AddMsg(TEXT("Veuillez réessayer ultérieurement..."));
myprintf(TEXT("Erreur connexion: erreur HTTP: %d\n"), http_statut);
- stoppe = true;
+ }
+ stoppe = true;
}
- if (!stop_maj || !stoppe)
- if (statut == eUpda_Check)
- AddStatut(TEXT("Récupération du fichier de version..."), 1);
+ if (stop_maj || stoppe)
+ return 0;
+ if (statut == eUpda_Check)
+ AddMsg(TEXT("Récupération du fichier de version..."));
+
+ // Tout est OK, on récupère le fichier
+ BYTE temp[8*1024]; // Buffer de 8 Ko
+ DWORD lu = sizeof(temp), dwLuTotal = 0;
+
if (statut == eUpda_Telecharge) {
// On initialise la barre de progression, avec autant de morceaux que nécessaire
- SendMessage(hProgressStatut, PBM_SETRANGE32 , 0, int(maj.GetTaille() / iTailleBuffer)+1);
- SendMessage(hProgressStatut, PBM_SETPOS, 0, 0); // Se positionne au début de la barre de progression
+ InitProgress(int(maj.GetTaille() / sizeof(temp))+1);
}
- //
- // Tout est OK, on récupère le fichier
- BYTE temp[iTailleBuffer];
- DWORD lu = iTailleBuffer, dwLuTotal = 0;
while (!stop_maj && maj.RecupereFichier(temp, &lu)) {
- if (!*data) {
- // Pas encore initialisé, on le fait
- *data = (LPBYTE)malloc(sizeof(BYTE)*(lu+1));
- memcpy_s(*data, lu, temp, lu);
- } else {
- // Déjà initialisé, on aggrandit le tableau
- LPBYTE _temp = (LPBYTE)malloc(sizeof(BYTE)*dwLuTotal);
- memcpy_s(_temp, dwLuTotal, *data, dwLuTotal);
- free(*data);
- *data = (LPBYTE)malloc(sizeof(BYTE)*(dwLuTotal+lu+1));
- memcpy_s(*data, dwLuTotal, _temp, dwLuTotal);
- memcpy_s(*data+dwLuTotal, lu, temp, lu);
- free(_temp);
- }
+ vData.resize(dwLuTotal+lu); // Redimensionnement
+ memcpy_s(&vData[dwLuTotal], lu, temp, lu);
+
dwLuTotal += lu;
// Remet le compteur de lecture à sa valeur max
- lu = iTailleBuffer;
+ lu = sizeof(temp);
if (stop_maj)
// Arrêt demandé, on quitte, mais on nettoie la mémoire avant
break;
// Si on télécharge, on met à jour la barre de progression
- if (statut == eUpda_Telecharge) {
- AddStatut(NULL, 1);
- }
+ if (statut == eUpda_Telecharge)
+ AddProgress();
}
+
+ vData.sTime = maj.GetModifTime();
return dwLuTotal;
}
/**
- * Fonction traitant le fichier XML décrivant la mise à jour
+ * Lance la récupération du fichier compressé, dont l'url est passée en paramètre,
+ * et stocke le fichier récupéré dans \p vData
*
- * \param[in] action action devant être effectuée si des versions plus récentes sont trouvées
- * (affichage de messages de status, téléchargements des nouveaus fichiers, etc.)
+ * \param[in] url Adresse contenant les fichiers à récupérer
+ * \param[out] vData Vecteur d'octets contenant le fichier récupéré, initialisé dans la fonction
+ * \param[in] statut Affiche la progression
+ * \return Taille du fichier récupéré ( = vData.size() )
**/
-int UpdateTraiteXml(int action) {
- //
- // Commence le parcours des versions dans le fichier XML parsé
- int retval = 0;
- TiXmlElement *xmlVersionElem = 0;
+static INT GetCompressedInternetFile(LPCTSTR url, InternetFile & vData, eUPDATE_ACTION statut)
+{
+ INT nSize = 0;
+ InternetFile vCompressedData;
- if (!xmlVersionDocument.FirstChildElement("Versions")) {
- // Fichier bien XML, mais pas la bonne racine, on quitte donc
- AddStatut(TEXT("Fichier de version invalide. Réessayez ultérieurement..."), 5);
- return 0;
+ if (GetInternetFile(url, vCompressedData, statut) > 0) {
+ // Des données ont été récupérées
+ ELzmaStatus resLzma; // Valeur de retour des fonctions de décodage
+
+ resLzma = DecompressLzma(vData, vCompressedData);
+ vData.sTime = vCompressedData.sTime;
+
+ if (resLzma == LZMA_STATUS_FINISHED_WITH_MARK && !vData.empty())
+ nSize = (INT)vData.size();
+ else
+ return -1; // Erreur à la décompression
}
+ return nSize;
+}
- for (xmlVersionElem = xmlVersionDocument.FirstChildElement("Versions")->FirstChildElement("version");
- xmlVersionElem;
- xmlVersionElem = xmlVersionElem->NextSiblingElement("version")) {
- // Récupère la version de la branche
- int updateversion;
- if (xmlVersionElem->QueryIntAttribute("version", &updateversion) == TIXML_NO_ATTRIBUTE || // anciennes versions de PTVM, on ignore
- updateversion > UPDATE_VERSION_MAX) { // nœud plus récent, on le saute, il sera lu une fois PTVM mis à jour
- continue;
- }
+static bool UpdateTraiteApp(const TiXmlElement & sTiXml, eUPDATE_ACTION action, LPCTSTR pszDispType)
+{
+ AppVersion sAppVers(PTVM_VERSION_STR); // Version courante de PTVM
+ AppVersion sXmlVers(sTiXml); // Version du noeud XML
+ bool bUpdate = false;
- // On récupère le type de fichier concerné par la mise à jour
- // Valeurs possibles actuellement :
- // "stable", "commun"
- const char *szXmlVersionConcernee = xmlVersionElem->Attribute("type");
+ if (sXmlVers > sAppVers) {
+ // Nouvelle version disponible
- if (strcmp(szXmlVersionConcernee, "stable") != 0 && strcmp(szXmlVersionConcernee, "common") != 0)
- // On ignore les autres types de noeuds
- continue;
+ if (action == eUpda_Check) {
+ // Affiche simplement le message informatif dans la fenêtre de statut
- TiXmlElement *xmlTypeMaj = 0;
+ AddMsg(
+ TEXT("Nouvelle version %s de %s disponible : %s"),
+ pszDispType, szAppName, sXmlVers.toString());
+ AddMsg(TEXT("Version actuellement utilisée : %s"), sAppVers.toString());
+ bUpdate = true;
+ } else if (action == eUpda_Telecharge) {
+ // Télécharge la nouvelle version de PTVM
- for (xmlTypeMaj = xmlVersionElem->FirstChildElement();
- xmlTypeMaj;
- xmlTypeMaj = xmlTypeMaj->NextSiblingElement()) {
+ AddMsg(TEXT("Téléchargement de la mise à jour de %s..."), szAppName);
- // On récupère le nom du noeud, qui indique le type de mise à jour
- // Valeurs possibles actuellement :
- // "app", "icones"
- const char *szXmlTypeMaj = xmlTypeMaj->Value();
+ tstring strUrl = ConvertUTF82Char(sTiXml.FirstChild()->Value());
+ InternetFile vData;
+ INT nSize = GetCompressedInternetFile(strUrl.c_str(), vData, eUpda_Telecharge);
- //
- if (strcmp(szXmlTypeMaj, "app") == 0) {
+ if (nSize > 0) {
+ // Des données ont été récupérées
+ // Tout semble bon, on sauvegarde le nouveau fichier
+ DWORD nRes = RemplaceFichier(vData, szAppFileName, true);
- // Il s'agit de la mise à jour de PTVM lui même
- int major, minor, rev, subrev, xml_major, xml_minor, xml_rev;
-
- //
- // on récupère donc la version de PTVM fonctionnant actuellement
- {
- const char *ch = PTVM_VERSION_STR;
- major = atoi(ch);
- ch = strstr(ch, ".");
- minor = atoi(++ch);
- ch = strstr(ch, ".");
- rev = atoi(++ch);
- ch = strstr(ch, ".");
- subrev = atoi(++ch);
+ if (nRes==0) {
+ AddMsg(TEXT("%s a été mis à jour."), szAppName);
+ AddMsg(TEXT("Veuillez relancer %s pour voir les changements."), szAppName);
+ bUpdate = true;
+ } else {
+ // Des erreurs d'écriture du fichier se sont produite. L'indiquer
+ AddMsg(TEXT("Erreur %u : %s"), nRes, SystemErrorToString(nRes).c_str());
+ AddMsg(TEXT("Impossible de mettre à jour %s."), szAppName);
+ AddMsg(TEXT("Vérifiez que vous avez le droit de modifier les fichiers."));
}
- // maintenant que l'on a les versions de l'exécutable, on vérifie les versions dans le ficher XML
- xmlTypeMaj->QueryIntAttribute("major", &xml_major);
- xmlTypeMaj->QueryIntAttribute("minor", &xml_minor);
- xmlTypeMaj->QueryIntAttribute("rev", &xml_rev);
+ } else if (nSize < 0)
+ AddMsg(TEXT("Le fichier téléchargé n'est pas valide. Veuillez réessayer."));
+ else
+ AddMsg(TEXT("Le fichier n'a pas pu être récupéré."));
+ } // if (action == eUpda_Telecharge)
+ } else
+ if (action == eUpda_Check)
+ AddMsg(
+ TEXT("Aucune nouvelle version %s de %s disponible"),
+ pszDispType, szAppName);
- // On compare maintenant
- if (xml_major>major ||
- (xml_major==major && xml_minor>minor) ||
- (xml_major==major && xml_minor==minor && xml_rev>rev)) {
- // Nouvelle version disponible
+ return bUpdate;
+}
- if (action == eUpda_Check) {
- // Affiche simplement le message informatif dans la fenêtre de statut
+static bool UpdateTraiteIcons(const TiXmlElement & sTiXml, eUPDATE_ACTION action)
+{
+ bool bUpdate = false;
+ // on parse les icones. Établissement de la liste locale
- TCHAR phrase[100];
- _stprintf_s(phrase, _countof(phrase), TEXT("Nouvelle version de Pouchin TV Mod disponible (%d.%d.%d)"), xml_major, xml_minor, xml_rev);
- AddStatut(phrase, 0);
- _stprintf_s(phrase, _countof(phrase), TEXT("Version actuellement utilisée (%d.%d.%d.%d)"), major, minor, rev, subrev);
- AddStatut(phrase, 0);
+ // on liste les packs d'icônes
+ for (ITERATE_XML_ELEMENTS_NAMED(&sTiXml, xmlIconesPack, "pack")) {
+ // Pays du pack (pour classer les icônes)
+ tstring strPays = ConvertUTF82Char(xmlIconesPack->Attribute("pays"));
+ tstring strDirPays = strPays==TEXT("France") ? TEXT("") : (strPays + TEXT("\\")).c_str();
+ tstring strFound; // Réceptacle générique pour les résultats de recherches
- retval |= 0x1;
+ if (!strDirPays.empty()) {
+ // Si le sous-répertoire de pays n'existe pas, c'est que l'utilisateur n'a pas
+ // sélectionné le pack correspondant à l'installation. On ignore donc.
+ if (
+ FindAppFile(TEXT("Icones"), strPays.c_str() /* strPays car on ne veut pas du "\" */,
+ strFound, FF_DIRECTORY)==pd_notfound
+ ) {
+ continue;
+ }
+ }
- } else if (action == eUpda_Telecharge) {
- // Télécharge la nouvelle version de PTVM
+ // On parcourt les différentes icônes (au cas où certaines seraient manquantes)
+ for (ITERATE_XML_ELEMENTS_NAMED(xmlIconesPack, xmlIconesIcone, "icone")) {
+ tstring strIcone = ConvertUTF82Char(xmlIconesIcone->GetText());
+ tstring strIconFile = strIcone + TEXT(".bmp");
- AddStatut(TEXT("Téléchargement de la mise à jour de Pouchin TV Mod..."), 0);
+ // Recherche dans les répertoires de l'application :
+ if (FindAppFile(TEXT("Icones"), strIconFile.c_str(), strFound)!=pd_notfound)
+ continue; // si trouvé
- LPCSTR url = xmlTypeMaj->FirstChild()->Value();
+ // L'icône n'existe pas
+ if (action == eUpda_Check) {
+ AddMsg(TEXT("Vous n'avez pas toutes les icônes de «%s»"), strPays.c_str());
- COPY_STR_ON_STACK(TCHAR, tUrl, url, longueur);
+ bUpdate = true;
+ break;
+ } else if (action == eUpda_Telecharge) {
+ // Télécharge les images manquantes
- LPBYTE data = 0;
- size_t taille = GetInternetFile(tUrl, &data, eUpda_Telecharge);
+ tstring strUrlBase = ConvertUTF82Char(sTiXml.Attribute("base"));
+ tstring strUrlPath = ConvertUTF82Char(sTiXml.Attribute("path"));
- if (taille) {
- // Des données ont été récupérées
+ // Ajustement du répertoire dans l'URL
+ if (strUrlPath==TEXT("/"))
+ strUrlPath.clear();
+ else
+ strUrlPath += TEXT("/");
- UInt32 tailleDecompresse = 0; // Taille du fichier une fois décompressé
- LPBYTE decompresse = 0; // Tabeau d'octets contenant le fichier décodé
- ELzmaStatus resLzma; // Valeur de retour des fonctions de décodage
- resLzma = DecompressLzma(&decompresse, &tailleDecompresse, data, taille);
- free(data);
+ tstring strUrl = strUrlBase + strUrlPath + strIconFile;
+ InternetFile vData;
- if ( resLzma == LZMA_STATUS_FINISHED_WITH_MARK && decompresse) {
- // Tout semble bon, on sauvegarde le nouveau fichier
+ AddMsg(TEXT("Téléchargement de l'icône «%s»"), strIconFile.c_str());
- if (RemplaceFichier(decompresse, tailleDecompresse, szAppFileName, true)) {
- AddStatut(TEXT("Pouchin TV Mod a été mis à jour."), 0);
- retval |= 0x1;
- } else {
- // Des erreurs d'écriture du fichier se sont produite. L'indique
- AddStatut(TEXT("Impossible de mettre à jour PTVM."), 0);
- AddStatut(TEXT("Vérifiez que vous avez le droit de modifier les fichiers."), 0);
- }
- } else {
- // Le fichier traité n'est pas valide
- AddStatut(TEXT("Le fichier téléchargé n'est pas valide. Veuillez réessayer."), 0);
- }
- free(decompresse);
+ // Envoie la connexion
+ if (GetInternetFile(strUrl.c_str(), vData, eUpda_Telecharge) > 0) {
+ // Des données ont été récupérées
+ tstring strIconPath = tstr_printf( // Chemin vers l'image locale
+ TEXT("%sIcones\\%s%s"),
+ pouchindir_prog, strDirPays.c_str(), strIconFile.c_str());
- } else // if (taille)
- AddStatut(TEXT("Le fichier n'a pas pu être récupérer."), 0);
- } // if (action == eUpda_Telecharge)
- } else
- if (action == eUpda_Check)
- AddStatut(TEXT("Votre version de Pouchin TV Mod est à jour"), 0);
+ DWORD nRes = SauveFichier(vData, strIconPath.c_str());
- AddStatut(TEXT(""), 1);
+ if (nRes!=0) {
+ // Impossible de sauvegarder dans le répertoire de l'application :
+ // utiliser le répertoire de configuration
+ strIconPath = tstr_printf(
+ TEXT("%sIcones\\%s%s"),
+ pouchindir_conf, strDirPays.c_str(), strIconFile.c_str());
+ nRes = SauveFichier(vData, strIconPath.c_str());
+ }
- //
- } else if ((strcmp(szXmlTypeMaj, "icones") == 0)) {
+ if (nRes==0) {
+ AddMsg(TEXT("Icône pour «%s» téléchargée et installée."), strIcone.c_str());
+ bUpdate = true;
+ } else {
+ // Des erreurs d'écriture du fichier se sont produites. L'indiquer.
+ AddMsg(TEXT("Erreur %u : %s"), nRes, SystemErrorToString(nRes).c_str());
+ AddMsg(TEXT("Erreur lors de la sauvegarde de l'icône pour «%s» ."), strIcone.c_str());
+ AddMsg(TEXT("Vérifiez que vous avez le droit de modifier les fichiers."));
+ }
+ } // if (taille)
+ } // if (action == eUpda_Telecharge)
+ } // For (icone)
+ } // For (pack)
+ // Plus d'îcones à traiter
+ return bUpdate;
+}
- // on parse les icones. Établissement de la liste locale
+/// Vérification de la version du noeud XML
+/// Retourne \true si le nœud est valide
+static bool CheckVersionVersion(const TiXmlElement & sTiXml)
+{
+ // Récupère la version de la branche
+ int updateversion;
+ int nQueryResult = sTiXml.QueryIntAttribute("version", &updateversion);
- // on liste les packs d'icônes
- TiXmlElement *xmlIconesPack = 0;
- for (xmlIconesPack = xmlTypeMaj->FirstChildElement("pack");
- xmlIconesPack;
- xmlIconesPack = xmlIconesPack->NextSiblingElement("pack")) {
+ if (
+ nQueryResult == TIXML_NO_ATTRIBUTE || // anciennes versions de PTVM, on ignore
+ updateversion > UPDATE_VERSION_MAX // nœud plus récent, on le saute, il sera lu une fois PTVM mis à jour
+ ) {
+ return false;
+ }
+ return true;
+}
- // Pays du pack (pour classer les icônes)
- const char* szXmlIconePays = xmlIconesPack->Attribute("pays");
+static bool UpdateTraiteAppNode(eUPDATE_ACTION action, LPCSTR pszReqType, LPCTSTR pszDispType)
+{
+ bool bUpdateNodeFound = false;
+ bool bUpdateFound = false;
- // On parcourt les différentes icônes (au cas ou certaines seraient manquantes)
- TiXmlElement *xmlIconesIcone = 0;
- for (xmlIconesIcone = xmlIconesPack->FirstChildElement("icone");
- xmlIconesIcone;
- xmlIconesIcone = xmlIconesIcone->NextSiblingElement("icone")) {
- const char* szIconeUtf = xmlIconesIcone->GetText();
+ myprintf(TEXT("Vérification pour la version %s\n"), pszDispType);
+ for (ITERATE_XML_ELEMENTS_NAMED(xmlVersionDocument.FirstChildElement("Versions"), xmlVersionElem, "version")) {
+ if (!CheckVersionVersion(*xmlVersionElem))
+ continue;
- // Initialisation des variables pour rechercher les icones
- TCHAR fileName[MAX_PATH], pathName[MAX_PATH], *szIconeChar = 0;
- LPTSTR fichier = 0;
- // Regarde si on a des caractères UTF-8 dans la chaine, et les remplace le cas échéant
- ConvertUTF82Char(szIconeUtf, szIconeChar);
- strcpy_T(fileName, szIconeChar);
- strcat_T(fileName, TEXT(".bmp"));
- _stprintf_s(pathName, _countof(pathName), TEXT("%s\\Icones"), pouchindir_prog);
- if (! FindFileRecur(pathName, fileName, &fichier)) {
- _stprintf_s(pathName, _countof(pathName), TEXT("%s\\Icones"), pouchindir_conf);
- if (! FindFileRecur(pathName, fileName, &fichier)) {
- TCHAR message[100]; // Pour afficher les messages
- if (action == eUpda_Check) {
- _stprintf_s(message, _countof(message), TEXT("Vous n'avez pas toutes les icônes de «%") A2t TEXT("»"), szXmlIconePays);
- AddStatut(message, 0);
+ // On ignore les versions dont le type de vérification n'a pas été choisi
+ if (_stricmp(xmlVersionElem->Attribute("type"), pszReqType)!=0)
+ continue;
- retval |= 0x2;
+ bUpdateNodeFound = true; // On a trouvé un descripteur de mise à jour (ce qui n'implique
+ // pas nécessairement qu'on ait trouvé une mise à jour ...)
- free(szIconeChar);
- break;
- } else if (action == eUpda_Telecharge) {
- // Télécharge les images manquantes
+ // Récupération des mises à jour de l'application
+ for (ITERATE_XML_ELEMENTS_NAMED(xmlVersionElem, xmlTypeMaj, REQ_APP_TYPE)) {
+ if (UpdateTraiteApp(*xmlTypeMaj, action, pszDispType)) {
+ bUpdateFound = true; // Voilà, maintenant on a trouvé une mise à jour
+ break; // Une seule mise à jour possible, donc on sort
+ }
+ }
+ if (bUpdateFound) // toujours pas de "break" multi-niveaux en C/C++ ...
+ break;
+ }
+ if (!bUpdateNodeFound)
+ AddMsg(TEXT("Aucune information de mise à jour %s disponible"), pszDispType);
+ myprintf(TEXT("%s version %s\n"), (bUpdateFound ? TEXT("Trouvé") : TEXT("Pas trouvé")), pszDispType);
+ return bUpdateFound;
+}
- LPCSTR urlBase = xmlTypeMaj->Attribute("base");
- LPCSTR urlPath = xmlIconesPack->Attribute("path");
- UINT longueur = strlen_T(urlBase) + strlen_T(urlPath) + strlen_T(szIconeUtf) + 6; // car path+"/"+icone+".bmp\0"
- LPBYTE data = 0;
- LPSTR url = (LPSTR)malloc(longueur);
- LPTSTR tUrl = (LPTSTR)malloc(sizeof(TCHAR)*longueur);
+#define UPDATE_APP_FLAG 0x01
+#define UPDATE_ICON_FLAG 0x02
- // Obligé de passer la une conversion, car sinon, les caractères sont mal traduits
- sprintf_s(url, longueur, "%s%s/%s.bmp", urlBase, urlPath, szIconeUtf);
- strcpy_T(tUrl, longueur, url);
- free(url); url=0;
- // Envoie la connexion
- UINT taille = GetInternetFile(tUrl, &data, eUpda_Telecharge);
- free(tUrl); tUrl=0;
- if (taille) {
- // Des données ont été récupérées
+/**
+ * Fonction traitant le fichier XML décrivant la mise à jour
+ *
+ * \param[in] action action devant être effectuée si des versions plus récentes sont trouvées
+ * (affichage de messages de status, téléchargements des nouveaus fichiers, etc.)
+ * \return Cumul de \p UPDATE_APP_FLAG (si une mise à jour d'application a été détectée ou réalisée)
+ ou \p UPDATE_ICON_FLAG (si une mise à jour d'icône(s) a été détectée ou réalisée)
+ **/
+static BYTE UpdateTraiteXml(eUPDATE_ACTION action, bool bWithBeta)
+{
+ // Récupération de la version de PTVM fonctionnant actuellement, pour comparaison :
+ AppVersion sAppVers(PTVM_VERSION_STR);
- TCHAR icone[MAX_PATH]; // Chemin vers l'image locale
+ if (!xmlVersionDocument.FirstChildElement("Versions")) {
+ // Fichier bien XML, mais pas la bonne racine, on quitte donc
+ AddMsg(TEXT("Fichier de version invalide. Réessayez ultérieurement..."));
+ return 0;
+ }
- // Écriture du fichier
- _stprintf_s(icone, _countof(icone), TEXT("%sIcones\\%") A2t TEXT("\\%s"), pouchindir_prog, (strcmp(szXmlIconePays, "France")==0 ? "." : szXmlIconePays), fileName);
- if (SauveFichier(data, taille, icone)) {
- _stprintf_s(message, _countof(message), TEXT("Icône pour «%s» téléchargée et installée."), szIconeChar);
- AddStatut(message, 0);
- retval |= 0x2;
- } else {
- // Des erreurs d'écriture du fichier se sont produite. L'indique
- _stprintf_s(message, _countof(message), TEXT("Erreur lors de la sauvegarde de l'icône pour «%s» ."), szIconeChar);
- AddStatut(icone, 0);
- AddStatut(TEXT("Vérifiez que vous avez le droit de modifier les fichiers."), 0);
- }
- free(data);
- } // if (taille)
- } // if (action == eUpda_Telecharge)
- } else {
- // L'icône existe dans le profil de l'utilisateur
- }
- } else {
- // L'icône existe dans le dossier de PTVM
- }
- free(szIconeChar);
- free(fichier);
- } // For (icone)
- } // For (pack)
- // Plus d'îcones à traiter
- AddStatut(TEXT(""), 1);
- }
+ // Commence le parcours des versions dans le fichier XML parsé
+ BYTE retval = 0;
+
+ if (UpdateTraiteAppNode(action, "stable", TEXT("stable")))
+ retval |= UPDATE_APP_FLAG;
+
+ myprintf(TEXT("retval=0x%02x, bWithBeta=%u\n"), retval, bWithBeta);
+
+ if (retval==0 && bWithBeta) {
+ // Si (et seulement si) aucune version stable n'a été trouvée, et que l'utilisateur
+ // souhaite aussi les versions beta, alors on recherche celles-ci.
+ // S'il y a à la fois une version stable et une version beta, on ne prend que la
+ // stable. La version beta sera éventuellement mise à jour à la recherche suivante.
+ if (UpdateTraiteAppNode(action, "beta", TEXT("beta")))
+ retval |= UPDATE_APP_FLAG;
+ }
+
+ for (ITERATE_XML_ELEMENTS_NAMED(xmlVersionDocument.FirstChildElement("Versions"), xmlVersionElem, "version")) {
+ if (!CheckVersionVersion(*xmlVersionElem))
+ continue;
+
+ // Récupération des mises à jour des icônes
+ for (ITERATE_XML_ELEMENTS_NAMED(xmlVersionElem, xmlTypeMaj, "icones")) {
+ if (UpdateTraiteIcons(*xmlTypeMaj, action))
+ retval |= UPDATE_ICON_FLAG;
}
- } // while (xmlVersion)
+ }
return retval;
}
@@ -527,20 +689,27 @@
/**
* On a lancé le téléchargement des nouveaux fichiers
**/
-DWORD WINAPI UpdateTelechargeThreadPRoc(LPVOID lpParameter) {
- int ret = UpdateTraiteXml(eUpda_Telecharge);
+static DWORD WINAPI UpdateTelechargeThreadProc(LPVOID lpParameter)
+{
+ bool bWithBeta = reinterpret_cast(lpParameter);
- if (ret & 1) {
+ InitProgress(1); // Une seule étape, en attendant d'en connaître le nombre
+
+ BYTE ret = UpdateTraiteXml(eUpda_Telecharge, bWithBeta);
+
+ if (ret & UPDATE_APP_FLAG) {
+ bUpdateNeedRestart = true;
if (enregistrements_actuels.recording())
- AddStatut(TEXT("Vous avez des enregistrements en cours. Redémarrez plus tard"), 0);
-
- SetWindowText(hUpdateButton, szButtonUpdateRestart);
- } else
+ AddMsg(TEXT("Vous avez des enregistrements en cours. Redémarrez plus tard"));
+ else {
+ SetWindowText(hUpdateButton, szButtonUpdateRestart);
+ EnableWindow(hUpdateButton, true); // Active le bouton
+ }
+ } else {
SetWindowText(hUpdateButton, szButtonUpdateCheck);
+ EnableWindow(hUpdateButton, true); // Active le bouton
+ }
- // Active le bouton
- EnableWindow(hUpdateButton, true);
-
// Efface le contenue du XML de la mémoire
xmlVersionDocument.Clear();
@@ -551,64 +720,88 @@
* Fonction réalisant la connection internet, et les tests pour la vérification de la version,
* le tout dans un nouveau Thread pour ne pas geler PTVM
**/
-DWORD WINAPI UpdateCheckThreadProc(LPVOID lpParameter) {
- LPBYTE bytVersion = 0; // Tableau d'octets recevant le fichier XML de mise à jour
+static DWORD WINAPI UpdateCheckThreadProc(LPVOID lpParameter)
+{
+ bool bWithBeta = reinterpret_cast(lpParameter);
+ InternetFile vBytVersion; // Tableau d'octets recevant le fichier XML de mise à jour
- SendMessage(hProgressStatut, PBM_SETRANGE, 0, MAKELPARAM(0, 4)); // On met 5 étapes pour la vérification de la version
- SendMessage(hProgressStatut, PBM_SETPOS, 0, 0); // Se positionne au début de la barre de progression
+ InitProgress(4); // On met 4 étapes pour la vérification de la version
+#ifdef _DEBUG
+ { // Le debugging de modules d'accès Internet pose de gros problèmes si Visual Studio a été
+ // configuré pour mettre à jour sa bibliothèque de symboles via le serveur de symboles de
+ // Microsoft, au fil du chargement des modules : cette mise à jour se faisant par Internet,
+ // un "deadlock" peut en résulter, provoquant un plantage de Visual Studio.
+ // Les symboles ne sont normalement chargés qu'une fois, et rechargés seulement
+ // si une mise à jour "Windows Update" a changé le module ".dll" correspondant, donc
+ // le problème ne survient qu'au premier chargement, et ensuite très occasionnellement.
+ // Le code qui suit vise à prévenir ce bloquage en forcant le chargement des modules incriminés
+ // (donc provoquant le chargement des symboles) préalablement à tout accès Internet réel.
+ // Si d'autres modules provoquent le même type de bloquage (on voit lesquels dans la barre d'état
+ // de Visual Studio au moment du "deadlock"), il suffit de les rajouter dans la table qui suit.
+ static LPCTSTR aszModules[] = {
+ TEXT("rasapi32.dll"),
+ TEXT("credssp.dll"),
+ TEXT("schannel.dll")
+ };
- int taille = GetInternetFile(
-#if 1
- UPDATE_URL
-#else
- TEXT("http://get.pouchintv.baysse.fr")
+ for (int nInx = 0; nInx < _countof(aszModules); ++nInx) {
+ HMODULE hLib = LoadLibrary(aszModules[nInx]);
+
+ if (hLib)
+ FreeLibrary(hLib);
+ }
+ }
#endif
- , &bytVersion, eUpda_Check
- ); // Objet traitant de la connexion Internet
+ AddProgress();
+ GetInternetFile(TEXT(UPDATE_URL), vBytVersion, eUpda_Check); // Objet traitant de la connexion Internet
+#ifdef _DEBUG
+ if (!vBytVersion.empty()) {
+ // Enregistrement du fichier XML reçu, en compilation _DEBUG seulement
+ TempPathName sUpdateFileName("pouchin_update.xml");
+
+ SauveFichier(vBytVersion, sUpdateFileName);
+ }
+#endif
if (stop_maj) {
- // Libère la mémoire allouée
- if (bytVersion)
- free(bytVersion);
-
// Active le bouton
EnableWindow(hUpdateButton, true);
return 1;
- } else { // if (*stop_maj)
- AddStatut(TEXT("Traitement des mises à jour..."), 1);
+ } else if (!vBytVersion.empty()) { // if (*stop_maj)
+ AddMsg(TEXT("Traitement des mises à jour..."));
+ AddProgress();
// On ajoute un caractère '\0' à la fin (car c'est un fichier texte dont il s'agit)
- bytVersion[taille] = 0;
+ vBytVersion.resize(vBytVersion.size()+1, 0);
// Parsage du fichier récupéré
xmlVersionDocument.Clear();
- xmlVersionDocument.Parse((char*)bytVersion, 0, TIXML_ENCODING_UTF8);
- // On a fini avec le fichier récupéré
- if (bytVersion){
- free(bytVersion);
- bytVersion = 0;
- }
+ xmlVersionDocument.Parse(reinterpret_cast(&vBytVersion[0]), 0, TIXML_ENCODING_UTF8);
+ vBytVersion.clear();
if (xmlVersionDocument.Error()) {
- AddStatut(TEXT("Le fichier de version est invalide."), 0);
- AddStatut(TEXT("Je ne peux déterminer la version !!!"), 5);
+ AddMsg(TEXT("Le fichier de version est invalide."));
+ AddMsg(TEXT("Je ne peux déterminer la version !!!"));
} else { // if (xmlVersionDocument.Error())
- int ret = UpdateTraiteXml(eUpda_Check);
- AddStatut(TEXT(""), 1);
+ BYTE ret = UpdateTraiteXml(eUpda_Check, bWithBeta);
+
+ AddMsg(TEXT("Vérification terminée"));
if (ret) {
+ EnableWindow(hUpdateBetaCheckBox, false);
SetWindowText(hUpdateButton, szButtonUpdateGet);
}
} // if (xmlVersionDocument.Error())
- EnableWindow(hUpdateButton, true);
- return 0;
} // if (*stop_maj)
+
+ AddProgress(-1);
+ EnableWindow(hUpdateButton, true);
+ return 0;
}
-
/**
* Fonction de gestion des évènements
**/
-INT_PTR CALLBACK UpdateDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+static INT_PTR CALLBACK UpdateDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
// Handle du Thread gérant la mise à jour
static HANDLE hThread = NULL;
@@ -618,9 +811,9 @@
hUpdateStatut = GetDlgItem(hDlg, IDC_UPDATE_LIST);
hProgressStatut = GetDlgItem(hDlg, IDC_UPDATE_PROGRESS);
hUpdateButton = GetDlgItem(hDlg, IDC_UPDATE_CHECK);
+ hUpdateBetaCheckBox = GetDlgItem(hDlg, IDC_UPDATE_BETA);
SetWindowText(hUpdateButton, szButtonUpdateCheck);
- GetModuleFileName(NULL, szAppFileName, _countof(szAppFileName));
AddLineToList(hUpdateStatut, TEXT("Statut inconnu, presser le bouton «Vérifier» ci-dessous."));
@@ -636,22 +829,19 @@
GetWindowText(hUpdateButton, szTemp, _countof(szTemp)-1);
+ bool bWithBeta = IsDlgButtonChecked(hDlg, IDC_UPDATE_BETA)==BST_CHECKED;
+
stop_maj = false;
if (_tcscmp(szTemp, szButtonUpdateCheck) == 0) {
// On lance la recherche de mise à jour
- hThread = CreateThread(NULL, 0, UpdateCheckThreadProc, NULL, NULL, NULL);
+ hThread = CreateThread(NULL, 0, UpdateCheckThreadProc, reinterpret_cast(bWithBeta), NULL, NULL);
} else if (_tcscmp(szTemp, szButtonUpdateGet) == 0) {
// On lance le téléchargement des fichiers
- hThread = CreateThread(NULL, 0, UpdateTelechargeThreadPRoc, NULL, NULL, NULL);
+ hThread = CreateThread(NULL, 0, UpdateTelechargeThreadProc, reinterpret_cast(bWithBeta), NULL, NULL);
} else if (_tcscmp(szTemp, szButtonUpdateRestart) == 0) {
- // On redémarre
- TCHAR szTemp[MAX_PATH];
- STARTUPINFO si = { sizeof(STARTUPINFO) };
- PROCESS_INFORMATION pi;
- _stprintf_s(szTemp, _countof(szTemp), TEXT("\"%s\""), szAppFileName);
- CreateProcess(NULL, szTemp, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi);
EndDialog(hDlg, IDOK);
- PostQuitMessage(0);
+ // Redémarrage (complet) de l'application
+ PostMessage(hMainWnd, WM_COMMAND, IDM_APP_RESTART, 1);
}
EnableWindow(hUpdateButton, FALSE);
@@ -667,8 +857,9 @@
WaitForSingleObject(hThread, 4 * 1000);
}
EndDialog(hDlg, LOWORD(wParam));
- hUpdateButton = 0;
- hProgressStatut = 0;
+ hUpdateButton = NULL;
+ hUpdateBetaCheckBox = NULL;
+ hProgressStatut = NULL;
return TRUE;
}
break; // case WM_COMMAND
@@ -684,5 +875,11 @@
**/
void do_web_update(HWND hOwner)
{
+ if (bUpdateNeedRestart) {
+ MessageBox(hOwner, TEXT("Une mise à jour a déjà eu lieu, mais l'application n'a pas été redémarrée"),
+ TEXT("Mise à jour"), MB_ICONERROR);
+ return;
+ }
+
DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_UPDATE), hOwner, UpdateDialogProc);
}
Modifié: trunk/utils.cpp
===================================================================
--- trunk/utils.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/utils.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -145,13 +145,9 @@
**/
tstring tstr_printf(LPCTSTR pszFmt, ...)
{
- TCHAR szBuffer[1024];
+ FMT_BUF(szBuf, 1024, pszFmt, pszFmt);
- va_list args;
- va_start(args, pszFmt);
- _vstprintf_s(szBuffer, pszFmt, args);
- va_end(args);
- return tstring(szBuffer);
+ return szBuf;
}
/**
@@ -339,8 +335,8 @@
* \note \p pszList doit être une chaîne constante, ou bien au moins statique.
* \note Cette fonction permet de ne pas avoir de tableau externe pour effectuer la conversion.
* \note Aucun item ne peut être vide, puisqu'il serait alors d'office terminateur.
- * \note Étant donnée la longueur possible de la chaîne \p pszList et le fait que la
- * fonction est plutôt d'usage debugging, on n'utilise pas de caractères \p TCHAR.
+ * \note Étant donnée la longueur possible de la chaîne \p pszList, on n'utilise
+ * pas de caractères \p TCHAR.
**/
LPCSTR EnumToString(int nVal, LPCSTR pszList, LPCSTR pszDefault)
{
@@ -359,223 +355,206 @@
}
/**
- * Recherche le premier fichier passé en paramètre, et ceci, de manière récursive
- *
- * \param[in] szDir répertoire initial pour la recherche
- * \param[in] szFile fichier, ou patern de recherche
- * \param[out] result nom du premier fichier trouvé avec le chemin (ne pas oublier de libérer avec free)
- * \warning n'oubliez pas de libérer la mémoire allouée dans la fonction
- * \retval TRUE si un fichier a été trouvé
- * \retval FALSE si rin n'est trouvé
+ * Fonction inverse de \p EnumToString : recherche d'une chaîne de caractères dans une liste.
+ * La liste de chaînes est fournie sous la forme d'une seule chaîne avec des "\0" à
+ * la fin de chaque item. Un double "\0" termine donc implicitement.
+ * La comparaison n'est pas sensible à la casse.
+ * \param[in] pszList Chaîne contenant une suite d'items séparés par des zéros binaires ;
+ * un item vide (donc deux zéros successifs) DOIT terminer.
+ * \param[in] pszStr Chaîne recherchée.
+ * \return Index de la chaîne trouvée, ou bien -1 si pas trouvé.
**/
-BOOL FindFileRecur(LPCTSTR szDir, LPCTSTR szFile, LPTSTR *result) {
- WIN32_FIND_DATA w32fs; // Structure recevant les informations pour la recherche
- TCHAR chemin[MAX_PATH]; // Chemin de recherche : szDir + \\*
- HANDLE h; // Handle utilisé pour la recherche
- BOOL next = TRUE; // Continue la recherche pour le récursif
+int StringToEnum(LPCSTR pszList, LPCSTR pszStr)
+{
+ int nVal = 0;
- //
- // Recherche avec le motif passé
- _stprintf_s(chemin, _countof(chemin), TEXT("%s\\%s"), szDir, szFile);
- h = FindFirstFile(chemin, &w32fs);
-
- if (h != INVALID_HANDLE_VALUE) {
- // on détermine le chemin cmplet du fichier (dossier + fichier)
- *result = (LPTSTR)malloc(sizeof(TCHAR)*MAX_PATH);
- _stprintf_s(*result, MAX_PATH, TEXT("%s\\%s"), szDir, w32fs.cFileName);
-
- // Ferme le handle
- FindClose(h);
-
- return TRUE;
+ if (pszStr && pszList) {
+ while (*pszList) {
+ if (_stricmp(pszList, pszStr)==0)
+ return nVal;
+ pszList += strlen(pszList)+1;
+ ++nVal;
+ }
}
+ return -1;
+}
- //
- // Chemin de recherche pour le récursif
- _stprintf_s(chemin, _countof(chemin), TEXT("%s\\*"), szDir);
- for (
- h = FindFirstFile(chemin, &w32fs);
- h != INVALID_HANDLE_VALUE && next != 0;
- next = FindNextFile(h, &w32fs)
- ) {
- if (
- w32fs.cFileName[0] == TEXT('.') && w32fs.cFileName[1] == 0 ||
- w32fs.cFileName[0] == TEXT('.') && w32fs.cFileName[1] == TEXT('.') && w32fs.cFileName[2] == 0 ||
- !(w32fs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- )
- continue;
+/**
+ * Recherche d'un fichier correspondant au nom passé en paramètre
+ *
+ * \param[in] pszDir Répertoire initial pour la recherche
+ * \param[in] pszFile Fichier, ou motif de recherche
+ * \param[in] dwFlags Options de recherche (FF_RECURSIVE, FF_DIRECTORY)
+ * \return Nom du premier fichier trouvé avec le chemin, ou une chaîne vide si pas trouvé
+ **/
+tstring FindFile(LPCTSTR pszDir, LPCTSTR pszFile, DWORD dwFlags)
+{
+ std::vector vResult;
- // on part en récursif
- _stprintf_s(chemin, _countof(chemin), TEXT("%s\\%s"), szDir, w32fs.cFileName);
+ UINT nFound = FindFile(pszDir, pszFile, vResult, dwFlags|FF_STOPATFIRST);
- if (FindFileRecur(chemin, szFile, result))
- return TRUE;
- }
+ if (nFound)
+ return vResult[0];
+ return TEXT("");
+}
- // Ferme le handle
- FindClose(h);
+/// Tester si \p w32fs référence un fichier normal
+static inline bool isFile(const WIN32_FIND_DATA & w32fs)
+{
+ return (w32fs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0;
+}
- return FALSE;
+/// Tester si \p w32fs référence un répertoire
+static inline bool isDir(const WIN32_FIND_DATA & w32fs)
+{
+ return
+ (w32fs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
+ !(w32fs.cFileName[0] == TEXT('.') && (
+ w32fs.cFileName[1] == 0 ||
+ w32fs.cFileName[1] == TEXT('.') && w32fs.cFileName[2] == 0));
}
/**
- * Recherche les fichiers passé en paramètre, et ceci, de manière récursive
+ * Recherche de tous les fichiers correspondant au motif passé en paramètre
*
- * \param[in] szDir répertoire initial pour la recherche
- * \param[in] szFile fichier, ou patern de recherche
- * \param[out] result vector de TCHAR contenant les fichiers répondant au nom passé en paramètre (ne pas oublier de libérer avec free)
- * \warning n'oubliez pas de libérer la mémoire allouée dans la fonction
- * \return le nombre de fichiers trouvés correspondant
- * \todo Essayer de définir \p result comme étant std:vector plutôt que std::vector, ainsi
- * le problème de la libération de mémoire à laquelle penser ne devrait plus se poser.
+ * \param[in] pszDir Répertoire initial pour la recherche
+ * \param[in] pszFile Fichier, ou motif de recherche
+ * \param[out] vResult Vecteur contenant les fichiers répondant au nom passé en paramètre
+ * \param[in] dwFlags Options de recherche (FF_RECURSIVE, FF_STOPATFIRST, FF_DIRECTORY)
+ * \return Le nombre de fichiers trouvés correspondant
**/
-UINT FindFileRecur(LPCTSTR szDir, LPCTSTR szFile, std::vector *result) {
+UINT FindFile(LPCTSTR pszDir, LPCTSTR pszFile, std::vector & vResult, DWORD dwFlags)
+{
WIN32_FIND_DATA w32fs; // Structure recevant les informations pour la recherche
- TCHAR chemin[MAX_PATH]; // Chemin de recherche : szDir + \\*
- UINT trouve = 0; // Indique le nombre de fichiers déjà trouvés
+ TCHAR szTmp[MAX_PATH]; // Chemin de recherche : szDir + \\*
+ UINT nFound = 0; // Indique le nombre de fichiers déjà trouvés
HANDLE h; // Handle utilisé pour la recherche
- BOOL next = TRUE;
+ BOOL bNext = TRUE;
- //
// Recherche avec le motif passé
- _stprintf_s(chemin, _countof(chemin), TEXT("%s\\%s"), szDir, szFile);
- for (h = FindFirstFile(chemin, &w32fs); h != INVALID_HANDLE_VALUE && next != 0; next = FindNextFile(h, &w32fs)) {
- if (w32fs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ _stprintf_s(szTmp, TEXT("%s\\%s"), pszDir, pszFile);
+ for (
+ h = FindFirstFile(szTmp, &w32fs);
+ h != INVALID_HANDLE_VALUE && bNext;
+ bNext = FindNextFile(h, &w32fs)
+ ) {
+ if ((dwFlags&FF_DIRECTORY)!=0 ? !isDir(w32fs) : !isFile(w32fs))
continue;
- // on détermine le chemin cmplet du fichier (dossier + fichier)
- LPTSTR temp = (LPTSTR)malloc(sizeof(TCHAR)*MAX_PATH);
- _stprintf_s(temp, MAX_PATH, TEXT("%s\\%s"), szDir, w32fs.cFileName);
- result->push_back(temp);
- trouve++;
+ // on détermine le szTmp complet du fichier (dossier + fichier)
+ _stprintf_s(szTmp, TEXT("%s\\%s"), pszDir, w32fs.cFileName);
+ vResult.push_back(szTmp);
+ ++nFound;
+ if ((dwFlags&FF_STOPATFIRST) != 0)
+ break;
}
- // Ferme le handle
- FindClose(h);
+ FindClose(h); // Ferme le handle
- //
+ if ((dwFlags&FF_RECURSIVE) == 0 || (dwFlags&FF_STOPATFIRST) != 0 && nFound > 0)
+ return nFound;
+
+ bNext = TRUE;
+
// Chemin de recherche pour le récursif
- _stprintf_s(chemin, _countof(chemin), TEXT("%s\\*"), szDir);
- next = TRUE;
- for (h = FindFirstFile(chemin, &w32fs); h != INVALID_HANDLE_VALUE && next != 0; next = FindNextFile(h, &w32fs)) {
- if (w32fs.cFileName[0] == TEXT('.') && w32fs.cFileName[1] == 0 ||
- w32fs.cFileName[0] == TEXT('.') && w32fs.cFileName[1] == TEXT('.') && w32fs.cFileName[2] == 0 ||
- !(w32fs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ _stprintf_s(szTmp, TEXT("%s\\*"), pszDir);
+ for (
+ h = FindFirstFile(szTmp, &w32fs);
+ h != INVALID_HANDLE_VALUE && bNext;
+ bNext = FindNextFile(h, &w32fs)
+ ) {
+ if (!isDir(w32fs))
continue;
// on part en récursif
- _stprintf_s(chemin, _countof(chemin), TEXT("%s\\%s"), szDir, w32fs.cFileName);
+ _stprintf_s(szTmp, TEXT("%s\\%s"), pszDir, w32fs.cFileName);
- trouve += FindFileRecur(chemin, szFile, result);
+ nFound += FindFile(szTmp, pszFile, vResult, dwFlags);
+ if (nFound > 0 && (dwFlags&FF_STOPATFIRST) != 0)
+ break;
}
// Ferme le handle
FindClose(h);
- return trouve;
+ return nFound;
}
/**
- * Convertit une chaîne de caractères UTF-8
+ * Convertit une chaîne de caractères en UTF-8
*
* \param[in] aconvertir chaîne de caractères contenant éventuellement des caractères UTF-8
- * \param[out] convertis chaîne de caractères convertie (à libérer après utilisation avec free() )
- * \return le nombre de caractères convertis
+ * \return chaîne de caractères convertie
**/
-int ConvertUTF82Char(LPCSTR aconvertir, LPTSTR & convertis) {
+tstring ConvertUTF82Char(LPCSTR aconvertir)
+{
UINT i, j; // Itérateurs
- TCHAR c; // Caractères à convertir
+ UCHAR c; // Caractères à convertir
UINT taille = strlen_T(aconvertir); // La taille de la chaîne résultante est forcément plus courte
LPTSTR _tmp = STK_ALLOC(TCHAR, taille+1); // Chaîne temporaire
for( i=0, j=0; i= 0xE0) {
- // Permet de prévenir que la chaîne ne peut pas être convertie,
- // car il faudrait plus de 8 bits pour produire le caractère
- return i;
- }
-#endif
+ UINT32 nTmp = '?'; // Caractère par défaut si conversion impossible
if (c <= 0x7F)
- _tmp[j++] = c;
+ nTmp = c;
else if (c < 0xE0)
- _tmp[j++] = ((c & 0x1F) << 6) + (aconvertir[++i] & 0x3F);
+ nTmp = ((c & 0x1F) << 6) + (aconvertir[++i] & 0x3F);
+#ifdef _UNICODE
+ // Seulement en _UNICODE, car il faut plus de 8 bits pour produire ces caractères
else if (c < 0xF0)
- _tmp[j++] = ((c & 0x0F) << 12) + ((aconvertir[++i] & 0x3F) << 6) + (aconvertir[++i] & 0x3F);
+ nTmp = ((c & 0x0F) << 12) + ((aconvertir[++i] & 0x3F) << 6) + (aconvertir[++i] & 0x3F);
else // c < 0xF8
- _tmp[j++] = ((c & 0x07) << 18) + ((aconvertir[++i] & 0x0F) << 12) + ((aconvertir[++i] & 0x3F) << 6) + (aconvertir[++i] & 0x3F);
+ nTmp = ((c & 0x07) << 18) + ((aconvertir[++i] & 0x0F) << 12) + ((aconvertir[++i] & 0x3F) << 6) + (aconvertir[++i] & 0x3F);
+#endif
+ _tmp[j++] = TCHAR(nTmp);
}
_tmp[j] = 0;
- convertis = (LPTSTR)malloc(sizeof(wchar_t)*(j + 1));
- strcpy_T(convertis, j+1, _tmp);
-
- return i;
+ return _tmp; // Conversion implicite en tstring
}
/**
* Convertir une chaine de caractères en UTF-8
*
* \param[in] aconvertir chaîne de caractères contenant éventuellement des caractères devant être encodés en UTF-8
- * \param[out] convertis chaîne de caractères convertie (à libérer après utilisation avec free() )
- * \return le nombre de caractères convertis
+ * \return chaîne de caractères convertie
**/
-int ConvertChar2UTF8(LPCSTR aconvertir, LPSTR & convertis) {
+std::string ConvertChar2UTF8(LPCSTR aconvertir)
+{
COPY_STR_ON_STACK(WCHAR, temp, aconvertir, taille);
- return ConvertChar2UTF8(temp, convertis);
+ return ConvertChar2UTF8(temp);
}
/**
* Convertir une chaine de caractères en UTF-8
*
* \param[in] aconvertir chaîne de caractères contenant éventuellement des caractères devant être encodés en UTF-8
- * \param[out] convertis chaîne de caractères convertie (à libérer après utilisation avec free() )
- * \return le nombre de caractères convertis
+ * \return chaîne de caractères convertie
**/
-int ConvertChar2UTF8(LPCWSTR aconvertir, LPSTR & convertis)
+std::string ConvertChar2UTF8(LPCWSTR aconvertir)
{
#if 0 // expérimental
- UINT taille = WideCharToMultiByte(CP_UTF8, 0, aconvertir, -1, NULL, 0, NULL, NULL);
+ UINT j = WideCharToMultiByte(CP_UTF8, 0, aconvertir, -1, NULL, 0, NULL, NULL);
- convertis = reinterpret_cast(malloc(taille));
- taille = WideCharToMultiByte(CP_UTF8, 0, aconvertir, -1, convertis, taille, NULL, NULL);
- return taille;
+ LPSTR pszTmp = STK_ALLOC(CHAR, j);
+ j = WideCharToMultiByte(CP_UTF8, 0, aconvertir, -1, convertis, j, NULL, NULL);
#else
UINT i, j; // Itérateurs
- WCHAR c; // Caractère à convertir
UINT taille = strlen_T(aconvertir);
- LPSTR _tmp = STK_ALLOC(CHAR, taille*4+1); // Chaîne de carastères temporaire (la taille max de la
- // chaîne est de 4 octets par caractère original)
- for( i=0, j=0; i>6) & 0x1F));
- _tmp[j++] = (char)(0x80 | (c & 0x3F));
- } else if (c <= 0xFFFF) {
- _tmp[j++] = (char)(0xE0 | ((c>>12) & 0x0F));
- _tmp[j++] = (char)(0x80 | ((c>>6) & 0x3F));
- _tmp[j++] = (char)(0x80 | (c & 0x3F));
- } else { // c <= 0x10FFFF
-#pragma warning(suppress: 4333)
- _tmp[j++] = (char)(0xF0 | ((c>>18) & 0x07));
- _tmp[j++] = (char)(0x80 | ((c>>12) & 0x3F));
- _tmp[j++] = (char)(0x80 | ((c>>6) & 0x3F));
- _tmp[j++] = (char)(0x80 | (c & 0x3F));
- }
- }
- _tmp[j] = 0;
- convertis = (LPSTR)malloc(j+1);
- strcpy_T(convertis, j+1, _tmp);
+ // Allouer l'espace
+ LPSTR pszTmp = STK_ALLOC(CHAR, taille*4+1); // Chaîne de carastères temporaire (la taille max de la
+ // chaîne est de 4 octets par caractère original)
+ // Effectuer la conversion
+ for(i=0, j=0; i(&aconvertir),
- 1, _tmp, _countof(_tmp), NULL, NULL);
-
- _tmp[taille] = 0; // zéro terminateur
- convertis = reinterpret_cast(malloc(taille+1));
- strcpy_T(convertis, taille+1, _tmp);
- return taille;
+ j = WideCharToMultiByte(
+ CP_UTF8, 0, reinterpret_cast(&aconvertir),
+ 1, convertis, 5, NULL, NULL);
#else
- int j=0; // Itérateur
- CHAR _tmp[5]; // Chaîne de caractères temporaire
- if (aconvertir <= 0x7F)
- _tmp[j++] = (char)aconvertir;
- else if (aconvertir <= 0x7FF) {
- _tmp[j++] = (char)(0xC0 | ((aconvertir>>6) & 0x1F));
- _tmp[j++] = (char)(0x80 | (aconvertir & 0x3F));
+ if (aconvertir <= 0x7F) {
+ convertis[0] = (char)aconvertir;
+ j = 1;
+ } else if (aconvertir <= 0x7FF) {
+ convertis[0] = (char)(0xC0 | ((aconvertir>>6) & 0x1F));
+ convertis[1] = (char)(0x80 | (aconvertir & 0x3F));
+ j = 2;
} else if (aconvertir <= 0xFFFF) {
- _tmp[j++] = (char)(0xE0 | ((aconvertir>>12) & 0x0F));
- _tmp[j++] = (char)(0x80 | ((aconvertir>>6) & 0x3F));
- _tmp[j++] = (char)(0x80 | (aconvertir & 0x3F));
+ convertis[0] = (char)(0xE0 | ((aconvertir>>12) & 0x0F));
+ convertis[1] = (char)(0x80 | ((aconvertir>>6) & 0x3F));
+ convertis[2] = (char)(0x80 | (aconvertir & 0x3F));
+ j = 3;
} else { // aconvertir <= 0x10FFFF
#pragma warning(suppress: 4333)
- _tmp[j++] = (char)(0xF0 | ((aconvertir>>18) & 0x07));
- _tmp[j++] = (char)(0x80 | ((aconvertir>>12) & 0x3F));
- _tmp[j++] = (char)(0x80 | ((aconvertir>>6) & 0x3F));
- _tmp[j++] = (char)(0x80 | (aconvertir & 0x3F));
+ convertis[0] = (char)(0xF0 | ((aconvertir>>18) & 0x07));
+ convertis[1] = (char)(0x80 | ((aconvertir>>12) & 0x3F));
+ convertis[2] = (char)(0x80 | ((aconvertir>>6) & 0x3F));
+ convertis[3] = (char)(0x80 | (aconvertir & 0x3F));
+ j = 4;
}
- _tmp[j] = 0;
+#endif
+ convertis[j] = 0; // zéro terminateur
- convertis = (LPSTR)malloc(j+1);
- strcpy_T(convertis, j+1, _tmp);
-
return j;
-#endif
}
+
+/**
+ * Nettoyage des espaces et caractères spéciaux (tels CR/LF) à la fin d'une chaîne de caractères
+ * \param[in,out] pszStr Chaîne de caractères à nettoyer, et résultat
+ * \return Pointeur sur cette même chaîne
+ **/
+LPTSTR RTrimStr(LPTSTR pszStr)
+{
+ UINT nLen = strlen_T(pszStr);
+
+ while (nLen>0 && UINT(pszStr[--nLen])<=' ')
+ pszStr[nLen]=0;
+ return pszStr;
+}
+
+/**
+ * Conversion d'un code d'erreur système (retourné par \p GetLastError)
+ * en une chaîne de caractères affichable.
+ *
+ * \param[in] dwErr Code d'erreur à convertir
+ * \return Une chaîne de caractères, format \p tstring (= \p string ou \p wstring),
+ * contenant le message d'erreur correspondant
+ **/
+tstring SystemErrorToString(DWORD dwErr)
+{
+ TCHAR szBuffer[512];
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, 0x040c /* = français */, szBuffer, _countof(szBuffer), NULL);
+ return RTrimStr(szBuffer); // Conversion implicite en tstring
+}
Modifié: trunk/utils.h
===================================================================
--- trunk/utils.h 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/utils.h 2009-08-06 17:55:25 UTC (rev 199)
@@ -361,15 +361,16 @@
#ifdef _UNICODE
#define WCHAR2TCHAR(str) str
#else
- inline std::auto_ptr WChar2Char(LPCWSTR pszStr)
+ inline std::string WChar2Char(LPCWSTR pszStr)
{
- UINT nLen = strlen_T(pszStr)+1;
- std::auto_ptr pszRes(new CHAR[nLen]);
+ UINT nLen = strlen_T(pszStr);
+ std::string strRes;
- strcpy_T(pszRes.get(), nLen, pszStr);
- return pszRes;
+ strRes.resize(nLen);
+ strcpy_T(&strRes[0], nLen+1, pszStr);
+ return strRes;
}
- #define WCHAR2TCHAR(str) WChar2Char(str).get()
+ #define WCHAR2TCHAR(str) WChar2Char(str).c_str()
#endif
/**
@@ -438,6 +439,26 @@
**/
tstring tstr_printf(LPCTSTR pszFmt, ...);
+/**
+ * Macro d'assistance à l'encapsulation de fonctionnalités "printf"
+ *
+ * Après exécution du code correspondant, la chaîne formatée est disponible
+ * dans la variable dont le nom est choisi en premier argument.
+ * \param[in] buffer Nom de la chaîne tampon à utiliser
+ * \param[in] size Taille de la chaîne tampon à utiliser
+ * \param[in] fmt Chaîne de formatage
+ * \param[in] prevarg Argument prédédant la liste d'arguments variables
+ * \note Une tentative d'utiliser un template pour ce faire a été abandonnée
+ * pour cause d'impossibilité de se conformer au standard C++ (cela fonctionnait
+ * en compilation 32 bits mais pas en compilation 64 bits).
+ **/
+#define FMT_BUF(buffer, size, fmt, prevarg) \
+ TCHAR buffer[size]; { \
+ va_list args; \
+ va_start(args, prevarg); \
+ _vstprintf_s(buffer, fmt, args); \
+ va_end(args); }
+
// ----------------------------------------------------------------------------
/**
@@ -643,60 +664,71 @@
* \note \p pszList doit être une chaîne constante, ou bien au moins statique.
* \note Cette fonction permet de ne pas avoir de tableau externe pour effectuer la conversion.
* \note Aucun item ne peut être vide, puisqu'il serait alors d'office terminateur.
- * \note Étant donnée la longueur possible de la chaîne \p pszList et le fait que la
- * fonction est plutôt d'usage debugging, on n'utilise pas de caractères \p TCHAR.
+ * \note Étant donnée la longueur possible de la chaîne \p pszList, on n'utilise
+ * pas de caractères \p TCHAR.
**/
LPCSTR EnumToString(int nVal, LPCSTR pszList, LPCSTR pszDefault="??");
/**
- * Recherche le premier fichier passé en paramètre, et ceci, de manière récursive
+ * Fonction inverse de \p EnumToString : recherche d'une chaîne de caractères dans une liste.
+ * La liste de chaînes est fournie sous la forme d'une seule chaîne avec des "\0" à
+ * la fin de chaque item. Un double "\0" termine donc implicitement.
+ * La comparaison n'est pas sensible à la casse.
+ * \param[in] pszList Chaîne contenant une suite d'items séparés par des zéros binaires ;
+ * un item vide (donc deux zéros successifs) DOIT terminer.
+ * \param[in] pszStr Chaîne recherchée.
+ * \return Index de la chaîne trouvée, ou bien -1 si pas trouvé.
+ **/
+int StringToEnum(LPCSTR pszList, LPCSTR pszStr);
+
+#define FF_RECURSIVE 0x01 //!< Recherche dans les sous-répertoires
+#define FF_STOPATFIRST 0x02 //!< Arrêt au premier résultat trouvé
+#define FF_DIRECTORY 0x04 //!< Recherche d'un répertoire
+
+/**
+ * Recherche d'un fichier correspondant au nom passé en paramètre
*
- * \param[in] szDir répertoire initial pour la recherche
- * \param[in] szFile fichier, ou patern de recherche
- * \param[out] result nom du premier fichier trouvé avec le chemin
- * \warning n'oubliez pas de libérer la mémoire allouée dans la fonction
- * \retval TRUE si un fichier a été trouvé
- * \retval FALSE si rin n'est trouvé
+ * \param[in] pszDir Répertoire initial pour la recherche
+ * \param[in] pszFile Fichier, ou motif de recherche
+ * \param[in] dwFlags Options de recherche (FF_RECURSIVE, FF_DIRECTORY)
+ * \return Nom du premier fichier trouvé avec le chemin, ou une chaîne vide si pas trouvé
**/
-BOOL FindFileRecur(LPCTSTR szDir, LPCTSTR szFile, LPTSTR *result);
+tstring FindFile(LPCTSTR pszDir, LPCTSTR pszFile, DWORD dwFlags=FF_RECURSIVE);
/**
- * Recherche les fichiers passé en paramètre, et ceci, de manière récursive
+ * Recherche de tous les fichiers correspondant au motif passé en paramètre
*
- * \param[in] szDir répertoire initial pour la recherche
- * \param[in] szFile fichier, ou patern de recherche
- * \param[out] result vector de TCHAR contenant les fichiers répondant au nom passé en paramètre
- * \warning n'oubliez pas de libérer la mémoire allouée dans la fonction
- * \return le nombre de fichiers trouvés correspondant
+ * \param[in] pszDir Répertoire initial pour la recherche
+ * \param[in] pszFile Fichier, ou motif de recherche
+ * \param[out] vResult Vecteur contenant les fichiers répondant au nom passé en paramètre
+ * \param[in] dwFlags Options de recherche (FF_RECURSIVE, FF_STOPATFIRST, FF_DIRECTORY)
+ * \return Le nombre de fichiers trouvés correspondant
**/
-UINT FindFileRecur(LPCTSTR szDir, LPCTSTR szFile, std::vector *result);
+UINT FindFile(LPCTSTR pszDir, LPCTSTR pszFile, std::vector & vResult, DWORD dwFlags);
/**
* Convertit une chaîne de caractères en UTF-8
*
* \param[in] aconvertir chaîne de caractères contenant éventuellement des caractères UTF-8
- * \param[out] convertis chaîne de carastères convertie
- * \return le nombre de caractères convertis
+ * \return chaîne de caractères convertie
**/
-int ConvertUTF82Char(LPCSTR aconvertir, LPTSTR & convertis);
+tstring ConvertUTF82Char(LPCSTR aconvertir);
/**
* Convertir une chaine de caractères en UTF-8
*
* \param[in] aconvertir chaîne de caractères contenant éventuellement des caractères devant être encodés en UTF-8
- * \param[out] convertis chaîne de caractères convertie
- * \return le nombre de caractères convertis
+ * \return chaîne de caractères convertie
**/
-int ConvertChar2UTF8(LPCWSTR aconvertir, LPSTR & convertis);
+std::string ConvertChar2UTF8(LPCWSTR aconvertir);
/**
* Convertir une chaine de caractères en UTF-8
*
* \param[in] aconvertir chaîne de caractères contenant éventuellement des caractères devant être encodés en UTF-8
- * \param[out] convertis chaîne de caractères convertie
- * \return le nombre de caractères convertis
+ * \return chaîne de caractères convertie
**/
-int ConvertChar2UTF8(LPCSTR aconvertir, LPSTR & convertis);
+std::string ConvertChar2UTF8(LPCSTR aconvertir);
/**
* Convertir un caractère en UTF-8
@@ -707,8 +739,10 @@
* \note \p aconvertir est de type \p UINT32 car :
* - TCHAR pose des problèmes étant donné qu'il s'agit d'une valeur *signée*
* - La fonction est capable de convertir des caractères codés sur plus de 16 bits
+ * \note \p convertis doit pointer sur une variable de taille suffisante
+ * pour être capable de recevoir au moins 5 caractères (terminateur compris).
**/
-int ConvertChar2UTF8(UINT32 aconvertir, LPSTR & convertis);
+int ConvertChar2UTF8(UINT32 aconvertir, LPSTR convertis);
// ----------------------------------------------------------------------------
@@ -746,4 +780,57 @@
name++
+/// Macro d'assistance à l'énumération de nœuds enfants d'un nœud TiXML
+#define ITERATE_XML_CHILDREN(parent, child) \
+ const TiXmlNode * child = (parent)->FirstChild(); \
+ child != NULL; \
+ child = child->NextSibling()
+
+/// Macro d'assistance à l'énumération d'éléments enfants d'un nœud TiXML
+#define ITERATE_XML_ELEMENTS(parent, child) \
+ const TiXmlElement * child = (parent)->FirstChildElement(); \
+ child != NULL; \
+ child = child->NextSiblingElement()
+
+/// Macro d'assistance à l'énumération d'éléments enfants nommés d'un nœud TiXML
+#define ITERATE_XML_ELEMENTS_NAMED(parent, child, name) \
+ const TiXmlElement * child = (parent)->FirstChildElement(name); \
+ child != NULL; \
+ child = child->NextSiblingElement(name)
+
// ----------------------------------------------------------------------------
+
+/// Structure d'assistance à la création de noms de fichiers situés dans le répertoire %TEMP%
+struct TempPathName
+{
+ TCHAR szPath[MAX_PATH];
+
+ /// Constructeur
+ template
+ TempPathName(const T * pszFileName)
+ {
+ GetTempPath(_countof(szPath), szPath);
+ strcat_T(szPath, pszFileName);
+ }
+
+ /// Récupération du résultat
+ operator LPCTSTR() {
+ return szPath;}
+};
+
+/**
+ * Nettoyage des espaces et caractères spéciaux (tels CR/LF) à la fin d'une chaîne de caractères
+ * \param[in,out] pszStr Chaîne de caractères à nettoyer, et résultat
+ * \return Pointeur sur cette même chaîne
+ **/
+LPTSTR RTrimStr(LPTSTR pszStr);
+
+/**
+ * Conversion d'un code d'erreur système (retourné par \p GetLastError)
+ * en une chaîne de caractères affichable.
+ *
+ * \param[in] dwErr Code d'erreur à convertir
+ * \return Une chaîne de caractères, format \p tstring (= \p string ou \p wstring),
+ * contenant le message d'erreur correspondant
+ **/
+tstring SystemErrorToString(DWORD dwErr);
Modifié: trunk/xml.cpp
===================================================================
--- trunk/xml.cpp 2009-07-24 20:42:06 UTC (rev 198)
+++ trunk/xml.cpp 2009-08-06 17:55:25 UTC (rev 199)
@@ -410,10 +410,7 @@
CXMLOpenChild::CXMLOpenChild(CXMLOutput & rf, LPCSTR name) :
ref(rf)
{
- LPSTR sztemp=0;
- ConvertChar2UTF8(name, sztemp);
- strcpy_T(str, sztemp);
- free(sztemp);
+ strcpy_T(str, ConvertChar2UTF8(name).c_str());
ref.add_open(str);
ref.send();
++ref.indent;
@@ -552,29 +549,26 @@
**/
int CXMLOutput::put(LPCSTR name, LPCWSTR str)
{
- UINT ch;
- LPSTR buff = NULL;
+ UINT ch;
+ std::string buff = ConvertChar2UTF8(name);
add_indent();
- ConvertChar2UTF8(name, buff);
- add_open(buff);
+ add_open(buff.c_str());
while ((ch = *str++)!=0) {
+ CHAR bufch[8];
+
switch (ch) {
case '&': add("&"); break;
case '<': add("<"); break;
case '>': add(">"); break;
- default: {
- LPSTR bufch = NULL;
-
+ default:
ConvertChar2UTF8(ch, bufch);
add(bufch);
- free(bufch); }
}
}
- add_close(buff);
- free(buff);
+ add_close(buff.c_str());
return send();
}
From pouchintv-dev at baysse.fr Sat Aug 8 17:14:23 2009
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: Sat, 08 Aug 2009 15:14:23 -0000
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r200 - trunk
Message-ID: <20090808151416.0B0EA6EFF4@mail.baysse.fr>
Author: gingko
Date: 2009-08-08 17:14:15 +0200 (sam 08 aoû 2009)
New Revision: 200
Added:
trunk/dshow_inc.h
Modified:
trunk/Doxyfile
trunk/Pouchin TV_2005.vcproj
trunk/Pouchin TV_2008.vcproj
trunk/base.h
trunk/changelog.html
trunk/filters.cpp
trunk/filters.h
trunk/graph.cpp
trunk/graph.h
trunk/ini.cpp
trunk/ini.h
trunk/main.cpp
trunk/make_lzma.cmd
trunk/rendering.h
trunk/res.rc
trunk/resource.h
trunk/settings.cpp
trunk/update.cpp
Log:
Utilisation d'un filtre EAC3 dédié.
graph.h, graph.cpp, ini.h, ini.cpp, main.cpp, resource.h, res.rc :
* Ajout d'un filtre dédié (merci à MatMaul), sélectionnable dans la configuration,
pour l'audio en mode EAC3.
* Par souci de pouvoir continuer à fonctionner selon le mode précédent (sinon certains
utilisateurs auraient des difficultés), le fait de sélectionner "Aucun" pour le
codec "EAC3" a pour effet de provoquer l'usage du filtre AC3 en présence d'une
piste EAC3.
* Dans le menu des filtres, les filtres "Audio MPEG2" et "Audio AC3", qui auraient
dû se voir adjoindre le filtre "Audio EAC3" s'ils étaient restés inchangés, sont
remplacés par la commande unique "Rendu audio...", qui affiche le rendu audio
effectivement utilisé par le codec audio courant.
base.h, dshow_inc.h, Pouchin TV_2005.vcproj, Pouchin TV_2008.vcproj :
* Les déclarations d'inclusion DirectShow sont regroupées dans un fichier
spécifique, "dshow_inc.h" (dans l'optique de faire en sorte, progressivement,
que ces déclaration soient importées seulement dans certains modules sélectionnés
plutôt que dans toute l'application).
filters.h, filters.cpp :
* Ajout d'un membre "isNull" Ã la structure "FilterData".
rendering.h :
* Ajout de COsdAllObjects::DisplayBotRightMsg, pour afficher un texte
quelconque dans l'OSD (coin inférieur droit)
main.cpp, ini.cpp :
* Ajout de commandes (en mode debugging seulement) pour débrancher et rebrancher
"manuellement" les sorties vidéo et audio.
* Ajout de messages OSD pour confirmer l'effet de ces deux commandes, ainsi que
des messages d'arrêt et de redémarrage du graphe précedemment existantes.
Doxyfile, update.cpp, make_lzma.cmd :
* Corrections mineures
Modifié: trunk/Doxyfile
===================================================================
--- trunk/Doxyfile 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/Doxyfile 2009-08-08 15:14:15 UTC (rev 200)
@@ -1063,7 +1063,12 @@
EXPAND_AS_DEFINED = IF_CONSOLE \
IF_CONSOLE_CA \
IF_CONSOLE_CB \
- IF_CONSOLE_WE
+ IF_CONSOLE_WE \
+ Interface \
+ DeclareInterface \
+ DeclareBasedInterface \
+ EndInterface \
+ implements
#Note: Expansion des macros IF_CONSOLE pour éviter des erreurs de documentation
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
Modifié: trunk/Pouchin TV_2005.vcproj
===================================================================
--- trunk/Pouchin TV_2005.vcproj 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/Pouchin TV_2005.vcproj 2009-08-08 15:14:15 UTC (rev 200)
@@ -908,6 +908,10 @@
>
+
+
Modifié: trunk/Pouchin TV_2008.vcproj
===================================================================
--- trunk/Pouchin TV_2008.vcproj 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/Pouchin TV_2008.vcproj 2009-08-08 15:14:15 UTC (rev 200)
@@ -901,6 +901,10 @@
>
+
+
Modifié: trunk/base.h
===================================================================
--- trunk/base.h 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/base.h 2009-08-08 15:14:15 UTC (rev 200)
@@ -28,7 +28,7 @@
#pragma once
-#define _WIN32_DCOM
+#define _WIN32_DCOM // "Enables DCOM extensions" ? (probablement plus nécessaire)
#ifndef __D3DRM_H__
#define __D3DRM_H__ ///< Pour éviter les problèmes de compatibilité entre \p qedit.h et \p vrm9.h
@@ -45,40 +45,8 @@
#include
#include
-#include
+#include "dshow_inc.h" // Inclusion des éléments DirectShow
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-// **********************************************************************************
-// * Les lignes qui suivent sont une mise en oeuvre d'une suggestion proposée dans *
-// * un forum Microsoft pour pallier au fait que le fichier "dxtrans.h" n'est plus *
-// * inclus dans le DirectX SDK au-delà de celui d'août 2007. *
-// * *
-// * Pour que cela fonctionne, il faut aussi ouvrir le fichier "qedit.h" (dans le *
-// * Windows SDK !!) et y mettre en commentaires la ligne "#include "dxtrans.h" *
-// * (ligne 498, en principe, mais ça peut changer selon les versions). *
-// * Voir (Ctrl-clic pour suivre le lien dans Visual Studio) : **************************************************************
-// * http://social.msdn.microsoft.com/Forums/en-US/windowssdk/thread/ed097d2c-3d68-4f48-8448-277eaaf68252/#70fb4aca-960c-4a76-b48c-6b3fa328b271 *
-// ***********************************************************************************************************************************************
-#define __IDxtCompositor_INTERFACE_DEFINED__
-#define __IDxtAlphaSetter_INTERFACE_DEFINED__
-#define __IDxtJpeg_INTERFACE_DEFINED__
-#define __IDxtKey_INTERFACE_DEFINED__
-// (fin de mise en oeuvre de suggestion)
-
-#include
-
-#include
-
-#pragma warning(disable:4995)
-
#include
#include
#include
@@ -94,8 +62,13 @@
#include "vstudio_edition.h"
#if !defined(COMPILER_EDITION_VCEXPRESS)
+ #pragma warning(push)
+ #pragma warning(disable:4995) // Quelques inconsistances de Microsoft dans les en-têtes ATL
+
#include
#include
+
+ #pragma warning(pop)
#else
#include "atlbase_ptvm.h"
#endif
@@ -196,12 +169,6 @@
**/
const COLORREF colorKey = RGB(1,1,1);
-/// GUID pour le codec h264
-const GUID guid_H264 = {
- 0x31435641, 0x0000, 0x0010,
- {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}
-};
-
/**
* Met en file d'attente le message d'erreur passé en paramètre pour un affichage ultérieur
*
Modifié: trunk/changelog.html
===================================================================
--- trunk/changelog.html 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/changelog.html 2009-08-08 15:14:15 UTC (rev 200)
@@ -56,6 +56,23 @@
Changements réalisés pour la version 0.5
+ - SVN rév. 200 :
+
+ - Utilisation d'un filtre EAC3 dédié, sélectionnable dans la configuration,
+ d'après d'un patch proposé par MatMaul.
+ - Un rebasculement en AC3 est prévu si aucun filtre EAC3 n'existe ou n'est choisi.
+ - Dans le menu des filtres, les filtres de rendu audio sont fusionnés sous une seule commande,
+ affichant les propriétés du filtre effectivement utilisé.
+
+
+
+ - SVN rév. 199 :
+
+ - Mise à jour du système des … euh … mises à jour de Pouchin TV Mod,
+ avec prise en charge correcte des versions 64 bits ainsi que des versions expérimentales.
+
+
+
- 0.5.198 (expérimentale, publiée dans le forum le 24 juillet 2009) :
- Dernière étape d'une importante réorganisation du code dans le graphe.
Ajouté: trunk/dshow_inc.h
===================================================================
--- trunk/dshow_inc.h (rev 0)
+++ trunk/dshow_inc.h 2009-08-08 15:14:15 UTC (rev 200)
@@ -0,0 +1,66 @@
+/*
+ * dshow_inc.h
+ * Copyright (C) 2009 gingko - http://gingko.homeip.net/
+ *
+ * This file is part of Pouchin TV Mod, a free DVB-T viewer.
+ * See http://pouchintv.baysse.fr/ for updates.
+ *
+ * Pouchin TV Mod is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Pouchin TV Mod is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *
+ * Most files of this project have been changed from the Pouchin TV
+ * project (Copyright (C) 2006 Pouchin ),
+ * to use with a modified version of this software.
+ * See http://pouchinteve.free.fr/ for the original project.
+ */
+
+#pragma once
+
+// ====================================================================================
+// Inclusions spécifiques à l'utilisation de DirectShow
+// ====================================================================================
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+// **********************************************************************************
+// * Les lignes qui suivent sont une mise en oeuvre d'une suggestion proposée dans *
+// * un forum Microsoft pour pallier au fait que le fichier "dxtrans.h" n'est plus *
+// * inclus dans le DirectX SDK au-delà de celui d'août 2007. *
+// * *
+// * Pour que cela fonctionne, il faut aussi ouvrir le fichier "qedit.h" (dans le *
+// * Windows SDK !!) et y mettre en commentaires la ligne "#include "dxtrans.h" *
+// * (ligne 498, en principe, mais ça peut changer selon les versions). *
+// * Voir (Ctrl-clic pour suivre le lien dans Visual Studio) : **************************************************************
+// * http://social.msdn.microsoft.com/Forums/en-US/windowssdk/thread/ed097d2c-3d68-4f48-8448-277eaaf68252/#70fb4aca-960c-4a76-b48c-6b3fa328b271 *
+// ***********************************************************************************************************************************************
+#define __IDxtCompositor_INTERFACE_DEFINED__
+#define __IDxtAlphaSetter_INTERFACE_DEFINED__
+#define __IDxtJpeg_INTERFACE_DEFINED__
+#define __IDxtKey_INTERFACE_DEFINED__
+// (fin de mise en oeuvre de suggestion)
+
+#include
+
+#include
Modifié: trunk/filters.cpp
===================================================================
--- trunk/filters.cpp 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/filters.cpp 2009-08-08 15:14:15 UTC (rev 200)
@@ -112,7 +112,7 @@
**/
bool FilterData::check_property_dialog() const
{
- if (IsNullName(pszName) || !pFilter)
+ if (isNull() || !pFilter)
return false;
CComQIPtr pPages(pFilter);
Modifié: trunk/filters.h
===================================================================
--- trunk/filters.h 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/filters.h 2009-08-08 15:14:15 UTC (rev 200)
@@ -99,6 +99,12 @@
VOID create_property_dialog();
/**
+ * \brief Retourne \p true si le filtre a été déclaré comme "Aucun"
+ **/
+ bool isNull() const {
+ return IsNullName(pszName); }
+
+ /**
* \brief Vérification de l'existence d'un dialogue de propriétés sur ce filtre
*
* \return \p true si un dialogue de propriétés existe
Modifié: trunk/graph.cpp
===================================================================
--- trunk/graph.cpp 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/graph.cpp 2009-08-08 15:14:15 UTC (rev 200)
@@ -48,6 +48,21 @@
#endif
// ====================================================================================
+// GUIDs
+// ====================================================================================
+
+/// CLSID pour EAC3
+// A7FB87AF-2D02-42FB-A4D4-05CD93843BDD
+CLSID MEDIASUBTYPE_DOLBY_DDPLUS =
+ {0xA7FB87AF, 0x2D02, 0x42FB, {0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD}};
+
+/// CLSID pour TIF
+// FC772AB0-0C7F-11D3-8FF2-00A0C9224CF4
+static CLSID CLSID_BDA_MPEG2_TIF =
+ {0xFC772AB0, 0x0C7F, 0x11D3, {0x8F, 0xF2, 0x00, 0xA0, 0xC9, 0x22, 0x4C, 0xF4}};
+
+
+// ====================================================================================
// Descripteurs de médias
// ====================================================================================
@@ -129,8 +144,8 @@
(LPBYTE)&sH264_fmt // pbFormat
};
-/// Format, Audio MPEG2
-static const WAVEFORMATEX sMp2a_fmt = {
+/// Format, Audio (commun)
+static const WAVEFORMATEX sAudioFmt = {
WAVE_FORMAT_PCM, // wFormatTag
2, // nChannels
48000, // nSamplesPerSec
@@ -149,21 +164,10 @@
0, // lSampleSize
FORMAT_WaveFormatEx, // formattype
NULL, // pUnk
- sizeof(sMp2a_fmt), // cbFormat
- (LPBYTE)&sMp2a_fmt // pbFormat
+ sizeof(sAudioFmt), // cbFormat
+ (LPBYTE)&sAudioFmt // pbFormat
};
-/// Format, Audio AC3
-static const WAVEFORMATEX sAc3__fmt = {
- WAVE_FORMAT_PCM, // wFormatTag
- 2, // nChannels
- 48000, // nSamplesPerSec
- 48000*4, // nAvgBytesPerSec
- 4, // nBlockAlign
- 16, // wBitsPerSample
- 0 // cbSize
-};
-
/// Media type, Audio AC3
static const AM_MEDIA_TYPE sAc3__am = {
MEDIATYPE_Audio, // majortype
@@ -173,10 +177,23 @@
0, // lSampleSize
FORMAT_WaveFormatEx, // formattype
NULL, // pUnk
- sizeof(sAc3__fmt), // cbFormat
- (LPBYTE)&sAc3__fmt, // pbFormat
+ sizeof(sAudioFmt), // cbFormat
+ (LPBYTE)&sAudioFmt, // pbFormat
};
+/// Media type, Audio EAC3
+static const AM_MEDIA_TYPE sEac3_am = {
+ MEDIATYPE_Audio, // majortype
+ MEDIASUBTYPE_DOLBY_DDPLUS, // subtype
+ TRUE, // bFixedSizeSamples
+ FALSE, // bTemporalCompression
+ 0, // lSampleSize
+ FORMAT_WaveFormatEx, // formattype
+ NULL, // pUnk
+ sizeof(sAudioFmt), // cbFormat
+ (LPBYTE)&sAudioFmt, // pbFormat
+};
+
/// Media type, PSI
static const AM_MEDIA_TYPE sPsi__am = {
MEDIATYPE_MPEG2_SECTIONS, // majortype
@@ -190,11 +207,6 @@
NULL // pbFormat
};
-/// CLSID pour TIF
-// FC772AB0-0C7F-11D3-8FF2-00A0C9224CF4
-static CLSID CLSID_BDA_MPEG2_TIF =
- {0xFC772AB0, 0x0C7F, 0x11D3, {0x8F, 0xF2, 0x00, 0xA0, 0xC9, 0x22, 0x4C, 0xF4}};
-
/// Media type, TIF
static const AM_MEDIA_TYPE sTif__am = {
MEDIATYPE_MPEG2_SECTIONS, // majortype
@@ -690,9 +702,11 @@
DecoderData sH264Codec;
DecoderData sMp2aCodec;
DecoderData sAc3_Codec;
+ DecoderData sEac3Codec;
FilterData sDSound;
FilterData sDSoundAc3;
+ FilterData sDSoundEac3;
#if USE_PMTFILTER
DecoderData sPMT_Filter;
@@ -782,7 +796,7 @@
* \param[in] pid PID de la piste à brancher
* \param[in] type Type de la piste audio
**/
- virtual HRESULT branche_son(UINT16 pid, TrackStreamType type);
+ virtual HRESULT branche_son(UINT16 pid, TrackStreamType type);
/**
* Débranchement de toutes les pistes sonores
@@ -832,8 +846,10 @@
sH264Codec(&sH264_am, "vidéo H264", filtreH264, L"h264"),
sMp2aCodec(&sMp2a_am, "audio MPEG2", filtreAudio, L"mp2a"),
sAc3_Codec(&sAc3__am, "audio AC3", filtreAc3, L"ac3"),
+ sEac3Codec(&sEac3_am, "audio EAC3", filtreEac3, L"eac3"),
sDSound(TEXT("DirectSound (MPEG2)"), CLSID_DSoundRender),
sDSoundAc3(TEXT("DirectSound (AC3)"), CLSID_DSoundRender),
+ sDSoundEac3(TEXT("DirectSound (EAC3)"), CLSID_DSoundRender),
#if USE_PMTFILTER
sPMT_Filter(&sPmt__am, "PMT", TEXT(PMT_FILTER_NAME), L"pmt", MEDIA_MPEG2_PSI, CPMTFilter::CreateInstance),
#endif
@@ -1073,7 +1089,7 @@
return S_OK;
}
- if (IsNullName(sDData.pszName))
+ if (sDData.isNull())
return S_OK;
CComPtr pOutPin;
@@ -1107,7 +1123,7 @@
HRESULT CPTvM_TunerGraph::render_audio(IMpeg2Demultiplexer & iMp2Demux,
DecoderData & sDData, FilterData & sSoundFilter)
{
- if (IsNullName(sDData.pszName))
+ if (sDData.isNull())
return S_OK;
CComPtr pOutPin;
@@ -1207,7 +1223,11 @@
return hr;
// ####### Audio AC3 :
- return render_audio(iMp2Demux, sAc3_Codec, sDSoundAc3);
+ if (FAILED(hr = render_audio(iMp2Demux, sAc3_Codec, sDSoundAc3)))
+ return hr;
+
+ // ####### Audio EAC3 :
+ return render_audio(iMp2Demux, sEac3Codec, sDSoundEac3);
}
// ====================================================================================
@@ -1717,7 +1737,7 @@
* \param[in] pid PID de la piste à brancher
* \param[in] type Type de la piste audio
**/
-HRESULT CPTvM_TunerGraph::branche_son(UINT16 pid, TrackStreamType type)
+HRESULT CPTvM_TunerGraph::branche_son(UINT16 pid, TrackStreamType type)
{
HRESULT hr = E_FAIL;
@@ -1728,8 +1748,16 @@
hr = sMp2aCodec.branche_pid(pid);
break;
+ case tst_EAC3:
+ if (!sEac3Codec.isNull()) {
+ hr = sEac3Codec.branche_pid(pid);
+ break;
+ }
+ // Si le filtre EAC3 n'existe pas, on se rabat sur le filtre AC3
+ // (car certains anciens codecs peuvent décoder l'EAC3 dans ce mode).
+ // Ce "mode de compatibilité" devrait pouvoir être supprimé d'ici un ou deux ans.
+ // ... (passage à travers)
case tst_AC3:
- case tst_EAC3:
hr = sAc3_Codec.branche_pid(pid);
break;
@@ -1747,6 +1775,7 @@
{
sMp2aCodec.debranche_pids();
sAc3_Codec.debranche_pids();
+ sEac3Codec.debranche_pids();
}
/**
@@ -1866,10 +1895,32 @@
case ft_Video_Mp2v: sMp2vCodec.create_property_dialog(); break;
case ft_Video_H264: sH264Codec.create_property_dialog(); break;
case ft_Audio_Mp2a: sMp2aCodec.create_property_dialog(); break;
- case ft_Audio_Ac3: sAc3_Codec.create_property_dialog(); break;
+
+ case ft_Audio_Eac3:
+ if (!sEac3Codec.isNull()) {
+ sEac3Codec.create_property_dialog();
+ break;
+ }
+ // si le filtre EAC3 n'est pas défini, on utilise le filtre AC3
+ // ... (passage à travers)
+ case ft_Audio_Ac3:
+ sAc3_Codec.create_property_dialog();
+ break;
+
case ft_Demux: sDemux.create_property_dialog(); break;
case ft_DSnd_Mp2a: sDSound.create_property_dialog(); break;
- case ft_DSnd_AC3: sDSoundAc3.create_property_dialog(); break;
+
+ case ft_DSnd_EAC3:
+ if (!sEac3Codec.isNull()) {
+ sDSoundEac3.create_property_dialog();
+ break;
+ }
+ // si le filtre EAC3 n'est pas défini, on utilise le filtre AC3
+ // ... (passage à travers)
+ case ft_DSnd_AC3:
+ sDSoundAc3.create_property_dialog();
+ break;
+
case ft_Renderer:
if (pVMR)
pVMR->create_property_dialog();
@@ -1889,9 +1940,11 @@
case ft_Video_H264: return sH264Codec.check_property_dialog();
case ft_Audio_Mp2a: return sMp2aCodec.check_property_dialog();
case ft_Audio_Ac3: return sAc3_Codec.check_property_dialog();
+ case ft_Audio_Eac3: return sEac3Codec.check_property_dialog();
case ft_Demux: return sDemux.check_property_dialog();
case ft_DSnd_Mp2a: return sDSound.check_property_dialog();
- case ft_DSnd_AC3: return sDSoundAc3.check_property_dialog();
+ case ft_DSnd_AC3: return sDSoundAc3.check_property_dialog(); // inutilisé
+ case ft_DSnd_EAC3: return sDSoundEac3.check_property_dialog(); // inutilisé
case ft_Renderer:
if (pVMR)
return pVMR->check_property_dialog();
Modifié: trunk/graph.h
===================================================================
--- trunk/graph.h 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/graph.h 2009-08-08 15:14:15 UTC (rev 200)
@@ -65,6 +65,9 @@
// ====================================================================================
+extern CLSID MEDIASUBTYPE_DOLBY_DDPLUS;
+
+// ====================================================================================
// Identifiants de types de filtres pour accès aux propriétés
enum FilterType
{
@@ -72,9 +75,11 @@
ft_Video_H264, //!< Vidéo H264
ft_Audio_Mp2a, //!< Audio MPEG2
ft_Audio_Ac3, //!< Audio AC3
+ ft_Audio_Eac3, //!< Audio EAC3
ft_Demux, //!< Démultiplexeur
ft_DSnd_Mp2a, //!< Sortie DirectSound pour MPEG2
ft_DSnd_AC3, //!< Sortie DirectSound pour AC3
+ ft_DSnd_EAC3, //!< Sortie DirectSound pour EAC3
ft_Renderer //!< Rendu vidéo
};
@@ -190,7 +195,7 @@
* \param[in] pid PID de la piste à brancher
* \param[in] type Type de la piste audio
**/
- virtual HRESULT branche_son(UINT16 pid, TrackStreamType type) = 0;
+ virtual HRESULT branche_son(UINT16 pid, TrackStreamType type) = 0;
/**
* Débranchement de toutes les pistes sonores
Modifié: trunk/ini.cpp
===================================================================
--- trunk/ini.cpp 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/ini.cpp 2009-08-08 15:14:15 UTC (rev 200)
@@ -96,6 +96,8 @@
{IDM_PAUSE_GRAPH, TEXT("Mettre le graphe en pause"), TEXT("Debug GraphePause"), {false, true, true, TEXT('R')}},
{IDM_STOP_GRAPH, TEXT("Arrêter le graphe"), TEXT("Debug GrapheArrêt"), {true, true, false, TEXT('R')}},
{IDM_GRAPH_STATE, TEXT("Voir l'état du graphe"), TEXT("Debug ÉtatGraphe"), {false, false, false, TEXT('R')}},
+ {IDM_BRANCHE, TEXT("Brancher les sorties"), TEXT("Debug Connect"), {false, true, false, TEXT('B')}},
+ {IDM_DEBRANCHE, TEXT("Débrancher les sorties"), TEXT("Debug Disconnect"), {true, true, false, TEXT('B')}},
#endif
{IDM_APP_RESTART, TEXT("Redémarrer le graphe"), TEXT("Graphe Relance"), {false, true, false, TEXT('Q')}},
{IDM_ABOUT, TEXT("Afficher la fenêtre des crédits"), NULL, {false, true, false, VK_F1}},
@@ -143,6 +145,7 @@
TCHAR filtreH264[256];
TCHAR filtreAudio[256];
TCHAR filtreAc3[256];
+TCHAR filtreEac3[256];
TCHAR nomVille[256];
TCHAR liste_canaux[256];
@@ -445,6 +448,7 @@
{TEXT("Filtre H264"), cit_DRV, NULL, CONFIG_STR(filtreH264)},
{TEXT("Filtre audio"), cit_DRV, NULL, CONFIG_STR(filtreAudio)},
{TEXT("Filtre AC3"), cit_DRV, NULL, CONFIG_STR(filtreAc3)},
+ {TEXT("Filtre EAC3"), cit_DRV, NULL, CONFIG_STR(filtreEac3)},
{TEXT("Recherche stricte"), cit_BOOL, true, & exact_match},
{TEXT("Graphe alternatif"), cit_BOOL, false, & autre_graphe},
@@ -899,7 +903,7 @@
* Sélection d'une nouvelle section
**/
CIniFile & NewSection(LPCTSTR pszSectionName) {
- _tcscpy(szSectionName, pszSectionName);
+ strcpy_T(szSectionName, pszSectionName);
return *this;
}
Modifié: trunk/ini.h
===================================================================
--- trunk/ini.h 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/ini.h 2009-08-08 15:14:15 UTC (rev 200)
@@ -149,6 +149,7 @@
extern TCHAR filtreH264[256]; //!< Nom du codec H264, utilisé pour la HD
extern TCHAR filtreAudio[256]; //!< Nom du codec Audio MPEG2 choisi
extern TCHAR filtreAc3[256]; //!< Nom du codec AC3 choisi
+extern TCHAR filtreEac3[256]; //!< Nom du codec EAC3 choisi
extern TCHAR nomVille[256]; //!< Nom de la ville de l'utilisateur
extern TCHAR liste_canaux[256]; //!< Liste de canaux à spécifier manuellement
Modifié: trunk/main.cpp
===================================================================
--- trunk/main.cpp 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/main.cpp 2009-08-08 15:14:15 UTC (rev 200)
@@ -658,16 +658,18 @@
static void update_filtres_menus(HMENU hMenu)
{
// Ajustement des menus
- set_menu_enable_state(hMenu, IDM_MPEG2, check_property_dialog(ft_Video_Mp2v));
+ set_menu_enable_state(hMenu, IDM_MP2V, check_property_dialog(ft_Video_Mp2v));
set_menu_enable_state(hMenu, IDM_H264, check_property_dialog(ft_Video_H264));
- set_menu_enable_state(hMenu, IDM_AUDIO, check_property_dialog(ft_Audio_Mp2a));
+ set_menu_enable_state(hMenu, IDM_MP2A, check_property_dialog(ft_Audio_Mp2a));
set_menu_enable_state(hMenu, IDM_AC3, check_property_dialog(ft_Audio_Ac3));
+ set_menu_enable_state(hMenu, IDM_EAC3, check_property_dialog(ft_Audio_Eac3));
bool bHaveVmr = vmr_mode!=vmt_null;
+ // Note : toutes les instances de rendu audio étant identiques, on se contente de n'en tester qu'une seule
+
set_menu_enable_state(hMenu, IDM_VMR, bHaveVmr && check_property_dialog(ft_Renderer));
set_menu_enable_state(hMenu, IDM_DSOUND, check_property_dialog(ft_DSnd_Mp2a));
- set_menu_enable_state(hMenu, IDM_DSOUNDAC3, check_property_dialog(ft_DSnd_AC3));
set_menu_enable_state(hMenu, IDM_DEMUX, check_property_dialog(ft_Demux));
set_menu_enable_state(hMenu, IDM_ZOOM, bHaveVmr);
@@ -1585,6 +1587,14 @@
}
}
+/// Retourner le type du son courant
+static TrackStreamType current_sound_type()
+{
+ if (ixChaine_ok(ixChaineCourante))
+ return Canaux[ixChaineCourante].sons.tbl[ixSonCourant].type;
+ return tst_MPEG2; // par défaut
+}
+
static void do_command(WORD wID, LPARAM lParam)
{
int ixRecDescr;
@@ -1639,15 +1649,22 @@
open_record_dialog();
break;
- case IDM_MPEG2: create_property_dialog(ft_Video_Mp2v); break;
+ case IDM_MP2V: create_property_dialog(ft_Video_Mp2v); break;
case IDM_H264: create_property_dialog(ft_Video_H264); break;
- case IDM_AUDIO: create_property_dialog(ft_Audio_Mp2a); break;
+ case IDM_MP2A: create_property_dialog(ft_Audio_Mp2a); break;
case IDM_AC3: create_property_dialog(ft_Audio_Ac3); break;
- case IDM_VMR: create_property_dialog(ft_Renderer); break;
- case IDM_DSOUND: create_property_dialog(ft_DSnd_Mp2a); break;
- case IDM_DSOUNDAC3: create_property_dialog(ft_DSnd_AC3); break;
+ case IDM_EAC3: create_property_dialog(ft_Audio_Eac3); break;
+ case IDM_VMR: create_property_dialog(ft_Renderer); break;
case IDM_DEMUX: create_property_dialog(ft_Demux); break;
+ case IDM_DSOUND:
+ switch(current_sound_type()) {
+ case tst_MPEG2: create_property_dialog(ft_DSnd_Mp2a); break;
+ case tst_AC3: create_property_dialog(ft_DSnd_AC3); break;
+ case tst_EAC3: create_property_dialog(ft_DSnd_EAC3);
+ }
+ break;
+
case IDM_ZOOM:
change_zoom(true);
break;
@@ -1870,6 +1887,8 @@
case IDM_RUN_GRAPH:
if (pGraph) {
+ if (pOSD)
+ pOSD->DisplayBotRightMsg(TEXT("Démarrage graphe"));
myprintf(TEXT("Mise en marche du graphe\n"));
pGraph->graph_Run();
}
@@ -1877,6 +1896,8 @@
case IDM_PAUSE_GRAPH:
if (pGraph) {
+ if (pOSD)
+ pOSD->DisplayBotRightMsg(TEXT("Pause graphe"));
myprintf(TEXT("Mise en pause du graphe\n"));
pGraph->graph_Pause();
}
@@ -1884,11 +1905,28 @@
case IDM_STOP_GRAPH:
if (pGraph) {
+ if (pOSD)
+ pOSD->DisplayBotRightMsg(TEXT("Arrêt graphe"));
myprintf(TEXT("Arrêt du graphe\n"));
pGraph->graph_Stop();
}
break;
+ case IDM_BRANCHE:
+ if (pGraph) {
+ if (pOSD)
+ pOSD->DisplayBotRightMsg(TEXT("Branchement"));
+ rebranche(false);
+ }
+ break;
+
+ case IDM_DEBRANCHE:
+ if (pGraph) {
+ if (pOSD)
+ pOSD->DisplayBotRightMsg(TEXT("Débranchement"));
+ debranche();
+ }
+ break;
#endif // #ifdef _DEBUG
case IDM_APP_RESTART:
@@ -3046,23 +3084,25 @@
startConsoleWin(true);
#endif // #if USE_CONSOLE==1
// Affiche divers renseignements pour le debogguage
- myprintf(TEXT("Compilé le : ") TEXT(__DATE__) TEXT(" ") TEXT(__TIME__) TEXT("\n"));
- myprintf(TEXT("Version : %s\n") , szAppVersion);
+ myprintf(TEXT("Compilé le : ") TEXT(__DATE__) TEXT(" ") TEXT(__TIME__) TEXT("\n"));
+ myprintf(TEXT("Version : %s\n") , szAppVersion);
myprintf(
- TEXT("Tuner : %s\n")
- TEXT("Récepteur : %s\n")
- TEXT("Codec MPEG2 : %s\n")
- TEXT("Codec H264 : %s\n")
- TEXT("Codec Audio : %s\n")
- TEXT("Codec AC3 : %s\n")
- TEXT("Ville : %s\n"),
+ TEXT("Tuner : %s\n")
+ TEXT("Récepteur : %s\n")
+ TEXT("Codec Vidéo MPEG2 : %s\n")
+ TEXT("Codec Vidéo H264 : %s\n")
+ TEXT("Codec Audio MPEG2 : %s\n")
+ TEXT("Codec Audio AC3 : %s\n")
+ TEXT("Codec Audio EAC3 : %s\n")
+ TEXT("Ville : %s\n"),
nom_tuner,
nom_receiver,
filtreMPEG2,
filtreH264,
filtreAudio,
filtreAc3,
+ filtreEac3,
nomVille);
myprintf(TEXT("Ligne de commande : [%s]\n"), GetCommandLine());
#endif // #if USE_CONSOLE
Modifié: trunk/make_lzma.cmd
===================================================================
--- trunk/make_lzma.cmd 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/make_lzma.cmd 2009-08-08 15:14:15 UTC (rev 200)
@@ -57,9 +57,12 @@
rem Version export‚e, tout est d‚j… OK
echo nS | tools\GeneRealVersion.exe version_$temp$.h version "SET SVN_VERSION=" > set_version_$temp$.cmd
)
+
call set_version_$temp$.cmd
del set_version_$temp$.cmd
echo ### G‚n‚ration de la mise … jour LZMA : %1.%SVN_VERSION%.lzma
tools\lzmac e %1\%2.exe %1\%2.%SVN_VERSION%.lzma
tools\lzmac e changelog.html %1\changelog.lzma
+
+if exist version_$temp$.h del version_$temp$.h
Modifié: trunk/rendering.h
===================================================================
--- trunk/rendering.h 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/rendering.h 2009-08-08 15:14:15 UTC (rev 200)
@@ -462,6 +462,10 @@
cBotRight.SetText(true,
bMuted ? TEXT("Sourdine") : TEXT(" "));} // si false, un espace pour effacer
+ /// Affichage d'un message quelconque (dans le coin inférieur droit)
+ void DisplayBotRightMsg(LPCTSTR pszMsg) {
+ cBotRight.SetText(true, pszMsg);}
+
/// Effacement de tous les objets OSD affichés
void Clear();
@@ -530,4 +534,4 @@
extern CVideoRenderer * pVMR;
/// Pointeur sur l'instance de l'OSD créée par lors de l'exécution du programme
-extern COsdAllObjects * pOSD;
+extern COsdAllObjects * pOSD;
Modifié: trunk/res.rc
===================================================================
--- trunk/res.rc 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/res.rc 2009-08-08 15:14:15 UTC (rev 200)
@@ -72,16 +72,16 @@
END
POPUP "Fi<res"
BEGIN
- MENUITEM "Codec &MPEG2…", IDM_MPEG2
- MENUITEM "C&odec H264…", IDM_H264
- MENUITEM "Codec a&udio…", IDM_AUDIO
- MENUITEM "Codec &AC3…", IDM_AC3
+ MENUITEM "Codec vidéo &MPEG2…", IDM_MP2V
+ MENUITEM "C&odec vidéo H264…", IDM_H264
+ MENUITEM "Codec a&udio MPEG2…", IDM_MP2A
+ MENUITEM "Codec audio &AC3…", IDM_AC3
+ MENUITEM "Codec audio EAC3…", IDM_EAC3
MENUITEM SEPARATOR
MENUITEM "&Rendu vidéo…", IDM_VMR
- MENUITEM "&Audio MPEG2…", IDM_DSOUND
- MENUITEM "Audio A&C3…", IDM_DSOUNDAC3
+ MENUITEM "Rendu &audio…", IDM_DSOUND
MENUITEM SEPARATOR
- MENUITEM "D&emux…", IDM_DEMUX
+ MENUITEM "D&émultiplexeur…", IDM_DEMUX
END
POPUP "C&ommandes"
BEGIN
@@ -145,23 +145,25 @@
CAPTION "Configuration"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- GROUPBOX "Équipement de réception TV",IDC_STATIC,7,3,276,70
- LTEXT "Tuner TNT",IDC_STATIC,14,17,55,12,SS_CENTERIMAGE
- COMBOBOX IDC_COMBO_TUNER,76,17,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "Récepteur TNT",IDC_STATIC,16,35,55,12,SS_CENTERIMAGE
- COMBOBOX IDC_COMBO_RECEIVER,76,35,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Équipement de réception TV",IDC_STATIC,7,3,276,68
+ LTEXT "Tuner TNT",IDC_STATIC,14,15,55,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO_TUNER,76,15,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Récepteur TNT",IDC_STATIC,16,33,55,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO_RECEIVER,76,33,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Mode alternatif (pour les tuners qui ne fonctionnent qu'avec les versions précédentes du programme)",IDC_ALT_GRAPH,
- "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,16,52,258,16
- GROUPBOX "Codecs vidéo",IDC_STATIC,7,78,276,48
- LTEXT "Codec MPEG2",IDC_STATIC,14,89,55,12,SS_CENTERIMAGE
- COMBOBOX IDC_COMBO_MPEG2,76,89,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "Codec H264",IDC_STATIC,14,107,55,12,SS_CENTERIMAGE
- COMBOBOX IDC_COMBO_H264,76,107,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- GROUPBOX "Codecs audio",IDC_STATIC,7,131,276,47
- LTEXT "Codec MPEG2",IDC_STATIC,14,141,55,12,SS_CENTERIMAGE
- COMBOBOX IDC_COMBO_AUDIO,76,141,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
- LTEXT "Codec AC3",IDC_STATIC,14,159,55,12,SS_CENTERIMAGE
- COMBOBOX IDC_COMBO_AC3,76,159,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,16,50,258,16
+ GROUPBOX "Codecs vidéo",IDC_STATIC,7,75,276,46
+ LTEXT "Codec MPEG2",IDC_STATIC,14,87,55,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO_MPEG2,76,85,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Codec H264",IDC_STATIC,14,105,55,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO_H264,76,103,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Codecs audio",IDC_STATIC,7,125,276,63
+ LTEXT "Codec MPEG2",IDC_STATIC,14,135,55,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO_AUDIO,76,135,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Codec AC3",IDC_STATIC,14,152,55,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO_AC3,76,152,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Codec EAC3",IDC_STATIC,14,170,55,12,SS_CENTERIMAGE
+ COMBOBOX IDC_COMBO_EAC3,76,170,200,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,88,193,54,14,WS_GROUP
PUSHBUTTON "Annuler",IDCANCEL,148,193,54,14
END
Modifié: trunk/resource.h
===================================================================
--- trunk/resource.h 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/resource.h 2009-08-08 15:14:15 UTC (rev 200)
@@ -34,6 +34,7 @@
#define IDC_COMBO_H264 1004
#define IDC_COMBO_AUDIO 1005
#define IDC_COMBO_AC3 1006
+#define IDC_COMBO_EAC3 1007
#define IDC_ALT_GRAPH 1008
#define IDC_SIGNAL_PRESENT 1010
#define IDC_SIGNAL_LOCK 1011
@@ -173,14 +174,14 @@
#define IDM_QUIT 40000
#define IDM_ABOUT 40001
#define IDM_CONFIG 40002
-#define IDM_MPEG2 40003
+#define IDM_MP2V 40003
#define IDM_H264 40004
-#define IDM_AUDIO 40005
-#define IDM_VMR 40006
-#define IDM_DSOUND 40007
-#define IDM_DEMUX 40008
-#define IDM_AC3 40009
-#define IDM_DSOUNDAC3 40010
+#define IDM_MP2A 40005
+#define IDM_AC3 40006
+#define IDM_EAC3 40007
+#define IDM_VMR 40008
+#define IDM_DSOUND 40009
+#define IDM_DEMUX 40010
#define IDM_SCREENSHOT 40014
#define IDM_FULLSCREEN 40015
#define IDM_AC3_AUDIO 40016
@@ -239,17 +240,19 @@
#define IDM_CHAN_RESTORNOM 40083
#define IDM_APP_RESTART 40084
-#define IDM_GRAPH_STATE 40086 // debug
-#define IDM_RUN_GRAPH 40087 // debug
-#define IDM_PAUSE_GRAPH 40088 // debug
-#define IDM_STOP_GRAPH 40089 // debug
+#define IDM_GRAPH_STATE 40090 // debug
+#define IDM_RUN_GRAPH 40091 // debug
+#define IDM_PAUSE_GRAPH 40092 // debug
+#define IDM_STOP_GRAPH 40093 // debug
+#define IDM_BRANCHE 40094 // debug
+#define IDM_DEBRANCHE 40095 // debug
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 137
-#define _APS_NEXT_COMMAND_VALUE 40090
+#define _APS_NEXT_COMMAND_VALUE 40096
#define _APS_NEXT_CONTROL_VALUE 1190
#define _APS_NEXT_SYMED_VALUE 121
#endif
Modifié: trunk/settings.cpp
===================================================================
--- trunk/settings.cpp 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/settings.cpp 2009-08-08 15:14:15 UTC (rev 200)
@@ -1424,10 +1424,10 @@
changed |= extrait_combo(GetDlgItem(hDlg, IDC_COMBO_H264), filtreH264, _countof(filtreH264), true);
changed |= extrait_combo(GetDlgItem(hDlg, IDC_COMBO_AUDIO), filtreAudio, _countof(filtreAudio), true);
changed |= extrait_combo(GetDlgItem(hDlg, IDC_COMBO_AC3), filtreAc3, _countof(filtreAc3), true);
+ changed |= extrait_combo(GetDlgItem(hDlg, IDC_COMBO_EAC3), filtreEac3, _countof(filtreEac3), true);
- // Récapitulatif des valeurs dans la fenêtre (pour debug uniquement)
- myprintf(TEXT("Tuner: %s\nReceiver: %s\nVideo: %s\nAudio: %s\nAc3: %s\n"),
- nom_tuner, nom_receiver, filtreMPEG2, filtreAudio, filtreAc3);
+ myprintf(TEXT("Tuner: %s\nReceiver: %s\nVideo: %s\nAudio: %s\nAc3: %s\nEac3: %s\n"),
+ nom_tuner, nom_receiver, filtreMPEG2, filtreAudio, filtreAc3, filtreEac3);
if (changed && _tcsstr(filtreMPEG2, TEXT("ffdshow")) && _tcsstr(filtreH264, TEXT("ffdshow"))) {
MessageBoxCheck(hDlg,
@@ -1471,7 +1471,7 @@
HWND hH264 = GetDlgItem(hDlg, IDC_COMBO_H264);
HWND hAudio = GetDlgItem(hDlg, IDC_COMBO_AUDIO);
HWND hAc3 = GetDlgItem(hDlg, IDC_COMBO_AC3);
-
+ HWND hEac3 = GetDlgItem(hDlg, IDC_COMBO_EAC3);
set_check(hDlg, IDC_ALT_GRAPH, autre_graphe);
// Liste des filtres définis dans la configuration mais qui ne sont plus disponibles
@@ -1489,6 +1489,8 @@
strListeAbsents += tstr_printf(TEXT("\n- %s"), filtreAudio);
if (!remplit_combo_filtre(hAc3, MEDIATYPE_Audio, MEDIASUBTYPE_DOLBY_AC3, filtreAc3))
strListeAbsents += tstr_printf(TEXT("\n- %s"), filtreAc3);
+ if (!remplit_combo_filtre(hEac3, MEDIATYPE_Audio, MEDIASUBTYPE_DOLBY_DDPLUS, filtreEac3))
+ strListeAbsents += tstr_printf(TEXT("\n- %s"), filtreEac3);
// Cherche s'il n'y a qu'un élément dans la liste
// Le sélectionne si oui
Modifié: trunk/update.cpp
===================================================================
--- trunk/update.cpp 2009-08-06 17:55:25 UTC (rev 199)
+++ trunk/update.cpp 2009-08-08 15:14:15 UTC (rev 200)
@@ -584,7 +584,7 @@
}
/// Vérification de la version du noeud XML
-/// Retourne \true si le nœud est valide
+/// Retourne \p true si le nœud est valide
static bool CheckVersionVersion(const TiXmlElement & sTiXml)
{
// Récupère la version de la branche
@@ -639,8 +639,9 @@
/**
* Fonction traitant le fichier XML décrivant la mise à jour
*
- * \param[in] action action devant être effectuée si des versions plus récentes sont trouvées
- * (affichage de messages de status, téléchargements des nouveaus fichiers, etc.)
+ * \param[in] action action devant être effectuée si des versions plus récentes sont trouvées
+ * (affichage de messages de status, téléchargements des nouveaus fichiers, etc.)
+ * \param[in] bWithBeta \p true si les versions beta sont à récupérer
* \return Cumul de \p UPDATE_APP_FLAG (si une mise à jour d'application a été détectée ou réalisée)
ou \p UPDATE_ICON_FLAG (si une mise à jour d'icône(s) a été détectée ou réalisée)
**/
From pouchintv-dev at baysse.fr Fri Aug 14 00:39:55 2009
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: Thu, 13 Aug 2009 22:39:55 -0000
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r201 - in trunk: . Icones
Message-ID: <20090813223940.A895686AC1@mail.baysse.fr>
Author: gingko
Date: 2009-08-14 00:39:40 +0200 (ven 14 aoû 2009)
New Revision: 201
Added:
trunk/Icones/France3.bmp
Modified:
trunk/base.cpp
trunk/capture.cpp
trunk/changelog.html
trunk/channels.cpp
trunk/channels.h
trunk/console.cpp
trunk/console.h
trunk/epg.cpp
trunk/epgfilter.cpp
trunk/epgfilter.h
trunk/filters.cpp
trunk/grabber.cpp
trunk/grabber.h
trunk/graph.cpp
trunk/graph.h
trunk/ini.cpp
trunk/main.cpp
trunk/main.h
trunk/network.cpp
trunk/network.h
trunk/parse.cpp
trunk/pmtfilter.cpp
trunk/pmtfilter.h
trunk/record.cpp
trunk/recprog.cpp
trunk/recprog.h
trunk/rendering.cpp
trunk/rendering.h
trunk/res.rc
trunk/search.cpp
trunk/search.h
trunk/settings.cpp
trunk/trayicon.cpp
trunk/update.cpp
trunk/xml.cpp
Log:
Optimisation du démarrage, couleurs console, correction de bugs.
channels.cpp, channels.h, graph.h, graph.cpp, main.cpp :
* L'initialisation du rendu vidéo (ex-VMR) est faite en même temps que celle
de tout le graphe, et non plus après son démarrage, évitant ainsi un arrêt et un
redémarrage du graphe inutile et qui prend beaucoup de temps.
* Cette précédente disposition était choisie car on ne connaissait pas à l'avance
le type de flux vidéo utilisé au premier démarrage. Maintenant, on détermine celui-ci
d'après les états antérieurs de la chaîne qui va démarrer, et si par hasard ce n'est
pas le bon (cas sans doute assez rare), en retombe dans le cas précédent (arrêt et
redémarrage pour corriger).
* En conséquence, la fonction "build_graph" se voit assigner ce type de flux (à titre
de présomption) en tant que paramètre.
graph.h, graph.cpp :
* Correction d'un bug : les exportations du graphe (pour GraphEdit) n'était pas
libérées à la destructions de celui-ci (bug introduit à la révision 198),
empêchant la destruction complète du graphe lui-même et générant une fuite
mémoire, en particuliers lors des redémarrages internes du graphe.
* Mémorisation de l'état "démarré/arrêté" du graphe à l'aide d'une variable
"bool" (et d'une fonction membre d'interrogation), car les interrogations de
l'état réel de celui-ci précédemment utilisées étaient parfois très longues
à traiter (jusqu'à 1,5 seconde).
* Le membre de classe "pGraph" est renommé en "pFGrph", afin d'éviter des
conflits éventuels avec la variable globale "pGraph".
* La fonction "DShowErrorToString" est un peu améliorée.
main.h, main.cpp :
* Décodage plus complet de la version de Windows sous laquelle tourne le logiciel.
rendering.cpp :
* Utilisation d'une variable "bool" pour mémoriser l'état absent/présent du bitmap
OSD (en VMR9 et EVR) et éviter ainsi des appels de fonctions générant des erreurs.
console.h, console.cpp, base.cpp, et à peu près tous les fichiers qui contiennent
des messages de debugging "myprintf" :
* Horodatage systématique de tous les messages de la console de debugging.
* Suppression de la fonction "myprintferror" qui réalisait précédemment
un horodatage de certains messages d'erreur seulement.
* En mode debugging, la console permet de surligner certains textes en
couleurs grâce à des codes de contrôle du style des codes "ANSI"
utilisés dans MS-DOS.
* Définition de macros pour générer ces codes dans les chaînes de caractères,
de telle sorte qu'ils ne soient pas présents si on compile en mode
debugging sans console.
* Les codes de fins de ligne sont insérés dans les chaînes avec des macros
"EOL" (facilite la manipulation des textes sans toucher à ces codes).
* De nombreux messages "myprintf" se voient assigner des colorisations.
* Plusieurs messages "myprintf" sont adaptés aux nouvelles contraintes de largeur.
* Quelques messages sont ajoutés.
epgfilter.h, epgfilter.cpp, pmtfilter.h, pmtfilter.cpp, network.h, network.cpp :
* Corrections relativement mineures concernant les noms de filtres ainsi que
les destructeurs de classes.
res.rc :
* Rectification vraiment très mineure.
Ajout d'une icône "France3.bmp" en doublon de "France 3.bmp", car il apparaît que
certaines diffusions régionales de France 3 indiquent parfois erronément le nom
de la chaîne sans espace.
Ajouté: trunk/Icones/France3.bmp
===================================================================
(les fichiers binaires diffèrent)
Property changes on: trunk/Icones/France3.bmp
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Modifié: trunk/base.cpp
===================================================================
--- trunk/base.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/base.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -42,41 +42,7 @@
/// Dernier code d'erreur traité (pour éviter la multiplication des messages identiques)
static HRESULT lastRes = S_OK;
-#if USE_CONSOLE
/**
- * Enregistre le message d'erreur dans les logs (au cas où ils doivent être étudiés)
- * en rajoutant l'heure d'intervention
- *
- * \param[in] str Message d'erreur à afficher dans le log
- **/
-void myprintferror(LPCTSTR str) {
- // Création d'un tampon intermédiaire basé sur "_alloca"
- // Taille identique à la chaîne source, ce qui est suffisant car
- // la chaîne générée aura *au plus* cette longueur (si pas de fin de ligne dedans).
- LPTSTR pszBuffer = STK_ALLOC(TCHAR, strlen_T(str)+1);
-
- LPTSTR pszPtr = pszBuffer;
- SYSTEMTIME time;
- TCHAR ch;
-
- // Remplace les nouvelles lignes par " / ", ce qui évite d'avoir de nouvelles
- // lignes inutiles (car même erreur) dans le log généré
- while (ch = *str++) {
- if (ch != TCHAR('\r'))
- *pszPtr++ = ch==TCHAR('\n') ? TCHAR('/') : ch;
- }
- *pszPtr = 0;
-
- GetLocalTime(&time);
-
- myprintf(TEXT("Erreur# %02u:%02u:%02u %s\n"), time.wHour, time.wMinute, time.wSecond, pszBuffer);
-}
-#else // #if USE_CONSOLE
-/// Pas de console, donc, pas de log
-#define myprintferror(str)
-#endif
-
-/**
* Met en file d'attente le message d'erreur passé en paramètre pour un affichage ultérieur
*
* \param[in] str Le message à stocker, et pouvant être passé à un printf
@@ -91,14 +57,14 @@
// Utile simplement si on passe un message d'erreur personnalisé
if (str) {
// Buffer de stockage temporaire
- FMT_BUF(buffer, 200, str, hr);
+ FMT_BUF(buffer, 512, str, hr);
if (!strErrBuf.empty())
- strErrBuf += TEXT("\n");
+ strErrBuf += EOL;
strErrBuf += buffer;
// Enregistre le message d'erreur
- myprintferror(buffer);
+ myprintf(ERRX(TEXT("Erreur# %s")), buffer);
}
if (FAILED(hr) && hr!=lastRes) {
Modifié: trunk/capture.cpp
===================================================================
--- trunk/capture.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/capture.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -35,7 +35,7 @@
CCapture::CCapture(HANDLE hFil) :
hFile(hFil)
{
- myprintf(TEXT("## Construction CCapture, début d'enregistrement (0x%08x)\n"), hFile);
+ myprintf(TEXT("## Construction CCapture, début d'enregistrement (0x%08x)") EOL, hFile);
}
//UINT64 CCapture::pos_fichier(void)
@@ -65,7 +65,7 @@
CCapture::~CCapture()
{
- myprintf(TEXT("## Destruction CCapture, fin d'enregistrement (0x%08x)\n"), hFile);
+ myprintf(TEXT("## Destruction CCapture, fin d'enregistrement (0x%08x)") EOL, hFile);
CloseHandle(hFile);
}
@@ -292,15 +292,15 @@
// fichier :
if (uw_ph.p_pts) {
*uw_ph.p_pts = cGrabber.adjustTime(*uw_ph.p_pts);
- // myprintf(TEXT("PS pts = %10.6f (%S)\n"), UINT64(*uw_ph.p_pts)/27000000.0, nom_debug);
+ // myprintf(TEXT("PS pts = %10.6f (%S)") EOL, UINT64(*uw_ph.p_pts)/27000000.0, nom_debug);
}
if (uw_ph.p_dts) {
*uw_ph.p_dts = cGrabber.adjustTime(*uw_ph.p_dts);
- // myprintf(TEXT("PS dts = %10.6f (%S)\n"), UINT64(*uw_ph.p_dts)/27000000.0, nom_debug);
+ // myprintf(TEXT("PS dts = %10.6f (%S)") EOL, UINT64(*uw_ph.p_dts)/27000000.0, nom_debug);
}
if (uw_ph.p_escr) {
*uw_ph.p_escr = cGrabber.adjustTime(*uw_ph.p_escr);
- // myprintf(TEXT("PS escr = %10.6f (%S)\n"), UINT64(*uw_ph.p_escr)/27000000.0, nom_debug);
+ // myprintf(TEXT("PS escr = %10.6f (%S)") EOL, UINT64(*uw_ph.p_escr)/27000000.0, nom_debug);
}
setBufferIndex(dst_hdr.end_of_header());
@@ -382,12 +382,12 @@
// Vérification de la continuité :
if (diff_ccounter == 0) {
- myprintf(TEXT("paquet dupliqué dans %") A2t TEXT("\n"), nom_debug);
+ myprintf(TEXT("paquet dupliqué dans %") A2t EOL, nom_debug);
return; // ignorer
}
if (diff_ccounter != 1) {
- myprintf(TEXT("discontinuité dans %") A2t TEXT("\n"), nom_debug);
+ myprintf(TEXT("discontinuité dans %") A2t EOL, nom_debug);
// envoie le paquet (incomplet) qui était en cours de construction
flush();
@@ -486,7 +486,7 @@
// Estimation du temps moyen qui sépare deux paquests TS du même canal :
pcr_rate_helper.submit(diff_time/pck_pcr_count);
pcr_rate = pcr_rate_helper.mean();
- // myprintf(TEXT("pcr rate=%u (packet count=%u)\n"), pcr_rate, pck_pcr_count);
+ // myprintf(TEXT("pcr rate=%u (packet count=%u)") EOL, pcr_rate, pck_pcr_count);
pck_pcr_count = 0;
}
} else {
@@ -497,7 +497,7 @@
}
if (new_pcr > last_pcr)
last_pcr = new_pcr;
- //myprintf(TEXT("TS pcr = %10.6f (ajusté = %10.6f)\n"),
+ //myprintf(TEXT("TS pcr = %10.6f (ajusté = %10.6f)") EOL,
// new_pcr/27000000.0, (new_pcr-first_pcr)/27000000.0);
}
}
@@ -512,7 +512,7 @@
// Evaluations statistiques :
if (second != curr_pcr_second) {
- myprintf(TEXT("second=%u\n"), second);
+ myprintf(TEXT("second=%u") EOL, second);
// Section appelée à chaque nouvelle seconde du PCR
curr_pcr_second = second;
switch (capt_state) {
@@ -532,7 +532,7 @@
UINT32 mux_rate = mux_rate_helper.mean();
byte_mux_rate = max(MIN_PROGRAM_MUX_RATE, min(MAX_PROGRAM_MUX_RATE, mux_rate));
- myprintf(TEXT("mux rate=0x%05x, avg=0x%05x\n"), byte_count/50, byte_mux_rate/50);
+ myprintf(TEXT("mux rate=0x%05x, avg=0x%05x") EOL, byte_count/50, byte_mux_rate/50);
byte_count = 0;
}
}
Modifié: trunk/changelog.html
===================================================================
--- trunk/changelog.html 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/changelog.html 2009-08-13 22:39:40 UTC (rev 201)
@@ -56,6 +56,14 @@
Changements réalisés pour la version 0.5
+ - 0.5.201 (expérimentale, publiée dans le forum le 14 août 2009) :
+
+ - Optimisation du démarrage du graphe, qui devrait être un peu plus rapide.
+ - Correction d'une fuite mémoire introduite à la révision 198.
+ - Icône
France3
(sans espace) ajoutée en doublon de France 3
(avec espace).
+
+
+
- SVN rév. 200 :
- Utilisation d'un filtre EAC3 dédié, sélectionnable dans la configuration,
Modifié: trunk/channels.cpp
===================================================================
--- trunk/channels.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/channels.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -286,7 +286,7 @@
**/
HRESULT Chaine::branche(bool reset_son) const
{
- myprintf(TEXT("Chaine::branche SID=%i, TSID=%i, ONID=%i, freq=%i\n"), SID, TSID, ONID, khz);
+ myprintf(TEXT("Chaine::branche SID=%i, TSID=%i, ONID=%i, freq=%i") EOL, SID, TSID, ONID, khz);
if (reset_son) {
ixSonCourant = 0; // par défaut
@@ -356,6 +356,23 @@
}
/**
+ * Recherche d'une restauration de chaîne en partant d'une clé 32 bits
+ * (identique à \p trouve_par_cle, mais retourne la première chaîne de la liste
+ * si pas trouvé, et ne retourne -1 que si aucune chaîne n'existe)
+ * \param[in] cleChaine Clé 32 bits de la chaîne, générée par ChaineIDs::cle
+ * \retval Index de la chaîne dans la table #Canaux
+ * \retval -1 si aucune chaîne n'existe
+ **/
+int Chaines::trouve_restauration_par_cle(UINT32 cleChaine) const
+{
+ int nRes = trouve_par_cle(cleChaine);
+
+ if (nRes < 0 && !empty())
+ nRes = 0;
+ return nRes;
+}
+
+/**
* Recherche d'une chaîne avec son jeu d'identificateurs complet
* \param[in] sIds série d'indentifiants de la chaîne
* \retval Index de la chaîne dans la table #Canaux
@@ -435,25 +452,12 @@
}
/**
- * S'assurer que le Video Mixing Renderer a été initialisé
- **/
-bool do_init_vmr()
-{
- HRESULT hr = init_vmr();
-
- if (FAILED(hr)) {
- affiche_erreurs(TEXT("Erreur lors de la création du VMR"), hr);
- return false;
- }
-
- return true;
-}
-
-/**
* Déconnexion globale des sorties vidéo et audio
**/
void debranche()
{
+ myprintf(BOLD(TEXT("Débranchement des sorties audio et vidéo")) EOL);
+
if (pGraph)
pGraph->debranche_medias();
suspendu = true;
@@ -472,21 +476,16 @@
if (!bProt) {
bProt = true;
- // Note : l'initialisation du VMR est en principe ici déjà faite (ce qui fait
- // que cet appel sera sans doute sans effet), mais ceci réserve la possibilité
- // de retarder cet appel jusqu'au 1er branchement des flux .... le jour où
- // j'aurai trouvé pourquoi cela pose problème ! - Gingko
- if (do_init_vmr()) {
+ myprintf(BOLD(TEXT("Branchement des sorties audio et vidéo")) EOL);
- if (suspendu) {
- HRESULT hr = Canaux[ixChaineCourante].branche(reset_son);
+ if (suspendu) {
+ HRESULT hr = Canaux[ixChaineCourante].branche(reset_son);
- if (FAILED(hr))
- affiche_erreurs(TEXT("Erreur lors du rebranchement des sorties"), hr);
- suspendu = false;
- }
- bRes = true;
+ if (FAILED(hr))
+ affiche_erreurs(TEXT("Erreur lors du rebranchement des sorties"), hr);
+ suspendu = false;
}
+ bRes = true;
bProt = false;
}
@@ -555,7 +554,9 @@
if (ixChaine >= 0) {
const Chaine & nouveau_canal = Canaux[ixChaine];
- myprintf(TEXT("Zappe ix=%i, no=%i, SID=%i, TSID=%i, ONID=%i, freq=%i, nom=\"%") A2t TEXT("\"\n"),
+ myprintf(
+ TEXT("Zappe ix=%i, no=%i, SID=%i, TSID=%i, ONID=%i,") EOL
+ TEXT(" freq=%i, nom=\"") COLR(HGREEN, TEXT("%") A2t) TEXT("\"") EOL,
ixChaine, nouveau_canal.nNumeroChaine, nouveau_canal.SID, nouveau_canal.TSID,
nouveau_canal.ONID, nouveau_canal.khz, nouveau_canal.nom);
@@ -564,7 +565,7 @@
tstring strErr;
#endif
pGraph->change_frequence(nouveau_canal.khz IF_CONSOLE_CB(&strErr));
- myprintf(TEXT("%?Erreur(s) change_frequence : %s\n"), !strErr.empty(), strErr.c_str());
+ myprintf(TEXT("%?") ERRX(TEXT("Erreur(s) change_frequence : %s")), !strErr.empty(), strErr.c_str());
}
ixChaineCourante = ixChaine_ok(ixChaine) ? ixChaine : -1;
Modifié: trunk/channels.h
===================================================================
--- trunk/channels.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/channels.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -266,6 +266,16 @@
int trouve_par_cle(UINT32 cleChaine) const;
/**
+ * Recherche d'une restauration de chaîne en partant d'une clé 32 bits
+ * (identique à \p trouve_par_cle, mais retourne la première chaîne de la liste
+ * si pas trouvé, et ne retourne -1 que si aucune chaîne n'existe)
+ * \param[in] cleChaine Clé 32 bits de la chaîne, générée par ChaineIDs::cle
+ * \retval Index de la chaîne dans la table #Canaux
+ * \retval -1 si aucune chaîne n'existe
+ **/
+ int trouve_restauration_par_cle(UINT32 cleChaine) const;
+
+ /**
* Recherche d'une chaîne avec son jeu d'identificateurs complet
* \param[in] sIds série d'indentifiants de la chaîne
* \retval Index de la chaîne dans la table #Canaux
@@ -286,11 +296,6 @@
extern int ixSonCourant; //!< Index de la piste sonore couramment utilisée
/**
- * S'assurer que le Video Mixing Renderer a été initialisé
- **/
-bool do_init_vmr();
-
-/**
* Changement de chaîne, sélection par index dans la table.
* \param[in] ixChaine Index dans la table #Canaux.
* (mettre -1 pour désactiver la sélection de chaîne)
Modifié: trunk/console.cpp
===================================================================
--- trunk/console.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/console.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -39,17 +39,241 @@
#include
#if USE_CONSOLE==1
+
HWND hConsoleWnd = NULL;
-HANDLE hStdOut = NULL;
WindowPos consolePos;
-void startConsoleWin(bool alloc)
+static struct AnsiConsole
{
+ HANDLE hStdOut;
+ HANDLE hConsMutex;
+ FILE * f;
+ errno_t nFileRes;
+
+ AnsiConsole() :
+ hStdOut(NULL),
+ hConsMutex(NULL),
+ f(NULL),
+ nFileRes(0)
+ {}
+
+ /// Sortie brute d'un message vers la console
+ void RawOutput(LPCTSTR pszMsg);
+
+ /**
+ * Affichage d'un message positionné après sauvegarde de l'état de la console,
+ * puis restauration de l'état antérieur.
+ * \param[in] X Position horizontale du message. Non modifié si < 0.
+ * \param[in] Y Position verticale du message. Non modifié si < 0.
+ * \param[in,out] pszMsg Message à afficher.
+ * \note Des caractères à l'intérieur du message peuvent être modifiés par la fonction.
+ **/
+ void PosAnsiOutput(int X, int Y, LPTSTR pszMsg);
+
+ /**
+ * Sortie d'un message formaté ANSI vers la console
+ * Les codes ANSI sont, au passage, éliminés de la chaîne de caractères
+ * Pour les codes ANSI, voir http://en.wikipedia.org/wiki/ANSI_escape_code
+ * Seules les couleurs et l'intensité sont couramment prises en charge
+ * \param[in,out] pszMsg Message à afficher.
+ * \note Des caractères à l'intérieur du message peuvent être modifiés par la fonction.
+ **/
+ void AnsiOutput(LPTSTR pszMsg);
+
+ /// Ouverture du fichier journal
+ void OpenLog();
+
+ /// Fermeture du fichier journal
+ void CloseLog();
+
+ void Init(bool alloc);
+
+ ~AnsiConsole() {
+ if (hConsMutex)
+ CloseHandle(hConsMutex);
+ }
+} cConsole;
+
+/// Sortie d'un message vers la console
+void AnsiConsole::RawOutput(LPCTSTR pszMsg)
+{
+ UINT nLen = strlen_T(pszMsg);
+
+ if (nLen > 0) {
+#ifdef _UNICODE
+ LPCTSTR pszOut = pszMsg;
+#else
+ LPTSTR pszOut = STK_ALLOC(TCHAR, nLen+1);
+
+ CharToOem(pszMsg, pszOut);
+#endif
+ DWORD cCharsWritten;
+
+ WriteConsole(hStdOut, pszOut, nLen, &cCharsWritten, NULL);
+
+ // Écriture dans le fichier journal
+ if (f && nFileRes==0)
+ _fputts(pszMsg, f);
+ }
+}
+
+/**
+ * Affichage d'un message positionné après sauvegarde de l'état de la console,
+ * puis restauration de l'état antérieur.
+ * \param[in] X Position horizontale du message. Non modifié si < 0.
+ * \param[in] Y Décalage vertical (négatif) du message. Non modifié si < 0.
+ * \param[in,out] pszMsg Message à afficher.
+ * \note Des caractères à l'intérieur du message peuvent être modifiés par la fonction.
+ **/
+void AnsiConsole::PosAnsiOutput(int X, int Y, LPTSTR pszMsg)
+{
+ CONSOLE_SCREEN_BUFFER_INFO sCsbi;
+
+ if (GetConsoleScreenBufferInfo(hStdOut, &sCsbi)) {
+ COORD dwCursorPosition = sCsbi.dwCursorPosition;
+
+ if (X >= 0)
+ dwCursorPosition.X = SHORT(X);
+ if (Y >= 0)
+ dwCursorPosition.Y = dwCursorPosition.Y - min(dwCursorPosition.Y, SHORT(Y));
+ SetConsoleCursorPosition(hStdOut, dwCursorPosition);
+ AnsiOutput(pszMsg);
+ SetConsoleCursorPosition(hStdOut, sCsbi.dwCursorPosition);
+ SetConsoleTextAttribute(hStdOut, sCsbi.wAttributes);
+ }
+}
+
+/**
+ * Sortie d'un message formaté ANSI vers la console
+ * Pour les codes ANSI, voir http://en.wikipedia.org/wiki/ANSI_escape_code
+ * Seules les couleurs et l'intensité sont couramment prises en charge
+ * \param[in,out] pszMsg Message à afficher.
+ * \note Des caractères à l'intérieur du message peuvent être modifiés par la fonction.
+ **/
+void AnsiConsole::AnsiOutput(LPTSTR pszMsg)
+{
+ if (hConsMutex) {
+ // Utilisation d'un mutex parce que les messages de ce type, quand on se met à les
+ // utiliser, peuvent être si fréquents qu'ils ont beaucoup de chance d'entrer en
+ // conflit avec des messages d'un autre thread.
+
+ // 1/2 seconde. Si ça dépasse, on y va quand même, on ne va
+ // tout de même pas bloquer l'application pour un message de debugging !
+ WaitForSingleObject(hConsMutex, 500);
+ }
+
+ struct AnsiDescr
+ {
+ UINT16 nCode;
+ BYTE nMask;
+ BYTE nVal;
+ };
+
+ #define FOREGROUND_MASK (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
+ #define BACKGROUND_MASK (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
+
+ static const AnsiDescr aAnsiTbl[] = {
+ { 0, 0xff, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE},
+ { 1, FOREGROUND_INTENSITY, FOREGROUND_INTENSITY},
+ {30, FOREGROUND_MASK, 0},
+ {31, FOREGROUND_MASK, FOREGROUND_RED},
+ {32, FOREGROUND_MASK, FOREGROUND_GREEN},
+ {33, FOREGROUND_MASK, FOREGROUND_RED|FOREGROUND_GREEN},
+ {34, FOREGROUND_MASK, FOREGROUND_BLUE},
+ {35, FOREGROUND_MASK, FOREGROUND_RED|FOREGROUND_BLUE},
+ {36, FOREGROUND_MASK, FOREGROUND_GREEN|FOREGROUND_BLUE},
+ {37, FOREGROUND_MASK, FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE},
+ {40, BACKGROUND_MASK, 0},
+ {41, BACKGROUND_MASK, BACKGROUND_RED},
+ {42, BACKGROUND_MASK, BACKGROUND_GREEN},
+ {43, BACKGROUND_MASK, BACKGROUND_RED|BACKGROUND_GREEN},
+ {44, BACKGROUND_MASK, BACKGROUND_BLUE},
+ {45, BACKGROUND_MASK, BACKGROUND_RED|BACKGROUND_BLUE},
+ {46, BACKGROUND_MASK, BACKGROUND_GREEN|BACKGROUND_BLUE},
+ {47, BACKGROUND_MASK, BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE}
+ };
+
+ LPTSTR pszPtr;
+ static BYTE nAttr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+
+ // Recherche d'une chaîne "ESC [", représentant un début de séquence ANSI
+ while ((pszPtr = _tcsstr(pszMsg, CSI))!=NULL) {
+ TCHAR szAnsiBuf[64];
+ int nSize;
+ TCHAR nCmd;
+
+ if (_stscanf_s(pszPtr, TEXT("\x1b%63[^@-Za-z]%c%n"), &szAnsiBuf, _countof(szAnsiBuf), &nCmd, sizeof(nCmd), &nSize)==2) {
+ // Sortie de la partie du message qui précède la séquence ANSI
+ if (pszPtr > pszMsg) {
+ *pszPtr = 0;
+ RawOutput(pszMsg);
+ *pszPtr = TCHAR('\x1b');
+ }
+
+ pszMsg = pszPtr+nSize;
+
+ LPTSTR pszSeq = szAnsiBuf+1; // Initialisation analyse des paramètres
+
+ switch (nCmd) {
+
+ case 'm': // CSI n [;k] m - SGR - Select Graphic Rendition
+ while (*pszSeq) {
+ UINT nAnsiCode = _tcstoul(pszSeq, &pszSeq, 10);
+
+ for (int nInx = 0; nInx<_countof(aAnsiTbl); ++nInx) {
+ AnsiDescr sAnsiDescr = aAnsiTbl[nInx];
+
+ if (sAnsiDescr.nCode == nAnsiCode) {
+ nAttr &= ~sAnsiDescr.nMask;
+ nAttr |= sAnsiDescr.nVal;
+ break;
+ }
+ }
+ if (*pszSeq != TCHAR(';'))
+ break;
+ ++pszSeq;
+ }
+ SetConsoleTextAttribute(hStdOut, nAttr);
+ }
+ } else
+ pszMsg = pszPtr+1;
+ }
+
+ RawOutput(pszMsg);
+
+ if (hConsMutex)
+ ReleaseMutex(hConsMutex);
+}
+
+/// Ouverture du fichier journal
+void AnsiConsole::OpenLog()
+{
+ // Variable statique, initialisation à la première exécution, seulement
+ static TempPathName sLogFileName("pouchin.log");
+
+ nFileRes = _tfopen_s(&f, sLogFileName, TEXT("a"));
+}
+
+/// Fermeture du fichier journal
+void AnsiConsole::CloseLog()
+{
+ if (nFileRes==0 && f)
+ fclose(f);
+}
+
+void AnsiConsole::Init(bool alloc)
+{
if (alloc) {
AllocConsole();
SetConsoleTitle(TEXT("Debug Window"));
}
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ hConsMutex = CreateMutex(NULL, FALSE, NULL);
+}
+
+void startConsoleWin(bool alloc)
+{
+ cConsole.Init(alloc);
if (consolePos.verifie()) {
hConsoleWnd = GetConsoleWindow();
MoveWindow(hConsoleWnd, consolePos.X, consolePos.Y, max(consolePos.L, 100), max(consolePos.H, 100), TRUE);
@@ -60,9 +284,7 @@
#if USE_CONSOLE
void myprintf(LPCTSTR fmt, ...)
{
- TCHAR s[512];
- va_list argptr;
- DWORD cnt;
+ va_list argptr;
va_start(argptr, fmt);
@@ -75,33 +297,66 @@
fmt += 2;
}
- cnt = _vstprintf_s(s, _countof(s), fmt, argptr);
+ TCHAR szFmtBuf[512];
+
+ _vstprintf_s(szFmtBuf, fmt, argptr);
va_end(argptr);
-#if USE_CONSOLE==-1
- OutputDebugString(s);
+ #if USE_CONSOLE==1
+ // Ouverture du fichier journal
+ cConsole.OpenLog();
//
// Les logiciels qui récupèrent les messages de debugging ont généralement
// leur propre système de capture, alors il est moins utile d'avoir
// une copie dans "pouchin.log".
-#else // #if USE_CONSOLE==-1
- // Initialisation à la première exécution, seulement
- static TempPathName sLogFileName("pouchin.log");
+ #endif
- FILE * f;
- errno_t nRes = _tfopen_s(&f, sLogFileName, TEXT("a"));
+ static bool bBegOfLine = true; //!< Si \p true, on est en début de ligne
+ bool bTimeSet = false;
- if (nRes==0) {
- _fputts(s, f);
- fclose(f);
- }
+ for (LPTSTR pszNl, pszStr = szFmtBuf; pszStr && *pszStr; pszStr = pszNl) {
+ // Repérage des retours chariot, en vue de reformater la ligne s'il y en a en milieu de ligne
+ TCHAR nCh = 0;
- DWORD cCharsWritten;
+ pszNl = _tcschr(pszStr, TCHAR('\n'));
+ if (pszNl) {
+ // Retour chariot trouvé : sauver le caractère suivant et le remplacer par un zéro
+ nCh = *(++pszNl);
+ *pszNl = 0;
+ }
-#ifndef _UNICODE
- CharToOem(s, s);
-#endif
- WriteConsole(hStdOut, s, cnt, &cCharsWritten, NULL);
-#endif // #if USE_CONSOLE==-1
+ TCHAR szOutBuf[256];
+
+ if (!bBegOfLine) {// Continuation d'un message précédent
+ strcpy_T(szOutBuf, pszStr);
+ } else {
+ if (!bTimeSet) { // Premier retour chariot
+ SYSTEMTIME time;
+
+ GetLocalTime(&time);
+ _stprintf_s(szOutBuf, COLR(LCYAN, TEXT("%02u:%02u:%02u.%03u>")) TEXT(" %s"),
+ time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, pszStr);
+ bTimeSet = true;
+ } else
+ _stprintf_s(szOutBuf, TEXT(" %s"), pszStr);
+ bBegOfLine = false;
+ }
+
+ if (pszNl) {
+ *pszNl = nCh; // Restaurer le caractère sauvegardé
+ bBegOfLine = true; // Mémoriser qu'on vient de passer à la ligne
+ }
+
+ #if USE_CONSOLE==-1
+ OutputDebugString(szOutBuf);
+ #else // #if USE_CONSOLE==-1
+ // Sortie console avec gestion des codes ANSI
+ cConsole.AnsiOutput(szOutBuf);
+ #endif // #if USE_CONSOLE==-1
+ }
+ #if USE_CONSOLE==1
+ // Fermeture du fichier journal
+ cConsole.CloseLog();
+ #endif
}
#endif // #if USE_CONSOLE
Modifié: trunk/console.h
===================================================================
--- trunk/console.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/console.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -49,11 +49,84 @@
#define myprintf(...)
#endif // #if USE_CONSOLE
+/// Caractère "fin de ligne"
+#define EOL TEXT("\n")
+
+#define HBLACK "30;1" // Gris foncé, en fait
+#define HRED "31;1"
+#define HGREEN "32;1"
+#define HYELLOW "33;1"
+#define HBLUE "34;1"
+#define HMAGENTA "35;1"
+#define HCYAN "36;1"
+#define HWHITE ";1" // Devrait être "37;1", mais le blanc étant "par défaut", la surbrillance suffit
+
+#define LBLACK ";30" // Noir sur fond noir ...
+#define LRED ";31"
+#define LGREEN ";32"
+#define LYELLOW ";33" // Plutôt brun/ocre
+#define LBLUE ";34"
+#define LMAGENTA ";35"
+#define LCYAN ";36"
+#define LWHITE "0" // Blanc normal (tout par défaut), =";37"
+
#if USE_CONSOLE==1
+
+/** \defgroup SeqAnsi Macros de synthèse de séquences ANSI
+ * Macros destinées à insérer des séquences ANSI dans les affichages \p myprintf
+ * @{ */
+
+#define CSI TEXT("\x1b[") //!< Début de séquence
+
+/** \brief "Select Graphic Rendition" (définit une couleur).
+ *
+ * \param[in] clr Couleur (suite de chiffres ANSI séparés par des ";".
+ **/
+ #define SGR(clr) CSI TEXT(clr) TEXT("m")
+
+/** \brief Macro à utiliser pour coloriser des parties de texte.
+ *
+ * \param[in] clr Couleur (suite de chiffres ANSI séparés par des ";".
+ * \param[in] msg Texte à coloriser
+ * \note Ne pas imbriquer les couleurs, ça ne marcherait pas.
+ **/
+#define COLR(clr, msg) SGR(clr) msg SGR(LWHITE) //!< Couleur
+
+/** \brief Macro à utiliser pour faire ressortir des mots ou des messages en surbrillance.
+ *
+ * \param[in] msg Texte à mettre en surbrillance
+ **/
+#define BOLD(msg) COLR(HWHITE, msg)
+
+/** \brief Message d'erreur surligné en magenta + EOL
+ *
+ * Macro à utiliser pour tout ce qui doit être considéré comme un message d'erreur.
+ * Ce texte apparaîtra en couleur "magenta" dans la console(le rouge était trop pénible à lire)
+ * Le code de fin de ligne est inclus dans la macro.
+ * \param[in] msg Texte du message d'erreur
+ **/
+#define ERRX(msg) COLR(HMAGENTA, msg) EOL
+
+/** @} */
+
/*
* Initialisation de la console de debugging.
* Le paramètre "alloc" doit être 'true' si on veut ouvrir une nouvelle console,
* ou bien 'false' si on veut s'attacher à la console existante.
*/
void startConsoleWin(bool alloc);
+
+#else
+/** \defgroup DummySeqAnsi Macros de substitution aux séquences ANSI
+ * Versions utilisées pour les messages d'erreur sans console
+ * @{ */
+
+#define CSI
+#define SGR(seq)
+#define COLR(clr, msg) msg
+#define BOLD(msg) msg
+#define ERRX(msg) msg EOL
+
+/** @} */
+
#endif
Modifié: trunk/epg.cpp
===================================================================
--- trunk/epg.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/epg.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -349,7 +349,7 @@
// Notification envoyée à la liste
if (p->hdr.code == NM_DBLCLK) {
// Double clic sur un élément de la liste
- myprintf(TEXT("double clic %i\n"), p->iItem);
+ myprintf(TEXT("double clic %i") EOL, p->iItem);
if (p->iItem >= 0) {
LVITEM item = {
Modifié: trunk/epgfilter.cpp
===================================================================
--- trunk/epgfilter.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/epgfilter.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -35,14 +35,14 @@
#include "epg.h"
CEPGFilter::CEPGFilter(IUnknown *pUnk, HRESULT *phr) :
- CBaseRenderer(__uuidof(this), WCHAR2TCHAR(szFilterName), pUnk, phr)
+ CBaseRenderer(__uuidof(this), TEXT(EPG_FILTER_NAME), pUnk, phr)
{
- myprintf(TEXT("%") W2t TEXT(" construit\n"), szFilterName);
+ myprintf(TEXT("%") W2t TEXT(" construit") EOL, szFilterName);
}
CEPGFilter::~CEPGFilter()
{
- myprintf(TEXT("%") W2t TEXT(" detruit\n"), szFilterName);
+ myprintf(TEXT("%") W2t TEXT(" detruit") EOL, szFilterName);
}
// Nettoyage des codes spéciaux (codes 0x80 à 0x9f) dans la chaîne,
@@ -193,7 +193,7 @@
const SI_EIT * peit;
size_t taille = pMediaSample->GetActualDataLength();
-// myprintf(TEXT("DoRenderSample %i %i\n"), taille, p[0]);
+// myprintf(TEXT("DoRenderSample %i %i") EOL, taille, p[0]);
pMediaSample->GetPointer((LPBYTE *)(&peit));
if (
Modifié: trunk/epgfilter.h
===================================================================
--- trunk/epgfilter.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/epgfilter.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -37,7 +37,7 @@
{
public:
CEPGFilter(IUnknown *pUnk, HRESULT *phr);
- ~CEPGFilter();
+ virtual ~CEPGFilter();
// Derived classes MUST override these
HRESULT DoRenderSample(IMediaSample *pMediaSample);
Modifié: trunk/filters.cpp
===================================================================
--- trunk/filters.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/filters.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -131,11 +131,11 @@
if (!pMap) // Filtre non défini : on ne branche rien et on retourne S_OK
return S_OK;
- myprintf(TEXT("Branche pid=%u sur broche %") A2t TEXT("\n"), pid, pszType);
+ myprintf(TEXT("Branche pid=") BOLD(TEXT("%u")) TEXT(" sur broche ") BOLD(TEXT("%") A2t) EOL, pid, pszType);
HRESULT hr = pMap->MapPID(1, &pid, eMsc);
- myprintf(TEXT("%?Échec branchement pid=%u sur broche %") A2t TEXT(", hr=0x%08x\n"), FAILED(hr), pid, pszType, hr);
+ myprintf(TEXT("%?") ERRX(TEXT("Échec branchement pid=%u sur broche %") A2t TEXT(", hr=0x%08x")), FAILED(hr), pid, pszType, hr);
return hr;
}
@@ -161,9 +161,9 @@
for (ULONG i=0; iUnmapPID(1, &pid))) {
- myprintf(TEXT("Échec UnmapPID(%u) (%") A2t TEXT("), hr=0x%08x\n"), pid, pszType, hr);
+ myprintf(ERRX(TEXT("Échec UnmapPID(%u) (%") A2t TEXT("), hr=0x%08x")), pid, pszType, hr);
break;
}
}
@@ -216,12 +216,12 @@
HRESULT cherche_pin(CComPtr & pFilter, PIN_DIRECTION dir,
CComPtr & result, const AM_MEDIA_TYPE * pmt)
{
- // myprintf(TEXT("** cherche_pin\n"));
+ // myprintf(TEXT("** cherche_pin") EOL);
CComPtr pEnumPins;
HRESULT hr = pFilter->EnumPins(&pEnumPins);
if (FAILED(hr)) {
- myprintf(TEXT("cherche_pin, 1, hr=0x%08x\n"), hr);
+ myprintf(TEXT("cherche_pin, 1, hr=0x%08x") EOL, hr);
return hr;
}
Modifié: trunk/grabber.cpp
===================================================================
--- trunk/grabber.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/grabber.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -53,9 +53,9 @@
taille_paquet_buf(0)
{
#if USE_SINGLE_GRABBER
- myprintf(TEXT("## Construction CSampleGrabber\n"));
+ myprintf(TEXT("## Construction CSampleGrabber") EOL);
#else
- myprintf(TEXT("## Construction CSampleGrabber, pCapture=0x%08x\n"), pCapture);
+ myprintf(TEXT("## Construction CSampleGrabber, pCapture=0x%08x") EOL, pCapture);
#endif
}
@@ -66,9 +66,9 @@
// (note : pSample->IsDiscontinuity ne semble pas donner d'informations significatives sur les
// tuners testés, mais qui sait d'autres tuners donneront peut-être des résultats meilleurs)
- myprintf(TEXT("%?SampleCB : Discontinuité\n"), pSample->IsDiscontinuity()==S_OK);
+ myprintf(TEXT("%?SampleCB : Discontinuité") EOL, pSample->IsDiscontinuity()==S_OK);
- // myprintf(TEXT("Echantillon SampleCB, t=%f, taille %u (%u paquets, frag=%u)\n"), SampleTime, l, l/TS_SIZE, l%TS_SIZE);
+ // myprintf(TEXT("Echantillon SampleCB, t=%f, taille %u (%u paquets, frag=%u)") EOL, SampleTime, l, l/TS_SIZE, l%TS_SIZE);
if (l>0) {
BYTE * p;
@@ -117,7 +117,7 @@
return;
}
- myprintf(TEXT("trouve index\n"));
+ myprintf(TEXT("trouve index") EOL);
i = (long)(res - pPtr);
}
@@ -173,7 +173,7 @@
DWORD CSampleGrabber::GrabThread()
{
- myprintf(TEXT("## Entrée dans CSampleGrabber::GrabThread\n"));
+ myprintf(TEXT("## Entrée dans CSampleGrabber::GrabThread") EOL);
const CMemFifoBlock * pBlock;
@@ -189,7 +189,7 @@
break;
}
- myprintf(TEXT("## Sortie de CSampleGrabber::GrabThread\n"));
+ myprintf(TEXT("## Sortie de CSampleGrabber::GrabThread") EOL);
return 0;
}
@@ -217,7 +217,7 @@
// Attendre une seconde
if (WaitForSingleObject(hThread, 1000)!=WAIT_OBJECT_0) {
- myprintf(TEXT("Le thread du grabber ne s'est pas terminé correctement\n"));
+ myprintf(TEXT("Le thread du grabber ne s'est pas terminé correctement") EOL);
return false;
}
hThread = NULL;
@@ -236,11 +236,11 @@
#endif // USE_THREAD_IN_GRABBER
#if USE_SINGLE_GRABBER
- myprintf(TEXT("## Destruction CSampleGrabber\n"));
+ myprintf(TEXT("## Destruction CSampleGrabber") EOL);
CloseHandle(hMutex);
hMutex = NULL;
#else
- myprintf(TEXT("## Destruction CSampleGrabber, pCapture=0x%08x\n"), pCapture);
+ myprintf(TEXT("## Destruction CSampleGrabber, pCapture=0x%08x") EOL, pCapture);
if (pCapture) {
delete pCapture;
pCapture = NULL;
Modifié: trunk/grabber.h
===================================================================
--- trunk/grabber.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/grabber.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -38,7 +38,6 @@
/// Classe implémentant les méthodes "callback" à associer à un "Sample grabber"
class CSampleGrabber : public CUnknown, public ISampleGrabberCB // The Filter Interface
{
-public:
//
// --- Implémentation des méthodes abstraites de l'interface ISampleGrabberCB --
//
@@ -49,7 +48,7 @@
* la classe de base est abstraite.
**/
STDMETHODIMP BufferCB(double SampleTime, BYTE *pBuffer,long BufferLen) {
- myprintf(TEXT("BufferCB\n"));
+ myprintf(ERRX(TEXT("Appel BufferCB inattendu")));
return S_OK;}
/**
@@ -102,11 +101,13 @@
/// Fonction d'exécution principale effective du 'thread'.
DWORD GrabThread();
+public:
/// Démarrage du "thread" de capture
bool StartThread();
/// Arrêt du "thread" de capture
bool StopThread();
+private:
#endif // USE_THREAD_IN_GRABBER
/**
Modifié: trunk/graph.cpp
===================================================================
--- trunk/graph.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/graph.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -47,6 +47,8 @@
#include "grabber.h"
#endif
+#include
+
// ====================================================================================
// GUIDs
// ====================================================================================
@@ -262,6 +264,12 @@
{
DWORD pdwRegister;
public:
+
+ /// Constructeur
+ CExportToRot() :
+ pdwRegister(0)
+ {}
+
HRESULT Add(IGraphBuilder * pGrph)
{
CComPtr pMoniker;
@@ -290,6 +298,13 @@
if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
pROT->Revoke(pdwRegister);
}
+
+ /// Destructeur
+ ~CExportToRot()
+ {
+ if (pdwRegister)
+ Remove();
+ }
};
#endif // #if EXPORT_GRAPH
@@ -300,9 +315,10 @@
class CPTvM_GraphBase : public virtual IPTvM_GraphBase
{
+ bool bRunning; //!< \p true si le graphe est en route
protected:
CComPtr
- pGraph; //!< Interface d'accès au graphe
+ pFGrph; //!< Interface d'accès au graphe
#if LOG_DSHOW
HANDLE logFile;
@@ -347,7 +363,7 @@
* \param[in] pszName Nom de ce filtre
**/
HRESULT AddFilterToGraph(IBaseFilter * pFilter, LPCWSTR pszName) {
- return pGraph->AddFilter(pFilter, pszName); }
+ return pFGrph->AddFilter(pFilter, pszName); }
#ifndef _UNICODE
/**
@@ -418,6 +434,15 @@
**/
virtual OAFilterState graph_GetState();
+ /**
+ * Vérifie si le graphe est en route
+ * \return \p true (en route), ou \p false (arrête)
+ * \note Se base sur une variable interne à la classe, alors que
+ \p graph_GetState interroge le graphe lui-même.
+ **/
+ virtual bool graph_isRunning() const {
+ return bRunning;}
+
/// Construction du graphe
virtual HRESULT Build();
@@ -430,9 +455,10 @@
};
/// Constructeur
-CPTvM_GraphBase::CPTvM_GraphBase()
+CPTvM_GraphBase::CPTvM_GraphBase() :
+ bRunning(false)
#if LOG_DSHOW
- : logFile(INVALID_HANDLE_VALUE)
+ , logFile(INVALID_HANDLE_VALUE)
#endif // #if LOG_DSHOW
{}
@@ -444,7 +470,7 @@
logFile = CreateFile(sLogFileName, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (logFile != INVALID_HANDLE_VALUE)
- return pGraph->SetLogFile((DWORD_PTR)logFile);
+ return pFGrph->SetLogFile((DWORD_PTR)logFile);
return E_FAIL;
}
#endif // #if LOG_DSHOW
@@ -452,7 +478,7 @@
#if EXPORT_GRAPH
HRESULT CPTvM_GraphBase::AddExport()
{
- HRESULT hr = cExport.Add(pGraph);
+ HRESULT hr = cExport.Add(pFGrph);
if (FAILED(hr))
return erreur(TEXT("Échec de l'exportation du graphe"), hr);
return S_OK;
@@ -467,7 +493,7 @@
**/
HRESULT CPTvM_GraphBase::AddEventNotifier(HWND hWnd, UINT uMsg)
{
- HRESULT hr = pGraph.QueryInterface(&pEvents);
+ HRESULT hr = pFGrph.QueryInterface(&pEvents);
if (SUCCEEDED(hr))
pEvents->SetNotifyWindow((OAHWND)hWnd, uMsg, 0);
@@ -517,7 +543,7 @@
HRESULT hr = CSearchByType_Get(sDData.pAmt->majortype, sDData.pAmt->subtype, exact_match, sDData.pszName, sDData.pFilter).Do();
if (SUCCEEDED(hr)) {
- myprintf(TEXT("Ajout codec %") A2t TEXT("\n"), sDData.pszType);
+ myprintf(TEXT("Ajout codec %") A2t EOL, sDData.pszType);
hr = AddFilterToGraph(sDData.pFilter, sDData.pszName);
if (FAILED(hr))
@@ -533,7 +559,7 @@
HRESULT hr = cherche_pin(pFilter, PINDIR_INPUT, pInPin, NOTCONNECTED);
if (SUCCEEDED(hr)) {
- hr = pGraph->ConnectDirect(pOutPin, pInPin, NULL);
+ hr = pFGrph->ConnectDirect(pOutPin, pInPin, NULL);
}
return hr;
}
@@ -570,9 +596,9 @@
return hr;
if (FAILED(hr = pInPin->ConnectedTo(&pOutPin)))
return hr;
- if (FAILED(hr = pGraph->Disconnect(pOutPin)))
+ if (FAILED(hr = pFGrph->Disconnect(pOutPin)))
return hr;
- return pGraph->Disconnect(pInPin);
+ return pFGrph->Disconnect(pInPin);
}
#ifdef _DEBUG
@@ -582,7 +608,7 @@
CComPtr pEnumfilters;
tstring strState;
- pGraph->EnumFilters(&pEnumfilters);
+ pFGrph->EnumFilters(&pEnumfilters);
for (ENUM_ITF(pEnumfilters, IBaseFilter, pFilter)) {
HRESULT hr;
@@ -600,7 +626,7 @@
// hr = pFilter->GetSyncSource(&pRefClock);
hr = pFilter->GetClassID(&clsidFlt);
- strFlt = tstr_printf(TEXT("\n- %") W2t, sInfo.achName);
+ strFlt = tstr_printf(EOL TEXT("- %") W2t, sInfo.achName);
if (pszVendorInfo)
strFlt += tstr_printf(TEXT(" [%") W2t TEXT("]"), pszVendorInfo.m_pData);
strFlt += tstr_printf(TEXT(", clsid=") GUIDFMT, GUIDPARM(clsidFlt));
@@ -618,7 +644,7 @@
strState.insert(0,
tstr_printf(
- TEXT("%") A2t TEXT("\n\n** Liste des filtres utilisés :"),
+ TEXT("%") A2t EOL TEXT("\n** Liste des filtres utilisés :"),
EnumToString(state,
"Le graphe est à l'arrêt\0"
"Le graphe est en pause\0"
@@ -631,7 +657,7 @@
/// Construction du graphe
HRESULT CPTvM_GraphBase::Build()
{
- HRESULT hr = pGraph.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER);
+ HRESULT hr = pFGrph.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER);
if (FAILED(hr) )
return erreur(TEXT("Pas réussi à créer le graphe DirectShow !"), hr);
@@ -774,17 +800,24 @@
virtual HRESULT set_volume(long volume);
/**
+ * Sélection d'un (nouveau ou pas) codec vidéo
+ * \param[in] eVideoType Codec à sélectionner
+ * \param[in] video_pid si != 0, branchement de ce PID au démultiplexeur en même temps
+ **/
+ virtual HRESULT select_video_codec(VideoStreamType eVideoType, UINT16 video_pid);
+
+ /**
* Branchement de tous les médias de sortie d'une chaîne.
*
* \param[in] pmt_pid PID du flux PMT de la chaîne
* \param[in] video_pid PID du flux vidéo
- * \param[in] video_type Type du flux vidéo
+ * \param[in] eVideoType Type du flux vidéo
* \param[in] audio_pid PID du flux audio
- * \param[in] audio_type Type du flux audio
+ * \param[in] eAudioType Type du flux audio
* \return Code d'erreur DirectShow
**/
- virtual HRESULT branche_medias(UINT16 pmt_pid, UINT16 video_pid, VideoStreamType video_type,
- UINT16 audio_pid, TrackStreamType audio_type);
+ virtual HRESULT branche_medias(UINT16 pmt_pid, UINT16 video_pid, VideoStreamType eVideoType,
+ UINT16 audio_pid, TrackStreamType eAudioType);
/**
* Débranchement de tous les médias
@@ -833,7 +866,7 @@
CPTvM_TunerGraph();
/// Construction du graphe
- HRESULT Build();
+ HRESULT Build();
/// Destructeur
virtual ~CPTvM_TunerGraph() {}
@@ -961,13 +994,11 @@
return; // Déjà détruit
// Arrêt de tous les enregistrements en cours
- myprintf(TEXT("Arrêt des enregistrements\n"));
+ myprintf(TEXT("Arrêt des enregistrements") EOL);
enregistrements_actuels.stop_all();
- myprintf(TEXT("Arrêt du graphe\n"));
pGraph->graph_Stop();
- myprintf(TEXT("Destruction du VMR\n"));
clean_vmr();
#if USE_SINGLE_GRABBER==0
@@ -977,7 +1008,7 @@
}
#endif
- myprintf(TEXT("Destruction du graphe\n"));
+ myprintf(TEXT("Destruction du graphe") EOL);
delete pGraph; // #### Destruction effective
pGraph = NULL;
}
@@ -1067,7 +1098,7 @@
if (bFindExisting) {
hr = cherche_pin(sDemux.pFilter, PINDIR_OUTPUT, pOutPin, sDData.pAmt);
if (hr != E_FAIL) {
- myprintf(TEXT("%?Broche existante trouvée pour \"%") W2t TEXT("\"\n"), SUCCEEDED(hr), sDData.pszPinName);
+ myprintf(TEXT("%?Broche existante trouvée pour \"") BOLD(TEXT("%") W2t) TEXT("\"") EOL, SUCCEEDED(hr), sDData.pszPinName);
return hr;
}
}
@@ -1076,7 +1107,7 @@
// "CreateOutputPin" modifie les objets pointés.
hr = iMp2Demux.CreateOutputPin(const_cast(sDData.pAmt),
const_cast(sDData.pszPinName), &pOutPin);
- myprintf(TEXT("%?Broche \"%") W2t TEXT("\" créée pour %") A2t TEXT("\n"), SUCCEEDED(hr), sDData.pszPinName, sDData.pszType);
+ myprintf(TEXT("%?Broche \"") BOLD(TEXT("%") W2t) TEXT("\" créée pour ") BOLD(TEXT("%") A2t) EOL, SUCCEEDED(hr), sDData.pszPinName, sDData.pszType);
if (FAILED(hr))
return erreur(TEXT("La broche %") A2t TEXT(" n'a pas pu être créée"), hr, sDData.pszType);
return hr;
@@ -1108,7 +1139,7 @@
hr, sDData.pszType, sDData.pszName);
} else {
#if AUTO_RENDER
- hr = pGraph->RenderEx(pOutPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);
+ hr = pFGrph->RenderEx(pOutPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);
if (FAILED(hr))
#endif
return erreur(TEXT("Pas de rendu possible depuis la broche %") A2t,
@@ -1152,7 +1183,7 @@
hr, sDData.pszType, sDData.pszName);
} else {
#if AUTO_RENDER
- hr = pGraph->RenderEx(pOutPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);
+ hr = pFGrph->RenderEx(pOutPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);
if (FAILED(hr))
#endif
return erreur(TEXT("Pas de rendu possible depuis la broche %") A2t,
@@ -1242,12 +1273,15 @@
**/
HRESULT CPTvM_GraphBase::graph_Run()
{
- CComQIPtr pControl(pGraph);
+ if (bRunning)
+ return S_OK;
+ CComQIPtr pControl(pFGrph);
+
if (!pControl)
return E_NOINTERFACE;
- myprintf(TEXT("Démarrage du graphe\n"));
+ myprintf(BOLD(TEXT("Démarrage du graphe")) EOL);
HRESULT hr = pControl->Run();
if (FAILED(hr))
@@ -1256,6 +1290,7 @@
for (UINT nInx=0; nInx<10; nInx++) { // 10 * 200 mS = 2 secondes
Sleep(200);
if (graph_GetState()==State_Running) {
+ bRunning = true;
hr = S_OK;
break;
}
@@ -1270,7 +1305,7 @@
**/
HRESULT CPTvM_GraphBase::graph_Pause()
{
- CComQIPtr pControl(pGraph);
+ CComQIPtr pControl(pFGrph);
if (!pControl)
return E_NOINTERFACE;
@@ -1283,13 +1318,21 @@
**/
HRESULT CPTvM_GraphBase::graph_Stop()
{
- CComQIPtr pControl(pGraph);
+ if (!bRunning)
+ return S_OK;
+ CComQIPtr pControl(pFGrph);
+
if (!pControl)
return E_NOINTERFACE;
- myprintf(TEXT("Arrêt du graphe\n"));
- return pControl->Stop();
+ myprintf(BOLD(TEXT("Arrêt du graphe")) EOL);
+
+ HRESULT hr = pControl->Stop();
+
+ if (SUCCEEDED(hr))
+ bRunning = false;
+ return hr;
}
/**
@@ -1302,8 +1345,8 @@
**/
OAFilterState CPTvM_GraphBase::graph_GetState()
{
- if (pGraph) {
- CComQIPtr pControl(pGraph);
+ if (pFGrph) {
+ CComQIPtr pControl(pFGrph);
OAFilterState state;
if (pControl && SUCCEEDED(pControl->GetState(1500, &state)))
@@ -1340,7 +1383,7 @@
while (SUCCEEDED(pEvents->GetEvent(&evCode, ¶m1, ¶m2, 0))) {
#if USE_CONSOLE
- myprintf(TEXT("Graph Event (%u) 0x%02x=EC_%") A2t TEXT(", %08x, %08x\n"), ++nEvCount, evCode,
+ myprintf(TEXT("Graph Event (%u) 0x%02x=EC_%") A2t TEXT(", %08x, %08x") EOL, ++nEvCount, evCode,
EnumToString(evCode,
"BASE\0" // 0x00
"COMPLETE\0" // 0x01
@@ -1413,7 +1456,7 @@
#if USE_CONSOLE
case EC_ERRORABORT: // 0x03
- myprintf(TEXT("EC_ERRORABORT, raison=%08x: %s\n"), HRESULT(param1),
+ myprintf(ERRX(TEXT("EC_ERRORABORT, raison=%08x: %s")), HRESULT(param1),
DShowErrorToString(HRESULT(param1)).c_str());
break;
#endif
@@ -1422,7 +1465,7 @@
/* Note : lien vers une discussion en relation avec ce problème d'événement EC_PAUSED :
http://www.eggheadcafe.com/conversation.aspx?messageid=29757074&threadid=29757074 */
#if USE_CONSOLE
- myprintf(TEXT("EC_PAUSED, raison=0x%08x: %s\n"), HRESULT(param1),
+ myprintf(ERRX(TEXT("EC_PAUSED, raison=0x%08x: %s")), HRESULT(param1),
DShowErrorToString(HRESULT(param1)).c_str());
#endif
#if USE_AUTO_RETUNE
@@ -1433,7 +1476,7 @@
case EC_STREAM_ERROR_STILLPLAYING:
#if USE_CONSOLE
- myprintf(TEXT("EC_STREAM_ERROR_STILLPLAYING, code=0x%08x: %s, minor=0x%08x\n"),
+ myprintf(ERRX(TEXT("EC_STREAM_ERROR_STILLPLAYING, code=0x%08x: %s, minor=0x%08x")),
HRESULT(param1),
DShowErrorToString(HRESULT(param1)).c_str(), DWORD(param2));
#endif
@@ -1460,7 +1503,7 @@
case EC_VIDEO_SIZE_CHANGED: // 0x0a
PostMessage(hWnd, WM_APP_VIDEOSIZE_CHG, 0, 0);
- myprintf(TEXT("Nouvelle taille vidéo = %u/%u\n"), LOWORD(param1), HIWORD(param1));
+ myprintf(BOLD(TEXT("Nouvelle taille vidéo = %u/%u")) EOL, LOWORD(param1), HIWORD(param1));
}
pEvents->FreeEventParams(evCode, param1, param2);
}
@@ -1640,9 +1683,10 @@
/**
* Construction et mise en route du graphe DirectShow
+ * \param[in] eVideoType Type de flux vidéo initial (présumé si inconnu)
* \return Code d'erreur DirectShow
**/
-HRESULT build_graph()
+HRESULT build_graph(VideoStreamType eVideoType)
{
if (pGraph)
return E_FAIL; // Déjà existant
@@ -1660,6 +1704,25 @@
if (FAILED(hr))
return erreur(TEXT("Erreur lors de la création du graphe"), hr);
+ hr = init_vmr();
+
+ // Une erreur à l'initialisation du VMR n'est pas interruptive : le reste du
+ // graphe doit pouvoir continuer à fonctionner (néanmoins, inutile de tenter
+ // d'insérer le codec vidéo également).
+ if (FAILED(hr)) {
+ affiche_erreurs(
+ TEXT("Le module de rendu vidéo (VMR) n'a pas pu s'initialiser. Le programme va s'exécuter") EOL
+ TEXT("avec l'affichage vidéo désactivé. Merci de vous assurer de la disponibilité de votre") EOL
+ TEXT("carte graphique, puis de vous rendre dans la configuration de Pouchin TV Mod") EOL
+ TEXT("(onglet \"Options\") pour y choisir et y (ré)activer une méthode de rendu vidéo."), S_OK);
+ vmr_mode = vmt_null;
+ } else {
+ hr = pGraph->select_video_codec(eVideoType, 0);
+
+ if (FAILED(hr))
+ return erreur(TEXT("Erreur lors de l'insertion du codec vidéo"), hr);
+ }
+
pGraph->AddEventNotifier(hMainWnd, WM_APP_GRAPHNOTIFY);
// mise en route
@@ -1762,7 +1825,7 @@
break;
default:
- myprintf(TEXT("Type de piste audio non identifié\n"));
+ myprintf(TEXT("Type de piste audio non identifié") EOL);
}
}
return hr;
@@ -1779,47 +1842,58 @@
}
/**
+ * Sélection d'un (nouveau ou pas) codec vidéo
+ * \param[in] eVideoType Codec à sélectionner
+ * \param[in] video_pid si != 0, branchement de ce PID au démultiplexeur en même temps
+ **/
+HRESULT CPTvM_TunerGraph::select_video_codec(VideoStreamType eVideoType, UINT16 video_pid)
+{
+ HRESULT hr=E_FAIL; // par défaut
+
+ switch (eVideoType) {
+
+ case vst_MPEG2:
+ if (pVMR && ePrevVideoType!=vst_MPEG2) {
+ if (FAILED(hr = switch_codec(sMp2vCodec)))
+ return hr;
+ ePrevVideoType = vst_MPEG2;
+ }
+ if (video_pid)
+ hr = sMp2vCodec.branche_pid(video_pid);
+ break;
+
+ case vst_H264:
+ if (pVMR && ePrevVideoType!=vst_H264) {
+ if (FAILED(hr = switch_codec(sH264Codec)))
+ return hr;
+ ePrevVideoType = vst_H264;
+ }
+ if (video_pid)
+ hr = sH264Codec.branche_pid(video_pid);
+ }
+
+ return hr;
+}
+
+/**
* Branchement de tous les médias de sortie d'une chaîne.
*
* \param[in] pmt_pid PID du flux PMT de la chaîne
* \param[in] video_pid PID du flux vidéo
- * \param[in] video_type Type du flux vidéo
+ * \param[in] eVideoType Type du flux vidéo
* \param[in] audio_pid PID du flux audio
- * \param[in] audio_type Type du flux audio
+ * \param[in] eAudioType Type du flux audio
* \return Code d'erreur DirectShow
**/
-HRESULT CPTvM_TunerGraph::branche_medias(UINT16 pmt_pid, UINT16 video_pid, VideoStreamType video_type, UINT16 audio_pid, TrackStreamType audio_type)
+HRESULT CPTvM_TunerGraph::branche_medias(UINT16 pmt_pid, UINT16 video_pid, VideoStreamType eVideoType, UINT16 audio_pid, TrackStreamType eAudioType)
{
HRESULT hr = E_FAIL; // valeur par défaut
if (bSuspended) {
- if (video_pid) {
- switch (video_type) {
- case vst_MPEG2:
- if (pVMR && ePrevVideoType!=vst_MPEG2) {
- if (FAILED(hr = switch_codec(sMp2vCodec)))
- return hr;
- ePrevVideoType = vst_MPEG2;
- }
- hr = sMp2vCodec.branche_pid(video_pid);
- break;
+ if (video_pid)
+ hr = select_video_codec(eVideoType, video_pid);
+ branche_son(audio_pid, eAudioType);
- case vst_H264:
- if (pVMR && ePrevVideoType!=vst_H264) {
- if (FAILED(hr = switch_codec(sH264Codec)))
- return hr;
- ePrevVideoType = vst_H264;
- }
- hr = sH264Codec.branche_pid(video_pid);
- break;
-
- default:
- hr=E_FAIL;
- }
- }
-
- branche_son(audio_pid, audio_type);
-
#if USE_PMTFILTER
// pmt
hr = sPMT_Filter.branche_pid(pmt_pid);
@@ -1852,7 +1926,7 @@
**/
HRESULT CPTvM_TunerGraph::set_volume(long volume)
{
- CComQIPtr pBas(pGraph);
+ CComQIPtr pBas(pFGrph);
if (!pBas)
return E_NOINTERFACE;
@@ -1984,7 +2058,7 @@
if (FAILED(hr = pStats->get_SignalPresent(&bBool))) {
if (hr!=E_PROP_ID_UNSUPPORTED) {
- myprintf(TEXT("Erreur get_SignalPresent, hr=0x%08x\n"), hr);
+ myprintf(ERRX(TEXT("Erreur get_SignalPresent, hr=0x%08x")), hr);
if (nErrStep==0) {
hr_1st = hr;
nErrStep |= 0x01;
@@ -1997,7 +2071,7 @@
if (FAILED(hr = pStats->get_SignalLocked(&bBool))) {
if (hr!=E_PROP_ID_UNSUPPORTED) {
- myprintf(TEXT("Erreur get_SignalLocked, hr=0x%08x\n"), hr);
+ myprintf(ERRX(TEXT("Erreur get_SignalLocked, hr=0x%08x")), hr);
if (nErrStep==0) {
hr_1st = hr;
nErrStep |= 0x02;
@@ -2010,7 +2084,7 @@
if (FAILED(hr = pStats->get_SignalStrength(&nStrength))) {
if (hr!=E_PROP_ID_UNSUPPORTED) {
- myprintf(TEXT("Erreur get_SignalStrength, hr=0x%08x\n"), hr);
+ myprintf(ERRX(TEXT("Erreur get_SignalStrength, hr=0x%08x")), hr);
if (nErrStep==0) {
hr_1st = hr;
nErrStep |= 0x04;
@@ -2022,7 +2096,7 @@
if (isPresenceOk() && isLockedOk()) {
if (FAILED(hr = pStats->get_SignalQuality(&nQuality))) {
if (hr!=E_PROP_ID_UNSUPPORTED) {
- myprintf(TEXT("Erreur get_SignalQuality, hr=0x%08x\n"), hr);
+ myprintf(ERRX(TEXT("Erreur get_SignalQuality, hr=0x%08x")), hr);
if (nErrStep==0) {
hr_1st = hr;
nErrStep |= 0x08;
@@ -2119,15 +2193,15 @@
filter.SectionNumber = nextSection++;
hr = pMpeg2Data->GetSection(_pid, _tid, &filter, _dwTimeout, &pSectionList);
if (!SUCCEEDED(hr)) {
- myprintf(TEXT("Pas eu la %") A2t TEXT(", hr=0x%08x\n"), (LPCSTR)&tableName, hr);
+ myprintf(TEXT("Pas eu la %") A2t TEXT(", hr=0x%08x") EOL, (LPCSTR)&tableName, hr);
return false;
}
hr = pSectionList->GetSectionData(0, &length, &data);
if (!SUCCEEDED(hr)) {
- myprintf(TEXT("Pas eu les données de la %") A2t TEXT(", hr=0x%08x\n"), (LPCSTR)&tableName, hr);
+ myprintf(TEXT("Pas eu les données de la %") A2t TEXT(", hr=0x%08x") EOL, (LPCSTR)&tableName, hr);
return false;
}
- myprintf(TEXT("Taille %") A2t TEXT(" : %u\n"), (LPCSTR)&tableName, length);
+ myprintf(TEXT("Taille %") A2t TEXT(" : %u") EOL, (LPCSTR)&tableName, length);
lastSection = ((const SI_hdr *)data)->last_section_number;
return true;
}
@@ -2145,8 +2219,17 @@
**/
tstring DShowErrorToString(HRESULT hr)
{
- TCHAR szBuffer[MAX_ERROR_TEXT_LEN];
+ // Note : contrairement à ce qui est dit dans la documentation de Microsoft,
+ // il existe des messages plus longs que MAX_ERROR_TEXT_LEN ...
+ TCHAR szBuffer[MAX_ERROR_TEXT_LEN*2];
- AMGetErrorText(hr, szBuffer, _countof(szBuffer));
+ if (AMGetErrorText(hr, szBuffer, _countof(szBuffer))==0) {
+ UINT nFacility = HIWORD(hr) & 0xfff;
+
+ if (nFacility == FACILITY_MF || nFacility == FACILITY_MF_WIN32)
+ _stprintf_s(szBuffer, TEXT("Erreur Media Foundation, code %u"), LOWORD(hr));
+ else
+ strcpy_T(szBuffer, TEXT("[code d'erreur inconnu]"));
+ }
return RTrimStr(szBuffer); // Conversion implicite en tstring
};
Modifié: trunk/graph.h
===================================================================
--- trunk/graph.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/graph.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -90,7 +90,7 @@
#pragma warning(disable: 4250) // 'classe1' : hérite de 'classe2::membre' via la dominance
DeclareInterface(IPTvM_GraphBase)
- virtual HRESULT Build() = 0;
+ virtual HRESULT Build() = 0;
/**
* Traitement d'un événement du graphe
@@ -152,6 +152,14 @@
**/
virtual OAFilterState graph_GetState() = 0;
+ /**
+ * Vérifie si le graphe est en route
+ * \return \p true (en route), ou \p false (arrête)
+ * \note Se base sur une variable interne à la classe, alors que
+ \p graph_GetState interroge le graphe lui-même.
+ **/
+ virtual bool graph_isRunning() const = 0;
+
#ifdef _DEBUG
virtual tstring get_graph_state() = 0;
#endif
@@ -173,17 +181,24 @@
virtual HRESULT set_volume(long volume) = 0;
/**
+ * Sélection d'un (nouveau ou pas) codec vidéo
+ * \param[in] eVideoType Codec à sélectionner
+ * \param[in] video_pid si != 0, branchement de ce PID au démultiplexeur en même temps
+ **/
+ virtual HRESULT select_video_codec(VideoStreamType eVideoType, UINT16 video_pid) = 0;
+
+ /**
* Branchement de tous les médias de sortie d'une chaîne.
*
* \param[in] pmt_pid PID du flux PMT de la chaîne
* \param[in] video_pid PID du flux vidéo
- * \param[in] video_type Type du flux vidéo
+ * \param[in] eVideoType Type du flux vidéo
* \param[in] audio_pid PID du flux audio
- * \param[in] audio_type Type du flux audio
+ * \param[in] eAudioType Type du flux audio
* \return Code d'erreur DirectShow
**/
- virtual HRESULT branche_medias(UINT16 pmt_pid, UINT16 video_pid, VideoStreamType video_type,
- UINT16 audio_pid, TrackStreamType audio_type) = 0;
+ virtual HRESULT branche_medias(UINT16 pmt_pid, UINT16 video_pid, VideoStreamType eVideoType,
+ UINT16 audio_pid, TrackStreamType eAudioType) = 0;
/**
* Débranchement de tous les médias
@@ -244,9 +259,10 @@
/**
* Construction et mise en route du graphe DirectShow
+ * \param[in] eVideoType Type de flux vidéo initial (présumé si inconnu)
* \return Code d'erreur DirectShow
**/
-HRESULT build_graph(); // retourne S_OK = pas d'erreur, != S_OK = erreur
+HRESULT build_graph(VideoStreamType eVideoType);
/**
* Arrêt du graphe avec nettoyage de toutes les ressources utilisées par celui-ci
Modifié: trunk/ini.cpp
===================================================================
--- trunk/ini.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/ini.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -1388,9 +1388,9 @@
FILE * fop;
if (_tfopen_s(&fop, fileName, TEXT("wb")))
- myprintf(TEXT("Fichier %s => Erreur écriture\n"), scan_ini);
+ myprintf(ERRX(TEXT("Fichier %s => Erreur écriture")), scan_ini);
else {
- myprintf(TEXT("Fichier %s => Création\n"), scan_ini);
+ myprintf(TEXT("Fichier %s => Création") EOL, scan_ini);
fputs(canaux, fop);
fclose(fop);
}
@@ -1957,17 +1957,6 @@
// Désactivation optionnelle des informations sur les flux vidéo, son et autre
#if STREAMS_SAVE_ALL
- // Mémorise le type de flux vidéo
- //switch (canal.video_type) {
- //case vst_H264:
- //case vst_H264_encrypted:
- // oxml.put("Video_mpeg4", canal.video_pid);
- // break;
- //case vst_MPEG2:
- //case vst_MPEG2_encrypted:
- //default:
- // oxml.put("Video", canal.video_pid);
- //}
oxml.put("Video", canal.video_pid);
oxml.put("Video_type", oxml.fmt("%" T2a, dword2str(aVideoTypeTable, canal.video_type)));
Modifié: trunk/main.cpp
===================================================================
--- trunk/main.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/main.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -122,7 +122,7 @@
#define MENU_PROGRAMME_POSITION 6
#define SMENU_PRIORITE_POSITION 2 // dans menu "Programme"
-bool is_vista = false; //!< \p true si on est sous Windows Vista
+WinVersion eWinVers = wv_Unknown; //!< Version de Windows (décodage basique)
/// Diverses informations sur la version de Windows
OSVERSIONINFOEX windows_version;
@@ -970,7 +970,7 @@
**/
void zappe_index(int ixChaine)
{
- myprintf(TEXT("\n##################### (début sélection chaîne) #########################\n"));
+ myprintf(BOLD(TEXT("################# (début sélection chaîne) #####################")) EOL);
if (pOSD)
pOSD->Clear(); // Effacer tous les objets OSD courants
@@ -983,29 +983,6 @@
}
}
-/**
- * Restauration d'une chaîne sauvegardée par clé.
- * Si la clé n'est pas valide, on utilise la première de la liste.
- * Retourne 'true' si succès, 'false' si la liste est vide.
- **/
-bool restaure_chaine(UINT32 cleChaine)
-{
- // On essaye de remettre la même chaîne qu'avant, s'il y en avait une :
- if (!Canaux.empty()) {
- int ixChaine = Canaux.trouve_par_cle(cleChaine);
-
- if (ixChaine<0) {
- // S'il n'y en avait pas, ou bien si cette chaîne n'est plus captée,
- // on met la première de la liste ...
- // ... laquelle a toutes les chances d'être TF1, mais bon ... :-(
- ixChaine = 0;
- }
- zappe_index(ixChaine);
- return true;
- }
- return false;
-}
-
static void switch_etat_fenetre(EtatsFenetre nouvel_etat); // forward
static void switch_on_top(void)
@@ -1547,7 +1524,7 @@
{
if (!pGraph)
return;
- myprintf(TEXT("Demande de l'état du graphe\n"));
+ myprintf(TEXT("Demande de l'état du graphe") EOL);
MessageBox(
hMainWnd,
@@ -1630,8 +1607,8 @@
if (eNeedRestart != nr_None) {
if (enregistrements_actuels.recording()!=0) {
MessageBox(hMainWnd,
- TEXT("Au moins un enregistrement est en cours :\n")
- TEXT("Certaines des modifications apportées à la configuration\n")
+ TEXT("Au moins un enregistrement est en cours :") EOL
+ TEXT("Certaines des modifications apportées à la configuration") EOL
TEXT("ne s'appliqueront qu'après redémarrage de l'application."),
TEXT("Paramètres modifiés"), MB_ICONINFORMATION);
eNeedRestart = nr_None;
@@ -1889,7 +1866,7 @@
if (pGraph) {
if (pOSD)
pOSD->DisplayBotRightMsg(TEXT("Démarrage graphe"));
- myprintf(TEXT("Mise en marche du graphe\n"));
+ myprintf(TEXT("Mise en marche du graphe") EOL);
pGraph->graph_Run();
}
break;
@@ -1898,7 +1875,7 @@
if (pGraph) {
if (pOSD)
pOSD->DisplayBotRightMsg(TEXT("Pause graphe"));
- myprintf(TEXT("Mise en pause du graphe\n"));
+ myprintf(TEXT("Mise en pause du graphe") EOL);
pGraph->graph_Pause();
}
break;
@@ -1907,7 +1884,7 @@
if (pGraph) {
if (pOSD)
pOSD->DisplayBotRightMsg(TEXT("Arrêt graphe"));
- myprintf(TEXT("Arrêt du graphe\n"));
+ myprintf(TEXT("Arrêt du graphe") EOL);
pGraph->graph_Stop();
}
break;
@@ -1936,7 +1913,7 @@
break;
case IDM_CHAN_TUNE:
- myprintf(TEXT("Resyntonisation forcée\n"));
+ myprintf(BOLD(TEXT("Resyntonisation forcée")) EOL);
change_chaine(ixChaineCourante, true);
break;
@@ -2050,7 +2027,7 @@
break;
case TIMER_DELAYED_RECORD:
- if (pGraph && pGraph->graph_GetState()==State_Running) {
+ if (pGraph && pGraph->graph_isRunning()) {
// Gestion du timer des enregistrements :
KillTimer(hMainWnd, TIMER_DELAYED_RECORD);
@@ -2082,23 +2059,19 @@
switch (uMsg) {
case WM_CREATE: {
- myprintf(TEXT("Création fenêtre principale\n"));
+ myprintf(BOLD(TEXT("Création fenêtre principale")) EOL);
hMainWnd = hWnd;
break;
}
- case WM_PAINT:
- if (use_osd && pOSD) {
- PAINTSTRUCT ps;
- HDC hDC = BeginPaint(hWnd, &ps);
+ case WM_PAINT: {
+ PAINTSTRUCT ps;
+ HDC hDC = BeginPaint(hWnd, &ps);
- do_paint(hDC);
+ do_paint(hDC);
- EndPaint(hWnd, &ps);
- } else
- // Laisse Windows traiter les messages
- lRet = DefWindowProc(hWnd, uMsg, wParam, lParam);
- break;
+ EndPaint(hWnd, &ps);
+ break; }
case WM_DISPLAYCHANGE:
if (pVMR)
@@ -2163,7 +2136,7 @@
case APPCOMMAND_BROWSER_FAVORITES: wID = IDM_EPG; break; // Affiche la liste des programmes EPG
default: // Non traité, juste pour le connaitre
- myprintf(TEXT("WM_APPCOMMAND non traité: %d / Device: %s / Touches: %d\n"),
+ myprintf(TEXT("WM_APPCOMMAND non traité: %d / Device: %s / Touches: %d") EOL,
cmd,
(GET_DEVICE_LPARAM(lParam) == FAPPCOMMAND_KEY ? TEXT("Clavier") :
(GET_DEVICE_LPARAM(lParam) == FAPPCOMMAND_MOUSE ? TEXT("Souris") :
@@ -2335,7 +2308,7 @@
case SC_MONITORPOWER:
break;
case SC_MINIMIZE:
- myprintf(TEXT("WM_SYSCOMMAND minimize\n"));
+ myprintf(TEXT("WM_SYSCOMMAND minimize") EOL);
if (suspend_minimized)
debranche();
lRet = DefWindowProc(hWnd, uMsg, wParam, lParam);
@@ -2345,13 +2318,13 @@
case SC_RESTORE:
if (suspend_minimized && !rebranche(false))
return false;
- myprintf(TEXT("WM_SYSCOMMAND restore\n"));
+ myprintf(TEXT("WM_SYSCOMMAND restore") EOL);
if (minimize_system_tray)
ShowWindow(hWnd, SW_SHOW);
lRet = DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
case SC_MAXIMIZE:
- myprintf(TEXT("WM_SYSCOMMAND maximize\n"));
+ myprintf(TEXT("WM_SYSCOMMAND maximize") EOL);
// ...
default:
lRet = DefWindowProc(hWnd, uMsg, wParam, lParam);
@@ -2398,7 +2371,7 @@
break;
case WM_APP_PMT_UPDATED:
- myprintf(TEXT("Le pmt a changé\n"));
+ myprintf(TEXT("Le pmt a changé") EOL);
sauve_chaines();
change_chaine_update(ixChaineCourante);
if (pOSD)
@@ -2418,7 +2391,7 @@
default:
if (uMsg == nWM_TASKBARCREATED) {
// Recréation de l'icône de la barre des tâches après un plantage de l'explorateur Windows
- myprintf(TEXT("La barre des tâches a été recréée\n"));
+ myprintf(TEXT("La barre des tâches a été recréée") EOL);
niData.disable();
niData.update_state();
break;
@@ -2445,7 +2418,7 @@
SHGetFolderPath(NULL, csidl_default, NULL, SHGFP_TYPE_CURRENT, default_dir);
_stprintf_s(message, _countof(message),
- TEXT("Le répertoire « %s », spécifié pour sauvegarder les %s, n'existe pas.\n\n")
+ TEXT("Le répertoire « %s », spécifié pour sauvegarder les %s, n'existe pas.\n") EOL
TEXT("Voulez-vous le créer ?"), dir, dirUsage);
if (MessageBox(hMainWnd, message, TEXT("Dossier inexistant"), MB_ICONQUESTION | MB_YESNO) == IDYES) {
// On le crée donc
@@ -2453,7 +2426,7 @@
// Erreur lors de la création du dossier
strcpy_T(dir, dir_size, default_dir);
_stprintf_s(message, _countof(message),
- TEXT("Une erreur est survenue lors de la création du répertoire.\n")
+ TEXT("Une erreur est survenue lors de la création du répertoire.") EOL
TEXT("Le nouveau répertoire pour les %s est :\n\n%s"), dirUsage, dir);
MessageBox(hMainWnd, message, TEXT("Erreur de création du dossier"), MB_ICONEXCLAMATION);
}
@@ -2753,17 +2726,66 @@
ZeroMemory(&windows_version, sizeof(windows_version));
windows_version.dwOSVersionInfoSize = sizeof(windows_version);
if (GetVersionEx((OSVERSIONINFO *)&windows_version)) {
- is_vista = windows_version.dwMajorVersion >= 6;
+ // http://www.codeguru.com/cpp/w-p/system/systeminformation/article.php/c8973
+ switch (windows_version.dwMajorVersion) {
+ case 5:
+ switch (windows_version.dwMinorVersion) {
+ case 0:
+ eWinVers = wv_2000;
+ break;
+ case 2:
+ if (windows_version.wProductType > VER_NT_WORKSTATION) {
+ eWinVers = wv_Server2003;
+ break;
+ }
+ // ... (passage à travers) (cas particulier XP 64)
+ case 1:
+ eWinVers = wv_XP;
+ }
+ break;
+ case 6:
+ switch (windows_version.dwMinorVersion) {
+ case 0:
+ switch (windows_version.wProductType) {
+ case 1: eWinVers = wv_Vista; break;
+ case 3: eWinVers = wv_Server2008;
+ }
+ break;
+ case 1:
+ switch (windows_version.wProductType) {
+ case 1: eWinVers = wv_Seven; break;
+ case 3: eWinVers = wv_Server2008R2;
+ }
+ break;
+ default:
+ eWinVers = wv_Newer;
+ }
+ break;
+ default:
+ if (windows_version.dwMajorVersion < 5)
+ eWinVers = wv_Older;
+ else if (windows_version.dwMajorVersion > 6)
+ eWinVers = wv_Newer;
+ }
+
myprintf(
- TEXT("Fonctionne sous %s\n [Windows version %s]\n"),
- is_vista ?
- TEXT("Vista ou 2008 Serveur ou plus récent") :
- TEXT("2000 ou XP"),
+ TEXT("Fonctionne sous ") BOLD(TEXT("Windows ") TEXT("%s")) EOL TEXT("[Windows version %s]") EOL,
+ EnumToString(eWinVers,
+ "(version inconnue)\0"
+ "(version ancienne)\0"
+ "2000\0"
+ "XP\0"
+ "2003 Serveur\0"
+ "Vista\0"
+ "2008 Serveur\0"
+ "7\0"
+ "2008 Serveur R2\0"
+ "(version inconnue : trop récente)\0"),
GetWindowsVersionStr(windows_version).c_str());
} else
- myprintf(TEXT("Erreur lors de la récupération de la version de Windows\n"));
+ myprintf(ERRX(TEXT("Erreur lors de la récupération de la version de Windows")));
- myprintf(TEXT("\n##########\n\n"));
+ myprintf(BOLD(TEXT("################################################################")) EOL EOL);
HRESULT hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);
if (FAILED(hr)) {
@@ -2840,7 +2862,7 @@
static int MainTask(CmdOptions * cmdOptions)
{
// Sous Vista, on n'utilise l'OSD qu'avec le VMR9
- if (is_vista && (vmr_mode==vmt_VMR7_renderless || vmr_mode==vmt_VMR7_windowless))
+ if (eWinVers>=wv_Vista && (vmr_mode==vmt_VMR7_renderless || vmr_mode==vmt_VMR7_windowless))
use_osd = false;
// Si on minimise dans la zone système, n'affiche pas la fenêtre dans la barre des tâches
@@ -2881,8 +2903,25 @@
configState = etf_normal;
}
+ // Tester si l'état de la configuration est correct. Tester aussi si la touche "majuscules" est
+ // pressée, ce qui provoque une ouverture inconditionnelle du dialogue de configuration.
bool config_ok = check_config() && GetKeyState(VK_SHIFT)>=0;
+ // Sélectionner la chaîne qu'on va sélectionner au démarrage
+ int ixChaineStartup = -1; // Index de cette chaîne
+
+ if (cmdOptions && cmdOptions->nChaine > 0) {
+ // Un numéro de chaîne passé en paramètre est prioritaire sur la chaîne
+ // courante sauvegardée dans la configuration
+ ixChaineStartup = Canaux.trouve_par_no((WORD)cmdOptions->nChaine);
+ } else
+ ixChaineStartup = Canaux.trouve_restauration_par_cle(cleChaineConfig);
+
+ VideoStreamType eVideoInitialType = vst_MPEG2; // valeur par défaut
+
+ if (ixChaine_ok(ixChaineStartup))
+ eVideoInitialType = Canaux[ixChaineStartup].video_type;
+
for (;;) {
if (!config_ok) {
if (drivers_dialog()!=IDOK) {
@@ -2895,7 +2934,8 @@
}
}
- HRESULT hr = build_graph();
+ // ###### Ici est **LE** endroit où on construit le graphe !!
+ HRESULT hr = build_graph(eVideoInitialType);
if (SUCCEEDED(hr)) {
if (Canaux.size()> 0 || scan_dialog(hMainWnd)==IDOK) {
@@ -2917,45 +2957,24 @@
CoInitializeEx(NULL, COINIT_MULTITHREADED);
}
- if (!do_init_vmr()) {
- affiche_erreurs(
- TEXT("Le module de rendu vidéo (VMR) n'a pas pu s'initialiser. Le programme va s'exécuter\n")
- TEXT("avec l'affichage vidéo désactivé. Merci de vous assurer de la disponibilité de votre\n")
- TEXT("carte graphique, puis de vous rendre dans la configuration de Pouchin TV Mod\n")
- TEXT("(onglet \"Options\") pour y choisir et y (ré)activer une méthode de rendu vidéo."), S_OK);
- vmr_mode = vmt_null;
- }
-
// Mise à jour du menu des filtres (pour désactiver les items correspondant
// à des filtres inexistants ou n'ayant pas de pages de propriétés) :
update_filtres_menus(hMainMenu);
- if (cmdOptions && cmdOptions->nChaine > 0) {
- // Un numéro de chaîne passé en paramètre est prioritaire sur la chaîne
- // courante sauvegardée dans la configuration
+ // Sélectionner la chaîne
+ zappe_index(ixChaineStartup);
- // Vérifie que la chaîne passée en paramètre est connue
- int ixChaine = Canaux.trouve_par_no((WORD)cmdOptions->nChaine);
-
- if (ixChaine_ok(ixChaine))
- cleChaineConfig = Canaux[ixChaine].cle();
- }
-
- restaure_chaine(cleChaineConfig);
-
+ // Régler le volume
if (pGraph)
pGraph->set_volume(volumeCourant);
if (cmdOptions && cmdOptions->bMinimize) {
// On a lancé avec le paramètre demandant de masquer la fenêtre
- if(!suspend_minimized) {
- myprintf(TEXT("Branchement des sorties audio et vidéo (mode minimisé)\n"));
+ if (!suspend_minimized) {
if (!rebranche(true))
return -1;
}
} else {
- myprintf(TEXT("Branchement des sorties audio et vidéo\n"));
-
// Branchement initial des sorties audio et vidéo :
if (!rebranche(true))
return -1;
@@ -2995,7 +3014,7 @@
}
}
- myprintf(TEXT("Entrée dans la boucle de messages\n"));
+ myprintf(BOLD(TEXT("Entrée dans la boucle de messages")) EOL);
MSG msg;
@@ -3084,18 +3103,18 @@
startConsoleWin(true);
#endif // #if USE_CONSOLE==1
// Affiche divers renseignements pour le debogguage
- myprintf(TEXT("Compilé le : ") TEXT(__DATE__) TEXT(" ") TEXT(__TIME__) TEXT("\n"));
- myprintf(TEXT("Version : %s\n") , szAppVersion);
+ myprintf(TEXT("Compilé le : ") TEXT(__DATE__) TEXT(" ") TEXT(__TIME__) EOL);
+ myprintf(TEXT("Version : ") BOLD(TEXT("%s")) EOL , szAppVersion);
myprintf(
- TEXT("Tuner : %s\n")
- TEXT("Récepteur : %s\n")
- TEXT("Codec Vidéo MPEG2 : %s\n")
- TEXT("Codec Vidéo H264 : %s\n")
- TEXT("Codec Audio MPEG2 : %s\n")
- TEXT("Codec Audio AC3 : %s\n")
- TEXT("Codec Audio EAC3 : %s\n")
- TEXT("Ville : %s\n"),
+ TEXT("Tuner : ") COLR(HYELLOW, TEXT("%s")) EOL
+ TEXT("Récepteur : ") COLR(HYELLOW, TEXT("%s")) EOL
+ TEXT("Codec Vidéo MPEG2 : ") COLR(HCYAN, TEXT("%s")) EOL
+ TEXT("Codec Vidéo H264 : ") COLR(HCYAN, TEXT("%s")) EOL
+ TEXT("Codec Audio MPEG2 : ") COLR(HGREEN, TEXT("%s")) EOL
+ TEXT("Codec Audio AC3 : ") COLR(HGREEN, TEXT("%s")) EOL
+ TEXT("Codec Audio EAC3 : ") COLR(HGREEN, TEXT("%s")) EOL
+ TEXT("Ville : ") COLR(HBLUE, TEXT("%s")) EOL,
nom_tuner,
nom_receiver,
filtreMPEG2,
@@ -3104,7 +3123,10 @@
filtreAc3,
filtreEac3,
nomVille);
- myprintf(TEXT("Ligne de commande : [%s]\n"), GetCommandLine());
+ myprintf(
+ TEXT("Ligne de commande :") EOL
+ COLR(LGREEN, TEXT("%s")) EOL,
+ GetCommandLine());
#endif // #if USE_CONSOLE
// Initialisations d'instance d'application
@@ -3143,7 +3165,7 @@
delete [] cmdOptions;
cmdOptions = NULL; // Pas d'options en cas de redémarrage du programme
- myprintf(TEXT("%?\n############### (Redémarrage interne de l'application) #################\n\n"), eNeedRestart == nr_Partial);
+ myprintf(TEXT("%?") BOLD(TEXT("########### (Redémarrage interne de l'application) #############")) EOL EOL, eNeedRestart == nr_Partial);
} while (eNeedRestart == nr_Partial);
CleanInstance();
@@ -3156,11 +3178,11 @@
if (eNeedRestart == nr_Full) {
// Redémarrage demandé
- myprintf(TEXT("On redémarre !\n"));
+ myprintf(BOLD(TEXT("On redémarre !")) EOL);
Restart();
} else
// Pour témoigner qu'on est bien passés par ici en quittant :
- myprintf(TEXT("On quitte !\n"));
+ myprintf(BOLD(TEXT("On quitte !")) EOL);
return nRetCode;
}
Modifié: trunk/main.h
===================================================================
--- trunk/main.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/main.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -43,8 +43,22 @@
extern HICON hPrgIcon; //!< Icône normale du programme
extern HICON hRecIcon; //!< Icône utilisée en mode enregistrement
-extern bool is_vista; //!< \p true si on est sous Windows Vista
+enum WinVersion
+{
+ wv_Unknown,
+ wv_Older,
+ wv_2000,
+ wv_XP,
+ wv_Server2003,
+ wv_Vista,
+ wv_Server2008,
+ wv_Seven,
+ wv_Server2008R2,
+ wv_Newer
+};
+extern WinVersion eWinVers; //!< Version de Windows (décodage basique)
+
enum NeedRestart
{
nr_None,
Modifié: trunk/network.cpp
===================================================================
--- trunk/network.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/network.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -33,19 +33,19 @@
CPinBidon::CPinBidon(HRESULT *phr, CSource *pFilter) :
CSourceStream(TEXT("Pin de sortie d'antenne"), phr, pFilter, L"Antenna out")
{
- myprintf(TEXT("pin construit\n"));
+ myprintf(TEXT("CNetworkProvider : broche construite") EOL);
}
CPinBidon::~CPinBidon()
{
- myprintf(TEXT("pin detruit\n"));
+ myprintf(TEXT("CNetworkProvider : broche détruite") EOL);
}
HRESULT CPinBidon::CheckMediaType(const CMediaType *pmt)
{
-// myprintf(TEXT("CheckMediaType\n"));
+// myprintf(TEXT("CNetworkProvider : CheckMediaType") EOL);
if (*pmt->Type() == KSDATAFORMAT_TYPE_BDA_ANTENNA)
return S_OK;
return S_FALSE;
@@ -53,7 +53,7 @@
HRESULT CPinBidon::GetMediaType(int iPosition, CMediaType *pMediaType)
{
- myprintf(TEXT("GetMediaType %i\n"), iPosition);
+ myprintf(TEXT("CNetworkProvider : GetMediaType %i") EOL, iPosition);
if (iPosition == 0) {
pMediaType->SetType(&KSDATAFORMAT_TYPE_BDA_ANTENNA);
@@ -71,15 +71,17 @@
// fonction. C'est vaguement gênant quoique pas catastrophique, néanmoins si un jour
// on pouvait trouver un moyen élégant de traiter cette situation ...
+/*
#ifdef USE_CONSOLE
// Debugging - comptage "propre" (sans saut de ligne) du nombre de passages par cet endroit.
static UINT nCount = 0;
- LPBYTE ptr;
+ LPBYTE ptr;
+
pSamp->GetPointer(&ptr);
myprintf(TEXT("CPinBidon FillBuffer (size=%u, ptr=0x%08x) - count = %u \r"),
pSamp->GetSize(), ptr, ++nCount);
#endif
-
+*/
// Délai d'attente inséré par précaution : il a été constaté que sur certaines versions
// de Windows (en particulier sous Vista, quand on tourne en mode 32 bits dans un
// Vista 64 bits), la boucle d'appel du "thread" dans lequel on se trouve demande
@@ -96,12 +98,12 @@
HRESULT CPinBidon::DecideBufferSize(IMemAllocator * pAlloc,ALLOCATOR_PROPERTIES * ppropInputRequest)
{
- //myprintf(TEXT("CPinBidon DecideBufferSize\n"));
+ //myprintf(TEXT("CNetworkProvider : CPinBidon DecideBufferSize") EOL);
return S_OK;
}
CNetworkProvider::CNetworkProvider(IUnknown *pUnk, HRESULT *phr) :
- CSource(WCHAR2TCHAR(szFilterName), NULL, __uuidof(this))
+ CSource(TEXT(NETWORK_FILTER_NAME), NULL, __uuidof(this))
{
HRESULT hr;
m_bidon = new CPinBidon(&hr, this);
@@ -111,14 +113,14 @@
*phr = E_OUTOFMEMORY;
else {
*phr = S_OK;
- myprintf(TEXT("CNetworkProvider::CNetworkProvider : %s construit\n"), szFilterName);
+ myprintf(TEXT("CNetworkProvider : %") W2t TEXT(" construit") EOL, szFilterName);
}
}
}
CNetworkProvider::~CNetworkProvider()
{
- myprintf(TEXT("CNetworkProvider::~CNetworkProvider() : %s detruit\n"), szFilterName);
+ myprintf(TEXT("CNetworkProvider : %") W2t TEXT(" détruit") EOL, szFilterName);
delete m_bidon;
}
@@ -154,6 +156,6 @@
// Return a non-addref'd pointer to pin n
// needed by CBaseFilter
CBasePin *CNetworkProvider::GetPin(int n) {
-// myprintf(TEXT("CNetworkProvider::GetPin %i\n"), n);
+// myprintf(TEXT("CNetworkProvider::GetPin %i") EOL, n);
return (n==0) ? m_bidon : NULL;
}
Modifié: trunk/network.h
===================================================================
--- trunk/network.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/network.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -71,7 +71,7 @@
public:
CNetworkProvider(IUnknown *pUnk, HRESULT *phr);
- ~CNetworkProvider();
+ virtual ~CNetworkProvider();
int GetPinCount(void);
CBasePin *GetPin(int n);
Modifié: trunk/parse.cpp
===================================================================
--- trunk/parse.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/parse.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -54,7 +54,7 @@
int ixChaine = Canaux.trouve_par_Ids(sCIds);
UINT16 pid = se().pid();
- myprintf(TEXT("Service : 0x%04x, PMT PID : 0x%04x\n"), sCIds.SID, pid);
+ myprintf(TEXT("Service : 0x%04x, PMT PID : 0x%04x") EOL, sCIds.SID, pid);
if (ixChaine>=0)
Canaux[ixChaine].pmt_pid = pid;
}
@@ -179,9 +179,9 @@
UINT16 tsid = sdt.tsid(true); // transport_stream_id
UINT16 onid = sdt.onid(); // original_network_id
- myprintf(TEXT("Transport stream id : %i\n"), tsid);
- myprintf(TEXT("Onid : %i\n"), onid);
- myprintf(TEXT("chaînes : \n"));
+ myprintf(TEXT("Transport stream id : %i") EOL, tsid);
+ myprintf(TEXT("Onid : %i") EOL, onid);
+ myprintf(TEXT("chaînes : ") EOL);
for (streamScanner se(sdt.entryRange(true)); !se; ++se) {
for (descrScanner sd(se().descrRange()); !sd; sd++) {
@@ -198,7 +198,7 @@
d48.service_name().get(canal.nom);
canal.khz = khz;
- myprintf(TEXT("Groupe : %") A2t TEXT(", Chaine : %") A2t TEXT(", SID : %i\n"),
+ myprintf(TEXT("Groupe : %") A2t TEXT(", Chaine : %") A2t TEXT(", SID : %i") EOL,
canal.groupe, canal.nom, se().service_id());
// Tester si la chaîne est déjà dans la liste :
@@ -206,7 +206,7 @@
// Elle n'est pas dans la liste : on l'ajoute.
Canaux.push_back(canal);
} else
- myprintf(TEXT(" (%") A2t TEXT(" déjà dans la table des chaînes : ignoré)\n"), canal.nom);
+ myprintf(TEXT(" (%") A2t TEXT(" déjà dans la table des chaînes : ignoré)") EOL, canal.nom);
break;
}
@@ -223,7 +223,7 @@
if (sd().tag() == mdt_Network_Name) {
sd().as().get_network_name(nom);
if (*nom) {
- myprintf(TEXT("parse_nit: Nom réseau : %s\n"), nom);
+ myprintf(TEXT("parse_nit: Nom réseau : %s") EOL, nom);
cInfoNIT.strNetworkName = nom;
break;
}
@@ -236,16 +236,16 @@
chIDs.TSID = se().tsid();
chIDs.ONID = se().onid();
- // myprintf(TEXT("parse_nit: TSID=%i, ONID=%i, taille=%i\n"), chIDs.TSID, chIDs.ONID, se().dloop_length());
+ // myprintf(TEXT("parse_nit: TSID=%i, ONID=%i, taille=%i") EOL, chIDs.TSID, chIDs.ONID, se().dloop_length());
for (descrScanner sed(se().descrRange()); !sed; ++sed) {
- // myprintf(TEXT("parse_nit: type : %02X, taille : %i\n"), sed().tag(), sed().length);
+ // myprintf(TEXT("parse_nit: type : %02X, taille : %i") EOL, sed().tag(), sed().length);
if (sed().tag() == mdt_Logical_Channel) {
for (streamScanner seds(sed().as().subDescrRange()); !seds; ++seds) {
chIDs.SID = seds().service_id();
chIDs.nNumeroNit = seds().logical_channel_number();
- //myprintf(TEXT("parse_nit: ONID=%i, TSID=%i, SID=%i, numero=%i\n"),
+ //myprintf(TEXT("parse_nit: ONID=%i, TSID=%i, SID=%i, numero=%i") EOL,
// chIDs.ONID, chIDs.TSID, chIDs.SID, chIDs.nNumeroNit);
// On ne recherche pas les éventuels doublons : cette table est très provisoire,
@@ -293,7 +293,7 @@
sSStats.getStats();
if (sSStats.hr_1st!=S_OK) {
- log(TEXT("Erreur stats signal, hr=0x%08x, étapes=0x%02x\n"), sSStats.hr_1st, sSStats.nErrStep);
+ log(TEXT("Erreur stats signal, hr=0x%08x, étapes=0x%02x") EOL, sSStats.hr_1st, sSStats.nErrStep);
// return ss_error;
}
@@ -304,7 +304,7 @@
// toujours sous forme native)
sSStats.getStrengthStr(false, szStrength, _countof(szStrength), TEXT(""));
sSStats.getQualityStr(szQuality, _countof(szQuality), TEXT("%"));
- log(TEXT("%5u mS : Signal=%s, verrou=%s, force=%s, qualité=%s\n"), nTuneDelay,
+ log(TEXT("%5u mS : Signal=%s, verrou=%s, force=%s, qualité=%s") EOL, nTuneDelay,
sSStats.getPresentStr(), sSStats.getLockedStr(), szStrength, szQuality);
// Transmettre l'information de qualité du signal au dialogue de contrôle
@@ -338,7 +338,7 @@
HRESULT hr = pGraph->change_frequence(khz, &strErr);
if (FAILED(hr)) {
- log(TEXT("Erreur(s) au changement de fréquence : %s\n"), strErr.c_str());
+ log(TEXT("Erreur(s) au changement de fréquence : %s") EOL, strErr.c_str());
strErr.clear();
// return ss_error; // (apparemment certains tuners renvoient le code d'erreur alors qu'ils ont quand même changé la fréquence)
}
@@ -351,13 +351,13 @@
// réglés sur la fréquence exacte
if (eSState < ss_unlocked) {
khz += 5;
- log(TEXT("Pas de signal ; essai à +5 kHz = %i kHz\n"), khz);
+ log(TEXT("Pas de signal ; essai à +5 kHz = %i kHz") EOL, khz);
// Choppe le tunning space
hr = pGraph->change_frequence(khz, &strErr);
if (FAILED(hr)) {
- log(TEXT("Erreur(s) au changement de fréquence : %s\n"), strErr.c_str());
+ log(TEXT("Erreur(s) au changement de fréquence : %s") EOL, strErr.c_str());
// return ss_error;
}
@@ -367,12 +367,12 @@
// À ce stade, on quitte si le signal n'est même pas présent
if (eSState < ss_unlocked) {
- log(TEXT("Aucun signal détecté.\n"));
+ log(TEXT("Aucun signal détecté.") EOL);
return eSState;
}
}
- log(TEXT("Signal détecté : attente stabilisation.\n"));
+ log(TEXT("Signal détecté : attente stabilisation.") EOL);
int nTuneDelay = 0;
@@ -419,7 +419,7 @@
return false; // Pas reçu la SDT : inutile de continuer
if (prev_size >= Canaux.size()) {
- log(TEXT(" ** Aucun chaîne (supplémentaire) trouvée\n"));
+ log(TEXT(" ** Aucun chaîne (supplémentaire) trouvée") EOL);
return true;
}
@@ -452,18 +452,18 @@
// Logging des chaînes trouvées, et élimination des chaînes vides, ou bien dont le contenu n'est
// pas exploitable (note : ne pas sauver 'Canaux.size()' dans une variable car cette valeur peut
// diminuer au fil de l'exploration, si des chaînes invalides sont détruites) :
- log(TEXT(" ** Chaînes trouvées :\n"));
+ log(TEXT(" ** Chaînes trouvées :") EOL);
for (i = prev_size; i < Canaux.size(); i++) {
const Chaine & canal = Canaux[i];
log(TEXT(" -- %") A2t TEXT(" [groupe=%") A2t TEXT("],")
- TEXT(" OnId=%u, TsId=%u, SId=%u, vPId=%u, pPid=%u, pcrPid=%u\n"),
+ TEXT(" OnId=%u, TsId=%u, SId=%u, vPId=%u, pPid=%u, pcrPid=%u") EOL,
canal.nom, canal.groupe,
canal.ONID, canal.TSID, canal.SID, canal.video_pid, canal.pmt_pid, canal.pcr_pid);
if (canal.video_pid==0 && canal.video_type == vst_Unknown) {
//vire cette chaîne
- log(TEXT(" -- Invalide : destruction\n"));
+ log(TEXT(" -- Invalide : destruction") EOL);
Canaux.erase(Canaux.begin()+(i--));
} else {
TCHAR szWrk[128];
@@ -471,18 +471,18 @@
for (j=0; j= Canaux.size()) {
- log(TEXT(" ** Aucun chaîne valide trouvée\n"));
+ log(TEXT(" ** Aucun chaîne valide trouvée") EOL);
return true;
}
@@ -491,7 +491,7 @@
// Tenter d'attribuer les numéros NIT issue des multiplex précédents aux chaînes de celui-ci
if (place_numeros()) { // si au moins une chaîne n'a pas reçu de numéro, on recherche
// la table NIT du flux courant
- log(TEXT(" ** Numéro(s) de chaînes manquant(s) : lecture de la table NIT\n"));
+ log(TEXT(" ** Numéro(s) de chaînes manquant(s) : lecture de la table NIT") EOL);
PostMessage(hwndDlg, WM_APP_SCAN_NOTIFY, sn_info_nit, 0); // Pour déclencher affichage info "NIT"
handler.Init(p_pid_NIT, si_NIT, 10000, MAKEFOURCC('N','I','T',0));
while (handler.GetNextSection()) {
@@ -500,21 +500,21 @@
parse_nit(*reinterpret_cast(handler.data), cInfoNIT);
if (!cInfoNIT.strNetworkName.empty())
- log(TEXT(" -- Nom du réseau : %s\n"), cInfoNIT.strNetworkName.c_str());
+ log(TEXT(" -- Nom du réseau : %s") EOL, cInfoNIT.strNetworkName.c_str());
// Logging de ce qui a été trouvé :
UINT new_size = (UINT)cInfoNIT.size();
if (new_size>old_size) {
- log(TEXT(" -- Numéros trouvés :\n"));
+ log(TEXT(" -- Numéros trouvés :") EOL);
for (i = old_size; i < new_size; i++) {
const ChaineIdsNIT & sCIds = cInfoNIT[i];
- log(TEXT(" -- %3u pour SId=%4u (TsId=%2u, OnId=%4u)\n"),
+ log(TEXT(" -- %3u pour SId=%4u (TsId=%2u, OnId=%4u)") EOL,
sCIds.nNumeroNit, sCIds.SID, sCIds.TSID, sCIds.ONID);
}
} else
- log(TEXT(" -- Aucun numéro trouvé\n"));
+ log(TEXT(" -- Aucun numéro trouvé") EOL);
if (eScanState==ss_cancelling)
return false;
@@ -565,7 +565,7 @@
/// Sortir les informations concernant un filtre
void ChannelsScanner::logDeviceInfo(LPCTSTR pszTitle, LPCTSTR pszDevicePath)
{
- log(TEXT("\nPilote (%s) :\n"), pszTitle);
+ log(EOL TEXT("Pilote (%s) :") EOL, pszTitle);
CRegControlSet cRegCtlSet;
RegFilterInfo sFilterInfo;
@@ -580,7 +580,7 @@
if (nCnxLen<_countof(szCnx)) {
_tcsncpy_s(szCnx, pszDevicePath, nCnxLen);
szCnx[nCnxLen] = 0;
- log(TEXT(" -- Connexion : %s\n"), szCnx);
+ log(TEXT(" -- Connexion : %s") EOL, szCnx);
}
}
@@ -588,15 +588,15 @@
if (cRegCtlSet.GetDriverInfo(strDriverPath.c_str(), sFilterInfo)) {
if (!sFilterInfo.strDriverDesc.empty())
- log(TEXT(" -- Description : %s\n"), sFilterInfo.strDriverDesc.c_str());
+ log(TEXT(" -- Description : %s") EOL, sFilterInfo.strDriverDesc.c_str());
if (!sFilterInfo.strDriver.empty())
- log(TEXT(" -- Fichier(s) : %s\n"), sFilterInfo.strDriver.c_str());
+ log(TEXT(" -- Fichier(s) : %s") EOL, sFilterInfo.strDriver.c_str());
if (!sFilterInfo.strDriverVersion.empty())
- log(TEXT(" -- Version : %s\n"), sFilterInfo.strDriverVersion.c_str());
+ log(TEXT(" -- Version : %s") EOL, sFilterInfo.strDriverVersion.c_str());
if (!sFilterInfo.strDriverDate.empty())
- log(TEXT(" -- Date : %s\n"), sFilterInfo.strDriverDate.c_str());
+ log(TEXT(" -- Date : %s") EOL, sFilterInfo.strDriverDate.c_str());
if (!sFilterInfo.strProviderName.empty())
- log(TEXT(" -- Fabricant : %s\n"), sFilterInfo.strProviderName.c_str());
+ log(TEXT(" -- Fabricant : %s") EOL, sFilterInfo.strProviderName.c_str());
}
}
@@ -623,17 +623,17 @@
Canaux.clear();
}
- log(TEXT("\n############################################################################\n"));
+ log(EOL BOLD(TEXT("################################################################")) EOL);
time(&sTime);
if (localtime_s(&sTm, &sTime)==0) {
TCHAR szWrk[64];
_tcsftime(szWrk, _countof(szWrk), TEXT("%#c"), &sTm);
- log(TEXT("Début de la recherche : %s\n"), szWrk);
+ log(TEXT("Début de la recherche : %s") EOL, szWrk);
}
- log(TEXT(" [%s version %s]\n"), szAppName, szAppVersion);
- log(TEXT(" [Windows version %s]\n\n"), GetWindowsVersionStr(windows_version).c_str());
+ log(TEXT(" [%s version %s]") EOL, szAppName, szAppVersion);
+ log(TEXT(" [Windows version %s]") EOL EOL, GetWindowsVersionStr(windows_version).c_str());
CRegControlSet cRegCtlSet;
tstring strTunerDevicePath;
@@ -642,8 +642,8 @@
cRegCtlSet.GetDevicePath(KSCATEGORY_BDA_NETWORK_TUNER, nom_tuner, strTunerDevicePath);
cRegCtlSet.GetDevicePath(KSCATEGORY_BDA_RECEIVER_COMPONENT, nom_receiver, strReceiverDevicePath);
- log(TEXT("Tuner : %s\n"), nom_tuner);
- log(TEXT("Récepteur : %s\n"), nom_receiver);
+ log(TEXT("Tuner : %s") EOL, nom_tuner);
+ log(TEXT("Récepteur : %s") EOL, nom_receiver);
if (!strTunerDevicePath.empty() && !strReceiverDevicePath.empty()) {
if (strTunerDevicePath==strReceiverDevicePath)
@@ -656,23 +656,23 @@
}
}
- log(TEXT("\nOptions :\n")
- TEXT(" -- Ignorer présence du signal = %s\n")
- TEXT(" -- Ignorer signal verrouillé = %s\n")
- TEXT(" -- Ignorer qualité du signal = %s\n"),
+ log(EOL TEXT("Options :") EOL
+ TEXT(" -- Ignorer présence du signal = %s") EOL
+ TEXT(" -- Ignorer signal verrouillé = %s") EOL
+ TEXT(" -- Ignorer qualité du signal = %s") EOL,
boolToYesNo(scan_ignore_presence),
boolToYesNo(scan_ignore_lock),
boolToYesNo(scan_ignore_quality));
- log(TEXT(" -- Temps de stabilisation 1 = %u mS\n")
- TEXT(" -- Temps de stabilisation 2 = %u mS\n")
- TEXT(" -- Correction fréquence tuner = %i kHz (non inclus dans valeurs affichées)\n")
- // TEXT(" -- Utiliser fréquences paires = %s\n"),
- TEXT(" -- Essayer +5 kHz si échec = %s\n"),
+ log(TEXT(" -- Temps de stabilisation 1 = %u mS") EOL
+ TEXT(" -- Temps de stabilisation 2 = %u mS") EOL
+ TEXT(" -- Correction fréquence tuner = %i kHz (non inclus dans valeurs affichées)") EOL
+ // TEXT(" -- Utiliser fréquences paires = %s") EOL,
+ TEXT(" -- Essayer +5 kHz si échec = %s") EOL,
delai_tuner1, delai_tuner2, offset_tuner,
// boolToYesNo(use_even_frequencies),
boolToYesNo(try_adding_5khz));
- log(TEXT("\nCanaux/Ville : %s\n"),
+ log(EOL TEXT("Canaux/Ville : %s") EOL,
_tcscmp(nomVille, NULL_NAME)==0 ? TEXT("Tous") :
_tcscmp(nomVille, LIST_NAME)==0 ? liste_canaux : nomVille);
@@ -686,7 +686,7 @@
BYTE canal_no = liste_scan.aNoCan[nIndex];
INT32 khz = liste_scan.canal2khz(canal_no);
- log(TEXT("\nEssai du canal %u, fréquence = %i kHz\n"), canal_no, khz);
+ log(EOL TEXT("Essai du canal %u, fréquence = %i kHz") EOL, canal_no, khz);
prev_size = (UINT)Canaux.size(); // Mémoriser le nombre de chaînes déjà identifiées à cet instant
@@ -700,7 +700,7 @@
bool bSignalFound = tune(canal_no, khz, sSStats)==ss_signal_ok;
if (bSignalFound) {
- log(TEXT(" ** %s%sRecherche de canaux\n"),
+ log(TEXT(" ** %s%sRecherche de canaux") EOL,
(scan_ignore_presence ? TEXT("") : TEXT("Signal présent - ")),
(scan_ignore_lock ? TEXT("") : TEXT("Signal verrouillé - ")));
bSuccess = parse(canal_no, khz);
@@ -744,7 +744,7 @@
// en raison de sa situation, effectuer en plusieurs étapes, recherche qu'il pourrait alors
// vouloir compléter incrémentalement)
if ((methode_recherche==sm_prefs || methode_recherche==sm_incremental) && cInfoUser.size()>0) {
- log(TEXT("\nRestauration des préférences de l'utilisateur\n"));
+ log(EOL TEXT("Restauration des préférences de l'utilisateur") EOL);
SendMessage(hwndDlg, WM_APP_SCAN_NOTIFY, sn_restore, NULL);
restaure_prefs();
}
@@ -821,11 +821,11 @@
canal.nNumeroNit = nNumeroNit;
assigne_numero(i, nNumero, false);
if (nNumero==nNumeroNit) {
- log(TEXT("Assignation du numéro %u à la chaîne %") A2t TEXT(", d'après les informations du réseau\n"),
+ log(TEXT("Assignation du numéro %u à la chaîne %") A2t TEXT(", d'après les informations du réseau") EOL,
nNumero, canal.nom);
} else {
- log(TEXT("Le réseau assigne le numéro %u à la chaîne %") A2t TEXT(", mais celui-ci\n")
- TEXT(" est déjà utilisé ; attribution du numéro %u à la place\n"),
+ log(TEXT("Le réseau assigne le numéro %u à la chaîne %") A2t TEXT(", mais celui-ci") EOL
+ TEXT(" est déjà utilisé ; attribution du numéro %u à la place") EOL,
nNumeroNit, canal.nom, nNumero);
}
} else
@@ -856,7 +856,7 @@
if (canal.nNumeroChaine==0) {
UINT16 nNumero = nouveau_numero_chaine();
- log(TEXT("Attribution du numéro %u à la chaîne %") A2t TEXT(", qui n'en avait pas\n"),
+ log(TEXT("Attribution du numéro %u à la chaîne %") A2t TEXT(", qui n'en avait pas") EOL,
nNumero, canal.nom);
assigne_numero(i, nNumero, false);
}
@@ -936,12 +936,12 @@
if (canal.nNumeroChaine!=it->nNumeroChaine) {
assigne_numero(ixChaine, it->nNumeroChaine, true);
- log(TEXT(" -- Restauration préférence : numéro %u pour %") A2t TEXT ("\n"),
+ log(TEXT(" -- Restauration préférence : numéro %u pour %") A2t TEXT ("") EOL,
canal.nNumeroChaine, canal.nom);
}
if (canal.etat!=it->etat) {
canal.etat = it->etat;
- log(TEXT(" -- Restauration préférence : %") A2t TEXT (" = %") A2t TEXT ("\n"),
+ log(TEXT(" -- Restauration préférence : %") A2t TEXT (" = %") A2t TEXT ("") EOL,
canal.nom, EnumToString(canal.etat, "Inactive\0Active\0Préférée\0"));
}
}
Modifié: trunk/pmtfilter.cpp
===================================================================
--- trunk/pmtfilter.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/pmtfilter.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -37,14 +37,14 @@
#include "crc32.h"
CPMTFilter::CPMTFilter(IUnknown *pUnk, HRESULT *phr) :
- CBaseRenderer(__uuidof(this), WCHAR2TCHAR(szFilterName), pUnk, phr)
+ CBaseRenderer(__uuidof(this), TEXT(PMT_FILTER_NAME), pUnk, phr)
{
- myprintf(TEXT("%") W2t TEXT(" construit\n"), szFilterName);
+ myprintf(TEXT("%") W2t TEXT(" construit") EOL, szFilterName);
}
CPMTFilter::~CPMTFilter()
{
- myprintf(TEXT("%") W2t TEXT(" detruit\n"), szFilterName);
+ myprintf(TEXT("%") W2t TEXT(" detruit") EOL, szFilterName);
}
#define __WTXT(str) L##str
@@ -70,7 +70,7 @@
const SI_PMT * ppmt;
size_t taille = pMediaSample->GetActualDataLength();
-// myprintf(TEXT("PMT DoRenderSample %i\n"), taille);
+// myprintf(TEXT("PMT DoRenderSample %i") EOL, taille);
pMediaSample->GetPointer((LPBYTE *)(&ppmt));
if (
Modifié: trunk/pmtfilter.h
===================================================================
--- trunk/pmtfilter.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/pmtfilter.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -41,7 +41,7 @@
{
public:
CPMTFilter(IUnknown *pUnk, HRESULT *phr);
- ~CPMTFilter();
+ virtual ~CPMTFilter();
// Derived classes MUST override these
HRESULT DoRenderSample(IMediaSample *pMediaSample);
Modifié: trunk/record.cpp
===================================================================
--- trunk/record.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/record.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -162,6 +162,7 @@
ApresEnregistrement after = apr_null;
if (pGraph && recording()) {
+ myprintf(BOLD(TEXT("Arrêt d'enregistrement")) EOL);
after = apres;
#if USE_SINGLE_GRABBER
@@ -228,7 +229,7 @@
{
if (!pSample) {
HRESULT hr = pGrabber.QueryInterface(&pSample);
- myprintf(TEXT("%?erreur query pSample, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur query pSample, hr=0x%08x") EOL, FAILED(hr), hr);
}
}
@@ -342,7 +343,7 @@
if (!cRecord[nInx].recording())
return nInx;
}
- myprintf(TEXT("Plus aucun descripteur d'enregistrement disponible\n"));
+ myprintf(TEXT("Plus aucun descripteur d'enregistrement disponible") EOL);
return -1;
}
@@ -422,7 +423,7 @@
HANDLE hFile = nom_fichier.Create();
if (hFile == INVALID_HANDLE_VALUE) {
- myprintf(TEXT("Erreur création '%s' code %u\n"), nom_fichier.nom, GetLastError());
+ myprintf(ERRX(TEXT("Erreur création '%s' code %u")), nom_fichier.nom, GetLastError());
return -1;
}
@@ -432,7 +433,7 @@
if (pCapture==NULL)
return -1;
- myprintf(TEXT("Enregistre TS, video=%i, pmt=%i\n"), video, canal.pmt_pid);
+ myprintf(BOLD(TEXT("Enregistre TS")) TEXT(", video=%i, pmt=%i") EOL, video, canal.pmt_pid);
cRecord[ixRecDescr].start(pCapture, ixChaine, pProg);
return ixRecDescr;
}
@@ -469,7 +470,7 @@
HANDLE hFile = nom_fichier.Create();
if (hFile == INVALID_HANDLE_VALUE) {
- myprintf(TEXT("Erreur création '%s' code %u\n"), nom_fichier.nom, GetLastError());
+ myprintf(TEXT("Erreur création '%s' code %u") EOL, nom_fichier.nom, GetLastError());
return -1;
}
@@ -478,7 +479,7 @@
if (pCapture==NULL)
return -1;
- myprintf(TEXT("Enregistre PS, video=%i, audio=%i\n"), video_pid, audio_pid);
+ myprintf(BOLD(TEXT("Enregistre PS")) TEXT(", video=%i, audio=%i") EOL, video_pid, audio_pid);
cRecord[ixRecDescr].start(pCapture, ixChaine, pProg);
return ixRecDescr;
}
@@ -502,7 +503,7 @@
HANDLE hFile = nom_fichier.Create();
if (hFile == INVALID_HANDLE_VALUE) {
- myprintf(TEXT("Erreur création '%s' code %u\n"), nom_fichier.nom, GetLastError());
+ myprintf(TEXT("Erreur création '%s' code %u") EOL, nom_fichier.nom, GetLastError());
return -1;
}
@@ -511,7 +512,7 @@
if (pCapture==NULL)
return -1;
- myprintf(TEXT("Enregistre multiplex\n"));
+ myprintf(BOLD(TEXT("Enregistre multiplex")) EOL);
cRecord[ixRecDescr].start(pCapture, STREAM_PSEUDO_INDEX, pProg);
return ixRecDescr;
}
Modifié: trunk/recprog.cpp
===================================================================
--- trunk/recprog.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/recprog.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -217,7 +217,7 @@
{
tstring strMsg(pszMessage);
- strMsg += TEXT("\nVoulez-vous quand même effectuer cette programmation ?");
+ strMsg += EOL TEXT("Voulez-vous quand même effectuer cette programmation ?");
if (MessageBox(hMainWnd, strMsg.c_str(), TEXT("Avertissement"), MB_YESNO|MB_ICONWARNING)==IDNO)
return false;
@@ -368,7 +368,7 @@
hr = pITS.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER);
if (FAILED(hr)) {
- myprintf(TEXT("Erreur init task scheduler\n"));
+ myprintf(TEXT("Erreur init task scheduler") EOL);
return false;
}
// Supprime la tâche
@@ -379,7 +379,7 @@
}
if (FAILED(hr)) {
- myprintf(TEXT("Erreur création tâche %s\n"), taskName);
+ myprintf(TEXT("Erreur création tâche %s") EOL, taskName);
return false;
}
@@ -473,7 +473,7 @@
} else {
tache = planif_sans;
CheckDlgButton(hDlg, IDC_TACHE, BST_UNCHECKED);
- MessageBox(hDlg, TEXT("Vous n'avez pas saisi de mot de passe valide :\n")
+ MessageBox(hDlg, TEXT("Vous n'avez pas saisi de mot de passe valide :") EOL
TEXT("Cet enregistrement va être programmé sans ajout au gestionnaire des tâches."),
TEXT("Saisie de mot de passe annulée"), MB_ICONINFORMATION | MB_OK);
}
@@ -497,7 +497,7 @@
HRESULT hr = pITS.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER);
if (FAILED(hr)) {
- myprintf(TEXT("Erreur init task scheduler\n"));
+ myprintf(TEXT("Erreur init task scheduler") EOL);
return false;
}
@@ -608,7 +608,7 @@
**/
void set_timer_record()
{
- // myprintf(TEXT("Appel set_timer_record()\n"));
+ // myprintf(TEXT("Appel set_timer_record()") EOL);
SYSTEMTIME localtime;
@@ -620,12 +620,12 @@
if (reste==DUREE_INFINIE) {
KillTimer(hMainWnd, TIMER_DELAYED_RECORD);
- myprintf(TEXT("Aucun événement d'enregistrement en attente\n"));
+ myprintf(TEXT("Aucun événement d'enregistrement en attente") EOL);
} else {
// Si l'heure de début est déjà passée, on lance un timer qui aboutit immédiatement
long timer = min(max(reste, USER_TIMER_MINIMUM), DUREE_RECALCUL_TIMERS*1000);
- // myprintf(TEXT("Temps avant événement enreg : %i mS, timer = %i mS\n"), reste, timer);
+ // myprintf(TEXT("Temps avant événement enreg : %i mS, timer = %i mS") EOL, reste, timer);
SetTimer(hMainWnd, TIMER_DELAYED_RECORD, timer, NULL);
}
}
@@ -663,7 +663,7 @@
GetCtlTimeDate(hDlg, dateID, timeID, tempres);
long diff = DiffTime(tempres, result)/1000;
- myprintf(TEXT("GetCtlTimeDateChg, diff = %i S\n"), diff);
+ myprintf(TEXT("GetCtlTimeDateChg, diff = %i S") EOL, diff);
// Note : on ne traite le défilement rapide sur les heures que par unité, à cause de la
// difficulté à discriminer les sauts de 20 heures que le contrôle peut induire
@@ -1219,7 +1219,7 @@
// Récupération et vérification données du dialogue
if (prog.etat == epr_encours)
- MessageBox(hDlg, TEXT("Cet enregistrement est actuellement en cours.\n")
+ MessageBox(hDlg, TEXT("Cet enregistrement est actuellement en cours.") EOL
TEXT("Utilisez la commande \"Stopper l'enregistrement dans...\"")
TEXT(" pour y apporter des modifications maintenant."),
TEXT("Erreur lors de la modification"), MB_ICONERROR);
@@ -1626,7 +1626,7 @@
if (newSel!=CB_ERR && newSel!=edat.comboSel) {
if (edat.dlgEditState==des_needConfirm) {
switch (MessageBox(hDlg,
- TEXT("Vous avez apporté des modifications à la programmation de la chaîne en cours.\n")
+ TEXT("Vous avez apporté des modifications à la programmation de la chaîne en cours.") EOL
TEXT("Désirez-vous valider ces modifications ?"),
TEXT("Changement de chaîne"),
MB_YESNOCANCEL)) {
@@ -1907,7 +1907,7 @@
**/
bool do_record_events()
{
- // myprintf(TEXT("Appel do_record_events()\n"));
+ // myprintf(TEXT("Appel do_record_events()") EOL);
SYSTEMTIME localtime;
Modifié: trunk/recprog.h
===================================================================
--- trunk/recprog.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/recprog.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -104,9 +104,6 @@
* \param[in] prog_modif Si non NULL, pointeur sur la programmation qu'on modifie (pour
* éviter de la comparer à elle-même lors des tests de recouvrement)
* \retval \p true ou \p false selon succès ou échec, respectivement
- * \todo Ne plus interdire les programmations incompatibles pour cause de recouvrement
- * d'horaires. Se contenter de produire un avertissement qui peut être ignoré (laissant
- * ainsi à l'utilisateur la possibilité de résoudre l'incompatibilité a posteriori).
**/
bool verifie(const Programme * prog_modif=NULL) const;
Modifié: trunk/rendering.cpp
===================================================================
--- trunk/rendering.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/rendering.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -480,6 +480,8 @@
/// Initialisation générale
HRESULT CVideoRenderer::Init()
{
+ myprintf(TEXT("Initialisation du rendu vidéo (%s)") EOL, pszName);
+
// crée le VMR
HRESULT hr = CreateAndAdd();
if (FAILED(hr))
@@ -507,7 +509,10 @@
return hr;
// Récupération de la broche d'entrée (pour le ratio d'aspect)
- return cherche_pin(pFilter, PINDIR_INPUT, pInputPin);
+ hr = cherche_pin(pFilter, PINDIR_INPUT, pInputPin);
+
+ myprintf(TEXT("%?Rendu vidéo (%s) initialisé") EOL, SUCCEEDED(hr), pszName);
+ return hr;
}
/// Connexion à une sortie de codec
@@ -526,11 +531,11 @@
// = VFW_E_NO_ACCEPTABLE_TYPES ("There is no common media type between these pins")
if (FAILED(hr)) {
// Ici, on affiche l'erreur mais on ne quitte pas (ça laisse la possibilité d'enregistrer)
- affiche_erreurs(
- TEXT("Impossible de connecter le codec vidéo au VMR.\n")
- TEXT("C'est probablement l'overlay qui n'est pas disponible.\n\n")
- TEXT("Veuillez le libérer et relancer l'application"),
- hr);
+ erreur(
+ TEXT("Impossible de connecter le codec vidéo au module de\nrendu vidéo \"%s\".") EOL
+ TEXT("Le module d'affichage est incompatible ou indisponible.") EOL
+ TEXT("Veuillez résoudre le problème et relancer l'application"), hr, pszName);
+ affiche_erreurs(NULL);
hr = S_OK;
} else
bConnected = true;
@@ -581,7 +586,7 @@
FreeMediaType(am);
/*
- myprintf(TEXT("GetVideoInfo: ar=%i/%i, siz=%i/%i, type=%c%c%c%c\n"),
+ myprintf(TEXT("GetVideoInfo: ar=%i/%i, siz=%i/%i, type=%c%c%c%c") EOL,
sVInf.sAspectRatio.cx, sVInf.sAspectRatio.cy,
sVInf.sNativeSize.cx, sVInf.sNativeSize.cy,
LPCSTR(&am.subtype.Data1)[0], LPCSTR(&am.subtype.Data1)[1],
@@ -609,7 +614,7 @@
POINT ar = {sVInf.sAspectRatio.cx, sVInf.sAspectRatio.cy};
- // myprintf(TEXT("Aspect ratio: x=%i, y=%i\n"), ar.x, ar.y);
+ // myprintf(TEXT("Aspect ratio: x=%i, y=%i") EOL, ar.x, ar.y);
return ar;
}
@@ -645,7 +650,7 @@
// Calcule le rectangle de la vidéo :
RECT sRect = PlaceVideoInRect(CalcCliRect());
- // myprintf(TEXT("SetVideoPosition([") RECTFMT(",") TEXT("])\n"), RECTPARM(sRect));
+ // myprintf(TEXT("SetVideoPosition([") RECTFMT(",") TEXT("])") EOL, RECTPARM(sRect));
SetVideoPosition(&sRect, video_pan_mode==pm_Stretch);
}
@@ -657,6 +662,7 @@
class CVideoRendererWithBitmapOSD : public CVideoRenderer
{
HBITMAP hBmp; //!< Bitmap utilisé pour l'OSD
+ bool bBitmapSet; //!< \p true si un bitmap est chargé dans l'affichage
protected:
HDC hdcBmp; //!< "Device context" associé au bitmap
SIZE sBmpSize; //!< Dimensions actuelle du bitmap incrusté
@@ -678,6 +684,7 @@
CVideoRendererWithBitmapOSD(LPCTSTR pszNam, REFCLSID clsid) :
CVideoRenderer(pszNam, clsid),
hBmp(NULL),
+ bBitmapSet(false),
hdcBmp(NULL),
sBmpSize(SIZE()),
dwLastOsdSet(0)
@@ -1024,7 +1031,11 @@
HRESULT hr = SetAlphaBitmap(); // Incrustation du bitmap
- myprintf(TEXT("%?Échec SetAlphaBitmap (DrawOsdText) hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?") ERRX(TEXT("Échec SetAlphaBitmap (DrawOsdText) hr=0x%08x")) ERRX(TEXT("(%s)")),
+ FAILED(hr), hr, DShowErrorToString(hr).c_str());
+
+ if (!bBitmapSet && SUCCEEDED(hr))
+ bBitmapSet = true;
}
SelectObject(hdcBmp, hbmOld);
@@ -1034,10 +1045,16 @@
{
LimitOsdRate(); // Limitations du nombre de changements par seconde
- HRESULT hr = ClearAlphaBitmap();
+ if (bBitmapSet) {
+ HRESULT hr = ClearAlphaBitmap();
- myprintf(TEXT("%?Échec SetAlphaBitmap (ClearOsd) hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?") ERRX(TEXT("Échec SetAlphaBitmap (ClearOsd) hr=0x%08x")) ERRX(TEXT("(%s)")),
+ FAILED(hr), hr, DShowErrorToString(hr).c_str());
+ if (SUCCEEDED(hr))
+ bBitmapSet = false;
+ }
+
// Effacement du bitmap qui était conservé en mémoire :
ClearBitmap();
}
@@ -1145,7 +1162,7 @@
if (FAILED(hr))
return erreur(TEXT("Nombre de modes de désentrelacement non trouvé"), hr);
- myprintf(TEXT("Nombre de modes de désentrelacement : %i\n"), num);
+ myprintf(TEXT("Nombre de modes de désentrelacement : %i") EOL, num);
GUID guid[1];
num = 1;
@@ -1170,10 +1187,10 @@
return erreur(TEXT("L'interface de contrôle VMR n'est pas disponible"), hr);
hr = pVMR7Control->SetVideoClippingWindow(hMainWnd);
- myprintf(TEXT("%?erreur SetVideoClippingWindow, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetVideoClippingWindow, hr=0x%08x") EOL, FAILED(hr), hr);
hr = pVMR7Control->SetColorKey(colorKey);
- myprintf(TEXT("%?erreur SetColorKey, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetColorKey, hr=0x%08x") EOL, FAILED(hr), hr);
return hr;
}
@@ -1190,7 +1207,7 @@
HRESULT hr = pARC->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
return hr;
}
@@ -1203,11 +1220,11 @@
if (pVMR7Control) {
hr = pVMR7Control->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
if (pDstRect && !IsRectEmpty(pDstRect)) {
hr = pVMR7Control->SetVideoPosition(NULL, pDstRect);
- myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x") EOL, FAILED(hr), hr);
}
}
@@ -1236,7 +1253,7 @@
SIZE sSz = {768, 576}; // valeurs par défaut en cas d'erreur
HRESULT hr = pVMR7Control->GetNativeVideoSize(&sSz.cx, &sSz.cy, NULL, NULL);
- myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x") EOL, FAILED(hr), hr);
return sSz;
}
@@ -1295,7 +1312,7 @@
E_NOINTERFACE);
hr = pPresConf->SetRenderingPrefs(
- is_vista ?
+ eWinVers>=wv_Vista ?
RenderPrefs_AllowOffscreen :
(RenderPrefs_ForceOverlays | RenderPrefs_DoNotRenderColorKeyAndBorder)
);
@@ -1305,9 +1322,9 @@
}
hr = pNotify->AdviseSurfaceAllocator(0x118218, pSurfAlloc);
- myprintf(TEXT("%?erreur AdviseSurfaceAllocator, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur AdviseSurfaceAllocator, hr=0x%08x") EOL, FAILED(hr), hr);
hr = pSurfAlloc->AdviseNotify(pNotify);
- myprintf(TEXT("%?erreur AdviseNotify, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur AdviseNotify, hr=0x%08x") EOL, FAILED(hr), hr);
return hr;
}
@@ -1329,7 +1346,7 @@
if (SUCCEEDED(hr)) {
hr = pVMRConfig->SetRenderingPrefs(
- is_vista ?
+ eWinVers >= wv_Vista ?
RenderPrefs_AllowOffscreen :
(RenderPrefs_ForceOverlays | RenderPrefs_DoNotRenderColorKeyAndBorder)
);
@@ -1367,10 +1384,10 @@
}
hr = pVMR9Control->SetVideoClippingWindow(hMainWnd);
- myprintf(TEXT("%?erreur SetVideoClippingWindow, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetVideoClippingWindow, hr=0x%08x") EOL, FAILED(hr), hr);
hr = pVMR9Control->SetBorderColor(colorKey);
- myprintf(TEXT("%?erreur SetBorderColor, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetBorderColor, hr=0x%08x") EOL, FAILED(hr), hr);
if (FAILED(hr))
return hr;
@@ -1416,7 +1433,7 @@
HRESULT hr = pARC->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
return hr;
}
@@ -1433,7 +1450,7 @@
if (pVMR9Control) {
hr = pVMR9Control->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
if (pDstRect && !IsRectEmpty(pDstRect)) {
RECT rOldPos, rUnion;
@@ -1446,7 +1463,7 @@
!EqualRect(&rUnion, pDstRect);
hr = pVMR9Control->SetVideoPosition(NULL, pDstRect);
- myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x") EOL, FAILED(hr), hr);
// S'assurer que les bordures autour de l'image resteront noires :
if (bRedraw)
@@ -1486,7 +1503,7 @@
SIZE sSz = {768, 576}; // valeurs par défaut en cas d'erreur
HRESULT hr = pVMR9Control->GetNativeVideoSize(&sSz.cx, &sSz.cy, NULL, NULL);
- myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x") EOL, FAILED(hr), hr);
return sSz;
}
@@ -1498,7 +1515,7 @@
SIZE sSize = GetNativeSize();
- // myprintf(TEXT("GetBitmapSize, sSize: cx=%u/cy=%u\n"), sSize.cx, sSize.cy);
+ // myprintf(TEXT("GetBitmapSize, sSize: cx=%u/cy=%u") EOL, sSize.cx, sSize.cy);
return sSize;
}
@@ -1558,13 +1575,13 @@
}
hr = pEVRControl->SetVideoWindow(hMainWnd);
- myprintf(TEXT("%?erreur SetVideoWindow, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetVideoWindow, hr=0x%08x") EOL, FAILED(hr), hr);
if (FAILED(hr))
return hr;
hr = pEVRControl->SetBorderColor(colorKey);
- myprintf(TEXT("%?erreur SetBorderColor, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetBorderColor, hr=0x%08x") EOL, FAILED(hr), hr);
if (FAILED(hr))
return hr;
@@ -1594,7 +1611,7 @@
HRESULT hr = E_FAIL;
if (pEVRControl) {
hr = pEVRControl->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
}
return hr;
}
@@ -1608,7 +1625,7 @@
if (pEVRControl) {
hr = pEVRControl->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
if (pDstRect && !IsRectEmpty(pDstRect)) {
RECT rOldPos, rUnion;
@@ -1622,7 +1639,7 @@
!EqualRect(&rUnion, pDstRect);
hr = pEVRControl->SetVideoPosition(&rSource, pDstRect);
- myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x") EOL, FAILED(hr), hr);
// S'assurer que les bordures autour de l'image resteront noires :
if (bRedraw) {
@@ -1693,7 +1710,7 @@
SIZE sAr = {4, 3}; // valeurs par défaut en cas d'erreur
HRESULT hr = pEVRControl->GetNativeVideoSize(&sSz, &sAr);
- myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x\n"), FAILED(hr), hr);
+ myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x") EOL, FAILED(hr), hr);
// Ajustement de la taille horizontale, d'une manière similaire à ce qui semble être fait dans la fonction
// "GetNativeVideoSize" des autres modes ; passage par un type "double" car les valeurs utilisées pour
@@ -1712,7 +1729,7 @@
SIZE sSize = GetNativeSize();
- // myprintf(TEXT("GetBitmapSize, sSize: cx=%u/cy=%u\n"), sSize.cx, sSize.cy);
+ // myprintf(TEXT("GetBitmapSize, sSize: cx=%u/cy=%u") EOL, sSize.cx, sSize.cy);
return sSize;
}
@@ -1752,7 +1769,7 @@
{
if (pVMR)
// si le VMR existe, on lui délègue la tâche (même si on
- // sait qu'il va peut-être nous la réassigner)
+ // sait qu'il va peut-être la réassigner à l'OSD)
pVMR->Paint(hDC);
else if (pOSD)
// sinon, on fait juste dans l'OSD
@@ -1767,15 +1784,17 @@
{
if (!pGraph)
return E_FAIL;
- if (use_osd && !pOSD)
+ if (use_osd && !pOSD) {
+ myprintf(TEXT("Initialisation de l'OSD") EOL);
pOSD = new COsdAllObjects();
+ }
HRESULT hr = S_OK;
if (!pVMR) { // si pas déjà initialisé
- OAFilterState eState = pGraph->graph_GetState();
+ bool bRunning = pGraph->graph_isRunning();
- if (eState!=State_Stopped)
+ if (bRunning)
hr = pGraph->graph_Stop();
switch (vmr_mode) {
@@ -1804,10 +1823,11 @@
hr = pVMR->Init();
if (SUCCEEDED(hr)) {
- if (SUCCEEDED(hr) && eState==State_Running)
+ if (SUCCEEDED(hr) && bRunning)
hr = pGraph->graph_Run();
} else {
// Échec de l'initialisation du VMR
+ myprintf(TEXT("Échec de l'initialisation du rendu vidéo") EOL);
delete pVMR;
pVMR = NULL;
}
@@ -1823,16 +1843,16 @@
**/
void clean_vmr()
{
- if (pVMR) {
- delete pVMR;
- pVMR = NULL;
- }
-
// Destruction des objets OSD :
if (pOSD) {
delete pOSD;
pOSD = NULL;
}
+
+ if (pVMR) {
+ delete pVMR;
+ pVMR = NULL;
+ }
}
/**
@@ -1848,19 +1868,17 @@
HRESULT hr = S_OK;
if (pVMR) { // si pas déjà initialisé
- OAFilterState eSavState = pGraph->graph_GetState();
+ bool bRunning = pGraph->graph_isRunning();
- if (/*true ||*/ eSavState!=State_Stopped) {
- if ((hr = pGraph->graph_Stop()) != S_OK)
- return erreur(TEXT("Arrêt du graphe impossible"), hr);
- }
+ if (bRunning && (hr = pGraph->graph_Stop()) != S_OK)
+ return erreur(TEXT("Arrêt du graphe impossible"), hr);
if (FAILED(hr = pVMR->Disconnect()))
return erreur(TEXT("Erreur lors du retrait du codec vidéo précédent"), hr);
if (sDData.pFilter) { // Si le codec existe, bien sûr
if (FAILED(hr = pVMR->Connect(sDData.pFilter)))
return erreur(TEXT("Erreur lors de l'ajout du codec %") A2t, hr, sDData.pszType);
}
- if ((hr = pGraph->graph_Run())!=S_OK)
+ if (bRunning && (hr = pGraph->graph_Run())!=S_OK)
return erreur(TEXT("Redémarrage du graphe impossible"), hr);
}
return hr;
Modifié: trunk/rendering.h
===================================================================
--- trunk/rendering.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/rendering.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -130,7 +130,9 @@
FilterData(pszNam, clsid),
last_tick(0),
bConnected(false)
- {}
+ {
+ myprintf(TEXT("Construction du rendu vidéo (%s)") EOL, pszName);
+ }
/// Signifier au VMR que le mode d'affichage a changé
virtual HRESULT DisplayModeChanged() {
@@ -195,7 +197,8 @@
void UpdateVideoPos();
/// Destructeur
- virtual ~CVideoRenderer() {}
+ virtual ~CVideoRenderer() {
+ myprintf(TEXT("Destruction du rendu vidéo (%s)") EOL, pszName);}
};
// ====================================================================================
Modifié: trunk/res.rc
===================================================================
--- trunk/res.rc 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/res.rc 2009-08-13 22:39:40 UTC (rev 201)
@@ -76,12 +76,12 @@
MENUITEM "C&odec vidéo H264…", IDM_H264
MENUITEM "Codec a&udio MPEG2…", IDM_MP2A
MENUITEM "Codec audio &AC3…", IDM_AC3
- MENUITEM "Codec audio EAC3…", IDM_EAC3
+ MENUITEM "Codec audio &EAC3…", IDM_EAC3
MENUITEM SEPARATOR
MENUITEM "&Rendu vidéo…", IDM_VMR
MENUITEM "Rendu &audio…", IDM_DSOUND
MENUITEM SEPARATOR
- MENUITEM "D&émultiplexeur…", IDM_DEMUX
+ MENUITEM "&Démultiplexeur…", IDM_DEMUX
END
POPUP "C&ommandes"
BEGIN
Modifié: trunk/search.cpp
===================================================================
--- trunk/search.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/search.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -64,7 +64,7 @@
{
hr = pMapper.CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC);
if (FAILED(hr)) {
- myprintf(TEXT("CSearchByType, CoCreateInstance, hr=0x%08x\n"), hr);
+ myprintf(ERRX(TEXT("CSearchByType, CoCreateInstance, hr=0x%08x")), hr);
return;
}
@@ -88,7 +88,7 @@
NULL); // Output pin category.
if (FAILED(hr)) {
- myprintf(TEXT("CSearchByType, EnumMatchingFilters, hr=0x%08x\n"), hr);
+ myprintf(ERRX(TEXT("CSearchByType, EnumMatchingFilters, hr=0x%08x")), hr);
return;
}
}
@@ -176,13 +176,13 @@
{
hr = pDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER);
if (FAILED(hr)) {
- myprintf(TEXT("CSearchByCategory, ICreateDevEnum : hr=0x%08x\n"), hr);
+ myprintf(ERRX(TEXT("CSearchByCategory, ICreateDevEnum : hr=0x%08x")), hr);
return;
}
hr = pDevEnum->CreateClassEnumerator(clsid, &pEnumMoniker, 0);
if (FAILED(hr) || pEnumMoniker == NULL) {
- myprintf(TEXT("CSearchByCategory, erreur création Enum Moniker : hr=0x%08x\n"), hr);
+ myprintf(ERRX(TEXT("CSearchByCategory, erreur création Enum Moniker : hr=0x%08x")), hr);
return;
}
}
Modifié: trunk/search.h
===================================================================
--- trunk/search.h 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/search.h 2009-08-13 22:39:40 UTC (rev 201)
@@ -127,9 +127,10 @@
pFilter(pFltr)
{
myprintf(
- TEXT("CSearchByType_Get: type=") GUIDFMT TEXT("\n")
- TEXT("\tsubtype=") GUIDFMT TEXT("\n\tnom=%s\n"),
- GUIDPARM(type), GUIDPARM(subtype), pszSrch);
+ TEXT("CSearchByType_Get: nom=%s") EOL
+ TEXT(" type=") GUIDFMT EOL
+ TEXT(" subtype=") GUIDFMT EOL,
+ pszSrch, GUIDPARM(type), GUIDPARM(subtype));
pFltr.Release(); // précaution
}
@@ -248,7 +249,7 @@
virtual HRESULT ApplyOne(CComPtr & pCurFltr, LPCTSTR pszName)
{
if (filtre_compat(pCurFltr)!=compat_None) {
- myprintf(TEXT("CSearchByCategory_FillVector : %s\n"), pszName);
+ myprintf(TEXT("CSearchByCategory_FillVector : %s") EOL, pszName);
AddToVector(vStrFiltres, pszName);
}
return S_OK;
@@ -278,8 +279,9 @@
pFilter(pFltr)
{
myprintf(
- TEXT("CSearchByCategory_Get: clsid=") GUIDFMT TEXT(",\n\tnom=%s\n"),
- GUIDPARM(clsid), pszSrch);
+ TEXT("CSearchByCategory_Get: nom=%s") EOL
+ TEXT(" clsid=") GUIDFMT EOL,
+ pszSrch, GUIDPARM(clsid));
pFltr.Release(); // précaution
}
Modifié: trunk/settings.cpp
===================================================================
--- trunk/settings.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/settings.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -653,7 +653,7 @@
iItemEmpty = ListView_InsertItem(hListItem, &item);
}
- myprintf(TEXT("ChannelsLVDrag construit\n"));
+ myprintf(TEXT("ChannelsLVDrag construit") EOL);
}
/**
@@ -720,7 +720,7 @@
ImageList_DragEnter(GetDesktopWindow(), p.x, p.y);
SetCapture(hDlg); // Capture de la souris
- myprintf(TEXT("ChannelsLVDrag::Begin\n"));
+ myprintf(TEXT("ChannelsLVDrag::Begin") EOL);
}
/**
@@ -884,7 +884,7 @@
**/
int ChannelsLVDrag::End(LONG x, LONG y)
{
- myprintf(TEXT("ChannelsLVDrag::End\n"));
+ myprintf(TEXT("ChannelsLVDrag::End") EOL);
KillTimer(hDlg, TIMER_CHAN_LVDRAG);
ImageList_DragLeave(hListItem);
@@ -931,7 +931,7 @@
}
// Redessiner tout le contrôle contenant les chaînes :
InvalidateRect(hListItem, NULL, TRUE);
- myprintf(TEXT("ChannelsLVDrag détruit\n"));
+ myprintf(TEXT("ChannelsLVDrag détruit") EOL);
}
/**
@@ -969,7 +969,7 @@
ListView_GetItemText(hListItem, iItem, CHAN_COL_NO, buf2, _countof(buf2));
_stprintf_s(bufmsg, _countof(bufmsg),
TEXT("Le nouveau numéro que vous assignez à la chaîne %s est déjà attribué ")
- TEXT("à la chaîne %s.\nConfirmez-vous le changement ?\n")
+ TEXT("à la chaîne %s.\nConfirmez-vous le changement ?") EOL
TEXT("(les numéros seront alors échangés : la chaîne %s recevra le numéro %s)"),
chnom1, chnom2, chnom2, buf2);
confirm = MessageBox(hDlg, bufmsg,
@@ -1426,7 +1426,9 @@
changed |= extrait_combo(GetDlgItem(hDlg, IDC_COMBO_AC3), filtreAc3, _countof(filtreAc3), true);
changed |= extrait_combo(GetDlgItem(hDlg, IDC_COMBO_EAC3), filtreEac3, _countof(filtreEac3), true);
- myprintf(TEXT("Tuner: %s\nReceiver: %s\nVideo: %s\nAudio: %s\nAc3: %s\nEac3: %s\n"),
+ myprintf(
+ TEXT("Nouvelle configuration :\nTuner : %s\nReceiver : %s\nVideo : %s") EOL
+ TEXT("Audio : %s\nAc3 : %s\nEac3 : %s") EOL,
nom_tuner, nom_receiver, filtreMPEG2, filtreAudio, filtreAc3, filtreEac3);
if (changed && _tcsstr(filtreMPEG2, TEXT("ffdshow")) && _tcsstr(filtreH264, TEXT("ffdshow"))) {
@@ -1479,18 +1481,18 @@
tstring strListeAbsents;
if (!remplit_combo_tuner(hTuner, KSCATEGORY_BDA_NETWORK_TUNER, nom_tuner))
- strListeAbsents += tstr_printf(TEXT("\n- %s"), nom_tuner);
+ strListeAbsents += tstr_printf(EOL TEXT("- %s"), nom_tuner);
if (!remplit_combo_tuner(hReceiver, KSCATEGORY_BDA_RECEIVER_COMPONENT, nom_receiver))
- strListeAbsents += tstr_printf(TEXT("\n- %s"), nom_receiver);
+ strListeAbsents += tstr_printf(EOL TEXT("- %s"), nom_receiver);
if (!remplit_combo_filtre(hMpeg2, MEDIATYPE_Video, MEDIASUBTYPE_MPEG2_VIDEO, filtreMPEG2))
- strListeAbsents += tstr_printf(TEXT("\n- %s"), filtreMPEG2);
+ strListeAbsents += tstr_printf(EOL TEXT("- %s"), filtreMPEG2);
remplit_combo_filtre(hH264, MEDIATYPE_Video, MEDIASUBTYPE_H264, filtreH264);
if (!remplit_combo_filtre(hAudio, MEDIATYPE_Audio, MEDIASUBTYPE_MPEG2_AUDIO, filtreAudio))
- strListeAbsents += tstr_printf(TEXT("\n- %s"), filtreAudio);
+ strListeAbsents += tstr_printf(EOL TEXT("- %s"), filtreAudio);
if (!remplit_combo_filtre(hAc3, MEDIATYPE_Audio, MEDIASUBTYPE_DOLBY_AC3, filtreAc3))
- strListeAbsents += tstr_printf(TEXT("\n- %s"), filtreAc3);
+ strListeAbsents += tstr_printf(EOL TEXT("- %s"), filtreAc3);
if (!remplit_combo_filtre(hEac3, MEDIATYPE_Audio, MEDIASUBTYPE_DOLBY_DDPLUS, filtreEac3))
- strListeAbsents += tstr_printf(TEXT("\n- %s"), filtreEac3);
+ strListeAbsents += tstr_printf(EOL TEXT("- %s"), filtreEac3);
// Cherche s'il n'y a qu'un élément dans la liste
// Le sélectionne si oui
@@ -1503,8 +1505,8 @@
if (!strListeAbsents.empty()) {
strListeAbsents.insert(0,
- TEXT("Au moins un filtre, précédemment défini, n'est plus disponible.\n")
- TEXT("Veuillez effectuer une autre sélection.\n")
+ TEXT("Au moins un filtre, précédemment défini, n'est plus disponible.") EOL
+ TEXT("Veuillez effectuer une autre sélection.") EOL
TEXT("Liste des filtres manquants :"));
MessageBox(hDlg, strListeAbsents.c_str(), TEXT("Filtres non disponibles"),
MB_OK|MB_ICONEXCLAMATION);
@@ -1554,7 +1556,7 @@
if (extrait_combo(GetDlgItem(hDlg, IDC_COMBO_TUNER), szWrk, _countof(szWrk), false) &&
!IsNullName(szWrk))
if (ePSN_KILLACTIVE_discriminator == epkd_pagechange) {
- MessageBox(hDlg, TEXT("Le tuner sélectionné a été modifié.\n")
+ MessageBox(hDlg, TEXT("Le tuner sélectionné a été modifié.") EOL
TEXT("Vous devez appliquer les changements avant de poursuivre."),
TEXT("Tuner modifié"), MB_OK);
return psn_result(hDlg, TRUE);
@@ -1735,7 +1737,7 @@
case _cmd_(IDC_SCAN_DEFAULT, BN_CLICKED):
if (MessageBox(hDlg,
- TEXT("Tous les paramètres de cette page vont être réinitialisés à leur valeur par défaut.\n")
+ TEXT("Tous les paramètres de cette page vont être réinitialisés à leur valeur par défaut.") EOL
TEXT("Confirmez-vous cette demande ?"),
TEXT("Confirmation réinitialisation"), MB_YESNO)==IDYES)
{
@@ -2130,7 +2132,7 @@
// Si la recherche est annulée par l'utilisateur, alors on recharge
// le fichier de chaînes précédent :
lit_chaines();
- restaure_chaine(cleChaine);
+ zappe_index(Canaux.trouve_restauration_par_cle(cleChaine));
}
EndDialog(hDlg, cancelCode); // IDCANCEL = annulé sans scan,
// IDABORT = annulé après tentative de scan
@@ -2243,8 +2245,8 @@
AddLineToList(hListItem, msg_aucune);
} else {
EnableWindow(hOkBut, nNewChannelsTotal!=0);
- do_init_vmr();
- restaure_chaine(cleChaine);
+
+ zappe_index(Canaux.trouve_restauration_par_cle(cleChaine));
if (nNewChannels==0) {
if (methode_recherche==sm_incremental)
AddLineToList(hListItem, TEXT("Aucune chaîne supplémentaire n'a été trouvée"));
@@ -2650,7 +2652,7 @@
def.ToString(szRaccourci);
_stprintf_s(buffer,
- TEXT("Le raccourci «%s» est déjà affecté à l'action «%s».\n\n")
+ TEXT("Le raccourci «%s» est déjà affecté à l'action «%s».") EOL EOL
TEXT("Voulez-vous le remplacer ?"), szRaccourci, item.nom);
if (MessageBox(hDlg, buffer, TEXT("Raccourci déjà utilisé"), MB_YESNO) == IDYES) {
@@ -2921,7 +2923,7 @@
void SetOSDState(HWND hDlg)
{
VMRTypes eSelMode = GetVMRSel(hDlg);
- bool bCanUseOSD = !is_vista || eSelMode!=vmt_VMR7_renderless && eSelMode!=vmt_VMR7_windowless;
+ bool bCanUseOSD = eWinVers < wv_Vista || eSelMode!=vmt_VMR7_renderless && eSelMode!=vmt_VMR7_windowless;
EnableWindow(GetDlgItem(hDlg, IDC_USE_OSD), bCanUseOSD);
EnableWindow(GetDlgItem(hDlg, IDC_USE_OSD_S), bCanUseOSD);
Modifié: trunk/trayicon.cpp
===================================================================
--- trunk/trayicon.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/trayicon.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -47,7 +47,7 @@
if (hMainWnd != NULL) {
hWnd = hMainWnd;
uID = MY_TRAY_ICON_ID;
- //myprintf(TEXT("MyNOTIFYICONDATA::notify() - msg=%u, flg=0x%02x\n"), dwMessage, uFlags);
+ //myprintf(TEXT("MyNOTIFYICONDATA::notify() - msg=%u, flg=0x%02x") EOL, dwMessage, uFlags);
return Shell_NotifyIcon(dwMessage, this)==TRUE;
}
return false;
Modifié: trunk/update.cpp
===================================================================
--- trunk/update.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/update.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -168,7 +168,7 @@
{
TCHAR fichierBackup[MAX_PATH]; // Fichier temporaire
- myprintf(TEXT("Remplace «%s» par «%s» en %s\n"), original, nouveau, backup ? TEXT("sauvegardant") : TEXT("effaçant"));
+ myprintf(TEXT("Remplace «%s» par «%s» en %s") EOL, original, nouveau, backup ? TEXT("sauvegardant") : TEXT("effaçant"));
// Nom du fichier de backup
strcpy_T(fichierBackup, original);
@@ -200,7 +200,7 @@
{
DWORD dwEcrit; // Variable recevant le nombre d'octets écrits
- myprintf(TEXT("Sauvegarde «%s» depuis un téléchargement de %u octets\n"), nom, vContenu.size());
+ myprintf(TEXT("Sauvegarde «%s» depuis un téléchargement de %u octets") EOL, nom, vContenu.size());
// Sauvegarde du fichier
HANDLE hFile = CreateFile(nom, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
@@ -235,7 +235,7 @@
{
TCHAR fichierTemp[MAX_PATH]; // Fichier temporaire
- myprintf(TEXT("Remplace «%s» depuis un téléchargement de %u octets\n"), original, vContenu.size());
+ myprintf(TEXT("Remplace «%s» depuis un téléchargement de %u octets") EOL, original, vContenu.size());
// Nom du fichier de mise à jour
strcpy_T(fichierTemp, original);
@@ -356,18 +356,18 @@
ConnexionInternet maj(ConvertChar2UTF8(url).c_str()); // Objet traitant de la connexion Internet
#endif
- myprintf(TEXT("Téléchargement de «%s»\n"), url);
+ myprintf(TEXT("Téléchargement de «%s»") EOL, url);
int http_statut = maj.EnvoieRequete();
if (http_statut != maj.HTTP_ERR_OK) {
if (http_statut == 0) {
AddMsg(TEXT("Erreur lors de l'établissement de la connexion."));
- myprintf(TEXT("Erreur connexion\n"));
+ myprintf(ERRX(TEXT("Erreur connexion")));
} else {
AddMsg(TEXT("Erreur %d lors du téléchargement du fichier."), http_statut);
AddMsg(TEXT("Veuillez réessayer ultérieurement..."));
- myprintf(TEXT("Erreur connexion: erreur HTTP: %d\n"), http_statut);
+ myprintf(ERRX(TEXT("Erreur connexion: erreur HTTP: %d")), http_statut);
}
stoppe = true;
}
@@ -605,7 +605,7 @@
bool bUpdateNodeFound = false;
bool bUpdateFound = false;
- myprintf(TEXT("Vérification pour la version %s\n"), pszDispType);
+ myprintf(TEXT("Vérification pour la version %s") EOL, pszDispType);
for (ITERATE_XML_ELEMENTS_NAMED(xmlVersionDocument.FirstChildElement("Versions"), xmlVersionElem, "version")) {
if (!CheckVersionVersion(*xmlVersionElem))
continue;
@@ -629,7 +629,7 @@
}
if (!bUpdateNodeFound)
AddMsg(TEXT("Aucune information de mise à jour %s disponible"), pszDispType);
- myprintf(TEXT("%s version %s\n"), (bUpdateFound ? TEXT("Trouvé") : TEXT("Pas trouvé")), pszDispType);
+ myprintf(TEXT("%s version %s") EOL, (bUpdateFound ? TEXT("Trouvé") : TEXT("Pas trouvé")), pszDispType);
return bUpdateFound;
}
@@ -662,7 +662,7 @@
if (UpdateTraiteAppNode(action, "stable", TEXT("stable")))
retval |= UPDATE_APP_FLAG;
- myprintf(TEXT("retval=0x%02x, bWithBeta=%u\n"), retval, bWithBeta);
+ myprintf(TEXT("retval=0x%02x, bWithBeta=%u") EOL, retval, bWithBeta);
if (retval==0 && bWithBeta) {
// Si (et seulement si) aucune version stable n'a été trouvée, et que l'utilisateur
Modifié: trunk/xml.cpp
===================================================================
--- trunk/xml.cpp 2009-08-08 15:14:15 UTC (rev 200)
+++ trunk/xml.cpp 2009-08-13 22:39:40 UTC (rev 201)
@@ -43,7 +43,7 @@
CXMLElement::CXMLElement(IXMLDOMElement * element) :
m_ele(element)
{
-// myprintf(TEXT("élément contruit\n"));
+// myprintf(TEXT("élément contruit") EOL);
}
/**
@@ -51,7 +51,7 @@
**/
CXMLElement::~CXMLElement()
{
-// myprintf(TEXT("élément détruit\n"));
+// myprintf(TEXT("élément détruit") EOL);
}
/**
@@ -95,7 +95,7 @@
CXMLNode::CXMLNode(IXMLDOMNode * element) :
m_node(element)
{
-// myprintf(TEXT("noeud construit\n"));
+// myprintf(TEXT("noeud construit") EOL);
}
/**
@@ -103,7 +103,7 @@
**/
CXMLNode::~CXMLNode()
{
-// myprintf(TEXT("noeud détruit\n"));
+// myprintf(TEXT("noeud détruit") EOL);
}
/**
@@ -302,7 +302,7 @@
{
m_doc.CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER);
-// myprintf(TEXT("wrapper contruit\n"));
+// myprintf(TEXT("wrapper contruit") EOL);
}
/**
@@ -310,7 +310,7 @@
**/
CXMLWrapper::~CXMLWrapper()
{
-// myprintf(TEXT("wrapper détruit\n"));
+// myprintf(TEXT("wrapper détruit") EOL);
}
/**
From pouchintv-dev at baysse.fr Sun Aug 30 19:09:45 2009
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: Sun, 30 Aug 2009 17:09:45 -0000
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r202 - in trunk: . Icones
Message-ID: <20090830170937.647466EFF3@mail.baysse.fr>
Author: gingko
Date: 2009-08-30 19:09:36 +0200 (dim 30 aoû 2009)
New Revision: 202
Added:
trunk/Icones/Fr3 PaysLoire.bmp
trunk/Icones/Fr3 Poitiers.bmp
Modified:
trunk/changelog.html
trunk/channels.cpp
trunk/channels.h
trunk/console.h
trunk/filters.cpp
trunk/grabber.cpp
trunk/grabber.h
trunk/graph.cpp
trunk/graph.h
trunk/ini.cpp
trunk/ini.h
trunk/main.cpp
trunk/parse.h
trunk/record.cpp
trunk/record.h
trunk/rendering.cpp
trunk/settings.cpp
Log:
Corrections de bugs + ajout d'icônes.
channels.cpp :
* Correction d'un bug introduit récemment, qui provoquait un plantage à l'issue d'une
recherche de chaînes en présence d'un tiner nouvellement installé (aucune chaîne
préexistante).
graph.cpp :
* Correction d'un bug provoquant un plantage si la fenêtre de qualité du signal est
ouverte pendant les redémarrages du graphe.
ini.h, ini.cpp :
* Ajout de fonctions "set_running_state" et "get_running_state" en vue de l'implémentation
prochaine d'une détection de plantages au redémarrage.
console.h :
* Ajout d'une macro "CMyP" pour ajouter les préfixes "%?" indiquant des sorties de
debugging conditionnelles.
main.cpp :
* L'affichage de la version de Windows, en mode debugging, était tronqué pour cause
de transition CHAR -> TCHAR incorrecte (sauf SBCS).
* Utilisation de la variable ixChaineAvance (déjà existante) en remplacement de la variable
locale ixChaineStartup, en prévision d'une évolution à venir.
parse.h :
* Commentaires ajoutés ou modifiés.
settings.cpp :
* Changement mineurs
Nombreux fichiers :
* Les macros de compilation conditionnelle USE_SINGLE_GRABBER et USE_THREAD_IN_GRABBER
sont supprimées, validant en principe définitivement les modifications correspondantes.
* Ajout de surlignements supplémentaires de messages d'erreur en mode debugging.
Ajout des icônes "Fr3 PaysLoire.bmp" et "Fr3 Poitiers.bmp" en doublon de "France 3.bmp",
pour la même raison que dans la livraison précédente avec "France3.bmp".
Ajouté: trunk/Icones/Fr3 PaysLoire.bmp
===================================================================
(les fichiers binaires diffèrent)
Property changes on: trunk/Icones/Fr3 PaysLoire.bmp
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Ajouté: trunk/Icones/Fr3 Poitiers.bmp
===================================================================
(les fichiers binaires diffèrent)
Property changes on: trunk/Icones/Fr3 Poitiers.bmp
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Modifié: trunk/changelog.html
===================================================================
--- trunk/changelog.html 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/changelog.html 2009-08-30 17:09:36 UTC (rev 202)
@@ -56,6 +56,17 @@
Changements réalisés pour la version 0.5
+ - 0.5.202 (expérimentale, publiée via le service de mise à jour le 30 août 2009) :
+
+ - Correction d'un bug introduit récemment, qui provoquait un plantage à l'issue
+ d'unerecherche de chaînes en présence d'un tiner nouvellement installé (aucune
+ chaîne préexistante).
+ - Correction d'un bug provoquant un plantage si la fenêtre de qualité du signal est
+ ouverte pendant les redémarrages du graphe.
+ - Icônes
Fr3 PaysLoire
et Fr3 Poitiers
ajoutées en doublon de France 3
.
+
+
+
- 0.5.201 (expérimentale, publiée dans le forum le 14 août 2009) :
- Optimisation du démarrage du graphe, qui devrait être un peu plus rapide.
Modifié: trunk/channels.cpp
===================================================================
--- trunk/channels.cpp 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/channels.cpp 2009-08-30 17:09:36 UTC (rev 202)
@@ -478,7 +478,7 @@
myprintf(BOLD(TEXT("Branchement des sorties audio et vidéo")) EOL);
- if (suspendu) {
+ if (suspendu && ixChaine_ok(ixChaineCourante)) {
HRESULT hr = Canaux[ixChaineCourante].branche(reset_son);
if (FAILED(hr))
@@ -528,7 +528,7 @@
if (!pGraph)
return E_FAIL;
if ( !ixChaine_ok(ixChaine) && ixChaine != -1) {
- myprintf(TEXT("change_chaine(%d) invalide"), ixChaine);
+ myprintf(ERRX(TEXT("change_chaine(%d) invalide")), ixChaine);
return E_FAIL;
}
bool freq_differente = true;
@@ -565,7 +565,7 @@
tstring strErr;
#endif
pGraph->change_frequence(nouveau_canal.khz IF_CONSOLE_CB(&strErr));
- myprintf(TEXT("%?") ERRX(TEXT("Erreur(s) change_frequence : %s")), !strErr.empty(), strErr.c_str());
+ myprintf(CMyP ERRX(TEXT("Erreur(s) change_frequence : %s")), !strErr.empty(), strErr.c_str());
}
ixChaineCourante = ixChaine_ok(ixChaine) ? ixChaine : -1;
Modifié: trunk/channels.h
===================================================================
--- trunk/channels.h 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/channels.h 2009-08-30 17:09:36 UTC (rev 202)
@@ -289,9 +289,9 @@
extern Chaines Canaux;
extern int ixChaineCourante; //!< Index de la chaîne couramment utilisée
-extern int ixChaineAvance; /*!< Index de la chaîne pendant les transitions de zapping
- (normalement identique à \p ixChaineCourante, sauf entre la
- sélection d'une chaîne et l'application de cette sélection) */
+extern int ixChaineAvance; /*!< Index de la chaîne pendant les transitions de zapping, ainsi qu'en
+ phase de démarrage (normalement identique à \p ixChaineCourante, sauf
+ entre la sélection d'une chaîne et l'application de cette sélection) */
extern int ixSonCourant; //!< Index de la piste sonore couramment utilisée
Modifié: trunk/console.h
===================================================================
--- trunk/console.h 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/console.h 2009-08-30 17:09:36 UTC (rev 202)
@@ -52,24 +52,9 @@
/// Caractère "fin de ligne"
#define EOL TEXT("\n")
-#define HBLACK "30;1" // Gris foncé, en fait
-#define HRED "31;1"
-#define HGREEN "32;1"
-#define HYELLOW "33;1"
-#define HBLUE "34;1"
-#define HMAGENTA "35;1"
-#define HCYAN "36;1"
-#define HWHITE ";1" // Devrait être "37;1", mais le blanc étant "par défaut", la surbrillance suffit
+/// "myprintf" conditionnel (à son 1er argument)
+#define CMyP TEXT("%?")
-#define LBLACK ";30" // Noir sur fond noir ...
-#define LRED ";31"
-#define LGREEN ";32"
-#define LYELLOW ";33" // Plutôt brun/ocre
-#define LBLUE ";34"
-#define LMAGENTA ";35"
-#define LCYAN ";36"
-#define LWHITE "0" // Blanc normal (tout par défaut), =";37"
-
#if USE_CONSOLE==1
/** \defgroup SeqAnsi Macros de synthèse de séquences ANSI
@@ -78,6 +63,26 @@
#define CSI TEXT("\x1b[") //!< Début de séquence
+// (noter que débuter par un ";" équivaut à placer un 0 devant)
+
+#define HBLACK "30;1" //!< Noir haute intensité (gris foncé, en fait)
+#define HRED "31;1" //!< Rouge haute intensité
+#define HGREEN "32;1" //!< Vert haute intensité
+#define HYELLOW "33;1" //!< Jaune haute intensité
+#define HBLUE "34;1" //!< Bleu haute intensité
+#define HMAGENTA "35;1" //!< Magenta haute intensité
+#define HCYAN "36;1" //!< Cyan haute intensité
+#define HWHITE ";1" //!< Blanc haute intensité (devrait être "37;1", mais le blanc étant "par défaut", la surbrillance suffit)
+
+#define LBLACK ";30" //!< Noir normal (= noir sur fond noir ...)
+#define LRED ";31" //!< Rouge normal
+#define LGREEN ";32" //!< Vert normal
+#define LYELLOW ";33" //!< Jaune normal (plutôt brun/ocre, en fait)
+#define LBLUE ";34" //!< Bleu normal
+#define LMAGENTA ";35" //!< Magenta normal
+#define LCYAN ";36" //!< Cyan normal
+#define LWHITE "0" //!< Blanc normal (tout par défaut), =";37"
+
/** \brief "Select Graphic Rendition" (définit une couleur).
*
* \param[in] clr Couleur (suite de chiffres ANSI séparés par des ";".
Modifié: trunk/filters.cpp
===================================================================
--- trunk/filters.cpp 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/filters.cpp 2009-08-30 17:09:36 UTC (rev 202)
@@ -135,7 +135,7 @@
HRESULT hr = pMap->MapPID(1, &pid, eMsc);
- myprintf(TEXT("%?") ERRX(TEXT("Échec branchement pid=%u sur broche %") A2t TEXT(", hr=0x%08x")), FAILED(hr), pid, pszType, hr);
+ myprintf(CMyP ERRX(TEXT("Échec branchement pid=%u sur broche %") A2t TEXT(", hr=0x%08x")), FAILED(hr), pid, pszType, hr);
return hr;
}
@@ -221,31 +221,32 @@
HRESULT hr = pFilter->EnumPins(&pEnumPins);
if (FAILED(hr)) {
- myprintf(TEXT("cherche_pin, 1, hr=0x%08x") EOL, hr);
+ myprintf(ERRX(TEXT("Erreur cherche_pin/EnumPins hr=0x%08x")), hr);
return hr;
}
- for (
- CComPtr pPin;
- (hr = pEnumPins->Next(1, &pPin, NULL))==S_OK;
- pPin.Release()
- ) {
+ for (ENUM_ITF(pEnumPins, IPin, pPin)) {
PIN_DIRECTION direction;
- pPin->QueryDirection(&direction);
+ if (FAILED(hr = pPin->QueryDirection(&direction))) {
+ myprintf(ERRX(TEXT("Erreur cherche_pin/QueryDirection, hr=0x%08x")), hr);
+ break;
+ }
if (direction == dir) {
if (pmt) {
// write_pin_info(pPin);
CComPtr connected;
- pPin->ConnectedTo(&connected);
-
- if (!connected) {
+ if ((hr = pPin->ConnectedTo(&connected)) == VFW_E_NOT_CONNECTED) {
+ hr = S_OK;
if (pmt==NOTCONNECTED || check_pin_for_media(pPin, *pmt)) {
result = pPin;
break;
}
+ } else if (FAILED(hr)) {
+ myprintf(ERRX(TEXT("Erreur cherche_pin/ConnectedTo, hr=0x%08x")), hr);
+ break;
}
} else {
result = pPin;
Modifié: trunk/grabber.cpp
===================================================================
--- trunk/grabber.cpp 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/grabber.cpp 2009-08-30 17:09:36 UTC (rev 202)
@@ -30,33 +30,16 @@
#include "grabber.h"
#include "record.h"
-
-#if USE_THREAD_IN_GRABBER
#include "memfifo.h"
-#endif
/// Constructeur de base
-#if USE_SINGLE_GRABBER
CSampleGrabber::CSampleGrabber() :
-#else
-CSampleGrabber::CSampleGrabber(CCapture * pCapt) :
-#endif
CUnknown(TEXT("Sample grabber"), NULL),
-#if USE_SINGLE_GRABBER
hMutex(CreateMutex(NULL, FALSE, NULL)),
-#else
- pCapture(pCapt),
-#endif
-#if USE_THREAD_IN_GRABBER
hThread(NULL),
-#endif
taille_paquet_buf(0)
{
-#if USE_SINGLE_GRABBER
myprintf(TEXT("## Construction CSampleGrabber") EOL);
-#else
- myprintf(TEXT("## Construction CSampleGrabber, pCapture=0x%08x") EOL, pCapture);
-#endif
}
STDMETHODIMP CSampleGrabber::SampleCB(double SampleTime, IMediaSample *pSample) // virtual
@@ -66,7 +49,7 @@
// (note : pSample->IsDiscontinuity ne semble pas donner d'informations significatives sur les
// tuners testés, mais qui sait d'autres tuners donneront peut-être des résultats meilleurs)
- myprintf(TEXT("%?SampleCB : Discontinuité") EOL, pSample->IsDiscontinuity()==S_OK);
+ myprintf(CMyP TEXT("SampleCB : Discontinuité") EOL, pSample->IsDiscontinuity()==S_OK);
// myprintf(TEXT("Echantillon SampleCB, t=%f, taille %u (%u paquets, frag=%u)") EOL, SampleTime, l, l/TS_SIZE, l%TS_SIZE);
@@ -74,12 +57,7 @@
BYTE * p;
pSample->GetPointer(&p);
-
-#if USE_THREAD_IN_GRABBER
cMemFifo.Put(l, p);
-#else
- traite_sample(l, p);
-#endif
}
return S_OK;
}
@@ -138,7 +116,6 @@
**/
void CSampleGrabber::traite_paquet(const TS_packet & p) // virtual
{
-#if USE_SINGLE_GRABBER
if (Lock()) {
for (int nInx=0; nInx < enregistrements_actuels.count(); ++nInx) {
Enregistrement & sRec = enregistrements_actuels[nInx];
@@ -148,13 +125,8 @@
}
Unlock();
}
-#else // USE_SINGLE_GRABBER
- if (pCapture)
- pCapture->traite_paquet(p);
-#endif // USE_SINGLE_GRABBER
}
-#if USE_SINGLE_GRABBER
/// Verrouillage de l'accès aux descripteurs d'enregistrements pendant l'accès ou la modification
/// à ceux-ci.
bool CSampleGrabber::Lock()
@@ -167,10 +139,7 @@
{
ReleaseMutex(hMutex);
}
-#endif // USE_SINGLE_GRABBER
-#if USE_THREAD_IN_GRABBER
-
DWORD CSampleGrabber::GrabThread()
{
myprintf(TEXT("## Entrée dans CSampleGrabber::GrabThread") EOL);
@@ -226,24 +195,12 @@
return true;
}
-#endif // USE_THREAD_IN_GRABBER
-
/// Destructeur général
CSampleGrabber::~CSampleGrabber()
{
-#if USE_THREAD_IN_GRABBER
StopThread(); // S'assurer de l'arrêt du "thread"
-#endif // USE_THREAD_IN_GRABBER
-#if USE_SINGLE_GRABBER
myprintf(TEXT("## Destruction CSampleGrabber") EOL);
CloseHandle(hMutex);
hMutex = NULL;
-#else
- myprintf(TEXT("## Destruction CSampleGrabber, pCapture=0x%08x") EOL, pCapture);
- if (pCapture) {
- delete pCapture;
- pCapture = NULL;
- }
-#endif
}
Modifié: trunk/grabber.h
===================================================================
--- trunk/grabber.h 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/grabber.h 2009-08-30 17:09:36 UTC (rev 202)
@@ -29,12 +29,8 @@
#pragma once
#include "capture.h"
-#include "graph.h" // pour USE_SINGLE_GRABBER & USE_THREAD_IN_GRABBER
+#include "memfifo.h"
-#if USE_THREAD_IN_GRABBER
- #include "memfifo.h"
-#endif
-
/// Classe implémentant les méthodes "callback" à associer à un "Sample grabber"
class CSampleGrabber : public CUnknown, public ISampleGrabberCB // The Filter Interface
{
@@ -78,20 +74,12 @@
// --- Données et méthodes propres à l'application ---
//
-#if USE_SINGLE_GRABBER
HANDLE hMutex; //!< Mutex protégeant les débuts et fins d'enregistrements
-#else
- CCapture * pCapture; //!< Pointeur sur la classe de traitement des paquets TS capturés
-#endif
-#if USE_THREAD_IN_GRABBER
HANDLE hThread;
-#endif
BYTE taille_paquet_buf; //!< Longueur du paquet partiel mémorisé
TS_packet paquet_buf; //!< Tampon de mémorisation de paquet partiel
-#if USE_THREAD_IN_GRABBER
-
CMemFifo cMemFifo; //!< Buffer "First In First Out" de mémorisation des échantillons reçus
/// Fonction d'exécution principale statique du 'thread'.
@@ -107,8 +95,8 @@
/// Arrêt du "thread" de capture
bool StopThread();
+
private:
-#endif // USE_THREAD_IN_GRABBER
/**
* Traitement d'un échantillon reçu du tuner
@@ -126,7 +114,7 @@
void traite_paquet(const TS_packet & p);
public:
-#if USE_SINGLE_GRABBER
+
/// Constructeur de base
CSampleGrabber();
@@ -136,10 +124,6 @@
/// Libération de l'accès aux descripteurs d'enregistrements
void Unlock();
-#else
- /// Constructeur de base
- CSampleGrabber(CCapture * pCapt);
-#endif
/// Destructeur général
virtual ~CSampleGrabber();
Modifié: trunk/graph.cpp
===================================================================
--- trunk/graph.cpp 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/graph.cpp 2009-08-30 17:09:36 UTC (rev 202)
@@ -43,9 +43,7 @@
#include
#include // Pour log10() dans calcul du volume sonore
-#if USE_SINGLE_GRABBER
- #include "grabber.h"
-#endif
+#include "grabber.h"
#include
@@ -719,9 +717,7 @@
protected:
CComPtr pStats;
-#if USE_SINGLE_GRABBER
GrabberData sGrabber;
-#endif
FilterData sDemux;
DecoderData sMp2vCodec;
@@ -850,11 +846,9 @@
**/
virtual void create_property_dialog(FilterType eFltType);
-#if USE_SINGLE_GRABBER
/// Obtenir l'interface du grabber
virtual GrabberData & GetGrabberInterface() {
return sGrabber;}
-#endif
/**
* Obtenir l'interface \p Mpeg2Data (pour la recherche de chaînes)
@@ -869,7 +863,8 @@
HRESULT Build();
/// Destructeur
- virtual ~CPTvM_TunerGraph() {}
+ virtual ~CPTvM_TunerGraph() {
+ }
};
/// Constructeur
@@ -1001,16 +996,18 @@
clean_vmr();
-#if USE_SINGLE_GRABBER==0
- // Libère les interfaces d'enregistrements
- for (int i=0; i < enregistrements_actuels.count(); i++) {
- enregistrements_actuels[i].release();
- }
-#endif
-
myprintf(TEXT("Destruction du graphe") EOL);
- delete pGraph; // #### Destruction effective
+
+ // Éviter les accès au graphe pendant la destruction
+ IPTvM_TunerGraph * pTmpGraph = pGraph;
+
pGraph = NULL;
+ delete pTmpGraph; // #### Destruction effective
+ #ifdef _DEBUG
+ Sleep(200);
+ DbgDumpObjectRegister();
+ DbgTerminate();
+ #endif
}
// ====================================================================================
@@ -1098,7 +1095,8 @@
if (bFindExisting) {
hr = cherche_pin(sDemux.pFilter, PINDIR_OUTPUT, pOutPin, sDData.pAmt);
if (hr != E_FAIL) {
- myprintf(TEXT("%?Broche existante trouvée pour \"") BOLD(TEXT("%") W2t) TEXT("\"") EOL, SUCCEEDED(hr), sDData.pszPinName);
+ myprintf(CMyP TEXT("Broche existante trouvée pour \"") BOLD(TEXT("%") W2t) TEXT("\"") EOL,
+ SUCCEEDED(hr), sDData.pszPinName);
return hr;
}
}
@@ -1107,7 +1105,8 @@
// "CreateOutputPin" modifie les objets pointés.
hr = iMp2Demux.CreateOutputPin(const_cast(sDData.pAmt),
const_cast(sDData.pszPinName), &pOutPin);
- myprintf(TEXT("%?Broche \"") BOLD(TEXT("%") W2t) TEXT("\" créée pour ") BOLD(TEXT("%") A2t) EOL, SUCCEEDED(hr), sDData.pszPinName, sDData.pszType);
+ myprintf(CMyP TEXT("Broche \"") BOLD(TEXT("%") W2t) TEXT("\" créée pour ") BOLD(TEXT("%") A2t) EOL,
+ SUCCEEDED(hr), sDData.pszPinName, sDData.pszType);
if (FAILED(hr))
return erreur(TEXT("La broche %") A2t TEXT(" n'a pas pu être créée"), hr, sDData.pszType);
return hr;
@@ -1328,6 +1327,10 @@
myprintf(BOLD(TEXT("Arrêt du graphe")) EOL);
+#ifdef _DEBUG
+ // DumpGraph(pFGrph, 3);
+#endif
+
HRESULT hr = pControl->Stop();
if (SUCCEEDED(hr))
@@ -1585,7 +1588,6 @@
{
HRESULT hr;
-#if USE_SINGLE_GRABBER
FilterData sGrabberFilter(TEXT("Grabber"), CLSID_SampleGrabber);
hr = create_and_add_filter(sGrabberFilter);
@@ -1606,28 +1608,6 @@
if (sGrabber.pCallback==NULL)
return erreur(TEXT("L'interface de callback du grabber n'a pas pu être créée"), E_FAIL);
pLastAddedFilter = sGrabberFilter.pFilter; // Mémoriser pour connexion suivante
-
-#else
- for (int i=0; i < enregistrements_actuels.count(); i++) {
- TCHAR nom[20];
-
- _stprintf_s(nom, _countof(nom), TEXT("Grabber %u"), i);
-
- FilterData sGrabberFilter(nom, CLSID_SampleGrabber);
-
- if (FAILED(hr = create_and_add_filter(sGrabberFilter)))
- return hr;
-
- hr = connect_filters(pLastAddedFilter, sGrabberFilter.pFilter);
- if (FAILED(hr))
- return erreur(
- TEXT("Le grabber n'a pas pu être connecté à la carte TNT, ")
- TEXT("veuillez effacer \"%s%s\" et redémarrer"), hr, prefix_conf, config_file);
-
- enregistrements_actuels[i].query(sGrabberFilter.pFilter);
- pLastAddedFilter = sGrabberFilter.pFilter; // Mémoriser pour connexion suivante
- }
-#endif
return hr;
}
@@ -1691,6 +1671,10 @@
if (pGraph)
return E_FAIL; // Déjà existant
+ #ifdef _DEBUG
+ DbgInitialise(hAppInstance);
+ #endif
+
if (autre_graphe)
pGraph = new CLegacyTunerGraph();
else
Modifié: trunk/graph.h
===================================================================
--- trunk/graph.h 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/graph.h 2009-08-30 17:09:36 UTC (rev 202)
@@ -45,11 +45,6 @@
#define USE_AUTO_RETUNE 1 //!< Resyntonisation automatique
-#define USE_SINGLE_GRABBER 1 //!< Tests réduction à un seul filtre pour enregistrer
-#define USE_THREAD_IN_GRABBER 1 /*!< \brief Le "grabber" délègue l'enregistrement à un "thread" distinct
- \note Utiliser de préférence avec \p USE_SINGLE_GRABBER, car
- sinon on va créer trois threads ! */
-
#define USE_PMTFILTER 1 //!< Activation/désactivation filtre PMT
/**
@@ -231,10 +226,8 @@
**/
virtual void create_property_dialog(FilterType eFltType) = 0;
-#if USE_SINGLE_GRABBER
/// Obtenir l'interface du grabber
virtual GrabberData & GetGrabberInterface() = 0;
-#endif
/**
* Obtenir l'interface \p Mpeg2Data (pour la recherche de chaînes)
Modifié: trunk/ini.cpp
===================================================================
--- trunk/ini.cpp 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/ini.cpp 2009-08-30 17:09:36 UTC (rev 202)
@@ -435,12 +435,14 @@
#define CONFIG_VAL(val) reinterpret_cast(val)
// Sections dans le fichier de config
-static LPCTSTR ini_config_section = TEXT("Config"); ///< Nom de la section contenant la configuration
-static LPCTSTR ini_shortcut_section = TEXT("Raccourcis"); ///< Nom de la section contenant les raccourcis clavier
-static LPCTSTR ini_dontshow_section = TEXT("Désactiver"); ///< Nom de la section des messages à ne plus afficher
+static LPCTSTR ini_config_section = TEXT("Config"); //!< Nom de la section contenant la configuration
+static LPCTSTR ini_shortcut_section = TEXT("Raccourcis"); //!< Nom de la section contenant les raccourcis clavier
+static LPCTSTR ini_dontshow_section = TEXT("Désactiver"); //!< Nom de la section des messages à ne plus afficher
-static LPCTSTR ini_color_num = TEXT("Couleur Perso %02u"); ///< Nom de sauvegarde des couleurs perso
+static LPCTSTR ini_color_num = TEXT("Couleur Perso %02u"); //!< Nom de sauvegarde des couleurs perso
+static LPCTSTR ini_running = TEXT("Exécution"); //!< Nom de sauvegarde de l'état "en cours d'exécution"
+
/// Liste des items sauvegardés globalement
static ConfigItem ini_general_items[] =
{ // Nom Type Défaut Variable Extra
@@ -1809,7 +1811,35 @@
// Liste des chaînes définies
// ====================================================================================
+#if STREAMS_SAVE_ALL
/**
+ * Lecture de la liste de pistes d'un type donné.
+ * \param[in] cNode Noeud XML
+ * \param[in] sPistes Liste de pistes
+ * \param[in] pszTagStr Partie spécifique du tag XML à utiliser
+ **/
+static void lit_pistes(CXMLNode & cNode, liste_pistes & sPistes, LPCTSTR pszTagStr)
+{
+ TCHAR szTmp[16];
+
+ _stprintf_s(szTmp, TEXT("Nb_%s"), pszTagStr);
+ sPistes.nbr = (WORD)cNode.getInt(szTmp);
+ for (int i=0; igetInt(TEXT("Nb_Son"));
- for (int i=0;igetInt(var);
-
- _stprintf_s(var, _countof(var), TEXT("Son%i_Type"), i);
- canal_son.type = (TrackStreamType)pNode->getInt(var);
-
- _stprintf_s(var, _countof(var), TEXT("Son%i_Lang"), i);
- pNode->getStr(var, canal_son.lang, _countof(canal_son.lang));
- }
- // Récupère les autres information
- canal.autr.nbr = (WORD)pNode->getInt(TEXT("Nb_Autre"));
- for (int i=0;igetInt(var);
-
- _stprintf_s(var, _countof(var), TEXT("Autre%i_Lang"), i);
- pNode->getStr(var, canal_autre.lang, _countof(canal_autre.lang));
- }
+ lit_pistes(*pNode, canal.sons, TEXT("Son"));
+ // Récupère les autres informations
+ lit_pistes(*pNode, canal.autr, TEXT("Autre"));
#endif
// Mémorise le canal généré
@@ -1914,7 +1923,30 @@
return S_OK;
}
+#if STREAMS_SAVE_ALL
/**
+ * Sauvegarde de la liste de pistes d'un type donné.
+ * \param[in] oxml Noeud XML
+ * \param[in] sPistes Liste de pistes
+ * \param[in] pszTagStr Partie spécifique du tag XML à utiliser
+ **/
+static void sauve_pistes(CXMLOutput & oxml, const liste_pistes & sPistes, LPCSTR pszTagStr)
+{
+ oxml.put(oxml.fmt("Nb_%s", pszTagStr), sPistes.nbr);
+
+ // Mémorise toutes les pistes sons
+ for (int j=0; j=0;
- // Sélectionner la chaîne qu'on va sélectionner au démarrage
- int ixChaineStartup = -1; // Index de cette chaîne
-
+ // Déterminer la chaîne qu'on va sélectionner au démarrage
if (cmdOptions && cmdOptions->nChaine > 0) {
// Un numéro de chaîne passé en paramètre est prioritaire sur la chaîne
// courante sauvegardée dans la configuration
- ixChaineStartup = Canaux.trouve_par_no((WORD)cmdOptions->nChaine);
+ ixChaineAvance = Canaux.trouve_par_no((WORD)cmdOptions->nChaine);
} else
- ixChaineStartup = Canaux.trouve_restauration_par_cle(cleChaineConfig);
+ ixChaineAvance = Canaux.trouve_restauration_par_cle(cleChaineConfig);
VideoStreamType eVideoInitialType = vst_MPEG2; // valeur par défaut
- if (ixChaine_ok(ixChaineStartup))
- eVideoInitialType = Canaux[ixChaineStartup].video_type;
+ if (ixChaine_ok(ixChaineAvance))
+ eVideoInitialType = Canaux[ixChaineAvance].video_type;
for (;;) {
if (!config_ok) {
@@ -2962,7 +2959,7 @@
update_filtres_menus(hMainMenu);
// Sélectionner la chaîne
- zappe_index(ixChaineStartup);
+ zappe_index(ixChaineAvance);
// Régler le volume
if (pGraph)
@@ -3165,7 +3162,7 @@
delete [] cmdOptions;
cmdOptions = NULL; // Pas d'options en cas de redémarrage du programme
- myprintf(TEXT("%?") BOLD(TEXT("########### (Redémarrage interne de l'application) #############")) EOL EOL, eNeedRestart == nr_Partial);
+ myprintf(CMyP BOLD(TEXT("########### (Redémarrage interne de l'application) #############")) EOL EOL, eNeedRestart == nr_Partial);
} while (eNeedRestart == nr_Partial);
CleanInstance();
Modifié: trunk/parse.h
===================================================================
--- trunk/parse.h 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/parse.h 2009-08-30 17:09:36 UTC (rev 202)
@@ -32,29 +32,39 @@
#include "graph.h"
#include "mpeg2defs.h"
+/**
+ * Analyse d'une table PMT reçue dans le flux TS, en vue de déterminer le format du flux vidéo
+ * \param[in] pmt Table à analyser
+ * \param[in] bMicrosoft \p true si la table a été obtenue, transformée, depuis une fonction
+ * Microsoft, \p false si elle l'a été depuis un flux natif
+ * \param[in] lpmt_e Résultat de l'analyse
+ * \note Les fonctions Microsoft transforment le contenu d'une partie de la table, en inversant
+ * l'ordre des octets de certains éléments de l'en-tête (big endian -> little endian)
+ **/
void parse_pmt(const SI_PMT & pmt, bool bMicrosoft, ChainePMT & lpmt_e);
+/// État de la recherche de chaînes
enum ScanState {
- ss_idle,
- ss_cancelling,
- ss_stopping,
- ss_running
+ ss_idle, //!< Inactif
+ ss_cancelling, //!< En cours d'annulation
+ ss_stopping, //!< En cours d'arrêt
+ ss_running //!< Recherche en cours
};
/// Codes de notification passés dans \p LOBYTE(wParam) avec le message \p WM_APP_SCAN_NOTIFY
enum ScanNotifications {
- sn_init, //!< Initialisation (\p lParam = nombre d'étapes, HIWORD(wParam) = numéro répétition)
+ sn_init, //!< Initialisation (\p lParam = nombre d'étapes, \p HIWORD(wParam) = numéro répétition)
sn_info_freq, //!< Message fréquence en cours de recherche
- //!< \p lParam = fréquence en cours d'examen, HIWORD(wParam) = numéro canal
+ //!< \p lParam = fréquence en cours d'examen, \p HIWORD(wParam) = numéro canal
sn_info_stats, //!< Message statistiques du signal
- //!< lParam = informations statistiques du signal
+ //!< \p lParam = informations statistiques du signal
sn_completed, //!< Scan d'une fréquence terminé
- //!< (HIWORD(wParam) = numéro canal, lParam = fréquence)
- sn_info_nit, //!< Message lecture de la NIT
+ //!< (\p HIWORD(wParam) = numéro canal, \p lParam = fréquence)
+ sn_info_nit, //!< Message "lecture de la NIT"
sn_info_clear, //!< Effacement du message d'information
sn_restore, //!< Restauration des préférences utilisateur
sn_scan_end //!< Recherche terminée
- //!< (HIWORD(wParam) = état 'ScanState' à la fin, lParam = nombre d'étapes)
+ //!< (\p HIWORD(wParam) = état 'ScanState' à la fin, \p lParam = nombre d'étapes)
};
/// Contient les informations récupérées dans la NIT pour définir les numéros des chaînes.
Modifié: trunk/record.cpp
===================================================================
--- trunk/record.cpp 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/record.cpp 2009-08-30 17:09:36 UTC (rev 202)
@@ -55,7 +55,6 @@
UINT32 cleCh = indexToCle(ixChaine);
stop(epr_interrompu); // précaution
-#if USE_SINGLE_GRABBER // USE_SINGLE_GRABBER
if (!pGraph)
return false;
@@ -84,33 +83,12 @@
// S'il n'y avait aucun enregitrement en cours auparavant, on démarre le "callback" maintenant :
if (nPrevRecCount==0) {
sGrabber.SetCallback();
- #if USE_THREAD_IN_GRABBER
cSg.StartThread(); // Démarrage du "thread"
- #endif
}
return true;
}
}
-#else // USE_SINGLE_GRABBER
- if (pSample && cleCh!=0) {
- CSampleGrabber * pGrabberCB = new CSampleGrabber(pCapt);
- if (pGrabberCB) {
- if (pProg) {
- memcpy(this, pProg, sizeof(RecordInfo));
- pProg->etat = epr_encours;
- programmation_modifiee = true;
- }
- pSample->SetCallback(pGrabberCB, 0);
- #if USE_THREAD_IN_GRABBER
- pGrabberCB->StartThread();
- #endif
- cleChaine = cleCh;
- return true;
- }
- }
-
-#endif // USE_SINGLE_GRABBER
// Si on arrive ici, c'est que la requête a échoué
delete pCapt; // Déstruction de l'objet de capture que l'on ne peut pas utiliser
return false;
@@ -165,7 +143,6 @@
myprintf(BOLD(TEXT("Arrêt d'enregistrement")) EOL);
after = apres;
-#if USE_SINGLE_GRABBER
if (cleChaine!=0) {
if (raison!=epr_null) {
int ixProg = trouve_prog_par_nom(nom);
@@ -195,27 +172,11 @@
// S'il n'y a plus aucun enregistrement en cours, on arrête le "callback" maintenant :
if (nPrevRecCount==0) {
sGrabber.ResetCallback();
- #if USE_THREAD_IN_GRABBER
cSg.StopThread();
- #endif
}
}
}
}
-#else // USE_SINGLE_GRABBER
- if (pSample && cleChaine!=0) {
- if (raison!=epr_null) {
- int ixProg = trouve_prog_par_nom(nom);
-
- if (ixProg>=0) {
- Programmes[ixProg].etat = raison;
- programmation_modifiee = true;
- }
- }
- pSample->SetCallback(NULL, 0); // Ceci appelle indirectement "CSampleGrabber::Release()",
- // CSampleGrabber::StopThread() ainsi que "delete pCapture;"
- }
-#endif // USE_SINGLE_GRABBER
nom[0] = 0;
cleChaine = 0; // Parfois redondant, mais tant pis
apres = apr_null;
@@ -223,23 +184,6 @@
return after;
}
-#if USE_SINGLE_GRABBER == 0
-
-void Enregistrement::query(CComPtr & pGrabber)
-{
- if (!pSample) {
- HRESULT hr = pGrabber.QueryInterface(&pSample);
- myprintf(TEXT("%?erreur query pSample, hr=0x%08x") EOL, FAILED(hr), hr);
- }
-}
-
-void Enregistrement::release()
-{
- pSample.Release();
-}
-
-#endif // #if USE_SINGLE_GRABBER == 0
-
/**
* Obtenir le nom de la chaîne enregistrée (retourne un "*" s'il s'agit du multiplex entier) :
* \retval Pointeur sur le nom de la chaîne
Modifié: trunk/record.h
===================================================================
--- trunk/record.h 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/record.h 2009-08-30 17:09:36 UTC (rev 202)
@@ -32,13 +32,8 @@
#include "graph.h"
#include "capture.h"
-#if USE_SINGLE_GRABBER
/// Nombre max d'enregistrements simultanés sur un même multiplex
#define NB_MAX_ENREG 4
-#else
-/// Nombre max d'enregistrements simultanés sur un même multiplex
-#define NB_MAX_ENREG 3
-#endif
/**
* Durée maximale qui sépare deux appels au timer de début d'enregistrement.
@@ -56,17 +51,11 @@
/// Description d'un enregistrement (capture) de chaîne qui est en cours de traitement
class Enregistrement : public RecordInfo {
public:
-#if USE_SINGLE_GRABBER
CCapture * pCapture;
-#else
- CComPtr pSample;
-#endif
/// Constructeur
- Enregistrement()
-#if USE_SINGLE_GRABBER
- : pCapture(NULL)
-#endif
+ Enregistrement() :
+ pCapture(NULL)
{}
/// Déterminer si cet enregistrement de chaîne est couramment actif
@@ -106,14 +95,6 @@
**/
bool modify_prog(Programme * pProg);
-#if USE_SINGLE_GRABBER == 0
- /// Obtenir l'interface du "Sample grabber"
- void query(CComPtr & pGrabber);
-
- /// Libérer l'interface du "Sample grabber"
- void release();
-#endif
-
/**
* Calcul du temps restant avant la fin de l'enregistrement.
* \param[in] localtime Heure de référence (en principe l'heure système)
Modifié: trunk/rendering.cpp
===================================================================
--- trunk/rendering.cpp 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/rendering.cpp 2009-08-30 17:09:36 UTC (rev 202)
@@ -511,7 +511,7 @@
// Récupération de la broche d'entrée (pour le ratio d'aspect)
hr = cherche_pin(pFilter, PINDIR_INPUT, pInputPin);
- myprintf(TEXT("%?Rendu vidéo (%s) initialisé") EOL, SUCCEEDED(hr), pszName);
+ myprintf(CMyP TEXT("Rendu vidéo (%s) initialisé") EOL, SUCCEEDED(hr), pszName);
return hr;
}
@@ -1031,7 +1031,7 @@
HRESULT hr = SetAlphaBitmap(); // Incrustation du bitmap
- myprintf(TEXT("%?") ERRX(TEXT("Échec SetAlphaBitmap (DrawOsdText) hr=0x%08x")) ERRX(TEXT("(%s)")),
+ myprintf(CMyP ERRX(TEXT("Échec SetAlphaBitmap (DrawOsdText) hr=0x%08x")) ERRX(TEXT("(%s)")),
FAILED(hr), hr, DShowErrorToString(hr).c_str());
if (!bBitmapSet && SUCCEEDED(hr))
@@ -1048,7 +1048,7 @@
if (bBitmapSet) {
HRESULT hr = ClearAlphaBitmap();
- myprintf(TEXT("%?") ERRX(TEXT("Échec SetAlphaBitmap (ClearOsd) hr=0x%08x")) ERRX(TEXT("(%s)")),
+ myprintf(CMyP ERRX(TEXT("Échec SetAlphaBitmap (ClearOsd) hr=0x%08x")) ERRX(TEXT("(%s)")),
FAILED(hr), hr, DShowErrorToString(hr).c_str());
if (SUCCEEDED(hr))
@@ -1187,10 +1187,10 @@
return erreur(TEXT("L'interface de contrôle VMR n'est pas disponible"), hr);
hr = pVMR7Control->SetVideoClippingWindow(hMainWnd);
- myprintf(TEXT("%?erreur SetVideoClippingWindow, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetVideoClippingWindow, hr=0x%08x")), FAILED(hr), hr);
hr = pVMR7Control->SetColorKey(colorKey);
- myprintf(TEXT("%?erreur SetColorKey, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetColorKey, hr=0x%08x")), FAILED(hr), hr);
return hr;
}
@@ -1207,7 +1207,7 @@
HRESULT hr = pARC->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetAspectRatioMode, hr=0x%08x")), FAILED(hr), hr);
return hr;
}
@@ -1220,11 +1220,11 @@
if (pVMR7Control) {
hr = pVMR7Control->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("échec SetAspectRatioMode, hr=0x%08x")), FAILED(hr), hr);
if (pDstRect && !IsRectEmpty(pDstRect)) {
hr = pVMR7Control->SetVideoPosition(NULL, pDstRect);
- myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("échec SetVideoPosition, hr=0x%08x")), FAILED(hr), hr);
}
}
@@ -1253,7 +1253,7 @@
SIZE sSz = {768, 576}; // valeurs par défaut en cas d'erreur
HRESULT hr = pVMR7Control->GetNativeVideoSize(&sSz.cx, &sSz.cy, NULL, NULL);
- myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("GetNativeVideoSize FAILED!, hr=0x%08x")), FAILED(hr), hr);
return sSz;
}
@@ -1322,9 +1322,9 @@
}
hr = pNotify->AdviseSurfaceAllocator(0x118218, pSurfAlloc);
- myprintf(TEXT("%?erreur AdviseSurfaceAllocator, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur AdviseSurfaceAllocator, hr=0x%08x")), FAILED(hr), hr);
hr = pSurfAlloc->AdviseNotify(pNotify);
- myprintf(TEXT("%?erreur AdviseNotify, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur AdviseNotify, hr=0x%08x")), FAILED(hr), hr);
return hr;
}
@@ -1384,10 +1384,10 @@
}
hr = pVMR9Control->SetVideoClippingWindow(hMainWnd);
- myprintf(TEXT("%?erreur SetVideoClippingWindow, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetVideoClippingWindow, hr=0x%08x")), FAILED(hr), hr);
hr = pVMR9Control->SetBorderColor(colorKey);
- myprintf(TEXT("%?erreur SetBorderColor, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetBorderColor, hr=0x%08x")), FAILED(hr), hr);
if (FAILED(hr))
return hr;
@@ -1433,7 +1433,7 @@
HRESULT hr = pARC->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetAspectRatioMode, hr=0x%08x")), FAILED(hr), hr);
return hr;
}
@@ -1450,7 +1450,7 @@
if (pVMR9Control) {
hr = pVMR9Control->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("échec SetAspectRatioMode, hr=0x%08x")), FAILED(hr), hr);
if (pDstRect && !IsRectEmpty(pDstRect)) {
RECT rOldPos, rUnion;
@@ -1463,7 +1463,7 @@
!EqualRect(&rUnion, pDstRect);
hr = pVMR9Control->SetVideoPosition(NULL, pDstRect);
- myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("échec SetVideoPosition, hr=0x%08x")), FAILED(hr), hr);
// S'assurer que les bordures autour de l'image resteront noires :
if (bRedraw)
@@ -1503,7 +1503,7 @@
SIZE sSz = {768, 576}; // valeurs par défaut en cas d'erreur
HRESULT hr = pVMR9Control->GetNativeVideoSize(&sSz.cx, &sSz.cy, NULL, NULL);
- myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("GetNativeVideoSize FAILED!, hr=0x%08x")), FAILED(hr), hr);
return sSz;
}
@@ -1575,13 +1575,13 @@
}
hr = pEVRControl->SetVideoWindow(hMainWnd);
- myprintf(TEXT("%?erreur SetVideoWindow, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetVideoWindow, hr=0x%08x")), FAILED(hr), hr);
if (FAILED(hr))
return hr;
hr = pEVRControl->SetBorderColor(colorKey);
- myprintf(TEXT("%?erreur SetBorderColor, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetBorderColor, hr=0x%08x")), FAILED(hr), hr);
if (FAILED(hr))
return hr;
@@ -1611,7 +1611,7 @@
HRESULT hr = E_FAIL;
if (pEVRControl) {
hr = pEVRControl->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?erreur SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("erreur SetAspectRatioMode, hr=0x%08x")), FAILED(hr), hr);
}
return hr;
}
@@ -1625,7 +1625,7 @@
if (pEVRControl) {
hr = pEVRControl->SetAspectRatioMode(ARMode(bEtirer));
- myprintf(TEXT("%?échec SetAspectRatioMode, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("échec SetAspectRatioMode, hr=0x%08x")), FAILED(hr), hr);
if (pDstRect && !IsRectEmpty(pDstRect)) {
RECT rOldPos, rUnion;
@@ -1639,7 +1639,7 @@
!EqualRect(&rUnion, pDstRect);
hr = pEVRControl->SetVideoPosition(&rSource, pDstRect);
- myprintf(TEXT("%?échec SetVideoPosition, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("échec SetVideoPosition, hr=0x%08x")), FAILED(hr), hr);
// S'assurer que les bordures autour de l'image resteront noires :
if (bRedraw) {
@@ -1710,7 +1710,7 @@
SIZE sAr = {4, 3}; // valeurs par défaut en cas d'erreur
HRESULT hr = pEVRControl->GetNativeVideoSize(&sSz, &sAr);
- myprintf(TEXT("%?GetNativeVideoSize FAILED!, hr=0x%08x") EOL, FAILED(hr), hr);
+ myprintf(CMyP ERRX(TEXT("GetNativeVideoSize FAILED!, hr=0x%08x")), FAILED(hr), hr);
// Ajustement de la taille horizontale, d'une manière similaire à ce qui semble être fait dans la fonction
// "GetNativeVideoSize" des autres modes ; passage par un type "double" car les valeurs utilisées pour
Modifié: trunk/settings.cpp
===================================================================
--- trunk/settings.cpp 2009-08-13 22:39:40 UTC (rev 201)
+++ trunk/settings.cpp 2009-08-30 17:09:36 UTC (rev 202)
@@ -2893,7 +2893,7 @@
* \param[in] hDlg Handle de la boîte de dialogue contenant les contrôles à interroger
* \param[in] eCurrMode Méthode de rendu à sélectionner
**/
-void SetVMRSel(HWND hDlg, VMRTypes eCurrMode)
+static void SetVMRSel(HWND hDlg, VMRTypes eCurrMode)
{
HWND hCtl = GetDlgItem(hDlg, IDC_COMBO_RENDERING);
@@ -2911,16 +2911,16 @@
* \retval Méthode de rendu sélectionnée
**/
-VMRTypes GetVMRSel(HWND hDlg)
+static VMRTypes GetVMRSel(HWND hDlg)
{
return (VMRTypes)SendDlgItemMessage(hDlg, IDC_COMBO_RENDERING, CB_GETCURSEL, 0, 0);
}
/**
- * Accorder l'état de la configuration OSD à celle du VMR et de la variable #is_vista.
+ * Accorder l'état de la configuration OSD à celle du VMR et de la variable #eWinVers.
* \param[in] hDlg Handle de la boîte de dialogue contenant le contrôle à ajuster
**/
-void SetOSDState(HWND hDlg)
+static void SetOSDState(HWND hDlg)
{
VMRTypes eSelMode = GetVMRSel(hDlg);
bool bCanUseOSD = eWinVers < wv_Vista || eSelMode!=vmt_VMR7_renderless && eSelMode!=vmt_VMR7_windowless;
From pouchintv-dev at baysse.fr Sun Aug 30 20:44:25 2009
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: Sun, 30 Aug 2009 18:44:25 -0000
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r203 - in trunk: . Icones
Icones/Locales
Message-ID: <20090830184419.9EDFF6F00A@mail.baysse.fr>
Author: gingko
Date: 2009-08-30 20:44:19 +0200 (dim 30 aoû 2009)
New Revision: 203
Added:
trunk/Icones/Locales/Fr3 PaysLoire.bmp
trunk/Icones/Locales/Fr3 Poitiers.bmp
trunk/Icones/Locales/France3.bmp
Removed:
trunk/Icones/Fr3 PaysLoire.bmp
trunk/Icones/Fr3 Poitiers.bmp
trunk/Icones/France3.bmp
Modified:
trunk/changelog.html
trunk/grabber.cpp
trunk/grabber.h
trunk/parse.cpp
trunk/parse.h
trunk/settings.cpp
trunk/update.cpp
trunk/utils.cpp
trunk/utils.h
Log:
Correction d'un bug dans la mise à jour des icônes + Ajout d'une classe
update.cpp :
* Correction d'un bug concernant la mise à jour des icônes.
utils.h, utils.cpp :
* Les fonctions de conversion CHAR <-> UTF8 acceptent un pointeur NULL en paramètre
(en retournant une chaîne vide).
* Ajout d'une classe de base pour la gestion de threads de travail.
parse.h, parse.cpp, grabber.h, grabber.cpp :
* Les threads gérés dans ces fichiers utilisent maintenant la classe de base définie
dans utils.h / utils.cpp.
Les trois dernières icônes clonées de France 3 sont déplacées dans le répertoires des
chaînes locales
Supprimé: trunk/Icones/Fr3 PaysLoire.bmp
===================================================================
(les fichiers binaires diffèrent)
Supprimé: trunk/Icones/Fr3 Poitiers.bmp
===================================================================
(les fichiers binaires diffèrent)
Supprimé: trunk/Icones/France3.bmp
===================================================================
(les fichiers binaires diffèrent)
Ajouté: trunk/Icones/Locales/Fr3 PaysLoire.bmp
===================================================================
(les fichiers binaires diffèrent)
Property changes on: trunk/Icones/Locales/Fr3 PaysLoire.bmp
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Ajouté: trunk/Icones/Locales/Fr3 Poitiers.bmp
===================================================================
(les fichiers binaires diffèrent)
Property changes on: trunk/Icones/Locales/Fr3 Poitiers.bmp
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Ajouté: trunk/Icones/Locales/France3.bmp
===================================================================
(les fichiers binaires diffèrent)
Property changes on: trunk/Icones/Locales/France3.bmp
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Modifié: trunk/changelog.html
===================================================================
--- trunk/changelog.html 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/changelog.html 2009-08-30 18:44:19 UTC (rev 203)
@@ -56,8 +56,14 @@
Changements réalisés pour la version 0.5
- - 0.5.202 (expérimentale, publiée via le service de mise à jour le 30 août 2009) :
+ - 0.5.203 (expérimentale, publiée via le service de mise à jour le 30 août 2009) :
+ - Correction d'un bug dans la mise à jour des icônes
+
+
+
+ - SVN rév. 202 :
+
- Correction d'un bug introduit récemment, qui provoquait un plantage à l'issue
d'unerecherche de chaînes en présence d'un tiner nouvellement installé (aucune
chaîne préexistante).
@@ -78,7 +84,7 @@
- SVN rév. 200 :
- Utilisation d'un filtre EAC3 dédié, sélectionnable dans la configuration,
- d'après d'un patch proposé par MatMaul.
+ d'après un patch proposé par MatMaul.
- Un rebasculement en AC3 est prévu si aucun filtre EAC3 n'existe ou n'est choisi.
- Dans le menu des filtres, les filtres de rendu audio sont fusionnés sous une seule commande,
affichant les propriétés du filtre effectivement utilisé.
Modifié: trunk/grabber.cpp
===================================================================
--- trunk/grabber.cpp 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/grabber.cpp 2009-08-30 18:44:19 UTC (rev 203)
@@ -30,13 +30,13 @@
#include "grabber.h"
#include "record.h"
- #include "memfifo.h"
+#include "memfifo.h"
/// Constructeur de base
CSampleGrabber::CSampleGrabber() :
+ WorkingThread(false),
CUnknown(TEXT("Sample grabber"), NULL),
hMutex(CreateMutex(NULL, FALSE, NULL)),
- hThread(NULL),
taille_paquet_buf(0)
{
myprintf(TEXT("## Construction CSampleGrabber") EOL);
@@ -140,7 +140,7 @@
ReleaseMutex(hMutex);
}
-DWORD CSampleGrabber::GrabThread()
+DWORD CSampleGrabber::ThreadProc()
{
myprintf(TEXT("## Entrée dans CSampleGrabber::GrabThread") EOL);
@@ -162,34 +162,18 @@
return 0;
}
-DWORD WINAPI CSampleGrabber::GrabThreadProc(LPVOID lpParameter)
-{
- CSampleGrabber * pGrabberCB = reinterpret_cast(lpParameter);
-
- return pGrabberCB->GrabThread();
-}
-
-/// Démarrage du "thread" de capture
-bool CSampleGrabber::StartThread()
-{
- if (hThread==NULL)
- hThread = CreateThread(0, 0, GrabThreadProc, this, 0, 0);
- return hThread != NULL;
-}
-
/// Arrêt du "thread" de capture
bool CSampleGrabber::StopThread()
{
- if (hThread) {
+ if (isThreadRunning()) {
// Envoyer un échantillon vide pour terminer le "Thread"
cMemFifo.Put(NULL, 0);
// Attendre une seconde
- if (WaitForSingleObject(hThread, 1000)!=WAIT_OBJECT_0) {
+ if (!WaitThreadExit(1000)) {
myprintf(TEXT("Le thread du grabber ne s'est pas terminé correctement") EOL);
return false;
}
- hThread = NULL;
}
cMemFifo.Free(); // Libération des échantillons mémoire résiduels
return true;
Modifié: trunk/grabber.h
===================================================================
--- trunk/grabber.h 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/grabber.h 2009-08-30 18:44:19 UTC (rev 203)
@@ -32,7 +32,7 @@
#include "memfifo.h"
/// Classe implémentant les méthodes "callback" à associer à un "Sample grabber"
-class CSampleGrabber : public CUnknown, public ISampleGrabberCB // The Filter Interface
+class CSampleGrabber : public CUnknown, public ISampleGrabberCB, public WorkingThread // The Filter Interface
{
//
// --- Implémentation des méthodes abstraites de l'interface ISampleGrabberCB --
@@ -74,27 +74,20 @@
// --- Données et méthodes propres à l'application ---
//
- HANDLE hMutex; //!< Mutex protégeant les débuts et fins d'enregistrements
- HANDLE hThread;
+ HANDLE hMutex; //!< Mutex protégeant les débuts et fins d'enregistrements
BYTE taille_paquet_buf; //!< Longueur du paquet partiel mémorisé
- TS_packet paquet_buf; //!< Tampon de mémorisation de paquet partiel
+ TS_packet paquet_buf; //!< Tampon de mémorisation de paquet partiel
- CMemFifo cMemFifo; //!< Buffer "First In First Out" de mémorisation des échantillons reçus
+ CMemFifo cMemFifo; //!< Buffer "First In First Out" de mémorisation des échantillons reçus
- /// Fonction d'exécution principale statique du 'thread'.
- static DWORD WINAPI
- GrabThreadProc(LPVOID lpParameter);
-
/// Fonction d'exécution principale effective du 'thread'.
- DWORD GrabThread();
+ virtual DWORD ThreadProc();
public:
- /// Démarrage du "thread" de capture
- bool StartThread();
/// Arrêt du "thread" de capture
- bool StopThread();
+ bool StopThread();
private:
@@ -103,7 +96,7 @@
* param[in] nSize Taille de l'échantillon
* param[in] pPtr Pointeur sur les données de l'échantillon
**/
- void traite_sample(size_t nSize, const BYTE * pPtr);
+ void traite_sample(size_t nSize, const BYTE * pPtr);
/**
* Traitement d'un paquet TS reçu du tuner (issu du découpage de l'échantillon, et même
@@ -111,7 +104,7 @@
*
* param[in] p Référence sur le paquet reçu (qui a une longueur fixe)
**/
- void traite_paquet(const TS_packet & p);
+ void traite_paquet(const TS_packet & p);
public:
@@ -120,10 +113,10 @@
/// Verrouillage de l'accès aux descripteurs d'enregistrements pendant l'accès ou la modification
/// à ceux-ci.
- bool Lock();
+ bool Lock();
/// Libération de l'accès aux descripteurs d'enregistrements
- void Unlock();
+ void Unlock();
/// Destructeur général
virtual ~CSampleGrabber();
Modifié: trunk/parse.cpp
===================================================================
--- trunk/parse.cpp 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/parse.cpp 2009-08-30 18:44:19 UTC (rev 203)
@@ -600,7 +600,7 @@
}
}
-DWORD ChannelsScanner::ScanThread()
+DWORD ChannelsScanner::ThreadProc()
{
setlocale(LC_ALL, "French"); // Pour affichage de la date
@@ -757,18 +757,6 @@
return eScanState;
}
-DWORD WINAPI ChannelsScanner::ScanThreadProc(LPVOID lpParameter)
-{
- ChannelsScanner * pScan = reinterpret_cast(lpParameter);
-
- return pScan->ScanThread();
-}
-
-void ChannelsScanner::Run()
-{
- CreateThread(0, 0, ScanThreadProc, this, 0, 0);
-}
-
/**
* Assignation d'un numéro à une chaîne. Si une autre chaîne avait ce numéro, les numéros sont
* échangés.
@@ -950,6 +938,7 @@
/// Constructeur
ChannelsScanner::ChannelsScanner(HWND hDlg, const CInfoUser & cInfoUsr) :
+ WorkingThread(false),
hwndDlg(hDlg),
fLog(NULL),
cInfoUser(cInfoUsr),
Modifié: trunk/parse.h
===================================================================
--- trunk/parse.h 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/parse.h 2009-08-30 18:44:19 UTC (rev 203)
@@ -91,7 +91,7 @@
};
/// Données et méthodes nécessaires à la recherche de chaînes
-class ChannelsScanner
+class ChannelsScanner : public WorkingThread
{
enum SignalState {
ss_error, //!< Erreur à la détection du signal
@@ -119,24 +119,22 @@
/// correspondant à un numéro non alloué contient la valeur -1.
SHORT aRefNumeros[1000];
+ // ### Méthodes
+
/// Réinitialisation de la carte des chaînes à vide
- void raz_carte();
+ void raz_carte();
/// Réalisation de la cartographie des chaînes
- void cartographier();
+ void cartographier();
- /// Fonction d'exécution principale statique du 'thread'.
- static DWORD WINAPI
- ScanThreadProc(LPVOID lpParameter);
-
/// Fonction d'exécution principale effective du 'thread'.
- DWORD ScanThread();
+ virtual DWORD ThreadProc();
/// Sortie d'un message de log
- void log(LPCTSTR pszFmt, ...) const;
+ void log(LPCTSTR pszFmt, ...) const;
/// Sortir les informations concernant un filtre
- void logDeviceInfo(LPCTSTR pszTitle, LPCTSTR pszDevicePath);
+ void logDeviceInfo(LPCTSTR pszTitle, LPCTSTR pszDevicePath);
/**
* Fonction générant en même temps le log des stats du signal à cet instant, et
@@ -144,7 +142,7 @@
* \param[in] nTuneDelay Temps depuis lequel le tuner est syntonisé (mS)
* \return \p true si la qualité du signal est suffisante
**/
- SignalState CheckQuality(UINT nTuneDelay) const;
+ SignalState CheckQuality(UINT nTuneDelay) const;
/**
* Attribution d'un nouveau numéro pour une nouvelle chaîne, à partir d'un numéro proposé.
@@ -157,7 +155,7 @@
* \retval Numéro trouvé (intervalle 1 à 999)
* \retval 0 si aucun numéro décalé disponible
**/
- UINT16 nouveau_numero_decale(UINT16 nNumeroPropose) const;
+ UINT16 nouveau_numero_decale(UINT16 nNumeroPropose) const;
/**
* Attribution d'un nouveau numéro pour une nouvelle chaîne qui n'a pas de numéro proposé.
@@ -166,7 +164,7 @@
* \retval Numéro trouvé (intervalle 1 à 999)
* \retval 0 si plus aucun numéro disponible (hypothèse assez improbable)
**/
- UINT16 nouveau_numero_chaine() const;
+ UINT16 nouveau_numero_chaine() const;
/**
* Assignation d'un numéro à une chaîne. Si une autre chaîne avait ce numéro, les numéros sont
@@ -176,7 +174,7 @@
* \param[in] bPref \p true s'il s'agit d'une préférence utilisateur (par opposition
* à un numéro automatiquement calculé)
**/
- void assigne_numero(int ixChaine, UINT16 nNumero, bool bPref);
+ void assigne_numero(int ixChaine, UINT16 nNumero, bool bPref);
/**
* Attribution d'un numéro à toutes les chaînes qui n'en ont pas reçu.
@@ -185,16 +183,16 @@
* Au passage, marque également comme "inactives" les chaînes qui ne diffusent pas
* couramment en norme MPEG2.
**/
- void attribue_numeros();
+ void attribue_numeros();
/**
* Restauration des préférences utilisateur sauvegardées
**/
- void restaure_prefs();
+ void restaure_prefs();
/// Transfert des numéros de chaîne de la NIT vers les chaînes qui viennent d'être ajoutées
/// \retval \p true si au moins une chaîne n'a pas reçu de numéro
- bool place_numeros();
+ bool place_numeros();
/**
* Syntonisation du tuner pour un canal, et évaluation des caractéristiques
@@ -204,28 +202,28 @@
* \param[out] sSStats Statistiques de qualité du signal
* \return Estimation du succès de la syntonisation
**/
- SignalState tune(BYTE nNoCanal, INT32 & khz, SignalStatistics & sSStats);
+ SignalState tune(BYTE nNoCanal, INT32 & khz, SignalStatistics & sSStats);
- bool parse(BYTE nNoCanal, INT32 khz);
+ bool parse(BYTE nNoCanal, INT32 khz);
public:
/// Index du nombre de chaînes lues à l'issue du scan des multiplex précédents.
/// L'intervalle entre cette valeur et la taille de la table des chaînes permet de
/// définir quelles sont les chaînes qui viennent d'être ajoutées dans le scan
/// de multiplex le plus récent.
- UINT prev_size;
+ UINT prev_size;
- ScanState eScanState;
- int nIndex;
+ ScanState eScanState;
+ int nIndex;
+ // ### Méthodes
+
/// Liste de canaux (pour recherche de chaînes)
- ListeCanaux liste_scan;
+ ListeCanaux liste_scan;
/// Constructeur
ChannelsScanner(HWND hDlg, const CInfoUser & cInfoUsr);
- void Run();
-
/// Destructeur
~ChannelsScanner();
};
Modifié: trunk/settings.cpp
===================================================================
--- trunk/settings.cpp 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/settings.cpp 2009-08-30 18:44:19 UTC (rev 203)
@@ -2108,7 +2108,7 @@
pScan->liste_scan.lit_fichier_scan(nomVille);
}
//
- pScan->Run();
+ pScan->StartThread();
} else if (pScan->eScanState==ss_running) {
// Une recherche est déjà en cours (appui sur arrêt)
EnableWindow(hStartBut, FALSE);
Modifié: trunk/update.cpp
===================================================================
--- trunk/update.cpp 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/update.cpp 2009-08-30 18:44:19 UTC (rev 203)
@@ -535,7 +535,7 @@
// Télécharge les images manquantes
tstring strUrlBase = ConvertUTF82Char(sTiXml.Attribute("base"));
- tstring strUrlPath = ConvertUTF82Char(sTiXml.Attribute("path"));
+ tstring strUrlPath = ConvertUTF82Char(xmlIconesPack->Attribute("path"));
// Ajustement du répertoire dans l'URL
if (strUrlPath==TEXT("/"))
Modifié: trunk/utils.cpp
===================================================================
--- trunk/utils.cpp 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/utils.cpp 2009-08-30 18:44:19 UTC (rev 203)
@@ -488,30 +488,34 @@
**/
tstring ConvertUTF82Char(LPCSTR aconvertir)
{
- UINT i, j; // Itérateurs
- UCHAR c; // Caractères à convertir
- UINT taille = strlen_T(aconvertir); // La taille de la chaîne résultante est forcément plus courte
- LPTSTR _tmp = STK_ALLOC(TCHAR, taille+1); // Chaîne temporaire
+ LPTSTR _tmp = TEXT("");
- for( i=0, j=0; i(lpParameter);
+
+ if (pWThread) {
+ DWORD dwRes = pWThread->ThreadProc();
+
+ if (pWThread->bDeleteOnExit)
+ delete pWThread;
+ return dwRes;
+ }
+ return 0;
+}
+
+/**
+ * Démarrage du thread
+ * \return \p true si le thread a démarré correctement, \p false sinon
+ **/
+bool WorkingThread::StartThread()
+{
+ if (hThread==NULL)
+ hThread = CreateThread(NULL, 0, ThreadProc_static, this, 0, &dwThreadId);
+ return hThread != NULL;
+}
+
+/**
+ * Attente de la terminaison du thread (penda
+ * \param[in] dwMilliseconds Temps d'attente maximal
+ * \return \p true si le thread s'est terminé correctement, \p false sinon
+ **/
+bool WorkingThread::WaitThreadExit(DWORD dwMilliseconds)
+{
+ if (WaitForSingleObject(hThread, dwMilliseconds) != WAIT_OBJECT_0)
+ return false;
+ hThread = NULL;
+ return true;
+}
+
+/// Destructeur
+WorkingThread::~WorkingThread()
+{
+ /// Attendre un peu la terminaison (précaution, le thread devrait déjà avoir été arrêté)
+ if (hThread && GetCurrentThreadId() != dwThreadId)
+ WaitThreadExit(5000); /// 5 secondes
+}
Modifié: trunk/utils.h
===================================================================
--- trunk/utils.h 2009-08-30 17:09:36 UTC (rev 202)
+++ trunk/utils.h 2009-08-30 18:44:19 UTC (rev 203)
@@ -834,3 +834,58 @@
* contenant le message d'erreur correspondant
**/
tstring SystemErrorToString(DWORD dwErr);
+
+// ----------------------------------------------------------------------------
+
+class WorkingThread
+{
+ HANDLE hThread;
+ DWORD dwThreadId;
+ bool bDeleteOnExit; //!< \p true si doit être détruit par \p delete
+
+ virtual DWORD ThreadProc() = 0;
+
+ /**
+ * Point d'entrée (statique) du thread
+ * \param[in] lpParameter Pointeur \p this de la classe associée
+ **/
+ static DWORD WINAPI ThreadProc_static(LPVOID lpParameter);
+
+public:
+ /**
+ * Constructeur
+ * \param[in] bDelOnExit si \p true, l'objet sera détruit par \p delete après sortie du thread
+ **/
+ WorkingThread(bool bDelOnExit) :
+ hThread(NULL),
+ dwThreadId(0),
+ bDeleteOnExit(bDelOnExit)
+ {}
+
+ /**
+ * Démarrage du thread
+ * \return \p true si le thread a démarré correctement, \p false sinon
+ **/
+ bool StartThread();
+
+ /**
+ * Envoi d'un message dans la file d'attente de messages du thread
+ **/
+ BOOL PostMessageInThread(UINT nMsg, WPARAM wParam=0, LPARAM lParam=0) {
+ return ::PostThreadMessage(dwThreadId, nMsg, wParam, lParam);}
+
+ /**
+ * Attente de la terminaison du thread
+ * \param[in] dwMilliseconds Temps d'attente maximal
+ * \return \p true si le thread s'est terminé correctement, \p false sinon
+ **/
+ bool WaitThreadExit(DWORD dwMilliseconds);
+
+ /// Test si le thread est actif
+ bool isThreadRunning() const {
+ return hThread != NULL && WaitForSingleObject(hThread, 0) != WAIT_OBJECT_0; }
+
+ /// Destructeur
+ virtual ~WorkingThread();
+};
+