From 87bd2cf368a9a070a44e9ae9a53802a386fdafc2 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Wed, 9 Sep 2020 09:47:27 +0200 Subject: [PATCH] Lavc audio: realloc codec context Codec context needs to be realloced because avcodec_close() strips codec specific part from the context and then eg. setting frame_duration for OPUS fails. --- src/audio/codec/libavcodec.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/audio/codec/libavcodec.cpp b/src/audio/codec/libavcodec.cpp index 6dc4a4e54..5caff9ce1 100644 --- a/src/audio/codec/libavcodec.cpp +++ b/src/audio/codec/libavcodec.cpp @@ -211,7 +211,6 @@ static void *libavcodec_init(audio_codec_t audio_codec, audio_codec_direction_t delete s; return NULL; } - s->codec_ctx->strict_std_compliance = -2; s->bitrate = bitrate; @@ -247,9 +246,12 @@ static bool reinitialize_coder(struct libavcodec_codec_state *s, struct audio_de { cleanup_common(s); - pthread_mutex_lock(s->libav_global_lock); - avcodec_close(s->codec_ctx); - pthread_mutex_unlock(s->libav_global_lock); + s->codec_ctx = avcodec_alloc_context3(s->codec); + if (s->codec_ctx == nullptr) { // not likely :) + LOG(LOG_LEVEL_ERROR) << MOD_NAME << "Could not allocate audio codec context\n"; + return false; + } + s->codec_ctx->strict_std_compliance = -2; /* put sample parameters */ if (s->bitrate > 0) { @@ -371,9 +373,12 @@ static bool reinitialize_decoder(struct libavcodec_codec_state *s, struct audio_ { cleanup_common(s); - pthread_mutex_lock(s->libav_global_lock); - avcodec_close(s->codec_ctx); - pthread_mutex_unlock(s->libav_global_lock); + s->codec_ctx = avcodec_alloc_context3(s->codec); + if (s->codec_ctx == nullptr) { // not likely :) + LOG(LOG_LEVEL_ERROR) << MOD_NAME << "Could not allocate audio codec context\n"; + return false; + } + s->codec_ctx->strict_std_compliance = -2; s->codec_ctx->channels = 1; @@ -667,6 +672,11 @@ static void cleanup_common(struct libavcodec_codec_state *s) #endif } + pthread_mutex_lock(s->libav_global_lock); + avcodec_close(s->codec_ctx); + avcodec_free_context(&s->codec_ctx); + pthread_mutex_unlock(s->libav_global_lock); + s->context_initialized = false; } @@ -677,11 +687,6 @@ static void libavcodec_done(void *state) cleanup_common(s); - pthread_mutex_lock(s->libav_global_lock); - avcodec_close(s->codec_ctx); - avcodec_free_context(&s->codec_ctx); - pthread_mutex_unlock(s->libav_global_lock); - rm_release_shared_lock(LAVCD_LOCK_NAME); av_frame_free(&s->av_frame);