Factorize code and provide ratio parsing consistency.
Unified · Split
| @@ -13,6 +13,12 @@ libavutil: 2011-04-18 · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | API changes, most recent first: |
| 15 | 15 | |
| 16 | +2012-02-06 - xxxxxxx - lavu 51.38.100 | |
| 17 | + Add av_parse_ratio() function to parseutils.h. | |
| 18 | + | |
| 19 | +2012-02-06 - xxxxxxx - lavu 51.38.100 | |
| 20 | + Add AV_LOG_MAX_OFFSET macro to log.h. | |
| 21 | + | |
| 16 | 22 | 2012-02-02 - xxxxxxx - lavu 51.37.100 |
| 17 | 23 | Add public timecode helpers. |
| 18 | 24 | |
| @@ -3141,30 +3141,6 @@ static int opt_pad(const char *opt, const char *arg) · 3140 unmodified lines | ||
| 3141 | 3141 | return -1; |
| 3142 | 3142 | } |
| 3143 | 3143 | |
| 3144 | −static double parse_frame_aspect_ratio(const char *arg) | |
| 3145 | −{ | |
| 3146 | − int x = 0, y = 0; | |
| 3147 | − double ar = 0; | |
| 3148 | − const char *p; | |
| 3149 | − char *end; | |
| 3150 | − | |
| 3151 | − p = strchr(arg, ':'); | |
| 3152 | − if (p) { | |
| 3153 | − x = strtol(arg, &end, 10); | |
| 3154 | − if (end == p) | |
| 3155 | − y = strtol(end + 1, &end, 10); | |
| 3156 | − if (x > 0 && y > 0) | |
| 3157 | − ar = (double)x / (double)y; | |
| 3158 | − } else | |
| 3159 | − ar = strtod(arg, NULL); | |
| 3160 | − | |
| 3161 | − if (!ar) { | |
| 3162 | − av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n"); | |
| 3163 | − exit_program(1); | |
| 3164 | − } | |
| 3165 | − return ar; | |
| 3166 | −} | |
| 3167 | − | |
| 3168 | 3144 | static int opt_video_channel(const char *opt, const char *arg) |
| 3169 | 3145 | { |
| 3170 | 3146 | 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) · 815 unmodified lines | ||
| 3986 | 3962 | } |
| 3987 | 3963 | |
| 3988 | 3964 | MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st); |
| 3989 | − if (frame_aspect_ratio) | |
| 3990 | − ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio); | |
| 3965 | + if (frame_aspect_ratio) { | |
| 3966 | + AVRational q; | |
| 3967 | + if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 || | |
| 3968 | + q.num <= 0 || q.den <= 0) { | |
| 3969 | + av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio); | |
| 3970 | + exit_program(1); | |
| 3971 | + } | |
| 3972 | + ost->frame_aspect_ratio = av_q2d(q); | |
| 3973 | + } | |
| 3991 | 3974 | |
| 3992 | 3975 | video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; |
| 3993 | 3976 | MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st); |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | */ |
| 25 | 25 | |
| 26 | 26 | #include "libavutil/mathematics.h" |
| 27 | +#include "libavutil/parseutils.h" | |
| 27 | 28 | #include "avfilter.h" |
| 28 | 29 | |
| 29 | 30 | typedef struct { |
| @@ -33,32 +34,18 @@ typedef struct { · 3 unmodified lines | ||
| 33 | 34 | static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
| 34 | 35 | { |
| 35 | 36 | AspectContext *aspect = ctx->priv; |
| 36 | − double ratio; | |
| 37 | − int64_t gcd; | |
| 38 | − char c = 0; | |
| 37 | + int ret; | |
| 39 | 38 | |
| 40 | 39 | if (args) { |
| 41 | − if (sscanf(args, "%d:%d%c", &aspect->aspect.num, &aspect->aspect.den, &c) != 2) | |
| 42 | − if (sscanf(args, "%lf%c", &ratio, &c) == 1) | |
| 43 | − aspect->aspect = av_d2q(ratio, 100); | |
| 44 | − | |
| 45 | − if (c || aspect->aspect.num <= 0 || aspect->aspect.den <= 0) { | |
| 40 | + if ((ret = av_parse_ratio(&aspect->aspect, args, 100, 0, ctx)) < 0 || | |
| 41 | + aspect->aspect.num < 0 || aspect->aspect.den <= 0) { | |
| 46 | 42 | av_log(ctx, AV_LOG_ERROR, |
| 47 | 43 | "Invalid string '%s' for aspect ratio.\n", args); |
| 48 | − return AVERROR(EINVAL); | |
| 44 | + return ret; | |
| 49 | 45 | } |
| 50 | 46 | |
| 51 | − gcd = av_gcd(FFABS(aspect->aspect.num), FFABS(aspect->aspect.den)); | |
| 52 | − if (gcd) { | |
| 53 | − aspect->aspect.num /= gcd; | |
| 54 | − aspect->aspect.den /= gcd; | |
| 55 | − } | |
| 47 | + av_log(ctx, AV_LOG_INFO, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den); | |
| 56 | 48 | } |
| 57 | − | |
| 58 | − if (aspect->aspect.den == 0) | |
| 59 | − aspect->aspect = (AVRational) {0, 1}; | |
| 60 | − | |
| 61 | − av_log(ctx, AV_LOG_INFO, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den); | |
| 62 | 49 | return 0; |
| 63 | 50 | } |
| 64 | 51 | |
| @@ -154,7 +154,7 @@ · 153 unmodified lines | ||
| 154 | 154 | */ |
| 155 | 155 | |
| 156 | 156 | #define LIBAVUTIL_VERSION_MAJOR 51 |
| 157 | −#define LIBAVUTIL_VERSION_MINOR 37 | |
| 157 | +#define LIBAVUTIL_VERSION_MINOR 38 | |
| 158 | 158 | #define LIBAVUTIL_VERSION_MICRO 100 |
| 159 | 159 | |
| 160 | 160 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |
| @@ -124,6 +124,8 @@ typedef struct AVClass { · 123 unmodified lines | ||
| 124 | 124 | */ |
| 125 | 125 | #define AV_LOG_DEBUG 48 |
| 126 | 126 | |
| 127 | +#define AV_LOG_MAX_OFFSET (AV_LOG_DEBUG - AV_LOG_QUIET) | |
| 128 | + | |
| 127 | 129 | /** |
| 128 | 130 | * Send the specified message to the log if the level is less than or equal |
| 129 | 131 | * to the current av_log_level. By default, all logging messages are sent to |
| @@ -31,6 +31,32 @@ · 30 unmodified lines | ||
| 31 | 31 | #include "random_seed.h" |
| 32 | 32 | #include "parseutils.h" |
| 33 | 33 | |
| 34 | +int av_parse_ratio(AVRational *q, const char *str, int max, | |
| 35 | + int log_offset, void *log_ctx) | |
| 36 | +{ | |
| 37 | + char c; | |
| 38 | + int ret; | |
| 39 | + int64_t gcd; | |
| 40 | + | |
| 41 | + if (sscanf(str, "%d:%d%c", &q->num, &q->den, &c) != 2) { | |
| 42 | + double d; | |
| 43 | + ret = av_expr_parse_and_eval(&d, str, NULL, NULL, | |
| 44 | + NULL, NULL, NULL, NULL, | |
| 45 | + NULL, log_offset, log_ctx); | |
| 46 | + if (ret < 0) | |
| 47 | + return ret; | |
| 48 | + *q = av_d2q(d, max); | |
| 49 | + } | |
| 50 | + | |
| 51 | + gcd = av_gcd(FFABS(q->num), FFABS(q->den)); | |
| 52 | + if (gcd) { | |
| 53 | + q->num /= gcd; | |
| 54 | + q->den /= gcd; | |
| 55 | + } | |
| 56 | + | |
| 57 | + return 0; | |
| 58 | +} | |
| 59 | + | |
| 34 | 60 | typedef struct { |
| 35 | 61 | const char *abbr; |
| 36 | 62 | int width, height; |
| @@ -124,7 +150,6 @@ int av_parse_video_rate(AVRational *rate, const char *arg) · 87 unmodified lines | ||
| 124 | 150 | { |
| 125 | 151 | int i, ret; |
| 126 | 152 | int n = FF_ARRAY_ELEMS(video_rate_abbrs); |
| 127 | − double res; | |
| 128 | 153 | |
| 129 | 154 | /* First, we check our abbreviation table */ |
| 130 | 155 | for (i = 0; i < n; ++i) |
| @@ -134,10 +159,8 @@ int av_parse_video_rate(AVRational *rate, const char *arg) · 3 unmodified lines | ||
| 134 | 159 | } |
| 135 | 160 | |
| 136 | 161 | /* Then, we try to parse it as fraction */ |
| 137 | − if ((ret = av_expr_parse_and_eval(&res, arg, NULL, NULL, NULL, NULL, NULL, NULL, | |
| 138 | − NULL, 0, NULL)) < 0) | |
| 162 | + if ((ret = av_parse_ratio_quiet(rate, arg, 1001000)) < 0) | |
| 139 | 163 | return ret; |
| 140 | − *rate = av_d2q(res, 1001000); | |
| 141 | 164 | if (rate->num <= 0 || rate->den <= 0) |
| 142 | 165 | return AVERROR(EINVAL); |
| 143 | 166 | return 0; |
| @@ -28,6 +28,30 @@ · 27 unmodified lines | ||
| 28 | 28 | * misc parsing utilities |
| 29 | 29 | */ |
| 30 | 30 | |
| 31 | +/** | |
| 32 | + * Parse str and store the parsed ratio in q. | |
| 33 | + * | |
| 34 | + * Note that a ratio with infinite (1/0) or negative value is | |
| 35 | + * considered valid, so you should check on the returned value if you | |
| 36 | + * want to exclude those values. | |
| 37 | + * | |
| 38 | + * The undefined value can be expressed using the "0:0" string. | |
| 39 | + * | |
| 40 | + * @param[in,out] q pointer to the AVRational which will contain the ratio | |
| 41 | + * @param[in] str the string to parse: it has to be a string in the format | |
| 42 | + * num:den, a float number or an expression | |
| 43 | + * @param[in] max the maximum allowed numerator and denominator | |
| 44 | + * @param[in] log_offset log level offset which is applied to the log | |
| 45 | + * level of log_ctx | |
| 46 | + * @param[in] log_ctx parent logging context | |
| 47 | + * @return >= 0 on success, a negative error code otherwise | |
| 48 | + */ | |
| 49 | +int av_parse_ratio(AVRational *q, const char *str, int max, | |
| 50 | + int log_offset, void *log_ctx); | |
| 51 | + | |
| 52 | +#define av_parse_ratio_quiet(rate, str, max) \ | |
| 53 | + av_parse_ratio(rate, str, max, AV_LOG_MAX_OFFSET, NULL) | |
| 54 | + | |
| 31 | 55 | /** |
| 32 | 56 | * Parse str and put in width_ptr and height_ptr the detected values. |
| 33 | 57 | * |