media_codec.cpp 8.96 KB
Newer Older
Eloi Bail's avatar
Eloi Bail committed
1
/*
Sébastien Blin's avatar
Sébastien Blin committed
2
 *  Copyright (C) 2015-2019 Savoir-faire Linux Inc.
Guillaume Roguez's avatar
Guillaume Roguez committed
3
 *
Eloi Bail's avatar
Eloi Bail committed
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
Guillaume Roguez's avatar
Guillaume Roguez committed
18
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
Eloi Bail's avatar
Eloi Bail committed
19
20
 */

21
#include "libav_deps.h" // MUST BE INCLUDED FIRST
Eloi Bail's avatar
Eloi Bail committed
22
#include "media_codec.h"
Eloi Bail's avatar
Eloi Bail committed
23
#include "account_const.h"
Eloi Bail's avatar
Eloi Bail committed
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>
Eloi Bail's avatar
Eloi Bail committed
29
30
#include <sstream>

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

33
static unsigned
Eloi Bail's avatar
Eloi Bail committed
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,
Eloi Bail's avatar
Eloi Bail committed
45
                                 MediaType mediaType, CodecType codecType,
46
47
48
49
                                 unsigned bitrate,
                                 unsigned payloadType,
                                 unsigned minQuality,
                                 unsigned maxQuality)
Eloi Bail's avatar
Eloi Bail committed
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)
Eloi Bail's avatar
Eloi Bail committed
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,
Eloi Bail's avatar
Eloi Bail committed
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}
Eloi Bail's avatar
Eloi Bail committed
77
78
79
80
81
82
{}

SystemAudioCodecInfo::~SystemAudioCodecInfo()
{}


Eloi Bail's avatar
Eloi Bail committed
83
std::map<std::string, std::string>
Eloi Bail's avatar
Eloi Bail committed
84
85
SystemAudioCodecInfo::getCodecSpecifications()
{
Eloi Bail's avatar
Eloi Bail committed
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)}
Eloi Bail's avatar
Eloi Bail committed
92
        };
Eloi Bail's avatar
Eloi Bail committed
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,
Eloi Bail's avatar
Eloi Bail committed
101
                                           CodecType m_type,
102
                                           unsigned m_bitrate,
103
104
                                           unsigned m_minQuality,
                                           unsigned m_maxQuality,
Eloi Bail's avatar
Eloi Bail committed
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)
Eloi Bail's avatar
Eloi Bail committed
110
    , frameRate(m_frameRate), profileId(m_profileId)
Eloi Bail's avatar
Eloi Bail committed
111
112
113
114
115
{}

SystemVideoCodecInfo::~SystemVideoCodecInfo()
{}

Eloi Bail's avatar
Eloi Bail committed
116
std::map<std::string, std::string>
Eloi Bail's avatar
Eloi Bail committed
117
118
SystemVideoCodecInfo::getCodecSpecifications()
{
Eloi Bail's avatar
Eloi Bail committed
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
    };
Eloi Bail's avatar
Eloi Bail committed
127
128
}

129
AccountCodecInfo::AccountCodecInfo(const SystemCodecInfo& sysCodecInfo) noexcept
Eloi Bail's avatar
Eloi Bail committed
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;
Eloi Bail's avatar
Eloi Bail committed
136
137
    else
        quality = SystemCodecInfo::DEFAULT_NO_QUALITY;
138
}
Eloi Bail's avatar
Eloi Bail committed
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;
}
Eloi Bail's avatar
Eloi Bail committed
152
153
154

AccountAudioCodecInfo::AccountAudioCodecInfo(const SystemAudioCodecInfo& sysCodecInfo)
    : AccountCodecInfo(sysCodecInfo)
155
    , audioformat{sysCodecInfo.audioformat}
Eloi Bail's avatar
Eloi Bail committed
156
157
{}

Eloi Bail's avatar
Eloi Bail committed
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
    };
Eloi Bail's avatar
Eloi Bail committed
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;
}

Eloi Bail's avatar
Eloi Bail committed
188
189
190
191
192
193
AccountVideoCodecInfo::AccountVideoCodecInfo(const SystemVideoCodecInfo& sysCodecInfo)
    : AccountCodecInfo(sysCodecInfo)
    , frameRate(sysCodecInfo.frameRate)
    , profileId(sysCodecInfo.profileId)
{}

Eloi Bail's avatar
Eloi Bail committed
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
    };
Eloi Bail's avatar
Eloi Bail committed
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);
}
Eloi Bail's avatar
Eloi Bail committed
235

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