Factorize code and provide ratio parsing consistency.
Unified · Split
| @@ -13,6 +13,12 @@ libavutil: 2011-04-18 · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | API changes, most recent first: | 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 | 2012-02-02 - xxxxxxx - lavu 51.37.100 | 22 | 2012-02-02 - xxxxxxx - lavu 51.37.100 |
| 17 | Add public timecode helpers. | 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 | return -1; | 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 | static int opt_video_channel(const char *opt, const char *arg) | 3144 | static int opt_video_channel(const char *opt, const char *arg) |
| 3169 | { | 3145 | { |
| 3170 | av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -channel.\n"); | 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 | MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st); | 3964 | MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st); |
| 3989 | if (frame_aspect_ratio) | 3965 | if (frame_aspect_ratio) { |
| 3990 | ost->frame_aspect_ratio = parse_frame_aspect_ratio(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 | video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; | 3975 | video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; |
| 3993 | MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st); | 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 | #include "libavutil/mathematics.h" | 26 | #include "libavutil/mathematics.h" |
| 27 | #include "libavutil/parseutils.h" | ||
| 27 | #include "avfilter.h" | 28 | #include "avfilter.h" |
| 28 | 29 | ||
| 29 | typedef struct { | 30 | typedef struct { |
| @@ -33,32 +34,18 @@ typedef struct { · 3 unmodified lines | |||
| 33 | static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) | 34 | static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
| 34 | { | 35 | { |
| 35 | AspectContext *aspect = ctx->priv; | 36 | AspectContext *aspect = ctx->priv; |
| 36 | double ratio; | 37 | int ret; |
| 37 | int64_t gcd; | ||
| 38 | char c = 0; | ||
| 39 | 38 | ||
| 40 | if (args) { | 39 | if (args) { |
| 41 | if (sscanf(args, "%d:%d%c", &aspect->aspect.num, &aspect->aspect.den, &c) != 2) | 40 | if ((ret = av_parse_ratio(&aspect->aspect, args, 100, 0, ctx)) < 0 || |
| 42 | if (sscanf(args, "%lf%c", &ratio, &c) == 1) | 41 | aspect->aspect.num < 0 || aspect->aspect.den <= 0) { |
| 43 | aspect->aspect = av_d2q(ratio, 100); | ||
| 44 | |||
| 45 | if (c || aspect->aspect.num <= 0 || aspect->aspect.den <= 0) { | ||
| 46 | av_log(ctx, AV_LOG_ERROR, | 42 | av_log(ctx, AV_LOG_ERROR, |
| 47 | "Invalid string '%s' for aspect ratio.\n", args); | 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)); | 47 | av_log(ctx, AV_LOG_INFO, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den); |
| 52 | if (gcd) { | ||
| 53 | aspect->aspect.num /= gcd; | ||
| 54 | aspect->aspect.den /= gcd; | ||
| 55 | } | ||
| 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 | return 0; | 49 | return 0; |
| 63 | } | 50 | } |
| 64 | 51 | ||
| @@ -154,7 +154,7 @@ · 153 unmodified lines | |||
| 154 | */ | 154 | */ |
| 155 | 155 | ||
| 156 | #define LIBAVUTIL_VERSION_MAJOR 51 | 156 | #define LIBAVUTIL_VERSION_MAJOR 51 |
| 157 | #define LIBAVUTIL_VERSION_MINOR 37 | 157 | #define LIBAVUTIL_VERSION_MINOR 38 |
| 158 | #define LIBAVUTIL_VERSION_MICRO 100 | 158 | #define LIBAVUTIL_VERSION_MICRO 100 |
| 159 | 159 | ||
| 160 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | 160 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |
| @@ -124,6 +124,8 @@ typedef struct AVClass { · 123 unmodified lines | |||
| 124 | */ | 124 | */ |
| 125 | #define AV_LOG_DEBUG 48 | 125 | #define AV_LOG_DEBUG 48 |
| 126 | 126 | ||
| 127 | #define AV_LOG_MAX_OFFSET (AV_LOG_DEBUG - AV_LOG_QUIET) | ||
| 128 | |||
| 127 | /** | 129 | /** |
| 128 | * Send the specified message to the log if the level is less than or equal | 130 | * Send the specified message to the log if the level is less than or equal |
| 129 | * to the current av_log_level. By default, all logging messages are sent to | 131 | * to the current av_log_level. By default, all logging messages are sent to |
| @@ -31,6 +31,32 @@ · 30 unmodified lines | |||
| 31 | #include "random_seed.h" | 31 | #include "random_seed.h" |
| 32 | #include "parseutils.h" | 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 | typedef struct { | 60 | typedef struct { |
| 35 | const char *abbr; | 61 | const char *abbr; |
| 36 | int width, height; | 62 | int width, height; |
| @@ -124,7 +150,6 @@ int av_parse_video_rate(AVRational *rate, const char *arg) · 87 unmodified lines | |||
| 124 | { | 150 | { |
| 125 | int i, ret; | 151 | int i, ret; |
| 126 | int n = FF_ARRAY_ELEMS(video_rate_abbrs); | 152 | int n = FF_ARRAY_ELEMS(video_rate_abbrs); |
| 127 | double res; | ||
| 128 | 153 | ||
| 129 | /* First, we check our abbreviation table */ | 154 | /* First, we check our abbreviation table */ |
| 130 | for (i = 0; i < n; ++i) | 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 | /* Then, we try to parse it as fraction */ | 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, | 162 | if ((ret = av_parse_ratio_quiet(rate, arg, 1001000)) < 0) |
| 138 | NULL, 0, NULL)) < 0) | ||
| 139 | return ret; | 163 | return ret; |
| 140 | *rate = av_d2q(res, 1001000); | ||
| 141 | if (rate->num <= 0 || rate->den <= 0) | 164 | if (rate->num <= 0 || rate->den <= 0) |
| 142 | return AVERROR(EINVAL); | 165 | return AVERROR(EINVAL); |
| 143 | return 0; | 166 | return 0; |
| @@ -28,6 +28,30 @@ · 27 unmodified lines | |||
| 28 | * misc parsing utilities | 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 | * Parse str and put in width_ptr and height_ptr the detected values. | 56 | * Parse str and put in width_ptr and height_ptr the detected values. |
| 33 | * | 57 | * |