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{
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...
103
104 StartNewFile();
105
109 (m_recordMpts) ? m_ringBuffer->GetFilename() : QString());
110
111 while (IsRecordingRequested() && !IsErrored())
112 {
113 if (PauseAndWait())
114 continue;
115
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
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
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
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
159bool 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
188{
189 return m_channel->GetSIStandard();
190}
191
192/* vim: set expandtab tabstop=4 shiftwidth=4: */
virtual int GetInputID(void) const
Definition: channelbase.h:67
int GetMajorID(void)
QString GetSIStandard(void) const
Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
Definition: dtvchannel.cpp:45
QString GetFormat(void)
Definition: dtvchannel.h:46
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:161
void FinishRecording(void) override
Flushes the ringbuffer, and if this is not a live LiveTV recording saves the position map and filesiz...
ProgramMapTable * m_inputPmt
PMT on input side.
Definition: dtvrecorder.h:174
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:46
void ResetForNewFile(void) override
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
MPEGStreamData * m_streamData
Definition: dtvrecorder.h:163
bool m_recordMptsOnly
Definition: dtvrecorder.h:179
bool m_recordMpts
Definition: dtvrecorder.h:178
virtual void SetStreamData(MPEGStreamData *data)
void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override
QString GetDevice(void) const override
Returns String representing device, useful for debugging.
Definition: hdhrchannel.h:35
void StartNewFile(void) override
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
bool Open(void)
HDHRStreamHandler * m_streamHandler
Definition: hdhrrecorder.h:40
QString GetSIStandard(void) const override
bool IsOpen(void) const
Definition: hdhrrecorder.h:28
void Close(void)
bool PauseAndWait(std::chrono::milliseconds timeout=100ms) override
If m_requestPause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
HDHRChannel * m_channel
Definition: hdhrrecorder.h:39
static HDHRStreamHandler * Get(const QString &devname, int inputid, int majorid)
void AddListener(MPEGStreamData *data, bool=false, bool=false, const QString &output_file=QString()) override
static void Return(HDHRStreamHandler *&ref, int inputid)
const ProgramMapTable * PMTSingleProgram(void) const
void AddWritingListener(TSPacketListener *val)
void RemoveWritingListener(TSPacketListener *val)
const ProgramAssociationTable * PATSingleProgram(void) const
void RemoveAVListener(TSPacketListenerAV *val)
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
void AddAVListener(TSPacketListenerAV *val)
QString GetFilename(void) const
@ DVB_TDT_PID
Definition: mpegtables.h:219
QMutex m_pauseLock
Definition: recorderbase.h:313
bool m_requestPause
Definition: recorderbase.h:314
TVRec * m_tvrec
Definition: recorderbase.h:290
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.
bool m_recording
True while recording is actually being performed.
Definition: recorderbase.h:321
QWaitCondition m_pauseWait
Definition: recorderbase.h:316
MythMediaBuffer * m_ringBuffer
Definition: recorderbase.h:291
virtual bool IsPaused(bool holding_lock=false) const
Returns true iff recorder is paused.
bool m_requestRecording
True if API call has requested a recording be [re]started.
Definition: recorderbase.h:319
QWaitCondition m_unpauseWait
Definition: recorderbase.h:317
QWaitCondition m_recordingWait
Definition: recorderbase.h:322
virtual bool AddNamedOutputFile(const QString &filename)
Called with _listener_lock locked just after adding new output file.
bool IsRunning(void) const
virtual void RemoveListener(MPEGStreamData *data)
Specialized version of MPEGStreamData which is used to 'blindly' record the entire MPTS transport fro...
Definition: tsstreamdata.h:12
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
Definition: tv_rec.cpp:2996
uint GetInputId(void) const
Returns the inputid.
Definition: tv_rec.h:234
#define LOC
-*- Mode: c++ -*- HDHRRecorder Copyright (c) 2006-2009 by Silicondust Engineering Ltd,...
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39