30 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
31 #define loadRelaxed load
36 "MPEG-2 PS",
"MPEG-2 TS",
"MPEG-1 VCD",
"PES AV",
37 "",
"PES V",
"",
"PES A",
39 "SVCD",
"DVD-Special 1",
"DVD-Special 2"
44 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
49 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
54 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
57 #define LOC QString("V4L2SH[%1](%2): ").arg(m_inputId).arg(m_device)
64 int audioinput,
int inputid)
68 const QString& devkey = devname;
70 QMap<QString,V4L2encStreamHandler*>::iterator it =
s_handlers.find(devkey);
79 LOG(VB_RECORD, LOG_INFO,
80 QString(
"V4L2SH[%1]: Creating new stream handler for %2")
81 .arg(inputid).arg(devname));
87 LOG(VB_RECORD, LOG_INFO,
88 QString(
"V4L2SH[%1]: Using existing stream handler for %2")
89 .arg(inputid).arg(devkey) + QString(
" (%1 in use)").arg(rcount));
105 LOG(VB_RECORD, LOG_INFO, QString(
"V4L2SH[%1]: Return '%2' in use %3")
106 .arg(inputid).arg(devname).arg(*rit));
115 QMap<QString, V4L2encStreamHandler*>::iterator it =
119 LOG(VB_RECORD, LOG_INFO, QString(
"V4L2SH[%1]: Closing handler for %2")
120 .arg(inputid).arg(devname));
126 LOG(VB_GENERAL, LOG_ERR,
127 QString(
"V4L2SH[%1]: Error: Couldn't find handler for %2")
128 .arg(inputid).arg(devname));
142 return !failed && !failing;
146 int audio_input,
int inputid)
148 , m_audioInput(audio_input)
154 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"-- Failed to open %1: ")
159 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"'%1' open").arg(
m_device));
172 LOG(VB_RECORD, LOG_INFO,
LOC +
"run() -- begin");
176 LOG(VB_GENERAL, LOG_WARNING,
LOC +
177 "Starting stream handler, but v4l2 is not open!");
180 LOG(VB_GENERAL, LOG_ERR,
LOC +
181 QString(
"run() -- Failed to open %1: ")
194 bool good_data =
false;
207 LOG(VB_RECORD, LOG_INFO,
LOC +
"Waiting for stream start.");
218 int len =
m_drb->
Read(
reinterpret_cast<unsigned char *
>(pkt_buf),
222 LOG(VB_GENERAL, LOG_ERR,
LOC +
"run() -- Device error detected");
240 LOG(VB_GENERAL, LOG_ERR,
LOC +
"run() -- Device EOF detected");
245 #if 0 // For this to work, the data needs to be propagated back up to
253 QMutexLocker locker(&statisticsLock);
256 for (Irec = m_rec_gaps.begin();
257 Irec != m_rec_caps.end(); ++Irec)
260 (gap_start, gap_end));
262 LOG(VB_RECORD, LOG_DEBUG,
263 LOC + QString(
"Inserted gap %1 dur %2")
264 .arg(recordingGaps.back().toString())
265 .arg(gap_start.secsTo(gap_end)));
282 LOG(VB_GENERAL, LOG_ERR,
LOC +
283 QString(
"run() -- error reading from: %1")
289 buffer.append(pkt_buf, len);
300 LOG(VB_GENERAL, LOG_ERR,
LOC +
301 QString(
"run() -- _stream_data_list is empty, %1 buffered")
302 .arg(buffer.size()));
310 remainder = sit.key()->ProcessData
311 (
reinterpret_cast<const uint8_t *
>
312 (buffer.constData()), len);
317 if (remainder > 0 && (len > remainder))
318 buffer.remove(0, len - remainder);
324 LOG(VB_GENERAL, LOG_WARNING,
LOC +
325 QString(
"_running_desired(%1) _error(%2)")
328 LOG(VB_RECORD, LOG_INFO,
LOC +
"run() -- finishing up");
336 LOG(VB_RECORD, LOG_INFO,
LOC +
"run() -- end");
342 LOG(VB_RECORD, LOG_INFO,
LOC +
"open() -- begin");
346 LOG(VB_RECORD, LOG_WARNING,
LOC +
"run() -- Already open.");
362 m_error =
"V4L version 2 required";
382 m_error =
"Failed to allocate DRB buffer";
391 m_error =
"Failed to setup DRB buffer";
397 LOG(VB_RECORD, LOG_INFO,
LOC +
"open() -- done");
405 LOG(VB_RECORD, LOG_INFO,
LOC +
"Configure() -- Already configured.");
409 LOG(VB_RECORD, LOG_INFO,
LOC +
"Configure() -- begin");
415 LOG(VB_RECORD, LOG_ERR,
LOC +
"Configure() -- failed");
428 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"Options for %1")
436 if (m_maxBitrate < 0 && m_highPeakBitrate > 0)
438 if (m_bitrate < 0 && m_highBitrate > 0)
453 LOG(VB_CHANNEL, LOG_WARNING,
"Audio input not set.");
464 LOG(VB_RECORD, LOG_INFO,
LOC +
"Configure() -- done");
472 if (m_vbi_thread !=
nullptr)
474 m_vbi_thread->wait();
476 m_vbi_thread =
nullptr;
495 LOG(VB_RECORD, LOG_INFO,
LOC +
"Closed.");
503 LOG(VB_RECORD, LOG_INFO,
LOC +
"StartEncoding() -- begin");
510 LOG(VB_GENERAL, LOG_ERR,
LOC +
"V4L2 recorder not initialized.");
518 LOG(VB_GENERAL, LOG_INFO,
LOC +
519 QString(
"Streaming mode %1. Not using it.")
524 for (
int idx = 0; idx < 10; ++idx)
541 for ( ; idx < 50; ++idx)
547 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"StartEncoding read %1 bytes").arg(len));
552 LOG(VB_GENERAL, LOG_ERR,
LOC +
553 "StartEncoding: read failing, re-opening device: " +
ENO);
555 std::this_thread::sleep_for(2ms);
559 LOG(VB_GENERAL, LOG_ERR,
LOC +
560 "StartEncoding: Can't open video device." +
ENO);
561 m_error =
"Failed to start recording";
567 LOG(VB_GENERAL, LOG_ERR,
LOC +
568 QString(
"StartEncoding: read failed, retry in %1 msec:")
569 .arg(100 * idx) +
ENO);
570 std::this_thread::sleep_for(idx * 100us);
575 LOG(VB_GENERAL, LOG_ERR,
LOC +
576 "StartEncoding: read from video device failed." +
ENO);
577 m_error =
"Failed to start recording";
584 LOG(VB_RECORD, LOG_WARNING,
LOC +
585 QString(
"%1 read attempts required to start encoding").arg(idx));
595 LOG(VB_RECORD, LOG_INFO,
LOC +
"Already encoding");
601 LOG(VB_RECORD, LOG_INFO,
LOC +
602 QString(
"StartEncoding() -- %1->%2 listeners")
605 LOG(VB_RECORD, LOG_INFO,
LOC +
"StartEncoding() -- end");
616 LOG(VB_RECORD, LOG_INFO,
LOC +
"StopEncoding: already stopped.");
624 LOG(VB_RECORD, LOG_INFO,
LOC +
625 QString(
"StopEncoding() -- delayed, still have %1 listeners")
632 LOG(VB_GENERAL, LOG_ERR,
LOC +
633 "StopEncoding() -- V4L2enc recorder not started.");
648 std::this_thread::sleep_for(20ms);
654 LOG(VB_RECORD, LOG_INFO,
LOC +
655 QString(
"StopEncoding() -- %1->%2 listeners")
663 LOG(VB_RECORD, LOG_INFO,
LOC +
"RestartEncoding()");
682 if (V4L2_TUNER_MODE_LANG1_LANG2 ==
m_langMode &&
685 LOG(VB_GENERAL, LOG_WARNING,
LOC +
686 "SetLanguageMode() -- Dual audio mode incompatible "
687 "with Layer I audio. Falling back to Main Language");
694 static int find_index(
const std::array<const int,14> &audio_rate,
int value)
696 for (
size_t i = 0; i < audio_rate.size(); ++i)
698 if (audio_rate[i] == value)
712 else if (opt ==
"height")
714 else if (opt ==
"mpeg2bitratemode")
717 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
719 else if (opt ==
"mpeg2bitrate")
723 else if (opt ==
"mpeg2maxbitrate")
727 else if (opt ==
"samplerate")
742 else if (opt ==
"mpeg2audbitratel1")
749 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L1): " +
750 QString(
"%1 is invalid").arg(value));
754 else if (opt ==
"mpeg2audbitratel2")
761 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L2): " +
762 QString(
"%1 is invalid").arg(value));
766 else if (opt ==
"mpeg2audbitratel3")
773 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Audiorate(L2): " +
774 QString(
"%1 is invalid").arg(value));
778 else if (opt ==
"mpeg2audvolume")
780 else if (opt ==
"low_mpegbitratemode")
782 else if (opt ==
"medium_mpegbitratemode")
784 else if (opt ==
"high_mpegbitratemode")
786 else if (opt.endsWith(
"avgbitrate"))
788 if (opt.startsWith(
"low"))
790 else if (opt.startsWith(
"medium"))
792 else if (opt.startsWith(
"high"))
797 else if (opt.endsWith(
"peakbitrate"))
799 if (opt.startsWith(
"low"))
801 else if (opt.startsWith(
"medium"))
803 else if (opt.startsWith(
"high"))
811 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetOption('%1', %2) -- success")
812 .arg(opt).arg(value));
828 if (opt ==
"vbidevice")
830 else if (opt ==
"mpeg2streamtype")
840 LOG(VB_GENERAL, LOG_ERR,
LOC +
841 QString(
"MPEG2 stream type %1 is invalid ").arg(value));
844 else if (opt ==
"mpeg2language")
847 int lang_mode = value.toInt(&ok);
850 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 language (stereo) flag " +
851 QString(
"'%1' is invalid").arg(value));
868 else if (opt ==
"mpeg2aspectratio")
870 if (value ==
"Square")
872 else if (value ==
"4:3")
874 else if (value ==
"16:9")
876 else if (value ==
"2.21:1")
881 else if (opt ==
"mpeg2audtype")
883 if (value ==
"Layer I")
885 else if (value ==
"Layer II")
887 else if (value ==
"Layer III")
891 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MPEG2 audio layer: " +
892 QString(
"%1 is invalid").arg(value));
895 else if (opt ==
"audiocodec")
897 if (value.startsWith(
"V4L2:"))
907 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetOption('%1', '%2') -- success")
924 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"GetSignalStrength() -- "
925 "returning cached value (%1)")
935 int bitratemode,
const QString & reason)
937 if (maxbitrate == bitrate)
939 LOG(VB_RECORD, LOG_INFO,
LOC +
940 QString(
"SetBitrate() -- %1 bitrate %2 kbps CBR")
941 .arg(reason).arg(bitrate));
945 LOG(VB_RECORD, LOG_INFO,
LOC +
946 QString(
"SetBitrate() -- %1 bitrate %2/%3 kbps VBR")
947 .arg(reason).arg(bitrate).arg(maxbitrate));
951 if (bitratemode >= 0)
970 for ( ; idx < 10; ++idx)
979 std::this_thread::sleep_for(100us);
986 int pix = width * height;
1015 if (old_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
1017 LOG(VB_RECORD, LOG_INFO,
LOC +
1018 QString(
"Old bitrate %1 CBR").arg(old_avg));
1022 LOG(VB_RECORD, LOG_INFO,
LOC +
1023 QString(
"Old bitrate %1/%2 VBR").arg(old_avg).arg(old_max));
1034 LOG(VB_GENERAL, LOG_INFO,
LOC +
"ConfigureVBI() -- begin");
1037 LOG(VB_RECORD, LOG_INFO,
LOC +
"ConfigureVBI() -- end");