14 #include <sys/types.h>
16 #include <sys/ioctl.h>
20 #include <linux/videodev2.h>
22 #include "libmythbase/mythconfig.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"
92 static 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)
107 else if (opt ==
"height")
109 else if (opt ==
"mpeg2bitrate")
111 else if (opt ==
"mpeg2maxbitrate")
113 else if (opt ==
"samplerate")
115 else if (opt ==
"mpeg2audbitratel1")
122 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L1): " +
123 QString(
"%1 is invalid").arg(value));
126 else if (opt ==
"mpeg2audbitratel2")
133 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L2): " +
134 QString(
"%1 is invalid").arg(value));
137 else if (opt ==
"mpeg2audbitratel3")
144 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L2): " +
145 QString(
"%1 is invalid").arg(value));
148 else if (opt ==
"mpeg2audvolume")
150 else if (opt.endsWith(
"_mpeg4avgbitrate"))
152 if (opt.startsWith(
"low"))
154 else if (opt.startsWith(
"medium"))
156 else if (opt.startsWith(
"high"))
161 else if (opt.endsWith(
"_mpeg4peakbitrate"))
163 if (opt.startsWith(
"low"))
165 else if (opt.startsWith(
"medium"))
167 else if (opt.startsWith(
"high"))
178 std::string value_ss = value.toStdString();
179 if (opt ==
"mpeg2streamtype")
208 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 stream type: " +
209 QString(
"%1 is invalid").arg(value));
212 else if (opt ==
"mpeg2language")
218 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 language (stereo) flag " +
219 QString(
"'%1' is invalid").arg(value));
222 else if (opt ==
"mpeg2aspectratio")
237 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 Aspect-ratio: " +
238 QString(
"%1 is invalid").arg(value));
241 else if (opt ==
"mpeg2audtype")
243 if (value ==
"Layer I")
244 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_1 + 1;
245 else if (value ==
"Layer II")
246 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_2 + 1;
247 else if (value ==
"Layer III")
248 m_audType = V4L2_MPEG_AUDIO_ENCODING_LAYER_3 + 1;
251 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 audio layer: " +
252 QString(
"%1 is invalid").arg(value));
255 else if (opt ==
"audiocodec")
257 if (value ==
"AAC Hardware Encoder")
258 m_audType = V4L2_MPEG_AUDIO_ENCODING_AAC + 1;
259 else if (value ==
"AC3 Hardware Encoder")
260 m_audType = V4L2_MPEG_AUDIO_ENCODING_AC3 + 1;
269 const QString &videodev,
270 [[maybe_unused]]
const QString &audiodev,
271 [[maybe_unused]]
const QString &vbidev)
273 if (videodev.startsWith(
"file:", Qt::CaseInsensitive))
277 QString newVideoDev = videodev;
278 if (newVideoDev.startsWith(
"file:", Qt::CaseInsensitive))
279 newVideoDev = newVideoDev.remove(0,5);
341 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Can't open MPEG File '%1'")
343 m_error =
LOC + QString(
"Can't open MPEG File '%1'")
356 m_chanfd = open(vdevice.constData(), O_RDWR);
359 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't open video device. " +
ENO);
366 bool supports_tuner =
false;
367 bool supports_audio =
false;
368 uint32_t capabilities = 0;
372 supports_tuner = ((capabilities & V4L2_CAP_TUNER) != 0U);
373 supports_audio = ((capabilities & V4L2_CAP_AUDIO) != 0U);
382 if (!(capabilities & V4L2_CAP_VIDEO_CAPTURE))
384 LOG(VB_GENERAL, LOG_ERR,
LOC +
"V4L version 1, unsupported");
417 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't open video device." +
ENO);
437 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate DRB buffer");
438 m_error =
"Failed to allocate DRB buffer";
448 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to setup DRB buffer");
449 m_error =
"Failed to setup DRB buffer";
457 LOG(VB_RECORD, LOG_INFO,
LOC +
"DRB ready");
471 struct v4l2_format vfmt {};
473 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
475 if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) < 0)
477 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error getting format" +
ENO);
485 if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0)
487 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error setting format" +
ENO);
498 struct v4l2_tuner vt {};
499 if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0)
501 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to get audio mode" +
ENO);
508 vt.audmode = V4L2_TUNER_MODE_LANG1;
511 vt.audmode = V4L2_TUNER_MODE_LANG2;
514 vt.audmode = V4L2_TUNER_MODE_LANG1_LANG2;
517 vt.audmode = V4L2_TUNER_MODE_LANG1;
524 LOG(VB_GENERAL, LOG_WARNING,
525 "Dual audio mode incompatible with Layer I audio."
526 "\n\t\t\tFalling back to Main Language");
527 vt.audmode = V4L2_TUNER_MODE_LANG1;
531 if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0)
533 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to set audio mode" +
ENO);
543 struct v4l2_queryctrl qctrl {};
544 qctrl.id = V4L2_CID_AUDIO_VOLUME;
545 if ((ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) ||
546 (qctrl.flags & V4L2_CTRL_FLAG_DISABLED))
548 LOG(VB_CHANNEL, LOG_WARNING,
549 LOC +
"Audio volume control not supported.");
554 int range = qctrl.maximum - qctrl.minimum;
555 int value = (int) ((range *
m_audVolume * 0.01F) + qctrl.minimum);
556 int ctrl_volume = std::min(qctrl.maximum, std::max(qctrl.minimum, value));
559 struct v4l2_control ctrl {V4L2_CID_AUDIO_VOLUME, ctrl_volume};
561 if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
563 LOG(VB_GENERAL, LOG_WARNING,
LOC +
564 "Unable to set recording volume" +
ENO +
"\n\t\t\t" +
565 "If you are using an AverMedia M179 card this is normal.");
580 case 2: st = 2;
break;
583 case 14: st = 10;
break;
584 case 11: st = 11;
break;
585 case 12: st = 12;
break;
586 default: st = 0;
break;
592 LOG(VB_GENERAL, LOG_WARNING,
LOC +
593 QString(
"Stream type '%1'\n\t\t\t"
594 "is not supported by %2 driver, using '%3' instead.")
607 sr = (
m_driver ==
"ivtv") ? 48000 : sr;
611 LOG(VB_GENERAL, LOG_WARNING,
LOC +
612 QString(
"Audio sample rate %1 Hz\n\t\t\t"
613 "is not supported by %2 driver, using %3 Hz instead.")
619 case 32000:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000;
620 case 44100:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100;
622 default:
return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
630 layer = std::max(std::min(layer, 3U), 1U);
632 layer = (
m_driver ==
"ivtv") ? 2 : layer;
636 LOG(VB_GENERAL, LOG_WARNING,
LOC +
637 QString(
"MPEG layer %1 does not work properly\n\t\t\t"
638 "with %2 driver. Using MPEG layer %3 audio instead.")
655 case 0:
return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
656 case 1:
return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
657 case 2:
return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD;
661 return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
662 case 10:
return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
663 case 11:
return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD;
664 case 12:
return V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD;
667 return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
668 default:
return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
672 static void add_ext_ctrl(std::vector<struct v4l2_ext_control> &ctrl_list,
673 uint32_t
id, int32_t value)
675 struct v4l2_ext_control tmp_ctrl {};
677 tmp_ctrl.value = value;
678 ctrl_list.push_back(tmp_ctrl);
681 static void set_ctrls(
int fd, std::vector<struct v4l2_ext_control> &ext_ctrls)
683 static QMutex s_controlDescriptionLock;
684 static QMap<uint32_t,QString> s_controlDescription;
686 s_controlDescriptionLock.lock();
687 if (s_controlDescription.isEmpty())
689 s_controlDescription[V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ] =
690 "Audio Sampling Frequency";
691 s_controlDescription[V4L2_CID_MPEG_VIDEO_ASPECT] =
692 "Video Aspect ratio";
693 s_controlDescription[V4L2_CID_MPEG_AUDIO_ENCODING] =
695 s_controlDescription[V4L2_CID_MPEG_AUDIO_L2_BITRATE] =
697 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE_PEAK] =
698 "Video Peak Bitrate";
699 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE] =
700 "Video Average Bitrate";
701 s_controlDescription[V4L2_CID_MPEG_STREAM_TYPE] =
703 s_controlDescription[V4L2_CID_MPEG_VIDEO_BITRATE_MODE] =
706 s_controlDescriptionLock.unlock();
708 for (
auto & ext_ctrl : ext_ctrls)
710 struct v4l2_ext_controls ctrls {};
712 int value = ext_ctrl.value;
714 ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
716 ctrls.controls = &ext_ctrl;
718 if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
720 QMutexLocker locker(&s_controlDescriptionLock);
721 LOG(VB_GENERAL, LOG_ERR, QString(
"mpegrecorder.cpp:set_ctrls(): ") +
722 QString(
"Could not set %1 to %2")
723 .arg(s_controlDescription[ext_ctrl.id]).arg(value) +
731 std::vector<struct v4l2_ext_control> ext_ctrls;
736 if (!
m_driver.startsWith(
"saa7164"))
738 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
766 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
768 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR :
769 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
775 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
784 struct v4l2_audio ain {};
785 ain.index = audioinput;
786 if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) < 0)
788 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unable to get audio input.");
792 ain.index = audioinput;
793 if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) < 0)
795 LOG(VB_GENERAL, LOG_WARNING,
796 LOC +
"Unable to set audio input.");
802 if (
m_driver ==
"hdpvr" && audioinput != 2)
804 struct v4l2_queryctrl qctrl {};
805 qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
807 if (!ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl))
809 uint audio_enc = std::max(std::min(
m_audType-1, qctrl.maximum), qctrl.minimum);
810 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING, audio_enc);
814 LOG(VB_GENERAL, LOG_WARNING,
LOC +
815 "Unable to get supported audio codecs." +
ENO);
830 #ifdef V4L2_CAP_SLICED_VBI_CAPTURE
840 struct v4l2_format vbifmt {};
841 vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
843 V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
845 if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
850 if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
852 LOG(VB_GENERAL, LOG_WARNING,
LOC +
853 "Unable to enable VBI embedding (/dev/vbiX)" +
ENO);
859 LOG(VB_GENERAL, LOG_WARNING,
LOC +
860 "Unable to enable VBI embedding (/dev/videoX)" +
ENO);
865 if (ioctl(fd, VIDIOC_G_FMT, &vbifmt) >= 0)
867 LOG(VB_RECORD, LOG_INFO,
868 LOC + QString(
"VBI service: %1, io size: %2")
869 .arg(vbifmt.fmt.sliced.service_set)
870 .arg(vbifmt.fmt.sliced.io_size));
872 struct v4l2_ext_control vbi_ctrl {};
873 vbi_ctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT;
874 vbi_ctrl.value = V4L2_MPEG_STREAM_VBI_FMT_IVTV;
876 struct v4l2_ext_controls ctrls {};
877 ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
879 ctrls.controls = &vbi_ctrl;
881 if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
883 LOG(VB_GENERAL, LOG_WARNING,
LOC +
884 "Unable to set VBI embedding format" +
ENO);
892 #endif // V4L2_CAP_SLICED_VBI_CAPTURE
908 m_error =
"Failed to open V4L device";
912 bool has_select =
true;
914 #if defined(__FreeBSD__)
949 bool good_data =
false;
955 long long bytesRead = 0;
959 int dummyBPS = qEnvironmentVariableIntValue(
"DUMMYBPS", &ok) / 8;
962 LOG(VB_GENERAL, LOG_INFO,
963 LOC + QString(
"Throttling dummy recorder to %1 bits per second")
967 struct timeval tv {};
971 elapsedTimer.
start();
974 LOG(VB_RECORD, LOG_INFO,
LOC +
"Initial startup of recorder");
986 if (dummyBPS && bytesRead)
988 elapsed = (elapsedTimer.
elapsed().count() / 1000.0) + 1;
989 while ((bytesRead / elapsed) > dummyBPS)
991 std::this_thread::sleep_for(50ms);
992 elapsed = (elapsedTimer.
elapsed().count() / 1000.0) + 1;
997 elapsed = (elapsedTimer.
elapsed().count() / 1000.0) + 1;
1000 std::this_thread::sleep_for(50ms);
1001 elapsed = (elapsedTimer.
elapsed().count() / 1000.0) + 1;
1014 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Device error detected");
1034 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Device EOF detected");
1035 m_error =
"Device EOF detected";
1048 (gap_start, gap_end));
1049 LOG(VB_RECORD, LOG_DEBUG,
1050 LOC + QString(
"Inserted gap %1 dur %2")
1052 .arg(gap_start.secsTo(gap_end)));
1073 switch (select(
m_readfd + 1, &rdset,
nullptr,
nullptr, &tv))
1079 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Select error" +
ENO);
1083 LOG(VB_GENERAL, LOG_ERR,
LOC +
"select timeout - "
1084 "driver has stopped responding");
1088 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Close error" +
ENO);
1102 if (len < 0 && !has_select)
1113 m_readfd = open(vdevice.constData(), O_RDONLY);
1123 m_error =
"Failed to read from video file";
1127 else if (len < 0 && errno != EAGAIN)
1129 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"error reading from: %1")
1143 int start_remain = len - remainder;
1144 if (remainder && (start_remain >= remainder))
1145 memcpy(buffer, buffer+start_remain, remainder);
1147 memmove(buffer, buffer+start_remain, remainder);
1156 LOG(VB_RECORD, LOG_INFO,
LOC +
"run finishing up");
1192 const uint pid = tspacket_real.
PID();
1195 if ((
m_driver ==
"hdpvr") && (pid == 0x1001))
1203 const TSPacket &tspacket = (tspacket_fake)
1204 ? *tspacket_fake : tspacket_real;
1208 delete tspacket_fake;
1215 LOG(VB_RECORD, LOG_INFO,
LOC +
"Reset(void)");
1246 LOG(VB_RECORD, LOG_INFO,
LOC +
"PauseAndWait pause");
1262 LOG(VB_RECORD, LOG_INFO,
LOC +
"PauseAndWait unpause");
1283 LOG(VB_RECORD, LOG_INFO,
LOC +
"RestartEncoding");
1309 LOG(VB_RECORD, LOG_INFO,
LOC +
"StartEncoding");
1316 LOG(VB_GENERAL, LOG_ERR,
LOC +
1317 "StartEncoding: Can't open video device." +
ENO);
1318 m_error =
"Failed to start recording";
1326 bool good_res =
true;
1339 for ( ; idx < 50; ++idx)
1347 LOG(VB_GENERAL, LOG_ERR,
LOC +
1348 "StartEncoding: read failing, re-opening device: " +
ENO);
1350 std::this_thread::sleep_for(2ms);
1355 LOG(VB_GENERAL, LOG_ERR,
LOC +
1356 "StartEncoding: Can't open video device." +
ENO);
1357 m_error =
"Failed to start recording";
1363 LOG(VB_GENERAL, LOG_ERR,
LOC +
1364 QString(
"StartEncoding: read failed, retry in %1 msec:")
1365 .arg(100 * idx) +
ENO);
1366 std::this_thread::sleep_for(idx * 100us);
1371 LOG(VB_GENERAL, LOG_ERR,
LOC +
1372 "StartEncoding: read from video device failed." +
ENO);
1373 m_error =
"Failed to start recording";
1380 LOG(VB_RECORD, LOG_WARNING,
LOC +
1381 QString(
"%1 read attempts required to start encoding").arg(idx));
1401 LOG(VB_RECORD, LOG_INFO,
LOC +
"StopEncoding");
1406 struct v4l2_encoder_cmd command {};
1407 command.cmd = V4L2_ENC_CMD_STOP;
1408 command.flags = V4L2_ENC_CMD_STOP_AT_GOP_END;
1413 bool stopped = 0 == ioctl(
m_readfd, VIDIOC_ENCODER_CMD, &command);
1416 LOG(VB_RECORD, LOG_INFO,
LOC +
"Encoding stopped");
1418 else if (errno != ENOTTY && errno != EINVAL)
1424 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"StopEncoding failed" +
ENO);
1430 std::this_thread::sleep_for(20ms);
1446 const QString & reason)
1448 if (maxbitrate == bitrate)
1450 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"%1 bitrate %2 kbps CBR")
1451 .arg(reason).arg(bitrate));
1455 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"%1 bitrate %2/%3 kbps VBR")
1456 .arg(reason).arg(bitrate).arg(maxbitrate));
1459 std::vector<struct v4l2_ext_control> ext_ctrls;
1460 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
1461 (maxbitrate == bitrate) ?
1462 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR :
1463 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
1468 add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
1476 LOG(VB_RECORD, LOG_INFO,
LOC +
"Checking Resolution");
1478 struct v4l2_format vfmt {};
1479 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1481 if (0 == ioctl(
m_chanfd, VIDIOC_G_FMT, &vfmt))
1483 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"Got Resolution %1x%2")
1484 .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height));
1485 pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height;
1490 LOG(VB_RECORD, LOG_INFO,
LOC +
"Giving up detecting resolution: " +
ENO);
1501 else if (pix >= 1920*1080)
1515 if (old_max == old_avg)
1517 LOG(VB_RECORD, LOG_INFO,
LOC +
1518 QString(
"Old bitrate %1 CBR").arg(old_avg));
1522 LOG(VB_RECORD, LOG_INFO,
LOC +
1523 QString(
"Old bitrate %1/%2 VBR") .arg(old_avg).arg(old_max));
1534 LOG(VB_VBI, LOG_INFO,
LOC + QString(
"FormatCC(0x%1,0x%2)")
1535 .arg(code1,0,16).arg(code2,0,16));