MythTV  master
firewirerecorder.cpp
Go to the documentation of this file.
1 
7 // MythTV includes
9 
10 #include "firewirechannel.h"
11 #include "firewirerecorder.h"
12 #include "mpeg/mpegstreamdata.h"
13 #include "mpeg/mpegtables.h"
14 #include "tv_rec.h"
15 
16 #define LOC QString("FireRecBase[%1](%2): ") \
17  .arg(m_tvrec ? m_tvrec->GetInputId() : -1) \
18  .arg(m_channel->GetDevice())
19 
21  DTVRecorder(rec),
22  m_channel(chan)
23 {
24 }
25 
27 {
28  Close();
29 }
30 
32 {
33  if (!m_isopen)
34  {
37  }
38  return m_isopen;
39 }
40 
42 {
43  if (m_isopen)
44  {
46  m_isopen = false;
47  }
48 }
49 
51 {
53 }
54 
56 {
58 }
59 
61 {
62  LOG(VB_RECORD, LOG_INFO, LOC + "run");
63 
64  if (!Open())
65  {
66  m_error = "Failed to open firewire device";
67  LOG(VB_GENERAL, LOG_ERR, LOC + m_error);
68  return;
69  }
70 
71  {
72  QMutexLocker locker(&m_pauseLock);
73  m_requestRecording = true;
74  m_recording = true;
75  m_recordingWait.wakeAll();
76  }
77 
79 
80  while (IsRecordingRequested() && !IsErrored())
81  {
82  if (PauseAndWait())
83  continue;
84 
85  if (!IsRecordingRequested())
86  break;
87 
88  { // sleep 1 seconds unless StopRecording() or Unpause() is called,
89  // just to avoid running this too often.
90  QMutexLocker locker(&m_pauseLock);
92  continue;
93  m_unpauseWait.wait(&m_pauseLock, 1000);
94  }
95  }
96 
97  StopStreaming();
99 
100  QMutexLocker locker(&m_pauseLock);
101  m_recording = false;
102  m_recordingWait.wakeAll();
103 }
104 
105 void FirewireRecorder::AddData(const unsigned char *data, uint len)
106 {
107  uint bufsz = m_buffer.size();
108  if ((SYNC_BYTE == data[0]) && (TSPacket::kSize == len) &&
109  (TSPacket::kSize > bufsz))
110  {
111  if (bufsz)
112  m_buffer.clear();
113 
114  ProcessTSPacket(*(reinterpret_cast<const TSPacket*>(data)));
115  return;
116  }
117 
118  m_buffer.insert(m_buffer.end(), data, data + len);
119  bufsz += len;
120 
121  int sync_at = -1;
122  for (uint i = 0; (i < bufsz) && (sync_at < 0); i++)
123  {
124  if (m_buffer[i] == SYNC_BYTE)
125  sync_at = i;
126  }
127 
128  if (sync_at < 0)
129  return;
130 
131  if (bufsz < 30 * TSPacket::kSize)
132  return; // build up a little buffer
133 
134  while (sync_at + TSPacket::kSize < bufsz)
135  {
136  ProcessTSPacket(*(reinterpret_cast<const TSPacket*>(
137  (m_buffer).data() + sync_at)));
138 
139  sync_at += TSPacket::kSize;
140  }
141 
142  m_buffer.erase(m_buffer.begin(), m_buffer.begin() + sync_at);
143 }
144 
146 {
147  const uint pid = tspacket.PID();
148 
149  if (pid == 0x1fff) // Stuffing
150  return true;
151 
152  if (tspacket.TransportError())
153  return true;
154 
155  if (tspacket.Scrambled())
156  return true;
157 
158  if (tspacket.HasAdaptationField())
160 
161  if (GetStreamData()->IsVideoPID(tspacket.PID()))
162  return ProcessVideoTSPacket(tspacket);
163 
164  if (GetStreamData()->IsAudioPID(tspacket.PID()))
165  return ProcessAudioTSPacket(tspacket);
166 
167  if (GetStreamData()->IsWritingPID(tspacket.PID()))
168  BufferedWrite(tspacket);
169 
170  if (GetStreamData()->IsListeningPID(tspacket.PID()) && tspacket.HasPayload())
171  GetStreamData()->HandleTSTables(&tspacket);
172 
173  return true;
174 }
175 
176 // documented in recorderbase.cpp
177 bool FirewireRecorder::PauseAndWait(std::chrono::milliseconds timeout)
178 {
179  QMutexLocker locker(&m_pauseLock);
180  if (m_requestPause)
181  {
182  LOG(VB_RECORD, LOG_INFO, LOC +
183  QString("PauseAndWait(%1) -- pause").arg(timeout.count()));
184  if (!IsPaused(true))
185  {
186  StopStreaming();
187  m_paused = true;
188  m_pauseWait.wakeAll();
189  if (m_tvrec)
191  }
192  m_unpauseWait.wait(&m_pauseLock, timeout.count());
193  }
194 
195  if (!m_requestPause && IsPaused(true))
196  {
197  LOG(VB_RECORD, LOG_INFO, LOC +
198  QString("PauseAndWait(%1) -- unpause").arg(timeout.count()));
199  m_paused = false;
200  StartStreaming();
201  m_unpauseWait.wakeAll();
202  }
203 
204  return IsPaused(true);
205 }
206 
208 {
210 
211  if (m_streamData->DesiredProgram() >= 0)
213 }
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:102
FirewireDevice::RemoveListener
virtual void RemoveListener(TSDataListener *listener)
Definition: firewiredevice.cpp:50
MPEGStreamData::SetDesiredProgram
void SetDesiredProgram(int p)
Definition: mpegstreamdata.cpp:65
FirewireRecorder::AddData
void AddData(const unsigned char *data, uint len) override
Callback function to add MPEG2 TS data.
Definition: firewirerecorder.cpp:105
MPEGStreamData::AddMPEGSPListener
void AddMPEGSPListener(MPEGSingleProgramStreamListener *val)
Definition: mpegstreamdata.cpp:1716
FirewireRecorder::Open
bool Open(void)
Definition: firewirerecorder.cpp:31
DTVRecorder::ResetForNewFile
void ResetForNewFile(void) override
Definition: dtvrecorder.cpp:140
LOC
#define LOC
FirewireRecorder Copyright (c) 2005 by Jim Westfall and Dave Abrahams Distributed as part of MythTV u...
Definition: firewirerecorder.cpp:16
firewirechannel.h
DTVRecorder::ProcessVideoTSPacket
bool ProcessVideoTSPacket(const TSPacket &tspacket) override
Definition: dtvrecorder.cpp:1605
TSHeader::PID
unsigned int PID(void) const
Definition: tspacket.h:91
firewirerecorder.h
DTVRecorder::BufferedWrite
void BufferedWrite(const TSPacket &tspacket, bool insert=false)
Definition: dtvrecorder.cpp:259
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
FirewireDevice::AddListener
virtual void AddListener(TSDataListener *listener)
Definition: firewiredevice.cpp:37
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
TSHeader::Scrambled
bool Scrambled(void) const
Definition: tspacket.h:110
FirewireRecorder::m_buffer
std::vector< unsigned char > m_buffer
Definition: firewirerecorder.h:63
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
FirewireRecorder::StopStreaming
void StopStreaming(void)
Definition: firewirerecorder.cpp:55
FirewireRecorder::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: firewirerecorder.cpp:177
TSHeader::HasAdaptationField
bool HasAdaptationField(void) const
Definition: tspacket.h:111
RecorderBase::m_pauseLock
QMutex m_pauseLock
Definition: recorderbase.h:338
RecorderBase::m_requestPause
bool m_requestPause
Definition: recorderbase.h:339
RecorderBase::m_recordingWait
QWaitCondition m_recordingWait
Definition: recorderbase.h:347
TVRec::RecorderPaused
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
Definition: tv_rec.cpp:2984
RecorderBase::m_paused
bool m_paused
Definition: recorderbase.h:340
mythlogging.h
FirewireRecorder::m_isopen
bool m_isopen
Definition: firewirerecorder.h:62
FirewireChannel
FirewireChannel Copyright (c) 2005 by Jim Westfall and Dave Abrahams Distributed as part of MythTV un...
Definition: firewirechannel.h:14
TSPacket
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:205
RecorderBase::IsRecordingRequested
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.
Definition: recorderbase.cpp:250
FirewireRecorder::StartStreaming
void StartStreaming(void)
Definition: firewirerecorder.cpp:50
DTVRecorder::GetStreamData
MPEGStreamData * GetStreamData(void) const
Definition: dtvrecorder.h:57
mpegtables.h
DTVRecorder
This is a specialization of RecorderBase used to handle MPEG-2, MPEG-4, MPEG-4 AVC,...
Definition: dtvrecorder.h:25
FirewireRecorder::m_channel
FirewireChannel * m_channel
Definition: firewirerecorder.h:61
uint
unsigned int uint
Definition: compat.h:81
mpegstreamdata.h
RecorderBase::m_pauseWait
QWaitCondition m_pauseWait
Definition: recorderbase.h:341
DTVRecorder::ProcessAudioTSPacket
bool ProcessAudioTSPacket(const TSPacket &tspacket) override
Definition: dtvrecorder.cpp:1639
DTVRecorder::m_streamData
MPEGStreamData * m_streamData
Definition: dtvrecorder.h:162
MPEGStreamData::DesiredProgram
int DesiredProgram(void) const
Definition: mpegstreamdata.h:260
FirewireRecorder::ProcessTSPacket
bool ProcessTSPacket(const TSPacket &tspacket) override
Definition: firewirerecorder.cpp:145
DTVRecorder::m_error
QString m_error
non-empty iff irrecoverable recording error detected
Definition: dtvrecorder.h:160
FirewireRecorder::FirewireRecorder
FirewireRecorder(TVRec *rec, FirewireChannel *chan)
Definition: firewirerecorder.cpp:20
TVRec
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:142
FirewireRecorder::InitStreamData
void InitStreamData(void) override
Definition: firewirerecorder.cpp:207
TSHeader::HasPayload
bool HasPayload(void) const
Definition: tspacket.h:114
RecorderBase::m_recording
bool m_recording
True while recording is actually being performed.
Definition: recorderbase.h:346
FirewireChannel::GetFirewireDevice
virtual FirewireDevice * GetFirewireDevice(void)
Definition: firewirechannel.h:51
tv_rec.h
FirewireRecorder::Close
void Close(void)
Definition: firewirerecorder.cpp:41
MPEGStreamData::HandleAdaptationFieldControl
void HandleAdaptationFieldControl(const TSPacket *tspacket)
Definition: mpegstreamdata.h:405
FirewireRecorder::run
void run(void) override
run() starts the recording process, and does not exit until the recording is complete.
Definition: firewirerecorder.cpp:60
MPEGStreamData::HandleTSTables
virtual void HandleTSTables(const TSPacket *tspacket)
Assembles PSIP packets and processes them.
Definition: mpegstreamdata.cpp:864
FirewireRecorder::~FirewireRecorder
~FirewireRecorder() override
Definition: firewirerecorder.cpp:26
SYNC_BYTE
static constexpr uint8_t SYNC_BYTE
Definition: tspacket.h:19
RecorderBase::m_unpauseWait
QWaitCondition m_unpauseWait
Definition: recorderbase.h:342
RecorderBase::IsPaused
virtual bool IsPaused(bool holding_lock=false) const
Returns true iff recorder is paused.
Definition: recorderbase.cpp:281
FirewireDevice::ClosePort
virtual bool ClosePort(void)=0
TSHeader::TransportError
bool TransportError(void) const
Definition: tspacket.h:84
RecorderBase::m_requestRecording
bool m_requestRecording
True if API call has requested a recording be [re]started.
Definition: recorderbase.h:344
TSPacket::kSize
static constexpr unsigned int kSize
Definition: tspacket.h:259
FirewireDevice::OpenPort
virtual bool OpenPort(void)=0