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
26 
27 #include "dvbchannel.h"
28 #include "dvbrecorder.h"
29 #include "dvbstreamhandler.h"
30 #include "io/mythmediabuffer.h"
31 #include "mpeg/mpegstreamdata.h"
32 #include "mpeg/tsstreamdata.h"
33 #include "tv_rec.h"
34 
35 #define LOC QString("DVBRec[%1](%2): ") \
36  .arg(m_tvrec ? m_tvrec->GetInputId() : -1).arg(m_videodevice)
37 
39  : DTVRecorder(rec), m_channel(channel)
40 {
41  m_videodevice.clear();
42 }
43 
45 {
46  if (IsOpen())
47  {
48  LOG(VB_GENERAL, LOG_WARNING, LOC + "Card already open");
49  return true;
50  }
51 
52  if (m_videodevice.isEmpty())
53  return false;
54 
56 
57  if (m_channel->GetFormat().compare("MPTS") == 0)
58  {
59  // MPTS only. Use TSStreamData to write out unfiltered data
60  LOG(VB_RECORD, LOG_INFO, LOC + "Using TSStreamData");
62  m_recordMptsOnly = true;
63  m_recordMpts = false;
64  }
65 
67  m_tvrec ? m_tvrec->GetInputId() : -1);
68 
69  LOG(VB_RECORD, LOG_INFO, LOC + "Card opened successfully");
70 
71  return true;
72 }
73 
74 bool DVBRecorder::IsOpen(void) const
75 {
76  return (nullptr != m_streamHandler);
77 }
78 
80 {
81  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
82 
84 
85  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
86 }
87 
89 {
90  if (!m_recordMptsOnly)
91  {
92  if (m_recordMpts)
94 
95  // Make sure the first things in the file are a PAT & PMT
98  }
99 }
100 
102 {
103  if (!Open())
104  {
105  m_error = "Failed to open DVB device";
106  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
107  return;
108  }
109 
110  {
111  QMutexLocker locker(&m_pauseLock);
112  m_requestRecording = true;
113  m_recording = true;
114  m_recordingWait.wakeAll();
115  }
116 
117  // Listen for time table on DVB standard streams
118  if (m_channel && (m_channel->GetSIStandard() == "dvb"))
120  if (m_recordMptsOnly)
121  m_streamData->AddListeningPID(0x2000);
122 
123  StartNewFile();
124 
128  (m_recordMpts) ? m_ringBuffer->GetFilename() : QString());
129 
130  while (IsRecordingRequested() && !IsErrored())
131  {
132  if (PauseAndWait())
133  continue;
134 
135  { // sleep 100 milliseconds unless StopRecording() or Unpause()
136  // is called, just to avoid running this too often.
137  QMutexLocker locker(&m_pauseLock);
139  continue;
140  m_unpauseWait.wait(&m_pauseLock, 100);
141  }
142 
143  if (!m_inputPmt && !m_recordMptsOnly)
144  {
145  LOG(VB_GENERAL, LOG_WARNING, LOC +
146  "Recording will not commence until a PMT is set.");
147  usleep(5000);
148  continue;
149  }
150 
151  if (!m_streamHandler->IsRunning())
152  {
153  m_error = "Stream handler died unexpectedly.";
154  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
155  }
156  }
157 
161 
162  Close();
163 
164  FinishRecording();
165 
166  QMutexLocker locker(&m_pauseLock);
167  m_recording = false;
168  m_recordingWait.wakeAll();
169 }
170 
171 bool DVBRecorder::PauseAndWait(std::chrono::milliseconds timeout)
172 {
173  QMutexLocker locker(&m_pauseLock);
174  if (m_requestPause)
175  {
176  if (!IsPaused(true))
177  {
179 
180  m_paused = true;
181  m_pauseWait.wakeAll();
182  if (m_tvrec)
184  }
185 
186  m_unpauseWait.wait(&m_pauseLock, timeout.count());
187  }
188 
189  if (!m_requestPause && IsPaused(true))
190  {
191  m_paused = false;
193  m_unpauseWait.wakeAll();
194  }
195 
196  return IsPaused(true);
197 }
198 
199 QString DVBRecorder::GetSIStandard(void) const
200 {
201  return m_channel->GetSIStandard();
202 }
203 
205 {
206  if (pmt->IsEncrypted(m_channel->GetSIStandard()))
207  m_channel->SetPMT(pmt);
208 }
209 
211 {
213 }
214 
215 /* vim: set expandtab tabstop=4 shiftwidth=4: */
DTVRecorder::HandleSingleProgramPMT
void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override
Definition: dtvrecorder.cpp:1405
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
DTVRecorder::m_inputPmt
ProgramMapTable * m_inputPmt
PMT on input side.
Definition: dtvrecorder.h:177
DVBRecorder::DVBRecorder
DVBRecorder(TVRec *rec, DVBChannel *channel)
Definition: dvbrecorder.cpp:38
DTVRecorder::ResetForNewFile
void ResetForNewFile(void) override
Definition: dtvrecorder.cpp:140
ProgramMapTable
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:694
DVBRecorder::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: dvbrecorder.cpp:171
DTVRecorder::SetStreamData
virtual void SetStreamData(MPEGStreamData *data)
Definition: dtvrecorder.cpp:218
RecorderBase::m_tvrec
TVRec * m_tvrec
Definition: recorderbase.h:315
DTVRecorder::IsErrored
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:45
DTVChannel::GetFormat
QString GetFormat(void)
Definition: dtvchannel.h:46
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
DVBChannel::SetPMT
void SetPMT(const ProgramMapTable *pmt)
Tells the Conditional Access Module which streams we wish to decode.
Definition: dvbchannel.cpp:726
PID::DVB_TDT_PID
@ DVB_TDT_PID
Definition: mpegtables.h:219
ProgramMapTable::IsEncrypted
bool IsEncrypted(const QString &sistandard) const
Returns true iff PMT contains CA descriptor for a vid/aud stream.
Definition: mpegtables.cpp:552
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
DVBRecorder::run
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
Definition: dvbrecorder.cpp:101
MPEGStreamData::PMTSingleProgram
const ProgramMapTable * PMTSingleProgram(void) const
Definition: mpegstreamdata.h:266
dvbchannel.h
StreamHandler::RemoveListener
virtual void RemoveListener(MPEGStreamData *data)
Definition: streamhandler.cpp:80
DVBRecorder::SetCAMPMT
void SetCAMPMT(const ProgramMapTable *pmt) override
Definition: dvbrecorder.cpp:204
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:338
RecorderBase::m_requestPause
bool m_requestPause
Definition: recorderbase.h:339
dvbstreamhandler.h
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:347
dvbrecorder.h
TVRec::RecorderPaused
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
Definition: tv_rec.cpp:2897
MythMediaBuffer::GetFilename
QString GetFilename(void) const
Definition: mythmediabuffer.cpp:1740
TVRec::GetInputId
uint GetInputId(void) const
Returns the inputid.
Definition: tv_rec.h:236
RecorderBase::m_paused
bool m_paused
Definition: recorderbase.h:340
MPEGStreamData::PATSingleProgram
const ProgramAssociationTable * PATSingleProgram(void) const
Definition: mpegstreamdata.h:264
DTVRecorder::HandleSingleProgramPAT
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
Definition: dtvrecorder.cpp:1385
mythlogging.h
DVBStreamHandler::Return
static void Return(DVBStreamHandler *&ref, int inputid)
Definition: dvbstreamhandler.cpp:74
DTVRecorder::m_recordMptsOnly
bool m_recordMptsOnly
Definition: dtvrecorder.h:182
DVBStreamHandler::Get
static DVBStreamHandler * Get(const QString &devname, int inputid)
Definition: dvbstreamhandler.cpp:44
MPEGStreamData::RemoveWritingListener
void RemoveWritingListener(TSPacketListener *val)
Definition: mpegstreamdata.cpp:1660
RecorderBase::IsRecordingRequested
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.
Definition: recorderbase.cpp:250
DTVRecorder::GetStreamData
MPEGStreamData * GetStreamData(void) const
Definition: dtvrecorder.h:57
DTVRecorder
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:25
mythmediabuffer.h
mpegstreamdata.h
RecorderBase::m_videodevice
QString m_videodevice
Definition: recorderbase.h:323
DTVChannel::GetSIStandard
QString GetSIStandard(void) const
Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
Definition: dtvchannel.cpp:45
TimeOffset
Definition: channelsettings.cpp:199
RecorderBase::m_pauseWait
QWaitCondition m_pauseWait
Definition: recorderbase.h:341
RecorderBase::m_ringBuffer
MythMediaBuffer * m_ringBuffer
Definition: recorderbase.h:316
MPEGStreamData::AddAVListener
void AddAVListener(TSPacketListenerAV *val)
Definition: mpegstreamdata.cpp:1674
DVBChannel
Provides interface to the tuning hardware when using DVB drivers.
Definition: dvbchannel.h:31
DTVRecorder::m_streamData
MPEGStreamData * m_streamData
Definition: dtvrecorder.h:162
MPEGStreamData::AddWritingListener
void AddWritingListener(TSPacketListener *val)
Definition: mpegstreamdata.cpp:1649
DVBRecorder::Open
bool Open(void)
Definition: dvbrecorder.cpp:44
DTVRecorder::m_error
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:160
DTVRecorder::m_recordMpts
bool m_recordMpts
Definition: dtvrecorder.h:181
LOC
#define LOC
Definition: dvbrecorder.cpp:35
DVBChannel::SetTimeOffset
void SetTimeOffset(double offset)
Tells the Conditional Access Module the offset from the computers utc time to dvb time.
Definition: dvbchannel.cpp:738
TVRec
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:144
RecorderBase::m_recording
bool m_recording
True while recording is actually being performed.
Definition: recorderbase.h:346
DVBRecorder::m_channel
DVBChannel * m_channel
Definition: dvbrecorder.h:41
tv_rec.h
DVBRecorder::UpdateCAMTimeOffset
void UpdateCAMTimeOffset(void) override
Definition: dvbrecorder.cpp:210
StreamHandler::AddListener
virtual void AddListener(MPEGStreamData *data, bool allow_section_reader=false, bool needs_buffering=false, const QString &output_file=QString())
Definition: streamhandler.cpp:35
MPEGStreamData::AddListeningPID
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
Definition: mpegstreamdata.h:120
DVBRecorder::IsOpen
bool IsOpen(void) const
Definition: dvbrecorder.cpp:74
DVBRecorder::GetSIStandard
QString GetSIStandard(void) const override
Definition: dvbrecorder.cpp:199
DVBRecorder::StartNewFile
void StartNewFile(void) override
Definition: dvbrecorder.cpp:88
StreamHandler::IsRunning
bool IsRunning(void) const
Definition: streamhandler.cpp:163
DVBRecorder::Close
void Close(void)
Definition: dvbrecorder.cpp:79
RecorderBase::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: recorderbase.h:342
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:1695
DVBRecorder::m_streamHandler
DVBStreamHandler * m_streamHandler
Definition: dvbrecorder.h:42
RecorderBase::IsPaused
virtual bool IsPaused(bool holding_lock=false) const
Returns true iff recorder is paused.
Definition: recorderbase.cpp:282
tsstreamdata.h
RecorderBase::m_requestRecording
bool m_requestRecording
True if API call has requested a recording be [re]started.
Definition: recorderbase.h:344