MythTV master
mythpreviewgen.cpp
Go to the documentation of this file.
1// C++ headers
2#include <cerrno>
3#include <csignal>
4#include <cstdlib>
5#include <fcntl.h>
6#include <fstream>
7#include <iostream>
8#include <libgen.h>
9#include <sys/stat.h>
10#include <sys/time.h> // for setpriority
11#include <sys/types.h>
12#include <unistd.h>
13
14// Qt
15#include <QtGlobal>
16#ifndef _WIN32
17#include <QCoreApplication>
18#else
19#include <QApplication>
20#endif
21#include <QDir>
22#include <QFile>
23#include <QFileInfo>
24#include <QMap>
25
26// MythTV
27#include "libmyth/mythcontext.h"
28#include "libmythbase/compat.h"
31#include "libmythbase/mythdb.h"
33#include "libmythbase/mythversion.h"
36#include "libmythtv/dbcheck.h"
39
40//MythPreviewGen
42
43#define LOC QString("MythPreviewGen: ")
44#define LOC_WARN QString("MythPreviewGen, Warning: ")
45#define LOC_ERR QString("MythPreviewGen, Error: ")
46
47#ifdef Q_OS_MACOS
48// 10.6 uses some file handles for its new Grand Central Dispatch thingy
49static constexpr long UNUSED_FILENO { 5 };
50#else
51static constexpr long UNUSED_FILENO { 3 };
52#endif
53
54int preview_helper(uint chanid, QDateTime starttime,
55 long long previewFrameNumber, std::chrono::seconds previewSeconds,
56 const QSize previewSize,
57 const QString &infile, const QString &outfile)
58{
59 // Lower scheduling priority, to avoid problems with recordings.
60 if (setpriority(PRIO_PROCESS, 0, 9))
61 LOG(VB_GENERAL, LOG_ERR, "Setting priority failed." + ENO);
62
63 if (!QFileInfo(infile).isReadable() && ((chanid == 0U) || !starttime.isValid()))
64 ProgramInfo::QueryKeyFromPathname(infile, chanid, starttime);
65
66 ProgramInfo *pginfo = nullptr;
67 if (chanid && starttime.isValid())
68 {
69 pginfo = new ProgramInfo(chanid, starttime);
70 if (!pginfo->GetChanID())
71 {
72 LOG(VB_GENERAL, LOG_ERR,
73 QString("Cannot locate recording made on '%1' at '%2'")
74 .arg(chanid).arg(starttime.toString(Qt::ISODate)));
75 delete pginfo;
77 }
78 pginfo->SetPathname(pginfo->GetPlaybackURL(false, true));
79 }
80 else if (!infile.isEmpty())
81 {
82 if (!QFileInfo(infile).isReadable())
83 {
84 LOG(VB_GENERAL, LOG_ERR,
85 QString("Cannot read this file '%1'").arg(infile));
87 }
88 pginfo = new ProgramInfo(
89 infile, ""/*plot*/, ""/*title*/, ""/*sortTitle*/, ""/*subtitle*/,
90 ""/*sortSubtitle*/, ""/*director*/, 0/*season*/, 0/*episode*/,
91 ""/*inetref*/, 120min/*length_in_minutes*/, 1895/*year*/, ""/*id*/);
92 }
93 else
94 {
95 LOG(VB_GENERAL, LOG_ERR, "Cannot locate recording to preview");
97 }
98
99 auto *previewgen = new PreviewGenerator(pginfo, QString(),
101
102 if (previewFrameNumber >= 0)
103 previewgen->SetPreviewTimeAsFrameNumber(previewFrameNumber);
104
105 if (previewSeconds >= 0s)
106 previewgen->SetPreviewTimeAsSeconds(previewSeconds);
107
108 previewgen->SetOutputSize(previewSize);
109 previewgen->SetOutputFilename(outfile);
110 bool ok = previewgen->RunReal();
111 previewgen->deleteLater();
112
113 delete pginfo;
114
115 return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_NOT_OK;
116}
117
118int main(int argc, char **argv)
119{
121 if (!cmdline.Parse(argc, argv))
122 {
125 }
126
127 if (cmdline.toBool("showhelp"))
128 {
130 return GENERIC_EXIT_OK;
131 }
132
133 if (cmdline.toBool("showversion"))
134 {
136 return GENERIC_EXIT_OK;
137 }
138
139#ifndef _WIN32
140#if HAVE_CLOSE_RANGE
141 close_range(UNUSED_FILENO, sysconf(_SC_OPEN_MAX) - 1, 0);
142#else
143 for (long i = UNUSED_FILENO; i < sysconf(_SC_OPEN_MAX) - 1; ++i)
144 close(i);
145#endif
146 QCoreApplication a(argc, argv);
147#else
148 // MINGW application needs a window to receive messages
149 // such as socket notifications :[
150 QApplication a(argc, argv);
151#endif
152 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHPREVIEWGEN);
153
154 int retval = cmdline.ConfigureLogging();
155 if (retval != GENERIC_EXIT_OK)
156 return retval;
157
158 if ((!cmdline.toBool("chanid") || !cmdline.toBool("starttime")) &&
159 !cmdline.toBool("inputfile"))
160 {
161 std::cerr << "--generate-preview must be accompanied by either " <<std::endl
162 << "\nboth --chanid and --starttime parameters, " << std::endl
163 << "\nor the --infile parameter." << std::endl;
165 }
166
168
169 // Don't listen to console input
170 close(0);
171
172 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
173 LOG(VB_GENERAL, LOG_WARNING, LOC + "Unable to ignore SIGPIPE");
174
175 MythContext context {MYTH_BINARY_VERSION};
176 if (!context.Init(false))
177 {
178 LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext.");
180 }
181
182 int ret = preview_helper(
183 cmdline.toUInt("chanid"), cmdline.toDateTime("starttime"),
184 cmdline.toLongLong("frame"), std::chrono::seconds(cmdline.toLongLong("seconds")),
185 cmdline.toSize("size"),
186 cmdline.toString("inputfile"), cmdline.toString("outputfile"));
187 return ret;
188}
189
190/* vim: set expandtab tabstop=4 shiftwidth=4: */
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
QSize toSize(const QString &key) const
Returns stored QVariant as a QSize value, falling to default if not provided.
int ConfigureLogging(const QString &mask="general", bool progress=false)
Read in logging options and initialize the logging interface.
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
long long toLongLong(const QString &key) const
Returns stored QVariant as a long integer, falling to default if not provided.
static void PrintVersion(void)
Print application version information.
QDateTime toDateTime(const QString &key) const
Returns stored QVariant as a QDateTime, falling to default if not provided.
uint toUInt(const QString &key) const
Returns stored QVariant as an unsigned integer, falling to default if not provided.
void PrintHelp(void) const
Print command line option help.
Startup context for MythTV.
Definition: mythcontext.h:20
This class creates a preview image of a recording.
Holds information on recordings and videos.
Definition: programinfo.h:68
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:373
static bool QueryKeyFromPathname(const QString &pathname, uint &chanid, QDateTime &recstartts)
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false)
Returns filename or URL to be used to play back this recording.
void SetPathname(const QString &pn)
#define setpriority(x, y, z)
Definition: compat.h:129
#define SIGPIPE
Definition: compat.h:138
#define PRIO_PROCESS
Definition: compat.h:128
#define close
Definition: compat.h:39
@ GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:16
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:18
@ GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:14
unsigned int uint
Definition: freesurround.h:24
static constexpr const char * MYTH_APPNAME_MYTHPREVIEWGEN
Definition: mythappname.h:11
MythCommFlagCommandLineParser cmdline
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:74
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
#define LOC
int main(int argc, char **argv)
int preview_helper(uint chanid, QDateTime starttime, long long previewFrameNumber, std::chrono::seconds previewSeconds, const QSize previewSize, const QString &infile, const QString &outfile)
static constexpr long UNUSED_FILENO
@ ISODate
Default UTC.
Definition: mythdate.h:17