3#include "libmythbase/mythconfig.h"
6#include <linux/videodev2.h>
20#define TVREC_CARDNUM \
21 ((m_tvrec != nullptr) ? QString::number(m_tvrec->GetInputId()) : "NULL")
23#define LOC QString("V4LRec[%1](%2): ") \
24 .arg(TVREC_CARDNUM, m_videodevice)
58 if (name ==
"audiodevice")
60 else if (name ==
"vbidevice")
62 else if (name ==
"vbiformat")
81 fd = open(vbidev.constData(), O_RDONLY);
85 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid CC/Teletext mode");
91 LOG(VB_GENERAL, LOG_ERR,
LOC +
99 struct v4l2_format fmt {};
100 fmt.type = V4L2_BUF_TYPE_VBI_CAPTURE;
101 if (0 != ioctl(fd, VIDIOC_G_FMT, &fmt))
103 LOG(VB_RECORD, LOG_ERR,
"V4L2 VBI setup failed");
107 LOG(VB_RECORD, LOG_INFO,
LOC +
108 QString(
"vbi_format rate: %1"
109 "\n\t\t\t offset: %2"
110 "\n\t\t\tsamples_per_line: %3"
111 "\n\t\t\t starts: %4, %5"
112 "\n\t\t\t counts: %6, %7"
113 "\n\t\t\t flags: 0x%8")
114 .arg(fmt.fmt.vbi.sampling_rate)
115 .arg(fmt.fmt.vbi.offset)
116 .arg(fmt.fmt.vbi.samples_per_line)
117 .arg(fmt.fmt.vbi.start[0])
118 .arg(fmt.fmt.vbi.start[1])
119 .arg(fmt.fmt.vbi.count[0])
120 .arg(fmt.fmt.vbi.count[1])
121 .arg(fmt.fmt.vbi.flags,0,16));
123 width = fmt.fmt.vbi.samples_per_line;
124 start_line = fmt.fmt.vbi.start[0];
125 line_count = fmt.fmt.vbi.count[0];
126 if (line_count != fmt.fmt.vbi.count[1])
128 LOG(VB_GENERAL, LOG_ERR,
LOC +
129 "VBI must have the same number of "
130 "odd and even fields for our decoder");
134 if (start_line > 21 || start_line + line_count < 22)
136 LOG(VB_GENERAL, LOG_ERR,
LOC +
"VBI does not include line 21");
175 unsigned char *buf =
nullptr;
176 unsigned char *ptr =
nullptr;
177 unsigned char *ptr_end =
nullptr;
181 buf = ptr =
new unsigned char[sz];
193 struct timeval tv {0, 5000};
199 int nr = select(
m_vbiFd + 1, &rdset,
nullptr,
nullptr, &tv);
201 LOG(VB_GENERAL, LOG_ERR,
LOC +
"vbi select failed" +
ENO);
206 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"vbi select timed out");
212 ptr = (ret > 0) ? ptr + ret : ptr;
213 if ((ptr_end - ptr) == 0)
215 unsigned char *line21_field1 =
217 unsigned char *line21_field2 =
226 code1 = (0xFFFF==code1) ? -1 : code1;
227 code2 = (0xFFFF==code2) ? -1 : code2;
234 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Reading VBI data" +
ENO);
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
void SetOption(const QString &name, const QString &value) override
Set an specific option.
bool isRunning(void) const
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
virtual void StopRecording(void)
StopRecording() signals to the recorder that it should stop recording and exit cleanly.
virtual bool PauseAndWait(std::chrono::milliseconds timeout=100ms)
If m_requestPause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
bool m_requestRecording
True if API call has requested a recording be [re]started.
QWaitCondition m_unpauseWait
virtual bool IsHelperRequested(void) const
VBI608Extractor * m_vbi608
void CloseVBIDevice(void)
void StopRecording(void) override
StopRecording() signals to the recorder that it should stop recording and exit cleanly.
void SetOption(const QString &name, const QString &value) override
Set an specific option.
virtual void FormatCC(uint, uint)
volatile bool m_requestHelper
QString m_audioDeviceName
static uint Parse(const QString &vbiformat)
#define ENO
This can be appended to the LOG args with "+".
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
def read(device=None, features=[])