[FFmpeg-cvslog] avconv: Add an option for automatically rotating video according to display matrix

Martin Storsjö git at videolan.org
Sat May 2 23:12:59 CEST 2015


ffmpeg | branch: master | Martin Storsjö <martin at martin.st> | Wed Apr 29 17:59:01 2015 +0300| [16302246b1fcb7ad4e6f7bd31c49956a455336d2] | committer: Martin Storsjö

avconv: Add an option for automatically rotating video according to display matrix

The option is enabled by default, but can be disabled.

If this is enabled, such side data isn't copied into the output stream
(except when doing stream copy).

Signed-off-by: Martin Storsjö <martin at martin.st>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=16302246b1fcb7ad4e6f7bd31c49956a455336d2
---

 Changelog       |    1 +
 avconv.c        |    2 ++
 avconv.h        |    3 +++
 avconv_filter.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 avconv_opt.c    |    6 ++++++
 doc/avconv.texi |    3 +++
 6 files changed, 58 insertions(+)

diff --git a/Changelog b/Changelog
index c3ea67c..2fd1583 100644
--- a/Changelog
+++ b/Changelog
@@ -28,6 +28,7 @@ version <next>:
 - MMAL-accelerated H.264 decoding
 - DTS decoding through libdcadec
 - Canopus HQ/HQA decoder
+- Automatically rotate videos based on metadata in avconv
 
 
 version 11:
diff --git a/avconv.c b/avconv.c
index 1ad6e5e..275c3eb 100644
--- a/avconv.c
+++ b/avconv.c
@@ -2433,6 +2433,8 @@ static int process_input(void)
 
             if (av_packet_get_side_data(&pkt, src_sd->type, NULL))
                 continue;
+            if (ist->autorotate && src_sd->type == AV_PKT_DATA_DISPLAYMATRIX)
+                continue;
 
             dst_data = av_packet_new_side_data(&pkt, src_sd->type, src_sd->size);
             if (!dst_data)
diff --git a/avconv.h b/avconv.h
index b932d7e..5fddf98 100644
--- a/avconv.h
+++ b/avconv.h
@@ -113,6 +113,8 @@ typedef struct OptionsContext {
     int        nb_hwaccels;
     SpecifierOpt *hwaccel_devices;
     int        nb_hwaccel_devices;
+    SpecifierOpt *autorotate;
+    int        nb_autorotate;
 
     /* output options */
     StreamMap *stream_maps;
@@ -236,6 +238,7 @@ typedef struct InputStream {
     AVDictionary *decoder_opts;
     AVRational framerate;               /* framerate forced with -r */
 
+    int autorotate;
     int resample_height;
     int resample_width;
     int resample_pix_fmt;
diff --git a/avconv_filter.c b/avconv_filter.c
index e54da56..c3360f1 100644
--- a/avconv_filter.c
+++ b/avconv_filter.c
@@ -29,6 +29,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/display.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/pixfmt.h"
@@ -226,6 +227,28 @@ static int insert_trim(int64_t start_time, int64_t duration,
     return 0;
 }
 
+static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
+                         const char *filter_name, const char *args)
+{
+    AVFilterGraph *graph = (*last_filter)->graph;
+    AVFilterContext *ctx;
+    int ret;
+
+    ret = avfilter_graph_create_filter(&ctx,
+                                       avfilter_get_by_name(filter_name),
+                                       filter_name, args, NULL, graph);
+    if (ret < 0)
+        return ret;
+
+    ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
+    if (ret < 0)
+        return ret;
+
+    *last_filter = ctx;
+    *pad_idx     = 0;
+    return 0;
+}
+
 static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
 {
     char *pix_fmts;
@@ -446,6 +469,26 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
         return ret;
     last_filter = ifilter->filter;
 
+    if (ist->autorotate) {
+        uint8_t* displaymatrix = av_stream_get_side_data(ist->st,
+                                                         AV_PKT_DATA_DISPLAYMATRIX, NULL);
+        if (displaymatrix) {
+            double rot = av_display_rotation_get((int32_t*) displaymatrix);
+            if (rot < -135 || rot > 135) {
+                ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
+                if (ret < 0)
+                    return ret;
+                ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
+            } else if (rot < -45) {
+                ret = insert_filter(&last_filter, &pad_idx, "transpose", "dir=clock");
+            } else if (rot > 45) {
+                ret = insert_filter(&last_filter, &pad_idx, "transpose", "dir=cclock");
+            }
+            if (ret < 0)
+                return ret;
+        }
+    }
+
     if (ist->framerate.num) {
         AVFilterContext *setpts;
 
diff --git a/avconv_opt.c b/avconv_opt.c
index 1625429..29fc2be 100644
--- a/avconv_opt.c
+++ b/avconv_opt.c
@@ -488,6 +488,9 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
         ist->ts_scale = 1.0;
         MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
 
+        ist->autorotate = 1;
+        MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
+
         MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
         if (codec_tag) {
             uint32_t tag = strtol(codec_tag, &next, 0);
@@ -2372,6 +2375,9 @@ const OptionDef options[] = {
     { "hwaccel_device",   OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
                           OPT_SPEC | OPT_INPUT,                                  { .off = OFFSET(hwaccel_devices) },
         "select a device for HW acceleration" "devicename" },
+    { "autorotate",       HAS_ARG | OPT_BOOL | OPT_SPEC |
+                          OPT_EXPERT | OPT_INPUT,                                { .off = OFFSET(autorotate) },
+        "automatically insert correct rotate filters" },
 
     /* audio options */
     { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_frames },
diff --git a/doc/avconv.texi b/doc/avconv.texi
index 37733bc..aea41d9 100644
--- a/doc/avconv.texi
+++ b/doc/avconv.texi
@@ -401,6 +401,9 @@ Technical note -- attachments are implemented as codec extradata, so this
 option can actually be used to extract extradata from any stream, not just
 attachments.
 
+ at item -noautorotate
+Disable automatically rotating video based on file metadata.
+
 @end table
 
 @section Video Options



More information about the ffmpeg-cvslog mailing list