Browse Source

mock: add subitems/node support

Example:
"mock://node[2]{video_track_count=1};node_count=4;length=1000000;node[1]{length=2000000}"
Will create the following sub items:
 - input_item_New(mock://length=1000000, submock[0]);
 - input_item_New(mock://length=2000000, submock[1]);
 - input_item_New(mock://video_track_count=1, submock[2]);
 - input_item_New(mock://length=1000000, submock[3]);

If specified with node[]{}, a sub item will use the params between "{}".
If not specified, all subitems will use the same params from the url (here:
"length=1000000").

This will be needed for the future and reworked media_list_player test.
pull/162/head
Thomas Guillem 3 years ago
committed by Jean-Baptiste Kempf
parent
commit
33fc5b2051
  1. 158
      modules/demux/mock.c

158
modules/demux/mock.c

@ -148,6 +148,7 @@ var_Read_float(const char *psz)
/* var_name, type, module_header_type, getter, default_value */
#define OPTIONS_GLOBAL(X) \
X(node_count, ssize_t, add_integer, Ssize, 0) \
X(length, vlc_tick_t, add_integer, Integer, VLC_TICK_FROM_MS(5000)) \
X(audio_track_count, ssize_t, add_integer, Ssize, 0) \
X(video_track_count, ssize_t, add_integer, Ssize, 0) \
@ -971,6 +972,156 @@ Demux(demux_t *demux)
return eof ? VLC_DEMUXER_EOF : VLC_DEMUXER_SUCCESS;
}
static char *
StripNodeParams(const char *orignal_url)
{
char *url = strdup(orignal_url);
if (url == NULL)
return NULL;
/* Strip "node_count=xxx" */
char *substr_start = strcasestr(url, "node_count=");
assert(substr_start != NULL);
char *substr_end = strchr(substr_start, ';');
if (substr_end != NULL)
substr_end++;
else
substr_end = strchr(substr_start, '\0');
assert(substr_end != NULL);
memmove(substr_start, substr_end, strlen(substr_end) + 1);
/* Strip "node[xxx]={xxx}" */
while ((substr_start = strcasestr(url, "node[")) != NULL)
{
substr_end = strchr(substr_start, '{');
if (substr_end != NULL)
{
substr_end = strchr(substr_start, '}');
substr_end++;
if (*substr_end == ';')
substr_end++;
}
if (substr_end == NULL)
{
free(url);
return NULL;
}
memmove(substr_start, substr_end, strlen(substr_end) + 1);
}
return url;
}
/*
* Create sub items from the demux URL
*
* Example:
* "mock://node[2]{video_track_count=1};node_count=4;length=1000000;node[1]{length=2000000}"
* Will create the following sub items:
* - input_item_New(mock://length=1000000, submock[0]);
* - input_item_New(mock://length=2000000, submock[1]);
* - input_item_New(mock://video_track_count=1, submock[2]);
* - input_item_New(mock://length=1000000, submock[3]);
*
* If specified with node[]{}, a sub item will use the params between "{}".
* If not specified, all subitems will use the same params from the url (here:
* "length=1000000").
*/
static int
Readdir(stream_t *demux, input_item_node_t *node)
{
struct demux_sys *sys = demux->p_sys;
char *default_url = StripNodeParams(demux->psz_url);
if (default_url == NULL)
return VLC_EGENERIC;
int ret = VLC_ENOMEM;
for (ssize_t i = 0; i < sys->node_count; ++i)
{
const char *url;
char *name, *option_name, *url_buf = NULL;
int len;
len = asprintf(&option_name, "node[%zd]{", i);
if (len < 0)
goto error;
char *option = strstr(demux->psz_url, option_name);
free(option_name);
if (option != NULL)
{
option = strchr(option, '{');
assert(option != NULL);
option++;
char *option_end = strchr(option, '}');
if (option_end == NULL)
{
ret = VLC_EINVAL;
goto error;
}
ptrdiff_t option_size = option_end - option;
if (option_size > INT_MAX)
{
ret = VLC_EINVAL;
goto error;
}
len = asprintf(&url_buf, "mock://%.*s", (int) option_size, option);
if (len < 0)
goto error;
url = url_buf;
}
else
url = default_url;
len = asprintf(&name, "submock[%zd]", i);
if (len < 0)
{
free(url_buf);
goto error;
}
input_item_t *item = input_item_New(url, name);
free(name);
free(url_buf);
if (item == NULL)
goto error;
input_item_node_AppendItem(node, item);
input_item_Release(item);
}
ret = VLC_SUCCESS;
error:
free(default_url);
return ret;
}
static int
ReaddirControl(demux_t *demux, int query, va_list args)
{
(void) demux;
switch (query)
{
case DEMUX_GET_META:
case DEMUX_GET_TYPE:
return VLC_EGENERIC;
case DEMUX_HAS_UNSUPPORTED_META:
{
*(va_arg(args, bool *)) = false;
return VLC_SUCCESS;
}
}
return VLC_EGENERIC;
}
static void
Close(vlc_object_t *obj)
{
@ -1010,6 +1161,13 @@ Open(vlc_object_t *obj)
OPTIONS_VIDEO(READ_SUBOPTION)
OPTIONS_SUB(READ_SUBOPTION)
if (sys->node_count > 0)
{
demux->pf_control = ReaddirControl;
demux->pf_readdir = Readdir;
return VLC_SUCCESS;
}
if (sys->chapter_count > 0 && sys->title_count == 0)
sys->title_count++;

Loading…
Cancel
Save