fftools: remove parse_time_or_die()

Replace it with calling av_parse_time() directly, which provides
graceful error handling and more accurate error messages.
This commit is contained in:
Anton Khirnov 2023-07-14 16:37:19 +02:00
parent 9cb47c78d6
commit 49ac7fc485
5 changed files with 46 additions and 53 deletions

View File

@ -127,18 +127,6 @@ int parse_number(const char *context, const char *numstr, int type,
return AVERROR(EINVAL);
}
int64_t parse_time_or_die(const char *context, const char *timestr,
int is_duration)
{
int64_t us;
if (av_parse_time(&us, timestr, is_duration) < 0) {
av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
is_duration ? "duration" : "date", context, timestr);
exit_program(1);
}
return us;
}
void show_help_options(const OptionDef *options, const char *msg, int req_flags,
int rej_flags, int alt_flags)
{
@ -304,7 +292,12 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt,
*(int64_t *)dst = num;
} else if (po->flags & OPT_TIME) {
*(int64_t *)dst = parse_time_or_die(opt, arg, 1);
ret = av_parse_time(dst, arg, 1);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Invalid duration for option %s: %s\n",
opt, arg);
return ret;
}
} else if (po->flags & OPT_FLOAT) {
ret = parse_number(opt, arg, OPT_FLOAT, -INFINITY, INFINITY, &num);
if (ret < 0)

View File

@ -112,23 +112,6 @@ int opt_timelimit(void *optctx, const char *opt, const char *arg);
int parse_number(const char *context, const char *numstr, int type,
double min, double max, double *dst);
/**
* Parse a string specifying a time and return its corresponding
* value as a number of microseconds. Exit from the application if
* the string cannot be correctly parsed.
*
* @param context the context of the value to be set (e.g. the
* corresponding command line option name)
* @param timestr the string to be parsed
* @param is_duration a flag which tells how to interpret timestr, if
* not zero timestr is interpreted as a duration, otherwise as a
* date
*
* @see av_parse_time()
*/
int64_t parse_time_or_die(const char *context, const char *timestr,
int is_duration);
typedef struct SpecifierOpt {
char *specifier; /**< stream/chapter/program/... specifier */
union {

View File

@ -2399,11 +2399,11 @@ static int compare_int64(const void *a, const void *b)
return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
}
static int parse_forced_key_frames(KeyframeForceCtx *kf, const Muxer *mux,
const char *spec)
static int parse_forced_key_frames(void *log, KeyframeForceCtx *kf,
const Muxer *mux, const char *spec)
{
const char *p;
int n = 1, i, size, index = 0;
int n = 1, i, ret, size, index = 0;
int64_t t, *pts;
for (p = spec; *p; p++)
@ -2430,7 +2430,16 @@ static int parse_forced_key_frames(KeyframeForceCtx *kf, const Muxer *mux,
!(pts = av_realloc_f(pts, size += nb_ch - 1,
sizeof(*pts))))
return AVERROR(ENOMEM);
t = p[8] ? parse_time_or_die("force_key_frames", p + 8, 1) : 0;
if (p[8]) {
ret = av_parse_time(&t, p + 8, 1);
if (ret < 0) {
av_log(log, AV_LOG_ERROR,
"Invalid chapter time offset: %s\n", p + 8);
goto fail;
}
} else
t = 0;
for (j = 0; j < nb_ch; j++) {
const AVChapter *c = ch[j];
@ -2441,7 +2450,13 @@ static int parse_forced_key_frames(KeyframeForceCtx *kf, const Muxer *mux,
} else {
av_assert1(index < size);
pts[index++] = parse_time_or_die("force_key_frames", p, 1);
ret = av_parse_time(&t, p, 1);
if (ret < 0) {
av_log(log, AV_LOG_ERROR, "Invalid keyframe time: %s\n", p);
goto fail;
}
pts[index++] = t;
}
p = next;
@ -2453,6 +2468,9 @@ static int parse_forced_key_frames(KeyframeForceCtx *kf, const Muxer *mux,
kf->pts = pts;
return 0;
fail:
av_freep(&pts);
return ret;
}
static int process_forced_keyframes(Muxer *mux, const OptionsContext *o)
@ -2487,7 +2505,7 @@ static int process_forced_keyframes(Muxer *mux, const OptionsContext *o)
} else if (!strcmp(forced_keyframes, "source_no_drop")) {
ost->kf.type = KF_FORCE_SOURCE_NO_DROP;
} else {
int ret = parse_forced_key_frames(&ost->kf, mux, forced_keyframes);
int ret = parse_forced_key_frames(ost, &ost->kf, mux, forced_keyframes);
if (ret < 0)
return ret;
}

View File

@ -326,7 +326,10 @@ static int opt_abort_on(void *optctx, const char *opt, const char *arg)
static int opt_stats_period(void *optctx, const char *opt, const char *arg)
{
int64_t user_stats_period = parse_time_or_die(opt, arg, 1);
int64_t user_stats_period;
int ret = av_parse_time(&user_stats_period, arg, 1);
if (ret < 0)
return ret;
if (user_stats_period <= 0) {
av_log(NULL, AV_LOG_ERROR, "stats_period %s must be positive.\n", arg);
@ -636,8 +639,16 @@ static int opt_recording_timestamp(void *optctx, const char *opt, const char *ar
{
OptionsContext *o = optctx;
char buf[128];
int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;
struct tm time = *gmtime((time_t*)&recording_timestamp);
int64_t recording_timestamp;
int ret;
struct tm time;
ret = av_parse_time(&recording_timestamp, arg, 0);
if (ret < 0)
return ret;
recording_timestamp /= 1e6;
time = *gmtime((time_t*)&recording_timestamp);
if (!strftime(buf, sizeof(buf), "creation_time=%Y-%m-%dT%H:%M:%S%z", &time))
return -1;
parse_option(o, "metadata", buf, options);

View File

@ -3485,18 +3485,6 @@ static int opt_sync(void *optctx, const char *opt, const char *arg)
return 0;
}
static int opt_seek(void *optctx, const char *opt, const char *arg)
{
start_time = parse_time_or_die(opt, arg, 1);
return 0;
}
static int opt_duration(void *optctx, const char *opt, const char *arg)
{
duration = parse_time_or_die(opt, arg, 1);
return 0;
}
static int opt_show_mode(void *optctx, const char *opt, const char *arg)
{
show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
@ -3561,8 +3549,8 @@ static const OptionDef options[] = {
{ "ast", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_specifier" },
{ "vst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_specifier" },
{ "sst", OPT_STRING | HAS_ARG | OPT_EXPERT, { &wanted_stream_spec[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_specifier" },
{ "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
{ "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
{ "ss", HAS_ARG | OPT_TIME, { &start_time }, "seek to a given position in seconds", "pos" },
{ "t", HAS_ARG | OPT_TIME, { &duration }, "play \"duration\" seconds of audio/video", "duration" },
{ "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
{ "seek_interval", OPT_FLOAT | HAS_ARG, { &seek_interval }, "set seek interval for left/right keys, in seconds", "seconds" },
{ "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },