options: add an option type for byte sizes

And use it for 2 demuxer options. It could be used for more options
later. (Though the --cache options can not use this, because they use KB
as base unit.)
This commit is contained in:
wm4 2018-01-24 01:32:56 +01:00 committed by Kevin Mitchell
parent cabfbc34b5
commit 11f5713e3b
5 changed files with 108 additions and 25 deletions

View File

@ -2868,7 +2868,7 @@ Demuxer
``--demuxer-rawvideo-size=<value>``
Frame size in bytes when using ``--demuxer=rawvideo``.
``--demuxer-max-bytes=<bytes>``
``--demuxer-max-bytes=<bytesize>``
This controls how much the demuxer is allowed to buffer ahead. The demuxer
will normally try to read ahead as much as necessary, or as much is
requested with ``--demuxer-readahead-secs``. The option can be used to
@ -2880,9 +2880,10 @@ Demuxer
Set these limits higher if you get a packet queue overflow warning, and
you think normal playback would be possible with a larger packet queue.
See ``--list-options`` for defaults and value range.
See ``--list-options`` for defaults and value range. ``<bytesize>`` options
accept suffixes such as ``KiB`` and ``MiB``.
``--demuxer-max-back-bytes=<value>``
``--demuxer-max-back-bytes=<bytesize>``
This controls how much past data the demuxer is allowed to preserve. This
is useful only if the ``--demuxer-seekable-cache`` option is enabled.
Unlike the forward cache, there is no control how many seconds are actually

View File

