Browse Source

input: decoder: add stream output flush test

The test check that the stream output is correctly flushed when the
input decoder is flushed, ensuring that previous commit didn't break
the triggering of the flush.
pull/138/head
Alexandre Janniaux 4 years ago
committed by Steve Lhomme
parent
commit
29303ae49b
  1. 56
      test/src/input/decoder/input_decoder.c
  2. 2
      test/src/input/decoder/input_decoder.h
  3. 31
      test/src/input/decoder/input_decoder_scenarios.c

56
test/src/input/decoder/input_decoder.c

@ -43,6 +43,7 @@ const char vlc_module_name[] = MODULE_STRING;
#include <vlc_filter.h>
#include <vlc_threads.h>
#include <vlc_vout_display.h>
#include <vlc_sout.h>
#include <limits.h>
@ -169,6 +170,49 @@ static int OpenWindow(vlc_window_t *wnd)
return VLC_SUCCESS;
}
static void *SoutFilterAdd(sout_stream_t *stream, const es_format_t *fmt)
{
(void)stream; (void)fmt;
void *id = malloc(1);
assert(id != NULL);
return id;
}
static void SoutFilterDel(sout_stream_t *stream, void *id)
{
(void)stream;
free(id);
}
static int SoutFilterSend(sout_stream_t *stream, void *id, block_t *block)
{
struct input_decoder_scenario *scenario = &input_decoder_scenarios[current_scenario];
if (scenario->sout_filter_send != NULL)
return scenario->sout_filter_send(stream, id, block);
block_Release(block);
return VLC_SUCCESS;
}
static void SoutFilterFlush(sout_stream_t *stream, void *id)
{
struct input_decoder_scenario *scenario = &input_decoder_scenarios[current_scenario];
if (scenario->sout_filter_flush != NULL)
scenario->sout_filter_flush(stream, id);
}
static int OpenSoutFilter(vlc_object_t *obj)
{
sout_stream_t *stream = (sout_stream_t *)obj;
static const struct sout_stream_operations ops = {
.add = SoutFilterAdd,
.del = SoutFilterDel,
.send = SoutFilterSend,
.flush = SoutFilterFlush,
};
stream->ops = &ops;
return VLC_SUCCESS;
};
static void on_state_changed(vlc_player_t *player, enum vlc_player_state state, void *opaque)
{
(void)player; (void)state; (void) opaque;
@ -184,6 +228,14 @@ static void play_scenario(intf_thread_t *intf, struct input_decoder_scenario *sc
var_Create(intf, "codec", VLC_VAR_STRING);
var_SetString(intf, "codec", MODULE_STRING);
if (scenario->sout != NULL)
{
char *sout;
assert(asprintf(&sout, ":sout=%s", scenario->sout) != -1);
input_item_AddOption(media, sout, VLC_INPUT_OPTION_TRUSTED);
free(sout);
}
vlc_player_t *player = vlc_player_New(&intf->obj,
VLC_PLAYER_LOCK_NORMAL, NULL, NULL);
assert(player);
@ -260,6 +312,10 @@ vlc_module_begin()
add_submodule()
set_callback_display(OpenDisplay, 0)
add_submodule()
set_callback(OpenSoutFilter)
set_capability("sout output", 0)
vlc_module_end()
/* Helper typedef for vlc_static_modules */

2
test/src/input/decoder/input_decoder.h

@ -36,6 +36,8 @@ struct input_decoder_scenario {
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);
};

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

@ -43,6 +43,7 @@ static struct scenario_data
vlc_sem_t wait_ready_to_flush;
struct vlc_video_context *decoder_vctx;
bool skip_decoder;
bool stream_out_sent;
} scenario_data;
static void decoder_fixed_size(decoder_t *dec, vlc_fourcc_t chroma,
@ -240,6 +241,22 @@ static void interface_setup_check_flush(intf_thread_t *intf)
vlc_player_Unlock(player);
}
static int sout_filter_send(sout_stream_t *stream, void *id, block_t *block)
{
(void)stream; (void)id;
block_Release(block);
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;
assert(scenario_data.stream_out_sent);
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";
struct input_decoder_scenario input_decoder_scenarios[] =
{{
@ -256,6 +273,19 @@ struct input_decoder_scenario input_decoder_scenarios[] =
.decoder_flush = decoder_flush_signal,
.display_prepare = display_prepare_signal,
.interface_setup = interface_setup_check_flush,
},
{
/* Check that stream output is also flushed:
- the test cannot work if the stream_out filter is not added
- sout_filter_send(), signal the interface that it can flush
- the interface change player position to trigger a flush
- the flush is signaled to the stream_out filter
- the stream_out filter signal the end of the test */
.source = source_800_600,
.sout = "#" MODULE_STRING,
.sout_filter_send = sout_filter_send,
.sout_filter_flush = sout_filter_flush,
.interface_setup = interface_setup_check_flush,
}};
size_t input_decoder_scenarios_count = ARRAY_SIZE(input_decoder_scenarios);
@ -263,6 +293,7 @@ void input_decoder_scenario_init(void)
{
scenario_data.decoder_vctx = NULL;
scenario_data.skip_decoder = false;
scenario_data.stream_out_sent = false;
vlc_sem_init(&scenario_data.wait_stop, 0);
vlc_sem_init(&scenario_data.display_prepare_signal, 0);
vlc_sem_init(&scenario_data.wait_ready_to_flush, 0);

Loading…
Cancel
Save