[vlc-commits] [Git][videolan/vlc][master] 4 commits: test: input_decoder: add a pf_getcc test

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu Aug 31 10:36:19 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
e3057533 by Alaric Senat at 2023-08-31T09:58:35+00:00
test: input_decoder: add a pf_getcc test

The test checks that the closed-captions are correctly forwarded to the
stream output chain when they are output from the packetizer.

As a side effect, it also checks that a packetizer is used in the stream
output pipeline, even when the input has already been packetized.

Co-authored-by: Alexandre Janniaux <ajanni at videolabs.io>

- - - - -
61750113 by Alexandre Janniaux at 2023-08-31T09:58:35+00:00
input: decoder: use early return

- - - - -
2ed6c7eb by Alexandre Janniaux at 2023-08-31T09:58:35+00:00
input: decoder: unlock before playing CC

Regression from 6369ea50377624694572d6ba5f5bcae26d278fe4. This commit
introduced a lock re-entrancy to the fifo lock, which is not allowed,
when DecoderPlayCc is used to play a closed caption from the packetizer.

- - - - -
998b623d by Alexandre Janniaux at 2023-08-31T09:58:35+00:00
test: input_decoder: add a get_cc test for playback

This check the path where pf_getcc() is called from the packetizer and
then DecoderPlayCc() is used to play the closed-caption.

This is a non-regression test, checking what's fixed from the previous
commit and introduced in 6369ea50377624694572d6ba5f5bcae26d278fe4.

- - - - -


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
=====================================
@@ -1227,7 +1227,10 @@ static void PacketizerGetCc( vlc_input_decoder_t *p_owner, decoder_t *p_dec_cc )
     p_cc = p_dec_cc->pf_get_cc( p_dec_cc, &desc );
     if( !p_cc )
         return;
+
+    vlc_fifo_Unlock(p_owner->p_fifo);
     DecoderPlayCc( p_owner, p_cc, &desc );
+    vlc_fifo_Lock(p_owner->p_fifo);
 }
 
 static void ModuleThread_QueueCc( decoder_t *p_videodec, vlc_frame_t *p_cc,
@@ -1235,14 +1238,17 @@ 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( unlikely( p_cc != NULL ) )
+    if (likely(p_cc == NULL))
+        return;
+
+    if (!p_owner->cc.b_supported ||
+       (p_owner->p_packetizer != NULL && p_owner->p_packetizer->pf_get_cc == NULL))
     {
-        if( p_owner->cc.b_supported &&
-           ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
-            DecoderPlayCc( p_owner, p_cc, p_desc );
-        else
-            block_Release( p_cc );
+        block_Release(p_cc);
+        return;
     }
+
+    DecoderPlayCc(p_owner, p_cc, p_desc);
 }
 
 static int ModuleThread_PlayVideo( vlc_input_decoder_t *p_owner, picture_t *p_picture )


=====================================
test/src/input/decoder/input_decoder.c
=====================================
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * input_decoder.c: test for vlc_input_decoder state machine
  *****************************************************************************
- * Copyright (C) 2022 VideoLabs
+ * Copyright (C) 2022-2023 VideoLabs
  *
  * Author: Alexandre Janniaux <ajanni at videolabs.io>
  *
@@ -112,6 +112,39 @@ static void CloseDecoder(vlc_object_t *obj)
         vlc_video_context_Release(vctx);
 }
 
