Factorize code and provide ratio parsing consistency.
| ... | ... |
@@ -13,6 +13,12 @@ libavutil: 2011-04-18 |
| 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) |
| 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) |
| 3986 | 3986 |
} |
| 3987 | 3987 |
|
| 3988 | 3988 |
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); |
|
| 3989 |
+ if (frame_aspect_ratio) {
|
|
| 3990 |
+ AVRational q; |
|
| 3991 |
+ if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 || |
|
| 3992 |
+ q.num <= 0 || q.den <= 0) {
|
|
| 3993 |
+ av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio); |
|
| 3994 |
+ exit_program(1); |
|
| 3995 |
+ } |
|
| 3996 |
+ ost->frame_aspect_ratio = av_q2d(q); |
|
| 3997 |
+ } |
|
| 3991 | 3998 |
|
| 3992 | 3999 |
video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; |
| 3993 | 4000 |
MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st); |
| ... | ... |
@@ -24,6 +24,7 @@ |
| 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 {
|
| 33 | 33 |
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
| 34 | 34 |
{
|
| 35 | 35 |
AspectContext *aspect = ctx->priv; |
| 36 |
- double ratio; |
|
| 37 |
- int64_t gcd; |
|
| 38 |
- char c = 0; |
|
| 36 |
+ int ret; |
|
| 39 | 37 |
|
| 40 | 38 |
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) {
|
|
| 39 |
+ if ((ret = av_parse_ratio(&aspect->aspect, args, 100, 0, ctx)) < 0 || |
|
| 40 |
+ aspect->aspect.num < 0 || aspect->aspect.den <= 0) {
|
|
| 46 | 41 |
av_log(ctx, AV_LOG_ERROR, |
| 47 | 42 |
"Invalid string '%s' for aspect ratio.\n", args); |
| 48 |
- return AVERROR(EINVAL); |
|
| 43 |
+ return ret; |
|
| 49 | 44 |
} |
| 50 | 45 |
|
| 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 |
- } |
|
| 46 |
+ av_log(ctx, AV_LOG_INFO, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den); |
|
| 56 | 47 |
} |
| 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 | 48 |
return 0; |
| 63 | 49 |
} |
| 64 | 50 |
|
| ... | ... |
@@ -154,7 +154,7 @@ |
| 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 {
|
| 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 @@ |
| 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) |
| 124 | 124 |
{
|
| 125 | 125 |
int i, ret; |
| 126 | 126 |
int n = FF_ARRAY_ELEMS(video_rate_abbrs); |
| 127 |
- double res; |
|
| 128 | 127 |
|
| 129 | 128 |
/* First, we check our abbreviation table */ |
| 130 | 129 |
for (i = 0; i < n; ++i) |
| ... | ... |
@@ -134,10 +159,8 @@ int av_parse_video_rate(AVRational *rate, const char *arg) |
| 134 | 134 |
} |
| 135 | 135 |
|
| 136 | 136 |
/* 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) |
|
| 137 |
+ if ((ret = av_parse_ratio_quiet(rate, arg, 1001000)) < 0) |
|
| 139 | 138 |
return ret; |
| 140 |
- *rate = av_d2q(res, 1001000); |
|
| 141 | 139 |
if (rate->num <= 0 || rate->den <= 0) |
| 142 | 140 |
return AVERROR(EINVAL); |
| 143 | 141 |
return 0; |
| ... | ... |
@@ -29,6 +29,30 @@ |
| 29 | 29 |
*/ |
| 30 | 30 |
|
| 31 | 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 |
+ |
|
| 55 |
+/** |
|
| 32 | 56 |
* Parse str and put in width_ptr and height_ptr the detected values. |
| 33 | 57 |
* |
| 34 | 58 |
* @param[in,out] width_ptr pointer to the variable which will contain the detected |