Torc  0.1
torcomxport.cpp
Go to the documentation of this file.
1 /* Class TorcOMXPort
2 *
3 * This file is part of the Torc project.
4 *
5 * Copyright (C) Mark Kendall 2013-18
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 // Qt
24 #include <QElapsedTimer>
25 
26 // Torc
27 #include "torclogging.h"
28 #include "torcomxport.h"
29 
30 TorcOMXPort::TorcOMXPort(TorcOMXComponent *Parent, OMX_HANDLETYPE Handle, OMX_U32 Port, OMX_INDEXTYPE Domain)
31  : m_owner(nullptr),
32  m_parent(Parent),
33  m_handle(Handle),
34  m_port(Port),
35  m_domain(Domain),
36  m_lock(QMutex::NonRecursive),
37  m_wait(),
38  m_buffers(),
39  m_availableBuffers(),
40  m_alignment(16)
41 {
42 }
43 
45 {
47 }
48 
49 OMX_U32 TorcOMXPort::GetPort(void)
50 {
51  return m_port;
52 }
53 
54 OMX_INDEXTYPE TorcOMXPort::GetDomain(void)
55 {
56  return m_domain;
57 }
58 
59 OMX_ERRORTYPE TorcOMXPort::EnablePort(bool Enable, bool Wait /*=true*/)
60 {
61  if (!m_handle || !m_parent)
62  return OMX_ErrorUndefined;
63 
64  OMX_PARAM_PORTDEFINITIONTYPE portdefinition;
65  OMX_INITSTRUCTURE(portdefinition);
66  portdefinition.nPortIndex = m_port;
67 
68  OMX_ERRORTYPE error = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portdefinition);
69  OMX_CHECK(error, m_parent->GetName(), QStringLiteral("Failed to get port definition"));
70 
71  if (portdefinition.bEnabled == OMX_FALSE && Enable)
72  {
73  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("%1: Enabling port %2").arg(m_parent->GetName()).arg(m_port));
74  error = OMX_SendCommand(m_handle, OMX_CommandPortEnable, m_port, nullptr);
75  OMX_CHECK(error, m_parent->GetName(), QStringLiteral("Failed to send command"));
76  if (Wait)
77  return m_parent->WaitForResponse(OMX_CommandPortEnable, m_port, 1000);
78  else
79  return OMX_ErrorNone;
80  }
81  else if (portdefinition.bEnabled == OMX_TRUE && !Enable)
82  {
83  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("%1: Disabling port %2").arg(m_parent->GetName()).arg(m_port));
84  error = OMX_SendCommand(m_handle, OMX_CommandPortDisable, m_port, nullptr);
85  OMX_CHECK(error, m_parent->GetName(), QStringLiteral("Failed to send command"));
86  if (Wait)
87  return m_parent->WaitForResponse(OMX_CommandPortDisable, m_port, 1000);
88  else
89  return OMX_ErrorNone;
90  }
91 
92  return OMX_ErrorNone;
93 }
94 
96 {
97  m_lock.lock();
98  OMX_U32 result = m_availableBuffers.size();
99  m_lock.unlock();
100  return result;
101 }
102 
104 {
105  m_lock.lock();
106  OMX_U32 result = m_buffers.size() - m_availableBuffers.size();
107  m_lock.unlock();
108  return result;
109 }
110 
111 OMX_ERRORTYPE TorcOMXPort::CreateBuffers(QObject *Owner /*=nullptr*/)
112 {
113  if (!m_handle)
114  return OMX_ErrorUndefined;
115 
116  QMutexLocker locker(&m_lock);
117 
118  m_owner = Owner;
119  if (m_owner)
120  connect(this, SIGNAL(BufferReady(OMX_BUFFERHEADERTYPE*, quint64)), m_owner, SLOT(BufferReady(OMX_BUFFERHEADERTYPE*, quint64)), Qt::QueuedConnection); // clazy:exclude=old-style-connect
121 
122  OMX_PARAM_PORTDEFINITIONTYPE portdefinition;
123  OMX_INITSTRUCTURE(portdefinition);
124  portdefinition.nPortIndex = m_port;
125 
126  OMX_ERRORTYPE error = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portdefinition);
127  OMX_CHECK(error, m_parent->GetName(), QStringLiteral("Failed to get port definition"));
128 
129  m_alignment = portdefinition.nBufferAlignment;
130 
131  for (OMX_U32 i = 0; i < portdefinition.nBufferCountActual; ++i)
132  {
133  OMX_BUFFERHEADERTYPE *buffer = nullptr;
134  error = OMX_AllocateBuffer(m_handle, &buffer, m_port, nullptr, portdefinition.nBufferSize);
135  if (OMX_ErrorNone != error)
136  {
137  OMX_ERROR(error, m_parent->GetName(), QStringLiteral("Failed to allocate buffer"));
138  return error;
139  }
140 
141  buffer->pAppPrivate = (void*)this;
142  buffer->nFilledLen = 0;
143  buffer->nOffset = 0;
144  buffer->nInputPortIndex = m_port;
145 
146  m_buffers.append(buffer);
147  m_availableBuffers.enqueue(buffer);
148  }
149 
150  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("%1: Created %2 %3byte buffers")
151  .arg(m_parent->GetName()).arg(portdefinition.nBufferCountActual).arg(portdefinition.nBufferSize));
152 
153  return OMX_ErrorNone;
154 }
155 
156 OMX_ERRORTYPE TorcOMXPort::DestroyBuffers(void)
157 {
158  if (!m_handle || !m_parent)
159  return OMX_ErrorUndefined;
160 
161  if (m_owner)
162  {
163  disconnect(this, SIGNAL(BufferReady(OMX_BUFFERHEADERTYPE*, quint64)), m_owner, SLOT(BufferReady(OMX_BUFFERHEADERTYPE*, quint64))); // clazy:exclude=old-style-connect
164  m_owner = nullptr;
165  }
166 
167  (void)EnablePort(false);
168 
169  {
170  QMutexLocker locker(&m_lock);
171  for (int i = 0; i < m_buffers.size(); ++i)
172  {
173  OMX_ERRORTYPE error = OMX_FreeBuffer(m_handle, m_port, m_buffers.at(i));
174  OMX_CHECKX(error, m_parent->GetName(), QStringLiteral("Failed to free buffer"));
175  }
176 
177  m_buffers.clear();
178  m_availableBuffers.clear();
179  m_alignment = 0;
180  }
181 
182  return OMX_ErrorNone;
183 }
184 
185 OMX_ERRORTYPE TorcOMXPort::Flush(void)
186 {
187  if (!m_handle || !m_parent)
188  return OMX_ErrorUndefined;
189 
190  QMutexLocker locker(&m_lock);
191 
192  OMX_ERRORTYPE error = OMX_SendCommand(m_handle, OMX_CommandFlush, m_port, nullptr);
193  OMX_CHECK(error, m_parent->GetName(), QStringLiteral("Failed to send command"));
194 
195  return OMX_ErrorNone;
196 }
197 
198 OMX_ERRORTYPE TorcOMXPort::MakeAvailable(OMX_BUFFERHEADERTYPE *Buffer)
199 {
200  m_lock.lock();
201  if (!m_buffers.contains(Buffer))
202  LOG(VB_GENERAL, LOG_WARNING, QStringLiteral("%1: Unknown buffer").arg(m_parent->GetName()));
203  m_availableBuffers.enqueue(Buffer);
204  m_lock.unlock();
205 
206  m_wait.wakeAll();
207  emit BufferReady(Buffer, (quint64)m_domain);
208  return OMX_ErrorNone;
209 }
210 
211 OMX_BUFFERHEADERTYPE* TorcOMXPort::GetBuffer(OMX_S32 Timeout)
212 {
213  OMX_BUFFERHEADERTYPE* result = nullptr;
214 
215  m_lock.lock();
216 
217  QElapsedTimer timer;
218  timer.start();
219 
220  while (timer.elapsed() < Timeout)
221  {
222  if (!m_availableBuffers.isEmpty())
223  {
224  result = m_availableBuffers.dequeue();
225  m_lock.unlock();
226  return result;
227  }
228 
229  m_wait.wait(&m_lock, 10);
230  }
231 
232  m_lock.unlock();
233  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("%1: Timed out waiting for available buffer").arg(m_parent->GetName()));
234  return result;
235 }
OMX_ERRORTYPE Flush(void)
OMX_U32 GetInUseBuffers(void)
OMX_ERRORTYPE DestroyBuffers(void)
QString GetName(void)
OMX_ERRORTYPE MakeAvailable(OMX_BUFFERHEADERTYPE *Buffer)
TorcOMXPort(TorcOMXComponent *Parent, OMX_HANDLETYPE Handle, OMX_U32 Port, OMX_INDEXTYPE Domain)
Definition: torcomxport.cpp:30
OMX_U32 GetAvailableBuffers(void)
Definition: torcomxport.cpp:95
OMX_ERRORTYPE CreateBuffers(QObject *Owner=nullptr)
OMX_U32 GetPort(void)
Definition: torcomxport.cpp:49
OMX_ERRORTYPE EnablePort(bool Enable, bool Wait=true)
Definition: torcomxport.cpp:59
#define OMX_CHECKX(Error, Component, Message)
Definition: torcomxcore.h:46
#define OMX_ERROR(Error, Component, Message)
Definition: torcomxcore.h:42
OMX_INDEXTYPE GetDomain(void)
Definition: torcomxport.cpp:54
#define OMX_CHECK(Error, Component, Message)
Definition: torcomxcore.h:44
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: torclogging.h:20
void BufferReady(OMX_BUFFERHEADERTYPE *Buffer, quint64 Type)
OMX_BUFFERHEADERTYPE * GetBuffer(OMX_S32 Timeout)
OMX_ERRORTYPE WaitForResponse(OMX_U32 Command, OMX_U32 Data2, OMX_S32 Timeout)
#define OMX_INITSTRUCTURE(Struct)
Definition: torcomxcore.h:28