MythTV  master
mpegrecorder.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 // C++ headers
4 #include <algorithm>
5 #include <chrono> // for milliseconds
6 #include <cinttypes>
7 #include <ctime>
8 #include <fcntl.h>
9 #include <thread> // for sleep_for
10 #include <unistd.h>
11 #include <vector>
12 using namespace std;
13 
14 // System headers
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/ioctl.h>
18 #include <sys/time.h>
19 #include <sys/poll.h>
20 
21 #include <linux/videodev2.h>
22 
23 #include "mythconfig.h"
24 
25 // MythTV headers
26 #include "mpegrecorder.h"
27 #include "ringbuffer.h"
28 #include "mythcorecontext.h"
29 #include "programinfo.h"
30 #include "recordingprofile.h"
31 #include "tv_rec.h"
32 #include "mythdate.h"
33 #include "cardutil.h"
34 
35 // ivtv header
36 extern "C" {
37 #include "ivtv_myth.h"
38 }
39 
40 #define IVTV_KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
41 
42 #define LOC QString("MPEGRec[%1](%2): ") \
43  .arg(m_tvrec ? m_tvrec->GetInputId() : -1).arg(m_videodevice)
44 
45 const int MpegRecorder::s_audRateL1[] =
46 {
47  32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0
48 };
49 
50 const int MpegRecorder::s_audRateL2[] =
51 {
52  32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0
53 };
54 
55 const int MpegRecorder::s_audRateL3[] =
56 {
57  32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0
58 };
59 
60 const char* MpegRecorder::s_streamType[] =
61 {
62  "MPEG-2 PS", "MPEG-2 TS", "MPEG-1 VCD", "PES AV",
63  "", "PES V", "", "PES A",
64  "", "", "DVD", "VCD",
65  "SVCD", "DVD-Special 1", "DVD-Special 2", nullptr
66 };
67 
68 const char* MpegRecorder::s_aspectRatio[] =
69 {
70  "Square", "4:3", "16:9", "2.21:1", nullptr
71 };
72 
74 {
75  StopRecording();
76 
77  if (m_chanfd >= 0)
78  {
79  close(m_chanfd);
80  m_chanfd = -1;
81  }
82  if (m_readfd >= 0)
83  {
84  close(m_readfd);
85  m_readfd = -1;
86  }
87 
88  if (m_device_read_buffer)
89  {
90  if (m_device_read_buffer->IsRunning())
91  m_device_read_buffer->Stop();
92 
93  delete m_device_read_buffer;
94  m_device_read_buffer = nullptr;
95  }
96 
97 }
98 
99 static int find_index(const int *audio_rate, int value)
100 {
101  for (uint i = 0; audio_rate[i] != 0; i++)
102  {
103  if (audio_rate[i] == value)
104  return i;
105  }
106 
107  return -1;
108 }
109 
110 void MpegRecorder::SetOption(const QString &opt, int value)
111 {
112  if (opt == "width")
113  m_width = value;
114  else if (opt == "height")
115  m_height = value;
116  else if (opt == "mpeg2bitrate")
117  m_bitrate = value;
118  else if (opt == "mpeg2maxbitrate")
119  m_maxbitrate = value;
120  else if (opt == "samplerate")
121  m_audsamplerate = value;
122  else if (opt == "mpeg2audbitratel1")
123  {
124  int index = find_index(s_audRateL1, value);
125  if (index >= 0)
126  m_audbitratel1 = index + 1;
127  else
128  {
129  LOG(VB_GENERAL, LOG_ERR, LOC + "Audiorate(L1): " +
130  QString("%1 is invalid").arg(value));
131  }
132  }
133  else if (opt == "mpeg2audbitratel2")
134  {
135  int index = find_index(s_audRateL2, value);
136  if (index >= 0)
137  m_audbitratel2 = index + 1;
138  else
139  {
140  LOG(VB_GENERAL, LOG_ERR, LOC + "Audiorate(L2): " +
141  QString("%1 is invalid").arg(value));
142  }
143  }
144  else if (opt == "mpeg2audbitratel3")
145  {
146  int index = find_index(s_audRateL3, value);
147  if (index >= 0)
148  m_audbitratel3 = index + 1;
149  else
150  {
151  LOG(VB_GENERAL, LOG_ERR, LOC + "Audiorate(L2): " +
152  QString("%1 is invalid").arg(value));
153  }
154  }
155  else if (opt == "mpeg2audvolume")
156  m_audvolume = value;
157  else if (opt.endsWith("_mpeg4avgbitrate"))
158  {
159  if (opt.startsWith("low"))
160  m_low_mpeg4avgbitrate = value;
161  else if (opt.startsWith("medium"))
162  m_medium_mpeg4avgbitrate = value;
163  else if (opt.startsWith("high"))
164  m_high_mpeg4avgbitrate = value;
165  else
166  V4LRecorder::SetOption(opt, value);
167  }
168  else if (opt.endsWith("_mpeg4peakbitrate"))
169  {
170  if (opt.startsWith("low"))
171  m_low_mpeg4peakbitrate = value;
172  else if (opt.startsWith("medium"))
173  m_medium_mpeg4peakbitrate = value;
174  else if (opt.startsWith("high"))
175  m_high_mpeg4peakbitrate = value;
176  else
177  V4LRecorder::SetOption(opt, value);
178  }
179  else
180  V4LRecorder::SetOption(opt, value);
181 }
182 
183 void MpegRecorder::SetOption(const QString &opt, const QString &value)
184 {
185  if (opt == "mpeg2streamtype")
186  {
187  bool found = false;
188  for (size_t i = 0; i < sizeof(s_streamType) / sizeof(char*); i++)
189  {
190  if (QString(s_streamType[i]) == value)
191  {
192  if (QString(s_streamType[i]) == "MPEG-2 TS")
193  {
194  m_containerFormat = formatMPEG2_TS;
195  }
196  else if (QString(s_streamType[i]) == "MPEG-2 PS")
197  {
198  m_containerFormat = formatMPEG2_PS;
199  }
200  else
201  {
202  // TODO Expand AVContainer to include other types in
203  // streamType
204  m_containerFormat = formatUnknown;
205  }
206  m_streamtype = i;
207  found = true;
208  break;
209  }
210  }
211 
212  if (!found)
213  {
214  LOG(VB_GENERAL, LOG_ERR, LOC + "MPEG2 stream type: " +
215  QString("%1 is invalid").arg(value));
216  }
217  }
218  else if (opt == "mpeg2language")
219  {
220  bool ok = false;
221  m_language = value.toInt(&ok); // on failure language will be 0
222  if (!ok)
223  {
224  LOG(VB_GENERAL, LOG_ERR, LOC + "MPEG2 language (stereo) flag " +
225  QString("'%1' is invalid").arg(value));
226  }
227  }
228  else if (opt == "mpeg2aspectratio")
229  {
230  bool found = false;
231  for (int i = 0; s_aspectRatio[i] != nullptr; i++)
232  {
233  if (QString(s_aspectRatio[i]) == value)
234  {
235  m_aspectratio = i + 1;
236  found = true;
237  break;
238  }
239  }
240 
241  if (!found)
242  {
243  LOG(VB_GENERAL, LOG_ERR, LOC + "MPEG2 Aspect-ratio: " +
244  QString("%1 is invalid").arg(value));
245  }
246  }
247  else if (opt == "mpeg2audtype")
248  {
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;
255  else
256  {
257  LOG(VB_GENERAL, LOG_ERR, LOC + "MPEG2 audio layer: " +
258  QString("%1 is invalid").arg(value));
259  }
260  }
261  else if (opt == "audiocodec")
262  {
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;
267  }
268  else
269  {
270  V4LRecorder::SetOption(opt, value);
271  }
272 }
273 
275  const QString &videodev,
276  const QString &audiodev,
277  const QString &vbidev)
278 {
279  (void)audiodev;
280  (void)vbidev;
281 
282  if (videodev.toLower().startsWith("file:"))
283  {
284  m_deviceIsMpegFile = true;
285  m_bufferSize = 64000;
286  QString newVideoDev = videodev;
287  if (newVideoDev.startsWith("file:", Qt::CaseInsensitive))
288  newVideoDev = newVideoDev.remove(0,5);
289  SetOption("videodevice", newVideoDev);
290  }
291  else
292  {
293  SetOption("videodevice", videodev);
294  }
295  SetOption("vbidevice", vbidev);
296  SetOption("audiodevice", audiodev);
297 
298  SetOption("tvformat", gCoreContext->GetSetting("TVFormat"));
299  SetOption("vbiformat", gCoreContext->GetSetting("VbiFormat"));
300 
301  SetIntOption(profile, "mpeg2bitrate");
302  SetIntOption(profile, "mpeg2maxbitrate");
303  SetStrOption(profile, "mpeg2streamtype");
304  SetStrOption(profile, "mpeg2aspectratio");
305  SetStrOption(profile, "mpeg2language");
306 
307  SetIntOption(profile, "samplerate");
308  SetStrOption(profile, "mpeg2audtype");
309  SetIntOption(profile, "mpeg2audbitratel1");
310  SetIntOption(profile, "mpeg2audbitratel2");
311  SetIntOption(profile, "mpeg2audbitratel3");
312  SetIntOption(profile, "mpeg2audvolume");
313 
314  SetIntOption(profile, "width");
315  SetIntOption(profile, "height");
316 
317  SetIntOption(profile, "low_mpeg4avgbitrate");
318  SetIntOption(profile, "low_mpeg4peakbitrate");
319  SetIntOption(profile, "medium_mpeg4avgbitrate");
320  SetIntOption(profile, "medium_mpeg4peakbitrate");
321  SetIntOption(profile, "high_mpeg4avgbitrate");
322  SetIntOption(profile, "high_mpeg4peakbitrate");
323 
324  SetStrOption(profile, "audiocodec");
325 }
326 
327 // same as the base class, it just doesn't complain if an option is missing
329 {
330  const StandardSetting *setting = profile->byName(name);
331  if (setting)
332  SetOption(name, setting->getValue().toInt());
333 }
334 
335 // same as the base class, it just doesn't complain if an option is missing
337 {
338  const StandardSetting *setting = profile->byName(name);
339  if (setting)
340  SetOption(name, setting->getValue());
341 }
342 
344 {
345  QByteArray vdevice = m_videodevice.toLatin1();
346  m_chanfd = m_readfd = open(vdevice.constData(), O_RDONLY);
347 
348  if (m_readfd < 0)
349  {
350  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Can't open MPEG File '%1'")
351  .arg(m_videodevice) + ENO);
352  m_error = LOC + QString("Can't open MPEG File '%1'")
353  .arg(m_videodevice) + ENO;
354  return false;
355  }
356  return true;
357 }
358 
360 {
361  // open implicitly starts encoding, so we need the lock..
362  QMutexLocker locker(&m_start_stop_encoding_lock);
363 
364  QByteArray vdevice = m_videodevice.toLatin1();
365  m_chanfd = open(vdevice.constData(), O_RDWR);
366  if (m_chanfd < 0)
367  {
368  LOG(VB_GENERAL, LOG_ERR, LOC + "Can't open video device. " + ENO);
369  m_error = LOC + "Can't open video device. " + ENO;
370  return false;
371  }
372 
373  m_bufferSize = 4096;
374 
375  bool supports_tuner = false, supports_audio = false;
376  uint32_t capabilities = 0;
377  if (CardUtil::GetV4LInfo(m_chanfd, m_card, m_driver, m_version, capabilities))
378  {
379  m_supports_sliced_vbi = ((capabilities & V4L2_CAP_SLICED_VBI_CAPTURE) != 0U);
380  supports_tuner = ((capabilities & V4L2_CAP_TUNER) != 0U);
381  supports_audio = ((capabilities & V4L2_CAP_AUDIO) != 0U);
383  if (m_driver == "hdpvr")
384  {
385  m_bufferSize = 1500 * TSPacket::kSize;
386  m_h264_parser.use_I_forKeyframes(false);
387  }
388  }
389 
390  if (!(capabilities & V4L2_CAP_VIDEO_CAPTURE))
391  {
392  LOG(VB_GENERAL, LOG_ERR, LOC + "V4L version 1, unsupported");
393  m_error = LOC + "V4L version 1, unsupported";
394  close(m_chanfd);
395  m_chanfd = -1;
396  return false;
397  }
398 
399  if (!SetVideoCaptureFormat(m_chanfd))
400  {
401  close(m_chanfd);
402  m_chanfd = -1;
403  return false;
404  }
405 
406  if (supports_tuner)
407  SetLanguageMode(m_chanfd); // we don't care if this fails...
408 
409  if (supports_audio)
410  SetRecordingVolume(m_chanfd); // we don't care if this fails...
411 
412  if (!SetV4L2DeviceOptions(m_chanfd))
413  {
414  close(m_chanfd);
415  m_chanfd = -1;
416  return false;
417  }
418 
419  SetVBIOptions(m_chanfd); // we don't care if this fails...
420 
421  m_readfd = open(vdevice.constData(), O_RDWR | O_NONBLOCK);
422 
423  if (m_readfd < 0)
424  {
425  LOG(VB_GENERAL, LOG_ERR, LOC + "Can't open video device." + ENO);
426  m_error = LOC + "Can't open video device." + ENO;
427  close(m_chanfd);
428  m_chanfd = -1;
429  return false;
430  }
431 
432  if (m_device_read_buffer)
433  {
434  if (m_device_read_buffer->IsRunning())
435  m_device_read_buffer->Stop();
436 
437  delete m_device_read_buffer;
438  m_device_read_buffer = nullptr;
439  }
440 
441  m_device_read_buffer = new DeviceReadBuffer(this);
442 
443  if (!m_device_read_buffer)
444  {
445  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate DRB buffer");
446  m_error = "Failed to allocate DRB buffer";
447  close(m_chanfd);
448  m_chanfd = -1;
449  close(m_readfd);
450  m_readfd = -1;
451  return false;
452  }
453 
454  if (!m_device_read_buffer->Setup(vdevice.constData(), m_readfd))
455  {
456  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to setup DRB buffer");
457  m_error = "Failed to setup DRB buffer";
458  close(m_chanfd);
459  m_chanfd = -1;
460  close(m_readfd);
461  m_readfd = -1;
462  return false;
463  }
464 
465  LOG(VB_RECORD, LOG_INFO, LOC + "DRB ready");
466 
467  if (m_vbi_fd >= 0)
468  m_vbi_thread = new VBIThread(this);
469 
470  return true;
471 }
472 
473 
475 {
476  if (m_driver == "hdpvr")
477  return true;
478 
479  struct v4l2_format vfmt;
480  memset(&vfmt, 0, sizeof(vfmt));
481 
482  vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
483 
484  if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) < 0)
485  {
486  LOG(VB_GENERAL, LOG_ERR, LOC + "Error getting format" + ENO);
487  m_error = LOC + "Error getting format" + ENO;
488  return false;
489  }
490 
491  vfmt.fmt.pix.width = m_width;
492  vfmt.fmt.pix.height = m_height;
493 
494  if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0)
495  {
496  LOG(VB_GENERAL, LOG_ERR, LOC + "Error setting format" + ENO);
497  m_error = LOC + "Error setting format" + ENO;
498  return false;
499  }
500 
501  return true;
502 }
503 
506 {
507  struct v4l2_tuner vt;
508  memset(&vt, 0, sizeof(struct v4l2_tuner));
509  if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0)
510  {
511  LOG(VB_GENERAL, LOG_WARNING, LOC + "Unable to get audio mode" + ENO);
512  return false;
513  }
514 
515  switch (m_language)
516  {
517  case 0:
518  vt.audmode = V4L2_TUNER_MODE_LANG1;
519  break;
520  case 1:
521  vt.audmode = V4L2_TUNER_MODE_LANG2;
522  break;
523  case 2:
524  vt.audmode = V4L2_TUNER_MODE_LANG1_LANG2;
525  break;
526  default:
527  vt.audmode = V4L2_TUNER_MODE_LANG1;
528  }
529 
530  int audio_layer = GetFilteredAudioLayer();
531  bool success = true;
532  if ((2 == m_language) && (1 == audio_layer))
533  {
534  LOG(VB_GENERAL, LOG_WARNING,
535  "Dual audio mode incompatible with Layer I audio."
536  "\n\t\t\tFalling back to Main Language");
537  vt.audmode = V4L2_TUNER_MODE_LANG1;
538  success = false;
539  }
540 
541  if (ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0)
542  {
543  LOG(VB_GENERAL, LOG_WARNING, LOC + "Unable to set audio mode" + ENO);
544  success = false;
545  }
546 
547  return success;
548 }
549 
551 {
552  // Get volume min/max values
553  struct v4l2_queryctrl qctrl;
554  memset(&qctrl, 0 , sizeof(struct v4l2_queryctrl));
555  qctrl.id = V4L2_CID_AUDIO_VOLUME;
556  if ((ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) ||
557  (qctrl.flags & V4L2_CTRL_FLAG_DISABLED))
558  {
559  LOG(VB_CHANNEL, LOG_WARNING,
560  LOC + "Audio volume control not supported.");
561  return false;
562  }
563 
564  // calculate volume in card units.
565  int range = qctrl.maximum - qctrl.minimum;
566  int value = (int) ((range * m_audvolume * 0.01F) + qctrl.minimum);
567  int ctrl_volume = min(qctrl.maximum, max(qctrl.minimum, value));
568 
569  // Set recording volume
570  struct v4l2_control ctrl;
571  ctrl.id = V4L2_CID_AUDIO_VOLUME;
572  ctrl.value = ctrl_volume;
573 
574  if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0)
575  {
576  LOG(VB_GENERAL, LOG_WARNING, LOC +
577  "Unable to set recording volume" + ENO + "\n\t\t\t" +
578  "If you are using an AverMedia M179 card this is normal.");
579  return false;
580  }
581 
582  return true;
583 }
584 
586 {
587  uint st = (uint) m_streamtype;
588 
589  if (m_driver == "ivtv")
590  {
591  switch (st)
592  {
593  case 2: st = 2; break;
594  case 10:
595  case 13:
596  case 14: st = 10; break;
597  case 11: st = 11; break;
598  case 12: st = 12; break;
599  default: st = 0; break;
600  }
601  }
602 
603  if (st != (uint) m_streamtype)
604  {
605  LOG(VB_GENERAL, LOG_WARNING, LOC +
606  QString("Stream type '%1'\n\t\t\t"
607  "is not supported by %2 driver, using '%3' instead.")
608  .arg(s_streamType[m_streamtype]).arg(m_driver).arg(s_streamType[st]));
609  }
610 
611  return st;
612 }
613 
615 {
616  uint sr = (uint) m_audsamplerate;
617 
618  sr = (m_driver == "ivtv") ? 48000 : sr; // only 48kHz works properly.
619 
620  if (sr != (uint) m_audsamplerate)
621  {
622  LOG(VB_GENERAL, LOG_WARNING, LOC +
623  QString("Audio sample rate %1 Hz\n\t\t\t"
624  "is not supported by %2 driver, using %3 Hz instead.")
625  .arg(m_audsamplerate).arg(m_driver).arg(sr));
626  }
627 
628  switch (sr)
629  {
630  case 32000: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000;
631  case 44100: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100;
632  case 48000: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
633  default: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
634  }
635 }
636 
638 {
639  uint layer = (uint) m_audtype;
640 
641  layer = max(min(layer, 3U), 1U);
642 
643  layer = (m_driver == "ivtv") ? 2 : layer;
644 
645  if (layer != (uint) m_audtype)
646  {
647  LOG(VB_GENERAL, LOG_WARNING, LOC +
648  QString("MPEG layer %1 does not work properly\n\t\t\t"
649  "with %2 driver. Using MPEG layer %3 audio instead.")
650  .arg(m_audtype).arg(m_driver).arg(layer));
651  }
652 
653  return layer;
654 }
655 
657 {
658  return ((2 == audio_layer) ? max(m_audbitratel2, 10) :
659  ((3 == audio_layer) ? m_audbitratel3 : max(m_audbitratel1, 6)));
660 }
661 
662 static int streamtype_ivtv_to_v4l2(int st)
663 {
664  switch (st)
665  {
666  case 0: return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
667  case 1: return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
668  case 2: return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD;
669  case 3: return V4L2_MPEG_STREAM_TYPE_MPEG2_PS; /* PES A/V */
670  case 5: return V4L2_MPEG_STREAM_TYPE_MPEG2_PS; /* PES V */
671  case 7: return V4L2_MPEG_STREAM_TYPE_MPEG2_PS; /* PES A */
672  case 10: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
673  case 11: return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD; /* VCD */
674  case 12: return V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD;
675  case 13: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; /* DVD-Special 1 */
676  case 14: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; /* DVD-Special 2 */
677  default: return V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
678  }
679 }
680 
681 static void add_ext_ctrl(vector<struct v4l2_ext_control> &ctrl_list,
682  uint32_t id, int32_t value)
683 {
684  struct v4l2_ext_control tmp_ctrl;
685  memset(&tmp_ctrl, 0, sizeof(struct v4l2_ext_control));
686  tmp_ctrl.id = id;
687  tmp_ctrl.value = value;
688  ctrl_list.push_back(tmp_ctrl);
689 }
690 
691 static void set_ctrls(int fd, vector<struct v4l2_ext_control> &ext_ctrls)
692 {
693  static QMutex control_description_lock;
694  static QMap<uint32_t,QString> control_description;
695 
696  control_description_lock.lock();
697  if (control_description.isEmpty())
698  {
699  control_description[V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ] =
700  "Audio Sampling Frequency";
701  control_description[V4L2_CID_MPEG_VIDEO_ASPECT] =
702  "Video Aspect ratio";
703  control_description[V4L2_CID_MPEG_AUDIO_ENCODING] =
704  "Audio Encoding";
705  control_description[V4L2_CID_MPEG_AUDIO_L2_BITRATE] =
706  "Audio L2 Bitrate";
707  control_description[V4L2_CID_MPEG_VIDEO_BITRATE_PEAK] =
708  "Video Peak Bitrate";
709  control_description[V4L2_CID_MPEG_VIDEO_BITRATE] =
710  "Video Average Bitrate";
711  control_description[V4L2_CID_MPEG_STREAM_TYPE] =
712  "MPEG Stream type";
713  control_description[V4L2_CID_MPEG_VIDEO_BITRATE_MODE] =
714  "MPEG Bitrate mode";
715  }
716  control_description_lock.unlock();
717 
718  for (size_t i = 0; i < ext_ctrls.size(); i++)
719  {
720  struct v4l2_ext_controls ctrls;
721  memset(&ctrls, 0, sizeof(struct v4l2_ext_controls));
722 
723  int value = ext_ctrls[i].value;
724 
725  ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
726  ctrls.count = 1;
727  ctrls.controls = &ext_ctrls[i];
728 
729  if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
730  {
731  QMutexLocker locker(&control_description_lock);
732  LOG(VB_GENERAL, LOG_ERR, QString("mpegrecorder.cpp:set_ctrls(): ") +
733  QString("Could not set %1 to %2")
734  .arg(control_description[ext_ctrls[i].id]).arg(value) +
735  ENO);
736  }
737  }
738 }
739 
741 {
742  vector<struct v4l2_ext_control> ext_ctrls;
743 
744  // Set controls
745  if (m_driver != "hdpvr")
746  {
747  if (!m_driver.startsWith("saa7164"))
748  {
749  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
750  GetFilteredAudioSampleRate());
751 
752  uint audio_layer = GetFilteredAudioLayer();
753  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING,
754  audio_layer - 1);
755 
756  uint audbitrate = GetFilteredAudioBitRate(audio_layer);
757  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_L2_BITRATE,
758  audbitrate - 1);
759  }
760 
761  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_ASPECT,
762  m_aspectratio - 1);
763 
764  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_STREAM_TYPE,
765  streamtype_ivtv_to_v4l2(GetFilteredStreamType()));
766 
767  }
768  else
769  {
770  m_maxbitrate = m_high_mpeg4peakbitrate;
771  m_bitrate = m_high_mpeg4avgbitrate;
772  }
773  m_maxbitrate = std::max(m_maxbitrate, m_bitrate);
774 
775  if (m_driver == "hdpvr" || m_driver.startsWith("saa7164"))
776  {
777  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
778  (m_maxbitrate == m_bitrate) ?
779  V4L2_MPEG_VIDEO_BITRATE_MODE_CBR :
780  V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
781  }
782 
783  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE,
784  m_bitrate * 1000);
785 
786  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
787  m_maxbitrate * 1000);
788 
789  set_ctrls(chanfd, ext_ctrls);
790 
791  bool ok;
792  int audioinput = m_audiodevice.toUInt(&ok);
793  if (ok)
794  {
795  struct v4l2_audio ain;
796  memset(&ain, 0, sizeof(ain));
797  ain.index = audioinput;
798  if (ioctl(chanfd, VIDIOC_ENUMAUDIO, &ain) < 0)
799  {
800  LOG(VB_GENERAL, LOG_WARNING, LOC + "Unable to get audio input.");
801  }
802  else
803  {
804  ain.index = audioinput;
805  if (ioctl(chanfd, VIDIOC_S_AUDIO, &ain) < 0)
806  {
807  LOG(VB_GENERAL, LOG_WARNING,
808  LOC + "Unable to set audio input.");
809  }
810  }
811  }
812 
813  // query supported audio codecs if spdif is not used
814  if (m_driver == "hdpvr" && audioinput != 2)
815  {
816  struct v4l2_queryctrl qctrl;
817  qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
818 
819  if (!ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl))
820  {
821  uint audio_enc = max(min(m_audtype-1, qctrl.maximum), qctrl.minimum);
822  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_AUDIO_ENCODING, audio_enc);
823  }
824  else
825  {
826  LOG(VB_GENERAL, LOG_WARNING, LOC +
827  "Unable to get supported audio codecs." + ENO);
828  }
829  }
830 
831  return true;
832 }
833 
835 {
836  if (VBIMode::None == m_vbimode)
837  return true;
838 
839  if (m_driver == "hdpvr")
840  return true;
841 
842 #ifdef V4L2_CAP_SLICED_VBI_CAPTURE
843  if (m_supports_sliced_vbi)
844  {
845  int fd;
846 
847  if (OpenVBIDevice() >= 0)
848  fd = m_vbi_fd;
849  else
850  fd = chanfd;
851 
852  struct v4l2_format vbifmt;
853  memset(&vbifmt, 0, sizeof(struct v4l2_format));
854  vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
855  vbifmt.fmt.sliced.service_set |= (VBIMode::PAL_TT == m_vbimode) ?
856  V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
857 
858  if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
859  {
860  if (m_vbi_fd >= 0)
861  {
862  fd = chanfd; // Retry with video device instead
863  if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
864  {
865  LOG(VB_GENERAL, LOG_WARNING, LOC +
866  "Unable to enable VBI embedding (/dev/vbiX)" + ENO);
867  return false;
868  }
869  }
870  else
871  {
872  LOG(VB_GENERAL, LOG_WARNING, LOC +
873  "Unable to enable VBI embedding (/dev/videoX)" + ENO);
874  return false;
875  }
876  }
877 
878  if (ioctl(fd, VIDIOC_G_FMT, &vbifmt) >= 0)
879  {
880  LOG(VB_RECORD, LOG_INFO,
881  LOC + QString("VBI service: %1, io size: %2")
882  .arg(vbifmt.fmt.sliced.service_set)
883  .arg(vbifmt.fmt.sliced.io_size));
884 
885  struct v4l2_ext_control vbi_ctrl;
886  vbi_ctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT;
887  vbi_ctrl.value = V4L2_MPEG_STREAM_VBI_FMT_IVTV;
888 
889  struct v4l2_ext_controls ctrls;
890  memset(&ctrls, 0, sizeof(struct v4l2_ext_controls));
891  ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
892  ctrls.count = 1;
893  ctrls.controls = &vbi_ctrl;
894 
895  if (ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
896  {
897  LOG(VB_GENERAL, LOG_WARNING, LOC +
898  "Unable to set VBI embedding format" + ENO);
899  }
900  else
901  {
902  return true;
903  }
904  }
905  }
906 #endif // V4L2_CAP_SLICED_VBI_CAPTURE
907 
908  return OpenVBIDevice() >= 0;
909 }
910 
912 {
913  ResetForNewFile();
914  return (m_deviceIsMpegFile) ? OpenMpegFileAsInput() : OpenV4L2DeviceAsInput();
915 }
916 
918 {
919  if (!Open())
920  {
921  if (m_error.isEmpty())
922  m_error = "Failed to open V4L device";
923  return;
924  }
925 
926  bool has_select = true;
927 
928 #if defined(__FreeBSD__)
929  // HACK. FreeBSD PVR150/500 driver doesn't currently support select()
930  has_select = false;
931 #endif
932 
933  if (m_driver == "hdpvr")
934  {
935  int progNum = 1;
937  (progNum, m_tvrec ? m_tvrec->GetInputId() : -1,
938  true);
939  sd->SetRecordingType(m_recording_type);
940  SetStreamData(sd);
941 
942  m_stream_data->AddAVListener(this);
943  m_stream_data->AddWritingListener(this);
944 
945  // Make sure the first things in the file are a PAT & PMT
946  HandleSingleProgramPAT(m_stream_data->PATSingleProgram(), true);
947  HandleSingleProgramPMT(m_stream_data->PMTSingleProgram(), true);
948  m_wait_for_keyframe_option = true;
949  }
950 
951  {
952  QMutexLocker locker(&m_pauseLock);
953  m_request_recording = true;
954  m_request_helper = true;
955  m_recording = true;
956  m_recordingWait.wakeAll();
957  }
958 
959  unsigned char *buffer = new unsigned char[m_bufferSize + 1];
960  int len;
961  int remainder = 0;
962 
963  bool good_data = false;
964  bool gap = false;
965  QDateTime gap_start;
966 
967  MythTimer elapsedTimer;
968  float elapsed;
969  long long bytesRead = 0;
970  int dummyBPS = 0; // Bytes per second, but env var is BITS PER SECOND
971 
972  if (getenv("DUMMYBPS"))
973  {
974  dummyBPS = atoi(getenv("DUMMYBPS")) / 8;
975  LOG(VB_GENERAL, LOG_INFO,
976  LOC + QString("Throttling dummy recorder to %1 bits per second")
977  .arg(dummyBPS * 8));
978  }
979 
980  struct timeval tv;
981  fd_set rdset;
982 
983  if (m_deviceIsMpegFile)
984  elapsedTimer.start();
985  else if (m_device_read_buffer)
986  {
987  LOG(VB_RECORD, LOG_INFO, LOC + "Initial startup of recorder");
988  StartEncoding();
989  }
990 
991  QByteArray vdevice = m_videodevice.toLatin1();
992  while (IsRecordingRequested() && !IsErrored())
993  {
994  if (PauseAndWait(100))
995  continue;
996 
997  if (m_deviceIsMpegFile)
998  {
999  if (dummyBPS && bytesRead)
1000  {
1001  elapsed = (elapsedTimer.elapsed() / 1000.0) + 1;
1002  while ((bytesRead / elapsed) > dummyBPS)
1003  {
1004  std::this_thread::sleep_for(std::chrono::milliseconds(50));
1005  elapsed = (elapsedTimer.elapsed() / 1000.0) + 1;
1006  }
1007  }
1008  else if (GetFramesWritten())
1009  {
1010  elapsed = (elapsedTimer.elapsed() / 1000.0) + 1;
1011  while ((GetFramesWritten() / elapsed) > 30)
1012  {
1013  std::this_thread::sleep_for(std::chrono::milliseconds(50));
1014  elapsed = (elapsedTimer.elapsed() / 1000.0) + 1;
1015  }
1016  }
1017  }
1018 
1019  if (m_device_read_buffer)
1020  {
1021  len = m_device_read_buffer->Read
1022  (&(buffer[remainder]), m_bufferSize - remainder);
1023 
1024  // Check for DRB errors
1025  if (m_device_read_buffer->IsErrored())
1026  {
1027  LOG(VB_GENERAL, LOG_ERR, LOC + "Device error detected");
1028 
1029  if (good_data)
1030  {
1031  if (gap)
1032  {
1033  /* Already processing a gap, which means
1034  * restarting the encoding didn't work! */
1035  SetRecordingStatus(RecStatus::Failing, __FILE__, __LINE__);
1036  }
1037  else
1038  gap = true;
1039  }
1040 
1041  if (!RestartEncoding())
1042  SetRecordingStatus(RecStatus::Failing, __FILE__, __LINE__);
1043  }
1044  else if (m_device_read_buffer->IsEOF() &&
1045  IsRecordingRequested())
1046  {
1047  LOG(VB_GENERAL, LOG_ERR, LOC + "Device EOF detected");
1048  m_error = "Device EOF detected";
1049  }
1050  else
1051  {
1052  // If we have seen good data, but now have a gap, note it
1053  if (good_data)
1054  {
1055  if (gap)
1056  {
1057  QMutexLocker locker(&m_statisticsLock);
1058  QDateTime gap_end(MythDate::current());
1059 
1060  m_recordingGaps.push_back(RecordingGap
1061  (gap_start, gap_end));
1062  LOG(VB_RECORD, LOG_DEBUG,
1063  LOC + QString("Inserted gap %1 dur %2")
1064  .arg(m_recordingGaps.back().toString())
1065  .arg(gap_start.secsTo(gap_end)));
1066  gap = false;
1067  }
1068  else
1069  gap_start = MythDate::current();
1070  }
1071  else
1072  good_data = true;
1073  }
1074  }
1075  else if (m_readfd < 0)
1076  continue;
1077  else
1078  {
1079  if (has_select)
1080  {
1081  tv.tv_sec = 5;
1082  tv.tv_usec = 0;
1083  FD_ZERO(&rdset);
1084  FD_SET(m_readfd, &rdset);
1085 
1086  switch (select(m_readfd + 1, &rdset, nullptr, nullptr, &tv))
1087  {
1088  case -1:
1089  if (errno == EINTR)
1090  continue;
1091 
1092  LOG(VB_GENERAL, LOG_ERR, LOC + "Select error" + ENO);
1093  continue;
1094 
1095  case 0:
1096  LOG(VB_GENERAL, LOG_ERR, LOC + "select timeout - "
1097  "driver has stopped responding");
1098 
1099  if (close(m_readfd) != 0)
1100  {
1101  LOG(VB_GENERAL, LOG_ERR, LOC + "Close error" + ENO);
1102  }
1103 
1104  // Force card to be reopened on next iteration..
1105  m_readfd = -1;
1106  continue;
1107 
1108  default:
1109  break;
1110  }
1111  }
1112 
1113  len = read(m_readfd, &(buffer[remainder]), m_bufferSize - remainder);
1114 
1115  if (len < 0 && !has_select)
1116  {
1117  QMutexLocker locker(&m_pauseLock);
1118  if (m_request_recording && !m_request_pause)
1119  m_unpauseWait.wait(&m_pauseLock, 25);
1120  continue;
1121  }
1122 
1123  if ((len == 0) && (m_deviceIsMpegFile))
1124  {
1125  close(m_readfd);
1126  m_readfd = open(vdevice.constData(), O_RDONLY);
1127 
1128  if (m_readfd >= 0)
1129  {
1130  len = read(m_readfd,
1131  &(buffer[remainder]), m_bufferSize - remainder);
1132  }
1133 
1134  if (len <= 0)
1135  {
1136  m_error = "Failed to read from video file";
1137  continue;
1138  }
1139  }
1140  else if (len < 0 && errno != EAGAIN)
1141  {
1142  LOG(VB_GENERAL, LOG_ERR, LOC + QString("error reading from: %1")
1143  .arg(m_videodevice) + ENO);
1144  continue;
1145  }
1146  }
1147 
1148  if (len > 0)
1149  {
1150  bytesRead += len;
1151  len += remainder;
1152 
1153  if (m_driver == "hdpvr")
1154  {
1155  remainder = m_stream_data->ProcessData(buffer, len);
1156  int start_remain = len - remainder;
1157  if (remainder && (start_remain >= remainder))
1158  memcpy(buffer, buffer+start_remain, remainder);
1159  else if (remainder)
1160  memmove(buffer, buffer+start_remain, remainder);
1161  }
1162  else
1163  {
1164  FindPSKeyFrames(buffer, len);
1165  }
1166  }
1167  }
1168 
1169  LOG(VB_RECORD, LOG_INFO, LOC + "run finishing up");
1170 
1171  StopEncoding();
1172 
1173  {
1174  QMutexLocker locker(&m_pauseLock);
1175  m_request_helper = false;
1176  }
1177 
1178  if (m_vbi_thread)
1179  {
1180  m_vbi_thread->wait();
1181  delete m_vbi_thread;
1182  m_vbi_thread = nullptr;
1183  CloseVBIDevice();
1184  }
1185 
1186  FinishRecording();
1187 
1188  delete[] buffer;
1189 
1190  if (m_driver == "hdpvr")
1191  {
1192  m_stream_data->RemoveWritingListener(this);
1193  m_stream_data->RemoveAVListener(this);
1194  SetStreamData(nullptr);
1195  }
1196 
1197  QMutexLocker locker(&m_pauseLock);
1198  m_request_recording = false;
1199  m_recording = false;
1200  m_recordingWait.wakeAll();
1201 }
1202 
1203 bool MpegRecorder::ProcessTSPacket(const TSPacket &tspacket_real)
1204 {
1205  const uint pid = tspacket_real.PID();
1206 
1207  TSPacket *tspacket_fake = nullptr;
1208  if ((m_driver == "hdpvr") && (pid == 0x1001)) // PCRPID for HD-PVR
1209  {
1210  tspacket_fake = tspacket_real.CreateClone();
1211  uint cc = (m_continuity_counter[pid] == 0xFF) ?
1212  0 : (m_continuity_counter[pid] + 1) & 0xf;
1213  tspacket_fake->SetContinuityCounter(cc);
1214  }
1215 
1216  const TSPacket &tspacket = (tspacket_fake)
1217  ? *tspacket_fake : tspacket_real;
1218 
1219  bool ret = DTVRecorder::ProcessTSPacket(tspacket);
1220 
1221  delete tspacket_fake;
1222 
1223  return ret;
1224 }
1225 
1227 {
1228  LOG(VB_RECORD, LOG_INFO, LOC + "Reset(void)");
1229  ResetForNewFile();
1230 
1231  m_start_code = 0xffffffff;
1232 
1233  if (m_curRecording)
1234  {
1235  m_curRecording->ClearPositionMap(MARK_GOP_BYFRAME);
1236  }
1237  if (m_stream_data)
1238  m_stream_data->Reset(m_stream_data->DesiredProgram());
1239 }
1240 
1242 {
1243  QMutexLocker locker(&m_pauseLock);
1244  m_cleartimeonpause = clear;
1245  m_paused = false;
1246  m_request_pause = true;
1247 }
1248 
1250 {
1251  QMutexLocker locker(&m_pauseLock);
1252  if (m_request_pause)
1253  {
1254  if (!IsPaused(true))
1255  {
1256  LOG(VB_RECORD, LOG_INFO, LOC + "PauseAndWait pause");
1257 
1258  StopEncoding();
1259 
1260  m_paused = true;
1261  m_pauseWait.wakeAll();
1262 
1263  if (m_tvrec)
1264  m_tvrec->RecorderPaused();
1265  }
1266 
1267  m_unpauseWait.wait(&m_pauseLock, timeout);
1268  }
1269 
1270  if (!m_request_pause && IsPaused(true))
1271  {
1272  LOG(VB_RECORD, LOG_INFO, LOC + "PauseAndWait unpause");
1273 
1274  if (m_driver == "hdpvr")
1275  {
1276  m_h264_parser.Reset();
1277  m_wait_for_keyframe_option = true;
1278  m_seen_sps = false;
1279  // HD-PVR will sometimes reset to defaults
1280  SetV4L2DeviceOptions(m_chanfd);
1281  }
1282 
1283  StartEncoding();
1284 
1285  if (m_stream_data)
1286  m_stream_data->Reset(m_stream_data->DesiredProgram());
1287 
1288  m_paused = false;
1289  }
1290 
1291  return IsPaused(true);
1292 }
1293 
1295 {
1296  LOG(VB_RECORD, LOG_INFO, LOC + "RestartEncoding");
1297 
1298  QMutexLocker locker(&m_start_stop_encoding_lock);
1299 
1300  StopEncoding();
1301 
1302  // Make sure the next things in the file are a PAT & PMT
1303  if (m_stream_data &&
1304  m_stream_data->PATSingleProgram() &&
1305  m_stream_data->PMTSingleProgram())
1306  {
1307  m_payload_buffer.clear(); // No reason to keep part of a frame
1308  HandleSingleProgramPAT(m_stream_data->PATSingleProgram(), true);
1309  HandleSingleProgramPMT(m_stream_data->PMTSingleProgram(), true);
1310  }
1311 
1312  if (m_driver == "hdpvr") // HD-PVR will sometimes reset to defaults
1313  SetV4L2DeviceOptions(m_chanfd);
1314 
1315  return StartEncoding();
1316 }
1317 
1319 {
1320  QMutexLocker locker(&m_start_stop_encoding_lock);
1321 
1322  LOG(VB_RECORD, LOG_INFO, LOC + "StartEncoding");
1323 
1324  if (m_readfd < 0)
1325  {
1326  m_readfd = open(m_videodevice.toLatin1().constData(), O_RDWR | O_NONBLOCK);
1327  if (m_readfd < 0)
1328  {
1329  LOG(VB_GENERAL, LOG_ERR, LOC +
1330  "StartEncoding: Can't open video device." + ENO);
1331  m_error = "Failed to start recording";
1332  return false;
1333  }
1334  }
1335 
1336  bool good_res = true;
1337  if (m_driver == "hdpvr")
1338  {
1339  m_h264_parser.Reset();
1340  m_wait_for_keyframe_option = true;
1341  m_seen_sps = false;
1342  good_res = HandleResolutionChanges();
1343  }
1344 
1345  // (at least) with the 3.10 kernel, the V4L2_ENC_CMD_START does
1346  // not reliably start the data flow from a HD-PVR. A read() seems
1347  // to work, though.
1348 
1349  int idx = 1;
1350  for ( ; idx < 50; ++idx)
1351  {
1352  uint8_t dummy;
1353  int len = read(m_readfd, &dummy, 0);
1354  if (len == 0)
1355  break;
1356  if (idx == 20)
1357  {
1358  LOG(VB_GENERAL, LOG_ERR, LOC +
1359  "StartEncoding: read failing, re-opening device: " + ENO);
1360  close(m_readfd);
1361  std::this_thread::sleep_for(std::chrono::milliseconds(2));
1362  m_readfd = open(m_videodevice.toLatin1().constData(),
1363  O_RDWR | O_NONBLOCK);
1364  if (m_readfd < 0)
1365  {
1366  LOG(VB_GENERAL, LOG_ERR, LOC +
1367  "StartEncoding: Can't open video device." + ENO);
1368  m_error = "Failed to start recording";
1369  return false;
1370  }
1371  }
1372  else
1373  {
1374  LOG(VB_GENERAL, LOG_ERR, LOC +
1375  QString("StartEncoding: read failed, retry in %1 msec:")
1376  .arg(100 * idx) + ENO);
1377  std::this_thread::sleep_for(std::chrono::microseconds(idx * 100));
1378  }
1379  }
1380  if (idx == 50)
1381  {
1382  LOG(VB_GENERAL, LOG_ERR, LOC +
1383  "StartEncoding: read from video device failed." + ENO);
1384  m_error = "Failed to start recording";
1385  close(m_readfd);
1386  m_readfd = -1;
1387  return false;
1388  }
1389  if (idx > 0)
1390  {
1391  LOG(VB_RECORD, LOG_WARNING, LOC +
1392  QString("%1 read attempts required to start encoding").arg(idx));
1393  }
1394 
1395  if (!good_res) // Try again
1396  HandleResolutionChanges();
1397 
1398  if (m_device_read_buffer)
1399  {
1400  m_device_read_buffer->Reset(m_videodevice.toLatin1().constData(), m_readfd);
1401  m_device_read_buffer->SetRequestPause(false);
1402  m_device_read_buffer->Start();
1403  }
1404 
1405  return true;
1406 }
1407 
1409 {
1410  QMutexLocker locker(&m_start_stop_encoding_lock);
1411 
1412  LOG(VB_RECORD, LOG_INFO, LOC + "StopEncoding");
1413 
1414  if (m_readfd < 0)
1415  return;
1416 
1417  struct v4l2_encoder_cmd command;
1418  memset(&command, 0, sizeof(struct v4l2_encoder_cmd));
1419  command.cmd = V4L2_ENC_CMD_STOP;
1420  command.flags = V4L2_ENC_CMD_STOP_AT_GOP_END;
1421 
1422  if (m_device_read_buffer)
1423  m_device_read_buffer->SetRequestPause(true);
1424 
1425  bool stopped = 0 == ioctl(m_readfd, VIDIOC_ENCODER_CMD, &command);
1426  if (stopped)
1427  {
1428  LOG(VB_RECORD, LOG_INFO, LOC + "Encoding stopped");
1429  }
1430  else if (errno != ENOTTY && errno != EINVAL)
1431  {
1432  // Some drivers do not support this ioctl at all. It is marked as
1433  // "experimental" in the V4L2 API spec. These drivers return EINVAL
1434  // in older kernels and ENOTTY in 3.1+
1435 
1436  LOG(VB_GENERAL, LOG_WARNING, LOC + "StopEncoding failed" + ENO);
1437  }
1438 
1439  if (m_device_read_buffer && m_device_read_buffer->IsRunning())
1440  {
1441  // allow last bits of data through..
1442  std::this_thread::sleep_for(std::chrono::milliseconds(20));
1443  m_device_read_buffer->Stop();
1444  }
1445 
1446  // close the fd so streamoff/streamon work in V4LChannel
1447  close(m_readfd);
1448  m_readfd = -1;
1449 }
1450 
1452 {
1453  m_stream_data->AddMPEGSPListener(this);
1454  m_stream_data->SetDesiredProgram(1);
1455 }
1456 
1457 void MpegRecorder::SetBitrate(int bitrate, int maxbitrate,
1458  const QString & reason)
1459 {
1460  if (maxbitrate == bitrate)
1461  {
1462  LOG(VB_RECORD, LOG_INFO, LOC + QString("%1 bitrate %2 kbps CBR")
1463  .arg(reason).arg(bitrate));
1464  }
1465  else
1466  {
1467  LOG(VB_RECORD, LOG_INFO, LOC + QString("%1 bitrate %2/%3 kbps VBR")
1468  .arg(reason).arg(bitrate).arg(maxbitrate));
1469  }
1470 
1471  vector<struct v4l2_ext_control> ext_ctrls;
1472  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
1473  (maxbitrate == bitrate) ?
1474  V4L2_MPEG_VIDEO_BITRATE_MODE_CBR :
1475  V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
1476 
1477  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE,
1478  bitrate * 1000);
1479 
1480  add_ext_ctrl(ext_ctrls, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
1481  maxbitrate * 1000);
1482 
1483  set_ctrls(m_readfd, ext_ctrls);
1484 }
1485 
1487 {
1488  LOG(VB_RECORD, LOG_INFO, LOC + "Checking Resolution");
1489  uint pix = 0;
1490  struct v4l2_format vfmt;
1491  memset(&vfmt, 0, sizeof(vfmt));
1492  vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1493 
1494  if (0 == ioctl(m_chanfd, VIDIOC_G_FMT, &vfmt))
1495  {
1496  LOG(VB_RECORD, LOG_INFO, LOC + QString("Got Resolution %1x%2")
1497  .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height));
1498  pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height;
1499  }
1500 
1501  if (!pix)
1502  {
1503  LOG(VB_RECORD, LOG_INFO, LOC + "Giving up detecting resolution: " + ENO);
1504  return false; // nothing to do, we don't have a resolution yet
1505  }
1506 
1507  int old_max = m_maxbitrate, old_avg = m_bitrate;
1508  if (pix <= 768*568)
1509  {
1510  m_maxbitrate = m_low_mpeg4peakbitrate;
1511  m_bitrate = m_low_mpeg4avgbitrate;
1512  }
1513  else if (pix >= 1920*1080)
1514  {
1515  m_maxbitrate = m_high_mpeg4peakbitrate;
1516  m_bitrate = m_high_mpeg4avgbitrate;
1517  }
1518  else
1519  {
1520  m_maxbitrate = m_medium_mpeg4peakbitrate;
1521  m_bitrate = m_medium_mpeg4avgbitrate;
1522  }
1523  m_maxbitrate = std::max(m_maxbitrate, m_bitrate);
1524 
1525  if ((old_max != m_maxbitrate) || (old_avg != m_bitrate))
1526  {
1527  if (old_max == old_avg)
1528  {
1529  LOG(VB_RECORD, LOG_INFO, LOC +
1530  QString("Old bitrate %1 CBR").arg(old_avg));
1531  }
1532  else
1533  {
1534  LOG(VB_RECORD, LOG_INFO,LOC +
1535  QString("Old bitrate %1/%2 VBR") .arg(old_avg).arg(old_max));
1536  }
1537 
1538  SetBitrate(m_bitrate, m_maxbitrate, "New");
1539  }
1540 
1541  return true;
1542 }
1543 
1545 {
1546  LOG(VB_VBI, LOG_INFO, LOC + QString("FormatCC(0x%1,0x%2)")
1547  .arg(code1,0,16).arg(code2,0,16));
1548  // TODO add to CC data vector
1549 
1550  // TODO find video frames in output and insert cc_data
1551  // as CEA-708 user_data packets containing CEA-608 captions
1553 }
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:166
Definition: cc.h:13
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
bool ProcessTSPacket(const TSPacket &tspacket) override
void SetOption(const QString &name, const QString &value) override
Set an specific option.
Definition: v4lrecorder.cpp:59
static const int s_audRateL2[]
Definition: mpegrecorder.h:122
#define O_NONBLOCK
Definition: mythmedia.cpp:25
uint GetFilteredAudioSampleRate(void) const
uint GetFilteredAudioLayer(void) const
void Reset(void) override
Reset the recorder to the startup state.
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
void TeardownAll(void)
static void set_ctrls(int fd, vector< struct v4l2_ext_control > &ext_ctrls)
void SetBitrate(int bitrate, int maxbitrate, const QString &reason)
bool SetV4L2DeviceOptions(int chanfd)
bool StartEncoding(void)
unsigned int uint
Definition: compat.h:140
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void SetOption(const QString &opt, int value) override
handles the "wait_for_seqstart" option.
void SetContinuityCounter(unsigned int cc)
Definition: tspacket.h:148
bool SetVBIOptions(int chanfd)
bool PauseAndWait(int timeout=100) override
If m_request_pause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
static bool GetV4LInfo(int videofd, QString &input, QString &driver, uint32_t &version, uint32_t &capabilities)
Definition: cardutil.cpp:2123
def read(device=None, features=[])
Definition: disc.py:35
virtual QString getValue(void) const
#define close
Definition: compat.h:16
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
Definition: mythdb.cpp:830
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
QString GetSetting(const QString &key, const QString &defaultval="")
bool HandleResolutionChanges(void)
bool Open(void)
uint GetFilteredStreamType(void) const
void StopEncoding(void)
static const char * s_streamType[]
Definition: mpegrecorder.h:124
const char * name
Definition: ParseText.cpp:328
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:99
bool OpenV4L2DeviceAsInput(void)
bool SetVideoCaptureFormat(int chanfd)
void InitStreamData(void) override
int elapsed(void) const
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:90
void Pause(bool clear=true) override
Pause tells recorder to pause, it should not block.
void SetRecordingType(const QString &recording_type)
bool SetLanguageMode(int chanfd)
Set audio language mode.
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
bool OpenMpegFileAsInput(void)
static const unsigned int kSize
Definition: tspacket.h:220
uint GetFilteredAudioBitRate(uint audio_layer) const
void SetIntOption(RecordingProfile *profile, const QString &name)
bool ProcessTSPacket(const TSPacket &tspacket) override
unsigned int PID(void) const
Definition: tspacket.h:71
bool RestartEncoding(void)
#define LOC
static const char * s_aspectRatio[]
Definition: mpegrecorder.h:125
Buffers reads from device files.
TSPacket * CreateClone(void) const
Definition: tspacket.h:183
bool SetRecordingVolume(int chanfd)
static const int s_audRateL3[]
Definition: mpegrecorder.h:123
void SetStrOption(RecordingProfile *profile, const QString &name)
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
void FormatCC(uint code1, uint code2) override
static const int s_audRateL1[]
Definition: mpegrecorder.h:121
Encapsulates data about MPEG stream and emits events for each table.
static int find_index(const int *audio_rate, int value)
static void add_ext_ctrl(vector< struct v4l2_ext_control > &ctrl_list, uint32_t id, int32_t value)
static int streamtype_ivtv_to_v4l2(int st)
void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev) override
Sets basic recorder options.