diff options
author | Martin Storsjö <martin@martin.st> | 2015-04-29 17:59:01 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2015-05-02 22:09:06 +0300 |
commit | 16302246b1fcb7ad4e6f7bd31c49956a455336d2 (patch) | |
tree | c5c5a29b3f25d02b7e56cf0aa2bc679a07ac5d2d | |
parent | e2d50fc2f5f3600e13055acf1a10fec35e941f37 (diff) | |
download | ffmpeg-16302246b1fcb7ad4e6f7bd31c49956a455336d2.tar.gz |
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@martin.st>
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | avconv.c | 2 | ||||
-rw-r--r-- | avconv.h | 3 | ||||
-rw-r--r-- | avconv_filter.c | 43 | ||||
-rw-r--r-- | avconv_opt.c | 6 | ||||
-rw-r--r-- | doc/avconv.texi | 3 |
6 files changed, 58 insertions, 0 deletions
@@ -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: @@ -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) @@ -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 e54da56c7a..c3360f1741 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 16254299e2..29fc2be6dd 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 37733bc2a9..aea41d9eec 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. +@item -noautorotate +Disable automatically rotating video based on file metadata. + @end table @section Video Options |