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
74bool 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{
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"))
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
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
152 {
153 m_error = "Stream handler died unexpectedly.";
154 LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
155 }
156 }
157
161
162 Close();
163
165
166 QMutexLocker locker(&m_pauseLock);
167 m_recording = false;
168 m_recordingWait.wakeAll();
169}
170
171bool 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
199QString DVBRecorder::GetSIStandard(void) const
200{
201 return m_channel->GetSIStandard();
202}
203
205{
207 m_channel->SetPMT(pmt);
208}
209
211{
213}
214
215/* vim: set expandtab tabstop=4 shiftwidth=4: */
QString GetSIStandard(void) const
Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
Definition: dtvchannel.cpp:45
QString GetFormat(void)
Definition: dtvchannel.h:46
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:35
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
MPEGStreamData * GetStreamData(void) const
Definition: dtvrecorder.h:58
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
Provides interface to the tuning hardware when using DVB drivers.
Definition: dvbchannel.h:31
void SetPMT(const ProgramMapTable *pmt)
Tells the Conditional Access Module which streams we wish to decode.
Definition: dvbchannel.cpp:729
void SetTimeOffset(double offset)
Tells the Conditional Access Module the offset from the computers utc time to dvb time.
Definition: dvbchannel.cpp:741
void UpdateCAMTimeOffset(void) override
bool Open(void)
Definition: dvbrecorder.cpp:44
DVBChannel * m_channel
Definition: dvbrecorder.h:41
DVBStreamHandler * m_streamHandler
Definition: dvbrecorder.h:42
void SetCAMPMT(const ProgramMapTable *pmt) override
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
bool IsOpen(void) const
Definition: dvbrecorder.cpp:74
QString GetSIStandard(void) const override
void Close(void)
Definition: dvbrecorder.cpp:79
bool PauseAndWait(std::chrono::milliseconds timeout=100ms) override
If m_requestPause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
void StartNewFile(void) override
Definition: dvbrecorder.cpp:88
DVBRecorder(TVRec *rec, DVBChannel *channel)
Definition: dvbrecorder.cpp:38
static void Return(DVBStreamHandler *&ref, int inputid)
static DVBStreamHandler * Get(const QString &devname, 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
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:676
bool IsEncrypted(const QString &sistandard) const
Returns true iff PMT contains CA descriptor for a vid/aud stream.
Definition: mpegtables.cpp:556
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
QString m_videodevice
Definition: recorderbase.h:298
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)
virtual void AddListener(MPEGStreamData *data, bool allow_section_reader=false, bool needs_buffering=false, const QString &output_file=QString())
Specialized version of MPEGStreamData which is used to 'blindly' record the entire MPTS transport fro...
Definition: tsstreamdata.h:12
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:143
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
Definition: dvbrecorder.cpp:35
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39