MythTV  master
dvbrecorder.cpp
Go to the documentation of this file.
1 /*
2  * Class DVBRecorder
3  *
4  * Copyright (C) Daniel Thor Kristjansson 2010
5  *
6  * This class glues the DVBStreamHandler which handles the DVB devices
7  * to the DTVRecorder that handles recordings in MythTV.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 // MythTV includes
25 #include "dvbstreamhandler.h"
26 #include "mpegstreamdata.h"
27 #include "tsstreamdata.h"
28 #include "dvbrecorder.h"
29 #include "dvbchannel.h"
30 #include "ringbuffer.h"
31 #include "tv_rec.h"
32 #include "mythlogging.h"
33 
34 #define LOC QString("DVBRec[%1](%2): ") \
35  .arg(m_tvrec ? m_tvrec->GetInputId() : -1).arg(m_videodevice)
36 
38  : DTVRecorder(rec), m_channel(channel)
39 {
40  m_videodevice.clear();
41 }
42 
44 {
45  if (IsOpen())
46  {
47  LOG(VB_GENERAL, LOG_WARNING, LOC + "Card already open");
48  return true;
49  }
50 
51  if (m_videodevice.isEmpty())
52  return false;
53 
55 
56  if (m_channel->GetFormat().compare("MPTS") == 0)
57  {
58  // MPTS only. Use TSStreamData to write out unfiltered data
59  LOG(VB_RECORD, LOG_INFO, LOC + "Using TSStreamData");
61  m_record_mpts_only = true;
62  m_record_mpts = false;
63  }
64 
66  m_tvrec ? m_tvrec->GetInputId() : -1);
67 
68  LOG(VB_RECORD, LOG_INFO, LOC + "Card opened successfully");
69 
70  return true;
71 }
72 
73 bool DVBRecorder::IsOpen(void) const
74 {
75  return (nullptr != m_stream_handler);
76 }
77 
79 {
80  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
81 
83 
84  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
85 }
86 
88 {
89  if (!m_record_mpts_only)
90  {
91  if (m_record_mpts)
93 
94  // Make sure the first things in the file are a PAT & PMT
97  }
98 }
99 
101 {
102  if (!Open())
103  {
104  m_error = "Failed to open DVB device";
105  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
106  return;
107  }
108 
109  {
110  QMutexLocker locker(&m_pauseLock);
111  m_request_recording = true;
112  m_recording = true;
113  m_recordingWait.wakeAll();
114  }
115 
116  // Listen for time table on DVB standard streams
117  if (m_channel && (m_channel->GetSIStandard() == "dvb"))
119  if (m_record_mpts_only)
121 
122  StartNewFile();
123 
127  (m_record_mpts) ? m_ringBuffer->GetFilename() : QString());
128 
129  while (IsRecordingRequested() && !IsErrored())
130  {
131  if (PauseAndWait())
132  continue;
133 
134  { // sleep 100 milliseconds unless StopRecording() or Unpause()
135  // is called, just to avoid running this too often.
136  QMutexLocker locker(&m_pauseLock);
138  continue;
139  m_unpauseWait.wait(&m_pauseLock, 100);
140  }
141 
143  {
144  LOG(VB_GENERAL, LOG_WARNING, LOC +
145  "Recording will not commence until a PMT is set.");
146  usleep(5000);
147  continue;
148  }
149 
150  if (!m_stream_handler->IsRunning())
151  {
152  m_error = "Stream handler died unexpectedly.";
153  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
154  }
155  }
156 
160 
161  Close();
162 
163  FinishRecording();
164 
165  QMutexLocker locker(&m_pauseLock);
166  m_recording = false;
167  m_recordingWait.wakeAll();
168 }
169 
171 {
172  QMutexLocker locker(&m_pauseLock);
173  if (m_request_pause)
174  {
175  if (!IsPaused(true))
176  {
178 
179  m_paused = true;
180  m_pauseWait.wakeAll();
181  if (m_tvrec)
183  }
184 
186  }
187 
188  if (!m_request_pause && IsPaused(true))
189  {
190  m_paused = false;
192  m_unpauseWait.wakeAll();
193  }
194 
195  return IsPaused(true);
196 }
197 
198 QString DVBRecorder::GetSIStandard(void) const
199 {
200  return m_channel->GetSIStandard();
201 }
202 
204 {
205  if (pmt->IsEncrypted(m_channel->GetSIStandard()))
206  m_channel->SetPMT(pmt);
207 }
208 
210 {
212 }
213 
214 /* vim: set expandtab tabstop=4 shiftwidth=4: */
bool PauseAndWait(int timeout=100) override
If m_request_pause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
const ProgramAssociationTable * PATSingleProgram(void) const
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:28
uint GetInputId(void)
Returns the inputid.
Definition: tv_rec.h:232
DVBRecorder(TVRec *, DVBChannel *)
Definition: dvbrecorder.cpp:37
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
bool IsEncrypted(const QString &sistandard) const
Returns true iff PMT contains CA descriptor for a vid/aud stream.
Definition: mpegtables.cpp:552
QMutex m_pauseLock
Definition: recorderbase.h:326
void SetCAMPMT(const ProgramMapTable *) override
void ResetForNewFile(void) override
bool m_record_mpts
Definition: dtvrecorder.h:179
void SetPMT(const ProgramMapTable *)
Tells the Conditional Access Module which streams we wish to decode.
Definition: dvbchannel.cpp:495
virtual void RemoveListener(MPEGStreamData *data)
QString GetFilename(void) const
Returns name of file used by this RingBuffer.
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
Provides interface to the tuning hardware when using DVB drivers.
Definition: dvbchannel.h:29
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:48
DVBStreamHandler * m_stream_handler
Definition: dvbrecorder.h:42
bool m_request_recording
True if API call has requested a recording be [re]started.
Definition: recorderbase.h:332
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
ProgramMapTable * m_input_pmt
PMT on input side.
Definition: dtvrecorder.h:175
static void Return(DVBStreamHandler *&ref, int inputid)
void SetTimeOffset(double offset)
Tells the Conditional Access Module the offset from the computers utc time to dvb time.
Definition: dvbchannel.cpp:507
static DVBStreamHandler * Get(const QString &devname, int inputid)
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...
QWaitCondition m_pauseWait
Definition: recorderbase.h:329
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:141
virtual void AddListener(MPEGStreamData *data, bool allow_section_reader=false, bool needs_buffering=false, QString output_file=QString())
MPEGStreamData * m_stream_data
Definition: dtvrecorder.h:164
QString GetFormat(void)
Definition: dtvchannel.h:47
void RemoveWritingListener(TSPacketListener *)
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
Definition: tv_rec.cpp:2935
void AddAVListener(TSPacketListenerAV *)
QWaitCondition m_recordingWait
Definition: recorderbase.h:335
bool Open(void)
Definition: dvbrecorder.cpp:43
bool m_recording
True while recording is actually being performed.
Definition: recorderbase.h:334
MPEGStreamData * GetStreamData(void) const
Definition: dtvrecorder.h:60
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
bool m_request_pause
Definition: recorderbase.h:327
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
TVRec * m_tvrec
Definition: recorderbase.h:303
const ProgramMapTable * PMTSingleProgram(void) const
void AddWritingListener(TSPacketListener *)
QString GetSIStandard(void) const override
bool m_record_mpts_only
Definition: dtvrecorder.h:180
#define LOC
Definition: dvbrecorder.cpp:34
Specialized version of MPEGStreamData which is used to 'blindly' record the entire MPTS transport fro...
Definition: tsstreamdata.h:11
QString m_videodevice
Definition: recorderbase.h:311
DVBChannel * m_channel
Definition: dvbrecorder.h:41
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:162
QString GetSIStandard(void) const
Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
Definition: dtvchannel.cpp:44
void RemoveAVListener(TSPacketListenerAV *)
void StartNewFile(void) override
Definition: dvbrecorder.cpp:87
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:656
void Close(void)
Definition: dvbrecorder.cpp:78
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
void UpdateCAMTimeOffset(void) override
bool IsOpen(void) const
Definition: dvbrecorder.cpp:73
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.