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 "hdhrrecorder.h"
15 #include "hdhrchannel.h"
16 #include "ringbuffer.h"
17 #include "tv_rec.h"
18 #include "mythlogging.h"
19 
20 #define LOC QString("HDHRRec[%1]: ") \
21  .arg(m_tvrec ? m_tvrec->GetInputId() : -1)
22 
24 {
25  if (IsOpen())
26  {
27  LOG(VB_GENERAL, LOG_WARNING, LOC + "Card already open");
28  return true;
29  }
30 
32 
36 
37  LOG(VB_RECORD, LOG_INFO, LOC + "HDHR opened successfully");
38 
39  return true;
40 }
41 
43 {
44  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
45 
46  if (IsOpen())
48  (m_tvrec ? m_tvrec->GetInputId() : -1));
49 
50  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
51 }
52 
54 {
55  if (m_record_mpts)
57 
58  // Make sure the first things in the file are a PAT & PMT
61 }
62 
64 {
65  LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin");
66 
67  /* Create video socket. */
68  if (!Open())
69  {
70  m_error = "Failed to open HDHRRecorder device";
71  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
72  return;
73  }
74 
75  {
76  QMutexLocker locker(&m_pauseLock);
77  m_request_recording = true;
78  m_recording = true;
79  m_recordingWait.wakeAll();
80  }
81 
82  StartNewFile();
83 
87  (m_record_mpts) ? m_ringBuffer->GetFilename() : QString());
88 
89  while (IsRecordingRequested() && !IsErrored())
90  {
91  if (PauseAndWait())
92  continue;
93 
94  if (!IsRecordingRequested())
95  break;
96 
97  { // sleep 100 milliseconds unless StopRecording() or Unpause()
98  // is called, just to avoid running this too often.
99  QMutexLocker locker(&m_pauseLock);
101  continue;
102  m_unpauseWait.wait(&m_pauseLock, 100);
103  }
104 
105  if (!m_input_pmt)
106  {
107  LOG(VB_GENERAL, LOG_WARNING, LOC +
108  "Recording will not commence until a PMT is set.");
109  std::this_thread::sleep_for(std::chrono::milliseconds(5));
110  continue;
111  }
112 
113  if (!m_stream_handler->IsRunning())
114  {
115  m_error = "Stream handler died unexpectedly.";
116  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
117  }
118  }
119 
120  LOG(VB_RECORD, LOG_INFO, LOC + "run -- ending...");
121 
125 
126  Close();
127 
128  FinishRecording();
129 
130  QMutexLocker locker(&m_pauseLock);
131  m_recording = false;
132  m_recordingWait.wakeAll();
133 
134  LOG(VB_RECORD, LOG_INFO, LOC + "run -- end");
135 }
136 
138 {
139  QMutexLocker locker(&m_pauseLock);
140  if (m_request_pause)
141  {
142  if (!IsPaused(true))
143  {
145 
146  m_paused = true;
147  m_pauseWait.wakeAll();
148  if (m_tvrec)
150  }
151 
153  }
154 
155  if (!m_request_pause && IsPaused(true))
156  {
157  m_paused = false;
159  m_unpauseWait.wakeAll();
160  }
161 
162  return IsPaused(true);
163 }
164 
165 QString HDHRRecorder::GetSIStandard(void) const
166 {
167  return m_channel->GetSIStandard();
168 }
169 
170 /* vim: set expandtab tabstop=4 shiftwidth=4: */
QString GetSIStandard(void) const override
const ProgramAssociationTable * PATSingleProgram(void) const
bool Open(void)
uint GetInputId(void)
Returns the inputid.
Definition: tv_rec.h:241
QMutex m_pauseLock
Definition: recorderbase.h:326
void ResetForNewFile(void) override
bool m_record_mpts
Definition: dtvrecorder.h:179
virtual void RemoveListener(MPEGStreamData *data)
QString GetFilename(void) const
Returns name of file used by this RingBuffer.
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:48
bool m_request_recording
True if API call has requested a recording be [re]started.
Definition: recorderbase.h:332
bool PauseAndWait(int timeout=100) override
If m_request_pause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
static void Return(HDHRStreamHandler *&ref, int inputid)
virtual bool IsPaused(bool holding_lock=false) const
Returns true iff recorder is paused.
QWaitCondition m_unpauseWait
Definition: recorderbase.h:330
ProgramMapTable * m_input_pmt
PMT on input side.
Definition: dtvrecorder.h:175
RingBuffer * m_ringBuffer
Definition: recorderbase.h:304
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
QWaitCondition m_pauseWait
Definition: recorderbase.h:329
MPEGStreamData * m_stream_data
Definition: dtvrecorder.h:164
void RemoveWritingListener(TSPacketListener *)
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
Definition: tv_rec.cpp:2929
void AddAVListener(TSPacketListenerAV *)
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
bool m_request_pause
Definition: recorderbase.h:327
HDHRStreamHandler * m_stream_handler
Definition: hdhrrecorder.h:40
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
TVRec * m_tvrec
Definition: recorderbase.h:303
const ProgramMapTable * PMTSingleProgram(void) const
void AddWritingListener(TSPacketListener *)
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
virtual int GetInputID(void) const
Definition: channelbase.h:67
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:162
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
void RemoveAVListener(TSPacketListenerAV *)
static HDHRStreamHandler * Get(const QString &devname, int inputid, int majorid)
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,...
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.