21#include <linux/videodev2.h>
23#include "libmythbase/mythconfig.h"
37#define LOC QString("MPEGRec[%1](%2): ") \
38 .arg(m_tvrec ? m_tvrec->GetInputId() : -1).arg(m_videodevice)
42 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
47 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
52 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
57 "MPEG-2 PS",
"MPEG-2 TS",
"MPEG-1 VCD",
"PES AV",
58 "",
"PES V",
"",
"PES A",
60 "SVCD",
"DVD-Special 1",
"DVD-Special 2"
65 "Square",
"4:3",
"16:9",
"2.21:1"
94static int find_index(
const std::array<const int,14> &audio_rate,
int value)
96 for (
uint i = 0; i < audio_rate.size(); i++)
98 if (audio_rate[i] == value)
109 else if (opt ==
"height")
111 else if (opt ==
"mpeg2bitrate")
113 else if (opt ==
"mpeg2maxbitrate")
115 else if (opt ==
"samplerate")
117 else if (opt ==
"mpeg2audbitratel1")
124 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L1): " +
125 QString(
"%1 is invalid").arg(value));
128 else if (opt ==
"mpeg2audbitratel2")
135 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L2): " +
136 QString(
"%1 is invalid").arg(value));
139 else if (opt ==
"mpeg2audbitratel3")
146 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L2): " +
147 QString(
"%1 is invalid").arg(value));
150 else if (opt ==
"mpeg2audvolume")
154 else if (opt.endsWith(
"_mpeg4avgbitrate"))
156 if (opt.startsWith(
"low"))
158 else if (opt.startsWith(
"medium"))
160 else if (opt.startsWith(
"high"))
165 else if (opt.endsWith(
"_mpeg4peakbitrate"))
167 if (opt.startsWith(
"low"))
169 else if (opt.startsWith(
"medium"))
171 else if (opt.startsWith(
"high"))
184 std::string value_ss = value.toStdString();
185 if (opt ==
"mpeg2streamtype")
214 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 stream type: " +
215 QString(
"%1 is invalid").arg(value));
218 else if (opt ==
"mpeg2language")
224 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 language (stereo) flag " +
225 QString(
"'%1' is invalid").arg(value));
228 else if (opt ==
"mpeg2aspectratio")
243 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 Aspect-ratio: " +
244 QString(
"%1 is invalid").arg(value));
247 else if (opt ==
"mpeg2audtype")
249 if (value ==
"Layer I")
250 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_1 + 1;
251 else if (value ==
"Layer II")
252 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_2 + 1;
253 else if (value ==
"Layer III")
254 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_3 + 1;
257 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 audio layer: " +
258 QString(
"%1 is invalid").arg(value));
261 else if (opt ==
"audiocodec")
263 if (value ==
"AAC Hardware Encoder")
264 m_audType = V4L2_MPEG_AUDIO_ENCODING_AAC + 1;
265 else if (value ==
"AC3 Hardware Encoder")
266 m_audType = V4L2_MPEG_AUDIO_ENCODING_AC3 + 1;
275 const QString &videodev,
276 [[maybe_unused]]
const QString &audiodev,
277 [[maybe_unused]]
const QString &vbidev)
279 if (videodev.startsWith(
"file:", Qt::CaseInsensitive))
283 QString newVideoDev = videodev;
284 if (newVideoDev.startsWith(
"file:", Qt::CaseInsensitive))
285 newVideoDev = newVideoDev.remove(0,5);
347 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Can't open MPEG File '%1'")
349 m_error =
LOC + QString(
"Can't open MPEG File '%1'")
362 m_chanfd = open(vdevice.constData(), O_RDWR);
365 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't open video device. " +
ENO);
372 bool supports_tuner =
false;
373 bool supports_audio =
false;
374 uint32_t capabilities = 0;
378 supports_tuner = ((capabilities & V4L2_CAP_TUNER) != 0U);
379 supports_audio = ((capabilities & V4L2_CAP_AUDIO) != 0U);
388 if (!(capabilities & V4L2_CAP_VIDEO_CAPTURE))
390 LOG(VB_GENERAL, LOG_ERR,
LOC +
"V4L version 1, unsupported");
423 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't open video device." +
ENO);
443 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate DRB buffer");
444 m_error =
"Failed to allocate DRB buffer";
454 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to setup DRB buffer");
455 m_error =
"Failed to setup DRB buffer";
463 LOG(VB_RECORD, LOG_INFO,
LOC +
"DRB ready");
477 struct v4l2_format vfmt {};
479 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
481 if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) < 0)
483 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error getting format" +
ENO);
491 if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0)
493 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error setting format" +
ENO);
504 struct v4l2_tuner vt {};
505 if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0)
507 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to get audio mode" +
ENO);
514 vt.audmode = V4L2_TUNER_MODE_LANG1;
517 vt.audmode = V4L2_TUNER_MODE_LANG2;
520 vt.audmode = V4L2_TUNER_MODE_LANG1_LANG2;
523 vt.audmode = V4L2_TUNER_MODE_LANG1;
530 LOG(VB_GENERAL, LOG_WARNING,
531 "Dual audio mode incompatible with Layer I audio."
532 "\n\t\t\tFalling back to Main Language");
533 vt.audmode = V4L2_TUNER_MODE_LANG1;
537 if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0)
539 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to set audio mode" +
ENO);
549 struct v4l2_queryctrl qctrl {};
550 qctrl.id = V4L2_CID_AUDIO_VOLUME;
551 if ((ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) ||
552 (qctrl.flags & V4L2_CTRL_FLAG_DISABLED))
554 LOG(VB_CHANNEL, LOG_WARNING,
555 LOC +
"Audio volume control not supported.");
560 int range = qctrl.maximum - qctrl.minimum;
561 int value = (int) ((range *
m_audVolume * 0.01F) + qctrl.minimum);
562 int ctrl_volume =
std::clamp(value, qctrl.minimum, qctrl.maximum);
565 struct v4l2_control ctrl {V4L2_CID_AUDIO_VOLUME, ctrl_volume};
567 if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
569 LOG(VB_GENERAL, LOG_WARNING,
LOC +
570 "Unable to set recording volume" +
ENO +
"\n\t\t\t" +
571 "If you are using an AverMedia M179 card this is normal.");
586 case 2: st = 2;
break;
589 case 14: st = 10;
break;
590 case 11: st = 11;
break;
591 case 12: st = 12;
break;
592 default: st = 0;
break;
598 LOG(VB_GENERAL, LOG_WARNING,
LOC +
599 QString(
"Stream type '%1'\n\t\t\t"
600 "is not supported by %2 driver, using '%3' instead.")
613 sr = (
m_driver ==
"ivtv") ? 48000 : sr;
617 LOG(VB_GENERAL, LOG_WARNING,
LOC +
618 QString(
"Audio sample rate %1 Hz\n\t\t\t"
619 "is not supported by %2 driver, using %3 Hz instead.")
625 case 32000:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000;
626 case 44100:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100;
628 default:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
638 layer = (
m_driver ==
"ivtv") ? 2 : layer;
642 LOG(VB_GENERAL, LOG_WARNING,
LOC +
643 QString(
"MPEG layer %1 does not work properly\n\t\t\t"
644 "with %2 driver. Using MPEG layer %3 audio instead.")
653 if (2 == audio_layer)
655 if (3 == audio_layer)
664 case 0:
return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
665 case 1:
return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
666 case 2:
return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD;
670 return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
671 case 10:
return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
672 case 11:
return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD;
673 case 12:
return V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD;
676 return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
677 default:
return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
681static void add_ext_ctrl(std::vector<struct v4l2_ext_control> &ctrl_list,
682 uint32_t
id, int32_t value)
684 struct v4l2_ext_control tmp_ctrl {};
686 tmp_ctrl.value = value;
687 ctrl_list.push_back(tmp_ctrl);
690static void set_ctrls(
int fd, std::vector<struct v4l2_ext_control> &ext_ctrls)
692 static QMutex s_controlDescriptionLock;
693 static QMap<uint32_t,QString> s_controlDescription;
695 s_controlDescriptionLock.lock();
696 if (s_controlDescription.isEmpty())
698 s_controlDescription[V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ] =
699 "Audio Sampling Frequency";
700 s_controlDescription[V4L2_CID_MPEG_VIDEO_ASPECT] =
701 "Video Aspect ratio";
702 s_controlDescription[V4L2_CID_MPEG_AUDIO_ENCODING] =
704 s_controlDescription[V4L2_CID_MPEG_AUDIO_L2_BITRATE] =
706 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE_PEAK] =
707 "Video Peak Bitrate";
708 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE] =
709 "Video Average Bitrate";
710 s_controlDescription[V4L2_CID_MPEG_STREAM_TYPE] =
712 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE_MODE] =
715 s_controlDescriptionLock.unlock();
717 for (
auto & ext_ctrl : ext_ctrls)
719 struct v4l2_ext_controls ctrls {};
721 int value = ext_ctrl.value;
723 ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
725 ctrls.controls = &ext_ctrl;
727 if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
729 QMutexLocker locker(&s_controlDescriptionLock);
730 LOG(VB_GENERAL, LOG_ERR, QString(
"mpegrecorder.cpp:set_ctrls(): ") +
731 QString(
"Could not set %1 to %2")
732 .arg(s_controlDescription[ext_ctrl.id]).arg(value) +
740 std::vector<struct v4l2_ext_control> ext_ctrls;
745 if (!
m_driver.startsWith(
"saa7164"))
747 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
775 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
777 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR :
778 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
784 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
793 struct v4l2_audio ain {};
794 ain.index = audioinput;
795 if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) < 0)
797 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to get audio input.");
801 ain.index = audioinput;
802 if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) < 0)
804 LOG(VB_GENERAL, LOG_WARNING,
805 LOC +
"Unable to set audio input.");
811 if (
m_driver ==
"hdpvr" && audioinput != 2)
813 struct v4l2_queryctrl qctrl {};
814 qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
816 if (!ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl))
819 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING, audio_enc);
823 LOG(VB_GENERAL, LOG_WARNING,
LOC +
824 "Unable to get supported audio codecs." +
ENO);
839#ifdef V4L2_CAP_SLICED_VBI_CAPTURE
849 struct v4l2_format vbifmt {};
850 vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
852 V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
854 if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
859 if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
861 LOG(VB_GENERAL, LOG_WARNING,
LOC +
862 "Unable to enable VBI embedding (/dev/vbiX)" +
ENO);
868 LOG(VB_GENERAL, LOG_WARNING,
LOC +
869 "Unable to enable VBI embedding (/dev/videoX)" +
ENO);
874 if (ioctl(fd, VIDIOC_G_FMT, &vbifmt) >= 0)
876 LOG(VB_RECORD, LOG_INFO,
877 LOC + QString(
"VBI service: %1, io size: %2")
878 .arg(vbifmt.fmt.sliced.service_set)
879 .arg(vbifmt.fmt.sliced.io_size));
881 struct v4l2_ext_control vbi_ctrl {};
882 vbi_ctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT;
883 vbi_ctrl.value = V4L2_MPEG_STREAM_VBI_FMT_IVTV;
885 struct v4l2_ext_controls ctrls {};
886 ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
888 ctrls.controls = &vbi_ctrl;
890 if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
892 LOG(VB_GENERAL, LOG_WARNING,
LOC +
893 "Unable to set VBI embedding format" +
ENO);
917 m_error =
"Failed to open V4L device";
921 bool has_select =
true;
958 bool good_data =
false;
964 long long bytesRead = 0;
968 int dummyBPS = qEnvironmentVariableIntValue(
"DUMMYBPS", &ok) / 8;
971 LOG(VB_GENERAL, LOG_INFO,
972 LOC + QString(
"Throttling dummy recorder to %1 bits per second")
976 struct timeval tv {};
980 elapsedTimer.
start();
983 LOG(VB_RECORD, LOG_INFO,
LOC +
"Initial startup of recorder");
995 if (dummyBPS && bytesRead)
997 elapsed = (elapsedTimer.
elapsed().count() / 1000.0F) + 1;
998 while ((bytesRead / elapsed) > dummyBPS)
1000 std::this_thread::sleep_for(50ms);
1001 elapsed = (elapsedTimer.
elapsed().count() / 1000.0F) + 1;
1006 elapsed = (elapsedTimer.
elapsed().count() / 1000.0F) + 1;
1009 std::this_thread::sleep_for(50ms);
1010 elapsed = (elapsedTimer.
elapsed().count() / 1000.0F) + 1;
1023 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Device error detected");
1045 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Device EOF detected");
1046 m_error =
"Device EOF detected";
1059 (gap_start, gap_end));
1060 LOG(VB_RECORD, LOG_DEBUG,
1061 LOC + QString(
"Inserted gap %1 dur %2")
1063 .arg(gap_start.secsTo(gap_end)));
1090 switch (select(
m_readfd + 1, &rdset,
nullptr,
nullptr, &tv))
1096 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Select error" +
ENO);
1100 LOG(VB_GENERAL, LOG_ERR,
LOC +
"select timeout - "
1101 "driver has stopped responding");
1105 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Close error" +
ENO);
1119 if (len < 0 && !has_select)
1130 m_readfd = open(vdevice.constData(), O_RDONLY);
1140 m_error =
"Failed to read from video file";
1144 else if (len < 0 && errno != EAGAIN)
1146 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"error reading from: %1")
1160 int start_remain = len - remainder;
1161 if (remainder && (start_remain >= remainder))
1162 memcpy(buffer, buffer+start_remain, remainder);
1164 memmove(buffer, buffer+start_remain, remainder);
1173 LOG(VB_RECORD, LOG_INFO,
LOC +
"run finishing up");
1209 const uint pid = tspacket_real.
PID();
1212 if ((
m_driver ==
"hdpvr") && (pid == 0x1001))
1220 const TSPacket &tspacket = (tspacket_fake)
1221 ? *tspacket_fake : tspacket_real;
1225 delete tspacket_fake;
1232 LOG(VB_RECORD, LOG_INFO,
LOC +
"Reset(void)");
1263 LOG(VB_RECORD, LOG_INFO,
LOC +
"PauseAndWait pause");
1279 LOG(VB_RECORD, LOG_INFO,
LOC +
"PauseAndWait unpause");
1300 LOG(VB_RECORD, LOG_INFO,
LOC +
"RestartEncoding");
1326 LOG(VB_RECORD, LOG_INFO,
LOC +
"StartEncoding");
1333 LOG(VB_GENERAL, LOG_ERR,
LOC +
1334 "StartEncoding: Can't open video device." +
ENO);
1335 m_error =
"Failed to start recording";
1343 bool good_res =
true;
1356 for ( ; idx < 50; ++idx)
1364 LOG(VB_GENERAL, LOG_ERR,
LOC +
1365 "StartEncoding: read failing, re-opening device: " +
ENO);
1367 std::this_thread::sleep_for(2ms);
1372 LOG(VB_GENERAL, LOG_ERR,
LOC +
1373 "StartEncoding: Can't open video device." +
ENO);
1374 m_error =
"Failed to start recording";
1380 LOG(VB_GENERAL, LOG_ERR,
LOC +
1381 QString(
"StartEncoding: read failed, retry in %1 msec:")
1382 .arg(100 * idx) +
ENO);
1383 std::this_thread::sleep_for(idx * 100us);
1388 LOG(VB_GENERAL, LOG_ERR,
LOC +
1389 "StartEncoding: read from video device failed." +
ENO);
1390 m_error =
"Failed to start recording";
1397 LOG(VB_RECORD, LOG_WARNING,
LOC +
1398 QString(
"%1 read attempts required to start encoding").arg(idx));
1418 LOG(VB_RECORD, LOG_INFO,
LOC +
"StopEncoding");
1423 struct v4l2_encoder_cmd command {};
1424 command.cmd = V4L2_ENC_CMD_STOP;
1425 command.flags = V4L2_ENC_CMD_STOP_AT_GOP_END;
1430 bool stopped = 0 == ioctl(
m_readfd, VIDIOC_ENCODER_CMD, &command);
1433 LOG(VB_RECORD, LOG_INFO,
LOC +
"Encoding stopped");
1435 else if (errno != ENOTTY && errno != EINVAL)
1441 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"StopEncoding failed" +
ENO);
1447 std::this_thread::sleep_for(20ms);
1463 const QString & reason)
1465 if (maxbitrate == bitrate)
1467 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"%1 bitrate %2 kbps CBR")
1468 .arg(reason).arg(bitrate));
1472 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"%1 bitrate %2/%3 kbps VBR")
1473 .arg(reason).arg(bitrate).arg(maxbitrate));
1476 std::vector<struct v4l2_ext_control> ext_ctrls;
1477 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
1478 (maxbitrate == bitrate) ?
1479 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR :
1480 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
1485 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
1493 LOG(VB_RECORD, LOG_INFO,
LOC +
"Checking Resolution");
1495 struct v4l2_format vfmt {};
1496 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1498 if (0 == ioctl(
m_chanfd, VIDIOC_G_FMT, &vfmt))
1500 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"Got Resolution %1x%2")
1501 .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height));
1502 pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height;
1507 LOG(VB_RECORD, LOG_INFO,
LOC +
"Giving up detecting resolution: " +
ENO);
1518 else if (pix >= 1920*1080)
1532 if (old_max == old_avg)
1534 LOG(VB_RECORD, LOG_INFO,
LOC +
1535 QString(
"Old bitrate %1 CBR").arg(old_avg));
1539 LOG(VB_RECORD, LOG_INFO,
LOC +
1540 QString(
"Old bitrate %1/%2 VBR") .arg(old_avg).arg(old_max));
1551 LOG(VB_VBI, LOG_INFO,
LOC + QString(
"FormatCC(0x%1,0x%2)")
1552 .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)