21#include <linux/videodev2.h>
35#define LOC QString("MPEGRec[%1](%2): ") \
36 .arg(m_tvrec ? m_tvrec->GetInputId() : -1).arg(m_videodevice)
40 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
45 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
50 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
55 "MPEG-2 PS",
"MPEG-2 TS",
"MPEG-1 VCD",
"PES AV",
56 "",
"PES V",
"",
"PES A",
58 "SVCD",
"DVD-Special 1",
"DVD-Special 2"
63 "Square",
"4:3",
"16:9",
"2.21:1"
92static int find_index(
const std::array<const int,14> &audio_rate,
int value)
94 for (
uint i = 0; i < audio_rate.size(); i++)
96 if (audio_rate[i] == value)
109 else if (opt ==
"height")
113 else if (opt ==
"mpeg2bitrate")
117 else if (opt ==
"mpeg2maxbitrate")
121 else if (opt ==
"samplerate")
125 else if (opt ==
"mpeg2audbitratel1")
134 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L1): " +
135 QString(
"%1 is invalid").arg(value));
138 else if (opt ==
"mpeg2audbitratel2")
147 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L2): " +
148 QString(
"%1 is invalid").arg(value));
151 else if (opt ==
"mpeg2audbitratel3")
160 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L2): " +
161 QString(
"%1 is invalid").arg(value));
164 else if (opt ==
"mpeg2audvolume")
168 else if (opt.endsWith(
"_mpeg4avgbitrate"))
170 if (opt.startsWith(
"low"))
172 else if (opt.startsWith(
"medium"))
174 else if (opt.startsWith(
"high"))
179 else if (opt.endsWith(
"_mpeg4peakbitrate"))
181 if (opt.startsWith(
"low"))
183 else if (opt.startsWith(
"medium"))
185 else if (opt.startsWith(
"high"))
198 std::string value_ss = value.toStdString();
199 if (opt ==
"mpeg2streamtype")
228 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 stream type: " +
229 QString(
"%1 is invalid").arg(value));
232 else if (opt ==
"mpeg2language")
238 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 language (stereo) flag " +
239 QString(
"'%1' is invalid").arg(value));
242 else if (opt ==
"mpeg2aspectratio")
257 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 Aspect-ratio: " +
258 QString(
"%1 is invalid").arg(value));
261 else if (opt ==
"mpeg2audtype")
263 if (value ==
"Layer I")
265 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_1 + 1;
267 else if (value ==
"Layer II")
269 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_2 + 1;
271 else if (value ==
"Layer III")
273 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_3 + 1;
277 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 audio layer: " +
278 QString(
"%1 is invalid").arg(value));
281 else if (opt ==
"audiocodec")
283 if (value ==
"AAC Hardware Encoder")
284 m_audType = V4L2_MPEG_AUDIO_ENCODING_AAC + 1;
285 else if (value ==
"AC3 Hardware Encoder")
286 m_audType = V4L2_MPEG_AUDIO_ENCODING_AC3 + 1;
295 const QString &videodev,
296 [[maybe_unused]]
const QString &audiodev,
297 [[maybe_unused]]
const QString &vbidev)
299 if (videodev.startsWith(
"file:", Qt::CaseInsensitive))
303 QString newVideoDev = videodev;
304 if (newVideoDev.startsWith(
"file:", Qt::CaseInsensitive))
305 newVideoDev = newVideoDev.remove(0,5);
367 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Can't open MPEG File '%1'")
369 m_error =
LOC + QString(
"Can't open MPEG File '%1'")
382 m_chanfd = open(vdevice.constData(), O_RDWR);
385 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't open video device. " +
ENO);
392 bool supports_tuner =
false;
393 bool supports_audio =
false;
394 uint32_t capabilities = 0;
398 supports_tuner = ((capabilities & V4L2_CAP_TUNER) != 0U);
399 supports_audio = ((capabilities & V4L2_CAP_AUDIO) != 0U);
408 if (!(capabilities & V4L2_CAP_VIDEO_CAPTURE))
410 LOG(VB_GENERAL, LOG_ERR,
LOC +
"V4L version 1, unsupported");
443 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't open video device." +
ENO);
463 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate DRB buffer");
464 m_error =
"Failed to allocate DRB buffer";
474 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to setup DRB buffer");
475 m_error =
"Failed to setup DRB buffer";
483 LOG(VB_RECORD, LOG_INFO,
LOC +
"DRB ready");
497 struct v4l2_format vfmt {};
499 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
501 if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) < 0)
503 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error getting format" +
ENO);
511 if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0)
513 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error setting format" +
ENO);
524 struct v4l2_tuner vt {};
525 if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0)
527 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to get audio mode" +
ENO);
534 vt.audmode = V4L2_TUNER_MODE_LANG1;
537 vt.audmode = V4L2_TUNER_MODE_LANG2;
540 vt.audmode = V4L2_TUNER_MODE_LANG1_LANG2;
543 vt.audmode = V4L2_TUNER_MODE_LANG1;
550 LOG(VB_GENERAL, LOG_WARNING,
551 "Dual audio mode incompatible with Layer I audio."
552 "\n\t\t\tFalling back to Main Language");
553 vt.audmode = V4L2_TUNER_MODE_LANG1;
557 if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0)
559 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to set audio mode" +
ENO);
569 struct v4l2_queryctrl qctrl {};
570 qctrl.id = V4L2_CID_AUDIO_VOLUME;
571 if ((ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) ||
572 (qctrl.flags & V4L2_CTRL_FLAG_DISABLED))
574 LOG(VB_CHANNEL, LOG_WARNING,
575 LOC +
"Audio volume control not supported.");
580 int range = qctrl.maximum - qctrl.minimum;
581 int value = (int) ((range *
m_audVolume * 0.01F) + qctrl.minimum);
582 int ctrl_volume =
std::clamp(value, qctrl.minimum, qctrl.maximum);
585 struct v4l2_control ctrl {.id=V4L2_CID_AUDIO_VOLUME, .value=ctrl_volume};
587 if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
589 LOG(VB_GENERAL, LOG_WARNING,
LOC +
590 "Unable to set recording volume" +
ENO +
"\n\t\t\t" +
591 "If you are using an AverMedia M179 card this is normal.");
606 case 2: st = 2;
break;
609 case 14: st = 10;
break;
610 case 11: st = 11;
break;
611 case 12: st = 12;
break;
612 default: st = 0;
break;
618 LOG(VB_GENERAL, LOG_WARNING,
LOC +
619 QString(
"Stream type '%1'\n\t\t\t"
620 "is not supported by %2 driver, using '%3' instead.")
633 sr = (
m_driver ==
"ivtv") ? 48000 : sr;
637 LOG(VB_GENERAL, LOG_WARNING,
LOC +
638 QString(
"Audio sample rate %1 Hz\n\t\t\t"
639 "is not supported by %2 driver, using %3 Hz instead.")
645 case 32000:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000;
646 case 44100:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100;
648 default:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
658 layer = (
m_driver ==
"ivtv") ? 2 : layer;
662 LOG(VB_GENERAL, LOG_WARNING,
LOC +
663 QString(
"MPEG layer %1 does not work properly\n\t\t\t"
664 "with %2 driver. Using MPEG layer %3 audio instead.")
673 if (2 == audio_layer)
675 if (3 == audio_layer)
684 case 0:
return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
685 case 1:
return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
686 case 2:
return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD;
690 return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
691 case 10:
return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
692 case 11:
return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD;
693 case 12:
return V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD;
696 return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
697 default:
return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
701static void add_ext_ctrl(std::vector<struct v4l2_ext_control> &ctrl_list,
702 uint32_t
id, int32_t value)
704 struct v4l2_ext_control tmp_ctrl {};
706 tmp_ctrl.value = value;
707 ctrl_list.push_back(tmp_ctrl);
710static void set_ctrls(
int fd, std::vector<struct v4l2_ext_control> &ext_ctrls)
712 static QMutex s_controlDescriptionLock;
713 static QMap<uint32_t,QString> s_controlDescription;
715 s_controlDescriptionLock.lock();
716 if (s_controlDescription.isEmpty())
718 s_controlDescription[V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ] =
719 "Audio Sampling Frequency";
720 s_controlDescription[V4L2_CID_MPEG_VIDEO_ASPECT] =
721 "Video Aspect ratio";
722 s_controlDescription[V4L2_CID_MPEG_AUDIO_ENCODING] =
724 s_controlDescription[V4L2_CID_MPEG_AUDIO_L2_BITRATE] =
726 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE_PEAK] =
727 "Video Peak Bitrate";
728 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE] =
729 "Video Average Bitrate";
730 s_controlDescription[V4L2_CID_MPEG_STREAM_TYPE] =
732 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE_MODE] =
735 s_controlDescriptionLock.unlock();
737 for (
auto & ext_ctrl : ext_ctrls)
739 struct v4l2_ext_controls ctrls {};
741 int value = ext_ctrl.value;
743 ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
745 ctrls.controls = &ext_ctrl;
747 if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
749 QMutexLocker locker(&s_controlDescriptionLock);
750 LOG(VB_GENERAL, LOG_ERR, QString(
"mpegrecorder.cpp:set_ctrls(): ") +
751 QString(
"Could not set %1 to %2")
752 .arg(s_controlDescription[ext_ctrl.id]).arg(value) +
760 std::vector<struct v4l2_ext_control> ext_ctrls;
765 if (!
m_driver.startsWith(
"saa7164"))
767 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
795 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
797 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR :
798 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
804 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
813 struct v4l2_audio ain {};
814 ain.index = audioinput;
815 if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) < 0)
817 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to get audio input.");
821 ain.index = audioinput;
822 if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) < 0)
824 LOG(VB_GENERAL, LOG_WARNING,
825 LOC +
"Unable to set audio input.");
831 if (
m_driver ==
"hdpvr" && audioinput != 2)
833 struct v4l2_queryctrl qctrl {};
834 qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
836 if (!ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl))
839 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING, audio_enc);
843 LOG(VB_GENERAL, LOG_WARNING,
LOC +
844 "Unable to get supported audio codecs." +
ENO);
859#ifdef V4L2_CAP_SLICED_VBI_CAPTURE
869 struct v4l2_format vbifmt {};
870 vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
872 V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
874 if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
879 if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
881 LOG(VB_GENERAL, LOG_WARNING,
LOC +
882 "Unable to enable VBI embedding (/dev/vbiX)" +
ENO);
888 LOG(VB_GENERAL, LOG_WARNING,
LOC +
889 "Unable to enable VBI embedding (/dev/videoX)" +
ENO);
894 if (ioctl(fd, VIDIOC_G_FMT, &vbifmt) >= 0)
896 LOG(VB_RECORD, LOG_INFO,
897 LOC + QString(
"VBI service: %1, io size: %2")
898 .arg(vbifmt.fmt.sliced.service_set)
899 .arg(vbifmt.fmt.sliced.io_size));
901 struct v4l2_ext_control vbi_ctrl {};
902 vbi_ctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT;
903 vbi_ctrl.value = V4L2_MPEG_STREAM_VBI_FMT_IVTV;
905 struct v4l2_ext_controls ctrls {};
906 ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
908 ctrls.controls = &vbi_ctrl;
910 if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
912 LOG(VB_GENERAL, LOG_WARNING,
LOC +
913 "Unable to set VBI embedding format" +
ENO);
937 m_error =
"Failed to open V4L device";
941 bool has_select =
true;
978 bool good_data =
false;
984 long long bytesRead = 0;
988 int dummyBPS = qEnvironmentVariableIntValue(
"DUMMYBPS", &ok) / 8;
991 LOG(VB_GENERAL, LOG_INFO,
992 LOC + QString(
"Throttling dummy recorder to %1 bits per second")
996 struct timeval tv {};
1001 elapsedTimer.
start();
1005 LOG(VB_RECORD, LOG_INFO,
LOC +
"Initial startup of recorder");
1017 if (dummyBPS && bytesRead)
1019 elapsed = (elapsedTimer.
elapsed().count() / 1000.0F) + 1;
1020 while ((bytesRead / elapsed) > dummyBPS)
1022 std::this_thread::sleep_for(50ms);
1023 elapsed = (elapsedTimer.
elapsed().count() / 1000.0F) + 1;
1028 elapsed = (elapsedTimer.
elapsed().count() / 1000.0F) + 1;
1031 std::this_thread::sleep_for(50ms);
1032 elapsed = (elapsedTimer.
elapsed().count() / 1000.0F) + 1;
1045 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Device error detected");
1067 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Device EOF detected");
1068 m_error =
"Device EOF detected";
1081 (gap_start, gap_end));
1082 LOG(VB_RECORD, LOG_DEBUG,
1083 LOC + QString(
"Inserted gap %1 dur %2")
1085 .arg(gap_start.secsTo(gap_end)));
1112 switch (select(
m_readfd + 1, &rdset,
nullptr,
nullptr, &tv))
1118 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Select error" +
ENO);
1122 LOG(VB_GENERAL, LOG_ERR,
LOC +
"select timeout - "
1123 "driver has stopped responding");
1127 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Close error" +
ENO);
1141 if (len < 0 && !has_select)
1152 m_readfd = open(vdevice.constData(), O_RDONLY);
1162 m_error =
"Failed to read from video file";
1166 else if (len < 0 && errno != EAGAIN)
1168 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"error reading from: %1")
1182 int start_remain = len - remainder;
1183 if (remainder && (start_remain >= remainder))
1184 memcpy(buffer, buffer+start_remain, remainder);
1186 memmove(buffer, buffer+start_remain, remainder);
1195 LOG(VB_RECORD, LOG_INFO,
LOC +
"run finishing up");
1231 const uint pid = tspacket_real.
PID();
1234 if ((
m_driver ==
"hdpvr") && (pid == 0x1001))
1242 const TSPacket &tspacket = tspacket_fake
1243 ? *tspacket_fake : tspacket_real;
1247 delete tspacket_fake;
1254 LOG(VB_RECORD, LOG_INFO,
LOC +
"Reset(void)");
1285 LOG(VB_RECORD, LOG_INFO,
LOC +
"PauseAndWait pause");
1301 LOG(VB_RECORD, LOG_INFO,
LOC +
"PauseAndWait unpause");
1322 LOG(VB_RECORD, LOG_INFO,
LOC +
"RestartEncoding");
1348 LOG(VB_RECORD, LOG_INFO,
LOC +
"StartEncoding");
1355 LOG(VB_GENERAL, LOG_ERR,
LOC +
1356 "StartEncoding: Can't open video device." +
ENO);
1357 m_error =
"Failed to start recording";
1365 bool good_res =
true;
1378 for ( ; idx < 50; ++idx)
1386 LOG(VB_GENERAL, LOG_ERR,
LOC +
1387 "StartEncoding: read failing, re-opening device: " +
ENO);
1389 std::this_thread::sleep_for(2ms);
1394 LOG(VB_GENERAL, LOG_ERR,
LOC +
1395 "StartEncoding: Can't open video device." +
ENO);
1396 m_error =
"Failed to start recording";
1402 LOG(VB_GENERAL, LOG_ERR,
LOC +
1403 QString(
"StartEncoding: read failed, retry in %1 msec:")
1404 .arg(100 * idx) +
ENO);
1405 std::this_thread::sleep_for(idx * 100us);
1410 LOG(VB_GENERAL, LOG_ERR,
LOC +
1411 "StartEncoding: read from video device failed." +
ENO);
1412 m_error =
"Failed to start recording";
1419 LOG(VB_RECORD, LOG_WARNING,
LOC +
1420 QString(
"%1 read attempts required to start encoding").arg(idx));
1440 LOG(VB_RECORD, LOG_INFO,
LOC +
"StopEncoding");
1445 struct v4l2_encoder_cmd command {};
1446 command.cmd = V4L2_ENC_CMD_STOP;
1447 command.flags = V4L2_ENC_CMD_STOP_AT_GOP_END;
1452 bool stopped = 0 == ioctl(
m_readfd, VIDIOC_ENCODER_CMD, &command);
1455 LOG(VB_RECORD, LOG_INFO,
LOC +
"Encoding stopped");
1457 else if (errno != ENOTTY && errno != EINVAL)
1463 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"StopEncoding failed" +
ENO);
1469 std::this_thread::sleep_for(20ms);
1485 const QString & reason)
1487 if (maxbitrate == bitrate)
1489 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"%1 bitrate %2 kbps CBR")
1490 .arg(reason).arg(bitrate));
1494 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"%1 bitrate %2/%3 kbps VBR")
1495 .arg(reason).arg(bitrate).arg(maxbitrate));
1498 std::vector<struct v4l2_ext_control> ext_ctrls;
1499 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
1500 (maxbitrate == bitrate) ?
1501 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR :
1502 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
1507 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
1515 LOG(VB_RECORD, LOG_INFO,
LOC +
"Checking Resolution");
1517 struct v4l2_format vfmt {};
1518 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1520 if (0 == ioctl(
m_chanfd, VIDIOC_G_FMT, &vfmt))
1522 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"Got Resolution %1x%2")
1523 .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height));
1524 pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height;
1529 LOG(VB_RECORD, LOG_INFO,
LOC +
"Giving up detecting resolution: " +
ENO);
1540 else if (pix >= 1920*1080)
1554 if (old_max == old_avg)
1556 LOG(VB_RECORD, LOG_INFO,
LOC +
1557 QString(
"Old bitrate %1 CBR").arg(old_avg));
1561 LOG(VB_RECORD, LOG_INFO,
LOC +
1562 QString(
"Old bitrate %1/%2 VBR") .arg(old_avg).arg(old_max));
1573 LOG(VB_VBI, LOG_INFO,
LOC + QString(
"FormatCC(0x%1,0x%2)")
1574 .arg(code1,0,16).arg(code2,0,16));
static bool GetV4LInfo(int videofd, QString &input, QString &driver, uint32_t &version, uint32_t &capabilities)
QString m_error
non-empty iff irrecoverable recording error detected
void FinishRecording(void) override
Flushes the ringbuffer, and if this is not a live LiveTV recording saves the position map and filesiz...
std::array< uint8_t, 0x1fff+1 > m_continuityCounter
std::vector< unsigned char > m_payloadBuffer
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
void ResetForNewFile(void) override
bool ProcessTSPacket(const TSPacket &tspacket) override
H2645Parser * m_h2645Parser
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
long long GetFramesWritten(void) override
Returns number of frames written to disk.
bool m_waitForKeyframeOption
Wait for the a GOP/SEQ-start before sending data.
MPEGStreamData * m_streamData
void FindPSKeyFrames(const uint8_t *buffer, uint len) override
virtual void SetStreamData(MPEGStreamData *data)
void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override
Buffers reads from device files.
bool IsRunning(void) const
bool Setup(const QString &streamName, int streamfd, uint readQuanta=sizeof(TSPacket), uint deviceBufferSize=0, uint deviceBufferCount=1)
void SetRequestPause(bool request)
uint Read(unsigned char *buf, uint count)
Try to Read count bytes from into buffer.
bool IsErrored(void) const
void Reset(const QString &streamName, int streamfd)
Encapsulates data about MPEG stream and emits events for each table.
void SetDesiredProgram(int p)
const ProgramMapTable * PMTSingleProgram(void) const
void AddWritingListener(TSPacketListener *val)
void AddMPEGSPListener(MPEGSingleProgramStreamListener *val)
int DesiredProgram(void) const
void RemoveWritingListener(TSPacketListener *val)
const ProgramAssociationTable * PATSingleProgram(void) const
virtual int ProcessData(const unsigned char *buffer, int len)
void RemoveAVListener(TSPacketListenerAV *val)
void AddAVListener(TSPacketListenerAV *val)
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
QRecursiveMutex m_startStopEncodingLock
void InitStreamData(void) override
unsigned int m_mediumMpeg4PeakBitrate
static const std::array< const int, 14 > kAudRateL1
void SetOption(const QString &opt, int value) override
handles the "wait_for_seqstart" option.
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
unsigned int m_mediumMpeg4AvgBitrate
bool PauseAndWait(std::chrono::milliseconds timeout=100ms) override
If m_requestPause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
bool SetV4L2DeviceOptions(int chanfd)
static const std::array< const int, 14 > kAudRateL2
void Reset(void) override
Reset the recorder to the startup state.
void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev) override
Sets basic recorder options.
static const std::array< const std::string, 15 > kStreamType
bool ProcessTSPacket(const TSPacket &tspacket) override
void SetBitrate(int bitrate, int maxbitrate, const QString &reason)
void SetStrOption(RecordingProfile *profile, const QString &name)
bool SetRecordingVolume(int chanfd)
DeviceReadBuffer * m_deviceReadBuffer
void SetIntOption(RecordingProfile *profile, const QString &name)
uint GetFilteredAudioSampleRate(void) const
static const std::array< const std::string, 4 > kAspectRatio
bool RestartEncoding(void)
bool OpenMpegFileAsInput(void)
unsigned int m_lowMpeg4PeakBitrate
bool OpenV4L2DeviceAsInput(void)
bool SetLanguageMode(int chanfd)
Set audio language mode.
uint GetFilteredAudioLayer(void) const
static const std::array< const int, 14 > kAudRateL3
unsigned int m_highMpeg4PeakBitrate
bool HandleResolutionChanges(void)
unsigned int m_language
0 is Main Lang; 1 is SAP Lang; 2 is Dual
void Pause(bool clear=true) override
Pause tells recorder to pause, it should not block.
unsigned int m_lowMpeg4AvgBitrate
uint GetFilteredAudioBitRate(uint audio_layer) const
bool SetVideoCaptureFormat(int chanfd)
void FormatCC(uint code1, uint code2) override
bool SetVBIOptions(int chanfd)
uint GetFilteredStreamType(void) const
unsigned int m_highMpeg4AvgBitrate
QString GetSetting(const QString &key, const QString &defaultval="")
A QElapsedTimer based timer to replace use of QTime as a timer.
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
void start(void)
starts measuring elapsed time.
void ClearPositionMap(MarkTypes type) const
AVContainer m_containerFormat
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.
bool m_recording
True while recording is actually being performed.
virtual void SetRecordingStatus(RecStatus::Type status, const QString &file, int line)
QWaitCondition m_pauseWait
RecordingGaps m_recordingGaps
virtual bool IsPaused(bool holding_lock=false) const
Returns true iff recorder is paused.
bool m_requestRecording
True if API call has requested a recording be [re]started.
RecordingInfo * m_curRecording
QWaitCondition m_unpauseWait
QWaitCondition m_recordingWait
virtual QString getValue(void) const
Used to access the data of a Transport Stream packet.
TSPacket * CreateClone(void) const
static constexpr unsigned int kSize
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
uint GetInputId(void) const
Returns the inputid.
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.
volatile bool m_requestHelper
QString m_audioDeviceName
static void add_ext_ctrl(std::vector< struct v4l2_ext_control > &ctrl_list, uint32_t id, int32_t value)
static int find_index(const std::array< const int, 14 > &audio_rate, int value)
static int streamtype_ivtv_to_v4l2(int st)
static void set_ctrls(int fd, std::vector< struct v4l2_ext_control > &ext_ctrls)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
#define ENO
This can be appended to the LOG args with "+".
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
def read(device=None, features=[])
static eu8 clamp(eu8 value, eu8 low, eu8 high)