00001
00002 #include <sys/time.h>
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>
00013 #endif
00014
00015
00016 #include <cstdlib>
00017 #include <cerrno>
00018
00019
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
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
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, "", "", "", "",
00124 0, 0, "", 120,
00125 1895, "");
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
00179
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
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);
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