Torc  0.1
torccamerathread.cpp
Go to the documentation of this file.
1 /* Class TorcCameraThread
2 *
3 * This file is part of the Torc project.
4 *
5 * Copyright (C) Mark Kendall 2018
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA.
21 */
22 
23 // Torc
24 #include "torclogging.h"
25 #include "torccameraoutput.h"
26 #include "torccamerathread.h"
27 
37 void TorcCameraThread::CreateOrDestroy(TorcCameraThread *&Thread, const QString &Type, const TorcCameraParams &Params)
38 {
39  static QMutex lock(QMutex::NonRecursive);
40  static QMutexLocker locker(&lock);
41  static QMap<QString,TorcCameraThread*> threads;
42 
43  if (Thread)
44  {
45  if (threads.contains(Type))
46  {
47  TorcCameraThread* thread = threads.value(Type);
48  if (thread != Thread)
49  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("Mismatch between thread and type for '%1'").arg(Type));
50 
51  thread->DownRef();
52  // release our own ref
53  if (!thread->IsShared())
54  {
55  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("Removing camera thread - no longer in use '%1'").arg(Type));
56  thread->DownRef();
57  threads.remove(Type);
58  }
59  }
60  else
61  {
62  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("Unknown camera thread type '%1'").arg(Type));
63  }
64  }
65  else
66  {
67  TorcCameraThread* thread = nullptr;
68  if (threads.contains(Type))
69  {
70  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("Sharing existing camera thread '%1'").arg(Type));
71  thread = threads.value(Type);
72  }
73  else
74  {
75  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("Creating shared camera thread '%1'").arg(Type));
76  thread = new TorcCameraThread(Type, Params);
77  threads.insert(Type, thread);
78  }
79  // as creator, we hold one reference. Add another for the requestor.
80  thread->UpRef();
81  Thread = thread;
82  }
83 }
84 
87 TorcCameraThread::TorcCameraThread( const QString &Type, const TorcCameraParams &Params)
88  : TorcQThread(QStringLiteral("Camera")),
89  m_type(Type),
90  m_params(Params),
91  m_camera(nullptr),
92  m_cameraLock(QReadWriteLock::Recursive)
93 {
94 }
95 
97 {
98  delete m_camera;
99 }
100 
104 {
105  if (!Parent)
106  return;
107 
108  QWriteLocker locker(&m_cameraLock);
117 }
118 
122 {
123  if (!Parent)
124  return;
125 
126  QWriteLocker locker(&m_cameraLock);
131 }
132 
138 bool TorcCameraThread::DownRef(void)
139 {
140  if (!m_refCount.deref())
141  {
142  quit();
143  wait();
144  if (!m_eventLoopEnding)
145  {
146  deleteLater();
147  return true;
148  }
149 
150  delete this;
151  return true;
152  }
153 
154  return false;
155 }
156 
158 {
159  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("Camera thread starting"));
160 
161  QWriteLocker locker(&m_cameraLock);
162  m_camera = TorcCameraFactory::GetCamera(m_type, m_params);
163  if (!m_camera)
164  {
165  quit();
166  return;
167  }
168 
169  // outbound streaming signals
177  // inbound streaming signals
179  // outbound stills signals
181  // inbound stills signals
183 
184  if (!m_camera->Setup() || !m_camera->Start())
185  quit();
186 }
187 
189 {
190  if (m_camera)
191  {
192  m_camera->Stop();
193  delete m_camera;
194  m_camera = nullptr;
195  }
196 
197  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("Camera thread stopping"));
198 }
199 
200 QByteArray TorcCameraThread::GetSegment(int Segment)
201 {
202  QReadLocker locker(&m_cameraLock);
203  if (m_camera)
204  return m_camera->GetSegment(Segment);
205  return QByteArray();
206 }
207 
209 {
210  QReadLocker locker(&m_cameraLock);
211  if (m_camera)
212  return m_camera->GetInitSegment();
213  return QByteArray();
214 }
215 
void Finish(void) override
void TakeStills(uint Count)
void Start(void) override
static TorcCameraDevice * GetCamera(const QString &Type, const TorcCameraParams &Params)
Definition: torccamera.cpp:447
virtual bool Stop(void)=0
void ParamsChanged(TorcCameraParams &Params)
Notify the output that the camera parameters have changed.
void CameraErrored(bool Errored) override
QByteArray GetSegment(int Segment)
QByteArray GetInitSegment(void)
Definition: torccamera.cpp:317
void InitSegmentReady(void)
The &#39;init&#39; segment is ready and available.
void SetErrored(bool Errored)
void SegmentRemoved(int Segment)
void WritingStarted(void)
virtual void TakeStills(uint Count)
Tell the camera to take Count number of still images.
Definition: torccamera.cpp:330
void WritingStopped(void)
The camera is no longer recording any video.
void StreamVideo(bool Video)
virtual void StreamVideo(bool Video)=0
void StillReady(const QString &File)
void StreamVideo(bool Video)
virtual bool Start(void)=0
void SetVideoParent(TorcCameraVideoOutput *Parent)
Connect camera signals for video streaming to the stream output device.
TorcQThread(const QString &Name)
Definition: torcqthread.cpp:64
QByteArray GetInitSegment(void)
void ParamsChanged(TorcCameraParams &Params)
void StillReady(const QString &File)
void CameraErrored(bool)
void InitSegmentReady(void)
void WritingStarted(void)
void StillReady(const QString &File)
QByteArray GetSegment(int Segment)
Definition: torccamera.cpp:309
void SegmentReady(int)
void SegmentReady(int Segment)
void WritingStarted(void)
The camera has started to record video.
void ParametersChanged(TorcCameraParams &Params)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: torclogging.h:20
virtual bool Setup(void)
Definition: torccamera.cpp:286
void CameraErrored(bool Errored) override
void WritingStopped(void)
void InitSegmentReady(void)
void SegmentRemoved(int)
void WritingStopped(void)
void TakeStills(uint Count)
void SegmentReady(int Segment)
static void CreateOrDestroy(TorcCameraThread *&Thread, const QString &Type, const TorcCameraParams &Params=TorcCameraParams())
Create and release shared camera threads/devices.
void SegmentRemoved(int Segment)
void SetStillsParent(TorcCameraStillsOutput *Parent)
Connect camera signals for stills capture.