[vlc-commits] [Git][videolan/vlc][master] 5 commits: input: decoder: fix format cleaning on destroy
Steve Lhomme (@robUx4)
gitlab at videolan.org
Wed Nov 23 14:34:45 UTC 2022
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
3007bc4a by Alexandre Janniaux at 2022-11-23T14:06:19+00:00
input: decoder: fix format cleaning on destroy
When destroying the decoder, the decoder module can be triggering a
decoder_UpdateVideoFormat call which will check the format we've been
clearing.
Regression from 08b24866dc443c30df8f9d5ee4f7e2045bf62956.
Refs #27532
- - - - -
d794eac3 by Alexandre Janniaux at 2022-11-23T14:06:19+00:00
test: input: decoder: check decoder destruction
Check that the decoder is correctly destroyed, even if it is being
running a decoder_UpdateVideoOutput at the point of destruction.
Refs #27532
- - - - -
1dbe1fe2 by Alexandre Janniaux at 2022-11-23T14:06:19+00:00
test: input: decoder: handle VLCDEC_RELOAD
When VLCDEC_RELOAD is returned by the decoder_t::pf_decode method, the
vlc_frame_t block will be reused for the next decoder, and cannot be
released.
- - - - -
2e928f40 by Alexandre Janniaux at 2022-11-23T14:06:19+00:00
input: decoder: fix format cleaning on reload
When reloading the decoder, the decoder module can be triggering a
decoder_UpdateVideoFormat call which will check the format we've been
clearing.
Regression from 08b24866dc443c30df8f9d5ee4f7e2045bf62956.
Refs #27532
- - - - -
579d97da by Alexandre Janniaux at 2022-11-23T14:06:19+00:00
test: input: decoder: check decoder reload
Check that the decoder is correctly reload, even if it is being
running a decoder_UpdateVideoOutput at the point of reloading.
Fixes #27532
- - - - -
4 changed files:
- src/input/decoder.c
- test/src/input/decoder/input_decoder.c
- test/src/input/decoder/input_decoder.h
- test/src/input/decoder/input_decoder_scenarios.c
Changes:
=====================================
src/input/decoder.c
=====================================
@@ -309,8 +309,8 @@ static int DecoderThread_Reload( vlc_input_decoder_t *p_owner,
}
/* Restart the decoder module */
- es_format_Clean( &p_owner->dec_fmt_in );
decoder_Clean( p_dec );
+ es_format_Clean( &p_owner->dec_fmt_in );
p_owner->error = false;
if( reload == RELOAD_DECODER_AOUT )
@@ -2015,9 +2015,8 @@ static void DeleteDecoder( vlc_input_decoder_t *p_owner, enum es_format_category
msg_Dbg( p_dec, "killing decoder fourcc `%4.4s'",
(char*)&p_dec->fmt_in->i_codec );
- es_format_Clean( &p_owner->dec_fmt_in );
- es_format_Clean( &p_owner->pktz_fmt_in );
decoder_Clean( p_dec );
+
if ( p_owner->out_pool )
{
picture_pool_Release( p_owner->out_pool );
@@ -2089,6 +2088,8 @@ static void DeleteDecoder( vlc_input_decoder_t *p_owner, enum es_format_category
vlc_assert_unreachable();
}
+ es_format_Clean( &p_owner->dec_fmt_in );
+ es_format_Clean( &p_owner->pktz_fmt_in );
es_format_Clean( &p_owner->fmt );
if( p_owner->p_description )
=====================================
test/src/input/decoder/input_decoder.c
=====================================
@@ -84,11 +84,13 @@ static int DecoderDecode(decoder_t *dec, block_t *block)
assert(pic);
pic->date = block->i_pts;
pic->b_progressive = true;
- block_Release(block);
struct input_decoder_scenario *scenario = &input_decoder_scenarios[current_scenario];
assert(scenario->decoder_decode != NULL);
- return scenario->decoder_decode(dec, pic);
+ int ret = scenario->decoder_decode(dec, pic);
+ if (ret != VLCDEC_RELOAD)
+ block_Release(block);
+ return ret;
}
static void DecoderFlush(decoder_t *dec)
@@ -100,7 +102,11 @@ static void DecoderFlush(decoder_t *dec)
static void CloseDecoder(vlc_object_t *obj)
{
+ struct input_decoder_scenario *scenario = &input_decoder_scenarios[current_scenario];
decoder_t *dec = (decoder_t*)obj;
+
+ if (scenario->decoder_destroy != NULL)
+ scenario->decoder_destroy(dec);
struct vlc_video_context *vctx = dec->p_sys;
if (vctx)
vlc_video_context_Release(vctx);
=====================================
test/src/input/decoder/input_decoder.h
=====================================
@@ -32,6 +32,7 @@ struct input_decoder_scenario {
const char *source;
const char *sout;
void (*decoder_setup)(decoder_t *);
+ void (*decoder_destroy)(decoder_t *);
int (*decoder_decode)(decoder_t *, picture_t *);
void (*decoder_flush)(decoder_t *);
void (*display_prepare)(vout_display_t *vd, picture_t *pic);
=====================================
test/src/input/decoder/input_decoder_scenarios.c
=====================================
@@ -44,6 +44,7 @@ static struct scenario_data
vlc_sem_t wait_ready_to_flush;
struct vlc_video_context *decoder_vctx;
bool skip_decoder;
+ bool has_reload;
bool stream_out_sent;
size_t decoder_image_sent;
} scenario_data;
@@ -65,6 +66,12 @@ static void decoder_fixed_size(decoder_t *dec, vlc_fourcc_t chroma,
static void decoder_i420_800_600(decoder_t *dec)
{ decoder_fixed_size(dec, VLC_CODEC_I420, 800, 600); }
+static void decoder_i420_800_600_stop(decoder_t *dec)
+{
+ decoder_i420_800_600(dec);
+ vlc_sem_post(&scenario_data.wait_stop);
+}
+
static int decoder_decode_check_cc(decoder_t *dec, picture_t *pic)
{
vlc_tick_t date = pic->date;
@@ -204,6 +211,36 @@ static void decoder_flush_signal(decoder_t *dec)
vlc_sem_post(&scenario_data.wait_stop);
}
+static void* SendUpdateOutput(void *opaque)
+{
+ decoder_t *dec = opaque;
+ decoder_UpdateVideoOutput(dec, NULL);
+ return NULL;
+}
+
+static void decoder_destroy_trigger_update(decoder_t *dec)
+{
+ /* Use another thread to ensure we don't double-lock, but
+ * at most deadlock instead. */
+ vlc_thread_t thread;
+ int ret = vlc_clone(&thread, SendUpdateOutput, dec);
+ assert(ret == VLC_SUCCESS);
+ vlc_join(thread, NULL);
+}
+
+static int decoder_decode_trigger_reload(decoder_t *dec, picture_t *pic)
+{
+ (void)dec;
+ picture_Release(pic);
+
+ if (!scenario_data.has_reload)
+ {
+ vlc_sem_post(&scenario_data.wait_stop);
+ return VLCDEC_RELOAD;
+ }
+ return VLCDEC_SUCCESS;
+}
+
static void display_prepare_signal(vout_display_t *vd, picture_t *pic)
{
(void)vd;
@@ -311,6 +348,23 @@ struct input_decoder_scenario input_decoder_scenarios[] =
.sout_filter_send = sout_filter_send,
.sout_filter_flush = sout_filter_flush,
.interface_setup = interface_setup_check_flush,
+},
+{
+ /* Check that releasing a decoder while it is triggering an update
+ * of the video output format doesn't lead to a crash. Non-regression
+ * test from issue #27532. */
+ .source = source_800_600,
+ .decoder_setup = decoder_i420_800_600_stop,
+ .decoder_destroy = decoder_destroy_trigger_update,
+},
+{
+ /* Check that reloading a decoder while it is triggering an update
+ * of the video output format doesn't lead to a crash. Non-regression
+ * test from issue #27532. */
+ .source = source_800_600,
+ .decoder_setup = decoder_i420_800_600,
+ .decoder_decode = decoder_decode_trigger_reload,
+ .decoder_destroy = decoder_destroy_trigger_update,
}};
size_t input_decoder_scenarios_count = ARRAY_SIZE(input_decoder_scenarios);
@@ -318,6 +372,7 @@ void input_decoder_scenario_init(void)
{
scenario_data.decoder_vctx = NULL;
scenario_data.skip_decoder = false;
+ scenario_data.has_reload = false;
scenario_data.stream_out_sent = false;
scenario_data.decoder_image_sent = 0;
vlc_sem_init(&scenario_data.wait_stop, 0);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/5e7d2af4277a508f856d8b65f3a60765e35a4313...579d97daa24134e7ea8bd393c572069bcfc3a729
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/5e7d2af4277a508f856d8b65f3a60765e35a4313...579d97daa24134e7ea8bd393c572069bcfc3a729
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list