MythTV  master
mythtv/programs/mythpreviewgen/main.cpp
Go to the documentation of this file.
1 #include "mythconfig.h"
2 #if CONFIG_DARWIN
3  #include <sys/aio.h> // O_SYNC
4 #endif
5 
6 // C++ headers
7 #include <cerrno>
8 #include <csignal>
9 #include <cstdlib>
10 #include <fcntl.h>
11 #include <fstream>
12 #include <iostream>
13 #include <libgen.h>
14 #include <sys/stat.h>
15 #include <sys/time.h> // for setpriority
16 #include <sys/types.h>
17 #include <unistd.h>
18 using namespace std;
19 
20 #ifndef _WIN32
21 #include <QCoreApplication>
22 #else
23 #include <QApplication>
24 #endif
25 
26 #include <QFile>
27 #include <QFileInfo>
28 #include <QDir>
29 #include <QMap>
30 #include <QRegExp>
31 
32 #include "mythcontext.h"
33 #include "mythcorecontext.h"
34 #include "mythversion.h"
35 #include "mythdb.h"
36 #include "exitcodes.h"
37 #include "compat.h"
38 #include "storagegroup.h"
39 #include "programinfo.h"
40 #include "dbcheck.h"
41 #include "previewgenerator.h"
42 #include "commandlineparser.h"
43 #include "mythsystemevent.h"
44 #include "loggingserver.h"
45 #include "mythlogging.h"
46 #include "signalhandling.h"
47 #include "cleanupguard.h"
48 
49 #define LOC QString("MythPreviewGen: ")
50 #define LOC_WARN QString("MythPreviewGen, Warning: ")
51 #define LOC_ERR QString("MythPreviewGen, Error: ")
52 
53 #ifdef Q_OS_MACX
54  // 10.6 uses some file handles for its new Grand Central Dispatch thingy
55  #define UNUSED_FILENO 5
56 #else
57  #define UNUSED_FILENO 3
58 #endif
59 
60 namespace
61 {
62  void cleanup()
63  {
64  delete gContext;
65  gContext = nullptr;
67  }
68 }
69 
70 int preview_helper(uint chanid, QDateTime starttime,
71  long long previewFrameNumber, long long previewSeconds,
72  const QSize &previewSize,
73  const QString &infile, const QString &outfile)
74 {
75  // Lower scheduling priority, to avoid problems with recordings.
76  if (setpriority(PRIO_PROCESS, 0, 9))
77  LOG(VB_GENERAL, LOG_ERR, "Setting priority failed." + ENO);
78 
79  if (!QFileInfo(infile).isReadable() && (!chanid || !starttime.isValid()))
80  ProgramInfo::QueryKeyFromPathname(infile, chanid, starttime);
81 
82  ProgramInfo *pginfo = nullptr;
83  if (chanid && starttime.isValid())
84  {
85  pginfo = new ProgramInfo(chanid, starttime);
86  if (!pginfo->GetChanID())
87  {
88  LOG(VB_GENERAL, LOG_ERR,
89  QString("Cannot locate recording made on '%1' at '%2'")
90  .arg(chanid).arg(starttime.toString(Qt::ISODate)));
91  delete pginfo;
92  return GENERIC_EXIT_NOT_OK;
93  }
94  pginfo->SetPathname(pginfo->GetPlaybackURL(false, true));
95  }
96  else if (!infile.isEmpty())
97  {
98  if (!QFileInfo(infile).isReadable())
99  {
100  LOG(VB_GENERAL, LOG_ERR,
101  QString("Cannot read this file '%1'").arg(infile));
102  return GENERIC_EXIT_NOT_OK;
103  }
104  pginfo = new ProgramInfo(
105  infile, ""/*plot*/, ""/*title*/, ""/*sortTitle*/, ""/*subtitle*/,
106  ""/*sortSubtitle*/, ""/*director*/, 0/*season*/, 0/*episode*/,
107  ""/*inetref*/, 120/*length_in_minutes*/, 1895/*year*/, ""/*id*/);
108  }
109  else
110  {
111  LOG(VB_GENERAL, LOG_ERR, "Cannot locate recording to preview");
112  return GENERIC_EXIT_NOT_OK;
113  }
114 
115  PreviewGenerator *previewgen = new PreviewGenerator(
116  pginfo, QString(), PreviewGenerator::kLocal);
117 
118  if (previewFrameNumber >= 0)
119  previewgen->SetPreviewTimeAsFrameNumber(previewFrameNumber);
120 
121  if (previewSeconds >= 0)
122  previewgen->SetPreviewTimeAsSeconds(previewSeconds);
123 
124  previewgen->SetOutputSize(previewSize);
125  previewgen->SetOutputFilename(outfile);
126  bool ok = previewgen->RunReal();
127  previewgen->deleteLater();
128 
129  delete pginfo;
130 
131  return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_NOT_OK;
132 }
133 
134 int main(int argc, char **argv)
135 {
137  if (!cmdline.Parse(argc, argv))
138  {
139  cmdline.PrintHelp();
141  }
142 
143  if (cmdline.toBool("showhelp"))
144  {
145  cmdline.PrintHelp();
146  return GENERIC_EXIT_OK;
147  }
148 
149  if (cmdline.toBool("showversion"))
150  {
152  return GENERIC_EXIT_OK;
153  }
154 
155 #ifndef _WIN32
156  for (long i = UNUSED_FILENO; i < sysconf(_SC_OPEN_MAX) - 1; ++i)
157  close(i);
158  QCoreApplication a(argc, argv);
159 #else
160  // MINGW application needs a window to receive messages
161  // such as socket notifications :[
162  QApplication a(argc, argv);
163 #endif
164  QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHPREVIEWGEN);
165 
166  int retval;
167  if ((retval = cmdline.ConfigureLogging()) != GENERIC_EXIT_OK)
168  return retval;
169 
170  if ((!cmdline.toBool("chanid") || !cmdline.toBool("starttime")) &&
171  !cmdline.toBool("inputfile"))
172  {
173  cerr << "--generate-preview must be accompanied by either " <<endl
174  << "\nboth --chanid and --starttime parameters, " << endl
175  << "\nor the --infile parameter." << endl;
177  }
178 
180 
181  // Don't listen to console input
182  close(0);
183 
184  CleanupGuard callCleanup(cleanup);
185 
186 #ifndef _WIN32
187  QList<int> signallist;
188  signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
189  << SIGILL;
190 #if ! CONFIG_DARWIN
191  signallist << SIGRTMIN;
192 #endif
193  SignalHandler::Init(signallist);
194  SignalHandler::SetHandler(SIGHUP, logSigHup);
195 #endif
196 
197  if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
198  LOG(VB_GENERAL, LOG_WARNING, LOC + "Unable to ignore SIGPIPE");
199 
201 
202  if (!gContext->Init(false))
203  {
204  LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext.");
206  }
207 
208  int ret = preview_helper(
209  cmdline.toUInt("chanid"), cmdline.toDateTime("starttime"),
210  cmdline.toLongLong("frame"), cmdline.toLongLong("seconds"),
211  cmdline.toSize("size"),
212  cmdline.toString("inputfile"), cmdline.toString("outputfile"));
213  return ret;
214 }
215 
216 /* vim: set expandtab tabstop=4 shiftwidth=4: */
QDateTime toDateTime(const QString &key) const
Returns stored QVariant as a QDateTime, falling to default if not provided.
Startup context for MythTV.
Definition: mythcontext.h:42
int main(int argc, char **argv)
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
long long toLongLong(const QString &key) const
Returns stored QVariant as a long integer, falling to default if not provided.
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
void SetPathname(const QString &) const
void SetOutputFilename(const QString &)
void PrintHelp(void) const
Print command line option help.
static void Init(QList< int > &signallist, QObject *parent=nullptr)
QSize toSize(const QString &key) const
Returns stored QVariant as a QSize value, falling to default if not provided.
unsigned int uint
Definition: compat.h:140
MythContext * gContext
This global variable contains the MythContext instance for the application.
Definition: mythcontext.cpp:63
This class creates a preview image of a recording.
Holds information on recordings and videos.
Definition: programinfo.h:66
#define close
Definition: compat.h:16
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
static void Done(void)
static void SetHandler(int signum, SigHandlerFunc handler)
MythCommFlagCommandLineParser cmdline
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:99
static bool QueryKeyFromPathname(const QString &pathname, uint &chanid, QDateTime &recstartts)
void SetPreviewTimeAsFrameNumber(long long frame_number)
void SetOutputSize(const QSize &size)
void SetPreviewTimeAsSeconds(long long seconds_in)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
int preview_helper(uint chanid, QDateTime starttime, long long previewFrameNumber, long long previewSeconds, const QSize &previewSize, const QString &infile, const QString &outfile)
#define setpriority(x, y, z)
Definition: compat.h:203
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:364
static void cleanup(VideoFilter *filter)
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false) const
Returns filename or URL to be used to play back this recording.
#define SIGHUP
Definition: compat.h:213
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:16
#define MYTH_APPNAME_MYTHPREVIEWGEN
bool Init(const bool gui=true, const bool promptForBackend=false, const bool disableAutoDiscovery=false, const bool ignoreDB=false)
#define PRIO_PROCESS
Definition: compat.h:202
int ConfigureLogging(QString mask="general", unsigned int progress=0)
Read in logging options and initialize the logging interface.
#define GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:13
#define SIGPIPE
Definition: compat.h:218
bool RunReal(void)
This call creates a preview without starting a new thread.
#define GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:15
#define GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:11
uint toUInt(const QString &key) const
Returns stored QVariant as an unsigned integer, falling to default if not provided.
void PrintVersion(void) const
Print application version information.
Default UTC.
Definition: mythdate.h:14