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#include <thread>
21
22// Qt includes
23#include <QString>
24
25// MythTV includes
28
29#include "asichannel.h"
30#include "asirecorder.h"
31#include "asistreamhandler.h"
32#include "io/mythmediabuffer.h"
33#include "mpeg/tsstreamdata.h"
34#include "tv_rec.h"
35
36#define LOC QString("ASIRec[%1](%2): ") \
37 .arg(m_tvrec ? m_tvrec->GetInputId() : -1) \
38 .arg(m_channel->GetDevice())
39
41 DTVRecorder(rec), m_channel(channel)
42{
43 if (channel->GetFormat().compare("MPTS") == 0)
44 {
45 // MPTS only. Use TSStreamData to write out unfiltered data
46 LOG(VB_RECORD, LOG_INFO, LOC + "Using TSStreamData");
48 m_recordMptsOnly = true;
49 m_recordMpts = false;
50 }
51 else
52 {
53 LOG(VB_RECORD, LOG_INFO, LOC + "Using MPEGStreamData");
54 SetStreamData(new MPEGStreamData(-1, rec ? rec->GetInputId() : -1,
55 false));
56 if (channel->GetProgramNumber() < 0 || !channel->GetMinorChannel())
58 }
59}
60
62 const QString &videodev,
63 const QString &/*audiodev*/,
64 const QString &/*vbidev*/)
65{
66 // We don't want to call DTVRecorder::SetOptionsFromProfile() since
67 // we do not have a "recordingtype" in our profile.
68 DTVRecorder::SetOption("videodevice", videodev);
69 DTVRecorder::SetOption("tvformat", gCoreContext->GetSetting("TVFormat"));
70 SetIntOption(profile, "recordmpts");
71}
72
74{
76 {
77 if (m_recordMpts)
79
80 // Make sure the first things in the file are a PAT & PMT
83 }
84}
85
86
88{
89 if (!Open())
90 {
91 m_error = "Failed to open device";
92 LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
93 return;
94 }
95
96 if (!m_streamData)
97 {
98 m_error = "MPEGStreamData pointer has not been set";
99 LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
100 Close();
101 return;
102 }
103
104 {
105 QMutexLocker locker(&m_pauseLock);
106 m_requestRecording = true;
107 m_recording = true;
108 m_recordingWait.wakeAll();
109 }
110
112 {
117 m_streamData->HandleTables(pat->ProgramPID(0), *pmt);
118 }
119
120 // Listen for time table on DVB standard streams
121 if (m_channel && (m_channel->GetSIStandard() == "dvb"))
123
124 StartNewFile();
125
129 m_streamData, false, true,
130 (m_recordMpts) ? m_ringBuffer->GetFilename() : QString());
131
132 while (IsRecordingRequested() && !IsErrored())
133 {
134 if (PauseAndWait())
135 continue;
136
137 { // sleep 100 milliseconds unless StopRecording() or Unpause()
138 // is called, just to avoid running this too often.
139 QMutexLocker locker(&m_pauseLock);
141 continue;
142 m_unpauseWait.wait(&m_pauseLock, 100);
143 }
144
146 {
147 LOG(VB_GENERAL, LOG_WARNING, LOC +
148 "Recording will not commence until a PMT is set.");
149 std::this_thread::sleep_for(5ms);
150 continue;
151 }
152
154 {
155 m_error = "Stream handler died unexpectedly.";
156 LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
157 }
158 }
159
163
164 Close();
165
167
168 QMutexLocker locker(&m_pauseLock);
169 m_recording = false;
170 m_recordingWait.wakeAll();
171}
172
174{
175 if (IsOpen())
176 {
177 LOG(VB_GENERAL, LOG_WARNING, LOC + "Card already open");
178 return true;
179 }
180
182
184 m_tvrec ? m_tvrec->GetInputId() : -1);
185
186
187 LOG(VB_RECORD, LOG_INFO, LOC + "Opened successfully");
188
189 return true;
190}
191
192bool ASIRecorder::IsOpen(void) const
193{
194 return m_streamHandler;
195}
196
198{
199 LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
200
201 if (IsOpen())
203 m_tvrec ? m_tvrec->GetInputId() : -1);
204
205 LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
206}
#define LOC
Definition: asirecorder.cpp:36
-*- Mode: c++ -*-
Definition: asichannel.h:15
QString GetDevice(void) const override
Returns String representing device, useful for debugging.
Definition: asichannel.h:34
void StartNewFile(void) override
Definition: asirecorder.cpp:73
bool IsOpen(void) const
void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev) override
Sets basic recorder options.
Definition: asirecorder.cpp:61
ASIChannel * m_channel
Definition: asirecorder.h:73
bool Open(void)
void Close(void)
ASIStreamHandler * m_streamHandler
Definition: asirecorder.h:74
ASIRecorder(TVRec *rec, ASIChannel *channel)
Definition: asirecorder.cpp:40
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
Definition: asirecorder.cpp:87
static ASIStreamHandler * Get(const QString &devname, int inputid)
void AddListener(MPEGStreamData *data, bool=false, bool=false, const QString &output_file=QString()) override
static void Return(ASIStreamHandler *&ref, int inputid)
int GetProgramNumber(void) const
Returns program number in PAT, -1 if unknown.
Definition: dtvchannel.h:89
QString GetSIStandard(void) const
Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
Definition: dtvchannel.cpp:45
QString GetFormat(void)
Definition: dtvchannel.h:46
uint GetMinorChannel(void) const
Returns minor channel, 0 if unknown.
Definition: dtvchannel.h:97
bool HasGeneratedPAT(void) const
Definition: dtvchannel.h:135
const ProgramMapTable * GetGeneratedPMT(void) const
Definition: dtvchannel.h:138
const ProgramAssociationTable * GetGeneratedPAT(void) const
Definition: dtvchannel.h:137
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
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
MPEGStreamData * m_streamData
Definition: dtvrecorder.h:163
void SetOption(const QString &name, const QString &value) override
Set an specific option.
Definition: dtvrecorder.cpp:98
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
Encapsulates data about MPEG stream and emits events for each table.
const ProgramMapTable * PMTSingleProgram(void) const
void AddWritingListener(TSPacketListener *val)
void RemoveWritingListener(TSPacketListener *val)
const ProgramAssociationTable * PATSingleProgram(void) const
virtual void Reset(void)
void RemoveAVListener(TSPacketListenerAV *val)
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
void SetListeningDisabled(bool lt)
virtual bool HandleTables(uint pid, const PSIPTable &psip)
Process PSIP packets.
void AddAVListener(TSPacketListenerAV *val)
QString GetSetting(const QString &key, const QString &defaultval="")
QString GetFilename(void) const
@ DVB_TDT_PID
Definition: mpegtables.h:219
@ MPEG_PAT_PID
Definition: mpegtables.h:211
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:599
uint ProgramNumber(uint i) const
Definition: mpegtables.h:626
uint ProgramPID(uint i) const
Definition: mpegtables.h:629
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:676
QMutex m_pauseLock
Definition: recorderbase.h:314
bool m_requestPause
Definition: recorderbase.h:315
TVRec * m_tvrec
Definition: recorderbase.h:291
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.
virtual bool PauseAndWait(std::chrono::milliseconds timeout=100ms)
If m_requestPause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
bool m_recording
True while recording is actually being performed.
Definition: recorderbase.h:322
MythMediaBuffer * m_ringBuffer
Definition: recorderbase.h:292
bool m_requestRecording
True if API call has requested a recording be [re]started.
Definition: recorderbase.h:320
QWaitCondition m_unpauseWait
Definition: recorderbase.h:318
QWaitCondition m_recordingWait
Definition: recorderbase.h:323
void SetIntOption(RecordingProfile *profile, const QString &name)
Convenience function used to set integer options from a profile.
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
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:142
uint GetInputId(void) const
Returns the inputid.
Definition: tv_rec.h:233
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39