MythTV  master
hdhrrecorder.cpp
Go to the documentation of this file.
1 
8 #include <chrono> // for milliseconds
9 #include <thread> // for sleep_for
10 
11 // MythTV includes
13 
14 #include "hdhrchannel.h"
15 #include "hdhrrecorder.h"
16 #include "hdhrstreamhandler.h"
17 #include "io/mythmediabuffer.h"
18 #include "mpeg/atscstreamdata.h"
19 #include "mpeg/tsstreamdata.h"
20 #include "tv_rec.h"
21 
22 #define LOC QString("HDHRRec[%1]: ") \
23  .arg(m_tvrec ? m_tvrec->GetInputId() : -1)
24 
26 {
27  if (IsOpen())
28  {
29  LOG(VB_GENERAL, LOG_WARNING, LOC + "Card already open");
30  return true;
31  }
32 
34 
35  if (m_channel->GetFormat().compare("MPTS") == 0)
36  {
37  // MPTS only. Use TSStreamData to write out unfiltered data.
38  LOG(VB_RECORD, LOG_INFO, LOC + "Using TSStreamData");
40  m_recordMptsOnly = true;
41  m_recordMpts = false;
42  }
43 
47 
48  LOG(VB_RECORD, LOG_INFO, LOC + "HDHR opened successfully");
49 
50  return true;
51 }
52 
54 {
55  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
56 
57  if (IsOpen())
59  (m_tvrec ? m_tvrec->GetInputId() : -1));
60 
61  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
62 }
63 
65 {
66  if (!m_recordMptsOnly)
67  {
68  if (m_recordMpts)
70 
71  // Make sure the first things in the file are a PAT & PMT
74  }
75 }
76 
78 {
79  LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin");
80 
81  /* Create video socket. */
82  if (!Open())
83  {
84  m_error = "Failed to open HDHRRecorder device";
85  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
86  return;
87  }
88 
89  {
90  QMutexLocker locker(&m_pauseLock);
91  m_requestRecording = true;
92  m_recording = true;
93  m_recordingWait.wakeAll();
94  }
95 
96  // Listen for time table on DVB standard streams
97  if (m_channel && (m_channel->GetSIStandard() == "dvb"))
99 
100  // Gives errors about invalid PID but it does work...
101  if (m_recordMptsOnly)
102  m_streamData->AddListeningPID(0x2000);
103 
104  StartNewFile();
105 
109  (m_recordMpts) ? m_ringBuffer->GetFilename() : QString());
110 
111  while (IsRecordingRequested() && !IsErrored())
112  {
113  if (PauseAndWait())
114  continue;
115 
116  if (!IsRecordingRequested())
117  break;
118 
119  { // sleep 100 milliseconds unless StopRecording() or Unpause()
120  // is called, just to avoid running this too often.
121  QMutexLocker locker(&m_pauseLock);
123  continue;
124  m_unpauseWait.wait(&m_pauseLock, 100);
125  }
126 
127  if (!m_inputPmt && !m_recordMptsOnly)
128  {
129  LOG(VB_GENERAL, LOG_WARNING, LOC +
130  "Recording will not commence until a PMT is set.");
131  std::this_thread::sleep_for(5ms);
132  continue;
133  }
134 
135  if (!m_streamHandler->IsRunning())
136  {
137  m_error = "Stream handler died unexpectedly.";
138  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
139  }
140  }
141 
142  LOG(VB_RECORD, LOG_INFO, LOC + "run -- ending...");
143 
147 
148  Close();
149 
150  FinishRecording();
151 
152  QMutexLocker locker(&m_pauseLock);
153  m_recording = false;
154  m_recordingWait.wakeAll();
155 
156  LOG(VB_RECORD, LOG_INFO, LOC + "run -- end");
157 }
158 
159 bool HDHRRecorder::PauseAndWait(std::chrono::milliseconds timeout)
160 {
161  QMutexLocker locker(&m_pauseLock);
162  if (m_requestPause)
163  {
164  if (!IsPaused(true))
165  {
167 
168  m_paused = true;
169  m_pauseWait.wakeAll();
170  if (m_tvrec)
172  }
173 
174  m_unpauseWait.wait(&m_pauseLock, timeout.count());
175  }
176 
177  if (!m_requestPause && IsPaused(true))
178  {
179  m_paused = false;
181  m_unpauseWait.wakeAll();
182  }
183 
184  return IsPaused(true);
185 }
186 
187 QString HDHRRecorder::GetSIStandard(void) const
188 {
189  return m_channel->GetSIStandard();
190 }
191 
192 /* vim: set expandtab tabstop=4 shiftwidth=4: */
DTVRecorder::HandleSingleProgramPMT
void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override
Definition: dtvrecorder.cpp:1408
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:102
DTVRecorder::m_inputPmt
ProgramMapTable * m_inputPmt
PMT on input side.
Definition: dtvrecorder.h:174
HDHRRecorder::m_channel
HDHRChannel * m_channel
Definition: hdhrrecorder.h:39
HDHRStreamHandler::AddListener
void AddListener(MPEGStreamData *data, bool=false, bool=false, const QString &output_file=QString()) override
Definition: hdhrstreamhandler.h:54
DTVRecorder::ResetForNewFile
void ResetForNewFile(void) override
Definition: dtvrecorder.cpp:140
HDHRRecorder::Close
void Close(void)
Definition: hdhrrecorder.cpp:53
DTVRecorder::SetStreamData
virtual void SetStreamData(MPEGStreamData *data)
Definition: dtvrecorder.cpp:218
RecorderBase::m_tvrec
TVRec * m_tvrec
Definition: recorderbase.h:309
DTVRecorder::IsErrored
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:46
atscstreamdata.h
DTVChannel::GetFormat
QString GetFormat(void)
Definition: dtvchannel.h:46
HDHRRecorder::GetSIStandard
QString GetSIStandard(void) const override
Definition: hdhrrecorder.cpp:187
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
StreamHandler::AddNamedOutputFile
virtual bool AddNamedOutputFile(const QString &filename)
Called with _listener_lock locked just after adding new output file.
Definition: streamhandler.cpp:362
DTVRecorder::FinishRecording
void FinishRecording(void) override
Flushes the ringbuffer, and if this is not a live LiveTV recording saves the position map and filesiz...
Definition: dtvrecorder.cpp:126
MPEGStreamData::PMTSingleProgram
const ProgramMapTable * PMTSingleProgram(void) const
Definition: mpegstreamdata.h:266
StreamHandler::RemoveListener
virtual void RemoveListener(MPEGStreamData *data)
Definition: streamhandler.cpp:80
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:332
RecorderBase::m_requestPause
bool m_requestPause
Definition: recorderbase.h:333
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:341
TVRec::RecorderPaused
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
Definition: tv_rec.cpp:2999
MythMediaBuffer::GetFilename
QString GetFilename(void) const
Definition: mythmediabuffer.cpp:1745
TVRec::GetInputId
uint GetInputId(void) const
Returns the inputid.
Definition: tv_rec.h:234
RecorderBase::m_paused
bool m_paused
Definition: recorderbase.h:334
MPEGStreamData::PATSingleProgram
const ProgramAssociationTable * PATSingleProgram(void) const
Definition: mpegstreamdata.h:264
DTVRecorder::HandleSingleProgramPAT
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
Definition: dtvrecorder.cpp:1388
mythlogging.h
HDHRStreamHandler::Return
static void Return(HDHRStreamHandler *&ref, int inputid)
Definition: hdhrstreamhandler.cpp:60
DTVRecorder::m_recordMptsOnly
bool m_recordMptsOnly
Definition: dtvrecorder.h:179
MPEGStreamData::RemoveWritingListener
void RemoveWritingListener(TSPacketListener *val)
Definition: mpegstreamdata.cpp:1659
HDHRRecorder::PauseAndWait
bool PauseAndWait(std::chrono::milliseconds timeout=100ms) override
If m_requestPause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
Definition: hdhrrecorder.cpp:159
RecorderBase::IsRecordingRequested
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.
Definition: recorderbase.cpp:256
hdhrrecorder.h
HDHRRecorder::StartNewFile
void StartNewFile(void) override
Definition: hdhrrecorder.cpp:64
HDHRChannel::GetDevice
QString GetDevice(void) const override
Returns String representing device, useful for debugging.
Definition: hdhrchannel.h:35
LOC
#define LOC
-*- Mode: c++ -*- HDHRRecorder Copyright (c) 2006-2009 by Silicondust Engineering Ltd,...
Definition: hdhrrecorder.cpp:22
mythmediabuffer.h
DTVChannel::GetSIStandard
QString GetSIStandard(void) const
Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
Definition: dtvchannel.cpp:45
RecorderBase::m_pauseWait
QWaitCondition m_pauseWait
Definition: recorderbase.h:335
RecorderBase::m_ringBuffer
MythMediaBuffer * m_ringBuffer
Definition: recorderbase.h:310
MPEGStreamData::AddAVListener
void AddAVListener(TSPacketListenerAV *val)
Definition: mpegstreamdata.cpp:1673
PID::DVB_TDT_PID
@ DVB_TDT_PID
Definition: mpegtables.h:219
DTVRecorder::m_streamData
MPEGStreamData * m_streamData
Definition: dtvrecorder.h:163
MPEGStreamData::AddWritingListener
void AddWritingListener(TSPacketListener *val)
Definition: mpegstreamdata.cpp:1648
DTVRecorder::m_error
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:161
DTVRecorder::m_recordMpts
bool m_recordMpts
Definition: dtvrecorder.h:178
HDHRRecorder::m_streamHandler
HDHRStreamHandler * m_streamHandler
Definition: hdhrrecorder.h:40
RecorderBase::m_recording
bool m_recording
True while recording is actually being performed.
Definition: recorderbase.h:340
tv_rec.h
ChannelBase::GetInputID
virtual int GetInputID(void) const
Definition: channelbase.h:67
MPEGStreamData::AddListeningPID
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
Definition: mpegstreamdata.h:120
HDHRStreamHandler::Get
static HDHRStreamHandler * Get(const QString &devname, int inputid, int majorid)
Definition: hdhrstreamhandler.cpp:29
hdhrstreamhandler.h
StreamHandler::IsRunning
bool IsRunning(void) const
Definition: streamhandler.cpp:163
hdhrchannel.h
RecorderBase::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: recorderbase.h:336
ChannelBase::GetMajorID
int GetMajorID(void)
Definition: channelbase.cpp:860
TSStreamData
Specialized version of MPEGStreamData which is used to 'blindly' record the entire MPTS transport fro...
Definition: tsstreamdata.h:11
MPEGStreamData::RemoveAVListener
void RemoveAVListener(TSPacketListenerAV *val)
Definition: mpegstreamdata.cpp:1694
HDHRRecorder::IsOpen
bool IsOpen(void) const
Definition: hdhrrecorder.h:28
HDHRRecorder::run
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
Definition: hdhrrecorder.cpp:77
RecorderBase::IsPaused
virtual bool IsPaused(bool holding_lock=false) const
Returns true iff recorder is paused.
Definition: recorderbase.cpp:287
tsstreamdata.h
HDHRRecorder::Open
bool Open(void)
Definition: hdhrrecorder.cpp:25
RecorderBase::m_requestRecording
bool m_requestRecording
True if API call has requested a recording be [re]started.
Definition: recorderbase.h:338