Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
dea9fc60 by Alaric Senat at 2023-07-20T13:42:03+00:00
stream: beautify stream control queries doc
- - - - -
8b1e2b36 by Alaric Senat at 2023-07-20T13:42:03+00:00
stream: introduce a `get_mtime()` accessor
This helps sharing file information via libvlc.
Libvlc applications have been requesting sorting by and accessing parsed
file statistics like `mtime` since quite some time.
The accessor is optional and is implemented both as an `ops` callback
and as a control query for full compatibility with the old system.
Refs #18600 !2194
- - - - -
26e10e65 by Alaric Senat at 2023-07-20T13:42:03+00:00
input: fill file stats at master initialization
Libvlc applications have been requesting sorting by and accessing parsed
file statistics like `mtime` since quite some time.
This allow un-discovered inputs to have their file stats filled.
- - - - -
ae2d573b by Alaric Senat at 2023-07-20T13:42:03+00:00
cache_read: forward `STREAM_GET_MTIME`
Avoid systematic "unknown query ... in demux_vaControlHelper" error.
- - - - -
d95fc560 by Alaric Senat at 2023-07-20T13:42:03+00:00
prefetch: switch to Control wrappers
Instead of calling controls directly, this leads to better readability.
- - - - -
dc069434 by Alaric Senat at 2023-07-20T13:42:03+00:00
prefetch: add `STREAM_GET_MTIME` support
- - - - -
922c7056 by Alaric Senat at 2023-07-20T13:42:03+00:00
inflate: forward `STREAM_GET_MTIME`
- - - - -
2d39ddd2 by Alaric Senat at 2023-07-20T13:42:03+00:00
cache_block: forward `STREAM_GET_MTIME`
- - - - -
11d60d9f by Alaric Senat at 2023-07-20T13:42:03+00:00
archive: add `STREAM_GET_MTIME` support
- - - - -
53dc8886 by Alaric Senat at 2023-07-20T13:42:03+00:00
decomp: handle `SET_PAUSE_STATE` failure
- - - - -
a950598d by Alaric Senat at 2023-07-20T13:42:03+00:00
decomp: switch to Control wrappers
Instead of calling controls directly, this leads to better readability.
- - - - -
a6f1b5fa by Alaric Senat at 2023-07-20T13:42:03+00:00
decomp: add `STREAM_GET_MTIME` support
- - - - -
cb97a808 by Alaric Senat at 2023-07-20T13:42:03+00:00
access: file: implement `STREAM_GET_MTIME`
- - - - -
10 changed files:
- include/vlc_stream.h
- modules/access/file.c
- modules/stream_extractor/archive.c
- modules/stream_filter/cache_block.c
- modules/stream_filter/cache_read.c
- modules/stream_filter/decomp.c
- modules/stream_filter/inflate.c
- modules/stream_filter/prefetch.c
- src/input/input.c
- src/input/stream.c
Changes:
=====================================
include/vlc_stream.h
=====================================
@@ -69,6 +69,7 @@ struct vlc_stream_operations {
int (*get_title)(stream_t *, unsigned *);
int (*get_seekpoint)(stream_t *, unsigned *);
int (*get_size)(stream_t *, uint64_t *);
+ int (*get_mtime)(stream_t *, uint64_t *);
int (*get_title_info)(stream_t *, input_title_t ***, int *);
int (*get_content_type)(stream_t *, char **);
int (*get_tags)(stream_t *, const block_t **);
@@ -249,35 +250,37 @@ struct stream_t
enum stream_query_e
{
/* capabilities */
- STREAM_CAN_SEEK, /**< arg1= bool * res=cannot fail*/
- STREAM_CAN_FASTSEEK, /**< arg1= bool * res=cannot fail*/
- STREAM_CAN_PAUSE, /**< arg1= bool * res=cannot fail*/
- STREAM_CAN_CONTROL_PACE, /**< arg1= bool * res=cannot fail*/
+ STREAM_CAN_SEEK, /**< arg1=(bool *) res=cannot fail
*/
+ STREAM_CAN_FASTSEEK, /**< arg1=(bool *) res=cannot fail
*/
+ STREAM_CAN_PAUSE, /**< arg1=(bool *) res=cannot fail
*/
+ STREAM_CAN_CONTROL_PACE, /**< arg1=(bool *) res=cannot fail
*/
/* */
- STREAM_GET_SIZE=6, /**< arg1= uint64_t * res=can fail */
+ STREAM_GET_SIZE=6, /**< arg1=(uint64_t *) res=can
fail */
+ STREAM_GET_MTIME, /**< arg1=(uint64_t *) res=can fail
+ Returns the last modified
time in seconds since epoch. */
/* */
- STREAM_GET_PTS_DELAY = 0x101,/**< arg1= vlc_tick_t* res=cannot fail */
- STREAM_GET_TITLE_INFO, /**< arg1=input_title_t*** arg2=int* res=can fail */
- STREAM_GET_TITLE, /**< arg1=unsigned * res=can fail */
- STREAM_GET_SEEKPOINT, /**< arg1=unsigned * res=can fail */
- STREAM_GET_META, /**< arg1= vlc_meta_t * res=can fail */
- STREAM_GET_CONTENT_TYPE, /**< arg1= char ** res=can fail */
- STREAM_GET_SIGNAL, /**< arg1=double *pf_quality, arg2=double
*pf_strength res=can fail */
- STREAM_GET_TAGS, /**< arg1=const block_t ** res=can fail */
- STREAM_GET_TYPE, /**< arg1=int* res=can fail */
-
- STREAM_SET_PAUSE_STATE = 0x200, /**< arg1= bool res=can fail */
- STREAM_SET_TITLE, /**< arg1= int res=can fail */
- STREAM_SET_SEEKPOINT, /**< arg1= int res=can fail */
+ STREAM_GET_PTS_DELAY = 0x101, /**< arg1=(vlc_tick_t *)
res=cannot fail */
+ STREAM_GET_TITLE_INFO, /**< arg1=(input_title_t***)
arg2=(int*) res=can fail */
+ STREAM_GET_TITLE, /**< arg1=(unsigned *) res=can
fail */
+ STREAM_GET_SEEKPOINT, /**< arg1=(unsigned *) res=can
fail */
+ STREAM_GET_META, /**< arg1=(vlc_meta_t *) res=can
fail */
+ STREAM_GET_CONTENT_TYPE, /**< arg1=(char **) res=can fail */
+ STREAM_GET_SIGNAL, /**< arg1=(double *pf_quality),
arg2=(double *pf_strength) res=can fail */
+ STREAM_GET_TAGS, /**< arg1=(const block_t **)
res=can fail */
+ STREAM_GET_TYPE, /**< arg1=(int*) res=can fail */
+
+ STREAM_SET_PAUSE_STATE = 0x200, /**< arg1=(bool) res=can fail */
+ STREAM_SET_TITLE, /**< arg1=(int) res=can fail */
+ STREAM_SET_SEEKPOINT, /**< arg1=(int) res=can fail */
/* XXX only data read through vlc_stream_Read/Block will be recorded */
- STREAM_SET_RECORD_STATE, /**< arg1=bool, arg2=const char *dir_path (if
arg1 is true)
- arg3=const char *psz_ext (if arg1 is
true) res=can fail */
+ STREAM_SET_RECORD_STATE, /**< arg1=bool, arg2=const char
*dir_path (if arg1 is true),
+ arg3=const char *psz_ext (if
arg1 is true) res=can fail */
- STREAM_SET_PRIVATE_ID_STATE = 0x1000, /* arg1= int i_private_data, bool
b_selected res=can fail */
- STREAM_SET_PRIVATE_ID_CA, /* arg1= void * */
- STREAM_GET_PRIVATE_ID_STATE, /* arg1=int i_private_data arg2=bool
* res=can fail */
+ STREAM_SET_PRIVATE_ID_STATE = 0x1000, /**< arg1=(int i_private_data)
arg2=(bool b_selected) res=can fail */
+ STREAM_SET_PRIVATE_ID_CA, /**< arg1=(void *) */
+ STREAM_GET_PRIVATE_ID_STATE, /**< arg1=(int i_private_data)
arg2=(bool *) res=can fail */
};
/**
@@ -497,6 +500,11 @@ VLC_USED static inline int vlc_stream_GetSize(stream_t *s,
uint64_t *size)
return vlc_stream_Control(s, STREAM_GET_SIZE, size);
}
+VLC_USED static inline int vlc_stream_GetMTime(stream_t *s, uint64_t *mtime)
+{
+ return vlc_stream_Control(s, STREAM_GET_MTIME, mtime);
+}
+
VLC_USED static inline int vlc_stream_GetTitleInfo(stream_t *s, input_title_t
***title_info, int *size)
{
return vlc_stream_Control(s, STREAM_GET_TITLE_INFO, title_info, size);
=====================================
modules/access/file.c
=====================================
@@ -362,12 +362,15 @@ static int FileControl( stream_t *p_access, int i_query,
va_list args )
break;
case STREAM_GET_SIZE:
+ case STREAM_GET_MTIME:
{
struct stat st;
if (fstat (p_sys->fd, &st) || !S_ISREG(st.st_mode))
return VLC_EGENERIC;
- *va_arg( args, uint64_t * ) = st.st_size;
+ const uint64_t stat =
+ (i_query == STREAM_GET_SIZE) ? st.st_size : st.st_mtime;
+ *va_arg( args, uint64_t * ) = stat;
break;
}
=====================================
modules/stream_extractor/archive.c
=====================================
@@ -514,6 +514,16 @@ static int Control( stream_extractor_t* p_extractor, int
i_query, va_list args )
*va_arg( args, uint64_t* ) = archive_entry_size( p_sys->p_entry );
break;
+ case STREAM_GET_MTIME:
+ if( p_sys->p_entry == NULL )
+ return VLC_EGENERIC;
+
+ if( !archive_entry_mtime_is_set( p_sys->p_entry ) )
+ return VLC_EGENERIC;
+
+ *va_arg( args, uint64_t* ) = archive_entry_mtime( p_sys->p_entry );
+ break;
+
default:
return vlc_stream_vaControl( p_extractor->source, i_query, args );
}
=====================================
modules/stream_filter/cache_block.c
=====================================
@@ -242,6 +242,7 @@ static int AStreamControl(stream_t *s, int i_query, va_list
args)
case STREAM_CAN_FASTSEEK:
case STREAM_CAN_PAUSE:
case STREAM_CAN_CONTROL_PACE:
+ case STREAM_GET_MTIME:
case STREAM_GET_SIZE:
case STREAM_GET_PTS_DELAY:
case STREAM_GET_TITLE_INFO:
=====================================
modules/stream_filter/cache_read.c
=====================================
@@ -468,6 +468,7 @@ static int AStreamControl(stream_t *s, int i_query, va_list
args)
case STREAM_SET_PRIVATE_ID_STATE:
case STREAM_SET_PRIVATE_ID_CA:
case STREAM_GET_PRIVATE_ID_STATE:
+ case STREAM_GET_MTIME:
return vlc_stream_vaControl(s->s, i_query, args);
case STREAM_SET_TITLE:
=====================================
modules/stream_filter/decomp.c
=====================================
@@ -83,6 +83,7 @@ typedef struct
bool can_pace;
bool can_pause;
vlc_tick_t pts_delay;
+ uint64_t mtime;
} stream_sys_t;
extern char **environ;
@@ -213,6 +214,11 @@ static int Control (stream_t *stream, int query, va_list
args)
case STREAM_CAN_CONTROL_PACE:
*(va_arg (args, bool *)) = p_sys->can_pace;
break;
+ case STREAM_GET_MTIME:
+ if (p_sys->mtime == (uint64_t)-1)
+ return VLC_EGENERIC;
+ *va_arg(args, uint64_t *) = p_sys->mtime;
+ break;
case STREAM_GET_SIZE:
*(va_arg (args, uint64_t *)) = 0;
break;
@@ -224,11 +230,11 @@ static int Control (stream_t *stream, int query, va_list
args)
bool paused = va_arg (args, unsigned);
vlc_mutex_lock (&p_sys->lock);
- vlc_stream_Control(stream->s, STREAM_SET_PAUSE_STATE, paused);
+ const int status = vlc_stream_SetPauseState(stream->s, paused);
p_sys->paused = paused;
vlc_cond_signal (&p_sys->wait);
vlc_mutex_unlock (&p_sys->lock);
- break;
+ return status;
}
default:
return VLC_EGENERIC;
@@ -251,9 +257,12 @@ static int Open (stream_t *stream, const char *path)
vlc_mutex_init (&p_sys->lock);
p_sys->paused = false;
p_sys->pid = -1;
- vlc_stream_Control(stream->s, STREAM_CAN_PAUSE, &p_sys->can_pause);
- vlc_stream_Control(stream->s, STREAM_CAN_CONTROL_PACE, &p_sys->can_pace);
- vlc_stream_Control(stream->s, STREAM_GET_PTS_DELAY, &p_sys->pts_delay);
+ p_sys->can_pause = vlc_stream_CanPause(stream->s);
+ p_sys->can_pace = vlc_stream_CanPace(stream->s);
+ vlc_stream_GetPtsDelay(stream->s, &p_sys->pts_delay);
+
+ if (vlc_stream_GetMTime(stream->s, &p_sys->mtime) != VLC_SUCCESS)
+ p_sys->mtime = -1;
/* I am not a big fan of the pyramid style, but I cannot think of anything
* better here. There are too many failure cases. */
=====================================
modules/stream_filter/inflate.c
=====================================
@@ -115,6 +115,7 @@ static int Control(stream_t *stream, int query, va_list
args)
case STREAM_GET_CONTENT_TYPE:
case STREAM_GET_SIGNAL:
case STREAM_SET_PAUSE_STATE:
+ case STREAM_GET_MTIME:
return vlc_stream_vaControl(stream->s, query, args);
case STREAM_GET_SIZE:
case STREAM_GET_TITLE_INFO:
=====================================
modules/stream_filter/prefetch.c
=====================================
@@ -65,6 +65,7 @@ typedef struct
bool can_pace;
bool can_pause;
uint64_t size;
+ uint64_t mtime;
vlc_tick_t pts_delay;
char *content_type;
@@ -365,6 +366,11 @@ static int Control(stream_t *stream, int query, va_list
args)
return VLC_EGENERIC;
*va_arg(args, uint64_t *) = sys->size;
break;
+ case STREAM_GET_MTIME:
+ if (sys->mtime == (uint64_t)-1)
+ return VLC_EGENERIC;
+ *va_arg(args, uint64_t *) = sys->mtime;
+ break;
case STREAM_GET_PTS_DELAY:
*va_arg(args, vlc_tick_t *) = sys->pts_delay;
break;
@@ -426,37 +432,36 @@ static int Open(vlc_object_t *obj)
{
stream_t *stream = (stream_t *)obj;
- bool fast_seek;
-
- if (vlc_stream_Control(stream->s, STREAM_CAN_FASTSEEK, &fast_seek))
- return VLC_EGENERIC; /* not a byte stream */
/* For local files, the operating system is likely to do a better work at
* caching/prefetching. Also, prefetching with this module could cause
* undesirable high load at start-up. Lastly, local files may require
* support for title/seekpoint and meta control requests. */
- if (fast_seek)
+ if (vlc_stream_CanFastSeek(stream->s))
return VLC_EGENERIC;
/* PID-filtered streams are not suitable for prefetching, as they would
* suffer excessive latency to enable a PID. DVB would also require support
* for the signal level and Conditional Access controls.
* TODO? For seekable streams, a forced could work around the problem. */
- if (vlc_stream_Control(stream->s, STREAM_GET_PRIVATE_ID_STATE, 0,
- &(bool){ false }) == VLC_SUCCESS)
+ if (vlc_stream_GetPrivateIdState(stream->s, 0, &(bool){false}) ==
+ VLC_SUCCESS)
return VLC_EGENERIC;
stream_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
- vlc_stream_Control(stream->s, STREAM_CAN_SEEK, &sys->can_seek);
- vlc_stream_Control(stream->s, STREAM_CAN_PAUSE, &sys->can_pause);
- vlc_stream_Control(stream->s, STREAM_CAN_CONTROL_PACE, &sys->can_pace);
- if (vlc_stream_Control(stream->s, STREAM_GET_SIZE, &sys->size))
+ sys->can_seek = vlc_stream_CanSeek(stream->s);
+ sys->can_pause = vlc_stream_CanPause(stream->s);
+ sys->can_pace = vlc_stream_CanPace(stream->s);
+
+ if (vlc_stream_GetSize(stream->s, &sys->size) != VLC_SUCCESS)
sys->size = -1;
- vlc_stream_Control(stream->s, STREAM_GET_PTS_DELAY, &sys->pts_delay);
- if (vlc_stream_Control(stream->s, STREAM_GET_CONTENT_TYPE,
- &sys->content_type))
+ if (vlc_stream_GetMTime(stream->s, &sys->mtime) != VLC_SUCCESS)
+ sys->mtime = -1;
+
+ vlc_stream_GetPtsDelay(stream->s, &sys->pts_delay);
+ if (vlc_stream_GetContentType(stream->s, &sys->content_type) !=
VLC_SUCCESS)
sys->content_type = NULL;
sys->eof = false;
=====================================
src/input/input.c
=====================================
@@ -869,6 +869,25 @@ static void InitTitle( input_thread_t * p_input, bool
had_titles )
});
}
+static void FillFileStatsIfAny( input_thread_t * p_input )
+{
+ input_thread_private_t *priv = input_priv( p_input );
+ input_source_t *master = priv->master;
+ stream_t *stream_filters = master->p_demux->s;
+
+ if( stream_filters == NULL )
+ return;
+
+ uint64_t size;
+
+ if( vlc_stream_GetSize(stream_filters, &size) == VLC_SUCCESS )
+ input_item_AddStat( priv->p_item, "size", size );
+
+ uint64_t mtime;
+ if( vlc_stream_GetMTime(stream_filters, &mtime) == VLC_SUCCESS )
+ input_item_AddStat( priv->p_item, "mtime", mtime );
+}
+
static void StartTitle( input_thread_t * p_input )
{
input_thread_private_t *priv = input_priv(p_input);
@@ -1314,6 +1333,8 @@ static int Init( input_thread_t * p_input )
/* Load master infos */
InputSourceStatistics( master, priv->p_item, priv->p_es_out );
+ FillFileStatsIfAny( p_input );
+
if( priv->type != INPUT_TYPE_PREPARSING )
{
StartTitle( p_input );
=====================================
src/input/stream.c
=====================================
@@ -795,6 +795,12 @@ int vlc_stream_vaControl(stream_t *s, int cmd, va_list
args)
return s->ops->stream.get_size(s, size);
}
return VLC_EGENERIC;
+ case STREAM_GET_MTIME:
+ if (s->ops->stream.get_mtime != NULL) {
+ uint64_t *mtime = va_arg(args, uint64_t *);
+ return s->ops->stream.get_mtime(s, mtime);
+ }
+ return VLC_EGENERIC;
case STREAM_GET_PTS_DELAY:
if (s->ops->get_pts_delay != NULL) {
vlc_tick_t *pts_delay = va_arg(args, vlc_tick_t *);
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/2807d7adf972f8f7613eb2e381b4f5d8aa5798ee...cb97a80815e17bcb6632c1b1e59685cd952a90cd
--
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/2807d7adf972f8f7613eb2e381b4f5d8aa5798ee...cb97a80815e17bcb6632c1b1e59685cd952a90cd
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits