From bd3838064aebb0e19a157317f9b5cee9512fbc44 Mon Sep 17 00:00:00 2001 From: philippegorley <philippe.gorley@savoirfairelinux.com> Date: Thu, 7 Jun 2018 10:18:29 -0400 Subject: [PATCH] encoder: fix segfault if key isn't in dictionary Change-Id: If32273538b24853b7aba236efd8db730faa5b954 --- src/media/libav_utils.cpp | 10 ++++++++++ src/media/libav_utils.h | 3 +++ src/media/media_encoder.cpp | 12 ++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/media/libav_utils.cpp b/src/media/libav_utils.cpp index 7bb5588537..8d76e4548f 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 c8f97d32f5..67efca9d67 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 eab867310c..b4ea60b312 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 -- GitLab