Browse code

lavfi/ass: add dar option

Allow to specify the display aspect ratio adopted for rendering
subtitles.

Stefano Sabatini authored on 2012/03/20 03:28:56
Showing 3 changed files
... ...
@@ -753,7 +753,18 @@ using the libass library.
753 753
 To enable compilation of this filter you need to configure FFmpeg with
754 754
 @code{--enable-libass}.
755 755
 
756
-This filter accepts in input the name of the ass file to render.
756
+This filter accepts the syntax: @var{ass_filename}[:@var{options}],
757
+where @var{ass_filename} is the filename of the ASS file to read, and
758
+@var{options} is an optional sequence of @var{key}=@var{value} pairs,
759
+separated by ":".
760
+
761
+A description of the accepted options follows.
762
+
763
+@table @option
764
+@item dar
765
+Specifies the display aspect ratio adopted for rendering the
766
+subtitles. Default value is "1.0".
767
+@end table
757 768
 
758 769
 For example, to render the file @file{sub.ass} on top of the input
759 770
 video, use the command:
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 #define LIBAVFILTER_VERSION_MAJOR  2
32 32
 #define LIBAVFILTER_VERSION_MINOR 65
33
-#define LIBAVFILTER_VERSION_MICRO 101
33
+#define LIBAVFILTER_VERSION_MICRO 102
34 34
 
35 35
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
36 36
                                                LIBAVFILTER_VERSION_MINOR, \
... ...
@@ -30,11 +30,14 @@
30 30
 
31 31
 #include "libavutil/avstring.h"
32 32
 #include "libavutil/imgutils.h"
33
+#include "libavutil/opt.h"
34
+#include "libavutil/parseutils.h"
33 35
 #include "libavutil/pixdesc.h"
34 36
 #include "drawutils.h"
35 37
 #include "avfilter.h"
36 38
 
37 39
 typedef struct {
40
+    const AVClass *class;
38 41
     ASS_Library  *library;
39 42
     ASS_Renderer *renderer;
40 43
     ASS_Track    *track;
... ...
@@ -42,8 +45,28 @@ typedef struct {
42 42
     char *filename;
43 43
     uint8_t rgba_map[4];
44 44
     int     pix_step[4];       ///< steps per pixel for each plane of the main output
45
+    char *dar_str;
46
+    AVRational dar;
45 47
 } AssContext;
46 48
 
49
+#define OFFSET(x) offsetof(AssContext, x)
50
+
51
+static const AVOption ass_options[] = {
52
+    {"dar",  "set subtitles display aspect ratio", OFFSET(dar_str), AV_OPT_TYPE_STRING, {.str = "1.0"},  CHAR_MIN, CHAR_MAX },
53
+    {NULL},
54
+};
55
+
56
+static const char *ass_get_name(void *ctx)
57
+{
58
+    return "ass";
59
+}
60
+
61
+static const AVClass ass_class = {
62
+    "AssContext",
63
+    ass_get_name,
64
+    ass_options
65
+};
66
+
47 67
 /* libass supports a log level ranging from 0 to 7 */
48 68
 int ass_libav_log_level_map[] = {
49 69
     AV_LOG_QUIET,               /* 0 */
... ...
@@ -67,6 +90,10 @@ static void ass_log(int ass_level, const char *fmt, va_list args, void *ctx)
67 67
 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
68 68
 {
69 69
     AssContext *ass = ctx->priv;
70
+    int ret;
71
+
72
+    ass->class = &ass_class;
73
+    av_opt_set_defaults(ass);
70 74
 
71 75
     if (args)
72 76
         ass->filename = av_get_token(&args, ":");
... ...
@@ -75,6 +102,18 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
75 75
         return AVERROR(EINVAL);
76 76
     }
77 77
 
78
+    if (*args++ == ':' && (ret = av_set_options_string(ass, args, "=", ":")) < 0) {
79
+        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
80
+        return ret;
81
+    }
82
+
83
+    if (av_parse_ratio(&ass->dar, ass->dar_str, 100, 0, ctx) < 0 ||
84
+        ass->dar.num < 0 || ass->dar.den <= 0) {
85
+        av_log(ctx, AV_LOG_ERROR,
86
+               "Invalid string '%s' or value for display aspect ratio.\n", ass->dar_str);
87
+        return AVERROR(EINVAL);
88
+    }
89
+
78 90
     ass->library = ass_library_init();
79 91
     if (!ass->library) {
80 92
         av_log(ctx, AV_LOG_ERROR, "Could not initialize libass.\n");
... ...
@@ -98,6 +137,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
98 98
 
99 99
     ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
100 100
 
101
+    av_log(ctx, AV_LOG_INFO, "dar:%f\n", av_q2d(ass->dar));
101 102
     return 0;
102 103
 }
103 104
 
... ...
@@ -106,6 +146,7 @@ static av_cold void uninit(AVFilterContext *ctx)
106 106
     AssContext *ass = ctx->priv;
107 107
 
108 108
     av_freep(&ass->filename);
109
+    av_freep(&ass->dar_str);
109 110
     if (ass->track)
110 111
         ass_free_track(ass->track);
111 112
     if (ass->renderer)
... ...
@@ -142,7 +183,7 @@ static int config_input(AVFilterLink *inlink)
142 142
     ass->vsub = pix_desc->log2_chroma_h;
143 143
 
144 144
     ass_set_frame_size  (ass->renderer, inlink->w, inlink->h);
145
-    ass_set_aspect_ratio(ass->renderer, 1.0, sar);
145
+    ass_set_aspect_ratio(ass->renderer, av_q2d(ass->dar), sar);
146 146
 
147 147
     return 0;
148 148
 }