@ -84,8 +84,8 @@ const demuxer_desc_t *const demuxer_list[] = {
};
struct demux_opts {
int max_bytes;
int max_bytes_bw;
int64_t max_bytes;
int64_t max_bytes_bw;
double min_secs;
int force_seekable;
double min_secs_cache;
@ -99,8 +99,8 @@ struct demux_opts {
const struct m_sub_options demux_conf = {
.opts = (const struct m_option[]){
OPT_DOUBLE("demuxer-readahead-secs", min_secs, M_OPT_MIN, .min = 0),
OPT_INTRANGE("demuxer-max-bytes", max_bytes, 0, 0, INT_MAX),
OPT_INTRANGE("demuxer-max-back-bytes", max_bytes_bw, 0, 0, INT_MAX),
OPT_BYTE_SIZE("demuxer-max-bytes", max_bytes, 0, 0, INT_MAX),
OPT_BYTE_SIZE("demuxer-max-back-bytes", max_bytes_bw, 0, 0, INT_MAX),
OPT_FLAG("force-seekable", force_seekable, 0),
OPT_DOUBLE("cache-secs", min_secs_cache, M_OPT_MIN, .min = 0),
OPT_FLAG("access-references", access_references, 0),

View File

@ -393,6 +393,101 @@ const m_option_type_t m_option_type_int64 = {
.get = int64_get,
};
static int parse_byte_size(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param, void *dst)
{
if (param.len == 0)
return M_OPT_MISSING_PARAM;
struct bstr r;
long long tmp_int = bstrtoll(param, &r, 0);
int64_t unit = 1;
if (r.len) {
if (bstrcasecmp0(r, "kib") == 0 || bstrcasecmp0(r, "k") == 0) {
unit = 1024;
} else if (bstrcasecmp0(r, "mib") == 0 || bstrcasecmp0(r, "m") == 0) {
unit = 1024 * 1024;
} else if (bstrcasecmp0(r, "gib") == 0 || bstrcasecmp0(r, "g") == 0) {
unit = 1024 * 1024 * 1024;
} else if (bstrcasecmp0(r, "tib") == 0 || bstrcasecmp0(r, "t") == 0) {
unit = 1024 * 1024 * 1024 * 1024LL;
} else {
mp_err(log, "The %.*s option must be an integer: %.*s\n",
BSTR_P(name), BSTR_P(param));
mp_err(log, "The following suffixes are also allowed: "
"KiB, MiB, GiB, TiB, K, M, G, T.\n");
return M_OPT_INVALID;
}
}
if (tmp_int < 0) {
mp_err(log, "The %.*s option does not support negative numbers: %.*s\n",
BSTR_P(name), BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
if (INT64_MAX / unit < tmp_int) {
mp_err(log, "The %.*s option overflows: %.*s\n",
BSTR_P(name), BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
tmp_int *= unit;
if ((opt->flags & M_OPT_MIN) && (tmp_int < opt->min)) {
mp_err(log, "The %.*s option must be >= %d: %.*s\n",
BSTR_P(name), (int) opt->min, BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
if ((opt->flags & M_OPT_MAX) && (tmp_int > opt->max)) {
mp_err(log, "The %.*s option must be <= %d: %.*s\n",
BSTR_P(name), (int) opt->max, BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
if (dst)
*(int64_t *)dst = tmp_int;
return 1;
}
char *format_file_size(int64_t size)
{
double s = size;
if (size < 1024)
return talloc_asprintf(NULL, "%.0f", s);
if (size < (1024 * 1024))
return talloc_asprintf(NULL, "%.3f KiB", s / (1024.0));
if (size < (1024 * 1024 * 1024))
return talloc_asprintf(NULL, "%.3f MiB", s / (1024.0 * 1024.0));
if (size < (1024LL * 1024LL * 1024LL * 1024LL))
return talloc_asprintf(NULL, "%.3f GiB", s / (1024.0 * 1024.0 * 1024.0));
return talloc_asprintf(NULL, "%.3f TiB", s / (1024.0 * 1024.0 * 1024.0 * 1024.0));
}
static char *pretty_print_byte_size(const m_option_t *opt, const void *val)
{
return format_file_size(*(int64_t *)val);
}
const m_option_type_t m_option_type_byte_size = {
.name = "ByteSize",
.size = sizeof(int64_t),
.parse = parse_byte_size,
.print = print_int,
.pretty_print = pretty_print_byte_size,
.copy = copy_opt,
.add = add_int64,
.multiply = multiply_int64,
.set = int64_set,
.get = int64_get,
};
static int parse_intpair(struct mp_log *log, const struct m_option *opt,
struct bstr name, struct bstr param, void *dst)
{

View File

@ -41,6 +41,7 @@ extern const m_option_type_t m_option_type_flag;
extern const m_option_type_t m_option_type_dummy_flag;
extern const m_option_type_t m_option_type_int;
extern const m_option_type_t m_option_type_int64;
extern const m_option_type_t m_option_type_byte_size;
extern const m_option_type_t m_option_type_intpair;
extern const m_option_type_t m_option_type_float;
extern const m_option_type_t m_option_type_double;
@ -371,6 +372,7 @@ struct m_option {
const char *deprecation_message;
};
char *format_file_size(int64_t size);
// The option has a minimum set in \ref m_option::min.
#define M_OPT_MIN (1 << 0)
@ -670,6 +672,9 @@ extern const char m_option_path_separator;
#define OPT_COLOR(...) \
OPT_GENERAL(struct m_color, __VA_ARGS__, .type = &m_option_type_color)
#define OPT_BYTE_SIZE(...) \
OPT_RANGE_(int64_t, __VA_ARGS__, .type = &m_option_type_byte_size)
#define OPT_GEOMETRY(...) \
OPT_GENERAL(struct m_geometry, __VA_ARGS__, .type = &m_option_type_geometry)

View File

@ -320,24 +320,6 @@ static char *cut_osd_list(struct MPContext *mpctx, char *text, int pos)
return new;
}
static char *format_file_size(int64_t size)
{
double s = size;
if (size < 1024)
return talloc_asprintf(NULL, "%.0f", s);
if (size < (1024 * 1024))
return talloc_asprintf(NULL, "%.3f KiB", s / (1024.0));
if (size < (1024 * 1024 * 1024))
return talloc_asprintf(NULL, "%.3f MiB", s / (1024.0 * 1024.0));
if (size < (1024LL * 1024LL * 1024LL * 1024LL))
return talloc_asprintf(NULL, "%.3f GiB", s / (1024.0 * 1024.0 * 1024.0));
return talloc_asprintf(NULL, "%.3f TiB", s / (1024.0 * 1024.0 * 1024.0 * 1024.0));
}
static char *format_delay(double time)
{
return talloc_asprintf(NULL, "%d ms", (int)lrint(time * 1000));