File indexing completed on 2025-01-19 06:44:37
0001 /* 0002 * BluezQt - Asynchronous Bluez wrapper library 0003 * 0004 * SPDX-FileCopyrightText: 2018 Manuel Weichselbaumer <mincequi@web.de> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "mediaendpoint.h" 0010 #include "a2dp-codecs.h" 0011 #include "mediaendpoint_p.h" 0012 0013 namespace BluezQt 0014 { 0015 MediaEndpoint::MediaEndpoint(const Configuration &configuration, QObject *parent) 0016 : QObject(parent) 0017 , d(new MediaEndpointPrivate(configuration)) 0018 { 0019 } 0020 0021 MediaEndpoint::~MediaEndpoint() = default; 0022 0023 QDBusObjectPath MediaEndpoint::objectPath() const 0024 { 0025 return d->m_objectPath; 0026 } 0027 0028 const QVariantMap &MediaEndpoint::properties() const 0029 { 0030 return d->m_properties; 0031 } 0032 0033 void MediaEndpoint::setConfiguration(const QString &transportObjectPath, const QVariantMap &properties) 0034 { 0035 Q_EMIT configurationSet(transportObjectPath, properties); 0036 } 0037 0038 void MediaEndpoint::selectConfiguration(const QByteArray &capabilities, const Request<QByteArray> &request) 0039 { 0040 switch (d->m_configuration.codec) { 0041 case MediaEndpoint::Codec::Sbc: { 0042 if (capabilities.size() != sizeof(a2dp_sbc_t)) { 0043 Q_EMIT configurationSelected(capabilities, QByteArray()); 0044 request.reject(); 0045 return; 0046 } 0047 0048 a2dp_sbc_t caps = *reinterpret_cast<const a2dp_sbc_t *>(capabilities.constData()); 0049 if (caps.frequency & SBC_SAMPLING_FREQ_44100) { 0050 caps.frequency = SBC_SAMPLING_FREQ_44100; 0051 } else if (caps.frequency & SBC_SAMPLING_FREQ_48000) { 0052 caps.frequency = SBC_SAMPLING_FREQ_48000; 0053 } else { 0054 break; 0055 } 0056 0057 if (caps.channel_mode & SBC_CHANNEL_MODE_STEREO) { 0058 caps.channel_mode = SBC_CHANNEL_MODE_STEREO; 0059 } else if (caps.channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO) { 0060 caps.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO; 0061 } else { 0062 break; 0063 } 0064 0065 if (caps.block_length & SBC_BLOCK_LENGTH_16) { 0066 caps.block_length = SBC_BLOCK_LENGTH_16; 0067 } else if (caps.block_length & SBC_BLOCK_LENGTH_12) { 0068 caps.block_length = SBC_BLOCK_LENGTH_12; 0069 } else if (caps.block_length & SBC_BLOCK_LENGTH_8) { 0070 caps.block_length = SBC_BLOCK_LENGTH_8; 0071 } else if (caps.block_length & SBC_BLOCK_LENGTH_4) { 0072 caps.block_length = SBC_BLOCK_LENGTH_4; 0073 } else { 0074 break; 0075 } 0076 0077 if (caps.subbands & SBC_SUBBANDS_8) { 0078 caps.subbands = SBC_SUBBANDS_8; 0079 } else if (caps.subbands & SBC_SUBBANDS_4) { 0080 caps.subbands = SBC_SUBBANDS_4; 0081 } else { 0082 break; 0083 } 0084 0085 if (caps.allocation_method & SBC_ALLOCATION_LOUDNESS) { 0086 caps.allocation_method = SBC_ALLOCATION_LOUDNESS; 0087 } else if (caps.allocation_method & SBC_ALLOCATION_SNR) { 0088 caps.allocation_method = SBC_ALLOCATION_SNR; 0089 } else { 0090 break; 0091 } 0092 0093 caps.min_bitpool = 2; 0094 caps.max_bitpool = 53; 0095 0096 const QByteArray configuration(reinterpret_cast<const char *>(&caps), sizeof(caps)); 0097 Q_EMIT configurationSelected(capabilities, configuration); 0098 request.accept(configuration); 0099 return; 0100 0101 break; 0102 } 0103 case MediaEndpoint::Codec::Aac: 0104 if (capabilities.size() != sizeof(a2dp_aac_t)) { 0105 Q_EMIT configurationSelected(capabilities, QByteArray()); 0106 request.reject(); 0107 return; 0108 } 0109 0110 // TODO: implement AAC. However selectConfiguration seems not to be used by iOS nor Android. 0111 Q_EMIT configurationSelected(capabilities, QByteArray()); 0112 request.reject(); 0113 return; 0114 0115 break; 0116 } 0117 0118 Q_EMIT configurationSelected(capabilities, QByteArray()); 0119 request.reject(); 0120 } 0121 0122 void MediaEndpoint::clearConfiguration(const QString &transportObjectPath) 0123 { 0124 Q_EMIT configurationCleared(transportObjectPath); 0125 } 0126 0127 void MediaEndpoint::release() 0128 { 0129 } 0130 0131 } // namespace BluezQt 0132 0133 #include "moc_mediaendpoint.cpp"