12 #include <QCoreApplication>
21 #include "libmythbase/mythversion.h"
28 static constexpr
const char*
VERSION {
"1.0.0" };
29 #define LOC QString("File(%1): ").arg(m_fileName)
32 int data_rate,
bool loopinput) :
33 m_parent(parent), m_fileName(std::move(fname)),
34 m_loop(loopinput), m_dataRate(data_rate)
36 setObjectName(
"Streamer");
43 LOG(VB_RECORD, LOG_INFO,
LOC +
"Streamer::dtor -- begin");
45 LOG(VB_RECORD, LOG_INFO,
LOC +
"Streamer::dtor -- end");
53 LOG(VB_RECORD, LOG_ERR,
LOC + QString(
"Failed to open '%1' - ")
60 LOG(VB_RECORD, LOG_INFO,
LOC +
"Streamer::Close -- begin");
68 LOG(VB_RECORD, LOG_INFO,
LOC +
"Streamer::Close -- end");
76 LOG(VB_RECORD, LOG_DEBUG,
LOC +
"SendBytes -- start");
80 LOG(VB_GENERAL, LOG_ERR,
LOC +
"SendBytes -- file not open");
100 read_sz = std::min(rate, read_sz);
101 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
109 QByteArray buffer =
m_file->read(read_sz);
111 pkt_size = buffer.size();
118 LOG(VB_RECORD, LOG_WARNING,
LOC +
119 QString(
"SendBytes -- Overflow: %1 > %2, "
120 "dropping first %3 bytes.")
131 LOG(VB_RECORD, LOG_DEBUG,
LOC +
"SendBytes -- Buffer is empty.");
136 LOG(VB_RECORD, LOG_DEBUG,
LOC +
137 QString(
"SendBytes -- Read %1 from file. %2 bytes buffered")
138 .arg(pkt_size).arg(buf_size));
141 write_len = std::min(write_len, buf_size);
142 LOG(VB_RECORD, LOG_DEBUG,
LOC +
143 QString(
"SendBytes -- writing %1 bytes").arg(write_len));
147 LOG(VB_RECORD, LOG_DEBUG,
LOC +
148 QString(
"SendBytes -- wrote %1 bytes").arg(wrote));
150 if (wrote < buf_size)
153 LOG(VB_RECORD, LOG_WARNING,
LOC +
154 QString(
"%1 bytes unwritten").arg(
m_buffer.size()));
161 LOG(VB_RECORD, LOG_DEBUG,
LOC +
"SendBytes -- end");
167 setObjectName(
"Command");
172 QByteArray buf = status.toLatin1() +
'\n';
173 int len =
write(2, buf.constData(), buf.size());
174 if (len != buf.size())
176 LOG(VB_RECORD, LOG_ERR,
LOC +
177 QString(
"Status -- Wrote %1 of %2 bytes of status '%3'")
178 .arg(len).arg(status.size()).arg(status));
181 LOG(VB_RECORD, LOG_DEBUG,
"Status: " + status);
187 LOG(VB_RECORD, LOG_DEBUG,
LOC + cmd);
189 if (cmd.startsWith(
"Version?"))
194 if (cmd.startsWith(
"APIVersion?"))
199 if (cmd.startsWith(
"APIVersion:1"))
201 QString reply = (
API_VERSION == 1) ?
"OK:Yes":
"OK:No";
205 if (cmd.startsWith(
"HasLock?"))
210 if (cmd.startsWith(
"SignalStrengthPercent"))
215 if (cmd.startsWith(
"LockTimeout"))
220 if (cmd.startsWith(
"HasTuner?"))
225 if (cmd.startsWith(
"HasPictureAttributes?"))
234 LOG(VB_RECORD, LOG_ERR,
LOC + QString(
"%1 failed - not initialized!")
239 if (cmd.startsWith(
"SendBytes"))
244 LOG(VB_RECORD, LOG_ERR,
LOC +
"SendBytes - file not open.");
248 if (
m_eof.loadAcquire() != 0)
258 else if (cmd.startsWith(
"XON"))
262 else if (cmd.startsWith(
"XOFF"))
266 else if (cmd.startsWith(
"TuneChannel"))
275 else if (cmd.startsWith(
"IsOpen?"))
283 else if (cmd.startsWith(
"CloseRecorder"))
289 else if (cmd.startsWith(
"FlowControl?"))
293 else if (cmd.startsWith(
"BlockSize"))
298 else if (cmd.startsWith(
"StartStreaming"))
302 else if (cmd.startsWith(
"StopStreaming"))
311 send_status(QString(
"ERR:Unknown command '%1'").arg(cmd));
312 LOG(VB_RECORD, LOG_ERR,
LOC + QString(
"Unknown command '%1'")
324 std::array<struct pollfd,2> polls {};
327 polls[0].events = POLLIN | POLLPRI;
328 polls[0].revents = 0;
333 auto *streamThread =
new QThread(
this);
336 connect(streamThread, &QThread::finished,
342 streamThread->start();
345 input.open(stdin, QIODevice::ReadOnly);
346 QTextStream qtin(&input);
348 LOG(VB_RECORD, LOG_INFO,
LOC +
"Listening for commands");
352 int ret = poll(polls.data(), poll_cnt,
m_timeout);
354 if (polls[0].revents & POLLHUP)
356 LOG(VB_RECORD, LOG_ERR,
LOC +
"poll eof (POLLHUP)");
359 if (polls[0].revents & POLLNVAL)
361 LOG(VB_RECORD, LOG_ERR,
LOC +
"poll error");
365 if (polls[0].revents & POLLIN)
369 cmd = qtin.readLine();
372 streamThread->quit();
373 streamThread->wait();
375 streamThread =
nullptr;
382 if ((EOVERFLOW == errno))
384 LOG(VB_RECORD, LOG_ERR,
LOC +
"command overflow.");
388 if ((EAGAIN == errno) || (EINTR == errno))
390 LOG(VB_RECORD, LOG_ERR,
LOC +
"retry command read.");
394 LOG(VB_RECORD, LOG_ERR,
LOC +
"unknown error reading command.");
403 int main(
int argc,
char *argv[])
428 QCoreApplication a(argc, argv);
429 QCoreApplication::setApplicationName(
"mythfilerecorder");