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