Skip to content
Snippets Groups Projects
Commit aff0eda4 authored by Philippe Gorley's avatar Philippe Gorley Committed by Sébastien Blin
Browse files

encoder: allow config to override some settings


MediaEncoder sets some of AVCodecContext's fields. Allow the
configuration file to override these fields.

Change-Id: Ic44da217344aca2da0634e81bf247d4a21bb9510
Reviewed-by: default avatarSébastien Blin <sebastien.blin@savoirfairelinux.com>
parent 19442e3b
Branches
No related tags found
No related merge requests found
...@@ -277,7 +277,7 @@ MediaEncoder::addStream(const SystemCodecInfo& systemCodecInfo, std::string para ...@@ -277,7 +277,7 @@ MediaEncoder::addStream(const SystemCodecInfo& systemCodecInfo, std::string para
currentStreamIdx_ = stream->index; currentStreamIdx_ = stream->index;
readConfig(&options_, outputCodec->name); readConfig(&options_, encoderCtx);
if (avcodec_open2(encoderCtx, outputCodec, &options_) < 0) if (avcodec_open2(encoderCtx, outputCodec, &options_) < 0)
throw MediaEncoderException("Could not open encoder"); throw MediaEncoderException("Could not open encoder");
...@@ -662,9 +662,10 @@ MediaEncoder::getStream(const std::string& name, int streamIdx) const ...@@ -662,9 +662,10 @@ MediaEncoder::getStream(const std::string& name, int streamIdx) const
} }
void void
MediaEncoder::readConfig(AVDictionary** dict, const std::string& encoder) MediaEncoder::readConfig(AVDictionary** dict, AVCodecContext* encoderCtx)
{ {
std::string path = fileutils::get_config_dir() + DIR_SEPARATOR_STR + "encoder.json"; std::string path = fileutils::get_config_dir() + DIR_SEPARATOR_STR + "encoder.json";
std::string name = encoderCtx->codec->name;
if (fileutils::isFile(path)) { if (fileutils::isFile(path)) {
try { try {
Json::Value root; Json::Value root;
...@@ -674,13 +675,13 @@ MediaEncoder::readConfig(AVDictionary** dict, const std::string& encoder) ...@@ -674,13 +675,13 @@ MediaEncoder::readConfig(AVDictionary** dict, const std::string& encoder)
RING_ERR() << "Invalid encoder configuration: root is not an object"; RING_ERR() << "Invalid encoder configuration: root is not an object";
return; return;
} }
const auto& config = root[encoder]; const auto& config = root[name];
if (config.isNull()) { if (config.isNull()) {
RING_WARN() << "Encoder '" << encoder << "' not found in configuration file"; RING_WARN() << "Encoder '" << name << "' not found in configuration file";
return; return;
} }
if (!config.isObject()) { if (!config.isObject()) {
RING_ERR() << "Invalid encoder configuration: '" << encoder << "' is not an object"; RING_ERR() << "Invalid encoder configuration: '" << name << "' is not an object";
return; return;
} }
// If users want to change these, they should use the settings page. // If users want to change these, they should use the settings page.
...@@ -689,14 +690,32 @@ MediaEncoder::readConfig(AVDictionary** dict, const std::string& encoder) ...@@ -689,14 +690,32 @@ MediaEncoder::readConfig(AVDictionary** dict, const std::string& encoder)
Json::Value v = *it; Json::Value v = *it;
if (!it.key().isConvertibleTo(Json::ValueType::stringValue) if (!it.key().isConvertibleTo(Json::ValueType::stringValue)
|| !v.isConvertibleTo(Json::ValueType::stringValue)) { || !v.isConvertibleTo(Json::ValueType::stringValue)) {
RING_ERR() << "Invalid configuration for '" << encoder << "'"; RING_ERR() << "Invalid configuration for '" << name << "'";
return; return;
} }
const auto& key = it.key().asString(); const auto& key = it.key().asString();
const auto& value = v.asString(); const auto& value = v.asString();
// TODO treat some keys specially, such as profile, level, bit_rate, rate control options, qmin, qmax, as these are AVCodecContext fields // provides a way to override all AVCodecContext fields MediaEncoder sets
if (std::find(ignoredKeys.cbegin(), ignoredKeys.cend(), key) != ignoredKeys.cend()) if (std::find(ignoredKeys.cbegin(), ignoredKeys.cend(), key) != ignoredKeys.cend())
continue; continue;
else if (value.empty())
libav_utils::setDictValue(dict, key, nullptr);
else if (key == "profile")
encoderCtx->profile = v.asInt();
else if (key == "level")
encoderCtx->level = v.asInt();
else if (key == "bit_rate")
encoderCtx->bit_rate = v.asInt();
else if (key == "rc_buffer_size")
encoderCtx->rc_buffer_size = v.asInt();
else if (key == "rc_min_rate")
encoderCtx->rc_min_rate = v.asInt();
else if (key == "rc_max_rate")
encoderCtx->rc_max_rate = v.asInt();
else if (key == "qmin")
encoderCtx->qmin = v.asInt();
else if (key == "qmax")
encoderCtx->qmax = v.asInt();
else else
libav_utils::setDictValue(dict, key, value); libav_utils::setDictValue(dict, key, value);
} }
......
...@@ -124,7 +124,7 @@ private: ...@@ -124,7 +124,7 @@ private:
bool is_muted = false; bool is_muted = false;
protected: protected:
void readConfig(AVDictionary** dict, const std::string& encoder); void readConfig(AVDictionary** dict, AVCodecContext* encoderCtx);
AVDictionary *options_ = nullptr; AVDictionary *options_ = nullptr;
DeviceParams device_; DeviceParams device_;
std::shared_ptr<const AccountCodecInfo> codec_; std::shared_ptr<const AccountCodecInfo> codec_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment