Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (2)
  • Thomas Guillem's avatar
    tracer: add vlc_tracer_vaTraceWithTs() · f9d0c115
    Thomas Guillem authored and Steve Lhomme's avatar Steve Lhomme committed
    f9d0c115
  • Thomas Guillem's avatar
    test: add clock test · 08950258
    Thomas Guillem authored and Steve Lhomme's avatar Steve Lhomme committed
    Possible to run all tests (by default from the test suite):
    
    vlc/build-linux/test $ ./test_src_clock_clock
    [normal]: checking that normal update has a coeff of 1.0f
    [lowprecision]: checking that low precision update has a coeff near 1.0f
    [drift_72]: checking that a drift of 72ms in 2h is handled
    [drift_-72]: checking that a drift of -72ms in 2h is handled
    [drift_864]: checking that a drift of 864ms in 24h is handled
    [drift_-864]: checking that a drift of -864ms in 24h is handled
    [drift_sudden]: checking that a sudden drift is handled
    
    Or run one test with traces:
    
    ./test_src_clock_clock lowprecision --tracer=json --json-tracer-file=foo.trace -vv
    
    The test fake the timestamps that are sent to the default tracer to
    behave like a live playback.
    
    One possible future scenario would be to feed the clock with real points
    taken from a real 24h live-streaming playback.
    08950258
