ADTF  3.18.2
builds/digitalwerk/solutions/adtf_content/adtf_base/adtf_core/src/libraries/javascriptfiltersdk/src/reader.h
Go to the documentation of this file.
1 
8 /*
9  * This file depends on Qt which is licensed under LGPLv3.
10  * See ADTF_DIR/3rdparty/qt5 and doc/license for detailed information.
11  */
12 #pragma once
16 
17 #include <QJsonObject>
18 #include <QImage>
19 #include <QJSEngine>
20 
21 #include <unordered_map>
22 #include <mutex>
23 #include <string>
24 
25 using namespace adtf::ucom;
26 using namespace adtf::util;
27 using namespace adtf::base;
28 using namespace adtf::streaming;
29 using namespace adtf::mediadescription;
30 
31 namespace adtf
32 {
33 
34 namespace javascript
35 {
36 
37 namespace scripting
38 {
39 
41 struct tConversionFormat
42 {
43  QImage::Format eDestinationFormat;
44  bool bRequiresInvert;
45  QImage::InvertMode eInvertMode;
46 };
47 
48 class cImageConverter
49 {
50  public:
51  cImageConverter(const IStreamType& oType);
52  QImage convert(const ISample& oSample);
53 
54  private:
55  tStreamImageFormat m_sInputFormat;
56  tConversionFormat m_sOutputFormat;
57 };
58 
59 inline tResult script_error_to_result(const QJSValue& oScriptResult)
60 {
61  if (oScriptResult.isError())
62  {
63  RETURN_ERROR_DESC(ERR_FAILED, "Uncaught script exception at %s:%u: %s",
64  oScriptResult.property("fileName").toString().toLocal8Bit().data(),
65  oScriptResult.property("lineNumber").toInt(),
66  oScriptResult.toString().toLocal8Bit().data());
67  }
68  else
69  {
70  RETURN_ERROR_DESC(ERR_FAILED, "Uncaught script exception: %s",
71  oScriptResult.toString().toLocal8Bit().data());
72  }
73 }
74 
75 class cSyncSignalRecievers: public QObject
76 {
77  Q_OBJECT
78 
79  public:
80  Q_INVOKABLE void connect(QJSValue oReciever)
81  {
82  m_oRecievers.push_back(oReciever);
83  }
84 
85  template <typename ...Arguments>
86  tResult call(Arguments&& ... arguments)
87  {
88  QJSValueList oJSArgs{std::forward<Arguments>(arguments)...};
89  for (auto& oReciever: m_oRecievers)
90  {
91  auto oScriptResult = oReciever.call(oJSArgs);
92  if (!oScriptResult.isNull() && !oScriptResult.isUndefined())
93  {
94  return script_error_to_result(oScriptResult);
95  }
96  }
97 
99  }
100 
101  bool isConnected() const
102  {
103  return !m_oRecievers.empty();
104  }
105 
106  private:
107  std::vector<QJSValue> m_oRecievers;
108 };
110 
127 class cScriptReader: public QObject
128 {
129  Q_OBJECT
130 
131  public:
133  cScriptReader(cDynamicSampleReader* pReader, QJSEngine& oEngine);
134  tResult Check();
136 
145  Q_INVOKABLE QVariant getNextSample();
146 
156  Q_INVOKABLE QVariant getLastSample();
157 
166  Q_INVOKABLE void requestSamples(const QString& strSubStream);
167 
172  Q_INVOKABLE void cancelRequest(const QString& strSubStream);
173 
175 #ifdef DOXYGEN
176  signals:
185  void streamTypeChanged(QObject* type);
186 
198  void trigger(qint64 timestamp);
199 
210  void sample(const QVariant& sample);
211 #endif
212 
214  virtual tResult OnTrigger(tNanoSeconds tmTrigger) = 0;
215 
216  protected:
217  void DiscardSamples();
218  std::string GetName();
219  virtual tResult ForwardStreamTypeToScriptHandler(QObject* oType) = 0;
220  virtual std::pair<bool, bool> TriggerAndSampleCallbacks() const = 0;
221  QJSEngine& m_oEngine;
222 
223  private:
224  QVariantMap Transform(const iobject_ptr<const ISample>& pSample);
225 
226  cDynamicSampleReader* m_pReader = nullptr;
227  std::mutex m_oSubStreamsLock;
228  struct tSubStream
229  {
230  QString strName;
231  cSampleCodecFactory oCodecFactory;
232  std::unique_ptr<cImageConverter> pImageConverter;
233  };
234  bool m_bUseSampleSubStreamId = false;
235  std::unordered_map<uint32_t, tSubStream> m_oSubStreams;
236  std::unordered_map<std::string, object_ptr<IStreamingRequest>> m_oRequestedSubStreams;
238 
239  static tSubStream GetSubStream(const iobject_ptr<const IStreamType>& pType);
241 };
242 
248 class cAsyncScriptReader: public cScriptReader
249 {
250  Q_OBJECT
251 
252  public:
253  using cScriptReader::cScriptReader;
254  tResult OnTrigger(tNanoSeconds tmTrigger) override;
255 
256  signals:
257  void streamTypeChanged(QObject* type);
258  void trigger(qint64 timestamp);
259  void sample(const QVariant& sample);
260  void triggerProcessed(qint64 timestamp);
261 
262  protected:
263  tResult ForwardStreamTypeToScriptHandler(QObject* oType) override;
264  std::pair<bool, bool> TriggerAndSampleCallbacks() const override;
265 };
267 
272 class cSyncScriptReader: public cScriptReader
273 {
274  Q_OBJECT
275  Q_PROPERTY(QObject* streamTypeChanged READ getSyncStreamTypes)
276  Q_PROPERTY(QObject* trigger READ getSyncTrigger)
277  Q_PROPERTY(QObject* sample READ getSyncSample)
278 
279  public:
280  cSyncScriptReader(cDynamicSampleReader* pReader, QJSEngine& oEngine);
281  tResult OnTrigger(tNanoSeconds tmTrigger) override;
282 
283  protected:
284  tResult ForwardStreamTypeToScriptHandler(QObject* oType) override;
285  std::pair<bool, bool> TriggerAndSampleCallbacks() const override;
286 
287  private:
288  QObject* getSyncStreamTypes()
289  {
290  return &m_oSyncStreamTypeRecievers;
291  }
292 
293  QObject* getSyncTrigger()
294  {
295  return &m_oSyncTriggerRecievers;
296  }
297 
298  QObject* getSyncSample()
299  {
300  return &m_oSyncSampleRecievers;
301  }
302 
303  cSyncSignalRecievers m_oSyncStreamTypeRecievers;
304  cSyncSignalRecievers m_oSyncTriggerRecievers;
305  cSyncSignalRecievers m_oSyncSampleRecievers;
306 };
308 
309 }
310 }
311 }
#define RETURN_ERROR_DESC(_code,...)
Same as RETURN_ERROR(_error) using a printf like parameter list for detailed error description.
#define RETURN_NOERROR
Return status ERR_NOERROR, which requires the calling function's return type to be tResult.
Q_INVOKABLE void cancelRequest(const QString &strSubStream)
Cancels a request for samples from a given Substream.
void sample(const QVariant &sample)
Connect to this signal to handle Samples received via the associated Pin.
Q_INVOKABLE void requestSamples(const QString &strSubStream)
Request samples from a given Substream.
void trigger(qint64 timestamp)
Connect to this signal to handle Data In Triggers in the associated Pin.
void streamTypeChanged(QObject *type)
Connect to this signal to handle new Stream Types recieved via the associated Pin.
Q_INVOKABLE QVariant getLastSample()
Returns the last available sample.
Q_INVOKABLE QVariant getNextSample()
Returns the next available sample.
Factory class for ddl codecs for samples.
Definition: sample_codec.h:946
The ISample interface sets and retrieves properties on samples .
Definition: sample_intf.h:35
Defines access methods for the interface of a Stream Type - see also Stream Type and Stream Meta Type...
Base object pointer to realize binary compatible reference counting in interface methods.
Object pointer implementation used for reference counting on objects of type IObject.
Definition: object_ptr.h:163
Namespace for the ADTF Base SDK.
Namespace for the ADTF Media Description SDK.
WRITER_TYPE & trigger(WRITER_TYPE &oWriter)
Global function template to trigger a writers sample stream manually.
sample_reader< cDynamicSampleReaderQueue > cDynamicSampleReader
The cDynamicSampleReader will create a sample reader which will create a internal sample queue with u...
Definition: samplereader.h:813
Namespace for the ADTF Streaming SDK.
Namespace for the ADTF uCOM3 SDK.
alias namespace for the A_UTILS Library.
Namespace for entire ADTF SDK.
Copyright © Audi Electronics Venture GmbH.
Copyright © Audi Electronics Venture GmbH.
Copyright © Audi Electronics Venture GmbH.
Simple Stream Type and Stream Meta Type definition for video frames or an image sequence as a conveni...