+static vlc_frame_t *PacketizerPacketize(decoder_t *dec, vlc_frame_t **in)
+{
+    (void)dec;
+    if (in == NULL)
+        return NULL;
+
+    vlc_frame_t *ret = *in;
+    if (ret != NULL)
+        *in = NULL;
+    return ret;
+}
+
+static vlc_frame_t *PacketizerGetCC(decoder_t *dec, decoder_cc_desc_t *cc_desc)
+{
+    struct input_decoder_scenario *scenario = &input_decoder_scenarios[current_scenario];
+    if (scenario->packetizer_getcc != NULL)
+        return scenario->packetizer_getcc(dec, cc_desc);
+    return NULL;
+}
+
+static int OpenPacketizer(vlc_object_t *obj)
+{
+    decoder_t *dec = (decoder_t*)obj;
+
+    dec->pf_packetize = PacketizerPacketize;
+    dec->pf_get_cc = PacketizerGetCC;
+    dec->pf_flush = NULL;
+    es_format_Clean(&dec->fmt_out);
+    es_format_Copy(&dec->fmt_out, dec->fmt_in);
+
+    return VLC_SUCCESS;
+}
+
 static int OpenDecoder(vlc_object_t *obj)
 {
     decoder_t *dec = (decoder_t*)obj;
@@ -121,6 +154,7 @@ static int OpenDecoder(vlc_object_t *obj)
     vlc_decoder_device_Release(device);
 
     dec->pf_decode = DecoderDecode;
+    dec->pf_get_cc = NULL;
     dec->pf_flush = DecoderFlush;
     es_format_Clean(&dec->fmt_out);
     es_format_Copy(&dec->fmt_out, dec->fmt_in);
@@ -179,9 +213,10 @@ static int OpenWindow(vlc_window_t *wnd)
 static void *SoutFilterAdd(sout_stream_t *stream, const es_format_t *fmt,
                            const char *es_id)
 {
-    (void)stream; (void)fmt; (void)es_id;
-    void *id = malloc(1);
+    (void)stream; (void)es_id;
+    vlc_fourcc_t *id = malloc(sizeof(*id));
     assert(id != NULL);
+    *id = fmt->i_codec;
     return id;
 }
 
@@ -207,6 +242,15 @@ static void SoutFilterFlush(sout_stream_t *stream, void *id)
         scenario->sout_filter_flush(stream, id);
 }
 
+static int SoutFilterControl(sout_stream_t *stream, int query, va_list args)
+{
+    (void)stream;
+    if (query != SOUT_STREAM_WANTS_SUBSTREAMS)
+        return VLC_EGENERIC;
+    *va_arg(args, bool *) = true;
+    return VLC_SUCCESS;
+}
+
 static int OpenSoutFilter(vlc_object_t *obj)
 {
     sout_stream_t *stream = (sout_stream_t *)obj;
@@ -215,6 +259,7 @@ static int OpenSoutFilter(vlc_object_t *obj)
         .del = SoutFilterDel,
         .send = SoutFilterSend,
         .flush = SoutFilterFlush,
+        .control = SoutFilterControl,
     };
     stream->ops = &ops;
     return VLC_SUCCESS;
@@ -226,6 +271,17 @@ static void on_state_changed(vlc_player_t *player, enum vlc_player_state state,
     vlc_cond_signal(&player_cond);
 }
 
