6#include <QtCore/qcoreapplication.h>
8#include <private/qmediastoragelocation_p.h>
10#include <mm/renderer.h>
17 QByteArray devicePath = QByteArrayLiteral(
"snd:/dev/snd/") + deviceId + QByteArrayLiteral(
"?");
19 if (settings.audioSampleRate() > 0)
20 devicePath += QByteArrayLiteral(
"frate=") + QByteArray::number(settings.audioSampleRate());
22 if (settings.audioChannelCount() > 0)
23 devicePath += QByteArrayLiteral(
"nchan=") + QByteArray::number(settings.audioChannelCount());
30QQnxAudioRecorder::QQnxAudioRecorder(QObject *parent)
44 static int idCounter = 0;
46 m_connection = ConnectionUniquePtr { mmr_connect(
nullptr) };
49 qWarning(
"QQnxAudioRecorder: Unable to connect to the multimedia renderer");
55 char contextName[256];
57 std::snprintf(contextName,
sizeof contextName,
"QQnxAudioRecorder_%d_%llu",
58 m_id, QCoreApplication::applicationPid());
60 m_context = ContextUniquePtr { mmr_context_create(m_connection.get(),
61 contextName, 0, S_IRWXU|S_IRWXG|S_IRWXO) };
66 qWarning(
"QQnxAudioRecorder: Unable to create context");
84 const QString container = m_encoderSettings.preferredSuffix();
85 const QString location = QMediaStorageLocation::generateFileName(m_outputUrl.toLocalFile(),
86 QStandardPaths::MusicLocation, container);
88 m_audioId = mmr_output_attach(m_context.get(), qPrintable(location),
"file");
90 if (m_audioId == -1) {
91 qWarning(
"QQnxAudioRecorder: mmr_output_attach() for file failed");
95 configureOutputBitRate();
97 const QByteArray devicePath = buildDevicePath(m_inputDeviceId, m_encoderSettings);
99 if (mmr_input_attach(m_context.get(), devicePath.constData(),
"track") != 0) {
100 qWarning(
"QQnxAudioRecorder: mmr_input_attach() failed");
103 Q_EMIT actualLocationChanged(location);
112 mmr_input_detach(m_context.get());
113 mmr_output_detach(m_context.get(), m_audioId);
120 const int bitRate = m_encoderSettings.audioBitRate();
122 if (!isAttached() || bitRate <= 0)
126 std::snprintf(buf,
sizeof buf,
"%d", bitRate);
128 strm_dict_t *dict = strm_dict_new();
129 dict = strm_dict_set(dict,
"audio_bitrate", buf);
131 if (mmr_output_parameters(m_context.get(), m_audioId, dict) != 0)
132 qWarning(
"mmr_output_parameters: setting bitrate failed");
137 return m_context && m_audioId != -1;
142 m_inputDeviceId = id;
152 m_encoderSettings = settings;
164 if (mmr_play(m_context.get()) != 0)
165 qWarning(
"QQnxAudioRecorder: mmr_play() failed");
173 mmr_stop(m_context.get());
180 m_eventThread = std::make_unique<QQnxMediaEventThread>(m_context.get());
182 connect(m_eventThread.get(), &QQnxMediaEventThread::eventPending,
183 this, &QQnxAudioRecorder::readEvents);
185 m_eventThread->setObjectName(QStringLiteral(
"MmrAudioEventThread-") + QString::number(m_id));
186 m_eventThread->start();
192 m_eventThread.reset();
197 while (
const mmr_event_t *event = mmr_event_get(m_context.get())) {
198 if (event->type == MMR_EVENT_NONE)
201 switch (event->type) {
202 case MMR_EVENT_STATUS:
203 handleMmEventStatus(event);
205 case MMR_EVENT_STATE:
206 handleMmEventState(event);
208 case MMR_EVENT_ERROR:
209 handleMmEventError(event);
211 case MMR_EVENT_METADATA:
213 case MMR_EVENT_OVERFLOW:
214 case MMR_EVENT_WARNING:
215 case MMR_EVENT_PLAYLIST:
216 case MMR_EVENT_INPUT:
217 case MMR_EVENT_OUTPUT:
218 case MMR_EVENT_CTXTPAR:
219 case MMR_EVENT_TRKPAR:
220 case MMR_EVENT_OTHER:
226 m_eventThread->signalRead();
231 if (!event || event->type != MMR_EVENT_STATUS)
237 const QByteArray valueBa(event->pos_str);
240 const qint64 duration = valueBa.toLongLong(&ok);
243 qCritical(
"Could not parse duration from '%s'", valueBa.constData());
245 durationChanged(duration);
250 if (!event || event->type != MMR_EVENT_STATE)
253 switch (event->state) {
254 case MMR_STATE_DESTROYED:
256 case MMR_STATE_STOPPED:
257 Q_EMIT stateChanged(QMediaRecorder::StoppedState);
259 case MMR_STATE_PLAYING:
260 Q_EMIT stateChanged(QMediaRecorder::RecordingState);
275 if (event->details.error.info.error_code == MMR_ERROR_NONE) {
277 Q_EMIT stateChanged(QMediaRecorder::StoppedState);
284#include "moc_qqnxaudiorecorder_p.cpp"
void setInputDeviceId(const QByteArray &id)
void setOutputUrl(const QUrl &url)
void setMediaEncoderSettings(const QMediaEncoderSettings &settings)
static QByteArray buildDevicePath(const QByteArray &deviceId, const QMediaEncoderSettings &settings)