media_codec.cpp 8.96 KB
Newer Older
1
/*
2
 *  Copyright (C) 2015-2019 Savoir-faire Linux Inc.
3
 *
4 5 6 7 8 9 10 11 12 13 14 15 16 17
 *  Author: Eloi BAIL <eloi.bail@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
19 20
 */

21
#include "libav_deps.h" // MUST BE INCLUDED FIRST
22
#include "media_codec.h"
23
#include "account_const.h"
24

Adrien Béraud's avatar
Adrien Béraud committed
25
#include "string_utils.h"
26
#include "logger.h"
Adrien Béraud's avatar
Adrien Béraud committed
27 28

#include <string>
29 30
#include <sstream>

Adrien Béraud's avatar
Adrien Béraud committed
31
namespace jami {
32

33
static unsigned
34 35 36 37 38 39 40 41 42
generateId()
{
    static unsigned id = 0;
    return ++id;
}

/*
 * SystemCodecInfo
 */
Adrien Béraud's avatar
Adrien Béraud committed
43 44
SystemCodecInfo::SystemCodecInfo(unsigned avcodecId, const std::string& name,
                                 const std::string& libName,
45
                                 MediaType mediaType, CodecType codecType,
46 47 48 49
                                 unsigned bitrate,
                                 unsigned payloadType,
                                 unsigned minQuality,
                                 unsigned maxQuality)
50 51 52 53 54 55 56 57
    : id(generateId())
    , avcodecId(avcodecId)
    , name(name)
    , libName(libName)
    , codecType(codecType)
    , mediaType(mediaType)
    , payloadType(payloadType)
    , bitrate(bitrate)
58 59
    , minQuality(minQuality)
    , maxQuality(maxQuality)
60 61 62 63 64 65 66 67 68
{}

SystemCodecInfo::~SystemCodecInfo()
{}

/*
 * SystemAudioCodecInfo
 */
SystemAudioCodecInfo::SystemAudioCodecInfo(unsigned m_avcodecId,
Adrien Béraud's avatar
Adrien Béraud committed
69 70
                                           const std::string& m_name,
                                           const std::string& m_libName,
71 72 73 74 75
                                           CodecType m_type, unsigned m_bitrate,
                                           unsigned m_sampleRate,
                                           unsigned m_nbChannels,
                                           unsigned m_payloadType)
    : SystemCodecInfo(m_avcodecId, m_name, m_libName, MEDIA_AUDIO, m_type, m_bitrate, m_payloadType)
76
    , audioformat{m_sampleRate, m_nbChannels}
77 78 79 80 81 82
{}

SystemAudioCodecInfo::~SystemAudioCodecInfo()
{}


83
std::map<std::string, std::string>
84 85
SystemAudioCodecInfo::getCodecSpecifications()
{
86 87 88
    return {
        {DRing::Account::ConfProperties::CodecInfo::NAME, name},
        {DRing::Account::ConfProperties::CodecInfo::TYPE, (mediaType & MEDIA_AUDIO ? "AUDIO" : "VIDEO")},
89 90 91
        {DRing::Account::ConfProperties::CodecInfo::BITRATE, std::to_string(bitrate)},
        {DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE, std::to_string(audioformat.sample_rate)},
        {DRing::Account::ConfProperties::CodecInfo::CHANNEL_NUMBER, std::to_string(audioformat.nb_channels)}
92
        };
93 94 95 96 97 98
}

/*
 * SystemVideoCodecInfo
 */
SystemVideoCodecInfo::SystemVideoCodecInfo(unsigned m_avcodecId,
Adrien Béraud's avatar
Adrien Béraud committed
99 100
                                           const std::string& m_name,
                                           const std::string& m_libName,
101
                                           CodecType m_type,
102
                                           unsigned m_bitrate,
103 104
                                           unsigned m_minQuality,
                                           unsigned m_maxQuality,
105 106 107
                                           unsigned m_payloadType,
                                           unsigned m_frameRate,
                                           unsigned m_profileId)
108
    : SystemCodecInfo(m_avcodecId, m_name, m_libName, MEDIA_VIDEO,
109
                      m_type, m_bitrate, m_payloadType, m_minQuality, m_maxQuality)
110
    , frameRate(m_frameRate), profileId(m_profileId)
111 112 113 114 115
{}

SystemVideoCodecInfo::~SystemVideoCodecInfo()
{}

116
std::map<std::string, std::string>
117 118
SystemVideoCodecInfo::getCodecSpecifications()
{
119 120 121
    return {
        {DRing::Account::ConfProperties::CodecInfo::NAME, name},
        {DRing::Account::ConfProperties::CodecInfo::TYPE, (mediaType & MEDIA_AUDIO ? "AUDIO" : "VIDEO")},
122 123 124 125
        {DRing::Account::ConfProperties::CodecInfo::BITRATE, std::to_string(bitrate)},
        {DRing::Account::ConfProperties::CodecInfo::FRAME_RATE, std::to_string(frameRate)},
        {DRing::Account::ConfProperties::CodecInfo::MIN_BITRATE, std::to_string(minBitrate)},
        {DRing::Account::ConfProperties::CodecInfo::MAX_BITRATE, std::to_string(maxBitrate)},
126
    };
127 128
}

129
AccountCodecInfo::AccountCodecInfo(const SystemCodecInfo& sysCodecInfo) noexcept
130 131 132
    : systemCodecInfo(sysCodecInfo)
    , payloadType(sysCodecInfo.payloadType)
    , bitrate(sysCodecInfo.bitrate)
133 134 135
{
    if (sysCodecInfo.minQuality != SystemCodecInfo::DEFAULT_NO_QUALITY)
        quality = SystemCodecInfo::DEFAULT_CODEC_QUALITY;
Éloi Bail's avatar
Éloi Bail committed
136 137
    else
        quality = SystemCodecInfo::DEFAULT_NO_QUALITY;
138
}
139

140 141 142 143 144 145 146 147 148 149 150 151
AccountCodecInfo&
AccountCodecInfo::operator=(const AccountCodecInfo& o)
{
    if (&systemCodecInfo != &o.systemCodecInfo)
        throw std::runtime_error("cannot assign codec info object pointing to another codec.");
    order = o.order;
    isActive = o.isActive;
    payloadType = o.payloadType;
    bitrate = o.bitrate;
    quality = o.quality;
    return *this;
}
152 153 154

AccountAudioCodecInfo::AccountAudioCodecInfo(const SystemAudioCodecInfo& sysCodecInfo)
    : AccountCodecInfo(sysCodecInfo)
155
    , audioformat{sysCodecInfo.audioformat}
156 157
{}

158 159 160 161 162 163
std::map<std::string, std::string>
AccountAudioCodecInfo::getCodecSpecifications()
{
    return {
        {DRing::Account::ConfProperties::CodecInfo::NAME, systemCodecInfo.name},
        {DRing::Account::ConfProperties::CodecInfo::TYPE, (systemCodecInfo.mediaType & MEDIA_AUDIO ? "AUDIO" : "VIDEO")},
164 165 166
        {DRing::Account::ConfProperties::CodecInfo::BITRATE, std::to_string(bitrate)},
        {DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE, std::to_string(audioformat.sample_rate)},
        {DRing::Account::ConfProperties::CodecInfo::CHANNEL_NUMBER, std::to_string(audioformat.nb_channels)}
167
    };
168 169
}

170 171 172
void
AccountAudioCodecInfo::setCodecSpecifications(const std::map<std::string, std::string>& details)
{
Adrien Béraud's avatar
Adrien Béraud committed
173
    decltype(bitrate) tmp_bitrate = jami::stoi(details.at(DRing::Account::ConfProperties::CodecInfo::BITRATE));
174
    decltype(audioformat) tmp_audioformat = audioformat;
Adrien Béraud's avatar
Adrien Béraud committed
175
    tmp_audioformat.sample_rate = jami::stoi(details.at(DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE));
176

177 178 179
    // copy back if no exception was raised
    bitrate = tmp_bitrate;
    audioformat = tmp_audioformat;
180 181
}

182 183 184 185 186 187
bool
AccountAudioCodecInfo::isPCMG722() const
{
    return systemCodecInfo.avcodecId == AV_CODEC_ID_ADPCM_G722;
}

188 189 190 191 192 193
AccountVideoCodecInfo::AccountVideoCodecInfo(const SystemVideoCodecInfo& sysCodecInfo)
    : AccountCodecInfo(sysCodecInfo)
    , frameRate(sysCodecInfo.frameRate)
    , profileId(sysCodecInfo.profileId)
{}

194 195 196 197 198 199
std::map<std::string, std::string>
AccountVideoCodecInfo::getCodecSpecifications()
{
    return {
        {DRing::Account::ConfProperties::CodecInfo::NAME, systemCodecInfo.name},
        {DRing::Account::ConfProperties::CodecInfo::TYPE, (systemCodecInfo.mediaType & MEDIA_AUDIO ? "AUDIO" : "VIDEO")},
200 201 202 203 204 205 206
        {DRing::Account::ConfProperties::CodecInfo::BITRATE, std::to_string(bitrate)},
        {DRing::Account::ConfProperties::CodecInfo::MAX_BITRATE, std::to_string(systemCodecInfo.maxBitrate)},
        {DRing::Account::ConfProperties::CodecInfo::MIN_BITRATE, std::to_string(systemCodecInfo.minBitrate)},
        {DRing::Account::ConfProperties::CodecInfo::QUALITY, std::to_string(quality)},
        {DRing::Account::ConfProperties::CodecInfo::MAX_QUALITY, std::to_string(systemCodecInfo.maxQuality)},
        {DRing::Account::ConfProperties::CodecInfo::MIN_QUALITY, std::to_string(systemCodecInfo.minQuality)},
        {DRing::Account::ConfProperties::CodecInfo::FRAME_RATE, std::to_string(frameRate)},
207
        {DRing::Account::ConfProperties::CodecInfo::AUTO_QUALITY_ENABLED, bool_to_str(isAutoQualityEnabled)}
208
    };
209 210
}

211 212 213
void
AccountVideoCodecInfo::setCodecSpecifications(const std::map<std::string, std::string>& details)
{
214 215
    auto copy = *this;

216 217
    auto it = details.find(DRing::Account::ConfProperties::CodecInfo::BITRATE);
    if (it != details.end())
Adrien Béraud's avatar
Adrien Béraud committed
218
        copy.bitrate = jami::stoi(it->second);
219 220 221

    it = details.find(DRing::Account::ConfProperties::CodecInfo::FRAME_RATE);
    if (it != details.end())
Adrien Béraud's avatar
Adrien Béraud committed
222
        copy.frameRate = jami::stoi(it->second);
223 224 225

    it = details.find(DRing::Account::ConfProperties::CodecInfo::QUALITY);
    if (it != details.end())
Adrien Béraud's avatar
Adrien Béraud committed
226
        copy.quality = jami::stoi(it->second);
227 228 229

    it = details.find(DRing::Account::ConfProperties::CodecInfo::AUTO_QUALITY_ENABLED);
    if (it != details.end())
230
        copy.isAutoQualityEnabled = (it->second == TRUE_STR) ? true : false;
231

232 233 234
    // copy back if no exception was raised
    *this = std::move(copy);
}
235

Adrien Béraud's avatar
Adrien Béraud committed
236
} // namespace jami