diff --git a/src/media/libav_utils.cpp b/src/media/libav_utils.cpp index 7bb5588537c765d6e170ec16bd4f87c87a3f3eef..8d76e4548f9ea0c6f94cd292bcb52d5fd7944d19 100644 --- a/src/media/libav_utils.cpp +++ b/src/media/libav_utils.cpp @@ -216,4 +216,14 @@ getError(int err) return ret; } +const char* +getDictValue(const AVDictionary* d, const std::string& key, int flags) +{ + auto kv = av_dict_get(d, key.c_str(), nullptr, flags); + if (kv) + return kv->value; + else + return ""; +} + }} // namespace ring::libav_utils diff --git a/src/media/libav_utils.h b/src/media/libav_utils.h index c8f97d32f5aad2d3562a98cf8f9dd684a73c4640..67efca9d67c3c54351c757bf516417431eaf4ec3 100644 --- a/src/media/libav_utils.h +++ b/src/media/libav_utils.h @@ -24,6 +24,7 @@ #include <map> #include <string> +struct AVDictionary; struct AVPixFmtDescriptor; namespace ring { namespace libav_utils { @@ -44,4 +45,6 @@ namespace ring { namespace libav_utils { std::string getError(int err); + const char* getDictValue(const AVDictionary* d, const std::string& key, int flags=0); + }} // namespace ring::libav_utils diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp index eab867310cbf89fcb68724aacae21e799f1e5389..b4ea60b312e0812e86acbfc39d36781ed9218f85 100644 --- a/src/media/media_encoder.cpp +++ b/src/media/media_encoder.cpp @@ -203,9 +203,9 @@ MediaEncoder::addStream(const SystemCodecInfo& systemCodecInfo, std::string para encoderCtx = prepareEncoderContext(outputCodec, systemCodecInfo.mediaType == MEDIA_VIDEO); encoders_.push_back(encoderCtx); - auto maxBitrate = 1000 * atoi(av_dict_get(options_, "max_rate", nullptr, 0)->value); + auto maxBitrate = 1000 * std::atoi(libav_utils::getDictValue(options_, "max_rate")); auto bufSize = 2 * maxBitrate; // as recommended (TODO: make it customizable) - auto crf = atoi(av_dict_get(options_, "crf", nullptr, 0)->value); + auto crf = std::atoi(libav_utils::getDictValue(options_, "crf")); /* let x264 preset override our encoder settings */ if (systemCodecInfo.avcodecId == AV_CODEC_ID_H264) { @@ -217,7 +217,7 @@ MediaEncoder::addStream(const SystemCodecInfo& systemCodecInfo, std::string para crf = 30; // good value for H264-720p@30 RING_DBG("H264 encoder setup: crf=%u, maxrate=%u, bufsize=%u", crf, maxBitrate, bufSize); - av_opt_set(encoderCtx->priv_data, "crf", av_dict_get(options_, "crf", nullptr, 0)->value, 0); + av_opt_set_int(encoderCtx->priv_data, "crf", crf, 0); encoderCtx->rc_buffer_size = bufSize; encoderCtx->rc_max_rate = maxBitrate; } else if (systemCodecInfo.avcodecId == AV_CODEC_ID_VP8) { @@ -242,7 +242,7 @@ MediaEncoder::addStream(const SystemCodecInfo& systemCodecInfo, std::string para encoderCtx->rc_buffer_size = maxBitrate; encoderCtx->bit_rate = maxBitrate; if (crf != SystemCodecInfo::DEFAULT_NO_QUALITY) { - av_opt_set(encoderCtx->priv_data, "crf", av_dict_get(options_, "crf", nullptr, 0)->value, 0); + av_opt_set_int(encoderCtx->priv_data, "crf", crf, 0); RING_DBG("Using quality factor %d", crf); } else { RING_DBG("Using Max bitrate %d", maxBitrate); @@ -554,8 +554,8 @@ AVCodecContext* MediaEncoder::prepareEncoderContext(AVCodec* outputCodec, bool i encoderCtx->width = device_.width; encoderCtx->height = device_.height; } else { - encoderCtx->width = atoi(av_dict_get(options_, "width", nullptr, 0)->value); - encoderCtx->height = atoi(av_dict_get(options_, "height", nullptr, 0)->value); + encoderCtx->width = std::atoi(libav_utils::getDictValue(options_, "width")); + encoderCtx->height = std::atoi(libav_utils::getDictValue(options_, "height")); } // satisfy ffmpeg: denominator must be 16bit or less value