|
MythTV
0.26-pre
|
00001 // POSIX headers 00002 #include <sys/time.h> // for setpriority 00003 #include <unistd.h> 00004 #include <sys/types.h> 00005 #include <sys/stat.h> 00006 #include <fcntl.h> 00007 #include <libgen.h> 00008 #include <signal.h> 00009 00010 #include "mythconfig.h" 00011 #if CONFIG_DARWIN 00012 #include <sys/aio.h> // O_SYNC 00013 #endif 00014 00015 // C headers 00016 #include <cstdlib> 00017 #include <cerrno> 00018 00019 // C++ headers 00020 #include <iostream> 00021 #include <fstream> 00022 using namespace std; 00023 00024 #ifndef _WIN32 00025 #include <QCoreApplication> 00026 #else 00027 #include <QApplication> 00028 #endif 00029 00030 #include <QFile> 00031 #include <QFileInfo> 00032 #include <QDir> 00033 #include <QMap> 00034 #include <QRegExp> 00035 00036 #include "mythcontext.h" 00037 #include "mythcorecontext.h" 00038 #include "mythversion.h" 00039 #include "mythdb.h" 00040 #include "exitcodes.h" 00041 #include "compat.h" 00042 #include "storagegroup.h" 00043 #include "programinfo.h" 00044 #include "dbcheck.h" 00045 #include "previewgenerator.h" 00046 #include "commandlineparser.h" 00047 #include "mythsystemevent.h" 00048 #include "mythlogging.h" 00049 00050 #define LOC QString("MythPreviewGen: ") 00051 #define LOC_WARN QString("MythPreviewGen, Warning: ") 00052 #define LOC_ERR QString("MythPreviewGen, Error: ") 00053 00054 #ifdef Q_OS_MACX 00055 // 10.6 uses some file handles for its new Grand Central Dispatch thingy 00056 #define UNUSED_FILENO 5 00057 #else 00058 #define UNUSED_FILENO 3 00059 #endif 00060 00061 namespace 00062 { 00063 void cleanup() 00064 { 00065 delete gContext; 00066 gContext = NULL; 00067 } 00068 00069 class CleanupGuard 00070 { 00071 public: 00072 typedef void (*CleanupFunc)(); 00073 00074 public: 00075 CleanupGuard(CleanupFunc cleanFunction) : 00076 m_cleanFunction(cleanFunction) {} 00077 00078 ~CleanupGuard() 00079 { 00080 m_cleanFunction(); 00081 } 00082 00083 private: 00084 CleanupFunc m_cleanFunction; 00085 }; 00086 } 00087 00088 int preview_helper(uint chanid, QDateTime starttime, 00089 long long previewFrameNumber, long long previewSeconds, 00090 const QSize &previewSize, 00091 const QString &infile, const QString &outfile) 00092 { 00093 // Lower scheduling priority, to avoid problems with recordings. 00094 if (setpriority(PRIO_PROCESS, 0, 9)) 00095 LOG(VB_GENERAL, LOG_ERR, "Setting priority failed." + ENO); 00096 00097 if (!chanid || !starttime.isValid()) 00098 ProgramInfo::QueryKeyFromPathname(infile, chanid, starttime); 00099 00100 ProgramInfo *pginfo = NULL; 00101 if (chanid && starttime.isValid()) 00102 { 00103 pginfo = new ProgramInfo(chanid, starttime); 00104 if (!pginfo->GetChanID()) 00105 { 00106 LOG(VB_GENERAL, LOG_ERR, 00107 QString("Cannot locate recording made on '%1' at '%2'") 00108 .arg(chanid).arg(starttime.toString("yyyyMMddhhmmss"))); 00109 delete pginfo; 00110 return GENERIC_EXIT_NOT_OK; 00111 } 00112 pginfo->SetPathname(pginfo->GetPlaybackURL(false, true)); 00113 } 00114 else if (!infile.isEmpty()) 00115 { 00116 if (!QFileInfo(infile).isReadable()) 00117 { 00118 LOG(VB_GENERAL, LOG_ERR, 00119 QString("Cannot read this file '%1'").arg(infile)); 00120 return GENERIC_EXIT_NOT_OK; 00121 } 00122 pginfo = new ProgramInfo( 00123 infile, ""/*plot*/, ""/*title*/, ""/*subtitle*/, ""/*director*/, 00124 0/*season*/, 0/*episode*/, ""/*inetref*/, 120/*length_in_minutes*/, 00125 1895/*year*/, ""/*id*/); 00126 } 00127 else 00128 { 00129 LOG(VB_GENERAL, LOG_ERR, "Cannot locate recording to preview"); 00130 return GENERIC_EXIT_NOT_OK; 00131 } 00132 00133 PreviewGenerator *previewgen = new PreviewGenerator( 00134 pginfo, QString(), PreviewGenerator::kLocal); 00135 00136 if (previewFrameNumber >= 0) 00137 previewgen->SetPreviewTimeAsFrameNumber(previewFrameNumber); 00138 00139 if (previewSeconds >= 0) 00140 previewgen->SetPreviewTimeAsSeconds(previewSeconds); 00141 00142 previewgen->SetOutputSize(previewSize); 00143 previewgen->SetOutputFilename(outfile); 00144 bool ok = previewgen->RunReal(); 00145 previewgen->deleteLater(); 00146 00147 delete pginfo; 00148 00149 return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_NOT_OK; 00150 } 00151 00152 int main(int argc, char **argv) 00153 { 00154 MythPreviewGeneratorCommandLineParser cmdline; 00155 if (!cmdline.Parse(argc, argv)) 00156 { 00157 cmdline.PrintHelp(); 00158 return GENERIC_EXIT_INVALID_CMDLINE; 00159 } 00160 00161 if (cmdline.toBool("showhelp")) 00162 { 00163 cmdline.PrintHelp(); 00164 return GENERIC_EXIT_OK; 00165 } 00166 00167 if (cmdline.toBool("showversion")) 00168 { 00169 cmdline.PrintVersion(); 00170 return GENERIC_EXIT_OK; 00171 } 00172 00173 #ifndef _WIN32 00174 for (int i = UNUSED_FILENO; i < sysconf(_SC_OPEN_MAX) - 1; ++i) 00175 close(i); 00176 QCoreApplication a(argc, argv); 00177 #else 00178 // MINGW application needs a window to receive messages 00179 // such as socket notifications :[ 00180 QApplication a(argc, argv); 00181 #endif 00182 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHPREVIEWGEN); 00183 00184 int retval; 00185 if ((retval = cmdline.ConfigureLogging()) != GENERIC_EXIT_OK) 00186 return retval; 00187 00188 if ((!cmdline.toBool("chanid") || !cmdline.toBool("starttime")) && 00189 !cmdline.toBool("inputfile")) 00190 { 00191 cerr << "--generate-preview must be accompanied by either " <<endl 00192 << "\nboth --chanid and --starttime parameters, " << endl 00193 << "\nor the --infile parameter." << endl; 00194 return GENERIC_EXIT_INVALID_CMDLINE; 00195 } 00196 00198 00199 // Don't listen to console input 00200 close(0); 00201 00202 CleanupGuard callCleanup(cleanup); 00203 00204 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) 00205 LOG(VB_GENERAL, LOG_WARNING, LOC + "Unable to ignore SIGPIPE"); 00206 00207 gContext = new MythContext(MYTH_BINARY_VERSION); 00208 00209 if (!gContext->Init(false)) 00210 { 00211 LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext."); 00212 return GENERIC_EXIT_NO_MYTHCONTEXT; 00213 } 00214 gCoreContext->SetBackend(false); // TODO Required? 00215 00216 int ret = preview_helper( 00217 cmdline.toUInt("chanid"), cmdline.toDateTime("starttime"), 00218 cmdline.toLongLong("frame"), cmdline.toLongLong("seconds"), 00219 cmdline.toSize("size"), 00220 cmdline.toString("inputfile"), cmdline.toString("outputfile")); 00221 return ret; 00222 } 00223 00224 /* vim: set expandtab tabstop=4 shiftwidth=4: */
1.7.6.1