code: Fix encoder::ffmpeg causing recursive mutex lock on Singleton

Not sure why I did it any other way before - there's no benefit to the previous design, only downsides.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2023-05-14 20:20:02 +02:00 committed by Xaymar
parent 8817248dfd
commit a802b0007f
2 changed files with 8 additions and 7 deletions

View file

@ -928,7 +928,7 @@ void ffmpeg_instance::parse_ffmpeg_commandline(std::string_view text)
} }
} }
ffmpeg_factory::ffmpeg_factory(const AVCodec* codec) : _avcodec(codec) ffmpeg_factory::ffmpeg_factory(ffmpeg_manager* manager, const AVCodec* codec) : _avcodec(codec)
{ {
// Generate default identifier. // Generate default identifier.
{ {
@ -958,7 +958,7 @@ ffmpeg_factory::ffmpeg_factory(const AVCodec* codec) : _avcodec(codec)
} }
// Find any available handlers for this codec. // Find any available handlers for this codec.
if (_handler = ffmpeg_manager::instance()->get_handler(_avcodec->name); _handler) { if (_handler = manager->get_handler(_avcodec->name); _handler) {
// Override any found info with the one specified by the handler. // Override any found info with the one specified by the handler.
_handler->adjust_info(this, _avcodec, _id, _name, _codec); _handler->adjust_info(this, _avcodec, _id, _name, _codec);
@ -1175,7 +1175,7 @@ ffmpeg_manager::ffmpeg_manager() : _factories(), _handlers(), _debug_handler()
if ((codec->type == AVMediaType::AVMEDIA_TYPE_AUDIO) || (codec->type == AVMediaType::AVMEDIA_TYPE_VIDEO)) { if ((codec->type == AVMediaType::AVMEDIA_TYPE_AUDIO) || (codec->type == AVMediaType::AVMEDIA_TYPE_VIDEO)) {
try { try {
_factories.emplace(codec, std::make_shared<ffmpeg_factory>(codec)); _factories.emplace(codec, std::make_shared<ffmpeg_factory>(this, codec));
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
DLOG_ERROR("Failed to register encoder '%s': %s", codec->name, ex.what()); DLOG_ERROR("Failed to register encoder '%s': %s", codec->name, ex.what());
} }
@ -1210,11 +1210,10 @@ bool ffmpeg_manager::has_handler(std::string_view codec)
return (_handlers.find(codec.data()) != _handlers.end()); return (_handlers.find(codec.data()) != _handlers.end());
} }
std::shared_ptr<ffmpeg_manager> ffmpeg_manager::instance() std::shared_ptr<ffmpeg_manager> ffmpeg_manager::instance()
{ {
static std::weak_ptr<ffmpeg_manager> winst; static std::weak_ptr<ffmpeg_manager> winst;
static std::mutex mtx; static std::mutex mtx;
std::unique_lock<decltype(mtx)> lock(mtx); std::unique_lock<decltype(mtx)> lock(mtx);
auto instance = winst.lock(); auto instance = winst.lock();

View file

@ -29,7 +29,9 @@ extern "C" {
} }
namespace streamfx::encoder::ffmpeg { namespace streamfx::encoder::ffmpeg {
class ffmpeg_instance;
class ffmpeg_factory; class ffmpeg_factory;
class ffmpeg_manager;
class ffmpeg_instance : public obs::encoder_instance { class ffmpeg_instance : public obs::encoder_instance {
ffmpeg_factory* _factory; ffmpeg_factory* _factory;
@ -117,7 +119,7 @@ namespace streamfx::encoder::ffmpeg {
std::shared_ptr<handler::handler> _handler; std::shared_ptr<handler::handler> _handler;
public: public:
ffmpeg_factory(const AVCodec* codec); ffmpeg_factory(ffmpeg_manager* manager, const AVCodec* codec);
virtual ~ffmpeg_factory(); virtual ~ffmpeg_factory();
const char* get_name() override; const char* get_name() override;