Factorize code and provide ratio parsing consistency.tags/n0.11
| @@ -13,6 +13,12 @@ libavutil: 2011-04-18 | |||
| API changes, most recent first: | |||
| 2012-02-06 - xxxxxxx - lavu 51.38.100 | |||
| Add av_parse_ratio() function to parseutils.h. | |||
| 2012-02-06 - xxxxxxx - lavu 51.38.100 | |||
| Add AV_LOG_MAX_OFFSET macro to log.h. | |||
| 2012-02-02 - xxxxxxx - lavu 51.37.100 | |||
| Add public timecode helpers. | |||
| @@ -3141,30 +3141,6 @@ static int opt_pad(const char *opt, const char *arg) | |||
| return -1; | |||
| } | |||
| static double parse_frame_aspect_ratio(const char *arg) | |||
| { | |||
| int x = 0, y = 0; | |||
| double ar = 0; | |||
| const char *p; | |||
| char *end; | |||
| p = strchr(arg, ':'); | |||
| if (p) { | |||
| x = strtol(arg, &end, 10); | |||
| if (end == p) | |||
| y = strtol(end + 1, &end, 10); | |||
| if (x > 0 && y > 0) | |||
| ar = (double)x / (double)y; | |||
| } else | |||
| ar = strtod(arg, NULL); | |||
| if (!ar) { | |||
| av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n"); | |||
| exit_program(1); | |||
| } | |||
| return ar; | |||
| } | |||
| static int opt_video_channel(const char *opt, const char *arg) | |||
| { | |||
| av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -channel.\n"); | |||
| @@ -3986,8 +3962,15 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) | |||
| } | |||
| MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st); | |||
| if (frame_aspect_ratio) | |||
| ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio); | |||
| if (frame_aspect_ratio) { | |||
| AVRational q; | |||
| if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 || | |||
| q.num <= 0 || q.den <= 0) { | |||
| av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio); | |||
| exit_program(1); | |||
| } | |||
| ost->frame_aspect_ratio = av_q2d(q); | |||
| } | |||
| video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; | |||
| MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st); | |||
| @@ -24,6 +24,7 @@ | |||
| */ | |||
| #include "libavutil/mathematics.h" | |||
| #include "libavutil/parseutils.h" | |||
| #include "avfilter.h" | |||
| typedef struct { | |||
| @@ -33,32 +34,18 @@ typedef struct { | |||
| static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) | |||
| { | |||
| AspectContext *aspect = ctx->priv; | |||
| double ratio; | |||
| int64_t gcd; | |||
| char c = 0; | |||
| int ret; | |||
| if (args) { | |||
| if (sscanf(args, "%d:%d%c", &aspect->aspect.num, &aspect->aspect.den, &c) != 2) | |||
| if (sscanf(args, "%lf%c", &ratio, &c) == 1) | |||
| aspect->aspect = av_d2q(ratio, 100); | |||
| if (c || aspect->aspect.num <= 0 || aspect->aspect.den <= 0) { | |||
| if ((ret = av_parse_ratio(&aspect->aspect, args, 100, 0, ctx)) < 0 || | |||
| aspect->aspect.num < 0 || aspect->aspect.den <= 0) { | |||
| av_log(ctx, AV_LOG_ERROR, | |||
| "Invalid string '%s' for aspect ratio.\n", args); | |||
| return AVERROR(EINVAL); | |||
| return ret; | |||
| } | |||
| gcd = av_gcd(FFABS(aspect->aspect.num), FFABS(aspect->aspect.den)); | |||
| if (gcd) { | |||
| aspect->aspect.num /= gcd; | |||
| aspect->aspect.den /= gcd; | |||
| } | |||
| av_log(ctx, AV_LOG_INFO, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den); | |||
| } | |||
| if (aspect->aspect.den == 0) | |||
| aspect->aspect = (AVRational) {0, 1}; | |||
| av_log(ctx, AV_LOG_INFO, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den); | |||
| return 0; | |||
| } | |||
| @@ -154,7 +154,7 @@ | |||
| */ | |||
| #define LIBAVUTIL_VERSION_MAJOR 51 | |||
| #define LIBAVUTIL_VERSION_MINOR 37 | |||
| #define LIBAVUTIL_VERSION_MINOR 38 | |||
| #define LIBAVUTIL_VERSION_MICRO 100 | |||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | |||
| @@ -124,6 +124,8 @@ typedef struct AVClass { | |||
| */ | |||
| #define AV_LOG_DEBUG 48 | |||
| #define AV_LOG_MAX_OFFSET (AV_LOG_DEBUG - AV_LOG_QUIET) | |||
| /** | |||
| * Send the specified message to the log if the level is less than or equal | |||
| * to the current av_log_level. By default, all logging messages are sent to | |||
| @@ -31,6 +31,32 @@ | |||
| #include "random_seed.h" | |||
| #include "parseutils.h" | |||
| int av_parse_ratio(AVRational *q, const char *str, int max, | |||
| int log_offset, void *log_ctx) | |||
| { | |||
| char c; | |||
| int ret; | |||
| int64_t gcd; | |||
| if (sscanf(str, "%d:%d%c", &q->num, &q->den, &c) != 2) { | |||
| double d; | |||
| ret = av_expr_parse_and_eval(&d, str, NULL, NULL, | |||
| NULL, NULL, NULL, NULL, | |||
| NULL, log_offset, log_ctx); | |||
| if (ret < 0) | |||
| return ret; | |||
| *q = av_d2q(d, max); | |||
| } | |||
| gcd = av_gcd(FFABS(q->num), FFABS(q->den)); | |||
| if (gcd) { | |||
| q->num /= gcd; | |||
| q->den /= gcd; | |||
| } | |||
| return 0; | |||
| } | |||
| typedef struct { | |||
| const char *abbr; | |||
| int width, height; | |||
| @@ -124,7 +150,6 @@ int av_parse_video_rate(AVRational *rate, const char *arg) | |||
| { | |||
| int i, ret; | |||
| int n = FF_ARRAY_ELEMS(video_rate_abbrs); | |||
| double res; | |||
| /* First, we check our abbreviation table */ | |||
| for (i = 0; i < n; ++i) | |||
| @@ -134,10 +159,8 @@ int av_parse_video_rate(AVRational *rate, const char *arg) | |||
| } | |||
| /* Then, we try to parse it as fraction */ | |||
| if ((ret = av_expr_parse_and_eval(&res, arg, NULL, NULL, NULL, NULL, NULL, NULL, | |||
| NULL, 0, NULL)) < 0) | |||
| if ((ret = av_parse_ratio_quiet(rate, arg, 1001000)) < 0) | |||
| return ret; | |||
| *rate = av_d2q(res, 1001000); | |||
| if (rate->num <= 0 || rate->den <= 0) | |||
| return AVERROR(EINVAL); | |||
| return 0; | |||
| @@ -28,6 +28,30 @@ | |||
| * misc parsing utilities | |||
| */ | |||
| /** | |||
| * Parse str and store the parsed ratio in q. | |||
| * | |||
| * Note that a ratio with infinite (1/0) or negative value is | |||
| * considered valid, so you should check on the returned value if you | |||
| * want to exclude those values. | |||
| * | |||
| * The undefined value can be expressed using the "0:0" string. | |||
| * | |||
| * @param[in,out] q pointer to the AVRational which will contain the ratio | |||
| * @param[in] str the string to parse: it has to be a string in the format | |||
| * num:den, a float number or an expression | |||
| * @param[in] max the maximum allowed numerator and denominator | |||
| * @param[in] log_offset log level offset which is applied to the log | |||
| * level of log_ctx | |||
| * @param[in] log_ctx parent logging context | |||
| * @return >= 0 on success, a negative error code otherwise | |||
| */ | |||
| int av_parse_ratio(AVRational *q, const char *str, int max, | |||
| int log_offset, void *log_ctx); | |||
| #define av_parse_ratio_quiet(rate, str, max) \ | |||
| av_parse_ratio(rate, str, max, AV_LOG_MAX_OFFSET, NULL) | |||
| /** | |||
| * Parse str and put in width_ptr and height_ptr the detected values. | |||
| * | |||