MythTV  master
asirecorder.cpp
Go to the documentation of this file.
1 /* -*- Mode: c++ -*-
2  * Class ASIRecorder
3  *
4  * Copyright (C) Daniel Kristjansson 2010
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 // Qt includes
22 #include <QString>
23 
24 // MythTV includes
27 
28 #include "asichannel.h"
29 #include "asirecorder.h"
30 #include "asistreamhandler.h"
31 #include "io/mythmediabuffer.h"
32 #include "mpeg/tsstreamdata.h"
33 #include "tv_rec.h"
34 
35 #define LOC QString("ASIRec[%1](%2): ") \
36  .arg(m_tvrec ? m_tvrec->GetInputId() : -1) \
37  .arg(m_channel->GetDevice())
38 
40  DTVRecorder(rec), m_channel(channel)
41 {
42  if (channel->GetFormat().compare("MPTS") == 0)
43  {
44  // MPTS only. Use TSStreamData to write out unfiltered data
45  LOG(VB_RECORD, LOG_INFO, LOC + "Using TSStreamData");
47  m_recordMptsOnly = true;
48  m_recordMpts = false;
49  }
50  else
51  {
52  LOG(VB_RECORD, LOG_INFO, LOC + "Using MPEGStreamData");
53  SetStreamData(new MPEGStreamData(-1, rec ? rec->GetInputId() : -1,
54  false));
55  if (channel->GetProgramNumber() < 0 || !channel->GetMinorChannel())
57  }
58 }
59 
61  const QString &videodev,
62  const QString &/*audiodev*/,
63  const QString &/*vbidev*/)
64 {
65  // We don't want to call DTVRecorder::SetOptionsFromProfile() since
66  // we do not have a "recordingtype" in our profile.
67  DTVRecorder::SetOption("videodevice", videodev);
68  DTVRecorder::SetOption("tvformat", gCoreContext->GetSetting("TVFormat"));
69  SetIntOption(profile, "recordmpts");
70 }
71 
73 {
74  if (!m_recordMptsOnly)
75  {
76  if (m_recordMpts)
78 
79  // Make sure the first things in the file are a PAT & PMT
82  }
83 }
84 
85 
86 void ASIRecorder::run(void)
87 {
88  if (!Open())
89  {
90  m_error = "Failed to open device";
91  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
92  return;
93  }
94 
95  if (!m_streamData)
96  {
97  m_error = "MPEGStreamData pointer has not been set";
98  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
99  Close();
100  return;
101  }
102 
103  {
104  QMutexLocker locker(&m_pauseLock);
105  m_requestRecording = true;
106  m_recording = true;
107  m_recordingWait.wakeAll();
108  }
109 
110  if (m_channel->HasGeneratedPAT())
111  {
113  const ProgramMapTable *pmt = m_channel->GetGeneratedPMT();
114  m_streamData->Reset(pat->ProgramNumber(0));
116  m_streamData->HandleTables(pat->ProgramPID(0), *pmt);
117  }
118 
119  // Listen for time table on DVB standard streams
120  if (m_channel && (m_channel->GetSIStandard() == "dvb"))
122 
123  StartNewFile();
124 
128  m_streamData, false, true,
129  (m_recordMpts) ? m_ringBuffer->GetFilename() : QString());
130 
131  while (IsRecordingRequested() && !IsErrored())
132  {
133  if (PauseAndWait())
134  continue;
135 
136  { // sleep 100 milliseconds unless StopRecording() or Unpause()
137  // is called, just to avoid running this too often.
138  QMutexLocker locker(&m_pauseLock);
140  continue;
141  m_unpauseWait.wait(&m_pauseLock, 100);
142  }
143 
144  if (!m_inputPmt && !m_recordMptsOnly)
145  {
146  LOG(VB_GENERAL, LOG_WARNING, LOC +
147  "Recording will not commence until a PMT is set.");
148  usleep(5000);
149  continue;
150  }
151 
152  if (!m_streamHandler->IsRunning())
153  {
154  m_error = "Stream handler died unexpectedly.";
155  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
156  }
157  }
158 
162 
163  Close();
164 
165  FinishRecording();
166 
167  QMutexLocker locker(&m_pauseLock);
168  m_recording = false;
169  m_recordingWait.wakeAll();
170 }
171 
173 {
174  if (IsOpen())
175  {
176  LOG(VB_GENERAL, LOG_WARNING, LOC + "Card already open");
177  return true;
178  }
179 
180  ResetForNewFile();
181 
183  m_tvrec ? m_tvrec->GetInputId() : -1);
184 
185 
186  LOG(VB_RECORD, LOG_INFO, LOC + "Opened successfully");
187 
188  return true;
189 }
190 
191 bool ASIRecorder::IsOpen(void) const
192 {
193  return m_streamHandler;
194 }
195 
197 {
198  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
199 
200  if (IsOpen())
202  m_tvrec ? m_tvrec->GetInputId() : -1);
203 
204  LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
205 }
DTVRecorder::HandleSingleProgramPMT
void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override
Definition: dtvrecorder.cpp:1410
ProgramAssociationTable::ProgramPID
uint ProgramPID(uint i) const
Definition: mpegtables.h:629
PID::MPEG_PAT_PID
@ MPEG_PAT_PID
Definition: mpegtables.h:211
DTVRecorder::m_inputPmt
ProgramMapTable * m_inputPmt
PMT on input side.
Definition: dtvrecorder.h:174
DTVRecorder::ResetForNewFile
void ResetForNewFile(void) override
Definition: dtvrecorder.cpp:141
ASIRecorder::SetOptionsFromProfile
void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev) override
Sets basic recorder options.
Definition: asirecorder.cpp:60
ProgramMapTable
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:675
DTVRecorder::SetStreamData
virtual void SetStreamData(MPEGStreamData *data)
Definition: dtvrecorder.cpp:219
DTVChannel::GetMinorChannel
uint GetMinorChannel(void) const
Returns minor channel, 0 if unknown.
Definition: dtvchannel.h:97
RecorderBase::m_tvrec
TVRec * m_tvrec
Definition: recorderbase.h:290
DTVRecorder::IsErrored
bool IsErrored(void) override
Tells us whether an unrecoverable error has been encountered.
Definition: dtvrecorder.h:46
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:363
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:127
DTVChannel::GetGeneratedPMT
const ProgramMapTable * GetGeneratedPMT(void) const
Definition: dtvchannel.h:138
MPEGStreamData::PMTSingleProgram
const ProgramMapTable * PMTSingleProgram(void) const
Definition: mpegstreamdata.h:266
StreamHandler::RemoveListener
virtual void RemoveListener(MPEGStreamData *data)
Definition: streamhandler.cpp:81
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:313
ASIRecorder::run
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
Definition: asirecorder.cpp:86
RecorderBase::m_requestPause
bool m_requestPause
Definition: recorderbase.h:314
ASIRecorder::Open
bool Open(void)
Definition: asirecorder.cpp:172
asistreamhandler.h
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:322
asirecorder.h
MythMediaBuffer::GetFilename
QString GetFilename(void) const
Definition: mythmediabuffer.cpp:1749
ASIRecorder::IsOpen
bool IsOpen(void) const
Definition: asirecorder.cpp:191
TVRec::GetInputId
uint GetInputId(void) const
Returns the inputid.
Definition: tv_rec.h:234
MPEGStreamData::PATSingleProgram
const ProgramAssociationTable * PATSingleProgram(void) const
Definition: mpegstreamdata.h:264
DTVRecorder::HandleSingleProgramPAT
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
Definition: dtvrecorder.cpp:1390
mythlogging.h
ASIStreamHandler::Get
static ASIStreamHandler * Get(const QString &devname, int inputid)
Definition: asistreamhandler.cpp:35
ProgramAssociationTable::ProgramNumber
uint ProgramNumber(uint i) const
Definition: mpegtables.h:626
hardwareprofile.scan.profile
profile
Definition: scan.py:96
DTVRecorder::m_recordMptsOnly
bool m_recordMptsOnly
Definition: dtvrecorder.h:179
ASIRecorder::m_channel
ASIChannel * m_channel
Definition: asirecorder.h:73
MPEGStreamData::HandleTables
virtual bool HandleTables(uint pid, const PSIPTable &psip)
Process PSIP packets.
Definition: mpegstreamdata.cpp:669
ASIRecorder::ASIRecorder
ASIRecorder(TVRec *rec, ASIChannel *channel)
Definition: asirecorder.cpp:39
DTVChannel::GetGeneratedPAT
const ProgramAssociationTable * GetGeneratedPAT(void) const
Definition: dtvchannel.h:137
MPEGStreamData
Encapsulates data about MPEG stream and emits events for each table.
Definition: mpegstreamdata.h:85
MPEGStreamData::RemoveWritingListener
void RemoveWritingListener(TSPacketListener *val)
Definition: mpegstreamdata.cpp:1666
RecorderBase::IsRecordingRequested
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.
Definition: recorderbase.cpp:254
ASIStreamHandler::Return
static void Return(ASIStreamHandler *&ref, int inputid)
Definition: asistreamhandler.cpp:68
ASIChannel::GetDevice
QString GetDevice(void) const override
Returns String representing device, useful for debugging.
Definition: asichannel.h:34
ASIStreamHandler::AddListener
void AddListener(MPEGStreamData *data, bool=false, bool=false, const QString &output_file=QString()) override
Definition: asistreamhandler.h:49
DTVRecorder::SetOption
void SetOption(const QString &name, const QString &value) override
Set an specific option.
Definition: dtvrecorder.cpp:92
LOC
#define LOC
Definition: asirecorder.cpp:35
DTVRecorder
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:26
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
ProgramAssociationTable
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:598
ASIRecorder::Close
void Close(void)
Definition: asirecorder.cpp:196
asichannel.h
mythmediabuffer.h
DTVChannel::GetSIStandard
QString GetSIStandard(void) const
Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
Definition: dtvchannel.cpp:45
RecorderBase::m_ringBuffer
MythMediaBuffer * m_ringBuffer
Definition: recorderbase.h:291
MPEGStreamData::AddAVListener
void AddAVListener(TSPacketListenerAV *val)
Definition: mpegstreamdata.cpp:1680
ASIRecorder::m_streamHandler
ASIStreamHandler * m_streamHandler
Definition: asirecorder.h:74
ASIChannel
-*- Mode: c++ -*-
Definition: asichannel.h:14
PID::DVB_TDT_PID
@ DVB_TDT_PID
Definition: mpegtables.h:219
DTVRecorder::m_streamData
MPEGStreamData * m_streamData
Definition: dtvrecorder.h:163
mythcorecontext.h
MPEGStreamData::AddWritingListener
void AddWritingListener(TSPacketListener *val)
Definition: mpegstreamdata.cpp:1655
DTVRecorder::m_error
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:161
DTVRecorder::m_recordMpts
bool m_recordMpts
Definition: dtvrecorder.h:178
TVRec
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:142
RecorderBase::m_recording
bool m_recording
True while recording is actually being performed.
Definition: recorderbase.h:321
DTVChannel::GetProgramNumber
int GetProgramNumber(void) const
Returns program number in PAT, -1 if unknown.
Definition: dtvchannel.h:89
MPEGStreamData::Reset
virtual void Reset(void)
Definition: mpegstreamdata.h:94
tv_rec.h
ASIRecorder::StartNewFile
void StartNewFile(void) override
Definition: asirecorder.cpp:72
MPEGStreamData::AddListeningPID
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
Definition: mpegstreamdata.h:120
DTVChannel::HasGeneratedPAT
bool HasGeneratedPAT(void) const
Definition: dtvchannel.h:135
RecordingProfile
Definition: recordingprofile.h:41
StreamHandler::IsRunning
bool IsRunning(void) const
Definition: streamhandler.cpp:164
RecorderBase::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: recorderbase.h:317
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:1701
MPEGStreamData::SetListeningDisabled
void SetListeningDisabled(bool lt)
Definition: mpegstreamdata.h:92
RecorderBase::PauseAndWait
virtual bool PauseAndWait(std::chrono::milliseconds timeout=100ms)
If m_requestPause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
Definition: recorderbase.cpp:330
tsstreamdata.h
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:904
RecorderBase::m_requestRecording
bool m_requestRecording
True if API call has requested a recording be [re]started.
Definition: recorderbase.h:319
RecorderBase::SetIntOption
void SetIntOption(RecordingProfile *profile, const QString &name)
Convenience function used to set integer options from a profile.
Definition: recorderbase.cpp:203