[vlc-commits] [Git][videolan/vlc][master] 4 commits: decoder: p_cc NULL is very unlikely

Steve Lhomme (@robUx4) gitlab at videolan.org
Sat Oct 28 09:18:37 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
9fd38571 by Thomas Guillem at 2023-10-28T09:00:22+00:00
decoder: p_cc NULL is very unlikely

- - - - -
f7e9e96e by Thomas Guillem at 2023-10-28T09:00:22+00:00
test: input_decoder: fix unused warning

- - - - -
e9dacbf7 by Thomas Guillem at 2023-10-28T09:00:22+00:00
decoder: fix read-after-free when using multiple CCs

Pushing a block to a sub decoder move the ownership. It was possible
that the first CC decoder already processed and released the block,
while the parent decoder was still duplicating it in order to send it to
the next CC decoder.

Fixes #28411

- - - - -
4946185a by Thomas Guillem at 2023-10-28T09:00:22+00:00
decoder: don't loop if there is no CCs

- - - - -


2 changed files:

- src/input/decoder.c
- test/src/input/decoder/input_decoder_scenarios.c


Changes:

=====================================
src/input/decoder.c
=====================================
@@ -224,6 +224,7 @@ struct vlc_input_decoder_t
     struct
     {
         /* All members guarded by subdecs.lock */
+        size_t count;
         vlc_fourcc_t selected_codec;
         bool b_supported;
         decoder_cc_desc_t desc;
@@ -1230,17 +1231,21 @@ static void DecoderPlayCcLocked( vlc_input_decoder_t *p_owner, vlc_frame_t *p_cc
         p_owner->cc.desc_changed = true;
     }
 
-    bool first_cc = true;
+    if (p_owner->cc.count == 0)
+        goto end;
+
+    size_t cc_idx = 0;
     vlc_input_decoder_t *it;
+
     vlc_list_foreach(it, &p_owner->subdecs.list, node)
     {
         if (!SubDecoderIsCc(it))
             continue;
 
-        if (first_cc)
+        if (++cc_idx == p_owner->cc.count)
         {
             block_FifoPut(it->p_fifo, p_cc);
-            first_cc = false;
+            p_cc = NULL;
         }
         else
         {
@@ -1251,9 +1256,10 @@ static void DecoderPlayCcLocked( vlc_input_decoder_t *p_owner, vlc_frame_t *p_cc
         }
     }
 
+end:
     vlc_mutex_unlock(&p_owner->subdecs.lock);
 
-    if (first_cc) /* can have bitmap set but no created decs */
+    if (p_cc != NULL) /* can have bitmap set but no created decs */
         block_Release( p_cc );
 }
 
@@ -1280,7 +1286,7 @@ static void ModuleThread_QueueCc( decoder_t *p_videodec, vlc_frame_t *p_cc,
 {
     vlc_input_decoder_t *p_owner = dec_get_owner( p_videodec );
 
-    if (likely(p_cc == NULL))
+    if (unlikely(p_cc == NULL))
         return;
 
     if (!p_owner->cc.b_supported ||
@@ -2047,6 +2053,7 @@ CreateDecoder( vlc_object_t *p_parent, const struct vlc_input_decoder_cfg *cfg )
     p_owner->cc.desc.i_608_channels = 0;
     p_owner->cc.desc.i_708_channels = 0;
     vlc_list_init(&p_owner->subdecs.list);
+    p_owner->cc.count = 0;
     p_owner->cc.p_sout_input = NULL;
     p_owner->cc.sout_es_id = NULL;
     p_owner->cc.b_sout_created = false;
@@ -2263,6 +2270,7 @@ static void RemoveCcDecoder(vlc_input_decoder_t *owner,
         if (it == subdec)
         {
             vlc_list_remove(&it->node);
+            owner->cc.count--;
             vlc_mutex_unlock(&owner->subdecs.lock);
             return;
         }
@@ -2290,6 +2298,7 @@ void vlc_input_decoder_Delete( vlc_input_decoder_t *p_owner )
 #ifndef NDEBUG
     vlc_mutex_lock(&p_owner->subdecs.lock);
     assert(vlc_list_is_empty(&p_owner->subdecs.list));
+    assert(p_owner->cc.count == 0);
     vlc_mutex_unlock(&p_owner->subdecs.lock);
 #endif
 
@@ -2568,6 +2577,7 @@ vlc_input_decoder_CreateSubDec(vlc_input_decoder_t *p_owner,
     }
 
     vlc_list_append(&p_ccowner->node, &p_owner->subdecs.list);
+    p_owner->cc.count++;
     p_ccowner->master_dec = p_owner;
 
     vlc_mutex_unlock(&p_owner->subdecs.lock);


=====================================
test/src/input/decoder/input_decoder_scenarios.c
=====================================
@@ -596,8 +596,9 @@ static void cc_decoder_setup_608(decoder_t *dec)
 }
 
 static void cc_text_renderer_render_608_02(filter_t *filter,
-                                             subpicture_region_t *region_in)
+                                           subpicture_region_t *region_in)
 {
+    (void) filter;
     assert(strcmp(region_in->p_text->psz_text, "cc02_dec") == 0);
     vlc_sem_post(&scenario_data.wait_stop);
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ac3bd26b700377da9e4ea8e00d95b84dcb6ff705...4946185a1135488a9dde934cab02e397d75c17fb

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ac3bd26b700377da9e4ea8e00d95b84dcb6ff705...4946185a1135488a9dde934cab02e397d75c17fb
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