+static void on_track_list_changed(vlc_player_t *player,
+        enum vlc_player_list_action action,
+        const struct vlc_player_track *track,
+        void *data)
+{
+    (void)player; (void)data;
+    struct input_decoder_scenario *scenario = &input_decoder_scenarios[current_scenario];
+    if (scenario->on_track_list_changed != NULL)
+        scenario->on_track_list_changed(action, track);
+}
+
 static void play_scenario(intf_thread_t *intf, struct input_decoder_scenario *scenario)
 {
     input_decoder_scenario_init();
@@ -251,6 +307,7 @@ static void play_scenario(intf_thread_t *intf, struct input_decoder_scenario *sc
 
     static const struct vlc_player_cbs player_cbs = {
         .on_state_changed = on_state_changed,
+        .on_track_list_changed = on_track_list_changed,
     };
 
     vlc_player_Lock(player);
@@ -311,6 +368,10 @@ vlc_module_begin()
         set_callbacks(OpenDecoder, CloseDecoder)
         set_capability("video decoder", INT_MAX)
 
+    add_submodule()
+        set_callback(OpenPacketizer)
+        set_capability("packetizer", INT_MAX)
+
     add_submodule()
         set_callback(OpenWindow)
         set_capability("vout window", INT_MAX)


=====================================
test/src/input/decoder/input_decoder.h
=====================================
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * input_decoder.h: test for input_decoder state machine
  *****************************************************************************
- * Copyright (C) 2022 VideoLabs
+ * Copyright (C) 2022-2023 VideoLabs
  *
  * Author: Alexandre Janniaux <ajanni at videolabs.io>
  *
@@ -27,6 +27,7 @@
 
 typedef struct vout_display_t vout_display_t;
 typedef struct intf_thread_t intf_thread_t;
+typedef struct decoder_cc_desc_t decoder_cc_desc_t;
 
 struct input_decoder_scenario {
     const char *source;
@@ -34,11 +35,14 @@ struct input_decoder_scenario {
     void (*decoder_setup)(decoder_t *);
     void (*decoder_destroy)(decoder_t *);
     int (*decoder_decode)(decoder_t *, picture_t *);
+    vlc_frame_t * (*packetizer_getcc)(decoder_t *, decoder_cc_desc_t *);
     void (*decoder_flush)(decoder_t *);
     void (*display_prepare)(vout_display_t *vd, picture_t *pic);
     void (*interface_setup)(intf_thread_t *intf);
     int (*sout_filter_send)(sout_stream_t *stream, void *id, block_t *block);
     void (*sout_filter_flush)(sout_stream_t *stream, void *id);
+    void (*on_track_list_changed)(enum vlc_player_list_action action,
+                                  const struct vlc_player_track *track);
 };
 
 


=====================================
test/src/input/decoder/input_decoder_scenarios.c
=====================================
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * input_decoder_scenario.c: testflight for input_decoder state machine
  *****************************************************************************
- * Copyright (C) 2022 VideoLabs
+ * Copyright (C) 2022-2023 VideoLabs
  *
  * Author: Alexandre Janniaux <ajanni at videolabs.io>
  *
@@ -30,6 +30,7 @@
 #include <vlc_messages.h>
 #include <vlc_player.h>
 #include <vlc_interface.h>
+#include <vlc_frame.h>
 #include <vlc_codec.h>
 #include <vlc_vout_display.h>
 
@@ -317,6 +318,19 @@ static int sout_filter_send(sout_stream_t *stream, void *id, block_t *block)
     return VLC_SUCCESS;
 }
 
+static int sout_filter_wait_cc(sout_stream_t *stream, void *id, block_t *block)
+{
+    (void)stream; (void)id;
+    block_Release(block);
+    vlc_fourcc_t *codec = id;
+    if (*codec == VLC_CODEC_CEA608)
+    {
+        scenario_data.stream_out_sent = true;
+        vlc_sem_post(&scenario_data.wait_ready_to_flush);
+    }
+    return VLC_SUCCESS;
+}
+
 static void sout_filter_flush(sout_stream_t *stream, void *id)
 {
     (void)stream; (void)id;
@@ -324,7 +338,34 @@ static void sout_filter_flush(sout_stream_t *stream, void *id)
     vlc_sem_post(&scenario_data.wait_stop);
 }
 
-const char source_800_600[] = "mock://video_track_count=1;length=100000000000;video_width=800;video_height=600";
+static vlc_frame_t *packetizer_getcc(decoder_t *dec, decoder_cc_desc_t *cc_desc)
+{
+    (void)dec;
+
+    cc_desc->i_608_channels = 1;
+    cc_desc->i_reorder_depth = -1;
+
+    vlc_frame_t *f =  vlc_frame_Alloc(1);
+    assert(f != NULL);
+
+    return f;
+}
+
+static void on_track_list_changed_check_cea608(
+        enum vlc_player_list_action action,
+        const struct vlc_player_track *track)
+{
+    if (action != VLC_PLAYER_LIST_ADDED)
+        return;
+
+    if (strcmp(vlc_es_id_GetStrId(track->es_id), "video/0/cc/spu/auto/0") != 0)
+        return;
+
+    assert(track->fmt.i_codec == VLC_CODEC_CEA608);
+    vlc_sem_post(&scenario_data.wait_stop);
+}
+
+#define source_800_600 "mock://video_track_count=1;length=100000000000;video_width=800;video_height=600"
 struct input_decoder_scenario input_decoder_scenarios[] =
 {{
     .source = source_800_600,
@@ -371,6 +412,21 @@ struct input_decoder_scenario input_decoder_scenarios[] =
     .decoder_setup = decoder_i420_800_600,
     .decoder_decode = decoder_decode_trigger_reload,
     .decoder_destroy = decoder_destroy_trigger_update,
+},
+{
+    .source = source_800_600,
+    .sout = "#" MODULE_STRING,
+    .packetizer_getcc = packetizer_getcc,
+    .sout_filter_send = sout_filter_wait_cc,
+    .sout_filter_flush = sout_filter_flush,
+    .interface_setup = interface_setup_check_flush,
+},
+{
+    .source = source_800_600 ";video_packetized=false",
+    .packetizer_getcc = packetizer_getcc,
+    .decoder_setup = decoder_i420_800_600,
+    .decoder_decode = decoder_decode_drop,
+    .on_track_list_changed = on_track_list_changed_check_cea608,
 }};
 size_t input_decoder_scenarios_count = ARRAY_SIZE(input_decoder_scenarios);
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e1c8bf95d02e42f0743e9d27adb49c083ddb0128...998b623df50ed3ca7a6296e3bfd2808ffcaf50a8

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e1c8bf95d02e42f0743e9d27adb49c083ddb0128...998b623df50ed3ca7a6296e3bfd2808ffcaf50a8
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