Allow to specify the display aspect ratio adopted for rendering
subtitles.
... | ... |
@@ -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 |
} |