lavfi/ass: add dar option
authorStefano Sabatini <stefasab@gmail.com>
Mon, 19 Mar 2012 18:28:56 +0000 (19:28 +0100)
committerStefano Sabatini <stefasab@gmail.com>
Wed, 21 Mar 2012 14:14:28 +0000 (15:14 +0100)
Allow to specify the display aspect ratio adopted for rendering
subtitles.

doc/filters.texi
libavfilter/version.h
libavfilter/vf_ass.c

index 9aedb01..2863f8c 100644 (file)
@@ -753,7 +753,18 @@ using the libass library.
 To enable compilation of this filter you need to configure FFmpeg with
 @code{--enable-libass}.
 
-This filter accepts in input the name of the ass file to render.
+This filter accepts the syntax: @var{ass_filename}[:@var{options}],
+where @var{ass_filename} is the filename of the ASS file to read, and
+@var{options} is an optional sequence of @var{key}=@var{value} pairs,
+separated by ":".
+
+A description of the accepted options follows.
+
+@table @option
+@item dar
+Specifies the display aspect ratio adopted for rendering the
+subtitles. Default value is "1.0".
+@end table
 
 For example, to render the file @file{sub.ass} on top of the input
 video, use the command:
index 2a85b2c..fa24bbd 100644 (file)
@@ -30,7 +30,7 @@
 
 #define LIBAVFILTER_VERSION_MAJOR  2
 #define LIBAVFILTER_VERSION_MINOR 65
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MICRO 102
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
                                                LIBAVFILTER_VERSION_MINOR, \
index b63d0db..bf13287 100644 (file)
 
 #include "libavutil/avstring.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
 #include "drawutils.h"
 #include "avfilter.h"
 
 typedef struct {
+    const AVClass *class;
     ASS_Library  *library;
     ASS_Renderer *renderer;
     ASS_Track    *track;
@@ -42,8 +45,28 @@ typedef struct {
     char *filename;
     uint8_t rgba_map[4];
     int     pix_step[4];       ///< steps per pixel for each plane of the main output
+    char *dar_str;
+    AVRational dar;
 } AssContext;
 
+#define OFFSET(x) offsetof(AssContext, x)
+
+static const AVOption ass_options[] = {
+    {"dar",  "set subtitles display aspect ratio", OFFSET(dar_str), AV_OPT_TYPE_STRING, {.str = "1.0"},  CHAR_MIN, CHAR_MAX },
+    {NULL},
+};
+
+static const char *ass_get_name(void *ctx)
+{
+    return "ass";
+}
+
+static const AVClass ass_class = {
+    "AssContext",
+    ass_get_name,
+    ass_options
+};
+
 /* libass supports a log level ranging from 0 to 7 */
 int ass_libav_log_level_map[] = {
     AV_LOG_QUIET,               /* 0 */
@@ -67,6 +90,10 @@ static void ass_log(int ass_level, const char *fmt, va_list args, void *ctx)
 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
 {
     AssContext *ass = ctx->priv;
+    int ret;
+
+    ass->class = &ass_class;
+    av_opt_set_defaults(ass);
 
     if (args)
         ass->filename = av_get_token(&args, ":");
@@ -75,6 +102,18 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
         return AVERROR(EINVAL);
     }
 
+    if (*args++ == ':' && (ret = av_set_options_string(ass, args, "=", ":")) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+        return ret;
+    }
+
+    if (av_parse_ratio(&ass->dar, ass->dar_str, 100, 0, ctx) < 0 ||
+        ass->dar.num < 0 || ass->dar.den <= 0) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Invalid string '%s' or value for display aspect ratio.\n", ass->dar_str);
+        return AVERROR(EINVAL);
+    }
+
     ass->library = ass_library_init();
     if (!ass->library) {
         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)
 
     ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1);
 
+    av_log(ctx, AV_LOG_INFO, "dar:%f\n", av_q2d(ass->dar));
     return 0;
 }
 
@@ -106,6 +146,7 @@ static av_cold void uninit(AVFilterContext *ctx)
     AssContext *ass = ctx->priv;
 
     av_freep(&ass->filename);
+    av_freep(&ass->dar_str);
     if (ass->track)
         ass_free_track(ass->track);
     if (ass->renderer)
@@ -142,7 +183,7 @@ static int config_input(AVFilterLink *inlink)
     ass->vsub = pix_desc->log2_chroma_h;
 
     ass_set_frame_size  (ass->renderer, inlink->w, inlink->h);
-    ass_set_aspect_ratio(ass->renderer, 1.0, sar);
+    ass_set_aspect_ratio(ass->renderer, av_q2d(ass->dar), sar);
 
     return 0;
 }