......@@ -136,10 +136,21 @@ VLC_API void vlc_tracer_Destroy(struct vlc_tracer *tracer);
/**
* Emit traces
*
* va-args are a list of key / value parameters.
* \param tracer tracer emitting the traces
* \param ts timestamp of the current trace
* \param entries list of key / value parameters.
* Key must be a not NULL string.
* Value has to be defined with one of the type defined
* in the \ref vlc_tracer_entry union.
*/
VLC_API void vlc_tracer_vaTraceWithTs(struct vlc_tracer *tracer, vlc_tick_t ts,
va_list entries);
/**
* Emit traces
*
* cf. vlc_tracer_vaTraceWithTs()
*
* \param tracer tracer emitting the traces
* \param ts timestamp of the current trace
*/
......
......@@ -293,6 +293,7 @@ vlc_vaLog
vlc_tracer_Create
vlc_tracer_Destroy
vlc_tracer_TraceWithTs
vlc_tracer_vaTraceWithTs
vlc_LogHeaderCreate
vlc_LogDestroy
vlc_strerror
......
......@@ -46,6 +46,19 @@ struct vlc_tracer_module {
void *opaque;
};
void vlc_tracer_vaTraceWithTs(struct vlc_tracer *tracer, vlc_tick_t ts,
va_list entries)
{
assert(tracer->ops->trace != NULL);
struct vlc_tracer_module *module =
container_of(tracer, struct vlc_tracer_module, tracer);
va_list copy;
va_copy(copy, entries);
tracer->ops->trace(module->opaque, ts, copy);
va_end(copy);
}
void vlc_tracer_TraceWithTs(struct vlc_tracer *tracer, vlc_tick_t ts, ...)
{
assert(tracer->ops->trace != NULL);
......
......@@ -24,6 +24,7 @@ check_PROGRAMS = \
test_libvlc_renderer_discoverer \
test_libvlc_slaves \
test_src_config_chain \
test_src_clock_clock \
test_src_misc_ancillary \
test_src_misc_variables \
test_src_input_stream \
......@@ -155,6 +156,10 @@ test_libvlc_slaves_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_libvlc_meta_SOURCES = libvlc/meta.c
test_libvlc_meta_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_src_clock_clock_SOURCES = src/clock/clock.c \
../src/clock/clock.c \
../src/clock/clock_internal.c
test_src_clock_clock_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_src_misc_ancillary_SOURCES = src/misc/ancillary.c
test_src_misc_ancillary_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_src_misc_variables_SOURCES = src/misc/variables.c
......
/*****************************************************************************
* clock/clock.c: test for the vlc clock
*****************************************************************************
* Copyright (C) 2023 VLC authors, VideoLAN and Videolabs SAS
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_tick.h>
#include <vlc_es.h>
#include <vlc_tracer.h>
#include "../../../src/clock/clock.h"
#include <vlc/vlc.h>
#include "../../libvlc/test.h"
#include "../../../lib/libvlc_internal.h"
#define MODULE_NAME test_clock_clock
#undef VLC_DYNAMIC_PLUGIN
#include <vlc_plugin.h>
#include <vlc_vector.h>
/* Define a builtin module for mocked parts */
const char vlc_module_name[] = MODULE_STRING;
struct clock_ctx;
struct clock_scenario
{
const char *name;
const char *desc;
vlc_tick_t stream_start;
vlc_tick_t system_start; /* VLC_TICK_INVALID for vlc_tick_now() */
vlc_tick_t duration;
vlc_tick_t stream_increment; /* VLC_TICK_INVALID for manual increment */
vlc_tick_t total_drift_duration; /* VLC_TICK_INVALID for non-drift test */
void (*update)(const struct clock_ctx *ctx, size_t index,
vlc_tick_t *system, vlc_tick_t stream);
void (*check)(const struct clock_ctx *ctx, size_t update_count,
vlc_tick_t expected_system_end, vlc_tick_t stream_end);
};
struct clock_ctx
{
vlc_clock_main_t *mainclk;
vlc_clock_t *master;
vlc_clock_t *slave;
const struct clock_scenario *scenario;
};
enum tracer_event_type {
TRACER_EVENT_TYPE_UPDATE,
TRACER_EVENT_TYPE_STATUS,
};
enum tracer_event_status {
TRACER_EVENT_STATUS_RESET_USER,
TRACER_EVENT_STATUS_RESET_BADSOURCE,
};
struct tracer_event
{
enum tracer_event_type type;
union {
struct {
double coeff;
vlc_tick_t offset;
} update;
enum tracer_event_status status;
};
};
struct tracer_ctx
{
vlc_tick_t forced_ts;
struct VLC_VECTOR(struct tracer_event) events;
};
static struct tracer_ctx tracer_ctx;
static void tracer_ctx_Reset(struct tracer_ctx *ctx)
{
ctx->events.size = 0;
ctx->forced_ts = VLC_TICK_INVALID;
}
static void tracer_ctx_Init(struct tracer_ctx *ctx)
{
tracer_ctx_Reset(ctx);
vlc_vector_init(&ctx->events);
};
static void tracer_ctx_Destroy(struct tracer_ctx *ctx)
{
vlc_vector_destroy(&ctx->events);
}
static void tracer_ctx_PushUpdate(struct tracer_ctx *ctx,
double coeff, vlc_tick_t offset)
{
struct tracer_event event = {
.type = TRACER_EVENT_TYPE_UPDATE,
.update = {
.coeff = coeff,
.offset = offset,
},
};
bool ret = vlc_vector_push(&ctx->events, event);
assert(ret);
}
static void tracer_ctx_PushStatus(struct tracer_ctx *ctx,
enum tracer_event_status status)
{
struct tracer_event event = {
.type = TRACER_EVENT_TYPE_STATUS,
.status = status,
};
bool ret = vlc_vector_push(&ctx->events, event);
assert(ret);
}
static void TracerTrace(void *opaque, vlc_tick_t ts, va_list entries)
{
(void) ts;
struct vlc_tracer *libvlc_tracer = opaque;
if (libvlc_tracer != NULL)
{
/* If the user specified a tracer, forward directly to it after faking
* the system ts */
assert(tracer_ctx.forced_ts != VLC_TICK_INVALID);
vlc_tracer_vaTraceWithTs(libvlc_tracer, tracer_ctx.forced_ts, entries);
}
struct vlc_tracer_entry entry = va_arg(entries, struct vlc_tracer_entry);
bool is_render = false, is_status = false;
unsigned nb_update = 0;
double coeff = 0.0f;
vlc_tick_t offset = VLC_TICK_INVALID;
enum tracer_event_status status = 0;
while (entry.key != NULL)
{
switch (entry.type)
{
case VLC_TRACER_INT:
if (!is_render)
continue;
assert(!is_status);
if (strcmp(entry.key, "offset") == 0)
{
nb_update++;
offset = VLC_TICK_FROM_NS(entry.value.integer);
}
break;
case VLC_TRACER_DOUBLE:
if (!is_render)
continue;
assert(!is_status);
if (strcmp(entry.key, "coeff") == 0)
{
nb_update++;
coeff = entry.value.double_;
}
break;
case VLC_TRACER_STRING:
if (strcmp(entry.key, "type") == 0)
{
if (strcmp(entry.value.string, "RENDER") == 0)
is_render = true;
}
if (!is_render)
continue;
/* Assert that there is no "reset_bad_source" */
if (strcmp(entry.key, "event") == 0)
{
is_status = true;
if (strcmp(entry.value.string, "reset_bad_source") == 0)
status = TRACER_EVENT_STATUS_RESET_BADSOURCE;
else if (strcmp(entry.value.string, "reset_user") == 0)
status = TRACER_EVENT_STATUS_RESET_USER;
else
vlc_assert_unreachable();
}
break;
default: vlc_assert_unreachable();
}
entry = va_arg(entries, struct vlc_tracer_entry);
}
if (!is_render)
return;
if (is_status)
tracer_ctx_PushStatus(&tracer_ctx, status);
else if (nb_update > 0)
{
assert(nb_update == 2);
tracer_ctx_PushUpdate(&tracer_ctx, coeff, offset);
}
}
/* Used to check for some trace value and hack the ts to the user tracer */
static const struct vlc_tracer_operations *
OpenTracer(vlc_object_t *obj, void **restrict sysp)
{
static const struct vlc_tracer_operations ops =
{
.trace = TracerTrace,
};
*sysp = vlc_object_get_tracer(obj);
return &ops;
}
vlc_module_begin()
set_callback(OpenTracer)
set_capability("tracer", 0)
vlc_module_end()
VLC_EXPORT const vlc_plugin_cb vlc_static_modules[] = {
VLC_SYMBOL(vlc_entry),
NULL
};
static void play_scenario(libvlc_int_t *vlc, struct vlc_tracer *tracer,
struct clock_scenario *scenario)
{
fprintf(stderr, "[%s]: checking that %s\n", scenario->name, scenario->desc);
assert(scenario->update != NULL);
tracer_ctx_Reset(&tracer_ctx);
struct vlc_logger *logger = vlc->obj.logger;
vlc_clock_main_t *mainclk = vlc_clock_main_New(logger, tracer);
assert(mainclk != NULL);
vlc_clock_t *master = vlc_clock_main_CreateMaster(mainclk, scenario->name,
NULL, NULL);
assert(master != NULL);
vlc_clock_t *slave = vlc_clock_main_CreateSlave(mainclk, NULL, VIDEO_ES,
NULL, NULL);
assert(slave != NULL);
const struct clock_ctx ctx = {
.mainclk = mainclk,
.master = master,
.slave = slave,
.scenario = scenario,
};
vlc_tick_t stream_end = scenario->stream_start + scenario->duration;
vlc_tick_t stream = scenario->stream_start;
if (scenario->system_start == VLC_TICK_INVALID)
scenario->system_start = vlc_tick_now();
vlc_tick_t system = scenario->system_start;
vlc_tick_t expected_system = scenario->system_start;
tracer_ctx.forced_ts = expected_system;
size_t index = 0;
for(; stream < stream_end;
stream += scenario->stream_increment, ++index)
{
scenario->update(&ctx, index, &system, stream);
expected_system += scenario->stream_increment;
tracer_ctx.forced_ts = expected_system;
}
if (scenario->check != NULL)
{
assert(expected_system == scenario->system_start + scenario->duration);
scenario->check(&ctx, index, expected_system, stream_end);
}
if (master != NULL)
vlc_clock_Delete(master);
vlc_clock_Delete(slave);
vlc_clock_main_Delete(mainclk);
}
static void run_scenarios(int main_argc, const char *main_argv[],
struct clock_scenario *scenarios, size_t count)
{
int argc;
const char * const *argv;
const char *scenario_name = NULL;
if (main_argc > 1)
{
/* specific test run from the user with custom options */
scenario_name = main_argv[1];
argc = main_argc - 1;
argv = &main_argv[1];
}
else
{
argc = main_argc;
argv = main_argv;
}
libvlc_instance_t *vlc = libvlc_new(argc, argv);
assert(vlc != NULL);
tracer_ctx_Init(&tracer_ctx);
struct vlc_tracer *tracer = vlc_tracer_Create(VLC_OBJECT(vlc->p_libvlc_int),
MODULE_STRING);
assert(tracer != NULL);
for (size_t i = 0; i < count; ++i)
{
if (scenario_name == NULL
|| strcmp(scenario_name, scenarios[i].name) == 0)
play_scenario(vlc->p_libvlc_int, tracer, &scenarios[i]);
}
vlc_tracer_Destroy(tracer);
tracer_ctx_Destroy(&tracer_ctx);
libvlc_release(vlc);
}
static void normal_update(const struct clock_ctx *ctx, size_t index,
vlc_tick_t *system, vlc_tick_t stream)
{
(void) index;
const struct clock_scenario *scenario = ctx->scenario;
vlc_tick_t drift =
vlc_clock_Update(ctx->master, *system, stream, 1.0f);
/* The master can't drift */
assert(drift == VLC_TICK_INVALID);
/* Check the slave is drifting (only system is moving) */
drift = vlc_clock_Update(ctx->slave, *system,
VLC_TICK_0, 1.0f);
assert(drift == - (stream - VLC_TICK_0));
*system += scenario->stream_increment;
}
static void check_no_event_error(size_t expected_update_count)
{
/* assert that there is no error/status */
assert(tracer_ctx.events.size > 0);
size_t update_count = 0;
for (size_t i = 0; i < tracer_ctx.events.size; ++i)
{
struct tracer_event event = tracer_ctx.events.data[i];
switch (event.type)
{
case TRACER_EVENT_TYPE_UPDATE:
update_count++;
break;
case TRACER_EVENT_TYPE_STATUS:
switch (event.status)
{
case TRACER_EVENT_STATUS_RESET_USER:
case TRACER_EVENT_STATUS_RESET_BADSOURCE:
assert("clock reset not expected" == NULL);
break;
}
break;
}
}
assert(update_count == expected_update_count);
}
static void normal_check(const struct clock_ctx *ctx, size_t update_count,
vlc_tick_t expected_system_end,
vlc_tick_t stream_end)
{
(void) expected_system_end; (void) stream_end;
const struct clock_scenario *scenario = ctx->scenario;
check_no_event_error(update_count);
for (size_t i = 0; i < tracer_ctx.events.size; ++i)
{
struct tracer_event event = tracer_ctx.events.data[i];
if (event.type == TRACER_EVENT_TYPE_UPDATE)
{
assert(event.update.coeff == 1.0f);
assert(event.update.offset ==
scenario->system_start - scenario->stream_start);
}
}
vlc_tick_t converted =
vlc_clock_ConvertToSystem(ctx->slave, expected_system_end,
stream_end, 1.0f);
assert(converted == expected_system_end);
}
static void lowprecision_update(const struct clock_ctx *ctx, size_t index,
vlc_tick_t *system, vlc_tick_t stream)
{
(void) index;
const struct clock_scenario *scenario = ctx->scenario;
vlc_tick_t base_system = stream - scenario->stream_start
+ scenario->system_start;
/* random imprecision (seed based on stream) */
srand(stream);
vlc_tick_t imprecision = rand() % VLC_TICK_FROM_MS(5);
*system = base_system + imprecision;
vlc_tick_t drift =
vlc_clock_Update(ctx->master, *system, stream, 1.0f);
/* The master can't drift */
assert(drift == VLC_TICK_INVALID);
}
static void lowprecision_check(const struct clock_ctx *ctx, size_t update_count,
vlc_tick_t expected_system_end,
vlc_tick_t stream_end)
{
(void) ctx; (void) expected_system_end; (void) stream_end;
check_no_event_error(update_count);
static const double epsilon = 0.005;
for (size_t i = 0; i < tracer_ctx.events.size; ++i)
{
struct tracer_event event = tracer_ctx.events.data[i];
if (event.type == TRACER_EVENT_TYPE_UPDATE)
assert(fabs(event.update.coeff - 1.0f) <= epsilon);
}
}
static void drift_update(const struct clock_ctx *ctx, size_t index,
vlc_tick_t *system, vlc_tick_t stream)
{
(void) index;
const struct clock_scenario *scenario = ctx->scenario;
vlc_tick_t drift =
vlc_clock_Update(ctx->master, *system, stream, 1.0f);
/* The master can't drift */
assert(drift == VLC_TICK_INVALID);
*system += scenario->stream_increment;
/* Simulate 1us drift every stream_increment */
if (scenario->total_drift_duration > 0)
*system += VLC_TICK_FROM_US(1);
else
*system -= VLC_TICK_FROM_US(1);
}
static void drift_check(const struct clock_ctx *ctx, size_t update_count,
vlc_tick_t expected_system_end,
vlc_tick_t stream_end)
{
const struct clock_scenario *scenario = ctx->scenario;
check_no_event_error(update_count);
vlc_tick_t converted =
vlc_clock_ConvertToSystem(ctx->slave, expected_system_end,
stream_end, 1.0f);
assert(converted - expected_system_end == scenario->total_drift_duration);
}
static void drift_sudden_update(const struct clock_ctx *ctx, size_t index,
vlc_tick_t *system, vlc_tick_t stream)
{
(void) index;
const struct clock_scenario *scenario = ctx->scenario;
vlc_tick_t drift =
vlc_clock_Update(ctx->master, *system, stream, 1.0f);
/* The master can't drift */
assert(drift == VLC_TICK_INVALID);
*system += scenario->stream_increment;
if (stream - scenario->stream_start >= scenario->duration * 3 / 4)
{
/* Simulate a sudden high drift */
*system += VLC_TICK_FROM_US(4);
}
}
#define VLC_TICK_24H VLC_TICK_FROM_SEC(24 * 60 * 60)
#define VLC_TICK_2H VLC_TICK_FROM_SEC(2 * 60 * 60)
#define DEFAULT_STREAM_INCREMENT VLC_TICK_FROM_MS(100)
#define INIT_SYSTEM_STREAM_TIMING(duration_, increment_) \
.stream_start = VLC_TICK_0 + VLC_TICK_FROM_MS(31000000), \
.system_start = VLC_TICK_INVALID, \
.duration = duration_, \
.stream_increment = increment_
#define DRIFT_SCENARIO(name_, desc_, duration_, increment_, drift_) \
.name = name_, \
.desc = desc_, \
INIT_SYSTEM_STREAM_TIMING(duration_, increment_), \
.total_drift_duration = drift_, \
.update = drift_update, \
.check = drift_check,
static struct clock_scenario clock_scenarios[] = {
{
.name = "normal",
.desc = "normal update has a coeff of 1.0f",
INIT_SYSTEM_STREAM_TIMING(VLC_TICK_2H, DEFAULT_STREAM_INCREMENT),
.update = normal_update,
.check = normal_check,
},
{
.name = "lowprecision",
.desc = "low precision update has a coeff near 1.0f",
INIT_SYSTEM_STREAM_TIMING(VLC_TICK_2H, DEFAULT_STREAM_INCREMENT),
.update = lowprecision_update,
.check = lowprecision_check,
},
{
DRIFT_SCENARIO(
"drift_72",
"a drift of 72ms in 2h is handled",
VLC_TICK_2H,
DEFAULT_STREAM_INCREMENT,
VLC_TICK_FROM_MS(72)
)},
{
DRIFT_SCENARIO(
"drift_-72",
"a drift of -72ms in 2h is handled",
VLC_TICK_2H,
DEFAULT_STREAM_INCREMENT,
-VLC_TICK_FROM_MS(72)
)
},
{
DRIFT_SCENARIO(
"drift_864",
"a drift of 864ms in 24h is handled",
VLC_TICK_24H,
DEFAULT_STREAM_INCREMENT,
VLC_TICK_FROM_MS(864)
)
},
{
DRIFT_SCENARIO(
"drift_-864",
"a drift of -864ms in 24h is handled",
VLC_TICK_24H,
DEFAULT_STREAM_INCREMENT,
-VLC_TICK_FROM_MS(864)
)
},
{
.name = "drift_sudden",
.desc = "a sudden drift is handled",
INIT_SYSTEM_STREAM_TIMING(VLC_TICK_24H, DEFAULT_STREAM_INCREMENT),
.total_drift_duration = VLC_TICK_FROM_MS(864),
.update = drift_sudden_update,
.check = drift_check,
},
};
int main(int argc, const char *argv[])
{
test_init();
run_scenarios(argc, argv, clock_scenarios, ARRAY_SIZE(clock_scenarios));
}