Browse code

ass: fix aspect ratio computation.

Nicolas George authored on 2012/03/23 04:59:36
Showing 3 changed files
... ...
@@ -761,9 +761,10 @@ separated by ":".
761 761
 A description of the accepted options follows.
762 762
 
763 763
 @table @option
764
-@item dar
765
-Specifies the display aspect ratio adopted for rendering the
766
-subtitles. Default value is "1.0".
764
+@item original_size
765
+Specifies the size of the original video, the video for which the ASS file
766
+was composed. Due to a misdesign in ASS aspect ratio arithmetic, this is
767
+necessary to correctly scale the fonts if the aspect ratio has been changed.
767 768
 @end table
768 769
 
769 770
 For example, to render the file @file{sub.ass} on top of the input
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 #define LIBAVFILTER_VERSION_MAJOR  2
32 32
 #define LIBAVFILTER_VERSION_MINOR 66
33
-#define LIBAVFILTER_VERSION_MICRO 100
33
+#define LIBAVFILTER_VERSION_MICRO 101
34 34
 
35 35
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
36 36
                                                LIBAVFILTER_VERSION_MINOR, \
... ...
@@ -45,14 +45,14 @@ typedef struct {
45 45
     char *filename;
46 46
     uint8_t rgba_map[4];
47 47
     int     pix_step[4];       ///< steps per pixel for each plane of the main output
48
-    char *dar_str;
49
-    AVRational dar;
48
+    char *original_size_str;
49
+    int original_w, original_h;
50 50
 } AssContext;
51 51
 
52 52
 #define OFFSET(x) offsetof(AssContext, x)
53 53
 
54 54
 static const AVOption ass_options[] = {
55
-    {"dar",  "set subtitles display aspect ratio", OFFSET(dar_str), AV_OPT_TYPE_STRING, {.str = "1.0"},  CHAR_MIN, CHAR_MAX },
55
+    {"original_size",  "set the size of the original video (used to scale fonts)", OFFSET(original_size_str), AV_OPT_TYPE_STRING, {.str = NULL},  CHAR_MIN, CHAR_MAX },
56 56
     {NULL},
57 57
 };
58 58
 
... ...
@@ -107,10 +107,11 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
107 107
         return ret;
108 108
     }
109 109
 
110
-    if (av_parse_ratio(&ass->dar, ass->dar_str, 100, 0, ctx) < 0 ||
111
-        ass->dar.num < 0 || ass->dar.den <= 0) {
110
+    if (ass->original_size_str &&
111
+        av_parse_video_size(&ass->original_w, &ass->original_h,
112
+                            ass->original_size_str) < 0) {
112 113
         av_log(ctx, AV_LOG_ERROR,
113
-               "Invalid string '%s' or value for display aspect ratio.\n", ass->dar_str);
114
+               "Invalid original size '%s'.\n", ass->original_size_str);
114 115
         return AVERROR(EINVAL);
115 116
     }
116 117
 
... ...
@@ -136,8 +137,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
136 136
     }
137 137
 
138 138
     ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
139
-
140
-    av_log(ctx, AV_LOG_INFO, "dar:%f\n", av_q2d(ass->dar));
141 139
     return 0;
142 140
 }
143 141
 
... ...
@@ -146,7 +145,7 @@ static av_cold void uninit(AVFilterContext *ctx)
146 146
     AssContext *ass = ctx->priv;
147 147
 
148 148
     av_freep(&ass->filename);
149
-    av_freep(&ass->dar_str);
149
+    av_freep(&ass->original_size_str);
150 150
     if (ass->track)
151 151
         ass_free_track(ass->track);
152 152
     if (ass->renderer)
... ...
@@ -173,8 +172,6 @@ static int config_input(AVFilterLink *inlink)
173 173
 {
174 174
     AssContext *ass = inlink->dst->priv;
175 175
     const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[inlink->format];
176
-    double sar = inlink->sample_aspect_ratio.num ?
177
-        av_q2d(inlink->sample_aspect_ratio) : 1;
178 176
 
179 177
     av_image_fill_max_pixsteps(ass->pix_step, NULL, pix_desc);
180 178
     ff_fill_rgba_map(ass->rgba_map, inlink->format);
... ...
@@ -183,7 +180,9 @@ static int config_input(AVFilterLink *inlink)
183 183
     ass->vsub = pix_desc->log2_chroma_h;
184 184
 
185 185
     ass_set_frame_size  (ass->renderer, inlink->w, inlink->h);
186
-    ass_set_aspect_ratio(ass->renderer, av_q2d(ass->dar), sar);
186
+    if (ass->original_w && ass->original_h)
187
+        ass_set_aspect_ratio(ass->renderer, (double)inlink->w / inlink->h,
188
+                             (double)ass->original_w / ass->original_h);
187 189
 
188 190
     return 0;
189 191
 }