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).
---
 avconv.c        |  2 ++
 avconv.h        |  3 +++
 avconv_filter.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 avconv_opt.c    |  6 ++++++
 doc/avconv.texi |  3 +++
 5 files changed, 57 insertions(+)

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..f3986e6 100644
--- a/doc/avconv.texi
+++ b/doc/avconv.texi
@@ -403,6 +403,9 @@ attachments.
 
 @end table
 
+@item -noautorotate
+Disable automatically rotating video based on file metadata.
+
 @section Video Options
 
 @table @option
-- 
1.9.5 (Apple Git-50.3)

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to